Jupiter X Core - Version 2.0.9

Version Description

  • Fixed security issues
  • Improved control panel
  • Improved customizer
Download this release

Release Info

Developer artbees
Plugin Icon wp plugin Jupiter X Core
Version 2.0.9
Comparing to
See all releases

Code changes from version 1.16.2 to 2.0.9

Files changed (107) hide show
  1. includes/admin/options.php +62 -62
  2. includes/admin/tgmpa/tgmpa-plugin-list.php +221 -203
  3. includes/admin/update-plugins/class-update-plugins.php +141 -141
  4. includes/compiler/class-compiler.php +1077 -1067
  5. includes/compiler/functions.php +438 -438
  6. includes/compiler/preprocess-aliases.ini +277 -277
  7. includes/compiler/vendors/CSSJanus.php +543 -543
  8. includes/compiler/vendors/js-minifier.php +395 -395
  9. includes/compiler/vendors/lessc.php +3694 -3694
  10. includes/custom-fields/title-bar.php +33 -33
  11. includes/customizer/api/classes/class-cache.php +134 -0
  12. includes/customizer/api/classes/class-multilingual.php +452 -448
  13. includes/customizer/api/classes/class-status.php +64 -64
  14. includes/customizer/api/customizer.php +303 -295
  15. includes/customizer/api/includes/base/class-control.php +269 -243
  16. includes/customizer/api/includes/base/class-group-control.php +264 -264
  17. includes/customizer/api/includes/base/class-input-group.php +112 -103
  18. includes/customizer/api/includes/class-autoloader.php +119 -119
  19. includes/customizer/api/includes/class-templates.php +84 -184
  20. includes/customizer/api/includes/control/class-alert.php +91 -89
  21. includes/customizer/api/includes/control/class-box-model.php +211 -210
  22. includes/customizer/api/includes/control/class-child-popup.php +114 -115
  23. includes/customizer/api/includes/control/class-choose.php +135 -124
  24. includes/customizer/api/includes/control/class-color.php +66 -66
  25. includes/customizer/api/includes/control/class-divider.php +71 -71
  26. includes/customizer/api/includes/control/class-exceptions.php +86 -88
  27. includes/customizer/api/includes/control/class-font.php +78 -74
  28. includes/customizer/api/includes/control/class-image.php +70 -53
  29. includes/customizer/api/includes/control/class-input.php +206 -176
  30. includes/customizer/api/includes/control/class-label.php +86 -86
  31. includes/customizer/api/includes/control/class-multicheck.php +108 -108
  32. includes/customizer/api/includes/control/class-popup.php +102 -102
  33. includes/customizer/api/includes/control/class-pro-box.php +107 -107
  34. includes/customizer/api/includes/control/class-radio-image.php +78 -78
  35. includes/customizer/api/includes/control/class-select.php +132 -97
  36. includes/customizer/api/includes/control/class-template.php +112 -110
  37. includes/customizer/api/includes/control/class-text.php +147 -142
  38. includes/customizer/api/includes/control/class-textarea.php +45 -45
  39. includes/customizer/api/includes/control/class-toggle.php +50 -48
  40. includes/customizer/api/includes/control/group/class-background.php +342 -350
  41. includes/customizer/api/includes/control/group/class-border.php +102 -107
  42. includes/customizer/api/includes/control/group/class-box-shadow.php +127 -136
  43. includes/customizer/api/includes/control/group/class-typography.php +199 -204
  44. includes/customizer/api/includes/section/class-link.php +103 -103
  45. includes/customizer/api/includes/section/class-pane.php +84 -84
  46. includes/customizer/api/includes/section/class-popup.php +258 -258
  47. includes/customizer/api/init.php +162 -159
  48. includes/customizer/api/modules/compiler/class-compiler.php +66 -66
  49. includes/customizer/api/modules/compiler/class-get-variables.php +191 -182
  50. includes/customizer/api/modules/kirki-extend/base/class-output.php +77 -77
  51. includes/customizer/api/modules/kirki-extend/class-kirki-extend.php +201 -201
  52. includes/customizer/api/modules/kirki-extend/output/class-background.php +103 -103
  53. includes/customizer/api/modules/kirki-extend/output/class-border.php +109 -109
  54. includes/customizer/api/modules/kirki-extend/output/class-box-model.php +86 -86
  55. includes/customizer/api/modules/kirki-extend/output/class-box-shadow.php +50 -50
  56. includes/customizer/api/modules/kirki-extend/output/class-input.php +62 -62
  57. includes/customizer/api/modules/kirki-extend/output/class-typography.php +73 -73
  58. includes/customizer/api/modules/post-message/class-post-message.php +67 -67
  59. includes/customizer/functions.php +845 -507
  60. includes/customizer/settings/404/popup.php +67 -42
  61. includes/customizer/settings/blog-archive/popup.php +82 -34
  62. includes/customizer/settings/blog-archive/settings.php +111 -35
  63. includes/customizer/settings/blog-single/author-box.php +16 -15
  64. includes/customizer/settings/blog-single/avatar.php +83 -65
  65. includes/customizer/settings/blog-single/featured-image.php +300 -304
  66. includes/customizer/settings/blog-single/meta.php +194 -179
  67. includes/customizer/settings/blog-single/navigation.php +16 -15
  68. includes/customizer/settings/blog-single/popup.php +13 -134
  69. includes/customizer/settings/blog-single/post-content.php +82 -66
  70. includes/customizer/settings/blog-single/related-posts.php +16 -15
  71. includes/customizer/settings/blog-single/settings.php +151 -144
  72. includes/customizer/settings/blog-single/social-share.php +16 -15
  73. includes/customizer/settings/blog-single/tags.php +278 -219
  74. includes/customizer/settings/blog-single/title.php +87 -66
  75. includes/customizer/settings/cart-quick-view/popup.php +44 -48
  76. includes/customizer/settings/cart-quick-view/settings.php +62 -45
  77. includes/customizer/settings/cart-quick-view/styles.php +179 -134
  78. includes/customizer/settings/checkout-cart/popup.php +90 -57
  79. includes/customizer/settings/checkout-cart/settings.php +28 -27
  80. includes/customizer/settings/comment/action-link.php +129 -93
  81. includes/customizer/settings/comment/avatar.php +68 -54
  82. includes/customizer/settings/comment/button.php +235 -180
  83. includes/customizer/settings/comment/comment-text.php +52 -49
  84. includes/customizer/settings/comment/date.php +37 -27
  85. includes/customizer/settings/comment/field.php +218 -163
  86. includes/customizer/settings/comment/name.php +28 -27
  87. includes/customizer/settings/comment/popup.php +64 -91
  88. includes/customizer/settings/comment/settings.php +31 -37
  89. includes/customizer/settings/comment/title.php +52 -49
  90. includes/customizer/settings/footer/popup.php +94 -164
  91. includes/customizer/settings/footer/settings.php +359 -264
  92. includes/customizer/settings/footer/subfooter-container.php +102 -77
  93. includes/customizer/settings/footer/subfooter-copyright.php +71 -52
  94. includes/customizer/settings/footer/subfooter-menu.php +206 -137
  95. includes/customizer/settings/footer/widget-area-container.php +115 -98
  96. includes/customizer/settings/footer/widgets-container.php +115 -87
  97. includes/customizer/settings/footer/widgets-divider.php +96 -71
  98. includes/customizer/settings/footer/widgets-link.php +140 -92
  99. includes/customizer/settings/footer/widgets-text.php +36 -26
  100. includes/customizer/settings/footer/widgets-thumbnail.php +92 -77
  101. includes/customizer/settings/footer/widgets-title.php +82 -66
  102. includes/customizer/settings/header/container.php +99 -84
  103. includes/customizer/settings/header/logo.php +105 -64
  104. includes/customizer/settings/header/menu.php +278 -222
  105. includes/customizer/settings/header/popup.php +87 -129
  106. includes/customizer/settings/header/search.php +170 -148
  107. includes/customizer/settings/header/settings.php +60 -274
includes/admin/options.php CHANGED
@@ -1,62 +1,62 @@
1
- <?php
2
- /**
3
- * Add Jupiter X admin options.
4
- *
5
- * @package JupiterX_Core\Admin
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- add_filter( 'upload_mimes', 'jupiterx_add_extra_mime_types' );
11
-
12
- if ( ! function_exists( 'jupiterx_add_extra_mime_types' ) ) {
13
- /**
14
- * Add more mime type.
15
- *
16
- * @since 1.9.0
17
- *
18
- * @param array $mimes Current array of mime types..
19
- *
20
- * @return array Updated array of mime types.
21
- */
22
- function jupiterx_add_extra_mime_types( $mimes ) {
23
-
24
- if ( ! empty( jupiterx_get_option( 'svg_support' ) ) ) {
25
- $mimes['svg'] = 'image/svg+xml';
26
- }
27
-
28
- $mimes['zip'] = 'application/zip';
29
-
30
- return $mimes;
31
- }
32
- }
33
-
34
- add_filter( 'wp_check_filetype_and_ext', 'jupiterx_fix_filetype_check', 10, 4 );
35
- /**
36
- * Fix the mime type filtering issue.
37
- *
38
- * @since 1.9.0
39
- *
40
- * @param array $data file data.
41
- * @param string $file Full path to the file.
42
- * @param string $filename The name of the file (may differ from $file due to $file being in a tmp.
43
- * @param array $mimes Key is the file extension with value as the mime type.
44
- * @return array Filetype data.
45
- *
46
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
47
- */
48
- function jupiterx_fix_filetype_check( $data, $file, $filename, $mimes ) {
49
- if ( ! empty( $data['ext'] ) && ! empty( $data['type'] ) ) {
50
- return $data;
51
- }
52
-
53
- $wp_filetype = wp_check_filetype( $filename, $mimes );
54
-
55
- if ( 'svg' === $wp_filetype['ext'] || 'svgz' === $wp_filetype['ext'] ) {
56
- $data['ext'] = $wp_filetype['ext'];
57
- $data['type'] = 'image/svg+xml';
58
- }
59
-
60
- return $data;
61
- }
62
-
1
+ <?php
2
+ /**
3
+ * Add Jupiter X admin options.
4
+ *
5
+ * @package JupiterX_Core\Admin
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ add_filter( 'upload_mimes', 'jupiterx_add_extra_mime_types' );
11
+
12
+ if ( ! function_exists( 'jupiterx_add_extra_mime_types' ) ) {
13
+ /**
14
+ * Add more mime type.
15
+ *
16
+ * @since 1.9.0
17
+ *
18
+ * @param array $mimes Current array of mime types..
19
+ *
20
+ * @return array Updated array of mime types.
21
+ */
22
+ function jupiterx_add_extra_mime_types( $mimes ) {
23
+
24
+ if ( ! empty( jupiterx_get_option( 'svg_support' ) ) ) {
25
+ $mimes['svg'] = 'image/svg+xml';
26
+ }
27
+
28
+ $mimes['zip'] = 'application/zip';
29
+
30
+ return $mimes;
31
+ }
32
+ }
33
+
34
+ add_filter( 'wp_check_filetype_and_ext', 'jupiterx_fix_filetype_check', 10, 4 );
35
+ /**
36
+ * Fix the mime type filtering issue.
37
+ *
38
+ * @since 1.9.0
39
+ *
40
+ * @param array $data file data.
41
+ * @param string $file Full path to the file.
42
+ * @param string $filename The name of the file (may differ from $file due to $file being in a tmp.
43
+ * @param array $mimes Key is the file extension with value as the mime type.
44
+ * @return array Filetype data.
45
+ *
46
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
47
+ */
48
+ function jupiterx_fix_filetype_check( $data, $file, $filename, $mimes ) {
49
+ if ( ! empty( $data['ext'] ) && ! empty( $data['type'] ) ) {
50
+ return $data;
51
+ }
52
+
53
+ $wp_filetype = wp_check_filetype( $filename, $mimes );
54
+
55
+ if ( 'svg' === $wp_filetype['ext'] || 'svgz' === $wp_filetype['ext'] ) {
56
+ $data['ext'] = $wp_filetype['ext'];
57
+ $data['type'] = 'image/svg+xml';
58
+ }
59
+
60
+ return $data;
61
+ }
62
+
includes/admin/tgmpa/tgmpa-plugin-list.php CHANGED
@@ -1,203 +1,221 @@
1
- <?php
2
- /**
3
- * Add Jupiter X pro plugins.
4
- *
5
- * @package JupiterX_Core\Admin
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- add_filter( 'jupiterx_tgmpa_plugins', 'jupiterx_pro_plugins' );
11
-
12
- /**
13
- * Add Jupiter X Pro plugins.
14
- *
15
- * @since 1.9.0
16
- *
17
- * @param array $plugins Array of free Jupiter x plugins.
18
- * @return array Array af free and pro plugins.
19
- */
20
- function jupiterx_pro_plugins( $plugins ) {
21
-
22
- $pro_plugins = [
23
- [
24
- 'name' => __( 'Raven', 'jupiterx-core' ),
25
- 'slug' => 'raven',
26
- 'required' => false,
27
- 'force_activation' => false,
28
- 'force_deactivation' => false,
29
- 'pro' => true,
30
- 'source' => 'external',
31
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
32
- ],
33
- [
34
- 'name' => __( 'Jupiter Donut', 'jupiterx-core' ),
35
- 'slug' => 'jupiter-donut',
36
- 'required' => false,
37
- 'force_activation' => false,
38
- 'force_deactivation' => false,
39
- 'pro' => true,
40
- 'source' => 'external',
41
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
42
- ],
43
- [
44
- 'name' => __( 'Jet Elements', 'jupiterx-core' ),
45
- 'slug' => 'jet-elements',
46
- 'required' => false,
47
- 'force_activation' => false,
48
- 'force_deactivation' => false,
49
- 'pro' => true,
50
- 'source' => 'external',
51
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
52
- ],
53
- [
54
- 'name' => __( 'Jet Blog', 'jupiterx-core' ),
55
- 'slug' => 'jet-blog',
56
- 'required' => false,
57
- 'force_activation' => false,
58
- 'force_deactivation' => false,
59
- 'pro' => true,
60
- 'source' => 'external',
61
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
62
- ],
63
- [
64
- 'name' => __( 'Jet Menu', 'jupiterx-core' ),
65
- 'slug' => 'jet-menu',
66
- 'required' => false,
67
- 'force_activation' => false,
68
- 'force_deactivation' => false,
69
- 'pro' => true,
70
- 'source' => 'external',
71
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
72
- ],
73
- [
74
- 'name' => __( 'Jet Popup', 'jupiterx-core' ),
75
- 'slug' => 'jet-popup',
76
- 'required' => false,
77
- 'force_activation' => false,
78
- 'force_deactivation' => false,
79
- 'pro' => true,
80
- 'source' => 'external',
81
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
82
- ],
83
- [
84
- 'name' => __( 'Jet Tabs', 'jupiterx-core' ),
85
- 'slug' => 'jet-tabs',
86
- 'required' => false,
87
- 'force_activation' => false,
88
- 'force_deactivation' => false,
89
- 'pro' => true,
90
- 'source' => 'external',
91
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
92
- ],
93
- [
94
- 'name' => __( 'Jet WooBuilder', 'jupiterx-core' ),
95
- 'slug' => 'jet-woo-builder',
96
- 'required' => false,
97
- 'force_activation' => false,
98
- 'force_deactivation' => false,
99
- 'pro' => true,
100
- 'source' => 'external',
101
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
102
- ],
103
- [
104
- 'name' => __( 'Jet Tricks', 'jupiterx-core' ),
105
- 'slug' => 'jet-tricks',
106
- 'required' => false,
107
- 'force_activation' => false,
108
- 'force_deactivation' => false,
109
- 'pro' => true,
110
- 'source' => 'external',
111
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
112
- ],
113
- [
114
- 'name' => __( 'Jet Engine', 'jupiterx-core' ),
115
- 'slug' => 'jet-engine',
116
- 'required' => false,
117
- 'force_activation' => false,
118
- 'force_deactivation' => false,
119
- 'pro' => true,
120
- 'source' => 'external',
121
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
122
- ],
123
- [
124
- 'name' => __( 'Jet SmartFilters', 'jupiterx-core' ),
125
- 'slug' => 'jet-smart-filters',
126
- 'required' => false,
127
- 'force_activation' => false,
128
- 'force_deactivation' => false,
129
- 'pro' => true,
130
- 'source' => 'external',
131
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
132
- ],
133
- [
134
- 'name' => __( 'Advanced Custom Fields PRO', 'jupiterx-core' ),
135
- 'slug' => 'advanced-custom-fields-pro',
136
- 'required' => false,
137
- 'force_activation' => false,
138
- 'force_deactivation' => false,
139
- 'pro' => true,
140
- 'source' => 'external',
141
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
142
- ],
143
- [
144
- 'name' => __( 'Slider Revolution', 'jupiterx-core' ),
145
- 'slug' => 'revslider',
146
- 'required' => false,
147
- 'force_activation' => false,
148
- 'force_deactivation' => false,
149
- 'pro' => true,
150
- 'source' => 'external',
151
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
152
- ],
153
- [
154
- 'name' => __( 'Master Slider', 'jupiterx-core' ),
155
- 'slug' => 'masterslider',
156
- 'required' => false,
157
- 'force_activation' => false,
158
- 'force_deactivation' => false,
159
- 'pro' => true,
160
- 'source' => 'external',
161
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
162
- ],
163
- [
164
- 'name' => __( 'Layer Slider', 'jupiterx-core' ),
165
- 'slug' => 'layerslider',
166
- 'required' => false,
167
- 'force_activation' => false,
168
- 'force_deactivation' => false,
169
- 'pro' => true,
170
- 'source' => 'external',
171
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
172
- ],
173
- [
174
- 'name' => __( 'WPBakery Page Builder', 'jupiterx-core' ),
175
- 'slug' => 'raven',
176
- 'required' => false,
177
- 'force_activation' => false,
178
- 'force_deactivation' => false,
179
- 'pro' => true,
180
- 'source' => 'external',
181
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
182
- ],
183
- [
184
- 'name' => __( 'Customizer Reset', 'jupiterx-core' ),
185
- 'slug' => 'customizer-reset-by-wpzoom',
186
- 'required' => false,
187
- 'force_activation' => false,
188
- 'force_deactivation' => false,
189
- 'pro' => false,
190
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
191
- ],
192
- [
193
- 'name' => __( 'Customizer Export/Import', 'jupiterx-core' ),
194
- 'slug' => 'customizer-export-import',
195
- 'required' => false,
196
- 'force_activation' => false,
197
- 'force_deactivation' => false,
198
- 'pro' => false,
199
- 'label_type' => __( 'Optional', 'jupiterx-core' ),
200
- ],
201
- ];
202
- return array_merge( $pro_plugins, $plugins );
203
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter X pro plugins.
4
+ *
5
+ * @package JupiterX_Core\Admin
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ add_filter( 'jupiterx_tgmpa_plugins', 'jupiterx_pro_plugins' );
11
+
12
+ /**
13
+ * Add Jupiter X Pro plugins.
14
+ *
15
+ * @since 1.9.0
16
+ *
17
+ * @param array $plugins Array of free Jupiter x plugins.
18
+ * @return array Array af free and pro plugins.
19
+ */
20
+ function jupiterx_pro_plugins( $plugins ) {
21
+ $pro_plugins = [
22
+ [
23
+ 'name' => __( 'Raven', 'jupiterx-core' ),
24
+ 'slug' => 'raven',
25
+ 'required' => false,
26
+ 'force_activation' => false,
27
+ 'force_deactivation' => false,
28
+ 'pro' => true,
29
+ 'source' => 'external',
30
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
31
+ ],
32
+ [
33
+ 'name' => __( 'Jupiter Donut', 'jupiterx-core' ),
34
+ 'slug' => 'jupiter-donut',
35
+ 'required' => false,
36
+ 'force_activation' => false,
37
+ 'force_deactivation' => false,
38
+ 'pro' => true,
39
+ 'source' => 'external',
40
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
41
+ ],
42
+ [
43
+ 'name' => __( 'Jet Elements', 'jupiterx-core' ),
44
+ 'slug' => 'jet-elements',
45
+ 'required' => false,
46
+ 'force_activation' => false,
47
+ 'force_deactivation' => false,
48
+ 'pro' => true,
49
+ 'source' => 'external',
50
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
51
+ ],
52
+ [
53
+ 'name' => __( 'Jet Blog', 'jupiterx-core' ),
54
+ 'slug' => 'jet-blog',
55
+ 'required' => false,
56
+ 'force_activation' => false,
57
+ 'force_deactivation' => false,
58
+ 'pro' => true,
59
+ 'source' => 'external',
60
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
61
+ ],
62
+ [
63
+ 'name' => __( 'Jet Menu', 'jupiterx-core' ),
64
+ 'slug' => 'jet-menu',
65
+ 'required' => false,
66
+ 'force_activation' => false,
67
+ 'force_deactivation' => false,
68
+ 'pro' => true,
69
+ 'source' => 'external',
70
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
71
+ ],
72
+ [
73
+ 'name' => __( 'Jet Popup', 'jupiterx-core' ),
74
+ 'slug' => 'jet-popup',
75
+ 'required' => false,
76
+ 'force_activation' => false,
77
+ 'force_deactivation' => false,
78
+ 'pro' => true,
79
+ 'source' => 'external',
80
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
81
+ ],
82
+ [
83
+ 'name' => __( 'Jet Tabs', 'jupiterx-core' ),
84
+ 'slug' => 'jet-tabs',
85
+ 'required' => false,
86
+ 'force_activation' => false,
87
+ 'force_deactivation' => false,
88
+ 'pro' => true,
89
+ 'source' => 'external',
90
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
91
+ ],
92
+ [
93
+ 'name' => __( 'Jet WooBuilder', 'jupiterx-core' ),
94
+ 'slug' => 'jet-woo-builder',
95
+ 'required' => false,
96
+ 'force_activation' => false,
97
+ 'force_deactivation' => false,
98
+ 'pro' => true,
99
+ 'source' => 'external',
100
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
101
+ ],
102
+ [
103
+ 'name' => __( 'Jet Tricks', 'jupiterx-core' ),
104
+ 'slug' => 'jet-tricks',
105
+ 'required' => false,
106
+ 'force_activation' => false,
107
+ 'force_deactivation' => false,
108
+ 'pro' => true,
109
+ 'source' => 'external',
110
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
111
+ ],
112
+ [
113
+ 'name' => __( 'Jet Engine', 'jupiterx-core' ),
114
+ 'slug' => 'jet-engine',
115
+ 'required' => false,
116
+ 'force_activation' => false,
117
+ 'force_deactivation' => false,
118
+ 'pro' => true,
119
+ 'source' => 'external',
120
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
121
+ ],
122
+ [
123
+ 'name' => __( 'Jet SmartFilters', 'jupiterx-core' ),
124
+ 'slug' => 'jet-smart-filters',
125
+ 'required' => false,
126
+ 'force_activation' => false,
127
+ 'force_deactivation' => false,
128
+ 'pro' => true,
129
+ 'source' => 'external',
130
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
131
+ ],
132
+ [
133
+ 'name' => __( 'Advanced Custom Fields PRO', 'jupiterx-core' ),
134
+ 'slug' => 'advanced-custom-fields-pro',
135
+ 'required' => false,
136
+ 'force_activation' => false,
137
+ 'force_deactivation' => false,
138
+ 'pro' => true,
139
+ 'source' => 'external',
140
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
141
+ ],
142
+ [
143
+ 'name' => __( 'Slider Revolution', 'jupiterx-core' ),
144
+ 'slug' => 'revslider',
145
+ 'required' => false,
146
+ 'force_activation' => false,
147
+ 'force_deactivation' => false,
148
+ 'pro' => true,
149
+ 'source' => 'external',
150
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
151
+ ],
152
+ [
153
+ 'name' => __( 'Master Slider', 'jupiterx-core' ),
154
+ 'slug' => 'masterslider',
155
+ 'required' => false,
156
+ 'force_activation' => false,
157
+ 'force_deactivation' => false,
158
+ 'pro' => true,
159
+ 'source' => 'external',
160
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
161
+ ],
162
+ [
163
+ 'name' => __( 'Layer Slider', 'jupiterx-core' ),
164
+ 'slug' => 'layerslider',
165
+ 'required' => false,
166
+ 'force_activation' => false,
167
+ 'force_deactivation' => false,
168
+ 'pro' => true,
169
+ 'source' => 'external',
170
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
171
+ ],
172
+ [
173
+ 'name' => __( 'WPBakery Page Builder', 'jupiterx-core' ),
174
+ 'slug' => 'raven',
175
+ 'required' => false,
176
+ 'force_activation' => false,
177
+ 'force_deactivation' => false,
178
+ 'pro' => true,
179
+ 'source' => 'external',
180
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
181
+ ],
182
+ [
183
+ 'name' => __( 'Customizer Reset', 'jupiterx-core' ),
184
+ 'slug' => 'customizer-reset-by-wpzoom',
185
+ 'required' => false,
186
+ 'force_activation' => false,
187
+ 'force_deactivation' => false,
188
+ 'pro' => false,
189
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
190
+ ],
191
+ [
192
+ 'name' => __( 'Customizer Export/Import', 'jupiterx-core' ),
193
+ 'slug' => 'customizer-export-import',
194
+ 'required' => false,
195
+ 'force_activation' => false,
196
+ 'force_deactivation' => false,
197
+ 'pro' => false,
198
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
199
+ ],
200
+ [
201
+ 'name' => __( 'Sellkit Pro', 'jupiterx-core' ),
202
+ 'slug' => 'sellkit-pro',
203
+ 'required' => false,
204
+ 'force_activation' => false,
205
+ 'force_deactivation' => false,
206
+ 'pro' => false,
207
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
208
+ ],
209
+ [
210
+ 'name' => __( 'Sellkit', 'jupiterx-core' ),
211
+ 'slug' => 'sellkit',
212
+ 'required' => false,
213
+ 'force_activation' => false,
214
+ 'force_deactivation' => false,
215
+ 'pro' => false,
216
+ 'label_type' => __( 'Optional', 'jupiterx-core' ),
217
+ ],
218
+ ];
219
+
220
+ return array_merge( $pro_plugins, $plugins );
221
+ }
includes/admin/update-plugins/class-update-plugins.php CHANGED
@@ -1,141 +1,141 @@
1
- <?php
2
- /**
3
- * JupiterX_Core_Update_Plugins class filters the update plugins.
4
- *
5
- * @package JupiterX_Core\Admin
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- if ( ! class_exists( 'JupiterX_Core_Update_Plugins' ) ) {
11
- /**
12
- * Filter Update Plugins.
13
- *
14
- * @since 1.9.0
15
- */
16
- class JupiterX_Core_Update_Plugins {
17
-
18
- /**
19
- * Constructor.
20
- *
21
- * @since 1.9.0
22
- */
23
- public function __construct() {
24
- add_filter( 'pre_set_site_transient_update_plugins', [ $this, 'update_plugins' ], 999, 1 );
25
- }
26
-
27
- /**
28
- * Filter updates for managed pro plugins.
29
- *
30
- * @SuppressWarnings(PHPMD.NPathComplexity)
31
- *
32
- * @since 1.9.0
33
- *
34
- * @param array $transient Transient object.
35
- * @return object
36
- */
37
- public function update_plugins( $transient ) {
38
- if ( ! is_object( $transient ) ) {
39
- return $transient;
40
- }
41
-
42
- if ( ! isset( $transient->response ) ) {
43
- return $transient;
44
- }
45
-
46
- if ( ! function_exists( 'jupiterx_get_managed_plugins' ) ) {
47
- return $transient;
48
- }
49
-
50
- $force_check = ! empty( jupiterx_get( 'force-check' ) );
51
- $installed_plugins = $this->get_plugins();
52
- $managed_plugins = jupiterx_get_managed_plugins( $force_check );
53
-
54
- foreach ( $managed_plugins as $managed_plugin ) {
55
- if ( empty( $managed_plugin->source ) || 'wp-repo' === $managed_plugin->source ) {
56
- continue;
57
- }
58
-
59
- foreach ( $installed_plugins as $basename => $installed_plugin ) {
60
- if ( in_array( $basename, $this->skip_plugins(), true ) ) {
61
- continue;
62
- }
63
-
64
- if ( strpos( $basename, $managed_plugin->slug ) === false ) {
65
- continue;
66
- }
67
-
68
- if ( version_compare( $managed_plugin->version, $installed_plugin['Version'] ) <= 0 ) {
69
- unset( $transient->response[ $basename ] );
70
-
71
- continue;
72
- }
73
-
74
- $update = new stdClass();
75
-
76
- $update->slug = $managed_plugin->slug;
77
- $update->plugin = $basename;
78
- $update->new_version = $managed_plugin->version;
79
- $update->url = false;
80
- $update->package = $managed_plugin->source;
81
-
82
- $transient->response[ $basename ] = $update;
83
- }
84
- }
85
-
86
- return $transient;
87
- }
88
-
89
- /**
90
- * Wrapper around the core WP get_plugins function, making sure it's actually available.
91
- *
92
- * @since 1.9.0
93
- *
94
- * @return array Array of installed plugins with plugin information.
95
- */
96
- public function get_plugins() {
97
- if ( ! function_exists( 'get_plugins' ) ) {
98
- require_once ABSPATH . 'wp-admin/includes/plugin.php';
99
- }
100
-
101
- return get_plugins();
102
- }
103
-
104
- /**
105
- * Ignore plugins update source from Artbees.
106
- *
107
- * @since 1.16.0
108
- * @access public
109
- *
110
- * @return array
111
- */
112
- public function skip_plugins() {
113
- $plugins = [];
114
-
115
- $this->skip_revslider( $plugins );
116
-
117
- return $plugins;
118
- }
119
-
120
- /**
121
- * Ignore revslider update source from Artbees.
122
- *
123
- * @since 1.16.0
124
- * @access public
125
- *
126
- * @param array $plugins Plugins array.
127
- */
128
- public function skip_revslider( &$plugins ) {
129
- if (
130
- 'true' !== get_option( 'revslider-valid' ) ||
131
- empty( get_option( 'revslider-code' ) )
132
- ) {
133
- return;
134
- }
135
-
136
- $plugins[] = 'revslider/revslider.php';
137
- }
138
- }
139
-
140
- new JupiterX_Core_Update_Plugins();
141
- }
1
+ <?php
2
+ /**
3
+ * JupiterX_Core_Update_Plugins class filters the update plugins.
4
+ *
5
+ * @package JupiterX_Core\Admin
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ if ( ! class_exists( 'JupiterX_Core_Update_Plugins' ) ) {
11
+ /**
12
+ * Filter Update Plugins.
13
+ *
14
+ * @since 1.9.0
15
+ */
16
+ class JupiterX_Core_Update_Plugins {
17
+
18
+ /**
19
+ * Constructor.
20
+ *
21
+ * @since 1.9.0
22
+ */
23
+ public function __construct() {
24
+ add_filter( 'pre_set_site_transient_update_plugins', [ $this, 'update_plugins' ], 999, 1 );
25
+ }
26
+
27
+ /**
28
+ * Filter updates for managed pro plugins.
29
+ *
30
+ * @SuppressWarnings(PHPMD.NPathComplexity)
31
+ *
32
+ * @since 1.9.0
33
+ *
34
+ * @param array $transient Transient object.
35
+ * @return object
36
+ */
37
+ public function update_plugins( $transient ) {
38
+ if ( ! is_object( $transient ) ) {
39
+ return $transient;
40
+ }
41
+
42
+ if ( ! isset( $transient->response ) ) {
43
+ return $transient;
44
+ }
45
+
46
+ if ( ! function_exists( 'jupiterx_get_managed_plugins' ) ) {
47
+ return $transient;
48
+ }
49
+
50
+ $force_check = ! empty( jupiterx_get( 'force-check' ) );
51
+ $installed_plugins = $this->get_plugins();
52
+ $managed_plugins = jupiterx_get_managed_plugins( $force_check );
53
+
54
+ foreach ( $managed_plugins as $managed_plugin ) {
55
+ if ( empty( $managed_plugin->source ) || 'wp-repo' === $managed_plugin->source ) {
56
+ continue;
57
+ }
58
+
59
+ foreach ( $installed_plugins as $basename => $installed_plugin ) {
60
+ if ( in_array( $basename, $this->skip_plugins(), true ) ) {
61
+ continue;
62
+ }
63
+
64
+ if ( strpos( $basename, $managed_plugin->slug ) === false ) {
65
+ continue;
66
+ }
67
+
68
+ if ( version_compare( $managed_plugin->version, $installed_plugin['Version'] ) <= 0 ) {
69
+ unset( $transient->response[ $basename ] );
70
+
71
+ continue;
72
+ }
73
+
74
+ $update = new stdClass();
75
+
76
+ $update->slug = $managed_plugin->slug;
77
+ $update->plugin = $basename;
78
+ $update->new_version = $managed_plugin->version;
79
+ $update->url = false;
80
+ $update->package = $managed_plugin->source;
81
+
82
+ $transient->response[ $basename ] = $update;
83
+ }
84
+ }
85
+
86
+ return $transient;
87
+ }
88
+
89
+ /**
90
+ * Wrapper around the core WP get_plugins function, making sure it's actually available.
91
+ *
92
+ * @since 1.9.0
93
+ *
94
+ * @return array Array of installed plugins with plugin information.
95
+ */
96
+ public function get_plugins() {
97
+ if ( ! function_exists( 'get_plugins' ) ) {
98
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
99
+ }
100
+
101
+ return get_plugins();
102
+ }
103
+
104
+ /**
105
+ * Ignore plugins update source from Artbees.
106
+ *
107
+ * @since 1.16.0
108
+ * @access public
109
+ *
110
+ * @return array
111
+ */
112
+ public function skip_plugins() {
113
+ $plugins = [];
114
+
115
+ $this->skip_revslider( $plugins );
116
+
117
+ return $plugins;
118
+ }
119
+
120
+ /**
121
+ * Ignore revslider update source from Artbees.
122
+ *
123
+ * @since 1.16.0
124
+ * @access public
125
+ *
126
+ * @param array $plugins Plugins array.
127
+ */
128
+ public function skip_revslider( &$plugins ) {
129
+ if (
130
+ 'true' !== get_option( 'revslider-valid' ) ||
131
+ empty( get_option( 'revslider-code' ) )
132
+ ) {
133
+ return;
134
+ }
135
+
136
+ $plugins[] = 'revslider/revslider.php';
137
+ }
138
+ }
139
+
140
+ new JupiterX_Core_Update_Plugins();
141
+ }
includes/compiler/class-compiler.php CHANGED
@@ -1,1067 +1,1077 @@
1
- <?php
2
- /**
3
- * This class compiles and minifies CSS, LESS and JS.
4
- *
5
- * @package JupiterX\Framework\API\Compiler
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- /**
11
- * Compiles and minifies CSS, LESS and JS.
12
- *
13
- * @since 1.0.0
14
- * @ignore
15
- * @access private
16
- *
17
- * @package JupiterX\Framework\API\Compiler
18
- * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
19
- * @SuppressWarnings(PHPMD.ExcessiveClassLength)
20
- */
21
- final class _JupiterX_Compiler {
22
-
23
- /**
24
- * Compiler's runtime configuration parameters.
25
- *
26
- * @var array
27
- */
28
- private $config;
29
-
30
- /**
31
- * Cache dir.
32
- *
33
- * @var string
34
- */
35
- private $dir;
36
-
37
- /**
38
- * Cache url.
39
- *
40
- * @var string
41
- */
42
- private $url;
43
-
44
- /**
45
- * The fragment currently being processed.
46
- *
47
- * @var string
48
- */
49
- private $current_fragment;
50
-
51
- /**
52
- * The compiled content.
53
- *
54
- * @var string
55
- */
56
- private $compiled_content;
57
-
58
- /**
59
- * Compiled content's filename.
60
- *
61
- * @var string
62
- */
63
- private $filename;
64
-
65
- /**
66
- * Create a new Compiler.
67
- *
68
- * @since 1.0.0
69
- *
70
- * @param array $config Runtime configuration parameters for the Compiler.
71
- */
72
- public function __construct( array $config ) {
73
- $this->config = $this->init_config( $config );
74
- $this->dir = jupiterx_get_compiler_dir( is_admin() ) . $this->config['id'];
75
- $this->url = jupiterx_get_compiler_url( is_admin() ) . $this->config['id'];
76
- }
77
-
78
- /**
79
- * Run the compiler.
80
- *
81
- * @since 1.0.0
82
- *
83
- * @return void
84
- */
85
- public function run_compiler() {
86
- // Modify the WP Filesystem method.
87
- add_filter( 'filesystem_method', array( $this, 'modify_filesystem_method' ) );
88
-
89
- $this->set_fragments();
90
- $this->set_filename();
91
-
92
- if ( ! $this->cache_file_exist() ) {
93
- $this->filesystem();
94
- $this->maybe_make_dir();
95
- $this->combine_fragments();
96
- $this->cache_file();
97
- }
98
-
99
- if ( $this->config['enqueue'] ) {
100
- $this->enqueue_file();
101
- }
102
-
103
- // Keep it safe and reset the WP Filesystem method.
104
- remove_filter( 'filesystem_method', array( $this, 'modify_filesystem_method' ) );
105
- }
106
-
107
- /**
108
- * Callback to set the WP Filesystem method.
109
- *
110
- * @since 1.0.0
111
- *
112
- * @return string
113
- */
114
- public function modify_filesystem_method() {
115
- return 'direct';
116
- }
117
-
118
- /**
119
- * Initialise the WP Filesystem.
120
- *
121
- * @since 1.0.0
122
- *
123
- * @return bool|void
124
- */
125
- public function filesystem() {
126
-
127
- // If the WP_Filesystem is not already loaded, load it.
128
- if ( ! function_exists( 'WP_Filesystem' ) ) {
129
- require_once ABSPATH . '/wp-admin/includes/file.php';
130
- }
131
-
132
- // If the WP_Filesystem is not initialized or is not set to WP_Filesystem_Direct, then initialize it.
133
- if ( $this->is_wp_filesystem_direct() ) {
134
- return true;
135
- }
136
-
137
- // Initialize the filesystem.
138
- $response = WP_Filesystem();
139
-
140
- // If the filesystem did not initialize, then generate a report and exit.
141
- if ( true !== $response || ! $this->is_wp_filesystem_direct() ) {
142
- return $this->kill();
143
- }
144
-
145
- return true;
146
- }
147
-
148
- /**
149
- * Check if the filesystem is set to "direct".
150
- *
151
- * @since 1.0.0
152
- *
153
- * @return bool
154
- */
155
- private function is_wp_filesystem_direct() {
156
- return isset( $GLOBALS['wp_filesystem'] ) && is_a( $GLOBALS['wp_filesystem'], 'WP_Filesystem_Direct' );
157
- }
158
-
159
- /**
160
- * Make directory.
161
- *
162
- * @since 1.0.0
163
- *
164
- * @return bool
165
- */
166
- private function maybe_make_dir() {
167
-
168
- if ( ! @is_dir( $this->dir ) ) { // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- This is a valid use case.
169
- wp_mkdir_p( $this->dir );
170
- }
171
-
172
- return is_writable( $this->dir );
173
- }
174
-
175
- /**
176
- * Set class fragments.
177
- *
178
- * @since 1.0.0
179
- *
180
- * @return void
181
- */
182
- public function set_fragments() {
183
- global $_jupiterx_compiler_added_fragments;
184
-
185
- $added_fragments = jupiterx_get( $this->config['id'], $_jupiterx_compiler_added_fragments[ $this->config['format'] ] );
186
-
187
- if ( $added_fragments ) {
188
- $this->config['fragments'] = array_merge( $this->config['fragments'], $added_fragments );
189
- }
190
-
191
- /**
192
- * Filter the compiler fragment files.
193
- *
194
- * The dynamic portion of the hook name, $this->config['id'], refers to the compiler id used as a reference.
195
- *
196
- * @since 1.0.0
197
- *
198
- * @param array $fragments An array of fragment files.
199
- */
200
- $this->config['fragments'] = apply_filters( 'jupiterx_compiler_fragments_' . $this->config['id'], $this->config['fragments'] );
201
- }
202
-
203
- /**
204
- * Set the filename for the compiled asset.
205
- *
206
- * @since 1.0.0
207
- *
208
- * @return void
209
- */
210
- public function set_filename() {
211
- $hash = $this->hash( $this->config );
212
-
213
- if ( empty( _jupiterx_get_cache_busting() ) ) {
214
- $this->config['version'] = $hash;
215
-
216
- $hash = 'style';
217
-
218
- if ( 'script' === $this->config['type'] ) {
219
- $hash = 'script';
220
- }
221
- }
222
-
223
- $this->filename = $hash . '.' . $this->get_extension();
224
- }
225
-
226
- /**
227
- * Hash the given array.
228
- *
229
- * @since 1.0.0
230
- *
231
- * @param array $given_array Given array to be hashed.
232
- *
233
- * @return string
234
- */
235
- public function hash( array $given_array ) {
236
- return substr( md5( @serialize( $given_array ) ), 0, 7 ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize -- Valid use case.
237
- }
238
-
239
- /**
240
- * Checks if the file exists on the filesystem, meaning it's been cached.
241
- *
242
- * @since 1.0.0
243
- *
244
- * @return bool
245
- */
246
- public function cache_file_exist() {
247
- $filename = $this->get_filename();
248
-
249
- if ( _jupiterx_is_compiler_dev_mode() || is_customize_preview() ) {
250
- return false;
251
- }
252
-
253
- if ( empty( $filename ) ) {
254
- return false;
255
- }
256
-
257
- return file_exists( $filename );
258
- }
259
-
260
- /**
261
- * Get the absolute path of the cached and compiled file.
262
- *
263
- * @since 1.0.0
264
- *
265
- * @return string
266
- */
267
- public function get_filename() {
268
- if ( isset( $this->filename ) ) {
269
- return $this->dir . '/' . $this->filename;
270
- }
271
-
272
- return '';
273
- }
274
-
275
- /**
276
- * Create cached file.
277
- *
278
- * @since 1.0.0
279
- *
280
- * @return bool
281
- */
282
- public function cache_file() {
283
- $filename = $this->get_filename();
284
-
285
- if ( empty( $filename ) ) {
286
- return false;
287
- }
288
-
289
- // It is safe to access the filesystem because we made sure it was set.
290
- return $GLOBALS['wp_filesystem']->put_contents( $filename, $this->compiled_content, FS_CHMOD_FILE );
291
- }
292
-
293
- /**
294
- * Enqueue cached file.
295
- *
296
- * @since 1.0.0
297
- *
298
- * @return void|bool
299
- */
300
- private function enqueue_file() {
301
-
302
- // Enqueue CSS file.
303
- if ( 'style' === $this->config['type'] ) {
304
- return wp_enqueue_style(
305
- $this->config['id'],
306
- $this->get_url(),
307
- $this->config['dependencies'],
308
- $this->config['version']
309
- );
310
- }
311
-
312
- // Enqueue JS file.
313
- if ( 'script' === $this->config['type'] ) {
314
- return wp_enqueue_script(
315
- $this->config['id'],
316
- $this->get_url(),
317
- $this->config['dependencies'],
318
- $this->config['version'],
319
- $this->config['in_footer']
320
- );
321
- }
322
-
323
- return false;
324
- }
325
-
326
- /**
327
- * Get cached file url.
328
- *
329
- * @since 1.0.0
330
- *
331
- * @return string
332
- */
333
- public function get_url() {
334
- $url = trailingslashit( $this->url ) . $this->filename;
335
-
336
- if ( is_ssl() ) {
337
- $url = str_replace( 'http://', 'https://', $url );
338
- }
339
-
340
- return $url;
341
- }
342
-
343
- /**
344
- * Get the file extension from the configured "type".
345
- *
346
- * @since 1.0.0
347
- *
348
- * @return string|null
349
- */
350
- public function get_extension() {
351
-
352
- if ( 'style' === $this->config['type'] ) {
353
- return 'css';
354
- }
355
-
356
- if ( 'script' === $this->config['type'] ) {
357
- return 'js';
358
- }
359
- }
360
-
361
- /**
362
- * Combine content of the fragments.
363
- *
364
- * @since 1.0.0
365
- *
366
- * @return void
367
- */
368
- public function combine_fragments() {
369
- $content = '';
370
-
371
- // Loop through fragments.
372
- foreach ( $this->config['fragments'] as $fragment ) {
373
-
374
- // Stop here if the fragment is empty.
375
- if ( empty( $fragment ) ) {
376
- continue;
377
- }
378
-
379
- $fragment_content = $this->get_content( $fragment );
380
-
381
- // Stop here if no content or content is an html page.
382
- if ( ! $fragment_content || preg_match( '#^\s*\<#', $fragment_content ) ) {
383
- continue;
384
- }
385
-
386
- // Continue processing style.
387
- if ( 'style' === $this->config['type'] ) {
388
- $fragment_content = $this->replace_css_url( $fragment_content );
389
- $fragment_content = $this->add_content_media_query( $fragment_content );
390
- }
391
-
392
- // If there's content, start a new line.
393
- if ( $content ) {
394
- $content .= "\n\n";
395
- }
396
-
397
- $content .= $fragment_content;
398
- }
399
-
400
- $this->compiled_content = ! empty( $content ) ? $this->format_content( $content ) : '';
401
- }
402
-
403
- /**
404
- * Get the fragment's content.
405
- *
406
- * @since 1.0.0
407
- *
408
- * @param string|callable $fragment The given fragment from which to get the content.
409
- *
410
- * @return bool|string
411
- */
412
- private function get_content( $fragment ) {
413
- // Set the current fragment used by other functions.
414
- $this->current_fragment = $fragment;
415
-
416
- // If the fragment is callable, call it to get the content.
417
- if ( $this->is_function( $fragment ) ) {
418
- return $this->get_function_content();
419
- }
420
-
421
- $content = $this->get_internal_content();
422
-
423
- // Try remote content if the internal content returned false.
424
- if ( empty( $content ) ) {
425
- $content = $this->get_remote_content();
426
- }
427
-
428
- return $content;
429
- }
430
-
431
- /**
432
- * Get internal file content.
433
- *
434
- * @since 1.0.0
435
- *
436
- * @return string|bool
437
- */
438
- public function get_internal_content() {
439
- $fragment = $this->current_fragment;
440
-
441
- if ( ! file_exists( $fragment ) ) {
442
-
443
- // Replace URL with path.
444
- $fragment = jupiterx_url_to_path( $fragment );
445
-
446
- // Stop here if it isn't a valid file.
447
- if ( ! file_exists( $fragment ) || 0 === @filesize( $fragment ) ) { // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Valid use case.
448
- return false;
449
- }
450
- }
451
-
452
- // It is safe to access the filesystem because we made sure it was set.
453
- return $GLOBALS['wp_filesystem']->get_contents( $fragment );
454
- }
455
-
456
- /**
457
- * Get external file content.
458
- *
459
- * @since 1.0.0
460
- *
461
- * @return string|bool
462
- */
463
- public function get_remote_content() {
464
- $fragment = $this->current_fragment;
465
-
466
- if ( empty( $fragment ) ) {
467
- return false;
468
- }
469
-
470
- // For a relative URL, add http: to it.
471
- if ( substr( $fragment, 0, 2 ) === '//' ) {
472
- $fragment = 'http:' . $fragment;
473
- } elseif ( substr( $fragment, 0, 1 ) === '/' ) { // Add domain if it is local but could not be fetched as a file.
474
- $fragment = site_url( $fragment );
475
- }
476
-
477
- $request = wp_remote_get( $fragment );
478
-
479
- if ( is_wp_error( $request ) ) {
480
- return '';
481
- }
482
-
483
- // If no content was received and the URL is not https, then convert the URL to SSL and retry.
484
- if (
485
- ( ! isset( $request['body'] ) || 200 !== $request['response']['code'] ) &&
486
- ( substr( $fragment, 0, 8 ) !== 'https://' )
487
- ) {
488
- $fragment = str_replace( 'http://', 'https://', $fragment );
489
- $request = wp_remote_get( $fragment );
490
-
491
- if ( is_wp_error( $request ) ) {
492
- return '';
493
- }
494
- }
495
-
496
- if ( ( ! isset( $request['body'] ) || 200 !== $request['response']['code'] ) ) {
497
- return false;
498
- }
499
-
500
- return wp_remote_retrieve_body( $request );
501
- }
502
-
503
- /**
504
- * Get function content.
505
- *
506
- * @since 1.0.0
507
- *
508
- * @return string|bool
509
- */
510
- public function get_function_content() {
511
-
512
- if ( ! is_callable( $this->current_fragment ) ) {
513
- return false;
514
- }
515
-
516
- return call_user_func( $this->current_fragment );
517
- }
518
-
519
- /**
520
- * Wrap content in query.
521
- *
522
- * @since 1.0.0
523
- *
524
- * @param string $content Given content to process.
525
- *
526
- * @return string
527
- */
528
- public function add_content_media_query( $content ) {
529
-
530
- // Ignore if the fragment is a function.
531
- if ( $this->is_function( $this->current_fragment ) ) {
532
- return $content;
533
- }
534
-
535
- $query = wp_parse_url( $this->current_fragment, PHP_URL_QUERY );
536
-
537
- // Bail out if there are no query args or no media query.
538
- if ( empty( $query ) || false === stripos( $query, 'jupiterx_compiler_media_query' ) ) {
539
- return $content;
540
- }
541
-
542
- // Wrap the content in the query.
543
- return sprintf(
544
- "@media %s {\n%s\n}\n",
545
- jupiterx_get( 'jupiterx_compiler_media_query', wp_parse_args( $query ) ),
546
- $content
547
- );
548
- }
549
-
550
- /**
551
- * Format CSS, LESS and JS content.
552
- *
553
- * @since 1.0.0
554
- *
555
- * @param string $content Given content to process.
556
- *
557
- * @return string
558
- */
559
- public function format_content( $content ) {
560
-
561
- if ( 'style' === $this->config['type'] ) {
562
-
563
- if ( 'less' === $this->config['format'] ) {
564
-
565
- if ( ! class_exists( 'JupiterX_Lessc' ) ) {
566
- jupiterx_core()->load_files( [ 'compiler/vendors/lessc' ] );
567
- }
568
-
569
- $parser = new JupiterX_Lessc();
570
-
571
- $parser = $this->register_less_functions( $parser );
572
-
573
- $parser->setVariables( apply_filters( 'jupiterx_compiler_less_variables', $this->config['variables'] ) );
574
-
575
- $content = $parser->compile( $content );
576
-
577
- $content = $this->clean_style( $content );
578
- }
579
-
580
- if ( is_rtl() ) {
581
- if ( ! class_exists( 'CSSJanus' ) ) {
582
- jupiterx_core()->load_files( [ 'compiler/vendors/CSSJanus' ] );
583
- }
584
-
585
- $content = CSSJanus::transform( $content );
586
- }
587
-
588
- if ( ! _jupiterx_is_compiler_dev_mode() ) {
589
- $content = $this->minify_style_2( $content );
590
- }
591
-
592
- return $content;
593
- }
594
-
595
- if ( 'script' === $this->config['type'] && ! _jupiterx_is_compiler_dev_mode() && $this->config['minify_js'] ) {
596
-
597
- if ( ! class_exists( 'JSMin' ) ) {
598
- jupiterx_core()->load_files( [ 'compiler/vendors/js-minifier' ] );
599
- }
600
-
601
- $js_min = new JSMin( $content );
602
- return $js_min->min();
603
- }
604
-
605
- return $content;
606
- }
607
-
608
- /**
609
- * Replace CSS URL shortcuts with a valid URL.
610
- *
611
- * @since 1.0.0
612
- *
613
- * @param string $content Given content to process.
614
- *
615
- * @return string
616
- */
617
- public function replace_css_url( $content ) {
618
- return preg_replace_callback(
619
- '#url\s*\(\s*[\'"]*?([^\'"\)]+)[\'"]*\s*\)#i',
620
- array( $this, 'replace_css_url_callback' ),
621
- $content
622
- );
623
- }
624
-
625
- /**
626
- * Convert any CSS URL relative paths to absolute URLs.
627
- *
628
- * @since 1.0.0
629
- *
630
- * @param array $matches Matches to process, where 0 is the CSS' URL() and 1 is the URI.
631
- *
632
- * @return string
633
- */
634
- public function replace_css_url_callback( $matches ) {
635
-
636
- // If the URI is absolute, bail out and return the CSS.
637
- if ( _jupiterx_is_uri( $matches[1] ) ) {
638
- return $matches[0];
639
- }
640
-
641
- $base = $this->current_fragment;
642
-
643
- // Separate the placeholders and path.
644
- $paths = explode( '../', $matches[1] );
645
-
646
- /**
647
- * Walk backwards through each of the the fragment's directories, one-by-one. The `foreach` loop
648
- * provides us with a performant way to walk the fragment back to its base path based upon the
649
- * number of placeholders.
650
- */
651
- foreach ( $paths as $path ) {
652
- $base = dirname( $base );
653
- }
654
-
655
- // Make sure it is a valid base.
656
- if ( '.' === $base ) {
657
- $base = '';
658
- }
659
-
660
- // Rebuild the URL and make sure it is valid using the jupiterx_path_to_url function.
661
- $url = jupiterx_path_to_url( trailingslashit( $base ) . ltrim( end( $paths ), '/\\' ) );
662
-
663
- // Return the rebuilt path converted to an URL.
664
- return 'url("' . $url . '")';
665
- }
666
-
667
- /**
668
- * Register LESS_PHP functions.
669
- *
670
- * @since 1.0.0
671
- *
672
- * @param object $parser The LESS parser.
673
- *
674
- * @todo Refactoring is required.
675
- *
676
- * @return object
677
- */
678
- private function register_less_functions( $parser ) {
679
- $parser->registerFunction( 'jupiterx_value', function( $arg ) {
680
- $output = '';
681
-
682
- if ( isset( $arg[2][1][2][0] ) ) {
683
- $output = $arg[2][1][2][0]; // Default.
684
- }
685
-
686
- if ( ! empty( $arg[2][0][2][1][1] ) ) {
687
- return $arg[2][0][2][1][1]; // E.g. ~"@{@{var}-width}".
688
- }
689
-
690
- if ( ! empty( $arg[2][0][1] ) ) {
691
- $value = $arg[2][0][1]; // E.g. @text-size.
692
- $unit = empty( $arg[2][0][2] ) ? '' : $arg[2][0][2]; // E.g. @text-size unit.
693
-
694
- return $value . $unit;
695
- }
696
-
697
- return $output;
698
- } );
699
-
700
- $parser->registerFunction( 'jupiterx_value_pattern', function( $arg ) {
701
- if ( 0 === strlen( $arg[2][0][1] ) ) {
702
- return '';
703
- }
704
-
705
- list($type, $value, $unit) = $arg[2][0];
706
-
707
- $format = $arg[2][1][2][0];
708
-
709
- // When value is 0px, parser automatically remove px (but not %) from it.
710
- if ( 0 == $arg[2][0][1] ) { // @codingStandardsIgnoreLine
711
- $unit = '%';
712
- }
713
-
714
- return sprintf( $format, $value . $unit );
715
- } );
716
-
717
- $parser->registerFunction( 'jupiterx_replace', function( $args ) {
718
- list( $string, $search, $replace ) = $args[2];
719
-
720
- // Arrange if string is from a variable use the true condition. e.g. @{var-name}.
721
- $string = isset( $string[2][1][1] ) ? $string[2][1][1] : $string[2][0];
722
- $search = $search[2][0];
723
- $replace = $replace[2][0];
724
-
725
- return str_replace( $search, $replace, $string );
726
- } );
727
-
728
- return $parser;
729
- }
730
-
731
- /**
732
- * Initialize the configuration.
733
- *
734
- * @since 1.0.0
735
- *
736
- * @param array $config Runtime configuration parameters for the Compiler.
737
- *
738
- * @return array
739
- * @SuppressWarnings(PHPMD.ElseExpression)
740
- */
741
- private function init_config( array $config ) {
742
- // Fix dependencies, if "depedencies" is specified.
743
- if ( isset( $config['depedencies'] ) ) {
744
- $config['dependencies'] = $config['depedencies'];
745
- unset( $config['depedencies'] );
746
- }
747
-
748
- $defaults = [
749
- 'id' => false,
750
- 'type' => false,
751
- 'format' => false,
752
- 'fragments' => [],
753
- 'variables' => [],
754
- 'dependencies' => false,
755
- 'in_footer' => false,
756
- 'minify_js' => true,
757
- 'version' => JUPITERX_VERSION,
758
- 'enqueue' => true,
759
- ];
760
-
761
- if ( is_customize_preview() ) {
762
- $defaults['uniqid'] = uniqid();
763
- } else {
764
- $defaults['theme_mods'] = get_theme_mods();
765
- }
766
-
767
- return array_merge( $defaults, $config );
768
- }
769
-
770
- /**
771
- * Get the fragments' modification times.
772
- *
773
- * @since 1.0.0
774
- *
775
- * @return array
776
- * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
777
- */
778
- private function get_fragments_filemtime() {
779
- $fragments_filemtime = array();
780
-
781
- foreach ( $this->config['fragments'] as $index => $fragment ) {
782
-
783
- // Skip this one if the fragment is a function.
784
- if ( $this->is_function( $fragment ) ) {
785
- if ( ! is_callable( $fragment ) ) {
786
- continue;
787
- }
788
-
789
- $fragments_filemtime[ $index ] = $this->hash( [ call_user_func( $fragment ) ] );
790
-
791
- }
792
-
793
- if ( file_exists( $fragment ) ) {
794
- $fragments_filemtime[ $index ] = @filemtime( $fragment ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Valid use case.
795
- }
796
- }
797
-
798
- return $fragments_filemtime;
799
- }
800
-
801
- /**
802
- * Get the new hash for the given fragments' modification times.
803
- *
804
- * @since 1.0.0
805
- *
806
- * @param string $hash The original hash to modify.
807
- * @param array $fragments_filemtime Array of fragments' modification times.
808
- *
809
- * @return string
810
- * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
811
- */
812
- private function get_new_hash( $hash, array $fragments_filemtime ) {
813
-
814
- if ( empty( $fragments_filemtime ) ) {
815
- return $hash;
816
- }
817
-
818
- // Set filemtime hash.
819
- $_hash = $this->hash( $fragments_filemtime );
820
-
821
- $this->remove_modified_files( $hash, $_hash );
822
-
823
- // Set the new hash which will trigger a new compiling.
824
- return $hash . '-' . $_hash;
825
- }
826
-
827
- /**
828
- * Remove any modified files. A file is considered modified when:
829
- *
830
- * 1. It has both a base hash and filemtime hash, separated by '-'.
831
- * 2. Its base hash matches the given hash.
832
- * 3. Its filemtime hash does not match the given filemtime hash.
833
- *
834
- * @since 1.0.0
835
- *
836
- * @param string $hash Base hash.
837
- * @param string $filemtime_hash The filemtime hash (from hashing the fragments).
838
- *
839
- * @return void
840
- */
841
- private function remove_modified_files( $hash, $filemtime_hash ) {
842
-
843
- if ( ! is_dir( $this->dir ) ) {
844
- return;
845
- }
846
-
847
- $items = @scandir( $this->dir ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Valid use case.
848
- unset( $items[0], $items[1] );
849
-
850
- if ( empty( $items ) ) {
851
- return;
852
- }
853
-
854
- foreach ( $items as $item ) {
855
-
856
- // Skip this one if it's a directory.
857
- if ( @is_dir( $item ) ) { // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Valid use case.
858
- continue;
859
- }
860
-
861
- // Skip this one if it's not the same type.
862
- if ( pathinfo( $item, PATHINFO_EXTENSION ) !== $this->get_extension() ) {
863
- continue;
864
- }
865
-
866
- // Skip this one if it does not have a '-' in the filename.
867
- if ( strpos( $item, '-' ) === false ) {
868
- continue;
869
- }
870
-
871
- $hash_parts = explode( '-', pathinfo( $item, PATHINFO_FILENAME ) );
872
-
873
- // Skip this one if it does not match the given base hash.
874
- if ( $hash_parts[0] !== $hash ) {
875
- continue;
876
- }
877
-
878
- // Skip this one if it does match the given filemtime's hash.
879
- if ( $hash_parts[1] === $filemtime_hash ) {
880
- continue;
881
- }
882
-
883
- // Clean up other modified files.
884
- @unlink( $this->dir . '/' . $item ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Valid use case.
885
- }
886
- }
887
-
888
- /**
889
- * Clean the CSS.
890
- *
891
- * @since 1.15.0
892
- *
893
- * @param string $content Given content to process.
894
- *
895
- * @return string
896
- */
897
- private function clean_style( $content ) {
898
- $content = preg_replace( '/\n.+: ;/', '', $content ); // Remove properties without value. (e.g. font-size: ;).
899
-
900
- return $content;
901
- }
902
-
903
- /**
904
- * Minify the CSS.
905
- *
906
- * @since 1.15.0
907
- *
908
- * @param string $content Given content to process.
909
- *
910
- * @return string
911
- */
912
- private function minify_style_2( $content ) {
913
- $replace = [
914
- '/[^{}\r\n]+(?:\r?\n[^{}\r\n]+)*{\s*}/' => '', // Strip empty selectors.
915
- '/\s*@media.*(\n|\s.)*\n.*}/' => '', // Strip empty @media.
916
- '/\n/' => '', // Strip line breaks.
917
- ];
918
-
919
- $search = array_keys( $replace );
920
- $content = preg_replace( $search, $replace, $content );
921
-
922
- return $content;
923
- }
924
-
925
- /**
926
- * Minify the CSS.
927
- *
928
- * @since 1.0.0
929
- *
930
- * @param string $content Given content to process.
931
- *
932
- * @return string
933
- * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
934
- */
935
- private function minify_style( $content ) {
936
- $replace = array(
937
- '/([^\r\n{}]+)(,(?=[^}]*{)|\s*{)}/' => '', // Strip empty selectors.
938
- '/@media\s\(.*\).*{}/' => '', // Strip empty @media.
939
- '#/\*.*?\*/#s' => '', // Strip comments.
940
- '#\s\s+#' => ' ', // Strip excess whitespace.
941
- );
942
-
943
- $search = array_keys( $replace );
944
- $content = preg_replace( $search, $replace, $content );
945
-
946
- $replace = array(
947
- ': ' => ':',
948
- '; ' => ';',
949
- ' {' => '{',
950
- ' }' => '}',
951
- ', ' => ',',
952
- '{ ' => '{',
953
- ',\n' => ',', // Don't wrap multiple selectors.
954
- '\n}' => '}', // Don't wrap closing braces.
955
- '} ' => "}\n", // Put each rule on it's own line.
956
- '\n' => '', // Remove all line breaks.
957
- );
958
-
959
- $search = array_keys( $replace );
960
-
961
- return trim( str_replace( $search, $replace, $content ) );
962
- }
963
-
964
- /**
965
- * Check if the given fragment is a callable.
966
- *
967
- * @since 1.0.0
968
- *
969
- * @param mixed $fragment Given fragment to check.
970
- *
971
- * @return bool
972
- */
973
- private function is_function( $fragment ) {
974
- return ( is_array( $fragment ) || is_callable( $fragment ) );
975
- }
976
-
977
- /**
978
- * Kill it :(
979
- *
980
- * @since 1.0.0
981
- *
982
- * @return void
983
- */
984
- private function kill() {
985
-
986
- // Send report if set.
987
- if ( jupiterx_get( 'jupiterx_send_compiler_report' ) ) { // @codingStandardsIgnoreLine
988
- // $this->report(); // @codingStandardsIgnoreLine
989
- }
990
-
991
- $html = jupiterx_output( 'jupiterx_compiler_error_title_text', sprintf(
992
- '<h2>%s</h2>',
993
- __( 'Not cool, Jupiter cannot work its magic :(', 'jupiterx-core' )
994
- ) );
995
-
996
- $html .= jupiterx_output( 'jupiterx_compiler_error_message_text', sprintf(
997
- '<p>%s</p>',
998
- __( 'Your current install or file permission prevents Jupiter from working its magic. Please get in touch with Jupiter support. We will gladly get you started within 24 - 48 hours (working days).', 'jupiterx-core' )
999
- ) );
1000
-
1001
- $html .= jupiterx_output( 'jupiterx_compiler_error_contact_text', sprintf(
1002
- '<a class="button" href="https://themes.artbees.net/support/" target="_blank">%s</a>',
1003
- __( 'Contact Jupiter Support', 'jupiterx-core' )
1004
- ) );
1005
-
1006
- $html .= jupiterx_output( 'jupiterx_compiler_error_report_text', sprintf(
1007
- '<p style="margin-top: 12px; font-size: 12px;"><a href="' . add_query_arg( 'jupiterx_send_compiler_report', true ) . '">%1$s</a>. %2$s</p>',
1008
- __( 'Send us an automatic report', 'jupiterx-core' ),
1009
- __( 'We respect your time and understand you might not be able to contact us.', 'jupiterx-core' )
1010
- ) );
1011
-
1012
- wp_die( wp_kses_post( $html ) );
1013
- }
1014
-
1015
- /**
1016
- * Send report.
1017
- *
1018
- * @since 1.0.0
1019
- *
1020
- * @todo Decide if we want to use and change the report recipient.
1021
- *
1022
- * @return void
1023
- * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
1024
- */
1025
- private function report() {
1026
- // Send report.
1027
- wp_mail(
1028
- 'hello@getjupiter.io',
1029
- 'Compiler error',
1030
- 'Compiler error reported by ' . home_url(),
1031
- array(
1032
- 'MIME-Version: 1.0' . "\r\n",
1033
- 'Content-type: text/html; charset=utf-8' . "\r\n",
1034
- "X-Mailer: PHP \r\n",
1035
- 'From: ' . wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) . ' < ' . get_option( 'admin_email' ) . '>' . "\r\n",
1036
- 'Reply-To: ' . get_option( 'admin_email' ) . "\r\n",
1037
- )
1038
- );
1039
-
1040
- // Die and display message.
1041
- $message = jupiterx_output(
1042
- 'jupiterx_compiler_report_error_text',
1043
- sprintf(
1044
- '<p>%s<p>',
1045
- __( 'Thanks for your contribution by reporting this issue. We hope to hear from you again.', 'jupiterx-core' )
1046
- )
1047
- );
1048
-
1049
- wp_die( wp_kses_post( $message ) );
1050
- }
1051
-
1052
- /**
1053
- * Get the property's value.
1054
- *
1055
- * @since 1.0.0
1056
- *
1057
- * @param string $property Name of the property to get.
1058
- *
1059
- * @return mixed
1060
- */
1061
- public function __get( $property ) {
1062
-
1063
- if ( property_exists( $this, $property ) ) {
1064
- return $this->{$property};
1065
- }
1066
- }
1067
- }
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This class compiles and minifies CSS, LESS and JS.
4
+ *
5
+ * @package JupiterX\Framework\API\Compiler
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ /**
11
+ * Compiles and minifies CSS, LESS and JS.
12
+ *
13
+ * @since 1.0.0
14
+ * @ignore
15
+ * @access private
16
+ *
17
+ * @package JupiterX\Framework\API\Compiler
18
+ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
19
+ * @SuppressWarnings(PHPMD.ExcessiveClassLength)
20
+ */
21
+ final class _JupiterX_Compiler {
22
+
23
+ /**
24
+ * Compiler's runtime configuration parameters.
25
+ *
26
+ * @var array
27
+ */
28
+ private $config;
29
+
30
+ /**
31
+ * Cache dir.
32
+ *
33
+ * @var string
34
+ */
35
+ private $dir;
36
+
37
+ /**
38
+ * Cache url.
39
+ *
40
+ * @var string
41
+ */
42
+ private $url;
43
+
44
+ /**
45
+ * The fragment currently being processed.
46
+ *
47
+ * @var string
48
+ */
49
+ private $current_fragment;
50
+
51
+ /**
52
+ * The compiled content.
53
+ *
54
+ * @var string
55
+ */
56
+ private $compiled_content;
57
+
58
+ /**
59
+ * Compiled content's filename.
60
+ *
61
+ * @var string
62
+ */
63
+ private $filename;
64
+
65
+ /**
66
+ * Create a new Compiler.
67
+ *
68
+ * @since 1.0.0
69
+ *
70
+ * @param array $config Runtime configuration parameters for the Compiler.
71
+ */
72
+ public function __construct( array $config ) {
73
+ $this->config = $this->init_config( $config );
74
+ $this->dir = jupiterx_get_compiler_dir( is_admin() ) . $this->config['id'];
75
+ $this->url = jupiterx_get_compiler_url( is_admin() ) . $this->config['id'];
76
+ }
77
+
78
+ /**
79
+ * Run the compiler.
80
+ *
81
+ * @since 1.0.0
82
+ *
83
+ * @return void
84
+ */
85
+ public function run_compiler() {
86
+ // Modify the WP Filesystem method.
87
+ add_filter( 'filesystem_method', array( $this, 'modify_filesystem_method' ) );
88
+
89
+ $this->set_fragments();
90
+ $this->set_filename();
91
+
92
+ if ( ! $this->cache_file_exist() ) {
93
+ $this->filesystem();
94
+ $this->maybe_make_dir();
95
+ $this->combine_fragments();
96
+ $this->cache_file();
97
+ }
98
+
99
+ if ( $this->config['enqueue'] ) {
100
+ $this->enqueue_file();
101
+ }
102
+
103
+ // Keep it safe and reset the WP Filesystem method.
104
+ remove_filter( 'filesystem_method', array( $this, 'modify_filesystem_method' ) );
105
+ }
106
+
107
+ /**
108
+ * Callback to set the WP Filesystem method.
109
+ *
110
+ * @since 1.0.0
111
+ *
112
+ * @return string
113
+ */
114
+ public function modify_filesystem_method() {
115
+ return 'direct';
116
+ }
117
+
118
+ /**
119
+ * Initialise the WP Filesystem.
120
+ *
121
+ * @since 1.0.0
122
+ *
123
+ * @return bool|void
124
+ */
125
+ public function filesystem() {
126
+
127
+ // If the WP_Filesystem is not already loaded, load it.
128
+ if ( ! function_exists( 'WP_Filesystem' ) ) {
129
+ require_once ABSPATH . '/wp-admin/includes/file.php';
130
+ }
131
+
132
+ // If the WP_Filesystem is not initialized or is not set to WP_Filesystem_Direct, then initialize it.
133
+ if ( $this->is_wp_filesystem_direct() ) {
134
+ return true;
135
+ }
136
+
137
+ // Initialize the filesystem.
138
+ $response = WP_Filesystem();
139
+
140
+ // If the filesystem did not initialize, then generate a report and exit.
141
+ if ( true !== $response || ! $this->is_wp_filesystem_direct() ) {
142
+ return $this->kill();
143
+ }
144
+
145
+ return true;
146
+ }
147
+
148
+ /**
149
+ * Check if the filesystem is set to "direct".
150
+ *
151
+ * @since 1.0.0
152
+ *
153
+ * @return bool
154
+ */
155
+ private function is_wp_filesystem_direct() {
156
+ return isset( $GLOBALS['wp_filesystem'] ) && is_a( $GLOBALS['wp_filesystem'], 'WP_Filesystem_Direct' );
157
+ }
158
+
159
+ /**
160
+ * Make directory.
161
+ *
162
+ * @since 1.0.0
163
+ *
164
+ * @return bool
165
+ */
166
+ private function maybe_make_dir() {
167
+
168
+ if ( ! @is_dir( $this->dir ) ) { // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- This is a valid use case.
169
+ wp_mkdir_p( $this->dir );
170
+ }
171
+
172
+ return is_writable( $this->dir );
173
+ }
174
+
175
+ /**
176
+ * Set class fragments.
177
+ *
178
+ * @since 1.0.0
179
+ *
180
+ * @return void
181
+ */
182
+ public function set_fragments() {
183
+ global $_jupiterx_compiler_added_fragments;
184
+
185
+ $added_fragments = jupiterx_get( $this->config['id'], $_jupiterx_compiler_added_fragments[ $this->config['format'] ] );
186
+
187
+ if ( $added_fragments ) {
188
+ $this->config['fragments'] = array_merge( $this->config['fragments'], $added_fragments );
189
+ }
190
+
191
+ /**
192
+ * Filter the compiler fragment files.
193
+ *
194
+ * The dynamic portion of the hook name, $this->config['id'], refers to the compiler id used as a reference.
195
+ *
196
+ * @since 1.0.0
197
+ *
198
+ * @param array $fragments An array of fragment files.
199
+ */
200
+ $this->config['fragments'] = apply_filters( 'jupiterx_compiler_fragments_' . $this->config['id'], $this->config['fragments'] );
201
+ }
202
+
203
+ /**
204
+ * Set the filename for the compiled asset.
205
+ *
206
+ * @since 1.0.0
207
+ *
208
+ * @return void
209
+ */
210
+ public function set_filename() {
211
+ $hash = $this->hash( $this->config );
212
+
213
+ if ( empty( _jupiterx_get_cache_busting() ) ) {
214
+ $this->config['version'] = $hash;
215
+
216
+ $hash = 'style';
217
+
218
+ if ( 'script' === $this->config['type'] ) {
219
+ $hash = 'script';
220
+ }
221
+ }
222
+
223
+ $this->filename = $hash . '.' . $this->get_extension();
224
+ }
225
+
226
+ /**
227
+ * Hash the given array.
228
+ *
229
+ * @since 1.0.0
230
+ *
231
+ * @param array $given_array Given array to be hashed.
232
+ *
233
+ * @return string
234
+ */
235
+ public function hash( array $given_array ) {
236
+ return substr( md5( @serialize( $given_array ) ), 0, 7 ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged, WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize -- Valid use case.
237
+ }
238
+
239
+ /**
240
+ * Checks if the file exists on the filesystem, meaning it's been cached.
241
+ *
242
+ * @since 1.0.0
243
+ *
244
+ * @return bool
245
+ */
246
+ public function cache_file_exist() {
247
+ $filename = $this->get_filename();
248
+
249
+ if ( _jupiterx_is_compiler_dev_mode() || is_customize_preview() ) {
250
+ return false;
251
+ }
252
+
253
+ if ( empty( $filename ) ) {
254
+ return false;
255
+ }
256
+
257
+ return file_exists( $filename );
258
+ }
259
+
260
+ /**
261
+ * Get the absolute path of the cached and compiled file.
262
+ *
263
+ * @since 1.0.0
264
+ *
265
+ * @return string
266
+ */
267
+ public function get_filename() {
268
+ if ( isset( $this->filename ) ) {
269
+ return $this->dir . '/' . $this->filename;
270
+ }
271
+
272
+ return '';
273
+ }
274
+
275
+ /**
276
+ * Create cached file.
277
+ *
278
+ * @since 1.0.0
279
+ *
280
+ * @return bool
281
+ */
282
+ public function cache_file() {
283
+ $filename = $this->get_filename();
284
+
285
+ if ( empty( $filename ) ) {
286
+ return false;
287
+ }
288
+
289
+ // It is safe to access the filesystem because we made sure it was set.
290
+ return $GLOBALS['wp_filesystem']->put_contents( $filename, $this->compiled_content, FS_CHMOD_FILE );
291
+ }
292
+
293
+ /**
294
+ * Enqueue cached file.
295
+ *
296
+ * @since 1.0.0
297
+ *
298
+ * @return void|bool
299
+ */
300
+ private function enqueue_file() {
301
+
302
+ // Enqueue CSS file.
303
+ if ( 'style' === $this->config['type'] ) {
304
+ return wp_enqueue_style(
305
+ $this->config['id'],
306
+ $this->get_url(),
307
+ $this->config['dependencies'],
308
+ $this->config['version']
309
+ );
310
+ }
311
+
312
+ // Enqueue JS file.
313
+ if ( 'script' === $this->config['type'] ) {
314
+ return wp_enqueue_script(
315
+ $this->config['id'],
316
+ $this->get_url(),
317
+ $this->config['dependencies'],
318
+ $this->config['version'],
319
+ $this->config['in_footer']
320
+ );
321
+ }
322
+
323
+ return false;
324
+ }
325
+
326
+ /**
327
+ * Get cached file url.
328
+ *
329
+ * @since 1.0.0
330
+ *
331
+ * @return string
332
+ */
333
+ public function get_url() {
334
+ $url = trailingslashit( $this->url ) . $this->filename;
335
+
336
+ if ( is_ssl() ) {
337
+ $url = str_replace( 'http://', 'https://', $url );
338
+ }
339
+
340
+ return $url;
341
+ }
342
+
343
+ /**
344
+ * Get the file extension from the configured "type".
345
+ *
346
+ * @since 1.0.0
347
+ *
348
+ * @return string|null
349
+ */
350
+ public function get_extension() {
351
+
352
+ if ( 'style' === $this->config['type'] ) {
353
+ return 'css';
354
+ }
355
+
356
+ if ( 'script' === $this->config['type'] ) {
357
+ return 'js';
358
+ }
359
+ }
360
+
361
+ /**
362
+ * Combine content of the fragments.
363
+ *
364
+ * @since 1.0.0
365
+ *
366
+ * @return void
367
+ */
368
+ public function combine_fragments() {
369
+ $content = '';
370
+
371
+ // Loop through fragments.
372
+ foreach ( $this->config['fragments'] as $fragment ) {
373
+
374
+ // Stop here if the fragment is empty.
375
+ if ( empty( $fragment ) ) {
376
+ continue;
377
+ }
378
+
379
+ $fragment_content = $this->get_content( $fragment );
380
+
381
+ // Stop here if no content or content is an html page.
382
+ if ( ! $fragment_content || preg_match( '#^\s*\<#', $fragment_content ) ) {
383
+ continue;
384
+ }
385
+
386
+ // Continue processing style.
387
+ if ( 'style' === $this->config['type'] ) {
388
+ $fragment_content = $this->replace_css_url( $fragment_content );
389
+ $fragment_content = $this->add_content_media_query( $fragment_content );
390
+ }
391
+
392
+ // If there's content, start a new line.
393
+ if ( $content ) {
394
+ $content .= "\n\n";
395
+ }
396
+
397
+ $content .= $fragment_content;
398
+ }
399
+
400
+ $this->compiled_content = ! empty( $content ) ? $this->format_content( $content ) : '';
401
+ }
402
+
403
+ /**
404
+ * Get the fragment's content.
405
+ *
406
+ * @since 1.0.0
407
+ *
408
+ * @param string|callable $fragment The given fragment from which to get the content.
409
+ *
410
+ * @return bool|string
411
+ */
412
+ private function get_content( $fragment ) {
413
+ // Set the current fragment used by other functions.
414
+ $this->current_fragment = $fragment;
415
+
416
+ // If the fragment is callable, call it to get the content.
417
+ if ( $this->is_function( $fragment ) ) {
418
+ return $this->get_function_content();
419
+ }
420
+
421
+ $content = $this->get_internal_content();
422
+
423
+ // Try remote content if the internal content returned false.
424
+ if ( empty( $content ) ) {
425
+ $content = $this->get_remote_content();
426
+ }
427
+
428
+ // If the fragment is string.
429
+ if ( empty( $content ) && is_string( $fragment ) ) {
430
+ return $fragment;
431
+ }
432
+
433
+ return $content;
434
+ }
435
+
436
+ /**
437
+ * Get internal file content.
438
+ *
439
+ * @since 1.0.0
440
+ *
441
+ * @return string|bool
442
+ */
443
+ public function get_internal_content() {
444
+ $fragment = $this->current_fragment;
445
+
446
+ if ( 'string' === $this->config['fragments_type'] ) {
447
+ return $fragment;
448
+ }
449
+
450
+ if ( ! file_exists( $fragment ) ) {
451
+
452
+ // Replace URL with path.
453
+ $fragment = jupiterx_url_to_path( $fragment );
454
+
455
+ // Stop here if it isn't a valid file.
456
+ if ( ! file_exists( $fragment ) || 0 === @filesize( $fragment ) ) { // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Valid use case.
457
+ return false;
458
+ }
459
+ }
460
+
461
+ // It is safe to access the filesystem because we made sure it was set.
462
+ return $GLOBALS['wp_filesystem']->get_contents( $fragment );
463
+ }
464
+
465
+ /**
466
+ * Get external file content.
467
+ *
468
+ * @since 1.0.0
469
+ *
470
+ * @return string|bool
471
+ */
472
+ public function get_remote_content() {
473
+ $fragment = $this->current_fragment;
474
+
475
+ if ( empty( $fragment ) ) {
476
+ return false;
477
+ }
478
+
479
+ // For a relative URL, add http: to it.
480
+ if ( substr( $fragment, 0, 2 ) === '//' ) {
481
+ $fragment = 'http:' . $fragment;
482
+ } elseif ( substr( $fragment, 0, 1 ) === '/' ) { // Add domain if it is local but could not be fetched as a file.
483
+ $fragment = site_url( $fragment );
484
+ }
485
+
486
+ $request = wp_remote_get( $fragment );
487
+
488
+ if ( is_wp_error( $request ) ) {
489
+ return '';
490
+ }
491
+
492
+ // If no content was received and the URL is not https, then convert the URL to SSL and retry.
493
+ if (
494
+ ( ! isset( $request['body'] ) || 200 !== $request['response']['code'] ) &&
495
+ ( substr( $fragment, 0, 8 ) !== 'https://' )
496
+ ) {
497
+ $fragment = str_replace( 'http://', 'https://', $fragment );
498
+ $request = wp_remote_get( $fragment );
499
+
500
+ if ( is_wp_error( $request ) ) {
501
+ return '';
502
+ }
503
+ }
504
+
505
+ if ( ( ! isset( $request['body'] ) || 200 !== $request['response']['code'] ) ) {
506
+ return false;
507
+ }
508
+
509
+ return wp_remote_retrieve_body( $request );
510
+ }
511
+
512
+ /**
513
+ * Get function content.
514
+ *
515
+ * @since 1.0.0
516
+ *
517
+ * @return string|bool
518
+ */
519
+ public function get_function_content() {
520
+
521
+ if ( ! is_callable( $this->current_fragment ) ) {
522
+ return false;
523
+ }
524
+
525
+ return call_user_func( $this->current_fragment );
526
+ }
527
+
528
+ /**
529
+ * Wrap content in query.
530
+ *
531
+ * @since 1.0.0
532
+ *
533
+ * @param string $content Given content to process.
534
+ *
535
+ * @return string
536
+ */
537
+ public function add_content_media_query( $content ) {
538
+
539
+ // Ignore if the fragment is a function.
540
+ if ( $this->is_function( $this->current_fragment ) ) {
541
+ return $content;
542
+ }
543
+
544
+ $query = wp_parse_url( $this->current_fragment, PHP_URL_QUERY );
545
+
546
+ // Bail out if there are no query args or no media query.
547
+ if ( empty( $query ) || false === stripos( $query, 'jupiterx_compiler_media_query' ) ) {
548
+ return $content;
549
+ }
550
+
551
+ // Wrap the content in the query.
552
+ return sprintf(
553
+ "@media %s {\n%s\n}\n",
554
+ jupiterx_get( 'jupiterx_compiler_media_query', wp_parse_args( $query ) ),
555
+ $content
556
+ );
557
+ }
558
+
559
+ /**
560
+ * Format CSS, LESS and JS content.
561
+ *
562
+ * @since 1.0.0
563
+ *
564
+ * @param string $content Given content to process.
565
+ *
566
+ * @return string
567
+ */
568
+ public function format_content( $content ) {
569
+
570
+ if ( 'style' === $this->config['type'] ) {
571
+
572
+ if ( 'less' === $this->config['format'] ) {
573
+
574
+ if ( ! class_exists( 'JupiterX_Lessc' ) ) {
575
+ jupiterx_core()->load_files( [ 'compiler/vendors/lessc' ] );
576
+ }
577
+
578
+ $parser = new JupiterX_Lessc();
579
+
580
+ $parser = $this->register_less_functions( $parser );
581
+
582
+ $parser->setVariables( apply_filters( 'jupiterx_compiler_less_variables', $this->config['variables'] ) );
583
+
584
+ $content = $parser->compile( $content );
585
+
586
+ $content = $this->clean_style( $content );
587
+ }
588
+
589
+ if ( is_rtl() ) {
590
+ if ( ! class_exists( 'CSSJanus' ) ) {
591
+ jupiterx_core()->load_files( [ 'compiler/vendors/CSSJanus' ] );
592
+ }
593
+
594
+ $content = CSSJanus::transform( $content );
595
+ }
596
+
597
+ if ( ! _jupiterx_is_compiler_dev_mode() ) {
598
+ $content = $this->minify_style_2( $content );
599
+ }
600
+
601
+ return $content;
602
+ }
603
+
604
+ if ( 'script' === $this->config['type'] && ! _jupiterx_is_compiler_dev_mode() && $this->config['minify_js'] ) {
605
+
606
+ if ( ! class_exists( 'JSMin' ) ) {
607
+ jupiterx_core()->load_files( [ 'compiler/vendors/js-minifier' ] );
608
+ }
609
+
610
+ $js_min = new JSMin( $content );
611
+ return $js_min->min();
612
+ }
613
+
614
+ return $content;
615
+ }
616
+
617
+ /**
618
+ * Replace CSS URL shortcuts with a valid URL.
619
+ *
620
+ * @since 1.0.0
621
+ *
622
+ * @param string $content Given content to process.
623
+ *
624
+ * @return string
625
+ */
626
+ public function replace_css_url( $content ) {
627
+ return preg_replace_callback(
628
+ '#url\s*\(\s*[\'"]*?([^\'"\)]+)[\'"]*\s*\)#i',
629
+ array( $this, 'replace_css_url_callback' ),
630
+ $content
631
+ );
632
+ }
633
+
634
+ /**
635
+ * Convert any CSS URL relative paths to absolute URLs.
636
+ *
637
+ * @since 1.0.0
638
+ *
639
+ * @param array $matches Matches to process, where 0 is the CSS' URL() and 1 is the URI.
640
+ *
641
+ * @return string
642
+ */
643
+ public function replace_css_url_callback( $matches ) {
644
+
645
+ // If the URI is absolute, bail out and return the CSS.
646
+ if ( _jupiterx_is_uri( $matches[1] ) ) {
647
+ return $matches[0];
648
+ }
649
+
650
+ $base = $this->current_fragment;
651
+
652
+ // Separate the placeholders and path.
653
+ $paths = explode( '../', $matches[1] );
654
+
655
+ /**
656
+ * Walk backwards through each of the the fragment's directories, one-by-one. The `foreach` loop
657
+ * provides us with a performant way to walk the fragment back to its base path based upon the
658
+ * number of placeholders.
659
+ */
660
+ foreach ( $paths as $path ) {
661
+ $base = dirname( $base );
662
+ }
663
+
664
+ // Make sure it is a valid base.
665
+ if ( '.' === $base ) {
666
+ $base = '';
667
+ }
668
+
669
+ // Rebuild the URL and make sure it is valid using the jupiterx_path_to_url function.
670
+ $url = jupiterx_path_to_url( trailingslashit( $base ) . ltrim( end( $paths ), '/\\' ) );
671
+
672
+ // Return the rebuilt path converted to an URL.
673
+ return 'url("' . $url . '")';
674
+ }
675
+
676
+ /**
677
+ * Register LESS_PHP functions.
678
+ *
679
+ * @since 1.0.0
680
+ *
681
+ * @param object $parser The LESS parser.
682
+ *
683
+ * @todo Refactoring is required.
684
+ *
685
+ * @return object
686
+ */
687
+ private function register_less_functions( $parser ) {
688
+ $parser->registerFunction( 'jupiterx_value', function( $arg ) {
689
+ $output = '';
690
+
691
+ if ( isset( $arg[2][1][2][0] ) ) {
692
+ $output = $arg[2][1][2][0]; // Default.
693
+ }
694
+
695
+ if ( ! empty( $arg[2][0][2][1][1] ) ) {
696
+ return $arg[2][0][2][1][1]; // E.g. ~"@{@{var}-width}".
697
+ }
698
+
699
+ if ( ! empty( $arg[2][0][1] ) ) {
700
+ $value = $arg[2][0][1]; // E.g. @text-size.
701
+ $unit = empty( $arg[2][0][2] ) ? '' : $arg[2][0][2]; // E.g. @text-size unit.
702
+
703
+ return $value . $unit;
704
+ }
705
+
706
+ return $output;
707
+ } );
708
+
709
+ $parser->registerFunction( 'jupiterx_value_pattern', function( $arg ) {
710
+ if ( 0 === strlen( $arg[2][0][1] ) ) {
711
+ return '';
712
+ }
713
+
714
+ list($type, $value, $unit) = $arg[2][0];
715
+
716
+ $format = $arg[2][1][2][0];
717
+
718
+ // When value is 0px, parser automatically remove px (but not %) from it.
719
+ if ( 0 == $arg[2][0][1] ) { // @codingStandardsIgnoreLine
720
+ $unit = '%';
721
+ }
722
+
723
+ return sprintf( $format, $value . $unit );
724
+ } );
725
+
726
+ $parser->registerFunction( 'jupiterx_replace', function( $args ) {
727
+ list( $string, $search, $replace ) = $args[2];
728
+
729
+ // Arrange if string is from a variable use the true condition. e.g. @{var-name}.
730
+ $string = isset( $string[2][1][1] ) ? $string[2][1][1] : $string[2][0];
731
+ $search = $search[2][0];
732
+ $replace = $replace[2][0];
733
+
734
+ return str_replace( $search, $replace, $string );
735
+ } );
736
+
737
+ return $parser;
738
+ }
739
+
740
+ /**
741
+ * Initialize the configuration.
742
+ *
743
+ * @since 1.0.0
744
+ *
745
+ * @param array $config Runtime configuration parameters for the Compiler.
746
+ *
747
+ * @return array
748
+ * @SuppressWarnings(PHPMD.ElseExpression)
749
+ */
750
+ private function init_config( array $config ) {
751
+ // Fix dependencies, if "depedencies" is specified.
752
+ if ( isset( $config['depedencies'] ) ) {
753
+ $config['dependencies'] = $config['depedencies'];
754
+ unset( $config['depedencies'] );
755
+ }
756
+
757
+ $defaults = [
758
+ 'id' => false,
759
+ 'type' => false,
760
+ 'format' => false,
761
+ 'fragments' => [],
762
+ 'fragments_type' => 'path', // url, path, string.
763
+ 'variables' => [],
764
+ 'dependencies' => false,
765
+ 'in_footer' => false,
766
+ 'minify_js' => true,
767
+ 'version' => JUPITERX_VERSION,
768
+ 'enqueue' => true,
769
+ ];
770
+
771
+ if ( is_customize_preview() ) {
772
+ $defaults['uniqid'] = uniqid();
773
+ } else {
774
+ $defaults['theme_mods'] = get_theme_mods();
775
+ }
776
+
777
+ return array_merge( $defaults, $config );
778
+ }
779
+
780
+ /**
781
+ * Get the fragments' modification times.
782
+ *
783
+ * @since 1.0.0
784
+ *
785
+ * @return array
786
+ * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
787
+ */
788
+ private function get_fragments_filemtime() {
789
+ $fragments_filemtime = array();
790
+
791
+ foreach ( $this->config['fragments'] as $index => $fragment ) {
792
+
793
+ // Skip this one if the fragment is a function.
794
+ if ( $this->is_function( $fragment ) ) {
795
+ if ( ! is_callable( $fragment ) ) {
796
+ continue;
797
+ }
798
+
799
+ $fragments_filemtime[ $index ] = $this->hash( [ call_user_func( $fragment ) ] );
800
+
801
+ }
802
+
803
+ if ( file_exists( $fragment ) ) {
804
+ $fragments_filemtime[ $index ] = @filemtime( $fragment ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Valid use case.
805
+ }
806
+ }
807
+
808
+ return $fragments_filemtime;
809
+ }
810
+
811
+ /**
812
+ * Get the new hash for the given fragments' modification times.
813
+ *
814
+ * @since 1.0.0
815
+ *
816
+ * @param string $hash The original hash to modify.
817
+ * @param array $fragments_filemtime Array of fragments' modification times.
818
+ *
819
+ * @return string
820
+ * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
821
+ */
822
+ private function get_new_hash( $hash, array $fragments_filemtime ) {
823
+
824
+ if ( empty( $fragments_filemtime ) ) {
825
+ return $hash;
826
+ }
827
+
828
+ // Set filemtime hash.
829
+ $_hash = $this->hash( $fragments_filemtime );
830
+
831
+ $this->remove_modified_files( $hash, $_hash );
832
+
833
+ // Set the new hash which will trigger a new compiling.
834
+ return $hash . '-' . $_hash;
835
+ }
836
+
837
+ /**
838
+ * Remove any modified files. A file is considered modified when:
839
+ *
840
+ * 1. It has both a base hash and filemtime hash, separated by '-'.
841
+ * 2. Its base hash matches the given hash.
842
+ * 3. Its filemtime hash does not match the given filemtime hash.
843
+ *
844
+ * @since 1.0.0
845
+ *
846
+ * @param string $hash Base hash.
847
+ * @param string $filemtime_hash The filemtime hash (from hashing the fragments).
848
+ *
849
+ * @return void
850
+ */
851
+ private function remove_modified_files( $hash, $filemtime_hash ) {
852
+
853
+ if ( ! is_dir( $this->dir ) ) {
854
+ return;
855
+ }
856
+
857
+ $items = @scandir( $this->dir ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Valid use case.
858
+ unset( $items[0], $items[1] );
859
+
860
+ if ( empty( $items ) ) {
861
+ return;
862
+ }
863
+
864
+ foreach ( $items as $item ) {
865
+
866
+ // Skip this one if it's a directory.
867
+ if ( @is_dir( $item ) ) { // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Valid use case.
868
+ continue;
869
+ }
870
+
871
+ // Skip this one if it's not the same type.
872
+ if ( pathinfo( $item, PATHINFO_EXTENSION ) !== $this->get_extension() ) {
873
+ continue;
874
+ }
875
+
876
+ // Skip this one if it does not have a '-' in the filename.
877
+ if ( strpos( $item, '-' ) === false ) {
878
+ continue;
879
+ }
880
+
881
+ $hash_parts = explode( '-', pathinfo( $item, PATHINFO_FILENAME ) );
882
+
883
+ // Skip this one if it does not match the given base hash.
884
+ if ( $hash_parts[0] !== $hash ) {
885
+ continue;
886
+ }
887
+
888
+ // Skip this one if it does match the given filemtime's hash.
889
+ if ( $hash_parts[1] === $filemtime_hash ) {
890
+ continue;
891
+ }
892
+
893
+ // Clean up other modified files.
894
+ @unlink( $this->dir . '/' . $item ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Valid use case.
895
+ }
896
+ }
897
+
898
+ /**
899
+ * Clean the CSS.
900
+ *
901
+ * @since 1.15.0
902
+ *
903
+ * @param string $content Given content to process.
904
+ *
905
+ * @return string
906
+ */
907
+ private function clean_style( $content ) {
908
+ $content = preg_replace( '/\n.+: ;/', '', $content ); // Remove properties without value. (e.g. font-size: ;).
909
+
910
+ return $content;
911
+ }
912
+
913
+ /**
914
+ * Minify the CSS.
915
+ *
916
+ * @since 1.15.0
917
+ *
918
+ * @param string $content Given content to process.
919
+ *
920
+ * @return string
921
+ */
922
+ private function minify_style_2( $content ) {
923
+ $replace = [
924
+ '/[^{}\r\n]+(?:\r?\n[^{}\r\n]+)*{\s*}/' => '', // Strip empty selectors.
925
+ '/\s*@media.*(\n|\s.)*\n.*}/' => '', // Strip empty @media.
926
+ '/\n/' => '', // Strip line breaks.
927
+ ];
928
+
929
+ $search = array_keys( $replace );
930
+ $content = preg_replace( $search, $replace, $content );
931
+
932
+ return $content;
933
+ }
934
+
935
+ /**
936
+ * Minify the CSS.
937
+ *
938
+ * @since 1.0.0
939
+ *
940
+ * @param string $content Given content to process.
941
+ *
942
+ * @return string
943
+ * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
944
+ */
945
+ private function minify_style( $content ) {
946
+ $replace = array(
947
+ '/([^\r\n{}]+)(,(?=[^}]*{)|\s*{)}/' => '', // Strip empty selectors.
948
+ '/@media\s\(.*\).*{}/' => '', // Strip empty @media.
949
+ '#/\*.*?\*/#s' => '', // Strip comments.
950
+ '#\s\s+#' => ' ', // Strip excess whitespace.
951
+ );
952
+
953
+ $search = array_keys( $replace );
954
+ $content = preg_replace( $search, $replace, $content );
955
+
956
+ $replace = array(
957
+ ': ' => ':',
958
+ '; ' => ';',
959
+ ' {' => '{',
960
+ ' }' => '}',
961
+ ', ' => ',',
962
+ '{ ' => '{',
963
+ ',\n' => ',', // Don't wrap multiple selectors.
964
+ '\n}' => '}', // Don't wrap closing braces.
965
+ '} ' => "}\n", // Put each rule on it's own line.
966
+ '\n' => '', // Remove all line breaks.
967
+ );
968
+
969
+ $search = array_keys( $replace );
970
+
971
+ return trim( str_replace( $search, $replace, $content ) );
972
+ }
973
+
974
+ /**
975
+ * Check if the given fragment is a callable.
976
+ *
977
+ * @since 1.0.0
978
+ *
979
+ * @param mixed $fragment Given fragment to check.
980
+ *
981
+ * @return bool
982
+ */
983
+ private function is_function( $fragment ) {
984
+ return ( is_array( $fragment ) || is_callable( $fragment ) );
985
+ }
986
+
987
+ /**
988
+ * Kill it :(
989
+ *
990
+ * @since 1.0.0
991
+ *
992
+ * @return void
993
+ */
994
+ private function kill() {
995
+
996
+ // Send report if set.
997
+ if ( jupiterx_get( 'jupiterx_send_compiler_report' ) ) { // @codingStandardsIgnoreLine
998
+ // $this->report(); // @codingStandardsIgnoreLine
999
+ }
1000
+
1001
+ $html = jupiterx_output( 'jupiterx_compiler_error_title_text', sprintf(
1002
+ '<h2>%s</h2>',
1003
+ __( 'Not cool, Jupiter cannot work its magic :(', 'jupiterx-core' )
1004
+ ) );
1005
+
1006
+ $html .= jupiterx_output( 'jupiterx_compiler_error_message_text', sprintf(
1007
+ '<p>%s</p>',
1008
+ __( 'Your current install or file permission prevents Jupiter from working its magic. Please get in touch with Jupiter support. We will gladly get you started within 24 - 48 hours (working days).', 'jupiterx-core' )
1009
+ ) );
1010
+
1011
+ $html .= jupiterx_output( 'jupiterx_compiler_error_contact_text', sprintf(
1012
+ '<a class="button" href="https://themes.artbees.net/support/" target="_blank">%s</a>',
1013
+ __( 'Contact Jupiter Support', 'jupiterx-core' )
1014
+ ) );
1015
+
1016
+ $html .= jupiterx_output( 'jupiterx_compiler_error_report_text', sprintf(
1017
+ '<p style="margin-top: 12px; font-size: 12px;"><a href="' . add_query_arg( 'jupiterx_send_compiler_report', true ) . '">%1$s</a>. %2$s</p>',
1018
+ __( 'Send us an automatic report', 'jupiterx-core' ),
1019
+ __( 'We respect your time and understand you might not be able to contact us.', 'jupiterx-core' )
1020
+ ) );
1021
+
1022
+ wp_die( wp_kses_post( $html ) );
1023
+ }
1024
+
1025
+ /**
1026
+ * Send report.
1027
+ *
1028
+ * @since 1.0.0
1029
+ *
1030
+ * @todo Decide if we want to use and change the report recipient.
1031
+ *
1032
+ * @return void
1033
+ * @SuppressWarnings(PHPMD.UnusedPrivateMethod)
1034
+ */
1035
+ private function report() {
1036
+ // Send report.
1037
+ wp_mail(
1038
+ 'hello@getjupiter.io',
1039
+ 'Compiler error',
1040
+ 'Compiler error reported by ' . home_url(),
1041
+ array(
1042
+ 'MIME-Version: 1.0' . "\r\n",
1043
+ 'Content-type: text/html; charset=utf-8' . "\r\n",
1044
+ "X-Mailer: PHP \r\n",
1045
+ 'From: ' . wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) . ' < ' . get_option( 'admin_email' ) . '>' . "\r\n",
1046
+ 'Reply-To: ' . get_option( 'admin_email' ) . "\r\n",
1047
+ )
1048
+ );
1049
+
1050
+ // Die and display message.
1051
+ $message = jupiterx_output(
1052
+ 'jupiterx_compiler_report_error_text',
1053
+ sprintf(
1054
+ '<p>%s<p>',
1055
+ __( 'Thanks for your contribution by reporting this issue. We hope to hear from you again.', 'jupiterx-core' )
1056
+ )
1057
+ );
1058
+
1059
+ wp_die( wp_kses_post( $message ) );
1060
+ }
1061
+
1062
+ /**
1063
+ * Get the property's value.
1064
+ *
1065
+ * @since 1.0.0
1066
+ *
1067
+ * @param string $property Name of the property to get.
1068
+ *
1069
+ * @return mixed
1070
+ */
1071
+ public function __get( $property ) {
1072
+
1073
+ if ( property_exists( $this, $property ) ) {
1074
+ return $this->{$property};
1075
+ }
1076
+ }
1077
+ }
includes/compiler/functions.php CHANGED
@@ -1,438 +1,438 @@
1
- <?php
2
- /**
3
- * Compile and cache CSS, LESS and JS files.
4
- *
5
- * The Jupiter Compiler compiles multiple internal or external CSS, LESS and JS files on a
6
- * per page basis. LESS content will automatically be converted to CSS.
7
- *
8
- * Internal file changes are automatically detected if development mode is enabled.
9
- * Third party enqueued styles and scripts can be compiled and cached into a single file.
10
- *
11
- * @package API\Compiler
12
- */
13
-
14
- /**
15
- * Compile CSS fragments and enqueue compiled file.
16
- *
17
- * This function should be used in a similar fashion to
18
- * {@link http://codex.wordpress.org/Function_Reference/wp_enqueue_script wp_enqueue_script()}.
19
- *
20
- * Fragments can be added to the compiler using {@see jupiterx_compiler_add_fragment()}.
21
- *
22
- * @since 1.0.0
23
- *
24
- * @param string $id A unique string used as a reference. Similar to the WordPress scripts
25
- * $handle argument.
26
- * @param string|array $fragments File(s) absolute path. Internal or external file(s) url accepted but may increase
27
- * compiling time.
28
- * @param array $args {
29
- * Optional. Array of arguments used by the compiler.
30
- *
31
- * @type array $depedencies An array of registered handles this script depends on. Default false.
32
- * }
33
- *
34
- * @return object Compiler object.
35
- */
36
- function jupiterx_compile_css_fragments( $id, $fragments, $args = array() ) {
37
-
38
- if ( empty( $fragments ) ) {
39
- return false;
40
- }
41
-
42
- $params = array(
43
- 'id' => $id,
44
- 'type' => 'style',
45
- 'format' => 'css',
46
- 'fragments' => (array) $fragments,
47
- );
48
-
49
- $compiler = new _JupiterX_Compiler( array_merge( $params, $args ) );
50
- $compiler->run_compiler();
51
-
52
- return $compiler;
53
- }
54
-
55
- /**
56
- * Compile LESS fragments, convert to CSS and enqueue compiled file.
57
- *
58
- * This function should be used in a similar fashion to
59
- * {@link http://codex.wordpress.org/Function_Reference/wp_enqueue_script wp_enqueue_script()}.
60
- *
61
- * Fragments can be added to the compiler using {@see jupiterx_compiler_add_fragment()}.
62
- *
63
- * @since 1.0.0
64
- *
65
- * @param string $id The compiler ID. Similar to the WordPress scripts $handle argument.
66
- * @param string|array $fragments File(s) absolute path. Internal or external file(s) url accepted but may increase
67
- * compiling time.
68
- * @param array $args {
69
- * Optional. Array of arguments used by the compiler.
70
- *
71
- * @type array $depedencies An array of registered handles this script depends on. Default false.
72
- * }
73
- *
74
- * @return object Compiler object.
75
- */
76
- function jupiterx_compile_less_fragments( $id, $fragments, $args = array() ) {
77
-
78
- if ( empty( $fragments ) ) {
79
- return false;
80
- }
81
-
82
- $params = array(
83
- 'id' => $id,
84
- 'type' => 'style',
85
- 'format' => 'less',
86
- 'fragments' => (array) $fragments,
87
- );
88
-
89
- $compiler = new _JupiterX_Compiler( array_merge( $params, $args ) );
90
- $compiler->run_compiler();
91
-
92
- return $compiler;
93
- }
94
-
95
- /**
96
- * Compile LESS fragments, convert to CSS and enqueue compiled file.
97
- *
98
- * This function should be used in a similar fashion to
99
- * {@link http://codex.wordpress.org/Function_Reference/wp_enqueue_script wp_enqueue_script()}.
100
- *
101
- * Fragments can be added to the compiler using {@see jupiterx_compiler_add_fragment()}.
102
- *
103
- * @since 1.0.0
104
- *
105
- * @param string $id The compiler ID. Similar to the WordPress scripts $handle argument.
106
- * @param string|array $fragments File(s) absolute path. Internal or external file(s) url accepted but may increase
107
- * compiling time.
108
- * @param array $args {
109
- * Optional. Array of arguments used by the compiler.
110
- *
111
- * @type array $depedencies An array of registered handles this script depends on. Default false.
112
- * }
113
- *
114
- * @return object Compiler object.
115
- */
116
- function jupiterx_compile_scss_fragments( $id, $fragments, $args = array() ) {
117
-
118
- if ( empty( $fragments ) ) {
119
- return false;
120
- }
121
-
122
- $params = array(
123
- 'id' => $id,
124
- 'type' => 'style',
125
- 'format' => 'scss',
126
- 'fragments' => (array) $fragments,
127
- );
128
-
129
- $compiler = new _JupiterX_Compiler( array_merge( $params, $args ) );
130
- $compiler->run_compiler();
131
-
132
- return $compiler;
133
- }
134
-
135
- /**
136
- * Compile JS fragments and enqueue compiled file.
137
- *
138
- * This function should be used in a similar fashion to
139
- * {@link http://codex.wordpress.org/Function_Reference/wp_enqueue_script wp_enqueue_script()}.
140
- *
141
- * Fragments can be added to the compiler using {@see jupiterx_compiler_add_fragment()}.
142
- *
143
- * @since 1.0.0
144
- *
145
- * @param string $id The compiler ID. Similar to the WordPress scripts $handle argument.
146
- * @param string|array $fragments File(s) absolute path. Internal or external file(s) URL accepted but may increase
147
- * compiling time.
148
- * @param array $args {
149
- * Optional. Array of arguments used by the compiler.
150
- *
151
- * @type array $depedencies An array of registered handles this script depends on. Default false.
152
- * @type bool $in_footer Whether to enqueue the script before </head> or before </body>. Default false.
153
- * @type bool $minify_js Whether the JavaScript should be minified or not. Be aware that minifying
154
- * the JavaScript can considerably slow down the process of compiling files.
155
- * Default false.
156
- * }
157
- *
158
- * @return object Compiler object.
159
- */
160
- function jupiterx_compile_js_fragments( $id, $fragments, $args = array() ) {
161
-
162
- if ( empty( $fragments ) ) {
163
- return false;
164
- }
165
-
166
- $params = array(
167
- 'id' => $id,
168
- 'type' => 'script',
169
- 'format' => 'js',
170
- 'fragments' => (array) $fragments,
171
- );
172
-
173
- $compiler = new _JupiterX_Compiler( array_merge( $params, $args ) );
174
- $compiler->run_compiler();
175
-
176
- return $compiler;
177
- }
178
-
179
- /**
180
- * Add CSS, LESS or JS fragments to a compiler.
181
- *
182
- * This function should be used in a similar fashion to
183
- * {@link http://codex.wordpress.org/Function_Reference/wp_enqueue_script wp_enqueue_script()}.
184
- *
185
- * @since 1.0.0
186
- *
187
- * @param string $id The compiler ID. Similar to the WordPress scripts $handle argument.
188
- * @param string|array $fragments File(s) absolute path. Internal or external file(s) url accepted but may increase
189
- * compiling time.
190
- * @param string $format Compiler format the fragments should be added to. Accepts 'css',
191
- * 'less' or 'js'.
192
- *
193
- * @return void|bool
194
- * @SuppressWarnings(PHPMD.ElseExpression)
195
- */
196
- function jupiterx_compiler_add_fragment( $id, $fragments, $format ) {
197
-
198
- if ( empty( $fragments ) ) {
199
- return false;
200
- }
201
-
202
- global $_jupiterx_compiler_added_fragments;
203
-
204
- foreach ( (array) $fragments as $key => $fragment ) {
205
-
206
- // Stop here if the format isn't valid.
207
- if ( ! isset( $_jupiterx_compiler_added_fragments[ $format ] ) ) {
208
- continue;
209
- }
210
-
211
- // Register a new compiler ID if it doesn't exist and add fragment.
212
- if ( ! isset( $_jupiterx_compiler_added_fragments[ $format ][ $id ] ) ) {
213
- $_jupiterx_compiler_added_fragments[ $format ][ $id ] = array( $fragment );
214
- } else { // Add fragment to existing compiler.
215
- $_jupiterx_compiler_added_fragments[ $format ][ $id ][] = $fragment;
216
- }
217
- }
218
- }
219
-
220
- /**
221
- * Flush cached compiler files.
222
- *
223
- * Each compiler has its own folder which contains the cached CSS and JS files. The file format
224
- * of the cached file can be specified if needed.
225
- *
226
- * @since 1.0.0
227
- *
228
- * @param string $id The compiler ID. Similar to the WordPress scripts $handle argument.
229
- * @param string|bool $file_format Optional. Define which file format(s) should be removed. Both CSS and JS
230
- * files will be removed if set to false. Accepts 'false', 'css' or 'js'.
231
- * @param bool $admin Optional. Whether it is an admin compiler or not.
232
- *
233
- * @return void|bool
234
- */
235
- function jupiterx_flush_compiler( $id, $file_format = false, $admin = false ) {
236
- static $jupiterx_flushed = false;
237
-
238
- $cache_dir = jupiterx_get_compiler_dir( $admin );
239
-
240
- // Always flush Jupiter' global cache.
241
- if ( ! $jupiterx_flushed && ! $id ) {
242
- $jupiterx_flushed = true;
243
-
244
- jupiterx_flush_compiler( 'jupiterx', $file_format, $admin );
245
- }
246
-
247
- $dir = trailingslashit( $cache_dir ) . $id;
248
-
249
- // Stop here if directory doesn't exist.
250
- if ( ! is_dir( $dir ) ) {
251
- return;
252
- }
253
-
254
- // Remove only the specified file format.
255
- if ( $file_format ) {
256
- $items = scandir( $dir );
257
- unset( $items[0], $items[1] );
258
-
259
- foreach ( $items as $item ) {
260
- if ( false !== stripos( $item, '.' . $file_format ) ) {
261
- @unlink( trailingslashit( $dir ) . $item ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Valid use case.
262
- }
263
- }
264
-
265
- return;
266
- }
267
-
268
- // Remove all file formats.
269
- jupiterx_remove_dir( $dir );
270
-
271
- jupiterx_flush_cache_plugins();
272
- }
273
-
274
- /**
275
- * Flush admin cached compiler files.
276
- *
277
- * This function is a shortcut of {@see jupiterx_flush_compiler()}.
278
- *
279
- * @since 1.0.0
280
- *
281
- * @param string $id The compiler ID. Similar to the WordPress scripts $handle argument.
282
- * @param string|bool $file_format Optional. Define which file formats should be removed. Both CSS and JS
283
- * files will be removed if set to false. Accepts 'false', 'css' or 'js'.
284
- *
285
- * @return void
286
- */
287
- function jupiterx_flush_admin_compiler( $id, $file_format = false ) {
288
- jupiterx_flush_compiler( $id, $file_format, true );
289
- }
290
-
291
- /**
292
- * Flush cache plugins
293
- *
294
- * @since 1.0.0
295
- *
296
- * @return void
297
- */
298
- function jupiterx_flush_cache_plugins() {
299
-
300
- if ( function_exists( 'w3tc_pgcache_flush' ) ) {
301
- w3tc_pgcache_flush();
302
- }
303
-
304
- if ( function_exists( 'wp_cache_clear_cache' ) ) {
305
- wp_cache_clear_cache();
306
- }
307
-
308
- if ( function_exists( 'rocket_clean_domain' ) ) {
309
- rocket_clean_domain();
310
- }
311
-
312
- if ( class_exists( 'WpFastestCache' ) ) {
313
- $GLOBALS['wp_fastest_cache']->deleteCache();
314
- }
315
-
316
- if ( class_exists( 'autoptimizeCache' ) ) {
317
- autoptimizeCache::clearall();
318
- }
319
- }
320
-
321
- /**
322
- * Get absolute path to the Jupiter' compiler directory.
323
- *
324
- * @since 1.0.0
325
- *
326
- * @param bool $is_admin Optional. When true, gets the admin compiler directory. Default is false.
327
- *
328
- * @return string
329
- */
330
- function jupiterx_get_compiler_dir( $is_admin = false ) {
331
- $wp_upload_dir = wp_upload_dir();
332
- $suffix = $is_admin ? 'jupiterx/admin-compiler/' : 'jupiterx/compiler/';
333
-
334
- /**
335
- * Deprecated. Filter the Jupiter compiler directory.
336
- *
337
- * This filter is deprecated for security and compatibility purposes.
338
- *
339
- * @since 1.0.0
340
- * @deprecated 1.3.0
341
- */
342
- apply_filters( 'jupiterx_compiler_dir', false, $is_admin );
343
-
344
- return wp_normalize_path( trailingslashit( $wp_upload_dir['basedir'] ) . $suffix );
345
- }
346
-
347
- /**
348
- * Get absolute URL to the Jupiter' compiler directory.
349
- *
350
- * @since 1.0.0
351
- *
352
- * @param bool $is_admin Optional. When true, gets the admin compiler directory. Default is false.
353
- *
354
- * @return string
355
- */
356
- function jupiterx_get_compiler_url( $is_admin = false ) {
357
- $wp_upload_dir = wp_upload_dir();
358
- $suffix = $is_admin ? 'jupiterx/admin-compiler/' : 'jupiterx/compiler/';
359
-
360
- return trailingslashit( $wp_upload_dir['baseurl'] ) . $suffix;
361
- }
362
-
363
- /**
364
- * Handle child theme script backward compatibility.
365
- *
366
- * @since 1.15.1
367
- *
368
- * @param string $id The compiler ID.
369
- * @param string|array $fragments File(s) absolute path.
370
- * @param string $format Compiler format.
371
- *
372
- * @return void
373
- */
374
- function jupiterx_handle_child_compatibility( $id, $fragments, $format ) {
375
-
376
- if ( 'jupiterx' !== $id || 'js' !== $format ) {
377
- return;
378
- }
379
-
380
- jupiterx_compile_js_fragments(
381
- 'jupiterx-child',
382
- $fragments,
383
- [
384
- 'dependencies' => [ 'jquery' ],
385
- 'in_footer' => true,
386
- ]
387
- );
388
- }
389
-
390
- /**
391
- * Check if development mode is enabled.
392
- *
393
- * Takes legacy constant into consideration.
394
- *
395
- * @since 1.0.0
396
- * @ignore
397
- * @access private
398
- *
399
- * @return bool
400
- */
401
- function _jupiterx_is_compiler_dev_mode() {
402
-
403
- if ( defined( 'JUPITERX_COMPILER_DEV_MODE' ) ) {
404
- return JUPITERX_COMPILER_DEV_MODE;
405
- }
406
-
407
- return jupiterx_get_option( 'dev_mode', false );
408
- }
409
-
410
- /**
411
- * Get cache busting method.
412
- *
413
- * @since 1.0.0
414
- * @access private
415
- *
416
- * @return bool
417
- */
418
- function _jupiterx_get_cache_busting() {
419
- return jupiterx_get_option( 'cache_busting', true );
420
- }
421
-
422
- /**
423
- * Initialize added fragments global.
424
- *
425
- * @since 1.0.0
426
- * @ignore
427
- * @access private
428
- */
429
- global $_jupiterx_compiler_added_fragments;
430
-
431
- if ( ! isset( $_jupiterx_compiler_added_fragments ) ) {
432
- $_jupiterx_compiler_added_fragments = array(
433
- 'css' => array(),
434
- 'less' => array(),
435
- 'scss' => array(),
436
- 'js' => array(),
437
- );
438
- }
1
+ <?php
2
+ /**
3
+ * Compile and cache CSS, LESS and JS files.
4
+ *
5
+ * The Jupiter Compiler compiles multiple internal or external CSS, LESS and JS files on a
6
+ * per page basis. LESS content will automatically be converted to CSS.
7
+ *
8
+ * Internal file changes are automatically detected if development mode is enabled.
9
+ * Third party enqueued styles and scripts can be compiled and cached into a single file.
10
+ *
11
+ * @package API\Compiler
12
+ */
13
+
14
+ /**
15
+ * Compile CSS fragments and enqueue compiled file.
16
+ *
17
+ * This function should be used in a similar fashion to
18
+ * {@link http://codex.wordpress.org/Function_Reference/wp_enqueue_script wp_enqueue_script()}.
19
+ *
20
+ * Fragments can be added to the compiler using {@see jupiterx_compiler_add_fragment()}.
21
+ *
22
+ * @since 1.0.0
23
+ *
24
+ * @param string $id A unique string used as a reference. Similar to the WordPress scripts
25
+ * $handle argument.
26
+ * @param string|array $fragments File(s) absolute path. Internal or external file(s) url accepted but may increase
27
+ * compiling time.
28
+ * @param array $args {
29
+ * Optional. Array of arguments used by the compiler.
30
+ *
31
+ * @type array $depedencies An array of registered handles this script depends on. Default false.
32
+ * }
33
+ *
34
+ * @return object Compiler object.
35
+ */
36
+ function jupiterx_compile_css_fragments( $id, $fragments, $args = array() ) {
37
+
38
+ if ( empty( $fragments ) ) {
39
+ return false;
40
+ }
41
+
42
+ $params = array(
43
+ 'id' => $id,
44
+ 'type' => 'style',
45
+ 'format' => 'css',
46
+ 'fragments' => (array) $fragments,
47
+ );
48
+
49
+ $compiler = new _JupiterX_Compiler( array_merge( $params, $args ) );
50
+ $compiler->run_compiler();
51
+
52
+ return $compiler;
53
+ }
54
+
55
+ /**
56
+ * Compile LESS fragments, convert to CSS and enqueue compiled file.
57
+ *
58
+ * This function should be used in a similar fashion to
59
+ * {@link http://codex.wordpress.org/Function_Reference/wp_enqueue_script wp_enqueue_script()}.
60
+ *
61
+ * Fragments can be added to the compiler using {@see jupiterx_compiler_add_fragment()}.
62
+ *
63
+ * @since 1.0.0
64
+ *
65
+ * @param string $id The compiler ID. Similar to the WordPress scripts $handle argument.
66
+ * @param string|array $fragments File(s) absolute path. Internal or external file(s) url accepted but may increase
67
+ * compiling time.
68
+ * @param array $args {
69
+ * Optional. Array of arguments used by the compiler.
70
+ *
71
+ * @type array $depedencies An array of registered handles this script depends on. Default false.
72
+ * }
73
+ *
74
+ * @return object Compiler object.
75
+ */
76
+ function jupiterx_compile_less_fragments( $id, $fragments, $args = array() ) {
77
+
78
+ if ( empty( $fragments ) ) {
79
+ return false;
80
+ }
81
+
82
+ $params = array(
83
+ 'id' => $id,
84
+ 'type' => 'style',
85
+ 'format' => 'less',
86
+ 'fragments' => (array) $fragments,
87
+ );
88
+
89
+ $compiler = new _JupiterX_Compiler( array_merge( $params, $args ) );
90
+ $compiler->run_compiler();
91
+
92
+ return $compiler;
93
+ }
94
+
95
+ /**
96
+ * Compile LESS fragments, convert to CSS and enqueue compiled file.
97
+ *
98
+ * This function should be used in a similar fashion to
99
+ * {@link http://codex.wordpress.org/Function_Reference/wp_enqueue_script wp_enqueue_script()}.
100
+ *
101
+ * Fragments can be added to the compiler using {@see jupiterx_compiler_add_fragment()}.
102
+ *
103
+ * @since 1.0.0
104
+ *
105
+ * @param string $id The compiler ID. Similar to the WordPress scripts $handle argument.
106
+ * @param string|array $fragments File(s) absolute path. Internal or external file(s) url accepted but may increase
107
+ * compiling time.
108
+ * @param array $args {
109
+ * Optional. Array of arguments used by the compiler.
110
+ *
111
+ * @type array $depedencies An array of registered handles this script depends on. Default false.
112
+ * }
113
+ *
114
+ * @return object Compiler object.
115
+ */
116
+ function jupiterx_compile_scss_fragments( $id, $fragments, $args = array() ) {
117
+
118
+ if ( empty( $fragments ) ) {
119
+ return false;
120
+ }
121
+
122
+ $params = array(
123
+ 'id' => $id,
124
+ 'type' => 'style',
125
+ 'format' => 'scss',
126
+ 'fragments' => (array) $fragments,
127
+ );
128
+
129
+ $compiler = new _JupiterX_Compiler( array_merge( $params, $args ) );
130
+ $compiler->run_compiler();
131
+
132
+ return $compiler;
133
+ }
134
+
135
+ /**
136
+ * Compile JS fragments and enqueue compiled file.
137
+ *
138
+ * This function should be used in a similar fashion to
139
+ * {@link http://codex.wordpress.org/Function_Reference/wp_enqueue_script wp_enqueue_script()}.
140
+ *
141
+ * Fragments can be added to the compiler using {@see jupiterx_compiler_add_fragment()}.
142
+ *
143
+ * @since 1.0.0
144
+ *
145
+ * @param string $id The compiler ID. Similar to the WordPress scripts $handle argument.
146
+ * @param string|array $fragments File(s) absolute path. Internal or external file(s) URL accepted but may increase
147
+ * compiling time.
148
+ * @param array $args {
149
+ * Optional. Array of arguments used by the compiler.
150
+ *
151
+ * @type array $depedencies An array of registered handles this script depends on. Default false.
152
+ * @type bool $in_footer Whether to enqueue the script before </head> or before </body>. Default false.
153
+ * @type bool $minify_js Whether the JavaScript should be minified or not. Be aware that minifying
154
+ * the JavaScript can considerably slow down the process of compiling files.
155
+ * Default false.
156
+ * }
157
+ *
158
+ * @return object Compiler object.
159
+ */
160
+ function jupiterx_compile_js_fragments( $id, $fragments, $args = array() ) {
161
+
162
+ if ( empty( $fragments ) ) {
163
+ return false;
164
+ }
165
+
166
+ $params = array(
167
+ 'id' => $id,
168
+ 'type' => 'script',
169
+ 'format' => 'js',
170
+ 'fragments' => (array) $fragments,
171
+ );
172
+
173
+ $compiler = new _JupiterX_Compiler( array_merge( $params, $args ) );
174
+ $compiler->run_compiler();
175
+
176
+ return $compiler;
177
+ }
178
+
179
+ /**
180
+ * Add CSS, LESS or JS fragments to a compiler.
181
+ *
182
+ * This function should be used in a similar fashion to
183
+ * {@link http://codex.wordpress.org/Function_Reference/wp_enqueue_script wp_enqueue_script()}.
184
+ *
185
+ * @since 1.0.0
186
+ *
187
+ * @param string $id The compiler ID. Similar to the WordPress scripts $handle argument.
188
+ * @param string|array $fragments File(s) absolute path. Internal or external file(s) url accepted but may increase
189
+ * compiling time.
190
+ * @param string $format Compiler format the fragments should be added to. Accepts 'css',
191
+ * 'less' or 'js'.
192
+ *
193
+ * @return void|bool
194
+ * @SuppressWarnings(PHPMD.ElseExpression)
195
+ */
196
+ function jupiterx_compiler_add_fragment( $id, $fragments, $format ) {
197
+
198
+ if ( empty( $fragments ) ) {
199
+ return false;
200
+ }
201
+
202
+ global $_jupiterx_compiler_added_fragments;
203
+
204
+ foreach ( (array) $fragments as $key => $fragment ) {
205
+
206
+ // Stop here if the format isn't valid.
207
+ if ( ! isset( $_jupiterx_compiler_added_fragments[ $format ] ) ) {
208
+ continue;
209
+ }
210
+
211
+ // Register a new compiler ID if it doesn't exist and add fragment.
212
+ if ( ! isset( $_jupiterx_compiler_added_fragments[ $format ][ $id ] ) ) {
213
+ $_jupiterx_compiler_added_fragments[ $format ][ $id ] = array( $fragment );
214
+ } else { // Add fragment to existing compiler.
215
+ $_jupiterx_compiler_added_fragments[ $format ][ $id ][] = $fragment;
216
+ }
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Flush cached compiler files.
222
+ *
223
+ * Each compiler has its own folder which contains the cached CSS and JS files. The file format
224
+ * of the cached file can be specified if needed.
225
+ *
226
+ * @since 1.0.0
227
+ *
228
+ * @param string $id The compiler ID. Similar to the WordPress scripts $handle argument.
229
+ * @param string|bool $file_format Optional. Define which file format(s) should be removed. Both CSS and JS
230
+ * files will be removed if set to false. Accepts 'false', 'css' or 'js'.
231
+ * @param bool $admin Optional. Whether it is an admin compiler or not.
232
+ *
233
+ * @return void|bool
234
+ */
235
+ function jupiterx_flush_compiler( $id, $file_format = false, $admin = false ) {
236
+ static $jupiterx_flushed = false;
237
+
238
+ $cache_dir = jupiterx_get_compiler_dir( $admin );
239
+
240
+ // Always flush Jupiter' global cache.
241
+ if ( ! $jupiterx_flushed && ! $id ) {
242
+ $jupiterx_flushed = true;
243
+
244
+ jupiterx_flush_compiler( 'jupiterx', $file_format, $admin );
245
+ }
246
+
247
+ $dir = trailingslashit( $cache_dir ) . $id;
248
+
249
+ // Stop here if directory doesn't exist.
250
+ if ( ! is_dir( $dir ) ) {
251
+ return;
252
+ }
253
+
254
+ // Remove only the specified file format.
255
+ if ( $file_format ) {
256
+ $items = scandir( $dir );
257
+ unset( $items[0], $items[1] );
258
+
259
+ foreach ( $items as $item ) {
260
+ if ( false !== stripos( $item, '.' . $file_format ) ) {
261
+ @unlink( trailingslashit( $dir ) . $item ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Valid use case.
262
+ }
263
+ }
264
+
265
+ return;
266
+ }
267
+
268
+ // Remove all file formats.
269
+ jupiterx_remove_dir( $dir );
270
+
271
+ jupiterx_flush_cache_plugins();
272
+ }
273
+
274
+ /**
275
+ * Flush admin cached compiler files.
276
+ *
277
+ * This function is a shortcut of {@see jupiterx_flush_compiler()}.
278
+ *
279
+ * @since 1.0.0
280
+ *
281
+ * @param string $id The compiler ID. Similar to the WordPress scripts $handle argument.
282
+ * @param string|bool $file_format Optional. Define which file formats should be removed. Both CSS and JS
283
+ * files will be removed if set to false. Accepts 'false', 'css' or 'js'.
284
+ *
285
+ * @return void
286
+ */
287
+ function jupiterx_flush_admin_compiler( $id, $file_format = false ) {
288
+ jupiterx_flush_compiler( $id, $file_format, true );
289
+ }
290
+
291
+ /**
292
+ * Flush cache plugins
293
+ *
294
+ * @since 1.0.0
295
+ *
296
+ * @return void
297
+ */
298
+ function jupiterx_flush_cache_plugins() {
299
+
300
+ if ( function_exists( 'w3tc_pgcache_flush' ) ) {
301
+ w3tc_pgcache_flush();
302
+ }
303
+
304
+ if ( function_exists( 'wp_cache_clear_cache' ) ) {
305
+ wp_cache_clear_cache();
306
+ }
307
+
308
+ if ( function_exists( 'rocket_clean_domain' ) ) {
309
+ rocket_clean_domain();
310
+ }
311
+
312
+ if ( class_exists( 'WpFastestCache' ) ) {
313
+ $GLOBALS['wp_fastest_cache']->deleteCache();
314
+ }
315
+
316
+ if ( class_exists( 'autoptimizeCache' ) ) {
317
+ autoptimizeCache::clearall();
318
+ }
319
+ }
320
+
321
+ /**
322
+ * Get absolute path to the Jupiter' compiler directory.
323
+ *
324
+ * @since 1.0.0
325
+ *
326
+ * @param bool $is_admin Optional. When true, gets the admin compiler directory. Default is false.
327
+ *
328
+ * @return string
329
+ */
330
+ function jupiterx_get_compiler_dir( $is_admin = false ) {
331
+ $wp_upload_dir = wp_upload_dir();
332
+ $suffix = $is_admin ? 'jupiterx/admin-compiler/' : 'jupiterx/compiler/';
333
+
334
+ /**
335
+ * Deprecated. Filter the Jupiter compiler directory.
336
+ *
337
+ * This filter is deprecated for security and compatibility purposes.
338
+ *
339
+ * @since 1.0.0
340
+ * @deprecated 1.3.0
341
+ */
342
+ apply_filters( 'jupiterx_compiler_dir', false, $is_admin );
343
+
344
+ return wp_normalize_path( trailingslashit( $wp_upload_dir['basedir'] ) . $suffix );
345
+ }
346
+
347
+ /**
348
+ * Get absolute URL to the Jupiter' compiler directory.
349
+ *
350
+ * @since 1.0.0
351
+ *
352
+ * @param bool $is_admin Optional. When true, gets the admin compiler directory. Default is false.
353
+ *
354
+ * @return string
355
+ */
356
+ function jupiterx_get_compiler_url( $is_admin = false ) {
357
+ $wp_upload_dir = wp_upload_dir();
358
+ $suffix = $is_admin ? 'jupiterx/admin-compiler/' : 'jupiterx/compiler/';
359
+
360
+ return trailingslashit( $wp_upload_dir['baseurl'] ) . $suffix;
361
+ }
362
+
363
+ /**
364
+ * Handle child theme script backward compatibility.
365
+ *
366
+ * @since 1.15.1
367
+ *
368
+ * @param string $id The compiler ID.
369
+ * @param string|array $fragments File(s) absolute path.
370
+ * @param string $format Compiler format.
371
+ *
372
+ * @return void
373
+ */
374
+ function jupiterx_handle_child_compatibility( $id, $fragments, $format ) {
375
+
376
+ if ( 'jupiterx' !== $id || 'js' !== $format ) {
377
+ return;
378
+ }
379
+
380
+ jupiterx_compile_js_fragments(
381
+ 'jupiterx-child',
382
+ $fragments,
383
+ [
384
+ 'dependencies' => [ 'jquery' ],
385
+ 'in_footer' => true,
386
+ ]
387
+ );
388
+ }
389
+
390
+ /**
391
+ * Check if development mode is enabled.
392
+ *
393
+ * Takes legacy constant into consideration.
394
+ *
395
+ * @since 1.0.0
396
+ * @ignore
397
+ * @access private
398
+ *
399
+ * @return bool
400
+ */
401
+ function _jupiterx_is_compiler_dev_mode() {
402
+
403
+ if ( defined( 'JUPITERX_COMPILER_DEV_MODE' ) ) {
404
+ return JUPITERX_COMPILER_DEV_MODE;
405
+ }
406
+
407
+ return jupiterx_get_option( 'dev_mode', false );
408
+ }
409
+
410
+ /**
411
+ * Get cache busting method.
412
+ *
413
+ * @since 1.0.0
414
+ * @access private
415
+ *
416
+ * @return bool
417
+ */
418
+ function _jupiterx_get_cache_busting() {
419
+ return jupiterx_get_option( 'cache_busting', true );
420
+ }
421
+
422
+ /**
423
+ * Initialize added fragments global.
424
+ *
425
+ * @since 1.0.0
426
+ * @ignore
427
+ * @access private
428
+ */
429
+ global $_jupiterx_compiler_added_fragments;
430
+
431
+ if ( ! isset( $_jupiterx_compiler_added_fragments ) ) {
432
+ $_jupiterx_compiler_added_fragments = array(
433
+ 'css' => array(),
434
+ 'less' => array(),
435
+ 'scss' => array(),
436
+ 'js' => array(),
437
+ );
438
+ }
includes/compiler/preprocess-aliases.ini CHANGED
@@ -1,277 +1,277 @@
1
- ;----------------------------------------------------------------
2
- ;
3
- ; Add or delete aliases to suit your needs.
4
- ; Modified for Jupiter X.
5
- ;
6
- ; Sources:
7
- ; http://developer.mozilla.org/en-US/docs/CSS/CSS_Reference
8
- ; http://caniuse.com/#cats=CSS
9
- ;
10
- ;----------------------------------------------------------------
11
-
12
- ; Property aliases.
13
-
14
- [properties]
15
-
16
- ; Animations.
17
- animation[] = -webkit-animation
18
- animation-delay[] = -webkit-animation-delay
19
- animation-direction[] = -webkit-animation-direction
20
- animation-duration[] = -webkit-animation-duration
21
- animation-fill-mode[] = -webkit-animation-fill-mode
22
- animation-iteration-count[] = -webkit-animation-iteration-count
23
- animation-name[] = -webkit-animation-name
24
- animation-play-state[] = -webkit-animation-play-state
25
- animation-timing-function[] = -webkit-animation-timing-function
26
-
27
- ; Backface visibility.
28
- backface-visibility[] = -webkit-backface-visibility
29
-
30
- ; Border-image.
31
- border-image[] = -webkit-border-image
32
-
33
- ; Box decoration.
34
- box-decoration-break[] = -webkit-box-decoration-break
35
-
36
- ; Box shadow.
37
- ; box-shadow[] = -webkit-box-shadow
38
-
39
- ; Box sizing.
40
- ; box-sizing[] = -webkit-box-sizing
41
- ; box-sizing[] = -moz-box-sizing
42
-
43
- ; Columns.
44
- columns[] = -webkit-columns
45
- columns[] = -moz-columns
46
- column-count[] = -webkit-column-count
47
- column-count[] = -moz-column-count
48
- column-fill[] = -webkit-column-fill
49
- column-fill[] = -moz-column-fill
50
- column-gap[] = -webkit-column-gap
51
- column-gap[] = -moz-column-gap
52
- column-rule[] = -webkit-column-rule
53
- column-rule[] = -moz-column-rule
54
- column-rule-style[] = -webkit-column-rule-style
55
- column-rule-style[] = -moz-column-rule-style
56
- column-rule-width[] = -webkit-column-rule-width
57
- column-rule-width[] = -moz-column-rule-width
58
- column-rule-style[] = -webkit-column-rule-style
59
- column-rule-style[] = -moz-column-rule-style
60
- column-rule-color[] = -webkit-column-rule-color
61
- column-rule-color[] = -moz-column-rule-color
62
- column-span[] = -webkit-column-span
63
- column-span[] = -moz-column-span
64
- column-width[] = -webkit-column-width
65
- column-width[] = -moz-column-width
66
-
67
- ; Filter.
68
- filter[] = -webkit-filter
69
-
70
- ; Flexbox (2012).
71
- ;
72
- ; Merges two similar versions of the flexbox spec:
73
- ; - September 2012 (for non IE): http://www.w3.org/TR/2012/CR-css3-flexbox-20120918
74
- ; - March 2012 (for IE10): http://www.w3.org/TR/2012/WD-css3-flexbox-20120322
75
- ;
76
- ; The early 2012 spec mostly differs only in syntax to the later one, with the notable
77
- ; exception of not supporting seperate properties for <flex-grow>, <flex-shrink>
78
- ; and <flex-basis>. These properties are available in both 2012 implementations via
79
- ; <flex> shorthand.
80
- ;
81
- ; Support for the early 2012 syntax implemented in IE10 is achieved here in part with
82
- ; property aliases, and in part with declaration aliases later in this file.
83
- ;
84
- ; align-content[] = -webkit-align-content
85
- ; align-items[] = -webkit-align-items
86
- ; align-self[] = -webkit-align-self
87
- ; flex[] = -webkit-flex
88
- flex[] = -ms-flexbox
89
- ; flex-basis[] = -webkit-flex-basis
90
- ; flex-direction[] = -webkit-flex-direction
91
- flex-direction[] = -ms-flex-direction
92
- ; flex-flow[] = -webkit-flex-flow
93
- flex-flow[] = -ms-flex-flow
94
- ; flex-grow[] = -webkit-flex-grow
95
- ; flex-shrink[] = -webkit-flex-shrink
96
- ; flex-wrap[] = -webkit-flex-wrap
97
- ; flex-wrap[] = -ms-flex-wrap
98
- ; justify-content[] = -webkit-justify-content
99
- ; order[] = -webkit-order
100
- order[] = -ms-flex-order
101
-
102
- ; Hyphens.
103
- hyphens[] = -webkit-hyphens
104
- hyphens[] = -moz-hyphens
105
- hyphens[] = -ms-hyphens
106
-
107
- ; Outline radius.
108
- outline-radius[] = -moz-outline-radius
109
- outline-top-left-radius[] = -moz-outline-radius-topleft
110
- outline-top-right-radius[] = -moz-outline-radius-topright
111
- outline-bottom-left-radius[] = -moz-outline-radius-bottomleft
112
- outline-bottom-right-radius[] = -moz-outline-radius-bottomright
113
-
114
- ; Perspective.
115
- perspective[] = -webkit-perspective
116
- perspective-origin[] = -webkit-perspective-origin
117
-
118
- ; Shapes
119
- shape-image-threshold[] = -webkit-shape-image-threshold
120
- shape-outside[] = -webkit-shape-outside
121
- shape-margin[] = -webkit-shape-margin
122
-
123
- ; Tab size.
124
- tab-size[] = -moz-tab-size
125
- tab-size[] = -o-tab-size
126
-
127
- ; Text align last.
128
- text-align-last[] = -webkit-text-align-last
129
- text-align-last[] = -moz-text-align-last
130
-
131
- ; Text decoration.
132
- text-decoration-color[] = -moz-text-decoration-color
133
- text-decoration-line[] = -moz-text-decoration-line
134
- text-decoration-style[] = -moz-text-decoration-style
135
-
136
- ; Text overflow (Opera mini support).
137
- text-overflow[] = -o-text-overflow
138
-
139
- ; Transforms.
140
- transform[] = -webkit-transform
141
- ; transform[] = -ms-transform
142
- transform-origin[] = -webkit-transform-origin
143
- ; transform-origin[] = -ms-transform-origin
144
- transform-style[] = -webkit-transform-style
145
- ; transform-style[] = -ms-transform-style
146
-
147
- ; Transitions.
148
- ; transition[] = -webkit-transition
149
- ; transition-delay[] = -webkit-transition-delay
150
- ; transition-duration[] = -webkit-transition-duration
151
- ; transition-property[] = -webkit-transition-property
152
- ; transition-timing-function[] = -webkit-transition-timing-function
153
-
154
- ; User select (non standard).
155
- user-select[] = -webkit-user-select
156
- user-select[] = -moz-user-select
157
- user-select[] = -ms-user-select
158
-
159
-
160
- ;----------------------------------------------------------------
161
- ; Declaration aliases.
162
-
163
- [declarations]
164
-
165
- ; Flexbox (2012).
166
- display:flex[] = display:-ms-flexbox
167
- ; display:flex[] = display:-webkit-flex
168
- display:inline-flex[] = display:-ms-inline-flexbox
169
- ; display:inline-flex[] = display:-webkit-inline-flex
170
-
171
- ; Flexbox (early 2012).
172
- align-content:flex-start[] = -ms-flex-line-pack:start
173
- align-content:flex-end[] = -ms-flex-line-pack:end
174
- align-content:center[] = -ms-flex-line-pack:center
175
- align-content:space-between[] = -ms-flex-line-pack:justify
176
- align-content:space-around[] = -ms-flex-line-pack:distribute
177
- align-content:stretch[] = -ms-flex-line-pack:stretch
178
-
179
- align-items:flex-start[] = -ms-flex-align:start
180
- align-items:flex-end[] = -ms-flex-align:end
181
- align-items:center[] = -ms-flex-align:center
182
- align-items:baseline[] = -ms-flex-align:baseline
183
- align-items:stretch[] = -ms-flex-align:stretch
184
-
185
- align-self:auto[] = -ms-flex-item-align:auto
186
- align-self:flex-start[] = -ms-flex-item-align:start
187
- align-self:flex-end[] = -ms-flex-item-align:end
188
- align-self:center[] = -ms-flex-item-align:center
189
- align-self:baseline[] = -ms-flex-item-align:baseline
190
- align-self:stretch[] = -ms-flex-item-align:stretch
191
-
192
- justify-content:flex-start[] = -ms-flex-pack:start
193
- justify-content:flex-end[] = -ms-flex-pack:end
194
- justify-content:center[] = -ms-flex-pack:center
195
- justify-content:space-between[] = -ms-flex-pack:justify
196
- justify-content:space-around[] = -ms-flex-pack:distribute
197
-
198
- ; Cursor values (non-standard).
199
- cursor:zoom-in[] = cursor:-webkit-zoom-in
200
- cursor:zoom-in[] = cursor:-moz-zoom-in
201
- cursor:zoom-out[] = cursor:-webkit-zoom-out
202
- cursor:zoom-out[] = cursor:-moz-zoom-out
203
- cursor:grab[] = cursor:-webkit-grab
204
- cursor:grab[] = cursor:-moz-grab
205
- cursor:grabbing[] = cursor:-webkit-grabbing
206
- cursor:grabbing[] = cursor:-moz-grabbing
207
-
208
- ; Experimental width values.
209
- width:max-content[] = width:intrinsic
210
- width:max-content[] = width:-webkit-max-content
211
- width:max-content[] = width:-moz-max-content
212
- width:min-content[] = width:-webkit-min-content
213
- width:min-content[] = width:-moz-min-content
214
- width:available[] = width:-webkit-available
215
- width:available[] = width:-moz-available
216
- width:fit-content[] = width:-webkit-fit-content
217
- width:fit-content[] = width:-moz-fit-content
218
-
219
- max-width:max-content[] = max-width:intrinsic
220
- max-width:max-content[] = max-width:-webkit-max-content
221
- max-width:max-content[] = max-width:-moz-max-content
222
- max-width:min-content[] = max-width:-webkit-min-content
223
- max-width:min-content[] = max-width:-moz-min-content
224
- max-width:available[] = max-width:-webkit-available
225
- max-width:available[] = max-width:-moz-available
226
- max-width:fit-content[] = max-width:-webkit-fit-content
227
- max-width:fit-content[] = max-width:-moz-fit-content
228
-
229
- min-width:max-content[] = min-width:intrinsic
230
- min-width:max-content[] = min-width:-webkit-max-content
231
- min-width:max-content[] = min-width:-moz-max-content
232
- min-width:min-content[] = min-width:-webkit-min-content
233
- min-width:min-content[] = min-width:-moz-min-content
234
- min-width:available[] = min-width:-webkit-available
235
- min-width:available[] = min-width:-moz-available
236
- min-width:fit-content[] = min-width:-webkit-fit-content
237
- min-width:fit-content[] = min-width:-moz-fit-content
238
-
239
- ; Appearance (non-standard).
240
- appearance:none[] = -webkit-appearance:none
241
- appearance:none[] = -moz-appearance:none
242
-
243
- position:sticky[] = position:-webkit-sticky
244
-
245
-
246
- ;----------------------------------------------------------------
247
- ; Function aliases.
248
-
249
- [functions]
250
-
251
- ; Calc.
252
- ; calc[] = -webkit-calc÷
253
-
254
-
255
- [functions.gradients]
256
-
257
- ; Gradients.
258
- ; linear-gradient[] = -webkit-linear-gradient
259
- ; radial-gradient[] = -webkit-radial-gradient
260
-
261
- ; Repeating gradients.
262
- ; repeating-linear-gradient[] = -webkit-repeating-linear-gradient
263
- ; repeating-radial-gradient[] = -webkit-repeating-radial-gradient
264
-
265
-
266
- ;----------------------------------------------------------------
267
- ; @rule aliases.
268
-
269
- [at-rules]
270
-
271
- ; Keyframes.
272
- keyframes[] = -webkit-keyframes
273
-
274
- ; Viewport.
275
- viewport[] = -webkit-viewport
276
- viewport[] = -ms-viewport
277
- viewport[] = -o-viewport
1
+ ;----------------------------------------------------------------
2
+ ;
3
+ ; Add or delete aliases to suit your needs.
4
+ ; Modified for Jupiter X.
5
+ ;
6
+ ; Sources:
7
+ ; http://developer.mozilla.org/en-US/docs/CSS/CSS_Reference
8
+ ; http://caniuse.com/#cats=CSS
9
+ ;
10
+ ;----------------------------------------------------------------
11
+
12
+ ; Property aliases.
13
+
14
+ [properties]
15
+
16
+ ; Animations.
17
+ animation[] = -webkit-animation
18
+ animation-delay[] = -webkit-animation-delay
19
+ animation-direction[] = -webkit-animation-direction
20
+ animation-duration[] = -webkit-animation-duration
21
+ animation-fill-mode[] = -webkit-animation-fill-mode
22
+ animation-iteration-count[] = -webkit-animation-iteration-count
23
+ animation-name[] = -webkit-animation-name
24
+ animation-play-state[] = -webkit-animation-play-state
25
+ animation-timing-function[] = -webkit-animation-timing-function
26
+
27
+ ; Backface visibility.
28
+ backface-visibility[] = -webkit-backface-visibility
29
+
30
+ ; Border-image.
31
+ border-image[] = -webkit-border-image
32
+
33
+ ; Box decoration.
34
+ box-decoration-break[] = -webkit-box-decoration-break
35
+
36
+ ; Box shadow.
37
+ ; box-shadow[] = -webkit-box-shadow
38
+
39
+ ; Box sizing.
40
+ ; box-sizing[] = -webkit-box-sizing
41
+ ; box-sizing[] = -moz-box-sizing
42
+
43
+ ; Columns.
44
+ columns[] = -webkit-columns
45
+ columns[] = -moz-columns
46
+ column-count[] = -webkit-column-count
47
+ column-count[] = -moz-column-count
48
+ column-fill[] = -webkit-column-fill
49
+ column-fill[] = -moz-column-fill
50
+ column-gap[] = -webkit-column-gap
51
+ column-gap[] = -moz-column-gap
52
+ column-rule[] = -webkit-column-rule
53
+ column-rule[] = -moz-column-rule
54
+ column-rule-style[] = -webkit-column-rule-style
55
+ column-rule-style[] = -moz-column-rule-style
56
+ column-rule-width[] = -webkit-column-rule-width
57
+ column-rule-width[] = -moz-column-rule-width
58
+ column-rule-style[] = -webkit-column-rule-style
59
+ column-rule-style[] = -moz-column-rule-style
60
+ column-rule-color[] = -webkit-column-rule-color
61
+ column-rule-color[] = -moz-column-rule-color
62
+ column-span[] = -webkit-column-span
63
+ column-span[] = -moz-column-span
64
+ column-width[] = -webkit-column-width
65
+ column-width[] = -moz-column-width
66
+
67
+ ; Filter.
68
+ filter[] = -webkit-filter
69
+
70
+ ; Flexbox (2012).
71
+ ;
72
+ ; Merges two similar versions of the flexbox spec:
73
+ ; - September 2012 (for non IE): http://www.w3.org/TR/2012/CR-css3-flexbox-20120918
74
+ ; - March 2012 (for IE10): http://www.w3.org/TR/2012/WD-css3-flexbox-20120322
75
+ ;
76
+ ; The early 2012 spec mostly differs only in syntax to the later one, with the notable
77
+ ; exception of not supporting seperate properties for <flex-grow>, <flex-shrink>
78
+ ; and <flex-basis>. These properties are available in both 2012 implementations via
79
+ ; <flex> shorthand.
80
+ ;
81
+ ; Support for the early 2012 syntax implemented in IE10 is achieved here in part with
82
+ ; property aliases, and in part with declaration aliases later in this file.
83
+ ;
84
+ ; align-content[] = -webkit-align-content
85
+ ; align-items[] = -webkit-align-items
86
+ ; align-self[] = -webkit-align-self
87
+ ; flex[] = -webkit-flex
88
+ flex[] = -ms-flexbox
89
+ ; flex-basis[] = -webkit-flex-basis
90
+ ; flex-direction[] = -webkit-flex-direction
91
+ flex-direction[] = -ms-flex-direction
92
+ ; flex-flow[] = -webkit-flex-flow
93
+ flex-flow[] = -ms-flex-flow
94
+ ; flex-grow[] = -webkit-flex-grow
95
+ ; flex-shrink[] = -webkit-flex-shrink
96
+ ; flex-wrap[] = -webkit-flex-wrap
97
+ ; flex-wrap[] = -ms-flex-wrap
98
+ ; justify-content[] = -webkit-justify-content
99
+ ; order[] = -webkit-order
100
+ order[] = -ms-flex-order
101
+
102
+ ; Hyphens.
103
+ hyphens[] = -webkit-hyphens
104
+ hyphens[] = -moz-hyphens
105
+ hyphens[] = -ms-hyphens
106
+
107
+ ; Outline radius.
108
+ outline-radius[] = -moz-outline-radius
109
+ outline-top-left-radius[] = -moz-outline-radius-topleft
110
+ outline-top-right-radius[] = -moz-outline-radius-topright
111
+ outline-bottom-left-radius[] = -moz-outline-radius-bottomleft
112
+ outline-bottom-right-radius[] = -moz-outline-radius-bottomright
113
+
114
+ ; Perspective.
115
+ perspective[] = -webkit-perspective
116
+ perspective-origin[] = -webkit-perspective-origin
117
+
118
+ ; Shapes
119
+ shape-image-threshold[] = -webkit-shape-image-threshold
120
+ shape-outside[] = -webkit-shape-outside
121
+ shape-margin[] = -webkit-shape-margin
122
+
123
+ ; Tab size.
124
+ tab-size[] = -moz-tab-size
125
+ tab-size[] = -o-tab-size
126
+
127
+ ; Text align last.
128
+ text-align-last[] = -webkit-text-align-last
129
+ text-align-last[] = -moz-text-align-last
130
+
131
+ ; Text decoration.
132
+ text-decoration-color[] = -moz-text-decoration-color
133
+ text-decoration-line[] = -moz-text-decoration-line
134
+ text-decoration-style[] = -moz-text-decoration-style
135
+
136
+ ; Text overflow (Opera mini support).
137
+ text-overflow[] = -o-text-overflow
138
+
139
+ ; Transforms.
140
+ transform[] = -webkit-transform
141
+ ; transform[] = -ms-transform
142
+ transform-origin[] = -webkit-transform-origin
143
+ ; transform-origin[] = -ms-transform-origin
144
+ transform-style[] = -webkit-transform-style
145
+ ; transform-style[] = -ms-transform-style
146
+
147
+ ; Transitions.
148
+ ; transition[] = -webkit-transition
149
+ ; transition-delay[] = -webkit-transition-delay
150
+ ; transition-duration[] = -webkit-transition-duration
151
+ ; transition-property[] = -webkit-transition-property
152
+ ; transition-timing-function[] = -webkit-transition-timing-function
153
+
154
+ ; User select (non standard).
155
+ user-select[] = -webkit-user-select
156
+ user-select[] = -moz-user-select
157
+ user-select[] = -ms-user-select
158
+
159
+
160
+ ;----------------------------------------------------------------
161
+ ; Declaration aliases.
162
+
163
+ [declarations]
164
+
165
+ ; Flexbox (2012).
166
+ display:flex[] = display:-ms-flexbox
167
+ ; display:flex[] = display:-webkit-flex
168
+ display:inline-flex[] = display:-ms-inline-flexbox
169
+ ; display:inline-flex[] = display:-webkit-inline-flex
170
+
171
+ ; Flexbox (early 2012).
172
+ align-content:flex-start[] = -ms-flex-line-pack:start
173
+ align-content:flex-end[] = -ms-flex-line-pack:end
174
+ align-content:center[] = -ms-flex-line-pack:center
175
+ align-content:space-between[] = -ms-flex-line-pack:justify
176
+ align-content:space-around[] = -ms-flex-line-pack:distribute
177
+ align-content:stretch[] = -ms-flex-line-pack:stretch
178
+
179
+ align-items:flex-start[] = -ms-flex-align:start
180
+ align-items:flex-end[] = -ms-flex-align:end
181
+ align-items:center[] = -ms-flex-align:center
182
+ align-items:baseline[] = -ms-flex-align:baseline
183
+ align-items:stretch[] = -ms-flex-align:stretch
184
+
185
+ align-self:auto[] = -ms-flex-item-align:auto
186
+ align-self:flex-start[] = -ms-flex-item-align:start
187
+ align-self:flex-end[] = -ms-flex-item-align:end
188
+ align-self:center[] = -ms-flex-item-align:center
189
+ align-self:baseline[] = -ms-flex-item-align:baseline
190
+ align-self:stretch[] = -ms-flex-item-align:stretch
191
+
192
+ justify-content:flex-start[] = -ms-flex-pack:start
193
+ justify-content:flex-end[] = -ms-flex-pack:end
194
+ justify-content:center[] = -ms-flex-pack:center
195
+ justify-content:space-between[] = -ms-flex-pack:justify
196
+ justify-content:space-around[] = -ms-flex-pack:distribute
197
+
198
+ ; Cursor values (non-standard).
199
+ cursor:zoom-in[] = cursor:-webkit-zoom-in
200
+ cursor:zoom-in[] = cursor:-moz-zoom-in
201
+ cursor:zoom-out[] = cursor:-webkit-zoom-out
202
+ cursor:zoom-out[] = cursor:-moz-zoom-out
203
+ cursor:grab[] = cursor:-webkit-grab
204
+ cursor:grab[] = cursor:-moz-grab
205
+ cursor:grabbing[] = cursor:-webkit-grabbing
206
+ cursor:grabbing[] = cursor:-moz-grabbing
207
+
208
+ ; Experimental width values.
209
+ width:max-content[] = width:intrinsic
210
+ width:max-content[] = width:-webkit-max-content
211
+ width:max-content[] = width:-moz-max-content
212
+ width:min-content[] = width:-webkit-min-content
213
+ width:min-content[] = width:-moz-min-content
214
+ width:available[] = width:-webkit-available
215
+ width:available[] = width:-moz-available
216
+ width:fit-content[] = width:-webkit-fit-content
217
+ width:fit-content[] = width:-moz-fit-content
218
+
219
+ max-width:max-content[] = max-width:intrinsic
220
+ max-width:max-content[] = max-width:-webkit-max-content
221
+ max-width:max-content[] = max-width:-moz-max-content
222
+ max-width:min-content[] = max-width:-webkit-min-content
223
+ max-width:min-content[] = max-width:-moz-min-content
224
+ max-width:available[] = max-width:-webkit-available
225
+ max-width:available[] = max-width:-moz-available
226
+ max-width:fit-content[] = max-width:-webkit-fit-content
227
+ max-width:fit-content[] = max-width:-moz-fit-content
228
+
229
+ min-width:max-content[] = min-width:intrinsic
230
+ min-width:max-content[] = min-width:-webkit-max-content
231
+ min-width:max-content[] = min-width:-moz-max-content
232
+ min-width:min-content[] = min-width:-webkit-min-content
233
+ min-width:min-content[] = min-width:-moz-min-content
234
+ min-width:available[] = min-width:-webkit-available
235
+ min-width:available[] = min-width:-moz-available
236
+ min-width:fit-content[] = min-width:-webkit-fit-content
237
+ min-width:fit-content[] = min-width:-moz-fit-content
238
+
239
+ ; Appearance (non-standard).
240
+ appearance:none[] = -webkit-appearance:none
241
+ appearance:none[] = -moz-appearance:none
242
+
243
+ position:sticky[] = position:-webkit-sticky
244
+
245
+
246
+ ;----------------------------------------------------------------
247
+ ; Function aliases.
248
+
249
+ [functions]
250
+
251
+ ; Calc.
252
+ ; calc[] = -webkit-calc÷
253
+
254
+
255
+ [functions.gradients]
256
+
257
+ ; Gradients.
258
+ ; linear-gradient[] = -webkit-linear-gradient
259
+ ; radial-gradient[] = -webkit-radial-gradient
260
+
261
+ ; Repeating gradients.
262
+ ; repeating-linear-gradient[] = -webkit-repeating-linear-gradient
263
+ ; repeating-radial-gradient[] = -webkit-repeating-radial-gradient
264
+
265
+
266
+ ;----------------------------------------------------------------
267
+ ; @rule aliases.
268
+
269
+ [at-rules]
270
+
271
+ ; Keyframes.
272
+ keyframes[] = -webkit-keyframes
273
+
274
+ ; Viewport.
275
+ viewport[] = -webkit-viewport
276
+ viewport[] = -ms-viewport
277
+ viewport[] = -o-viewport
includes/compiler/vendors/CSSJanus.php CHANGED
@@ -1,543 +1,543 @@
1
- <?php
2
- /**
3
- * PHP port of CSSJanus.
4
- * https://github.com/cssjanus/php-cssjanus
5
- *
6
- * Copyright 2008 Google Inc.
7
- * Copyright 2010 Roan Kattouw
8
- *
9
- * Licensed under the Apache License, Version 2.0 (the "License");
10
- * you may not use this file except in compliance with the License.
11
- * You may obtain a copy of the License at
12
- *
13
- * http://www.apache.org/licenses/LICENSE-2.0
14
- *
15
- * Unless required by applicable law or agreed to in writing, software
16
- * distributed under the License is distributed on an "AS IS" BASIS,
17
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
- * See the License for the specific language governing permissions and
19
- * limitations under the License.
20
- *
21
- * @file
22
- */
23
-
24
- /**
25
- * This is a PHP port of CSSJanus, a utility that transforms CSS style sheets
26
- * written for LTR to RTL.
27
- *
28
- * Original code: http://code.google.com/p/cssjanus/source/browse/trunk/cssjanus.py
29
- *
30
- * @author Lindsey Simon <elsigh@google.com>
31
- * @author Roan Kattouw
32
- */
33
- class CSSJanus {
34
- // Patterns defined as null are built dynamically by buildPatterns()
35
- private static $patterns = array(
36
- 'tmpToken' => '`TMP`',
37
- 'nonAscii' => '[\200-\377]',
38
- 'unicode' => '(?:(?:\\\\[0-9a-f]{1,6})(?:\r\n|\s)?)',
39
- 'num' => '(?:[0-9]*\.[0-9]+|[0-9]+)',
40
- 'unit' => '(?:em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|%)',
41
- 'body_selector' => 'body\s*{\s*',
42
- 'direction' => 'direction\s*:\s*',
43
- 'escape' => null,
44
- 'nmstart' => null,
45
- 'nmchar' => null,
46
- 'ident' => null,
47
- 'quantity' => null,
48
- 'possibly_negative_quantity' => null,
49
- 'color' => null,
50
- 'url_special_chars' => '[!#$%&*-~]',
51
- 'valid_after_uri_chars' => '[\'\"]?\s*',
52
- 'url_chars' => null,
53
- 'lookahead_not_open_brace' => null,
54
- 'lookahead_not_closing_paren' => null,
55
- 'lookahead_for_closing_paren' => null,
56
- 'lookahead_not_letter' => '(?![a-zA-Z])',
57
- 'lookbehind_not_letter' => '(?<![a-zA-Z])',
58
- 'chars_within_selector' => '[^\}]*?',
59
- 'noflip_annotation' => '\/\*\!?\s*@noflip\s*\*\/',
60
- 'noflip_single' => null,
61
- 'noflip_class' => null,
62
- 'comment' => '/\/\*[^*]*\*+([^\/*][^*]*\*+)*\//',
63
- 'direction_ltr' => null,
64
- 'direction_rtl' => null,
65
- 'left' => null,
66
- 'right' => null,
67
- 'left_in_url' => null,
68
- 'right_in_url' => null,
69
- 'ltr_in_url' => null,
70
- 'rtl_in_url' => null,
71
- 'cursor_east' => null,
72
- 'cursor_west' => null,
73
- 'four_notation_quantity' => null,
74
- 'four_notation_color' => null,
75
- 'border_radius' => null,
76
- 'box_shadow' => null,
77
- 'text_shadow1' => null,
78
- 'text_shadow2' => null,
79
- 'bg_horizontal_percentage' => null,
80
- 'bg_horizontal_percentage_x' => null,
81
- 'suffix' => '(\s*(?:!important\s*)?[;}])'
82
- );
83
-
84
- /**
85
- * Build patterns we can't define above because they depend on other patterns.
86
- */
87
- private static function buildPatterns() {
88
- if (!is_null(self::$patterns['escape'])) {
89
- // Patterns have already been built
90
- return;
91
- }
92
-
93
- // @codingStandardsIgnoreStart Generic.Files.LineLength.TooLong
94
- $patterns =& self::$patterns;
95
- $patterns['escape'] = "(?:{$patterns['unicode']}|\\\\[^\\r\\n\\f0-9a-f])";
96
- $patterns['nmstart'] = "(?:[_a-z]|{$patterns['nonAscii']}|{$patterns['escape']})";
97
- $patterns['nmchar'] = "(?:[_a-z0-9-]|{$patterns['nonAscii']}|{$patterns['escape']})";
98
- $patterns['ident'] = "-?{$patterns['nmstart']}{$patterns['nmchar']}*";
99
- $patterns['quantity'] = "{$patterns['num']}(?:\s*{$patterns['unit']}|{$patterns['ident']})?";
100
- $patterns['possibly_negative_quantity'] = "((?:-?{$patterns['quantity']})|(?:inherit|auto))";
101
- $patterns['color'] = "(#?{$patterns['nmchar']}+|(?:rgba?|hsla?)\([ \d.,%-]+\))";
102
- // Use "*+" instead of "*?" to avoid reaching the backtracking limit.
103
- // <https://github.com/cssjanus/php-cssjanus/issues/14>, <https://phabricator.wikimedia.org/T215746#4944830>.
104
- $patterns['url_chars'] = "(?:{$patterns['url_special_chars']}|{$patterns['nonAscii']}|{$patterns['escape']})*+";
105
- $patterns['lookahead_not_open_brace'] = "(?!({$patterns['nmchar']}|\\r?\\n|\s|#|\:|\.|\,|\+|>|\(|\)|\[|\]|=|\*=|~=|\^=|'[^']*'])*+{)";
106
- $patterns['lookahead_not_closing_paren'] = "(?!{$patterns['url_chars']}{$patterns['valid_after_uri_chars']}\))";
107
- $patterns['lookahead_for_closing_paren'] = "(?={$patterns['url_chars']}{$patterns['valid_after_uri_chars']}\))";
108
- $patterns['noflip_single'] = "/({$patterns['noflip_annotation']}{$patterns['lookahead_not_open_brace']}[^;}]+;?)/i";
109
- $patterns['noflip_class'] = "/({$patterns['noflip_annotation']}{$patterns['chars_within_selector']}})/i";
110
- $patterns['direction_ltr'] = "/({$patterns['direction']})ltr/i";
111
- $patterns['direction_rtl'] = "/({$patterns['direction']})rtl/i";
112
- $patterns['left'] = "/{$patterns['lookbehind_not_letter']}(left){$patterns['lookahead_not_letter']}{$patterns['lookahead_not_closing_paren']}{$patterns['lookahead_not_open_brace']}/i";
113
- $patterns['right'] = "/{$patterns['lookbehind_not_letter']}(right){$patterns['lookahead_not_letter']}{$patterns['lookahead_not_closing_paren']}{$patterns['lookahead_not_open_brace']}/i";
114
- $patterns['left_in_url'] = "/{$patterns['lookbehind_not_letter']}(left){$patterns['lookahead_for_closing_paren']}/i";
115
- $patterns['right_in_url'] = "/{$patterns['lookbehind_not_letter']}(right){$patterns['lookahead_for_closing_paren']}/i";
116
- $patterns['ltr_in_url'] = "/{$patterns['lookbehind_not_letter']}(ltr){$patterns['lookahead_for_closing_paren']}/i";
117
- $patterns['rtl_in_url'] = "/{$patterns['lookbehind_not_letter']}(rtl){$patterns['lookahead_for_closing_paren']}/i";
118
- $patterns['cursor_east'] = "/{$patterns['lookbehind_not_letter']}([ns]?)e-resize/";
119
- $patterns['cursor_west'] = "/{$patterns['lookbehind_not_letter']}([ns]?)w-resize/";
120
- $patterns['four_notation_quantity_props'] = "((?:margin|padding|border-width)\s*:\s*)";
121
- $patterns['four_notation_quantity'] = "/{$patterns['four_notation_quantity_props']}{$patterns['possibly_negative_quantity']}(\s+){$patterns['possibly_negative_quantity']}(\s+){$patterns['possibly_negative_quantity']}(\s+){$patterns['possibly_negative_quantity']}{$patterns['suffix']}/i";
122
- $patterns['four_notation_color'] = "/((?:-color|border-style)\s*:\s*){$patterns['color']}(\s+){$patterns['color']}(\s+){$patterns['color']}(\s+){$patterns['color']}{$patterns['suffix']}/i";
123
- // border-radius: <length or percentage>{1,4} [optional: / <length or percentage>{1,4} ]
124
- $patterns['border_radius'] = '/(border-radius\s*:\s*)' . $patterns['possibly_negative_quantity']
125
- . '(?:(?:\s+' . $patterns['possibly_negative_quantity'] . ')(?:\s+' . $patterns['possibly_negative_quantity'] . ')?(?:\s+' . $patterns['possibly_negative_quantity'] . ')?)?'
126
- . '(?:(?:(?:\s*\/\s*)' . $patterns['possibly_negative_quantity'] . ')(?:\s+' . $patterns['possibly_negative_quantity'] . ')?(?:\s+' . $patterns['possibly_negative_quantity'] . ')?(?:\s+' . $patterns['possibly_negative_quantity'] . ')?)?' . $patterns['suffix']
127
- . '/i';
128
- $patterns['box_shadow'] = "/(box-shadow\s*:\s*(?:inset\s*)?){$patterns['possibly_negative_quantity']}/i";
129
- $patterns['text_shadow1'] = "/(text-shadow\s*:\s*){$patterns['possibly_negative_quantity']}(\s*){$patterns['color']}/i";
130
- $patterns['text_shadow2'] = "/(text-shadow\s*:\s*){$patterns['color']}(\s*){$patterns['possibly_negative_quantity']}/i";
131
- $patterns['text_shadow3'] = "/(text-shadow\s*:\s*){$patterns['possibly_negative_quantity']}/i";
132
- $patterns['bg_horizontal_percentage'] = "/(background(?:-position)?\s*:\s*(?:[^:;}\s]+\s+)*?)({$patterns['quantity']})/i";
133
- $patterns['bg_horizontal_percentage_x'] = "/(background-position-x\s*:\s*)(-?{$patterns['num']}%)/i";
134
- $patterns['translate_x'] = "/(transform\s*:[^;}]*)(translateX\s*\(\s*){$patterns['possibly_negative_quantity']}(\s*\))/i";
135
- $patterns['translate'] = "/(transform\s*:[^;}]*)(translate\s*\(\s*){$patterns['possibly_negative_quantity']}((?:\s*,\s*{$patterns['possibly_negative_quantity']}){0,2}\s*\))/i";
136
- // @codingStandardsIgnoreEnd
137
- }
138
-
139
- /**
140
- * Transform an LTR stylesheet to RTL
141
- * @param string $css Stylesheet to transform
142
- * @param array|bool $options Options array or value of transformDirInUrl option (back-compat)
143
- * @param bool $options['transformDirInUrl'] Transform directions in URLs (ltr/rtl). Default: false.
144
- * @param bool $options['transformEdgeInUrl'] Transform edges in URLs (left/right). Default: false.
145
- * @param bool $transformEdgeInUrl [optional] For back-compat
146
- * @return string Transformed stylesheet
147
- */
148
- public static function transform($css, $options = array(), $transformEdgeInUrl = false) {
149
- if (!is_array($options)) {
150
- $options = array(
151
- 'transformDirInUrl' => (bool)$options,
152
- 'transformEdgeInUrl' => (bool)$transformEdgeInUrl,
153
- );
154
- }
155
-
156
- // Defaults
157
- $options += array(
158
- 'transformDirInUrl' => false,
159
- 'transformEdgeInUrl' => false,
160
- );
161
-
162
- // We wrap tokens in ` , not ~ like the original implementation does.
163
- // This was done because ` is not a legal character in CSS and can only
164
- // occur in URLs, where we escape it to %60 before inserting our tokens.
165
- $css = str_replace('`', '%60', $css);
166
-
167
- self::buildPatterns();
168
-
169
- // Tokenize single line rules with /* @noflip */
170
- $noFlipSingle = new CSSJanusTokenizer(self::$patterns['noflip_single'], '`NOFLIP_SINGLE`');
171
- $css = $noFlipSingle->tokenize($css);
172
-
173
- // Tokenize class rules with /* @noflip */
174
- $noFlipClass = new CSSJanusTokenizer(self::$patterns['noflip_class'], '`NOFLIP_CLASS`');
175
- $css = $noFlipClass->tokenize($css);
176
-
177
- // Tokenize comments
178
- $comments = new CSSJanusTokenizer(self::$patterns['comment'], '`C`');
179
- $css = $comments->tokenize($css);
180
-
181
- // LTR->RTL fixes start here
182
- $css = self::fixDirection($css);
183
- if ($options['transformDirInUrl']) {
184
- $css = self::fixLtrRtlInURL($css);
185
- }
186
-
187
- if ($options['transformEdgeInUrl']) {
188
- $css = self::fixLeftRightInURL($css);
189
- }
190
- $css = self::fixLeftAndRight($css);
191
- $css = self::fixCursorProperties($css);
192
- $css = self::fixFourPartNotation($css);
193
- $css = self::fixBorderRadius($css);
194
- $css = self::fixBackgroundPosition($css);
195
- $css = self::fixShadows($css);
196
- $css = self::fixTranslate($css);
197
-
198
- // Detokenize stuff we tokenized before
199
- $css = $comments->detokenize($css);
200
- $css = $noFlipClass->detokenize($css);
201
- $css = $noFlipSingle->detokenize($css);
202
-
203
- return $css;
204
- }
205
-
206
- /**
207
- * Replace direction: ltr; with direction: rtl; and vice versa.
208
- *
209
- * The original implementation only does this inside body selectors
210
- * and misses "body\n{\ndirection:ltr;\n}". This function does not have
211
- * these problems.
212
- *
213
- * See https://code.google.com/p/cssjanus/issues/detail?id=15
214
- *
215
- * @param $css string
216
- * @return string
217
- */
218
- private static function fixDirection($css) {
219
- $css = preg_replace(
220
- self::$patterns['direction_ltr'],
221
- '$1' . self::$patterns['tmpToken'],
222
- $css
223
- );
224
- $css = preg_replace(self::$patterns['direction_rtl'], '$1ltr', $css);
225
- $css = str_replace(self::$patterns['tmpToken'], 'rtl', $css);
226
-
227
- return $css;
228
- }
229
-
230
- /**
231
- * Replace 'ltr' with 'rtl' and vice versa in background URLs
232
- * @param $css string
233
- * @return string
234
- */
235
- private static function fixLtrRtlInURL($css) {
236
- $css = preg_replace(self::$patterns['ltr_in_url'], self::$patterns['tmpToken'], $css);
237
- $css = preg_replace(self::$patterns['rtl_in_url'], 'ltr', $css);
238
- $css = str_replace(self::$patterns['tmpToken'], 'rtl', $css);
239
-
240
- return $css;
241
- }
242
-
243
- /**
244
- * Replace 'left' with 'right' and vice versa in background URLs
245
- * @param $css string
246
- * @return string
247
- */
248
- private static function fixLeftRightInURL($css) {
249
- $css = preg_replace(self::$patterns['left_in_url'], self::$patterns['tmpToken'], $css);
250
- $css = preg_replace(self::$patterns['right_in_url'], 'left', $css);
251
- $css = str_replace(self::$patterns['tmpToken'], 'right', $css);
252
-
253
- return $css;
254
- }
255
-
256
- /**
257
- * Flip rules like left: , padding-right: , etc.
258
- * @param $css string
259
- * @return string
260
- */
261
- private static function fixLeftAndRight($css) {
262
- $css = preg_replace(self::$patterns['left'], self::$patterns['tmpToken'], $css);
263
- $css = preg_replace(self::$patterns['right'], 'left', $css);
264
- $css = str_replace(self::$patterns['tmpToken'], 'right', $css);
265
-
266
- return $css;
267
- }
268
-
269
- /**
270
- * Flip East and West in rules like cursor: nw-resize;
271
- * @param $css string
272
- * @return string
273
- */
274
- private static function fixCursorProperties($css) {
275
- $css = preg_replace(
276
- self::$patterns['cursor_east'],
277
- '$1' . self::$patterns['tmpToken'],
278
- $css
279
- );
280
- $css = preg_replace(self::$patterns['cursor_west'], '$1e-resize', $css);
281
- $css = str_replace(self::$patterns['tmpToken'], 'w-resize', $css);
282
-
283
- return $css;
284
- }
285
-
286
- /**
287
- * Swap the second and fourth parts in four-part notation rules like
288
- * padding: 1px 2px 3px 4px;
289
- *
290
- * Unlike the original implementation, this function doesn't suffer from
291
- * the bug where whitespace is not preserved when flipping four-part rules
292
- * and four-part color rules with multiple whitespace characters between
293
- * colors are not recognized.
294
- * See https://code.google.com/p/cssjanus/issues/detail?id=16
295
- * @param $css string
296
- * @return string
297
- */
298
- private static function fixFourPartNotation($css) {
299
- $css = preg_replace(self::$patterns['four_notation_quantity'], '$1$2$3$8$5$6$7$4$9', $css);
300
- $css = preg_replace(self::$patterns['four_notation_color'], '$1$2$3$8$5$6$7$4$9', $css);
301
- return $css;
302
- }
303
-
304
- /**
305
- * Swaps appropriate corners in border-radius values.
306
- *
307
- * @param $css string
308
- * @return string
309
- */
310
- private static function fixBorderRadius($css) {
311
- return preg_replace_callback(
312
- self::$patterns['border_radius'],
313
- array('self', 'calculateBorderRadius'),
314
- $css
315
- );
316
- }
317
-
318
- /**
319
- * Callback for fixBorderRadius()
320
- * @param $matches array
321
- * @return string
322
- */
323
- private static function calculateBorderRadius($matches) {
324
- $pre = $matches[1];
325
- $firstGroup = array_filter(array_slice($matches, 2, 4), function ($match) {
326
- return $match !== '';
327
- });
328
- $secondGroup = array_filter(array_slice($matches, 6, 4), function ($match) {
329
- return $match !== '';
330
- });
331
- $post = $matches[10] ?: '';
332
-
333
- if ($secondGroup) {
334
- $values = self::flipBorderRadiusValues($firstGroup)
335
- . ' / ' . self::flipBorderRadiusValues($secondGroup);
336
- } else {
337
- $values = self::flipBorderRadiusValues($firstGroup);
338
- }
339
-
340
- return $pre . $values . $post;
341
- }
342
-
343
- /**
344
- * Callback for fixBorderRadius()
345
- * @param array $values Matched values
346
- * @return string Flipped values
347
- */
348
- private static function flipBorderRadiusValues($values) {
349
- switch (count($values)) {
350
- case 4:
351
- $values = array($values[1], $values[0], $values[3], $values[2]);
352
- break;
353
- case 3:
354
- $values = array($values[1], $values[0], $values[1], $values[2]);
355
- break;
356
- case 2:
357
- $values = array($values[1], $values[0]);
358
- break;
359
- case 1:
360
- $values = array($values[0]);
361
- break;
362
- }
363
- return implode(' ', $values);
364
- }
365
-
366
- /**
367
- * Flips the sign of a CSS value, possibly with a unit.
368
- *
369
- * We can't just negate the value with unary minus due to the units.
370
- *
371
- * @param $cssValue string
372
- * @return string
373
- */
374
- private static function flipSign($cssValue) {
375
- // Don't mangle zeroes
376
- if (floatval($cssValue) === 0.0) {
377
- return $cssValue;
378
- } elseif ($cssValue[0] === '-') {
379
- return substr($cssValue, 1);
380
- } else {
381
- return "-" . $cssValue;
382
- }
383
- }
384
-
385
- /**
386
- * Negates horizontal offset in box-shadow and text-shadow rules.
387
- *
388
- * @param $css string
389
- * @return string
390
- */
391
- private static function fixShadows($css) {
392
- $css = preg_replace_callback(self::$patterns['box_shadow'], function ($matches) {
393
- return $matches[1] . self::flipSign($matches[2]);
394
- }, $css);
395
-
396
- $css = preg_replace_callback(self::$patterns['text_shadow1'], function ($matches) {
397
- return $matches[1] . $matches[2] . $matches[3] . self::flipSign($matches[4]);
398
- }, $css);
399
-
400
- $css = preg_replace_callback(self::$patterns['text_shadow2'], function ($matches) {
401
- return $matches[1] . $matches[2] . $matches[3] . self::flipSign($matches[4]);
402
- }, $css);
403
-
404
- $css = preg_replace_callback(self::$patterns['text_shadow3'], function ($matches) {
405
- return $matches[1] . self::flipSign($matches[2]);
406
- }, $css);
407
-
408
- return $css;
409
- }
410
-
411
- /**
412
- * Negates horizontal offset in tranform: translate()
413
- *
414
- * @param $css string
415
- * @return string
416
- */
417
- private static function fixTranslate($css) {
418
- $css = preg_replace_callback(self::$patterns['translate'], function ($matches) {
419
- return $matches[1] . $matches[2] . self::flipSign($matches[3]) . $matches[4];
420
- }, $css);
421
-
422
- $css = preg_replace_callback(self::$patterns['translate_x'], function ($matches) {
423
- return $matches[1] . $matches[2] . self::flipSign($matches[3]) . $matches[4];
424
- }, $css);
425
-
426
- return $css;
427
- }
428
-
429
- /**
430
- * Flip horizontal background percentages.
431
- * @param $css string
432
- * @return string
433
- */
434
- private static function fixBackgroundPosition($css) {
435
- $replaced = preg_replace_callback(
436
- self::$patterns['bg_horizontal_percentage'],
437
- array('self', 'calculateNewBackgroundPosition'),
438
- $css
439
- );
440
- if ($replaced !== null) {
441
- // preg_replace_callback() sometimes returns null
442
- $css = $replaced;
443
- }
444
- $replaced = preg_replace_callback(
445
- self::$patterns['bg_horizontal_percentage_x'],
446
- array('self', 'calculateNewBackgroundPosition'),
447
- $css
448
- );
449
- if ($replaced !== null) {
450
- $css = $replaced;
451
- }
452
-
453
- return $css;
454
- }
455
-
456
- /**
457
- * Callback for fixBackgroundPosition()
458
- * @param $matches array
459
- * @return string
460
- */
461
- private static function calculateNewBackgroundPosition($matches) {
462
- $value = $matches[2];
463
- if (substr($value, -1) === '%') {
464
- $idx = strpos($value, '.');
465
- if ($idx !== false) {
466
- $len = strlen($value) - $idx - 2;
467
- $value = number_format(100 - (float)$value, $len) . '%';
468
- } else {
469
- $value = (100 - (float)$value) . '%';
470
- }
471
- }
472
- return $matches[1] . $value;
473
- }
474
- }
475
-
476
- /**
477
- * Utility class used by CSSJanus that tokenizes and untokenizes things we want
478
- * to protect from being janused.
479
- * @author Roan Kattouw
480
- */
481
- class CSSJanusTokenizer {
482
- private $regex;
483
- private $token;
484
- private $originals;
485
-
486
- /**
487
- * Constructor
488
- * @param string $regex Regular expression whose matches to replace by a token.
489
- * @param string $token Token
490
- */
491
- public function __construct($regex, $token) {
492
- $this->regex = $regex;
493
- $this->token = $token;
494
- $this->originals = array();
495
- }
496
-
497
- /**
498
- * Replace all occurrences of $regex in $str with a token and remember
499
- * the original strings.
500
- * @param string $str to tokenize
501
- * @return string Tokenized string
502
- */
503
- public function tokenize($str) {
504
- return preg_replace_callback($this->regex, array($this, 'tokenizeCallback'), $str);
505
- }
506
-
507
- /**
508
- * @param $matches array
509
- * @return string
510
- */
511
- private function tokenizeCallback($matches) {
512
- $this->originals[] = $matches[0];
513
- return $this->token;
514
- }
515
-
516
- /**
517
- * Replace tokens with their originals. If multiple strings were tokenized, it's important they be
518
- * detokenized in exactly the SAME ORDER.
519
- * @param string $str previously run through tokenize()
520
- * @return string Original string
521
- */
522
- public function detokenize($str) {
523
- // PHP has no function to replace only the first occurrence or to
524
- // replace occurrences of the same string with different values,
525
- // so we use preg_replace_callback() even though we don't really need a regex
526
- return preg_replace_callback(
527
- '/' . preg_quote($this->token, '/') . '/',
528
- array($this, 'detokenizeCallback'),
529
- $str
530
- );
531
- }
532
-
533
- /**
534
- * @param $matches
535
- * @return mixed
536
- */
537
- private function detokenizeCallback($matches) {
538
- $retval = current($this->originals);
539
- next($this->originals);
540
-
541
- return $retval;
542
- }
543
- }
1
+ <?php
2
+ /**
3
+ * PHP port of CSSJanus.
4
+ * https://github.com/cssjanus/php-cssjanus
5
+ *
6
+ * Copyright 2008 Google Inc.
7
+ * Copyright 2010 Roan Kattouw
8
+ *
9
+ * Licensed under the Apache License, Version 2.0 (the "License");
10
+ * you may not use this file except in compliance with the License.
11
+ * You may obtain a copy of the License at
12
+ *
13
+ * http://www.apache.org/licenses/LICENSE-2.0
14
+ *
15
+ * Unless required by applicable law or agreed to in writing, software
16
+ * distributed under the License is distributed on an "AS IS" BASIS,
17
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ * See the License for the specific language governing permissions and
19
+ * limitations under the License.
20
+ *
21
+ * @file
22
+ */
23
+
24
+ /**
25
+ * This is a PHP port of CSSJanus, a utility that transforms CSS style sheets
26
+ * written for LTR to RTL.
27
+ *
28
+ * Original code: http://code.google.com/p/cssjanus/source/browse/trunk/cssjanus.py
29
+ *
30
+ * @author Lindsey Simon <elsigh@google.com>
31
+ * @author Roan Kattouw
32
+ */
33
+ class CSSJanus {
34
+ // Patterns defined as null are built dynamically by buildPatterns()
35
+ private static $patterns = array(
36
+ 'tmpToken' => '`TMP`',
37
+ 'nonAscii' => '[\200-\377]',
38
+ 'unicode' => '(?:(?:\\\\[0-9a-f]{1,6})(?:\r\n|\s)?)',
39
+ 'num' => '(?:[0-9]*\.[0-9]+|[0-9]+)',
40
+ 'unit' => '(?:em|ex|px|cm|mm|in|pt|pc|deg|rad|grad|ms|s|hz|khz|%)',
41
+ 'body_selector' => 'body\s*{\s*',
42
+ 'direction' => 'direction\s*:\s*',
43
+ 'escape' => null,
44
+ 'nmstart' => null,
45
+ 'nmchar' => null,
46
+ 'ident' => null,
47
+ 'quantity' => null,
48
+ 'possibly_negative_quantity' => null,
49
+ 'color' => null,
50
+ 'url_special_chars' => '[!#$%&*-~]',
51
+ 'valid_after_uri_chars' => '[\'\"]?\s*',
52
+ 'url_chars' => null,
53
+ 'lookahead_not_open_brace' => null,
54
+ 'lookahead_not_closing_paren' => null,
55
+ 'lookahead_for_closing_paren' => null,
56
+ 'lookahead_not_letter' => '(?![a-zA-Z])',
57
+ 'lookbehind_not_letter' => '(?<![a-zA-Z])',
58
+ 'chars_within_selector' => '[^\}]*?',
59
+ 'noflip_annotation' => '\/\*\!?\s*@noflip\s*\*\/',
60
+ 'noflip_single' => null,
61
+ 'noflip_class' => null,
62
+ 'comment' => '/\/\*[^*]*\*+([^\/*][^*]*\*+)*\//',
63
+ 'direction_ltr' => null,
64
+ 'direction_rtl' => null,
65
+ 'left' => null,
66
+ 'right' => null,
67
+ 'left_in_url' => null,
68
+ 'right_in_url' => null,
69
+ 'ltr_in_url' => null,
70
+ 'rtl_in_url' => null,
71
+ 'cursor_east' => null,
72
+ 'cursor_west' => null,
73
+ 'four_notation_quantity' => null,
74
+ 'four_notation_color' => null,
75
+ 'border_radius' => null,
76
+ 'box_shadow' => null,
77
+ 'text_shadow1' => null,
78
+ 'text_shadow2' => null,
79
+ 'bg_horizontal_percentage' => null,
80
+ 'bg_horizontal_percentage_x' => null,
81
+ 'suffix' => '(\s*(?:!important\s*)?[;}])'
82
+ );
83
+
84
+ /**
85
+ * Build patterns we can't define above because they depend on other patterns.
86
+ */
87
+ private static function buildPatterns() {
88
+ if (!is_null(self::$patterns['escape'])) {
89
+ // Patterns have already been built
90
+ return;
91
+ }
92
+
93
+ // @codingStandardsIgnoreStart Generic.Files.LineLength.TooLong
94
+ $patterns =& self::$patterns;
95
+ $patterns['escape'] = "(?:{$patterns['unicode']}|\\\\[^\\r\\n\\f0-9a-f])";
96
+ $patterns['nmstart'] = "(?:[_a-z]|{$patterns['nonAscii']}|{$patterns['escape']})";
97
+ $patterns['nmchar'] = "(?:[_a-z0-9-]|{$patterns['nonAscii']}|{$patterns['escape']})";
98
+ $patterns['ident'] = "-?{$patterns['nmstart']}{$patterns['nmchar']}*";
99
+ $patterns['quantity'] = "{$patterns['num']}(?:\s*{$patterns['unit']}|{$patterns['ident']})?";
100
+ $patterns['possibly_negative_quantity'] = "((?:-?{$patterns['quantity']})|(?:inherit|auto))";
101
+ $patterns['color'] = "(#?{$patterns['nmchar']}+|(?:rgba?|hsla?)\([ \d.,%-]+\))";
102
+ // Use "*+" instead of "*?" to avoid reaching the backtracking limit.
103
+ // <https://github.com/cssjanus/php-cssjanus/issues/14>, <https://phabricator.wikimedia.org/T215746#4944830>.
104
+ $patterns['url_chars'] = "(?:{$patterns['url_special_chars']}|{$patterns['nonAscii']}|{$patterns['escape']})*+";
105
+ $patterns['lookahead_not_open_brace'] = "(?!({$patterns['nmchar']}|\\r?\\n|\s|#|\:|\.|\,|\+|>|\(|\)|\[|\]|=|\*=|~=|\^=|'[^']*'])*+{)";
106
+ $patterns['lookahead_not_closing_paren'] = "(?!{$patterns['url_chars']}{$patterns['valid_after_uri_chars']}\))";
107
+ $patterns['lookahead_for_closing_paren'] = "(?={$patterns['url_chars']}{$patterns['valid_after_uri_chars']}\))";
108
+ $patterns['noflip_single'] = "/({$patterns['noflip_annotation']}{$patterns['lookahead_not_open_brace']}[^;}]+;?)/i";
109
+ $patterns['noflip_class'] = "/({$patterns['noflip_annotation']}{$patterns['chars_within_selector']}})/i";
110
+ $patterns['direction_ltr'] = "/({$patterns['direction']})ltr/i";
111
+ $patterns['direction_rtl'] = "/({$patterns['direction']})rtl/i";
112
+ $patterns['left'] = "/{$patterns['lookbehind_not_letter']}(left){$patterns['lookahead_not_letter']}{$patterns['lookahead_not_closing_paren']}{$patterns['lookahead_not_open_brace']}/i";
113
+ $patterns['right'] = "/{$patterns['lookbehind_not_letter']}(right){$patterns['lookahead_not_letter']}{$patterns['lookahead_not_closing_paren']}{$patterns['lookahead_not_open_brace']}/i";
114
+ $patterns['left_in_url'] = "/{$patterns['lookbehind_not_letter']}(left){$patterns['lookahead_for_closing_paren']}/i";
115
+ $patterns['right_in_url'] = "/{$patterns['lookbehind_not_letter']}(right){$patterns['lookahead_for_closing_paren']}/i";
116
+ $patterns['ltr_in_url'] = "/{$patterns['lookbehind_not_letter']}(ltr){$patterns['lookahead_for_closing_paren']}/i";
117
+ $patterns['rtl_in_url'] = "/{$patterns['lookbehind_not_letter']}(rtl){$patterns['lookahead_for_closing_paren']}/i";
118
+ $patterns['cursor_east'] = "/{$patterns['lookbehind_not_letter']}([ns]?)e-resize/";
119
+ $patterns['cursor_west'] = "/{$patterns['lookbehind_not_letter']}([ns]?)w-resize/";
120
+ $patterns['four_notation_quantity_props'] = "((?:margin|padding|border-width)\s*:\s*)";
121
+ $patterns['four_notation_quantity'] = "/{$patterns['four_notation_quantity_props']}{$patterns['possibly_negative_quantity']}(\s+){$patterns['possibly_negative_quantity']}(\s+){$patterns['possibly_negative_quantity']}(\s+){$patterns['possibly_negative_quantity']}{$patterns['suffix']}/i";
122
+ $patterns['four_notation_color'] = "/((?:-color|border-style)\s*:\s*){$patterns['color']}(\s+){$patterns['color']}(\s+){$patterns['color']}(\s+){$patterns['color']}{$patterns['suffix']}/i";
123
+ // border-radius: <length or percentage>{1,4} [optional: / <length or percentage>{1,4} ]
124
+ $patterns['border_radius'] = '/(border-radius\s*:\s*)' . $patterns['possibly_negative_quantity']
125
+ . '(?:(?:\s+' . $patterns['possibly_negative_quantity'] . ')(?:\s+' . $patterns['possibly_negative_quantity'] . ')?(?:\s+' . $patterns['possibly_negative_quantity'] . ')?)?'
126
+ . '(?:(?:(?:\s*\/\s*)' . $patterns['possibly_negative_quantity'] . ')(?:\s+' . $patterns['possibly_negative_quantity'] . ')?(?:\s+' . $patterns['possibly_negative_quantity'] . ')?(?:\s+' . $patterns['possibly_negative_quantity'] . ')?)?' . $patterns['suffix']
127
+ . '/i';
128
+ $patterns['box_shadow'] = "/(box-shadow\s*:\s*(?:inset\s*)?){$patterns['possibly_negative_quantity']}/i";
129
+ $patterns['text_shadow1'] = "/(text-shadow\s*:\s*){$patterns['possibly_negative_quantity']}(\s*){$patterns['color']}/i";
130
+ $patterns['text_shadow2'] = "/(text-shadow\s*:\s*){$patterns['color']}(\s*){$patterns['possibly_negative_quantity']}/i";
131
+ $patterns['text_shadow3'] = "/(text-shadow\s*:\s*){$patterns['possibly_negative_quantity']}/i";
132
+ $patterns['bg_horizontal_percentage'] = "/(background(?:-position)?\s*:\s*(?:[^:;}\s]+\s+)*?)({$patterns['quantity']})/i";
133
+ $patterns['bg_horizontal_percentage_x'] = "/(background-position-x\s*:\s*)(-?{$patterns['num']}%)/i";
134
+ $patterns['translate_x'] = "/(transform\s*:[^;}]*)(translateX\s*\(\s*){$patterns['possibly_negative_quantity']}(\s*\))/i";
135
+ $patterns['translate'] = "/(transform\s*:[^;}]*)(translate\s*\(\s*){$patterns['possibly_negative_quantity']}((?:\s*,\s*{$patterns['possibly_negative_quantity']}){0,2}\s*\))/i";
136
+ // @codingStandardsIgnoreEnd
137
+ }
138
+
139
+ /**
140
+ * Transform an LTR stylesheet to RTL
141
+ * @param string $css Stylesheet to transform
142
+ * @param array|bool $options Options array or value of transformDirInUrl option (back-compat)
143
+ * @param bool $options['transformDirInUrl'] Transform directions in URLs (ltr/rtl). Default: false.
144
+ * @param bool $options['transformEdgeInUrl'] Transform edges in URLs (left/right). Default: false.
145
+ * @param bool $transformEdgeInUrl [optional] For back-compat
146
+ * @return string Transformed stylesheet
147
+ */
148
+ public static function transform($css, $options = array(), $transformEdgeInUrl = false) {
149
+ if (!is_array($options)) {
150
+ $options = array(
151
+ 'transformDirInUrl' => (bool)$options,
152
+ 'transformEdgeInUrl' => (bool)$transformEdgeInUrl,
153
+ );
154
+ }
155
+
156
+ // Defaults
157
+ $options += array(
158
+ 'transformDirInUrl' => false,
159
+ 'transformEdgeInUrl' => false,
160
+ );
161
+
162
+ // We wrap tokens in ` , not ~ like the original implementation does.
163
+ // This was done because ` is not a legal character in CSS and can only
164
+ // occur in URLs, where we escape it to %60 before inserting our tokens.
165
+ $css = str_replace('`', '%60', $css);
166
+
167
+ self::buildPatterns();
168
+
169
+ // Tokenize single line rules with /* @noflip */
170
+ $noFlipSingle = new CSSJanusTokenizer(self::$patterns['noflip_single'], '`NOFLIP_SINGLE`');
171
+ $css = $noFlipSingle->tokenize($css);
172
+
173
+ // Tokenize class rules with /* @noflip */
174
+ $noFlipClass = new CSSJanusTokenizer(self::$patterns['noflip_class'], '`NOFLIP_CLASS`');
175
+ $css = $noFlipClass->tokenize($css);
176
+
177
+ // Tokenize comments
178
+ $comments = new CSSJanusTokenizer(self::$patterns['comment'], '`C`');
179
+ $css = $comments->tokenize($css);
180
+
181
+ // LTR->RTL fixes start here
182
+ $css = self::fixDirection($css);
183
+ if ($options['transformDirInUrl']) {
184
+ $css = self::fixLtrRtlInURL($css);
185
+ }
186
+
187
+ if ($options['transformEdgeInUrl']) {
188
+ $css = self::fixLeftRightInURL($css);
189
+ }
190
+ $css = self::fixLeftAndRight($css);
191
+ $css = self::fixCursorProperties($css);
192
+ $css = self::fixFourPartNotation($css);
193
+ $css = self::fixBorderRadius($css);
194
+ $css = self::fixBackgroundPosition($css);
195
+ $css = self::fixShadows($css);
196
+ $css = self::fixTranslate($css);
197
+
198
+ // Detokenize stuff we tokenized before
199
+ $css = $comments->detokenize($css);
200
+ $css = $noFlipClass->detokenize($css);
201
+ $css = $noFlipSingle->detokenize($css);
202
+
203
+ return $css;
204
+ }
205
+
206
+ /**
207
+ * Replace direction: ltr; with direction: rtl; and vice versa.
208
+ *
209
+ * The original implementation only does this inside body selectors
210
+ * and misses "body\n{\ndirection:ltr;\n}". This function does not have
211
+ * these problems.
212
+ *
213
+ * See https://code.google.com/p/cssjanus/issues/detail?id=15
214
+ *
215
+ * @param $css string
216
+ * @return string
217
+ */
218
+ private static function fixDirection($css) {
219
+ $css = preg_replace(
220
+ self::$patterns['direction_ltr'],
221
+ '$1' . self::$patterns['tmpToken'],
222
+ $css
223
+ );
224
+ $css = preg_replace(self::$patterns['direction_rtl'], '$1ltr', $css);
225
+ $css = str_replace(self::$patterns['tmpToken'], 'rtl', $css);
226
+
227
+ return $css;
228
+ }
229
+
230
+ /**
231
+ * Replace 'ltr' with 'rtl' and vice versa in background URLs
232
+ * @param $css string
233
+ * @return string
234
+ */
235
+ private static function fixLtrRtlInURL($css) {
236
+ $css = preg_replace(self::$patterns['ltr_in_url'], self::$patterns['tmpToken'], $css);
237
+ $css = preg_replace(self::$patterns['rtl_in_url'], 'ltr', $css);
238
+ $css = str_replace(self::$patterns['tmpToken'], 'rtl', $css);
239
+
240
+ return $css;
241
+ }
242
+
243
+ /**
244
+ * Replace 'left' with 'right' and vice versa in background URLs
245
+ * @param $css string
246
+ * @return string
247
+ */
248
+ private static function fixLeftRightInURL($css) {
249
+ $css = preg_replace(self::$patterns['left_in_url'], self::$patterns['tmpToken'], $css);
250
+ $css = preg_replace(self::$patterns['right_in_url'], 'left', $css);
251
+ $css = str_replace(self::$patterns['tmpToken'], 'right', $css);
252
+
253
+ return $css;
254
+ }
255
+
256
+ /**
257
+ * Flip rules like left: , padding-right: , etc.
258
+ * @param $css string
259
+ * @return string
260
+ */
261
+ private static function fixLeftAndRight($css) {
262
+ $css = preg_replace(self::$patterns['left'], self::$patterns['tmpToken'], $css);
263
+ $css = preg_replace(self::$patterns['right'], 'left', $css);
264
+ $css = str_replace(self::$patterns['tmpToken'], 'right', $css);
265
+
266
+ return $css;
267
+ }
268
+
269
+ /**
270
+ * Flip East and West in rules like cursor: nw-resize;
271
+ * @param $css string
272
+ * @return string
273
+ */
274
+ private static function fixCursorProperties($css) {
275
+ $css = preg_replace(
276
+ self::$patterns['cursor_east'],
277
+ '$1' . self::$patterns['tmpToken'],
278
+ $css
279
+ );
280
+ $css = preg_replace(self::$patterns['cursor_west'], '$1e-resize', $css);
281
+ $css = str_replace(self::$patterns['tmpToken'], 'w-resize', $css);
282
+
283
+ return $css;
284
+ }
285
+
286
+ /**
287
+ * Swap the second and fourth parts in four-part notation rules like
288
+ * padding: 1px 2px 3px 4px;
289
+ *
290
+ * Unlike the original implementation, this function doesn't suffer from
291
+ * the bug where whitespace is not preserved when flipping four-part rules
292
+ * and four-part color rules with multiple whitespace characters between
293
+ * colors are not recognized.
294
+ * See https://code.google.com/p/cssjanus/issues/detail?id=16
295
+ * @param $css string
296
+ * @return string
297
+ */
298
+ private static function fixFourPartNotation($css) {
299
+ $css = preg_replace(self::$patterns['four_notation_quantity'], '$1$2$3$8$5$6$7$4$9', $css);
300
+ $css = preg_replace(self::$patterns['four_notation_color'], '$1$2$3$8$5$6$7$4$9', $css);
301
+ return $css;
302
+ }
303
+
304
+ /**
305
+ * Swaps appropriate corners in border-radius values.
306
+ *
307
+ * @param $css string
308
+ * @return string
309
+ */
310
+ private static function fixBorderRadius($css) {
311
+ return preg_replace_callback(
312
+ self::$patterns['border_radius'],
313
+ array('self', 'calculateBorderRadius'),
314
+ $css
315
+ );
316
+ }
317
+
318
+ /**
319
+ * Callback for fixBorderRadius()
320
+ * @param $matches array
321
+ * @return string
322
+ */
323
+ private static function calculateBorderRadius($matches) {
324
+ $pre = $matches[1];
325
+ $firstGroup = array_filter(array_slice($matches, 2, 4), function ($match) {
326
+ return $match !== '';
327
+ });
328
+ $secondGroup = array_filter(array_slice($matches, 6, 4), function ($match) {
329
+ return $match !== '';
330
+ });
331
+ $post = $matches[10] ?: '';
332
+
333
+ if ($secondGroup) {
334
+ $values = self::flipBorderRadiusValues($firstGroup)
335
+ . ' / ' . self::flipBorderRadiusValues($secondGroup);
336
+ } else {
337
+ $values = self::flipBorderRadiusValues($firstGroup);
338
+ }
339
+
340
+ return $pre . $values . $post;
341
+ }
342
+
343
+ /**
344
+ * Callback for fixBorderRadius()
345
+ * @param array $values Matched values
346
+ * @return string Flipped values
347
+ */
348
+ private static function flipBorderRadiusValues($values) {
349
+ switch (count($values)) {
350
+ case 4:
351
+ $values = array($values[1], $values[0], $values[3], $values[2]);
352
+ break;
353
+ case 3:
354
+ $values = array($values[1], $values[0], $values[1], $values[2]);
355
+ break;
356
+ case 2:
357
+ $values = array($values[1], $values[0]);
358
+ break;
359
+ case 1:
360
+ $values = array($values[0]);
361
+ break;
362
+ }
363
+ return implode(' ', $values);
364
+ }
365
+
366
+ /**
367
+ * Flips the sign of a CSS value, possibly with a unit.
368
+ *
369
+ * We can't just negate the value with unary minus due to the units.
370
+ *
371
+ * @param $cssValue string
372
+ * @return string
373
+ */
374
+ private static function flipSign($cssValue) {
375
+ // Don't mangle zeroes
376
+ if (floatval($cssValue) === 0.0) {
377
+ return $cssValue;
378
+ } elseif ($cssValue[0] === '-') {
379
+ return substr($cssValue, 1);
380
+ } else {
381
+ return "-" . $cssValue;
382
+ }
383
+ }
384
+
385
+ /**
386
+ * Negates horizontal offset in box-shadow and text-shadow rules.
387
+ *
388
+ * @param $css string
389
+ * @return string
390
+ */
391
+ private static function fixShadows($css) {
392
+ $css = preg_replace_callback(self::$patterns['box_shadow'], function ($matches) {
393
+ return $matches[1] . self::flipSign($matches[2]);
394
+ }, $css);
395
+
396
+ $css = preg_replace_callback(self::$patterns['text_shadow1'], function ($matches) {
397
+ return $matches[1] . $matches[2] . $matches[3] . self::flipSign($matches[4]);
398
+ }, $css);
399
+
400
+ $css = preg_replace_callback(self::$patterns['text_shadow2'], function ($matches) {
401
+ return $matches[1] . $matches[2] . $matches[3] . self::flipSign($matches[4]);
402
+ }, $css);
403
+
404
+ $css = preg_replace_callback(self::$patterns['text_shadow3'], function ($matches) {
405
+ return $matches[1] . self::flipSign($matches[2]);
406
+ }, $css);
407
+
408
+ return $css;
409
+ }
410
+
411
+ /**
412
+ * Negates horizontal offset in tranform: translate()
413
+ *
414
+ * @param $css string
415
+ * @return string
416
+ */
417
+ private static function fixTranslate($css) {
418
+ $css = preg_replace_callback(self::$patterns['translate'], function ($matches) {
419
+ return $matches[1] . $matches[2] . self::flipSign($matches[3]) . $matches[4];
420
+ }, $css);
421
+
422
+ $css = preg_replace_callback(self::$patterns['translate_x'], function ($matches) {
423
+ return $matches[1] . $matches[2] . self::flipSign($matches[3]) . $matches[4];
424
+ }, $css);
425
+
426
+ return $css;
427
+ }
428
+
429
+ /**
430
+ * Flip horizontal background percentages.
431
+ * @param $css string
432
+ * @return string
433
+ */
434
+ private static function fixBackgroundPosition($css) {
435
+ $replaced = preg_replace_callback(
436
+ self::$patterns['bg_horizontal_percentage'],
437
+ array('self', 'calculateNewBackgroundPosition'),
438
+ $css
439
+ );
440
+ if ($replaced !== null) {
441
+ // preg_replace_callback() sometimes returns null
442
+ $css = $replaced;
443
+ }
444
+ $replaced = preg_replace_callback(
445
+ self::$patterns['bg_horizontal_percentage_x'],
446
+ array('self', 'calculateNewBackgroundPosition'),
447
+ $css
448
+ );
449
+ if ($replaced !== null) {
450
+ $css = $replaced;
451
+ }
452
+
453
+ return $css;
454
+ }
455
+
456
+ /**
457
+ * Callback for fixBackgroundPosition()
458
+ * @param $matches array
459
+ * @return string
460
+ */
461
+ private static function calculateNewBackgroundPosition($matches) {
462
+ $value = $matches[2];
463
+ if (substr($value, -1) === '%') {
464
+ $idx = strpos($value, '.');
465
+ if ($idx !== false) {
466
+ $len = strlen($value) - $idx - 2;
467
+ $value = number_format(100 - (float)$value, $len) . '%';
468
+ } else {
469
+ $value = (100 - (float)$value) . '%';
470
+ }
471
+ }
472
+ return $matches[1] . $value;
473
+ }
474
+ }
475
+
476
+ /**
477
+ * Utility class used by CSSJanus that tokenizes and untokenizes things we want
478
+ * to protect from being janused.
479
+ * @author Roan Kattouw
480
+ */
481
+ class CSSJanusTokenizer {
482
+ private $regex;
483
+ private $token;
484
+ private $originals;
485
+
486
+ /**
487
+ * Constructor
488
+ * @param string $regex Regular expression whose matches to replace by a token.
489
+ * @param string $token Token
490
+ */
491
+ public function __construct($regex, $token) {
492
+ $this->regex = $regex;
493
+ $this->token = $token;
494
+ $this->originals = array();
495
+ }
496
+
497
+ /**
498
+ * Replace all occurrences of $regex in $str with a token and remember
499
+ * the original strings.
500
+ * @param string $str to tokenize
501
+ * @return string Tokenized string
502
+ */
503
+ public function tokenize($str) {
504
+ return preg_replace_callback($this->regex, array($this, 'tokenizeCallback'), $str);
505
+ }
506
+
507
+ /**
508
+ * @param $matches array
509
+ * @return string
510
+ */
511
+ private function tokenizeCallback($matches) {
512
+ $this->originals[] = $matches[0];
513
+ return $this->token;
514
+ }
515
+
516
+ /**
517
+ * Replace tokens with their originals. If multiple strings were tokenized, it's important they be
518
+ * detokenized in exactly the SAME ORDER.
519
+ * @param string $str previously run through tokenize()
520
+ * @return string Original string
521
+ */
522
+ public function detokenize($str) {
523
+ // PHP has no function to replace only the first occurrence or to
524
+ // replace occurrences of the same string with different values,
525
+ // so we use preg_replace_callback() even though we don't really need a regex
526
+ return preg_replace_callback(
527
+ '/' . preg_quote($this->token, '/') . '/',
528
+ array($this, 'detokenizeCallback'),
529
+ $str
530
+ );
531
+ }
532
+
533
+ /**
534
+ * @param $matches
535
+ * @return mixed
536
+ */
537
+ private function detokenizeCallback($matches) {
538
+ $retval = current($this->originals);
539
+ next($this->originals);
540
+
541
+ return $retval;
542
+ }
543
+ }
includes/compiler/vendors/js-minifier.php CHANGED
@@ -1,396 +1,396 @@
1
- <?php
2
- /**
3
- * JavaScript compressor, minifies JavaScript.
4
- * Based on JSMin (https://github.com/mrclay/minify, Ryan Grove <ryan@wonko.com>, Stephen Clay <steve@mrclay.org>, BSD License)
5
- *
6
- * @ignore
7
- */
8
- class JSMin {
9
-
10
- const ORD_LF = 10;
11
- const ORD_SPACE = 32;
12
- const ACTION_KEEP_A = 1;
13
- const ACTION_DELETE_A = 2;
14
- const ACTION_DELETE_A_B = 3;
15
-
16
- protected $a = "\n";
17
- protected $b = '';
18
- protected $input = '';
19
- protected $inputIndex = 0;
20
- protected $inputLength = 0;
21
- protected $lookAhead = null;
22
- protected $output = '';
23
- protected $lastByteOut = '';
24
- protected $keptComment = '';
25
-
26
- /**
27
- * @param string $input
28
- */
29
- public function __construct($input)
30
- {
31
- $this->input = $input;
32
- }
33
-
34
- /**
35
- * Perform minification, return result
36
- *
37
- * @return string
38
- */
39
- public function min()
40
- {
41
- if ($this->output !== '') { // min already run
42
- return $this->output;
43
- }
44
-
45
- $mbIntEnc = null;
46
- if (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) {
47
- $mbIntEnc = mb_internal_encoding();
48
- mb_internal_encoding('8bit');
49
- }
50
- $this->input = str_replace("\r\n", "\n", $this->input);
51
- $this->inputLength = strlen($this->input);
52
-
53
- $this->action(self::ACTION_DELETE_A_B);
54
-
55
- while ($this->a !== null) {
56
- // determine next command
57
- $command = self::ACTION_KEEP_A; // default
58
- if ($this->a === ' ') {
59
- if (($this->lastByteOut === '+' || $this->lastByteOut === '-')
60
- && ($this->b === $this->lastByteOut)) {
61
- // Don't delete this space. If we do, the addition/subtraction
62
- // could be parsed as a post-increment
63
- } elseif (! $this->isAlphaNum($this->b)) {
64
- $command = self::ACTION_DELETE_A;
65
- }
66
- } elseif ($this->a === "\n") {
67
- if ($this->b === ' ') {
68
- $command = self::ACTION_DELETE_A_B;
69
-
70
- // in case of mbstring.func_overload & 2, must check for null b,
71
- // otherwise mb_strpos will give WARNING
72
- } elseif ($this->b === null
73
- || (false === strpos('{[(+-!~', $this->b)
74
- && ! $this->isAlphaNum($this->b))) {
75
- $command = self::ACTION_DELETE_A;
76
- }
77
- } elseif (! $this->isAlphaNum($this->a)) {
78
- if ($this->b === ' '
79
- || ($this->b === "\n"
80
- && (false === strpos('}])+-"\'', $this->a)))) {
81
- $command = self::ACTION_DELETE_A_B;
82
- }
83
- }
84
- $this->action($command);
85
- }
86
- $this->output = trim($this->output);
87
-
88
- if ($mbIntEnc !== null) {
89
- mb_internal_encoding($mbIntEnc);
90
- }
91
- return $this->output;
92
- }
93
-
94
- /**
95
- * ACTION_KEEP_A = Output A. Copy B to A. Get the next B.
96
- * ACTION_DELETE_A = Copy B to A. Get the next B.
97
- * ACTION_DELETE_A_B = Get the next B.
98
- *
99
- * @param int $command
100
- * @throws JSMin_UnterminatedRegExpException|JSMin_UnterminatedStringException
101
- */
102
- protected function action($command)
103
- {
104
- // make sure we don't compress "a + ++b" to "a+++b", etc.
105
- if ($command === self::ACTION_DELETE_A_B
106
- && $this->b === ' '
107
- && ($this->a === '+' || $this->a === '-')) {
108
- // Note: we're at an addition/substraction operator; the inputIndex
109
- // will certainly be a valid index
110
- if ($this->input[$this->inputIndex] === $this->a) {
111
- // This is "+ +" or "- -". Don't delete the space.
112
- $command = self::ACTION_KEEP_A;
113
- }
114
- }
115
-
116
- switch ($command) {
117
- case self::ACTION_KEEP_A: // 1
118
- $this->output .= $this->a;
119
-
120
- if ($this->keptComment) {
121
- $this->output = rtrim($this->output, "\n");
122
- $this->output .= $this->keptComment;
123
- $this->keptComment = '';
124
- }
125
-
126
- $this->lastByteOut = $this->a;
127
-
128
- // fallthrough intentional
129
- case self::ACTION_DELETE_A: // 2
130
- $this->a = $this->b;
131
- if ($this->a === "'" || $this->a === '"') { // string literal
132
- $str = $this->a; // in case needed for exception
133
- for(;;) {
134
- $this->output .= $this->a;
135
- $this->lastByteOut = $this->a;
136
-
137
- $this->a = $this->get();
138
- if ($this->a === $this->b) { // end quote
139
- break;
140
- }
141
- if ($this->isEOF($this->a)) {
142
- $byte = $this->inputIndex - 1;
143
- throw new JSMin_UnterminatedStringException(
144
- "JSMin: Unterminated String at byte {$byte}: {$str}");
145
- }
146
- $str .= $this->a;
147
- if ($this->a === '\\') {
148
- $this->output .= $this->a;
149
- $this->lastByteOut = $this->a;
150
-
151
- $this->a = $this->get();
152
- $str .= $this->a;
153
- }
154
- }
155
- }
156
-
157
- // fallthrough intentional
158
- case self::ACTION_DELETE_A_B: // 3
159
- $this->b = $this->next();
160
- if ($this->b === '/' && $this->isRegexpLiteral()) {
161
- $this->output .= $this->a . $this->b;
162
- $pattern = '/'; // keep entire pattern in case we need to report it in the exception
163
- for(;;) {
164
- $this->a = $this->get();
165
- $pattern .= $this->a;
166
- if ($this->a === '[') {
167
- for(;;) {
168
- $this->output .= $this->a;
169
- $this->a = $this->get();
170
- $pattern .= $this->a;
171
- if ($this->a === ']') {
172
- break;
173
- }
174
- if ($this->a === '\\') {
175
- $this->output .= $this->a;
176
- $this->a = $this->get();
177
- $pattern .= $this->a;
178
- }
179
- if ($this->isEOF($this->a)) {
180
- throw new JSMin_UnterminatedRegExpException(
181
- "JSMin: Unterminated set in RegExp at byte "
182
- . $this->inputIndex .": {$pattern}");
183
- }
184
- }
185
- }
186
-
187
- if ($this->a === '/') { // end pattern
188
- break; // while (true)
189
- } elseif ($this->a === '\\') {
190
- $this->output .= $this->a;
191
- $this->a = $this->get();
192
- $pattern .= $this->a;
193
- } elseif ($this->isEOF($this->a)) {
194
- $byte = $this->inputIndex - 1;
195
- throw new JSMin_UnterminatedRegExpException(
196
- "JSMin: Unterminated RegExp at byte {$byte}: {$pattern}");
197
- }
198
- $this->output .= $this->a;
199
- $this->lastByteOut = $this->a;
200
- }
201
- $this->b = $this->next();
202
- }
203
- // end case ACTION_DELETE_A_B
204
- }
205
- }
206
-
207
- /**
208
- * @return bool
209
- */
210
- protected function isRegexpLiteral()
211
- {
212
- if (false !== strpos("(,=:[!&|?+-~*{;", $this->a)) {
213
- // we obviously aren't dividing
214
- return true;
215
- }
216
-
217
- // we have to check for a preceding keyword, and we don't need to pattern
218
- // match over the whole output.
219
- $recentOutput = substr($this->output, -10);
220
-
221
- // check if return/typeof directly precede a pattern without a space
222
- foreach (array('return', 'typeof') as $keyword) {
223
- if ($this->a !== substr($keyword, -1)) {
224
- // certainly wasn't keyword
225
- continue;
226
- }
227
- if (preg_match("~(^|[\\s\\S])" . substr($keyword, 0, -1) . "$~", $recentOutput, $m)) {
228
- if ($m[1] === '' || !$this->isAlphaNum($m[1])) {
229
- return true;
230
- }
231
- }
232
- }
233
-
234
- // check all keywords
235
- if ($this->a === ' ' || $this->a === "\n") {
236
- if (preg_match('~(^|[\\s\\S])(?:case|else|in|return|typeof)$~', $recentOutput, $m)) {
237
- if ($m[1] === '' || !$this->isAlphaNum($m[1])) {
238
- return true;
239
- }
240
- }
241
- }
242
-
243
- return false;
244
- }
245
-
246
- /**
247
- * Return the next character from stdin. Watch out for lookahead. If the character is a control character,
248
- * translate it to a space or linefeed.
249
- *
250
- * @return string
251
- */
252
- protected function get()
253
- {
254
- $c = $this->lookAhead;
255
- $this->lookAhead = null;
256
- if ($c === null) {
257
- // getc(stdin)
258
- if ($this->inputIndex < $this->inputLength) {
259
- $c = $this->input[$this->inputIndex];
260
- $this->inputIndex += 1;
261
- } else {
262
- $c = null;
263
- }
264
- }
265
- if (ord($c) >= self::ORD_SPACE || $c === "\n" || $c === null) {
266
- return $c;
267
- }
268
- if ($c === "\r") {
269
- return "\n";
270
- }
271
- return ' ';
272
- }
273
-
274
- /**
275
- * Does $a indicate end of input?
276
- *
277
- * @param string $a
278
- * @return bool
279
- */
280
- protected function isEOF($a)
281
- {
282
- return ord($a) <= self::ORD_LF;
283
- }
284
-
285
- /**
286
- * Get next char (without getting it). If is ctrl character, translate to a space or newline.
287
- *
288
- * @return string
289
- */
290
- protected function peek()
291
- {
292
- $this->lookAhead = $this->get();
293
- return $this->lookAhead;
294
- }
295
-
296
- /**
297
- * Return true if the character is a letter, digit, underscore, dollar sign, or non-ASCII character.
298
- *
299
- * @param string $c
300
- *
301
- * @return bool
302
- */
303
- protected function isAlphaNum($c)
304
- {
305
- return (preg_match('/^[a-z0-9A-Z_\\$\\\\]$/', $c) || ord($c) > 126);
306
- }
307
-
308
- /**
309
- * Consume a single line comment from input (possibly retaining it)
310
- */
311
- protected function consumeSingleLineComment()
312
- {
313
- $comment = '';
314
- while (true) {
315
- $get = $this->get();
316
- $comment .= $get;
317
- if (ord($get) <= self::ORD_LF) { // end of line reached
318
- // if IE conditional comment
319
- if (preg_match('/^\\/@(?:cc_on|if|elif|else|end)\\b/', $comment)) {
320
- $this->keptComment .= "/{$comment}";
321
- }
322
- return;
323
- }
324
- }
325
- }
326
-
327
- /**
328
- * Consume a multiple line comment from input (possibly retaining it)
329
- *
330
- * @throws JSMin_UnterminatedCommentException
331
- */
332
- protected function consumeMultipleLineComment()
333
- {
334
- $this->get();
335
- $comment = '';
336
- for(;;) {
337
- $get = $this->get();
338
- if ($get === '*') {
339
- if ($this->peek() === '/') { // end of comment reached
340
- $this->get();
341
- if (0 === strpos($comment, '!')) {
342
- // preserved by YUI Compressor
343
- if (!$this->keptComment) {
344
- // don't prepend a newline if two comments right after one another
345
- $this->keptComment = "\n";
346
- }
347
- $this->keptComment .= "/*!" . substr($comment, 1) . "*/\n";
348
- } else if (preg_match('/^@(?:cc_on|if|elif|else|end)\\b/', $comment)) {
349
- // IE conditional
350
- $this->keptComment .= "/*{$comment}*/";
351
- }
352
- return;
353
- }
354
- } elseif ($get === null) {
355
- throw new JSMin_UnterminatedCommentException(
356
- "JSMin: Unterminated comment at byte {$this->inputIndex}: /*{$comment}");
357
- }
358
- $comment .= $get;
359
- }
360
- }
361
-
362
- /**
363
- * Get the next character, skipping over comments. Some comments may be preserved.
364
- *
365
- * @return string
366
- */
367
- protected function next()
368
- {
369
- $get = $this->get();
370
- if ($get === '/') {
371
- switch ($this->peek()) {
372
- case '/':
373
- $this->consumeSingleLineComment();
374
- $get = "\n";
375
- break;
376
- case '*':
377
- $this->consumeMultipleLineComment();
378
- $get = ' ';
379
- break;
380
- }
381
- }
382
- return $get;
383
- }
384
- }
385
- /**
386
- * @ignore
387
- */
388
- class JSMin_UnterminatedStringException extends Exception {}
389
- /**
390
- * @ignore
391
- */
392
- class JSMin_UnterminatedCommentException extends Exception {}
393
- /**
394
- * @ignore
395
- */
396
  class JSMin_UnterminatedRegExpException extends Exception {}
1
+ <?php
2
+ /**
3
+ * JavaScript compressor, minifies JavaScript.
4
+ * Based on JSMin (https://github.com/mrclay/minify, Ryan Grove <ryan@wonko.com>, Stephen Clay <steve@mrclay.org>, BSD License)
5
+ *
6
+ * @ignore
7
+ */
8
+ class JSMin {
9
+
10
+ const ORD_LF = 10;
11
+ const ORD_SPACE = 32;
12
+ const ACTION_KEEP_A = 1;
13
+ const ACTION_DELETE_A = 2;
14
+ const ACTION_DELETE_A_B = 3;
15
+
16
+ protected $a = "\n";
17
+ protected $b = '';
18
+ protected $input = '';
19
+ protected $inputIndex = 0;
20
+ protected $inputLength = 0;
21
+ protected $lookAhead = null;
22
+ protected $output = '';
23
+ protected $lastByteOut = '';
24
+ protected $keptComment = '';
25
+
26
+ /**
27
+ * @param string $input
28
+ */
29
+ public function __construct($input)
30
+ {
31
+ $this->input = $input;
32
+ }
33
+
34
+ /**
35
+ * Perform minification, return result
36
+ *
37
+ * @return string
38
+ */
39
+ public function min()
40
+ {
41
+ if ($this->output !== '') { // min already run
42
+ return $this->output;
43
+ }
44
+
45
+ $mbIntEnc = null;
46
+ if (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) {
47
+ $mbIntEnc = mb_internal_encoding();
48
+ mb_internal_encoding('8bit');
49
+ }
50
+ $this->input = str_replace("\r\n", "\n", $this->input);
51
+ $this->inputLength = strlen($this->input);
52
+
53
+ $this->action(self::ACTION_DELETE_A_B);
54
+
55
+ while ($this->a !== null) {
56
+ // determine next command
57
+ $command = self::ACTION_KEEP_A; // default
58
+ if ($this->a === ' ') {
59
+ if (($this->lastByteOut === '+' || $this->lastByteOut === '-')
60
+ && ($this->b === $this->lastByteOut)) {
61
+ // Don't delete this space. If we do, the addition/subtraction
62
+ // could be parsed as a post-increment
63
+ } elseif (! $this->isAlphaNum($this->b)) {
64
+ $command = self::ACTION_DELETE_A;
65
+ }
66
+ } elseif ($this->a === "\n") {
67
+ if ($this->b === ' ') {
68
+ $command = self::ACTION_DELETE_A_B;
69
+
70
+ // in case of mbstring.func_overload & 2, must check for null b,
71
+ // otherwise mb_strpos will give WARNING
72
+ } elseif ($this->b === null
73
+ || (false === strpos('{[(+-!~', $this->b)
74
+ && ! $this->isAlphaNum($this->b))) {
75
+ $command = self::ACTION_DELETE_A;
76
+ }
77
+ } elseif (! $this->isAlphaNum($this->a)) {
78
+ if ($this->b === ' '
79
+ || ($this->b === "\n"
80
+ && (false === strpos('}])+-"\'', $this->a)))) {
81
+ $command = self::ACTION_DELETE_A_B;
82
+ }
83
+ }
84
+ $this->action($command);
85
+ }
86
+ $this->output = trim($this->output);
87
+
88
+ if ($mbIntEnc !== null) {
89
+ mb_internal_encoding($mbIntEnc);
90
+ }
91
+ return $this->output;
92
+ }
93
+
94
+ /**
95
+ * ACTION_KEEP_A = Output A. Copy B to A. Get the next B.
96
+ * ACTION_DELETE_A = Copy B to A. Get the next B.
97
+ * ACTION_DELETE_A_B = Get the next B.
98
+ *
99
+ * @param int $command
100
+ * @throws JSMin_UnterminatedRegExpException|JSMin_UnterminatedStringException
101
+ */
102
+ protected function action($command)
103
+ {
104
+ // make sure we don't compress "a + ++b" to "a+++b", etc.
105
+ if ($command === self::ACTION_DELETE_A_B
106
+ && $this->b === ' '
107
+ && ($this->a === '+' || $this->a === '-')) {
108
+ // Note: we're at an addition/substraction operator; the inputIndex
109
+ // will certainly be a valid index
110
+ if ($this->input[$this->inputIndex] === $this->a) {
111
+ // This is "+ +" or "- -". Don't delete the space.
112
+ $command = self::ACTION_KEEP_A;
113
+ }
114
+ }
115
+
116
+ switch ($command) {
117
+ case self::ACTION_KEEP_A: // 1
118
+ $this->output .= $this->a;
119
+
120
+ if ($this->keptComment) {
121
+ $this->output = rtrim($this->output, "\n");
122
+ $this->output .= $this->keptComment;
123
+ $this->keptComment = '';
124
+ }
125
+
126
+ $this->lastByteOut = $this->a;
127
+
128
+ // fallthrough intentional
129
+ case self::ACTION_DELETE_A: // 2
130
+ $this->a = $this->b;
131
+ if ($this->a === "'" || $this->a === '"') { // string literal
132
+ $str = $this->a; // in case needed for exception
133
+ for(;;) {
134
+ $this->output .= $this->a;
135
+ $this->lastByteOut = $this->a;
136
+
137
+ $this->a = $this->get();
138
+ if ($this->a === $this->b) { // end quote
139
+ break;
140
+ }
141
+ if ($this->isEOF($this->a)) {
142
+ $byte = $this->inputIndex - 1;
143
+ throw new JSMin_UnterminatedStringException(
144
+ "JSMin: Unterminated String at byte {$byte}: {$str}");
145
+ }
146
+ $str .= $this->a;
147
+ if ($this->a === '\\') {
148
+ $this->output .= $this->a;
149
+ $this->lastByteOut = $this->a;
150
+
151
+ $this->a = $this->get();
152
+ $str .= $this->a;
153
+ }
154
+ }
155
+ }
156
+
157
+ // fallthrough intentional
158
+ case self::ACTION_DELETE_A_B: // 3
159
+ $this->b = $this->next();
160
+ if ($this->b === '/' && $this->isRegexpLiteral()) {
161
+ $this->output .= $this->a . $this->b;
162
+ $pattern = '/'; // keep entire pattern in case we need to report it in the exception
163
+ for(;;) {
164
+ $this->a = $this->get();
165
+ $pattern .= $this->a;
166
+ if ($this->a === '[') {
167
+ for(;;) {
168
+ $this->output .= $this->a;
169
+ $this->a = $this->get();
170
+ $pattern .= $this->a;
171
+ if ($this->a === ']') {
172
+ break;
173
+ }
174
+ if ($this->a === '\\') {
175
+ $this->output .= $this->a;
176
+ $this->a = $this->get();
177
+ $pattern .= $this->a;
178
+ }
179
+ if ($this->isEOF($this->a)) {
180
+ throw new JSMin_UnterminatedRegExpException(
181
+ "JSMin: Unterminated set in RegExp at byte "
182
+ . $this->inputIndex .": {$pattern}");
183
+ }
184
+ }
185
+ }
186
+
187
+ if ($this->a === '/') { // end pattern
188
+ break; // while (true)
189
+ } elseif ($this->a === '\\') {
190
+ $this->output .= $this->a;
191
+ $this->a = $this->get();
192
+ $pattern .= $this->a;
193
+ } elseif ($this->isEOF($this->a)) {
194
+ $byte = $this->inputIndex - 1;
195
+ throw new JSMin_UnterminatedRegExpException(
196
+ "JSMin: Unterminated RegExp at byte {$byte}: {$pattern}");
197
+ }
198
+ $this->output .= $this->a;
199
+ $this->lastByteOut = $this->a;
200
+ }
201
+ $this->b = $this->next();
202
+ }
203
+ // end case ACTION_DELETE_A_B
204
+ }
205
+ }
206
+
207
+ /**
208
+ * @return bool
209
+ */
210
+ protected function isRegexpLiteral()
211
+ {
212
+ if (false !== strpos("(,=:[!&|?+-~*{;", $this->a)) {
213
+ // we obviously aren't dividing
214
+ return true;
215
+ }
216
+
217
+ // we have to check for a preceding keyword, and we don't need to pattern
218
+ // match over the whole output.
219
+ $recentOutput = substr($this->output, -10);
220
+
221
+ // check if return/typeof directly precede a pattern without a space
222
+ foreach (array('return', 'typeof') as $keyword) {
223
+ if ($this->a !== substr($keyword, -1)) {
224
+ // certainly wasn't keyword
225
+ continue;
226
+ }
227
+ if (preg_match("~(^|[\\s\\S])" . substr($keyword, 0, -1) . "$~", $recentOutput, $m)) {
228
+ if ($m[1] === '' || !$this->isAlphaNum($m[1])) {
229
+ return true;
230
+ }
231
+ }
232
+ }
233
+
234
+ // check all keywords
235
+ if ($this->a === ' ' || $this->a === "\n") {
236
+ if (preg_match('~(^|[\\s\\S])(?:case|else|in|return|typeof)$~', $recentOutput, $m)) {
237
+ if ($m[1] === '' || !$this->isAlphaNum($m[1])) {
238
+ return true;
239
+ }
240
+ }
241
+ }
242
+
243
+ return false;
244
+ }
245
+
246
+ /**
247
+ * Return the next character from stdin. Watch out for lookahead. If the character is a control character,
248
+ * translate it to a space or linefeed.
249
+ *
250
+ * @return string
251
+ */
252
+ protected function get()
253
+ {
254
+ $c = $this->lookAhead;
255
+ $this->lookAhead = null;
256
+ if ($c === null) {
257
+ // getc(stdin)
258
+ if ($this->inputIndex < $this->inputLength) {
259
+ $c = $this->input[$this->inputIndex];
260
+ $this->inputIndex += 1;
261
+ } else {
262
+ $c = null;
263
+ }
264
+ }
265
+ if (ord($c) >= self::ORD_SPACE || $c === "\n" || $c === null) {
266
+ return $c;
267
+ }
268
+ if ($c === "\r") {
269
+ return "\n";
270
+ }
271
+ return ' ';
272
+ }
273
+
274
+ /**
275
+ * Does $a indicate end of input?
276
+ *
277
+ * @param string $a
278
+ * @return bool
279
+ */
280
+ protected function isEOF($a)
281
+ {
282
+ return ord($a) <= self::ORD_LF;
283
+ }
284
+
285
+ /**
286
+ * Get next char (without getting it). If is ctrl character, translate to a space or newline.
287
+ *
288
+ * @return string
289
+ */
290
+ protected function peek()
291
+ {
292
+ $this->lookAhead = $this->get();
293
+ return $this->lookAhead;
294
+ }
295
+
296
+ /**
297
+ * Return true if the character is a letter, digit, underscore, dollar sign, or non-ASCII character.
298
+ *
299
+ * @param string $c
300
+ *
301
+ * @return bool
302
+ */
303
+ protected function isAlphaNum($c)
304
+ {
305
+ return (preg_match('/^[a-z0-9A-Z_\\$\\\\]$/', $c) || ord($c) > 126);
306
+ }
307
+
308
+ /**
309
+ * Consume a single line comment from input (possibly retaining it)
310
+ */
311
+ protected function consumeSingleLineComment()
312
+ {
313
+ $comment = '';
314
+ while (true) {
315
+ $get = $this->get();
316
+ $comment .= $get;
317
+ if (ord($get) <= self::ORD_LF) { // end of line reached
318
+ // if IE conditional comment
319
+ if (preg_match('/^\\/@(?:cc_on|if|elif|else|end)\\b/', $comment)) {
320
+ $this->keptComment .= "/{$comment}";
321
+ }
322
+ return;
323
+ }
324
+ }
325
+ }
326
+
327
+ /**
328
+ * Consume a multiple line comment from input (possibly retaining it)
329
+ *
330
+ * @throws JSMin_UnterminatedCommentException
331
+ */
332
+ protected function consumeMultipleLineComment()
333
+ {
334
+ $this->get();
335
+ $comment = '';
336
+ for(;;) {
337
+ $get = $this->get();
338
+ if ($get === '*') {
339
+ if ($this->peek() === '/') { // end of comment reached
340
+ $this->get();
341
+ if (0 === strpos($comment, '!')) {
342
+ // preserved by YUI Compressor
343
+ if (!$this->keptComment) {
344
+ // don't prepend a newline if two comments right after one another
345
+ $this->keptComment = "\n";
346
+ }
347
+ $this->keptComment .= "/*!" . substr($comment, 1) . "*/\n";
348
+ } else if (preg_match('/^@(?:cc_on|if|elif|else|end)\\b/', $comment)) {
349
+ // IE conditional
350
+ $this->keptComment .= "/*{$comment}*/";
351
+ }
352
+ return;
353
+ }
354
+ } elseif ($get === null) {
355
+ throw new JSMin_UnterminatedCommentException(
356
+ "JSMin: Unterminated comment at byte {$this->inputIndex}: /*{$comment}");
357
+ }
358
+ $comment .= $get;
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Get the next character, skipping over comments. Some comments may be preserved.
364
+ *
365
+ * @return string
366
+ */
367
+ protected function next()
368
+ {
369
+ $get = $this->get();
370
+ if ($get === '/') {
371
+ switch ($this->peek()) {
372
+ case '/':
373
+ $this->consumeSingleLineComment();
374
+ $get = "\n";
375
+ break;
376
+ case '*':
377
+ $this->consumeMultipleLineComment();
378
+ $get = ' ';
379
+ break;
380
+ }
381
+ }
382
+ return $get;
383
+ }
384
+ }
385
+ /**
386
+ * @ignore
387
+ */
388
+ class JSMin_UnterminatedStringException extends Exception {}
389
+ /**
390
+ * @ignore
391
+ */
392
+ class JSMin_UnterminatedCommentException extends Exception {}
393
+ /**
394
+ * @ignore
395
+ */
396
  class JSMin_UnterminatedRegExpException extends Exception {}
includes/compiler/vendors/lessc.php CHANGED
@@ -1,3694 +1,3694 @@
1
- <?php
2
- /**
3
- * lessphp v0.4.0
4
- * http://leafo.net/lessphp
5
- *
6
- * LESS css compiler, adapted from http://lesscss.org
7
- *
8
- * Copyright 2012, Leaf Corcoran <leafot@gmail.com>
9
- * Licensed under MIT or GPLv3, see LICENSE
10
- *
11
- * @ignore
12
- */
13
-
14
-
15
- /**
16
- * The less compiler and parser.
17
- *
18
- * Converting LESS to CSS is a three stage process. The incoming file is parsed
19
- * by `lessc_parser` into a syntax tree, then it is compiled into another tree
20
- * representing the CSS structure by `lessc`. The CSS tree is fed into a
21
- * formatter, like `lessc_formatter` which then outputs CSS as a string.
22
- *
23
- * During the first compile, all values are *reduced*, which means that their
24
- * types are brought to the lowest form before being dump as strings. This
25
- * handles math equations, variable dereferences, and the like.
26
- *
27
- * The `parse` function of `lessc` is the entry point.
28
- *
29
- * In summary:
30
- *
31
- * The `lessc` class creates an intstance of the parser, feeds it LESS code,
32
- * then transforms the resulting tree to a CSS tree. This class also holds the
33
- * evaluation context, such as all available mixins and variables at any given
34
- * time.
35
- *
36
- * The `lessc_parser` class is only concerned with parsing its input.
37
- *
38
- * The `lessc_formatter` takes a CSS tree, and dumps it to a formatted string,
39
- * handling things like indentation.
40
- *
41
- * @ignore
42
- */
43
- class JupiterX_Lessc {
44
- static public $VERSION = "v0.4.0";
45
- static protected $TRUE = array("keyword", "true");
46
- static protected $FALSE = array("keyword", "false");
47
-
48
- protected $libFunctions = array();
49
- protected $registeredVars = array();
50
- protected $preserveComments = false;
51
-
52
- public $vPrefix = '@'; // prefix of abstract properties
53
- public $mPrefix = '$'; // prefix of abstract blocks
54
- public $parentSelector = '&';
55
-
56
- public $importDisabled = false;
57
- public $importDir = '';
58
-
59
- protected $numberPrecision = null;
60
-
61
- protected $allParsedFiles = array();
62
-
63
- // set to the parser that generated the current line when compiling
64
- // so we know how to create error messages
65
- protected $sourceParser = null;
66
- protected $sourceLoc = null;
67
-
68
- static public $defaultValue = array("keyword", "");
69
-
70
- static protected $nextImportId = 0; // uniquely identify imports
71
-
72
- // attempts to find the path of an import url, returns null for css files
73
- protected function findImport($url) {
74
- foreach ((array)$this->importDir as $dir) {
75
- $full = $dir.(substr($dir, -1) != '/' ? '/' : '').$url;
76
- if ($this->fileExists($file = $full.'.less') || $this->fileExists($file = $full)) {
77
- return $file;
78
- }
79
- }
80
-
81
- return null;
82
- }
83
-
84
- protected function fileExists($name) {
85
- return is_file($name);
86
- }
87
-
88
- static public function compressList($items, $delim) {
89
- if (!isset($items[1]) && isset($items[0])) return $items[0];
90
- else return array('list', $delim, $items);
91
- }
92
-
93
- static public function preg_quote($what) {
94
- return preg_quote($what, '/');
95
- }
96
-
97
- protected function tryImport($importPath, $parentBlock, $out) {
98
- if ($importPath[0] == "function" && $importPath[1] == "url") {
99
- $importPath = $this->flattenList($importPath[2]);
100
- }
101
-
102
- $str = $this->coerceString($importPath);
103
- if ($str === null) return false;
104
-
105
- $url = $this->compileValue($this->lib_unquote($str));
106
-
107
- // don't import if it ends in css
108
- if (substr_compare($url, '.css', -4, 4) === 0) return false;
109
-
110
- $realPath = $this->findImport($url);
111
-
112
- if ($realPath === null) return false;
113
-
114
- if ($this->importDisabled) {
115
- return array(false, "/* import disabled */");
116
- }
117
-
118
- if (isset($this->allParsedFiles[realpath($realPath)])) {
119
- return array(false, null);
120
- }
121
-
122
- $this->addParsedFile($realPath);
123
- $parser = $this->makeParser($realPath);
124
- $root = $parser->parse($GLOBALS['wp_filesystem']->get_contents($realPath));
125
-
126
- // set the parents of all the block props
127
- foreach ($root->props as $prop) {
128
- if ($prop[0] == "block") {
129
- $prop[1]->parent = $parentBlock;
130
- }
131
- }
132
-
133
- // copy mixins into scope, set their parents
134
- // bring blocks from import into current block
135
- // TODO: need to mark the source parser these came from this file
136
- foreach ($root->children as $childName => $child) {
137
- if (isset($parentBlock->children[$childName])) {
138
- $parentBlock->children[$childName] = array_merge(
139
- $parentBlock->children[$childName],
140
- $child);
141
- } else {
142
- $parentBlock->children[$childName] = $child;
143
- }
144
- }
145
-
146
- $pi = pathinfo($realPath);
147
- $dir = $pi["dirname"];
148
-
149
- list($top, $bottom) = $this->sortProps($root->props, true);
150
- $this->compileImportedProps($top, $parentBlock, $out, $parser, $dir);
151
-
152
- return array(true, $bottom, $parser, $dir);
153
- }
154
-
155
- protected function compileImportedProps($props, $block, $out, $sourceParser, $importDir) {
156
- $oldSourceParser = $this->sourceParser;
157
-
158
- $oldImport = $this->importDir;
159
-
160
- // TODO: this is because the importDir api is stupid
161
- $this->importDir = (array)$this->importDir;
162
- array_unshift($this->importDir, $importDir);
163
-
164
- foreach ($props as $prop) {
165
- $this->compileProp($prop, $block, $out);
166
- }
167
-
168
- $this->importDir = $oldImport;
169
- $this->sourceParser = $oldSourceParser;
170
- }
171
-
172
- /**
173
- * Recursively compiles a block.
174
- *
175
- * A block is analogous to a CSS block in most cases. A single LESS document
176
- * is encapsulated in a block when parsed, but it does not have parent tags
177
- * so all of it's children appear on the root level when compiled.
178
- *
179
- * Blocks are made up of props and children.
180
- *
181
- * Props are property instructions, array tuples which describe an action
182
- * to be taken, eg. write a property, set a variable, mixin a block.
183
- *
184
- * The children of a block are just all the blocks that are defined within.
185
- * This is used to look up mixins when performing a mixin.
186
- *
187
- * Compiling the block involves pushing a fresh environment on the stack,
188
- * and iterating through the props, compiling each one.
189
- *
190
- * See lessc::compileProp()
191
- *
192
- */
193
- protected function compileBlock($block) {
194
- switch ($block->type) {
195
- case "root":
196
- $this->compileRoot($block);
197
- break;
198
- case null:
199
- $this->compileCSSBlock($block);
200
- break;
201
- case "media":
202
- $this->compileMedia($block);
203
- break;
204
- case "directive":
205
- $name = "@" . $block->name;
206
- if (!empty($block->value)) {
207
- $name .= " " . $this->compileValue($this->reduce($block->value));
208
- }
209
-
210
- $this->compileNestedBlock($block, array($name));
211
- break;
212
- default:
213
- $this->throwError("unknown block type: $block->type\n");
214
- }
215
- }
216
-
217
- protected function compileCSSBlock($block) {
218
- $env = $this->pushEnv();
219
-
220
- $selectors = $this->compileSelectors($block->tags);
221
- $env->selectors = $this->multiplySelectors($selectors);
222
- $out = $this->makeOutputBlock(null, $env->selectors);
223
-
224
- $this->scope->children[] = $out;
225
- $this->compileProps($block, $out);
226
-
227
- $block->scope = $env; // mixins carry scope with them!
228
- $this->popEnv();
229
- }
230
-
231
- protected function compileMedia($media) {
232
- $env = $this->pushEnv($media);
233
- $parentScope = $this->mediaParent($this->scope);
234
-
235
- $query = $this->compileMediaQuery($this->multiplyMedia($env));
236
-
237
- $this->scope = $this->makeOutputBlock($media->type, array($query));
238
- $parentScope->children[] = $this->scope;
239
-
240
- $this->compileProps($media, $this->scope);
241
-
242
- if (count($this->scope->lines) > 0) {
243
- $orphanSelelectors = $this->findClosestSelectors();
244
- if (!is_null($orphanSelelectors)) {
245
- $orphan = $this->makeOutputBlock(null, $orphanSelelectors);
246
- $orphan->lines = $this->scope->lines;
247
- array_unshift($this->scope->children, $orphan);
248
- $this->scope->lines = array();
249
- }
250
- }
251
-
252
- $this->scope = $this->scope->parent;
253
- $this->popEnv();
254
- }
255
-
256
- protected function mediaParent($scope) {
257
- while (!empty($scope->parent)) {
258
- if (!empty($scope->type) && $scope->type != "media") {
259
- break;
260
- }
261
- $scope = $scope->parent;
262
- }
263
-
264
- return $scope;
265
- }
266
-
267
- protected function compileNestedBlock($block, $selectors) {
268
- $this->pushEnv($block);
269
- $this->scope = $this->makeOutputBlock($block->type, $selectors);
270
- $this->scope->parent->children[] = $this->scope;
271
-
272
- $this->compileProps($block, $this->scope);
273
-
274
- $this->scope = $this->scope->parent;
275
- $this->popEnv();
276
- }
277
-
278
- protected function compileRoot($root) {
279
- $this->pushEnv();
280
- $this->scope = $this->makeOutputBlock($root->type);
281
- $this->compileProps($root, $this->scope);
282
- $this->popEnv();
283
- }
284
-
285
- protected function compileProps($block, $out) {
286
- foreach ($this->sortProps($block->props) as $prop) {
287
- $this->compileProp($prop, $block, $out);
288
- }
289
-
290
- $out->lines = array_values(array_unique($out->lines));
291
- }
292
-
293
- protected function sortProps($props, $split = false) {
294
- $vars = array();
295
- $imports = array();
296
- $other = array();
297
-
298
- foreach ($props as $prop) {
299
- switch ($prop[0]) {
300
- case "assign":
301
- if (isset($prop[1][0]) && $prop[1][0] == $this->vPrefix) {
302
- $vars[] = $prop;
303
- } else {
304
- $other[] = $prop;
305
- }
306
- break;
307
- case "import":
308
- $id = self::$nextImportId++;
309
- $prop[] = $id;
310
- $imports[] = $prop;
311
- $other[] = array("import_mixin", $id);
312
- break;
313
- default:
314
- $other[] = $prop;
315
- }
316
- }
317
-
318
- if ($split) {
319
- return array(array_merge($vars, $imports), $other);
320
- } else {
321
- return array_merge($vars, $imports, $other);
322
- }
323
- }
324
-
325
- protected function compileMediaQuery($queries) {
326
- $compiledQueries = array();
327
- foreach ($queries as $query) {
328
- $parts = array();
329
- foreach ($query as $q) {
330
- switch ($q[0]) {
331
- case "mediaType":
332
- $parts[] = implode(" ", array_slice($q, 1));
333
- break;
334
- case "mediaExp":
335
- if (isset($q[2])) {
336
- $parts[] = "($q[1]: " .
337
- $this->compileValue($this->reduce($q[2])) . ")";
338
- } else {
339
- $parts[] = "($q[1])";
340
- }
341
- break;
342
- case "variable":
343
- $parts[] = $this->compileValue($this->reduce($q));
344
- break;
345
- }
346
- }
347
-
348
- if (count($parts) > 0) {
349
- $compiledQueries[] = implode(" and ", $parts);
350
- }
351
- }
352
-
353
- $out = "@media";
354
- if (!empty($parts)) {
355
- $out .= " " .
356
- implode($this->formatter->selectorSeparator, $compiledQueries);
357
- }
358
- return $out;
359
- }
360
-
361
- protected function multiplyMedia($env, $childQueries = null) {
362
- if (is_null($env) ||
363
- !empty($env->block->type) && $env->block->type != "media")
364
- {
365
- return $childQueries;
366
- }
367
-
368
- // plain old block, skip
369
- if (empty($env->block->type)) {
370
- return $this->multiplyMedia($env->parent, $childQueries);
371
- }
372
-
373
- $out = array();
374
- $queries = $env->block->queries;
375
- if (is_null($childQueries)) {
376
- $out = $queries;
377
- } else {
378
- foreach ($queries as $parent) {
379
- foreach ($childQueries as $child) {
380
- $out[] = array_merge($parent, $child);
381
- }
382
- }
383
- }
384
-
385
- return $this->multiplyMedia($env->parent, $out);
386
- }
387
-
388
- protected function expandParentSelectors(&$tag, $replace) {
389
- $parts = explode("$&$", $tag);
390
- $count = 0;
391
- foreach ($parts as &$part) {
392
- $part = str_replace($this->parentSelector, $replace, $part, $c);
393
- $count += $c;
394
- }
395
- $tag = implode($this->parentSelector, $parts);
396
- return $count;
397
- }
398
-
399
- protected function findClosestSelectors() {
400
- $env = $this->env;
401
- $selectors = null;
402
- while ($env !== null) {
403
- if (isset($env->selectors)) {
404
- $selectors = $env->selectors;
405
- break;
406
- }
407
- $env = $env->parent;
408
- }
409
-
410
- return $selectors;
411
- }
412
-
413
-
414
- // multiply $selectors against the nearest selectors in env
415
- protected function multiplySelectors($selectors) {
416
- // find parent selectors
417
-
418
- $parentSelectors = $this->findClosestSelectors();
419
- if (is_null($parentSelectors)) {
420
- // kill parent reference in top level selector
421
- foreach ($selectors as &$s) {
422
- $this->expandParentSelectors($s, "");
423
- }
424
-
425
- return $selectors;
426
- }
427
-
428
- $out = array();
429
- foreach ($parentSelectors as $parent) {
430
- foreach ($selectors as $child) {
431
- $count = $this->expandParentSelectors($child, $parent);
432
-
433
- // don't prepend the parent tag if & was used
434
- if ($count > 0) {
435
- $out[] = trim($child);
436
- } else {
437
- $out[] = trim($parent . ' ' . $child);
438
- }
439
- }
440
- }
441
-
442
- return $out;
443
- }
444
-
445
- // reduces selector expressions
446
- protected function compileSelectors($selectors) {
447
- $out = array();
448
-
449
- foreach ($selectors as $s) {
450
- if (is_array($s)) {
451
- list(, $value) = $s;
452
- $out[] = trim($this->compileValue($this->reduce($value)));
453
- } else {
454
- $out[] = $s;
455
- }
456
- }
457
-
458
- return $out;
459
- }
460
-
461
- protected function eq($left, $right) {
462
- return $left == $right;
463
- }
464
-
465
- protected function patternMatch($block, $orderedArgs, $keywordArgs) {
466
- // match the guards if it has them
467
- // any one of the groups must have all its guards pass for a match
468
- if (!empty($block->guards)) {
469
- $groupPassed = false;
470
- foreach ($block->guards as $guardGroup) {
471
- foreach ($guardGroup as $guard) {
472
- $this->pushEnv();
473
- $this->zipSetArgs($block->args, $orderedArgs, $keywordArgs);
474
-
475
- $negate = false;
476
- if ($guard[0] == "negate") {
477
- $guard = $guard[1];
478
- $negate = true;
479
- }
480
-
481
- $passed = $this->reduce($guard) == self::$TRUE;
482
- if ($negate) $passed = !$passed;
483
-
484
- $this->popEnv();
485
-
486
- if ($passed) {
487
- $groupPassed = true;
488
- } else {
489
- $groupPassed = false;
490
- break;
491
- }
492
- }
493
-
494
- if ($groupPassed) break;
495
- }
496
-
497
- if (!$groupPassed) {
498
- return false;
499
- }
500
- }
501
-
502
- if (empty($block->args)) {
503
- return $block->isVararg || empty($orderedArgs) && empty($keywordArgs);
504
- }
505
-
506
- $remainingArgs = $block->args;
507
- if ($keywordArgs) {
508
- $remainingArgs = array();
509
- foreach ($block->args as $arg) {
510
- if ($arg[0] == "arg" && isset($keywordArgs[$arg[1]])) {
511
- continue;
512
- }
513
-
514
- $remainingArgs[] = $arg;
515
- }
516
- }
517
-
518
- $i = -1; // no args
519
- // try to match by arity or by argument literal
520
- foreach ($remainingArgs as $i => $arg) {
521
- switch ($arg[0]) {
522
- case "lit":
523
- if (empty($orderedArgs[$i]) || !$this->eq($arg[1], $orderedArgs[$i])) {
524
- return false;
525
- }
526
- break;
527
- case "arg":
528
- // no arg and no default value
529
- if (!isset($orderedArgs[$i]) && !isset($arg[2])) {
530
- return false;
531
- }
532
- break;
533
- case "rest":
534
- $i--; // rest can be empty
535
- break 2;
536
- }
537
- }
538
-
539
- if ($block->isVararg) {
540
- return true; // not having enough is handled above
541
- } else {
542
- $numMatched = $i + 1;
543
- // greater than becuase default values always match
544
- return $numMatched >= count($orderedArgs);
545
- }
546
- }
547
-
548
- protected function patternMatchAll($blocks, $orderedArgs, $keywordArgs, $skip=array()) {
549
- $matches = null;
550
- foreach ($blocks as $block) {
551
- // skip seen blocks that don't have arguments
552
- if (isset($skip[$block->id]) && !isset($block->args)) {
553
- continue;
554
- }
555
-
556
- if ($this->patternMatch($block, $orderedArgs, $keywordArgs)) {
557
- $matches[] = $block;
558
- }
559
- }
560
-
561
- return $matches;
562
- }
563
-
564
- // attempt to find blocks matched by path and args
565
- protected function findBlocks($searchIn, $path, $orderedArgs, $keywordArgs, $seen=array()) {
566
- if ($searchIn == null) return null;
567
- if (isset($seen[$searchIn->id])) return null;
568
- $seen[$searchIn->id] = true;
569
-
570
- $name = $path[0];
571
-
572
- if (isset($searchIn->children[$name])) {
573
- $blocks = $searchIn->children[$name];
574
- if (count($path) == 1) {
575
- $matches = $this->patternMatchAll($blocks, $orderedArgs, $keywordArgs, $seen);
576
- if (!empty($matches)) {
577
- // This will return all blocks that match in the closest
578
- // scope that has any matching block, like lessjs
579
- return $matches;
580
- }
581
- } else {
582
- $matches = array();
583
- foreach ($blocks as $subBlock) {
584
- $subMatches = $this->findBlocks($subBlock,
585
- array_slice($path, 1), $orderedArgs, $keywordArgs, $seen);
586
-
587
- if (!is_null($subMatches)) {
588
- foreach ($subMatches as $sm) {
589
- $matches[] = $sm;
590
- }
591
- }
592
- }
593
-
594
- return count($matches) > 0 ? $matches : null;
595
- }
596
- }
597
- if ($searchIn->parent === $searchIn) return null;
598
- return $this->findBlocks($searchIn->parent, $path, $orderedArgs, $keywordArgs, $seen);
599
- }
600
-
601
- // sets all argument names in $args to either the default value
602
- // or the one passed in through $values
603
- protected function zipSetArgs($args, $orderedValues, $keywordValues) {
604
- $assignedValues = array();
605
-
606
- $i = 0;
607
- foreach ($args as $a) {
608
- if ($a[0] == "arg") {
609
- if (isset($keywordValues[$a[1]])) {
610
- // has keyword arg
611
- $value = $keywordValues[$a[1]];
612
- } elseif (isset($orderedValues[$i])) {
613
- // has ordered arg
614
- $value = $orderedValues[$i];
615
- $i++;
616
- } elseif (isset($a[2])) {
617
- // has default value
618
- $value = $a[2];
619
- } else {
620
- $this->throwError("Failed to assign arg " . $a[1]);
621
- $value = null; // :(
622
- }
623
-
624
- $value = $this->reduce($value);
625
- $this->set($a[1], $value);
626
- $assignedValues[] = $value;
627
- } else {
628
- // a lit
629
- $i++;
630
- }
631
- }
632
-
633
- // check for a rest
634
- $last = (array) end($args);
635
- if ($last[0] == "rest") {
636
- $rest = array_slice($orderedValues, count($args) - 1);
637
- $this->set($last[1], $this->reduce(array("list", " ", $rest)));
638
- }
639
-
640
- // wow is this the only true use of PHP's + operator for arrays?
641
- $this->env->arguments = $assignedValues + $orderedValues;
642
- }
643
-
644
- // compile a prop and update $lines or $blocks appropriately
645
- protected function compileProp($prop, $block, $out) {
646
- // set error position context
647
- $this->sourceLoc = isset($prop[-1]) ? $prop[-1] : -1;
648
-
649
- switch ($prop[0]) {
650
- case 'assign':
651
- list(, $name, $value) = $prop;
652
- if ($name[0] == $this->vPrefix) {
653
- $this->set($name, $value);
654
- } else {
655
- $out->lines[] = $this->formatter->property($name,
656
- $this->compileValue($this->reduce($value)));
657
- }
658
- break;
659
- case 'block':
660
- list(, $child) = $prop;
661
- $this->compileBlock($child);
662
- break;
663
- case 'mixin':
664
- list(, $path, $args, $suffix) = $prop;
665
-
666
- $orderedArgs = array();
667
- $keywordArgs = array();
668
- foreach ((array)$args as $arg) {
669
- $argval = null;
670
- switch ($arg[0]) {
671
- case "arg":
672
- if (!isset($arg[2])) {
673
- $orderedArgs[] = $this->reduce(array("variable", $arg[1]));
674
- } else {
675
- $keywordArgs[$arg[1]] = $this->reduce($arg[2]);
676
- }
677
- break;
678
-
679
- case "lit":
680
- $orderedArgs[] = $this->reduce($arg[1]);
681
- break;
682
- default:
683
- $this->throwError("Unknown arg type: " . $arg[0]);
684
- }
685
- }
686
-
687
- $mixins = $this->findBlocks($block, $path, $orderedArgs, $keywordArgs);
688
-
689
- if ($mixins === null) {
690
- break; // throw error here??
691
- }
692
-
693
- foreach ($mixins as $mixin) {
694
- if ($mixin === $block && !$orderedArgs) {
695
- continue;
696
- }
697
-
698
- $haveScope = false;
699
- if (isset($mixin->parent->scope)) {
700
- $haveScope = true;
701
- $mixinParentEnv = $this->pushEnv();
702
- $mixinParentEnv->storeParent = $mixin->parent->scope;
703
- }
704
-
705
- $haveArgs = false;
706
- if (isset($mixin->args)) {
707
- $haveArgs = true;
708
- $this->pushEnv();
709
- $this->zipSetArgs($mixin->args, $orderedArgs, $keywordArgs);
710
- }
711
-
712
- $oldParent = $mixin->parent;
713
- if ($mixin != $block) $mixin->parent = $block;
714
-
715
- foreach ($this->sortProps($mixin->props) as $subProp) {
716
- if ($suffix !== null &&
717
- $subProp[0] == "assign" &&
718
- is_string($subProp[1]) &&
719
- $subProp[1][0] != $this->vPrefix)
720
- {
721
- $subProp[2] = array(
722
- 'list', ' ',
723
- array($subProp[2], array('keyword', $suffix))
724
- );
725
- }
726
-
727
- $this->compileProp($subProp, $mixin, $out);
728
- }
729
-
730
- $mixin->parent = $oldParent;
731
-
732
- if ($haveArgs) $this->popEnv();
733
- if ($haveScope) $this->popEnv();
734
- }
735
-
736
- break;
737
- case 'raw':
738
- $out->lines[] = $prop[1];
739
- break;
740
- case "directive":
741
- list(, $name, $value) = $prop;
742
- $out->lines[] = "@$name " . $this->compileValue($this->reduce($value)).';';
743
- break;
744
- case "comment":
745
- $out->lines[] = $prop[1];
746
- break;
747
- case "import";
748
- list(, $importPath, $importId) = $prop;
749
- $importPath = $this->reduce($importPath);
750
-
751
- if (!isset($this->env->imports)) {
752
- $this->env->imports = array();
753
- }
754
-
755
- $result = $this->tryImport($importPath, $block, $out);
756
-
757
- $this->env->imports[$importId] = $result === false ?
758
- array(false, "@import " . $this->compileValue($importPath).";") :
759
- $result;
760
-
761
- break;
762
- case "import_mixin":
763
- list(,$importId) = $prop;
764
- $import = $this->env->imports[$importId];
765
- if ($import[0] === false) {
766
- if (isset($import[1])) {
767
- $out->lines[] = $import[1];
768
- }
769
- } else {
770
- list(, $bottom, $parser, $importDir) = $import;
771
- $this->compileImportedProps($bottom, $block, $out, $parser, $importDir);
772
- }
773
-
774
- break;
775
- default:
776
- $this->throwError("unknown op: {$prop[0]}\n");
777
- }
778
- }
779
-
780
-
781
- /**
782
- * Compiles a primitive value into a CSS property value.
783
- *
784
- * Values in lessphp are typed by being wrapped in arrays, their format is
785
- * typically:
786
- *
787
- * array(type, contents [, additional_contents]*)
788
- *
789
- * The input is expected to be reduced. This function will not work on
790
- * things like expressions and variables.
791
- */
792
- protected function compileValue($value) {
793
- switch ($value[0]) {
794
- case 'list':
795
- // [1] - delimiter
796
- // [2] - array of values
797
- return implode($value[1], array_map(array($this, 'compileValue'), $value[2]));
798
- case 'raw_color':
799
- if (!empty($this->formatter->compressColors)) {
800
- return $this->compileValue($this->coerceColor($value));
801
- }
802
- return $value[1];
803
- case 'keyword':
804
- // [1] - the keyword
805
- return $value[1];
806
- case 'number':
807
- list(, $num, $unit) = $value;
808
- // [1] - the number
809
- // [2] - the unit
810
- if ($this->numberPrecision !== null) {
811
- $num = round($num, $this->numberPrecision);
812
- }
813
- return $num . $unit;
814
- case 'string':
815
- // [1] - contents of string (includes quotes)
816
- list(, $delim, $content) = $value;
817
- foreach ($content as &$part) {
818
- if (is_array($part)) {
819
- $part = $this->compileValue($part);
820
- }
821
- }
822
- return $delim . implode($content) . $delim;
823
- case 'color':
824
- // [1] - red component (either number or a %)
825
- // [2] - green component
826
- // [3] - blue component
827
- // [4] - optional alpha component
828
- list(, $r, $g, $b) = $value;
829
- $r = round($r);
830
- $g = round($g);
831
- $b = round($b);
832
-
833
- if (count($value) == 5 && $value[4] != 1) { // rgba
834
- return 'rgba('.$r.','.$g.','.$b.','.$value[4].')';
835
- }
836
-
837
- $h = sprintf("#%02x%02x%02x", $r, $g, $b);
838
-
839
- if (!empty($this->formatter->compressColors)) {
840
- // Converting hex color to short notation (e.g. #003399 to #039)
841
- if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) {
842
- $h = '#' . $h[1] . $h[3] . $h[5];
843
- }
844
- }
845
-
846
- return $h;
847
-
848
- case 'function':
849
- list(, $name, $args) = $value;
850
- return $name.'('.$this->compileValue($args).')';
851
- default: // assumed to be unit
852
- $this->throwError("unknown value type: $value[0]");
853
- }
854
- }
855
-
856
- protected function lib_pow($args) {
857
- list($base, $exp) = $this->assertArgs($args, 2, "pow");
858
- return pow($this->assertNumber($base), $this->assertNumber($exp));
859
- }
860
-
861
- protected function lib_pi() {
862
- return pi();
863
- }
864
-
865
- protected function lib_mod($args) {
866
- list($a, $b) = $this->assertArgs($args, 2, "mod");
867
- return $this->assertNumber($a) % $this->assertNumber($b);
868
- }
869
-
870
- protected function lib_tan($num) {
871
- return tan($this->assertNumber($num));
872
- }
873
-
874
- protected function lib_sin($num) {
875
- return sin($this->assertNumber($num));
876
- }
877
-
878
- protected function lib_cos($num) {
879
- return cos($this->assertNumber($num));
880
- }
881
-
882
- protected function lib_atan($num) {
883
- $num = atan($this->assertNumber($num));
884
- return array("number", $num, "rad");
885
- }
886
-
887
- protected function lib_asin($num) {
888
- $num = asin($this->assertNumber($num));
889
- return array("number", $num, "rad");
890
- }
891
-
892
- protected function lib_acos($num) {
893
- $num = acos($this->assertNumber($num));
894
- return array("number", $num, "rad");
895
- }
896
-
897
- protected function lib_sqrt($num) {
898
- return sqrt($this->assertNumber($num));
899
- }
900
-
901
- protected function lib_extract($value) {
902
- list($list, $idx) = $this->assertArgs($value, 2, "extract");
903
- $idx = $this->assertNumber($idx);
904
- // 1 indexed
905
- if ($list[0] == "list" && isset($list[2][$idx - 1])) {
906
- return $list[2][$idx - 1];
907
- }
908
- }
909
-
910
- protected function lib_isnumber($value) {
911
- return $this->toBool($value[0] == "number");
912
- }
913
-
914
- protected function lib_isstring($value) {
915
- return $this->toBool($value[0] == "string");
916
- }
917
-
918
- protected function lib_iscolor($value) {
919
- return $this->toBool($this->coerceColor($value));
920
- }
921
-
922
- protected function lib_iskeyword($value) {
923
- return $this->toBool($value[0] == "keyword");
924
- }
925
-
926
- protected function lib_ispixel($value) {
927
- return $this->toBool($value[0] == "number" && $value[2] == "px");
928
- }
929
-
930
- protected function lib_ispercentage($value) {
931
- return $this->toBool($value[0] == "number" && $value[2] == "%");
932
- }
933
-
934
- protected function lib_isem($value) {
935
- return $this->toBool($value[0] == "number" && $value[2] == "em");
936
- }
937
-
938
- protected function lib_isrem($value) {
939
- return $this->toBool($value[0] == "number" && $value[2] == "rem");
940
- }
941
-
942
- protected function lib_rgbahex($color) {
943
- $color = $this->coerceColor($color);
944
- if (is_null($color))
945
- $this->throwError("color expected for rgbahex");
946
-
947
- return sprintf("#%02x%02x%02x%02x",
948
- isset($color[4]) ? $color[4]*255 : 255,
949
- $color[1],$color[2], $color[3]);
950
- }
951
-
952
- protected function lib_argb($color){
953
- return $this->lib_rgbahex($color);
954
- }
955
-
956
- // utility func to unquote a string
957
- // use func_get_arg to prevent Theme Checker triggering unrelated translation warning.
958
- protected function lib_e() {
959
- $arg = func_get_arg(0);
960
- switch ($arg[0]) {
961
- case "list":
962
- $items = $arg[2];
963
- if (isset($items[0])) {
964
- return $this->lib_unquote($items[0]);
965
- }
966
- return self::$defaultValue;
967
- case "string":
968
- $arg[1] = "";
969
- return $arg;
970
- case "keyword":
971
- return $arg;
972
- default:
973
- return array("keyword", $this->compileValue($arg));
974
- }
975
- }
976
-
977
- // use func_get_arg to prevent Theme Checker triggering unrelated translation warning.
978
- protected function lib_unquote($arg) {
979
- return $this->lib_e(func_get_arg(0));
980
- }
981
-
982
- protected function lib__sprintf($args) {
983
- if ($args[0] != "list") return $args;
984
- $values = $args[2];
985
- $string = array_shift($values);
986
- $template = $this->compileValue($this->lib_unquote($string));
987
-
988
- $i = 0;
989
- if (preg_match_all('/%[dsa]/', $template, $m)) {
990
- foreach ($m[0] as $match) {
991
- $val = isset($values[$i]) ?
992
- $this->reduce($values[$i]) : array('keyword', '');
993
-
994
- // lessjs compat, renders fully expanded color, not raw color
995
- if ($color = $this->coerceColor($val)) {
996
- $val = $color;
997
- }
998
-
999
- $i++;
1000
- $rep = $this->compileValue($this->lib_unquote($val));
1001
- $template = preg_replace('/'.self::preg_quote($match).'/',
1002
- $rep, $template, 1);
1003
- }
1004
- }
1005
-
1006
- $d = $string[0] == "string" ? $string[1] : '"';
1007
- return array("string", $d, array($template));
1008
- }
1009
-
1010
- protected function lib_floor($arg) {
1011
- $value = $this->assertNumber($arg);
1012
- return array("number", floor($value), $arg[2]);
1013
- }
1014
-
1015
- protected function lib_ceil($arg) {
1016
- $value = $this->assertNumber($arg);
1017
- return array("number", ceil($value), $arg[2]);
1018
- }
1019
-
1020
- protected function lib_round($arg) {
1021
- $value = $this->assertNumber($arg);
1022
- return array("number", round($value), $arg[2]);
1023
- }
1024
-
1025
- protected function lib_unit($arg) {
1026
- if ($arg[0] == "list") {
1027
- list($number, $newUnit) = $arg[2];
1028
- return array("number", $this->assertNumber($number),
1029
- $this->compileValue($this->lib_unquote($newUnit)));
1030
- } else {
1031
- return array("number", $this->assertNumber($arg), "");
1032
- }
1033
- }
1034
-
1035
- /**
1036
- * Helper function to get arguments for color manipulation functions.
1037
- * takes a list that contains a color like thing and a percentage
1038
- */
1039
- protected function colorArgs($args) {
1040
- if ($args[0] != 'list' || count($args[2]) < 2) {
1041
- return array(array('color', 0, 0, 0), 0);
1042
- }
1043
- list($color, $delta) = $args[2];
1044
- $color = $this->assertColor($color);
1045
- $delta = floatval($delta[1]);
1046
-
1047
- return array($color, $delta);
1048
- }
1049
-
1050
- protected function lib_darken($args) {
1051
- list($color, $delta) = $this->colorArgs($args);
1052
-
1053
- $hsl = $this->toHSL($color);
1054
- $hsl[3] = $this->clamp($hsl[3] - $delta, 100);
1055
- return $this->toRGB($hsl);
1056
- }
1057
-
1058
- protected function lib_lighten($args) {
1059
- list($color, $delta) = $this->colorArgs($args);
1060
-
1061
- $hsl = $this->toHSL($color);
1062
- $hsl[3] = $this->clamp($hsl[3] + $delta, 100);
1063
- return $this->toRGB($hsl);
1064
- }
1065
-
1066
- protected function lib_saturate($args) {
1067
- list($color, $delta) = $this->colorArgs($args);
1068
-
1069
- $hsl = $this->toHSL($color);
1070
- $hsl[2] = $this->clamp($hsl[2] + $delta, 100);
1071
- return $this->toRGB($hsl);
1072
- }
1073
-
1074
- protected function lib_desaturate($args) {
1075
- list($color, $delta) = $this->colorArgs($args);
1076
-
1077
- $hsl = $this->toHSL($color);
1078
- $hsl[2] = $this->clamp($hsl[2] - $delta, 100);
1079
- return $this->toRGB($hsl);
1080
- }
1081
-
1082
- protected function lib_spin($args) {
1083
- list($color, $delta) = $this->colorArgs($args);
1084
-
1085
- $hsl = $this->toHSL($color);
1086
-
1087
- $hsl[1] = $hsl[1] + $delta % 360;
1088
- if ($hsl[1] < 0) $hsl[1] += 360;
1089
-
1090
- return $this->toRGB($hsl);
1091
- }
1092
-
1093
- protected function lib_fadeout($args) {
1094
- list($color, $delta) = $this->colorArgs($args);
1095
- $color[4] = $this->clamp((isset($color[4]) ? $color[4] : 1) - $delta/100);
1096
- return $color;
1097
- }
1098
-
1099
- protected function lib_fadein($args) {
1100
- list($color, $delta) = $this->colorArgs($args);
1101
- $color[4] = $this->clamp((isset($color[4]) ? $color[4] : 1) + $delta/100);
1102
- return $color;
1103
- }
1104
-
1105
- protected function lib_hue($color) {
1106
- $hsl = $this->toHSL($this->assertColor($color));
1107
- return round($hsl[1]);
1108
- }
1109
-
1110
- protected function lib_saturation($color) {
1111
- $hsl = $this->toHSL($this->assertColor($color));
1112
- return round($hsl[2]);
1113
- }
1114
-
1115
- protected function lib_lightness($color) {
1116
- $hsl = $this->toHSL($this->assertColor($color));
1117
- return round($hsl[3]);
1118
- }
1119
-
1120
- // get the alpha of a color
1121
- // defaults to 1 for non-colors or colors without an alpha
1122
- protected function lib_alpha($value) {
1123
- if (!is_null($color = $this->coerceColor($value))) {
1124
- return isset($color[4]) ? $color[4] : 1;
1125
- }
1126
- }
1127
-
1128
- // set the alpha of the color
1129
- protected function lib_fade($args) {
1130
- list($color, $alpha) = $this->colorArgs($args);
1131
- $color[4] = $this->clamp($alpha / 100.0);
1132
- return $color;
1133
- }
1134
-
1135
- protected function lib_percentage($arg) {
1136
- $num = $this->assertNumber($arg);
1137
- return array("number", $num*100, "%");
1138
- }
1139
-
1140
- // mixes two colors by weight
1141
- // mix(@color1, @color2, [@weight: 50%]);
1142
- // http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#mix-instance_method
1143
- protected function lib_mix($args) {
1144
- if ($args[0] != "list" || count($args[2]) < 2)
1145
- $this->throwError("mix expects (color1, color2, weight)");
1146
-
1147
- list($first, $second) = $args[2];
1148
- $first = $this->assertColor($first);
1149
- $second = $this->assertColor($second);
1150
-
1151
- $first_a = $this->lib_alpha($first);
1152
- $second_a = $this->lib_alpha($second);
1153
-
1154
- if (isset($args[2][2])) {
1155
- $weight = $args[2][2][1] / 100.0;
1156
- } else {
1157
- $weight = 0.5;
1158
- }
1159
-
1160
- $w = $weight * 2 - 1;
1161
- $a = $first_a - $second_a;
1162
-
1163
- $w1 = (($w * $a == -1 ? $w : ($w + $a)/(1 + $w * $a)) + 1) / 2.0;
1164
- $w2 = 1.0 - $w1;
1165
-
1166
- $new = array('color',
1167
- $w1 * $first[1] + $w2 * $second[1],
1168
- $w1 * $first[2] + $w2 * $second[2],
1169
- $w1 * $first[3] + $w2 * $second[3],
1170
- );
1171
-
1172
- if ($first_a != 1.0 || $second_a != 1.0) {
1173
- $new[] = $first_a * $weight + $second_a * ($weight - 1);
1174
- }
1175
-
1176
- return $this->fixColor($new);
1177
- }
1178
-
1179
- protected function lib_contrast($args) {
1180
- if ($args[0] != 'list' || count($args[2]) < 3) {
1181
- return array(array('color', 0, 0, 0), 0);
1182
- }
1183
-
1184
- list($inputColor, $darkColor, $lightColor) = $args[2];
1185
-
1186
- $inputColor = $this->assertColor($inputColor);
1187
- $darkColor = $this->assertColor($darkColor);
1188
- $lightColor = $this->assertColor($lightColor);
1189
- $hsl = $this->toHSL($inputColor);
1190
-
1191
- if ($hsl[3] > 50) {
1192
- return $darkColor;
1193
- }
1194
-
1195
- return $lightColor;
1196
- }
1197
-
1198
- protected function assertColor($value, $error = "expected color value") {
1199
- $color = $this->coerceColor($value);
1200
- if (is_null($color)) $this->throwError($error);
1201
- return $color;
1202
- }
1203
-
1204
- protected function assertNumber($value, $error = "expecting number") {
1205
- if ($value[0] == "number") return $value[1];
1206
- $this->throwError($error);
1207
- }
1208
-
1209
- protected function assertArgs($value, $expectedArgs, $name="") {
1210
- if ($expectedArgs == 1) {
1211
- return $value;
1212
- } else {
1213
- if ($value[0] !== "list" || $value[1] != ",") $this->throwError("expecting list");
1214
- $values = $value[2];
1215
- $numValues = count($values);
1216
- if ($expectedArgs != $numValues) {
1217
- if ($name) {
1218
- $name = $name . ": ";
1219
- }
1220
-
1221
- $this->throwError("${name}expecting $expectedArgs arguments, got $numValues");
1222
- }
1223
-
1224
- return $values;
1225
- }
1226
- }
1227
-
1228
- protected function toHSL($color) {
1229
- if ($color[0] == 'hsl') return $color;
1230
-
1231
- $r = $color[1] / 255;
1232
- $g = $color[2] / 255;
1233
- $b = $color[3] / 255;
1234
-
1235
- $min = min($r, $g, $b);
1236
- $max = max($r, $g, $b);
1237
-
1238
- $L = ($min + $max) / 2;
1239
- if ($min == $max) {
1240
- $S = $H = 0;
1241
- } else {
1242
- if ($L < 0.5)
1243
- $S = ($max - $min)/($max + $min);
1244
- else
1245
- $S = ($max - $min)/(2.0 - $max - $min);
1246
-
1247
- if ($r == $max) $H = ($g - $b)/($max - $min);
1248
- elseif ($g == $max) $H = 2.0 + ($b - $r)/($max - $min);
1249
- elseif ($b == $max) $H = 4.0 + ($r - $g)/($max - $min);
1250
-
1251
- }
1252
-
1253
- $out = array('hsl',
1254
- ($H < 0 ? $H + 6 : $H)*60,
1255
- $S*100,
1256
- $L*100,
1257
- );
1258
-
1259
- if (count($color) > 4) $out[] = $color[4]; // copy alpha
1260
- return $out;
1261
- }
1262
-
1263
- protected function toRGB_helper($comp, $temp1, $temp2) {
1264
- if ($comp < 0) $comp += 1.0;
1265
- elseif ($comp > 1) $comp -= 1.0;
1266
-
1267
- if (6 * $comp < 1) return $temp1 + ($temp2 - $temp1) * 6 * $comp;
1268
- if (2 * $comp < 1) return $temp2;
1269
- if (3 * $comp < 2) return $temp1 + ($temp2 - $temp1)*((2/3) - $comp) * 6;
1270
-
1271
- return $temp1;
1272
- }
1273
-
1274
- /**
1275
- * Converts a hsl array into a color value in rgb.
1276
- * Expects H to be in range of 0 to 360, S and L in 0 to 100
1277
- */
1278
- protected function toRGB($color) {
1279
- if ($color[0] == 'color') return $color;
1280
-
1281
- $H = $color[1] / 360;
1282
- $S = $color[2] / 100;
1283
- $L = $color[3] / 100;
1284
-
1285
- if ($S == 0) {
1286
- $r = $g = $b = $L;
1287
- } else {
1288
- $temp2 = $L < 0.5 ?
1289
- $L*(1.0 + $S) :
1290
- $L + $S - $L * $S;
1291
-
1292
- $temp1 = 2.0 * $L - $temp2;
1293
-
1294
- $r = $this->toRGB_helper($H + 1/3, $temp1, $temp2);
1295
- $g = $this->toRGB_helper($H, $temp1, $temp2);
1296
- $b = $this->toRGB_helper($H - 1/3, $temp1, $temp2);
1297
- }
1298
-
1299
- // $out = array('color', round($r*255), round($g*255), round($b*255));
1300
- $out = array('color', $r*255, $g*255, $b*255);
1301
- if (count($color) > 4) $out[] = $color[4]; // copy alpha
1302
- return $out;
1303
- }
1304
-
1305
- protected function clamp($v, $max = 1, $min = 0) {
1306
- return min($max, max($min, $v));
1307
- }
1308
-
1309
- /**
1310
- * Convert the rgb, rgba, hsl color literals of function type
1311
- * as returned by the parser into values of color type.
1312
- */
1313
- protected function funcToColor($func) {
1314
- $fname = $func[1];
1315
- if ($func[2][0] != 'list') return false; // need a list of arguments
1316
- $rawComponents = $func[2][2];
1317
-
1318
- if ($fname == 'hsl' || $fname == 'hsla') {
1319
- $hsl = array('hsl');
1320
- $i = 0;
1321
- foreach ($rawComponents as $c) {
1322
- $val = $this->reduce($c);
1323
- $val = isset($val[1]) ? floatval($val[1]) : 0;
1324
-
1325
- if ($i == 0) $clamp = 360;
1326
- elseif ($i < 3) $clamp = 100;
1327
- else $clamp = 1;
1328
-
1329
- $hsl[] = $this->clamp($val, $clamp);
1330
- $i++;
1331
- }
1332
-
1333
- while (count($hsl) < 4) $hsl[] = 0;
1334
- return $this->toRGB($hsl);
1335
-
1336
- } elseif ($fname == 'rgb' || $fname == 'rgba') {
1337
- $components = array();
1338
- $i = 1;
1339
- foreach ($rawComponents as $c) {
1340
- $c = $this->reduce($c);
1341
- if ($i < 4) {
1342
- if ($c[0] == "number" && $c[2] == "%") {
1343
- $components[] = 255 * ($c[1] / 100);
1344
- } else {
1345
- $components[] = floatval($c[1]);
1346
- }
1347
- } elseif ($i == 4) {
1348
- if ($c[0] == "number" && $c[2] == "%") {
1349
- $components[] = 1.0 * ($c[1] / 100);
1350
- } else {
1351
- $components[] = floatval($c[1]);
1352
- }
1353
- } else break;
1354
-
1355
- $i++;
1356
- }
1357
- while (count($components) < 3) $components[] = 0;
1358
- array_unshift($components, 'color');
1359
- return $this->fixColor($components);
1360
- }
1361
-
1362
- return false;
1363
- }
1364
-
1365
- protected function reduce($value, $forExpression = false) {
1366
- switch ($value[0]) {
1367
- case "interpolate":
1368
- $reduced = $this->reduce($value[1]);
1369
- $var = $this->compileValue($reduced);
1370
- $res = $this->reduce(array("variable", $this->vPrefix . $var));
1371
-
1372
- if ($res[0] == "raw_color") {
1373
- $res = $this->coerceColor($res);
1374
- }
1375
-
1376
- if (empty($value[2])) $res = $this->lib_unquote($res);
1377
-
1378
- return $res;
1379
- case "variable":
1380
- $key = $value[1];
1381
- if (is_array($key)) {
1382
- $key = $this->reduce($key);
1383
- $key = $this->vPrefix . $this->compileValue($this->lib_unquote($key));
1384
- }
1385
-
1386
- $seen =& $this->env->seenNames;
1387
-
1388
- if (!empty($seen[$key])) {
1389
- $this->throwError("infinite loop detected: $key");
1390
- }
1391
-
1392
- $seen[$key] = true;
1393
- $out = $this->reduce($this->get($key, self::$defaultValue));
1394
- $seen[$key] = false;
1395
- return $out;
1396
- case "list":
1397
- foreach ($value[2] as &$item) {
1398
- $item = $this->reduce($item, $forExpression);
1399
- }
1400
- return $value;
1401
- case "expression":
1402
- return $this->evaluate($value);
1403
- case "string":
1404
- foreach ($value[2] as &$part) {
1405
- if (is_array($part)) {
1406
- $strip = $part[0] == "variable";
1407
- $part = $this->reduce($part);
1408
- if ($strip) $part = $this->lib_unquote($part);
1409
- }
1410
- }
1411
- return $value;
1412
- case "escape":
1413
- list(,$inner) = $value;
1414
- return $this->lib_unquote($this->reduce($inner));
1415
- case "function":
1416
- $color = $this->funcToColor($value);
1417
- if ($color) return $color;
1418
-
1419
- list(, $name, $args) = $value;
1420
- if ($name == "%") $name = "_sprintf";
1421
- $f = isset($this->libFunctions[$name]) ?
1422
- $this->libFunctions[$name] : array($this, 'lib_'.$name);
1423
-
1424
- if (is_callable($f)) {
1425
- if ($args[0] == 'list')
1426
- $args = self::compressList($args[2], $args[1]);
1427
-
1428
- $ret = call_user_func($f, $this->reduce($args, true), $this);
1429
-
1430
- if (is_null($ret)) {
1431
- return array("string", "", array(
1432
- $name, "(", $args, ")"
1433
- ));
1434
- }
1435
-
1436
- // convert to a typed value if the result is a php primitive
1437
- if (is_numeric($ret)) $ret = array('number', $ret, "");
1438
- elseif (!is_array($ret)) $ret = array('keyword', $ret);
1439
-
1440
- return $ret;
1441
- }
1442
-
1443
- // plain function, reduce args
1444
- $value[2] = $this->reduce($value[2]);
1445
- return $value;
1446
- case "unary":
1447
- list(, $op, $exp) = $value;
1448
- $exp = $this->reduce($exp);
1449
-
1450
- if ($exp[0] == "number") {
1451
- switch ($op) {
1452
- case "+":
1453
- return $exp;
1454
- case "-":
1455
- $exp[1] *= -1;
1456
- return $exp;
1457
- }
1458
- }
1459
- return array("string", "", array($op, $exp));
1460
- }
1461
-
1462
- if ($forExpression) {
1463
- switch ($value[0]) {
1464
- case "keyword":
1465
- if ($color = $this->coerceColor($value)) {
1466
- return $color;
1467
- }
1468
- break;
1469
- case "raw_color":
1470
- return $this->coerceColor($value);
1471
- }
1472
- }
1473
-
1474
- return $value;
1475
- }
1476
-
1477
-
1478
- // coerce a value for use in color operation
1479
- protected function coerceColor($value) {
1480
- switch($value[0]) {
1481
- case 'color': return $value;
1482
- case 'raw_color':
1483
- $c = array("color", 0, 0, 0);
1484
- $colorStr = substr($value[1], 1);
1485
- $num = hexdec($colorStr);
1486
- $width = strlen($colorStr) == 3 ? 16 : 256;
1487
-
1488
- for ($i = 3; $i > 0; $i--) { // 3 2 1
1489
- $t = $num % $width;
1490
- $num /= $width;
1491
-
1492
- $c[$i] = $t * (256/$width) + $t * floor(16/$width);
1493
- }
1494
-
1495
- return $c;
1496
- case 'keyword':
1497
- $name = $value[1];
1498
- if (isset(self::$cssColors[$name])) {
1499
- $rgba = explode(',', self::$cssColors[$name]);
1500
-
1501
- if(isset($rgba[3]))
1502
- return array('color', $rgba[0], $rgba[1], $rgba[2], $rgba[3]);
1503
-
1504
- return array('color', $rgba[0], $rgba[1], $rgba[2]);
1505
- }
1506
- return null;
1507
- }
1508
- }
1509
-
1510
- // make something string like into a string
1511
- protected function coerceString($value) {
1512
- switch ($value[0]) {
1513
- case "string":
1514
- return $value;
1515
- case "keyword":
1516
- return array("string", "", array($value[1]));
1517
- }
1518
- return null;
1519
- }
1520
-
1521
- // turn list of length 1 into value type
1522
- protected function flattenList($value) {
1523
- if ($value[0] == "list" && count($value[2]) == 1) {
1524
- return $this->flattenList($value[2][0]);
1525
- }
1526
- return $value;
1527
- }
1528
-
1529
- protected function toBool($a) {
1530
- if ($a) return self::$TRUE;
1531
- else return self::$FALSE;
1532
- }
1533
-
1534
- // evaluate an expression
1535
- protected function evaluate($exp) {
1536
- list(, $op, $left, $right, $whiteBefore, $whiteAfter) = $exp;
1537
-
1538
- $left = $this->reduce($left, true);
1539
- $right = $this->reduce($right, true);
1540
-
1541
- if ($leftColor = $this->coerceColor($left)) {
1542
- $left = $leftColor;
1543
- }
1544
-
1545
- if ($rightColor = $this->coerceColor($right)) {
1546
- $right = $rightColor;
1547
- }
1548
-
1549
- $ltype = $left[0];
1550
- $rtype = $right[0];
1551
-
1552
- // operators that work on all types
1553
- if ($op == "and") {
1554
- return $this->toBool($left == self::$TRUE && $right == self::$TRUE);
1555
- }
1556
-
1557
- if ($op == "=") {
1558
- return $this->toBool($this->eq($left, $right) );
1559
- }
1560
-
1561
- if ($op == "+" && !is_null($str = $this->stringConcatenate($left, $right))) {
1562
- return $str;
1563
- }
1564
-
1565
- // type based operators
1566
- $fname = "op_${ltype}_${rtype}";
1567
- if (is_callable(array($this, $fname))) {
1568
- $out = $this->$fname($op, $left, $right);
1569
- if (!is_null($out)) return $out;
1570
- }
1571
-
1572
- // make the expression look it did before being parsed
1573
- $paddedOp = $op;
1574
- if ($whiteBefore) $paddedOp = " " . $paddedOp;
1575
- if ($whiteAfter) $paddedOp .= " ";
1576
-
1577
- return array("string", "", array($left, $paddedOp, $right));
1578
- }
1579
-
1580
- protected function stringConcatenate($left, $right) {
1581
- if ($strLeft = $this->coerceString($left)) {
1582
- if ($right[0] == "string") {
1583
- $right[1] = "";
1584
- }
1585
- $strLeft[2][] = $right;
1586
- return $strLeft;
1587
- }
1588
-
1589
- if ($strRight = $this->coerceString($right)) {
1590
- array_unshift($strRight[2], $left);
1591
- return $strRight;
1592
- }
1593
- }
1594
-
1595
-
1596
- // make sure a color's components don't go out of bounds
1597
- protected function fixColor($c) {
1598
- foreach (range(1, 3) as $i) {
1599
- if ($c[$i] < 0) $c[$i] = 0;
1600
- if ($c[$i] > 255) $c[$i] = 255;
1601
- }
1602
-
1603
- return $c;
1604
- }
1605
-
1606
- protected function op_number_color($op, $lft, $rgt) {
1607
- if ($op == '+' || $op == '*') {
1608
- return $this->op_color_number($op, $rgt, $lft);
1609
- }
1610
- }
1611
-
1612
- protected function op_color_number($op, $lft, $rgt) {
1613
- if ($rgt[0] == '%') $rgt[1] /= 100;
1614
-
1615
- return $this->op_color_color($op, $lft,
1616
- array_fill(1, count($lft) - 1, $rgt[1]));
1617
- }
1618
-
1619
- protected function op_color_color($op, $left, $right) {
1620
- $out = array('color');
1621
- $max = count($left) > count($right) ? count($left) : count($right);
1622
- foreach (range(1, $max - 1) as $i) {
1623
- $lval = isset($left[$i]) ? $left[$i] : 0;
1624
- $rval = isset($right[$i]) ? $right[$i] : 0;
1625
- switch ($op) {
1626
- case '+':
1627
- $out[] = $lval + $rval;
1628
- break;
1629
- case '-':
1630
- $out[] = $lval - $rval;
1631
- break;
1632
- case '*':
1633
- $out[] = $lval * $rval;
1634
- break;
1635
- case '%':
1636
- $out[] = $lval % $rval;
1637
- break;
1638
- case '/':
1639
- if ($rval == 0) $this->throwError("evaluate error: can't divide by zero");
1640
- $out[] = $lval / $rval;
1641
- break;
1642
- default:
1643
- $this->throwError('evaluate error: color op number failed on op '.$op);
1644
- }
1645
- }
1646
- return $this->fixColor($out);
1647
- }
1648
-
1649
- function lib_red($color){
1650
- $color = $this->coerceColor($color);
1651
- if (is_null($color)) {
1652
- $this->throwError('color expected for red()');
1653
- }
1654
-
1655
- return $color[1];
1656
- }
1657
-
1658
- function lib_green($color){
1659
- $color = $this->coerceColor($color);
1660
- if (is_null($color)) {
1661
- $this->throwError('color expected for green()');
1662
- }
1663
-
1664
- return $color[2];
1665
- }
1666
-
1667
- function lib_blue($color){
1668
- $color = $this->coerceColor($color);
1669
- if (is_null($color)) {
1670
- $this->throwError('color expected for blue()');
1671
- }
1672
-
1673
- return $color[3];
1674
- }
1675
-
1676
-
1677
- // operator on two numbers
1678
- protected function op_number_number($op, $left, $right) {
1679
- $unit = empty($left[2]) ? $right[2] : $left[2];
1680
-
1681
- $value = 0;
1682
- switch ($op) {
1683
- case '+':
1684
- $value = $left[1] + $right[1];
1685
- break;
1686
- case '*':
1687
- $value = $left[1] * $right[1];
1688
- break;
1689
- case '-':
1690
- $value = $left[1] - $right[1];
1691
- break;
1692
- case '%':
1693
- $value = $left[1] % $right[1];
1694
- break;
1695
- case '/':
1696
- if ($right[1] == 0) $this->throwError('parse error: divide by zero');
1697
- $value = $left[1] / $right[1];
1698
- break;
1699
- case '<':
1700
- return $this->toBool($left[1] < $right[1]);
1701
- case '>':
1702
- return $this->toBool($left[1] > $right[1]);
1703
- case '>=':
1704
- return $this->toBool($left[1] >= $right[1]);
1705
- case '=<':
1706
- return $this->toBool($left[1] <= $right[1]);
1707
- default:
1708
- $this->throwError('parse error: unknown number operator: '.$op);
1709
- }
1710
-
1711
- return array("number", $value, $unit);
1712
- }
1713
-
1714
-
1715
- /* environment functions */
1716
-
1717
- protected function makeOutputBlock($type, $selectors = null) {
1718
- $b = new stdclass;
1719
- $b->lines = array();
1720
- $b->children = array();
1721
- $b->selectors = $selectors;
1722
- $b->type = $type;
1723
- $b->parent = $this->scope;
1724
- return $b;
1725
- }
1726
-
1727
- // the state of execution
1728
- protected function pushEnv($block = null) {
1729
- $e = new stdclass;
1730
- $e->parent = $this->env;
1731
- $e->store = array();
1732
- $e->block = $block;
1733
-
1734
- $this->env = $e;
1735
- return $e;
1736
- }
1737
-
1738
- // pop something off the stack
1739
- protected function popEnv() {
1740
- $old = $this->env;
1741
- $this->env = $this->env->parent;
1742
- return $old;
1743
- }
1744
-
1745
- // set something in the current env
1746
- protected function set($name, $value) {
1747
- $this->env->store[$name] = $value;
1748
- }
1749
-
1750
-
1751
- // get the highest occurrence entry for a name
1752
- protected function get($name, $default=null) {
1753
- $current = $this->env;
1754
-
1755
- $isArguments = $name == $this->vPrefix . 'arguments';
1756
- while ($current) {
1757
- if ($isArguments && isset($current->arguments)) {
1758
- return array('list', ' ', $current->arguments);
1759
- }
1760
-
1761
- if (isset($current->store[$name]))
1762
- return $current->store[$name];
1763
- else {
1764
- $current = isset($current->storeParent) ?
1765
- $current->storeParent : $current->parent;
1766
- }
1767
- }
1768
-
1769
- return $default;
1770
- }
1771
-
1772
- // inject array of unparsed strings into environment as variables
1773
- protected function injectVariables($args) {
1774
- $this->pushEnv();
1775
- $parser = new lessc_parser($this, __METHOD__);
1776
- foreach ($args as $name => $strValue) {
1777
- if ($name[0] != '@') $name = '@'.$name;
1778
- $parser->count = 0;
1779
- $parser->buffer = (string)$strValue;
1780
- if (!$parser->propertyValue($value)) {
1781
- throw new Exception("failed to parse passed in variable $name: $strValue");
1782
- }
1783
-
1784
- $this->set($name, $value);
1785
- }
1786
- }
1787
-
1788
- /**
1789
- * Initialize any static state, can initialize parser for a file
1790
- * $opts isn't used yet
1791
- */
1792
- public function __construct($fname = null) {
1793
- if ($fname !== null) {
1794
- // used for deprecated parse method
1795
- $this->_parseFile = $fname;
1796
- }
1797
- }
1798
-
1799
- public function compile($string, $name = null) {
1800
- $locale = setlocale(LC_NUMERIC, 0);
1801
- setlocale(LC_NUMERIC, "C");
1802
-
1803
- $this->parser = $this->makeParser($name);
1804
- $root = $this->parser->parse($string);
1805
-
1806
- $this->env = null;
1807
- $this->scope = null;
1808
-
1809
- $this->formatter = $this->newFormatter();
1810
-
1811
- if (!empty($this->registeredVars)) {
1812
- $this->injectVariables($this->registeredVars);
1813
- }
1814
-
1815
- $this->sourceParser = $this->parser; // used for error messages
1816
- $this->compileBlock($root);
1817
-
1818
- ob_start();
1819
- $this->formatter->block($this->scope);
1820
- $out = ob_get_clean();
1821
- setlocale(LC_NUMERIC, $locale);
1822
- return $out;
1823
- }
1824
-
1825
- public function compileFile($fname, $outFname = null) {
1826
- if (!is_readable($fname)) {
1827
- throw new Exception('load error: failed to find '.$fname);
1828
- }
1829
-
1830
- $pi = pathinfo($fname);
1831
-
1832
- $oldImport = $this->importDir;
1833
-
1834
- $this->importDir = (array)$this->importDir;
1835
- $this->importDir[] = $pi['dirname'].'/';
1836
-
1837
- $this->addParsedFile($fname);
1838
-
1839
- $out = $this->compile($GLOBALS['wp_filesystem']->get_contents($fname), $fname);
1840
-
1841
- $this->importDir = $oldImport;
1842
-
1843
- if ($outFname !== null) {
1844
- return $GLOBALS['wp_filesystem']->put_contents($outFname, $out);
1845
- }
1846
-
1847
- return $out;
1848
- }
1849
-
1850
- // compile only if changed input has changed or output doesn't exist
1851
- public function checkedCompile($in, $out) {
1852
- if (!is_file($out) || filemtime($in) > filemtime($out)) {
1853
- $this->compileFile($in, $out);
1854
- return true;
1855
- }
1856
- return false;
1857
- }
1858
-
1859
- /**
1860
- * Execute lessphp on a .less file or a lessphp cache structure
1861
- *
1862
- * The lessphp cache structure contains information about a specific
1863
- * less file having been parsed. It can be used as a hint for future
1864
- * calls to determine whether or not a rebuild is required.
1865
- *
1866
- * The cache structure contains two important keys that may be used
1867
- * externally:
1868
- *
1869
- * compiled: The final compiled CSS
1870
- * updated: The time (in seconds) the CSS was last compiled
1871
- *
1872
- * The cache structure is a plain-ol' PHP associative array and can
1873
- * be serialized and unserialized without a hitch.
1874
- *
1875
- * @param mixed $in Input
1876
- * @param bool $force Force rebuild?
1877
- * @return array lessphp cache structure
1878
- */
1879
- public function cachedCompile($in, $force = false) {
1880
- // assume no root
1881
- $root = null;
1882
-
1883
- if (is_string($in)) {
1884
- $root = $in;
1885
- } elseif (is_array($in) and isset($in['root'])) {
1886
- if ($force or ! isset($in['files'])) {
1887
- // If we are forcing a recompile or if for some reason the
1888
- // structure does not contain any file information we should
1889
- // specify the root to trigger a rebuild.
1890
- $root = $in['root'];
1891
- } elseif (isset($in['files']) and is_array($in['files'])) {
1892
- foreach ($in['files'] as $fname => $ftime ) {
1893
- if (!file_exists($fname) or filemtime($fname) > $ftime) {
1894
- // One of the files we knew about previously has changed
1895
- // so we should look at our incoming root again.
1896
- $root = $in['root'];
1897
- break;
1898
- }
1899
- }
1900
- }
1901
- } else {
1902
- // TODO: Throw an exception? We got neither a string nor something
1903
- // that looks like a compatible lessphp cache structure.
1904
- return null;
1905
- }
1906
-
1907
- if ($root !== null) {
1908
- // If we have a root value which means we should rebuild.
1909
- $out = array();
1910
- $out['root'] = $root;
1911
- $out['compiled'] = $this->compileFile($root);
1912
- $out['files'] = $this->allParsedFiles();
1913
- $out['updated'] = time();
1914
- return $out;
1915
- } else {
1916
- // No changes, pass back the structure
1917
- // we were given initially.
1918
- return $in;
1919
- }
1920
-
1921
- }
1922
-
1923
- // parse and compile buffer
1924
- // This is deprecated
1925
- public function parse($str = null, $initialVariables = null) {
1926
- if (is_array($str)) {
1927
- $initialVariables = $str;
1928
- $str = null;
1929
- }
1930
-
1931
- $oldVars = $this->registeredVars;
1932
- if ($initialVariables !== null) {
1933
- $this->setVariables($initialVariables);
1934
- }
1935
-
1936
- if ($str == null) {
1937
- if (empty($this->_parseFile)) {
1938
- throw new exception("nothing to parse");
1939
- }
1940
-
1941
- $out = $this->compileFile($this->_parseFile);
1942
- } else {
1943
- $out = $this->compile($str);
1944
- }
1945
-
1946
- $this->registeredVars = $oldVars;
1947
- return $out;
1948
- }
1949
-
1950
- protected function makeParser($name) {
1951
- $parser = new lessc_parser($this, $name);
1952
- $parser->writeComments = $this->preserveComments;
1953
-
1954
- return $parser;
1955
- }
1956
-
1957
- public function setFormatter($name) {
1958
- $this->formatterName = $name;
1959
- }
1960
-
1961
- protected function newFormatter() {
1962
- $className = "lessc_formatter_lessjs";
1963
- if (!empty($this->formatterName)) {
1964
- if (!is_string($this->formatterName))
1965
- return $this->formatterName;
1966
- $className = "lessc_formatter_$this->formatterName";
1967
- }
1968
-
1969
- return new $className;
1970
- }
1971
-
1972
- public function setPreserveComments($preserve) {
1973
- $this->preserveComments = $preserve;
1974
- }
1975
-
1976
- public function registerFunction($name, $func) {
1977
- $this->libFunctions[$name] = $func;
1978
- }
1979
-
1980
- public function unregisterFunction($name) {
1981
- unset($this->libFunctions[$name]);
1982
- }
1983
-
1984
- public function setVariables($variables) {
1985
- $this->registeredVars = array_merge($this->registeredVars, $variables);
1986
- }
1987
-
1988
- public function unsetVariable($name) {
1989
- unset($this->registeredVars[$name]);
1990
- }
1991
-
1992
- public function setImportDir($dirs) {
1993
- $this->importDir = (array)$dirs;
1994
- }
1995
-
1996
- public function addImportDir($dir) {
1997
- $this->importDir = (array)$this->importDir;
1998
- $this->importDir[] = $dir;
1999
- }
2000
-
2001
- public function allParsedFiles() {
2002
- return $this->allParsedFiles;
2003
- }
2004
-
2005
- protected function addParsedFile($file) {
2006
- $this->allParsedFiles[realpath($file)] = filemtime($file);
2007
- }
2008
-
2009
- /**
2010
- * Uses the current value of $this->count to show line and line number
2011
- */
2012
- protected function throwError($msg = null) {
2013
- if ($this->sourceLoc >= 0) {
2014
- $this->sourceParser->throwError($msg, $this->sourceLoc);
2015
- }
2016
- throw new exception($msg);
2017
- }
2018
-
2019
- // compile file $in to file $out if $in is newer than $out
2020
- // returns true when it compiles, false otherwise
2021
- public static function ccompile($in, $out, $less = null) {
2022
- if ($less === null) {
2023
- $less = new self;
2024
- }
2025
- return $less->checkedCompile($in, $out);
2026
- }
2027
-
2028
- public static function cexecute($in, $force = false, $less = null) {
2029
- if ($less === null) {
2030
- $less = new self;
2031
- }
2032
- return $less->cachedCompile($in, $force);
2033
- }
2034
-
2035
- static protected $cssColors = array(
2036
- 'aliceblue' => '240,248,255',
2037
- 'antiquewhite' => '250,235,215',
2038
- 'aqua' => '0,255,255',
2039
- 'aquamarine' => '127,255,212',
2040
- 'azure' => '240,255,255',
2041
- 'beige' => '245,245,220',
2042
- 'bisque' => '255,228,196',
2043
- 'black' => '0,0,0',
2044
- 'blanchedalmond' => '255,235,205',
2045
- 'blue' => '0,0,255',
2046
- 'blueviolet' => '138,43,226',
2047
- 'brown' => '165,42,42',
2048
- 'burlywood' => '222,184,135',
2049
- 'cadetblue' => '95,158,160',
2050
- 'chartreuse' => '127,255,0',
2051
- 'chocolate' => '210,105,30',
2052
- 'coral' => '255,127,80',
2053
- 'cornflowerblue' => '100,149,237',
2054
- 'cornsilk' => '255,248,220',
2055
- 'crimson' => '220,20,60',
2056
- 'cyan' => '0,255,255',
2057
- 'darkblue' => '0,0,139',
2058
- 'darkcyan' => '0,139,139',
2059
- 'darkgoldenrod' => '184,134,11',
2060
- 'darkgray' => '169,169,169',
2061
- 'darkgreen' => '0,100,0',
2062
- 'darkgrey' => '169,169,169',
2063
- 'darkkhaki' => '189,183,107',
2064
- 'darkmagenta' => '139,0,139',
2065
- 'darkolivegreen' => '85,107,47',
2066
- 'darkorange' => '255,140,0',
2067
- 'darkorchid' => '153,50,204',
2068
- 'darkred' => '139,0,0',
2069
- 'darksalmon' => '233,150,122',
2070
- 'darkseagreen' => '143,188,143',
2071
- 'darkslateblue' => '72,61,139',
2072
- 'darkslategray' => '47,79,79',
2073
- 'darkslategrey' => '47,79,79',
2074
- 'darkturquoise' => '0,206,209',
2075
- 'darkviolet' => '148,0,211',
2076
- 'deeppink' => '255,20,147',
2077
- 'deepskyblue' => '0,191,255',
2078
- 'dimgray' => '105,105,105',
2079
- 'dimgrey' => '105,105,105',
2080
- 'dodgerblue' => '30,144,255',
2081
- 'firebrick' => '178,34,34',
2082
- 'floralwhite' => '255,250,240',
2083
- 'forestgreen' => '34,139,34',
2084
- 'fuchsia' => '255,0,255',
2085
- 'gainsboro' => '220,220,220',
2086
- 'ghostwhite' => '248,248,255',
2087
- 'gold' => '255,215,0',
2088
- 'goldenrod' => '218,165,32',
2089
- 'gray' => '128,128,128',
2090
- 'green' => '0,128,0',
2091
- 'greenyellow' => '173,255,47',
2092
- 'grey' => '128,128,128',
2093
- 'honeydew' => '240,255,240',
2094
- 'hotpink' => '255,105,180',
2095
- 'indianred' => '205,92,92',
2096
- 'indigo' => '75,0,130',
2097
- 'ivory' => '255,255,240',
2098
- 'khaki' => '240,230,140',
2099
- 'lavender' => '230,230,250',
2100
- 'lavenderblush' => '255,240,245',
2101
- 'lawngreen' => '124,252,0',
2102
- 'lemonchiffon' => '255,250,205',
2103
- 'lightblue' => '173,216,230',
2104
- 'lightcoral' => '240,128,128',
2105
- 'lightcyan' => '224,255,255',
2106
- 'lightgoldenrodyellow' => '250,250,210',
2107
- 'lightgray' => '211,211,211',
2108
- 'lightgreen' => '144,238,144',
2109
- 'lightgrey' => '211,211,211',
2110
- 'lightpink' => '255,182,193',
2111
- 'lightsalmon' => '255,160,122',
2112
- 'lightseagreen' => '32,178,170',
2113
- 'lightskyblue' => '135,206,250',
2114
- 'lightslategray' => '119,136,153',
2115
- 'lightslategrey' => '119,136,153',
2116
- 'lightsteelblue' => '176,196,222',
2117
- 'lightyellow' => '255,255,224',
2118
- 'lime' => '0,255,0',
2119
- 'limegreen' => '50,205,50',
2120
- 'linen' => '250,240,230',
2121
- 'magenta' => '255,0,255',
2122
- 'maroon' => '128,0,0',
2123
- 'mediumaquamarine' => '102,205,170',
2124
- 'mediumblue' => '0,0,205',
2125
- 'mediumorchid' => '186,85,211',
2126
- 'mediumpurple' => '147,112,219',
2127
- 'mediumseagreen' => '60,179,113',
2128
- 'mediumslateblue' => '123,104,238',
2129
- 'mediumspringgreen' => '0,250,154',
2130
- 'mediumturquoise' => '72,209,204',
2131
- 'mediumvioletred' => '199,21,133',
2132
- 'midnightblue' => '25,25,112',
2133
- 'mintcream' => '245,255,250',
2134
- 'mistyrose' => '255,228,225',
2135
- 'moccasin' => '255,228,181',
2136
- 'navajowhite' => '255,222,173',
2137
- 'navy' => '0,0,128',
2138
- 'oldlace' => '253,245,230',
2139
- 'olive' => '128,128,0',
2140
- 'olivedrab' => '107,142,35',
2141
- 'orange' => '255,165,0',
2142
- 'orangered' => '255,69,0',
2143
- 'orchid' => '218,112,214',
2144
- 'palegoldenrod' => '238,232,170',
2145
- 'palegreen' => '152,251,152',
2146
- 'paleturquoise' => '175,238,238',
2147
- 'palevioletred' => '219,112,147',
2148
- 'papayawhip' => '255,239,213',
2149
- 'peachpuff' => '255,218,185',
2150
- 'peru' => '205,133,63',
2151
- 'pink' => '255,192,203',
2152
- 'plum' => '221,160,221',
2153
- 'powderblue' => '176,224,230',
2154
- 'purple' => '128,0,128',
2155
- 'red' => '255,0,0',
2156
- 'rosybrown' => '188,143,143',
2157
- 'royalblue' => '65,105,225',
2158
- 'saddlebrown' => '139,69,19',
2159
- 'salmon' => '250,128,114',
2160
- 'sandybrown' => '244,164,96',
2161
- 'seagreen' => '46,139,87',
2162
- 'seashell' => '255,245,238',
2163
- 'sienna' => '160,82,45',
2164
- 'silver' => '192,192,192',
2165
- 'skyblue' => '135,206,235',
2166
- 'slateblue' => '106,90,205',
2167
- 'slategray' => '112,128,144',
2168
- 'slategrey' => '112,128,144',
2169
- 'snow' => '255,250,250',
2170
- 'springgreen' => '0,255,127',
2171
- 'steelblue' => '70,130,180',
2172
- 'tan' => '210,180,140',
2173
- 'teal' => '0,128,128',
2174
- 'thistle' => '216,191,216',
2175
- 'tomato' => '255,99,71',
2176
- 'transparent' => '0,0,0,0',
2177
- 'turquoise' => '64,224,208',
2178
- 'violet' => '238,130,238',
2179
- 'wheat' => '245,222,179',
2180
- 'white' => '255,255,255',
2181
- 'whitesmoke' => '245,245,245',
2182
- 'yellow' => '255,255,0',
2183
- 'yellowgreen' => '154,205,50'
2184
- );
2185
- }
2186
-
2187
- // responsible for taking a string of LESS code and converting it into a
2188
- // syntax tree
2189
- /**
2190
- * @ignore
2191
- */
2192
- class lessc_parser {
2193
- static protected $nextBlockId = 0; // used to uniquely identify blocks
2194
-
2195
- static protected $precedence = array(
2196
- '=<' => 0,
2197
- '>=' => 0,
2198
- '=' => 0,
2199
- '<' => 0,
2200
- '>' => 0,
2201
-
2202
- '+' => 1,
2203
- '-' => 1,
2204
- '*' => 2,
2205
- '/' => 2,
2206
- '%' => 2,
2207
- );
2208
-
2209
- static protected $whitePattern;
2210
- static protected $commentMulti;
2211
-
2212
- static protected $commentSingle = "//";
2213
- static protected $commentMultiLeft = "/*";
2214
- static protected $commentMultiRight = "*/";
2215
-
2216
- // regex string to match any of the operators
2217
- static protected $operatorString;
2218
-
2219
- // these properties will supress division unless it's inside parenthases
2220
- static protected $supressDivisionProps =
2221
- array('/border-radius$/i', '/^font$/i');
2222
-
2223
- protected $blockDirectives = array("font-face", "keyframes", "page", "-moz-document", "viewport", "-moz-viewport", "-o-viewport", "-ms-viewport");
2224
- protected $lineDirectives = array("charset");
2225
-
2226
- /**
2227
- * if we are in parens we can be more liberal with whitespace around
2228
- * operators because it must evaluate to a single value and thus is less
2229
- * ambiguous.
2230
- *
2231
- * Consider:
2232
- * property1: 10 -5; // is two numbers, 10 and -5
2233
- * property2: (10 -5); // should evaluate to 5
2234
- */
2235
- protected $inParens = false;
2236
-
2237
- // caches preg escaped literals
2238
- static protected $literalCache = array();
2239
-
2240
- public function __construct($lessc, $sourceName = null) {
2241
- $this->eatWhiteDefault = true;
2242
- // reference to less needed for vPrefix, mPrefix, and parentSelector
2243
- $this->lessc = $lessc;
2244
-
2245
- $this->sourceName = $sourceName; // name used for error messages
2246
-
2247
- $this->writeComments = false;
2248
-
2249
- if (!self::$operatorString) {
2250
- self::$operatorString =
2251
- '('.implode('|', array_map(array('JupiterX_Lessc', 'preg_quote'),
2252
- array_keys(self::$precedence))).')';
2253
-
2254
- $commentSingle = JupiterX_Lessc::preg_quote(self::$commentSingle);
2255
- $commentMultiLeft = JupiterX_Lessc::preg_quote(self::$commentMultiLeft);
2256
- $commentMultiRight = JupiterX_Lessc::preg_quote(self::$commentMultiRight);
2257
-
2258
- self::$commentMulti = $commentMultiLeft.'.*?'.$commentMultiRight;
2259
- self::$whitePattern = '/'.$commentSingle.'[^\n]*\s*|('.self::$commentMulti.')\s*|\s+/Ais';
2260
- }
2261
- }
2262
-
2263
- public function parse($buffer) {
2264
- $this->count = 0;
2265
- $this->line = 1;
2266
-
2267
- $this->env = null; // block stack
2268
- $this->buffer = $this->writeComments ? $buffer : $this->removeComments($buffer);
2269
- $this->pushSpecialBlock("root");
2270
- $this->eatWhiteDefault = true;
2271
- $this->seenComments = array();
2272
-
2273
- // trim whitespace on head
2274
- // if (preg_match('/^\s+/', $this->buffer, $m)) {
2275
- // $this->line += substr_count($m[0], "\n");
2276
- // $this->buffer = ltrim($this->buffer);
2277
- // }
2278
- $this->whitespace();
2279
-
2280
- // parse the entire file
2281
- $lastCount = $this->count;
2282
- while (false !== $this->parseChunk());
2283
-
2284
- if ($this->count != strlen($this->buffer))
2285
- $this->throwError();
2286
-
2287
- // TODO report where the block was opened
2288
- if (!is_null($this->env->parent))
2289
- throw new exception('parse error: unclosed block');
2290
-
2291
- return $this->env;
2292
- }
2293
-
2294
- /**
2295
- * Parse a single chunk off the head of the buffer and append it to the
2296
- * current parse environment.
2297
- * Returns false when the buffer is empty, or when there is an error.
2298
- *
2299
- * This function is called repeatedly until the entire document is
2300
- * parsed.
2301
- *
2302
- * This parser is most similar to a recursive descent parser. Single
2303
- * functions represent discrete grammatical rules for the language, and
2304
- * they are able to capture the text that represents those rules.
2305
- *
2306
- * Consider the function lessc::keyword(). (all parse functions are
2307
- * structured the same)
2308
- *
2309
- * The function takes a single reference argument. When calling the
2310
- * function it will attempt to match a keyword on the head of the buffer.
2311
- * If it is successful, it will place the keyword in the referenced
2312
- * argument, advance the position in the buffer, and return true. If it
2313
- * fails then it won't advance the buffer and it will return false.
2314
- *
2315
- * All of these parse functions are powered by lessc::match(), which behaves
2316
- * the same way, but takes a literal regular expression. Sometimes it is
2317
- * more convenient to use match instead of creating a new function.
2318
- *
2319
- * Because of the format of the functions, to parse an entire string of
2320
- * grammatical rules, you can chain them together using &&.
2321
- *
2322
- * But, if some of the rules in the chain succeed before one fails, then
2323
- * the buffer position will be left at an invalid state. In order to
2324
- * avoid this, lessc::seek() is used to remember and set buffer positions.
2325
- *
2326
- * Before parsing a chain, use $s = $this->seek() to remember the current
2327
- * position into $s. Then if a chain fails, use $this->seek($s) to
2328
- * go back where we started.
2329
- */
2330
- protected function parseChunk() {
2331
- if (empty($this->buffer)) return false;
2332
- $s = $this->seek();
2333
-
2334
- // setting a property
2335
- if ($this->keyword($key) && $this->assign() &&
2336
- $this->propertyValue($value, $key) && $this->end())
2337
- {
2338
- $this->append(array('assign', $key, $value), $s);
2339
- return true;
2340
- } else {
2341
- $this->seek($s);
2342
- }
2343
-
2344
-
2345
- // look for special css blocks
2346
- if ($this->literal('@', false)) {
2347
- $this->count--;
2348
-
2349
- // media
2350
- if ($this->literal('@media')) {
2351
- if (($this->mediaQueryList($mediaQueries) || true)
2352
- && $this->literal('{'))
2353
- {
2354
- $media = $this->pushSpecialBlock("media");
2355
- $media->queries = is_null($mediaQueries) ? array() : $mediaQueries;
2356
- return true;
2357
- } else {
2358
- $this->seek($s);
2359
- return false;
2360
- }
2361
- }
2362
-
2363
- if ($this->literal("@", false) && $this->keyword($dirName)) {
2364
- if ($this->isDirective($dirName, $this->blockDirectives)) {
2365
- if (($this->openString("{", $dirValue, null, array(";")) || true) &&
2366
- $this->literal("{"))
2367
- {
2368
- $dir = $this->pushSpecialBlock("directive");
2369
- $dir->name = $dirName;
2370
- if (isset($dirValue)) $dir->value = $dirValue;
2371
- return true;
2372
- }
2373
- } elseif ($this->isDirective($dirName, $this->lineDirectives)) {
2374
- if ($this->propertyValue($dirValue) && $this->end()) {
2375
- $this->append(array("directive", $dirName, $dirValue));
2376
- return true;
2377
- }
2378
- }
2379
- }
2380
-
2381
- $this->seek($s);
2382
- }
2383
-
2384
- // setting a variable
2385
- if ($this->variable($var) && $this->assign() &&
2386
- $this->propertyValue($value) && $this->end())
2387
- {
2388
- $this->append(array('assign', $var, $value), $s);
2389
- return true;
2390
- } else {
2391
- $this->seek($s);
2392
- }
2393
-
2394
- if ($this->import($importValue)) {
2395
- $this->append($importValue, $s);
2396
- return true;
2397
- }
2398
-
2399
- // opening parametric mixin
2400
- if ($this->tag($tag, true) && $this->argumentDef($args, $isVararg) &&
2401
- ($this->guards($guards) || true) &&
2402
- $this->literal('{'))
2403
- {
2404
- $block = $this->pushBlock($this->fixTags(array($tag)));
2405
- $block->args = $args;
2406
- $block->isVararg = $isVararg;
2407
- if (!empty($guards)) $block->guards = $guards;
2408
- return true;
2409
- } else {
2410
- $this->seek($s);
2411
- }
2412
-
2413
- // opening a simple block
2414
- if ($this->tags($tags) && $this->literal('{')) {
2415
- $tags = $this->fixTags($tags);
2416
- $this->pushBlock($tags);
2417
- return true;
2418
- } else {
2419
- $this->seek($s);
2420
- }
2421
-
2422
- // closing a block
2423
- if ($this->literal('}', false)) {
2424
- try {
2425
- $block = $this->pop();
2426
- } catch (exception $e) {
2427
- $this->seek($s);
2428
- $this->throwError($e->getMessage());
2429
- }
2430
-
2431
- $hidden = false;
2432
- if (is_null($block->type)) {
2433
- $hidden = true;
2434
- if (!isset($block->args)) {
2435
- foreach ($block->tags as $tag) {
2436
- if (!is_string($tag) || $tag[0] != $this->lessc->mPrefix) {
2437
- $hidden = false;
2438
- break;
2439
- }
2440
- }
2441
- }
2442
-
2443
- foreach ($block->tags as $tag) {
2444
- if (is_string($tag)) {
2445
- $this->env->children[$tag][] = $block;
2446
- }
2447
- }
2448
- }
2449
-
2450
- if (!$hidden) {
2451
- $this->append(array('block', $block), $s);
2452
- }
2453
-
2454
- // this is done here so comments aren't bundled into he block that
2455
- // was just closed
2456
- $this->whitespace();
2457
- return true;
2458
- }
2459
-
2460
- // mixin
2461
- if ($this->mixinTags($tags) &&
2462
- ($this->argumentDef($argv, $isVararg) || true) &&
2463
- ($this->keyword($suffix) || true) && $this->end())
2464
- {
2465
- $tags = $this->fixTags($tags);
2466
- $this->append(array('mixin', $tags, $argv, $suffix), $s);
2467
- return true;
2468
- } else {
2469
- $this->seek($s);
2470
- }
2471
-
2472
- // spare ;
2473
- if ($this->literal(';')) return true;
2474
-
2475
- return false; // got nothing, throw error
2476
- }
2477
-
2478
- protected function isDirective($dirname, $directives) {
2479
- // TODO: cache pattern in parser
2480
- $pattern = implode("|",
2481
- array_map(array("JupiterX_Lessc", "preg_quote"), $directives));
2482
- $pattern = '/^(-[a-z-]+-)?(' . $pattern . ')$/i';
2483
-
2484
- return preg_match($pattern, $dirname);
2485
- }
2486
-
2487
- protected function fixTags($tags) {
2488
- // move @ tags out of variable namespace
2489
- foreach ($tags as &$tag) {
2490
- if ($tag[0] == $this->lessc->vPrefix)
2491
- $tag[0] = $this->lessc->mPrefix;
2492
- }
2493
- return $tags;
2494
- }
2495
-
2496
- // a list of expressions
2497
- protected function expressionList(&$exps) {
2498
- $values = array();
2499
-
2500
- while ($this->expression($exp)) {
2501
- $values[] = $exp;
2502
- }
2503
-
2504
- if (count($values) == 0) return false;
2505
-
2506
- $exps = JupiterX_Lessc::compressList($values, ' ');
2507
- return true;
2508
- }
2509
-
2510
- /**
2511
- * Attempt to consume an expression.
2512
- * @link http://en.wikipedia.org/wiki/Operator-precedence_parser#Pseudo-code
2513
- */
2514
- protected function expression(&$out) {
2515
- if ($this->value($lhs)) {
2516
- $out = $this->expHelper($lhs, 0);
2517
-
2518
- // look for / shorthand
2519
- if (!empty($this->env->supressedDivision)) {
2520
- unset($this->env->supressedDivision);
2521
- $s = $this->seek();
2522
- if ($this->literal("/") && $this->value($rhs)) {
2523
- $out = array("list", "",
2524
- array($out, array("keyword", "/"), $rhs));
2525
- } else {
2526
- $this->seek($s);
2527
- }
2528
- }
2529
-
2530
- return true;
2531
- }
2532
- return false;
2533
- }
2534
-
2535
- /**
2536
- * recursively parse infix equation with $lhs at precedence $minP
2537
- */
2538
- protected function expHelper($lhs, $minP) {
2539
- $this->inExp = true;
2540
- $ss = $this->seek();
2541
-
2542
- while (true) {
2543
- $whiteBefore = isset($this->buffer[$this->count - 1]) &&
2544
- ctype_space($this->buffer[$this->count - 1]);
2545
-
2546
- // If there is whitespace before the operator, then we require
2547
- // whitespace after the operator for it to be an expression
2548
- $needWhite = $whiteBefore && !$this->inParens;
2549
-
2550
- if ($this->match(self::$operatorString.($needWhite ? '\s' : ''), $m) && self::$precedence[$m[1]] >= $minP) {
2551
- if (!$this->inParens && isset($this->env->currentProperty) && $m[1] == "/" && empty($this->env->supressedDivision)) {
2552
- foreach (self::$supressDivisionProps as $pattern) {
2553
- if (preg_match($pattern, $this->env->currentProperty)) {
2554
- $this->env->supressedDivision = true;
2555
- break 2;
2556
- }
2557
- }
2558
- }
2559
-
2560
-
2561
- $whiteAfter = isset($this->buffer[$this->count - 1]) &&
2562
- ctype_space($this->buffer[$this->count - 1]);
2563
-
2564
- if (!$this->value($rhs)) break;
2565
-
2566
- // peek for next operator to see what to do with rhs
2567
- if ($this->peek(self::$operatorString, $next) && self::$precedence[$next[1]] > self::$precedence[$m[1]]) {
2568
- $rhs = $this->expHelper($rhs, self::$precedence[$next[1]]);
2569
- }
2570
-
2571
- $lhs = array('expression', $m[1], $lhs, $rhs, $whiteBefore, $whiteAfter);
2572
- $ss = $this->seek();
2573
-
2574
- continue;
2575
- }
2576
-
2577
- break;
2578
- }
2579
-
2580
- $this->seek($ss);
2581
-
2582
- return $lhs;
2583
- }
2584
-
2585
- // consume a list of values for a property
2586
- public function propertyValue(&$value, $keyName = null) {
2587
- $values = array();
2588
-
2589
- if ($keyName !== null) $this->env->currentProperty = $keyName;
2590
-
2591
- $s = null;
2592
- while ($this->expressionList($v)) {
2593
- $values[] = $v;
2594
- $s = $this->seek();
2595
- if (!$this->literal(',')) break;
2596
- }
2597
-
2598
- if ($s) $this->seek($s);
2599
-
2600
- if ($keyName !== null) unset($this->env->currentProperty);
2601
-
2602
- if (count($values) == 0) return false;
2603
-
2604
- $value = JupiterX_Lessc::compressList($values, ', ');
2605
- return true;
2606
- }
2607
-
2608
- protected function parenValue(&$out) {
2609
- $s = $this->seek();
2610
-
2611
- // speed shortcut
2612
- if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "(") {
2613
- return false;
2614
- }
2615
-
2616
- $inParens = $this->inParens;
2617
- if ($this->literal("(") &&
2618
- ($this->inParens = true) && $this->expression($exp) &&
2619
- $this->literal(")"))
2620
- {
2621
- $out = $exp;
2622
- $this->inParens = $inParens;
2623
- return true;
2624
- } else {
2625
- $this->inParens = $inParens;
2626
- $this->seek($s);
2627
- }
2628
-
2629
- return false;
2630
- }
2631
-
2632
- // a single value
2633
- protected function value(&$value) {
2634
- $s = $this->seek();
2635
-
2636
- // speed shortcut
2637
- if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "-") {
2638
- // negation
2639
- if ($this->literal("-", false) &&
2640
- (($this->variable($inner) && $inner = array("variable", $inner)) ||
2641
- $this->unit($inner) ||
2642
- $this->parenValue($inner)))
2643
- {
2644
- $value = array("unary", "-", $inner);
2645
- return true;
2646
- } else {
2647
- $this->seek($s);
2648
- }
2649
- }
2650
-
2651
- if ($this->parenValue($value)) return true;
2652
- if ($this->unit($value)) return true;
2653
- if ($this->color($value)) return true;
2654
- if ($this->func($value)) return true;
2655
- if ($this->string($value)) return true;
2656
-
2657
- if ($this->keyword($word)) {
2658
- $value = array('keyword', $word);
2659
- return true;
2660
- }
2661
-
2662
- // try a variable
2663
- if ($this->variable($var)) {
2664
- $value = array('variable', $var);
2665
- return true;
2666
- }
2667
-
2668
- // unquote string (should this work on any type?
2669
- if ($this->literal("~") && $this->string($str)) {
2670
- $value = array("escape", $str);
2671
- return true;
2672
- } else {
2673
- $this->seek($s);
2674
- }
2675
-
2676
- // css hack: \0
2677
- if ($this->literal('\\') && $this->match('([0-9]+)', $m)) {
2678
- $value = array('keyword', '\\'.$m[1]);
2679
- return true;
2680
- } else {
2681
- $this->seek($s);
2682
- }
2683
-
2684
- return false;
2685
- }
2686
-
2687
- // an import statement
2688
- protected function import(&$out) {
2689
- $s = $this->seek();
2690
- if (!$this->literal('@import')) return false;
2691
-
2692
- // @import "something.css" media;
2693
- // @import url("something.css") media;
2694
- // @import url(something.css) media;
2695
-
2696
- if ($this->propertyValue($value)) {
2697
- $out = array("import", $value);
2698
- return true;
2699
- }
2700
- }
2701
-
2702
- protected function mediaQueryList(&$out) {
2703
- if ($this->genericList($list, "mediaQuery", ",", false)) {
2704
- $out = $list[2];
2705
- return true;
2706
- }
2707
- return false;
2708
- }
2709
-
2710
- protected function mediaQuery(&$out) {
2711
- $s = $this->seek();
2712
-
2713
- $expressions = null;
2714
- $parts = array();
2715
-
2716
- if (($this->literal("only") && ($only = true) || $this->literal("not") && ($not = true) || true) && $this->keyword($mediaType)) {
2717
- $prop = array("mediaType");
2718
- if (isset($only)) $prop[] = "only";
2719
- if (isset($not)) $prop[] = "not";
2720
- $prop[] = $mediaType;
2721
- $parts[] = $prop;
2722
- } else {
2723
- $this->seek($s);
2724
- }
2725
-
2726
-
2727
- if (!empty($mediaType) && !$this->literal("and")) {
2728
- // ~
2729
- } else {
2730
- $this->genericList($expressions, "mediaExpression", "and", false);
2731
- if (is_array($expressions)) $parts = array_merge($parts, $expressions[2]);
2732
- }
2733
-
2734
- if (count($parts) == 0) {
2735
- $this->seek($s);
2736
- return false;
2737
- }
2738
-
2739
- $out = $parts;
2740
- return true;
2741
- }
2742
-
2743
- protected function mediaExpression(&$out) {
2744
- $s = $this->seek();
2745
- $value = null;
2746
- if ($this->literal("(") &&
2747
- $this->keyword($feature) &&
2748
- ($this->literal(":") && $this->expression($value) || true) &&
2749
- $this->literal(")"))
2750
- {
2751
- $out = array("mediaExp", $feature);
2752
- if ($value) $out[] = $value;
2753
- return true;
2754
- } elseif ($this->variable($variable)) {
2755
- $out = array('variable', $variable);
2756
- return true;
2757
- }
2758
-
2759
- $this->seek($s);
2760
- return false;
2761
- }
2762
-
2763
- // an unbounded string stopped by $end
2764
- protected function openString($end, &$out, $nestingOpen=null, $rejectStrs = null) {
2765
- $oldWhite = $this->eatWhiteDefault;
2766
- $this->eatWhiteDefault = false;
2767
-
2768
- $stop = array("'", '"', "@{", $end);
2769
- $stop = array_map(array("JupiterX_Lessc", "preg_quote"), $stop);
2770
- // $stop[] = self::$commentMulti;
2771
-
2772
- if (!is_null($rejectStrs)) {
2773
- $stop = array_merge($stop, $rejectStrs);
2774
- }
2775
-
2776
- $patt = '(.*?)('.implode("|", $stop).')';
2777
-
2778
- $nestingLevel = 0;
2779
-
2780
- $content = array();
2781
- while ($this->match($patt, $m, false)) {
2782
- if (!empty($m[1])) {
2783
- $content[] = $m[1];
2784
- if ($nestingOpen) {
2785
- $nestingLevel += substr_count($m[1], $nestingOpen);
2786
- }
2787
- }
2788
-
2789
- $tok = $m[2];
2790
-
2791
- $this->count-= strlen($tok);
2792
- if ($tok == $end) {
2793
- if ($nestingLevel == 0) {
2794
- break;
2795
- } else {
2796
- $nestingLevel--;
2797
- }
2798
- }
2799
-
2800
- if (($tok == "'" || $tok == '"') && $this->string($str)) {
2801
- $content[] = $str;
2802
- continue;
2803
- }
2804
-
2805
- if ($tok == "@{" && $this->interpolation($inter)) {
2806
- $content[] = $inter;
2807
- continue;
2808
- }
2809
-
2810
- if (!empty($rejectStrs) && in_array($tok, $rejectStrs)) {
2811
- break;
2812
- }
2813
-
2814
- $content[] = $tok;
2815
- $this->count+= strlen($tok);
2816
- }
2817
-
2818
- $this->eatWhiteDefault = $oldWhite;
2819
-
2820
- if (count($content) == 0) return false;
2821
-
2822
- // trim the end
2823
- if (is_string(end($content))) {
2824
- $content[count($content) - 1] = rtrim(end($content));
2825
- }
2826
-
2827
- $out = array("string", "", $content);
2828
- return true;
2829
- }
2830
-
2831
- protected function string(&$out) {
2832
- $s = $this->seek();
2833
- if ($this->literal('"', false)) {
2834
- $delim = '"';
2835
- } elseif ($this->literal("'", false)) {
2836
- $delim = "'";
2837
- } else {
2838
- return false;
2839
- }
2840
-
2841
- $content = array();
2842
-
2843
- // look for either ending delim , escape, or string interpolation
2844
- $patt = '([^\n]*?)(@\{|\\\\|' .
2845
- JupiterX_Lessc::preg_quote($delim).')';
2846
-
2847
- $oldWhite = $this->eatWhiteDefault;
2848
- $this->eatWhiteDefault = false;
2849
-
2850
- while ($this->match($patt, $m, false)) {
2851
- $content[] = $m[1];
2852
- if ($m[2] == "@{") {
2853
- $this->count -= strlen($m[2]);
2854
- if ($this->interpolation($inter, false)) {
2855
- $content[] = $inter;
2856
- } else {
2857
- $this->count += strlen($m[2]);
2858
- $content[] = "@{"; // ignore it
2859
- }
2860
- } elseif ($m[2] == '\\') {
2861
- $content[] = $m[2];
2862
- if ($this->literal($delim, false)) {
2863
- $content[] = $delim;
2864
- }
2865
- } else {
2866
- $this->count -= strlen($delim);
2867
- break; // delim
2868
- }
2869
- }
2870
-
2871
- $this->eatWhiteDefault = $oldWhite;
2872
-
2873
- if ($this->literal($delim)) {
2874
- $out = array("string", $delim, $content);
2875
- return true;
2876
- }
2877
-
2878
- $this->seek($s);
2879
- return false;
2880
- }
2881
-
2882
- protected function interpolation(&$out) {
2883
- $oldWhite = $this->eatWhiteDefault;
2884
- $this->eatWhiteDefault = true;
2885
-
2886
- $s = $this->seek();
2887
- if ($this->literal("@{") &&
2888
- $this->openString("}", $interp, null, array("'", '"', ";")) &&
2889
- $this->literal("}", false))
2890
- {
2891
- $out = array("interpolate", $interp);
2892
- $this->eatWhiteDefault = $oldWhite;
2893
- if ($this->eatWhiteDefault) $this->whitespace();
2894
- return true;
2895
- }
2896
-
2897
- $this->eatWhiteDefault = $oldWhite;
2898
- $this->seek($s);
2899
- return false;
2900
- }
2901
-
2902
- protected function unit(&$unit) {
2903
- // speed shortcut
2904
- if (isset($this->buffer[$this->count])) {
2905
- $char = $this->buffer[$this->count];
2906
- if (!ctype_digit($char) && $char != ".") return false;
2907
- }
2908
-
2909
- if ($this->match('([0-9]+(?:\.[0-9]*)?|\.[0-9]+)([%a-zA-Z]+)?', $m)) {
2910
- $unit = array("number", $m[1], empty($m[2]) ? "" : $m[2]);
2911
- return true;
2912
- }
2913
- return false;
2914
- }
2915
-
2916
- // a # color
2917
- protected function color(&$out) {
2918
- if ($this->match('(#(?:[0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{3}))', $m)) {
2919
- if (strlen($m[1]) > 7) {
2920
- $out = array("string", "", array($m[1]));
2921
- } else {
2922
- $out = array("raw_color", $m[1]);
2923
- }
2924
- return true;
2925
- }
2926
-
2927
- return false;
2928
- }
2929
-
2930
- // consume an argument definition list surrounded by ()
2931
- // each argument is a variable name with optional value
2932
- // or at the end a ... or a variable named followed by ...
2933
- // arguments are separated by , unless a ; is in the list, then ; is the
2934
- // delimiter.
2935
- protected function argumentDef(&$args, &$isVararg) {
2936
- $s = $this->seek();
2937
- if (!$this->literal('(')) return false;
2938
-
2939
- $values = array();
2940
- $delim = ",";
2941
- $method = "expressionList";
2942
-
2943
- $isVararg = false;
2944
- while (true) {
2945
- if ($this->literal("...")) {
2946
- $isVararg = true;
2947
- break;
2948
- }
2949
-
2950
- if ($this->$method($value)) {
2951
- if ($value[0] == "variable") {
2952
- $arg = array("arg", $value[1]);
2953
- $ss = $this->seek();
2954
-
2955
- if ($this->assign() && $this->$method($rhs)) {
2956
- $arg[] = $rhs;
2957
- } else {
2958
- $this->seek($ss);
2959
- if ($this->literal("...")) {
2960
- $arg[0] = "rest";
2961
- $isVararg = true;
2962
- }
2963
- }
2964
-
2965
- $values[] = $arg;
2966
- if ($isVararg) break;
2967
- continue;
2968
- } else {
2969
- $values[] = array("lit", $value);
2970
- }
2971
- }
2972
-
2973
-
2974
- if (!$this->literal($delim)) {
2975
- if ($delim == "," && $this->literal(";")) {
2976
- // found new delim, convert existing args
2977
- $delim = ";";
2978
- $method = "propertyValue";
2979
-
2980
- // transform arg list
2981
- if (isset($values[1])) { // 2 items
2982
- $newList = array();
2983
- foreach ($values as $i => $arg) {
2984
- switch($arg[0]) {
2985
- case "arg":
2986
- if ($i) {
2987
- $this->throwError("Cannot mix ; and , as delimiter types");
2988
- }
2989
- $newList[] = $arg[2];
2990
- break;
2991
- case "lit":
2992
- $newList[] = $arg[1];
2993
- break;
2994
- case "rest":
2995
- $this->throwError("Unexpected rest before semicolon");
2996
- }
2997
- }
2998
-
2999
- $newList = array("list", ", ", $newList);
3000
-
3001
- switch ($values[0][0]) {
3002
- case "arg":
3003
- $newArg = array("arg", $values[0][1], $newList);
3004
- break;
3005
- case "lit":
3006
- $newArg = array("lit", $newList);
3007
- break;
3008
- }
3009
-
3010
- } elseif ($values) { // 1 item
3011
- $newArg = $values[0];
3012
- }
3013
-
3014
- if ($newArg) {
3015
- $values = array($newArg);
3016
- }
3017
- } else {
3018
- break;
3019
- }
3020
- }
3021
- }
3022
-
3023
- if (!$this->literal(')')) {
3024
- $this->seek($s);
3025
- return false;
3026
- }
3027
-
3028
- $args = $values;
3029
-
3030
- return true;
3031
- }
3032
-
3033
- // consume a list of tags
3034
- // this accepts a hanging delimiter
3035
- protected function tags(&$tags, $simple = false, $delim = ',') {
3036
- $tags = array();
3037
- while ($this->tag($tt, $simple)) {
3038
- $tags[] = $tt;
3039
- if (!$this->literal($delim)) break;
3040
- }
3041
- if (count($tags) == 0) return false;
3042
-
3043
- return true;
3044
- }
3045
-
3046
- // list of tags of specifying mixin path
3047
- // optionally separated by > (lazy, accepts extra >)
3048
- protected function mixinTags(&$tags) {
3049
- $s = $this->seek();
3050
- $tags = array();
3051
- while ($this->tag($tt, true)) {
3052
- $tags[] = $tt;
3053
- $this->literal(">");
3054
- }
3055
-
3056
- if (count($tags) == 0) return false;
3057
-
3058
- return true;
3059
- }
3060
-
3061
- // a bracketed value (contained within in a tag definition)
3062
- protected function tagBracket(&$parts, &$hasExpression) {
3063
- // speed shortcut
3064
- if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "[") {
3065
- return false;
3066
- }
3067
-
3068
- $s = $this->seek();
3069
-
3070
- $hasInterpolation = false;
3071
-
3072
- if ($this->literal("[", false)) {
3073
- $attrParts = array("[");
3074
- // keyword, string, operator
3075
- while (true) {
3076
- if ($this->literal("]", false)) {
3077
- $this->count--;
3078
- break; // get out early
3079
- }
3080
-
3081
- if ($this->match('\s+', $m)) {
3082
- $attrParts[] = " ";
3083
- continue;
3084
- }
3085
- if ($this->string($str)) {
3086
- // escape parent selector, (yuck)
3087
- foreach ($str[2] as &$chunk) {
3088
- $chunk = str_replace($this->lessc->parentSelector, "$&$", $chunk);
3089
- }
3090
-
3091
- $attrParts[] = $str;
3092
- $hasInterpolation = true;
3093
- continue;
3094
- }
3095
-
3096
- if ($this->keyword($word)) {
3097
- $attrParts[] = $word;
3098
- continue;
3099
- }
3100
-
3101
- if ($this->interpolation($inter, false)) {
3102
- $attrParts[] = $inter;
3103
- $hasInterpolation = true;
3104
- continue;
3105
- }
3106
-
3107
- // operator, handles attr namespace too
3108
- if ($this->match('[|-~\$\*\^=]+', $m)) {
3109
- $attrParts[] = $m[0];
3110
- continue;
3111
- }
3112
-
3113
- break;
3114
- }
3115
-
3116
- if ($this->literal("]", false)) {
3117
- $attrParts[] = "]";
3118
- foreach ($attrParts as $part) {
3119
- $parts[] = $part;
3120
- }
3121
- $hasExpression = $hasExpression || $hasInterpolation;
3122
- return true;
3123
- }
3124
- $this->seek($s);
3125
- }
3126
-
3127
- $this->seek($s);
3128
- return false;
3129
- }
3130
-
3131
- // a space separated list of selectors
3132
- protected function tag(&$tag, $simple = false) {
3133
- if ($simple)
3134
- $chars = '^@,:;{}\][>\(\) "\'';
3135
- else
3136
- $chars = '^@,;{}["\'';
3137
-
3138
- $s = $this->seek();
3139
-
3140
- $hasExpression = false;
3141
- $parts = array();
3142
- while ($this->tagBracket($parts, $hasExpression));
3143
-
3144
- $oldWhite = $this->eatWhiteDefault;
3145
- $this->eatWhiteDefault = false;
3146
-
3147
- while (true) {
3148
- if ($this->match('(['.$chars.'0-9]['.$chars.']*)', $m)) {
3149
- $parts[] = $m[1];
3150
- if ($simple) break;
3151
-
3152
- while ($this->tagBracket($parts, $hasExpression));
3153
- continue;
3154
- }
3155
-
3156
- if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "@") {
3157
- if ($this->interpolation($interp)) {
3158
- $hasExpression = true;
3159
- $interp[2] = true; // don't unescape
3160
- $parts[] = $interp;
3161
- continue;
3162
- }
3163
-
3164
- if ($this->literal("@")) {
3165
- $parts[] = "@";
3166
- continue;
3167
- }
3168
- }
3169
-
3170
- if ($this->unit($unit)) { // for keyframes
3171
- $parts[] = $unit[1];
3172
- $parts[] = $unit[2];
3173
- continue;
3174
- }
3175
-
3176
- break;
3177
- }
3178
-
3179
- $this->eatWhiteDefault = $oldWhite;
3180
- if (!$parts) {
3181
- $this->seek($s);
3182
- return false;
3183
- }
3184
-
3185
- if ($hasExpression) {
3186
- $tag = array("exp", array("string", "", $parts));
3187
- } else {
3188
- $tag = trim(implode($parts));
3189
- }
3190
-
3191
- $this->whitespace();
3192
- return true;
3193
- }
3194
-
3195
- // a css function
3196
- protected function func(&$func) {
3197
- $s = $this->seek();
3198
-
3199
- if ($this->match('(%|[\w\-_][\w\-_:\.]+|[\w_])', $m) && $this->literal('(')) {
3200
- $fname = $m[1];
3201
-
3202
- $sPreArgs = $this->seek();
3203
-
3204
- $args = array();
3205
- while (true) {
3206
- $ss = $this->seek();
3207
- // this ugly nonsense is for ie filter properties
3208
- if ($this->keyword($name) && $this->literal('=') && $this->expressionList($value)) {
3209
- $args[] = array("string", "", array($name, "=", $value));
3210
- } else {
3211
- $this->seek($ss);
3212
- if ($this->expressionList($value)) {
3213
- $args[] = $value;
3214
- }
3215
- }
3216
-
3217
- if (!$this->literal(',')) break;
3218
- }
3219
- $args = array('list', ',', $args);
3220
-
3221
- if ($this->literal(')')) {
3222
- $func = array('function', $fname, $args);
3223
- return true;
3224
- } elseif ($fname == 'url') {
3225
- // couldn't parse and in url? treat as string
3226
- $this->seek($sPreArgs);
3227
- if ($this->openString(")", $string) && $this->literal(")")) {
3228
- $func = array('function', $fname, $string);
3229
- return true;
3230
- }
3231
- }
3232
- }
3233
-
3234
- $this->seek($s);
3235
- return false;
3236
- }
3237
-
3238
- // consume a less variable
3239
- protected function variable(&$name) {
3240
- $s = $this->seek();
3241
- if ($this->literal($this->lessc->vPrefix, false) &&
3242
- ($this->variable($sub) || $this->keyword($name)))
3243
- {
3244
- if (!empty($sub)) {
3245
- $name = array('variable', $sub);
3246
- } else {
3247
- $name = $this->lessc->vPrefix.$name;
3248
- }
3249
- return true;
3250
- }
3251
-
3252
- $name = null;
3253
- $this->seek($s);
3254
- return false;
3255
- }
3256
-
3257
- /**
3258
- * Consume an assignment operator
3259
- * Can optionally take a name that will be set to the current property name
3260
- */
3261
- protected function assign($name = null) {
3262
- if ($name) $this->currentProperty = $name;
3263
- return $this->literal(':') || $this->literal('=');
3264
- }
3265
-
3266
- // consume a keyword
3267
- protected function keyword(&$word) {
3268
- if ($this->match('([\w_\-\*!"][\w\-_"]*)', $m)) {
3269
- $word = $m[1];
3270
- return true;
3271
- }
3272
- return false;
3273
- }
3274
-
3275
- // consume an end of statement delimiter
3276
- protected function end() {
3277
- if ($this->literal(';')) {
3278
- return true;
3279
- } elseif ($this->count == strlen($this->buffer) || $this->buffer[$this->count] == '}') {
3280
- // if there is end of file or a closing block next then we don't need a ;
3281
- return true;
3282
- }
3283
- return false;
3284
- }
3285
-
3286
- protected function guards(&$guards) {
3287
- $s = $this->seek();
3288
-
3289
- if (!$this->literal("when")) {
3290
- $this->seek($s);
3291
- return false;
3292
- }
3293
-
3294
- $guards = array();
3295
-
3296
- while ($this->guardGroup($g)) {
3297
- $guards[] = $g;
3298
- if (!$this->literal(",")) break;
3299
- }
3300
-
3301
- if (count($guards) == 0) {
3302
- $guards = null;
3303
- $this->seek($s);
3304
- return false;
3305
- }
3306
-
3307
- return true;
3308
- }
3309
-
3310
- // a bunch of guards that are and'd together
3311
- // TODO rename to guardGroup
3312
- protected function guardGroup(&$guardGroup) {
3313
- $s = $this->seek();
3314
- $guardGroup = array();
3315
- while ($this->guard($guard)) {
3316
- $guardGroup[] = $guard;
3317
- if (!$this->literal("and")) break;
3318
- }
3319
-
3320
- if (count($guardGroup) == 0) {
3321
- $guardGroup = null;
3322
- $this->seek($s);
3323
- return false;
3324
- }
3325
-
3326
- return true;
3327
- }
3328
-
3329
- protected function guard(&$guard) {
3330
- $s = $this->seek();
3331
- $negate = $this->literal("not");
3332
-
3333
- if ($this->literal("(") && $this->expression($exp) && $this->literal(")")) {
3334
- $guard = $exp;
3335
- if ($negate) $guard = array("negate", $guard);
3336
- return true;
3337
- }
3338
-
3339
- $this->seek($s);
3340
- return false;
3341
- }
3342
-
3343
- /* raw parsing functions */
3344
-
3345
- protected function literal($what, $eatWhitespace = null) {
3346
- if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault;
3347
-
3348
- // shortcut on single letter
3349
- if (!isset($what[1]) && isset($this->buffer[$this->count])) {
3350
- if ($this->buffer[$this->count] == $what) {
3351
- if (!$eatWhitespace) {
3352
- $this->count++;
3353
- return true;
3354
- }
3355
- // goes below...
3356
- } else {
3357
- return false;
3358
- }
3359
- }
3360
-
3361
- if (!isset(self::$literalCache[$what])) {
3362
- self::$literalCache[$what] = JupiterX_Lessc::preg_quote($what);
3363
- }
3364
-
3365
- return $this->match(self::$literalCache[$what], $m, $eatWhitespace);
3366
- }
3367
-
3368
- protected function genericList(&$out, $parseItem, $delim="", $flatten=true) {
3369
- $s = $this->seek();
3370
- $items = array();
3371
- while ($this->$parseItem($value)) {
3372
- $items[] = $value;
3373
- if ($delim) {
3374
- if (!$this->literal($delim)) break;
3375
- }
3376
- }
3377
-
3378
- if (count($items) == 0) {
3379
- $this->seek($s);
3380
- return false;
3381
- }
3382
-
3383
- if ($flatten && count($items) == 1) {
3384
- $out = $items[0];
3385
- } else {
3386
- $out = array("list", $delim, $items);
3387
- }
3388
-
3389
- return true;
3390
- }
3391
-
3392
-
3393
- // advance counter to next occurrence of $what
3394
- // $until - don't include $what in advance
3395
- // $allowNewline, if string, will be used as valid char set
3396
- protected function to($what, &$out, $until = false, $allowNewline = false) {
3397
- if (is_string($allowNewline)) {
3398
- $validChars = $allowNewline;
3399
- } else {
3400
- $validChars = $allowNewline ? "." : "[^\n]";
3401
- }
3402
- if (!$this->match('('.$validChars.'*?)'.JupiterX_Lessc::preg_quote($what), $m, !$until)) return false;
3403
- if ($until) $this->count -= strlen($what); // give back $what
3404
- $out = $m[1];
3405
- return true;
3406
- }
3407
-
3408
- // try to match something on head of buffer
3409
- protected function match($regex, &$out, $eatWhitespace = null) {
3410
- if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault;
3411
-
3412
- $r = '/'.$regex.($eatWhitespace && !$this->writeComments ? '\s*' : '').'/Ais';
3413
- if (preg_match($r, $this->buffer, $out, null, $this->count)) {
3414
- $this->count += strlen($out[0]);
3415
- if ($eatWhitespace && $this->writeComments) $this->whitespace();
3416
- return true;
3417
- }
3418
- return false;
3419
- }
3420
-
3421
- // match some whitespace
3422
- protected function whitespace() {
3423
- if ($this->writeComments) {
3424
- $gotWhite = false;
3425
- while (preg_match(self::$whitePattern, $this->buffer, $m, null, $this->count)) {
3426
- if (isset($m[1]) && empty($this->commentsSeen[$this->count])) {
3427
- $this->append(array("comment", $m[1]));
3428
- $this->commentsSeen[$this->count] = true;
3429
- }
3430
- $this->count += strlen($m[0]);
3431
- $gotWhite = true;
3432
- }
3433
- return $gotWhite;
3434
- } else {
3435
- $this->match("", $m);
3436
- return strlen($m[0]) > 0;
3437
- }
3438
- }
3439
-
3440
- // match something without consuming it
3441
- protected function peek($regex, &$out = null, $from=null) {
3442
- if (is_null($from)) $from = $this->count;
3443
- $r = '/'.$regex.'/Ais';
3444
- $result = preg_match($r, $this->buffer, $out, null, $from);
3445
-
3446
- return $result;
3447
- }
3448
-
3449
- // seek to a spot in the buffer or return where we are on no argument
3450
- protected function seek($where = null) {
3451
- if ($where === null) return $this->count;
3452
- else $this->count = $where;
3453
- return true;
3454
- }
3455
-
3456
- /* misc functions */
3457
-
3458
- public function throwError($msg = "parse error", $count = null) {
3459
- $count = is_null($count) ? $this->count : $count;
3460
-
3461
- $line = $this->line +
3462
- substr_count(substr($this->buffer, 0, $count), "\n");
3463
-
3464
- if (!empty($this->sourceName)) {
3465
- $loc = "$this->sourceName on line $line";
3466
- } else {
3467
- $loc = "line: $line";
3468
- }
3469
-
3470
- // TODO this depends on $this->count
3471
- if ($this->peek("(.*?)(\n|$)", $m, $count)) {
3472
- throw new exception("$msg: failed at `$m[1]` $loc");
3473
- } else {
3474
- throw new exception("$msg: $loc");
3475
- }
3476
- }
3477
-
3478
- protected function pushBlock($selectors=null, $type=null) {
3479
- $b = new stdclass;
3480
- $b->parent = $this->env;
3481
-
3482
- $b->type = $type;
3483
- $b->id = self::$nextBlockId++;
3484
-
3485
- $b->isVararg = false; // TODO: kill me from here
3486
- $b->tags = $selectors;
3487
-
3488
- $b->props = array();
3489
- $b->children = array();
3490
-
3491
- $this->env = $b;
3492
- return $b;
3493
- }
3494
-
3495
- // push a block that doesn't multiply tags
3496
- protected function pushSpecialBlock($type) {
3497
- return $this->pushBlock(null, $type);
3498
- }
3499
-
3500
- // append a property to the current block
3501
- protected function append($prop, $pos = null) {
3502
- if ($pos !== null) $prop[-1] = $pos;
3503
- $this->env->props[] = $prop;
3504
- }
3505
-
3506
- // pop something off the stack
3507
- protected function pop() {
3508
- $old = $this->env;
3509
- $this->env = $this->env->parent;
3510
- return $old;
3511
- }
3512
-
3513
- // remove comments from $text
3514
- // todo: make it work for all functions, not just url
3515
- protected function removeComments($text) {
3516
- $look = array(
3517
- 'url(', '//', '/*', '"', "'"
3518
- );
3519
-
3520
- $out = '';
3521
- $min = null;
3522
- while (true) {
3523
- // find the next item
3524
- foreach ($look as $token) {
3525
- $pos = strpos($text, $token);
3526
- if ($pos !== false) {
3527
- if (!isset($min) || $pos < $min[1]) $min = array($token, $pos);
3528
- }
3529
- }
3530
-
3531
- if (is_null($min)) break;
3532
-
3533
- $count = $min[1];
3534
- $skip = 0;
3535
- $newlines = 0;
3536
- switch ($min[0]) {
3537
- case 'url(':
3538
- if (preg_match('/url\(.*?\)/', $text, $m, 0, $count))
3539
- $count += strlen($m[0]) - strlen($min[0]);
3540
- break;
3541
- case '"':
3542
- case "'":
3543
- if (preg_match('/'.$min[0].'.*?(?<!\\\\)'.$min[0].'/', $text, $m, 0, $count))
3544
- $count += strlen($m[0]) - 1;
3545
- break;
3546
- case '//':
3547
- $skip = strpos($text, "\n", $count);
3548
- if ($skip === false) $skip = strlen($text) - $count;
3549
- else $skip -= $count;
3550
- break;
3551
- case '/*':
3552
- if (preg_match('/\/\*.*?\*\//s', $text, $m, 0, $count)) {
3553
- $skip = strlen($m[0]);
3554
- $newlines = substr_count($m[0], "\n");
3555
- }
3556
- break;
3557
- }
3558
-
3559
- if ($skip == 0) $count += strlen($min[0]);
3560
-
3561
- $out .= substr($text, 0, $count).str_repeat("\n", $newlines);
3562
- $text = substr($text, $count + $skip);
3563
-
3564
- $min = null;
3565
- }
3566
-
3567
- return $out.$text;
3568
- }
3569
-
3570
- }
3571
-
3572
- /**
3573
- * @ignore
3574
- */
3575
- class lessc_formatter_classic {
3576
- public $indentChar = " ";
3577
-
3578
- public $break = "\n";
3579
- public $open = " {";
3580
- public $close = "}";
3581
- public $selectorSeparator = ", ";
3582
- public $assignSeparator = ":";
3583
-
3584
- public $openSingle = " { ";
3585
- public $closeSingle = " }";
3586
-
3587
- public $disableSingle = false;
3588
- public $breakSelectors = false;
3589
-
3590
- public $compressColors = false;
3591
-
3592
- public function __construct() {
3593
- $this->indentLevel = 0;
3594
- }
3595
-
3596
- public function indentStr($n = 0) {
3597
- return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
3598
- }
3599
-
3600
- public function property($name, $value) {
3601
- return $name . $this->assignSeparator . $value . ";";
3602
- }
3603
-
3604
- protected function isEmpty($block) {
3605
- if (empty($block->lines)) {
3606
- foreach ($block->children as $child) {
3607
- if (!$this->isEmpty($child)) return false;
3608
- }
3609
-
3610
- return true;
3611
- }
3612
- return false;
3613
- }
3614
-
3615
- public function block($block) {
3616
- if ($this->isEmpty($block)) return;
3617
-
3618
- $inner = $pre = $this->indentStr();
3619
-
3620
- $isSingle = !$this->disableSingle &&
3621
- is_null($block->type) && count($block->lines) == 1;
3622
-
3623
- if (!empty($block->selectors)) {
3624
- $this->indentLevel++;
3625
-
3626
- if ($this->breakSelectors) {
3627
- $selectorSeparator = $this->selectorSeparator . $this->break . $pre;
3628
- } else {
3629
- $selectorSeparator = $this->selectorSeparator;
3630
- }
3631
-
3632
- echo $pre .
3633
- implode($selectorSeparator, $block->selectors);
3634
- if ($isSingle) {
3635
- echo $this->openSingle;
3636
- $inner = "";
3637
- } else {
3638
- echo $this->open . $this->break;
3639
- $inner = $this->indentStr();
3640
- }
3641
-
3642
- }
3643
-
3644
- if (!empty($block->lines)) {
3645
- $glue = $this->break.$inner;
3646
- echo $inner . implode($glue, $block->lines);
3647
- if (!$isSingle && !empty($block->children)) {
3648
- echo $this->break;
3649
- }
3650
- }
3651
-
3652
- foreach ($block->children as $child) {
3653
- $this->block($child);
3654
- }
3655
-
3656
- if (!empty($block->selectors)) {
3657
- if (!$isSingle && empty($block->children)) echo $this->break;
3658
-
3659
- if ($isSingle) {
3660
- echo $this->closeSingle . $this->break;
3661
- } else {
3662
- echo $pre . $this->close . $this->break;
3663
- }
3664
-
3665
- $this->indentLevel--;
3666
- }
3667
- }
3668
- }
3669
-
3670
- /**
3671
- * @ignore
3672
- */
3673
- class lessc_formatter_compressed extends lessc_formatter_classic {
3674
- public $disableSingle = true;
3675
- public $open = "{";
3676
- public $selectorSeparator = ",";
3677
- public $assignSeparator = ":";
3678
- public $break = "";
3679
- public $compressColors = true;
3680
-
3681
- public function indentStr($n = 0) {
3682
- return "";
3683
- }
3684
- }
3685
-
3686
- /**
3687
- * @ignore
3688
- */
3689
- class lessc_formatter_lessjs extends lessc_formatter_classic {
3690
- public $disableSingle = true;
3691
- public $breakSelectors = true;
3692
- public $assignSeparator = ": ";
3693
- public $selectorSeparator = ",";
3694
- }
1
+ <?php
2
+ /**
3
+ * lessphp v0.4.0
4
+ * http://leafo.net/lessphp
5
+ *
6
+ * LESS css compiler, adapted from http://lesscss.org
7
+ *
8
+ * Copyright 2012, Leaf Corcoran <leafot@gmail.com>
9
+ * Licensed under MIT or GPLv3, see LICENSE
10
+ *
11
+ * @ignore
12
+ */
13
+
14
+
15
+ /**
16
+ * The less compiler and parser.
17
+ *
18
+ * Converting LESS to CSS is a three stage process. The incoming file is parsed
19
+ * by `jupiterx_lessc_parser` into a syntax tree, then it is compiled into another tree
20
+ * representing the CSS structure by `lessc`. The CSS tree is fed into a
21
+ * formatter, like `jupiterx_lessc_formatter` which then outputs CSS as a string.
22
+ *
23
+ * During the first compile, all values are *reduced*, which means that their
24
+ * types are brought to the lowest form before being dump as strings. This
25
+ * handles math equations, variable dereferences, and the like.
26
+ *
27
+ * The `parse` function of `lessc` is the entry point.
28
+ *
29
+ * In summary:
30
+ *
31
+ * The `lessc` class creates an intstance of the parser, feeds it LESS code,
32
+ * then transforms the resulting tree to a CSS tree. This class also holds the
33
+ * evaluation context, such as all available mixins and variables at any given
34
+ * time.
35
+ *
36
+ * The `jupiterx_lessc_parser` class is only concerned with parsing its input.
37
+ *
38
+ * The `jupiterx_lessc_formatter` takes a CSS tree, and dumps it to a formatted string,
39
+ * handling things like indentation.
40
+ *
41
+ * @ignore
42
+ */
43
+ class JupiterX_Lessc {
44
+ static public $VERSION = "v0.4.0";
45
+ static protected $TRUE = array("keyword", "true");
46
+ static protected $FALSE = array("keyword", "false");
47
+
48
+ protected $libFunctions = array();
49
+ protected $registeredVars = array();
50
+ protected $preserveComments = false;
51
+
52
+ public $vPrefix = '@'; // prefix of abstract properties
53
+ public $mPrefix = '$'; // prefix of abstract blocks
54
+ public $parentSelector = '&';
55
+
56
+ public $importDisabled = false;
57
+ public $importDir = '';
58
+
59
+ protected $numberPrecision = null;
60
+
61
+ protected $allParsedFiles = array();
62
+
63
+ // set to the parser that generated the current line when compiling
64
+ // so we know how to create error messages
65
+ protected $sourceParser = null;
66
+ protected $sourceLoc = null;
67
+
68
+ static public $defaultValue = array("keyword", "");
69
+
70
+ static protected $nextImportId = 0; // uniquely identify imports
71
+
72
+ // attempts to find the path of an import url, returns null for css files
73
+ protected function findImport($url) {
74
+ foreach ((array)$this->importDir as $dir) {
75
+ $full = $dir.(substr($dir, -1) != '/' ? '/' : '').$url;
76
+ if ($this->fileExists($file = $full.'.less') || $this->fileExists($file = $full)) {
77
+ return $file;
78
+ }
79
+ }
80
+
81
+ return null;
82
+ }
83
+
84
+ protected function fileExists($name) {
85
+ return is_file($name);
86
+ }
87
+
88
+ static public function compressList($items, $delim) {
89
+ if (!isset($items[1]) && isset($items[0])) return $items[0];
90
+ else return array('list', $delim, $items);
91
+ }
92
+
93
+ static public function preg_quote($what) {
94
+ return preg_quote($what, '/');
95
+ }
96
+
97
+ protected function tryImport($importPath, $parentBlock, $out) {
98
+ if ($importPath[0] == "function" && $importPath[1] == "url") {
99
+ $importPath = $this->flattenList($importPath[2]);
100
+ }
101
+
102
+ $str = $this->coerceString($importPath);
103
+ if ($str === null) return false;
104
+
105
+ $url = $this->compileValue($this->lib_unquote($str));
106
+
107
+ // don't import if it ends in css
108
+ if (substr_compare($url, '.css', -4, 4) === 0) return false;
109
+
110
+ $realPath = $this->findImport($url);
111
+
112
+ if ($realPath === null) return false;
113
+
114
+ if ($this->importDisabled) {
115
+ return array(false, "/* import disabled */");
116
+ }
117
+
118
+ if (isset($this->allParsedFiles[realpath($realPath)])) {
119
+ return array(false, null);
120
+ }
121
+
122
+ $this->addParsedFile($realPath);
123
+ $parser = $this->makeParser($realPath);
124
+ $root = $parser->parse($GLOBALS['wp_filesystem']->get_contents($realPath));
125
+
126
+ // set the parents of all the block props
127
+ foreach ($root->props as $prop) {
128
+ if ($prop[0] == "block") {
129
+ $prop[1]->parent = $parentBlock;
130
+ }
131
+ }
132
+
133
+ // copy mixins into scope, set their parents
134
+ // bring blocks from import into current block
135
+ // TODO: need to mark the source parser these came from this file
136
+ foreach ($root->children as $childName => $child) {
137
+ if (isset($parentBlock->children[$childName])) {
138
+ $parentBlock->children[$childName] = array_merge(
139
+ $parentBlock->children[$childName],
140
+ $child);
141
+ } else {
142
+ $parentBlock->children[$childName] = $child;
143
+ }
144
+ }
145
+
146
+ $pi = pathinfo($realPath);
147
+ $dir = $pi["dirname"];
148
+
149
+ list($top, $bottom) = $this->sortProps($root->props, true);
150
+ $this->compileImportedProps($top, $parentBlock, $out, $parser, $dir);
151
+
152
+ return array(true, $bottom, $parser, $dir);
153
+ }
154
+
155
+ protected function compileImportedProps($props, $block, $out, $sourceParser, $importDir) {
156
+ $oldSourceParser = $this->sourceParser;
157
+
158
+ $oldImport = $this->importDir;
159
+
160
+ // TODO: this is because the importDir api is stupid
161
+ $this->importDir = (array)$this->importDir;
162
+ array_unshift($this->importDir, $importDir);
163
+
164
+ foreach ($props as $prop) {
165
+ $this->compileProp($prop, $block, $out);
166
+ }
167
+
168
+ $this->importDir = $oldImport;
169
+ $this->sourceParser = $oldSourceParser;
170
+ }
171
+
172
+ /**
173
+ * Recursively compiles a block.
174
+ *
175
+ * A block is analogous to a CSS block in most cases. A single LESS document
176
+ * is encapsulated in a block when parsed, but it does not have parent tags
177
+ * so all of it's children appear on the root level when compiled.
178
+ *
179
+ * Blocks are made up of props and children.
180
+ *
181
+ * Props are property instructions, array tuples which describe an action
182
+ * to be taken, eg. write a property, set a variable, mixin a block.
183
+ *
184
+ * The children of a block are just all the blocks that are defined within.
185
+ * This is used to look up mixins when performing a mixin.
186
+ *
187
+ * Compiling the block involves pushing a fresh environment on the stack,
188
+ * and iterating through the props, compiling each one.
189
+ *
190
+ * See lessc::compileProp()
191
+ *
192
+ */
193
+ protected function compileBlock($block) {
194
+ switch ($block->type) {
195
+ case "root":
196
+ $this->compileRoot($block);
197
+ break;
198
+ case null:
199
+ $this->compileCSSBlock($block);
200
+ break;
201
+ case "media":
202
+ $this->compileMedia($block);
203
+ break;
204
+ case "directive":
205
+ $name = "@" . $block->name;
206
+ if (!empty($block->value)) {
207
+ $name .= " " . $this->compileValue($this->reduce($block->value));
208
+ }
209
+
210
+ $this->compileNestedBlock($block, array($name));
211
+ break;
212
+ default:
213
+ $this->throwError("unknown block type: $block->type\n");
214
+ }
215
+ }
216
+
217
+ protected function compileCSSBlock($block) {
218
+ $env = $this->pushEnv();
219
+
220
+ $selectors = $this->compileSelectors($block->tags);
221
+ $env->selectors = $this->multiplySelectors($selectors);
222
+ $out = $this->makeOutputBlock(null, $env->selectors);
223
+
224
+ $this->scope->children[] = $out;
225
+ $this->compileProps($block, $out);
226
+
227
+ $block->scope = $env; // mixins carry scope with them!
228
+ $this->popEnv();
229
+ }
230
+
231
+ protected function compileMedia($media) {
232
+ $env = $this->pushEnv($media);
233
+ $parentScope = $this->mediaParent($this->scope);
234
+
235
+ $query = $this->compileMediaQuery($this->multiplyMedia($env));
236
+
237
+ $this->scope = $this->makeOutputBlock($media->type, array($query));
238
+ $parentScope->children[] = $this->scope;
239
+
240
+ $this->compileProps($media, $this->scope);
241
+
242
+ if (count($this->scope->lines) > 0) {
243
+ $orphanSelelectors = $this->findClosestSelectors();
244
+ if (!is_null($orphanSelelectors)) {
245
+ $orphan = $this->makeOutputBlock(null, $orphanSelelectors);
246
+ $orphan->lines = $this->scope->lines;
247
+ array_unshift($this->scope->children, $orphan);
248
+ $this->scope->lines = array();
249
+ }
250
+ }
251
+
252
+ $this->scope = $this->scope->parent;
253
+ $this->popEnv();
254
+ }
255
+
256
+ protected function mediaParent($scope) {
257
+ while (!empty($scope->parent)) {
258
+ if (!empty($scope->type) && $scope->type != "media") {
259
+ break;
260
+ }
261
+ $scope = $scope->parent;
262
+ }
263
+
264
+ return $scope;
265
+ }
266
+
267
+ protected function compileNestedBlock($block, $selectors) {
268
+ $this->pushEnv($block);
269
+ $this->scope = $this->makeOutputBlock($block->type, $selectors);
270
+ $this->scope->parent->children[] = $this->scope;
271
+
272
+ $this->compileProps($block, $this->scope);
273
+
274
+ $this->scope = $this->scope->parent;
275
+ $this->popEnv();
276
+ }
277
+
278
+ protected function compileRoot($root) {
279
+ $this->pushEnv();
280
+ $this->scope = $this->makeOutputBlock($root->type);
281
+ $this->compileProps($root, $this->scope);
282
+ $this->popEnv();
283
+ }
284
+
285
+ protected function compileProps($block, $out) {
286
+ foreach ($this->sortProps($block->props) as $prop) {
287
+ $this->compileProp($prop, $block, $out);
288
+ }
289
+
290
+ $out->lines = array_values(array_unique($out->lines));
291
+ }
292
+
293
+ protected function sortProps($props, $split = false) {
294
+ $vars = array();
295
+ $imports = array();
296
+ $other = array();
297
+
298
+ foreach ($props as $prop) {
299
+ switch ($prop[0]) {
300
+ case "assign":
301
+ if (isset($prop[1][0]) && $prop[1][0] == $this->vPrefix) {
302
+ $vars[] = $prop;
303
+ } else {
304
+ $other[] = $prop;
305
+ }
306
+ break;
307
+ case "import":
308
+ $id = self::$nextImportId++;
309
+ $prop[] = $id;
310
+ $imports[] = $prop;
311
+ $other[] = array("import_mixin", $id);
312
+ break;
313
+ default:
314
+ $other[] = $prop;
315
+ }
316
+ }
317
+
318
+ if ($split) {
319
+ return array(array_merge($vars, $imports), $other);
320
+ } else {
321
+ return array_merge($vars, $imports, $other);
322
+ }
323
+ }
324
+
325
+ protected function compileMediaQuery($queries) {
326
+ $compiledQueries = array();
327
+ foreach ($queries as $query) {
328
+ $parts = array();
329
+ foreach ($query as $q) {
330
+ switch ($q[0]) {
331
+ case "mediaType":
332
+ $parts[] = implode(" ", array_slice($q, 1));
333
+ break;
334
+ case "mediaExp":
335
+ if (isset($q[2])) {
336
+ $parts[] = "($q[1]: " .
337
+ $this->compileValue($this->reduce($q[2])) . ")";
338
+ } else {
339
+ $parts[] = "($q[1])";
340
+ }
341
+ break;
342
+ case "variable":
343
+ $parts[] = $this->compileValue($this->reduce($q));
344
+ break;
345
+ }
346
+ }
347
+
348
+ if (count($parts) > 0) {
349
+ $compiledQueries[] = implode(" and ", $parts);
350
+ }
351
+ }
352
+
353
+ $out = "@media";
354
+ if (!empty($parts)) {
355
+ $out .= " " .
356
+ implode($this->formatter->selectorSeparator, $compiledQueries);
357
+ }
358
+ return $out;
359
+ }
360
+
361
+ protected function multiplyMedia($env, $childQueries = null) {
362
+ if (is_null($env) ||
363
+ !empty($env->block->type) && $env->block->type != "media")
364
+ {
365
+ return $childQueries;
366
+ }
367
+
368
+ // plain old block, skip
369
+ if (empty($env->block->type)) {
370
+ return $this->multiplyMedia($env->parent, $childQueries);
371
+ }
372
+
373
+ $out = array();
374
+ $queries = $env->block->queries;
375
+ if (is_null($childQueries)) {
376
+ $out = $queries;
377
+ } else {
378
+ foreach ($queries as $parent) {
379
+ foreach ($childQueries as $child) {
380
+ $out[] = array_merge($parent, $child);
381
+ }
382
+ }
383
+ }
384
+
385
+ return $this->multiplyMedia($env->parent, $out);
386
+ }
387
+
388
+ protected function expandParentSelectors(&$tag, $replace) {
389
+ $parts = explode("$&$", $tag);
390
+ $count = 0;
391
+ foreach ($parts as &$part) {
392
+ $part = str_replace($this->parentSelector, $replace, $part, $c);
393
+ $count += $c;
394
+ }
395
+ $tag = implode($this->parentSelector, $parts);
396
+ return $count;
397
+ }
398
+
399
+ protected function findClosestSelectors() {
400
+ $env = $this->env;
401
+ $selectors = null;
402
+ while ($env !== null) {
403
+ if (isset($env->selectors)) {
404
+ $selectors = $env->selectors;
405
+ break;
406
+ }
407
+ $env = $env->parent;
408
+ }
409
+
410
+ return $selectors;
411
+ }
412
+
413
+
414
+ // multiply $selectors against the nearest selectors in env
415
+ protected function multiplySelectors($selectors) {
416
+ // find parent selectors
417
+
418
+ $parentSelectors = $this->findClosestSelectors();
419
+ if (is_null($parentSelectors)) {
420
+ // kill parent reference in top level selector
421
+ foreach ($selectors as &$s) {
422
+ $this->expandParentSelectors($s, "");
423
+ }
424
+
425
+ return $selectors;
426
+ }
427
+
428
+ $out = array();
429
+ foreach ($parentSelectors as $parent) {
430
+ foreach ($selectors as $child) {
431
+ $count = $this->expandParentSelectors($child, $parent);
432
+
433
+ // don't prepend the parent tag if & was used
434
+ if ($count > 0) {
435
+ $out[] = trim($child);
436
+ } else {
437
+ $out[] = trim($parent . ' ' . $child);
438
+ }
439
+ }
440
+ }
441
+
442
+ return $out;
443
+ }
444
+
445
+ // reduces selector expressions
446
+ protected function compileSelectors($selectors) {
447
+ $out = array();
448
+
449
+ foreach ($selectors as $s) {
450
+ if (is_array($s)) {
451
+ list(, $value) = $s;
452
+ $out[] = trim($this->compileValue($this->reduce($value)));
453
+ } else {
454
+ $out[] = $s;
455
+ }
456
+ }
457
+
458
+ return $out;
459
+ }
460
+
461
+ protected function eq($left, $right) {
462
+ return $left == $right;
463
+ }
464
+
465
+ protected function patternMatch($block, $orderedArgs, $keywordArgs) {
466
+ // match the guards if it has them
467
+ // any one of the groups must have all its guards pass for a match
468
+ if (!empty($block->guards)) {
469
+ $groupPassed = false;
470
+ foreach ($block->guards as $guardGroup) {
471
+ foreach ($guardGroup as $guard) {
472
+ $this->pushEnv();
473
+ $this->zipSetArgs($block->args, $orderedArgs, $keywordArgs);
474
+
475
+ $negate = false;
476
+ if ($guard[0] == "negate") {
477
+ $guard = $guard[1];
478
+ $negate = true;
479
+ }
480
+
481
+ $passed = $this->reduce($guard) == self::$TRUE;
482
+ if ($negate) $passed = !$passed;
483
+
484
+ $this->popEnv();
485
+
486
+ if ($passed) {
487
+ $groupPassed = true;
488
+ } else {
489
+ $groupPassed = false;
490
+ break;
491
+ }
492
+ }
493
+
494
+ if ($groupPassed) break;
495
+ }
496
+
497
+ if (!$groupPassed) {
498
+ return false;
499
+ }
500
+ }
501
+
502
+ if (empty($block->args)) {
503
+ return $block->isVararg || empty($orderedArgs) && empty($keywordArgs);
504
+ }
505
+
506
+ $remainingArgs = $block->args;
507
+ if ($keywordArgs) {
508
+ $remainingArgs = array();
509
+ foreach ($block->args as $arg) {
510
+ if ($arg[0] == "arg" && isset($keywordArgs[$arg[1]])) {
511
+ continue;
512
+ }
513
+
514
+ $remainingArgs[] = $arg;
515
+ }
516
+ }
517
+
518
+ $i = -1; // no args
519
+ // try to match by arity or by argument literal
520
+ foreach ($remainingArgs as $i => $arg) {
521
+ switch ($arg[0]) {
522
+ case "lit":
523
+ if (empty($orderedArgs[$i]) || !$this->eq($arg[1], $orderedArgs[$i])) {
524
+ return false;
525
+ }
526
+ break;
527
+ case "arg":
528
+ // no arg and no default value
529
+ if (!isset($orderedArgs[$i]) && !isset($arg[2])) {
530
+ return false;
531
+ }
532
+ break;
533
+ case "rest":
534
+ $i--; // rest can be empty
535
+ break 2;
536
+ }
537
+ }
538
+
539
+ if ($block->isVararg) {
540
+ return true; // not having enough is handled above
541
+ } else {
542
+ $numMatched = $i + 1;
543
+ // greater than becuase default values always match
544
+ return $numMatched >= count($orderedArgs);
545
+ }
546
+ }
547
+
548
+ protected function patternMatchAll($blocks, $orderedArgs, $keywordArgs, $skip=array()) {
549
+ $matches = null;
550
+ foreach ($blocks as $block) {
551
+ // skip seen blocks that don't have arguments
552
+ if (isset($skip[$block->id]) && !isset($block->args)) {
553
+ continue;
554
+ }
555
+
556
+ if ($this->patternMatch($block, $orderedArgs, $keywordArgs)) {
557
+ $matches[] = $block;
558
+ }
559
+ }
560
+
561
+ return $matches;
562
+ }
563
+
564
+ // attempt to find blocks matched by path and args
565
+ protected function findBlocks($searchIn, $path, $orderedArgs, $keywordArgs, $seen=array()) {
566
+ if ($searchIn == null) return null;
567
+ if (isset($seen[$searchIn->id])) return null;
568
+ $seen[$searchIn->id] = true;
569
+
570
+ $name = $path[0];
571
+
572
+ if (isset($searchIn->children[$name])) {
573
+ $blocks = $searchIn->children[$name];
574
+ if (count($path) == 1) {
575
+ $matches = $this->patternMatchAll($blocks, $orderedArgs, $keywordArgs, $seen);
576
+ if (!empty($matches)) {
577
+ // This will return all blocks that match in the closest
578
+ // scope that has any matching block, like lessjs
579
+ return $matches;
580
+ }
581
+ } else {
582
+ $matches = array();
583
+ foreach ($blocks as $subBlock) {
584
+ $subMatches = $this->findBlocks($subBlock,
585
+ array_slice($path, 1), $orderedArgs, $keywordArgs, $seen);
586
+
587
+ if (!is_null($subMatches)) {
588
+ foreach ($subMatches as $sm) {
589
+ $matches[] = $sm;
590
+ }
591
+ }
592
+ }
593
+
594
+ return count($matches) > 0 ? $matches : null;
595
+ }
596
+ }
597
+ if ($searchIn->parent === $searchIn) return null;
598
+ return $this->findBlocks($searchIn->parent, $path, $orderedArgs, $keywordArgs, $seen);
599
+ }
600
+
601
+ // sets all argument names in $args to either the default value
602
+ // or the one passed in through $values
603
+ protected function zipSetArgs($args, $orderedValues, $keywordValues) {
604
+ $assignedValues = array();
605
+
606
+ $i = 0;
607
+ foreach ($args as $a) {
608
+ if ($a[0] == "arg") {
609
+ if (isset($keywordValues[$a[1]])) {
610
+ // has keyword arg
611
+ $value = $keywordValues[$a[1]];
612
+ } elseif (isset($orderedValues[$i])) {
613
+ // has ordered arg
614
+ $value = $orderedValues[$i];
615
+ $i++;
616
+ } elseif (isset($a[2])) {
617
+ // has default value
618
+ $value = $a[2];
619
+ } else {
620
+ $this->throwError("Failed to assign arg " . $a[1]);
621
+ $value = null; // :(
622
+ }
623
+
624
+ $value = $this->reduce($value);
625
+ $this->set($a[1], $value);
626
+ $assignedValues[] = $value;
627
+ } else {
628
+ // a lit
629
+ $i++;
630
+ }
631
+ }
632
+
633
+ // check for a rest
634
+ $last = (array) end($args);
635
+ if ($last[0] == "rest") {
636
+ $rest = array_slice($orderedValues, count($args) - 1);
637
+ $this->set($last[1], $this->reduce(array("list", " ", $rest)));
638
+ }
639
+
640
+ // wow is this the only true use of PHP's + operator for arrays?
641
+ $this->env->arguments = $assignedValues + $orderedValues;
642
+ }
643
+
644
+ // compile a prop and update $lines or $blocks appropriately
645
+ protected function compileProp($prop, $block, $out) {
646
+ // set error position context
647
+ $this->sourceLoc = isset($prop[-1]) ? $prop[-1] : -1;
648
+
649
+ switch ($prop[0]) {
650
+ case 'assign':
651
+ list(, $name, $value) = $prop;
652
+ if ($name[0] == $this->vPrefix) {
653
+ $this->set($name, $value);
654
+ } else {
655
+ $out->lines[] = $this->formatter->property($name,
656
+ $this->compileValue($this->reduce($value)));
657
+ }
658
+ break;
659
+ case 'block':
660
+ list(, $child) = $prop;
661
+ $this->compileBlock($child);
662
+ break;
663
+ case 'mixin':
664
+ list(, $path, $args, $suffix) = $prop;
665
+
666
+ $orderedArgs = array();
667
+ $keywordArgs = array();
668
+ foreach ((array)$args as $arg) {
669
+ $argval = null;
670
+ switch ($arg[0]) {
671
+ case "arg":
672
+ if (!isset($arg[2])) {
673
+ $orderedArgs[] = $this->reduce(array("variable", $arg[1]));
674
+ } else {
675
+ $keywordArgs[$arg[1]] = $this->reduce($arg[2]);
676
+ }
677
+ break;
678
+
679
+ case "lit":
680
+ $orderedArgs[] = $this->reduce($arg[1]);
681
+ break;
682
+ default:
683
+ $this->throwError("Unknown arg type: " . $arg[0]);
684
+ }
685
+ }
686
+
687
+ $mixins = $this->findBlocks($block, $path, $orderedArgs, $keywordArgs);
688
+
689
+ if ($mixins === null) {
690
+ break; // throw error here??
691
+ }
692
+
693
+ foreach ($mixins as $mixin) {
694
+ if ($mixin === $block && !$orderedArgs) {
695
+ continue;
696
+ }
697
+
698
+ $haveScope = false;
699
+ if (isset($mixin->parent->scope)) {
700
+ $haveScope = true;
701
+ $mixinParentEnv = $this->pushEnv();
702
+ $mixinParentEnv->storeParent = $mixin->parent->scope;
703
+ }
704
+
705
+ $haveArgs = false;
706
+ if (isset($mixin->args)) {
707
+ $haveArgs = true;
708
+ $this->pushEnv();
709
+ $this->zipSetArgs($mixin->args, $orderedArgs, $keywordArgs);
710
+ }
711
+
712
+ $oldParent = $mixin->parent;
713
+ if ($mixin != $block) $mixin->parent = $block;
714
+
715
+ foreach ($this->sortProps($mixin->props) as $subProp) {
716
+ if ($suffix !== null &&
717
+ $subProp[0] == "assign" &&
718
+ is_string($subProp[1]) &&
719
+ $subProp[1][0] != $this->vPrefix)
720
+ {
721
+ $subProp[2] = array(
722
+ 'list', ' ',
723
+ array($subProp[2], array('keyword', $suffix))
724
+ );
725
+ }
726
+
727
+ $this->compileProp($subProp, $mixin, $out);
728
+ }
729
+
730
+ $mixin->parent = $oldParent;
731
+
732
+ if ($haveArgs) $this->popEnv();
733
+ if ($haveScope) $this->popEnv();
734
+ }
735
+
736
+ break;
737
+ case 'raw':
738
+ $out->lines[] = $prop[1];
739
+ break;
740
+ case "directive":
741
+ list(, $name, $value) = $prop;
742
+ $out->lines[] = "@$name " . $this->compileValue($this->reduce($value)).';';
743
+ break;
744
+ case "comment":
745
+ $out->lines[] = $prop[1];
746
+ break;
747
+ case "import";
748
+ list(, $importPath, $importId) = $prop;
749
+ $importPath = $this->reduce($importPath);
750
+
751
+ if (!isset($this->env->imports)) {
752
+ $this->env->imports = array();
753
+ }
754
+
755
+ $result = $this->tryImport($importPath, $block, $out);
756
+
757
+ $this->env->imports[$importId] = $result === false ?
758
+ array(false, "@import " . $this->compileValue($importPath).";") :
759
+ $result;
760
+
761
+ break;
762
+ case "import_mixin":
763
+ list(,$importId) = $prop;
764
+ $import = $this->env->imports[$importId];
765
+ if ($import[0] === false) {
766
+ if (isset($import[1])) {
767
+ $out->lines[] = $import[1];
768
+ }
769
+ } else {
770
+ list(, $bottom, $parser, $importDir) = $import;
771
+ $this->compileImportedProps($bottom, $block, $out, $parser, $importDir);
772
+ }
773
+
774
+ break;
775
+ default:
776
+ $this->throwError("unknown op: {$prop[0]}\n");
777
+ }
778
+ }
779
+
780
+
781
+ /**
782
+ * Compiles a primitive value into a CSS property value.
783
+ *
784
+ * Values in lessphp are typed by being wrapped in arrays, their format is
785
+ * typically:
786
+ *
787
+ * array(type, contents [, additional_contents]*)
788
+ *
789
+ * The input is expected to be reduced. This function will not work on
790
+ * things like expressions and variables.
791
+ */
792
+ protected function compileValue($value) {
793
+ switch ($value[0]) {
794
+ case 'list':
795
+ // [1] - delimiter
796
+ // [2] - array of values
797
+ return implode($value[1], array_map(array($this, 'compileValue'), $value[2]));
798
+ case 'raw_color':
799
+ if (!empty($this->formatter->compressColors)) {
800
+ return $this->compileValue($this->coerceColor($value));
801
+ }
802
+ return $value[1];
803
+ case 'keyword':
804
+ // [1] - the keyword
805
+ return $value[1];
806
+ case 'number':
807
+ list(, $num, $unit) = $value;
808
+ // [1] - the number
809
+ // [2] - the unit
810
+ if ($this->numberPrecision !== null) {
811
+ $num = round($num, $this->numberPrecision);
812
+ }
813
+ return $num . $unit;
814
+ case 'string':
815
+ // [1] - contents of string (includes quotes)
816
+ list(, $delim, $content) = $value;
817
+ foreach ($content as &$part) {
818
+ if (is_array($part)) {
819
+ $part = $this->compileValue($part);
820
+ }
821
+ }
822
+ return $delim . implode($content) . $delim;
823
+ case 'color':
824
+ // [1] - red component (either number or a %)
825
+ // [2] - green component
826
+ // [3] - blue component
827
+ // [4] - optional alpha component
828
+ list(, $r, $g, $b) = $value;
829
+ $r = round($r);
830
+ $g = round($g);
831
+ $b = round($b);
832
+
833
+ if (count($value) == 5 && $value[4] != 1) { // rgba
834
+ return 'rgba('.$r.','.$g.','.$b.','.$value[4].')';
835
+ }
836
+
837
+ $h = sprintf("#%02x%02x%02x", $r, $g, $b);
838
+
839
+ if (!empty($this->formatter->compressColors)) {
840
+ // Converting hex color to short notation (e.g. #003399 to #039)
841
+ if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) {
842
+ $h = '#' . $h[1] . $h[3] . $h[5];
843
+ }
844
+ }
845
+
846
+ return $h;
847
+
848
+ case 'function':
849
+ list(, $name, $args) = $value;
850
+ return $name.'('.$this->compileValue($args).')';
851
+ default: // assumed to be unit
852
+ $this->throwError("unknown value type: $value[0]");
853
+ }
854
+ }
855
+
856
+ protected function lib_pow($args) {
857
+ list($base, $exp) = $this->assertArgs($args, 2, "pow");
858
+ return pow($this->assertNumber($base), $this->assertNumber($exp));
859
+ }
860
+
861
+ protected function lib_pi() {
862
+ return pi();
863
+ }
864
+
865
+ protected function lib_mod($args) {
866
+ list($a, $b) = $this->assertArgs($args, 2, "mod");
867
+ return $this->assertNumber($a) % $this->assertNumber($b);
868
+ }
869
+
870
+ protected function lib_tan($num) {
871
+ return tan($this->assertNumber($num));
872
+ }
873
+
874
+ protected function lib_sin($num) {
875
+ return sin($this->assertNumber($num));
876
+ }
877
+
878
+ protected function lib_cos($num) {
879
+ return cos($this->assertNumber($num));
880
+ }
881
+
882
+ protected function lib_atan($num) {
883
+ $num = atan($this->assertNumber($num));
884
+ return array("number", $num, "rad");
885
+ }
886
+
887
+ protected function lib_asin($num) {
888
+ $num = asin($this->assertNumber($num));
889
+ return array("number", $num, "rad");
890
+ }
891
+
892
+ protected function lib_acos($num) {
893
+ $num = acos($this->assertNumber($num));
894
+ return array("number", $num, "rad");
895
+ }
896
+
897
+ protected function lib_sqrt($num) {
898
+ return sqrt($this->assertNumber($num));
899
+ }
900
+
901
+ protected function lib_extract($value) {
902
+ list($list, $idx) = $this->assertArgs($value, 2, "extract");
903
+ $idx = $this->assertNumber($idx);
904
+ // 1 indexed
905
+ if ($list[0] == "list" && isset($list[2][$idx - 1])) {
906
+ return $list[2][$idx - 1];
907
+ }
908
+ }
909
+
910
+ protected function lib_isnumber($value) {
911
+ return $this->toBool($value[0] == "number");
912
+ }
913
+
914
+ protected function lib_isstring($value) {
915
+ return $this->toBool($value[0] == "string");
916
+ }
917
+
918
+ protected function lib_iscolor($value) {
919
+ return $this->toBool($this->coerceColor($value));
920
+ }
921
+
922
+ protected function lib_iskeyword($value) {
923
+ return $this->toBool($value[0] == "keyword");
924
+ }
925
+
926
+ protected function lib_ispixel($value) {
927
+ return $this->toBool($value[0] == "number" && $value[2] == "px");
928
+ }
929
+
930
+ protected function lib_ispercentage($value) {
931
+ return $this->toBool($value[0] == "number" && $value[2] == "%");
932
+ }
933
+
934
+ protected function lib_isem($value) {
935
+ return $this->toBool($value[0] == "number" && $value[2] == "em");
936
+ }
937
+
938
+ protected function lib_isrem($value) {
939
+ return $this->toBool($value[0] == "number" && $value[2] == "rem");
940
+ }
941
+
942
+ protected function lib_rgbahex($color) {
943
+ $color = $this->coerceColor($color);
944
+ if (is_null($color))
945
+ $this->throwError("color expected for rgbahex");
946
+
947
+ return sprintf("#%02x%02x%02x%02x",
948
+ isset($color[4]) ? $color[4]*255 : 255,
949
+ $color[1],$color[2], $color[3]);
950
+ }
951
+
952
+ protected function lib_argb($color){
953
+ return $this->lib_rgbahex($color);
954
+ }
955
+
956
+ // utility func to unquote a string
957
+ // use func_get_arg to prevent Theme Checker triggering unrelated translation warning.
958
+ protected function lib_e() {
959
+ $arg = func_get_arg(0);
960
+ switch ($arg[0]) {
961
+ case "list":
962
+ $items = $arg[2];
963
+ if (isset($items[0])) {
964
+ return $this->lib_unquote($items[0]);
965
+ }
966
+ return self::$defaultValue;
967
+ case "string":
968
+ $arg[1] = "";
969
+ return $arg;
970
+ case "keyword":
971
+ return $arg;
972
+ default:
973
+ return array("keyword", $this->compileValue($arg));
974
+ }
975
+ }
976
+
977
+ // use func_get_arg to prevent Theme Checker triggering unrelated translation warning.
978
+ protected function lib_unquote($arg) {
979
+ return $this->lib_e(func_get_arg(0));
980
+ }
981
+
982
+ protected function lib__sprintf($args) {
983
+ if ($args[0] != "list") return $args;
984
+ $values = $args[2];
985
+ $string = array_shift($values);
986
+ $template = $this->compileValue($this->lib_unquote($string));
987
+
988
+ $i = 0;
989
+ if (preg_match_all('/%[dsa]/', $template, $m)) {
990
+ foreach ($m[0] as $match) {
991
+ $val = isset($values[$i]) ?
992
+ $this->reduce($values[$i]) : array('keyword', '');
993
+
994
+ // lessjs compat, renders fully expanded color, not raw color
995
+ if ($color = $this->coerceColor($val)) {
996
+ $val = $color;
997
+ }
998
+
999
+ $i++;
1000
+ $rep = $this->compileValue($this->lib_unquote($val));
1001
+ $template = preg_replace('/'.self::preg_quote($match).'/',
1002
+ $rep, $template, 1);
1003
+ }
1004
+ }
1005
+
1006
+ $d = $string[0] == "string" ? $string[1] : '"';
1007
+ return array("string", $d, array($template));
1008
+ }
1009
+
1010
+ protected function lib_floor($arg) {
1011
+ $value = $this->assertNumber($arg);
1012
+ return array("number", floor($value), $arg[2]);
1013
+ }
1014
+
1015
+ protected function lib_ceil($arg) {
1016
+ $value = $this->assertNumber($arg);
1017
+ return array("number", ceil($value), $arg[2]);
1018
+ }
1019
+
1020
+ protected function lib_round($arg) {
1021
+ $value = $this->assertNumber($arg);
1022
+ return array("number", round($value), $arg[2]);
1023
+ }
1024
+
1025
+ protected function lib_unit($arg) {
1026
+ if ($arg[0] == "list") {
1027
+ list($number, $newUnit) = $arg[2];
1028
+ return array("number", $this->assertNumber($number),
1029
+ $this->compileValue($this->lib_unquote($newUnit)));
1030
+ } else {
1031
+ return array("number", $this->assertNumber($arg), "");
1032
+ }
1033
+ }
1034
+
1035
+ /**
1036
+ * Helper function to get arguments for color manipulation functions.
1037
+ * takes a list that contains a color like thing and a percentage
1038
+ */
1039
+ protected function colorArgs($args) {
1040
+ if ($args[0] != 'list' || count($args[2]) < 2) {
1041
+ return array(array('color', 0, 0, 0), 0);
1042
+ }
1043
+ list($color, $delta) = $args[2];
1044
+ $color = $this->assertColor($color);
1045
+ $delta = floatval($delta[1]);
1046
+
1047
+ return array($color, $delta);
1048
+ }
1049
+
1050
+ protected function lib_darken($args) {
1051
+ list($color, $delta) = $this->colorArgs($args);
1052
+
1053
+ $hsl = $this->toHSL($color);
1054
+ $hsl[3] = $this->clamp($hsl[3] - $delta, 100);
1055
+ return $this->toRGB($hsl);
1056
+ }
1057
+
1058
+ protected function lib_lighten($args) {
1059
+ list($color, $delta) = $this->colorArgs($args);
1060
+
1061
+ $hsl = $this->toHSL($color);
1062
+ $hsl[3] = $this->clamp($hsl[3] + $delta, 100);
1063
+ return $this->toRGB($hsl);
1064
+ }
1065
+
1066
+ protected function lib_saturate($args) {
1067
+ list($color, $delta) = $this->colorArgs($args);
1068
+
1069
+ $hsl = $this->toHSL($color);
1070
+ $hsl[2] = $this->clamp($hsl[2] + $delta, 100);
1071
+ return $this->toRGB($hsl);
1072
+ }
1073
+
1074
+ protected function lib_desaturate($args) {
1075
+ list($color, $delta) = $this->colorArgs($args);
1076
+
1077
+ $hsl = $this->toHSL($color);
1078
+ $hsl[2] = $this->clamp($hsl[2] - $delta, 100);
1079
+ return $this->toRGB($hsl);
1080
+ }
1081
+
1082
+ protected function lib_spin($args) {
1083
+ list($color, $delta) = $this->colorArgs($args);
1084
+
1085
+ $hsl = $this->toHSL($color);
1086
+
1087
+ $hsl[1] = $hsl[1] + $delta % 360;
1088
+ if ($hsl[1] < 0) $hsl[1] += 360;
1089
+
1090
+ return $this->toRGB($hsl);
1091
+ }
1092
+
1093
+ protected function lib_fadeout($args) {
1094
+ list($color, $delta) = $this->colorArgs($args);
1095
+ $color[4] = $this->clamp((isset($color[4]) ? $color[4] : 1) - $delta/100);
1096
+ return $color;
1097
+ }
1098
+
1099
+ protected function lib_fadein($args) {
1100
+ list($color, $delta) = $this->colorArgs($args);
1101
+ $color[4] = $this->clamp((isset($color[4]) ? $color[4] : 1) + $delta/100);
1102
+ return $color;
1103
+ }
1104
+
1105
+ protected function lib_hue($color) {
1106
+ $hsl = $this->toHSL($this->assertColor($color));
1107
+ return round($hsl[1]);
1108
+ }
1109
+
1110
+ protected function lib_saturation($color) {
1111
+ $hsl = $this->toHSL($this->assertColor($color));
1112
+ return round($hsl[2]);
1113
+ }
1114
+
1115
+ protected function lib_lightness($color) {
1116
+ $hsl = $this->toHSL($this->assertColor($color));
1117
+ return round($hsl[3]);
1118
+ }
1119
+
1120
+ // get the alpha of a color
1121
+ // defaults to 1 for non-colors or colors without an alpha
1122
+ protected function lib_alpha($value) {
1123
+ if (!is_null($color = $this->coerceColor($value))) {
1124
+ return isset($color[4]) ? $color[4] : 1;
1125
+ }
1126
+ }
1127
+
1128
+ // set the alpha of the color
1129
+ protected function lib_fade($args) {
1130
+ list($color, $alpha) = $this->colorArgs($args);
1131
+ $color[4] = $this->clamp($alpha / 100.0);
1132
+ return $color;
1133
+ }
1134
+
1135
+ protected function lib_percentage($arg) {
1136
+ $num = $this->assertNumber($arg);
1137
+ return array("number", $num*100, "%");
1138
+ }
1139
+
1140
+ // mixes two colors by weight
1141
+ // mix(@color1, @color2, [@weight: 50%]);
1142
+ // http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#mix-instance_method
1143
+ protected function lib_mix($args) {
1144
+ if ($args[0] != "list" || count($args[2]) < 2)
1145
+ $this->throwError("mix expects (color1, color2, weight)");
1146
+
1147
+ list($first, $second) = $args[2];
1148
+ $first = $this->assertColor($first);
1149
+ $second = $this->assertColor($second);
1150
+
1151
+ $first_a = $this->lib_alpha($first);
1152
+ $second_a = $this->lib_alpha($second);
1153
+
1154
+ if (isset($args[2][2])) {
1155
+ $weight = $args[2][2][1] / 100.0;
1156
+ } else {
1157
+ $weight = 0.5;
1158
+ }
1159
+
1160
+ $w = $weight * 2 - 1;
1161
+ $a = $first_a - $second_a;
1162
+
1163
+ $w1 = (($w * $a == -1 ? $w : ($w + $a)/(1 + $w * $a)) + 1) / 2.0;
1164
+ $w2 = 1.0 - $w1;
1165
+
1166
+ $new = array('color',
1167
+ $w1 * $first[1] + $w2 * $second[1],
1168
+ $w1 * $first[2] + $w2 * $second[2],
1169
+ $w1 * $first[3] + $w2 * $second[3],
1170
+ );
1171
+
1172
+ if ($first_a != 1.0 || $second_a != 1.0) {
1173
+ $new[] = $first_a * $weight + $second_a * ($weight - 1);
1174
+ }
1175
+
1176
+ return $this->fixColor($new);
1177
+ }
1178
+
1179
+ protected function lib_contrast($args) {
1180
+ if ($args[0] != 'list' || count($args[2]) < 3) {
1181
+ return array(array('color', 0, 0, 0), 0);
1182
+ }
1183
+
1184
+ list($inputColor, $darkColor, $lightColor) = $args[2];
1185
+
1186
+ $inputColor = $this->assertColor($inputColor);
1187
+ $darkColor = $this->assertColor($darkColor);
1188
+ $lightColor = $this->assertColor($lightColor);
1189
+ $hsl = $this->toHSL($inputColor);
1190
+
1191
+ if ($hsl[3] > 50) {
1192
+ return $darkColor;
1193
+ }
1194
+
1195
+ return $lightColor;
1196
+ }
1197
+
1198
+ protected function assertColor($value, $error = "expected color value") {
1199
+ $color = $this->coerceColor($value);
1200
+ if (is_null($color)) $this->throwError($error);
1201
+ return $color;
1202
+ }
1203
+
1204
+ protected function assertNumber($value, $error = "expecting number") {
1205
+ if ($value[0] == "number") return $value[1];
1206
+ $this->throwError($error);
1207
+ }
1208
+
1209
+ protected function assertArgs($value, $expectedArgs, $name="") {
1210
+ if ($expectedArgs == 1) {
1211
+ return $value;
1212
+ } else {
1213
+ if ($value[0] !== "list" || $value[1] != ",") $this->throwError("expecting list");
1214
+ $values = $value[2];
1215
+ $numValues = count($values);
1216
+ if ($expectedArgs != $numValues) {
1217
+ if ($name) {
1218
+ $name = $name . ": ";
1219
+ }
1220
+
1221
+ $this->throwError("${name}expecting $expectedArgs arguments, got $numValues");
1222
+ }
1223
+
1224
+ return $values;
1225
+ }
1226
+ }
1227
+
1228
+ protected function toHSL($color) {
1229
+ if ($color[0] == 'hsl') return $color;
1230
+
1231
+ $r = $color[1] / 255;
1232
+ $g = $color[2] / 255;
1233
+ $b = $color[3] / 255;
1234
+
1235
+ $min = min($r, $g, $b);
1236
+ $max = max($r, $g, $b);
1237
+
1238
+ $L = ($min + $max) / 2;
1239
+ if ($min == $max) {
1240
+ $S = $H = 0;
1241
+ } else {
1242
+ if ($L < 0.5)
1243
+ $S = ($max - $min)/($max + $min);
1244
+ else
1245
+ $S = ($max - $min)/(2.0 - $max - $min);
1246
+
1247
+ if ($r == $max) $H = ($g - $b)/($max - $min);
1248
+ elseif ($g == $max) $H = 2.0 + ($b - $r)/($max - $min);
1249
+ elseif ($b == $max) $H = 4.0 + ($r - $g)/($max - $min);
1250
+
1251
+ }
1252
+
1253
+ $out = array('hsl',
1254
+ ($H < 0 ? $H + 6 : $H)*60,
1255
+ $S*100,
1256
+ $L*100,
1257
+ );
1258
+
1259
+ if (count($color) > 4) $out[] = $color[4]; // copy alpha
1260
+ return $out;
1261
+ }
1262
+
1263
+ protected function toRGB_helper($comp, $temp1, $temp2) {
1264
+ if ($comp < 0) $comp += 1.0;
1265
+ elseif ($comp > 1) $comp -= 1.0;
1266
+
1267
+ if (6 * $comp < 1) return $temp1 + ($temp2 - $temp1) * 6 * $comp;
1268
+ if (2 * $comp < 1) return $temp2;
1269
+ if (3 * $comp < 2) return $temp1 + ($temp2 - $temp1)*((2/3) - $comp) * 6;
1270
+
1271
+ return $temp1;
1272
+ }
1273
+
1274
+ /**
1275
+ * Converts a hsl array into a color value in rgb.
1276
+ * Expects H to be in range of 0 to 360, S and L in 0 to 100
1277
+ */
1278
+ protected function toRGB($color) {
1279
+ if ($color[0] == 'color') return $color;
1280
+
1281
+ $H = $color[1] / 360;
1282
+ $S = $color[2] / 100;
1283
+ $L = $color[3] / 100;
1284
+
1285
+ if ($S == 0) {
1286
+ $r = $g = $b = $L;
1287
+ } else {
1288
+ $temp2 = $L < 0.5 ?
1289
+ $L*(1.0 + $S) :
1290
+ $L + $S - $L * $S;
1291
+
1292
+ $temp1 = 2.0 * $L - $temp2;
1293
+
1294
+ $r = $this->toRGB_helper($H + 1/3, $temp1, $temp2);
1295
+ $g = $this->toRGB_helper($H, $temp1, $temp2);
1296
+ $b = $this->toRGB_helper($H - 1/3, $temp1, $temp2);
1297
+ }
1298
+
1299
+ // $out = array('color', round($r*255), round($g*255), round($b*255));
1300
+ $out = array('color', $r*255, $g*255, $b*255);
1301
+ if (count($color) > 4) $out[] = $color[4]; // copy alpha
1302
+ return $out;
1303
+ }
1304
+
1305
+ protected function clamp($v, $max = 1, $min = 0) {
1306
+ return min($max, max($min, $v));
1307
+ }
1308
+
1309
+ /**
1310
+ * Convert the rgb, rgba, hsl color literals of function type
1311
+ * as returned by the parser into values of color type.
1312
+ */
1313
+ protected function funcToColor($func) {
1314
+ $fname = $func[1];
1315
+ if ($func[2][0] != 'list') return false; // need a list of arguments
1316
+ $rawComponents = $func[2][2];
1317
+
1318
+ if ($fname == 'hsl' || $fname == 'hsla') {
1319
+ $hsl = array('hsl');
1320
+ $i = 0;
1321
+ foreach ($rawComponents as $c) {
1322
+ $val = $this->reduce($c);
1323
+ $val = isset($val[1]) ? floatval($val[1]) : 0;
1324
+
1325
+ if ($i == 0) $clamp = 360;
1326
+ elseif ($i < 3) $clamp = 100;
1327
+ else $clamp = 1;
1328
+
1329
+ $hsl[] = $this->clamp($val, $clamp);
1330
+ $i++;
1331
+ }
1332
+
1333
+ while (count($hsl) < 4) $hsl[] = 0;
1334
+ return $this->toRGB($hsl);
1335
+
1336
+ } elseif ($fname == 'rgb' || $fname == 'rgba') {
1337
+ $components = array();
1338
+ $i = 1;
1339
+ foreach ($rawComponents as $c) {
1340
+ $c = $this->reduce($c);
1341
+ if ($i < 4) {
1342
+ if ($c[0] == "number" && $c[2] == "%") {
1343
+ $components[] = 255 * ($c[1] / 100);
1344
+ } else {
1345
+ $components[] = floatval($c[1]);
1346
+ }
1347
+ } elseif ($i == 4) {
1348
+ if ($c[0] == "number" && $c[2] == "%") {
1349
+ $components[] = 1.0 * ($c[1] / 100);
1350
+ } else {
1351
+ $components[] = floatval($c[1]);
1352
+ }
1353
+ } else break;
1354
+
1355
+ $i++;
1356
+ }
1357
+ while (count($components) < 3) $components[] = 0;
1358
+ array_unshift($components, 'color');
1359
+ return $this->fixColor($components);
1360
+ }
1361
+
1362
+ return false;
1363
+ }
1364
+
1365
+ protected function reduce($value, $forExpression = false) {
1366
+ switch ($value[0]) {
1367
+ case "interpolate":
1368
+ $reduced = $this->reduce($value[1]);
1369
+ $var = $this->compileValue($reduced);
1370
+ $res = $this->reduce(array("variable", $this->vPrefix . $var));
1371
+
1372
+ if ($res[0] == "raw_color") {
1373
+ $res = $this->coerceColor($res);
1374
+ }
1375
+
1376
+ if (empty($value[2])) $res = $this->lib_unquote($res);
1377
+
1378
+ return $res;
1379
+ case "variable":
1380
+ $key = $value[1];
1381
+ if (is_array($key)) {
1382
+ $key = $this->reduce($key);
1383
+ $key = $this->vPrefix . $this->compileValue($this->lib_unquote($key));
1384
+ }
1385
+
1386
+ $seen =& $this->env->seenNames;
1387
+
1388
+ if (!empty($seen[$key])) {
1389
+ $this->throwError("infinite loop detected: $key");
1390
+ }
1391
+
1392
+ $seen[$key] = true;
1393
+ $out = $this->reduce($this->get($key, self::$defaultValue));
1394
+ $seen[$key] = false;
1395
+ return $out;
1396
+ case "list":
1397
+ foreach ($value[2] as &$item) {
1398
+ $item = $this->reduce($item, $forExpression);
1399
+ }
1400
+ return $value;
1401
+ case "expression":
1402
+ return $this->evaluate($value);
1403
+ case "string":
1404
+ foreach ($value[2] as &$part) {
1405
+ if (is_array($part)) {
1406
+ $strip = $part[0] == "variable";
1407
+ $part = $this->reduce($part);
1408
+ if ($strip) $part = $this->lib_unquote($part);
1409
+ }
1410
+ }
1411
+ return $value;
1412
+ case "escape":
1413
+ list(,$inner) = $value;
1414
+ return $this->lib_unquote($this->reduce($inner));
1415
+ case "function":
1416
+ $color = $this->funcToColor($value);
1417
+ if ($color) return $color;
1418
+
1419
+ list(, $name, $args) = $value;
1420
+ if ($name == "%") $name = "_sprintf";
1421
+ $f = isset($this->libFunctions[$name]) ?
1422
+ $this->libFunctions[$name] : array($this, 'lib_'.$name);
1423
+
1424
+ if (is_callable($f)) {
1425
+ if ($args[0] == 'list')
1426
+ $args = self::compressList($args[2], $args[1]);
1427
+
1428
+ $ret = call_user_func($f, $this->reduce($args, true), $this);
1429
+
1430
+ if (is_null($ret)) {
1431
+ return array("string", "", array(
1432
+ $name, "(", $args, ")"
1433
+ ));
1434
+ }
1435
+
1436
+ // convert to a typed value if the result is a php primitive
1437
+ if (is_numeric($ret)) $ret = array('number', $ret, "");
1438
+ elseif (!is_array($ret)) $ret = array('keyword', $ret);
1439
+
1440
+ return $ret;
1441
+ }
1442
+
1443
+ // plain function, reduce args
1444
+ $value[2] = $this->reduce($value[2]);
1445
+ return $value;
1446
+ case "unary":
1447
+ list(, $op, $exp) = $value;
1448
+ $exp = $this->reduce($exp);
1449
+
1450
+ if ($exp[0] == "number") {
1451
+ switch ($op) {
1452
+ case "+":
1453
+ return $exp;
1454
+ case "-":
1455
+ $exp[1] *= -1;
1456
+ return $exp;
1457
+ }
1458
+ }
1459
+ return array("string", "", array($op, $exp));
1460
+ }
1461
+
1462
+ if ($forExpression) {
1463
+ switch ($value[0]) {
1464
+ case "keyword":
1465
+ if ($color = $this->coerceColor($value)) {
1466
+ return $color;
1467
+ }
1468
+ break;
1469
+ case "raw_color":
1470
+ return $this->coerceColor($value);
1471
+ }
1472
+ }
1473
+
1474
+ return $value;
1475
+ }
1476
+
1477
+
1478
+ // coerce a value for use in color operation
1479
+ protected function coerceColor($value) {
1480
+ switch($value[0]) {
1481
+ case 'color': return $value;
1482
+ case 'raw_color':
1483
+ $c = array("color", 0, 0, 0);
1484
+ $colorStr = substr($value[1], 1);
1485
+ $num = hexdec($colorStr);
1486
+ $width = strlen($colorStr) == 3 ? 16 : 256;
1487
+
1488
+ for ($i = 3; $i > 0; $i--) { // 3 2 1
1489
+ $t = floor( $num ) % floor( $width );
1490
+ $num /= $width;
1491
+
1492
+ $c[$i] = $t * (256/$width) + $t * floor(16/$width);
1493
+ }
1494
+
1495
+ return $c;
1496
+ case 'keyword':
1497
+ $name = $value[1];
1498
+ if (isset(self::$cssColors[$name])) {
1499
+ $rgba = explode(',', self::$cssColors[$name]);
1500
+
1501
+ if(isset($rgba[3]))
1502
+ return array('color', $rgba[0], $rgba[1], $rgba[2], $rgba[3]);
1503
+
1504
+ return array('color', $rgba[0], $rgba[1], $rgba[2]);
1505
+ }
1506
+ return null;
1507
+ }
1508
+ }
1509
+
1510
+ // make something string like into a string
1511
+ protected function coerceString($value) {
1512
+ switch ($value[0]) {
1513
+ case "string":
1514
+ return $value;
1515
+ case "keyword":
1516
+ return array("string", "", array($value[1]));
1517
+ }
1518
+ return null;
1519
+ }
1520
+
1521
+ // turn list of length 1 into value type
1522
+ protected function flattenList($value) {
1523
+ if ($value[0] == "list" && count($value[2]) == 1) {
1524
+ return $this->flattenList($value[2][0]);
1525
+ }
1526
+ return $value;
1527
+ }
1528
+
1529
+ protected function toBool($a) {
1530
+ if ($a) return self::$TRUE;
1531
+ else return self::$FALSE;
1532
+ }
1533
+
1534
+ // evaluate an expression
1535
+ protected function evaluate($exp) {
1536
+ list(, $op, $left, $right, $whiteBefore, $whiteAfter) = $exp;
1537
+
1538
+ $left = $this->reduce($left, true);
1539
+ $right = $this->reduce($right, true);
1540
+
1541
+ if ($leftColor = $this->coerceColor($left)) {
1542
+ $left = $leftColor;
1543
+ }
1544
+
1545
+ if ($rightColor = $this->coerceColor($right)) {
1546
+ $right = $rightColor;
1547
+ }
1548
+
1549
+ $ltype = $left[0];
1550
+ $rtype = $right[0];
1551
+
1552
+ // operators that work on all types
1553
+ if ($op == "and") {
1554
+ return $this->toBool($left == self::$TRUE && $right == self::$TRUE);
1555
+ }
1556
+
1557
+ if ($op == "=") {
1558
+ return $this->toBool($this->eq($left, $right) );
1559
+ }
1560
+
1561
+ if ($op == "+" && !is_null($str = $this->stringConcatenate($left, $right))) {
1562
+ return $str;
1563
+ }
1564
+
1565
+ // type based operators
1566
+ $fname = "op_${ltype}_${rtype}";
1567
+ if (is_callable(array($this, $fname))) {
1568
+ $out = $this->$fname($op, $left, $right);
1569
+ if (!is_null($out)) return $out;
1570
+ }
1571
+
1572
+ // make the expression look it did before being parsed
1573
+ $paddedOp = $op;
1574
+ if ($whiteBefore) $paddedOp = " " . $paddedOp;
1575
+ if ($whiteAfter) $paddedOp .= " ";
1576
+
1577
+ return array("string", "", array($left, $paddedOp, $right));
1578
+ }
1579
+
1580
+ protected function stringConcatenate($left, $right) {
1581
+ if ($strLeft = $this->coerceString($left)) {
1582
+ if ($right[0] == "string") {
1583
+ $right[1] = "";
1584
+ }
1585
+ $strLeft[2][] = $right;
1586
+ return $strLeft;
1587
+ }
1588
+
1589
+ if ($strRight = $this->coerceString($right)) {
1590
+ array_unshift($strRight[2], $left);
1591
+ return $strRight;
1592
+ }
1593
+ }
1594
+
1595
+
1596
+ // make sure a color's components don't go out of bounds
1597
+ protected function fixColor($c) {
1598
+ foreach (range(1, 3) as $i) {
1599
+ if ($c[$i] < 0) $c[$i] = 0;
1600
+ if ($c[$i] > 255) $c[$i] = 255;
1601
+ }
1602
+
1603
+ return $c;
1604
+ }
1605
+
1606
+ protected function op_number_color($op, $lft, $rgt) {
1607
+ if ($op == '+' || $op == '*') {
1608
+ return $this->op_color_number($op, $rgt, $lft);
1609
+ }
1610
+ }
1611
+
1612
+ protected function op_color_number($op, $lft, $rgt) {
1613
+ if ($rgt[0] == '%') $rgt[1] /= 100;
1614
+
1615
+ return $this->op_color_color($op, $lft,
1616
+ array_fill(1, count($lft) - 1, $rgt[1]));
1617
+ }
1618
+
1619
+ protected function op_color_color($op, $left, $right) {
1620
+ $out = array('color');
1621
+ $max = count($left) > count($right) ? count($left) : count($right);
1622
+ foreach (range(1, $max - 1) as $i) {
1623
+ $lval = isset($left[$i]) ? $left[$i] : 0;
1624
+ $rval = isset($right[$i]) ? $right[$i] : 0;
1625
+ switch ($op) {
1626
+ case '+':
1627
+ $out[] = $lval + $rval;
1628
+ break;
1629
+ case '-':
1630
+ $out[] = $lval - $rval;
1631
+ break;
1632
+ case '*':
1633
+ $out[] = $lval * $rval;
1634
+ break;
1635
+ case '%':
1636
+ $out[] = $lval % $rval;
1637
+ break;
1638
+ case '/':
1639
+ if ($rval == 0) $this->throwError("evaluate error: can't divide by zero");
1640
+ $out[] = $lval / $rval;
1641
+ break;
1642
+ default:
1643
+ $this->throwError('evaluate error: color op number failed on op '.$op);
1644
+ }
1645
+ }
1646
+ return $this->fixColor($out);
1647
+ }
1648
+
1649
+ function lib_red($color){
1650
+ $color = $this->coerceColor($color);
1651
+ if (is_null($color)) {
1652
+ $this->throwError('color expected for red()');
1653
+ }
1654
+
1655
+ return $color[1];
1656
+ }
1657
+
1658
+ function lib_green($color){
1659
+ $color = $this->coerceColor($color);
1660
+ if (is_null($color)) {
1661
+ $this->throwError('color expected for green()');
1662
+ }
1663
+
1664
+ return $color[2];
1665
+ }
1666
+
1667
+ function lib_blue($color){
1668
+ $color = $this->coerceColor($color);
1669
+ if (is_null($color)) {
1670
+ $this->throwError('color expected for blue()');
1671
+ }
1672
+
1673
+ return $color[3];
1674
+ }
1675
+
1676
+
1677
+ // operator on two numbers
1678
+ protected function op_number_number($op, $left, $right) {
1679
+ $unit = empty($left[2]) ? $right[2] : $left[2];
1680
+
1681
+ $value = 0;
1682
+ switch ($op) {
1683
+ case '+':
1684
+ $value = $left[1] + $right[1];
1685
+ break;
1686
+ case '*':
1687
+ $value = $left[1] * $right[1];
1688
+ break;
1689
+ case '-':
1690
+ $value = $left[1] - $right[1];
1691
+ break;
1692
+ case '%':
1693
+ $value = $left[1] % $right[1];
1694
+ break;
1695
+ case '/':
1696
+ if ($right[1] == 0) $this->throwError('parse error: divide by zero');
1697
+ $value = $left[1] / $right[1];
1698
+ break;
1699
+ case '<':
1700
+ return $this->toBool($left[1] < $right[1]);
1701
+ case '>':
1702
+ return $this->toBool($left[1] > $right[1]);
1703
+ case '>=':
1704
+ return $this->toBool($left[1] >= $right[1]);
1705
+ case '=<':
1706
+ return $this->toBool($left[1] <= $right[1]);
1707
+ default:
1708
+ $this->throwError('parse error: unknown number operator: '.$op);
1709
+ }
1710
+
1711
+ return array("number", $value, $unit);
1712
+ }
1713
+
1714
+
1715
+ /* environment functions */
1716
+
1717
+ protected function makeOutputBlock($type, $selectors = null) {
1718
+ $b = new stdclass;
1719
+ $b->lines = array();
1720
+ $b->children = array();
1721
+ $b->selectors = $selectors;
1722
+ $b->type = $type;
1723
+ $b->parent = $this->scope;
1724
+ return $b;
1725
+ }
1726
+
1727
+ // the state of execution
1728
+ protected function pushEnv($block = null) {
1729
+ $e = new stdclass;
1730
+ $e->parent = $this->env;
1731
+ $e->store = array();
1732
+ $e->block = $block;
1733
+
1734
+ $this->env = $e;
1735
+ return $e;
1736
+ }
1737
+
1738
+ // pop something off the stack
1739
+ protected function popEnv() {
1740
+ $old = $this->env;
1741
+ $this->env = $this->env->parent;
1742
+ return $old;
1743
+ }
1744
+
1745
+ // set something in the current env
1746
+ protected function set($name, $value) {
1747
+ $this->env->store[$name] = $value;
1748
+ }
1749
+
1750
+
1751
+ // get the highest occurrence entry for a name
1752
+ protected function get($name, $default=null) {
1753
+ $current = $this->env;
1754
+
1755
+ $isArguments = $name == $this->vPrefix . 'arguments';
1756
+ while ($current) {
1757
+ if ($isArguments && isset($current->arguments)) {
1758
+ return array('list', ' ', $current->arguments);
1759
+ }
1760
+
1761
+ if (isset($current->store[$name]))
1762
+ return $current->store[$name];
1763
+ else {
1764
+ $current = isset($current->storeParent) ?
1765
+ $current->storeParent : $current->parent;
1766
+ }
1767
+ }
1768
+
1769
+ return $default;
1770
+ }
1771
+
1772
+ // inject array of unparsed strings into environment as variables
1773
+ protected function injectVariables($args) {
1774
+ $this->pushEnv();
1775
+ $parser = new jupiterx_lessc_parser($this, __METHOD__);
1776
+ foreach ($args as $name => $strValue) {
1777
+ if ($name[0] != '@') $name = '@'.$name;
1778
+ $parser->count = 0;
1779
+ $parser->buffer = (string)$strValue;
1780
+ if (!$parser->propertyValue($value)) {
1781
+ throw new Exception("failed to parse passed in variable $name: $strValue");
1782
+ }
1783
+
1784
+ $this->set($name, $value);
1785
+ }
1786
+ }
1787
+
1788
+ /**
1789
+ * Initialize any static state, can initialize parser for a file
1790
+ * $opts isn't used yet
1791
+ */
1792
+ public function __construct($fname = null) {
1793
+ if ($fname !== null) {
1794
+ // used for deprecated parse method
1795
+ $this->_parseFile = $fname;
1796
+ }
1797
+ }
1798
+
1799
+ public function compile($string, $name = null) {
1800
+ $locale = setlocale(LC_NUMERIC, 0);
1801
+ setlocale(LC_NUMERIC, "C");
1802
+
1803
+ $this->parser = $this->makeParser($name);
1804
+ $root = $this->parser->parse($string);
1805
+
1806
+ $this->env = null;
1807
+ $this->scope = null;
1808
+
1809
+ $this->formatter = $this->newFormatter();
1810
+
1811
+ if (!empty($this->registeredVars)) {
1812
+ $this->injectVariables($this->registeredVars);
1813
+ }
1814
+
1815
+ $this->sourceParser = $this->parser; // used for error messages
1816
+ $this->compileBlock($root);
1817
+
1818
+ ob_start();
1819
+ $this->formatter->block($this->scope);
1820
+ $out = ob_get_clean();
1821
+ setlocale(LC_NUMERIC, $locale);
1822
+ return $out;
1823
+ }
1824
+
1825
+ public function compileFile($fname, $outFname = null) {
1826
+ if (!is_readable($fname)) {
1827
+ throw new Exception('load error: failed to find '.$fname);
1828
+ }
1829
+
1830
+ $pi = pathinfo($fname);
1831
+
1832
+ $oldImport = $this->importDir;
1833
+
1834
+ $this->importDir = (array)$this->importDir;
1835
+ $this->importDir[] = $pi['dirname'].'/';
1836
+
1837
+ $this->addParsedFile($fname);
1838
+
1839
+ $out = $this->compile($GLOBALS['wp_filesystem']->get_contents($fname), $fname);
1840
+
1841
+ $this->importDir = $oldImport;
1842
+
1843
+ if ($outFname !== null) {
1844
+ return $GLOBALS['wp_filesystem']->put_contents($outFname, $out);
1845
+ }
1846
+
1847
+ return $out;
1848
+ }
1849
+
1850
+ // compile only if changed input has changed or output doesn't exist
1851
+ public function checkedCompile($in, $out) {
1852
+ if (!is_file($out) || filemtime($in) > filemtime($out)) {
1853
+ $this->compileFile($in, $out);
1854
+ return true;
1855
+ }
1856
+ return false;
1857
+ }
1858
+
1859
+ /**
1860
+ * Execute lessphp on a .less file or a lessphp cache structure
1861
+ *
1862
+ * The lessphp cache structure contains information about a specific
1863
+ * less file having been parsed. It can be used as a hint for future
1864
+ * calls to determine whether or not a rebuild is required.
1865
+ *
1866
+ * The cache structure contains two important keys that may be used
1867
+ * externally:
1868
+ *
1869
+ * compiled: The final compiled CSS
1870
+ * updated: The time (in seconds) the CSS was last compiled
1871
+ *
1872
+ * The cache structure is a plain-ol' PHP associative array and can
1873
+ * be serialized and unserialized without a hitch.
1874
+ *
1875
+ * @param mixed $in Input
1876
+ * @param bool $force Force rebuild?
1877
+ * @return array lessphp cache structure
1878
+ */
1879
+ public function cachedCompile($in, $force = false) {
1880
+ // assume no root
1881
+ $root = null;
1882
+
1883
+ if (is_string($in)) {
1884
+ $root = $in;
1885
+ } elseif (is_array($in) and isset($in['root'])) {
1886
+ if ($force or ! isset($in['files'])) {
1887
+ // If we are forcing a recompile or if for some reason the
1888
+ // structure does not contain any file information we should
1889
+ // specify the root to trigger a rebuild.
1890
+ $root = $in['root'];
1891
+ } elseif (isset($in['files']) and is_array($in['files'])) {
1892
+ foreach ($in['files'] as $fname => $ftime ) {
1893
+ if (!file_exists($fname) or filemtime($fname) > $ftime) {
1894
+ // One of the files we knew about previously has changed
1895
+ // so we should look at our incoming root again.
1896
+ $root = $in['root'];
1897
+ break;
1898
+ }
1899
+ }
1900
+ }
1901
+ } else {
1902
+ // TODO: Throw an exception? We got neither a string nor something
1903
+ // that looks like a compatible lessphp cache structure.
1904
+ return null;
1905
+ }
1906
+
1907
+ if ($root !== null) {
1908
+ // If we have a root value which means we should rebuild.
1909
+ $out = array();
1910
+ $out['root'] = $root;
1911
+ $out['compiled'] = $this->compileFile($root);
1912
+ $out['files'] = $this->allParsedFiles();
1913
+ $out['updated'] = time();
1914
+ return $out;
1915
+ } else {
1916
+ // No changes, pass back the structure
1917
+ // we were given initially.
1918
+ return $in;
1919
+ }
1920
+
1921
+ }
1922
+
1923
+ // parse and compile buffer
1924
+ // This is deprecated
1925
+ public function parse($str = null, $initialVariables = null) {
1926
+ if (is_array($str)) {
1927
+ $initialVariables = $str;
1928
+ $str = null;
1929
+ }
1930
+
1931
+ $oldVars = $this->registeredVars;
1932
+ if ($initialVariables !== null) {
1933
+ $this->setVariables($initialVariables);
1934
+ }
1935
+
1936
+ if ($str == null) {
1937
+ if (empty($this->_parseFile)) {
1938
+ throw new exception("nothing to parse");
1939
+ }
1940
+
1941
+ $out = $this->compileFile($this->_parseFile);
1942
+ } else {
1943
+ $out = $this->compile($str);
1944
+ }
1945
+
1946
+ $this->registeredVars = $oldVars;
1947
+ return $out;
1948
+ }
1949
+
1950
+ protected function makeParser($name) {
1951
+ $parser = new jupiterx_lessc_parser($this, $name);
1952
+ $parser->writeComments = $this->preserveComments;
1953
+
1954
+ return $parser;
1955
+ }
1956
+
1957
+ public function setFormatter($name) {
1958
+ $this->formatterName = $name;
1959
+ }
1960
+
1961
+ protected function newFormatter() {
1962
+ $className = "jupiterx_lessc_formatter_lessjs";
1963
+ if (!empty($this->formatterName)) {
1964
+ if (!is_string($this->formatterName))
1965
+ return $this->formatterName;
1966
+ $className = "jupiterx_lessc_formatter_$this->formatterName";
1967
+ }
1968
+
1969
+ return new $className;
1970
+ }
1971
+
1972
+ public function setPreserveComments($preserve) {
1973
+ $this->preserveComments = $preserve;
1974
+ }
1975
+
1976
+ public function registerFunction($name, $func) {
1977
+ $this->libFunctions[$name] = $func;
1978
+ }
1979
+
1980
+ public function unregisterFunction($name) {
1981
+ unset($this->libFunctions[$name]);
1982
+ }
1983
+
1984
+ public function setVariables($variables) {
1985
+ $this->registeredVars = array_merge($this->registeredVars, $variables);
1986
+ }
1987
+
1988
+ public function unsetVariable($name) {
1989
+ unset($this->registeredVars[$name]);
1990
+ }
1991
+
1992
+ public function setImportDir($dirs) {
1993
+ $this->importDir = (array)$dirs;
1994
+ }
1995
+
1996
+ public function addImportDir($dir) {
1997
+ $this->importDir = (array)$this->importDir;
1998
+ $this->importDir[] = $dir;
1999
+ }
2000
+
2001
+ public function allParsedFiles() {
2002
+ return $this->allParsedFiles;
2003
+ }
2004
+
2005
+ protected function addParsedFile($file) {
2006
+ $this->allParsedFiles[realpath($file)] = filemtime($file);
2007
+ }
2008
+
2009
+ /**
2010
+ * Uses the current value of $this->count to show line and line number
2011
+ */
2012
+ protected function throwError($msg = null) {
2013
+ if ($this->sourceLoc >= 0) {
2014
+ $this->sourceParser->throwError($msg, $this->sourceLoc);
2015
+ }
2016
+ throw new exception($msg);
2017
+ }
2018
+
2019
+ // compile file $in to file $out if $in is newer than $out
2020
+ // returns true when it compiles, false otherwise
2021
+ public static function ccompile($in, $out, $less = null) {
2022
+ if ($less === null) {
2023
+ $less = new self;
2024
+ }
2025
+ return $less->checkedCompile($in, $out);
2026
+ }
2027
+
2028
+ public static function cexecute($in, $force = false, $less = null) {
2029
+ if ($less === null) {
2030
+ $less = new self;
2031
+ }
2032
+ return $less->cachedCompile($in, $force);
2033
+ }
2034
+
2035
+ static protected $cssColors = array(
2036
+ 'aliceblue' => '240,248,255',
2037
+ 'antiquewhite' => '250,235,215',
2038
+ 'aqua' => '0,255,255',
2039
+ 'aquamarine' => '127,255,212',
2040
+ 'azure' => '240,255,255',
2041
+ 'beige' => '245,245,220',
2042
+ 'bisque' => '255,228,196',
2043
+ 'black' => '0,0,0',
2044
+ 'blanchedalmond' => '255,235,205',
2045
+ 'blue' => '0,0,255',
2046
+ 'blueviolet' => '138,43,226',
2047
+ 'brown' => '165,42,42',
2048
+ 'burlywood' => '222,184,135',
2049
+ 'cadetblue' => '95,158,160',
2050
+ 'chartreuse' => '127,255,0',
2051
+ 'chocolate' => '210,105,30',
2052
+ 'coral' => '255,127,80',
2053
+ 'cornflowerblue' => '100,149,237',
2054
+ 'cornsilk' => '255,248,220',
2055
+ 'crimson' => '220,20,60',
2056
+ 'cyan' => '0,255,255',
2057
+ 'darkblue' => '0,0,139',
2058
+ 'darkcyan' => '0,139,139',
2059
+ 'darkgoldenrod' => '184,134,11',
2060
+ 'darkgray' => '169,169,169',
2061
+ 'darkgreen' => '0,100,0',
2062
+ 'darkgrey' => '169,169,169',
2063
+ 'darkkhaki' => '189,183,107',
2064
+ 'darkmagenta' => '139,0,139',
2065
+ 'darkolivegreen' => '85,107,47',
2066
+ 'darkorange' => '255,140,0',
2067
+ 'darkorchid' => '153,50,204',
2068
+ 'darkred' => '139,0,0',
2069
+ 'darksalmon' => '233,150,122',
2070
+ 'darkseagreen' => '143,188,143',
2071
+ 'darkslateblue' => '72,61,139',
2072
+ 'darkslategray' => '47,79,79',
2073
+ 'darkslategrey' => '47,79,79',
2074
+ 'darkturquoise' => '0,206,209',
2075
+ 'darkviolet' => '148,0,211',
2076
+ 'deeppink' => '255,20,147',
2077
+ 'deepskyblue' => '0,191,255',
2078
+ 'dimgray' => '105,105,105',
2079
+ 'dimgrey' => '105,105,105',
2080
+ 'dodgerblue' => '30,144,255',
2081
+ 'firebrick' => '178,34,34',
2082
+ 'floralwhite' => '255,250,240',
2083
+ 'forestgreen' => '34,139,34',
2084
+ 'fuchsia' => '255,0,255',
2085
+ 'gainsboro' => '220,220,220',
2086
+ 'ghostwhite' => '248,248,255',
2087
+ 'gold' => '255,215,0',
2088
+ 'goldenrod' => '218,165,32',
2089
+ 'gray' => '128,128,128',
2090
+ 'green' => '0,128,0',
2091
+ 'greenyellow' => '173,255,47',
2092
+ 'grey' => '128,128,128',
2093
+ 'honeydew' => '240,255,240',
2094
+ 'hotpink' => '255,105,180',
2095
+ 'indianred' => '205,92,92',
2096
+ 'indigo' => '75,0,130',
2097
+ 'ivory' => '255,255,240',
2098
+ 'khaki' => '240,230,140',
2099
+ 'lavender' => '230,230,250',
2100
+ 'lavenderblush' => '255,240,245',
2101
+ 'lawngreen' => '124,252,0',
2102
+ 'lemonchiffon' => '255,250,205',
2103
+ 'lightblue' => '173,216,230',
2104
+ 'lightcoral' => '240,128,128',
2105
+ 'lightcyan' => '224,255,255',
2106
+ 'lightgoldenrodyellow' => '250,250,210',
2107
+ 'lightgray' => '211,211,211',
2108
+ 'lightgreen' => '144,238,144',
2109
+ 'lightgrey' => '211,211,211',
2110
+ 'lightpink' => '255,182,193',
2111
+ 'lightsalmon' => '255,160,122',
2112
+ 'lightseagreen' => '32,178,170',
2113
+ 'lightskyblue' => '135,206,250',
2114
+ 'lightslategray' => '119,136,153',
2115
+ 'lightslategrey' => '119,136,153',
2116
+ 'lightsteelblue' => '176,196,222',
2117
+ 'lightyellow' => '255,255,224',
2118
+ 'lime' => '0,255,0',
2119
+ 'limegreen' => '50,205,50',
2120
+ 'linen' => '250,240,230',
2121
+ 'magenta' => '255,0,255',
2122
+ 'maroon' => '128,0,0',
2123
+ 'mediumaquamarine' => '102,205,170',
2124
+ 'mediumblue' => '0,0,205',
2125
+ 'mediumorchid' => '186,85,211',
2126
+ 'mediumpurple' => '147,112,219',
2127
+ 'mediumseagreen' => '60,179,113',
2128
+ 'mediumslateblue' => '123,104,238',
2129
+ 'mediumspringgreen' => '0,250,154',
2130
+ 'mediumturquoise' => '72,209,204',
2131
+ 'mediumvioletred' => '199,21,133',
2132
+ 'midnightblue' => '25,25,112',
2133
+ 'mintcream' => '245,255,250',
2134
+ 'mistyrose' => '255,228,225',
2135
+ 'moccasin' => '255,228,181',
2136
+ 'navajowhite' => '255,222,173',
2137
+ 'navy' => '0,0,128',
2138
+ 'oldlace' => '253,245,230',
2139
+ 'olive' => '128,128,0',
2140
+ 'olivedrab' => '107,142,35',
2141
+ 'orange' => '255,165,0',
2142
+ 'orangered' => '255,69,0',
2143
+ 'orchid' => '218,112,214',
2144
+ 'palegoldenrod' => '238,232,170',
2145
+ 'palegreen' => '152,251,152',
2146
+ 'paleturquoise' => '175,238,238',
2147
+ 'palevioletred' => '219,112,147',
2148
+ 'papayawhip' => '255,239,213',
2149
+ 'peachpuff' => '255,218,185',
2150
+ 'peru' => '205,133,63',
2151
+ 'pink' => '255,192,203',
2152
+ 'plum' => '221,160,221',
2153
+ 'powderblue' => '176,224,230',
2154
+ 'purple' => '128,0,128',
2155
+ 'red' => '255,0,0',
2156
+ 'rosybrown' => '188,143,143',
2157
+ 'royalblue' => '65,105,225',
2158
+ 'saddlebrown' => '139,69,19',
2159
+ 'salmon' => '250,128,114',
2160
+ 'sandybrown' => '244,164,96',
2161
+ 'seagreen' => '46,139,87',
2162
+ 'seashell' => '255,245,238',
2163
+ 'sienna' => '160,82,45',
2164
+ 'silver' => '192,192,192',
2165
+ 'skyblue' => '135,206,235',
2166
+ 'slateblue' => '106,90,205',
2167
+ 'slategray' => '112,128,144',
2168
+ 'slategrey' => '112,128,144',
2169
+ 'snow' => '255,250,250',
2170
+ 'springgreen' => '0,255,127',
2171
+ 'steelblue' => '70,130,180',
2172
+ 'tan' => '210,180,140',
2173
+ 'teal' => '0,128,128',
2174
+ 'thistle' => '216,191,216',
2175
+ 'tomato' => '255,99,71',
2176
+ 'transparent' => '0,0,0,0',
2177
+ 'turquoise' => '64,224,208',
2178
+ 'violet' => '238,130,238',
2179
+ 'wheat' => '245,222,179',
2180
+ 'white' => '255,255,255',
2181
+ 'whitesmoke' => '245,245,245',
2182
+ 'yellow' => '255,255,0',
2183
+ 'yellowgreen' => '154,205,50'
2184
+ );
2185
+ }
2186
+
2187
+ // responsible for taking a string of LESS code and converting it into a
2188
+ // syntax tree
2189
+ /**
2190
+ * @ignore
2191
+ */
2192
+ class jupiterx_lessc_parser {
2193
+ static protected $nextBlockId = 0; // used to uniquely identify blocks
2194
+
2195
+ static protected $precedence = array(
2196
+ '=<' => 0,
2197
+ '>=' => 0,
2198
+ '=' => 0,
2199
+ '<' => 0,
2200
+ '>' => 0,
2201
+
2202
+ '+' => 1,
2203
+ '-' => 1,
2204
+ '*' => 2,
2205
+ '/' => 2,
2206
+ '%' => 2,
2207
+ );
2208
+
2209
+ static protected $whitePattern;
2210
+ static protected $commentMulti;
2211
+
2212
+ static protected $commentSingle = "//";
2213
+ static protected $commentMultiLeft = "/*";
2214
+ static protected $commentMultiRight = "*/";
2215
+
2216
+ // regex string to match any of the operators
2217
+ static protected $operatorString;
2218
+
2219
+ // these properties will supress division unless it's inside parenthases
2220
+ static protected $supressDivisionProps =
2221
+ array('/border-radius$/i', '/^font$/i');
2222
+
2223
+ protected $blockDirectives = array("font-face", "keyframes", "page", "-moz-document", "viewport", "-moz-viewport", "-o-viewport", "-ms-viewport");
2224
+ protected $lineDirectives = array("charset");
2225
+
2226
+ /**
2227
+ * if we are in parens we can be more liberal with whitespace around
2228
+ * operators because it must evaluate to a single value and thus is less
2229
+ * ambiguous.
2230
+ *
2231
+ * Consider:
2232
+ * property1: 10 -5; // is two numbers, 10 and -5
2233
+ * property2: (10 -5); // should evaluate to 5
2234
+ */
2235
+ protected $inParens = false;
2236
+
2237
+ // caches preg escaped literals
2238
+ static protected $literalCache = array();
2239
+
2240
+ public function __construct($lessc, $sourceName = null) {
2241
+ $this->eatWhiteDefault = true;
2242
+ // reference to less needed for vPrefix, mPrefix, and parentSelector
2243
+ $this->lessc = $lessc;
2244
+
2245
+ $this->sourceName = $sourceName; // name used for error messages
2246
+
2247
+ $this->writeComments = false;
2248
+
2249
+ if (!self::$operatorString) {
2250
+ self::$operatorString =
2251
+ '('.implode('|', array_map(array('JupiterX_Lessc', 'preg_quote'),
2252
+ array_keys(self::$precedence))).')';
2253
+
2254
+ $commentSingle = JupiterX_Lessc::preg_quote(self::$commentSingle);
2255
+ $commentMultiLeft = JupiterX_Lessc::preg_quote(self::$commentMultiLeft);
2256
+ $commentMultiRight = JupiterX_Lessc::preg_quote(self::$commentMultiRight);
2257
+
2258
+ self::$commentMulti = $commentMultiLeft.'.*?'.$commentMultiRight;
2259
+ self::$whitePattern = '/'.$commentSingle.'[^\n]*\s*|('.self::$commentMulti.')\s*|\s+/Ais';
2260
+ }
2261
+ }
2262
+
2263
+ public function parse($buffer) {
2264
+ $this->count = 0;
2265
+ $this->line = 1;
2266
+
2267
+ $this->env = null; // block stack
2268
+ $this->buffer = $this->writeComments ? $buffer : $this->removeComments($buffer);
2269
+ $this->pushSpecialBlock("root");
2270
+ $this->eatWhiteDefault = true;
2271
+ $this->seenComments = array();
2272
+
2273
+ // trim whitespace on head
2274
+ // if (preg_match('/^\s+/', $this->buffer, $m)) {
2275
+ // $this->line += substr_count($m[0], "\n");
2276
+ // $this->buffer = ltrim($this->buffer);
2277
+ // }
2278
+ $this->whitespace();
2279
+
2280
+ // parse the entire file
2281
+ $lastCount = $this->count;
2282
+ while (false !== $this->parseChunk());
2283
+
2284
+ if ($this->count != strlen($this->buffer))
2285
+ $this->throwError();
2286
+
2287
+ // TODO report where the block was opened
2288
+ if (!is_null($this->env->parent))
2289
+ throw new exception('parse error: unclosed block');
2290
+
2291
+ return $this->env;
2292
+ }
2293
+
2294
+ /**
2295
+ * Parse a single chunk off the head of the buffer and append it to the
2296
+ * current parse environment.
2297
+ * Returns false when the buffer is empty, or when there is an error.
2298
+ *
2299
+ * This function is called repeatedly until the entire document is
2300
+ * parsed.
2301
+ *
2302
+ * This parser is most similar to a recursive descent parser. Single
2303
+ * functions represent discrete grammatical rules for the language, and
2304
+ * they are able to capture the text that represents those rules.
2305
+ *
2306
+ * Consider the function lessc::keyword(). (all parse functions are
2307
+ * structured the same)
2308
+ *
2309
+ * The function takes a single reference argument. When calling the
2310
+ * function it will attempt to match a keyword on the head of the buffer.
2311
+ * If it is successful, it will place the keyword in the referenced
2312
+ * argument, advance the position in the buffer, and return true. If it
2313
+ * fails then it won't advance the buffer and it will return false.
2314
+ *
2315
+ * All of these parse functions are powered by lessc::match(), which behaves
2316
+ * the same way, but takes a literal regular expression. Sometimes it is
2317
+ * more convenient to use match instead of creating a new function.
2318
+ *
2319
+ * Because of the format of the functions, to parse an entire string of
2320
+ * grammatical rules, you can chain them together using &&.
2321
+ *
2322
+ * But, if some of the rules in the chain succeed before one fails, then
2323
+ * the buffer position will be left at an invalid state. In order to
2324
+ * avoid this, lessc::seek() is used to remember and set buffer positions.
2325
+ *
2326
+ * Before parsing a chain, use $s = $this->seek() to remember the current
2327
+ * position into $s. Then if a chain fails, use $this->seek($s) to
2328
+ * go back where we started.
2329
+ */
2330
+ protected function parseChunk() {
2331
+ if (empty($this->buffer)) return false;
2332
+ $s = $this->seek();
2333
+
2334
+ // setting a property
2335
+ if ($this->keyword($key) && $this->assign() &&
2336
+ $this->propertyValue($value, $key) && $this->end())
2337
+ {
2338
+ $this->append(array('assign', $key, $value), $s);
2339
+ return true;
2340
+ } else {
2341
+ $this->seek($s);
2342
+ }
2343
+
2344
+
2345
+ // look for special css blocks
2346
+ if ($this->literal('@', false)) {
2347
+ $this->count--;
2348
+
2349
+ // media
2350
+ if ($this->literal('@media')) {
2351
+ if (($this->mediaQueryList($mediaQueries) || true)
2352
+ && $this->literal('{'))
2353
+ {
2354
+ $media = $this->pushSpecialBlock("media");
2355
+ $media->queries = is_null($mediaQueries) ? array() : $mediaQueries;
2356
+ return true;
2357
+ } else {
2358
+ $this->seek($s);
2359
+ return false;
2360
+ }
2361
+ }
2362
+
2363
+ if ($this->literal("@", false) && $this->keyword($dirName)) {
2364
+ if ($this->isDirective($dirName, $this->blockDirectives)) {
2365
+ if (($this->openString("{", $dirValue, null, array(";")) || true) &&
2366
+ $this->literal("{"))
2367
+ {
2368
+ $dir = $this->pushSpecialBlock("directive");
2369
+ $dir->name = $dirName;
2370
+ if (isset($dirValue)) $dir->value = $dirValue;
2371
+ return true;
2372
+ }
2373
+ } elseif ($this->isDirective($dirName, $this->lineDirectives)) {
2374
+ if ($this->propertyValue($dirValue) && $this->end()) {
2375
+ $this->append(array("directive", $dirName, $dirValue));
2376
+ return true;
2377
+ }
2378
+ }
2379
+ }
2380
+
2381
+ $this->seek($s);
2382
+ }
2383
+
2384
+ // setting a variable
2385
+ if ($this->variable($var) && $this->assign() &&
2386
+ $this->propertyValue($value) && $this->end())
2387
+ {
2388
+ $this->append(array('assign', $var, $value), $s);
2389
+ return true;
2390
+ } else {
2391
+ $this->seek($s);
2392
+ }
2393
+
2394
+ if ($this->import($importValue)) {
2395
+ $this->append($importValue, $s);
2396
+ return true;
2397
+ }
2398
+
2399
+ // opening parametric mixin
2400
+ if ($this->tag($tag, true) && $this->argumentDef($args, $isVararg) &&
2401
+ ($this->guards($guards) || true) &&
2402
+ $this->literal('{'))
2403
+ {
2404
+ $block = $this->pushBlock($this->fixTags(array($tag)));
2405
+ $block->args = $args;
2406
+ $block->isVararg = $isVararg;
2407
+ if (!empty($guards)) $block->guards = $guards;
2408
+ return true;
2409
+ } else {
2410
+ $this->seek($s);
2411
+ }
2412
+
2413
+ // opening a simple block
2414
+ if ($this->tags($tags) && $this->literal('{')) {
2415
+ $tags = $this->fixTags($tags);
2416
+ $this->pushBlock($tags);
2417
+ return true;
2418
+ } else {
2419
+ $this->seek($s);
2420
+ }
2421
+
2422
+ // closing a block
2423
+ if ($this->literal('}', false)) {
2424
+ try {
2425
+ $block = $this->pop();
2426
+ } catch (exception $e) {
2427
+ $this->seek($s);
2428
+ $this->throwError($e->getMessage());
2429
+ }
2430
+
2431
+ $hidden = false;
2432
+ if (is_null($block->type)) {
2433
+ $hidden = true;
2434
+ if (!isset($block->args)) {
2435
+ foreach ($block->tags as $tag) {
2436
+ if (!is_string($tag) || $tag[0] != $this->lessc->mPrefix) {
2437
+ $hidden = false;
2438
+ break;
2439
+ }
2440
+ }
2441
+ }
2442
+
2443
+ foreach ($block->tags as $tag) {
2444
+ if (is_string($tag)) {
2445
+ $this->env->children[$tag][] = $block;
2446
+ }
2447
+ }
2448
+ }
2449
+
2450
+ if (!$hidden) {
2451
+ $this->append(array('block', $block), $s);
2452
+ }
2453
+
2454
+ // this is done here so comments aren't bundled into he block that
2455
+ // was just closed
2456
+ $this->whitespace();
2457
+ return true;
2458
+ }
2459
+
2460
+ // mixin
2461
+ if ($this->mixinTags($tags) &&
2462
+ ($this->argumentDef($argv, $isVararg) || true) &&
2463
+ ($this->keyword($suffix) || true) && $this->end())
2464
+ {
2465
+ $tags = $this->fixTags($tags);
2466
+ $this->append(array('mixin', $tags, $argv, $suffix), $s);
2467
+ return true;
2468
+ } else {
2469
+ $this->seek($s);
2470
+ }
2471
+
2472
+ // spare ;
2473
+ if ($this->literal(';')) return true;
2474
+
2475
+ return false; // got nothing, throw error
2476
+ }
2477
+
2478
+ protected function isDirective($dirname, $directives) {
2479
+ // TODO: cache pattern in parser
2480
+ $pattern = implode("|",
2481
+ array_map(array("JupiterX_Lessc", "preg_quote"), $directives));
2482
+ $pattern = '/^(-[a-z-]+-)?(' . $pattern . ')$/i';
2483
+
2484
+ return preg_match($pattern, $dirname);
2485
+ }
2486
+
2487
+ protected function fixTags($tags) {
2488
+ // move @ tags out of variable namespace
2489
+ foreach ($tags as &$tag) {
2490
+ if ($tag[0] == $this->lessc->vPrefix)
2491
+ $tag[0] = $this->lessc->mPrefix;
2492
+ }
2493
+ return $tags;
2494
+ }
2495
+
2496
+ // a list of expressions
2497
+ protected function expressionList(&$exps) {
2498
+ $values = array();
2499
+
2500
+ while ($this->expression($exp)) {
2501
+ $values[] = $exp;
2502
+ }
2503
+
2504
+ if (count($values) == 0) return false;
2505
+
2506
+ $exps = JupiterX_Lessc::compressList($values, ' ');
2507
+ return true;
2508
+ }
2509
+
2510
+ /**
2511
+ * Attempt to consume an expression.
2512
+ * @link http://en.wikipedia.org/wiki/Operator-precedence_parser#Pseudo-code
2513
+ */
2514
+ protected function expression(&$out) {
2515
+ if ($this->value($lhs)) {
2516
+ $out = $this->expHelper($lhs, 0);
2517
+
2518
+ // look for / shorthand
2519
+ if (!empty($this->env->supressedDivision)) {
2520
+ unset($this->env->supressedDivision);
2521
+ $s = $this->seek();
2522
+ if ($this->literal("/") && $this->value($rhs)) {
2523
+ $out = array("list", "",
2524
+ array($out, array("keyword", "/"), $rhs));
2525
+ } else {
2526
+ $this->seek($s);
2527
+ }
2528
+ }
2529
+
2530
+ return true;
2531
+ }
2532
+ return false;
2533
+ }
2534
+
2535
+ /**
2536
+ * recursively parse infix equation with $lhs at precedence $minP
2537
+ */
2538
+ protected function expHelper($lhs, $minP) {
2539
+ $this->inExp = true;
2540
+ $ss = $this->seek();
2541
+
2542
+ while (true) {
2543
+ $whiteBefore = isset($this->buffer[$this->count - 1]) &&
2544
+ ctype_space($this->buffer[$this->count - 1]);
2545
+
2546
+ // If there is whitespace before the operator, then we require
2547
+ // whitespace after the operator for it to be an expression
2548
+ $needWhite = $whiteBefore && !$this->inParens;
2549
+
2550
+ if ($this->match(self::$operatorString.($needWhite ? '\s' : ''), $m) && self::$precedence[$m[1]] >= $minP) {
2551
+ if (!$this->inParens && isset($this->env->currentProperty) && $m[1] == "/" && empty($this->env->supressedDivision)) {
2552
+ foreach (self::$supressDivisionProps as $pattern) {
2553
+ if (preg_match($pattern, $this->env->currentProperty)) {
2554
+ $this->env->supressedDivision = true;
2555
+ break 2;
2556
+ }
2557
+ }
2558
+ }
2559
+
2560
+
2561
+ $whiteAfter = isset($this->buffer[$this->count - 1]) &&
2562
+ ctype_space($this->buffer[$this->count - 1]);
2563
+
2564
+ if (!$this->value($rhs)) break;
2565
+
2566
+ // peek for next operator to see what to do with rhs
2567
+ if ($this->peek(self::$operatorString, $next) && self::$precedence[$next[1]] > self::$precedence[$m[1]]) {
2568
+ $rhs = $this->expHelper($rhs, self::$precedence[$next[1]]);
2569
+ }
2570
+
2571
+ $lhs = array('expression', $m[1], $lhs, $rhs, $whiteBefore, $whiteAfter);
2572
+ $ss = $this->seek();
2573
+
2574
+ continue;
2575
+ }
2576
+
2577
+ break;
2578
+ }
2579
+
2580
+ $this->seek($ss);
2581
+
2582
+ return $lhs;
2583
+ }
2584
+
2585
+ // consume a list of values for a property
2586
+ public function propertyValue(&$value, $keyName = null) {
2587
+ $values = array();
2588
+
2589
+ if ($keyName !== null) $this->env->currentProperty = $keyName;
2590
+
2591
+ $s = null;
2592
+ while ($this->expressionList($v)) {
2593
+ $values[] = $v;
2594
+ $s = $this->seek();
2595
+ if (!$this->literal(',')) break;
2596
+ }
2597
+
2598
+ if ($s) $this->seek($s);
2599
+
2600
+ if ($keyName !== null) unset($this->env->currentProperty);
2601
+
2602
+ if (count($values) == 0) return false;
2603
+
2604
+ $value = JupiterX_Lessc::compressList($values, ', ');
2605
+ return true;
2606
+ }
2607
+
2608
+ protected function parenValue(&$out) {
2609
+ $s = $this->seek();
2610
+
2611
+ // speed shortcut
2612
+ if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "(") {
2613
+ return false;
2614
+ }
2615
+
2616
+ $inParens = $this->inParens;
2617
+ if ($this->literal("(") &&
2618
+ ($this->inParens = true) && $this->expression($exp) &&
2619
+ $this->literal(")"))
2620
+ {
2621
+ $out = $exp;
2622
+ $this->inParens = $inParens;
2623
+ return true;
2624
+ } else {
2625
+ $this->inParens = $inParens;
2626
+ $this->seek($s);
2627
+ }
2628
+
2629
+ return false;
2630
+ }
2631
+
2632
+ // a single value
2633
+ protected function value(&$value) {
2634
+ $s = $this->seek();
2635
+
2636
+ // speed shortcut
2637
+ if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "-") {
2638
+ // negation
2639
+ if ($this->literal("-", false) &&
2640
+ (($this->variable($inner) && $inner = array("variable", $inner)) ||
2641
+ $this->unit($inner) ||
2642
+ $this->parenValue($inner)))
2643
+ {
2644
+ $value = array("unary", "-", $inner);
2645
+ return true;
2646
+ } else {
2647
+ $this->seek($s);
2648
+ }
2649
+ }
2650
+
2651
+ if ($this->parenValue($value)) return true;
2652
+ if ($this->unit($value)) return true;
2653
+ if ($this->color($value)) return true;
2654
+ if ($this->func($value)) return true;
2655
+ if ($this->string($value)) return true;
2656
+
2657
+ if ($this->keyword($word)) {
2658
+ $value = array('keyword', $word);
2659
+ return true;
2660
+ }
2661
+
2662
+ // try a variable
2663
+ if ($this->variable($var)) {
2664
+ $value = array('variable', $var);
2665
+ return true;
2666
+ }
2667
+
2668
+ // unquote string (should this work on any type?
2669
+ if ($this->literal("~") && $this->string($str)) {
2670
+ $value = array("escape", $str);
2671
+ return true;
2672
+ } else {
2673
+ $this->seek($s);
2674
+ }
2675
+
2676
+ // css hack: \0
2677
+ if ($this->literal('\\') && $this->match('([0-9]+)', $m)) {
2678
+ $value = array('keyword', '\\'.$m[1]);
2679
+ return true;
2680
+ } else {
2681
+ $this->seek($s);
2682
+ }
2683
+
2684
+ return false;
2685
+ }
2686
+
2687
+ // an import statement
2688
+ protected function import(&$out) {
2689
+ $s = $this->seek();
2690
+ if (!$this->literal('@import')) return false;
2691
+
2692
+ // @import "something.css" media;
2693
+ // @import url("something.css") media;
2694
+ // @import url(something.css) media;
2695
+
2696
+ if ($this->propertyValue($value)) {
2697
+ $out = array("import", $value);
2698
+ return true;
2699
+ }
2700
+ }
2701
+
2702
+ protected function mediaQueryList(&$out) {
2703
+ if ($this->genericList($list, "mediaQuery", ",", false)) {
2704
+ $out = $list[2];
2705
+ return true;
2706
+ }
2707
+ return false;
2708
+ }
2709
+
2710
+ protected function mediaQuery(&$out) {
2711
+ $s = $this->seek();
2712
+
2713
+ $expressions = null;
2714
+ $parts = array();
2715
+
2716
+ if (($this->literal("only") && ($only = true) || $this->literal("not") && ($not = true) || true) && $this->keyword($mediaType)) {
2717
+ $prop = array("mediaType");
2718
+ if (isset($only)) $prop[] = "only";
2719
+ if (isset($not)) $prop[] = "not";
2720
+ $prop[] = $mediaType;
2721
+ $parts[] = $prop;
2722
+ } else {
2723
+ $this->seek($s);
2724
+ }
2725
+
2726
+
2727
+ if (!empty($mediaType) && !$this->literal("and")) {
2728
+ // ~
2729
+ } else {
2730
+ $this->genericList($expressions, "mediaExpression", "and", false);
2731
+ if (is_array($expressions)) $parts = array_merge($parts, $expressions[2]);
2732
+ }
2733
+
2734
+ if (count($parts) == 0) {
2735
+ $this->seek($s);
2736
+ return false;
2737
+ }
2738
+
2739
+ $out = $parts;
2740
+ return true;
2741
+ }
2742
+
2743
+ protected function mediaExpression(&$out) {
2744
+ $s = $this->seek();
2745
+ $value = null;
2746
+ if ($this->literal("(") &&
2747
+ $this->keyword($feature) &&
2748
+ ($this->literal(":") && $this->expression($value) || true) &&
2749
+ $this->literal(")"))
2750
+ {
2751
+ $out = array("mediaExp", $feature);
2752
+ if ($value) $out[] = $value;
2753
+ return true;
2754
+ } elseif ($this->variable($variable)) {
2755
+ $out = array('variable', $variable);
2756
+ return true;
2757
+ }
2758
+
2759
+ $this->seek($s);
2760
+ return false;
2761
+ }
2762
+
2763
+ // an unbounded string stopped by $end
2764
+ protected function openString($end, &$out, $nestingOpen=null, $rejectStrs = null) {
2765
+ $oldWhite = $this->eatWhiteDefault;
2766
+ $this->eatWhiteDefault = false;
2767
+
2768
+ $stop = array("'", '"', "@{", $end);
2769
+ $stop = array_map(array("JupiterX_Lessc", "preg_quote"), $stop);
2770
+ // $stop[] = self::$commentMulti;
2771
+
2772
+ if (!is_null($rejectStrs)) {
2773
+ $stop = array_merge($stop, $rejectStrs);
2774
+ }
2775
+
2776
+ $patt = '(.*?)('.implode("|", $stop).')';
2777
+
2778
+ $nestingLevel = 0;
2779
+
2780
+ $content = array();
2781
+ while ($this->match($patt, $m, false)) {
2782
+ if (!empty($m[1])) {
2783
+ $content[] = $m[1];
2784
+ if ($nestingOpen) {
2785
+ $nestingLevel += substr_count($m[1], $nestingOpen);
2786
+ }
2787
+ }
2788
+
2789
+ $tok = $m[2];
2790
+
2791
+ $this->count-= strlen($tok);
2792
+ if ($tok == $end) {
2793
+ if ($nestingLevel == 0) {
2794
+ break;
2795
+ } else {
2796
+ $nestingLevel--;
2797
+ }
2798
+ }
2799
+
2800
+ if (($tok == "'" || $tok == '"') && $this->string($str)) {
2801
+ $content[] = $str;
2802
+ continue;
2803
+ }
2804
+
2805
+ if ($tok == "@{" && $this->interpolation($inter)) {
2806
+ $content[] = $inter;
2807
+ continue;
2808
+ }
2809
+
2810
+ if (!empty($rejectStrs) && in_array($tok, $rejectStrs)) {
2811
+ break;
2812
+ }
2813
+
2814
+ $content[] = $tok;
2815
+ $this->count+= strlen($tok);
2816
+ }
2817
+
2818
+ $this->eatWhiteDefault = $oldWhite;
2819
+
2820
+ if (count($content) == 0) return false;
2821
+
2822
+ // trim the end
2823
+ if (is_string(end($content))) {
2824
+ $content[count($content) - 1] = rtrim(end($content));
2825
+ }
2826
+
2827
+ $out = array("string", "", $content);
2828
+ return true;
2829
+ }
2830
+
2831
+ protected function string(&$out) {
2832
+ $s = $this->seek();
2833
+ if ($this->literal('"', false)) {
2834
+ $delim = '"';
2835
+ } elseif ($this->literal("'", false)) {
2836
+ $delim = "'";
2837
+ } else {
2838
+ return false;
2839
+ }
2840
+
2841
+ $content = array();
2842
+
2843
+ // look for either ending delim , escape, or string interpolation
2844
+ $patt = '([^\n]*?)(@\{|\\\\|' .
2845
+ JupiterX_Lessc::preg_quote($delim).')';
2846
+
2847
+ $oldWhite = $this->eatWhiteDefault;
2848
+ $this->eatWhiteDefault = false;
2849
+
2850
+ while ($this->match($patt, $m, false)) {
2851
+ $content[] = $m[1];
2852
+ if ($m[2] == "@{") {
2853
+ $this->count -= strlen($m[2]);
2854
+ if ($this->interpolation($inter, false)) {
2855
+ $content[] = $inter;
2856
+ } else {
2857
+ $this->count += strlen($m[2]);
2858
+ $content[] = "@{"; // ignore it
2859
+ }
2860
+ } elseif ($m[2] == '\\') {
2861
+ $content[] = $m[2];
2862
+ if ($this->literal($delim, false)) {
2863
+ $content[] = $delim;
2864
+ }
2865
+ } else {
2866
+ $this->count -= strlen($delim);
2867
+ break; // delim
2868
+ }
2869
+ }
2870
+
2871
+ $this->eatWhiteDefault = $oldWhite;
2872
+
2873
+ if ($this->literal($delim)) {
2874
+ $out = array("string", $delim, $content);
2875
+ return true;
2876
+ }
2877
+
2878
+ $this->seek($s);
2879
+ return false;
2880
+ }
2881
+
2882
+ protected function interpolation(&$out) {
2883
+ $oldWhite = $this->eatWhiteDefault;
2884
+ $this->eatWhiteDefault = true;
2885
+
2886
+ $s = $this->seek();
2887
+ if ($this->literal("@{") &&
2888
+ $this->openString("}", $interp, null, array("'", '"', ";")) &&
2889
+ $this->literal("}", false))
2890
+ {
2891
+ $out = array("interpolate", $interp);
2892
+ $this->eatWhiteDefault = $oldWhite;
2893
+ if ($this->eatWhiteDefault) $this->whitespace();
2894
+ return true;
2895
+ }
2896
+
2897
+ $this->eatWhiteDefault = $oldWhite;
2898
+ $this->seek($s);
2899
+ return false;
2900
+ }
2901
+
2902
+ protected function unit(&$unit) {
2903
+ // speed shortcut
2904
+ if (isset($this->buffer[$this->count])) {
2905
+ $char = $this->buffer[$this->count];
2906
+ if (!ctype_digit($char) && $char != ".") return false;
2907
+ }
2908
+
2909
+ if ($this->match('([0-9]+(?:\.[0-9]*)?|\.[0-9]+)([%a-zA-Z]+)?', $m)) {
2910
+ $unit = array("number", $m[1], empty($m[2]) ? "" : $m[2]);
2911
+ return true;
2912
+ }
2913
+ return false;
2914
+ }
2915
+
2916
+ // a # color
2917
+ protected function color(&$out) {
2918
+ if ($this->match('(#(?:[0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{3}))', $m)) {
2919
+ if (strlen($m[1]) > 7) {
2920
+ $out = array("string", "", array($m[1]));
2921
+ } else {
2922
+ $out = array("raw_color", $m[1]);
2923
+ }
2924
+ return true;
2925
+ }
2926
+
2927
+ return false;
2928
+ }
2929
+
2930
+ // consume an argument definition list surrounded by ()
2931
+ // each argument is a variable name with optional value
2932
+ // or at the end a ... or a variable named followed by ...
2933
+ // arguments are separated by , unless a ; is in the list, then ; is the
2934
+ // delimiter.
2935
+ protected function argumentDef(&$args, &$isVararg) {
2936
+ $s = $this->seek();
2937
+ if (!$this->literal('(')) return false;
2938
+
2939
+ $values = array();
2940
+ $delim = ",";
2941
+ $method = "expressionList";
2942
+
2943
+ $isVararg = false;
2944
+ while (true) {
2945
+ if ($this->literal("...")) {
2946
+ $isVararg = true;
2947
+ break;
2948
+ }
2949
+
2950
+ if ($this->$method($value)) {
2951
+ if ($value[0] == "variable") {
2952
+ $arg = array("arg", $value[1]);
2953
+ $ss = $this->seek();
2954
+
2955
+ if ($this->assign() && $this->$method($rhs)) {
2956
+ $arg[] = $rhs;
2957
+ } else {
2958
+ $this->seek($ss);
2959
+ if ($this->literal("...")) {
2960
+ $arg[0] = "rest";
2961
+ $isVararg = true;
2962
+ }
2963
+ }
2964
+
2965
+ $values[] = $arg;
2966
+ if ($isVararg) break;
2967
+ continue;
2968
+ } else {
2969
+ $values[] = array("lit", $value);
2970
+ }
2971
+ }
2972
+
2973
+
2974
+ if (!$this->literal($delim)) {
2975
+ if ($delim == "," && $this->literal(";")) {
2976
+ // found new delim, convert existing args
2977
+ $delim = ";";
2978
+ $method = "propertyValue";
2979
+
2980
+ // transform arg list
2981
+ if (isset($values[1])) { // 2 items
2982
+ $newList = array();
2983
+ foreach ($values as $i => $arg) {
2984
+ switch($arg[0]) {
2985
+ case "arg":
2986
+ if ($i) {
2987
+ $this->throwError("Cannot mix ; and , as delimiter types");
2988
+ }
2989
+ $newList[] = $arg[2];
2990
+ break;
2991
+ case "lit":
2992
+ $newList[] = $arg[1];
2993
+ break;
2994
+ case "rest":
2995
+ $this->throwError("Unexpected rest before semicolon");
2996
+ }
2997
+ }
2998
+
2999
+ $newList = array("list", ", ", $newList);
3000
+
3001
+ switch ($values[0][0]) {
3002
+ case "arg":
3003
+ $newArg = array("arg", $values[0][1], $newList);
3004
+ break;
3005
+ case "lit":
3006
+ $newArg = array("lit", $newList);
3007
+ break;
3008
+ }
3009
+
3010
+ } elseif ($values) { // 1 item
3011
+ $newArg = $values[0];
3012
+ }
3013
+
3014
+ if ($newArg) {
3015
+ $values = array($newArg);
3016
+ }
3017
+ } else {
3018
+ break;
3019
+ }
3020
+ }
3021
+ }
3022
+
3023
+ if (!$this->literal(')')) {
3024
+ $this->seek($s);
3025
+ return false;
3026
+ }
3027
+
3028
+ $args = $values;
3029
+
3030
+ return true;
3031
+ }
3032
+
3033
+ // consume a list of tags
3034
+ // this accepts a hanging delimiter
3035
+ protected function tags(&$tags, $simple = false, $delim = ',') {
3036
+ $tags = array();
3037
+ while ($this->tag($tt, $simple)) {
3038
+ $tags[] = $tt;
3039
+ if (!$this->literal($delim)) break;
3040
+ }
3041
+ if (count($tags) == 0) return false;
3042
+
3043
+ return true;
3044
+ }
3045
+
3046
+ // list of tags of specifying mixin path
3047
+ // optionally separated by > (lazy, accepts extra >)
3048
+ protected function mixinTags(&$tags) {
3049
+ $s = $this->seek();
3050
+ $tags = array();
3051
+ while ($this->tag($tt, true)) {
3052
+ $tags[] = $tt;
3053
+ $this->literal(">");
3054
+ }
3055
+
3056
+ if (count($tags) == 0) return false;
3057
+
3058
+ return true;
3059
+ }
3060
+
3061
+ // a bracketed value (contained within in a tag definition)
3062
+ protected function tagBracket(&$parts, &$hasExpression) {
3063
+ // speed shortcut
3064
+ if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "[") {
3065
+ return false;
3066
+ }
3067
+
3068
+ $s = $this->seek();
3069
+
3070
+ $hasInterpolation = false;
3071
+
3072
+ if ($this->literal("[", false)) {
3073
+ $attrParts = array("[");
3074
+ // keyword, string, operator
3075
+ while (true) {
3076
+ if ($this->literal("]", false)) {
3077
+ $this->count--;
3078
+ break; // get out early
3079
+ }
3080
+
3081
+ if ($this->match('\s+', $m)) {
3082
+ $attrParts[] = " ";
3083
+ continue;
3084
+ }
3085
+ if ($this->string($str)) {
3086
+ // escape parent selector, (yuck)
3087
+ foreach ($str[2] as &$chunk) {
3088
+ $chunk = str_replace($this->lessc->parentSelector, "$&$", $chunk);
3089
+ }
3090
+
3091
+ $attrParts[] = $str;
3092
+ $hasInterpolation = true;
3093
+ continue;
3094
+ }
3095
+
3096
+ if ($this->keyword($word)) {
3097
+ $attrParts[] = $word;
3098
+ continue;
3099
+ }
3100
+
3101
+ if ($this->interpolation($inter, false)) {
3102
+ $attrParts[] = $inter;
3103
+ $hasInterpolation = true;
3104
+ continue;
3105
+ }
3106
+
3107
+ // operator, handles attr namespace too
3108
+ if ($this->match('[|-~\$\*\^=]+', $m)) {
3109
+ $attrParts[] = $m[0];
3110
+ continue;
3111
+ }
3112
+
3113
+ break;
3114
+ }
3115
+
3116
+ if ($this->literal("]", false)) {
3117
+ $attrParts[] = "]";
3118
+ foreach ($attrParts as $part) {
3119
+ $parts[] = $part;
3120
+ }
3121
+ $hasExpression = $hasExpression || $hasInterpolation;
3122
+ return true;
3123
+ }
3124
+ $this->seek($s);
3125
+ }
3126
+
3127
+ $this->seek($s);
3128
+ return false;
3129
+ }
3130
+
3131
+ // a space separated list of selectors
3132
+ protected function tag(&$tag, $simple = false) {
3133
+ if ($simple)
3134
+ $chars = '^@,:;{}\][>\(\) "\'';
3135
+ else
3136
+ $chars = '^@,;{}["\'';
3137
+
3138
+ $s = $this->seek();
3139
+
3140
+ $hasExpression = false;
3141
+ $parts = array();
3142
+ while ($this->tagBracket($parts, $hasExpression));
3143
+
3144
+ $oldWhite = $this->eatWhiteDefault;
3145
+ $this->eatWhiteDefault = false;
3146
+
3147
+ while (true) {
3148
+ if ($this->match('(['.$chars.'0-9]['.$chars.']*)', $m)) {
3149
+ $parts[] = $m[1];
3150
+ if ($simple) break;
3151
+
3152
+ while ($this->tagBracket($parts, $hasExpression));
3153
+ continue;
3154
+ }
3155
+
3156
+ if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "@") {
3157
+ if ($this->interpolation($interp)) {
3158
+ $hasExpression = true;
3159
+ $interp[2] = true; // don't unescape
3160
+ $parts[] = $interp;
3161
+ continue;
3162
+ }
3163
+
3164
+ if ($this->literal("@")) {
3165
+ $parts[] = "@";
3166
+ continue;
3167
+ }
3168
+ }
3169
+
3170
+ if ($this->unit($unit)) { // for keyframes
3171
+ $parts[] = $unit[1];
3172
+ $parts[] = $unit[2];
3173
+ continue;
3174
+ }
3175
+
3176
+ break;
3177
+ }
3178
+
3179
+ $this->eatWhiteDefault = $oldWhite;
3180
+ if (!$parts) {
3181
+ $this->seek($s);
3182
+ return false;
3183
+ }
3184
+
3185
+ if ($hasExpression) {
3186
+ $tag = array("exp", array("string", "", $parts));
3187
+ } else {
3188
+ $tag = trim(implode($parts));
3189
+ }
3190
+
3191
+ $this->whitespace();
3192
+ return true;
3193
+ }
3194
+
3195
+ // a css function
3196
+ protected function func(&$func) {
3197
+ $s = $this->seek();
3198
+
3199
+ if ($this->match('(%|[\w\-_][\w\-_:\.]+|[\w_])', $m) && $this->literal('(')) {
3200
+ $fname = $m[1];
3201
+
3202
+ $sPreArgs = $this->seek();
3203
+
3204
+ $args = array();
3205
+ while (true) {
3206
+ $ss = $this->seek();
3207
+ // this ugly nonsense is for ie filter properties
3208
+ if ($this->keyword($name) && $this->literal('=') && $this->expressionList($value)) {
3209
+ $args[] = array("string", "", array($name, "=", $value));
3210
+ } else {
3211
+ $this->seek($ss);
3212
+ if ($this->expressionList($value)) {
3213
+ $args[] = $value;
3214
+ }
3215
+ }
3216
+
3217
+ if (!$this->literal(',')) break;
3218
+ }
3219
+ $args = array('list', ',', $args);
3220
+
3221
+ if ($this->literal(')')) {
3222
+ $func = array('function', $fname, $args);
3223
+ return true;
3224
+ } elseif ($fname == 'url') {
3225
+ // couldn't parse and in url? treat as string
3226
+ $this->seek($sPreArgs);
3227
+ if ($this->openString(")", $string) && $this->literal(")")) {
3228
+ $func = array('function', $fname, $string);
3229
+ return true;
3230
+ }
3231
+ }
3232
+ }
3233
+
3234
+ $this->seek($s);
3235
+ return false;
3236
+ }
3237
+
3238
+ // consume a less variable
3239
+ protected function variable(&$name) {
3240
+ $s = $this->seek();
3241
+ if ($this->literal($this->lessc->vPrefix, false) &&
3242
+ ($this->variable($sub) || $this->keyword($name)))
3243
+ {
3244
+ if (!empty($sub)) {
3245
+ $name = array('variable', $sub);
3246
+ } else {
3247
+ $name = $this->lessc->vPrefix.$name;
3248
+ }
3249
+ return true;
3250
+ }
3251
+
3252
+ $name = null;
3253
+ $this->seek($s);
3254
+ return false;
3255
+ }
3256
+
3257
+ /**
3258
+ * Consume an assignment operator
3259
+ * Can optionally take a name that will be set to the current property name
3260
+ */
3261
+ protected function assign($name = null) {
3262
+ if ($name) $this->currentProperty = $name;
3263
+ return $this->literal(':') || $this->literal('=');
3264
+ }
3265
+
3266
+ // consume a keyword
3267
+ protected function keyword(&$word) {
3268
+ if ($this->match('([\w_\-\*!"][\w\-_"]*)', $m)) {
3269
+ $word = $m[1];
3270
+ return true;
3271
+ }
3272
+ return false;
3273
+ }
3274
+
3275
+ // consume an end of statement delimiter
3276
+ protected function end() {
3277
+ if ($this->literal(';')) {
3278
+ return true;
3279
+ } elseif ($this->count == strlen($this->buffer) || $this->buffer[$this->count] == '}') {
3280
+ // if there is end of file or a closing block next then we don't need a ;
3281
+ return true;
3282
+ }
3283
+ return false;
3284
+ }
3285
+
3286
+ protected function guards(&$guards) {
3287
+ $s = $this->seek();
3288
+
3289
+ if (!$this->literal("when")) {
3290
+ $this->seek($s);
3291
+ return false;
3292
+ }
3293
+
3294
+ $guards = array();
3295
+
3296
+ while ($this->guardGroup($g)) {
3297
+ $guards[] = $g;
3298
+ if (!$this->literal(",")) break;
3299
+ }
3300
+
3301
+ if (count($guards) == 0) {
3302
+ $guards = null;
3303
+ $this->seek($s);
3304
+ return false;
3305
+ }
3306
+
3307
+ return true;
3308
+ }
3309
+
3310
+ // a bunch of guards that are and'd together
3311
+ // TODO rename to guardGroup
3312
+ protected function guardGroup(&$guardGroup) {
3313
+ $s = $this->seek();
3314
+ $guardGroup = array();
3315
+ while ($this->guard($guard)) {
3316
+ $guardGroup[] = $guard;
3317
+ if (!$this->literal("and")) break;
3318
+ }
3319
+
3320
+ if (count($guardGroup) == 0) {
3321
+ $guardGroup = null;
3322
+ $this->seek($s);
3323
+ return false;
3324
+ }
3325
+
3326
+ return true;
3327
+ }
3328
+
3329
+ protected function guard(&$guard) {
3330
+ $s = $this->seek();
3331
+ $negate = $this->literal("not");
3332
+
3333
+ if ($this->literal("(") && $this->expression($exp) && $this->literal(")")) {
3334
+ $guard = $exp;
3335
+ if ($negate) $guard = array("negate", $guard);
3336
+ return true;
3337
+ }
3338
+
3339
+ $this->seek($s);
3340
+ return false;
3341
+ }
3342
+
3343
+ /* raw parsing functions */
3344
+
3345
+ protected function literal($what, $eatWhitespace = null) {
3346
+ if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault;
3347
+
3348
+ // shortcut on single letter
3349
+ if (!isset($what[1]) && isset($this->buffer[$this->count])) {
3350
+ if ($this->buffer[$this->count] == $what) {
3351
+ if (!$eatWhitespace) {
3352
+ $this->count++;
3353
+ return true;
3354
+ }
3355
+ // goes below...
3356
+ } else {
3357
+ return false;
3358
+ }
3359
+ }
3360
+
3361
+ if (!isset(self::$literalCache[$what])) {
3362
+ self::$literalCache[$what] = JupiterX_Lessc::preg_quote($what);
3363
+ }
3364
+
3365
+ return $this->match(self::$literalCache[$what], $m, $eatWhitespace);
3366
+ }
3367
+
3368
+ protected function genericList(&$out, $parseItem, $delim="", $flatten=true) {
3369
+ $s = $this->seek();
3370
+ $items = array();
3371
+ while ($this->$parseItem($value)) {
3372
+ $items[] = $value;
3373
+ if ($delim) {
3374
+ if (!$this->literal($delim)) break;
3375
+ }
3376
+ }
3377
+
3378
+ if (count($items) == 0) {
3379
+ $this->seek($s);
3380
+ return false;
3381
+ }
3382
+
3383
+ if ($flatten && count($items) == 1) {
3384
+ $out = $items[0];
3385
+ } else {
3386
+ $out = array("list", $delim, $items);
3387
+ }
3388
+
3389
+ return true;
3390
+ }
3391
+
3392
+
3393
+ // advance counter to next occurrence of $what
3394
+ // $until - don't include $what in advance
3395
+ // $allowNewline, if string, will be used as valid char set
3396
+ protected function to($what, &$out, $until = false, $allowNewline = false) {
3397
+ if (is_string($allowNewline)) {
3398
+ $validChars = $allowNewline;
3399
+ } else {
3400
+ $validChars = $allowNewline ? "." : "[^\n]";
3401
+ }
3402
+ if (!$this->match('('.$validChars.'*?)'.JupiterX_Lessc::preg_quote($what), $m, !$until)) return false;
3403
+ if ($until) $this->count -= strlen($what); // give back $what
3404
+ $out = $m[1];
3405
+ return true;
3406
+ }
3407
+
3408
+ // try to match something on head of buffer
3409
+ protected function match($regex, &$out, $eatWhitespace = null) {
3410
+ if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault;
3411
+
3412
+ $r = '/'.$regex.($eatWhitespace && !$this->writeComments ? '\s*' : '').'/Ais';
3413
+ if (preg_match($r, $this->buffer, $out, 0, $this->count)) {
3414
+ $this->count += strlen($out[0]);
3415
+ if ($eatWhitespace && $this->writeComments) $this->whitespace();
3416
+ return true;
3417
+ }
3418
+ return false;
3419
+ }
3420
+
3421
+ // match some whitespace
3422
+ protected function whitespace() {
3423
+ if ($this->writeComments) {
3424
+ $gotWhite = false;
3425
+ while (preg_match(self::$whitePattern, $this->buffer, $m, 0, $this->count)) {
3426
+ if (isset($m[1]) && empty($this->commentsSeen[$this->count])) {
3427
+ $this->append(array("comment", $m[1]));
3428
+ $this->commentsSeen[$this->count] = true;
3429
+ }
3430
+ $this->count += strlen($m[0]);
3431
+ $gotWhite = true;
3432
+ }
3433
+ return $gotWhite;
3434
+ } else {
3435
+ $this->match("", $m);
3436
+ return strlen($m[0]) > 0;
3437
+ }
3438
+ }
3439
+
3440
+ // match something without consuming it
3441
+ protected function peek($regex, &$out = null, $from=null) {
3442
+ if (is_null($from)) $from = $this->count;
3443
+ $r = '/'.$regex.'/Ais';
3444
+ $result = preg_match($r, $this->buffer, $out, 0, $from);
3445
+
3446
+ return $result;
3447
+ }
3448
+
3449
+ // seek to a spot in the buffer or return where we are on no argument
3450
+ protected function seek($where = null) {
3451
+ if ($where === null) return $this->count;
3452
+ else $this->count = $where;
3453
+ return true;
3454
+ }
3455
+
3456
+ /* misc functions */
3457
+
3458
+ public function throwError($msg = "parse error", $count = null) {
3459
+ $count = is_null($count) ? $this->count : $count;
3460
+
3461
+ $line = $this->line +
3462
+ substr_count(substr($this->buffer, 0, $count), "\n");
3463
+
3464
+ if (!empty($this->sourceName)) {
3465
+ $loc = "$this->sourceName on line $line";
3466
+ } else {
3467
+ $loc = "line: $line";
3468
+ }
3469
+
3470
+ // TODO this depends on $this->count
3471
+ if ($this->peek("(.*?)(\n|$)", $m, $count)) {
3472
+ throw new exception("$msg: failed at `$m[1]` $loc");
3473
+ } else {
3474
+ throw new exception("$msg: $loc");
3475
+ }
3476
+ }
3477
+
3478
+ protected function pushBlock($selectors=null, $type=null) {
3479
+ $b = new stdclass;
3480
+ $b->parent = $this->env;
3481
+
3482
+ $b->type = $type;
3483
+ $b->id = self::$nextBlockId++;
3484
+
3485
+ $b->isVararg = false; // TODO: kill me from here
3486
+ $b->tags = $selectors;
3487
+
3488
+ $b->props = array();
3489
+ $b->children = array();
3490
+
3491
+ $this->env = $b;
3492
+ return $b;
3493
+ }
3494
+
3495
+ // push a block that doesn't multiply tags
3496
+ protected function pushSpecialBlock($type) {
3497
+ return $this->pushBlock(null, $type);
3498
+ }
3499
+
3500
+ // append a property to the current block
3501
+ protected function append($prop, $pos = null) {
3502
+ if ($pos !== null) $prop[-1] = $pos;
3503
+ $this->env->props[] = $prop;
3504
+ }
3505
+
3506
+ // pop something off the stack
3507
+ protected function pop() {
3508
+ $old = $this->env;
3509
+ $this->env = $this->env->parent;
3510
+ return $old;
3511
+ }
3512
+
3513
+ // remove comments from $text
3514
+ // todo: make it work for all functions, not just url
3515
+ protected function removeComments($text) {
3516
+ $look = array(
3517
+ 'url(', '//', '/*', '"', "'"
3518
+ );
3519
+
3520
+ $out = '';
3521
+ $min = null;
3522
+ while (true) {
3523
+ // find the next item
3524
+ foreach ($look as $token) {
3525
+ $pos = strpos($text, $token);
3526
+ if ($pos !== false) {
3527
+ if (!isset($min) || $pos < $min[1]) $min = array($token, $pos);
3528
+ }
3529
+ }
3530
+
3531
+ if (is_null($min)) break;
3532
+
3533
+ $count = $min[1];
3534
+ $skip = 0;
3535
+ $newlines = 0;
3536
+ switch ($min[0]) {
3537
+ case 'url(':
3538
+ if (preg_match('/url\(.*?\)/', $text, $m, 0, $count))
3539
+ $count += strlen($m[0]) - strlen($min[0]);
3540
+ break;
3541
+ case '"':
3542
+ case "'":
3543
+ if (preg_match('/'.$min[0].'.*?(?<!\\\\)'.$min[0].'/', $text, $m, 0, $count))
3544
+ $count += strlen($m[0]) - 1;
3545
+ break;
3546
+ case '//':
3547
+ $skip = strpos($text, "\n", $count);
3548
+ if ($skip === false) $skip = strlen($text) - $count;
3549
+ else $skip -= $count;
3550
+ break;
3551
+ case '/*':
3552
+ if (preg_match('/\/\*.*?\*\//s', $text, $m, 0, $count)) {
3553
+ $skip = strlen($m[0]);
3554
+ $newlines = substr_count($m[0], "\n");
3555
+ }
3556
+ break;
3557
+ }
3558
+
3559
+ if ($skip == 0) $count += strlen($min[0]);
3560
+
3561
+ $out .= substr($text, 0, $count).str_repeat("\n", $newlines);
3562
+ $text = substr($text, $count + $skip);
3563
+
3564
+ $min = null;
3565
+ }
3566
+
3567
+ return $out.$text;
3568
+ }
3569
+
3570
+ }
3571
+
3572
+ /**
3573
+ * @ignore
3574
+ */
3575
+ class jupiterx_lessc_formatter_classic {
3576
+ public $indentChar = " ";
3577
+
3578
+ public $break = "\n";
3579
+ public $open = " {";
3580
+ public $close = "}";
3581
+ public $selectorSeparator = ", ";
3582
+ public $assignSeparator = ":";
3583
+
3584
+ public $openSingle = " { ";
3585
+ public $closeSingle = " }";
3586
+
3587
+ public $disableSingle = false;
3588
+ public $breakSelectors = false;
3589
+
3590
+ public $compressColors = false;
3591
+
3592
+ public function __construct() {
3593
+ $this->indentLevel = 0;
3594
+ }
3595
+
3596
+ public function indentStr($n = 0) {
3597
+ return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
3598
+ }
3599
+
3600
+ public function property($name, $value) {
3601
+ return $name . $this->assignSeparator . $value . ";";
3602
+ }
3603
+
3604
+ protected function isEmpty($block) {
3605
+ if (empty($block->lines)) {
3606
+ foreach ($block->children as $child) {
3607
+ if (!$this->isEmpty($child)) return false;
3608
+ }
3609
+
3610
+ return true;
3611
+ }
3612
+ return false;
3613
+ }
3614
+
3615
+ public function block($block) {
3616
+ if ($this->isEmpty($block)) return;
3617
+
3618
+ $inner = $pre = $this->indentStr();
3619
+
3620
+ $isSingle = !$this->disableSingle &&
3621
+ is_null($block->type) && count($block->lines) == 1;
3622
+
3623
+ if (!empty($block->selectors)) {
3624
+ $this->indentLevel++;
3625
+
3626
+ if ($this->breakSelectors) {
3627
+ $selectorSeparator = $this->selectorSeparator . $this->break . $pre;
3628
+ } else {
3629
+ $selectorSeparator = $this->selectorSeparator;
3630
+ }
3631
+
3632
+ echo $pre .
3633
+ implode($selectorSeparator, $block->selectors);
3634
+ if ($isSingle) {
3635
+ echo $this->openSingle;
3636
+ $inner = "";
3637
+ } else {
3638
+ echo $this->open . $this->break;
3639
+ $inner = $this->indentStr();
3640
+ }
3641
+
3642
+ }
3643
+
3644
+ if (!empty($block->lines)) {
3645
+ $glue = $this->break.$inner;
3646
+ echo $inner . implode($glue, $block->lines);
3647
+ if (!$isSingle && !empty($block->children)) {
3648
+ echo $this->break;
3649
+ }
3650
+ }
3651
+
3652
+ foreach ($block->children as $child) {
3653
+ $this->block($child);
3654
+ }
3655
+
3656
+ if (!empty($block->selectors)) {
3657
+ if (!$isSingle && empty($block->children)) echo $this->break;
3658
+
3659
+ if ($isSingle) {
3660
+ echo $this->closeSingle . $this->break;
3661
+ } else {
3662
+ echo $pre . $this->close . $this->break;
3663
+ }
3664
+
3665
+ $this->indentLevel--;
3666
+ }
3667
+ }
3668
+ }
3669
+
3670
+ /**
3671
+ * @ignore
3672
+ */
3673
+ class jupiterx_lessc_formatter_compressed extends jupiterx_lessc_formatter_classic {
3674
+ public $disableSingle = true;
3675
+ public $open = "{";
3676
+ public $selectorSeparator = ",";
3677
+ public $assignSeparator = ":";
3678
+ public $break = "";
3679
+ public $compressColors = true;
3680
+
3681
+ public function indentStr($n = 0) {
3682
+ return "";
3683
+ }
3684
+ }
3685
+
3686
+ /**
3687
+ * @ignore
3688
+ */
3689
+ class jupiterx_lessc_formatter_lessjs extends jupiterx_lessc_formatter_classic {
3690
+ public $disableSingle = true;
3691
+ public $breakSelectors = true;
3692
+ public $assignSeparator = ": ";
3693
+ public $selectorSeparator = ",";
3694
+ }
includes/custom-fields/title-bar.php CHANGED
@@ -1,33 +1,33 @@
1
- <?php
2
- /**
3
- * Add Jupiter Post Options > Title Bar meta options.
4
- *
5
- * @package JupiterX_Core\Custom_fields
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- add_action( 'jupiterx_custom_field_post_types', 'jupiterx_add_title_bar_field' );
11
- /**
12
- * Add title bar field to the new page/post/portfolio. Add due to prevent content creation rule.
13
- *
14
- * @since 1.9.0
15
- *
16
- * @return void
17
- */
18
- function jupiterx_add_title_bar_field() {
19
- if ( ! class_exists( 'acf' ) ) {
20
- return;
21
- }
22
- $key = 'field_jupiterx_post_title_bar';
23
- $parent = 'group_jupiterx_post';
24
-
25
- acf_add_local_field( [
26
- 'key' => "{$key}_subtitle",
27
- 'parent' => $parent,
28
- 'label' => __( 'Subtitle', 'jupiterx-core' ),
29
- 'name' => 'jupiterx_title_bar_subtitle',
30
- 'type' => 'textarea',
31
- 'rows' => '3',
32
- ] );
33
- }
1
+ <?php
2
+ /**
3
+ * Add Jupiter Post Options > Title Bar meta options.
4
+ *
5
+ * @package JupiterX_Core\Custom_fields
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ add_action( 'jupiterx_custom_field_post_types', 'jupiterx_add_title_bar_field' );
11
+ /**
12
+ * Add title bar field to the new page/post/portfolio. Add due to prevent content creation rule.
13
+ *
14
+ * @since 1.9.0
15
+ *
16
+ * @return void
17
+ */
18
+ function jupiterx_add_title_bar_field() {
19
+ if ( ! class_exists( 'acf' ) ) {
20
+ return;
21
+ }
22
+ $key = 'field_jupiterx_post_title_bar';
23
+ $parent = 'group_jupiterx_post';
24
+
25
+ acf_add_local_field( [
26
+ 'key' => "{$key}_subtitle",
27
+ 'parent' => $parent,
28
+ 'label' => __( 'Subtitle', 'jupiterx-core' ),
29
+ 'name' => 'jupiterx_title_bar_subtitle',
30
+ 'type' => 'textarea',
31
+ 'rows' => '3',
32
+ ] );
33
+ }
includes/customizer/api/classes/class-cache.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This class handles caching of customizer theme mods.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.15.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Customizer theme mods caching.
17
+ *
18
+ * @since 1.15.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ final class JupiterX_Customizer_Cache {
25
+
26
+ /**
27
+ * Theme mods storage.
28
+ *
29
+ * @var array
30
+ */
31
+ public $theme_mods = [];
32
+
33
+ /**
34
+ * Construct the class.
35
+ *
36
+ * @since 1.15.0
37
+ */
38
+ public function __construct() {
39
+ add_action( 'jupiterx_control_panel_settings_customizer_cache', [ $this, 'settings_html' ] );
40
+
41
+ if ( '1' !== jupiterx_get_option( 'customizer_cache', '1' ) ) {
42
+ return;
43
+ }
44
+
45
+ $slug = get_option( 'stylesheet' );
46
+
47
+ add_filter( "pre_update_option_theme_mods_$slug", [ $this, 'clear_cache' ], 5, 1 );
48
+ add_filter( "option_theme_mods_$slug", [ $this, 'set_cache' ], 5 );
49
+ add_filter( "pre_option_theme_mods_$slug", [ $this, 'get_cache' ], 5 );
50
+ }
51
+
52
+ /**
53
+ * Set cache.
54
+ *
55
+ * Ensured that all hooks are executed during the first run of the `get_theme_mod` function.
56
+ *
57
+ * @link https://developer.wordpress.org/reference/hooks/option_option
58
+ *
59
+ * @param array $value Serialized theme mods.
60
+ *
61
+ * @return array Theme mods value.
62
+ */
63
+ public function set_cache( $value ) {
64
+ // Save cache.
65
+ $this->theme_mods = $value;
66
+
67
+ return $value;
68
+ }
69
+
70
+ /**
71
+ * Get cache.
72
+ *
73
+ * Short-circuit pre option filter when theme mods are set.
74
+ *
75
+ * @link https://developer.wordpress.org/reference/hooks/pre_option_option
76
+ *
77
+ * @since 1.15.0
78
+ *
79
+ * @return array|boolean Theme mods when cache exists and false if not.
80
+ */
81
+ public function get_cache() {
82
+ if ( ! empty( $this->theme_mods ) ) {
83
+ return $this->theme_mods;
84
+ }
85
+
86
+ return false;
87
+ }
88
+
89
+ /**
90
+ * Clear cache.
91
+ *
92
+ * Clear cache if theme mods are updated.
93
+ *
94
+ * @link https://developer.wordpress.org/reference/hooks/update_option_option/
95
+ *
96
+ * @since 1.15.0
97
+ *
98
+ * @param array $value unserialized theme mods.
99
+ *
100
+ * @return array|boolean Theme mods when cache exists and false if not.
101
+ */
102
+ public function clear_cache( $value ) {
103
+ $this->theme_mods = [];
104
+
105
+ return $value;
106
+ }
107
+
108
+ /**
109
+ * Render Customizer Cache settings on control panel.
110
+ *
111
+ * @since 1.15.0
112
+ */
113
+ public function settings_html() {
114
+ $checked = jupiterx_get_option( 'customizer_cache', '1' );
115
+
116
+ if ( '1' === $checked ) {
117
+ $checked = true;
118
+ }
119
+ ?>
120
+ <div class="form-group col-md-6">
121
+ <label for="jupiterx-cp-settings-customizer-cache"><?php esc_html_e( 'Customizer Cache', 'jupiterx-core' ); ?></label>
122
+ <input type="hidden" name="jupiterx_customizer_cache" value="0">
123
+ <div class="jupiterx-switch">
124
+ <input type="checkbox" id="jupiterx-cp-settings-customizer-cache-enabled" name="jupiterx_customizer_cache" value="1" <?php checked( $checked, true ); ?>>
125
+ <label for="jupiterx-cp-settings-customizer-cache-enabled"></label>
126
+ </div>
127
+ <small class="form-text text-muted"><?php esc_html_e( 'Enable Customizer Cache to improve page load time.', 'jupiterx-core' ); ?></small>
128
+ </div>
129
+ <?php
130
+ }
131
+ }
132
+
133
+ // Initialize.
134
+ new JupiterX_Customizer_Cache();
includes/customizer/api/classes/class-multilingual.php CHANGED
@@ -1,448 +1,452 @@
1
- <?php
2
-
3
- // phpcs:ignoreFile
4
- /**
5
- * If Polylang is active:
6
- * - save and retrieve customizer setting per language.
7
- * - on front-page, set options and theme mod for the selected language.
8
- *
9
- * Inspired by https://github.com/fastlinemedia/customizer-export-import
10
- *
11
- * @package JupiterX\Framework\API\Customizer
12
- */
13
-
14
- if ( ! function_exists( 'pll_current_language' ) && ! class_exists( 'SitePress' ) ) {
15
- return;
16
- }
17
-
18
- /**
19
- * Functionality for multilingual customizer.
20
- *
21
- * @since 1.0.0
22
- *
23
- * @package JupiterX\Framework\API\Customizer
24
- * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
25
- */
26
- class CoreCustomizerMultilingual {
27
-
28
- public static function init() {
29
- $self = new self();
30
-
31
- // Disable detect browser language, will return default language instead.
32
- add_filter( 'pll_preferred_language', '__return_false' );
33
-
34
- add_action( 'customize_controls_enqueue_scripts', [ __CLASS__, 'add_lang_to_customizer_previewer' ], 9 );
35
- add_action( 'wp_before_admin_bar_render', [ __CLASS__, 'on_wp_before_admin_bar_render' ], 100 );
36
- add_action( 'admin_menu', [ __CLASS__, 'on_admin_menu' ], 100 );
37
- add_action( 'after_setup_theme', [ __CLASS__, 'remove_filters' ], 5 );
38
-
39
- $theme_stylesheet_slug = get_option( 'stylesheet' );
40
- $option_types = [ 'blogname', 'blogdescription', 'site_icon' ];
41
-
42
- if ( ! ( defined('DOING_AJAX') && DOING_AJAX && isset( $_POST['action'] ) && in_array( $_POST['action'], [ 'jupiterx_cp_cleanup_mods', 'abb_install_template_procedure' ], true ) ) ) {
43
- // Get theme mod options.
44
- add_filter( 'option_theme_mods_' . $theme_stylesheet_slug, [ $self, 'on_option_theme_mods_get' ], 10, 1 );
45
- // Update theme mod options.
46
- add_filter( 'pre_update_option_theme_mods_' . $theme_stylesheet_slug, [ $self, 'on_option_theme_mods_update' ], 10, 2 );
47
- }
48
-
49
- foreach ( $option_types as $option_type ) {
50
- add_filter( 'pre_option_' . $option_type, [ $self, 'on_wp_option_get' ], 10, 3 ); // get_option hook.
51
- add_filter( 'pre_update_option_' . $option_type, [ $self, 'on_wp_option_update' ], 10, 3 ); // update_option hook.
52
- }
53
-
54
- return $self;
55
- }
56
-
57
- /**
58
- * Remove bloginfo update filters. As we save options per language in this class, we don't need WPML functionality.
59
- *
60
- * @since 1.0.0
61
- *
62
- * @return void
63
- */
64
- public static function remove_filters() {
65
- global $WPML_String_Translation; // @phpcs:ignore
66
- remove_filter( 'pre_update_option_blogname', [ $WPML_String_Translation, 'pre_update_option_blogname' ], 5 ); // @phpcs:ignore
67
- remove_filter( 'pre_update_option_blogdescription', [ $WPML_String_Translation, 'pre_update_option_blogdescription' ], 5 ); // @phpcs:ignore
68
- }
69
-
70
- /**
71
- * Get current language.
72
- *
73
- * @since 1.0.0
74
- *
75
- * @return string|bool $language|false Current language or false when none of Polylang & WPML are active.
76
- */
77
- public static function get_language() {
78
- if ( function_exists( 'pll_current_language' ) ) {
79
- $language = pll_current_language();
80
-
81
- if ( ! $language ) {
82
- $language = pll_default_language();
83
- }
84
-
85
- return $language;
86
- }
87
-
88
- if ( class_exists( 'SitePress' ) && defined( 'ICL_LANGUAGE_CODE' ) ) {
89
- return ICL_LANGUAGE_CODE;
90
- }
91
-
92
- return false;
93
- }
94
-
95
- /**
96
- * Get a list of active languages with extra parameters like name and slug.
97
- *
98
- * @since 1.0.0
99
- *
100
- * @return array|bool $languages|false List of active languages or false when none of Polylang & WPML are active.
101
- */
102
- public static function get_languages_list() {
103
- if ( function_exists( 'pll_current_language' ) ) {
104
- return get_option( '_transient_pll_languages_list' );
105
- }
106
-
107
- if ( class_exists( 'SitePress' ) && defined( 'ICL_LANGUAGE_CODE' ) ) {
108
- $list = icl_get_languages( 'skip_missing=1' );
109
- $languages = [];
110
-
111
- foreach ( $list as $language ) {
112
- $temp = [];
113
- $temp['name'] = $language['native_name'];
114
- $temp['slug'] = $language['code'];
115
- $languages[] = $temp;
116
- }
117
-
118
- return $languages;
119
- }
120
-
121
- return false;
122
- }
123
-
124
- /**
125
- * Get a proper option key per plugin.
126
- *
127
- * @since 1.0.0
128
- *
129
- * @return string|bool Option key or false when none of Polylang & WPML are active.
130
- */
131
- public static function get_option_key() {
132
- if ( function_exists( 'pll_current_language' ) ) {
133
- return '_customizer_polylang_settings_';
134
- }
135
-
136
- if ( class_exists( 'SitePress' ) && defined( 'ICL_LANGUAGE_CODE' ) ) {
137
- return '_customizer_wpml_settings_';
138
- }
139
-
140
- return false;
141
- }
142
-
143
- /**
144
- * Get home URL of current language.
145
- *
146
- * @param string $language current language.
147
- *
148
- * @since 1.0.0
149
- *
150
- * @return string|bool Home URL of current language or false when none of Polylang & WPML are active.
151
- */
152
- public static function get_home_url( $language ) {
153
- if ( function_exists( 'pll_current_language' ) ) {
154
- return pll_home_url( $language );
155
- }
156
-
157
- if ( class_exists( 'SitePress' ) ) {
158
- global $sitepress;
159
- return $sitepress->language_url( $language );
160
- }
161
-
162
- return false;
163
- }
164
-
165
- /**
166
- * Helper to fetch custom customizer db content.
167
- *
168
- * @since 1.3.0
169
- *
170
- * @return mixed Customizer array or false.
171
- */
172
- protected function get_custom_customizer_option() {
173
- $current_language = self::get_language();
174
- $theme_slug = get_option( 'template' );
175
- $option_prefix = str_replace( '-', '_', $theme_slug );
176
- $option_name = $option_prefix . self::get_option_key() . $current_language;
177
-
178
- return get_option( $option_name, false );
179
- }
180
-
181
- /**
182
- * Helper to update custom customizer db content.
183
- *
184
- * @since 1.3.0
185
- *
186
- * @param mixed $data Data to insert.
187
- *
188
- * @return bool Success.
189
- */
190
- protected function update_custom_customizer_option( $data ) {
191
- $current_language = self::get_language();
192
- $theme_slug = get_option( 'template' );
193
- $option_prefix = str_replace( '-', '_', $theme_slug );
194
- $option_name = $option_prefix . self::get_option_key() . $current_language;
195
-
196
- return update_option( $option_name, $data );
197
- }
198
-
199
- /**
200
- * Helper
201
- *
202
- * @since 1.3.0
203
- *
204
- * @return bool If the current language is the default language.
205
- */
206
- protected function current_lang_not_default() {
207
- if ( class_exists( 'SitePress' ) ) {
208
- global $sitepress;
209
- return $sitepress->get_current_language() !== $sitepress->get_default_language();
210
- }
211
-
212
- return pll_current_language() !== pll_default_language();
213
- }
214
-
215
- /**
216
- * Check the custom db field on get_option hook to be able to return custom language value.
217
- * If the current language is default, then return from default wp option
218
- *
219
- * @since 1.3.0
220
- *
221
- * @param bool $pre_option This is false. If something else is returned wp exits the check in db and uses this value.
222
- * @param string $option Option name asked for.
223
- * @param mixed $default Default value, second args when asking for options.
224
- *
225
- * @return mixed
226
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
227
- */
228
- public function on_wp_option_get( $pre_option, $option, $default ) {
229
-
230
- // If not the default language, then skip the custom check and wp will the use default options.
231
- if ( $this->current_lang_not_default() ) {
232
- $data = $this->get_custom_customizer_option();
233
-
234
- // Found the custom option. Move on.
235
- if ( is_array( $data ) && isset( $data['options'] ) && isset( $data['options'][ $option ] ) ) {
236
- return $data['options'][ $option ];
237
- }
238
- }
239
-
240
- return $default;
241
- }
242
-
243
- /**
244
- * Update the custom db field on get_option hook.
245
- * If the current language is not default, then return old value to prevent from saving to default wp option.
246
- *
247
- * @since 1.3.0
248
- *
249
- * @param mixed $value The new, unserialized option value.
250
- * @param mixed $old_value The old option value.
251
- * @param string $option Option name.
252
- *
253
- * @return mixed
254
- */
255
- public function on_wp_option_update( $value, $old_value, $option ) {
256
- // Fetch custom option db field.
257
- $data = $this->get_custom_customizer_option();
258
- $theme_slug = get_option( 'template' );
259
- // If false, the field hasn't been created yet, so it must be created.
260
- if ( false === $data ) {
261
- $data = [
262
- 'template' => $theme_slug,
263
- 'mods' => [],
264
- 'options' => [],
265
- ];
266
- }
267
-
268
- // Make sure the options array exists. We are going to use it soon.
269
- if ( ! isset( $data['options'] ) ) {
270
- $data['options'] = [];
271
- }
272
-
273
- $data['options'][ $option ] = $value;
274
-
275
- // Update option value in custom db field. (Not necessary to save for default language since it uses default wp option fields for values when get option).
276
- $this->update_custom_customizer_option( $data );
277
-
278
- // If the current language is not the default language, prevent saving to option table by passing the old value back. It will then exit after the filter.
279
- if ( $this->current_lang_not_default() ) {
280
- return $old_value;
281
- }
282
-
283
- return $value;
284
- }
285
-
286
- /**
287
- * Check the custom db field on get_option customizer field option name hook to be able to return custom language value.
288
- * Parse arguments with default wp customizer values to make sure all are present in the return.
289
- *
290
- * @since 1.3.0
291
- *
292
- * @param array $value The customizer settings.
293
- *
294
- * @return array
295
- */
296
- public function on_option_theme_mods_get( $value ) {
297
- $data = $this->get_custom_customizer_option();
298
-
299
- if ( isset( $data['mods'] ) && is_array( $data['mods'] ) && ! empty( $data['mods'] ) ) {
300
- $value = wp_parse_args( $data['mods'], $value );
301
- }
302
-
303
- return $value;
304
- }
305
-
306
- /**
307
- * Update custom customizer option.
308
- * If the current language is not default, then return old value to prevent from saving to customizer wp option.
309
- *
310
- * @since 1.3.0
311
- *
312
- * @param mixed $value The new, unserialized option value.
313
- * @param mixed $old_value The old option value.
314
- */
315
- public function on_option_theme_mods_update( $value, $old_value ) {
316
-
317
- $current_data = $this->get_custom_customizer_option();
318
- $theme_slug = get_option( 'template' );
319
-
320
- $data = [
321
- 'template' => $theme_slug,
322
- 'mods' => isset( $current_data['mods'] ) ? $current_data['mods'] : [],
323
- 'options' => isset( $current_data['options'] ) ? $current_data['options'] : [],
324
- ];
325
-
326
- if ( is_array( $value ) && ! empty( $value ) ) {
327
- foreach ( $value as $key => $val ) {
328
- $data['mods'][ $key ] = $val;
329
- }
330
- }
331
- $this->update_custom_customizer_option( $data );
332
-
333
- if ( $this->current_lang_not_default() ) {
334
- return $old_value;
335
- }
336
-
337
- return $value;
338
- }
339
-
340
- /**
341
- * If Polylang activated, set the preview url and add select language control
342
- *
343
- * @author soderlind
344
- * @version 1.0.0
345
- * @link https://gist.github.com/soderlind/1908634f5eb0c1f69428666dd2a291d0
346
- *
347
- * @since 1.0.0
348
- */
349
- public static function add_lang_to_customizer_previewer() {
350
- $languages = self::get_languages_list();
351
-
352
- if ( ! $languages || jupiterx_get( 'kt-woomail-customize' ) ) {
353
- return;
354
- }
355
-
356
- $handle = 'dss-add-lang-to-template';
357
- $js_path_url = trailingslashit( apply_filters( 'scp_js_path_url', get_stylesheet_directory_uri() . '/js/' ) );
358
- $src = $js_path_url . 'customizer-multilingual.js';
359
- $deps = [ 'customize-controls' ];
360
- wp_enqueue_script( $handle, $src, $deps, JUPITERX_VERSION, true );
361
- $language = ( empty( $_REQUEST['lang'] ) ) ? self::get_language() : $_REQUEST['lang']; // @phpcs:ignore
362
-
363
- if ( empty( $language ) ) {
364
- $language = self::default_language();
365
- }
366
-
367
- $url = add_query_arg( 'lang', $language, self::get_home_url( $language ) );
368
-
369
- wp_add_inline_script(
370
- $handle,
371
- sprintf(
372
- 'JupiterXCustomizerMultilingual.init( %s );', wp_json_encode(
373
- [
374
- 'url' => $url,
375
- 'languages' => $languages,
376
- 'current_language' => $language,
377
- 'switcher_text' => __( 'Language:', 'jupiterx-core' ),
378
- ]
379
- )
380
- ), 'after'
381
- );
382
- }
383
-
384
- /**
385
- * Append lang="contrycode" to the customizer url in the adminbar
386
- *
387
- * @since 1.0.0
388
- *
389
- * @return void
390
- */
391
- public static function on_wp_before_admin_bar_render() {
392
- global $wp_admin_bar;
393
- $customize_node = $wp_admin_bar->get_node( 'customize' );
394
- if ( ! empty( $customize_node ) ) {
395
- $customize_node->href = add_query_arg( 'lang', self::get_language(), $customize_node->href );
396
- $wp_admin_bar->add_node( $customize_node );
397
- }
398
- }
399
-
400
- /**
401
- * Append lang="contrycode" to the customizer url in the Admin->Apperance->Customize menu
402
- *
403
- * @since 1.0.0
404
- *
405
- * @return void
406
- */
407
- public static function on_admin_menu() {
408
- global $menu, $submenu;
409
- $parent = 'themes.php';
410
- if ( ! isset( $submenu[ $parent ] ) ) {
411
- return;
412
- }
413
- foreach ( $submenu[ $parent ] as $k => $d ) {
414
- if ( 'customize' === $d['1'] ) {
415
- $submenu[ $parent ][ $k ]['2'] = add_query_arg( 'lang', self::get_language(), $submenu[ $parent ][ $k ]['2'] ); // @phpcs:ignore
416
- break;
417
- }
418
- }
419
- }
420
-
421
- }
422
-
423
- CoreCustomizerMultilingual::init();
424
-
425
- if ( class_exists( 'WP_Customize_Setting' ) ) {
426
- /**
427
- * A class that extends WP_Customize_Setting so we can access
428
- * the protected updated method when importing options.
429
- *
430
- * @since 0.3
431
- */
432
- final class Customizermultilingialoption extends WP_Customize_Setting { // @phpcs:ignore
433
-
434
-
435
- /**
436
- * Import an option value for this setting.
437
- *
438
- * @since 0.3
439
- *
440
- * @param mixed $value The option value.
441
- *
442
- * @return void
443
- */
444
- public function import( $value ) {
445
- $this->update( $value );
446
- }
447
- }
448
- }
 
 
 
 
1
+ <?php
2
+
3
+ // phpcs:ignoreFile
4
+ /**
5
+ * If Polylang is active:
6
+ * - save and retrieve customizer setting per language.
7
+ * - on front-page, set options and theme mod for the selected language.
8
+ *
9
+ * Inspired by https://github.com/fastlinemedia/customizer-export-import
10
+ *
11
+ * @package JupiterX\Framework\API\Customizer
12
+ */
13
+
14
+ if ( ! is_multilingual_customizer() ) {
15
+ return;
16
+ }
17
+
18
+ if ( ! function_exists( 'pll_current_language' ) && ! class_exists( 'SitePress' ) ) {
19
+ return;
20
+ }
21
+
22
+ /**
23
+ * Functionality for multilingual customizer.
24
+ *
25
+ * @since 1.0.0
26
+ *
27
+ * @package JupiterX\Framework\API\Customizer
28
+ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
29
+ */
30
+ class CoreCustomizerMultilingual {
31
+
32
+ public static function init() {
33
+ $self = new self();
34
+
35
+ // Disable detect browser language, will return default language instead.
36
+ add_filter( 'pll_preferred_language', '__return_false' );
37
+
38
+ add_action( 'customize_controls_enqueue_scripts', [ __CLASS__, 'add_lang_to_customizer_previewer' ], 9 );
39
+ add_action( 'wp_before_admin_bar_render', [ __CLASS__, 'on_wp_before_admin_bar_render' ], 100 );
40
+ add_action( 'admin_menu', [ __CLASS__, 'on_admin_menu' ], 100 );
41
+ add_action( 'after_setup_theme', [ __CLASS__, 'remove_filters' ], 5 );
42
+
43
+ $theme_stylesheet_slug = get_option( 'stylesheet' );
44
+ $option_types = [ 'blogname', 'blogdescription', 'site_icon' ];
45
+
46
+ if ( ! ( defined('DOING_AJAX') && DOING_AJAX && isset( $_POST['action'] ) && in_array( $_POST['action'], [ 'jupiterx_cp_cleanup_mods', 'abb_install_template_procedure' ], true ) ) ) {
47
+ // Get theme mod options.
48
+ add_filter( 'option_theme_mods_' . $theme_stylesheet_slug, [ $self, 'on_option_theme_mods_get' ], 10, 1 );
49
+ // Update theme mod options.
50
+ add_filter( 'pre_update_option_theme_mods_' . $theme_stylesheet_slug, [ $self, 'on_option_theme_mods_update' ], 10, 2 );
51
+ }
52
+
53
+ foreach ( $option_types as $option_type ) {
54
+ add_filter( 'pre_option_' . $option_type, [ $self, 'on_wp_option_get' ], 10, 3 ); // get_option hook.
55
+ add_filter( 'pre_update_option_' . $option_type, [ $self, 'on_wp_option_update' ], 10, 3 ); // update_option hook.
56
+ }
57
+
58
+ return $self;
59
+ }
60
+
61
+ /**
62
+ * Remove bloginfo update filters. As we save options per language in this class, we don't need WPML functionality.
63
+ *
64
+ * @since 1.0.0
65
+ *
66
+ * @return void
67
+ */
68
+ public static function remove_filters() {
69
+ global $WPML_String_Translation; // @phpcs:ignore
70
+ remove_filter( 'pre_update_option_blogname', [ $WPML_String_Translation, 'pre_update_option_blogname' ], 5 ); // @phpcs:ignore
71
+ remove_filter( 'pre_update_option_blogdescription', [ $WPML_String_Translation, 'pre_update_option_blogdescription' ], 5 ); // @phpcs:ignore
72
+ }
73
+
74
+ /**
75
+ * Get current language.
76
+ *
77
+ * @since 1.0.0
78
+ *
79
+ * @return string|bool $language|false Current language or false when none of Polylang & WPML are active.
80
+ */
81
+ public static function get_language() {
82
+ if ( function_exists( 'pll_current_language' ) ) {
83
+ $language = pll_current_language();
84
+
85
+ if ( ! $language ) {
86
+ $language = pll_default_language();
87
+ }
88
+
89
+ return $language;
90
+ }
91
+
92
+ if ( class_exists( 'SitePress' ) && defined( 'ICL_LANGUAGE_CODE' ) ) {
93
+ return ICL_LANGUAGE_CODE;
94
+ }
95
+
96
+ return false;
97
+ }
98
+
99
+ /**
100
+ * Get a list of active languages with extra parameters like name and slug.
101
+ *
102
+ * @since 1.0.0
103
+ *
104
+ * @return array|bool $languages|false List of active languages or false when none of Polylang & WPML are active.
105
+ */
106
+ public static function get_languages_list() {
107
+ if ( function_exists( 'pll_current_language' ) ) {
108
+ return get_option( '_transient_pll_languages_list' );
109
+ }
110
+
111
+ if ( class_exists( 'SitePress' ) && defined( 'ICL_LANGUAGE_CODE' ) ) {
112
+ $list = icl_get_languages( 'skip_missing=1' );
113
+ $languages = [];
114
+
115
+ foreach ( $list as $language ) {
116
+ $temp = [];
117
+ $temp['name'] = $language['native_name'];
118
+ $temp['slug'] = $language['code'];
119
+ $languages[] = $temp;
120
+ }
121
+
122
+ return $languages;
123
+ }
124
+
125
+ return false;
126
+ }
127
+
128
+ /**
129
+ * Get a proper option key per plugin.
130
+ *
131
+ * @since 1.0.0
132
+ *
133
+ * @return string|bool Option key or false when none of Polylang & WPML are active.
134
+ */
135
+ public static function get_option_key() {
136
+ if ( function_exists( 'pll_current_language' ) ) {
137
+ return '_customizer_polylang_settings_';
138
+ }
139
+
140
+ if ( class_exists( 'SitePress' ) && defined( 'ICL_LANGUAGE_CODE' ) ) {
141
+ return '_customizer_wpml_settings_';
142
+ }
143
+
144
+ return false;
145
+ }
146
+
147
+ /**
148
+ * Get home URL of current language.
149
+ *
150
+ * @param string $language current language.
151
+ *
152
+ * @since 1.0.0
153
+ *
154
+ * @return string|bool Home URL of current language or false when none of Polylang & WPML are active.
155
+ */
156
+ public static function get_home_url( $language ) {
157
+ if ( function_exists( 'pll_current_language' ) ) {
158
+ return pll_home_url( $language );
159
+ }
160
+
161
+ if ( class_exists( 'SitePress' ) ) {
162
+ global $sitepress;
163
+ return $sitepress->language_url( $language );
164
+ }
165
+
166
+ return false;
167
+ }
168
+
169
+ /**
170
+ * Helper to fetch custom customizer db content.
171
+ *
172
+ * @since 1.3.0
173
+ *
174
+ * @return mixed Customizer array or false.
175
+ */
176
+ protected function get_custom_customizer_option() {
177
+ $current_language = self::get_language();
178
+ $theme_slug = get_option( 'template' );
179
+ $option_prefix = str_replace( '-', '_', $theme_slug );
180
+ $option_name = $option_prefix . self::get_option_key() . $current_language;
181
+
182
+ return get_option( $option_name, false );
183
+ }
184
+
185
+ /**
186
+ * Helper to update custom customizer db content.
187
+ *
188
+ * @since 1.3.0
189
+ *
190
+ * @param mixed $data Data to insert.
191
+ *
192
+ * @return bool Success.
193
+ */
194
+ protected function update_custom_customizer_option( $data ) {
195
+ $current_language = self::get_language();
196
+ $theme_slug = get_option( 'template' );
197
+ $option_prefix = str_replace( '-', '_', $theme_slug );
198
+ $option_name = $option_prefix . self::get_option_key() . $current_language;
199
+
200
+ return update_option( $option_name, $data );
201
+ }
202
+
203
+ /**
204
+ * Helper
205
+ *
206
+ * @since 1.3.0
207
+ *
208
+ * @return bool If the current language is the default language.
209
+ */
210
+ protected function current_lang_not_default() {
211
+ if ( class_exists( 'SitePress' ) ) {
212
+ global $sitepress;
213
+ return $sitepress->get_current_language() !== $sitepress->get_default_language();
214
+ }
215
+
216
+ return pll_current_language() !== pll_default_language();
217
+ }
218
+
219
+ /**
220
+ * Check the custom db field on get_option hook to be able to return custom language value.
221
+ * If the current language is default, then return from default wp option
222
+ *
223
+ * @since 1.3.0
224
+ *
225
+ * @param bool $pre_option This is false. If something else is returned wp exits the check in db and uses this value.
226
+ * @param string $option Option name asked for.
227
+ * @param mixed $default Default value, second args when asking for options.
228
+ *
229
+ * @return mixed
230
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
231
+ */
232
+ public function on_wp_option_get( $pre_option, $option, $default ) {
233
+
234
+ // If not the default language, then skip the custom check and wp will the use default options.
235
+ if ( $this->current_lang_not_default() ) {
236
+ $data = $this->get_custom_customizer_option();
237
+
238
+ // Found the custom option. Move on.
239
+ if ( is_array( $data ) && isset( $data['options'] ) && isset( $data['options'][ $option ] ) ) {
240
+ return $data['options'][ $option ];
241
+ }
242
+ }
243
+
244
+ return $default;
245
+ }
246
+
247
+ /**
248
+ * Update the custom db field on get_option hook.
249
+ * If the current language is not default, then return old value to prevent from saving to default wp option.
250
+ *
251
+ * @since 1.3.0
252
+ *
253
+ * @param mixed $value The new, unserialized option value.
254
+ * @param mixed $old_value The old option value.
255
+ * @param string $option Option name.
256
+ *
257
+ * @return mixed
258
+ */
259
+ public function on_wp_option_update( $value, $old_value, $option ) {
260
+ // Fetch custom option db field.
261
+ $data = $this->get_custom_customizer_option();
262
+ $theme_slug = get_option( 'template' );
263
+ // If false, the field hasn't been created yet, so it must be created.
264
+ if ( false === $data ) {
265
+ $data = [
266
+ 'template' => $theme_slug,
267
+ 'mods' => [],
268
+ 'options' => [],
269
+ ];
270
+ }
271
+
272
+ // Make sure the options array exists. We are going to use it soon.
273
+ if ( ! isset( $data['options'] ) ) {
274
+ $data['options'] = [];
275
+ }
276
+
277
+ $data['options'][ $option ] = $value;
278
+
279
+ // Update option value in custom db field. (Not necessary to save for default language since it uses default wp option fields for values when get option).
280
+ $this->update_custom_customizer_option( $data );
281
+
282
+ // If the current language is not the default language, prevent saving to option table by passing the old value back. It will then exit after the filter.
283
+ if ( $this->current_lang_not_default() ) {
284
+ return $old_value;
285
+ }
286
+
287
+ return $value;
288
+ }
289
+
290
+ /**
291
+ * Check the custom db field on get_option customizer field option name hook to be able to return custom language value.
292
+ * Parse arguments with default wp customizer values to make sure all are present in the return.
293
+ *
294
+ * @since 1.3.0
295
+ *
296
+ * @param array $value The customizer settings.
297
+ *
298
+ * @return array
299
+ */
300
+ public function on_option_theme_mods_get( $value ) {
301
+ $data = $this->get_custom_customizer_option();
302
+
303
+ if ( isset( $data['mods'] ) && is_array( $data['mods'] ) && ! empty( $data['mods'] ) ) {
304
+ $value = wp_parse_args( $data['mods'], $value );
305
+ }
306
+
307
+ return $value;
308
+ }
309
+
310
+ /**
311
+ * Update custom customizer option.
312
+ * If the current language is not default, then return old value to prevent from saving to customizer wp option.
313
+ *
314
+ * @since 1.3.0
315
+ *
316
+ * @param mixed $value The new, unserialized option value.
317
+ * @param mixed $old_value The old option value.
318
+ */
319
+ public function on_option_theme_mods_update( $value, $old_value ) {
320
+
321
+ $current_data = $this->get_custom_customizer_option();
322
+ $theme_slug = get_option( 'template' );
323
+
324
+ $data = [
325
+ 'template' => $theme_slug,
326
+ 'mods' => isset( $current_data['mods'] ) ? $current_data['mods'] : [],
327
+ 'options' => isset( $current_data['options'] ) ? $current_data['options'] : [],
328
+ ];
329
+
330
+ if ( is_array( $value ) && ! empty( $value ) ) {
331
+ foreach ( $value as $key => $val ) {
332
+ $data['mods'][ $key ] = $val;
333
+ }
334
+ }
335
+ $this->update_custom_customizer_option( $data );
336
+
337
+ if ( $this->current_lang_not_default() ) {
338
+ return $old_value;
339
+ }
340
+
341
+ return $value;
342
+ }
343
+
344
+ /**
345
+ * If Polylang activated, set the preview url and add select language control
346
+ *
347
+ * @author soderlind
348
+ * @version 1.0.0
349
+ * @link https://gist.github.com/soderlind/1908634f5eb0c1f69428666dd2a291d0
350
+ *
351
+ * @since 1.0.0
352
+ */
353
+ public static function add_lang_to_customizer_previewer() {
354
+ $languages = self::get_languages_list();
355
+
356
+ if ( ! $languages || jupiterx_get( 'kt-woomail-customize' ) ) {
357
+ return;
358
+ }
359
+
360
+ $handle = 'dss-add-lang-to-template';
361
+ $js_path_url = trailingslashit( apply_filters( 'scp_js_path_url', get_stylesheet_directory_uri() . '/js/' ) );
362
+ $src = $js_path_url . 'customizer-multilingual.js';
363
+ $deps = [ 'customize-controls' ];
364
+ wp_enqueue_script( $handle, $src, $deps, JUPITERX_VERSION, true );
365
+ $language = ( empty( $_REQUEST['lang'] ) ) ? self::get_language() : $_REQUEST['lang']; // @phpcs:ignore
366
+
367
+ if ( empty( $language ) ) {
368
+ $language = self::default_language();
369
+ }
370
+
371
+ $url = add_query_arg( 'lang', $language, self::get_home_url( $language ) );
372
+
373
+ wp_add_inline_script(
374
+ $handle,
375
+ sprintf(
376
+ 'JupiterXCustomizerMultilingual.init( %s );', wp_json_encode(
377
+ [
378
+ 'url' => $url,
379
+ 'languages' => $languages,
380
+ 'current_language' => $language,
381
+ 'switcher_text' => __( 'Language:', 'jupiterx-core' ),
382
+ ]
383
+ )
384
+ ), 'after'
385
+ );
386
+ }
387
+
388
+ /**
389
+ * Append lang="contrycode" to the customizer url in the adminbar
390
+ *
391
+ * @since 1.0.0
392
+ *
393
+ * @return void
394
+ */
395
+ public static function on_wp_before_admin_bar_render() {
396
+ global $wp_admin_bar;
397
+ $customize_node = $wp_admin_bar->get_node( 'customize' );
398
+ if ( ! empty( $customize_node ) ) {
399
+ $customize_node->href = add_query_arg( 'lang', self::get_language(), $customize_node->href );
400
+ $wp_admin_bar->add_node( $customize_node );
401
+ }
402
+ }
403
+
404
+ /**
405
+ * Append lang="contrycode" to the customizer url in the Admin->Apperance->Customize menu
406
+ *
407
+ * @since 1.0.0
408
+ *
409
+ * @return void
410
+ */
411
+ public static function on_admin_menu() {
412
+ global $menu, $submenu;
413
+ $parent = 'themes.php';
414
+ if ( ! isset( $submenu[ $parent ] ) ) {
415
+ return;
416
+ }
417
+ foreach ( $submenu[ $parent ] as $k => $d ) {
418
+ if ( 'customize' === $d['1'] ) {
419
+ $submenu[ $parent ][ $k ]['2'] = add_query_arg( 'lang', self::get_language(), $submenu[ $parent ][ $k ]['2'] ); // @phpcs:ignore
420
+ break;
421
+ }
422
+ }
423
+ }
424
+
425
+ }
426
+
427
+ CoreCustomizerMultilingual::init();
428
+
429
+ if ( class_exists( 'WP_Customize_Setting' ) ) {
430
+ /**
431
+ * A class that extends WP_Customize_Setting so we can access
432
+ * the protected updated method when importing options.
433
+ *
434
+ * @since 0.3
435
+ */
436
+ final class Customizermultilingialoption extends WP_Customize_Setting { // @phpcs:ignore
437
+
438
+
439
+ /**
440
+ * Import an option value for this setting.
441
+ *
442
+ * @since 0.3
443
+ *
444
+ * @param mixed $value The option value.
445
+ *
446
+ * @return void
447
+ */
448
+ public function import( $value ) {
449
+ $this->update( $value );
450
+ }
451
+ }
452
+ }
includes/customizer/api/classes/class-status.php CHANGED
@@ -1,64 +1,64 @@
1
- <?php
2
- /**
3
- * This class handles status debug utils for customizer.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Run status debug.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- final class JupiterX_Customizer_Status {
25
-
26
- /**
27
- * Construct the class.
28
- *
29
- * @since 1.0.0
30
- */
31
- public function __construct() {
32
- add_action( 'init', [ $this, 'render_settings_table' ] );
33
- }
34
-
35
- /**
36
- * Construct the class.
37
- *
38
- * @since 1.0.0
39
- */
40
- public function render_settings_table() {
41
- $exclude_type = [ 'jupiterx-divider', 'jupiterx-label', 'jupiterx-child-popup' ];
42
-
43
- ?>
44
- <table class="table">
45
- <thead>
46
- <tr>
47
- <th><?php esc_html_e( 'Customizer Settings Name', 'jupiterx-core' ); ?></th>
48
- <th><?php esc_html_e( 'Control Type', 'jupiterx-core' ); ?></th>
49
- </tr>
50
- </thead>
51
- <tbody>
52
- <?php foreach ( JupiterX_Customizer::$settings as $id => $setting ) : ?>
53
- <?php if ( ! in_array( $setting['type'], $exclude_type, true ) ) : ?>
54
- <tr>
55
- <td><?php echo esc_html( $id ); // @codingStandardsIgnoreLine ?></td>
56
- <td><?php echo esc_html( $setting['type'] ); // @codingStandardsIgnoreLine ?></td>
57
- </tr>
58
- <?php endif; ?>
59
- <?php endforeach; ?>
60
- </tbody>
61
- </table>
62
- <?php
63
- }
64
- }
1
+ <?php
2
+ /**
3
+ * This class handles status debug utils for customizer.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Run status debug.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ final class JupiterX_Customizer_Status {
25
+
26
+ /**
27
+ * Construct the class.
28
+ *
29
+ * @since 1.0.0
30
+ */
31
+ public function __construct() {
32
+ add_action( 'init', [ $this, 'render_settings_table' ] );
33
+ }
34
+
35
+ /**
36
+ * Construct the class.
37
+ *
38
+ * @since 1.0.0
39
+ */
40
+ public function render_settings_table() {
41
+ $exclude_type = [ 'jupiterx-divider', 'jupiterx-label', 'jupiterx-child-popup' ];
42
+
43
+ ?>
44
+ <table class="table">
45
+ <thead>
46
+ <tr>
47
+ <th><?php esc_html_e( 'Customizer Settings Name', 'jupiterx-core' ); ?></th>
48
+ <th><?php esc_html_e( 'Control Type', 'jupiterx-core' ); ?></th>
49
+ </tr>
50
+ </thead>
51
+ <tbody>
52
+ <?php foreach ( JupiterX_Customizer::$settings as $id => $setting ) : ?>
53
+ <?php if ( ! in_array( $setting['type'], $exclude_type, true ) ) : ?>
54
+ <tr>
55
+ <td><?php echo esc_html( $id ); // @codingStandardsIgnoreLine ?></td>
56
+ <td><?php echo esc_html( $setting['type'] ); // @codingStandardsIgnoreLine ?></td>
57
+ </tr>
58
+ <?php endif; ?>
59
+ <?php endforeach; ?>
60
+ </tbody>
61
+ </table>
62
+ <?php
63
+ }
64
+ }
includes/customizer/api/customizer.php CHANGED
@@ -1,295 +1,303 @@
1
- <?php
2
- /**
3
- * This class handles API for customizer.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- if ( ! class_exists( 'JupiterX_Customizer' ) ) {
16
- /**
17
- * Customizer wrapper class.
18
- *
19
- * @since 1.0.0
20
- * @ignore
21
- * @access private
22
- *
23
- * @package JupiterX\Framework\API\Customizer
24
- */
25
- final class JupiterX_Customizer {
26
-
27
- /**
28
- * Registered panels.
29
- *
30
- * @since 1.0.0
31
- *
32
- * @var array
33
- */
34
- public static $panels = [];
35
-
36
- /**
37
- * Registered sections.
38
- *
39
- * @since 1.0.0
40
- *
41
- * @var array
42
- */
43
- public static $sections = [];
44
-
45
- /**
46
- * Registered settings.
47
- *
48
- * @since 1.0.0
49
- *
50
- * @var array
51
- */
52
- public static $settings = [];
53
-
54
- /**
55
- * Configuration ID.
56
- *
57
- * Defined for Kirki.
58
- *
59
- * @since 1.0.0
60
- *
61
- * @var string
62
- */
63
- public static $config_id = 'jupiterx';
64
-
65
- /**
66
- * Section types.
67
- *
68
- * @since 1.0.0
69
- *
70
- * @var array
71
- */
72
- public static $section_types = [
73
- 'kirki-popup' => 'JupiterX_Customizer_Section_Popup',
74
- 'kirki-pane' => 'JupiterX_Customizer_Section_Pane',
75
- 'kirki-jupiterx-link' => 'JupiterX_Customizer_Section_Link',
76
- ];
77
-
78
- /**
79
- * Control types.
80
- *
81
- * @since 1.0.0
82
- *
83
- * @var array
84
- */
85
- public static $control_types = [
86
- 'jupiterx-input' => 'JupiterX_Customizer_Control_Input',
87
- 'jupiterx-text' => 'JupiterX_Customizer_Control_Text',
88
- 'jupiterx-textarea' => 'JupiterX_Customizer_Control_Textarea',
89
- 'jupiterx-select' => 'JupiterX_Customizer_Control_Select',
90
- 'jupiterx-toggle' => 'JupiterX_Customizer_Control_Toggle',
91
- 'jupiterx-choose' => 'JupiterX_Customizer_Control_Choose',
92
- 'jupiterx-multicheck' => 'JupiterX_Customizer_Control_Multicheck',
93
- 'jupiterx-divider' => 'JupiterX_Customizer_Control_Divider',
94
- 'jupiterx-label' => 'JupiterX_Customizer_Control_Label',
95
- 'jupiterx-alert' => 'JupiterX_Customizer_Control_Alert',
96
- 'jupiterx-position' => 'JupiterX_Customizer_Control_Position',
97
- 'jupiterx-color' => 'JupiterX_Customizer_Control_Color',
98
- 'jupiterx-image' => 'JupiterX_Customizer_Control_Image',
99
- 'jupiterx-radio-image' => 'JupiterX_Customizer_Control_Radio_Image',
100
- 'jupiterx-child-popup' => 'JupiterX_Customizer_Control_Child_Popup',
101
- 'jupiterx-popup' => 'JupiterX_Customizer_Control_Popup',
102
- 'jupiterx-box-model' => 'JupiterX_Customizer_Control_Box_Model',
103
- 'jupiterx-fonts' => 'JupiterX_Customizer_Control_Fonts',
104
- 'jupiterx-font' => 'JupiterX_Customizer_Control_Font',
105
- 'jupiterx-exceptions' => 'JupiterX_Customizer_Control_Exceptions',
106
- 'jupiterx-template' => 'JupiterX_Customizer_Control_Template',
107
- 'jupiterx-pro-box' => 'JupiterX_Customizer_Control_PRO_Box',
108
- ];
109
-
110
- /**
111
- * Group control types.
112
- *
113
- * @since 1.0.0
114
- *
115
- * @var array
116
- */
117
- public static $group_control_types = [
118
- 'jupiterx-background' => 'JupiterX_Customizer_Group_Control_Background',
119
- 'jupiterx-box-shadow' => 'JupiterX_Customizer_Group_Control_Box_Shadow',
120
- 'jupiterx-typography' => 'JupiterX_Customizer_Group_Control_Typography',
121
- 'jupiterx-border' => 'JupiterX_Customizer_Group_Control_Border',
122
- ];
123
-
124
- /**
125
- * Responsive devices media query.
126
- *
127
- * @since 1.0.0
128
- *
129
- * @var array
130
- */
131
- public static $responsive_devices = [
132
- 'desktop' => 'global',
133
- 'tablet' => '@media (max-width: 767.98px)',
134
- 'mobile' => '@media (max-width: 575.98px)',
135
- ];
136
-
137
- /**
138
- * Store panel.
139
- *
140
- * @since 1.0.0
141
- *
142
- * @param string $id ID of the panel.
143
- * @param array $args Arguments of the panel.
144
- */
145
- public static function add_panel( $id = '', $args = [] ) {
146
- if ( empty( $id ) ) {
147
- return;
148
- }
149
-
150
- /**
151
- * Run action before section added.
152
- *
153
- * @since 1.3.0
154
- */
155
- do_action( "{$id}_before_panel" );
156
-
157
- // Add panel to stack.
158
- self::$panels[ $id ] = $args;
159
-
160
- /**
161
- * Run action after panel added.
162
- *
163
- * @since 1.3.0
164
- */
165
- do_action( "{$id}_after_panel" );
166
- }
167
-
168
- /**
169
- * Store section.
170
- *
171
- * @since 1.0.0
172
- *
173
- * @param string $id ID of the section.
174
- * @param array $args Arguments of the section.
175
- */
176
- public static function add_section( $id = '', $args = [] ) {
177
- if ( empty( $id ) ) {
178
- return;
179
- }
180
-
181
- /**
182
- * Run action before section added.
183
- *
184
- * @since 1.3.0
185
- */
186
- do_action( "{$id}_before_section" );
187
-
188
- /**
189
- * Add section to stack.
190
- */
191
- self::$sections[ $id ] = array_merge( [ 'priority' => 160 ], $args );
192
-
193
- /**
194
- * Run action after section added.
195
- *
196
- * @since 1.3.0
197
- */
198
- do_action( "{$id}_after_section" );
199
- }
200
-
201
- /**
202
- * Update section.
203
- *
204
- * @since 1.3.0
205
- *
206
- * @param string $id Section ID.
207
- * @param array $args Section arguments.
208
- */
209
- public static function update_section( $id, $args = [] ) {
210
- if ( ! isset( self::$sections[ $id ] ) ) {
211
- return;
212
- }
213
-
214
- $section = self::$sections[ $id ];
215
-
216
- self::$sections[ $id ] = array_merge( $section, $args );
217
- }
218
-
219
- /**
220
- * Store settings.
221
- *
222
- * @since 1.0.0
223
- *
224
- * @param array $args Arguments of the field.
225
- */
226
- public static function add_field( $args = [] ) {
227
- if ( ! isset( $args['type'] ) && ! isset( $args['settings'] ) ) {
228
- return;
229
- }
230
-
231
- /**
232
- * Run action before field added.
233
- *
234
- * @since 1.3.0
235
- */
236
- do_action( "{$args['settings']}_before_field" );
237
-
238
- /**
239
- * Add the field to stack.
240
- */
241
- self::$settings[ $args['settings'] ] = $args;
242
-
243
- /**
244
- * Run action after field added.
245
- *
246
- * @since 1.3.0
247
- */
248
- do_action( "{$args['settings']}_after_field" );
249
- }
250
-
251
- /**
252
- * Add responsive field.
253
- *
254
- * @since 1.0.0
255
- *
256
- * @param array $args Arguments of the field.
257
- */
258
- public static function add_responsive_field( $args = [] ) {
259
- $args['responsive'] = true;
260
-
261
- self::add_field( $args );
262
- }
263
-
264
- /**
265
- * Update field.
266
- *
267
- * @since 1.3.0
268
- *
269
- * @param string $id Field ID.
270
- * @param array $args Field arguments.
271
- */
272
- public static function update_field( $id, $args = [] ) {
273
- if ( ! isset( self::$settings[ $id ] ) ) {
274
- return;
275
- }
276
-
277
- $settings = self::$settings[ $id ];
278
-
279
- self::$settings[ $id ] = array_merge( $settings, $args );
280
- }
281
-
282
- /**
283
- * Remove field.
284
- *
285
- * @since 1.3.0
286
- *
287
- * @param string $id ID of the field.
288
- */
289
- public static function remove_field( $id ) {
290
- if ( isset( self::$settings[ $id ] ) ) {
291
- unset( self::$settings[ $id ] );
292
- }
293
- }
294
- }
295
- }
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This class handles API for customizer.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ if ( ! class_exists( 'JupiterX_Customizer' ) ) {
16
+ /**
17
+ * Customizer wrapper class.
18
+ *
19
+ * @since 1.0.0
20
+ * @ignore
21
+ * @access private
22
+ *
23
+ * @package JupiterX\Framework\API\Customizer
24
+ */
25
+ final class JupiterX_Customizer {
26
+
27
+ /**
28
+ * Registered panels.
29
+ *
30
+ * @since 1.0.0
31
+ *
32
+ * @var array
33
+ */
34
+ public static $panels = [];
35
+
36
+ /**
37
+ * Registered sections.
38
+ *
39
+ * @since 1.0.0
40
+ *
41
+ * @var array
42
+ */
43
+ public static $sections = [];
44
+
45
+ /**
46
+ * Registered settings.
47
+ *
48
+ * @since 1.0.0
49
+ *
50
+ * @var array
51
+ */
52
+ public static $settings = [];
53
+
54
+ /**
55
+ * Configuration ID.
56
+ *
57
+ * Defined for Kirki.
58
+ *
59
+ * @since 1.0.0
60
+ *
61
+ * @var string
62
+ */
63
+ public static $config_id = 'jupiterx';
64
+
65
+ /**
66
+ * Section types.
67
+ *
68
+ * @since 1.0.0
69
+ *
70
+ * @var array
71
+ */
72
+ public static $section_types = [
73
+ 'kirki-popup' => 'JupiterX_Customizer_Section_Popup',
74
+ 'kirki-pane' => 'JupiterX_Customizer_Section_Pane',
75
+ 'kirki-jupiterx-link' => 'JupiterX_Customizer_Section_Link',
76
+ 'kirki-container' => 'JupiterX_Customizer_Section_container',
77
+ ];
78
+
79
+ /**
80
+ * Control types.
81
+ *
82
+ * @since 1.0.0
83
+ *
84
+ * @var array
85
+ */
86
+ public static $control_types = [
87
+ 'jupiterx-input' => 'JupiterX_Customizer_Control_Input',
88
+ 'jupiterx-text' => 'JupiterX_Customizer_Control_Text',
89
+ 'jupiterx-textarea' => 'JupiterX_Customizer_Control_Textarea',
90
+ 'jupiterx-select' => 'JupiterX_Customizer_Control_Select',
91
+ 'jupiterx-toggle' => 'JupiterX_Customizer_Control_Toggle',
92
+ 'jupiterx-choose' => 'JupiterX_Customizer_Control_Choose',
93
+ 'jupiterx-multicheck' => 'JupiterX_Customizer_Control_Multicheck',
94
+ 'jupiterx-divider' => 'JupiterX_Customizer_Control_Divider',
95
+ 'jupiterx-label' => 'JupiterX_Customizer_Control_Label',
96
+ 'jupiterx-alert' => 'JupiterX_Customizer_Control_Alert',
97
+ 'jupiterx-color' => 'JupiterX_Customizer_Control_Color',
98
+ 'jupiterx-image' => 'JupiterX_Customizer_Control_Image',
99
+ 'jupiterx-radio-image' => 'JupiterX_Customizer_Control_Radio_Image',
100
+ 'jupiterx-child-popup' => 'JupiterX_Customizer_Control_Child_Popup',
101
+ 'jupiterx-popup' => 'JupiterX_Customizer_Control_Popup',
102
+ 'jupiterx-box-model' => 'JupiterX_Customizer_Control_Box_Model',
103
+ 'jupiterx-font' => 'JupiterX_Customizer_Control_Font',
104
+ 'jupiterx-exceptions' => 'JupiterX_Customizer_Control_Exceptions',
105
+ 'jupiterx-template' => 'JupiterX_Customizer_Control_Template',
106
+ 'jupiterx-pro-box' => 'JupiterX_Customizer_Control_PRO_Box',
107
+ ];
108
+
109
+ /**
110
+ * Group control types.
111
+ *
112
+ * @since 1.0.0
113
+ *
114
+ * @var array
115
+ */
116
+ public static $group_control_types = [
117
+ 'jupiterx-background' => 'JupiterX_Customizer_Group_Control_Background',
118
+ 'jupiterx-box-shadow' => 'JupiterX_Customizer_Group_Control_Box_Shadow',
119
+ 'jupiterx-typography' => 'JupiterX_Customizer_Group_Control_Typography',
120
+ 'jupiterx-border' => 'JupiterX_Customizer_Group_Control_Border',
121
+ ];
122
+
123
+ /**
124
+ * Responsive devices media query.
125
+ *
126
+ * @since 1.0.0
127
+ *
128
+ * @var array
129
+ */
130
+ public static $responsive_devices = [
131
+ 'desktop' => 'global',
132
+ 'tablet' => '@media (max-width: 767.98px)',
133
+ 'mobile' => '@media (max-width: 575.98px)',
134
+ ];
135
+
136
+ /**
137
+ * Store panel.
138
+ *
139
+ * @since 1.0.0
140
+ *
141
+ * @param string $id ID of the panel.
142
+ * @param array $args Arguments of the panel.
143
+ */
144
+ public static function add_panel( $id = '', $args = [] ) {
145
+ if ( empty( $id ) ) {
146
+ return;
147
+ }
148
+
149
+ /**
150
+ * Run action before section added.
151
+ *
152
+ * @since 1.3.0
153
+ */
154
+ do_action( "{$id}_before_panel" );
155
+
156
+ // Add panel to stack.
157
+ self::$panels[ $id ] = $args;
158
+
159
+ /**
160
+ * Run action after panel added.
161
+ *
162
+ * @since 1.3.0
163
+ */
164
+ do_action( "{$id}_after_panel" );
165
+ }
166
+
167
+ /**
168
+ * Store section.
169
+ *
170
+ * @since 1.0.0
171
+ *
172
+ * @param string $id ID of the section.
173
+ * @param array $args Arguments of the section.
174
+ */
175
+ public static function add_section( $id = '', $args = [] ) {
176
+ if ( empty( $id ) ) {
177
+ return;
178
+ }
179
+
180
+ /**
181
+ * Run action before section added.
182
+ *
183
+ * @since 1.3.0
184
+ */
185
+ do_action( "{$id}_before_section" );
186
+
187
+ /**
188
+ * Add section to stack.
189
+ */
190
+ self::$sections[ $id ] = array_merge( [ 'priority' => 160 ], $args );
191
+
192
+ /**
193
+ * Run action after section added.
194
+ *
195
+ * @since 1.3.0
196
+ */
197
+ do_action( "{$id}_after_section", $id );
198
+ }
199
+
200
+ /**
201
+ * Update section.
202
+ *
203
+ * @since 1.3.0
204
+ *
205
+ * @param string $id Section ID.
206
+ * @param array $args Section arguments.
207
+ */
208
+ public static function update_section( $id, $args = [] ) {
209
+ if ( ! isset( self::$sections[ $id ] ) ) {
210
+ return;
211
+ }
212
+
213
+ $section = self::$sections[ $id ];
214
+
215
+ self::$sections[ $id ] = array_merge( $section, $args );
216
+ }
217
+
218
+ /**
219
+ * Store settings.
220
+ *
221
+ * @since 1.0.0
222
+ *
223
+ * @param array $args Arguments of the field.
224
+ */
225
+ public static function add_field( $args = [] ) {
226
+ if ( ! isset( $args['type'] ) && ! isset( $args['settings'] ) ) {
227
+ return;
228
+ }
229
+
230
+ /**
231
+ * Run action before field added.
232
+ *
233
+ * @since 1.3.0
234
+ */
235
+ do_action( "{$args['settings']}_before_field" );
236
+
237
+ /**
238
+ * Add the field to stack.
239
+ */
240
+ self::$settings[ $args['settings'] ] = $args;
241
+
242
+ /**
243
+ * Run action after field added.
244
+ *
245
+ * @since 1.3.0
246
+ */
247
+ do_action( "{$args['settings']}_after_field" );
248
+ }
249
+
250
+ /**
251
+ * Add responsive field.
252
+ *
253
+ * @since 1.0.0
254
+ *
255
+ * @param array $args Arguments of the field.
256
+ */
257
+ public static function add_responsive_field( $args = [] ) {
258
+ $args['responsive'] = true;
259
+
260
+ self::add_field( $args );
261
+ }
262
+
263
+ /**
264
+ * Update field.
265
+ *
266
+ * @since 1.3.0
267
+ *
268
+ * @param string $id Field ID.
269
+ * @param array $args Field arguments.
270
+ */
271
+ public static function update_field( $id, $args = [] ) {
272
+ if ( ! isset( self::$settings[ $id ] ) ) {
273
+ return;
274
+ }
275
+
276
+ $settings = self::$settings[ $id ];
277
+
278
+ self::$settings[ $id ] = array_merge( $settings, $args );
279
+ }
280
+
281
+ /**
282
+ * Remove field.
283
+ *
284
+ * @since 1.3.0
285
+ *
286
+ * @param string $id ID of the field.
287
+ */
288
+ public static function remove_field( $id ) {
289
+ if ( isset( self::$settings[ $id ] ) ) {
290
+ unset( self::$settings[ $id ] );
291
+ }
292
+ }
293
+
294
+ /**
295
+ * Get all fields.
296
+ *
297
+ * @since 1.19.0
298
+ */
299
+ public static function get_fields() {
300
+ return self::$settings;
301
+ }
302
+ }
303
+ }
includes/customizer/api/includes/base/class-control.php CHANGED
@@ -1,243 +1,269 @@
1
- <?php
2
- /**
3
- * This class is a common class for all the controls.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Control base class.
17
- *
18
- * This is a special section for rendering tabs and child popups controls inside the Popup section.
19
- *
20
- * @since 1.0.0
21
- * @ignore
22
- * @access private
23
- *
24
- * @package JupiterX\Framework\API\Customizer
25
- */
26
- class JupiterX_Customizer_Base_Control extends WP_Customize_Control {
27
-
28
- /**
29
- * Column size of the control.
30
- *
31
- * @since 1.0.0
32
- *
33
- * @var string
34
- */
35
- public $column = '12';
36
-
37
- /**
38
- * Empty label.
39
- *
40
- * @since 1.0.0
41
- *
42
- * @var string
43
- */
44
- public $label_empty = false;
45
-
46
- /**
47
- * Used to automatically generate all CSS output.
48
- *
49
- * @since 1.0.0
50
- *
51
- * @var array
52
- */
53
- public $output = [];
54
-
55
- /**
56
- * Whitelisting the "required" argument.
57
- *
58
- * @since 1.0.0
59
- *
60
- * @var array
61
- */
62
- public $required = [];
63
-
64
- /**
65
- * Attributes for the control wrapper.
66
- *
67
- * @since 1.0.0
68
- *
69
- * @var array
70
- */
71
- public $control_attrs = [];
72
-
73
- /**
74
- * Responsive control.
75
- *
76
- * @since 1.0.0
77
- *
78
- * @var array
79
- */
80
- public $responsive = false;
81
-
82
- /**
83
- * Refresh the parameters passed to the JavaScript via JSON.
84
- *
85
- * @since 1.0.0
86
- */
87
- public function to_json() {
88
- parent::to_json();
89
-
90
- $this->json['default'] = $this->setting->default;
91
-
92
- if ( isset( $this->default ) ) {
93
- $this->json['default'] = $this->default;
94
- }
95
-
96
- // Add this to whitelist `active_callback` from Kirki.
97
- $this->json['required'] = $this->required;
98
-
99
- // Output.
100
- $this->json['output'] = $this->output;
101
-
102
- // Responsive.
103
- $this->json['responsive'] = (bool) $this->responsive;
104
-
105
- // Value.
106
- $this->json['value'] = $this->value();
107
-
108
- // Choices.
109
- $this->json['choices'] = $this->choices;
110
-
111
- // The link.
112
- $this->json['link'] = $this->get_link();
113
-
114
- // The ID.
115
- $this->json['id'] = $this->id;
116
-
117
- // Empty label.
118
- $this->json['labelEmpty'] = $this->label_empty;
119
-
120
- // Input attributes.
121
- $this->json['inputAttrs'] = '';
122
-
123
- foreach ( $this->input_attrs as $attr => $value ) {
124
- $this->json['inputAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
125
- }
126
-
127
- // Control wrapper attributes.
128
- $this->json['controlAttrs'] = '';
129
-
130
- foreach ( $this->control_attrs as $attr => $value ) {
131
- $this->json['controlAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
132
- }
133
- }
134
-
135
- /**
136
- * Renders the control wrapper and calls $this->render_content() for the internals.
137
- *
138
- * @since 1.0.0
139
- */
140
- protected function render() {
141
- $id = 'customize-control-' . str_replace( [ '[', ']' ], [ '-', '' ], $this->id );
142
- $class = sprintf( 'jupiterx-col-%1$s customize-control customize-control-%2$s', $this->column, $this->type );
143
-
144
- if ( $this->responsive ) {
145
- $class .= ' customize-control-responsive';
146
- }
147
-
148
- printf( '<li id="%s" class="%s">', esc_attr( $id ), esc_attr( $class ) );
149
- $this->render_content();
150
- echo '</li>';
151
- }
152
-
153
- /**
154
- * Render the control's content.
155
- *
156
- * Allows the content to be overridden without having to rewrite the wrapper in `$this::render()`.
157
- *
158
- * Supports basic input types `text`, `checkbox`, `textarea`, `radio`, `select` and `dropdown-pages`.
159
- * Additional input types such as `email`, `url`, `number`, `hidden` and `date` are supported implicitly.
160
- *
161
- * Control content can alternately be rendered in JS. See WP_Customize_Control::print_template().
162
- *
163
- * @since 1.0.0
164
- */
165
- protected function render_content() {}
166
-
167
- /**
168
- * An Underscore (JS) template for this control's content (but not its container).
169
- *
170
- * Class variables for this control class are available in the `data` JS object;
171
- * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
172
- *
173
- * @see WP_Customize_Control::print_template()
174
- *
175
- * Preferably not to overwrite this function, use the `control_template` function
176
- * to render the control template. Overwriting this only allows for some special
177
- * occasion or if your control doesn't need to render the label and description.
178
- *
179
- * @since 1.0.0
180
- */
181
- protected function content_template() {
182
- ?>
183
- <# viewport = [ 'global' ] #>
184
- <# if ( data.responsive ) { #>
185
- <#
186
- viewport = [ 'desktop', 'tablet', 'mobile' ]
187
- responsive = {
188
- link: data.link,
189
- id: data.id,
190
- property: ! _.isUndefined( data.property ) ? data.property : '',
191
- value: data.value || {}
192
- }
193
- #>
194
- <div class="jupiterx-responsive-control">
195
- <# } #>
196
- <# if ( data.label ) { #>
197
- <span class="customize-control-title">{{ data.label }}</span>
198
- <# } else if ( data.labelEmpty ) { #>
199
- <span class="customize-control-title">&nbsp;</span>
200
- <# } #>
201
- <# if ( data.description ) { #>
202
- <span class="description customize-control-description">{{ data.description }}</span>
203
- <# } #>
204
- <# _.each( viewport, function ( device ) { #>
205
- <# if ( data.responsive ) { #>
206
- <#
207
- data.link = responsive.link + ' data-setting-viewport-link="' + device + '"'
208
- data.id = responsive.id + '_' + device
209
- data.value = responsive.value[device] || ''
210
- #>
211
- <div class="jupiterx-viewport jupiterx-viewport-{{ device }}">
212
- <# } #>
213
- <?php $this->control_template(); ?>
214
- <# if ( data.responsive ) { #>
215
- </div>
216
- <# } #>
217
- <# } ) #>
218
- <# if ( data.responsive ) { #>
219
- <div class="jupiterx-responsive-switcher">
220
- <div class="jupiterx-responsive-switcher-buttons">
221
- <# _.each( viewport, function ( device ) { #>
222
- <a class="jupiterx-responsive-switcher-button jupiterx-responsive-switcher-{{ device }}" data-device="{{ device }}">
223
- <span class="jupiterx-responsive-switcher-icon">
224
- <img src="<?php echo esc_url( JupiterX_Customizer_Utils::get_assets_url() ); ?>/img/device-{{ device }}.svg">
225
- </span>
226
- </a>
227
- <# } ) #>
228
- </div>
229
- </div>
230
- </div>
231
- <# } #>
232
- <?php
233
- }
234
-
235
- /**
236
- * An Underscore (JS) template for control wrapper.
237
- *
238
- * Use to create the control template.
239
- *
240
- * @since 1.0.0
241
- */
242
- protected function control_template() {}
243
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This class is a common class for all the controls.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Control base class.
17
+ *
18
+ * This is a special section for rendering tabs and child popups controls inside the Popup section.
19
+ *
20
+ * @since 1.0.0
21
+ * @ignore
22
+ * @access private
23
+ *
24
+ * @package JupiterX\Framework\API\Customizer
25
+ */
26
+ class JupiterX_Customizer_Base_Control extends WP_Customize_Control {
27
+
28
+ /**
29
+ * Column size of the control.
30
+ *
31
+ * @since 1.0.0
32
+ *
33
+ * @var string
34
+ */
35
+ public $column = '12';
36
+
37
+ /**
38
+ * Empty label.
39
+ *
40
+ * @since 1.0.0
41
+ *
42
+ * @var string
43
+ */
44
+ public $label_empty = false;
45
+
46
+ /**
47
+ * Used to automatically generate all CSS output.
48
+ *
49
+ * @since 1.0.0
50
+ *
51
+ * @var array
52
+ */
53
+ public $output = [];
54
+
55
+ /**
56
+ * Whitelisting the "required" argument.
57
+ *
58
+ * @since 1.0.0
59
+ *
60
+ * @var array
61
+ */
62
+ public $required = [];
63
+
64
+ /**
65
+ * Attributes for the control wrapper.
66
+ *
67
+ * @since 1.0.0
68
+ *
69
+ * @var array
70
+ */
71
+ public $control_attrs = [];
72
+
73
+ /**
74
+ * Responsive control.
75
+ *
76
+ * @since 1.0.0
77
+ *
78
+ * @var array
79
+ */
80
+ public $responsive = false;
81
+
82
+ /**
83
+ * Jupiter X params.
84
+ *
85
+ * @since 1.17.0
86
+ *
87
+ * @var array
88
+ */
89
+ public $jupiterx = [];
90
+
91
+ public $box = '';
92
+
93
+ public $label_block = '';
94
+
95
+ /**
96
+ * Refresh the parameters passed to the JavaScript via JSON.
97
+ *
98
+ * @since 1.0.0
99
+ */
100
+ public function to_json() {
101
+ parent::to_json();
102
+
103
+ $this->json['default'] = $this->setting->default;
104
+
105
+ if ( isset( $this->default ) ) {
106
+ $this->json['default'] = $this->default;
107
+ }
108
+
109
+ // Add this to whitelist `active_callback` from Kirki.
110
+ $this->json['required'] = $this->required;
111
+
112
+ // Output.
113
+ $this->json['output'] = $this->output;
114
+
115
+ // Responsive.
116
+ $this->json['responsive'] = (bool) $this->responsive;
117
+
118
+ // Value.
119
+ $this->json['value'] = $this->value();
120
+
121
+ // Choices.
122
+ $this->json['choices'] = $this->choices;
123
+
124
+ // The link.
125
+ $this->json['link'] = $this->get_link();
126
+
127
+ // The ID.
128
+ $this->json['id'] = $this->id;
129
+
130
+ // Empty label.
131
+ $this->json['labelEmpty'] = $this->label_empty;
132
+
133
+ // Input attributes.
134
+ $this->json['inputAttrs'] = '';
135
+
136
+ foreach ( $this->input_attrs as $attr => $value ) {
137
+ $this->json['inputAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
138
+ }
139
+
140
+ // Control wrapper attributes.
141
+ $this->json['controlAttrs'] = '';
142
+
143
+ foreach ( $this->control_attrs as $attr => $value ) {
144
+ $this->json['controlAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
145
+ }
146
+
147
+ // Jupiter X.
148
+ $this->json['jupiterx'] = $this->jupiterx;
149
+ $this->json['box'] = $this->box;
150
+ $this->json['label_block'] = $this->label_block;
151
+ }
152
+
153
+ /**
154
+ * Renders the control wrapper and calls $this->render_content() for the internals.
155
+ *
156
+ * @since 1.0.0
157
+ */
158
+ protected function render() {
159
+ $id = 'customize-control-' . str_replace( [ '[', ']' ], [ '-', '' ], $this->id );
160
+ $class = sprintf( 'customize-control customize-control-%2$s', $this->column, $this->type );
161
+ $class .= $this->label_block ? ' control-label-block' : '';
162
+
163
+ if ( $this->responsive ) {
164
+ $class .= ' customize-controls-list customize-control-responsive';
165
+ }
166
+
167
+ if ( 'jupiterx-choose' === $this->type ) {
168
+ $class .= $this->inline ? ' jupiterx-choose-inline' : '';
169
+ }
170
+
171
+ printf( '<li id="%s" class="%s" data-box="%s">', esc_attr( $id ), esc_attr( $class ), esc_attr( $this->box ) . '-' . esc_attr( $this->section ) );
172
+ $this->render_content();
173
+ echo '</li>';
174
+ }
175
+
176
+ /**
177
+ * Render the control's content.
178
+ *
179
+ * Allows the content to be overridden without having to rewrite the wrapper in `$this::render()`.
180
+ *
181
+ * Supports basic input types `text`, `checkbox`, `textarea`, `radio`, `select` and `dropdown-pages`.
182
+ * Additional input types such as `email`, `url`, `number`, `hidden` and `date` are supported implicitly.
183
+ *
184
+ * Control content can alternately be rendered in JS. See WP_Customize_Control::print_template().
185
+ *
186
+ * @since 1.0.0
187
+ */
188
+ protected function render_content() {}
189
+
190
+ /**
191
+ * An Underscore (JS) template for this control's content (but not its container).
192
+ *
193
+ * Class variables for this control class are available in the `data` JS object;
194
+ * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
195
+ *
196
+ * @see WP_Customize_Control::print_template()
197
+ *
198
+ * Preferably not to overwrite this function, use the `control_template` function
199
+ * to render the control template. Overwriting this only allows for some special
200
+ * occasion or if your control doesn't need to render the label and description.
201
+ *
202
+ * @since 1.0.0
203
+ */
204
+ protected function content_template() {
205
+ ?>
206
+ <# viewport = [ 'global' ] #>
207
+ <# if ( data.responsive ) { #>
208
+ <#
209
+ viewport = [ 'desktop', 'tablet', 'mobile' ]
210
+ responsive = {
211
+ link: data.link,
212
+ id: data.id,
213
+ property: ! _.isUndefined( data.property ) ? data.property : '',
214
+ value: data.value || {}
215
+ }
216
+ #>
217
+ <div class="jupiterx-responsive-control">
218
+ <# } #>
219
+ <# if ( data.label ) { #>
220
+ <label for="{{data.id}}" class="customize-control-title">{{ data.label }}</label>
221
+ <# } else if ( data.labelEmpty ) { #>
222
+ <span class="customize-control-title">&nbsp;</span>
223
+ <# } #>
224
+ <# if ( data.description ) { #>
225
+ <span class="description customize-control-description">{{ data.description }}</span>
226
+ <# } #>
227
+ <# _.each( viewport, function ( device ) { #>
228
+ <# if ( data.responsive ) { #>
229
+ <#
230
+ data.link = responsive.link + ' data-setting-viewport-link="' + device + '"'
231
+ data.id = responsive.id + '_' + device
232
+ data.value = responsive.value[device] || ''
233
+ #>
234
+ <div class="jupiterx-viewport jupiterx-viewport-{{ device }}">
235
+ <# } #>
236
+ <?php $this->control_template(); ?>
237
+ <# if ( data.responsive ) { #>
238
+ </div>
239
+ <# } #>
240
+ <# } ) #>
241
+ <# if ( data.responsive ) { #>
242
+ <div class="jupiterx-responsive-switcher">
243
+ <div class="jupiterx-responsive-switcher-buttons">
244
+ <# _.each( viewport, function ( device ) { #>
245
+ <a class="jupiterx-responsive-switcher-button jupiterx-responsive-switcher-{{ device }}" data-device="{{ device }}">
246
+ <span class="jupiterx-responsive-switcher-icon">
247
+ <svg><use xlink:href="<?php echo esc_url( JupiterX_Customizer_Utils::get_assets_url() ); ?>/img/customizer-icons.svg#device-{{ device }}"></use></svg>
248
+ </span>
249
+ <span class="jupiterx-responsive-switcher-label">
250
+ {{ device }}
251
+ </span>
252
+ </a>
253
+ <# } ) #>
254
+ </div>
255
+ </div>
256
+ </div>
257
+ <# } #>
258
+ <?php
259
+ }
260
+
261
+ /**
262
+ * An Underscore (JS) template for control wrapper.
263
+ *
264
+ * Use to create the control template.
265
+ *
266
+ * @since 1.0.0
267
+ */
268
+ protected function control_template() {}
269
+ }
includes/customizer/api/includes/base/class-group-control.php CHANGED
@@ -1,264 +1,264 @@
1
- <?php
2
- /**
3
- * This class is a common class for all the group controls.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Group control base class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Base_Group_Control extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Fields for this control.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $fields = [];
34
-
35
- /**
36
- * Exclude fields for this control.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $exclude = [];
43
-
44
- /**
45
- * Include fields for this control.
46
- *
47
- * @since 1.0.0
48
- *
49
- * @var string
50
- */
51
- public $include = [];
52
-
53
- /**
54
- * Use to add, edit or remove field arguments.
55
- *
56
- * @since 1.0.4
57
- *
58
- * @var array
59
- */
60
- public $filter_fields = [];
61
-
62
- /**
63
- * Refresh the parameters passed to the JavaScript via JSON.
64
- *
65
- * @since 1.0.0
66
- */
67
- public function to_json() {
68
- parent::to_json();
69
-
70
- // Set the fields for this control.
71
- $this->set_fields();
72
-
73
- // Include fields.
74
- $this->include_fields();
75
-
76
- // Exclude fields.
77
- $this->exclude_fields();
78
-
79
- // Filter fields.
80
- $this->filter_fields();
81
-
82
- // Get fields.
83
- $this->json['fields'] = $this->get_fields();
84
- }
85
-
86
- /**
87
- * Set the fields for this control.
88
- *
89
- * @since 1.0.0
90
- */
91
- protected function set_fields() {}
92
-
93
- /**
94
- * Add field.
95
- *
96
- * @since 1.0.0
97
- *
98
- * @param string $property Property name of field.
99
- * @param array $args Field arguments.
100
- */
101
- final protected function add_field( $property, $args ) {
102
- $this->fields[ $property ] = array_merge( $args, [
103
- 'id' => sprintf( '%1$s_%2$s', $this->id, $property ),
104
- 'property' => $property,
105
- 'responsive' => $this->responsive && isset( $args['responsive'] ) ? true : false,
106
- ] );
107
- }
108
-
109
- /**
110
- * Update field.
111
- *
112
- * @since 1.0.0
113
- *
114
- * @param string $id ID of the field.
115
- * @param array $args Arguments of the field.
116
- */
117
- final protected function update_field( $id = '', $args ) {
118
- if ( ! isset( $this->fields[ $id ] ) ) {
119
- return;
120
- }
121
-
122
- $field = array_merge( $this->fields[ $id ], $args );
123
-
124
- $this->fields[ $id ] = $field;
125
- }
126
-
127
- /**
128
- * Get the fields for this control.
129
- *
130
- * @since 1.0.0
131
- */
132
- final protected function get_fields() {
133
- foreach ( $this->fields as $property => $field ) {
134
- if ( ! $field['responsive'] ) {
135
- $this->fields[ $property ]['value'] = $this->get_control_value( $property, $field );
136
- }
137
-
138
- if ( $field['responsive'] ) {
139
- $this->fields[ $property ]['value'] = $this->get_responsive_control_value( $property, $field );
140
- }
141
- }
142
-
143
- return $this->fields;
144
- }
145
-
146
- /**
147
- * Include fields.
148
- *
149
- * @since 1.0.0
150
- */
151
- protected function include_fields() {}
152
-
153
- /**
154
- * Exclude fields.
155
- *
156
- * @since 1.0.0
157
- */
158
- protected function exclude_fields() {
159
- if ( empty( $this->exclude ) ) {
160
- return;
161
- }
162
-
163
- $exclude = $this->exclude;
164
-
165
- $this->fields = array_filter( $this->fields, function( $field ) use ( $exclude ) {
166
- return ! in_array( $field['property'], $exclude, true );
167
- } );
168
- }
169
-
170
- /**
171
- * Filter fields before ppassing to JSON.
172
- *
173
- * @since 1.0.4
174
- */
175
- protected function filter_fields() {
176
- if ( empty( $this->filter_fields ) || ! is_array( $this->filter_fields ) ) {
177
- return;
178
- }
179
-
180
- foreach ( $this->filter_fields as $property => $args ) {
181
- if ( isset( $this->fields[ $property ] ) ) {
182
- $this->fields[ $property ] = array_merge( $this->fields[ $property ], $args );
183
- }
184
- }
185
- }
186
-
187
- /**
188
- * Get the control value.
189
- *
190
- * @since 1.0.0
191
- *
192
- * @param array $property Field property name.
193
- * @param array $field Control field.
194
- *
195
- * @return array Property value.
196
- */
197
- final protected function get_control_value( $property, $field ) {
198
- if ( $this->responsive && isset( $this->json['value']['desktop'][ $property ] ) ) {
199
- return $this->json['value']['desktop'][ $property ];
200
- }
201
-
202
- if ( isset( $this->json['value'][ $property ] ) ) {
203
- return $this->json['value'][ $property ];
204
- }
205
-
206
- if ( isset( $field['default'] ) ) {
207
- return $field['default'];
208
- }
209
-
210
- return null;
211
- }
212
-
213
- /**
214
- * Get the responsive control value.
215
- *
216
- * @since 1.0.0
217
- *
218
- * @param array $property Field property name.
219
- * @param array $field Control field.
220
- *
221
- * @return array Property value.
222
- */
223
- final protected function get_responsive_control_value( $property, $field ) {
224
- $value = [];
225
-
226
- foreach ( JupiterX_Customizer::$responsive_devices as $device => $media_query ) {
227
- if ( isset( $this->json['value'][ $device ][ $property ] ) ) {
228
- $value[ $device ] = $this->json['value'][ $device ][ $property ];
229
- continue;
230
- }
231
-
232
- if ( isset( $field['default'][ $device ] ) ) {
233
- $value[ $device ] = $field['default'][ $device ];
234
- continue;
235
- }
236
- }
237
-
238
- return $value;
239
- }
240
-
241
- /**
242
- * Render the control's static content.
243
- *
244
- * @since 1.0.0
245
- */
246
- final protected function render_content() {
247
- ?>
248
- <?php if ( ! empty( $this->label ) ) : ?>
249
- <span class="customize-control-title"><?php echo wp_kses_post( $this->label ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span>
250
- <?php endif; ?>
251
- <?php if ( ! empty( $this->description ) ) : ?>
252
- <span class="description customize-control-description"><?php echo wp_kses_post( $this->description ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span>
253
- <?php endif; ?>
254
- <ul class="jupiterx-group-controls jupiterx-row"></ul>
255
- <?php
256
- }
257
-
258
- /**
259
- * Don't render a JS template for this.
260
- *
261
- * @since 1.0.0
262
- */
263
- final protected function content_template() {}
264
- }
1
+ <?php
2
+ /**
3
+ * This class is a common class for all the group controls.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Group control base class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Base_Group_Control extends JupiterX_Customizer_Base_Control {
25
+
26
+ /**
27
+ * Fields for this control.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $fields = [];
34
+
35
+ /**
36
+ * Exclude fields for this control.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $exclude = [];
43
+
44
+ /**
45
+ * Include fields for this control.
46
+ *
47
+ * @since 1.0.0
48
+ *
49
+ * @var string
50
+ */
51
+ public $include = [];
52
+
53
+ /**
54
+ * Use to add, edit or remove field arguments.
55
+ *
56
+ * @since 1.0.4
57
+ *
58
+ * @var array
59
+ */
60
+ public $filter_fields = [];
61
+
62
+ /**
63
+ * Refresh the parameters passed to the JavaScript via JSON.
64
+ *
65
+ * @since 1.0.0
66
+ */
67
+ public function to_json() {
68
+ parent::to_json();
69
+
70
+ // Set the fields for this control.
71
+ $this->set_fields();
72
+
73
+ // Include fields.
74
+ $this->include_fields();
75
+
76
+ // Exclude fields.
77
+ $this->exclude_fields();
78
+
79
+ // Filter fields.
80
+ $this->filter_fields();
81
+
82
+ // Get fields.
83
+ $this->json['fields'] = $this->get_fields();
84
+ }
85
+
86
+ /**
87
+ * Set the fields for this control.
88
+ *
89
+ * @since 1.0.0
90
+ */
91
+ protected function set_fields() {}
92
+
93
+ /**
94
+ * Add field.
95
+ *
96
+ * @since 1.0.0
97
+ *
98
+ * @param string $property Property name of field.
99
+ * @param array $args Field arguments.
100
+ */
101
+ final protected function add_field( $property, $args ) {
102
+ $this->fields[ $property ] = array_merge( $args, [
103
+ 'id' => sprintf( '%1$s_%2$s', $this->id, $property ),
104
+ 'property' => $property,
105
+ 'responsive' => $this->responsive && isset( $args['responsive'] ) ? true : false,
106
+ ] );
107
+ }
108
+
109
+ /**
110
+ * Update field.
111
+ *
112
+ * @since 1.0.0
113
+ *
114
+ * @param string $id ID of the field.
115
+ * @param array $args Arguments of the field.
116
+ */
117
+ final protected function update_field( $id, $args ) {
118
+ if ( ! isset( $this->fields[ $id ] ) ) {
119
+ return;
120
+ }
121
+
122
+ $field = array_merge( $this->fields[ $id ], $args );
123
+
124
+ $this->fields[ $id ] = $field;
125
+ }
126
+
127
+ /**
128
+ * Get the fields for this control.
129
+ *
130
+ * @since 1.0.0
131
+ */
132
+ final protected function get_fields() {
133
+ foreach ( $this->fields as $property => $field ) {
134
+ if ( ! $field['responsive'] ) {
135
+ $this->fields[ $property ]['value'] = $this->get_control_value( $property, $field );
136
+ }
137
+
138
+ if ( $field['responsive'] ) {
139
+ $this->fields[ $property ]['value'] = $this->get_responsive_control_value( $property, $field );
140
+ }
141
+ }
142
+
143
+ return $this->fields;
144
+ }
145
+
146
+ /**
147
+ * Include fields.
148
+ *
149
+ * @since 1.0.0
150
+ */
151
+ protected function include_fields() {}
152
+
153
+ /**
154
+ * Exclude fields.
155
+ *
156
+ * @since 1.0.0
157
+ */
158
+ protected function exclude_fields() {
159
+ if ( empty( $this->exclude ) ) {
160
+ return;
161
+ }
162
+
163
+ $exclude = $this->exclude;
164
+
165
+ $this->fields = array_filter( $this->fields, function( $field ) use ( $exclude ) {
166
+ return ! in_array( $field['property'], $exclude, true );
167
+ } );
168
+ }
169
+
170
+ /**
171
+ * Filter fields before ppassing to JSON.
172
+ *
173
+ * @since 1.0.4
174
+ */
175
+ protected function filter_fields() {
176
+ if ( empty( $this->filter_fields ) || ! is_array( $this->filter_fields ) ) {
177
+ return;
178
+ }
179
+
180
+ foreach ( $this->filter_fields as $property => $args ) {
181
+ if ( isset( $this->fields[ $property ] ) ) {
182
+ $this->fields[ $property ] = array_merge( $this->fields[ $property ], $args );
183
+ }
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Get the control value.
189
+ *
190
+ * @since 1.0.0
191
+ *
192
+ * @param array $property Field property name.
193
+ * @param array $field Control field.
194
+ *
195
+ * @return array Property value.
196
+ */
197
+ final protected function get_control_value( $property, $field ) {
198
+ if ( $this->responsive && isset( $this->json['value']['desktop'][ $property ] ) ) {
199
+ return $this->json['value']['desktop'][ $property ];
200
+ }
201
+
202
+ if ( isset( $this->json['value'][ $property ] ) ) {
203
+ return $this->json['value'][ $property ];
204
+ }
205
+
206
+ if ( isset( $field['default'] ) ) {
207
+ return $field['default'];
208
+ }
209
+
210
+ return null;
211
+ }
212
+
213
+ /**
214
+ * Get the responsive control value.
215
+ *
216
+ * @since 1.0.0
217
+ *
218
+ * @param array $property Field property name.
219
+ * @param array $field Control field.
220
+ *
221
+ * @return array Property value.
222
+ */
223
+ final protected function get_responsive_control_value( $property, $field ) {
224
+ $value = [];
225
+
226
+ foreach ( JupiterX_Customizer::$responsive_devices as $device => $media_query ) {
227
+ if ( isset( $this->json['value'][ $device ][ $property ] ) ) {
228
+ $value[ $device ] = $this->json['value'][ $device ][ $property ];
229
+ continue;
230
+ }
231
+
232
+ if ( isset( $field['default'][ $device ] ) ) {
233
+ $value[ $device ] = $field['default'][ $device ];
234
+ continue;
235
+ }
236
+ }
237
+
238
+ return $value;
239
+ }
240
+
241
+ /**
242
+ * Render the control's static content.
243
+ *
244
+ * @since 1.0.0
245
+ */
246
+ final protected function render_content() {
247
+ ?>
248
+ <?php if ( ! empty( $this->label ) ) : ?>
249
+ <span class="customize-control-title"><?php echo wp_kses_post( $this->label ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span>
250
+ <?php endif; ?>
251
+ <?php if ( ! empty( $this->description ) ) : ?>
252
+ <span class="description customize-control-description"><?php echo wp_kses_post( $this->description ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span>
253
+ <?php endif; ?>
254
+ <ul class="jupiterx-group-controls"></ul>
255
+ <?php
256
+ }
257
+
258
+ /**
259
+ * Don't render a JS template for this.
260
+ *
261
+ * @since 1.0.0
262
+ */
263
+ final protected function content_template() {}
264
+ }
includes/customizer/api/includes/base/class-input-group.php CHANGED
@@ -1,103 +1,112 @@
1
- <?php
2
- /**
3
- * Base class for control with input group icon, text and unit.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Base input group class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Base_Input_Group extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Control's input group text.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $text = '';
34
-
35
- /**
36
- * Control's input group icon.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $icon = '';
43
-
44
- /**
45
- * Refresh the parameters passed to the JavaScript via JSON.
46
- *
47
- * @since 1.0.0
48
- */
49
- public function to_json() {
50
- parent::to_json();
51
-
52
- $this->json['text'] = $this->text;
53
- $this->json['icon'] = $this->icon;
54
- }
55
-
56
- /**
57
- * An Underscore (JS) template for control wrapper.
58
- *
59
- * Use to create the control template.
60
- *
61
- * @since 1.0.0
62
- */
63
- protected function control_template() {
64
- ?>
65
- <#
66
- hasText = ! _.isUndefined( data.text ) && ! _.isEmpty( data.text )
67
- hasIcon = ! _.isUndefined( data.icon ) && ! _.isEmpty( data.icon )
68
- controlClass = 'jupiterx-control ' + data.type + '-control'
69
- controlClass += ( hasIcon || hasText ) ? ' jupiterx-input-group' : ''
70
- controlClass += ( hasIcon ) ? ' has-icon' : ''
71
- controlClass += ( hasText ) ? ' has-text' : ''
72
- #>
73
- <div class="{{ controlClass }}" {{{ data.controlAttrs }}}>
74
- <?php
75
- $this->group_prefix_template();
76
- $this->group_field_template();
77
- ?>
78
- </div>
79
- <?php
80
- }
81
-
82
- /**
83
- * An Underscore (JS) template for field prefix.
84
- *
85
- * @since 1.0.0
86
- */
87
- protected function group_prefix_template() {
88
- ?>
89
- <# if ( hasText ) { #>
90
- <span class="jupiterx-input-group-text">{{ data.text }}</span>
91
- <# } else if ( hasIcon ) { #>
92
- <span class="jupiterx-input-group-icon"><img src="<?php echo esc_url( JupiterX_Customizer_Utils::get_assets_url() ); ?>/img/{{ data.icon }}.svg" /></span>
93
- <# } #>
94
- <?php
95
- }
96
-
97
- /**
98
- * An Underscore (JS) template for control field.
99
- *
100
- * @since 1.0.0
101
- */
102
- protected function group_field_template() {}
103
- }
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Base class for control with input group icon, text and unit.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Base input group class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Base_Input_Group extends JupiterX_Customizer_Base_Control {
25
+
26
+ /**
27
+ * Control's input group text.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $text = '';
34
+
35
+ /**
36
+ * Control's input group icon.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $icon = '';
43
+
44
+ /**
45
+ * Controls icon alt.
46
+ *
47
+ * @since 1.20.0
48
+ *
49
+ * @var string
50
+ */
51
+ public $alt = '';
52
+
53
+ /**
54
+ * Refresh the parameters passed to the JavaScript via JSON.
55
+ *
56
+ * @since 1.0.0
57
+ */
58
+ public function to_json() {
59
+ parent::to_json();
60
+
61
+ $this->json['text'] = $this->text;
62
+ $this->json['icon'] = $this->icon;
63
+ $this->json['alt'] = $this->alt;
64
+ }
65
+
66
+ /**
67
+ * An Underscore (JS) template for control wrapper.
68
+ *
69
+ * Use to create the control template.
70
+ *
71
+ * @since 1.0.0
72
+ */
73
+ protected function control_template() {
74
+ ?>
75
+ <#
76
+ hasText = ! _.isUndefined( data.text ) && ! _.isEmpty( data.text )
77
+ hasIcon = ! _.isUndefined( data.icon ) && ! _.isEmpty( data.icon )
78
+ controlClass = 'jupiterx-control ' + data.type + '-control'
79
+ controlClass += ( hasIcon || hasText ) ? ' jupiterx-input-group' : ''
80
+ controlClass += ( data.inline ) ? ' jupiterx-choose-inline' : ''
81
+ controlClass += ( hasIcon ) ? ' has-icon' : ''
82
+ controlClass += ( hasText ) ? ' has-text' : ''
83
+ #>
84
+ <div class="{{ controlClass }}" {{{ data.controlAttrs }}}>
85
+ <?php
86
+ $this->group_prefix_template();
87
+ $this->group_field_template();
88
+ ?>
89
+ </div>
90
+ <?php
91
+ }
92
+
93
+ /**
94
+ * An Underscore (JS) template for field prefix.
95
+ *
96
+ * @since 1.0.0
97
+ */
98
+ protected function group_prefix_template() {
99
+ ?>
100
+ <# if ( hasText ) { #>
101
+ <span class="jupiterx-input-group-text">{{ data.text }}</span>
102
+ <# } #>
103
+ <?php
104
+ }
105
+
106
+ /**
107
+ * An Underscore (JS) template for control field.
108
+ *
109
+ * @since 1.0.0
110
+ */
111
+ protected function group_field_template() {}
112
+ }
includes/customizer/api/includes/class-autoloader.php CHANGED
@@ -1,119 +1,119 @@
1
- <?php
2
- /**
3
- * This class handles customizer function.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- *
9
- * @todo Enhance the Customizer autoloading code.
10
- */
11
-
12
- // Exit if accessed directly.
13
- if ( ! defined( 'ABSPATH' ) ) {
14
- exit;
15
- }
16
-
17
- /**
18
- * Extends WordPress customizer capability.
19
- *
20
- * @since 1.0.0
21
- * @ignore
22
- * @access private
23
- *
24
- * @package JupiterX\Framework\API\Customizer
25
- */
26
- final class JupiterX_Core_Customizer_Autoloader {
27
-
28
- /**
29
- * Directory maps.
30
- *
31
- * @since 1.0.0
32
- *
33
- * @var array
34
- */
35
- public $dir_map = [
36
- 'base' => 'includes/base',
37
- 'control' => 'includes/control',
38
- 'group-control' => 'includes/control/group',
39
- 'output' => 'includes/output',
40
- 'section' => 'includes/section',
41
- 'kirki-extend-base' => 'modules/kirki-extend/base',
42
- 'kirki-extend-output' => 'modules/kirki-extend/output',
43
- 'kirki-extend' => 'modules/kirki-extend',
44
- 'get-variables' => 'modules/compiler',
45
- 'compiler' => 'modules/compiler',
46
- 'post-message' => 'modules/post-message',
47
- 'elementor' => 'modules/elementor',
48
- ];
49
-
50
- /**
51
- * Construct the class.
52
- *
53
- * @since 1.0.0
54
- */
55
- public function __construct() {
56
- spl_autoload_register( [ $this, 'autoload' ] );
57
- }
58
-
59
- /**
60
- * Customizer autoload function.
61
- *
62
- * @since 1.0.0
63
- *
64
- * @param string $class_name The class name from spl_autoload_register.
65
- */
66
- public function autoload( $class_name ) {
67
- if ( class_exists( $class_name ) || 0 !== stripos( $class_name, 'JupiterX_Customizer_' ) ) {
68
- return;
69
- }
70
-
71
- // Assumed file name.
72
- $file_name = strtolower( str_replace( [ 'JupiterX_Customizer_', '_' ], [ '', '-' ], $class_name ) );
73
-
74
- // Get path attributes.
75
- $path = $this->get_path( $file_name );
76
-
77
- // Create full path.
78
- $full_path = sprintf( '%1$s/%2$s', $path['dir'], $path['name'] );
79
-
80
- if ( file_exists( $full_path ) ) {
81
- include_once $full_path;
82
- }
83
- }
84
-
85
- /**
86
- * Get the file.
87
- *
88
- * @since 1.0.0
89
- *
90
- * @param string $file_name Assumed file name.
91
- *
92
- * @return array Path attributes.
93
- */
94
- public function get_path( $file_name ) {
95
- $path = [
96
- 'dir' => 'includes',
97
- 'name' => $file_name,
98
- ];
99
-
100
- // Change dir and file name if found in directory map.
101
- foreach ( $this->dir_map as $key => $dir ) {
102
- if ( 0 === stripos( $file_name, $key ) ) {
103
- $path = [
104
- 'dir' => $dir,
105
- 'name' => str_replace( $key . '-', '', $file_name ),
106
- ];
107
- break;
108
- }
109
- }
110
-
111
- return [
112
- 'dir' => wp_normalize_path( JUPITERX_CORE_CUSTOMIZER_PATH . $path['dir'] ),
113
- 'name' => sprintf( 'class-%1$s.php', $path['name'] ),
114
- ];
115
- }
116
- }
117
-
118
- // Initialize autoloader.
119
- new JupiterX_Core_Customizer_Autoloader();
1
+ <?php
2
+ /**
3
+ * This class handles customizer function.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ *
9
+ * @todo Enhance the Customizer autoloading code.
10
+ */
11
+
12
+ // Exit if accessed directly.
13
+ if ( ! defined( 'ABSPATH' ) ) {
14
+ exit;
15
+ }
16
+
17
+ /**
18
+ * Extends WordPress customizer capability.
19
+ *
20
+ * @since 1.0.0
21
+ * @ignore
22
+ * @access private
23
+ *
24
+ * @package JupiterX\Framework\API\Customizer
25
+ */
26
+ final class JupiterX_Core_Customizer_Autoloader {
27
+
28
+ /**
29
+ * Directory maps.
30
+ *
31
+ * @since 1.0.0
32
+ *
33
+ * @var array
34
+ */
35
+ public $dir_map = [
36
+ 'base' => 'includes/base',
37
+ 'control' => 'includes/control',
38
+ 'group-control' => 'includes/control/group',
39
+ 'output' => 'includes/output',
40
+ 'section' => 'includes/section',
41
+ 'kirki-extend-base' => 'modules/kirki-extend/base',
42
+ 'kirki-extend-output' => 'modules/kirki-extend/output',
43
+ 'kirki-extend' => 'modules/kirki-extend',
44
+ 'get-variables' => 'modules/compiler',
45
+ 'compiler' => 'modules/compiler',
46
+ 'post-message' => 'modules/post-message',
47
+ 'elementor' => 'modules/elementor',
48
+ ];
49
+
50
+ /**
51
+ * Construct the class.
52
+ *
53
+ * @since 1.0.0
54
+ */
55
+ public function __construct() {
56
+ spl_autoload_register( [ $this, 'autoload' ] );
57
+ }
58
+
59
+ /**
60
+ * Customizer autoload function.
61
+ *
62
+ * @since 1.0.0
63
+ *
64
+ * @param string $class_name The class name from spl_autoload_register.
65
+ */
66
+ public function autoload( $class_name ) {
67
+ if ( class_exists( $class_name ) || 0 !== stripos( $class_name, 'JupiterX_Customizer_' ) ) {
68
+ return;
69
+ }
70
+
71
+ // Assumed file name.
72
+ $file_name = strtolower( str_replace( [ 'JupiterX_Customizer_', '_' ], [ '', '-' ], $class_name ) );
73
+
74
+ // Get path attributes.
75
+ $path = $this->get_path( $file_name );
76
+
77
+ // Create full path.
78
+ $full_path = sprintf( '%1$s/%2$s', $path['dir'], $path['name'] );
79
+
80
+ if ( file_exists( $full_path ) ) {
81
+ include_once $full_path;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Get the file.
87
+ *
88
+ * @since 1.0.0
89
+ *
90
+ * @param string $file_name Assumed file name.
91
+ *
92
+ * @return array Path attributes.
93
+ */
94
+ public function get_path( $file_name ) {
95
+ $path = [
96
+ 'dir' => 'includes',
97
+ 'name' => $file_name,
98
+ ];
99
+
100
+ // Change dir and file name if found in directory map.
101
+ foreach ( $this->dir_map as $key => $dir ) {
102
+ if ( 0 === stripos( $file_name, $key ) ) {
103
+ $path = [
104
+ 'dir' => $dir,
105
+ 'name' => str_replace( $key . '-', '', $file_name ),
106
+ ];
107
+ break;
108
+ }
109
+ }
110
+
111
+ return [
112
+ 'dir' => wp_normalize_path( JUPITERX_CORE_CUSTOMIZER_PATH . $path['dir'] ),
113
+ 'name' => sprintf( 'class-%1$s.php', $path['name'] ),
114
+ ];
115
+ }
116
+ }
117
+
118
+ // Initialize autoloader.
119
+ new JupiterX_Core_Customizer_Autoloader();
includes/customizer/api/includes/class-templates.php CHANGED
@@ -1,184 +1,84 @@
1
- <?php
2
- /**
3
- * This class handles printing custom templates in Customizer preview.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Print custom templates.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- final class JupiterX_Core_Customizer_Templates {
25
-
26
- /**
27
- * Construct the class.
28
- *
29
- * @since 1.0.0
30
- */
31
- public function __construct() {
32
- add_action( 'customize_controls_print_footer_scripts', [ $this, 'render_templates' ], 0 );
33
- }
34
-
35
- /**
36
- * Print templates in Customizer page.
37
- *
38
- * @since 1.0.0
39
- * @SuppressWarnings(PHPMD.ElseExpression)
40
- */
41
- public function render_templates() {
42
- ?>
43
- <script type="text/html" id="tmpl-customize-jupiterx-popup-content">
44
- <div id="customize-jupiterx-popup-content" class="jupiterx-popup">
45
- <div id="customize-jupiterx-popup-controls" class="jupiterx-popup-container"></div>
46
- </div>
47
- </script>
48
-
49
- <script type="text/html" id="tmpl-customize-jupiterx-popup-child">
50
- <div class="jupiterx-popup-child">
51
- <div class="jupiterx-child-popup active">
52
- <# if ( data.title ) { #>
53
- <div class="jupiterx-child-popup-header">
54
- <h3 class="jupiterx-child-popup-title">{{{ data.title }}}</h3>
55
- <div class="jupiterx-child-popup-header-buttons">
56
- <button class="jupiterx-child-popup-button jupiterx-child-popup-close">
57
- <span class="dashicons dashicons-no"></span>
58
- <span class="screen-reader-text"><?php esc_html_e( 'Close', 'jupiterx-core' ); ?></span>
59
- </button>
60
- </div>
61
- </div>
62
- <# } #>
63
- <div class="jupiterx-child-popup-content"></div>
64
- </div>
65
- </div>
66
- </script>
67
-
68
- <script type="text/html" id="tmpl-customize-jupiterx-fonts-control-preview">
69
- <div class="jupiterx-fonts-control-preview" data-font-family="{{ data.name }}">
70
- <span class="jupiterx-fonts-control-preview-family">{{{ data.name }}}</span>
71
- <h3 class="jupiterx-fonts-control-preview-sample" style="font-family: {{ data.value || data.name }};"><?php esc_html_e( 'The spectate before us was indeed sublime.', 'jupiterx-core' ); ?></h3>
72
- <span class="jupiterx-fonts-control-preview-subsets">{{ data.subsets ? data.subsets.join(', ') : ''}}</span>
73
- <button class="jupiterx-fonts-control-preview-remove">
74
- <img src="<?php echo esc_url( JupiterX_Customizer_Utils::get_assets_url() ); ?>/img/x-white.svg" />
75
- <span class="screen-reader-text"><?php esc_html_e( 'Remove', 'jupiterx-core' ); ?></span>
76
- </button>
77
- </div>
78
- </script>
79
-
80
- <script type="text/html" id="tmpl-customize-jupiterx-fonts-control-selector">
81
- <div class="jupiterx-fonts-control-popup jupiterx-popup-child">
82
- <div class="jupiterx-child-popup active">
83
- <div class="jupiterx-child-popup-content">
84
- <div class="jupiterx-fonts-control-selector">
85
- <div class="jupiterx-fonts-control-selector-preview">
86
- <h3 class="jupiterx-fonts-control-selector-sample"><?php esc_html_e( 'The spectate before us was indeed sublime.', 'jupiterx-core' ); ?></h3>
87
- </div>
88
- <span class="customize-control-title"><?php esc_html_e( 'Select a Font Family', 'jupiterx-core' ); ?></span>
89
- <div class="jupiterx-fonts-control-selector-group">
90
- <div class="jupiterx-fonts-control-selector-families">
91
- <div class="jupiterx-control jupiterx-select-control">
92
- <select class="jupiterx-select-control-field">
93
- <# _.each( data.fontFamilies, function( props, name ) { #>
94
- <# type = props.type || props #>
95
- <# value = props.value || name #>
96
- <option data-type="{{ type }}" value="{{ value }}">{{{ name }}}</option>
97
- <# } ); #>
98
- </select>
99
- </div>
100
- </div>
101
- <div class="jupiterx-fonts-control-selector-filters">
102
- <div class="jupiterx-control jupiterx-select-control">
103
- <select class="jupiterx-select-control-field">
104
- <option value=""><?php esc_html_e( 'All Fonts', 'jupiterx-core' ); ?></option>
105
- <# _.each( data.fontTypes, function( fontName, fontType ) { #>
106
- <# disabled = fontName.indexOf('jupiterx-pro-badge') != -1 ? 'disabled' : '' #>
107
- <option value="{{ fontType }}" {{ disabled }}><span>{{ fontName }}</span></option>
108
- <# } ); #>
109
- </select>
110
- </div>
111
- </div>
112
- </div>
113
- <div class="jupiterx-fonts-control-selector-subsets">
114
- <div class="jupiterx-control jupiterx-multicheck-control">
115
- <div class="jupiterx-multicheck-control-items">
116
- <# _.each( data.subsets, function (value, key) { #>
117
- <div class="jupiterx-multicheck-control-item">
118
- <input
119
- id="jupiterx_fonts_subset_{{value}}"
120
- class="jupiterx-multicheck-control-checkbox"
121
- type="checkbox"
122
- value="{{value}}">
123
- <label
124
- class="jupiterx-multicheck-control-label"
125
- for="jupiterx_fonts_subset_{{value}}">
126
- <span class="jupiterx-multicheck-control-box"></span> {{key}}
127
- </label>
128
- </div>
129
- <# }) #>
130
- </div>
131
- </div>
132
- </div>
133
- <div class="jupiterx-fonts-control-selector-buttons">
134
- <button class="jupiterx-fonts-control-selector-cancel jupiterx-button jupiterx-button-danger">
135
- <img src="<?php echo esc_url( JupiterX_Customizer_Utils::get_icon_url( 'x' ) ); ?>">
136
- <span class="screen-reader-text"><?php esc_html_e( 'Cancel', 'jupiterx-core' ); ?></span>
137
- </button>
138
- <button class="jupiterx-fonts-control-selector-submit jupiterx-button">
139
- <img src="<?php echo esc_url( JupiterX_Customizer_Utils::get_icon_url( 'check' ) ); ?>">
140
- <span class="screen-reader-text"><?php esc_html_e( 'Submit', 'jupiterx-core' ); ?></span>
141
- </button>
142
- </div>
143
- </div>
144
- </div>
145
- </div>
146
- </div>
147
- </script>
148
-
149
- <script type="text/html" id="tmpl-customize-jupiterx-exceptions-control-group">
150
- <div class="jupiterx-exceptions-control-group">
151
- <h3>{{{ data.text }}}</h3>
152
- <button class="jupiterx-exceptions-control-remove jupiterx-button jupiterx-button-outline jupiterx-button-danger jupiterx-button-small" data-id="{{ data.id }}"><?php esc_html_e( 'Remove', 'jupiterx-core' ); ?></button>
153
- <ul class="jupiterx-row jupiterx-group-controls"></ul>
154
- </div>
155
- </script>
156
-
157
- <script type="text/html" id="tmpl-customize-jupiterx-pro-preview-lightbox">
158
- <div class="jupiterx-pro-preview">
159
- <div class="jupiterx-pro-preview-header">
160
- <a class="jupiterx-pro-preview-back" href="#"><span class="jupiterx-icon-arrow-left-solid"></span> <?php esc_html_e( 'Back', 'jupiterx-core' ); ?></a>
161
- <?php if ( jupiterx_is_premium() ) : ?>
162
- <span>
163
- <span class="jupiterx-pro-preview-modal-description"><?php esc_html_e( 'Activate Jupiter X to unlock this feature', 'jupiterx-core' ); ?></span>
164
- <a href="<?php echo esc_attr( jupiterx_upgrade_link( 'customizer' ) ); ?>" class="jupiterx-pro-preview-upgrade jupiterx-upgrade-modal-trigger" target="_blank"><?php esc_html_e( 'Activate Now', 'jupiterx-core' ); ?></a>
165
- </span>
166
- <?php else : ?>
167
- <a class="jupiterx-pro-preview-upgrade" href="<?php echo esc_attr( jupiterx_upgrade_link( 'customizer' ) ); ?>" target="_blank"><?php esc_html_e( 'Upgrade to Jupiter X Pro', 'jupiterx-core' ); ?></a>
168
- <?php endif; ?>
169
- </div>
170
- <div class="jupiterx-pro-preview-content">
171
- <div class="jupiterx-pro-preview-container">
172
- <# if ( data.preview ) { #>
173
- <img class="jupiterx-pro-preview-image" src="{{ data.preview }}" />
174
- <# } #>
175
- </div>
176
- </div>
177
- </div>
178
- </script>
179
- <?php
180
- }
181
- }
182
-
183
- // Initialize.
184
- new JupiterX_Core_Customizer_Templates();
1
+ <?php
2
+ /**
3
+ * This class handles printing custom templates in Customizer preview.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Print custom templates.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ final class JupiterX_Core_Customizer_Templates {
25
+
26
+ /**
27
+ * Construct the class.
28
+ *
29
+ * @since 1.0.0
30
+ */
31
+ public function __construct() {
32
+ add_action( 'customize_controls_print_footer_scripts', [ $this, 'render_templates' ], 0 );
33
+ }
34
+
35
+ /**
36
+ * Print templates in Customizer page.
37
+ *
38
+ * @since 1.0.0
39
+ * @SuppressWarnings(PHPMD.ElseExpression)
40
+ */
41
+ public function render_templates() {
42
+ ?>
43
+ <script type="text/html" id="tmpl-customize-jupiterx-popup-content">
44
+ <div id="customize-jupiterx-popup-content" class="jupiterx-popup">
45
+ <div id="customize-jupiterx-popup-controls" class="jupiterx-popup-container"></div>
46
+ </div>
47
+ </script>
48
+
49
+ <script type="text/html" id="tmpl-customize-jupiterx-exceptions-control-group">
50
+ <div class="jupiterx-exceptions-control-group">
51
+ <h3>{{{ data.text }}}</h3>
52
+ <button class="jupiterx-exceptions-control-remove jupiterx-button jupiterx-button-outline jupiterx-button-danger jupiterx-button-small" data-id="{{ data.id }}"><?php esc_html_e( 'Remove', 'jupiterx-core' ); ?></button>
53
+ <ul class="jupiterx-row jupiterx-group-controls"></ul>
54
+ </div>
55
+ </script>
56
+
57
+ <script type="text/html" id="tmpl-customize-jupiterx-pro-preview-lightbox">
58
+ <div class="jupiterx-pro-preview">
59
+ <div class="jupiterx-pro-preview-header">
60
+ <a class="jupiterx-pro-preview-back" href="#"><span class="jupiterx-icon-arrow-left-solid"></span> <?php esc_html_e( 'Back', 'jupiterx-core' ); ?></a>
61
+ <?php if ( jupiterx_is_premium() ) : ?>
62
+ <span>
63
+ <span class="jupiterx-pro-preview-modal-description"><?php esc_html_e( 'Activate Jupiter X to unlock this feature', 'jupiterx-core' ); ?></span>
64
+ <a href="<?php echo esc_attr( jupiterx_upgrade_link( 'customizer' ) ); ?>" class="jupiterx-pro-preview-upgrade jupiterx-upgrade-modal-trigger" target="_blank"><?php esc_html_e( 'Activate Now', 'jupiterx-core' ); ?></a>
65
+ </span>
66
+ <?php else : ?>
67
+ <a class="jupiterx-pro-preview-upgrade" href="<?php echo esc_attr( jupiterx_upgrade_link( 'customizer' ) ); ?>" target="_blank"><?php esc_html_e( 'Upgrade to Jupiter X Pro', 'jupiterx-core' ); ?></a>
68
+ <?php endif; ?>
69
+ </div>
70
+ <div class="jupiterx-pro-preview-content">
71
+ <div class="jupiterx-pro-preview-container">
72
+ <# if ( data.preview ) { #>
73
+ <img class="jupiterx-pro-preview-image" src="{{ data.preview }}" />
74
+ <# } #>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </script>
79
+ <?php
80
+ }
81
+ }
82
+
83
+ // Initialize.
84
+ new JupiterX_Core_Customizer_Templates();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/customizer/api/includes/control/class-alert.php CHANGED
@@ -1,89 +1,91 @@
1
- <?php
2
- /**
3
- * Handles alert control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Alert control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Alert extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-alert';
34
-
35
- /**
36
- * Control's alert type.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $jupiterx_type = 'warning';
43
-
44
- /**
45
- * Control's alert url.
46
- *
47
- * @since 1.0.0
48
- *
49
- * @var string
50
- */
51
- public $jupiterx_url = '#';
52
-
53
- /**
54
- * Refresh the parameters passed to the JavaScript via JSON.
55
- *
56
- * @since 1.0.0
57
- */
58
- public function to_json() {
59
- parent::to_json();
60
-
61
- $this->json['jupiterxType'] = $this->jupiterx_type;
62
- $this->json['jupiterxUrl'] = $this->jupiterx_url;
63
- }
64
-
65
- /**
66
- * An Underscore (JS) template for this control's content (but not its container).
67
- *
68
- * Class variables for this control class are available in the `data` JS object;
69
- * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
70
- *
71
- * @see WP_Customize_Control::print_template()
72
- *
73
- * @since 1.0.0
74
- */
75
- protected function content_template() {
76
- ?>
77
- <# type = data.jupiterxType ? 'jupiterx-alert-control-' + data.jupiterxType : '' #>
78
- <div class="jupiterx-control jupiterx-alert-control {{ type }}" role="alert">
79
- <span class="dashicons dashicons-warning"></span>
80
- <span class="jupiterx-alert-control-text">
81
- {{ data.label }}
82
- <a class="jupiterx-alert-control-link" href="{{ data.jupiterxUrl }}" target="_blank">
83
- <?php esc_html_e( 'Learn more', 'jupiterx-core' ); ?>
84
- </a>
85
- </span>
86
- </div>
87
- <?php
88
- }
89
- }
 
 
1
+ <?php
2
+ /**
3
+ * Handles alert control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Alert control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Alert extends JupiterX_Customizer_Base_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-alert';
34
+
35
+ /**
36
+ * Control's alert type.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $jupiterx_type = 'warning';
43
+
44
+ /**
45
+ * Control's alert url.
46
+ *
47
+ * @since 1.0.0
48
+ *
49
+ * @var string
50
+ */
51
+ public $jupiterx_url = '';
52
+
53
+ /**
54
+ * Refresh the parameters passed to the JavaScript via JSON.
55
+ *
56
+ * @since 1.0.0
57
+ */
58
+ public function to_json() {
59
+ parent::to_json();
60
+
61
+ $this->json['jupiterxType'] = $this->jupiterx_type;
62
+ $this->json['jupiterxUrl'] = $this->jupiterx_url;
63
+ }
64
+
65
+ /**
66
+ * An Underscore (JS) template for this control's content (but not its container).
67
+ *
68
+ * Class variables for this control class are available in the `data` JS object;
69
+ * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
70
+ *
71
+ * @see WP_Customize_Control::print_template()
72
+ *
73
+ * @since 1.0.0
74
+ */
75
+ protected function content_template() {
76
+ ?>
77
+ <# type = data.jupiterxType ? 'jupiterx-alert-control-' + data.jupiterxType : '' #>
78
+ <div class="jupiterx-control jupiterx-alert-control {{ type }}" role="alert">
79
+ <span class="dashicons dashicons-warning"></span>
80
+ <span class="jupiterx-alert-control-text">
81
+ {{{ data.label }}}
82
+ <# if ( data.jupiterxUrl ) { #>
83
+ <a class="jupiterx-alert-control-link" href="{{ data.jupiterxUrl }}" target="_blank">
84
+ <?php esc_html_e( 'Learn more', 'jupiterx-core' ); ?>
85
+ </a>
86
+ <# } #>
87
+ </span>
88
+ </div>
89
+ <?php
90
+ }
91
+ }
includes/customizer/api/includes/control/class-box-model.php CHANGED
@@ -1,210 +1,211 @@
1
- <?php
2
- /**
3
- * Handles box model control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Box model control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Box_Model extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-box-model';
34
-
35
- /**
36
- * Control's exclude box model parts.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $exclude = [];
43
-
44
- /**
45
- * Control's disable box model parts.
46
- *
47
- * @since 1.0.0
48
- *
49
- * @var string
50
- */
51
- public $disable = [];
52
-
53
- /**
54
- * Control's unit.
55
- *
56
- * @since 1.0.0
57
- *
58
- * @var string
59
- */
60
- public $units = [
61
- 'px',
62
- '%',
63
- 'em',
64
- 'rem',
65
- ];
66
-
67
- /**
68
- * Control's global default unitt.
69
- *
70
- * @since 1.0.0
71
- *
72
- * @var string
73
- */
74
- public static $default_unit = 'rem';
75
-
76
- /**
77
- * Refresh the parameters passed to the JavaScript via JSON.
78
- *
79
- * @since 1.0.0
80
- */
81
- public function to_json() {
82
- parent::to_json();
83
-
84
- $this->json['exclude'] = $this->exclude;
85
- $this->json['disable'] = $this->disable;
86
- $this->json['units'] = $this->units;
87
- $this->json['default_unit'] = self::$default_unit;
88
- }
89
-
90
- /**
91
- * An Underscore (JS) template for control wrapper.
92
- *
93
- * Use to create the control template.
94
- *
95
- * @since 1.0.0
96
- */
97
- protected function control_template() {
98
-
99
- ?>
100
- <#
101
- sides = [
102
- 'top',
103
- 'right',
104
- 'bottom',
105
- 'left'
106
- ]
107
- properties = {
108
- margin: {
109
- title: '<?php esc_attr_e( 'Margin', 'jupiterx-core' ); ?>',
110
- min: -1000,
111
- },
112
- padding: {
113
- title: '<?php esc_attr_e( 'Padding', 'jupiterx-core' ); ?>',
114
- min: 0,
115
- }
116
- }
117
- units = data.units
118
- selectorClass = _.isArray( units ) && 1 === _.size( units ) ? 'disabled' : ''
119
- #>
120
- <div class="jupiterx-control jupiterx-box-model-control">
121
- <# _.each( properties, function ( props, key ) { #>
122
- <# if ( data.exclude.indexOf( key ) < 0 ) {
123
- unitValue = _.isEmpty( data.value[ key + '_unit' ] ) ? data.default_unit : data.value[ key + '_unit' ]
124
- step = 'px' == unitValue ? 1 : .1 #>
125
- <div class="jupiterx-box-model-control-property jupiterx-box-model-control-property-{{ key }}">
126
- <span class="jupiterx-box-model-control-title">{{ props.title }}</span>
127
- <# _.each( sides, function ( side ) {
128
- propertyName = key + '_' + side
129
- value = ! _.isUndefined( data.value[ propertyName ] ) ? data.value[ propertyName ] : ''
130
- disable = _.indexOf( data.disable, propertyName.replace( '_', '-' ) ) !== -1 ? 'disabled' : '' #>
131
- <input class="jupiterx-box-model-control-input jupiterx-box-model-control-{{ side }}" min="{{ props.min }}" {{{ data.inputAttrs }}} type="text" value="{{ value }}" {{ disable }} step="{{ step }}" placeholder="-" {{{ data.link }}} data-setting-property-link="{{ propertyName }}" />
132
- <# } ) #>
133
- <# } #>
134
- <# } ) #>
135
- <# _.each( properties, function ( title, key ) { #>
136
- <# if ( data.exclude.indexOf( key ) < 0 ) { #>
137
- </div>
138
- <# } #>
139
- <# } ) #>
140
- <div class="jupiterx-unit-selector-wrapper">
141
- <# _.each( properties, function ( props, key ) { #>
142
- <# if ( data.exclude.indexOf( key ) < 0 ) { #>
143
- <# unitValue = _.isEmpty( data.value[ key + '_unit' ] ) ? data.default_unit : data.value[ key + '_unit' ] #>
144
- <div class="jupiterx-control-units-container">
145
- <input type="hidden" value="{{ unitValue }}" {{{ data.link }}} data-setting-property-link="{{key + '_unit'}}" />
146
- <span class="jupiterx-unit-selector-label">{{key}}</span>
147
- <ul class="jupiterx-control-unit-selector" data-inputs=".jupiterx-box-model-control-property-{{ key }} > input">
148
- <li class="jupiterx-control-unit selected-unit {{ selectorClass }}">{{ unitValue }}</li>
149
- <# _.each( units, function ( unit ) { #>
150
- <li class="jupiterx-control-unit">{{ unit }}</li>
151
- <# } ) #>
152
- </ul>
153
- </div>
154
- <# } #>
155
- <# } ) #>
156
- </div>
157
- </div>
158
- <?php
159
- }
160
-
161
- /**
162
- * Format CSS value from theme mod array value.
163
- *
164
- * @since 1.0.0
165
- *
166
- * @param array $value The field's value.
167
- * @param array $args The field's arguments.
168
- *
169
- * @return array The formatted properties.
170
- */
171
- public static function format_properties( $value, $args ) {
172
- $args = array_merge( [ 'exclude' => [] ], $args );
173
-
174
- $positions = [ 'top', 'right', 'bottom', 'left' ];
175
-
176
- $vars = [];
177
-
178
- if ( ! in_array( 'margin', $args['exclude'], true ) ) {
179
- $margin_unit = isset( $value['margin_unit'] ) ? $value['margin_unit'] : self::$default_unit;
180
-
181
- foreach ( $positions as $position ) {
182
- // Accepts non-numeric value such as 'auto'.
183
- if ( array_key_exists( 'margin_' . $position, $value ) ) {
184
- $property_value = $value[ 'margin_' . $position ];
185
- $unit = is_numeric( $property_value ) && 0 !== $property_value ? $margin_unit : '';
186
- $position = jupiterx_get_direction( $position );
187
-
188
- $vars[ 'margin-' . $position ] = $property_value . $unit;
189
- }
190
- }
191
- }
192
-
193
- if ( ! in_array( 'padding', $args['exclude'], true ) ) {
194
- $padding_unit = isset( $value['padding_unit'] ) ? $value['padding_unit'] : self::$default_unit;
195
-
196
- foreach ( $positions as $position ) {
197
- // Does not accept any value that is not numeric.
198
- if ( array_key_exists( 'padding_' . $position, $value ) && is_numeric( $value[ 'padding_' . $position ] ) ) {
199
- $property_value = $value[ 'padding_' . $position ];
200
- $unit = 0 !== $property_value ? $padding_unit : '';
201
- $position = jupiterx_get_direction( $position );
202
-
203
- $vars[ 'padding-' . $position ] = $property_value . $unit;
204
- }
205
- }
206
- }
207
-
208
- return $vars;
209
- }
210
- }
 
1
+ <?php
2
+ /**
3
+ * Handles box model control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Box model control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Box_Model extends JupiterX_Customizer_Base_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-box-model';
34
+
35
+ /**
36
+ * Control's exclude box model parts.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $exclude = [];
43
+
44
+ /**
45
+ * Control's disable box model parts.
46
+ *
47
+ * @since 1.0.0
48
+ *
49
+ * @var string
50
+ */
51
+ public $disable = [];
52
+
53
+ /**
54
+ * Control's unit.
55
+ *
56
+ * @since 1.0.0
57
+ *
58
+ * @var string
59
+ */
60
+ public $units = [
61
+ 'px',
62
+ '%',
63
+ 'em',
64
+ 'rem',
65
+ ];
66
+
67
+ /**
68
+ * Control's global default unitt.
69
+ *
70
+ * @since 1.0.0
71
+ *
72
+ * @var string
73
+ */
74
+ public static $default_unit = 'rem';
75
+
76
+ /**
77
+ * Refresh the parameters passed to the JavaScript via JSON.
78
+ *
79
+ * @since 1.0.0
80
+ */
81
+ public function to_json() {
82
+ parent::to_json();
83
+
84
+ $this->json['exclude'] = $this->exclude;
85
+ $this->json['disable'] = $this->disable;
86
+ $this->json['units'] = $this->units;
87
+ $this->json['default_unit'] = self::$default_unit;
88
+ }
89
+
90
+ /**
91
+ * An Underscore (JS) template for control wrapper.
92
+ *
93
+ * Use to create the control template.
94
+ *
95
+ * @since 1.0.0
96
+ */
97
+ protected function control_template() {
98
+
99
+ ?>
100
+ <#
101
+ sides = [
102
+ 'top',
103
+ 'right',
104
+ 'bottom',
105
+ 'left'
106
+ ]
107
+ properties = {
108
+ margin: {
109
+ title: '<?php esc_attr_e( 'Margin', 'jupiterx-core' ); ?>',
110
+ min: -1000,
111
+ },
112
+ padding: {
113
+ title: '<?php esc_attr_e( 'Padding', 'jupiterx-core' ); ?>',
114
+ min: 0,
115
+ }
116
+ }
117
+ units = data.units
118
+ selectorClass = _.isArray( units ) && 1 === _.size( units ) ? 'disabled' : ''
119
+ #>
120
+ <div class="jupiterx-control jupiterx-box-model-control">
121
+ <# _.each( properties, function ( props, key ) { #>
122
+ <# if ( data.exclude.indexOf( key ) < 0 ) {
123
+ unitValue = _.isEmpty( data.value[ key + '_unit' ] ) ? data.default_unit : data.value[ key + '_unit' ]
124
+ step = 'px' == unitValue ? 1 : .1 #>
125
+ <div class="jupiterx-box-model-head">
126
+ <label class="customize-control-title">{{ props.title }}</label>
127
+ <div class="jupiterx-unit-selector-wrapper">
128
+ <# selectedClass = '' #>
129
+ <# unitValue = _.isEmpty( data.value[ key + '_unit' ] ) ? data.default_unit : data.value[ key + '_unit' ] #>
130
+ <div class="jupiterx-control-units-container">
131
+ <input type="hidden" value="{{ unitValue }}" {{{ data.link }}} data-setting-property-link="{{key + '_unit'}}" />
132
+ <ul class="jupiterx-control-unit-selector" data-inputs=".jupiterx-box-model-control-property-{{ key }} > input">
133
+ <# _.each( units, function ( unit ) { #>
134
+ <# if(unit === unitValue) {
135
+ selectedClass = 'selected-unit'
136
+ } #>
137
+ <li class="jupiterx-control-unit {{ selectedClass }}">{{ unit }}</li>
138
+ <# } ) #>
139
+ </ul>
140
+ </div>
141
+ </div>
142
+ </div>
143
+ <div class="jupiterx-box-model-control-property jupiterx-box-model-control-property-{{ key }}">
144
+ <ul class="jupiterx-box-model-wrapper">
145
+ <# _.each( sides, function ( side ) {
146
+ propertyName = key + '_' + side
147
+ value = ! _.isUndefined( data.value[ propertyName ] ) ? data.value[ propertyName ] : ''
148
+ disable = _.indexOf( data.disable, propertyName.replace( '_', '-' ) ) !== -1 ? 'disabled' : '' #>
149
+ <li>
150
+ <input class="jupiterx-box-model-control-input jupiterx-box-model-control-{{ side }}" min="{{ props.min }}" {{{ data.inputAttrs }}} type="number" value="{{ value }}" {{ disable }} step="{{ step }}" placeholder="-" {{{ data.link }}} data-setting-property-link="{{ propertyName }}" />
151
+ <span class="box-model-label">{{ side }}</span>
152
+ </li>
153
+ <# } ) #>
154
+ </ul>
155
+ </div>
156
+ <# } #>
157
+ <# } ) #>
158
+ </div>
159
+ <?php
160
+ }
161
+
162
+ /**
163
+ * Format CSS value from theme mod array value.
164
+ *
165
+ * @since 1.0.0
166
+ *
167
+ * @param array $value The field's value.
168
+ * @param array $args The field's arguments.
169
+ *
170
+ * @return array The formatted properties.
171
+ */
172
+ public static function format_properties( $value, $args ) {
173
+ $args = array_merge( [ 'exclude' => [] ], $args );
174
+
175
+ $positions = [ 'top', 'right', 'bottom', 'left' ];
176
+
177
+ $vars = [];
178
+
179
+ if ( ! in_array( 'margin', $args['exclude'], true ) ) {
180
+ $margin_unit = isset( $value['margin_unit'] ) ? $value['margin_unit'] : self::$default_unit;
181
+
182
+ foreach ( $positions as $position ) {
183
+ // Accepts non-numeric value such as 'auto'.
184
+ if ( array_key_exists( 'margin_' . $position, $value ) ) {
185
+ $property_value = $value[ 'margin_' . $position ];
186
+ $unit = is_numeric( $property_value ) && 0 !== $property_value ? $margin_unit : '';
187
+ $position = jupiterx_get_direction( $position );
188
+
189
+ $vars[ 'margin-' . $position ] = $property_value . $unit;
190
+ }
191
+ }
192
+ }
193
+
194
+ if ( ! in_array( 'padding', $args['exclude'], true ) ) {
195
+ $padding_unit = isset( $value['padding_unit'] ) ? $value['padding_unit'] : self::$default_unit;
196
+
197
+ foreach ( $positions as $position ) {
198
+ // Does not accept any value that is not numeric.
199
+ if ( array_key_exists( 'padding_' . $position, $value ) && is_numeric( $value[ 'padding_' . $position ] ) ) {
200
+ $property_value = $value[ 'padding_' . $position ];
201
+ $unit = 0 !== $property_value ? $padding_unit : '';
202
+ $position = jupiterx_get_direction( $position );
203
+
204
+ $vars[ 'padding-' . $position ] = $property_value . $unit;
205
+ }
206
+ }
207
+ }
208
+
209
+ return $vars;
210
+ }
211
+ }
includes/customizer/api/includes/control/class-child-popup.php CHANGED
@@ -1,115 +1,114 @@
1
- <?php
2
- /**
3
- * This class handles opening child popup pane.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Open control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Child_Popup extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-child-popup';
34
-
35
- /**
36
- * Control's target section to open child pane.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $target = '';
43
-
44
- /**
45
- * Control's binded items to display from existing setting.
46
- *
47
- * @since 1.0.0
48
- *
49
- * @var string
50
- */
51
- public $bind_items = '';
52
-
53
- /**
54
- * Control's sortable enabler.
55
- *
56
- * @since 1.0.0
57
- *
58
- * @var string
59
- */
60
- public $sortable = false;
61
-
62
- /**
63
- * Refresh the parameters passed to the JavaScript via JSON.
64
- *
65
- * @since 1.0.0
66
- */
67
- public function to_json() {
68
- parent::to_json();
69
-
70
- $this->json['target'] = $this->target;
71
- $this->json['bindItems'] = $this->bind_items;
72
- $this->json['sortable'] = $this->sortable;
73
-
74
- foreach ( $this->choices as $key => $choice ) {
75
- // Transform label.
76
- if ( is_string( $choice ) ) {
77
- $this->json['choices'][ $key ] = [ 'label' => $choice ];
78
- continue;
79
- }
80
- }
81
- }
82
-
83
- /**
84
- * An Underscore (JS) template for this control's content (but not its container).
85
- *
86
- * Class variables for this control class are available in the `data` JS object;
87
- * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
88
- *
89
- * @see WP_Customize_Control::print_template()
90
- *
91
- * @since 1.0.0
92
- */
93
- protected function content_template() {
94
- ?>
95
- <#
96
- choices = _.keys( data.choices )
97
- items = ! _.isEmpty( data.value ) ? _.union( data.value, choices ) : choices
98
- #>
99
- <div class="jupiterx-control jupiterx-child-popup-control">
100
- <div class="jupiterx-child-popup-control-items">
101
- <# _.each( items, function( item ) { #>
102
- <# if ( ! _.isUndefined( data.choices[ item ] ) ) { #>
103
- <li class="jupiterx-child-popup-control-item" data-value="{{ item }}">
104
- <# if ( data.sortable ) { #><span class="jupiterx-child-popup-control-drag"><img src="<?php echo esc_url( JupiterX_Customizer_Utils::get_icon_url( 'drag-drop' ) ); ?>" /></span><# } #>
105
- <span class="jupiterx-child-popup-control-label">{{ data.choices[ item ].label }}</span>
106
- <# if ( data.choices[ item ].pro ) { #><img class="jupiterx-control-pro-badge" src="<?php echo esc_url( jupiterx_get_pro_badge_url() ); ?>" /><# } #>
107
- <button class="jupiterx-button" data-id="{{ item }}"><?php esc_html_e( 'Customize', 'jupiterx-core' ); ?></button>
108
- </li>
109
- <# } #>
110
- <# } ) #>
111
- </div>
112
- </div>
113
- <?php
114
- }
115
- }
1
+ <?php
2
+ /**
3
+ * This class handles opening child popup pane.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Open control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Child_Popup extends JupiterX_Customizer_Base_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-child-popup';
34
+
35
+ /**
36
+ * Control's target section to open child pane.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $target = '';
43
+
44
+ /**
45
+ * Control's binded items to display from existing setting.
46
+ *
47
+ * @since 1.0.0
48
+ *
49
+ * @var string
50
+ */
51
+ public $bind_items = '';
52
+
53
+ /**
54
+ * Control's sortable enabler.
55
+ *
56
+ * @since 1.0.0
57
+ *
58
+ * @var string
59
+ */
60
+ public $sortable = false;
61
+
62
+ /**
63
+ * Refresh the parameters passed to the JavaScript via JSON.
64
+ *
65
+ * @since 1.0.0
66
+ */
67
+ public function to_json() {
68
+ parent::to_json();
69
+
70
+ $this->json['target'] = $this->target;
71
+ $this->json['bindItems'] = $this->bind_items;
72
+ $this->json['sortable'] = $this->sortable;
73
+
74
+ foreach ( $this->choices as $key => $choice ) {
75
+ // Transform label.
76
+ if ( is_string( $choice ) ) {
77
+ $this->json['choices'][ $key ] = [ 'label' => $choice ];
78
+ continue;
79
+ }
80
+ }
81
+ }
82
+
83
+ /**
84
+ * An Underscore (JS) template for this control's content (but not its container).
85
+ *
86
+ * Class variables for this control class are available in the `data` JS object;
87
+ * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
88
+ *
89
+ * @see WP_Customize_Control::print_template()
90
+ *
91
+ * @since 1.0.0
92
+ */
93
+ protected function content_template() {
94
+ ?>
95
+ <#
96
+ choices = _.keys( data.choices )
97
+ items = ! _.isEmpty( data.value ) ? _.union( data.value, choices ) : choices
98
+ #>
99
+ <div class="jupiterx-control jupiterx-child-popup-control">
100
+ <div class="jupiterx-child-popup-control-items">
101
+ <# _.each( items, function( item ) { #>
102
+ <# if ( ! _.isUndefined( data.choices[ item ] ) ) { #>
103
+ <li class="jupiterx-child-popup-control-item" data-value="{{ item }}">
104
+ <# if ( data.sortable ) { #><span class="jupiterx-child-popup-control-drag"><svg><use xlink:href="<?php echo esc_url( jupiterx_core_get_pro_badge() ); ?>/img/customizer-icons.svg#drag-drop"></use></svg></span><# } #>
105
+ <span class="jupiterx-child-popup-control-label">{{ data.choices[ item ].label }}</span>
106
+ <# if ( data.choices[ item ].pro ) { #><svg class="jupiterx-control-pro-badge"><use xlink:href="<?php echo esc_url( jupiterx_core_get_pro_badge() ); ?>"><use></svg><# } #>
107
+ </li>
108
+ <# } #>
109
+ <# } ) #>
110
+ </div>
111
+ </div>
112
+ <?php
113
+ }
114
+ }
 
includes/customizer/api/includes/control/class-choose.php CHANGED
@@ -1,124 +1,135 @@
1
- <?php
2
- /**
3
- * Handles choose control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Choose control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Choose extends JupiterX_Customizer_Base_Input_Group {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-choose';
34
-
35
- /**
36
- * Choose multiple.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var boolean
41
- */
42
- public $multiple = false;
43
-
44
- /**
45
- * Refresh the parameters passed to the JavaScript via JSON.
46
- *
47
- * @since 1.0.0
48
- */
49
- public function to_json() {
50
- parent::to_json();
51
-
52
- foreach ( $this->choices as $key => $choice ) {
53
- // Transform label.
54
- if ( is_string( $choice ) ) {
55
- $this->json['choices'][ $key ] = [ 'label' => $choice ];
56
- continue;
57
- }
58
-
59
- // Icon choices.
60
- if ( isset( $choice['icon'] ) && ! empty( $choice['icon'] ) ) {
61
- $this->json['choices'][ $key ]['icon'] = $choice['icon'];
62
- }
63
- }
64
-
65
- $this->json['multiple'] = $this->multiple;
66
- }
67
-
68
- /**
69
- * An Underscore (JS) template for control field.
70
- *
71
- * @since 1.0.0
72
- */
73
- protected function group_field_template() {
74
- ?>
75
- <div class="jupiterx-control jupiterx-choose-control">
76
- <div class="jupiterx-choose-control-buttons">
77
- <# if ( data.multiple ) { #>
78
- <# _.each( data.choices, function( choice, key ) { #>
79
- <input class="jupiterx-choose-control-radio" {{{ data.inputAttrs }}} type="checkbox" value="{{ key }}" name="{{ data.id }}" id="{{ data.id }}-{{ key }}" <# if ( data.value.indexOf( key ) >= 0 ) { #> checked <# } #>>
80
- <label class="jupiterx-choose-control-button jupiterx-choose-control-{{ ( choice.icon ) ? 'icon' : 'label' }}" for="{{ data.id }}-{{ key }}">
81
- <# if ( choice.icon ) { #><img src="<?php echo esc_url( JupiterX_Customizer_Utils::get_assets_url() ); ?>/img/{{ choice.icon }}.svg" /><# } else { #>{{ choice.label }}<# } #>
82
- <# if ( choice.pro ) { #><img class="jupiterx-control-pro-badge" src="<?php echo esc_url( jupiterx_get_pro_badge_url() ); ?>" /><# } #>
83
- </label>
84
- <# } ) #>
85
- <input type="hidden" value="{{ data.value }}" {{{ data.link }}}>
86
- <# } else { #>
87
- <# _.each( data.choices, function( choice, key ) { #>
88
- <input class="jupiterx-choose-control-radio" {{{ data.inputAttrs }}} type="radio" value="{{ key }}" name="{{ data.id }}" id="{{ data.id }}-{{ key }}" {{{ data.link }}} <# if ( key === data.value ) { #> checked <# } #>>
89
- <label class="jupiterx-choose-control-button jupiterx-choose-control-{{ ( choice.icon ) ? 'icon' : 'label' }}" for="{{ data.id }}-{{ key }}">
90
- <# if ( choice.icon ) { #><img src="<?php echo esc_url( JupiterX_Customizer_Utils::get_assets_url() ); ?>/img/{{ choice.icon }}.svg" /><# } else { #>{{ choice.label }}<# } #>
91
- <# if ( choice.pro ) { #><img class="jupiterx-control-pro-badge" src="<?php echo esc_url( jupiterx_get_pro_badge_url() ); ?>" /><# } #>
92
- </label>
93
- <# } ) #>
94
- <# } #>
95
- </div>
96
- </div>
97
- <?php
98
- }
99
-
100
- /**
101
- * Format CSS value from theme mod array value.
102
- *
103
- * @since 1.0.0
104
- *
105
- * @param array $value The field's value.
106
- *
107
- * @return array The formatted value.
108
- */
109
- public static function format_value( $value ) {
110
- if ( ! is_rtl() ) {
111
- return $value;
112
- }
113
-
114
- if ( 'right' === $value ) {
115
- return 'left';
116
- }
117
-
118
- if ( 'left' === $value ) {
119
- return 'right';
120
- }
121
-
122
- return $value;
123
- }
124
- }
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles choose control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Choose control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Choose extends JupiterX_Customizer_Base_Input_Group {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-choose';
34
+
35
+ /**
36
+ * Choose multiple.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var boolean
41
+ */
42
+ public $multiple = false;
43
+
44
+ /**
45
+ * Choose inline style.
46
+ *
47
+ * @since 2.0.0
48
+ *
49
+ * @var boolean
50
+ */
51
+ public $inline = false;
52
+
53
+ /**
54
+ * Refresh the parameters passed to the JavaScript via JSON.
55
+ *
56
+ * @since 1.0.0
57
+ */
58
+ public function to_json() {
59
+ parent::to_json();
60
+
61
+ foreach ( $this->choices as $key => $choice ) {
62
+ // Transform label.
63
+ if ( is_string( $choice ) ) {
64
+ $this->json['choices'][ $key ] = [ 'label' => $choice ];
65
+ continue;
66
+ }
67
+
68
+ // Icon choices.
69
+ if ( isset( $choice['icon'] ) && ! empty( $choice['icon'] ) ) {
70
+ $this->json['choices'][ $key ]['icon'] = $choice['icon'];
71
+ }
72
+ }
73
+
74
+ $this->json['multiple'] = $this->multiple;
75
+ $this->json['inline'] = $this->inline;
76
+ }
77
+
78
+ /**
79
+ * An Underscore (JS) template for control field.
80
+ *
81
+ * @since 1.0.0
82
+ */
83
+ protected function group_field_template() {
84
+ ?>
85
+ <#
86
+ inlineClass = data.inline ? 'jupiterx-choose-control-buttons-inline' : '';
87
+ #>
88
+ <div class="jupiterx-choose-control-buttons {{ inlineClass }}">
89
+ <# if ( data.multiple ) { #>
90
+ <# _.each( data.choices, function( choice, key ) { #>
91
+ <input class="jupiterx-choose-control-radio" {{{ data.inputAttrs }}} type="checkbox" value="{{ key }}" name="{{ data.id }}" id="{{ data.id }}-{{ key }}" <# if ( data.value.indexOf( key ) >= 0 ) { #> checked <# } #>>
92
+ <label class="jupiterx-choose-control-button jupiterx-choose-control-{{ ( choice.icon ) ? 'icon' : 'label' }}" for="{{ data.id }}-{{ key }}">
93
+ <# if ( choice.icon ) { #><svg><use xlink:href="<?php echo esc_url( JupiterX_Customizer_Utils::get_assets_url() ); ?>/img/customizer-icons.svg#{{ choice.icon }}"></use></svg><# } else { #>{{ choice.label }}<# } #>
94
+ <# if ( choice.pro ) { #><svg class="jupiterx-control-pro-badge"><use xlink:href="<?php echo esc_url( jupiterx_core_get_pro_badge() ); ?>"><use></svg><# } #>
95
+ </label>
96
+ <# } ) #>
97
+ <input type="hidden" value="{{ data.value }}" {{{ data.link }}}>
98
+ <# } else { #>
99
+ <# _.each( data.choices, function( choice, key ) { #>
100
+ <input class="jupiterx-choose-control-radio" {{{ data.inputAttrs }}} type="radio" value="{{ key }}" name="{{ data.id }}" id="{{ data.id }}-{{ key }}" {{{ data.link }}} <# if ( key === data.value ) { #> checked <# } #>>
101
+ <label class="jupiterx-choose-control-button jupiterx-choose-control-{{ ( choice.icon ) ? 'icon' : 'label' }}" for="{{ data.id }}-{{ key }}">
102
+ <# if ( choice.icon ) { #><svg><use xlink:href="<?php echo esc_url( JupiterX_Customizer_Utils::get_assets_url() ); ?>/img/customizer-icons.svg#{{ choice.icon }}"></use></svg><# } else { #>{{ choice.label }}<# } #>
103
+ <# if ( choice.pro ) { #><svg class="jupiterx-control-pro-badge"><use xlink:href="<?php echo esc_url( jupiterx_core_get_pro_badge() ); ?>"><use></svg><# } #>
104
+ </label>
105
+ <# } ) #>
106
+ <# } #>
107
+ </div>
108
+ <?php
109
+ }
110
+
111
+ /**
112
+ * Format CSS value from theme mod array value.
113
+ *
114
+ * @since 1.0.0
115
+ *
116
+ * @param array $value The field's value.
117
+ *
118
+ * @return array The formatted value.
119
+ */
120
+ public static function format_value( $value ) {
121
+ if ( ! is_rtl() ) {
122
+ return $value;
123
+ }
124
+
125
+ if ( 'right' === $value ) {
126
+ return 'left';
127
+ }
128
+
129
+ if ( 'left' === $value ) {
130
+ return 'right';
131
+ }
132
+
133
+ return $value;
134
+ }
135
+ }
includes/customizer/api/includes/control/class-color.php CHANGED
@@ -1,66 +1,66 @@
1
- <?php
2
- /**
3
- * Handles color control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Color control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Color extends JupiterX_Customizer_Base_Input_Group {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-color';
34
-
35
- /**
36
- * Show opacity option.
37
- *
38
- * @since 1.0.4
39
- *
40
- * @var boolean
41
- */
42
- public $opacity = true;
43
-
44
- /**
45
- * Refresh the parameters passed to the JavaScript via JSON.
46
- *
47
- * @since 1.0.0
48
- */
49
- public function to_json() {
50
- parent::to_json();
51
-
52
- // Use RGBA.
53
- $this->json['opacity'] = $this->opacity;
54
- }
55
-
56
- /**
57
- * An Underscore (JS) template for control field.
58
- *
59
- * @since 1.0.0
60
- */
61
- protected function group_field_template() {
62
- ?>
63
- <input class="jupiterx-color-control-field" {{{ data.inputAttrs }}} type="text" id="{{ data.id }}" value="{{ data.value }}" {{{ data.link }}} />
64
- <?php
65
- }
66
- }
1
+ <?php
2
+ /**
3
+ * Handles color control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Color control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Color extends JupiterX_Customizer_Base_Input_Group {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-color';
34
+
35
+ /**
36
+ * Show opacity option.
37
+ *
38
+ * @since 1.0.4
39
+ *
40
+ * @var boolean
41
+ */
42
+ public $opacity = true;
43
+
44
+ /**
45
+ * Refresh the parameters passed to the JavaScript via JSON.
46
+ *
47
+ * @since 1.0.0
48
+ */
49
+ public function to_json() {
50
+ parent::to_json();
51
+
52
+ // Use RGBA.
53
+ $this->json['opacity'] = $this->opacity;
54
+ }
55
+
56
+ /**
57
+ * An Underscore (JS) template for control field.
58
+ *
59
+ * @since 1.0.0
60
+ */
61
+ protected function group_field_template() {
62
+ ?>
63
+ <input class="jupiterx-color-control-field" {{{ data.inputAttrs }}} type="text" id="{{ data.id }}" value="{{ data.value }}" {{{ data.link }}} />
64
+ <?php
65
+ }
66
+ }
includes/customizer/api/includes/control/class-divider.php CHANGED
@@ -1,71 +1,71 @@
1
- <?php
2
- /**
3
- * Handles divider control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Divider control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Divider extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-divider';
34
-
35
- /**
36
- * Divider type.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $divider_type = '';
43
-
44
- /**
45
- * Refresh the parameters passed to the JavaScript via JSON.
46
- *
47
- * @since 1.0.0
48
- */
49
- public function to_json() {
50
- parent::to_json();
51
-
52
- $this->json['dividerType'] = $this->divider_type;
53
- }
54
-
55
- /**
56
- * An Underscore (JS) template for this control's content (but not its container).
57
- *
58
- * Class variables for this control class are available in the `data` JS object;
59
- * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
60
- *
61
- * @see WP_Customize_Control::print_template()
62
- *
63
- * @since 1.0.0
64
- */
65
- protected function content_template() {
66
- ?>
67
- <# type = data.dividerType ? 'jupiterx-divider-control-' + data.dividerType : '' #>
68
- <div class="jupiterx-control jupiterx-divider-control {{ type }}" {{{ data.controlAttrs }}}></div>
69
- <?php
70
- }
71
- }
1
+ <?php
2
+ /**
3
+ * Handles divider control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Divider control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Divider extends JupiterX_Customizer_Base_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-divider';
34
+
35
+ /**
36
+ * Divider type.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $divider_type = '';
43
+
44
+ /**
45
+ * Refresh the parameters passed to the JavaScript via JSON.
46
+ *
47
+ * @since 1.0.0
48
+ */
49
+ public function to_json() {
50
+ parent::to_json();
51
+
52
+ $this->json['dividerType'] = $this->divider_type;
53
+ }
54
+
55
+ /**
56
+ * An Underscore (JS) template for this control's content (but not its container).
57
+ *
58
+ * Class variables for this control class are available in the `data` JS object;
59
+ * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
60
+ *
61
+ * @see WP_Customize_Control::print_template()
62
+ *
63
+ * @since 1.0.0
64
+ */
65
+ protected function content_template() {
66
+ ?>
67
+ <# type = data.dividerType ? 'jupiterx-divider-control-' + data.dividerType : '' #>
68
+ <div class="jupiterx-control jupiterx-divider-control {{ type }}" {{{ data.controlAttrs }}}></div>
69
+ <?php
70
+ }
71
+ }
includes/customizer/api/includes/control/class-exceptions.php CHANGED
@@ -1,88 +1,86 @@
1
- <?php
2
- /**
3
- * Handles exceptions control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Exceptions control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Exceptions extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Fields for this control.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $fields = [];
34
-
35
- /**
36
- * Control's type.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $type = 'jupiterx-exceptions';
43
-
44
- /**
45
- * Refresh the parameters passed to the JavaScript via JSON.
46
- *
47
- * @since 1.0.0
48
- */
49
- public function to_json() {
50
- parent::to_json();
51
-
52
- // Exceptions fields.
53
- $this->json['fields'] = $this->fields;
54
- }
55
-
56
- /**
57
- * An Underscore (JS) template for this control's content (but not its container).
58
- *
59
- * Class variables for this control class are available in the `data` JS object;
60
- * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
61
- *
62
- * @see WP_Customize_Control::print_template()
63
- *
64
- * @since 1.0.0
65
- */
66
- protected function content_template() {
67
- ?>
68
- <# if ( data.label ) { #>
69
- <span class="customize-control-title">{{ data.label }}</span>
70
- <# } #>
71
- <div class="jupiterx-control jupiterx-exceptions-control">
72
- <div class="jupiterx-exceptions-control-items"></div>
73
- <div class="jupiterx-row">
74
- <div class="jupiterx-col-6">
75
- <div class="jupiterx-control jupiterx-select-control jupiterx-select-control-plain jupiterx-exceptions-control-add">
76
- <button class="jupiterx-button"><img src="<?php echo esc_url( JupiterX_Customizer_Utils::get_icon_url( 'plus-white' ) ); ?>" alt="<?php esc_attr_e( 'Remove image icon', 'jupiterx-core' ); ?>" /> <?php esc_html_e( 'Add New Condition', 'jupiterx-core' ); ?></button>
77
- <select class="jupiterx-select-control-field">
78
- <# _.each( data.fields, function( field, key ) { #>
79
- <option value="{{ key }}">{{{ field.label }}}</option>
80
- <# } ); #>
81
- </select>
82
- </div>
83
- </div>
84
- </div>
85
- </div>
86
- <?php
87
- }
88
- }
1
+ <?php
2
+ /**
3
+ * Handles exceptions control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Exceptions control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Exceptions extends JupiterX_Customizer_Base_Control {
25
+
26
+ /**
27
+ * Fields for this control.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $fields = [];
34
+
35
+ /**
36
+ * Control's type.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $type = 'jupiterx-exceptions';
43
+
44
+ /**
45
+ * Refresh the parameters passed to the JavaScript via JSON.
46
+ *
47
+ * @since 1.0.0
48
+ */
49
+ public function to_json() {
50
+ parent::to_json();
51
+
52
+ // Exceptions fields.
53
+ $this->json['fields'] = $this->fields;
54
+ }
55
+
56
+ /**
57
+ * An Underscore (JS) template for this control's content (but not its container).
58
+ *
59
+ * Class variables for this control class are available in the `data` JS object;
60
+ * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
61
+ *
62
+ * @see WP_Customize_Control::print_template()
63
+ *
64
+ * @since 1.0.0
65
+ */
66
+ protected function content_template() {
67
+ ?>
68
+ <# if ( data.label ) { #>
69
+ <span class="customize-control-title">{{ data.label }}</span>
70
+ <# } #>
71
+ <div class="jupiterx-control jupiterx-exceptions-control">
72
+ <div class="jupiterx-exceptions-control-items"></div>
73
+ <div class="jupiterx-row">
74
+ <div class="jupiterx-control jupiterx-select-control jupiterx-select-control-plain jupiterx-exceptions-control-add">
75
+ <button class="jupiterx-button"><i class="eicon-plus-circle" aria-hidden="true"></i> <?php esc_html_e( 'Add New Condition', 'jupiterx-core' ); ?></button>
76
+ <select class="jupiterx-select-control-field">
77
+ <# _.each( data.fields, function( field, key ) { #>
78
+ <option value="{{ key }}">{{{ field.label }}}</option>
79
+ <# } ); #>
80
+ </select>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ <?php
85
+ }
86
+ }
 
 
includes/customizer/api/includes/control/class-font.php CHANGED
@@ -1,74 +1,78 @@
1
- <?php
2
- /**
3
- * Handles select control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Font control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Font extends JupiterX_Customizer_Base_Input_Group {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-font';
34
-
35
- /**
36
- * Control's placeholder.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $placeholder = '';
43
-
44
- /**
45
- * Refresh the parameters passed to the JavaScript via JSON.
46
- *
47
- * @since 1.0.0
48
- */
49
- public function to_json() {
50
- parent::to_json();
51
-
52
- $this->json['placeholder'] = $this->placeholder;
53
- }
54
-
55
- /**
56
- * An Underscore (JS) template for control field.
57
- *
58
- * @since 1.0.0
59
- */
60
- protected function group_field_template() {
61
- ?>
62
- <select class="jupiterx-font-control-field jupiterx-select-field" {{{ data.inputAttrs }}} value="{{ data.value }}" id="{{ data.id }}" {{{ data.link }}}>
63
- <# if ( ! _.isEmpty( data.placeholder ) ) { #>
64
- <option value="" <# if ( _.isEmpty( data.value ) ) { #> selected<# } #>>{{{ data.placeholder }}}</option>
65
- <# } #>
66
- <# _.each( wp.customize.JupiterX.fonts.stack, function( font ) { #>
67
- <# value = font.value || font.name #>
68
- <# selected = ( data.value === value ) #>
69
- <option value="{{ value }}" <# if ( selected ) { #> selected<# } #>>{{{ font.name }}}</option>
70
- <# } ); #>
71
- </select>
72
- <?php
73
- }
74
- }
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles select control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Font control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Font extends JupiterX_Customizer_Base_Input_Group {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-font';
34
+
35
+ /**
36
+ * Control's placeholder.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $placeholder = '';
43
+
44
+ /**
45
+ * Refresh the parameters passed to the JavaScript via JSON.
46
+ *
47
+ * @since 1.0.0
48
+ */
49
+ public function to_json() {
50
+ parent::to_json();
51
+
52
+ $this->json['placeholder'] = $this->placeholder;
53
+ }
54
+
55
+ /**
56
+ * An Underscore (JS) template for control field.
57
+ *
58
+ * @since 1.0.0
59
+ */
60
+ protected function group_field_template() {
61
+ ?>
62
+ <select class="jupiterx-font-control-field jupiterx-select-field" {{{ data.inputAttrs }}} value="{{ data.value }}" id="{{ data.id }}" {{{ data.link }}}>
63
+ <# if ( ! _.isEmpty( data.placeholder ) ) { #>
64
+ <option value="" <# if ( _.isEmpty( data.value ) ) { #> selected<# } #>>{{{ data.placeholder }}}</option>
65
+ <# } #>
66
+ <# _.each( wp.customize.JupiterX.fonts.stack, function( fonts, type ) { #>
67
+ <optgroup label="{{ type }}">
68
+ <# _.each( fonts, function( font ) { #>
69
+ <# value = font.value || font.name #>
70
+ <# selected = ( data.value === value ) #>
71
+ <option data-type="{{ font.type }}" value="{{ value }}" title="{{ font.name }}" <# if ( selected ) { #> selected<# } #>>{{{ font.name }}}</option>
72
+ <# } ); #>
73
+ </optgroup>
74
+ <# } ); #>
75
+ </select>
76
+ <?php
77
+ }
78
+ }
includes/customizer/api/includes/control/class-image.php CHANGED
@@ -1,53 +1,70 @@
1
- <?php
2
- /**
3
- * Handles image control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Image control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Image extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-image';
34
-
35
- /**
36
- * An Underscore (JS) template for control wrapper.
37
- *
38
- * Use to create the control template.
39
- *
40
- * @since 1.0.0
41
- */
42
- protected function control_template() {
43
- ?>
44
- <div class="jupiterx-control jupiterx-image-upload-control {{ data.value ? 'has-image' : '' }}">
45
- <span class="jupiterx-image-upload-control-remove"><img src="<?php echo esc_url( JupiterX_Customizer_Utils::get_icon_url( 'x' ) ); ?>" alt="<?php esc_attr_e( 'Remove image icon', 'jupiterx-core' ); ?>" /></span>
46
- <span class="jupiterx-image-upload-control-icon"><img src="<?php echo esc_url( JupiterX_Customizer_Utils::get_icon_url( 'upload' ) ); ?>" alt="<?php esc_attr_e( 'Upload image icon', 'jupiterx-core' ); ?>" /></span>
47
- <span class="jupiterx-image-upload-control-label"><?php esc_html_e( 'Click to Upload Image', 'jupiterx-core' ); ?></span>
48
- <img class="jupiterx-image-upload-control-preview" src="{{ data.value }}" />
49
- <input type="hidden" value="{{ data.value }}" {{{ data.link }}} />
50
- </div>
51
- <?php
52
- }
53
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles image control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Image control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Image extends JupiterX_Customizer_Base_Control {
25
+ public $template_type = '';
26
+
27
+ /**
28
+ * Control's type.
29
+ *
30
+ * @since 1.0.0
31
+ *
32
+ * @var string
33
+ */
34
+ public $type = 'jupiterx-image';
35
+
36
+ /**
37
+ * Refresh the parameters passed to the JavaScript via JSON.
38
+ *
39
+ * @since 1.0.0
40
+ */
41
+ public function to_json() {
42
+ parent::to_json();
43
+
44
+ $this->json['templateType'] = $this->template_type ? $this->template_type : 'default';
45
+ }
46
+
47
+ /**
48
+ * An Underscore (JS) template for control wrapper.
49
+ *
50
+ * Use to create the control template.
51
+ *
52
+ * @since 1.0.0
53
+ */
54
+ protected function control_template() {
55
+ ?>
56
+ <div class="jupiterx-control jupiterx-image-upload-control {{ data.value ? 'has-image' : '' }} {{ data.templateType !== 'logo' ? 'jupiterx-image-control-default-template' : 'jupiterx-image-control-logo-template' }}">
57
+ <div class="jupiterx-preview-image-control jupiterx-image-upload-control-add">
58
+ <span class="jupiterx-image-upload-control-icon"><i class="eicon-plus-circle" aria-hidden="true"></i></span>
59
+
60
+ <img class="jupiterx-image-upload-control-preview" src="{{ data.value }}" />
61
+ <input type="hidden" value="{{ data.value }}" {{{ data.link }}} />
62
+ </div>
63
+ <div class="jupiterx-image-buttons">
64
+ <button type="button" class="button jupiterx-image-upload-control-remove"><i class="eicon-trash-o"></i></button>
65
+ <button type="button" class="button jupiterx-image-upload-control-add"><?php esc_html_e( 'Choose Image', 'jupiterx-core' ); ?></button>
66
+ </div>
67
+ </div>
68
+ <?php
69
+ }
70
+ }
includes/customizer/api/includes/control/class-input.php CHANGED
@@ -1,176 +1,206 @@
1
- <?php
2
- /**
3
- * Handles input control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Input control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Input extends JupiterX_Customizer_Base_Input_Group {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-input';
34
-
35
- /**
36
- * Control's unit.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $units = [
43
- '-',
44
- 'px',
45
- '%',
46
- 'vh',
47
- 'vw',
48
- 'em',
49
- 'rem',
50
- ];
51
-
52
- /**
53
- * Control's default unit.
54
- *
55
- * @since 1.0.0
56
- *
57
- * @var string
58
- */
59
- public $default_unit = '';
60
-
61
- /**
62
- * Refresh the parameters passed to the JavaScript via JSON.
63
- *
64
- * @since 1.0.0
65
- */
66
- public function to_json() {
67
- parent::to_json();
68
-
69
- $this->json['units'] = $this->units;
70
- $this->json['defaultUnit'] = $this->default_unit;
71
- }
72
-
73
- /**
74
- * An Underscore (JS) template for control wrapper.
75
- *
76
- * Use to create the control template.
77
- *
78
- * @since 1.0.0
79
- */
80
- protected function control_template() {
81
- ?>
82
- <#
83
- value = _.isObject( data.value ) ? data.value : {}
84
- units = ! _.isEmpty( data.units ) ? data.units : [ '-' ]
85
- hasText = ! _.isUndefined( data.text ) && ! _.isEmpty( data.text )
86
- hasIcon = ! _.isUndefined( data.icon ) && ! _.isEmpty( data.icon )
87
- hasUnits = ! _.isUndefined( data.units ) && ! _.isEmpty( data.units )
88
- controlClass = 'jupiterx-control ' + data.type + '-control'
89
- controlClass += ( hasIcon || hasText || hasUnits ) ? ' jupiterx-input-group' : ''
90
- controlClass += ( hasIcon ) ? ' has-icon' : ''
91
- controlClass += ( hasText ) ? ' has-text' : ''
92
- controlClass += ( hasUnits ) ? ' has-units' : ''
93
- #>
94
- <div class="{{ controlClass }}" {{{ data.controlAttrs }}}>
95
- <?php
96
- $this->group_prefix_template();
97
- $this->group_field_template();
98
- $this->group_units_template();
99
- ?>
100
- </div>
101
- <?php
102
- }
103
-
104
- /**
105
- * An Underscore (JS) template for control field.
106
- *
107
- * @since 1.0.0
108
- */
109
- protected function group_field_template() {
110
- ?>
111
- <#
112
- size = value.size || ''
113
- defaultUnit = data.defaultUnit ? data.defaultUnit : _.first( units )
114
- unitValue = value.unit ? value.unit : defaultUnit
115
- step = 'px' == unitValue ? 1 : .1
116
- #>
117
- <input class="jupiterx-input-control-input" {{{ data.inputAttrs }}} type="text" value="{{ size }}" step="{{ step }}" {{{ data.link }}} data-setting-property-link="size" />
118
- <?php
119
- }
120
-
121
- /**
122
- * An Underscore (JS) template for control field.
123
- *
124
- * @since 1.0.0
125
- */
126
- protected function group_units_template() {
127
- ?>
128
- <#
129
- defaultUnit = data.defaultUnit ? data.defaultUnit : _.first( units )
130
- unitValue = value.unit ? value.unit : defaultUnit
131
- selectorClass = 1 === _.size( units ) ? 'disabled' : ''
132
- #>
133
- <div class="jupiterx-control-units-container">
134
- <input type="hidden" value="{{ unitValue }}" {{{ data.link }}} data-setting-property-link="unit" />
135
- <ul class="jupiterx-control-unit-selector" data-inputs=".jupiterx-input-control-input">
136
- <li class="jupiterx-control-unit selected-unit {{ selectorClass }}">{{ unitValue }}</li>
137
- <# _.each( units, function ( unit ) { #>
138
- <li class="jupiterx-control-unit">{{ unit }}</li>
139
- <# } ) #>
140
- </ul>
141
- </div>
142
- <?php
143
- }
144
-
145
- /**
146
- * Format CSS value from theme mod array value.
147
- *
148
- * @since 1.0.0
149
- *
150
- * @return array Empty properties
151
- */
152
- public static function format_properties() {
153
- return [];
154
- }
155
-
156
- /**
157
- * Format theme mod array value.
158
- *
159
- * @since 1.0.0
160
- *
161
- * @param array $value The field's value.
162
- *
163
- * @return string The formatted value.
164
- */
165
- public static function format_value( $value ) {
166
- if ( ! isset( $value['size'] ) || '' === $value['size'] || ! isset( $value['unit'] ) ) {
167
- return '';
168
- }
169
-
170
- $unit = '-' !== $value['unit'] ? $value['unit'] : '';
171
-
172
- $css_value = $value['size'] . $unit;
173
-
174
- return $css_value;
175
- }
176
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles input control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Input control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Input extends JupiterX_Customizer_Base_Input_Group {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-input';
34
+
35
+ /**
36
+ * Control's unit.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $units = [
43
+ '-',
44
+ 'px',
45
+ '%',
46
+ 'vh',
47
+ 'vw',
48
+ 'em',
49
+ 'rem',
50
+ ];
51
+
52
+ /**
53
+ * Control's default unit.
54
+ *
55
+ * @since 1.0.0
56
+ *
57
+ * @var string
58
+ */
59
+ public $default_unit = '';
60
+
61
+ /**
62
+ * Refresh the parameters passed to the JavaScript via JSON.
63
+ *
64
+ * @since 1.0.0
65
+ */
66
+ public function to_json() {
67
+ parent::to_json();
68
+
69
+ $this->json['units'] = $this->units;
70
+ $this->json['defaultUnit'] = $this->default_unit;
71
+ }
72
+
73
+ /**
74
+ * An Underscore (JS) template for control wrapper.
75
+ *
76
+ * Use to create the control template.
77
+ *
78
+ * @since 1.0.0
79
+ */
80
+ protected function control_template() {
81
+ ?>
82
+ <#
83
+ value = _.isObject( data.value ) ? data.value : {}
84
+ units = ! _.isEmpty( data.units ) ? data.units : [ '-' ]
85
+ hasText = ! _.isUndefined( data.text ) && ! _.isEmpty( data.text )
86
+ hasIcon = ! _.isUndefined( data.icon ) && ! _.isEmpty( data.icon )
87
+ hasUnits = ! _.isUndefined( data.units ) && ! _.isEmpty( data.units )
88
+ controlClass = 'jupiterx-control ' + data.type + '-control'
89
+ controlClass += ( hasIcon || hasText || hasUnits ) ? ' jupiterx-input-group' : ''
90
+ controlClass += ( hasIcon ) ? ' has-icon' : ''
91
+ controlClass += ( hasText ) ? ' has-text' : ''
92
+ controlClass += ( hasUnits ) ? ' has-units' : ''
93
+ #>
94
+ <div class="{{ controlClass }}" {{{ data.controlAttrs }}}>
95
+ <?php
96
+ $this->group_prefix_template();
97
+ $this->group_field_template();
98
+ $this->group_units_template();
99
+ ?>
100
+ </div>
101
+ <?php
102
+ }
103
+
104
+ /**
105
+ * An Underscore (JS) template for control field.
106
+ *
107
+ * @since 1.0.0
108
+ */
109
+ protected function group_field_template() {
110
+ ?>
111
+ <#
112
+ size = value.size || ''
113
+ defaultUnit = data.defaultUnit ? data.defaultUnit : _.first( units )
114
+ unitValue = value.unit ? value.unit : defaultUnit
115
+ step = 'px' == unitValue ? 1 : .1
116
+ inputAttrs = data.inputAttrs
117
+
118
+ if ( '%' === unitValue ) {
119
+ dataInputAttrs = data.inputAttrs ? data.inputAttrs : ''
120
+ dataInputAttrsArray = []
121
+
122
+ dataInputAttrs = dataInputAttrs.split('"')
123
+
124
+ dataInputAttrs.forEach( function get_attr( element, index ) {
125
+ if ( element === 'min=' ) {
126
+ dataInputAttrsArray[ index + 1 ] = "min=0"
127
+ }
128
+
129
+ if ( element === ' max=' ) {
130
+ dataInputAttrsArray[ index + 1 ] = "max=100"
131
+ }
132
+
133
+ if ( element !== ' max=' && element !== 'min=' && element.includes( '=' ) ) {
134
+ dataInputAttrsArray[ index ] = dataInputAttrs[ index ] + dataInputAttrs[ index + 1 ]
135
+ }
136
+ } )
137
+
138
+ dataInputAttrsArrayFiltered = dataInputAttrsArray.filter( function( element ) {
139
+ return element != null;
140
+ });
141
+
142
+ inputAttrs = dataInputAttrsArrayFiltered
143
+ }
144
+ #>
145
+ <div class="jupiterx-control-input-wrapper">
146
+ <input id="{{ data.id }}_range" class="jupiterx-input-control-input-range" {{{ inputAttrs }}} type="range" value="{{ size }}" step="{{ step }}" {{{ data.link }}} data-setting-property-link="size">
147
+ <input id="{{ data.id }}" class="jupiterx-input-control-input" {{{ data.inputAttrs }}} type="number" value="{{ size }}" step="{{ step }}" {{{ data.link }}} data-setting-property-link="size" />
148
+ </div>
149
+ <?php
150
+ }
151
+
152
+ /**
153
+ * An Underscore (JS) template for control field.
154
+ *
155
+ * @since 1.0.0
156
+ */
157
+ protected function group_units_template() {
158
+ ?>
159
+ <#
160
+ defaultUnit = data.defaultUnit ? data.defaultUnit : _.first( units )
161
+ unitValue = value.unit ? value.unit : defaultUnit
162
+ selectorClass = 1 === _.size( units ) ? 'disabled' : ''
163
+ #>
164
+ <div class="jupiterx-control-units-container">
165
+ <input type="hidden" value="{{ unitValue }}" {{{ data.link }}} data-setting-property-link="unit" />
166
+ <ul class="jupiterx-control-unit-selector" data-inputs=".jupiterx-input-control-input">
167
+ <# _.each( units, function ( unit ) { #>
168
+ <li class="jupiterx-control-unit {{ unit === unitValue ? 'selected-unit' : '' }}">{{ unit }}</li>
169
+ <# } ) #>
170
+ </ul>
171
+ </div>
172
+ <?php
173
+ }
174
+
175
+ /**
176
+ * Format CSS value from theme mod array value.
177
+ *
178
+ * @since 1.0.0
179
+ *
180
+ * @return array Empty properties
181
+ */
182
+ public static function format_properties() {
183
+ return [];
184
+ }
185
+
186
+ /**
187
+ * Format theme mod array value.
188
+ *
189
+ * @since 1.0.0
190
+ *
191
+ * @param array $value The field's value.
192
+ *
193
+ * @return string The formatted value.
194
+ */
195
+ public static function format_value( $value ) {
196
+ if ( ! isset( $value['size'] ) || '' === $value['size'] || ! isset( $value['unit'] ) ) {
197
+ return '';
198
+ }
199
+
200
+ $unit = '-' !== $value['unit'] ? $value['unit'] : '';
201
+
202
+ $css_value = $value['size'] . $unit;
203
+
204
+ return $css_value;
205
+ }
206
+ }
includes/customizer/api/includes/control/class-label.php CHANGED
@@ -1,86 +1,86 @@
1
- <?php
2
- /**
3
- * Handles label control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Label control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Label extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-label';
34
-
35
- /**
36
- * Control's label type.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $label_type = '';
43
-
44
- /**
45
- * Control's label color.
46
- *
47
- * @since 1.0.0
48
- *
49
- * @var string
50
- */
51
- public $color = '';
52
-
53
- /**
54
- * Refresh the parameters passed to the JavaScript via JSON.
55
- *
56
- * @since 1.0.0
57
- */
58
- public function to_json() {
59
- parent::to_json();
60
-
61
- $this->json['labelType'] = $this->label_type;
62
- $this->json['color'] = $this->color;
63
- }
64
-
65
- /**
66
- * An Underscore (JS) template for this control's content (but not its container).
67
- *
68
- * Class variables for this control class are available in the `data` JS object;
69
- * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
70
- *
71
- * @see WP_Customize_Control::print_template()
72
- *
73
- * @since 1.0.0
74
- */
75
- protected function content_template() {
76
- ?>
77
- <#
78
- type = data.labelType ? 'jupiterx-label-control-' + data.labelType : ''
79
- color = data.color ? 'jupiterx-label-control-' + data.color : ''
80
- #>
81
- <div class="jupiterx-control jupiterx-label-control {{ type }} {{ color }}">
82
- <span class="jupiterx-label-control-text">{{ data.label }}</span>
83
- </div>
84
- <?php
85
- }
86
- }
1
+ <?php
2
+ /**
3
+ * Handles label control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Label control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Label extends JupiterX_Customizer_Base_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-label';
34
+
35
+ /**
36
+ * Control's label type.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $label_type = '';
43
+
44
+ /**
45
+ * Control's label color.
46
+ *
47
+ * @since 1.0.0
48
+ *
49
+ * @var string
50
+ */
51
+ public $color = '';
52
+
53
+ /**
54
+ * Refresh the parameters passed to the JavaScript via JSON.
55
+ *
56
+ * @since 1.0.0
57
+ */
58
+ public function to_json() {
59
+ parent::to_json();
60
+
61
+ $this->json['labelType'] = $this->label_type;
62
+ $this->json['color'] = $this->color;
63
+ }
64
+
65
+ /**
66
+ * An Underscore (JS) template for this control's content (but not its container).
67
+ *
68
+ * Class variables for this control class are available in the `data` JS object;
69
+ * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
70
+ *
71
+ * @see WP_Customize_Control::print_template()
72
+ *
73
+ * @since 1.0.0
74
+ */
75
+ protected function content_template() {
76
+ ?>
77
+ <#
78
+ type = data.labelType ? 'jupiterx-label-control-' + data.labelType : ''
79
+ color = data.color ? 'jupiterx-label-control-' + data.color : ''
80
+ #>
81
+ <div class="jupiterx-control jupiterx-label-control {{ type }} {{ color }}">
82
+ <span class="jupiterx-label-control-text">{{ data.label }}</span>
83
+ </div>
84
+ <?php
85
+ }
86
+ }
includes/customizer/api/includes/control/class-multicheck.php CHANGED
@@ -1,108 +1,108 @@
1
- <?php
2
- /**
3
- * Handles multicheck control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Multicheck control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Multicheck extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-multicheck';
34
-
35
- /**
36
- * Choices via icons.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var array
41
- */
42
- public $icon_choices = [];
43
-
44
- /**
45
- * Refresh the parameters passed to the JavaScript via JSON.
46
- *
47
- * @since 1.0.0
48
- */
49
- public function to_json() {
50
- parent::to_json();
51
-
52
- $this->json['iconChoices'] = $this->icon_choices;
53
- }
54
-
55
- /**
56
- * An Underscore (JS) template for control wrapper.
57
- *
58
- * Use to create the control template.
59
- *
60
- * @since 1.0.0
61
- */
62
- protected function control_template() {
63
- ?>
64
- <div class="jupiterx-control jupiterx-multicheck-control">
65
- <# if ( ! _.isEmpty( data.iconChoices ) ) { #>
66
- <div class="jupiterx-multicheck-control-icon-items">
67
- <# _.each( data.iconChoices, function( icon, key ) { #>
68
- <div class="jupiterx-multicheck-control-icon-item">
69
- <input class="jupiterx-multicheck-control-checkbox" {{{ data.inputAttrs }}} type="checkbox" value="{{ key }}" id="{{ data.id }}-{{ key }}" <# if ( data.value.indexOf( key ) >= 0 ) { #> checked <# } #>>
70
- <label class="jupiterx-multicheck-control-icon-label" for="{{ data.id }}-{{ key }}"><img src="<?php echo esc_url( JupiterX_Customizer_Utils::get_assets_url() ); ?>/img/{{ icon }}.svg" /></label>
71
- </div>
72
- <# } ) #>
73
- </div>
74
- <# } #>
75
- <# if ( ! _.isEmpty( data.choices ) ) { #>
76
- <div class="jupiterx-multicheck-control-items">
77
- <# _.each( data.choices, function( label, key ) { #>
78
- <div class="jupiterx-multicheck-control-item">
79
- <input class="jupiterx-multicheck-control-checkbox" {{{ data.inputAttrs }}} type="checkbox" value="{{ key }}" id="{{ data.id }}-{{ key }}" <# if ( data.value.indexOf( key ) >= 0 ) { #> checked <# } #>>
80
- <label class="jupiterx-multicheck-control-label" for="{{ data.id }}-{{ key }}"><span class="jupiterx-multicheck-control-box"></span> {{ label }}</label>
81
- </div>
82
- <# } ) #>
83
- </div>
84
- <# } #>
85
- <input type="hidden" value="{{ data.value }}" {{{ data.link }}}>
86
- </div>
87
- <?php
88
- }
89
-
90
- /**
91
- * Format CSS value from theme mod array value.
92
- *
93
- * @since 1.0.0
94
- *
95
- * @param array $value The field's value.
96
- *
97
- * @return array The formatted properties.
98
- */
99
- public static function format_properties( $value ) {
100
- $vars = [];
101
-
102
- foreach ( $value as $key ) {
103
- $vars[ $key ] = 'true';
104
- }
105
-
106
- return $vars;
107
- }
108
- }
1
+ <?php
2
+ /**
3
+ * Handles multicheck control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Multicheck control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Multicheck extends JupiterX_Customizer_Base_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-multicheck';
34
+
35
+ /**
36
+ * Choices via icons.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var array
41
+ */
42
+ public $icon_choices = [];
43
+
44
+ /**
45
+ * Refresh the parameters passed to the JavaScript via JSON.
46
+ *
47
+ * @since 1.0.0
48
+ */
49
+ public function to_json() {
50
+ parent::to_json();
51
+
52
+ $this->json['iconChoices'] = $this->icon_choices;
53
+ }
54
+
55
+ /**
56
+ * An Underscore (JS) template for control wrapper.
57
+ *
58
+ * Use to create the control template.
59
+ *
60
+ * @since 1.0.0
61
+ */
62
+ protected function control_template() {
63
+ ?>
64
+ <div class="jupiterx-control jupiterx-multicheck-control">
65
+ <# if ( ! _.isEmpty( data.iconChoices ) ) { #>
66
+ <div class="jupiterx-multicheck-control-icon-items">
67
+ <# _.each( data.iconChoices, function( icon, key ) { #>
68
+ <div class="jupiterx-multicheck-control-icon-item">
69
+ <input class="jupiterx-multicheck-control-checkbox" {{{ data.inputAttrs }}} type="checkbox" value="{{ key }}" id="{{ data.id }}-{{ key }}" <# if ( data.value.indexOf( key ) >= 0 ) { #> checked <# } #>>
70
+ <label class="jupiterx-multicheck-control-icon-label" for="{{ data.id }}-{{ key }}"><svg><use xlink:href="<?php echo esc_url( JupiterX_Customizer_Utils::get_assets_url() ); ?>/img/customizer-icons.svg#{{ icon }}"></use></svg></label>
71
+ </div>
72
+ <# } ) #>
73
+ </div>
74
+ <# } #>
75
+ <# if ( ! _.isEmpty( data.choices ) ) { #>
76
+ <div class="jupiterx-multicheck-control-items">
77
+ <# _.each( data.choices, function( label, key ) { #>
78
+ <div class="jupiterx-multicheck-control-item">
79
+ <input class="jupiterx-multicheck-control-checkbox" {{{ data.inputAttrs }}} type="checkbox" value="{{ key }}" id="{{ data.id }}-{{ key }}" <# if ( data.value.indexOf( key ) >= 0 ) { #> checked <# } #>>
80
+ <label class="jupiterx-multicheck-control-label" for="{{ data.id }}-{{ key }}"><span class="jupiterx-multicheck-control-box"><span class="jupiterx-multicheck-control-handler"></span></span> {{ label }}</label>
81
+ </div>
82
+ <# } ) #>
83
+ </div>
84
+ <# } #>
85
+ <input type="hidden" value="{{ data.value }}" {{{ data.link }}}>
86
+ </div>
87
+ <?php
88
+ }
89
+
90
+ /**
91
+ * Format CSS value from theme mod array value.
92
+ *
93
+ * @since 1.0.0
94
+ *
95
+ * @param array $value The field's value.
96
+ *
97
+ * @return array The formatted properties.
98
+ */
99
+ public static function format_properties( $value ) {
100
+ $vars = [];
101
+
102
+ foreach ( $value as $key ) {
103
+ $vars[ $key ] = 'true';
104
+ }
105
+
106
+ return $vars;
107
+ }
108
+ }
includes/customizer/api/includes/control/class-popup.php CHANGED
@@ -1,102 +1,102 @@
1
- <?php
2
- /**
3
- * This class handles control opening popup.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Open popup control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Popup extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-popup';
34
-
35
- /**
36
- * Text of the button.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $text = '';
43
-
44
- /**
45
- * Control's target popup to open.
46
- *
47
- * @since 1.0.0
48
- *
49
- * @var string
50
- */
51
- public $target = '';
52
-
53
- /**
54
- * Refresh the parameters passed to the JavaScript via JSON.
55
- *
56
- * @since 1.0.0
57
- */
58
- public function to_json() {
59
- parent::to_json();
60
-
61
- $this->json['target'] = $this->target;
62
- $this->json['text'] = $this->text;
63
- }
64
-
65
- /**
66
- * Renders the control wrapper and calls $this->render_content() for the internals.
67
- *
68
- * @since 1.0.0
69
- */
70
- protected function render() {
71
- $id = 'customize-control-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id );
72
- $class = 'customize-control customize-control-' . $this->type;
73
-
74
- printf( '<li id="%s" class="%s">', esc_attr( $id ), esc_attr( $class ) );
75
- $this->render_content();
76
- echo '</li>';
77
- }
78
-
79
- /**
80
- * An Underscore (JS) template for this control's content (but not its container).
81
- *
82
- * Class variables for this control class are available in the `data` JS object;
83
- * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
84
- *
85
- * @see WP_Customize_Control::print_template()
86
- *
87
- * @since 1.0.0
88
- */
89
- protected function content_template() {
90
- ?>
91
- <# if ( data.label ) { #>
92
- <span class="customize-control-title">{{ data.label }}</span>
93
- <# } #>
94
- <# if ( data.description ) { #>
95
- <span class="description customize-control-description">{{ data.description }}</span>
96
- <# } #>
97
- <div class="jupiterx-control jupiterx-popup-control">
98
- <button class="jupiterx-popup-control-button">{{ data.text }}</button>
99
- </div>
100
- <?php
101
- }
102
- }
1
+ <?php
2
+ /**
3
+ * This class handles control opening popup.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Open popup control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Popup extends JupiterX_Customizer_Base_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-popup';
34
+
35
+ /**
36
+ * Text of the button.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $text = '';
43
+
44
+ /**
45
+ * Control's target popup to open.
46
+ *
47
+ * @since 1.0.0
48
+ *
49
+ * @var string
50
+ */
51
+ public $target = '';
52
+
53
+ /**
54
+ * Refresh the parameters passed to the JavaScript via JSON.
55
+ *
56
+ * @since 1.0.0
57
+ */
58
+ public function to_json() {
59
+ parent::to_json();
60
+
61
+ $this->json['target'] = $this->target;
62
+ $this->json['text'] = $this->text;
63
+ }
64
+
65
+ /**
66
+ * Renders the control wrapper and calls $this->render_content() for the internals.
67
+ *
68
+ * @since 1.0.0
69
+ */
70
+ protected function render() {
71
+ $id = 'customize-control-' . str_replace( array( '[', ']' ), array( '-', '' ), $this->id );
72
+ $class = 'customize-control customize-control-' . $this->type;
73
+
74
+ printf( '<li id="%s" class="%s">', esc_attr( $id ), esc_attr( $class ) );
75
+ $this->render_content();
76
+ echo '</li>';
77
+ }
78
+
79
+ /**
80
+ * An Underscore (JS) template for this control's content (but not its container).
81
+ *
82
+ * Class variables for this control class are available in the `data` JS object;
83
+ * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
84
+ *
85
+ * @see WP_Customize_Control::print_template()
86
+ *
87
+ * @since 1.0.0
88
+ */
89
+ protected function content_template() {
90
+ ?>
91
+ <# if ( data.label ) { #>
92
+ <span class="customize-control-title">{{ data.label }}</span>
93
+ <# } #>
94
+ <# if ( data.description ) { #>
95
+ <span class="description customize-control-description">{{ data.description }}</span>
96
+ <# } #>
97
+ <div class="jupiterx-control jupiterx-popup-control">
98
+ <button class="jupiterx-popup-control-button">{{ data.text }}</button>
99
+ </div>
100
+ <?php
101
+ }
102
+ }
includes/customizer/api/includes/control/class-pro-box.php CHANGED
@@ -1,107 +1,107 @@
1
- <?php
2
- /**
3
- * PRO Box UI control.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.3.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * PRO Box control class.
17
- *
18
- * @since 1.3.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_PRO_Box extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.3.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-pro-box';
34
-
35
- /**
36
- * Control's title.
37
- *
38
- * @since 1.3.0
39
- *
40
- * @var string
41
- */
42
- public $title = '';
43
-
44
- /**
45
- * Control's description.
46
- *
47
- * @since 1.3.0
48
- *
49
- * @var string
50
- */
51
- public $description = '';
52
-
53
- /**
54
- * Refresh the parameters passed to the JavaScript via JSON.
55
- *
56
- * @since 1.3.0
57
- */
58
- public function to_json() {
59
- parent::to_json();
60
-
61
- $this->json['title'] = $this->title;
62
- $this->json['description'] = $this->description;
63
- }
64
-
65
- /**
66
- * An Underscore (JS) template for this control's content (but not its container).
67
- *
68
- * Class variables for this control class are available in the `data` JS object;
69
- * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
70
- *
71
- * @see WP_Customize_Control::print_template()
72
- *
73
- * @since 1.3.0
74
- * @SuppressWarnings(PHPMD.ElseExpression)
75
- */
76
- protected function content_template() {
77
- if ( jupiterx_is_premium() ) {
78
- $title = __( 'Activate Jupiter X', 'jupiterx-core' );
79
- $description = __( 'To unlock this feature you must activate Jupiter X', 'jupiterx-core' );
80
- } else {
81
- $title = __( 'Upgrade to unlock this feature', 'jupiterx-core' );
82
- $description = __( 'You can unlock more customization options.', 'jupiterx-core' );
83
- }
84
- ?>
85
- <div class="jupiterx-control jupiterx-pro-box-control">
86
- <# title = data.title || '<?php echo $title; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>' #>
87
- <# description = data.description || '<?php echo $description; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>' #>
88
- <?php if ( jupiterx_is_premium() ) : ?>
89
- <img class="jupiterx-control-pro-badge" src="<?php echo esc_url( JUPITERX_ADMIN_ASSETS_URL . 'images/lock-badge-dark.svg' ); ?>">
90
- <?php else : ?>
91
- <span class="jupiterx-icon-pro"></span>
92
- <?php endif; ?>
93
- <div class="jupiterx-pro-box-control-title">{{ title }}</div>
94
- <div class="jupiterx-pro-box-control-description">{{ description }}</div>
95
- <?php if ( jupiterx_is_premium() ) : ?>
96
- <a class="jupiterx-pro-box-control-button jupiterx-upgrade-modal-trigger" href="#" data-upgrade-link="<?php echo esc_attr( jupiterx_upgrade_link( 'customizer' ) ); ?>">
97
- <?php esc_html_e( 'Activate Now', 'jupiterx-core' ); ?>
98
- </a>
99
- <?php else : ?>
100
- <a class="jupiterx-pro-box-control-button" href="<?php echo esc_attr( jupiterx_upgrade_link( 'customizer' ) ); ?>" target="_blank">
101
- <?php esc_html_e( 'Upgrade to Jupiter X Pro', 'jupiterx-core' ); ?>
102
- </a>
103
- <?php endif; ?>
104
- </div>
105
- <?php
106
- }
107
- }
1
+ <?php
2
+ /**
3
+ * PRO Box UI control.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.3.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * PRO Box control class.
17
+ *
18
+ * @since 1.3.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_PRO_Box extends JupiterX_Customizer_Base_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.3.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-pro-box';
34
+
35
+ /**
36
+ * Control's title.
37
+ *
38
+ * @since 1.3.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $title = '';
43
+
44
+ /**
45
+ * Control's description.
46
+ *
47
+ * @since 1.3.0
48
+ *
49
+ * @var string
50
+ */
51
+ public $description = '';
52
+
53
+ /**
54
+ * Refresh the parameters passed to the JavaScript via JSON.
55
+ *
56
+ * @since 1.3.0
57
+ */
58
+ public function to_json() {
59
+ parent::to_json();
60
+
61
+ $this->json['title'] = $this->title;
62
+ $this->json['description'] = $this->description;
63
+ }
64
+
65
+ /**
66
+ * An Underscore (JS) template for this control's content (but not its container).
67
+ *
68
+ * Class variables for this control class are available in the `data` JS object;
69
+ * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
70
+ *
71
+ * @see WP_Customize_Control::print_template()
72
+ *
73
+ * @since 1.3.0
74
+ * @SuppressWarnings(PHPMD.ElseExpression)
75
+ */
76
+ protected function content_template() {
77
+ if ( jupiterx_is_premium() ) {
78
+ $title = __( 'Activate Jupiter X', 'jupiterx-core' );
79
+ $description = __( 'To unlock this feature you must activate Jupiter X', 'jupiterx-core' );
80
+ } else {
81
+ $title = __( 'Upgrade to unlock this feature', 'jupiterx-core' );
82
+ $description = __( 'You can unlock more customization options.', 'jupiterx-core' );
83
+ }
84
+ ?>
85
+ <div class="jupiterx-control jupiterx-pro-box-control">
86
+ <# title = data.title || '<?php echo $title; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>' #>
87
+ <# description = data.description || '<?php echo $description; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>' #>
88
+ <?php if ( jupiterx_is_premium() ) : ?>
89
+ <img class="jupiterx-control-pro-badge" src="<?php echo esc_url( JUPITERX_ADMIN_ASSETS_URL . 'images/lock-badge-dark.svg' ); ?>">
90
+ <?php else : ?>
91
+ <span class="jupiterx-icon-pro"></span>
92
+ <?php endif; ?>
93
+ <div class="jupiterx-pro-box-control-title">{{ title }}</div>
94
+ <div class="jupiterx-pro-box-control-description">{{ description }}</div>
95
+ <?php if ( jupiterx_is_premium() ) : ?>
96
+ <a class="jupiterx-pro-box-control-button jupiterx-upgrade-modal-trigger" href="#" data-upgrade-link="<?php echo esc_attr( jupiterx_upgrade_link( 'customizer' ) ); ?>">
97
+ <?php esc_html_e( 'Activate Now', 'jupiterx-core' ); ?>
98
+ </a>
99
+ <?php else : ?>
100
+ <a class="jupiterx-pro-box-control-button" href="<?php echo esc_attr( jupiterx_upgrade_link( 'customizer' ) ); ?>" target="_blank">
101
+ <?php esc_html_e( 'Upgrade to Jupiter X Pro', 'jupiterx-core' ); ?>
102
+ </a>
103
+ <?php endif; ?>
104
+ </div>
105
+ <?php
106
+ }
107
+ }
includes/customizer/api/includes/control/class-radio-image.php CHANGED
@@ -1,78 +1,78 @@
1
- <?php
2
- /**
3
- * Handles radio image control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Radio image control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Radio_Image extends JupiterX_Customizer_Base_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-radio-image';
34
-
35
- /**
36
- * Refresh the parameters passed to the JavaScript via JSON.
37
- *
38
- * @since 1.0.0
39
- */
40
- public function to_json() {
41
- parent::to_json();
42
-
43
- foreach ( $this->choices as $key => $choice ) {
44
- // Transform label.
45
- if ( is_string( $choice ) ) {
46
- $this->json['choices'][ $key ] = [ 'name' => $choice ];
47
- continue;
48
- }
49
- }
50
- }
51
-
52
- /**
53
- * An Underscore (JS) template for control wrapper.
54
- *
55
- * Use to create the control template.
56
- *
57
- * @since 1.0.0
58
- */
59
- protected function control_template() {
60
- ?>
61
- <div class="jupiterx-control jupiterx-radio-image-control">
62
- <div class="jupiterx-radio-image-control-buttons">
63
- <# _.each( data.choices, function( image, key ) { #>
64
- <# if ( ! image.pro ) { #><input class="jupiterx-radio-image-control-radio" {{{ data.inputAttrs }}} type="radio" value="{{ key }}" name="{{ data.id }}" id="{{ data.id }}-{{ key }}" {{{ data.link }}} <# if ( key === data.value ) { #> checked <# } #>><# } #>
65
- <label
66
- class="jupiterx-radio-image-control-button <# if ( image.pro ) { #>pro-preview<# } #>"
67
- for="{{ data.id }}-{{ key }}"
68
- <# if ( image.pro ) { #>data-preview="{{ image.preview }}"<# } #>
69
- >
70
- <img class="jupiterx-radio-image-control-image" src="<?php echo esc_url( JupiterX_Customizer_Utils::get_assets_url() ); ?>/img/{{ image.name }}.svg" />
71
- <# if ( image.pro ) { #><img class="jupiterx-control-pro-badge" src="<?php echo esc_url( jupiterx_get_pro_badge_url() ); ?>" /><# } #>
72
- </label>
73
- <# } ) #>
74
- </div>
75
- </div>
76
- <?php
77
- }
78
- }
1
+ <?php
2
+ /**
3
+ * Handles radio image control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Radio image control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Radio_Image extends JupiterX_Customizer_Base_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-radio-image';
34
+
35
+ /**
36
+ * Refresh the parameters passed to the JavaScript via JSON.
37
+ *
38
+ * @since 1.0.0
39
+ */
40
+ public function to_json() {
41
+ parent::to_json();
42
+
43
+ foreach ( $this->choices as $key => $choice ) {
44
+ // Transform label.
45
+ if ( is_string( $choice ) ) {
46
+ $this->json['choices'][ $key ] = [ 'name' => $choice ];
47
+ continue;
48
+ }
49
+ }
50
+ }
51
+
52
+ /**
53
+ * An Underscore (JS) template for control wrapper.
54
+ *
55
+ * Use to create the control template.
56
+ *
57
+ * @since 1.0.0
58
+ */
59
+ protected function control_template() {
60
+ ?>
61
+ <div class="jupiterx-control jupiterx-radio-image-control">
62
+ <div class="jupiterx-radio-image-control-buttons">
63
+ <# _.each( data.choices, function( image, key ) { #>
64
+ <# if ( ! image.pro ) { #><input class="jupiterx-radio-image-control-radio" {{{ data.inputAttrs }}} type="radio" value="{{ key }}" name="{{ data.id }}" id="{{ data.id }}-{{ key }}" {{{ data.link }}} <# if ( key === data.value ) { #> checked <# } #>><# } #>
65
+ <label
66
+ class="jupiterx-radio-image-control-button <# if ( image.pro ) { #>pro-preview<# } #>"
67
+ for="{{ data.id }}-{{ key }}"
68
+ <# if ( image.pro ) { #>data-preview="{{ image.preview }}"<# } #>
69
+ >
70
+ <svg class="jupiterx-radio-image-control-image"><use xlink:href="<?php echo esc_url( JupiterX_Customizer_Utils::get_assets_url() ); ?>/img/customizer-icons.svg#{{ image.name }}"></use></svg>
71
+ <# if ( image.pro ) { #><svg class="jupiterx-control-pro-badge"><use xlink:href="<?php echo esc_url( jupiterx_core_get_pro_badge() ); ?>"><use></svg><# } #>
72
+ </label>
73
+ <# } ) #>
74
+ </div>
75
+ </div>
76
+ <?php
77
+ }
78
+ }
includes/customizer/api/includes/control/class-select.php CHANGED
@@ -1,97 +1,132 @@
1
- <?php
2
- /**
3
- * Handles select control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Select control class.
17
- *
18
- * This is a special section for rendering tabs and child popups controls inside the Popup section.
19
- *
20
- * @since 1.0.0
21
- * @ignore
22
- * @access private
23
- *
24
- * @package JupiterX\Framework\API\Customizer
25
- */
26
- class JupiterX_Customizer_Control_Select extends JupiterX_Customizer_Base_Input_Group {
27
-
28
- /**
29
- * Control's type.
30
- *
31
- * @since 1.0.0
32
- *
33
- * @var string
34
- */
35
- public $type = 'jupiterx-select';
36
-
37
- /**
38
- * Control's placeholder.
39
- *
40
- * @since 1.0.0
41
- *
42
- * @var string
43
- */
44
- public $placeholder = '';
45
-
46
- /**
47
- * Delayed data loading for choices.
48
- *
49
- * @since 1.0.0
50
- *
51
- * @var string
52
- */
53
- public $load_choices = '';
54
-
55
- /**
56
- * Refresh the parameters passed to the JavaScript via JSON.
57
- *
58
- * @since 1.0.0
59
- */
60
- public function to_json() {
61
- parent::to_json();
62
-
63
- $this->json['placeholder'] = $this->placeholder;
64
-
65
- // Choices to load.
66
- $this->json['load_choices'] = $this->load_choices;
67
- }
68
-
69
- /**
70
- * An Underscore (JS) template for control field.
71
- *
72
- * @since 1.0.0
73
- */
74
- protected function group_field_template() {
75
- ?>
76
- <# if ( data.load_choices === 'widgets_area' ) { #>
77
- <# data.choices = <?php echo json_encode( JupiterX_Customizer_Utils::get_select_widgets_area() ); // @codingStandardsIgnoreLine ?> #>
78
- <# } #>
79
-
80
- <# classes = 'jupiterx-select-control-field';
81
- if ( data ) {
82
- classes += ' jupiterx-renew-preview';
83
- } #>
84
- <select class="{{classes}}" {{{ data.inputAttrs }}} value="{{ data.value }}" id="{{ data.id }}" {{{ data.link }}}>
85
- <# if ( ! _.isEmpty( data.placeholder ) ) { #>
86
- <option value="" <# if ( _.isEmpty( data.value ) ) { #> selected<# } #>>{{{ data.placeholder }}}</option>
87
- <# } #>
88
- <# _.each( data.choices, function( label, key ) { #>
89
- <# if ( ! _.isEmpty( key ) ) { #>
90
- <# selected = ( data.value === key ) #>
91
- <option value="{{ key }}" <# if ( selected ) { #> selected<# } #>>{{{ label }}}</option>
92
- <# }#>
93
- <# } ); #>
94
- </select>
95
- <?php
96
- }
97
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles select control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Select control class.
17
+ *
18
+ * This is a special section for rendering tabs and child popups controls inside the Popup section.
19
+ *
20
+ * @since 1.0.0
21
+ * @ignore
22
+ * @access private
23
+ *
24
+ * @package JupiterX\Framework\API\Customizer
25
+ */
26
+ class JupiterX_Customizer_Control_Select extends JupiterX_Customizer_Base_Input_Group {
27
+
28
+ /**
29
+ * Control's type.
30
+ *
31
+ * @since 1.0.0
32
+ *
33
+ * @var string
34
+ */
35
+ public $type = 'jupiterx-select';
36
+
37
+ /**
38
+ * Control's placeholder.
39
+ *
40
+ * @since 1.0.0
41
+ *
42
+ * @var string
43
+ */
44
+ public $placeholder = '';
45
+
46
+ /**
47
+ * Delayed data loading for choices.
48
+ *
49
+ * @since 1.0.0
50
+ *
51
+ * @var string
52
+ */
53
+ public $load_choices = '';
54
+
55
+ /**
56
+ * Live reload icons.
57
+ *
58
+ * @since 1.20.0
59
+ *
60
+ * @var string
61
+ */
62
+ private $exclude_reload = [
63
+ 'font-weight',
64
+ 'text-decoration',
65
+ ];
66
+
67
+ /**
68
+ * Refresh the parameters passed to the JavaScript via JSON.
69
+ *
70
+ * @since 1.0.0
71
+ */
72
+ public function to_json() {
73
+ parent::to_json();
74
+
75
+ $this->json['placeholder'] = $this->placeholder;
76
+
77
+ // Choices to load.
78
+ $this->json['load_choices'] = $this->load_choices;
79
+
80
+ // live reloading
81
+ $this->json['exclude_reload'] = $this->require_reload();
82
+ }
83
+
84
+ /**
85
+ * Get selects with live reloading feature based ib their icons.
86
+ *
87
+ * @since 1.20.0
88
+ */
89
+ public function require_reload() {
90
+ if ( empty( $this->icon ) ) {
91
+ return false;
92
+ }
93
+
94
+ return in_array( $this->icon, $this->exclude_reload, true );
95
+ }
96
+
97
+ /**
98
+ * An Underscore (JS) template for control field.
99
+ *
100
+ * @since 1.0.0
101
+ */
102
+ protected function group_field_template() {
103
+ ?>
104
+ <# if ( data.load_choices === 'widgets_area' ) { #>
105
+ <# data.choices = <?php echo json_encode( JupiterX_Customizer_Utils::get_select_widgets_area() ); // @codingStandardsIgnoreLine ?> #>
106
+ <# } #>
107
+
108
+ <# classes = 'jupiterx-select-control-field';
109
+
110
+ if ( data && ! data.exclude_reload ) {
111
+ classes += ' jupiterx-renew-preview';
112
+ }
113
+
114
+ var isSelect2 = _.isEmpty( data.jupiterx ) || _.isEmpty( data.jupiterx.select2 )
115
+ #>
116
+ <select class="{{classes}}" {{{ data.inputAttrs }}} value="{{ data.value }}" id="{{ data.id }}" {{{ data.link }}}>
117
+ <# if ( isSelect2 && ! _.isEmpty( data.placeholder ) ) { #>
118
+ <option value="" <# if ( _.isEmpty( data.value ) ) { #> selected<# } #>>{{{ data.placeholder }}}</option>
119
+ <# } #>
120
+ <# _.each( data.choices, function( label, key ) { #>
121
+ <# if ( ! _.isEmpty( key ) ) { #>
122
+ <# selected = ( data.value === key ) #>
123
+ <option value="{{ key }}" <# if ( selected ) { #> selected<# } #>>{{{ label }}}</option>
124
+ <# }#>
125
+ <# } ); #>
126
+ <# if ( ! isSelect2 && ! _.isEmpty( data.value ) ) { #>
127
+ <option selected><?php esc_html_e( 'Fetching...', 'jupiterx-core' ); ?></option>
128
+ <# } #>
129
+ </select>
130
+ <?php
131
+ }
132
+ }
includes/customizer/api/includes/control/class-template.php CHANGED
@@ -1,110 +1,112 @@
1
- <?php
2
- /**
3
- * Handles Elementor template control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.1.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Elementor template control class.
17
- *
18
- * @since 1.1.0
19
- *
20
- * @package JupiterX\Framework\API\Customizer
21
- */
22
- class JupiterX_Customizer_Control_Template extends JupiterX_Customizer_Base_Control {
23
-
24
- /**
25
- * Control's type.
26
- *
27
- * @since 1.1.0
28
- *
29
- * @var string
30
- */
31
- public $type = 'jupiterx-template';
32
-
33
- /**
34
- * Control's select field placeholder.
35
- *
36
- * @since 1.1.0
37
- *
38
- * @var string
39
- */
40
- public $placeholder = '';
41
-
42
- /**
43
- * Type of template to create.
44
- *
45
- * @since 1.1.0
46
- *
47
- * @var string
48
- */
49
- public $template_type = '';
50
-
51
- /**
52
- * Show pro badge if locked.
53
- *
54
- * @since 1.11.0
55
- *
56
- * @var boolean
57
- */
58
- public $locked = false;
59
-
60
- /**
61
- * Refresh the parameters passed to the JavaScript via JSON.
62
- *
63
- * @since 1.1.0
64
- */
65
- public function to_json() {
66
- parent::to_json();
67
-
68
- // Select field placeholder.
69
- $this->json['placeholder'] = $this->placeholder;
70
-
71
- // Template type.
72
- $this->json['templateType'] = $this->template_type ? $this->template_type : 'post';
73
-
74
- $this->json['locked'] = $this->locked;
75
- }
76
-
77
- /**
78
- * An Underscore (JS) template for this control's content (but not its container).
79
- *
80
- * Class variables for this control class are available in the `data` JS object;
81
- * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
82
- *
83
- * @see WP_Customize_Control::print_template()
84
- *
85
- * @since 1.1.0
86
- */
87
- protected function content_template() {
88
- ?>
89
- <# if ( data.label ) { #>
90
- <span class="customize-control-title">{{ data.label }}</span>
91
- <# } #>
92
- <div class="jupiterx-control jupiterx-template-control">
93
- <div class="jupiterx-select-control">
94
- <select class="jupiterx-select-control" value="{{ data.value }}" id="{{ data.id }}" {{{ data.link }}}></select>
95
- </div>
96
- <span class="jupiterx-text-separator">
97
- <?php esc_html_e( 'OR', 'jupiterx-core' ); ?>
98
- </span>
99
- <button type="button" class="jupiterx-button jupiterx-edit">
100
- <?php esc_html_e( 'Edit', 'jupiterx-core' ); ?>
101
- <# if ( data.locked ) { #><img class="jupiterx-control-pro-badge" src="<?php echo esc_url( jupiterx_get_pro_badge_url() ); ?>" /><# } #>
102
- </button>
103
- <button type="button" class="jupiterx-button jupiterx-add">
104
- <?php esc_html_e( 'New', 'jupiterx-core' ); ?>
105
- <# if ( data.locked ) { #><img class="jupiterx-control-pro-badge" src="<?php echo esc_url( jupiterx_get_pro_badge_url() ); ?>" /><# } #>
106
- </button>
107
- </div>
108
- <?php
109
- }
110
- }
 
 
1
+ <?php
2
+ /**
3
+ * Handles Elementor template control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.1.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Elementor template control class.
17
+ *
18
+ * @since 1.1.0
19
+ *
20
+ * @package JupiterX\Framework\API\Customizer
21
+ */
22
+ class JupiterX_Customizer_Control_Template extends JupiterX_Customizer_Base_Control {
23
+
24
+ /**
25
+ * Control's type.
26
+ *
27
+ * @since 1.1.0
28
+ *
29
+ * @var string
30
+ */
31
+ public $type = 'jupiterx-template';
32
+
33
+ /**
34
+ * Control's select field placeholder.
35
+ *
36
+ * @since 1.1.0
37
+ *
38
+ * @var string
39
+ */
40
+ public $placeholder = '';
41
+
42
+ /**
43
+ * Type of template to create.
44
+ *
45
+ * @since 1.1.0
46
+ *
47
+ * @var string
48
+ */
49
+ public $template_type = '';
50
+
51
+ /**
52
+ * Show pro badge if locked.
53
+ *
54
+ * @since 1.11.0
55
+ *
56
+ * @var boolean
57
+ */
58
+ public $locked = false;
59
+
60
+ /**
61
+ * Refresh the parameters passed to the JavaScript via JSON.
62
+ *
63
+ * @since 1.1.0
64
+ */
65
+ public function to_json() {
66
+ parent::to_json();
67
+
68
+ // Select field placeholder.
69
+ $this->json['placeholder'] = $this->placeholder;
70
+
71
+ // Template type.
72
+ $this->json['templateType'] = $this->template_type ? $this->template_type : 'post';
73
+
74
+ $this->json['locked'] = $this->locked;
75
+ }
76
+
77
+ /**
78
+ * An Underscore (JS) template for this control's content (but not its container).
79
+ *
80
+ * Class variables for this control class are available in the `data` JS object;
81
+ * export custom variables by overriding {@see WP_Customize_Control::to_json()}.
82
+ *
83
+ * @see WP_Customize_Control::print_template()
84
+ *
85
+ * @since 1.1.0
86
+ */
87
+ protected function content_template() {
88
+ ?>
89
+ <# if ( data.label ) { #>
90
+ <span class="customize-control-title">{{ data.label }}</span>
91
+ <# } #>
92
+ <div class="jupiterx-control jupiterx-template-control">
93
+ <div class="jupiterx-select-control">
94
+ <select class="jupiterx-select-control" value="{{ data.value }}" id="{{ data.id }}" {{{ data.link }}}></select>
95
+ </div>
96
+ <span class="jupiterx-text-separator">
97
+ <?php esc_html_e( 'OR', 'jupiterx-core' ); ?>
98
+ </span>
99
+ <div class="jupiterx-template-button-wrapper">
100
+ <button type="button" class="jupiterx-button jupiterx-edit">
101
+ <?php esc_html_e( 'Edit', 'jupiterx-core' ); ?>
102
+ <# if ( data.locked ) { #><svg class="jupiterx-control-pro-badge"><use xlink:href="<?php echo esc_url( jupiterx_core_get_pro_badge() ); ?>"><use></svg><# } #>
103
+ </button>
104
+ <button type="button" class="jupiterx-button jupiterx-add">
105
+ <?php esc_html_e( 'New', 'jupiterx-core' ); ?>
106
+ <# if ( data.locked ) { #><svg class="jupiterx-control-pro-badge"><use xlink:href="<?php echo esc_url( jupiterx_core_get_pro_badge() ); ?>"><use></svg><# } #>
107
+ </button>
108
+ </div>
109
+ </div>
110
+ <?php
111
+ }
112
+ }
includes/customizer/api/includes/control/class-text.php CHANGED
@@ -1,142 +1,147 @@
1
- <?php
2
- /**
3
- * Handles input control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Text input control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Text extends JupiterX_Customizer_Base_Input_Group {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-text';
34
-
35
- /**
36
- * Control's text input type.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $input_type = 'text';
43
-
44
- /**
45
- * Control's input group unit.
46
- *
47
- * @since 1.0.0
48
- *
49
- * @var string
50
- */
51
- public $unit = '';
52
-
53
- /**
54
- * Refresh the parameters passed to the JavaScript via JSON.
55
- *
56
- * @since 1.0.0
57
- */
58
- public function to_json() {
59
- parent::to_json();
60
-
61
- $input_types = [ 'text', 'url', 'number', 'email' ];
62
-
63
- // Revert to text if acceptable type is not found.
64
- if ( ! in_array( $this->input_type, $input_types, true ) ) {
65
- $this->input_type = 'text';
66
- }
67
-
68
- $this->json['inputType'] = $this->input_type;
69
- $this->json['unit'] = $this->unit;
70
- }
71
-
72
- /**
73
- * An Underscore (JS) template for control wrapper.
74
- *
75
- * @since 1.0.0
76
- */
77
- protected function control_template() {
78
- ?>
79
- <#
80
- hasText = ! _.isUndefined( data.text ) && ! _.isEmpty( data.text )
81
- hasIcon = ! _.isUndefined( data.icon ) && ! _.isEmpty( data.icon )
82
- hasUnit = ! _.isUndefined( data.unit ) && ! _.isEmpty( data.unit )
83
- controlClass = 'jupiterx-control jupiterx-input-control ' + data.type + '-control'
84
- controlClass += ( hasIcon || hasText || hasUnit ) ? ' jupiterx-input-group' : ''
85
- controlClass += ( hasIcon ) ? ' has-icon' : ''
86
- controlClass += ( hasText ) ? ' has-text' : ''
87
- controlClass += ( hasUnit ) ? ' has-unit' : ''
88
- #>
89
- <label>
90
- <div class="{{ controlClass }}" {{{ data.controlAttrs }}}>
91
- <?php
92
- $this->group_prefix_template();
93
- $this->group_field_template();
94
- $this->group_suffix_template();
95
- ?>
96
- </div>
97
- </label>
98
- <?php
99
- }
100
-
101
- /**
102
- * An Underscore (JS) template for control field.
103
- *
104
- * @since 1.0.0
105
- */
106
- protected function group_field_template() {
107
- ?>
108
- <input class="jupiterx-input-control-field" {{{ data.inputAttrs }}} type="{{ data.inputType }}" id="{{ data.id }}" value="{{ data.value }}" {{{ data.link }}} />
109
- <?php
110
- }
111
-
112
- /**
113
- * An Underscore (JS) template for field suffix.
114
- *
115
- * @since 1.0.0
116
- */
117
- public function group_suffix_template() {
118
- ?>
119
- <# if ( hasUnit ) { #>
120
- <span class="jupiterx-input-group-unit">{{ data.unit }}</span>
121
- <# } #>
122
- <?php
123
- }
124
-
125
- /**
126
- * Format theme mod array value.
127
- *
128
- * @since 1.0.0
129
- *
130
- * @param array $value The field's value.
131
- * @param array $args The field's arguments.
132
- *
133
- * @return string The formatted value.
134
- */
135
- public static function format_value( $value, $args ) {
136
- if ( isset( $args['unit'] ) ) {
137
- $value .= $args['unit'];
138
- }
139
-
140
- return $value;
141
- }
142
- }
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Handles input control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Text input control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Text extends JupiterX_Customizer_Base_Input_Group {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-text';
34
+
35
+ /**
36
+ * Control's text input type.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $input_type = 'text';
43
+
44
+ /**
45
+ * Control's input group unit.
46
+ *
47
+ * @since 1.0.0
48
+ *
49
+ * @var string
50
+ */
51
+ public $unit = '';
52
+
53
+ /**
54
+ * Refresh the parameters passed to the JavaScript via JSON.
55
+ *
56
+ * @since 1.0.0
57
+ */
58
+ public function to_json() {
59
+ parent::to_json();
60
+
61
+ $input_types = [ 'text', 'url', 'number', 'email' ];
62
+
63
+ // Revert to text if acceptable type is not found.
64
+ if ( ! in_array( $this->input_type, $input_types, true ) ) {
65
+ $this->input_type = 'text';
66
+ }
67
+
68
+ $this->json['inputType'] = $this->input_type;
69
+ $this->json['unit'] = $this->unit;
70
+ }
71
+
72
+ /**
73
+ * An Underscore (JS) template for control wrapper.
74
+ *
75
+ * @since 1.0.0
76
+ */
77
+ protected function control_template() {
78
+ ?>
79
+ <#
80
+ hasText = ! _.isUndefined( data.text ) && ! _.isEmpty( data.text )
81
+ hasIcon = ! _.isUndefined( data.icon ) && ! _.isEmpty( data.icon )
82
+ hasUnit = ! _.isUndefined( data.unit ) && ! _.isEmpty( data.unit )
83
+ controlClass = 'jupiterx-control jupiterx-input-control ' + data.type + '-control'
84
+ controlClass += ( hasIcon || hasText || hasUnit ) ? ' jupiterx-input-group' : ''
85
+ controlClass += ( hasIcon ) ? ' has-icon' : ''
86
+ controlClass += ( hasText ) ? ' has-text' : ''
87
+ controlClass += ( hasUnit ) ? ' has-unit' : ''
88
+ controlClass += ( data.inputType === 'number' ) ? ' jupiterx-input-control-number' : ''
89
+ #>
90
+ <div class="{{ controlClass }}" {{{ data.controlAttrs }}}>
91
+ <?php
92
+ $this->group_prefix_template();
93
+ $this->group_field_template();
94
+ $this->group_suffix_template();
95
+ ?>
96
+ </div>
97
+ <?php
98
+ }
99
+
100
+ /**
101
+ * An Underscore (JS) template for control field.
102
+ *
103
+ * @since 1.0.0
104
+ */
105
+ protected function group_field_template() {
106
+ ?>
107
+ <#
108
+ unitValue = data.value ? data.value : 0
109
+ #>
110
+ <# if ( data.inputType === 'number' ) { #>
111
+ <input id="{{ data.id }}_range" class="jupiterx-input-control-field-range" {{{ data.inputAttrs }}} type="range" value="{{ unitValue }}" step="1" {{{ data.link }}}>
112
+ <# } #>
113
+ <input class="jupiterx-input-control-field" {{{ data.inputAttrs }}} type="{{ data.inputType }}" step="1" id="{{ data.id }}" value="{{ unitValue }}" {{{ data.link }}} />
114
+ <?php
115
+ }
116
+
117
+ /**
118
+ * An Underscore (JS) template for field suffix.
119
+ *
120
+ * @since 1.0.0
121
+ */
122
+ public function group_suffix_template() {
123
+ ?>
124
+ <# if ( hasUnit ) { #>
125
+ <span class="jupiterx-input-group-unit">{{ data.unit }}</span>
126
+ <# } #>
127
+ <?php
128
+ }
129
+
130
+ /**
131
+ * Format theme mod array value.
132
+ *
133
+ * @since 1.0.0
134
+ *
135
+ * @param array $value The field's value.
136
+ * @param array $args The field's arguments.
137
+ *
138
+ * @return string The formatted value.
139
+ */
140
+ public static function format_value( $value, $args ) {
141
+ if ( isset( $args['unit'] ) ) {
142
+ $value .= $args['unit'];
143
+ }
144
+
145
+ return $value;
146
+ }
147
+ }
includes/customizer/api/includes/control/class-textarea.php CHANGED
@@ -1,45 +1,45 @@
1
- <?php
2
- /**
3
- * Handles textarea control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Textarea control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Textarea extends JupiterX_Customizer_Base_Input_Group {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-textarea';
34
-
35
- /**
36
- * An Underscore (JS) template for control field.
37
- *
38
- * @since 1.0.0
39
- */
40
- protected function group_field_template() {
41
- ?>
42
- <textarea class="jupiterx-textarea-control-field" {{{ data.inputAttrs }}} id="{{ data.id }}" {{{ data.link }}}>{{ data.value }}</textarea>
43
- <?php
44
- }
45
- }
1
+ <?php
2
+ /**
3
+ * Handles textarea control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Textarea control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Textarea extends JupiterX_Customizer_Base_Input_Group {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-textarea';
34
+
35
+ /**
36
+ * An Underscore (JS) template for control field.
37
+ *
38
+ * @since 1.0.0
39
+ */
40
+ protected function group_field_template() {
41
+ ?>
42
+ <textarea class="jupiterx-textarea-control-field" {{{ data.inputAttrs }}} id="{{ data.id }}" {{{ data.link }}}>{{ data.value }}</textarea>
43
+ <?php
44
+ }
45
+ }
includes/customizer/api/includes/control/class-toggle.php CHANGED
@@ -1,48 +1,50 @@
1
- <?php
2
- /**
3
- * Handles toggle control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Toggle control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Control_Toggle extends JupiterX_Customizer_Base_Input_Group {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-toggle';
34
-
35
- /**
36
- * An Underscore (JS) template for control field.
37
- *
38
- * @since 1.0.0
39
- */
40
- protected function group_field_template() {
41
- ?>
42
- <label class="jupiterx-toggle-control-label">
43
- <input class="jupiterx-toggle-control-checkbox screen-reader-text" {{{ data.inputAttrs }}} type="checkbox" id="{{ data.id }}" value="{{ data.value }}" <# if ( data.value ) { #> checked <# } #> hidden {{{ data.link }}} />
44
- <span class="jupiterx-toggle-control-switch"></span>
45
- </label>
46
- <?php
47
- }
48
- }
 
 
1
+ <?php
2
+ /**
3
+ * Handles toggle control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Toggle control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Control_Toggle extends JupiterX_Customizer_Base_Input_Group {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-toggle';
34
+
35
+ /**
36
+ * An Underscore (JS) template for control field.
37
+ *
38
+ * @since 1.0.0
39
+ */
40
+ protected function group_field_template() {
41
+ ?>
42
+ <label class="jupiterx-toggle-control-label">
43
+ <input class="jupiterx-toggle-control-checkbox screen-reader-text" {{{ data.inputAttrs }}} type="checkbox" id="{{ data.id }}" value="{{ data.value }}" <# if ( data.value ) { #> checked <# } #> hidden {{{ data.link }}} />
44
+ <span class="jupiterx-toggle-control-switch">
45
+ <span class="jupiterx-toggle-control-handler"></span>
46
+ </span>
47
+ </label>
48
+ <?php
49
+ }
50
+ }
includes/customizer/api/includes/control/group/class-background.php CHANGED
@@ -1,350 +1,342 @@
1
- <?php
2
- /**
3
- * Handles background control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Background control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Group_Control_Background extends JupiterX_Customizer_Base_Group_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-background';
34
-
35
- /**
36
- * Set the fields for this control.
37
- *
38
- * @since 1.0.0
39
- */
40
- protected function set_fields() {
41
- $this->add_field( 'label', [
42
- 'type' => 'jupiterx-label',
43
- 'label' => __( 'Background Color Type', 'jupiterx-core' ),
44
- ] );
45
-
46
- $this->add_field( 'type', [
47
- 'type' => 'jupiterx-choose',
48
- 'column' => '4',
49
- 'default' => 'classic',
50
- 'choices' => [
51
- 'classic' => [
52
- 'icon' => 'background-type-color',
53
- ],
54
- 'gradient' => [
55
- 'icon' => 'background-type-gradient',
56
- ],
57
- ],
58
- ] );
59
-
60
- $this->add_field( 'color', [
61
- 'type' => 'jupiterx-color',
62
- 'column' => '8',
63
- 'icon' => 'background-color',
64
- 'cssClass' => 'for-classic',
65
- 'responsive' => true,
66
- ] );
67
-
68
- $this->add_field( 'image', [
69
- 'type' => 'jupiterx-image',
70
- 'column' => '4',
71
- 'label' => __( 'BG Image', 'jupiterx-core' ),
72
- 'cssClass' => 'for-classic',
73
- ] );
74
-
75
- $this->add_field( 'position', [
76
- 'type' => 'jupiterx-position',
77
- 'column' => '4',
78
- 'label' => __( 'Position', 'jupiterx-core' ),
79
- 'cssClass' => 'for-classic',
80
- ] );
81
-
82
- $this->add_field( 'repeat', [
83
- 'type' => 'jupiterx-choose',
84
- 'column' => '4',
85
- 'label' => __( 'Repeat', 'jupiterx-core' ),
86
- 'default' => 'no-repeat',
87
- 'choices' => [
88
- 'repeat' => [
89
- 'icon' => 'repeat',
90
- ],
91
- 'repeat-x' => [
92
- 'icon' => 'repeat-x',
93
- ],
94
- 'repeat-y' => [
95
- 'icon' => 'repeat-y',
96
- ],
97
- 'no-repeat' => [
98
- 'icon' => 'x',
99
- ],
100
- ],
101
- 'cssClass' => 'for-classic',
102
- ] );
103
-
104
- $this->add_field( 'attachment', [
105
- 'type' => 'jupiterx-choose',
106
- 'column' => '4',
107
- 'text' => __( 'Fixed', 'jupiterx-core' ),
108
- 'default' => 'scroll',
109
- 'choices' => [
110
- 'fixed' => [
111
- 'icon' => 'check',
112
- ],
113
- 'scroll' => [
114
- 'icon' => 'x',
115
- ],
116
- ],
117
- 'cssClass' => 'for-classic',
118
- ] );
119
-
120
- $this->add_field( 'size', [
121
- 'type' => 'jupiterx-choose',
122
- 'column' => '4',
123
- 'text' => __( 'Cover', 'jupiterx-core' ),
124
- 'default' => 'auto',
125
- 'choices' => [
126
- 'cover' => [
127
- 'icon' => 'check',
128
- ],
129
- 'auto' => [
130
- 'icon' => 'x',
131
- ],
132
- ],
133
- 'cssClass' => 'for-classic',
134
- ] );
135
-
136
- $this->add_field( 'divider', [
137
- 'type' => 'jupiterx-divider',
138
- 'dividerType' => 'empty',
139
- 'cssClass' => 'for-gradient jupiterx-divider-control-empty',
140
- ] );
141
-
142
- $gradient_colors = [
143
- 'color_from' => [
144
- 'type' => 'jupiterx-color',
145
- 'column' => '2',
146
- 'icon' => is_rtl() ? 'direction-arrow' : 'background-color',
147
- 'cssClass' => 'for-gradient',
148
- ],
149
- 'color_to' => [
150
- 'type' => 'jupiterx-color',
151
- 'column' => '2',
152
- 'icon' => is_rtl() ? 'background-color' : 'direction-arrow',
153
- 'cssClass' => 'for-gradient',
154
- ],
155
- ];
156
-
157
- if ( is_rtl() ) {
158
- $gradient_colors = array_reverse( $gradient_colors );
159
- }
160
-
161
- foreach ( $gradient_colors as $key => $value ) {
162
- $this->add_field( $key, $value );
163
- }
164
-
165
- $this->add_field( 'gradient_type', [
166
- 'type' => 'jupiterx-choose',
167
- 'column' => '4',
168
- 'default' => 'linear',
169
- 'choices' => [
170
- 'linear' => [
171
- 'label' => __( 'Linear', 'jupiterx-core' ),
172
- ],
173
- 'radial' => [
174
- 'label' => __( 'Radial', 'jupiterx-core' ),
175
- ],
176
- ],
177
- 'cssClass' => 'for-gradient',
178
- ] );
179
-
180
- $this->add_field( 'angle', [
181
- 'type' => 'jupiterx-text',
182
- 'inputType' => 'number',
183
- 'inputAttrs' => [
184
- 'placeholder' => 90,
185
- ],
186
- 'icon' => 'angle',
187
- 'column' => '4',
188
- 'default' => 90,
189
- 'cssClass' => 'for-gradient',
190
- ] );
191
- }
192
-
193
- /**
194
- * Include fields.
195
- *
196
- * @since 1.0.0
197
- */
198
- protected function include_fields() {
199
- if ( empty( $this->include ) ) {
200
- return;
201
- }
202
-
203
- $include = $this->include;
204
-
205
- if ( in_array( 'video', $include, true ) ) {
206
- $this->update_field( 'type', [
207
- 'choices' => [
208
- 'classic' => [
209
- 'icon' => 'background-type-color',
210
- ],
211
- 'gradient' => [
212
- 'icon' => 'background-type-gradient',
213
- ],
214
- 'video' => [
215
- 'icon' => 'background-type-video',
216
- ],
217
- ],
218
- ] );
219
-
220
- $this->add_field( 'video_divider', [
221
- 'type' => 'jupiterx-divider',
222
- 'dividerType' => 'empty',
223
- 'cssClass' => 'for-video',
224
- ] );
225
-
226
- $this->add_field( 'video_link', [
227
- 'type' => 'jupiterx-text',
228
- 'column' => '8',
229
- 'inputType' => 'url',
230
- 'inputAttrs' => [
231
- 'placeholder' => __( 'Social or Self hosted video link', 'jupiterx-core' ),
232
- ],
233
- 'label' => __( 'Video Link', 'jupiterx-core' ),
234
- 'cssClass' => 'for-video',
235
- ] );
236
-
237
- $this->add_field( 'video_fallback', [
238
- 'type' => 'jupiterx-image',
239
- 'column' => '4',
240
- 'label' => __( 'Video Fallback', 'jupiterx-core' ),
241
- 'cssClass' => 'for-video',
242
- ] );
243
- }
244
- }
245
-
246
- /**
247
- * Exclude fields.
248
- *
249
- * @since 1.0.0
250
- */
251
- protected function exclude_fields() {
252
- if ( ! empty( $this->exclude ) && in_array( 'image', $this->exclude, true ) ) {
253
- $this->exclude = [
254
- 'image',
255
- 'position',
256
- 'repeat',
257
- 'attachment',
258
- 'size',
259
- ];
260
- }
261
-
262
- parent::exclude_fields();
263
- }
264
-
265
- /**
266
- * Format CSS value from theme mod array value.
267
- *
268
- * @since 1.0.0
269
- *
270
- * @param array $value The field's value.
271
- * @param array $args The field's arguments.
272
- *
273
- * @return array The formatted properties.
274
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
275
- */
276
- public static function format_properties( $value, $args ) {
277
- $value = wp_parse_args(
278
- $value,
279
- [
280
- 'type' => 'classic',
281
- 'position' => 'top left',
282
- 'repeat' => 'no-repeat',
283
- 'attachment' => 'scroll',
284
- 'size' => 'auto',
285
- ]
286
- );
287
-
288
- if ( isset( $value['image'] ) && ! empty( $value['image'] ) ) {
289
- $value['image'] = "url({$value['image']})";
290
- }
291
-
292
- return $value;
293
- }
294
-
295
- /**
296
- * Format theme mod array value into a valid background value.
297
- *
298
- * @since 1.0.0
299
- *
300
- * @param array $value The field's value.
301
- *
302
- * @return string The formatted background value.
303
- */
304
- public static function format_value( $value ) {
305
- $value = array_merge(
306
- [
307
- 'type' => 'classic',
308
- 'color' => '',
309
- 'image' => '',
310
- 'repeat' => 'no-repeat',
311
- 'attachment' => '',
312
- 'position' => 'top left',
313
- 'gradient_type' => 'linear',
314
- 'angle' => '90',
315
- 'color_from' => 'transparent',
316
- 'color_to' => 'transparent',
317
- ],
318
- $value
319
- );
320
-
321
- if ( 'classic' === $value['type'] ) {
322
- if ( ! empty( $value['image'] ) ) {
323
- return sprintf(
324
- '%1$s %2$s %3$s %4$s %5$s',
325
- 'url(' . $value['image'] . ')',
326
- $value['color'],
327
- $value['attachment'],
328
- $value['repeat'],
329
- jupiterx_get_direction( $value['position'] )
330
- );
331
- }
332
-
333
- if ( ! empty( $value['color'] ) ) {
334
- return $value['color'];
335
- }
336
- }
337
-
338
- if ( 'gradient' === $value['type'] ) {
339
- if ( ! is_numeric( $value['angle'] ) ) {
340
- $value['angle'] = '90';
341
- }
342
-
343
- $gradient = 'radial' === $value['gradient_type'] ? sprintf( 'radial-gradient(%1$s, %2$s)', $value['color_from'], $value['color_to'] ) : sprintf( 'linear-gradient(%1$sdeg, %2$s, %3$s)', $value['angle'], $value['color_from'], $value['color_to'] );
344
-
345
- return $gradient;
346
- }
347
- }
348
-
349
-
350
- }
1
+ <?php
2
+ /**
3
+ * Handles background control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Background control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Group_Control_Background extends JupiterX_Customizer_Base_Group_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-background';
34
+
35
+ /**
36
+ * Set the fields for this control.
37
+ *
38
+ * @since 1.0.0
39
+ */
40
+ protected function set_fields() {
41
+ $this->add_field( 'label', [
42
+ 'type' => 'jupiterx-label',
43
+ 'label' => __( 'Background Color Type', 'jupiterx-core' ),
44
+ ] );
45
+
46
+ $this->add_field( 'type', [
47
+ 'type' => 'jupiterx-choose',
48
+ 'default' => 'classic',
49
+ 'choices' => [
50
+ 'classic' => [
51
+ 'label' => __( 'Color Type', 'jupiterx-core' ),
52
+ ],
53
+ 'gradient' => [
54
+ 'label' => __( 'Gradiant Type', 'jupiterx-core' ),
55
+ ],
56
+ ],
57
+ ] );
58
+
59
+ $this->add_field( 'color', [
60
+ 'type' => 'jupiterx-color',
61
+ 'label' => __( 'Background Color', 'jupiterx-core' ),
62
+ 'cssClass' => 'for-classic',
63
+ 'responsive' => true,
64
+ ] );
65
+
66
+ $this->add_field( 'image', [
67
+ 'type' => 'jupiterx-image',
68
+ 'label' => __( 'Background Image', 'jupiterx-core' ),
69
+ 'cssClass' => 'for-classic',
70
+ ] );
71
+
72
+ $this->add_field( 'position', [
73
+ 'type' => 'jupiterx-select',
74
+ 'label' => __( 'Position', 'jupiterx-core' ),
75
+ 'choices' => [
76
+ 'center' => __( 'Center Center', 'jupiterx-core' ),
77
+ 'center left' => __( 'Center Left', 'jupiterx-core' ),
78
+ 'center right' => __( 'Center Right', 'jupiterx-core' ),
79
+ 'top' => __( 'Top Center', 'jupiterx-core' ),
80
+ 'top left' => __( 'Top Left', 'jupiterx-core' ),
81
+ 'top right' => __( 'Top Right', 'jupiterx-core' ),
82
+ 'bottom' => __( 'Bottom Center', 'jupiterx-core' ),
83
+ 'bottom left' => __( 'Bottom Left', 'jupiterx-core' ),
84
+ 'bottom right' => __( 'Bottom Right', 'jupiterx-core' ),
85
+ ],
86
+ 'cssClass' => 'for-classic',
87
+ ] );
88
+
89
+ $this->add_field( 'repeat', [
90
+ 'type' => 'jupiterx-select',
91
+ 'label' => __( 'Repeat', 'jupiterx-core' ),
92
+ 'default' => 'no-repeat',
93
+ 'choices' => [
94
+ 'repeat' => __( 'Repeat', 'jupiterx-core' ),
95
+ 'repeat-x' => __( 'Repeat-x', 'jupiterx-core' ),
96
+ 'repeat-y' => __( 'Repeat-y', 'jupiterx-core' ),
97
+ 'no-repeat' => __( 'No-repeat', 'jupiterx-core' ),
98
+ ],
99
+ 'cssClass' => 'for-classic',
100
+ ] );
101
+
102
+ $this->add_field( 'attachment', [
103
+ 'type' => 'jupiterx-choose',
104
+ 'text' => __( 'Fixed', 'jupiterx-core' ),
105
+ 'default' => 'scroll',
106
+ 'inline' => true,
107
+ 'choices' => [
108
+ 'fixed' => [
109
+ 'icon' => 'check',
110
+ ],
111
+ 'scroll' => [
112
+ 'icon' => 'x',
113
+ ],
114
+ ],
115
+ 'cssClass' => 'for-classic',
116
+ ] );
117
+
118
+ $this->add_field( 'size', [
119
+ 'type' => 'jupiterx-choose',
120
+ 'text' => __( 'Cover', 'jupiterx-core' ),
121
+ 'default' => 'auto',
122
+ 'inline' => true,
123
+ 'choices' => [
124
+ 'cover' => [
125
+ 'icon' => 'check',
126
+ ],
127
+ 'auto' => [
128
+ 'icon' => 'x',
129
+ ],
130
+ ],
131
+ 'cssClass' => 'for-classic',
132
+ ] );
133
+
134
+ $this->add_field( 'divider', [
135
+ 'type' => 'jupiterx-divider',
136
+ 'dividerType' => 'empty',
137
+ 'cssClass' => 'for-gradient jupiterx-divider-control-empty',
138
+ ] );
139
+
140
+ $gradient_colors = [
141
+ 'color_from' => [
142
+ 'type' => 'jupiterx-color',
143
+ 'label' => is_rtl() ? __( 'Direction Arrow', 'jupiterx-core' ) : __( 'Background Color', 'jupiterx-core' ),
144
+ 'cssClass' => 'for-gradient',
145
+ ],
146
+ 'color_to' => [
147
+ 'type' => 'jupiterx-color',
148
+ 'label' => is_rtl() ? __( 'Background Color', 'jupiterx-core' ) : __( 'Direction Arrow', 'jupiterx-core' ),
149
+ 'cssClass' => 'for-gradient',
150
+ ],
151
+ ];
152
+
153
+ if ( is_rtl() ) {
154
+ $gradient_colors = array_reverse( $gradient_colors );
155
+ }
156
+
157
+ foreach ( $gradient_colors as $key => $value ) {
158
+ $this->add_field( $key, $value );
159
+ }
160
+
161
+ $this->add_field( 'gradient_type', [
162
+ 'type' => 'jupiterx-choose',
163
+ 'default' => 'linear',
164
+ 'choices' => [
165
+ 'linear' => [
166
+ 'label' => __( 'Linear', 'jupiterx-core' ),
167
+ ],
168
+ 'radial' => [
169
+ 'label' => __( 'Radial', 'jupiterx-core' ),
170
+ ],
171
+ ],
172
+ 'cssClass' => 'for-gradient',
173
+ ] );
174
+
175
+ $this->add_field( 'angle', [
176
+ 'type' => 'jupiterx-text',
177
+ 'inputType' => 'number',
178
+ 'label' => __( 'Angle', 'jupiterx-core' ),
179
+ 'inputAttrs' => [
180
+ 'placeholder' => 90,
181
+ ],
182
+ 'default' => 90,
183
+ 'cssClass' => 'for-gradient',
184
+ ] );
185
+ }
186
+
187
+ /**
188
+ * Include fields.
189
+ *
190
+ * @since 1.0.0
191
+ */
192
+ protected function include_fields() {
193
+ if ( empty( $this->include ) ) {
194
+ return;
195
+ }
196
+
197
+ $include = $this->include;
198
+
199
+ if ( in_array( 'video', $include, true ) ) {
200
+ $this->update_field( 'type', [
201
+ 'choices' => [
202
+ 'classic' => [
203
+ 'label' => __( 'Color Type', 'jupiterx-core' ),
204
+ ],
205
+ 'gradient' => [
206
+ 'label' => __( 'Color Type', 'jupiterx-core' ),
207
+ ],
208
+ 'video' => [
209
+ 'label' => __( 'Video Type', 'jupiterx-core' ),
210
+ ],
211
+ ],
212
+ ] );
213
+
214
+ $this->add_field( 'video_divider', [
215
+ 'type' => 'jupiterx-divider',
216
+ 'dividerType' => 'empty',
217
+ 'cssClass' => 'for-video',
218
+ ] );
219
+
220
+ $this->add_field( 'video_link', [
221
+ 'type' => 'jupiterx-text',
222
+ 'inputType' => 'url',
223
+ 'inputAttrs' => [
224
+ 'placeholder' => __( 'Social or Self hosted video link', 'jupiterx-core' ),
225
+ ],
226
+ 'label' => __( 'Video Link', 'jupiterx-core' ),
227
+ 'cssClass' => 'for-video',
228
+ ] );
229
+
230
+ $this->add_field( 'video_fallback', [
231
+ 'type' => 'jupiterx-image',
232
+ 'label' => __( 'Video Fallback', 'jupiterx-core' ),
233
+ 'cssClass' => 'for-video',
234
+ ] );
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Exclude fields.
240
+ *
241
+ * @since 1.0.0
242
+ */
243
+ protected function exclude_fields() {
244
+ if ( ! empty( $this->exclude ) && in_array( 'image', $this->exclude, true ) ) {
245
+ $this->exclude = [
246
+ 'image',
247
+ 'position',
248
+ 'repeat',
249
+ 'attachment',
250
+ 'size',
251
+ ];
252
+ }
253
+
254
+ parent::exclude_fields();
255
+ }
256
+
257
+ /**
258
+ * Format CSS value from theme mod array value.
259
+ *
260
+ * @since 1.0.0
261
+ *
262
+ * @param array $value The field's value.
263
+ * @param array $args The field's arguments.
264
+ *
265
+ * @return array The formatted properties.
266
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
267
+ */
268
+ public static function format_properties( $value, $args ) {
269
+ $value = wp_parse_args(
270
+ $value,
271
+ [
272
+ 'type' => 'classic',
273
+ 'position' => 'top left',
274
+ 'repeat' => 'no-repeat',
275
+ 'attachment' => 'scroll',
276
+ 'size' => 'auto',
277
+ ]
278
+ );
279
+
280
+ if ( isset( $value['image'] ) && ! empty( $value['image'] ) ) {
281
+ $value['image'] = "url({$value['image']})";
282
+ }
283
+
284
+ return $value;
285
+ }
286
+
287
+ /**
288
+ * Format theme mod array value into a valid background value.
289
+ *
290
+ * @since 1.0.0
291
+ *
292
+ * @param array $value The field's value.
293
+ *
294
+ * @return string The formatted background value.
295
+ */
296
+ public static function format_value( $value ) {
297
+ $value = array_merge(
298
+ [
299
+ 'type' => 'classic',
300
+ 'color' => '',
301
+ 'image' => '',
302
+ 'repeat' => 'no-repeat',
303
+ 'attachment' => '',
304
+ 'position' => 'top left',
305
+ 'gradient_type' => 'linear',
306
+ 'angle' => '90',
307
+ 'color_from' => 'transparent',
308
+ 'color_to' => 'transparent',
309
+ ],
310
+ $value
311
+ );
312
+
313
+ if ( 'classic' === $value['type'] ) {
314
+ if ( ! empty( $value['image'] ) ) {
315
+ return sprintf(
316
+ '%1$s %2$s %3$s %4$s %5$s',
317
+ 'url(' . $value['image'] . ')',
318
+ $value['color'],
319
+ $value['attachment'],
320
+ $value['repeat'],
321
+ jupiterx_get_direction( $value['position'] )
322
+ );
323
+ }
324
+
325
+ if ( ! empty( $value['color'] ) ) {
326
+ return $value['color'];
327
+ }
328
+ }
329
+
330
+ if ( 'gradient' === $value['type'] ) {
331
+ if ( ! is_numeric( $value['angle'] ) ) {
332
+ $value['angle'] = '90';
333
+ }
334
+
335
+ $gradient = 'radial' === $value['gradient_type'] ? sprintf( 'radial-gradient(%1$s, %2$s)', $value['color_from'], $value['color_to'] ) : sprintf( 'linear-gradient(%1$sdeg, %2$s, %3$s)', $value['angle'], $value['color_from'], $value['color_to'] );
336
+
337
+ return $gradient;
338
+ }
339
+ }
340
+
341
+
342
+ }
 
 
 
 
 
 
 
 
includes/customizer/api/includes/control/group/class-border.php CHANGED
@@ -1,107 +1,102 @@
1
- <?php
2
- /**
3
- * Handles border control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Border control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Group_Control_Border extends JupiterX_Customizer_Base_Group_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-border';
34
-
35
- /**
36
- * Set the fields for this control.
37
- *
38
- * @since 1.0.0
39
- */
40
- protected function set_fields() {
41
- $this->add_field( 'style', [
42
- 'type' => 'jupiterx-select',
43
- 'icon' => 'border-style',
44
- 'unit' => 'px',
45
- 'column' => '5',
46
- 'default' => 'solid',
47
- 'choices' => [
48
- 'dashed' => __( 'Dashed', 'jupiterx-core' ),
49
- 'dotted' => __( 'Dotted', 'jupiterx-core' ),
50
- 'solid' => __( 'Solid', 'jupiterx-core' ),
51
- ],
52
- ] );
53
-
54
- $this->add_field( 'size', [
55
- 'type' => 'jupiterx-input',
56
- 'icon' => 'border-size',
57
- 'units' => [ 'px', '%', 'em', 'rem' ],
58
- 'column' => '4',
59
- ] );
60
-
61
- $this->add_field( 'width', [
62
- 'type' => 'jupiterx-input',
63
- 'icon' => 'border',
64
- 'units' => [ 'px' ],
65
- 'column' => '5',
66
- 'responsive' => true,
67
- ] );
68
-
69
- $this->add_field( 'radius', [
70
- 'type' => 'jupiterx-input',
71
- 'icon' => 'corner-radius',
72
- 'units' => [ 'px', '%' ],
73
- 'column' => '4',
74
- ] );
75
-
76
- $this->add_field( 'color', [
77
- 'type' => 'jupiterx-color',
78
- 'icon' => 'border-color',
79
- 'column' => '3',
80
- ] );
81
- }
82
-
83
- /**
84
- * Format CSS value from theme mod array value.
85
- *
86
- * Add unit to border width.
87
- *
88
- * @since 1.0.0
89
- *
90
- * @param array $value The field's value.
91
- * @param array $args The field's arguments.
92
- *
93
- * @return array The formatted properties.
94
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
95
- */
96
- public static function format_properties( $value, $args ) {
97
- $with_unit = [ 'width', 'radius', 'size' ];
98
-
99
- foreach ( $with_unit as $property ) {
100
- if ( isset( $value[ $property ] ) && ! empty( $value[ $property ] ) ) {
101
- $value[ $property ] = JupiterX_Customizer_Control_Input::format_value( $value[ $property ] );
102
- }
103
- }
104
-
105
- return $value;
106
- }
107
- }
1
+ <?php
2
+ /**
3
+ * Handles border control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Border control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Group_Control_Border extends JupiterX_Customizer_Base_Group_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-border';
34
+
35
+ /**
36
+ * Set the fields for this control.
37
+ *
38
+ * @since 1.0.0
39
+ */
40
+ protected function set_fields() {
41
+ $this->add_field( 'style', [
42
+ 'type' => 'jupiterx-select',
43
+ 'label' => __( 'Border Style', 'jupiterx-core' ),
44
+ 'unit' => 'px',
45
+ 'default' => 'solid',
46
+ 'choices' => [
47
+ 'dashed' => __( 'Dashed', 'jupiterx-core' ),
48
+ 'dotted' => __( 'Dotted', 'jupiterx-core' ),
49
+ 'solid' => __( 'Solid', 'jupiterx-core' ),
50
+ ],
51
+ ] );
52
+
53
+ $this->add_field( 'size', [
54
+ 'type' => 'jupiterx-input',
55
+ 'label' => __( 'Width', 'jupiterx-core' ),
56
+ 'units' => [ 'px', '%', 'em', 'rem' ],
57
+ ] );
58
+
59
+ $this->add_field( 'width', [
60
+ 'type' => 'jupiterx-input',
61
+ 'label' => __( 'Border Width', 'jupiterx-core' ),
62
+ 'units' => [ 'px' ],
63
+ 'responsive' => true,
64
+ ] );
65
+
66
+ $this->add_field( 'radius', [
67
+ 'type' => 'jupiterx-input',
68
+ 'label' => __( 'Border Radius', 'jupiterx-core' ),
69
+ 'units' => [ 'px', '%', 'rem' ],
70
+ ] );
71
+
72
+ $this->add_field( 'color', [
73
+ 'type' => 'jupiterx-color',
74
+ 'label' => __( 'Border Color', 'jupiterx-core' ),
75
+ ] );
76
+ }
77
+
78
+ /**
79
+ * Format CSS value from theme mod array value.
80
+ *
81
+ * Add unit to border width.
82
+ *
83
+ * @since 1.0.0
84
+ *
85
+ * @param array $value The field's value.
86
+ * @param array $args The field's arguments.
87
+ *
88
+ * @return array The formatted properties.
89
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
90
+ */
91
+ public static function format_properties( $value, $args ) {
92
+ $with_unit = [ 'width', 'radius', 'size' ];
93
+
94
+ foreach ( $with_unit as $property ) {
95
+ if ( isset( $value[ $property ] ) && ! empty( $value[ $property ] ) ) {
96
+ $value[ $property ] = JupiterX_Customizer_Control_Input::format_value( $value[ $property ] );
97
+ }
98
+ }
99
+
100
+ return $value;
101
+ }
102
+ }
 
 
 
 
 
includes/customizer/api/includes/control/group/class-box-shadow.php CHANGED
@@ -1,136 +1,127 @@
1
- <?php
2
- /**
3
- * Handles box shadow control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Box_Shadow control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Group_Control_Box_Shadow extends JupiterX_Customizer_Base_Group_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-box-shadow';
34
-
35
- /**
36
- * Set the fields for this control.
37
- *
38
- * @since 1.0.0
39
- */
40
- protected function set_fields() {
41
- $this->add_field( 'horizontal', [
42
- 'type' => 'jupiterx-text',
43
- 'inputType' => 'number',
44
- 'label' => __( 'Horizontal', 'jupiterx-core' ),
45
- 'inputAttrs' => [ 'placeholder' => 0 ],
46
- 'column' => '3',
47
- 'icon' => 'box-shadow-x',
48
- ] );
49
-
50
- $this->add_field( 'vertical', [
51
- 'type' => 'jupiterx-text',
52
- 'inputType' => 'number',
53
- 'label' => __( 'Vertical', 'jupiterx-core' ),
54
- 'inputAttrs' => [ 'placeholder' => 0 ],
55
- 'column' => '3',
56
- 'icon' => 'box-shadow-y',
57
- ] );
58
-
59
- $this->add_field( 'blur', [
60
- 'type' => 'jupiterx-text',
61
- 'inputType' => 'number',
62
- 'label' => __( 'Blur', 'jupiterx-core' ),
63
- 'inputAttrs' => [ 'placeholder' => 0 ],
64
- 'column' => '3',
65
- 'icon' => 'box-shadow-blur',
66
- ] );
67
-
68
- $this->add_field( 'spread', [
69
- 'type' => 'jupiterx-text',
70
- 'inputType' => 'number',
71
- 'label' => __( 'Spread', 'jupiterx-core' ),
72
- 'inputAttrs' => [ 'placeholder' => 0 ],
73
- 'column' => '3',
74
- 'icon' => 'box-shadow-blur',
75
- ] );
76
-
77
- $this->add_field( 'position', [
78
- 'type' => 'jupiterx-choose',
79
- 'column' => '4',
80
- 'label' => __( 'Position', 'jupiterx-core' ),
81
- 'default' => '',
82
- 'choices' => [
83
- '' => [
84
- 'label' => __( 'Linear', 'jupiterx-core' ),
85
- ],
86
- 'inset' => [
87
- 'label' => __( 'Inset', 'jupiterx-core' ),
88
- ],
89
- ],
90
- ] );
91
-
92
- $this->add_field( 'color', [
93
- 'type' => 'jupiterx-color',
94
- 'label' => __( 'Color', 'jupiterx-core' ),
95
- 'column' => '8',
96
- 'icon' => 'box-shadow-color',
97
- ] );
98
- }
99
-
100
- /**
101
- * Format theme mod array value into a valid box shadow value.
102
- *
103
- * @since 1.0.0
104
- *
105
- * @param array $value The field's value.
106
- *
107
- * @return string The formatted box shadow value.
108
- */
109
- public static function format_value( $value ) {
110
- $value = array_merge(
111
- [
112
- 'horizontal' => 0,
113
- 'vertical' => 0,
114
- 'blur' => 0,
115
- 'spread' => 0,
116
- 'color' => '#0000',
117
- 'position' => '',
118
- 'unit' => 'px',
119
- ],
120
- $value
121
- );
122
-
123
- $value = sprintf(
124
- '%1$s%7$s %2$s%7$s %3$s%7$s %4$s%7$s %5$s %6$s',
125
- $value['horizontal'],
126
- $value['vertical'],
127
- $value['blur'],
128
- $value['spread'],
129
- $value['color'],
130
- $value['position'],
131
- $value['unit']
132
- );
133
-
134
- return $value;
135
- }
136
- }
1
+ <?php
2
+ /**
3
+ * Handles box shadow control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Box_Shadow control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Group_Control_Box_Shadow extends JupiterX_Customizer_Base_Group_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-box-shadow';
34
+
35
+ /**
36
+ * Set the fields for this control.
37
+ *
38
+ * @since 1.0.0
39
+ */
40
+ protected function set_fields() {
41
+ $this->add_field( 'horizontal', [
42
+ 'type' => 'jupiterx-text',
43
+ 'inputType' => 'number',
44
+ 'label' => __( 'Horizontal', 'jupiterx-core' ),
45
+ 'inputAttrs' => [
46
+ 'placeholder' => 0,
47
+ ],
48
+ ] );
49
+
50
+ $this->add_field( 'vertical', [
51
+ 'type' => 'jupiterx-text',
52
+ 'inputType' => 'number',
53
+ 'label' => __( 'Vertical', 'jupiterx-core' ),
54
+ 'inputAttrs' => [ 'placeholder' => 0 ],
55
+ ] );
56
+
57
+ $this->add_field( 'blur', [
58
+ 'type' => 'jupiterx-text',
59
+ 'inputType' => 'number',
60
+ 'label' => __( 'Blur', 'jupiterx-core' ),
61
+ 'inputAttrs' => [ 'placeholder' => 0 ],
62
+ ] );
63
+
64
+ $this->add_field( 'spread', [
65
+ 'type' => 'jupiterx-text',
66
+ 'inputType' => 'number',
67
+ 'label' => __( 'Spread', 'jupiterx-core' ),
68
+ 'inputAttrs' => [ 'placeholder' => 0 ],
69
+ ] );
70
+
71
+ $this->add_field( 'position', [
72
+ 'type' => 'jupiterx-choose',
73
+ 'label' => __( 'Position', 'jupiterx-core' ),
74
+ 'default' => '',
75
+ 'choices' => [
76
+ '' => [
77
+ 'label' => __( 'Outline', 'jupiterx-core' ),
78
+ ],
79
+ 'inset' => [
80
+ 'label' => __( 'Inset', 'jupiterx-core' ),
81
+ ],
82
+ ],
83
+ ] );
84
+
85
+ $this->add_field( 'color', [
86
+ 'type' => 'jupiterx-color',
87
+ 'label' => __( 'Color', 'jupiterx-core' ),
88
+ ] );
89
+ }
90
+
91
+ /**
92
+ * Format theme mod array value into a valid box shadow value.
93
+ *
94
+ * @since 1.0.0
95
+ *
96
+ * @param array $value The field's value.
97
+ *
98
+ * @return string The formatted box shadow value.
99
+ */
100
+ public static function format_value( $value ) {
101
+ $value = array_merge(
102
+ [
103
+ 'horizontal' => 0,
104
+ 'vertical' => 0,
105
+ 'blur' => 0,
106
+ 'spread' => 0,
107
+ 'color' => '#0000',
108
+ 'position' => '',
109
+ 'unit' => 'px',
110
+ ],
111
+ $value
112
+ );
113
+
114
+ $value = sprintf(
115
+ '%1$s%7$s %2$s%7$s %3$s%7$s %4$s%7$s %5$s %6$s',
116
+ $value['horizontal'],
117
+ $value['vertical'],
118
+ $value['blur'],
119
+ $value['spread'],
120
+ $value['color'],
121
+ $value['position'],
122
+ $value['unit']
123
+ );
124
+
125
+ return $value;
126
+ }
127
+ }
 
 
 
 
 
 
 
 
 
includes/customizer/api/includes/control/group/class-typography.php CHANGED
@@ -1,204 +1,199 @@
1
- <?php
2
- /**
3
- * Handles typography control class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Typography control class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Group_Control_Typography extends JupiterX_Customizer_Base_Group_Control {
25
-
26
- /**
27
- * Control's type.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'jupiterx-typography';
34
-
35
- /**
36
- * Set the fields for this control.
37
- *
38
- * @since 1.0.0
39
- */
40
- protected function set_fields() {
41
- $this->add_field( 'font_family', [
42
- 'type' => 'jupiterx-font',
43
- 'column' => '5',
44
- 'icon' => 'font-family',
45
- 'placeholder' => __( 'Default', 'jupiterx-core' ),
46
- ] );
47
-
48
- $this->add_field( 'font_size', [
49
- 'type' => 'jupiterx-input',
50
- 'column' => '4',
51
- 'icon' => 'font-size',
52
- 'units' => [ 'px', 'em', 'rem' ],
53
- 'defaultUnit' => 'rem',
54
- 'responsive' => true,
55
- ] );
56
-
57
- $this->add_field( 'color', [
58
- 'type' => 'jupiterx-color',
59
- 'column' => '3',
60
- 'icon' => 'font-color',
61
- ] );
62
-
63
- $this->add_field( 'font_weight', [
64
- 'type' => 'jupiterx-select',
65
- 'column' => '5',
66
- 'icon' => 'font-weight',
67
- 'placeholder' => __( 'Default', 'jupiterx-core' ),
68
- 'choices' => $this->get_font_weights(),
69
- ] );
70
-
71
- $this->add_field( 'font_style', [
72
- 'type' => 'jupiterx-choose',
73
- 'column' => '3',
74
- 'default' => 'normal',
75
- 'choices' => [
76
- 'normal' => [
77
- 'icon' => 'font-style-normal',
78
- ],
79
- 'italic' => [
80
- 'icon' => 'font-style-italic',
81
- ],
82
- ],
83
- ] );
84
-
85
- $this->add_field( 'line_height', [
86
- 'type' => 'jupiterx-input',
87
- 'column' => '4',
88
- 'icon' => 'line-height',
89
- 'units' => [ '-', 'px', 'em', 'rem' ],
90
- 'defaultUnit' => '-',
91
- ] );
92
-
93
- $this->add_field( 'letter_spacing', [
94
- 'type' => 'jupiterx-input',
95
- 'column' => '4',
96
- 'icon' => 'letter-spacing',
97
- 'inputAttrs' => [
98
- 'min' => -1000,
99
- ],
100
- 'units' => [ 'px', 'em', 'rem' ],
101
- 'defaultUnit' => 'px',
102
- ] );
103
-
104
- $this->add_field( 'text_transform', [
105
- 'type' => 'jupiterx-select',
106
- 'column' => '5',
107
- 'icon' => 'text-transform',
108
- 'placeholder' => __( 'Default', 'jupiterx-core' ),
109
- 'choices' => [
110
- 'capitalize' => __( 'Capitalize', 'jupiterx-core' ),
111
- 'lowercase' => __( 'Lowercase', 'jupiterx-core' ),
112
- 'uppercase' => __( 'Uppercase', 'jupiterx-core' ),
113
- ],
114
- ] );
115
- }
116
-
117
- /**
118
- * Get safe fonts.
119
- *
120
- * @since 1.0.0
121
- *
122
- * @return array Safe fonts.
123
- */
124
- protected function get_safe_fonts() {
125
- $font_family = [];
126
-
127
- $safe_fonts = [
128
- 'HelveticaNeue-Light, Helvetica Neue Light, Helvetica Neue, Helvetica, Arial, "Lucida Grande", sans-serif',
129
- 'Arial, Helvetica, sans-serif',
130
- 'Arial Black, Gadget, sans-serif',
131
- 'Bookman Old Style, serif',
132
- 'Courier, monospace',
133
- 'Courier New, Courier, monospace',
134
- 'Garamond, serif',
135
- 'Georgia, serif',
136
- 'Impact, Charcoal, sans-serif',
137
- 'Lucida Console, Monaco, monospace',
138
- 'Lucida Grande, Lucida Sans Unicode, sans-serif',
139
- 'MS Sans Serif, Geneva, sans-serif',
140
- 'MS Serif, New York, sans-serif',
141
- 'Palatino Linotype, Book Antiqua, Palatino, serif',
142
- 'Tahoma, Geneva, sans-serif',
143
- 'Times New Roman, Times, serif',
144
- 'Trebuchet MS, Helvetica, sans-serif',
145
- 'Verdana, Geneva, sans-serif',
146
- 'Comic Sans MS, cursive',
147
- ];
148
-
149
- foreach ( $safe_fonts as $font ) {
150
- $font_family[ $font ] = $font;
151
- }
152
-
153
- return $font_family;
154
- }
155
-
156
- /**
157
- * Get font weights.
158
- *
159
- * @since 1.0.0
160
- */
161
- protected function get_font_weights() {
162
- $font_weights = [
163
- 'normal' => __( 'Normal', 'jupiterx-core' ),
164
- 'bold' => __( 'Bold', 'jupiterx-core' ),
165
- 'bolder' => __( 'Bolder', 'jupiterx-core' ),
166
- 'lighter' => __( 'Lighter', 'jupiterx-core' ),
167
- '100' => __( '100', 'jupiterx-core' ),
168
- '200' => __( '200', 'jupiterx-core' ),
169
- '300' => __( '300', 'jupiterx-core' ),
170
- '400' => __( '400', 'jupiterx-core' ),
171
- '500' => __( '500', 'jupiterx-core' ),
172
- '600' => __( '600', 'jupiterx-core' ),
173
- '700' => __( '700', 'jupiterx-core' ),
174
- '800' => __( '800', 'jupiterx-core' ),
175
- '900' => __( '900', 'jupiterx-core' ),
176
- ];
177
-
178
- return $font_weights;
179
- }
180
-
181
- /**
182
- * Format CSS value from theme mod array value.
183
- *
184
- * @since 1.0.0
185
- *
186
- * @param array $value The field's value.
187
- * @param array $args The field's arguments.
188
- *
189
- * @return array The formatted properties.
190
- *
191
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
192
- */
193
- public static function format_properties( $value, $args ) {
194
- $with_unit = [ 'font_size', 'line_height', 'letter_spacing' ];
195
-
196
- foreach ( $with_unit as $property ) {
197
- if ( isset( $value[ $property ] ) && ! empty( $value[ $property ] ) ) {
198
- $value[ $property ] = JupiterX_Customizer_Control_Input::format_value( $value[ $property ] );
199
- }
200
- }
201
-
202
- return $value;
203
- }
204
- }
1
+ <?php
2
+ /**
3
+ * Handles typography control class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Typography control class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Group_Control_Typography extends JupiterX_Customizer_Base_Group_Control {
25
+
26
+ /**
27
+ * Control's type.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'jupiterx-typography';
34
+
35
+ /**
36
+ * Set the fields for this control.
37
+ *
38
+ * @since 1.0.0
39
+ */
40
+ protected function set_fields() {
41
+ $this->add_field( 'font_family', [
42
+ 'type' => 'jupiterx-font',
43
+ 'label' => __( 'Font Family', 'jupiterx-core' ),
44
+ 'placeholder' => __( 'Default', 'jupiterx-core' ),
45
+ ] );
46
+
47
+ $this->add_field( 'font_size', [
48
+ 'type' => 'jupiterx-input',
49
+ 'label' => __( 'Font Size', 'jupiterx-core' ),
50
+ 'units' => [ 'px', 'em', 'rem' ],
51
+ 'defaultUnit' => 'rem',
52
+ 'responsive' => true,
53
+ ] );
54
+
55
+ $this->add_field( 'color', [
56
+ 'type' => 'jupiterx-color',
57
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
58
+ ] );
59
+
60
+ $this->add_field( 'font_weight', [
61
+ 'type' => 'jupiterx-select',
62
+ 'exclude_reload' => true,
63
+ 'label' => __( 'Font Weight', 'jupiterx-core' ),
64
+ 'placeholder' => __( 'Default', 'jupiterx-core' ),
65
+ 'choices' => $this->get_font_weights(),
66
+ ] );
67
+
68
+ $this->add_field( 'font_style', [
69
+ 'type' => 'jupiterx-select',
70
+ 'default' => 'normal',
71
+ 'label' => __( 'Font Style', 'jupiterx-core' ),
72
+ 'choices' => [
73
+ 'normal' => __( 'Normal', 'jupiterx-core' ),
74
+ 'italic' => __( 'Italic', 'jupiterx-core' ),
75
+ ],
76
+ ] );
77
+
78
+ $this->add_field( 'line_height', [
79
+ 'type' => 'jupiterx-input',
80
+ 'label' => __( 'Line Height', 'jupiterx-core' ),
81
+ 'units' => [ '-', 'px', 'em', 'rem' ],
82
+ 'defaultUnit' => '-',
83
+ 'inputAttrs' => [
84
+ 'min' => -100,
85
+ 'max' => 100,
86
+ ],
87
+ ] );
88
+
89
+ $this->add_field( 'letter_spacing', [
90
+ 'type' => 'jupiterx-input',
91
+ 'label' => __( 'Letter Spacing', 'jupiterx-core' ),
92
+ 'inputAttrs' => [
93
+ 'min' => -100,
94
+ 'max' => 100,
95
+ ],
96
+ 'units' => [ 'px', 'em', 'rem' ],
97
+ 'defaultUnit' => 'px',
98
+ ] );
99
+
100
+ $this->add_field( 'text_transform', [
101
+ 'type' => 'jupiterx-select',
102
+ 'label' => __( 'Text Transform', 'jupiterx-core' ),
103
+ 'placeholder' => __( 'Default', 'jupiterx-core' ),
104
+ 'choices' => [
105
+ 'capitalize' => __( 'Capitalize', 'jupiterx-core' ),
106
+ 'lowercase' => __( 'Lowercase', 'jupiterx-core' ),
107
+ 'uppercase' => __( 'Uppercase', 'jupiterx-core' ),
108
+ ],
109
+ ] );
110
+ }
111
+
112
+ /**
113
+ * Get safe fonts.
114
+ *
115
+ * @since 1.0.0
116
+ *
117
+ * @return array Safe fonts.
118
+ */
119
+ protected function get_safe_fonts() {
120
+ $font_family = [];
121
+
122
+ $safe_fonts = [
123
+ 'HelveticaNeue-Light, Helvetica Neue Light, Helvetica Neue, Helvetica, Arial, "Lucida Grande", sans-serif',
124
+ 'Arial, Helvetica, sans-serif',
125
+ 'Arial Black, Gadget, sans-serif',
126
+ 'Bookman Old Style, serif',
127
+ 'Courier, monospace',
128
+ 'Courier New, Courier, monospace',
129
+ 'Garamond, serif',
130
+ 'Georgia, serif',
131
+ 'Impact, Charcoal, sans-serif',
132
+ 'Lucida Console, Monaco, monospace',
133
+ 'Lucida Grande, Lucida Sans Unicode, sans-serif',
134
+ 'MS Sans Serif, Geneva, sans-serif',
135
+ 'MS Serif, New York, sans-serif',
136
+ 'Palatino Linotype, Book Antiqua, Palatino, serif',
137
+ 'Tahoma, Geneva, sans-serif',
138
+ 'Times New Roman, Times, serif',
139
+ 'Trebuchet MS, Helvetica, sans-serif',
140
+ 'Verdana, Geneva, sans-serif',
141
+ 'Comic Sans MS, cursive',
142
+ ];
143
+
144
+ foreach ( $safe_fonts as $font ) {
145
+ $font_family[ $font ] = $font;
146
+ }
147
+
148
+ return $font_family;
149
+ }
150
+
151
+ /**
152
+ * Get font weights.
153
+ *
154
+ * @since 1.0.0
155
+ */
156
+ protected function get_font_weights() {
157
+ $font_weights = [
158
+ 'normal' => __( 'Normal', 'jupiterx-core' ),
159
+ 'bold' => __( 'Bold', 'jupiterx-core' ),
160
+ 'bolder' => __( 'Bolder', 'jupiterx-core' ),
161
+ 'lighter' => __( 'Lighter', 'jupiterx-core' ),
162
+ '100' => __( '100', 'jupiterx-core' ),
163
+ '200' => __( '200', 'jupiterx-core' ),
164
+ '300' => __( '300', 'jupiterx-core' ),
165
+ '400' => __( '400', 'jupiterx-core' ),
166
+ '500' => __( '500', 'jupiterx-core' ),
167
+ '600' => __( '600', 'jupiterx-core' ),
168
+ '700' => __( '700', 'jupiterx-core' ),
169
+ '800' => __( '800', 'jupiterx-core' ),
170
+ '900' => __( '900', 'jupiterx-core' ),
171
+ ];
172
+
173
+ return $font_weights;
174
+ }
175
+
176
+ /**
177
+ * Format CSS value from theme mod array value.
178
+ *
179
+ * @since 1.0.0
180
+ *
181
+ * @param array $value The field's value.
182
+ * @param array $args The field's arguments.
183
+ *
184
+ * @return array The formatted properties.
185
+ *
186
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
187
+ */
188
+ public static function format_properties( $value, $args ) {
189
+ $with_unit = [ 'font_size', 'line_height', 'letter_spacing' ];
190
+
191
+ foreach ( $with_unit as $property ) {
192
+ if ( isset( $value[ $property ] ) && ! empty( $value[ $property ] ) ) {
193
+ $value[ $property ] = JupiterX_Customizer_Control_Input::format_value( $value[ $property ] );
194
+ }
195
+ }
196
+
197
+ return $value;
198
+ }
199
+ }
 
 
 
 
 
includes/customizer/api/includes/section/class-link.php CHANGED
@@ -1,103 +1,103 @@
1
- <?php
2
- /**
3
- * This handles customizer custom link section.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.3.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Customizer Link class.
17
- *
18
- * This is a special section for rendering section as a static link.
19
- *
20
- * @since 1.3.0
21
- * @ignore
22
- * @access private
23
- *
24
- * @package JupiterX\Framework\API\Customizer
25
- */
26
- class JupiterX_Customizer_Section_Link extends WP_Customize_Section {
27
-
28
- /**
29
- * Type of this section.
30
- *
31
- * @since 1.3.0
32
- *
33
- * @var string
34
- */
35
- public $type = 'kirki-jupiterx-link';
36
-
37
- /**
38
- * Url of this section.
39
- *
40
- * @since 1.3.0
41
- *
42
- * @var string
43
- */
44
- public $jupiterx_url = '#';
45
-
46
- /**
47
- * Icon of this section.
48
- *
49
- * @since 1.3.0
50
- *
51
- * @var string
52
- */
53
- public $jupiterx_icon = '';
54
-
55
- /**
56
- * Upgrade link.
57
- *
58
- * @since 1.3.0
59
- *
60
- * @var string
61
- */
62
- public $upgrade_link = '';
63
-
64
- /**
65
- * Gather the parameters passed to client JavaScript via JSON.
66
- *
67
- * @since 1.3.0
68
- *
69
- * @return array The array to be exported to the client as JSON.
70
- */
71
- public function json() {
72
- $json = parent::json();
73
- $json['jupiterx_url'] = esc_url( $this->jupiterx_url );
74
- $json['jupiterx_icon'] = $this->jupiterx_icon;
75
- $json['upgradeLink'] = $this->upgrade_link;
76
-
77
- return $json;
78
- }
79
-
80
- /**
81
- * An Underscore (JS) template for rendering this section.
82
- *
83
- * @since 1.3.0
84
- * @SuppressWarnings(PHPMD.ElseExpression)
85
- */
86
- protected function render_template() {
87
- ?>
88
- <li id="jupiterx-popup-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}">
89
- <?php if ( jupiterx_is_premium() ) : ?>
90
- <a href="{{ data.jupiterx_url }}" class="accordion-section-title jupiterx-upgrade-modal-trigger" tabindex="0" target="_blank" <# if ( data.upgradeLink ) { #> data-upgrade-link="{{ data.upgradeLink }}" <# } #>>
91
- <?php else : ?>
92
- <a href="{{ data.upgradeLink }}" class="accordion-section-title" tabindex="0" target="_blank">
93
- <?php endif; ?>
94
- <# if ( data.jupiterx_icon ) { #>
95
- <span class="{{ data.jupiterx_icon }}"></span>
96
- <# } #>
97
- {{ data.title }}
98
- <span class="screen-reader-text"><?php esc_html_e( 'Press return or enter to open this section', 'jupiterx-core' ); ?></span>
99
- </a>
100
- </li>
101
- <?php
102
- }
103
- }
1
+ <?php
2
+ /**
3
+ * This handles customizer custom link section.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.3.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Customizer Link class.
17
+ *
18
+ * This is a special section for rendering section as a static link.
19
+ *
20
+ * @since 1.3.0
21
+ * @ignore
22
+ * @access private
23
+ *
24
+ * @package JupiterX\Framework\API\Customizer
25
+ */
26
+ class JupiterX_Customizer_Section_Link extends WP_Customize_Section {
27
+
28
+ /**
29
+ * Type of this section.
30
+ *
31
+ * @since 1.3.0
32
+ *
33
+ * @var string
34
+ */
35
+ public $type = 'kirki-jupiterx-link';
36
+
37
+ /**
38
+ * Url of this section.
39
+ *
40
+ * @since 1.3.0
41
+ *
42
+ * @var string
43
+ */
44
+ public $jupiterx_url = '#';
45
+
46
+ /**
47
+ * Icon of this section.
48
+ *
49
+ * @since 1.3.0
50
+ *
51
+ * @var string
52
+ */
53
+ public $jupiterx_icon = '';
54
+
55
+ /**
56
+ * Upgrade link.
57
+ *
58
+ * @since 1.3.0
59
+ *
60
+ * @var string
61
+ */
62
+ public $upgrade_link = '';
63
+
64
+ /**
65
+ * Gather the parameters passed to client JavaScript via JSON.
66
+ *
67
+ * @since 1.3.0
68
+ *
69
+ * @return array The array to be exported to the client as JSON.
70
+ */
71
+ public function json() {
72
+ $json = parent::json();
73
+ $json['jupiterx_url'] = esc_url( $this->jupiterx_url );
74
+ $json['jupiterx_icon'] = $this->jupiterx_icon;
75
+ $json['upgradeLink'] = $this->upgrade_link;
76
+
77
+ return $json;
78
+ }
79
+
80
+ /**
81
+ * An Underscore (JS) template for rendering this section.
82
+ *
83
+ * @since 1.3.0
84
+ * @SuppressWarnings(PHPMD.ElseExpression)
85
+ */
86
+ protected function render_template() {
87
+ ?>
88
+ <li id="jupiterx-popup-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}">
89
+ <?php if ( jupiterx_is_premium() ) : ?>
90
+ <a href="{{ data.jupiterx_url }}" class="accordion-section-title jupiterx-upgrade-modal-trigger" tabindex="0" target="_blank" <# if ( data.upgradeLink ) { #> data-upgrade-link="{{ data.upgradeLink }}" <# } #>>
91
+ <?php else : ?>
92
+ <a href="{{ data.upgradeLink }}" class="accordion-section-title" tabindex="0" target="_blank">
93
+ <?php endif; ?>
94
+ <# if ( data.jupiterx_icon ) { #>
95
+ <span class="{{ data.jupiterx_icon }}"></span>
96
+ <# } #>
97
+ {{ data.title }}
98
+ <span class="screen-reader-text"><?php esc_html_e( 'Press return or enter to open this section', 'jupiterx-core' ); ?></span>
99
+ </a>
100
+ </li>
101
+ <?php
102
+ }
103
+ }
includes/customizer/api/includes/section/class-pane.php CHANGED
@@ -1,84 +1,84 @@
1
- <?php
2
- /**
3
- * This handles customizer custom pane section.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Customizer Pane class.
17
- *
18
- * This is a special section for rendering tabs and child popups controls inside the Popup section.
19
- *
20
- * @since 1.0.0
21
- * @ignore
22
- * @access private
23
- *
24
- * @package JupiterX\Framework\API\Customizer
25
- */
26
- class JupiterX_Customizer_Section_Pane extends WP_Customize_Section {
27
-
28
- /**
29
- * Type of this section.
30
- *
31
- * @since 1.0.0
32
- *
33
- * @var string
34
- */
35
- public $type = 'kirki-pane';
36
-
37
- /**
38
- * Parent popup where to render this section.
39
- *
40
- * @since 1.0.0
41
- *
42
- * @var string
43
- */
44
- public $popup = '';
45
-
46
- /**
47
- * Get the pane type and id.
48
- *
49
- * @since 1.0.0
50
- *
51
- * @var array
52
- */
53
- public $pane = [];
54
-
55
- /**
56
- * Gather the parameters passed to client JavaScript via JSON.
57
- *
58
- * @since 1.0.0
59
- *
60
- * @return array The array to be exported to the client as JSON.
61
- */
62
- public function json() {
63
- $array = wp_array_slice_assoc( (array) $this, array( 'id', 'type' ) );
64
- $array['content'] = $this->get_content();
65
- $array['instanceNumber'] = $this->instance_number;
66
- $array['popup'] = $this->popup;
67
- $array['pane'] = $this->pane;
68
-
69
- return $array;
70
- }
71
-
72
- /**
73
- * An Underscore (JS) template for rendering this section.
74
- *
75
- * @since 1.0.0
76
- */
77
- protected function render_template() {
78
- ?>
79
- <li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}">
80
- <ul class="customize-jupiterx-pane-section jupiterx-controls jupiterx-row control-section control-section-{{ data.type }}"></ul>
81
- </li>
82
- <?php
83
- }
84
- }
1
+ <?php
2
+ /**
3
+ * This handles customizer custom pane section.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Customizer Pane class.
17
+ *
18
+ * This is a special section for rendering tabs and child popups controls inside the Popup section.
19
+ *
20
+ * @since 1.0.0
21
+ * @ignore
22
+ * @access private
23
+ *
24
+ * @package JupiterX\Framework\API\Customizer
25
+ */
26
+ class JupiterX_Customizer_Section_Pane extends WP_Customize_Section {
27
+
28
+ /**
29
+ * Type of this section.
30
+ *
31
+ * @since 1.0.0
32
+ *
33
+ * @var string
34
+ */
35
+ public $type = 'kirki-pane';
36
+
37
+ /**
38
+ * Parent popup where to render this section.
39
+ *
40
+ * @since 1.0.0
41
+ *
42
+ * @var string
43
+ */
44
+ public $popup = '';
45
+
46
+ /**
47
+ * Get the pane type and id.
48
+ *
49
+ * @since 1.0.0
50
+ *
51
+ * @var array
52
+ */
53
+ public $pane = [];
54
+
55
+ /**
56
+ * Gather the parameters passed to client JavaScript via JSON.
57
+ *
58
+ * @since 1.0.0
59
+ *
60
+ * @return array The array to be exported to the client as JSON.
61
+ */
62
+ public function json() {
63
+ $array = wp_array_slice_assoc( (array) $this, array( 'id', 'type' ) );
64
+ $array['content'] = $this->get_content();
65
+ $array['instanceNumber'] = $this->instance_number;
66
+ $array['popup'] = $this->popup;
67
+ $array['pane'] = $this->pane;
68
+
69
+ return $array;
70
+ }
71
+
72
+ /**
73
+ * An Underscore (JS) template for rendering this section.
74
+ *
75
+ * @since 1.0.0
76
+ */
77
+ protected function render_template() {
78
+ ?>
79
+ <li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}">
80
+ <ul class="customize-jupiterx-pane-section jupiterx-controls control-section control-section-{{ data.type }}"></ul>
81
+ </li>
82
+ <?php
83
+ }
84
+ }
includes/customizer/api/includes/section/class-popup.php CHANGED
@@ -1,258 +1,258 @@
1
- <?php
2
- /**
3
- * This handles customizer custom popup section.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Customizer Popup class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access public
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Section_Popup extends WP_Customize_Section {
25
-
26
- /**
27
- * Type of this section.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $type = 'kirki-popup';
34
-
35
- /**
36
- * Preview URL of popup.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $preview;
43
-
44
-
45
- /**
46
- * Order priority to load the control in Customizer.
47
- *
48
- * @since 1.0.0
49
- *
50
- * @var int
51
- */
52
- public $priority = 160;
53
-
54
- /**
55
- * Tabs for this section.
56
- *
57
- * @since 1.0.0
58
- *
59
- * @var array
60
- */
61
- public $tabs = [];
62
-
63
- /**
64
- * Popups for this section.
65
- *
66
- * @since 1.0.0
67
- *
68
- * @var array
69
- */
70
- public $popups = [];
71
-
72
- /**
73
- * Help link data for this section.
74
- *
75
- * @since 1.0.0
76
- *
77
- * @var array
78
- */
79
- public $help = [];
80
-
81
- /**
82
- * Set visibility to hidden.
83
- *
84
- * If set to true, it will remove the accordion title inside the panel.
85
- *
86
- * @since 1.0.0
87
- *
88
- * @var boolean
89
- */
90
- public $hidden = false;
91
-
92
- /**
93
- * Tag section as PRO.
94
- *
95
- * @since 1.3.0
96
- *
97
- * @var boolean
98
- */
99
- public $pro = false;
100
-
101
- /**
102
- * Gather the parameters passed to client JavaScript via JSON.
103
- *
104
- * @since 1.0.0
105
- *
106
- * @return array The array to be exported to the client as JSON.
107
- */
108
- public function json() {
109
- $array = wp_array_slice_assoc( (array) $this, array( 'id', 'description', 'priority', 'panel', 'type', 'description_hidden' ) );
110
- $array['title'] = html_entity_decode( $this->title, ENT_QUOTES, get_bloginfo( 'charset' ) );
111
- $array['content'] = $this->get_content();
112
- $array['active'] = $this->active();
113
- $array['instanceNumber'] = $this->instance_number;
114
- $array['tabs'] = $this->tabs;
115
- $array['popups'] = $this->popups;
116
- $array['hidden'] = $this->hidden;
117
- $array['preview'] = $this->preview;
118
- $array['help'] = $this->help;
119
- $array['pro'] = $this->pro;
120
-
121
- foreach ( $array['tabs'] as $key => $tab ) {
122
- // Transform label.
123
- if ( is_string( $tab ) ) {
124
- $array['tabs'][ $key ] = [ 'label' => $tab ];
125
- continue;
126
- }
127
- }
128
-
129
- return $array;
130
- }
131
-
132
- /**
133
- * An Underscore (JS) template for rendering this section.
134
- *
135
- * @since 1.0.0
136
- */
137
- protected function render_template() {
138
- ?>
139
- <li id="jupiterx-popup-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}">
140
- <h3 class="accordion-section-title" tabindex="0">
141
- {{ data.title }}
142
- <# if ( data.pro ) { #><img class="jupiterx-control-pro-badge" src="<?php echo esc_url( jupiterx_get_pro_badge_url() ); ?>" /><# } #>
143
- <span class="screen-reader-text"><?php esc_html_e( 'Press return or enter to open this section', 'jupiterx-core' ); ?></span>
144
- </h3>
145
- <?php $this->section_template(); ?>
146
- </li>
147
- <?php
148
- }
149
-
150
- /**
151
- * Template for content container.
152
- *
153
- * @since 1.0.0
154
- */
155
- protected function section_template() {
156
- ?>
157
- <div class="customize-jupiterx-popup-section jupiterx-popup-section">
158
- <div class="jupiterx-popup-header">
159
- <h3 class="jupiterx-popup-title">{{ data.title }}</h3>
160
- <div class="jupiterx-popup-header-buttons">
161
- <?php if ( jupiterx_is_help_links() ) : ?>
162
- <# if ( ! _.isEmpty( data.help.url ) ) { #>
163
- <a href="{{ data.help.url }}" class="jupiterx-help-link jupiterx-help-link-dark jupiterx-icon-question" title="{{ data.help.title }}" target="_blank"></a>
164
- <# } #>
165
- <?php endif; ?>
166
- <button class="jupiterx-popup-button jupiterx-popup-close">
167
- <span class="dashicons dashicons-no"></span>
168
- <?php esc_html_e( 'Close', 'jupiterx-core' ); ?>
169
- </button>
170
- </div>
171
- </div>
172
- <?php
173
- $this->content_template();
174
- $this->tabs_template();
175
- $this->popups_template();
176
- ?>
177
- </div>
178
- <?php
179
- }
180
-
181
- /**
182
- * Template for basic content.
183
- *
184
- * @since 1.0.0
185
- */
186
- protected function content_template() {
187
- ?>
188
- <# if ( _.isEmpty( data.tabs ) ) { #>
189
- <div class="jupiterx-popup-content">
190
- <ul class="jupiterx-controls jupiterx-row"></ul>
191
- </div>
192
- <# } #>
193
- <?php
194
- }
195
-
196
- /**
197
- * Content template for tabs.
198
- *
199
- * @since 1.0.0
200
- */
201
- protected function tabs_template() {
202
- ?>
203
- <# if ( ! _.isEmpty( data.tabs ) ) { #>
204
- <div class="jupiterx-popup-tabs">
205
- <div class="jupiterx-tabs">
206
- <div class="jupiterx-tabs-list">
207
- <# _.each( data.tabs, function( tab, tabId ) { #>
208
- <button
209
- class="jupiterx-tabs-button"
210
- data-target="tab-{{ tabId }}-{{ data.id }}"
211
- tabindex="-1"
212
- >
213
- <span class="jupiterx-tabs-label">{{{ tab.label }}}</span>
214
- <# if ( tab.pro ) { #><img class="jupiterx-control-pro-badge" src="<?php echo esc_url( jupiterx_get_pro_badge_url() ); ?>" /><# } #>
215
- </button>
216
- <# }) #>
217
- </div>
218
- <# _.each( data.tabs, function( tab, tabId ) { #>
219
- <div
220
- class="jupiterx-tabs-pane hidden"
221
- id="tab-{{ tabId }}-{{ data.id }}"
222
- tabindex="0"
223
- ></div>
224
- <# }) #>
225
- </div>
226
- </div>
227
- <# } #>
228
- <?php
229
- }
230
-
231
- /**
232
- * Content template for popups.
233
- *
234
- * @since 1.0.0
235
- */
236
- protected function popups_template() {
237
- ?>
238
- <# if ( ! _.isEmpty( data.popups ) ) { #>
239
- <div class="jupiterx-popup-child">
240
- <# _.each( data.popups, function( popup, popupId ) { #>
241
- <div class="jupiterx-child-popup" id="popup-{{ popupId }}-{{ data.id }}">
242
- <div class="jupiterx-child-popup-header">
243
- <h3 class="jupiterx-child-popup-title">{{ popup }}</h3>
244
- <div class="jupiterx-child-popup-header-buttons">
245
- <button class="jupiterx-child-popup-button jupiterx-child-popup-close">
246
- <span class="dashicons dashicons-no"></span>
247
- <span class="screen-reader-text"><?php esc_html_e( 'Close', 'jupiterx-core' ); ?></span>
248
- </button>
249
- </div>
250
- </div>
251
- <div class="jupiterx-child-popup-content"></div>
252
- </div>
253
- <# }) #>
254
- </div>
255
- <# } #>
256
- <?php
257
- }
258
- }
1
+ <?php
2
+ /**
3
+ * This handles customizer custom popup section.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Customizer Popup class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access public
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Section_Popup extends WP_Customize_Section {
25
+
26
+ /**
27
+ * Type of this section.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $type = 'kirki-popup';
34
+
35
+ /**
36
+ * Preview URL of popup.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $preview;
43
+
44
+
45
+ /**
46
+ * Order priority to load the control in Customizer.
47
+ *
48
+ * @since 1.0.0
49
+ *
50
+ * @var int
51
+ */
52
+ public $priority = 160;
53
+
54
+ /**
55
+ * Tabs for this section.
56
+ *
57
+ * @since 1.0.0
58
+ *
59
+ * @var array
60
+ */
61
+ public $tabs = [];
62
+
63
+ /**
64
+ * Popups for this section.
65
+ *
66
+ * @since 1.0.0
67
+ *
68
+ * @var array
69
+ */
70
+ public $popups = [];
71
+
72
+ /**
73
+ * Help link data for this section.
74
+ *
75
+ * @since 1.0.0
76
+ *
77
+ * @var array
78
+ */
79
+ public $help = [];
80
+
81
+ /**
82
+ * Set visibility to hidden.
83
+ *
84
+ * If set to true, it will remove the accordion title inside the panel.
85
+ *
86
+ * @since 1.0.0
87
+ *
88
+ * @var boolean
89
+ */
90
+ public $hidden = false;
91
+
92
+ /**
93
+ * Tag section as PRO.
94
+ *
95
+ * @since 1.3.0
96
+ *
97
+ * @var boolean
98
+ */
99
+ public $pro = false;
100
+
101
+ /**
102
+ * Gather the parameters passed to client JavaScript via JSON.
103
+ *
104
+ * @since 1.0.0
105
+ *
106
+ * @return array The array to be exported to the client as JSON.
107
+ */
108
+ public function json() {
109
+ $array = wp_array_slice_assoc( (array) $this, array( 'id', 'description', 'priority', 'panel', 'type', 'description_hidden' ) );
110
+ $array['title'] = html_entity_decode( $this->title, ENT_QUOTES, get_bloginfo( 'charset' ) );
111
+ $array['content'] = $this->get_content();
112
+ $array['active'] = $this->active();
113
+ $array['instanceNumber'] = $this->instance_number;
114
+ $array['tabs'] = $this->tabs;
115
+ $array['popups'] = $this->popups;
116
+ $array['hidden'] = $this->hidden;
117
+ $array['preview'] = $this->preview;
118
+ $array['help'] = $this->help;
119
+ $array['pro'] = $this->pro;
120
+
121
+ foreach ( $array['tabs'] as $key => $tab ) {
122
+ // Transform label.
123
+ if ( is_string( $tab ) ) {
124
+ $array['tabs'][ $key ] = [ 'label' => $tab ];
125
+ continue;
126
+ }
127
+ }
128
+
129
+ return $array;
130
+ }
131
+
132
+ /**
133
+ * An Underscore (JS) template for rendering this section.
134
+ *
135
+ * @since 1.0.0
136
+ */
137
+ protected function render_template() {
138
+ ?>
139
+ <li id="jupiterx-popup-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}">
140
+ <h3 class="accordion-section-title" tabindex="0">
141
+ {{ data.title }}
142
+ <# if ( data.pro ) { #><svg class="jupiterx-control-pro-badge"><use xlink:href="<?php echo esc_url( jupiterx_core_get_pro_badge() ); ?>"><use></svg><# } #>
143
+ <span class="screen-reader-text"><?php esc_html_e( 'Press return or enter to open this section', 'jupiterx-core' ); ?></span>
144
+ </h3>
145
+ <?php $this->section_template(); ?>
146
+ </li>
147
+ <?php
148
+ }
149
+
150
+ /**
151
+ * Template for content container.
152
+ *
153
+ * @since 1.0.0
154
+ */
155
+ protected function section_template() {
156
+ ?>
157
+ <div class="customize-jupiterx-popup-section jupiterx-popup-section">
158
+ <div class="jupiterx-popup-header">
159
+ <h3 class="jupiterx-popup-title">{{ data.title }}</h3>
160
+ <div class="jupiterx-popup-header-buttons">
161
+ <?php if ( jupiterx_is_help_links() ) : ?>
162
+ <# if ( ! _.isEmpty( data.help.url ) ) { #>
163
+ <a href="{{ data.help.url }}" class="jupiterx-help-link jupiterx-help-link-dark jupiterx-icon-question" title="{{ data.help.title }}" target="_blank"></a>
164
+ <# } #>
165
+ <?php endif; ?>
166
+ <button class="jupiterx-popup-button jupiterx-popup-close">
167
+ <span class="dashicons dashicons-no"></span>
168
+ <?php esc_html_e( 'Close', 'jupiterx-core' ); ?>
169
+ </button>
170
+ </div>
171
+ </div>
172
+ <?php
173
+ $this->content_template();
174
+ $this->tabs_template();
175
+ $this->popups_template();
176
+ ?>
177
+ </div>
178
+ <?php
179
+ }
180
+
181
+ /**
182
+ * Template for basic content.
183
+ *
184
+ * @since 1.0.0
185
+ */
186
+ protected function content_template() {
187
+ ?>
188
+ <# if ( _.isEmpty( data.tabs ) ) { #>
189
+ <div class="jupiterx-popup-content">
190
+ <ul class="jupiterx-controls"></ul>
191
+ </div>
192
+ <# } #>
193
+ <?php
194
+ }
195
+
196
+ /**
197
+ * Content template for tabs.
198
+ *
199
+ * @since 1.0.0
200
+ */
201
+ protected function tabs_template() {
202
+ ?>
203
+ <# if ( ! _.isEmpty( data.tabs ) ) { #>
204
+ <div class="jupiterx-popup-tabs">
205
+ <div class="jupiterx-tabs">
206
+ <div class="jupiterx-tabs-list">
207
+ <# _.each( data.tabs, function( tab, tabId ) { #>
208
+ <button
209
+ class="jupiterx-tabs-button"
210
+ data-target="tab-{{ tabId }}-{{ data.id }}"
211
+ tabindex="-1"
212
+ >
213
+ <span class="jupiterx-tabs-label">{{{ tab.label }}}</span>
214
+ <# if ( tab.pro ) { #><svg class="jupiterx-control-pro-badge"><use xlink:href="<?php echo esc_url( jupiterx_core_get_pro_badge() ); ?>"><use></svg><# } #>
215
+ </button>
216
+ <# }) #>
217
+ </div>
218
+ <# _.each( data.tabs, function( tab, tabId ) { #>
219
+ <div
220
+ class="jupiterx-tabs-pane hidden"
221
+ id="tab-{{ tabId }}-{{ data.id }}"
222
+ tabindex="0"
223
+ ></div>
224
+ <# }) #>
225
+ </div>
226
+ </div>
227
+ <# } #>
228
+ <?php
229
+ }
230
+
231
+ /**
232
+ * Content template for popups.
233
+ *
234
+ * @since 1.0.0
235
+ */
236
+ protected function popups_template() {
237
+ ?>
238
+ <# if ( ! _.isEmpty( data.popups ) ) { #>
239
+ <div class="jupiterx-popup-child">
240
+ <# _.each( data.popups, function( popup, popupId ) { #>
241
+ <div class="jupiterx-child-popup" id="popup-{{ popupId }}-{{ data.id }}">
242
+ <div class="jupiterx-child-popup-header">
243
+ <h3 class="jupiterx-child-popup-title">{{ popup }}</h3>
244
+ <div class="jupiterx-child-popup-header-buttons">
245
+ <button class="jupiterx-child-popup-button jupiterx-child-popup-close">
246
+ <span class="dashicons dashicons-no"></span>
247
+ <span class="screen-reader-text"><?php esc_html_e( 'Close', 'jupiterx-core' ); ?></span>
248
+ </button>
249
+ </div>
250
+ </div>
251
+ <div class="jupiterx-child-popup-content"></div>
252
+ </div>
253
+ <# }) #>
254
+ </div>
255
+ <# } #>
256
+ <?php
257
+ }
258
+ }
includes/customizer/api/init.php CHANGED
@@ -1,159 +1,162 @@
1
- <?php
2
- /**
3
- * This class handles customizer function.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- if ( ! class_exists( '_JupiterX_Core_Customizer_Init' ) ) {
16
- /**
17
- * Extends WordPress customizer capability.
18
- *
19
- * @since 1.0.0
20
- * @ignore
21
- * @access private
22
- *
23
- * @package JupiterX\Framework\API\Customizer
24
- */
25
- final class _JupiterX_Core_Customizer_Init {
26
-
27
- /**
28
- * List of autoloaded modules.
29
- *
30
- * @since 1.0.0
31
- *
32
- * @var array
33
- */
34
- protected $modules = [
35
- 'compiler' => 'JupiterX_Customizer_Compiler',
36
- 'kirki-extend' => 'JupiterX_Customizer_Kirki_Extend',
37
- 'post-message' => 'JupiterX_Customizer_Post_Message',
38
- ];
39
-
40
- /**
41
- * Construct the class.
42
- *
43
- * @since 1.0.0
44
- */
45
- public function __construct() {
46
- $this->define_constants();
47
- $this->includes();
48
- $this->add_hooks();
49
- $this->load_modules();
50
- }
51
-
52
- /**
53
- * Define customizer constants.
54
- *
55
- * @since 1.0.0
56
- */
57
- protected function define_constants() {
58
- define( 'JUPITERX_CORE_CUSTOMIZER_PATH', trailingslashit( jupiterx_core()->plugin_dir() . 'includes/customizer/api' ) );
59
- define( 'JUPITERX_CORE_CUSTOMIZER_URL', trailingslashit( jupiterx_core()->plugin_url() . 'includes/customizer/api' ) );
60
-
61
- if ( function_exists( 'jupiterx_core' ) && is_customize_preview() ) {
62
- jupiterx_customizer_kirki();
63
- }
64
- }
65
-
66
- /**
67
- * Include files.
68
- *
69
- * @since 1.0.0
70
- */
71
- protected function includes() {
72
- include_once JUPITERX_CORE_CUSTOMIZER_PATH . 'includes/class-autoloader.php';
73
- include_once JUPITERX_CORE_CUSTOMIZER_PATH . 'includes/class-templates.php';
74
- include_once JUPITERX_CORE_CUSTOMIZER_PATH . 'classes/class-multilingual.php';
75
- }
76
-
77
- /**
78
- * Add filters and actions.
79
- *
80
- * @since 1.0.0
81
- */
82
- protected function add_hooks() {
83
- add_action( 'customize_register', [ $this, 'register_control_types' ] );
84
- add_action( 'customize_controls_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
85
- add_action( 'customize_preview_init', [ $this, 'enqueue_preview_scripts' ] );
86
- add_action( 'scp_js_path_url', [ $this, 'multilingual_script_path' ] );
87
- }
88
-
89
- /**
90
- * Load modules.
91
- *
92
- * @since 1.0.0
93
- */
94
- protected function load_modules() {
95
- foreach ( $this->modules as $module ) {
96
- if ( class_exists( $module ) && ( ! method_exists( $module, 'active' ) || $module::active() ) ) {
97
- new $module();
98
- }
99
- }
100
- }
101
-
102
- /**
103
- * Register all control types.
104
- *
105
- * @since 1.0.0
106
- *
107
- * @param object $wp_customize Global customize object.
108
- */
109
- public function register_control_types( $wp_customize ) {
110
- foreach ( JupiterX_Customizer::$control_types as $control_type ) {
111
- $wp_customize->register_control_type( $control_type );
112
- }
113
- }
114
-
115
- /**
116
- * Enqueue styles and scripts.
117
- *
118
- * @since 1.0.0
119
- */
120
- public function enqueue_scripts() {
121
- wp_register_script( 'jupiterx-webfont', JUPITERX_ADMIN_ASSETS_URL . 'lib/webfont/webfont' . JUPITERX_MIN_JS . '.js', [], '1.6.26', false );
122
- wp_register_script( 'jupiterx-spectrum', JUPITERX_ASSETS_URL . 'customizer/lib/spectrum/spectrum' . JUPITERX_MIN_JS . '.js', [], '1.8.0', true );
123
- wp_register_script( 'jupiterx-select2', JUPITERX_ASSETS_URL . 'customizer/lib/select2/select2' . JUPITERX_MIN_JS . '.js', [], '4.0.6', true );
124
- wp_register_script( 'jupiterx-stepper', JUPITERX_ASSETS_URL . 'customizer/lib/stepper/stepper' . JUPITERX_MIN_JS . '.js', [], '1.0.0', true );
125
- wp_register_script( 'jupiterx-url-polyfill', JUPITERX_ASSETS_URL . 'customizer/lib/url-polyfill/url-polyfill' . JUPITERX_MIN_JS . '.js', [], '1.1.0', false );
126
- wp_register_script( 'jupiterx-help-links', JUPITERX_ASSETS_URL . 'dist/js/help-links' . JUPITERX_MIN_JS . '.js', [], JUPITERX_VERSION, true );
127
- wp_enqueue_script( 'jupiterx-customizer', JUPITERX_ASSETS_URL . 'dist/js/customizer' . JUPITERX_MIN_JS . '.js', [ 'jquery', 'jquery-ui-draggable', 'jquery-ui-sortable', 'jupiterx-webfont', 'jupiterx-spectrum', 'jupiterx-select2', 'jupiterx-stepper', 'jupiterx-url-polyfill', 'jupiterx-help-links' ], JUPITERX_VERSION, true );
128
- wp_register_style( 'jupiterx-help-links', JUPITERX_ASSETS_URL . 'dist/css/help-links' . JUPITERX_MIN_CSS . '.css', [], JUPITERX_VERSION );
129
- wp_register_style( 'jupiterx-spectrum', JUPITERX_ASSETS_URL . 'customizer/lib/spectrum/spectrum' . JUPITERX_MIN_CSS . '.css', [], '1.8.0' );
130
- wp_register_style( 'jupiterx-select2', JUPITERX_ASSETS_URL . 'customizer/lib/select2/select2' . JUPITERX_MIN_CSS . '.css', [], '4.0.6' );
131
- wp_enqueue_style( 'jupiterx-customizer', JUPITERX_ASSETS_URL . 'dist/css/customizer' . JUPITERX_RTL . JUPITERX_MIN_CSS . '.css', [ 'jupiterx-spectrum', 'jupiterx-select2', 'jupiterx-help-links' ], JUPITERX_VERSION );
132
-
133
- wp_localize_script( 'jupiterx-customizer', 'jupiterxCustomizer', [
134
- 'customizer_preview_redirect_url_nonce' => wp_create_nonce( 'jupiterx_core_get_customizer_preview_redirect_url' ),
135
- ] );
136
- }
137
-
138
- /**
139
- * Enqueue preview styles and scripts.
140
- *
141
- * @since 1.0.0
142
- */
143
- public function enqueue_preview_scripts() {
144
- wp_enqueue_script( 'jupiterx-customizer-preview', JUPITERX_ASSETS_URL . 'dist/js/customizer-preview' . JUPITERX_MIN_JS . '.js', [ 'customize-preview', 'jupiterx-utils' ], JUPITERX_VERSION, true );
145
- }
146
-
147
- /**
148
- * Filter js path for customizer multilingual scripts.
149
- *
150
- * @since 1.0.0
151
- */
152
- public function multilingual_script_path() {
153
- return JUPITERX_ASSETS_URL . 'customizer/lib/';
154
- }
155
- }
156
- }
157
-
158
- // Run customizer class.
159
- new _JupiterX_Core_Customizer_Init();
 
 
 
1
+ <?php
2
+ /**
3
+ * This class handles customizer function.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ if ( ! class_exists( '_JupiterX_Core_Customizer_Init' ) ) {
16
+ /**
17
+ * Extends WordPress customizer capability.
18
+ *
19
+ * @since 1.0.0
20
+ * @ignore
21
+ * @access private
22
+ *
23
+ * @package JupiterX\Framework\API\Customizer
24
+ */
25
+ final class _JupiterX_Core_Customizer_Init {
26
+
27
+ /**
28
+ * List of autoloaded modules.
29
+ *
30
+ * @since 1.0.0
31
+ *
32
+ * @var array
33
+ */
34
+ protected $modules = [
35
+ 'compiler' => 'JupiterX_Customizer_Compiler',
36
+ 'kirki-extend' => 'JupiterX_Customizer_Kirki_Extend',
37
+ 'post-message' => 'JupiterX_Customizer_Post_Message',
38
+ ];
39
+
40
+ /**
41
+ * Construct the class.
42
+ *
43
+ * @since 1.0.0
44
+ */
45
+ public function __construct() {
46
+ $this->define_constants();
47
+ $this->includes();
48
+ $this->add_hooks();
49
+ $this->load_modules();
50
+ }
51
+
52
+ /**
53
+ * Define customizer constants.
54
+ *
55
+ * @since 1.0.0
56
+ */
57
+ protected function define_constants() {
58
+ define( 'JUPITERX_CORE_CUSTOMIZER_PATH', trailingslashit( jupiterx_core()->plugin_dir() . 'includes/customizer/api' ) );
59
+ define( 'JUPITERX_CORE_CUSTOMIZER_URL', trailingslashit( jupiterx_core()->plugin_url() . 'includes/customizer/api' ) );
60
+
61
+ if ( function_exists( 'jupiterx_core' ) && is_customize_preview() ) {
62
+ jupiterx_customizer_kirki();
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Include files.
68
+ *
69
+ * @since 1.0.0
70
+ */
71
+ protected function includes() {
72
+ include_once JUPITERX_CORE_CUSTOMIZER_PATH . 'includes/class-autoloader.php';
73
+ include_once JUPITERX_CORE_CUSTOMIZER_PATH . 'includes/class-templates.php';
74
+ include_once JUPITERX_CORE_CUSTOMIZER_PATH . 'classes/class-multilingual.php';
75
+ }
76
+
77
+ /**
78
+ * Add filters and actions.
79
+ *
80
+ * @since 1.0.0
81
+ */
82
+ protected function add_hooks() {
83
+ add_action( 'customize_register', [ $this, 'register_control_types' ] );
84
+ add_action( 'customize_controls_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
85
+ add_action( 'customize_preview_init', [ $this, 'enqueue_preview_scripts' ] );
86
+ add_action( 'scp_js_path_url', [ $this, 'multilingual_script_path' ] );
87
+ }
88
+
89
+ /**
90
+ * Load modules.
91
+ *
92
+ * @since 1.0.0
93
+ */
94
+ protected function load_modules() {
95
+ foreach ( $this->modules as $module ) {
96
+ if ( class_exists( $module ) && ( ! method_exists( $module, 'active' ) || $module::active() ) ) {
97
+ new $module();
98
+ }
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Register all control types.
104
+ *
105
+ * @since 1.0.0
106
+ *
107
+ * @param object $wp_customize Global customize object.
108
+ */
109
+ public function register_control_types( $wp_customize ) {
110
+ foreach ( JupiterX_Customizer::$control_types as $control_type ) {
111
+ $wp_customize->register_control_type( $control_type );
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Enqueue styles and scripts.
117
+ *
118
+ * @since 1.0.0
119
+ */
120
+ public function enqueue_scripts() {
121
+ wp_register_script( 'jupiterx-webfont', JUPITERX_ADMIN_ASSETS_URL . 'lib/webfont/webfont' . JUPITERX_MIN_JS . '.js', [], '1.6.26', false );
122
+ wp_register_script( 'jupiterx-spectrum', JUPITERX_ASSETS_URL . 'customizer/lib/spectrum/spectrum' . JUPITERX_MIN_JS . '.js', [], '1.8.0', true );
123
+ wp_register_script( 'jupiterx-select2', JUPITERX_ASSETS_URL . 'customizer/lib/select2/select2' . JUPITERX_MIN_JS . '.js', [], '4.0.6', true );
124
+ wp_register_script( 'jupiterx-stepper', JUPITERX_ASSETS_URL . 'customizer/lib/stepper/stepper' . JUPITERX_MIN_JS . '.js', [], '1.0.0', true );
125
+ wp_register_script( 'jupiterx-url-polyfill', JUPITERX_ASSETS_URL . 'customizer/lib/url-polyfill/url-polyfill' . JUPITERX_MIN_JS . '.js', [], '1.1.0', false );
126
+ wp_register_script( 'jupiterx-help-links', JUPITERX_ASSETS_URL . 'dist/js/help-links' . JUPITERX_MIN_JS . '.js', [], JUPITERX_VERSION, true );
127
+ wp_enqueue_script( 'jupiterx-customizer', JUPITERX_ASSETS_URL . 'dist/js/customizer' . JUPITERX_MIN_JS . '.js', [ 'jquery', 'jquery-ui-draggable', 'jquery-ui-sortable', 'jupiterx-webfont', 'jupiterx-spectrum', 'jupiterx-select2', 'jupiterx-stepper', 'jupiterx-url-polyfill', 'jupiterx-help-links' ], JUPITERX_VERSION, true );
128
+ wp_register_style( 'jupiterx-help-links', JUPITERX_ASSETS_URL . 'dist/css/help-links' . JUPITERX_MIN_CSS . '.css', [], JUPITERX_VERSION );
129
+ wp_register_style( 'jupiterx-spectrum', JUPITERX_ASSETS_URL . 'customizer/lib/spectrum/spectrum' . JUPITERX_MIN_CSS . '.css', [], '1.8.0' );
130
+ wp_register_style( 'jupiterx-select2', JUPITERX_ASSETS_URL . 'customizer/lib/select2/select2' . JUPITERX_MIN_CSS . '.css', [], '4.0.6' );
131
+ wp_enqueue_style( 'jupiterx-customizer', JUPITERX_ASSETS_URL . 'dist/css/customizer' . JUPITERX_RTL . JUPITERX_MIN_CSS . '.css', [ 'jupiterx-spectrum', 'jupiterx-select2', 'jupiterx-help-links' ], JUPITERX_VERSION );
132
+
133
+ wp_localize_script( 'jupiterx-customizer', 'jupiterxCustomizer', [
134
+ 'nonce' => wp_create_nonce( 'jupiterx_customizer_preview' ),
135
+ 'customizer_preview_redirect_url_nonce' => wp_create_nonce( 'jupiterx_core_get_customizer_preview_redirect_url' ),
136
+ 'base_url' => get_stylesheet_directory_uri(),
137
+ 'themeBase' => JUPITERX_ASSETS_URL,
138
+ ] );
139
+ }
140
+
141
+ /**
142
+ * Enqueue preview styles and scripts.
143
+ *
144
+ * @since 1.0.0
145
+ */
146
+ public function enqueue_preview_scripts() {
147
+ wp_enqueue_script( 'jupiterx-customizer-preview', JUPITERX_ASSETS_URL . 'dist/js/customizer-preview' . JUPITERX_MIN_JS . '.js', [ 'customize-preview', 'jupiterx-utils' ], JUPITERX_VERSION, true );
148
+ }
149
+
150
+ /**
151
+ * Filter js path for customizer multilingual scripts.
152
+ *
153
+ * @since 1.0.0
154
+ */
155
+ public function multilingual_script_path() {
156
+ return JUPITERX_ASSETS_URL . 'customizer/lib/';
157
+ }
158
+ }
159
+ }
160
+
161
+ // Run customizer class.
162
+ new _JupiterX_Core_Customizer_Init();
includes/customizer/api/modules/compiler/class-compiler.php CHANGED
@@ -1,66 +1,66 @@
1
- <?php
2
- /**
3
- * This class initializes actions for compiling theme settings into CSS variables.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Initialize compiler actions.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- final class JupiterX_Customizer_Compiler {
25
-
26
- /**
27
- * Construct the class.
28
- *
29
- * @since 1.0.0
30
- */
31
- public function __construct() {
32
- add_action( 'customize_save_after', [ $this, 'customize_save' ] );
33
- add_filter( 'jupiterx_compiler_less_variables', [ $this, 'css_variables' ] );
34
- }
35
-
36
- /**
37
- * Run after customizer save.
38
- *
39
- * @since 1.0.0
40
- */
41
- public function customize_save() {
42
- if ( ! function_exists( 'jupiterx_flush_compiler' ) ) {
43
- return;
44
- }
45
-
46
- jupiterx_flush_compiler( 'jupiterx' );
47
- }
48
-
49
- /**
50
- * Get variables and pass to the Jupiter CSS compiler.
51
- *
52
- * @since 1.0.0
53
- *
54
- * @param array $vars Returns variables.
55
- */
56
- public function css_variables( $vars ) {
57
- // Start compiling vars.
58
- $compiler = new JupiterX_Customizer_Get_Variables();
59
-
60
- // Get compiled vars.
61
- $css_vars = $compiler->get_vars();
62
-
63
- // Combine and overwrite.
64
- return array_merge( $vars, $css_vars );
65
- }
66
- }
1
+ <?php
2
+ /**
3
+ * This class initializes actions for compiling theme settings into CSS variables.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Initialize compiler actions.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ final class JupiterX_Customizer_Compiler {
25
+
26
+ /**
27
+ * Construct the class.
28
+ *
29
+ * @since 1.0.0
30
+ */
31
+ public function __construct() {
32
+ add_action( 'customize_save_after', [ $this, 'customize_save' ] );
33
+ add_filter( 'jupiterx_compiler_less_variables', [ $this, 'css_variables' ] );
34
+ }
35
+
36
+ /**
37
+ * Run after customizer save.
38
+ *
39
+ * @since 1.0.0
40
+ */
41
+ public function customize_save() {
42
+ if ( ! function_exists( 'jupiterx_flush_compiler' ) ) {
43
+ return;
44
+ }
45
+
46
+ jupiterx_flush_compiler( 'jupiterx' );
47
+ }
48
+
49
+ /**
50
+ * Get variables and pass to the Jupiter CSS compiler.
51
+ *
52
+ * @since 1.0.0
53
+ *
54
+ * @param array $vars Returns variables.
55
+ */
56
+ public function css_variables( $vars ) {
57
+ // Start compiling vars.
58
+ $compiler = new JupiterX_Customizer_Get_Variables();
59
+
60
+ // Get compiled vars.
61
+ $css_vars = $compiler->get_vars();
62
+
63
+ // Combine and overwrite.
64
+ return array_merge( $vars, $css_vars );
65
+ }
66
+ }
includes/customizer/api/modules/compiler/class-get-variables.php CHANGED
@@ -1,182 +1,191 @@
1
- <?php
2
- /**
3
- * This class gets the theme mods and create the variables for the CSS compiler.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Customizer CSS compiler class.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- final class JupiterX_Customizer_Get_Variables {
25
-
26
- /**
27
- * Vars holder.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var array
32
- */
33
- private $vars = [];
34
-
35
- /**
36
- * Construct the class.
37
- *
38
- * @since 1.0.0
39
- */
40
- public function __construct() {
41
- // Include this class to avoid errors in using our controls class.
42
- require_once ABSPATH . WPINC . '/class-wp-customize-control.php';
43
-
44
- // Run compiler.
45
- $this->run();
46
- }
47
-
48
- /**
49
- * Start the process of compiling the variables.
50
- *
51
- * @since 1.0.0
52
- */
53
- public function run() {
54
- $controls = array_merge( JupiterX_Customizer::$control_types, JupiterX_Customizer::$group_control_types );
55
-
56
- foreach ( JupiterX_Customizer::$settings as $args ) {
57
- if ( ! isset( $args['css_var'] ) || ! isset( $args['type'] ) ) {
58
- continue;
59
- }
60
-
61
- $default = false;
62
-
63
- if ( isset( $args['default'] ) ) {
64
- $default = $args['default'];
65
- }
66
-
67
- $value = get_theme_mod( $args['settings'], $default );
68
-
69
- if ( empty( $value ) ) {
70
- continue;
71
- }
72
-
73
- if ( ! isset( $args['responsive'] ) ) {
74
- $this->add_vars( $args, $value, $controls );
75
- }
76
-
77
- if ( isset( $args['responsive'] ) && $args['responsive'] ) {
78
- $this->add_responsive_vars( $args, $value, $controls );
79
- }
80
- }
81
- }
82
-
83
- /**
84
- * Default variable addition.
85
- *
86
- * @since 1.0.0
87
- *
88
- * @param array $args Settings arguments.
89
- * @param mixed $value Settings value.
90
- * @param array $controls List of Controls.
91
- */
92
- public function add_vars( $args, $value, $controls ) {
93
- if ( is_array( $value ) ) {
94
- $this->add_properties_vars( $args, $value, $controls );
95
- }
96
-
97
- if ( method_exists( $controls[ $args['type'] ], 'format_value' ) ) {
98
- $value = call_user_func( [ $controls[ $args['type'] ], 'format_value' ], $value, $args );
99
- }
100
-
101
- // At this point when the value is still an array then we have to cancel adding this variable.
102
- if ( is_array( $value ) ) {
103
- return;
104
- }
105
-
106
- $name = isset( $args['css_var']['name'] ) ? $args['css_var']['name'] : $args['css_var'];
107
-
108
- $name = isset( $args['device'] ) && 'desktop' !== $args['device'] ? "{$name}-{$args['device']}" : $name;
109
-
110
- $name = str_replace( '_', '-', $name );
111
-
112
- // Set a value replacement.
113
- if ( isset( $args['css_var']['value'] ) ) {
114
- $value = str_replace( '$', $value, $args['css_var']['value'] );
115
- }
116
-
117
- if ( is_numeric( $value ) || ! empty( $value ) ) {
118
- $this->vars[ str_replace( '_', '-', $name ) ] = $value;
119
- }
120
- }
121
-
122
- /**
123
- * Responsive variable addition.
124
- *
125
- * @param array $args Settings arguments.
126
- * @param mixed $value Settings value.
127
- * @param array $controls List of Controls.
128
- */
129
- public function add_responsive_vars( $args, $value, $controls ) {
130
- foreach ( JupiterX_Customizer::$responsive_devices as $device => $media_query ) {
131
- if ( ! isset( $value[ $device ] ) ) {
132
- continue;
133
- }
134
-
135
- $device_args = array_merge( $args, [
136
- 'device' => $device,
137
- ] );
138
-
139
- $device_value = $value[ $device ];
140
-
141
- $this->add_vars( $device_args, $device_value, $controls );
142
- }
143
- }
144
-
145
- /**
146
- * Add properties variable from array value.
147
- *
148
- * @since 1.0.0
149
- *
150
- * @param array $args Settings arguments.
151
- * @param mixed $value Settings value.
152
- * @param array $controls List of Controls.
153
- */
154
- public function add_properties_vars( $args, $value, $controls ) {
155
- if ( method_exists( $controls[ $args['type'] ], 'format_properties' ) ) {
156
- $value = $controls[ $args['type'] ]::format_properties( $value, $args );
157
- }
158
-
159
- foreach ( $value as $property => $property_value ) {
160
- if ( isset( $args['device'] ) && 'desktop' !== $args['device'] ) {
161
- $property = $property . '-' . $args['device'];
162
- }
163
-
164
- $css_var = str_replace( '_', '-', sprintf( '%1$s-%2$s', $args['css_var'], $property ) );
165
-
166
- if ( ! is_array( $property_value ) && ( is_numeric( $property_value ) || ! empty( $property_value ) ) ) {
167
- $this->vars[ $css_var ] = $property_value;
168
- }
169
- }
170
- }
171
-
172
- /**
173
- * Get the compiled vars.
174
- *
175
- * @since 1.0.0
176
- *
177
- * @return array Compiled vars.
178
- */
179
- public function get_vars() {
180
- return $this->vars;
181
- }
182
- }
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This class gets the theme mods and create the variables for the CSS compiler.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Customizer CSS compiler class.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ final class JupiterX_Customizer_Get_Variables {
25
+
26
+ /**
27
+ * Vars holder.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var array
32
+ */
33
+ private $vars = [];
34
+
35
+ /**
36
+ * Construct the class.
37
+ *
38
+ * @since 1.0.0
39
+ */
40
+ public function __construct() {
41
+ // Include this class to avoid errors in using our controls class.
42
+ require_once ABSPATH . WPINC . '/class-wp-customize-control.php';
43
+
44
+ // Run compiler.
45
+ $this->run();
46
+ }
47
+
48
+ /**
49
+ * Start the process of compiling the variables.
50
+ *
51
+ * @since 1.0.0
52
+ */
53
+ public function run() {
54
+ $controls = array_merge( JupiterX_Customizer::$control_types, JupiterX_Customizer::$group_control_types );
55
+
56
+ foreach ( JupiterX_Customizer::$settings as $args ) {
57
+ if ( ! isset( $args['css_var'] ) || ! isset( $args['type'] ) ) {
58
+ continue;
59
+ }
60
+
61
+ $default = false;
62
+
63
+ if ( isset( $args['default'] ) ) {
64
+ $default = $args['default'];
65
+ }
66
+
67
+ $value = get_theme_mod( $args['settings'], $default );
68
+
69
+ if ( empty( $value ) ) {
70
+ continue;
71
+ }
72
+
73
+ if ( ! isset( $args['responsive'] ) ) {
74
+ $this->add_vars( $args, $value, $controls );
75
+ }
76
+
77
+ if ( isset( $args['responsive'] ) && $args['responsive'] ) {
78
+ $this->add_responsive_vars( $args, $value, $controls );
79
+ }
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Default variable addition.
85
+ *
86
+ * @since 1.0.0
87
+ *
88
+ * @param array $args Settings arguments.
89
+ * @param mixed $value Settings value.
90
+ * @param array $controls List of Controls.
91
+ * @SuppressWarnings(PHPMD.NPathComplexity)
92
+ */
93
+ public function add_vars( $args, $value, $controls ) {
94
+ if ( is_array( $value ) ) {
95
+ if (
96
+ 'jupiterx-box-shadow' === $args['type'] &&
97
+ isset( $value['position'] ) &&
98
+ ' ' === $value['position']
99
+ ) {
100
+ $value['position'] = '';
101
+ }
102
+
103
+ $this->add_properties_vars( $args, $value, $controls );
104
+ }
105
+
106
+ if ( method_exists( $controls[ $args['type'] ], 'format_value' ) ) {
107
+ $value = call_user_func( [ $controls[ $args['type'] ], 'format_value' ], $value, $args );
108
+ }
109
+
110
+ // At this point when the value is still an array then we have to cancel adding this variable.
111
+ if ( is_array( $value ) ) {
112
+ return;
113
+ }
114
+
115
+ $name = isset( $args['css_var']['name'] ) ? $args['css_var']['name'] : $args['css_var'];
116
+
117
+ $name = isset( $args['device'] ) && 'desktop' !== $args['device'] ? "{$name}-{$args['device']}" : $name;
118
+
119
+ $name = str_replace( '_', '-', $name );
120
+
121
+ // Set a value replacement.
122
+ if ( isset( $args['css_var']['value'] ) ) {
123
+ $value = str_replace( '$', $value, $args['css_var']['value'] );
124
+ }
125
+
126
+ if ( is_numeric( $value ) || ! empty( $value ) ) {
127
+ $this->vars[ str_replace( '_', '-', $name ) ] = $value;
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Responsive variable addition.
133
+ *
134
+ * @param array $args Settings arguments.
135
+ * @param mixed $value Settings value.
136
+ * @param array $controls List of Controls.
137
+ */
138
+ public function add_responsive_vars( $args, $value, $controls ) {
139
+ foreach ( JupiterX_Customizer::$responsive_devices as $device => $media_query ) {
140
+ if ( ! isset( $value[ $device ] ) ) {
141
+ continue;
142
+ }
143
+
144
+ $device_args = array_merge( $args, [
145
+ 'device' => $device,
146
+ ] );
147
+
148
+ $device_value = $value[ $device ];
149
+
150
+ $this->add_vars( $device_args, $device_value, $controls );
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Add properties variable from array value.
156
+ *
157
+ * @since 1.0.0
158
+ *
159
+ * @param array $args Settings arguments.
160
+ * @param mixed $value Settings value.
161
+ * @param array $controls List of Controls.
162
+ */
163
+ public function add_properties_vars( $args, $value, $controls ) {
164
+ if ( method_exists( $controls[ $args['type'] ], 'format_properties' ) ) {
165
+ $value = $controls[ $args['type'] ]::format_properties( $value, $args );
166
+ }
167
+
168
+ foreach ( $value as $property => $property_value ) {
169
+ if ( isset( $args['device'] ) && 'desktop' !== $args['device'] ) {
170
+ $property = $property . '-' . $args['device'];
171
+ }
172
+
173
+ $css_var = str_replace( '_', '-', sprintf( '%1$s-%2$s', $args['css_var'], $property ) );
174
+
175
+ if ( ! is_array( $property_value ) && ( is_numeric( $property_value ) || ! empty( $property_value ) ) ) {
176
+ $this->vars[ $css_var ] = $property_value;
177
+ }
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Get the compiled vars.
183
+ *
184
+ * @since 1.0.0
185
+ *
186
+ * @return array Compiled vars.
187
+ */
188
+ public function get_vars() {
189
+ return $this->vars;
190
+ }
191
+ }
includes/customizer/api/modules/kirki-extend/base/class-output.php CHANGED
@@ -1,77 +1,77 @@
1
- <?php
2
- /**
3
- * Base output class.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Handles default output.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Kirki_Extend_Base_Output extends Kirki_Output {
25
-
26
- /**
27
- * Process output.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @param array $output Defined single output.
32
- * @param array $value Settings value.
33
- */
34
- protected function process_output( $output, $value ) {
35
- if ( ! isset( $this->field['responsive'] ) ) {
36
- $this->apply_output( $output, $value );
37
- }
38
-
39
- if ( isset( $this->field['responsive'] ) && $this->field['responsive'] ) {
40
- $this->apply_responsive_output( $output, $value );
41
- }
42
- }
43
-
44
- /**
45
- * CSS output.
46
- *
47
- * @since 1.0.0
48
- *
49
- * @param array $output Defined single output.
50
- * @param array $value Settings value.
51
- */
52
- protected function apply_output( $output, $value ) {
53
- parent::process_output( $output, $value );
54
- }
55
-
56
- /**
57
- * Responsive CSS output.
58
- *
59
- * @since 1.0.0
60
- *
61
- * @param array $output Defined single output.
62
- * @param array $value Settings value.
63
- */
64
- protected function apply_responsive_output( $output, $value ) {
65
- foreach ( JupiterX_Customizer::$responsive_devices as $device => $media_query ) {
66
- if ( ! isset( $value[ $device ] ) ) {
67
- continue;
68
- }
69
-
70
- $device_output = array_merge( [ 'media_query' => $media_query ], $output );
71
-
72
- $device_value = $value[ $device ];
73
-
74
- $this->apply_output( $device_output, $device_value );
75
- }
76
- }
77
- }
1
+ <?php
2
+ /**
3
+ * Base output class.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Handles default output.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Kirki_Extend_Base_Output extends Kirki_Output {
25
+
26
+ /**
27
+ * Process output.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @param array $output Defined single output.
32
+ * @param array $value Settings value.
33
+ */
34
+ protected function process_output( $output, $value ) {
35
+ if ( ! isset( $this->field['responsive'] ) ) {
36
+ $this->apply_output( $output, $value );
37
+ }
38
+
39
+ if ( isset( $this->field['responsive'] ) && $this->field['responsive'] ) {
40
+ $this->apply_responsive_output( $output, $value );
41
+ }
42
+ }
43
+
44
+ /**
45
+ * CSS output.
46
+ *
47
+ * @since 1.0.0
48
+ *
49
+ * @param array $output Defined single output.
50
+ * @param array $value Settings value.
51
+ */
52
+ protected function apply_output( $output, $value ) {
53
+ parent::process_output( $output, $value );
54
+ }
55
+
56
+ /**
57
+ * Responsive CSS output.
58
+ *
59
+ * @since 1.0.0
60
+ *
61
+ * @param array $output Defined single output.
62
+ * @param array $value Settings value.
63
+ */
64
+ protected function apply_responsive_output( $output, $value ) {
65
+ foreach ( JupiterX_Customizer::$responsive_devices as $device => $media_query ) {
66
+ if ( ! isset( $value[ $device ] ) ) {
67
+ continue;
68
+ }
69
+
70
+ $device_output = array_merge( [ 'media_query' => $media_query ], $output );
71
+
72
+ $device_value = $value[ $device ];
73
+
74
+ $this->apply_output( $device_output, $device_value );
75
+ }
76
+ }
77
+ }
includes/customizer/api/modules/kirki-extend/class-kirki-extend.php CHANGED
@@ -1,201 +1,201 @@
1
- <?php
2
- /**
3
- * This class handles extending Kirki plugin framework.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Define all customizer utils.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- final class JupiterX_Customizer_Kirki_Extend {
25
-
26
- /**
27
- * Control outputs.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var array
32
- */
33
- public $control_outputs = [
34
- 'jupiterx-background' => 'JupiterX_Customizer_Kirki_Extend_Output_Background',
35
- 'jupiterx-box-model' => 'JupiterX_Customizer_Kirki_Extend_Output_Box_Model',
36
- 'jupiterx-box-shadow' => 'JupiterX_Customizer_Kirki_Extend_Output_Box_Shadow',
37
- 'jupiterx-typography' => 'JupiterX_Customizer_Kirki_Extend_Output_Typography',
38
- 'jupiterx-border' => 'JupiterX_Customizer_Kirki_Extend_Output_Border',
39
- 'jupiterx-input' => 'JupiterX_Customizer_Kirki_Extend_Output_Input',
40
- ];
41
-
42
- /**
43
- * Module activate condition.
44
- *
45
- * @since 1.0.0
46
- *
47
- * @return boolean Class active state.
48
- */
49
- public static function active() {
50
- return class_exists( 'Kirki' );
51
- }
52
-
53
- /**
54
- * Construct the class.
55
- *
56
- * @since 1.0.0
57
- */
58
- public function __construct() {
59
- add_filter( 'kirki_section_types', [ $this, 'add_section_types' ] );
60
- add_filter( 'kirki_control_types', [ $this, 'add_control_types' ] );
61
- add_filter( 'kirki_jupiterx_output_control_classnames', [ $this, 'add_control_outputs' ] );
62
- add_filter( 'kirki_control_types_exclude', [ __CLASS__, 'exclude_controls' ] );
63
- add_action( 'init', [ $this, 'register_settings' ], 15 );
64
- add_action( 'customize_controls_enqueue_scripts', [ $this, 'dequeue_scripts' ], 15 );
65
- }
66
-
67
- /**
68
- * Exclude controls.
69
- *
70
- * @since 1.0.4
71
- *
72
- * @return array
73
- */
74
- public static function exclude_controls() {
75
- return [
76
- 'Kirki_Control_Checkbox',
77
- 'Kirki_Control_Background',
78
- 'Kirki_Control_Code',
79
- 'Kirki_Control_Color',
80
- 'Kirki_Control_Color_Palette',
81
- 'Kirki_Control_Date',
82
- 'Kirki_Control_Dashicons',
83
- 'Kirki_Control_Dimension',
84
- 'Kirki_Control_Dimensions',
85
- 'Kirki_Control_Editor',
86
- 'Kirki_Control_FontAwesome',
87
- 'Kirki_Control_Image',
88
- 'Kirki_Control_Multicolor',
89
- 'Kirki_Control_MultiCheck',
90
- 'Kirki_Control_Number',
91
- 'Kirki_Control_Palette',
92
- 'Kirki_Control_Radio',
93
- 'Kirki_Control_Radio_ButtonSet',
94
- 'Kirki_Control_Radio_Image',
95
- 'Kirki_Control_Repeater',
96
- 'Kirki_Control_Select',
97
- 'Kirki_Control_Slider',
98
- 'Kirki_Control_Sortable',
99
- 'Kirki_Control_Dimensions',
100
- 'Kirki_Control_Switch',
101
- 'Kirki_Control_Generic',
102
- 'Kirki_Control_Toggle',
103
- 'Kirki_Control_Typography',
104
- 'Kirki_Control_Image',
105
- 'Kirki_Control_Cropped_Image',
106
- 'Kirki_Control_Upload',
107
- ];
108
- }
109
-
110
- /**
111
- * Add custom section types to Kirki.
112
- *
113
- * @since 1.0.0
114
- *
115
- * @param array $section_types Defined section types from Kirki.
116
- *
117
- * @return array
118
- */
119
- public function add_section_types( $section_types = [] ) {
120
- return array_merge( $section_types, JupiterX_Customizer::$section_types );
121
- }
122
-
123
- /**
124
- * Add custom control types to Kirki.
125
- *
126
- * @since 1.0.0
127
- *
128
- * @param array $control_types Defined control types from Kirki.
129
- *
130
- * @return array
131
- */
132
- public function add_control_types( $control_types = [] ) {
133
- return array_merge( $control_types, JupiterX_Customizer::$control_types, JupiterX_Customizer::$group_control_types );
134
- }
135
-
136
- /**
137
- * Add custom control outputs to Kirki.
138
- *
139
- * @since 1.0.0
140
- *
141
- * @return array
142
- */
143
- public function add_control_outputs() {
144
- $outputs = $this->control_outputs;
145
-
146
- $controls = array_merge( JupiterX_Customizer::$control_types, JupiterX_Customizer::$group_control_types );
147
-
148
- foreach ( $controls as $control => $class ) {
149
- if ( ! key_exists( $control, $outputs ) ) {
150
- $outputs[ $control ] = 'JupiterX_Customizer_Kirki_Extend_Base_Output';
151
- }
152
- }
153
-
154
- return $outputs;
155
- }
156
-
157
- /**
158
- * Register settings to Kirki.
159
- *
160
- * @since 1.0.0
161
- */
162
- public function register_settings() {
163
- /**
164
- * Add config.
165
- *
166
- * @link https://aristath.github.io/kirki/docs/getting-started/config.html
167
- *
168
- * @since 1.0.0
169
- */
170
- Kirki::add_config(
171
- JupiterX_Customizer::$config_id, [
172
- 'capability' => 'edit_theme_options',
173
- 'option_type' => 'theme_mod',
174
- ]
175
- );
176
-
177
- // Add panels.
178
- foreach ( JupiterX_Customizer::$panels as $id => $panel ) {
179
- Kirki::add_panel( $id, $panel );
180
- }
181
-
182
- // Add sections.
183
- foreach ( JupiterX_Customizer::$sections as $id => $section ) {
184
- Kirki::add_section( $id, $section );
185
- }
186
-
187
- // Add settings.
188
- foreach ( JupiterX_Customizer::$settings as $id => $setting ) {
189
- Kirki::add_field( JupiterX_Customizer::$config_id, $setting );
190
- }
191
- }
192
-
193
- /**
194
- * Dequeue scripts.
195
- *
196
- * @since 1.0.4
197
- */
198
- public function dequeue_scripts() {
199
- wp_dequeue_style( 'kirki-selectWoo' );
200
- }
201
- }
1
+ <?php
2
+ /**
3
+ * This class handles extending Kirki plugin framework.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Define all customizer utils.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ final class JupiterX_Customizer_Kirki_Extend {
25
+
26
+ /**
27
+ * Control outputs.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var array
32
+ */
33
+ public $control_outputs = [
34
+ 'jupiterx-background' => 'JupiterX_Customizer_Kirki_Extend_Output_Background',
35
+ 'jupiterx-box-model' => 'JupiterX_Customizer_Kirki_Extend_Output_Box_Model',
36
+ 'jupiterx-box-shadow' => 'JupiterX_Customizer_Kirki_Extend_Output_Box_Shadow',
37
+ 'jupiterx-typography' => 'JupiterX_Customizer_Kirki_Extend_Output_Typography',
38
+ 'jupiterx-border' => 'JupiterX_Customizer_Kirki_Extend_Output_Border',
39
+ 'jupiterx-input' => 'JupiterX_Customizer_Kirki_Extend_Output_Input',
40
+ ];
41
+
42
+ /**
43
+ * Module activate condition.
44
+ *
45
+ * @since 1.0.0
46
+ *
47
+ * @return boolean Class active state.
48
+ */
49
+ public static function active() {
50
+ return class_exists( 'Kirki' );
51
+ }
52
+
53
+ /**
54
+ * Construct the class.
55
+ *
56
+ * @since 1.0.0
57
+ */
58
+ public function __construct() {
59
+ add_filter( 'kirki_section_types', [ $this, 'add_section_types' ] );
60
+ add_filter( 'kirki_control_types', [ $this, 'add_control_types' ] );
61
+ add_filter( 'kirki_jupiterx_output_control_classnames', [ $this, 'add_control_outputs' ] );
62
+ add_filter( 'kirki_control_types_exclude', [ __CLASS__, 'exclude_controls' ] );
63
+ add_action( 'init', [ $this, 'register_settings' ], 15 );
64
+ add_action( 'customize_controls_enqueue_scripts', [ $this, 'dequeue_scripts' ], 15 );
65
+ }
66
+
67
+ /**
68
+ * Exclude controls.
69
+ *
70
+ * @since 1.0.4
71
+ *
72
+ * @return array
73
+ */
74
+ public static function exclude_controls() {
75
+ return [
76
+ 'Kirki_Control_Checkbox',
77
+ 'Kirki_Control_Background',
78
+ 'Kirki_Control_Code',
79
+ 'Kirki_Control_Color',
80
+ 'Kirki_Control_Color_Palette',
81
+ 'Kirki_Control_Date',
82
+ 'Kirki_Control_Dashicons',
83
+ 'Kirki_Control_Dimension',
84
+ 'Kirki_Control_Dimensions',
85
+ 'Kirki_Control_Editor',
86
+ 'Kirki_Control_FontAwesome',
87
+ 'Kirki_Control_Image',
88
+ 'Kirki_Control_Multicolor',
89
+ 'Kirki_Control_MultiCheck',
90
+ 'Kirki_Control_Number',
91
+ 'Kirki_Control_Palette',
92
+ 'Kirki_Control_Radio',
93
+ 'Kirki_Control_Radio_ButtonSet',
94
+ 'Kirki_Control_Radio_Image',
95
+ 'Kirki_Control_Repeater',
96
+ 'Kirki_Control_Select',
97
+ 'Kirki_Control_Slider',
98
+ 'Kirki_Control_Sortable',
99
+ 'Kirki_Control_Dimensions',
100
+ 'Kirki_Control_Switch',
101
+ 'Kirki_Control_Generic',
102
+ 'Kirki_Control_Toggle',
103
+ 'Kirki_Control_Typography',
104
+ 'Kirki_Control_Image',
105
+ 'Kirki_Control_Cropped_Image',
106
+ 'Kirki_Control_Upload',
107
+ ];
108
+ }
109
+
110
+ /**
111
+ * Add custom section types to Kirki.
112
+ *
113
+ * @since 1.0.0
114
+ *
115
+ * @param array $section_types Defined section types from Kirki.
116
+ *
117
+ * @return array
118
+ */
119
+ public function add_section_types( $section_types = [] ) {
120
+ return array_merge( $section_types, JupiterX_Customizer::$section_types );
121
+ }
122
+
123
+ /**
124
+ * Add custom control types to Kirki.
125
+ *
126
+ * @since 1.0.0
127
+ *
128
+ * @param array $control_types Defined control types from Kirki.
129
+ *
130
+ * @return array
131
+ */
132
+ public function add_control_types( $control_types = [] ) {
133
+ return array_merge( $control_types, JupiterX_Customizer::$control_types, JupiterX_Customizer::$group_control_types );
134
+ }
135
+
136
+ /**
137
+ * Add custom control outputs to Kirki.
138
+ *
139
+ * @since 1.0.0
140
+ *
141
+ * @return array
142
+ */
143
+ public function add_control_outputs() {
144
+ $outputs = $this->control_outputs;
145
+
146
+ $controls = array_merge( JupiterX_Customizer::$control_types, JupiterX_Customizer::$group_control_types );
147
+
148
+ foreach ( $controls as $control => $class ) {
149
+ if ( ! key_exists( $control, $outputs ) ) {
150
+ $outputs[ $control ] = 'JupiterX_Customizer_Kirki_Extend_Base_Output';
151
+ }
152
+ }
153
+
154
+ return $outputs;
155
+ }
156
+
157
+ /**
158
+ * Register settings to Kirki.
159
+ *
160
+ * @since 1.0.0
161
+ */
162
+ public function register_settings() {
163
+ /**
164
+ * Add config.
165
+ *
166
+ * @link https://aristath.github.io/kirki/docs/getting-started/config.html
167
+ *
168
+ * @since 1.0.0
169
+ */
170
+ Kirki::add_config(
171
+ JupiterX_Customizer::$config_id, [
172
+ 'capability' => 'edit_theme_options',
173
+ 'option_type' => 'theme_mod',
174
+ ]
175
+ );
176
+
177
+ // Add panels.
178
+ foreach ( JupiterX_Customizer::$panels as $id => $panel ) {
179
+ Kirki::add_panel( $id, $panel );
180
+ }
181
+
182
+ // Add sections.
183
+ foreach ( JupiterX_Customizer::$sections as $id => $section ) {
184
+ Kirki::add_section( $id, $section );
185
+ }
186
+
187
+ // Add settings.
188
+ foreach ( JupiterX_Customizer::$settings as $id => $setting ) {
189
+ Kirki::add_field( JupiterX_Customizer::$config_id, $setting );
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Dequeue scripts.
195
+ *
196
+ * @since 1.0.4
197
+ */
198
+ public function dequeue_scripts() {
199
+ wp_dequeue_style( 'kirki-selectWoo' );
200
+ }
201
+ }
includes/customizer/api/modules/kirki-extend/output/class-background.php CHANGED
@@ -1,103 +1,103 @@
1
- <?php
2
- /**
3
- * This class handles background control css output.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Overrides Kirki CSS output.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Kirki_Extend_Output_Background extends JupiterX_Customizer_Kirki_Extend_Base_Output {
25
-
26
- /**
27
- * CSS output.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @param array $output Defined single output.
32
- * @param array $value Settings value.
33
- */
34
- protected function apply_output( $output, $value ) {
35
- $output = wp_parse_args(
36
- $output, [
37
- 'element' => '',
38
- 'property' => '',
39
- 'media_query' => 'global',
40
- 'unit' => '',
41
- 'prefix' => '',
42
- 'suffix' => '',
43
- ]
44
- );
45
-
46
- if ( ! is_array( $value ) ) {
47
- return;
48
- }
49
-
50
- // Add fallback for value.
51
- $value = wp_parse_args(
52
- $value, [
53
- 'type' => 'classic',
54
- 'color' => '',
55
- 'image' => '',
56
- 'repeat' => 'no-repeat',
57
- 'attachment' => 'scroll',
58
- 'size' => 'auto',
59
- 'position' => 'initial',
60
- 'gradient_type' => 'linear',
61
- 'angle' => '90',
62
- 'color_from' => 'transparent',
63
- 'color_to' => 'transparent',
64
- ]
65
- );
66
-
67
- if ( 'classic' === $value['type'] ) {
68
- $this->styles[ $output['media_query'] ][ $output['element'] ]['background'] = 'none';
69
-
70
- // CSS for background color.
71
- if ( ! empty( $value['color'] ) ) {
72
- $this->styles[ $output['media_query'] ][ $output['element'] ]['background-color'] = $output['prefix'] . $value['color'] . $output['suffix'];
73
- }
74
-
75
- // Exit proceedings if background image is empty.
76
- if ( empty( $value['image'] ) ) {
77
- return;
78
- }
79
-
80
- // Style for background image.
81
- $this->styles[ $output['media_query'] ][ $output['element'] ]['background-image'] = $output['prefix'] . $this->process_property_value( 'background-image', $value['image'] ) . $output['suffix'];
82
-
83
- // CSS for these properties.
84
- foreach ( [ 'position', 'repeat', 'attachment', 'size' ] as $property ) {
85
- if ( isset( $value[ $property ] ) && ! empty( $value[ $property ] ) ) {
86
- $this->styles[ $output['media_query'] ][ $output['element'] ][ 'background-' . $property ] = $output['prefix'] . $value[ $property ] . $output['suffix'];
87
- }
88
- }
89
- }
90
-
91
- if ( 'gradient' === $value['type'] ) {
92
- if ( empty( $value['angle'] ) ) {
93
- $value['angle'] = '90';
94
- }
95
-
96
- // Create gradient value.
97
- $gradient = 'radial' === $value['gradient_type'] ? sprintf( 'radial-gradient(%1$s, %2$s)', $value['color_from'], $value['color_to'] ) : sprintf( 'linear-gradient(%1$sdeg, %2$s, %3$s)', $value['angle'], $value['color_from'], $value['color_to'] );
98
-
99
- // CSS for gradient.
100
- $this->styles[ $output['media_query'] ][ $output['element'] ]['background'] = $output['prefix'] . $gradient . $output['suffix'];
101
- }
102
- }
103
- }
1
+ <?php
2
+ /**
3
+ * This class handles background control css output.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Overrides Kirki CSS output.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Kirki_Extend_Output_Background extends JupiterX_Customizer_Kirki_Extend_Base_Output {
25
+
26
+ /**
27
+ * CSS output.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @param array $output Defined single output.
32
+ * @param array $value Settings value.
33
+ */
34
+ protected function apply_output( $output, $value ) {
35
+ $output = wp_parse_args(
36
+ $output, [
37
+ 'element' => '',
38
+ 'property' => '',
39
+ 'media_query' => 'global',
40
+ 'unit' => '',
41
+ 'prefix' => '',
42
+ 'suffix' => '',
43
+ ]
44
+ );
45
+
46
+ if ( ! is_array( $value ) ) {
47
+ return;
48
+ }
49
+
50
+ // Add fallback for value.
51
+ $value = wp_parse_args(
52
+ $value, [
53
+ 'type' => 'classic',
54
+ 'color' => '',
55
+ 'image' => '',
56
+ 'repeat' => 'no-repeat',
57
+ 'attachment' => 'scroll',
58
+ 'size' => 'auto',
59
+ 'position' => 'initial',
60
+ 'gradient_type' => 'linear',
61
+ 'angle' => '90',
62
+ 'color_from' => 'transparent',
63
+ 'color_to' => 'transparent',
64
+ ]
65
+ );
66
+
67
+ if ( 'classic' === $value['type'] ) {
68
+ $this->styles[ $output['media_query'] ][ $output['element'] ]['background'] = 'none';
69
+
70
+ // CSS for background color.
71
+ if ( ! empty( $value['color'] ) ) {
72
+ $this->styles[ $output['media_query'] ][ $output['element'] ]['background-color'] = $output['prefix'] . $value['color'] . $output['suffix'];
73
+ }
74
+
75
+ // Exit proceedings if background image is empty.
76
+ if ( empty( $value['image'] ) ) {
77
+ return;
78
+ }
79
+
80
+ // Style for background image.
81
+ $this->styles[ $output['media_query'] ][ $output['element'] ]['background-image'] = $output['prefix'] . $this->process_property_value( 'background-image', $value['image'] ) . $output['suffix'];
82
+
83
+ // CSS for these properties.
84
+ foreach ( [ 'position', 'repeat', 'attachment', 'size' ] as $property ) {
85
+ if ( isset( $value[ $property ] ) && ! empty( $value[ $property ] ) ) {
86
+ $this->styles[ $output['media_query'] ][ $output['element'] ][ 'background-' . $property ] = $output['prefix'] . $value[ $property ] . $output['suffix'];
87
+ }
88
+ }
89
+ }
90
+
91
+ if ( 'gradient' === $value['type'] ) {
92
+ if ( empty( $value['angle'] ) ) {
93
+ $value['angle'] = '90';
94
+ }
95
+
96
+ // Create gradient value.
97
+ $gradient = 'radial' === $value['gradient_type'] ? sprintf( 'radial-gradient(%1$s, %2$s)', $value['color_from'], $value['color_to'] ) : sprintf( 'linear-gradient(%1$sdeg, %2$s, %3$s)', $value['angle'], $value['color_from'], $value['color_to'] );
98
+
99
+ // CSS for gradient.
100
+ $this->styles[ $output['media_query'] ][ $output['element'] ]['background'] = $output['prefix'] . $gradient . $output['suffix'];
101
+ }
102
+ }
103
+ }
includes/customizer/api/modules/kirki-extend/output/class-border.php CHANGED
@@ -1,109 +1,109 @@
1
- <?php
2
- /**
3
- * This class handles border control css output.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Overrides Kirki CSS output.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Kirki_Extend_Output_Border extends JupiterX_Customizer_Kirki_Extend_Base_Output {
25
-
26
- /**
27
- * CSS output.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @param array $output Defined single output.
32
- * @param array $value Settings value.
33
- * @SuppressWarnings(PHPMD.NPathComplexity)
34
- */
35
- protected function apply_output( $output, $value ) {
36
- $output = array_merge(
37
- [
38
- 'element' => '',
39
- 'property' => 'border',
40
- 'media_query' => 'global',
41
- 'prefix' => '',
42
- 'suffix' => '',
43
- ],
44
- $output
45
- );
46
-
47
- $value = array_merge(
48
- [
49
- 'size' => [],
50
- 'radius' => [],
51
- 'width' => [],
52
- 'style' => 'solid',
53
- 'color' => '',
54
- ],
55
- $this->value
56
- );
57
-
58
- // Get a value from array and use it to the property.
59
- if ( isset( $output['choice'] ) && isset( $output['property'] ) ) {
60
- switch ( $output['choice'] ) {
61
- case 'size':
62
- case 'radius':
63
- case 'width':
64
- if ( isset( $value[ $output['choice'] ] ) && ! empty( $value[ $output['choice'] ] ) ) {
65
- $input_value = JupiterX_Customizer_Control_Input::format_value( $value[ $output['choice'] ] );
66
- $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] ] = $this->apply_value_pattern( $output, $input_value );
67
- }
68
- break;
69
-
70
- case 'style':
71
- case 'color':
72
- if ( isset( $value[ $output['choice'] ] ) && '' !== $value[ $output['choice'] ] ) {
73
- $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] ] = $this->apply_value_pattern( $output, $value[ $output['choice'] ] );
74
- }
75
- break;
76
- }
77
-
78
- return;
79
- }
80
-
81
- // Size.
82
- if ( ! empty( $value['size'] ) ) {
83
- $size = JupiterX_Customizer_Control_Input::format_value( $value['size'] );
84
- $this->styles[ $output['media_query'] ][ $output['element'] ]['width'] = $output['prefix'] . $size . $output['suffix'];
85
- }
86
-
87
- // Border Radius.
88
- if ( ! empty( $value['radius'] ) ) {
89
- $radius = JupiterX_Customizer_Control_Input::format_value( $value['radius'] );
90
- $this->styles[ $output['media_query'] ][ $output['element'] ]['border-radius'] = $output['prefix'] . $radius . $output['suffix'];
91
- }
92
-
93
- // Border Width.
94
- if ( ! empty( $value['width'] ) ) {
95
- $width = JupiterX_Customizer_Control_Input::format_value( $value['width'] );
96
- $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] . '-width' ] = $output['prefix'] . $width . $output['suffix'];
97
- }
98
-
99
- // Border Style.
100
- if ( ! empty( $value['style'] ) ) {
101
- $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] . '-style' ] = $output['prefix'] . $value['style'] . $output['suffix'];
102
- }
103
-
104
- // Border Color.
105
- if ( ! empty( $value['color'] ) ) {
106
- $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] . '-color' ] = $output['prefix'] . $value['color'] . $output['suffix'];
107
- }
108
- }
109
- }
1
+ <?php
2
+ /**
3
+ * This class handles border control css output.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Overrides Kirki CSS output.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Kirki_Extend_Output_Border extends JupiterX_Customizer_Kirki_Extend_Base_Output {
25
+
26
+ /**
27
+ * CSS output.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @param array $output Defined single output.
32
+ * @param array $value Settings value.
33
+ * @SuppressWarnings(PHPMD.NPathComplexity)
34
+ */
35
+ protected function apply_output( $output, $value ) {
36
+ $output = array_merge(
37
+ [
38
+ 'element' => '',
39
+ 'property' => 'border',
40
+ 'media_query' => 'global',
41
+ 'prefix' => '',
42
+ 'suffix' => '',
43
+ ],
44
+ $output
45
+ );
46
+
47
+ $value = array_merge(
48
+ [
49
+ 'size' => [],
50
+ 'radius' => [],
51
+ 'width' => [],
52
+ 'style' => 'solid',
53
+ 'color' => '',
54
+ ],
55
+ $this->value
56
+ );
57
+
58
+ // Get a value from array and use it to the property.
59
+ if ( isset( $output['choice'] ) && isset( $output['property'] ) ) {
60
+ switch ( $output['choice'] ) {
61
+ case 'size':
62
+ case 'radius':
63
+ case 'width':
64
+ if ( isset( $value[ $output['choice'] ] ) && ! empty( $value[ $output['choice'] ] ) ) {
65
+ $input_value = JupiterX_Customizer_Control_Input::format_value( $value[ $output['choice'] ] );
66
+ $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] ] = $this->apply_value_pattern( $output, $input_value );
67
+ }
68
+ break;
69
+
70
+ case 'style':
71
+ case 'color':
72
+ if ( isset( $value[ $output['choice'] ] ) && '' !== $value[ $output['choice'] ] ) {
73
+ $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] ] = $this->apply_value_pattern( $output, $value[ $output['choice'] ] );
74
+ }
75
+ break;
76
+ }
77
+
78
+ return;
79
+ }
80
+
81
+ // Size.
82
+ if ( ! empty( $value['size'] ) ) {
83
+ $size = JupiterX_Customizer_Control_Input::format_value( $value['size'] );
84
+ $this->styles[ $output['media_query'] ][ $output['element'] ]['width'] = $output['prefix'] . $size . $output['suffix'];
85
+ }
86
+
87
+ // Border Radius.
88
+ if ( ! empty( $value['radius'] ) ) {
89
+ $radius = JupiterX_Customizer_Control_Input::format_value( $value['radius'] );
90
+ $this->styles[ $output['media_query'] ][ $output['element'] ]['border-radius'] = $output['prefix'] . $radius . $output['suffix'];
91
+ }
92
+
93
+ // Border Width.
94
+ if ( ! empty( $value['width'] ) ) {
95
+ $width = JupiterX_Customizer_Control_Input::format_value( $value['width'] );
96
+ $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] . '-width' ] = $output['prefix'] . $width . $output['suffix'];
97
+ }
98
+
99
+ // Border Style.
100
+ if ( ! empty( $value['style'] ) ) {
101
+ $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] . '-style' ] = $output['prefix'] . $value['style'] . $output['suffix'];
102
+ }
103
+
104
+ // Border Color.
105
+ if ( ! empty( $value['color'] ) ) {
106
+ $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] . '-color' ] = $output['prefix'] . $value['color'] . $output['suffix'];
107
+ }
108
+ }
109
+ }
includes/customizer/api/modules/kirki-extend/output/class-box-model.php CHANGED
@@ -1,86 +1,86 @@
1
- <?php
2
- /**
3
- * This class handles box model control css output.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Overrides Kirki CSS output.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Kirki_Extend_Output_Box_Model extends JupiterX_Customizer_Kirki_Extend_Base_Output {
25
-
26
- /**
27
- * Processes a single item from the `output` array.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @param array $output Defined single output.
32
- * @param array $value Settings value.
33
- *
34
- * @SuppressWarnings(PHPMD.NPathComplexity)
35
- */
36
- protected function apply_output( $output, $value ) {
37
- $output = wp_parse_args(
38
- $output, array(
39
- 'element' => '',
40
- 'property' => '',
41
- 'media_query' => 'global',
42
- 'prefix' => '',
43
- 'suffix' => '',
44
- )
45
- );
46
-
47
- if ( ! is_array( $value ) ) {
48
- return;
49
- }
50
-
51
- if ( ! isset( $this->field['exclude'] ) ) {
52
- $this->field['exclude'] = [];
53
- }
54
-
55
- $positions = [ 'top', 'right', 'bottom', 'left' ];
56
- $default_unit = JupiterX_Customizer_Control_Box_Model::$default_unit;
57
-
58
- if ( ! in_array( 'margin', $this->field['exclude'], true ) ) {
59
- $margin_unit = isset( $value['margin_unit'] ) ? $value['margin_unit'] : $default_unit;
60
-
61
- foreach ( $positions as $position ) {
62
- // Accepts non-numeric value such as 'auto'.
63
- if ( array_key_exists( 'margin_' . $position, $value ) ) {
64
- $property = 'margin-' . $position;
65
- $unit = is_numeric( $value[ 'margin_' . $position ] ) ? $margin_unit : '';
66
-
67
- $this->styles[ $output['media_query'] ][ $output['element'] ][ $property ] = $output['prefix'] . $this->process_property_value( $property, $value[ 'margin_' . $position ] ) . $unit . $output['suffix'];
68
- }
69
- }
70
- }
71
-
72
- if ( ! in_array( 'padding', $this->field['exclude'], true ) ) {
73
- $padding_unit = isset( $value['padding_unit'] ) ? $value['padding_unit'] : $default_unit;
74
-
75
- foreach ( $positions as $position ) {
76
- // Does not accept any value that is not numeric.
77
- if ( array_key_exists( 'padding_' . $position, $value ) && is_numeric( $value[ 'padding_' . $position ] ) ) {
78
- $property = 'padding-' . $position;
79
- $unit = $padding_unit;
80
-
81
- $this->styles[ $output['media_query'] ][ $output['element'] ][ $property ] = $output['prefix'] . $this->process_property_value( $property, $value[ 'padding_' . $position ] ) . $unit . $output['suffix'];
82
- }
83
- }
84
- }
85
- }
86
- }
1
+ <?php
2
+ /**
3
+ * This class handles box model control css output.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Overrides Kirki CSS output.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Kirki_Extend_Output_Box_Model extends JupiterX_Customizer_Kirki_Extend_Base_Output {
25
+
26
+ /**
27
+ * Processes a single item from the `output` array.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @param array $output Defined single output.
32
+ * @param array $value Settings value.
33
+ *
34
+ * @SuppressWarnings(PHPMD.NPathComplexity)
35
+ */
36
+ protected function apply_output( $output, $value ) {
37
+ $output = wp_parse_args(
38
+ $output, array(
39
+ 'element' => '',
40
+ 'property' => '',
41
+ 'media_query' => 'global',
42
+ 'prefix' => '',
43
+ 'suffix' => '',
44
+ )
45
+ );
46
+
47
+ if ( ! is_array( $value ) ) {
48
+ return;
49
+ }
50
+
51
+ if ( ! isset( $this->field['exclude'] ) ) {
52
+ $this->field['exclude'] = [];
53
+ }
54
+
55
+ $positions = [ 'top', 'right', 'bottom', 'left' ];
56
+ $default_unit = JupiterX_Customizer_Control_Box_Model::$default_unit;
57
+
58
+ if ( ! in_array( 'margin', $this->field['exclude'], true ) ) {
59
+ $margin_unit = isset( $value['margin_unit'] ) ? $value['margin_unit'] : $default_unit;
60
+
61
+ foreach ( $positions as $position ) {
62
+ // Accepts non-numeric value such as 'auto'.
63
+ if ( array_key_exists( 'margin_' . $position, $value ) ) {
64
+ $property = 'margin-' . $position;
65
+ $unit = is_numeric( $value[ 'margin_' . $position ] ) ? $margin_unit : '';
66
+
67
+ $this->styles[ $output['media_query'] ][ $output['element'] ][ $property ] = $output['prefix'] . $this->process_property_value( $property, $value[ 'margin_' . $position ] ) . $unit . $output['suffix'];
68
+ }
69
+ }
70
+ }
71
+
72
+ if ( ! in_array( 'padding', $this->field['exclude'], true ) ) {
73
+ $padding_unit = isset( $value['padding_unit'] ) ? $value['padding_unit'] : $default_unit;
74
+
75
+ foreach ( $positions as $position ) {
76
+ // Does not accept any value that is not numeric.
77
+ if ( array_key_exists( 'padding_' . $position, $value ) && is_numeric( $value[ 'padding_' . $position ] ) ) {
78
+ $property = 'padding-' . $position;
79
+ $unit = $padding_unit;
80
+
81
+ $this->styles[ $output['media_query'] ][ $output['element'] ][ $property ] = $output['prefix'] . $this->process_property_value( $property, $value[ 'padding_' . $position ] ) . $unit . $output['suffix'];
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }
includes/customizer/api/modules/kirki-extend/output/class-box-shadow.php CHANGED
@@ -1,50 +1,50 @@
1
- <?php
2
- /**
3
- * Handles Box Shadow control css output.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Overrides Kirki CSS output.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Kirki_Extend_Output_Box_Shadow extends JupiterX_Customizer_Kirki_Extend_Base_Output {
25
-
26
- /**
27
- * CSS output.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @param array $output Defined single output.
32
- * @param array $value Settings value.
33
- */
34
- protected function apply_output( $output, $value ) {
35
- $output = wp_parse_args(
36
- $output, [
37
- 'element' => '',
38
- 'property' => 'box-shadow',
39
- 'media_query' => 'global',
40
- 'unit' => '',
41
- 'prefix' => '',
42
- 'suffix' => '',
43
- ]
44
- );
45
-
46
- $value = JupiterX_Customizer_Group_Control_Box_Shadow::format_value( $value, $output['units'] );
47
-
48
- $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] ] = $output['prefix'] . $this->process_property_value( $output['property'], $value ) . $output['suffix'];
49
- }
50
- }
1
+ <?php
2
+ /**
3
+ * Handles Box Shadow control css output.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Overrides Kirki CSS output.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Kirki_Extend_Output_Box_Shadow extends JupiterX_Customizer_Kirki_Extend_Base_Output {
25
+
26
+ /**
27
+ * CSS output.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @param array $output Defined single output.
32
+ * @param array $value Settings value.
33
+ */
34
+ protected function apply_output( $output, $value ) {
35
+ $output = wp_parse_args(
36
+ $output, [
37
+ 'element' => '',
38
+ 'property' => 'box-shadow',
39
+ 'media_query' => 'global',
40
+ 'unit' => '',
41
+ 'prefix' => '',
42
+ 'suffix' => '',
43
+ ]
44
+ );
45
+
46
+ $value = JupiterX_Customizer_Group_Control_Box_Shadow::format_value( $value, $output['units'] );
47
+
48
+ $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] ] = $output['prefix'] . $this->process_property_value( $output['property'], $value ) . $output['suffix'];
49
+ }
50
+ }
includes/customizer/api/modules/kirki-extend/output/class-input.php CHANGED
@@ -1,62 +1,62 @@
1
- <?php
2
- /**
3
- * Handles Input control css output.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Overrides Kirki CSS output.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Kirki_Extend_Output_Input extends JupiterX_Customizer_Kirki_Extend_Base_Output {
25
-
26
- /**
27
- * CSS output.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @param array $output Defined single output.
32
- * @param array $filtered_value Filtered settings value.
33
- */
34
- protected function apply_output( $output, $filtered_value ) {
35
- $output = array_merge(
36
- [
37
- 'element' => '',
38
- 'property' => '',
39
- 'media_query' => 'global',
40
- 'prefix' => '',
41
- 'suffix' => '',
42
- ],
43
- $output
44
- );
45
-
46
- if ( ! is_array( $this->value ) ) {
47
- return;
48
- }
49
-
50
- $value = array_merge(
51
- [
52
- 'size' => '',
53
- 'unit' => '',
54
- ],
55
- $this->value
56
- );
57
-
58
- $css_value = JupiterX_Customizer_Control_Input::format_value( $value );
59
-
60
- $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] ] = $output['prefix'] . $this->apply_value_pattern( $output, $css_value ) . $output['suffix'];
61
- }
62
- }
1
+ <?php
2
+ /**
3
+ * Handles Input control css output.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Overrides Kirki CSS output.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Kirki_Extend_Output_Input extends JupiterX_Customizer_Kirki_Extend_Base_Output {
25
+
26
+ /**
27
+ * CSS output.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @param array $output Defined single output.
32
+ * @param array $filtered_value Filtered settings value.
33
+ */
34
+ protected function apply_output( $output, $filtered_value ) {
35
+ $output = array_merge(
36
+ [
37
+ 'element' => '',
38
+ 'property' => '',
39
+ 'media_query' => 'global',
40
+ 'prefix' => '',
41
+ 'suffix' => '',
42
+ ],
43
+ $output
44
+ );
45
+
46
+ if ( ! is_array( $this->value ) ) {
47
+ return;
48
+ }
49
+
50
+ $value = array_merge(
51
+ [
52
+ 'size' => '',
53
+ 'unit' => '',
54
+ ],
55
+ $this->value
56
+ );
57
+
58
+ $css_value = JupiterX_Customizer_Control_Input::format_value( $value );
59
+
60
+ $this->styles[ $output['media_query'] ][ $output['element'] ][ $output['property'] ] = $output['prefix'] . $this->apply_value_pattern( $output, $css_value ) . $output['suffix'];
61
+ }
62
+ }
includes/customizer/api/modules/kirki-extend/output/class-typography.php CHANGED
@@ -1,73 +1,73 @@
1
- <?php
2
- /**
3
- * This class handles typography control css output.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Overrides Kirki CSS output.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- class JupiterX_Customizer_Kirki_Extend_Output_Typography extends JupiterX_Customizer_Kirki_Extend_Base_Output {
25
-
26
- /**
27
- * CSS output.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @param array $output Defined single output.
32
- * @param array $value Settings value.
33
- */
34
- protected function apply_output( $output, $value ) {
35
- $output = array_merge(
36
- [
37
- 'element' => '',
38
- 'property' => '',
39
- 'media_query' => 'global',
40
- 'prefix' => '',
41
- 'suffix' => '',
42
- ],
43
- $output
44
- );
45
-
46
- if ( ! is_array( $value ) ) {
47
- return;
48
- }
49
-
50
- $with_unit = [ 'font_size', 'line_height', 'letter_spacing' ];
51
-
52
- if ( isset( $value['font_size'] ) && empty( $value['font_size'] ) ) {
53
- $value['font_size'] = 'inherit';
54
- }
55
-
56
- foreach ( $value as $property => $raw_value ) {
57
- $css = [
58
- 'property' => str_replace( '_', '-', $property ),
59
- 'value' => $raw_value,
60
- ];
61
-
62
- if ( isset( $output['choice'] ) && $output['choice'] !== $property ) {
63
- continue;
64
- }
65
-
66
- if ( in_array( $property, $with_unit, true ) ) {
67
- $css['value'] = $this->apply_value_pattern( $output, JupiterX_Customizer_Control_Input::format_value( $raw_value ) );
68
- }
69
-
70
- $this->styles[ $output['media_query'] ][ $output['element'] ][ $css['property'] ] = $output['prefix'] . $this->process_property_value( $css['property'], $css['value'] ) . $output['suffix'];
71
- }
72
- }
73
- }
1
+ <?php
2
+ /**
3
+ * This class handles typography control css output.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Overrides Kirki CSS output.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ class JupiterX_Customizer_Kirki_Extend_Output_Typography extends JupiterX_Customizer_Kirki_Extend_Base_Output {
25
+
26
+ /**
27
+ * CSS output.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @param array $output Defined single output.
32
+ * @param array $value Settings value.
33
+ */
34
+ protected function apply_output( $output, $value ) {
35
+ $output = array_merge(
36
+ [
37
+ 'element' => '',
38
+ 'property' => '',
39
+ 'media_query' => 'global',
40
+ 'prefix' => '',
41
+ 'suffix' => '',
42
+ ],
43
+ $output
44
+ );
45
+
46
+ if ( ! is_array( $value ) ) {
47
+ return;
48
+ }
49
+
50
+ $with_unit = [ 'font_size', 'line_height', 'letter_spacing' ];
51
+
52
+ if ( isset( $value['font_size'] ) && empty( $value['font_size'] ) ) {
53
+ $value['font_size'] = 'inherit';
54
+ }
55
+
56
+ foreach ( $value as $property => $raw_value ) {
57
+ $css = [
58
+ 'property' => str_replace( '_', '-', $property ),
59
+ 'value' => $raw_value,
60
+ ];
61
+
62
+ if ( isset( $output['choice'] ) && $output['choice'] !== $property ) {
63
+ continue;
64
+ }
65
+
66
+ if ( in_array( $property, $with_unit, true ) ) {
67
+ $css['value'] = $this->apply_value_pattern( $output, JupiterX_Customizer_Control_Input::format_value( $raw_value ) );
68
+ }
69
+
70
+ $this->styles[ $output['media_query'] ][ $output['element'] ][ $css['property'] ] = $output['prefix'] . $this->process_property_value( $css['property'], $css['value'] ) . $output['suffix'];
71
+ }
72
+ }
73
+ }
includes/customizer/api/modules/post-message/class-post-message.php CHANGED
@@ -1,67 +1,67 @@
1
- <?php
2
- /**
3
- * This class handles CSS post message for Customizer previewer.
4
- *
5
- * @package JupiterX\Framework\API\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- if ( ! defined( 'ABSPATH' ) ) {
12
- exit;
13
- }
14
-
15
- /**
16
- * Post message preview scripts.
17
- *
18
- * @since 1.0.0
19
- * @ignore
20
- * @access private
21
- *
22
- * @package JupiterX\Framework\API\Customizer
23
- */
24
- final class JupiterX_Customizer_Post_Message {
25
-
26
- /**
27
- * Module activate condition.
28
- *
29
- * @since 1.0.0
30
- *
31
- * @return boolean Class active state.
32
- */
33
- public static function active() {
34
- return class_exists( 'Kirki' );
35
- }
36
-
37
- /**
38
- * Construct the class.
39
- *
40
- * @since 1.0.0
41
- */
42
- public function __construct() {
43
- add_action( 'customize_preview_init', [ $this, 'enqueue_preview_scripts' ] );
44
- }
45
-
46
- /**
47
- * Enqueue preview styles and scripts.
48
- *
49
- * @since 1.0.0
50
- */
51
- public function enqueue_preview_scripts() {
52
- wp_enqueue_script( 'jupiterx-customizer-postmessage', JUPITERX_ASSETS_URL . 'dist/js/customizer-postmessage' . JUPITERX_MIN_JS . '.js', [ 'jquery', 'kirki_auto_postmessage' ], JUPITERX_VERSION, true );
53
-
54
- $settings = [];
55
-
56
- foreach ( JupiterX_Customizer::$settings as $key => $setting ) {
57
- if ( isset( $setting['transport'] ) && 'postMessage' === $setting['transport'] && isset( $setting['output'] ) && ! empty( $setting['output'] ) ) {
58
- $settings[] = $setting;
59
- }
60
- }
61
-
62
- wp_localize_script( 'jupiterx-customizer-postmessage', 'jupiterPostMessage', [
63
- 'settings' => $settings,
64
- 'responsiveDevices' => JupiterX_Customizer::$responsive_devices,
65
- ] );
66
- }
67
- }
1
+ <?php
2
+ /**
3
+ * This class handles CSS post message for Customizer previewer.
4
+ *
5
+ * @package JupiterX\Framework\API\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Post message preview scripts.
17
+ *
18
+ * @since 1.0.0
19
+ * @ignore
20
+ * @access private
21
+ *
22
+ * @package JupiterX\Framework\API\Customizer
23
+ */
24
+ final class JupiterX_Customizer_Post_Message {
25
+
26
+ /**
27
+ * Module activate condition.
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @return boolean Class active state.
32
+ */
33
+ public static function active() {
34
+ return class_exists( 'Kirki' );
35
+ }
36
+
37
+ /**
38
+ * Construct the class.
39
+ *
40
+ * @since 1.0.0
41
+ */
42
+ public function __construct() {
43
+ add_action( 'customize_preview_init', [ $this, 'enqueue_preview_scripts' ] );
44
+ }
45
+
46
+ /**
47
+ * Enqueue preview styles and scripts.
48
+ *
49
+ * @since 1.0.0
50
+ */
51
+ public function enqueue_preview_scripts() {
52
+ wp_enqueue_script( 'jupiterx-customizer-postmessage', JUPITERX_ASSETS_URL . 'dist/js/customizer-postmessage' . JUPITERX_MIN_JS . '.js', [ 'jquery', 'kirki_auto_postmessage' ], JUPITERX_VERSION, true );
53
+
54
+ $settings = [];
55
+
56
+ foreach ( JupiterX_Customizer::$settings as $key => $setting ) {
57
+ if ( isset( $setting['transport'] ) && 'postMessage' === $setting['transport'] && isset( $setting['output'] ) && ! empty( $setting['output'] ) ) {
58
+ $settings[] = $setting;
59
+ }
60
+ }
61
+
62
+ wp_localize_script( 'jupiterx-customizer-postmessage', 'jupiterPostMessage', [
63
+ 'settings' => $settings,
64
+ 'responsiveDevices' => JupiterX_Customizer::$responsive_devices,
65
+ ] );
66
+ }
67
+ }
includes/customizer/functions.php CHANGED
@@ -1,507 +1,845 @@
1
- <?php
2
- /**
3
- * The Jupiter Customizer component.
4
- *
5
- * @package JupiterX_Core\Customizer
6
- */
7
-
8
- /**
9
- * Load Kirki library.
10
- *
11
- * @since 1.0.0
12
- */
13
- function jupiterx_customizer_kirki() {
14
- jupiterx_core()->load_files( [ 'customizer/vendors/kirki/kirki' ] );
15
- }
16
-
17
- add_action( 'jupiterx_init', 'jupiterx_load_customizer_dependencies', 5 );
18
- /**
19
- * Load Customzier.
20
- *
21
- * @since 1.9.0
22
- *
23
- * @return void
24
- */
25
- function jupiterx_load_customizer_dependencies() {
26
- jupiterx_core()->load_files( [ 'customizer/api/customizer' ] );
27
- jupiterx_core()->load_files( [ 'customizer/api/init' ] );
28
- }
29
-
30
- if ( ! function_exists( 'jupiterx_core_customizer_include' ) ) {
31
- add_action( 'init', 'jupiterx_core_customizer_include', 15 );
32
- /**
33
- * Include customizer setting file.
34
- *
35
- * With loading customizer on init, we have access to custom post types and custom taxonomies.
36
- *
37
- * @since 1.9.0
38
- *
39
- * @return void
40
- */
41
- function jupiterx_core_customizer_include() {
42
- /**
43
- * Hook after registering theme customizer settings.
44
- *
45
- * @since 1.3.0
46
- */
47
- do_action( 'jupiterx_before_customizer_register' );
48
-
49
- /**
50
- * Load customizer settings.
51
- */
52
- require_once jupiterx_core()->plugin_dir() . 'includes/customizer/settings/settings.php';
53
-
54
- /**
55
- * Hook after registering theme customizer settings.
56
- *
57
- * @since 1.3.0
58
- */
59
- do_action( 'jupiterx_after_customizer_register' );
60
- }
61
- }
62
-
63
- if ( version_compare( JUPITERX_VERSION, '1.17.1', '>' ) ) {
64
- add_action(
65
- 'wp_ajax_jupiterx_core_customizer_preview_redirect_url',
66
- 'jupiterx_core_customizer_preview_redirect_url'
67
- );
68
- }
69
-
70
- if ( ! function_exists( 'jupiterx_core_customizer_preview_redirect_url' ) ) {
71
- /**
72
- * Get Customizer redirect URL.
73
- *
74
- * @since 1.16.0
75
- *
76
- * @return void
77
- */
78
- function jupiterx_core_customizer_preview_redirect_url() {
79
- check_ajax_referer( 'jupiterx_core_get_customizer_preview_redirect_url' );
80
-
81
- $section = wp_unslash( filter_input( INPUT_POST, 'section' ) );
82
- $options = wp_unslash( json_decode( filter_input( INPUT_POST, 'options' ), true ) );
83
-
84
- if ( empty( $section ) ) {
85
- wp_send_json_error();
86
- }
87
-
88
- if ( ! is_array( $options ) ) {
89
- $options = [];
90
- }
91
-
92
- $url = jupiterx_core_get_customizer_preview_redirect_url( $section, $options );
93
-
94
- if ( empty( $url ) ) {
95
- wp_send_json_error();
96
- }
97
-
98
- wp_send_json_success( [ 'redirectUrl' => $url ] );
99
- }
100
- }
101
-
102
- /**
103
- * Ignore phpmd erros.
104
- *
105
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
106
- * @SuppressWarnings(PHPMD.ExitExpression)
107
- * @SuppressWarnings(PHPMD.NPathComplexity)
108
- */
109
- if ( ! function_exists( 'jupiterx_core_customizer_preview_redirect' ) ) {
110
- if ( version_compare( JUPITERX_VERSION, '1.17.1', '<=' ) ) {
111
- add_action( 'template_redirect', 'jupiterx_core_customizer_preview_redirect' );
112
- }
113
- /**
114
- * Redircet to desired template while selecting a pop-up.
115
- *
116
- * @since 1.9.0
117
- *
118
- * @param string $section Customizer Section.
119
- *
120
- * @return void
121
- *
122
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
123
- */
124
- function jupiterx_core_customizer_preview_redirect( $section = '' ) {
125
- $section = jupiterx_get( 'jupiterx' );
126
-
127
- switch ( $section ) {
128
- case 'jupiterx_post_single':
129
- $url = JupiterX_Customizer_Utils::get_preview_url( 'blog_single' );
130
- if ( ! is_singular( 'post' ) && $url ) {
131
- wp_safe_redirect( $url );
132
- exit;
133
- }
134
- break;
135
-
136
- case 'jupiterx_portfolio_single':
137
- $url = JupiterX_Customizer_Utils::get_preview_url( 'portfolio_single' );
138
- if ( ! is_singular( 'portfolio' ) && $url ) {
139
- wp_safe_redirect( $url );
140
- exit;
141
- }
142
- break;
143
-
144
- case 'jupiterx_search':
145
- $url = JupiterX_Customizer_Utils::get_preview_url( 'search' );
146
- if ( ! is_search() && $url ) {
147
- wp_safe_redirect( $url );
148
- exit;
149
- }
150
- break;
151
-
152
- case 'jupiterx_404':
153
- $template = get_theme_mod( 'jupiterx_404_template' );
154
- if ( ! empty( $template ) ) {
155
- wp_safe_redirect( get_permalink( intval( $template ) ) );
156
- exit;
157
- }
158
-
159
- global $wp_query;
160
-
161
- $wp_query->set_404();
162
- status_header( 404 );
163
-
164
- break;
165
-
166
- case 'jupiterx_maintenance':
167
- $template = get_theme_mod( 'jupiterx_maintenance_template' );
168
- if ( ! empty( $template ) ) {
169
- wp_safe_redirect( get_permalink( intval( $template ) ) );
170
- exit;
171
- }
172
- break;
173
-
174
- case 'jupiterx_blog_archive':
175
- $url = JupiterX_Customizer_Utils::get_preview_url( 'blog_archive' );
176
- if ( ! is_post_type_archive( 'post' ) && $url ) {
177
- wp_safe_redirect( $url );
178
- exit;
179
- }
180
- break;
181
-
182
- case 'jupiterx_portfolio_archive':
183
- $url = JupiterX_Customizer_Utils::get_preview_url( 'portfolio_archive' );
184
- if ( $url ) {
185
- wp_safe_redirect( $url );
186
- exit;
187
- }
188
- break;
189
-
190
- case 'jupiterx_checkout_cart':
191
- if ( class_exists( 'WooCommerce' ) ) {
192
- $url = get_permalink( wc_get_page_id( 'cart' ) );
193
- if ( ! is_cart() && ! is_checkout() && $url ) {
194
- wp_safe_redirect( $url );
195
- exit;
196
- }
197
- }
198
- break;
199
-
200
- case 'jupiterx_product_archive':
201
- if ( class_exists( 'WooCommerce' ) ) {
202
- $url = JupiterX_Customizer_Utils::get_preview_url( 'product_archive' );
203
- if ( ! is_product_category() && $url ) {
204
- wp_safe_redirect( $url );
205
- exit;
206
- }
207
- }
208
- break;
209
-
210
- case 'jupiterx_product_page':
211
- $url = JupiterX_Customizer_Utils::get_preview_url( 'product_single' );
212
- if ( ! is_singular( 'product' ) && $url ) {
213
- wp_safe_redirect( $url );
214
- exit;
215
- }
216
- break;
217
-
218
- case 'jupiterx_product_list':
219
- if ( class_exists( 'WooCommerce' ) ) {
220
- $url = get_permalink( wc_get_page_id( 'shop' ) );
221
- if ( ! is_shop() && $url ) {
222
- wp_safe_redirect( $url );
223
- exit;
224
- }
225
- }
226
- break;
227
-
228
- case 'jupiterx_page_single':
229
- $url = JupiterX_Customizer_Utils::get_preview_url( 'single_page' );
230
- if ( ! is_singular( 'page' ) && $url ) {
231
- wp_safe_redirect( $url );
232
- exit;
233
- }
234
- break;
235
-
236
- default:
237
- $post_type = jupiterx_get( 'post_type' );
238
-
239
- if ( $post_type && jupiterx_get( 'single' ) ) {
240
- $url = JupiterX_Customizer_Utils::get_permalink( JupiterX_Customizer_Utils::get_random_post( $post_type ) );
241
- } elseif ( $post_type && jupiterx_get( 'archive' ) ) {
242
- $url = get_post_type_archive_link( $post_type );
243
- }
244
-
245
- if ( isset( $url ) && $url ) {
246
- wp_safe_redirect( $url );
247
- exit;
248
- }
249
- break;
250
- }
251
- }
252
- }
253
-
254
- if ( ! function_exists( 'jupiterx_core_maintenance_page_redirect' ) ) {
255
- add_action( 'template_redirect', 'jupiterx_core_maintenance_page_redirect' );
256
- /**
257
- * Redirect maintenance pages to specific page template.
258
- *
259
- * @since 1.0.0
260
- *
261
- * @return void
262
- *
263
- * @SuppressWarnings(PHPMD.ExitExpression)
264
- */
265
- function jupiterx_core_maintenance_page_redirect() {
266
- // Current viewing page ID.
267
- $post_id = get_queried_object_id();
268
-
269
- // Is maintenance enabled?
270
- $is_enabled = get_theme_mod( 'jupiterx_maintenance', false );
271
-
272
- // The page where redirect ended up.
273
- $page_template = intval( get_theme_mod( 'jupiterx_maintenance_template' ) );
274
-
275
- // Disable when logged in or viewing the current template.
276
- if ( is_user_logged_in() || $page_template === $post_id ) {
277
- return;
278
- }
279
-
280
- // Maintenance is enabled, page template is not empty and the page status is published.
281
- if ( $is_enabled && ! empty( $page_template ) && 'publish' === get_post_status( $page_template ) ) {
282
- wp_safe_redirect( get_permalink( $page_template ) );
283
- exit;
284
- }
285
- }
286
- }
287
-
288
- if ( ! function_exists( 'jupiterx_core_404_page_redirect' ) ) {
289
- add_action( 'template_redirect', 'jupiterx_core_404_page_redirect' );
290
- /**
291
- * Redirect 404 pages to specific page template.
292
- *
293
- * @since 1.0.0
294
- *
295
- * @return void
296
- *
297
- * @SuppressWarnings(PHPMD.ExitExpression)
298
- */
299
- function jupiterx_core_404_page_redirect() {
300
- // The page where redirect ended up.
301
- $page_template = intval( get_theme_mod( 'jupiterx_404_template' ) );
302
-
303
- // Legitimate non existing page, page template is not empty and the page status must be published.
304
- if ( is_404() && ! empty( $page_template ) && 'publish' === get_post_status( $page_template ) ) {
305
- wp_safe_redirect( get_permalink( $page_template ), 301 );
306
- } elseif ( ! empty( $page_template ) && get_the_ID() === $page_template ) {
307
- status_header( 404 );
308
- }
309
- }
310
- }
311
-
312
- /**
313
- * Ignore phpmd erros.
314
- *
315
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
316
- * @SuppressWarnings(PHPMD.ExitExpression)
317
- * @SuppressWarnings(PHPMD.NPathComplexity)
318
- */
319
- if ( ! function_exists( 'jupiterx_core_get_customizer_preview_redirect_url' ) ) {
320
- /**
321
- * Calculate redirect URL for customizer preview.
322
- *
323
- * @since 1.16.0
324
- *
325
- * @param string $section Section open in customizer preview.
326
- * @param array $options Options changed in customizer preview.
327
- *
328
- * @return string
329
- */
330
- function jupiterx_core_get_customizer_preview_redirect_url( $section = '', $options = [] ) {
331
- switch ( $section ) {
332
- case 'jupiterx_post_single':
333
- return JupiterX_Customizer_Utils::get_preview_url( 'blog_single' );
334
-
335
- case 'jupiterx_portfolio_single':
336
- return JupiterX_Customizer_Utils::get_preview_url( 'portfolio_single' );
337
-
338
- case 'jupiterx_search':
339
- return JupiterX_Customizer_Utils::get_preview_url( 'search' );
340
-
341
- case 'jupiterx_404':
342
- $template = get_theme_mod( 'jupiterx_404_template' );
343
- if ( ! empty( $template ) ) {
344
- return get_permalink( intval( $template ) );
345
- }
346
-
347
- break;
348
-
349
- case 'jupiterx_maintenance':
350
- $template = get_theme_mod( 'jupiterx_maintenance_template' );
351
- if ( ! empty( $template ) ) {
352
- return get_permalink( intval( $template ) );
353
- }
354
- break;
355
-
356
- case 'jupiterx_blog_archive':
357
- return JupiterX_Customizer_Utils::get_preview_url( 'blog_archive' );
358
-
359
- case 'jupiterx_portfolio_archive':
360
- return JupiterX_Customizer_Utils::get_preview_url( 'portfolio_archive' );
361
-
362
- case 'jupiterx_checkout_cart':
363
- if ( class_exists( 'WooCommerce' ) ) {
364
- return get_permalink( wc_get_page_id( 'cart' ) );
365
- }
366
- break;
367
-
368
- case 'jupiterx_product_archive':
369
- if ( class_exists( 'WooCommerce' ) ) {
370
- return JupiterX_Customizer_Utils::get_preview_url( 'product_archive' );
371
- }
372
- break;
373
-
374
- case 'jupiterx_product_page':
375
- return JupiterX_Customizer_Utils::get_preview_url( 'product_single' );
376
-
377
- case 'jupiterx_product_list':
378
- if ( class_exists( 'WooCommerce' ) ) {
379
- return get_permalink( wc_get_page_id( 'shop' ) );
380
- }
381
- break;
382
-
383
- case 'jupiterx_page_single':
384
- return JupiterX_Customizer_Utils::get_preview_url( 'single_page' );
385
-
386
- case 'jupiterx_title_bar_settings':
387
- return jupiterx_core_customizer_exceptions_control_redirect_url(
388
- 'jupiterx_title_bar_exceptions',
389
- $options
390
- );
391
-
392
- case 'jupiterx_sidebar_settings':
393
- return jupiterx_core_customizer_exceptions_control_redirect_url(
394
- 'jupiterx_sidebar_exceptions',
395
- $options
396
- );
397
-
398
- default:
399
- $post_type = ! empty( $options['post_type'] ) ? $options['post_type'] : '';
400
-
401
- if ( $post_type && ! empty( $options['single'] ) ) {
402
- $url = JupiterX_Customizer_Utils::get_permalink( JupiterX_Customizer_Utils::get_random_post( $post_type ) );
403
- } elseif ( $post_type && ! empty( $options['archive'] ) ) {
404
- $url = get_post_type_archive_link( $post_type );
405
- }
406
-
407
- return $url;
408
- }
409
- }
410
- }
411
-
412
- /**
413
- * Ignore phpmd erros.
414
- *
415
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
416
- * @SuppressWarnings(PHPMD.ExitExpression)
417
- * @SuppressWarnings(PHPMD.NPathComplexity)
418
- */
419
- if ( ! function_exists( 'jupiterx_core_customizer_exceptions_control_redirect_url' ) ) {
420
- /**
421
- * Redirect Jupiter X Custom Exception Control changes to relevant page.
422
- *
423
- * @since 1.16.0
424
- *
425
- * @param string $exception Exception section.
426
- * @param array $options Options changed within Exception control.
427
- *
428
- * @return mixed
429
- */
430
- function jupiterx_core_customizer_exceptions_control_redirect_url( $exception, $options ) {
431
- $exception_changed = '';
432
- $exceptions = [];
433
-
434
- if ( ! empty( $options[ $exception ] ) && is_array( $options[ $exception ] ) ) {
435
- $exceptions = $options[ $exception ];
436
- }
437
-
438
- if ( empty( $options ) || ! is_array( $options ) ) {
439
- return null;
440
- }
441
-
442
- $option_keys = array_keys( $options );
443
- $option_id = array_shift( $option_keys );
444
- $option_value = $options[ $option_id ];
445
-
446
- foreach ( $exceptions as $e_key => $e_value ) {
447
- if ( 0 === strpos( $option_id, $exception . '_' . $e_key ) ) {
448
- $exception_changed = $e_key;
449
- break;
450
- }
451
- }
452
-
453
- if ( $exception === $option_id ) {
454
- $exception_changed = $option_value;
455
- $exception_changed = empty( $exception_changed ) ? '' : json_decode( $exception_changed, true );
456
-
457
- if ( is_array( $exception_changed ) ) {
458
- $exception_changed = array_pop( $exception_changed );
459
- }
460
- }
461
-
462
- if ( empty( $exception_changed ) ) {
463
- jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_post_single' );
464
-
465
- return null;
466
- }
467
-
468
- $custom_post_types = array_keys( jupiterx_get_post_types( 'label' ) );
469
-
470
- if ( in_array( $exception_changed, $custom_post_types, true ) ) {
471
- $url = JupiterX_Customizer_Utils::get_permalink(
472
- JupiterX_Customizer_Utils::get_random_post( $exception_changed )
473
- );
474
-
475
- if ( ! is_singular( $exception_changed ) && $url ) {
476
- return $url;
477
- }
478
- }
479
-
480
- $custom_post_types_archives = array_keys( jupiterx_get_post_types_archives() );
481
-
482
- if ( in_array( $exception_changed, $custom_post_types_archives, true ) ) {
483
- $url = get_post_type_archive_link( str_replace( 'archive__', '', $exception_changed ) );
484
-
485
- if ( ! is_post_type_archive( $exception_changed ) && $url ) {
486
- return $url;
487
- }
488
- }
489
-
490
- switch ( $exception_changed ) {
491
- case 'page':
492
- return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_page_single' );
493
- case 'post':
494
- return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_post_single' );
495
- case 'search':
496
- return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_search' );
497
- case 'product':
498
- return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_product_list' );
499
- case 'archive':
500
- return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_blog_archive' );
501
- case 'portfolio':
502
- return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_portfolio_single' );
503
- default:
504
- return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_404' );
505
- }
506
- }
507
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Jupiter Customizer component.
4
+ *
5
+ * @package JupiterX_Core\Customizer
6
+ */
7
+
8
+ /**
9
+ * Load Kirki library.
10
+ *
11
+ * @since 1.0.0
12
+ */
13
+ function jupiterx_customizer_kirki() {
14
+ jupiterx_core()->load_files( [ 'customizer/vendors/kirki/kirki' ] );
15
+ }
16
+
17
+ add_action( 'jupiterx_init', 'jupiterx_load_customizer_dependencies', 5 );
18
+ /**
19
+ * Load Customzier.
20
+ *
21
+ * @since 1.9.0
22
+ *
23
+ * @return void
24
+ */
25
+ function jupiterx_load_customizer_dependencies() {
26
+ jupiterx_core()->load_files( [ 'customizer/api/customizer' ] );
27
+ jupiterx_core()->load_files( [ 'customizer/api/init' ] );
28
+ }
29
+
30
+ if ( ! function_exists( 'jupiterx_core_customizer_include' ) ) {
31
+ add_action( 'init', 'jupiterx_core_customizer_include', 15 );
32
+ /**
33
+ * Include customizer setting file.
34
+ *
35
+ * With loading customizer on init, we have access to custom post types and custom taxonomies.
36
+ *
37
+ * @since 1.9.0
38
+ *
39
+ * @return void
40
+ */
41
+ function jupiterx_core_customizer_include() {
42
+ /**
43
+ * Hook after registering theme customizer settings.
44
+ *
45
+ * @since 1.3.0
46
+ */
47
+ do_action( 'jupiterx_before_customizer_register' );
48
+
49
+ /**
50
+ * Load customizer settings.
51
+ */
52
+ require_once jupiterx_core()->plugin_dir() . 'includes/customizer/settings/settings.php';
53
+
54
+ /**
55
+ * Hook after registering theme customizer settings.
56
+ *
57
+ * @since 1.3.0
58
+ */
59
+ do_action( 'jupiterx_after_customizer_register' );
60
+ }
61
+ }
62
+
63
+ if ( version_compare( JUPITERX_VERSION, '1.17.1', '>' ) ) {
64
+ add_action(
65
+ 'wp_ajax_jupiterx_core_customizer_preview_redirect_url',
66
+ 'jupiterx_core_customizer_preview_redirect_url'
67
+ );
68
+ }
69
+
70
+ if ( ! function_exists( 'jupiterx_core_customizer_preview_redirect_url' ) ) {
71
+ /**
72
+ * Get Customizer redirect URL.
73
+ *
74
+ * @since 1.16.0
75
+ *
76
+ * @return void
77
+ */
78
+ function jupiterx_core_customizer_preview_redirect_url() {
79
+ check_ajax_referer( 'jupiterx_core_get_customizer_preview_redirect_url' );
80
+
81
+ $section = wp_unslash( filter_input( INPUT_POST, 'section' ) );
82
+ $options = wp_unslash( json_decode( filter_input( INPUT_POST, 'options' ), true ) );
83
+
84
+ if ( empty( $section ) ) {
85
+ wp_send_json_error();
86
+ }
87
+
88
+ if ( ! is_array( $options ) ) {
89
+ $options = [];
90
+ }
91
+
92
+ $url = jupiterx_core_get_customizer_preview_redirect_url( $section, $options );
93
+
94
+ if ( empty( $url ) ) {
95
+ wp_send_json_error();
96
+ }
97
+
98
+ wp_send_json_success( [ 'redirectUrl' => $url ] );
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Ignore phpmd erros.
104
+ *
105
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
106
+ * @SuppressWarnings(PHPMD.ExitExpression)
107
+ * @SuppressWarnings(PHPMD.NPathComplexity)
108
+ */
109
+ if ( ! function_exists( 'jupiterx_core_customizer_preview_redirect' ) ) {
110
+ // phpcs:disable
111
+ if ( version_compare( JUPITERX_VERSION, '1.17.1', '<=' ) ) {
112
+ add_action( 'template_redirect', 'jupiterx_core_customizer_preview_redirect' );
113
+ }
114
+ // phpcs:enable
115
+ /**
116
+ * Redircet to desired template while selecting a pop-up.
117
+ *
118
+ * @since 1.9.0
119
+ *
120
+ * @param string $section Customizer Section.
121
+ *
122
+ * @return void
123
+ *
124
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
125
+ */
126
+ function jupiterx_core_customizer_preview_redirect( $section = '' ) {
127
+ $section = jupiterx_get( 'jupiterx' );
128
+
129
+ switch ( $section ) {
130
+ case 'jupiterx_post_single':
131
+ $url = JupiterX_Customizer_Utils::get_preview_url( 'blog_single' );
132
+ if ( ! is_singular( 'post' ) && $url ) {
133
+ wp_safe_redirect( $url );
134
+ exit;
135
+ }
136
+ break;
137
+
138
+ case 'jupiterx_portfolio_single':
139
+ $url = JupiterX_Customizer_Utils::get_preview_url( 'portfolio_single' );
140
+ if ( ! is_singular( 'portfolio' ) && $url ) {
141
+ wp_safe_redirect( $url );
142
+ exit;
143
+ }
144
+ break;
145
+
146
+ case 'jupiterx_search':
147
+ $url = JupiterX_Customizer_Utils::get_preview_url( 'search' );
148
+ if ( ! is_search() && $url ) {
149
+ wp_safe_redirect( $url );
150
+ exit;
151
+ }
152
+ break;
153
+
154
+ case 'jupiterx_404':
155
+ $template = get_theme_mod( 'jupiterx_404_template' );
156
+ if ( ! empty( $template ) ) {
157
+ wp_safe_redirect( get_permalink( intval( $template ) ) );
158
+ exit;
159
+ }
160
+
161
+ global $wp_query;
162
+
163
+ $wp_query->set_404();
164
+ status_header( 404 );
165
+
166
+ break;
167
+
168
+ case 'jupiterx_maintenance':
169
+ $template = get_theme_mod( 'jupiterx_maintenance_template' );
170
+ if ( ! empty( $template ) ) {
171
+ wp_safe_redirect( get_permalink( intval( $template ) ) );
172
+ exit;
173
+ }
174
+ break;
175
+
176
+ case 'jupiterx_blog_archive':
177
+ $url = JupiterX_Customizer_Utils::get_preview_url( 'blog_archive' );
178
+ if ( ! is_post_type_archive( 'post' ) && $url ) {
179
+ wp_safe_redirect( $url );
180
+ exit;
181
+ }
182
+ break;
183
+
184
+ case 'jupiterx_portfolio_archive':
185
+ $url = JupiterX_Customizer_Utils::get_preview_url( 'portfolio_archive' );
186
+ if ( $url ) {
187
+ wp_safe_redirect( $url );
188
+ exit;
189
+ }
190
+ break;
191
+
192
+ case 'jupiterx_checkout_cart':
193
+ if ( class_exists( 'WooCommerce' ) ) {
194
+ $url = get_permalink( wc_get_page_id( 'cart' ) );
195
+ if ( ! is_cart() && ! is_checkout() && $url ) {
196
+ wp_safe_redirect( $url );
197
+ exit;
198
+ }
199
+ }
200
+ break;
201
+
202
+ case 'jupiterx_product_archive':
203
+ if ( class_exists( 'WooCommerce' ) ) {
204
+ $url = JupiterX_Customizer_Utils::get_preview_url( 'product_archive' );
205
+ if ( ! is_product_category() && $url ) {
206
+ wp_safe_redirect( $url );
207
+ exit;
208
+ }
209
+ }
210
+ break;
211
+
212
+ case 'jupiterx_product_page':
213
+ $url = JupiterX_Customizer_Utils::get_preview_url( 'product_single' );
214
+ if ( ! is_singular( 'product' ) && $url ) {
215
+ wp_safe_redirect( $url );
216
+ exit;
217
+ }
218
+ break;
219
+
220
+ case 'jupiterx_product_list':
221
+ if ( class_exists( 'WooCommerce' ) ) {
222
+ $url = get_permalink( wc_get_page_id( 'shop' ) );
223
+ if ( ! is_shop() && $url ) {
224
+ wp_safe_redirect( $url );
225
+ exit;
226
+ }
227
+ }
228
+ break;
229
+
230
+ case 'jupiterx_page_single':
231
+ $url = JupiterX_Customizer_Utils::get_preview_url( 'single_page' );
232
+ if ( ! is_singular( 'page' ) && $url ) {
233
+ wp_safe_redirect( $url );
234
+ exit;
235
+ }
236
+ break;
237
+
238
+ default:
239
+ $post_type = jupiterx_get( 'post_type' );
240
+
241
+ if ( $post_type && jupiterx_get( 'single' ) ) {
242
+ $url = JupiterX_Customizer_Utils::get_permalink( JupiterX_Customizer_Utils::get_random_post( $post_type ) );
243
+ } elseif ( $post_type && jupiterx_get( 'archive' ) ) {
244
+ $url = get_post_type_archive_link( $post_type );
245
+ }
246
+
247
+ if ( isset( $url ) && $url ) {
248
+ wp_safe_redirect( $url );
249
+ exit;
250
+ }
251
+ break;
252
+ }
253
+ }
254
+ }
255
+
256
+ add_filter( 'template_include', 'jupiterx_core_404_page_template' );
257
+
258
+ /**
259
+ * Check function exists.
260
+ *
261
+ * @SuppressWarnings(PHPMD.NPathComplexity)
262
+ */
263
+ if ( ! function_exists( 'jupiterx_core_404_page_template' ) ) {
264
+ /**
265
+ * Replace 404 default template with custom.
266
+ *
267
+ * @since 1.17.0
268
+ *
269
+ * @param string $template Template path.
270
+ * @return string
271
+ */
272
+ function jupiterx_core_404_page_template( $template ) {
273
+ $section = jupiterx_get( 'jupiterx' );
274
+
275
+ if ( ! is_404() && 'jupiterx_force_404' !== $section ) {
276
+ return $template;
277
+ }
278
+
279
+ $page_id = intval( get_theme_mod( 'jupiterx_404_template' ) );
280
+ $post_id = get_queried_object_id();
281
+
282
+ if ( empty( $page_id ) || ! in_array( get_post_status( $page_id ), [ 'publish', 'private' ], true ) ) {
283
+ return $template;
284
+ }
285
+
286
+ if ( $post_id === $page_id ) {
287
+ jupiterx_add_filter( 'jupiterx_layout', 'c' );
288
+ jupiterx_remove_action( 'jupiterx_main_header_partial_template' );
289
+ jupiterx_remove_action( 'jupiterx_main_footer_partial_template' );
290
+
291
+ return $template;
292
+ }
293
+
294
+ $is_built_with_elementor = ! ! get_post_meta( $page_id, '_elementor_edit_mode', true );
295
+
296
+ if ( ! $is_built_with_elementor ) {
297
+ jupiterx_add_filter( 'jupiterx_layout', 'c' );
298
+ jupiterx_remove_action( 'jupiterx_main_header_partial_template' );
299
+ jupiterx_remove_action( 'jupiterx_main_footer_partial_template' );
300
+
301
+ jupiterx_modify_action( 'jupiterx_fullwidth_template_content', null, function () use ( $page_id ) {
302
+ $query = new WP_Query( [
303
+ 'post_type' => 'page',
304
+ 'post__in' => [ $page_id ],
305
+ ] );
306
+
307
+ if ( $query->have_posts() ) {
308
+ while ( $query->have_posts() ) {
309
+ $query->the_post();
310
+
311
+ the_content();
312
+ }
313
+ }
314
+
315
+ wp_reset_postdata();
316
+ } );
317
+
318
+ return JUPITERX_THEME_PATH . '/full-width.php';
319
+ }
320
+
321
+ if ( ! class_exists( '\Elementor\Plugin' ) ) {
322
+ return $template;
323
+ }
324
+
325
+ $elementor = \Elementor\Plugin::$instance;
326
+
327
+ if ( $elementor->preview->is_preview_mode() ) {
328
+ return $template;
329
+ }
330
+
331
+ if ( class_exists( '\ElementorPro\Modules\ThemeBuilder\Module' ) ) {
332
+ $conditions = ElementorPro\Modules\ThemeBuilder\Module::instance()->get_component( 'conditions' );
333
+
334
+ if ( ! empty( $conditions->get_location_templates( '404' ) ) ) {
335
+ return $template;
336
+ }
337
+ }
338
+
339
+ jupiterx_add_filter( 'jupiterx_layout', 'c' );
340
+ jupiterx_remove_action( 'jupiterx_main_header_partial_template' );
341
+ jupiterx_remove_action( 'jupiterx_main_footer_partial_template' );
342
+
343
+ $current_template = get_post_meta( $page_id, '_wp_page_template', true );
344
+ $page_template_module = $elementor->modules_manager->get_modules( 'page-templates' );
345
+ $page_templates = [ 'full-width.php', $page_template_module::TEMPLATE_CANVAS, $page_template_module::TEMPLATE_HEADER_FOOTER ];
346
+
347
+ // Switch to full layout for Elementor Canvas, Elementor Full Width and Full Width page templates.
348
+ if ( in_array( $current_template, $page_templates, true ) ) {
349
+ jupiterx_add_filter( 'jupiterx_layout', 'c' );
350
+ }
351
+
352
+ // Remove header & footer for Elementor Canvas page template.
353
+ if ( $current_template === $page_template_module::TEMPLATE_CANVAS ) {
354
+ jupiterx_remove_action( 'jupiterx_header_partial_template' );
355
+ jupiterx_remove_action( 'jupiterx_footer_partial_template' );
356
+ }
357
+
358
+ jupiterx_modify_action( 'jupiterx_fullwidth_template_content', null, function () use ( $page_id ) {
359
+ jupiterx_output_e( 'jupiterx_custom_single_template', jupiterx_get_custom_template( $page_id ) );
360
+ } );
361
+
362
+ return JUPITERX_THEME_PATH . '/full-width.php';
363
+ }
364
+ }
365
+
366
+ add_action( 'template_redirect', 'jupiterx_core_404_page_redirect' );
367
+
368
+ if ( ! function_exists( 'jupiterx_core_404_page_redirect' ) ) {
369
+ /**
370
+ * Redirect for only default 404 page.
371
+ *
372
+ * @since 1.0.0
373
+ *
374
+ * @return void
375
+ *
376
+ * @SuppressWarnings(PHPMD.ExitExpression)
377
+ */
378
+ function jupiterx_core_404_page_redirect() {
379
+ $template = intval( get_theme_mod( 'jupiterx_404_template' ) );
380
+
381
+ if ( ! empty( $template ) ) {
382
+ return;
383
+ }
384
+
385
+ $section = jupiterx_get( 'jupiterx' );
386
+
387
+ if ( 'jupiterx_force_404' !== $section ) {
388
+ return;
389
+ }
390
+
391
+ global $wp_query;
392
+
393
+ $wp_query->set_404();
394
+
395
+ status_header( 404 );
396
+ }
397
+ }
398
+
399
+ add_filter( 'template_include', 'jupiterx_core_maintenance_page_template', 99999, 1 );
400
+
401
+ /**
402
+ * Check function exists.
403
+ *
404
+ * @SuppressWarnings(PHPMD.NPathComplexity)
405
+ */
406
+ if ( ! function_exists( 'jupiterx_core_maintenance_page_template' ) ) {
407
+ /**
408
+ * Load custom maintenance template.
409
+ *
410
+ * @since 1.17.0
411
+ *
412
+ * @param string $template Template path.
413
+ * @return string
414
+ */
415
+ function jupiterx_core_maintenance_page_template( $template ) {
416
+ $section = jupiterx_get( 'jupiterx' );
417
+
418
+ $is_enabled = get_theme_mod( 'jupiterx_maintenance', false );
419
+
420
+ if ( ! $is_enabled && 'jupiterx_force_maintenance' !== $section ) {
421
+ return $template;
422
+ }
423
+
424
+ if ( is_user_logged_in() && 'jupiterx_force_maintenance' !== $section ) {
425
+ return $template;
426
+ }
427
+
428
+ $page_id = intval( get_theme_mod( 'jupiterx_maintenance_template' ) );
429
+ $post_id = get_queried_object_id();
430
+
431
+ if ( $post_id === $page_id ) {
432
+ jupiterx_add_filter( 'jupiterx_layout', 'c' );
433
+ jupiterx_remove_action( 'jupiterx_main_header_partial_template' );
434
+ jupiterx_remove_action( 'jupiterx_main_footer_partial_template' );
435
+
436
+ return $template;
437
+ }
438
+
439
+ $is_built_with_elementor = ! ! get_post_meta( $page_id, '_elementor_edit_mode', true );
440
+
441
+ if ( ! $is_built_with_elementor ) {
442
+ jupiterx_add_filter( 'jupiterx_layout', 'c' );
443
+ jupiterx_remove_action( 'jupiterx_main_header_partial_template' );
444
+ jupiterx_remove_action( 'jupiterx_main_footer_partial_template' );
445
+
446
+ jupiterx_modify_action( 'jupiterx_fullwidth_template_content', null, function () use ( $page_id ) {
447
+ $query = new WP_Query( [
448
+ 'post_type' => 'page',
449
+ 'post__in' => [ $page_id ],
450
+ ] );
451
+
452
+ if ( $query->have_posts() ) {
453
+ while ( $query->have_posts() ) {
454
+ $query->the_post();
455
+
456
+ the_content();
457
+ }
458
+ }
459
+
460
+ wp_reset_postdata();
461
+ } );
462
+
463
+ return JUPITERX_THEME_PATH . '/full-width.php';
464
+ }
465
+
466
+ if ( ! class_exists( '\Elementor\Plugin' ) ) {
467
+ return $template;
468
+ }
469
+
470
+ $elementor = \Elementor\Plugin::$instance;
471
+
472
+ if ( $elementor->preview->is_preview_mode() ) {
473
+ return $template;
474
+ }
475
+
476
+ if ( ! empty( $elementor->maintenance_mode->get( 'mode' ) ) ) {
477
+ return $template;
478
+ }
479
+
480
+ $protocol = wp_get_server_protocol();
481
+ header( "$protocol 503 Service Unavailable", true, 503 );
482
+ header( 'Content-Type: text/html; charset=utf-8' );
483
+ header( 'Retry-After: 600' );
484
+
485
+ $current_template = get_post_meta( $page_id, '_wp_page_template', true );
486
+ $page_template_module = $elementor->modules_manager->get_modules( 'page-templates' );
487
+ $page_templates = [ 'full-width.php', $page_template_module::TEMPLATE_CANVAS, $page_template_module::TEMPLATE_HEADER_FOOTER ];
488
+
489
+ // Switch to full layout for Elementor Canvas, Elementor Full Width and Full Width page templates.
490
+ if ( in_array( $current_template, $page_templates, true ) ) {
491
+ jupiterx_add_filter( 'jupiterx_layout', 'c' );
492
+ }
493
+
494
+ // Remove header & footer for Elementor Canvas page template.
495
+ if ( $current_template === $page_template_module::TEMPLATE_CANVAS ) {
496
+ jupiterx_remove_action( 'jupiterx_header_partial_template' );
497
+ jupiterx_remove_action( 'jupiterx_footer_partial_template' );
498
+ }
499
+
500
+ jupiterx_modify_action( 'jupiterx_fullwidth_template_content', null, function () use ( $page_id ) {
501
+ jupiterx_output_e( 'jupiterx_custom_single_template', jupiterx_get_custom_template( $page_id ) );
502
+ } );
503
+
504
+ return JUPITERX_THEME_PATH . '/full-width.php';
505
+ }
506
+ }
507
+
508
+ /**
509
+ * Ignore phpmd erros.
510
+ *
511
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
512
+ * @SuppressWarnings(PHPMD.ExitExpression)
513
+ * @SuppressWarnings(PHPMD.NPathComplexity)
514
+ */
515
+ if ( ! function_exists( 'jupiterx_core_get_customizer_preview_redirect_url' ) ) {
516
+ /**
517
+ * Calculate redirect URL for customizer preview.
518
+ *
519
+ * @since 1.16.0
520
+ *
521
+ * @param string $section Section open in customizer preview.
522
+ * @param array $options Options changed in customizer preview.
523
+ *
524
+ * @return string
525
+ */
526
+ function jupiterx_core_get_customizer_preview_redirect_url( $section = '', $options = [] ) {
527
+ switch ( $section ) {
528
+ case 'jupiterx_post_single':
529
+ return JupiterX_Customizer_Utils::get_preview_url( 'blog_single' );
530
+
531
+ case 'jupiterx_portfolio_single':
532
+ return JupiterX_Customizer_Utils::get_preview_url( 'portfolio_single' );
533
+
534
+ case 'jupiterx_search':
535
+ return JupiterX_Customizer_Utils::get_preview_url( 'search' );
536
+
537
+ case 'jupiterx_404':
538
+ $template = intval( get_theme_mod( 'jupiterx_404_template' ) );
539
+
540
+ if ( isset( $options['jupiterx_404_template'] ) ) {
541
+ $template = $options['jupiterx_404_template'];
542
+ }
543
+
544
+ if ( ! empty( $template ) && 'publish' === get_post_status( $template ) ) {
545
+ $url = get_permalink( $template );
546
+ $url .= ( wp_parse_url( $url, PHP_URL_QUERY ) ? '&' : '?' ) . 'jupiterx=jupiterx_force_404';
547
+
548
+ return $url;
549
+ }
550
+
551
+ return get_site_url() . '?jupiterx=jupiterx_force_404';
552
+
553
+ case 'jupiterx_maintenance':
554
+ $template = intval( get_theme_mod( 'jupiterx_maintenance_template' ) );
555
+
556
+ if ( isset( $options['jupiterx_maintenance_template'] ) ) {
557
+ $template = $options['jupiterx_maintenance_template'];
558
+ }
559
+
560
+ if ( ! empty( $template ) && 'publish' === get_post_status( $template ) ) {
561
+ $url = get_permalink( $template );
562
+ $url .= ( wp_parse_url( $url, PHP_URL_QUERY ) ? '&' : '?' ) . 'jupiterx=jupiterx_force_maintenance';
563
+
564
+ return $url;
565
+ }
566
+
567
+ return get_site_url();
568
+
569
+ case 'jupiterx_blog_archive':
570
+ return JupiterX_Customizer_Utils::get_preview_url( 'blog_archive' );
571
+
572
+ case 'jupiterx_portfolio_archive':
573
+ return JupiterX_Customizer_Utils::get_preview_url( 'portfolio_archive' );
574
+
575
+ case 'jupiterx_checkout_cart':
576
+ if ( class_exists( 'WooCommerce' ) ) {
577
+ return get_permalink( wc_get_page_id( 'cart' ) );
578
+ }
579
+ break;
580
+
581
+ case 'jupiterx_product_archive':
582
+ if ( class_exists( 'WooCommerce' ) ) {
583
+ return JupiterX_Customizer_Utils::get_preview_url( 'product_archive' );
584
+ }
585
+ break;
586
+
587
+ case 'jupiterx_product_page':
588
+ return JupiterX_Customizer_Utils::get_preview_url( 'product_single' );
589
+
590
+ case 'jupiterx_product_list':
591
+ if ( class_exists( 'WooCommerce' ) ) {
592
+ return get_permalink( wc_get_page_id( 'shop' ) );
593
+ }
594
+ break;
595
+
596
+ case 'jupiterx_page_single':
597
+ return JupiterX_Customizer_Utils::get_preview_url( 'single_page' );
598
+
599
+ case 'jupiterx_title_bar_settings':
600
+ return jupiterx_core_customizer_exceptions_control_redirect_url(
601
+ 'jupiterx_title_bar_exceptions',
602
+ $options
603
+ );
604
+
605
+ case 'jupiterx_sidebar_settings':
606
+ return jupiterx_core_customizer_exceptions_control_redirect_url(
607
+ 'jupiterx_sidebar_exceptions',
608
+ $options
609
+ );
610
+
611
+ default:
612
+ $post_type = ! empty( $options['post_type'] ) ? $options['post_type'] : '';
613
+
614
+ if ( $post_type && ! empty( $options['single'] ) ) {
615
+ $url = JupiterX_Customizer_Utils::get_permalink( JupiterX_Customizer_Utils::get_random_post( $post_type ) );
616
+ } elseif ( $post_type && ! empty( $options['archive'] ) ) {
617
+ $url = get_post_type_archive_link( $post_type );
618
+ }
619
+
620
+ return $url;
621
+ }
622
+ }
623
+ }
624
+
625
+ /**
626
+ * Ignore phpmd erros.
627
+ *
628
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
629
+ * @SuppressWarnings(PHPMD.ExitExpression)
630
+ * @SuppressWarnings(PHPMD.NPathComplexity)
631
+ */
632
+ if ( ! function_exists( 'jupiterx_core_customizer_exceptions_control_redirect_url' ) ) {
633
+ /**
634
+ * Redirect Jupiter X Custom Exception Control changes to relevant page.
635
+ *
636
+ * @since 1.16.0
637
+ *
638
+ * @param string $exception Exception section.
639
+ * @param array $options Options changed within Exception control.
640
+ *
641
+ * @return mixed
642
+ */
643
+ function jupiterx_core_customizer_exceptions_control_redirect_url( $exception, $options ) {
644
+ $exception_changed = '';
645
+ $exceptions = [];
646
+
647
+ if ( ! empty( $options[ $exception ] ) && is_array( $options[ $exception ] ) ) {
648
+ $exceptions = $options[ $exception ];
649
+ }
650
+
651
+ if ( empty( $options ) || ! is_array( $options ) ) {
652
+ return null;
653
+ }
654
+
655
+ $option_keys = array_keys( $options );
656
+ $option_id = array_shift( $option_keys );
657
+ $option_value = $options[ $option_id ];
658
+
659
+ foreach ( $exceptions as $e_key => $e_value ) {
660
+ if ( 0 === strpos( $option_id, $exception . '_' . $e_key ) ) {
661
+ $exception_changed = $e_key;
662
+ break;
663
+ }
664
+ }
665
+
666
+ if ( $exception === $option_id ) {
667
+ $exception_changed = $option_value;
668
+ $exception_changed = empty( $exception_changed ) ? '' : json_decode( $exception_changed, true );
669
+
670
+ if ( is_array( $exception_changed ) ) {
671
+ $exception_changed = array_pop( $exception_changed );
672
+ }
673
+ }
674
+
675
+ if ( empty( $exception_changed ) ) {
676
+ jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_post_single' );
677
+
678
+ return null;
679
+ }
680
+
681
+ $custom_post_types = array_keys( jupiterx_get_post_types( 'label' ) );
682
+
683
+ if ( in_array( $exception_changed, $custom_post_types, true ) ) {
684
+ $url = JupiterX_Customizer_Utils::get_permalink(
685
+ JupiterX_Customizer_Utils::get_random_post( $exception_changed )
686
+ );
687
+
688
+ if ( ! is_singular( $exception_changed ) && $url ) {
689
+ return $url;
690
+ }
691
+ }
692
+
693
+ $custom_post_types_archives = array_keys( jupiterx_get_post_types_archives() );
694
+
695
+ if ( in_array( $exception_changed, $custom_post_types_archives, true ) ) {
696
+ $url = get_post_type_archive_link( str_replace( 'archive__', '', $exception_changed ) );
697
+
698
+ if ( ! is_post_type_archive( $exception_changed ) && $url ) {
699
+ return $url;
700
+ }
701
+ }
702
+
703
+ switch ( $exception_changed ) {
704
+ case 'page':
705
+ return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_page_single' );
706
+ case 'post':
707
+ return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_post_single' );
708
+ case 'search':
709
+ return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_search' );
710
+ case 'product':
711
+ return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_product_list' );
712
+ case 'archive':
713
+ return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_blog_archive' );
714
+ case 'portfolio':
715
+ return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_portfolio_single' );
716
+ default:
717
+ return jupiterx_core_get_customizer_preview_redirect_url( 'jupiterx_404' );
718
+ }
719
+ }
720
+ }
721
+
722
+ add_action( 'wp_ajax_jupiterx_core_customizer_get_select2_options', 'jupiterx_core_customizer_get_select2_options' );
723
+
724
+ if ( ! function_exists( 'jupiterx_core_customizer_get_select2_options' ) ) {
725
+ /**
726
+ * Get Customizer select2 options.
727
+ *
728
+ * @since 1.17.0
729
+ *
730
+ * @return void
731
+ */
732
+ function jupiterx_core_customizer_get_select2_options() {
733
+ check_ajax_referer( 'jupiterx_customizer_preview' );
734
+
735
+ $s = wp_unslash( filter_input( INPUT_GET, 's' ) );
736
+ $post_type = wp_unslash( filter_input( INPUT_GET, 'post_type' ) );
737
+
738
+ if ( empty( $s ) ) {
739
+ wp_send_json_error( esc_html__( 'Search param is empty.', 'jupiterx-core' ) );
740
+ }
741
+
742
+ $data = [];
743
+ $posts = get_posts( [
744
+ 's' => $s,
745
+ 'post_type' => $post_type,
746
+ 'posts_per_page' => -1,
747
+ 'post_status' => [ 'publish', 'private' ],
748
+ ] );
749
+
750
+ foreach ( $posts as $post ) {
751
+ $data[] = [
752
+ 'id' => $post->ID,
753
+ 'text' => $post->post_title,
754
+ ];
755
+ }
756
+
757
+ wp_send_json_success( $data );
758
+ }
759
+ }
760
+
761
+ add_action( 'wp_ajax_jupiterx_core_customizer_get_post_title', 'jupiterx_core_customizer_get_post_title' );
762
+
763
+ if ( ! function_exists( 'jupiterx_core_customizer_get_post_title' ) ) {
764
+ /**
765
+ * Get Customizer post title.
766
+ *
767
+ * @since 1.17.0
768
+ *
769
+ * @return void
770
+ */
771
+ function jupiterx_core_customizer_get_post_title() {
772
+ check_ajax_referer( 'jupiterx_customizer_preview' );
773
+
774
+ $id = wp_unslash( filter_input( INPUT_GET, 'id' ) );
775
+
776
+ if ( empty( $id ) ) {
777
+ wp_send_json_error( esc_html__( 'ID param is empty.', 'jupiterx-core' ) );
778
+ }
779
+
780
+ $data = get_the_title( $id );
781
+
782
+ if ( empty( $data ) ) {
783
+ wp_send_json_error( esc_html__( 'No valid post is found.', 'jupiterx-core' ) );
784
+ }
785
+
786
+ wp_send_json_success( $data );
787
+ }
788
+ }
789
+
790
+ if ( ! function_exists( 'is_multilingual_customizer' ) ) {
791
+ /**
792
+ * Check if Multilingual Customizer is enabled.
793
+ *
794
+ * @since 1.19.1
795
+ *
796
+ * @return bool
797
+ */
798
+ function is_multilingual_customizer() {
799
+ return jupiterx_get_option( 'multilingual_customizer', 0 );
800
+ }
801
+ }
802
+
803
+ if ( ! function_exists( 'jupiterx_dependency_notice_handler' ) ) {
804
+ /**
805
+ * Check pane dependencies.
806
+ *
807
+ * @since 1.20.0
808
+ *
809
+ * @return void
810
+ */
811
+ function jupiterx_dependency_notice_handler( $id ) {
812
+ // it checks if the elementor and ACF was enabled or not.
813
+ if ( did_action( 'elementor/loaded' ) && class_exists( 'ACF' ) ) {
814
+ return;
815
+ }
816
+
817
+ /* translators: %s represents admin plugin url. */
818
+ $notice_message = sprintf( __( 'These options require "Required Plugins" to be installed. Please go to <a class="jupiterx-alert-control-link" href="%s"> Control Panel > Plugins</a>, install and activate all the required plugins.', 'jupiterx-core' ),
819
+ admin_url( 'admin.php?page=jupiterx#/plugins' ) );
820
+
821
+ JupiterX_Customizer::add_field( [
822
+ 'type' => 'jupiterx-alert',
823
+ 'settings' => $id . '_warning',
824
+ 'section' => $id,
825
+ 'label' => $notice_message,
826
+ ] );
827
+ }
828
+ }
829
+
830
+ if ( ! function_exists( 'jupiterx_core_get_pro_badge' ) ) {
831
+ /**
832
+ * Get pro badge.
833
+ *
834
+ * @since 2.0.6
835
+ *
836
+ * @return string
837
+ */
838
+ function jupiterx_core_get_pro_badge() {
839
+ if ( version_compare( JUPITERX_VERSION, '2.0.0', '>=' ) ) {
840
+ return JupiterX_Customizer_Utils::get_pro_badge_url();
841
+ }
842
+
843
+ return '';
844
+ }
845
+ }
includes/customizer/settings/404/popup.php CHANGED
@@ -1,42 +1,67 @@
1
- <?php
2
- /**
3
- * Add Jupiter 404 popup and tabs to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Layout popup.
11
- JupiterX_Customizer::add_section( 'jupiterx_404', [
12
- 'panel' => 'jupiterx_pages',
13
- 'title' => __( '404', 'jupiterx-core' ),
14
- 'type' => 'popup',
15
- 'tabs' => [
16
- 'settings' => __( 'Settings', 'jupiterx-core' ),
17
- ],
18
- 'preview' => true,
19
- 'help' => [
20
- 'url' => 'https://themes.artbees.net/docs/setting-custom-template-for-404-page',
21
- 'title' => __( 'Setting custom template for 404 page', 'jupiterx-core' ),
22
- ],
23
- ] );
24
-
25
- // Settings tab.
26
- JupiterX_Customizer::add_section( 'jupiterx_404_settings', [
27
- 'popup' => 'jupiterx_404',
28
- 'type' => 'pane',
29
- 'pane' => [
30
- 'type' => 'tab',
31
- 'id' => 'settings',
32
- ],
33
- 'help' => [
34
- 'url' => 'google.com',
35
- 'title' => 'google.com',
36
- ],
37
- ] );
38
-
39
- // Load all the settings.
40
- foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
41
- require_once $setting;
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Pages > 404 > Settings tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ add_action( 'jupiterx_404_settings_after_section', 'jupiterx_dependency_notice_handler', 10 );
11
+
12
+ JupiterX_Customizer::add_section( 'jupiterx_404', [
13
+ 'priority' => 330,
14
+ 'title' => __( '404', 'jupiterx-core' ),
15
+ 'type' => 'container',
16
+ 'preview' => true,
17
+ 'boxes' => [
18
+ 'settings' => [
19
+ 'label' => __( 'Settings', 'jupiterx-core' ),
20
+ ],
21
+ ],
22
+ 'help' => [
23
+ 'url' => 'https://themes.artbees.net/docs/setting-custom-template-for-404-page',
24
+ 'title' => __( 'Setting custom template for 404 page', 'jupiterx-core' ),
25
+ ],
26
+ 'group' => 'specific_pages',
27
+ 'icon' => '404',
28
+ ] );
29
+
30
+ // Warning.
31
+ JupiterX_Customizer::add_field( [
32
+ 'type' => 'jupiterx-alert',
33
+ 'settings' => 'jupiterx_404_warning',
34
+ 'section' => 'jupiterx_404',
35
+ 'box' => 'settings',
36
+ 'label' => __( 'Set the selected 404 page to "Private" to hide the page from search engines. Setting to private, does not affect the 404 functionality.', 'jupiterx-core' ),
37
+ 'jupiterx_url' => '',
38
+ ] );
39
+
40
+ // Warning.
41
+ JupiterX_Customizer::add_field( [
42
+ 'type' => 'jupiterx-alert',
43
+ 'settings' => 'jupiterx_404_custom_templates_notice',
44
+ 'section' => 'jupiterx_404',
45
+ 'box' => 'settings',
46
+ 'label' => jupiterx_customizer_custom_templates_notice(),
47
+ ] );
48
+
49
+ // Template.
50
+ JupiterX_Customizer::add_field( [
51
+ 'type' => 'jupiterx-select',
52
+ 'settings' => 'jupiterx_404_template',
53
+ 'section' => 'jupiterx_404',
54
+ 'box' => 'settings',
55
+ 'label' => __( 'Template', 'jupiterx-core' ),
56
+ 'default' => '',
57
+ 'placeholder' => __( 'None', 'jupiterx-core' ),
58
+ 'transport' => 'postMessage',
59
+ 'preview' => true,
60
+ 'jupiterx' => [
61
+ 'select2' => [
62
+ 'action' => 'jupiterx_core_customizer_get_select2_options',
63
+ 'post_type' => 'page',
64
+ ],
65
+ ],
66
+ ] );
67
+
includes/customizer/settings/blog-archive/popup.php CHANGED
@@ -1,34 +1,82 @@
1
- <?php
2
- /**
3
- * Add Jupiter blog archive popup and tabs to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Blog popup.
11
- JupiterX_Customizer::add_section( 'jupiterx_blog_archive', [
12
- 'panel' => 'jupiterx_blog_panel',
13
- 'title' => __( 'Blog Archive', 'jupiterx-core' ),
14
- 'type' => 'popup',
15
- 'tabs' => [
16
- 'settings' => __( 'Settings', 'jupiterx-core' ),
17
- ],
18
- 'preview' => true,
19
- ] );
20
-
21
- // Settings tab.
22
- JupiterX_Customizer::add_section( 'jupiterx_blog_archive_settings', [
23
- 'popup' => 'jupiterx_blog_archive',
24
- 'type' => 'pane',
25
- 'pane' => [
26
- 'type' => 'tab',
27
- 'id' => 'settings',
28
- ],
29
- ] );
30
-
31
- // Load all the settings.
32
- foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
33
- require_once $setting;
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter blog archive popup and tabs to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ add_action( 'jupiterx_blog_pages_after_section', 'jupiterx_dependency_notice_handler', 10 );
11
+
12
+ // Blog popup.
13
+ JupiterX_Customizer::add_section( 'jupiterx_blog_pages', [
14
+ 'title' => __( 'Blog', 'jupiterx-core' ),
15
+ 'type' => 'container',
16
+ 'tabs' => [
17
+ 'settings' => __( 'Settings', 'jupiterx-core' ),
18
+ 'styles' => __( 'Single Styles', 'jupiterx-core' ),
19
+ ],
20
+ 'boxes' => [
21
+ 'settings_archive' => [
22
+ 'label' => __( 'Blog Archive', 'jupiterx-core' ),
23
+ 'tab' => 'settings',
24
+ ],
25
+ 'settings_single' => [
26
+ 'label' => __( 'Blog Single', 'jupiterx-core' ),
27
+ 'tab' => 'settings',
28
+ ],
29
+ 'featured_image' => array(
30
+ 'label' => __( 'Featured Image', 'jupiterx-core' ),
31
+ 'tab' => 'styles',
32
+ ),
33
+ 'title' => [
34
+ 'label' => __( 'Title', 'jupiterx-core' ),
35
+ 'tab' => 'styles',
36
+ ],
37
+ 'avatar' => [
38
+ 'label' => __( 'Avatar', 'jupiterx-core' ),
39
+ 'tab' => 'styles',
40
+ ],
41
+ 'meta' => [
42
+ 'label' => __( 'Meta', 'jupiterx-core' ),
43
+ 'tab' => 'styles',
44
+ ],
45
+ 'post_content' => [
46
+ 'label' => __( 'Post Content', 'jupiterx-core' ),
47
+ 'tab' => 'styles',
48
+ ],
49
+ 'tags' => [
50
+ 'label' => __( 'Tags', 'jupiterx-core' ),
51
+ 'tab' => 'styles',
52
+ ],
53
+ 'social_share' => [
54
+ 'label' => __( 'Social Share', 'jupiterx-core' ),
55
+ 'tab' => 'styles',
56
+ ],
57
+ 'navigation' => [
58
+ 'label' => __( 'Navigation', 'jupiterx-core' ),
59
+ 'tab' => 'styles',
60
+ ],
61
+ 'author_box' => [
62
+ 'label' => __( 'Author Box', 'jupiterx-core' ),
63
+ 'tab' => 'styles',
64
+ ],
65
+ 'recommended_posts' => [
66
+ 'label' => __( 'Recommended Posts', 'jupiterx-core' ),
67
+ 'tab' => 'styles',
68
+ ],
69
+ 'empty_notice' => [
70
+ 'label' => __( 'Notice', 'jupiterx-core' ),
71
+ 'tab' => 'styles',
72
+ ],
73
+ ],
74
+ 'preview' => true,
75
+ 'group' => 'specific_pages',
76
+ 'icon' => 'blog',
77
+ ] );
78
+
79
+ // Load all the settings.
80
+ foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
81
+ require_once $setting;
82
+ }
includes/customizer/settings/blog-archive/settings.php CHANGED
@@ -1,35 +1,111 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Footer > Settings tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_blog_archive_settings';
11
-
12
- // Template.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-template',
15
- 'settings' => 'jupiterx_post_archive_template',
16
- 'section' => $section,
17
- 'label' => __( 'My Templates', 'jupiterx-core' ),
18
- 'placeholder' => __( 'Select one', 'jupiterx-core' ),
19
- 'template_type' => 'archive',
20
- 'locked' => true,
21
- ] );
22
-
23
- // Spacing.
24
- JupiterX_Customizer::add_responsive_field( [
25
- 'type' => 'jupiterx-box-model',
26
- 'settings' => 'jupiterx_blog_archive',
27
- 'section' => $section,
28
- 'css_var' => 'blog-archive',
29
- 'transport' => 'postMessage',
30
- 'output' => [
31
- [
32
- 'element' => '.archive.date .jupiterx-main-content, .archive.author .jupiterx-main-content, .archive.category .jupiterx-main-content, .archive.tag .jupiterx-main-content',
33
- ],
34
- ],
35
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Blog > Settings tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 2.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_blog_pages';
11
+
12
+ // Type.
13
+ JupiterX_Customizer::add_field( [
14
+ 'type' => 'jupiterx-choose',
15
+ 'settings' => 'jupiterx_post_archive_template_type',
16
+ 'section' => $section,
17
+ 'box' => 'settings_archive',
18
+ 'label' => __( 'Type', 'jupiterx-core' ),
19
+ 'default' => '',
20
+ 'choices' => [
21
+ '' => [
22
+ 'label' => __( 'Default', 'jupiterx-core' ),
23
+ ],
24
+ '_custom' => [
25
+ 'label' => __( 'Custom', 'jupiterx-core' ),
26
+ ],
27
+ ],
28
+ ] );
29
+
30
+ // Warning.
31
+ JupiterX_Customizer::add_field( [
32
+ 'type' => 'jupiterx-alert',
33
+ 'settings' => 'jupiterx_blog_custom_templates_notice',
34
+ 'section' => $section,
35
+ 'box' => 'settings_archive',
36
+ 'label' => jupiterx_customizer_custom_templates_notice(),
37
+ 'active_callback' => [
38
+ [
39
+ 'setting' => 'jupiterx_post_archive_template_type',
40
+ 'operator' => '===',
41
+ 'value' => '_custom',
42
+ ],
43
+ ],
44
+ ] );
45
+
46
+ // Custom Type.
47
+ JupiterX_Customizer::add_field( [
48
+ 'type' => 'jupiterx-choose',
49
+ 'settings' => 'jupiterx_post_archive_default_type',
50
+ 'section' => $section,
51
+ 'box' => 'settings_archive',
52
+ 'label' => __( 'Default Content Type', 'jupiterx-core' ),
53
+ 'default' => 'full',
54
+ 'choices' => [
55
+ 'full' => [
56
+ 'label' => __( 'Full Content', 'jupiterx-core' ),
57
+ ],
58
+ 'summary' => [
59
+ 'label' => __( 'Summary', 'jupiterx-core' ),
60
+ ],
61
+ ],
62
+ 'active_callback' => [
63
+ [
64
+ 'setting' => 'jupiterx_post_archive_template_type',
65
+ 'operator' => '===',
66
+ 'value' => '',
67
+ ],
68
+ ],
69
+ ] );
70
+
71
+ // Template.
72
+ JupiterX_Customizer::add_field( [
73
+ 'type' => 'jupiterx-template',
74
+ 'settings' => 'jupiterx_post_archive_template',
75
+ 'section' => $section,
76
+ 'box' => 'settings_archive',
77
+ 'label' => __( 'My Templates', 'jupiterx-core' ),
78
+ 'placeholder' => __( 'Select one', 'jupiterx-core' ),
79
+ 'template_type' => 'archive',
80
+ 'locked' => true,
81
+ 'active_callback' => [
82
+ [
83
+ 'setting' => 'jupiterx_post_archive_template_type',
84
+ 'operator' => '===',
85
+ 'value' => '_custom',
86
+ ],
87
+ ],
88
+ ] );
89
+
90
+ // Divider.
91
+ JupiterX_Customizer::add_field( [
92
+ 'type' => 'jupiterx-divider',
93
+ 'settings' => 'jupiterx_post_archive_template_divider',
94
+ 'section' => $section,
95
+ 'box' => 'settings_archive',
96
+ ] );
97
+
98
+ // Spacing.
99
+ JupiterX_Customizer::add_responsive_field( [
100
+ 'type' => 'jupiterx-box-model',
101
+ 'settings' => 'jupiterx_blog_archive',
102
+ 'section' => $section,
103
+ 'box' => 'settings_archive',
104
+ 'css_var' => 'blog-archive',
105
+ 'transport' => 'postMessage',
106
+ 'output' => [
107
+ [
108
+ 'element' => '.archive.date .jupiterx-main-content, .archive.author .jupiterx-main-content, .archive.category .jupiterx-main-content, .archive.tag .jupiterx-main-content',
109
+ ],
110
+ ],
111
+ ] );
includes/customizer/settings/blog-single/author-box.php CHANGED
@@ -1,15 +1,16 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Blog Single > Styles > Author Box tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Pro Box.
11
- JupiterX_Customizer::add_field( [
12
- 'type' => 'jupiterx-pro-box',
13
- 'settings' => 'jupiterx_post_single_author_box_pro_box',
14
- 'section' => 'jupiterx_post_single_author_box',
15
- ] );
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Blog Single > Styles > Author Box tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Pro Box.
11
+ JupiterX_Customizer::add_field( [
12
+ 'type' => 'jupiterx-pro-box',
13
+ 'settings' => 'jupiterx_post_single_author_box_pro_box',
14
+ 'section' => 'jupiterx_blog_pages',
15
+ 'box' => 'author_box',
16
+ ] );
includes/customizer/settings/blog-single/avatar.php CHANGED
@@ -1,65 +1,83 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Blog Single > Styles > Avatar tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.4
8
- */
9
-
10
- $section = 'jupiterx_post_single_avatar';
11
-
12
- // Width.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-input',
15
- 'settings' => 'jupiterx_post_single_avatar_width',
16
- 'section' => $section,
17
- 'css_var' => 'post-single-avatar-width',
18
- 'label' => __( 'Width', 'jupiterx-core' ),
19
- 'column' => '4',
20
- 'input_attrs' => [ 'placeholder' => '50' ],
21
- 'units' => [ 'px' ],
22
- 'output' => [
23
- [
24
- 'element' => '.jupiterx-post-template-2 .jupiterx-post-meta-author-avatar img',
25
- 'property' => 'width',
26
- ],
27
- ],
28
- ] );
29
-
30
- // Image Border.
31
- JupiterX_Customizer::add_field( [
32
- 'type' => 'jupiterx-border',
33
- 'settings' => 'jupiterx_post_single_avatar_border',
34
- 'section' => $section,
35
- 'css_var' => 'post-single-avatar-border',
36
- 'exclude' => [ 'style', 'size' ],
37
- 'transport' => 'postMessage',
38
- 'default' => [
39
- 'width' => [
40
- 'size' => '0',
41
- 'unit' => 'px',
42
- ],
43
- ],
44
- 'output' => [
45
- [
46
- 'element' => '.jupiterx-post-template-2 .jupiterx-post-meta-author-avatar img',
47
- 'property' => 'border',
48
- ],
49
- ],
50
- ] );
51
-
52
- // Spacing.
53
- JupiterX_Customizer::add_responsive_field( [
54
- 'type' => 'jupiterx-box-model',
55
- 'settings' => 'jupiterx_post_single_avatar_spacing',
56
- 'section' => $section,
57
- 'css_var' => 'post-single-avatar',
58
- 'exclude' => [ 'padding' ],
59
- 'transport' => 'postMessage',
60
- 'output' => [
61
- [
62
- 'element' => '.jupiterx-post-template-2 .jupiterx-post-meta-author-avatar img',
63
- ],
64
- ],
65
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Blog Single > Styles > Avatar tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.4
8
+ */
9
+
10
+ $section = 'jupiterx_blog_pages';
11
+
12
+ $avatar_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_post_single_template_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ [
19
+ 'setting' => 'jupiterx_post_single_template',
20
+ 'operator' => '==',
21
+ 'value' => '2',
22
+ ],
23
+ ];
24
+
25
+ // Width.
26
+ JupiterX_Customizer::add_field( [
27
+ 'type' => 'jupiterx-input',
28
+ 'settings' => 'jupiterx_post_single_avatar_width',
29
+ 'section' => $section,
30
+ 'box' => 'avatar',
31
+ 'css_var' => 'post-single-avatar-width',
32
+ 'label' => __( 'Width', 'jupiterx-core' ),
33
+ 'input_attrs' => [ 'placeholder' => '50' ],
34
+ 'units' => [ 'px' ],
35
+ 'output' => [
36
+ [
37
+ 'element' => '.jupiterx-post-template-2 .jupiterx-post-meta-author-avatar img',
38
+ 'property' => 'width',
39
+ ],
40
+ ],
41
+ 'active_callback' => $avatar_condition,
42
+ ] );
43
+
44
+ // Image Border.
45
+ JupiterX_Customizer::add_field( [
46
+ 'type' => 'jupiterx-border',
47
+ 'settings' => 'jupiterx_post_single_avatar_border',
48
+ 'section' => $section,
49
+ 'box' => 'avatar',
50
+ 'css_var' => 'post-single-avatar-border',
51
+ 'exclude' => [ 'style', 'size' ],
52
+ 'transport' => 'postMessage',
53
+ 'default' => [
54
+ 'width' => [
55
+ 'size' => '0',
56
+ 'unit' => 'px',
57
+ ],
58
+ ],
59
+ 'output' => [
60
+ [
61
+ 'element' => '.jupiterx-post-template-2 .jupiterx-post-meta-author-avatar img',
62
+ 'property' => 'border',
63
+ ],
64
+ ],
65
+ 'active_callback' => $avatar_condition,
66
+ ] );
67
+
68
+ // Spacing.
69
+ JupiterX_Customizer::add_responsive_field( [
70
+ 'type' => 'jupiterx-box-model',
71
+ 'settings' => 'jupiterx_post_single_avatar_spacing',
72
+ 'section' => $section,
73
+ 'box' => 'avatar',
74
+ 'css_var' => 'post-single-avatar',
75
+ 'exclude' => [ 'padding' ],
76
+ 'transport' => 'postMessage',
77
+ 'output' => [
78
+ [
79
+ 'element' => '.jupiterx-post-template-2 .jupiterx-post-meta-author-avatar img',
80
+ ],
81
+ ],
82
+ 'active_callback' => $avatar_condition,
83
+ ] );
includes/customizer/settings/blog-single/featured-image.php CHANGED
@@ -1,304 +1,300 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Blog Single > Styles > Featured Image tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_post_single_featured_image';
11
-
12
- // Full width.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-toggle',
15
- 'settings' => 'jupiterx_post_single_featured_image_full_width',
16
- 'section' => $section,
17
- 'label' => __( 'Full Width', 'jupiterx-core' ),
18
- 'column' => '3',
19
- 'active_callback' => [
20
- [
21
- 'setting' => 'jupiterx_post_single_template',
22
- 'operator' => '!=',
23
- 'value' => '2',
24
- ],
25
- ],
26
- ] );
27
-
28
- // Min height.
29
- JupiterX_Customizer::add_field( [
30
- 'type' => 'jupiterx-input',
31
- 'settings' => 'jupiterx_post_single_featured_image_min_height',
32
- 'section' => $section,
33
- 'css_var' => 'post-single-featured-image-min-height',
34
- 'label' => __( 'Min Height', 'jupiterx-core' ),
35
- 'column' => '4',
36
- 'input_attrs' => [ 'placeholder' => 'auto' ],
37
- 'transport' => 'postMessage',
38
- 'default' => [ 'unit' => '-' ],
39
- 'units' => [ '-', 'px', 'vh' ],
40
- 'output' => [
41
- [
42
- 'element' => '.single-post:not(.jupiterx-post-template-2) .jupiterx-post-image img',
43
- 'property' => 'min-height',
44
- ],
45
- ],
46
- 'active_callback' => [
47
- [
48
- 'setting' => 'jupiterx_post_single_template',
49
- 'operator' => '!=',
50
- 'value' => '2',
51
- ],
52
- ],
53
- ] );
54
-
55
- // Max height.
56
- JupiterX_Customizer::add_field( [
57
- 'type' => 'jupiterx-input',
58
- 'settings' => 'jupiterx_post_single_featured_image_max_height',
59
- 'section' => $section,
60
- 'css_var' => 'post-single-featured-image-max-height',
61
- 'label' => __( 'Max Height', 'jupiterx-core' ),
62
- 'column' => '4',
63
- 'input_attrs' => [ 'placeholder' => 'auto' ],
64
- 'transport' => 'postMessage',
65
- 'default' => [ 'unit' => '-' ],
66
- 'units' => [ '-', 'px', 'vh' ],
67
- 'output' => [
68
- [
69
- 'element' => '.single-post:not(.jupiterx-post-template-2) .jupiterx-post-image img',
70
- 'property' => 'max-height',
71
- ],
72
- ],
73
- 'active_callback' => [
74
- [
75
- 'setting' => 'jupiterx_post_single_template',
76
- 'operator' => '!=',
77
- 'value' => '2',
78
- ],
79
- ],
80
- ] );
81
-
82
- // Min height (template 2).
83
- JupiterX_Customizer::add_field( [
84
- 'type' => 'jupiterx-input',
85
- 'settings' => 'jupiterx_post_single_featured_image_template_2_min_height',
86
- 'section' => $section,
87
- 'css_var' => 'post-single-featured-image-template-2-min-height',
88
- 'label' => __( 'Min Height', 'jupiterx-core' ),
89
- 'column' => '4',
90
- 'input_attrs' => [ 'placeholder' => '60' ],
91
- 'transport' => 'postMessage',
92
- 'default' => [
93
- 'size' => 60,
94
- 'unit' => 'vh',
95
- ],
96
- 'units' => [ '-', 'px', 'vh' ],
97
- 'output' => [
98
- [
99
- 'element' => '.single-post.jupiterx-post-template-2 .jupiterx-post-header',
100
- 'property' => 'min-height',
101
- ],
102
- ],
103
- 'active_callback' => [
104
- [
105
- 'setting' => 'jupiterx_post_single_template',
106
- 'operator' => '==',
107
- 'value' => '2',
108
- ],
109
- ],
110
- ] );
111
-
112
- // Max height (template 2).
113
- JupiterX_Customizer::add_field( [
114
- 'type' => 'jupiterx-input',
115
- 'settings' => 'jupiterx_post_single_featured_image_template_2_max_height',
116
- 'section' => $section,
117
- 'css_var' => 'post-single-featured-image-template-2-max-height',
118
- 'label' => __( 'Max Height', 'jupiterx-core' ),
119
- 'column' => '4',
120
- 'input_attrs' => [ 'placeholder' => 'auto' ],
121
- 'transport' => 'postMessage',
122
- 'default' => [ 'unit' => '-' ],
123
- 'units' => [ '-', 'px', 'vh' ],
124
- 'output' => [
125
- [
126
- 'element' => '.single-post.jupiterx-post-template-2 .jupiterx-post-header',
127
- 'property' => 'max-height',
128
- ],
129
- ],
130
- 'active_callback' => [
131
- [
132
- 'setting' => 'jupiterx_post_single_template',
133
- 'operator' => '==',
134
- 'value' => '2',
135
- ],
136
- ],
137
- ] );
138
-
139
- // Overlay color.
140
- JupiterX_Customizer::add_field( [
141
- 'type' => 'jupiterx-color',
142
- 'settings' => 'jupiterx_post_single_featured_image_background_color',
143
- 'section' => $section,
144
- 'css_var' => 'post-single-featured-image-overlay-color',
145
- 'label' => __( 'Overlay Color', 'jupiterx-core' ),
146
- 'column' => '3',
147
- 'transport' => 'postMessage',
148
- 'default' => 'rgba(108, 117, 125, 0.5)',
149
- 'output' => [
150
- [
151
- 'element' => '.jupiterx-post-template-2 .jupiterx-post-image-overlay',
152
- 'property' => 'background-color',
153
- ],
154
- ],
155
- 'active_callback' => [
156
- [
157
- 'setting' => 'jupiterx_post_single_template',
158
- 'operator' => 'contains',
159
- 'value' => [ '2' ],
160
- ],
161
- ],
162
- ] );
163
-
164
- // Divider.
165
- JupiterX_Customizer::add_field( [
166
- 'type' => 'jupiterx-divider',
167
- 'settings' => 'jupiterx_post_single_featured_image_divider',
168
- 'section' => $section,
169
- 'column' => '12 jupiterx-divider-control-empty',
170
- ] );
171
-
172
- // Border width.
173
- JupiterX_Customizer::add_field( [
174
- 'type' => 'jupiterx-input',
175
- 'settings' => 'jupiterx_post_single_featured_image_border_width',
176
- 'section' => $section,
177
- 'css_var' => 'post-single-featured-image-border-width',
178
- 'column' => '4',
179
- 'icon' => 'border',
180
- 'units' => [ 'px' ],
181
- 'transport' => 'postMessage',
182
- 'output' => [
183
- [
184
- 'element' => '.jupiterx-post-template-1 .jupiterx-post-image img, .jupiterx-post-template-3 .jupiterx-post-image img',
185
- 'property' => 'border-width',
186
- ],
187
- [
188
- 'element' => '.jupiterx-post-template-2 .jupiterx-post-header',
189
- 'property' => 'border-width',
190
- ],
191
- ],
192
- ] );
193
-
194
- // Border radius.
195
- JupiterX_Customizer::add_field( [
196
- 'type' => 'jupiterx-input',
197
- 'settings' => 'jupiterx_post_single_featured_image_border_radius',
198
- 'section' => $section,
199
- 'css_var' => 'post-single-featured-image-border-radius',
200
- 'column' => '4',
201
- 'icon' => 'corner-radius',
202
- 'units' => [ 'px', '%' ],
203
- 'transport' => 'postMessage',
204
- 'output' => [
205
- [
206
- 'element' => '.single-post .jupiterx-main-content:not(.jupiterx-post-image-full-width) .jupiterx-post-image img',
207
- 'property' => 'border-radius',
208
- ],
209
- ],
210
- 'active_callback' => [
211
- [
212
- 'setting' => 'jupiterx_post_single_template',
213
- 'operator' => '!=',
214
- 'value' => '2',
215
- ],
216
- [
217
- 'setting' => 'jupiterx_post_single_featured_image_full_width',
218
- 'operator' => '!=',
219
- 'value' => true,
220
- ],
221
- ],
222
- ] );
223
-
224
- // Border color.
225
- JupiterX_Customizer::add_field( [
226
- 'type' => 'jupiterx-color',
227
- 'settings' => 'jupiterx_post_single_featured_image_border_color',
228
- 'section' => $section,
229
- 'css_var' => 'post-single-featured-image-border-color',
230
- 'column' => '3',
231
- 'icon' => 'border-color',
232
- 'transport' => 'postMessage',
233
- 'output' => [
234
- [
235
- 'element' => '.jupiterx-post-template-1 .jupiterx-post-image img, .jupiterx-post-template-3 .jupiterx-post-image img',
236
- 'property' => 'border-color',
237
- ],
238
- [
239
- 'element' => '.jupiterx-post-template-2 .jupiterx-post-header',
240
- 'property' => 'border-color',
241
- ],
242
- ],
243
- ] );
244
-
245
- // Divider.
246
- JupiterX_Customizer::add_field( [
247
- 'type' => 'jupiterx-divider',
248
- 'settings' => 'jupiterx_post_single_featured_image_divider_2',
249
- 'section' => $section,
250
- ] );
251
-
252
- // All Template except 2 spacing.
253
- JupiterX_Customizer::add_responsive_field( [
254
- 'type' => 'jupiterx-box-model',
255
- 'settings' => 'jupiterx_post_single_featured_image_spacing',
256
- 'section' => $section,
257
- 'css_var' => 'post-single-featured-image',
258
- 'transport' => 'postMessage',
259
- 'exclude' => [ 'padding' ],
260
- 'default' => [
261
- 'desktop' => [
262
- 'margin_bottom' => 2,
263
- ],
264
- ],
265
- 'output' => [
266
- [
267
- 'element' => '.single-post:not(.jupiterx-post-template-2) .jupiterx-post-image',
268
- ],
269
- ],
270
- 'active_callback' => [
271
- [
272
- 'setting' => 'jupiterx_post_single_template',
273
- 'operator' => 'contains',
274
- 'value' => [ '1', '3' ],
275
- ],
276
- ],
277
- ] );
278
-
279
- // Template 2 spacing.
280
- JupiterX_Customizer::add_responsive_field( [
281
- 'type' => 'jupiterx-box-model',
282
- 'settings' => 'jupiterx_post_single_featured_image_template_2_spacing',
283
- 'section' => $section,
284
- 'css_var' => 'post-single-template-2-featured-image',
285
- 'transport' => 'postMessage',
286
- 'exclude' => [ 'padding' ],
287
- 'default' => [
288
- 'desktop' => [
289
- 'margin_bottom' => 2,
290
- ],
291
- ],
292
- 'output' => [
293
- [
294
- 'element' => '.jupiterx-post-template-2 .jupiterx-post-header',
295
- ],
296
- ],
297
- 'active_callback' => [
298
- [
299
- 'setting' => 'jupiterx_post_single_template',
300
- 'operator' => 'contains',
301
- 'value' => [ '2' ],
302
- ],
303
- ],
304
- ] );
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Blog Single > Styles > Featured Image tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_blog_pages';
11
+
12
+ $featured_image_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_post_single_template_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ [
19
+ 'setting' => 'jupiterx_post_single_elements',
20
+ 'operator' => 'contains',
21
+ 'value' => 'featured_image',
22
+ ],
23
+ ];
24
+
25
+ $featured_image_templates_condition = [
26
+ [
27
+ 'setting' => 'jupiterx_post_single_template',
28
+ 'operator' => '!=',
29
+ 'value' => '2',
30
+ ],
31
+ ];
32
+
33
+ $featured_image_templates_condition = array_merge( $featured_image_condition, $featured_image_templates_condition );
34
+
35
+ $featured_image_second_template_condition = [
36
+ [
37
+ 'setting' => 'jupiterx_post_single_template',
38
+ 'operator' => '==',
39
+ 'value' => '2',
40
+ ],
41
+ ];
42
+
43
+ $featured_image_second_template_condition = array_merge( $featured_image_condition, $featured_image_second_template_condition );
44
+
45
+ $featured_image_full_width_condition = [
46
+ [
47
+ 'setting' => 'jupiterx_post_single_template',
48
+ 'operator' => '!=',
49
+ 'value' => '2',
50
+ ],
51
+ [
52
+ 'setting' => 'jupiterx_post_single_featured_image_full_width',
53
+ 'operator' => '!=',
54
+ 'value' => true,
55
+ ],
56
+ ];
57
+
58
+ $featured_image_full_width_condition = array_merge( $featured_image_condition, $featured_image_full_width_condition );
59
+
60
+ // Full width.
61
+ JupiterX_Customizer::add_field( [
62
+ 'type' => 'jupiterx-toggle',
63
+ 'settings' => 'jupiterx_post_single_featured_image_full_width',
64
+ 'section' => $section,
65
+ 'box' => 'featured_image',
66
+ 'label' => __( 'Full Width', 'jupiterx-core' ),
67
+ 'active_callback' => $featured_image_condition,
68
+ ] );
69
+
70
+ // Min height.
71
+ JupiterX_Customizer::add_field( [
72
+ 'type' => 'jupiterx-input',
73
+ 'settings' => 'jupiterx_post_single_featured_image_min_height',
74
+ 'section' => $section,
75
+ 'box' => 'featured_image',
76
+ 'css_var' => 'post-single-featured-image-min-height',
77
+ 'label' => __( 'Min Height', 'jupiterx-core' ),
78
+ 'input_attrs' => [ 'placeholder' => 'auto' ],
79
+ 'transport' => 'postMessage',
80
+ 'default' => [ 'unit' => '-' ],
81
+ 'units' => [ '-', 'px', 'vh' ],
82
+ 'output' => [
83
+ [
84
+ 'element' => '.single-post:not(.jupiterx-post-template-2) .jupiterx-post-image img',
85
+ 'property' => 'min-height',
86
+ ],
87
+ ],
88
+ 'active_callback' => $featured_image_condition,
89
+ ] );
90
+
91
+ // Max height.
92
+ JupiterX_Customizer::add_field( [
93
+ 'type' => 'jupiterx-input',
94
+ 'settings' => 'jupiterx_post_single_featured_image_max_height',
95
+ 'section' => $section,
96
+ 'box' => 'featured_image',
97
+ 'css_var' => 'post-single-featured-image-max-height',
98
+ 'label' => __( 'Max Height', 'jupiterx-core' ),
99
+ 'input_attrs' => [ 'placeholder' => 'auto' ],
100
+ 'transport' => 'postMessage',
101
+ 'default' => [ 'unit' => '-' ],
102
+ 'units' => [ '-', 'px', 'vh' ],
103
+ 'output' => [
104
+ [
105
+ 'element' => '.single-post:not(.jupiterx-post-template-2) .jupiterx-post-image img',
106
+ 'property' => 'max-height',
107
+ ],
108
+ ],
109
+ 'active_callback' => $featured_image_templates_condition,
110
+ ] );
111
+
112
+ // Min height (template 2).
113
+ JupiterX_Customizer::add_field( [
114
+ 'type' => 'jupiterx-input',
115
+ 'settings' => 'jupiterx_post_single_featured_image_template_2_min_height',
116
+ 'section' => $section,
117
+ 'box' => 'featured_image',
118
+ 'css_var' => 'post-single-featured-image-template-2-min-height',
119
+ 'label' => __( 'Min Height', 'jupiterx-core' ),
120
+ 'input_attrs' => [ 'placeholder' => '60' ],
121
+ 'transport' => 'postMessage',
122
+ 'default' => [
123
+ 'size' => 60,
124
+ 'unit' => 'vh',
125
+ ],
126
+ 'units' => [ '-', 'px', 'vh' ],
127
+ 'output' => [
128
+ [
129
+ 'element' => '.single-post.jupiterx-post-template-2 .jupiterx-post-header',
130
+ 'property' => 'min-height',
131
+ ],
132
+ ],
133
+ 'active_callback' => $featured_image_second_template_condition,
134
+ ] );
135
+
136
+ // Max height (template 2).
137
+ JupiterX_Customizer::add_field( [
138
+ 'type' => 'jupiterx-input',
139
+ 'settings' => 'jupiterx_post_single_featured_image_template_2_max_height',
140
+ 'section' => $section,
141
+ 'box' => 'featured_image',
142
+ 'css_var' => 'post-single-featured-image-template-2-max-height',
143
+ 'label' => __( 'Max Height', 'jupiterx-core' ),
144
+ 'input_attrs' => [ 'placeholder' => 'auto' ],
145
+ 'transport' => 'postMessage',
146
+ 'default' => [ 'unit' => '-' ],
147
+ 'units' => [ '-', 'px', 'vh' ],
148
+ 'output' => [
149
+ [
150
+ 'element' => '.single-post.jupiterx-post-template-2 .jupiterx-post-header',
151
+ 'property' => 'max-height',
152
+ ],
153
+ ],
154
+ 'active_callback' => $featured_image_second_template_condition,
155
+ ] );
156
+
157
+ // Overlay color.
158
+ JupiterX_Customizer::add_field( [
159
+ 'type' => 'jupiterx-color',
160
+ 'settings' => 'jupiterx_post_single_featured_image_background_color',
161
+ 'section' => $section,
162
+ 'box' => 'featured_image',
163
+ 'css_var' => 'post-single-featured-image-overlay-color',
164
+ 'label' => __( 'Overlay Color', 'jupiterx-core' ),
165
+ 'transport' => 'postMessage',
166
+ 'default' => 'rgba(108, 117, 125, 0.5)',
167
+ 'output' => [
168
+ [
169
+ 'element' => '.jupiterx-post-template-2 .jupiterx-post-image-overlay',
170
+ 'property' => 'background-color',
171
+ ],
172
+ ],
173
+ 'active_callback' => $featured_image_second_template_condition,
174
+ ] );
175
+
176
+ // Divider.
177
+ JupiterX_Customizer::add_field( [
178
+ 'type' => 'jupiterx-divider',
179
+ 'settings' => 'jupiterx_post_single_featured_image_divider',
180
+ 'section' => $section,
181
+ 'box' => 'featured_image',
182
+ 'active_callback' => $featured_image_condition,
183
+ ] );
184
+
185
+ // Border width.
186
+ JupiterX_Customizer::add_field( [
187
+ 'type' => 'jupiterx-input',
188
+ 'settings' => 'jupiterx_post_single_featured_image_border_width',
189
+ 'section' => $section,
190
+ 'box' => 'featured_image',
191
+ 'css_var' => 'post-single-featured-image-border-width',
192
+ 'label' => __( 'Border', 'jupiterx-core' ),
193
+ 'units' => [ 'px' ],
194
+ 'transport' => 'postMessage',
195
+ 'output' => [
196
+ [
197
+ 'element' => '.jupiterx-post-template-1 .jupiterx-post-image img, .jupiterx-post-template-3 .jupiterx-post-image img',
198
+ 'property' => 'border-width',
199
+ ],
200
+ [
201
+ 'element' => '.jupiterx-post-template-2 .jupiterx-post-header',
202
+ 'property' => 'border-width',
203
+ ],
204
+ ],
205
+ 'active_callback' => $featured_image_condition,
206
+ ] );
207
+
208
+ // Border radius.
209
+ JupiterX_Customizer::add_field( [
210
+ 'type' => 'jupiterx-input',
211
+ 'settings' => 'jupiterx_post_single_featured_image_border_radius',
212
+ 'section' => $section,
213
+ 'box' => 'featured_image',
214
+ 'css_var' => 'post-single-featured-image-border-radius',
215
+ 'label' => __( 'Border Radius', 'jupiterx-core' ),
216
+ 'units' => [ 'px', '%' ],
217
+ 'transport' => 'postMessage',
218
+ 'output' => [
219
+ [
220
+ 'element' => '.single-post .jupiterx-main-content:not(.jupiterx-post-image-full-width) .jupiterx-post-image img',
221
+ 'property' => 'border-radius',
222
+ ],
223
+ ],
224
+ 'active_callback' => $featured_image_full_width_condition,
225
+ ] );
226
+
227
+ // Border color.
228
+ JupiterX_Customizer::add_field( [
229
+ 'type' => 'jupiterx-color',
230
+ 'settings' => 'jupiterx_post_single_featured_image_border_color',
231
+ 'section' => $section,
232
+ 'box' => 'featured_image',
233
+ 'css_var' => 'post-single-featured-image-border-color',
234
+ 'label' => __( 'Border Color', 'jupiterx-core' ),
235
+ 'transport' => 'postMessage',
236
+ 'output' => [
237
+ [
238
+ 'element' => '.jupiterx-post-template-1 .jupiterx-post-image img, .jupiterx-post-template-3 .jupiterx-post-image img',
239
+ 'property' => 'border-color',
240
+ ],
241
+ [
242
+ 'element' => '.jupiterx-post-template-2 .jupiterx-post-header',
243
+ 'property' => 'border-color',
244
+ ],
245
+ ],
246
+ 'active_callback' => $featured_image_condition,
247
+ ] );
248
+
249
+ // Divider.
250
+ JupiterX_Customizer::add_field( [
251
+ 'type' => 'jupiterx-divider',
252
+ 'settings' => 'jupiterx_post_single_featured_image_divider_2',
253
+ 'section' => $section,
254
+ 'box' => 'featured_image',
255
+ 'active_callback' => $featured_image_condition,
256
+ ] );
257
+
258
+ // All Template except 2 spacing.
259
+ JupiterX_Customizer::add_responsive_field( [
260
+ 'type' => 'jupiterx-box-model',
261
+ 'settings' => 'jupiterx_post_single_featured_image_spacing',
262
+ 'section' => $section,
263
+ 'box' => 'featured_image',
264
+ 'css_var' => 'post-single-featured-image',
265
+ 'transport' => 'postMessage',
266
+ 'exclude' => [ 'padding' ],
267
+ 'default' => [
268
+ 'desktop' => [
269
+ 'margin_bottom' => 2,
270
+ ],
271
+ ],
272
+ 'output' => [
273
+ [
274
+ 'element' => '.single-post:not(.jupiterx-post-template-2) .jupiterx-post-image',
275
+ ],
276
+ ],
277
+ 'active_callback' => $featured_image_templates_condition,
278
+ ] );
279
+
280
+ // Template 2 spacing.
281
+ JupiterX_Customizer::add_responsive_field( [
282
+ 'type' => 'jupiterx-box-model',
283
+ 'settings' => 'jupiterx_post_single_featured_image_template_2_spacing',
284
+ 'section' => $section,
285
+ 'box' => 'featured_image',
286
+ 'css_var' => 'post-single-template-2-featured-image',
287
+ 'transport' => 'postMessage',
288
+ 'exclude' => [ 'padding' ],
289
+ 'default' => [
290
+ 'desktop' => [
291
+ 'margin_bottom' => 2,
292
+ ],
293
+ ],
294
+ 'output' => [
295
+ [
296
+ 'element' => '.jupiterx-post-template-2 .jupiterx-post-header',
297
+ ],
298
+ ],
299
+ 'active_callback' => $featured_image_second_template_condition,
300
+ ] );
 
 
 
 
includes/customizer/settings/blog-single/meta.php CHANGED
@@ -1,179 +1,194 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Blog Single > Styles > Meta tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_post_single_meta';
11
-
12
- // Align.
13
- JupiterX_Customizer::add_responsive_field( [
14
- 'type' => 'jupiterx-choose',
15
- 'settings' => 'jupiterx_post_single_meta_align',
16
- 'section' => $section,
17
- 'css_var' => 'post-single-meta-align',
18
- 'label' => __( 'Align', 'jupiterx-core' ),
19
- 'column' => '4',
20
- 'transport' => 'postMessage',
21
- 'choices' => JupiterX_Customizer_Utils::get_align(),
22
- 'output' => [
23
- [
24
- 'element' => '.single-post .jupiterx-post-meta',
25
- 'property' => 'text-align',
26
- ],
27
- ],
28
- 'active_callback' => [
29
- [
30
- 'setting' => 'jupiterx_post_single_template',
31
- 'operator' => 'contains',
32
- 'value' => [ '1', '2' ],
33
- ],
34
- ],
35
- ] );
36
-
37
- // Avatar.
38
- JupiterX_Customizer::add_field( [
39
- 'type' => 'jupiterx-toggle',
40
- 'settings' => 'jupiterx_post_single_meta_avatar',
41
- 'section' => $section,
42
- 'label' => __( 'Avatar', 'jupiterx-core' ),
43
- 'column' => '3',
44
- 'default' => true,
45
- 'active_callback' => [
46
- [
47
- 'setting' => 'jupiterx_post_single_template',
48
- 'operator' => 'contains',
49
- 'value' => [ '2', '3' ],
50
- ],
51
- ],
52
- ] );
53
-
54
- // Typography.
55
- JupiterX_Customizer::add_responsive_field( [
56
- 'type' => 'jupiterx-typography',
57
- 'settings' => 'jupiterx_post_single_meta_typography',
58
- 'section' => $section,
59
- 'css_var' => 'post-single-meta',
60
- 'transport' => 'postMessage',
61
- 'exclude' => [ 'line_height', 'text_transform' ],
62
- 'output' => [
63
- [
64
- 'element' => '.single-post .jupiterx-post-meta',
65
- ],
66
- ],
67
- ] );
68
-
69
- // Meta divider.
70
- JupiterX_Customizer::add_field( [
71
- 'type' => 'jupiterx-text',
72
- 'settings' => 'jupiterx_post_single_meta_meta_divider',
73
- 'section' => $section,
74
- 'css_var' => [
75
- 'name' => 'post-single-meta-breadcrumb-divider',
76
- 'value' => '"$"',
77
- ],
78
- 'label' => __( 'Meta Divider', 'jupiterx-core' ),
79
- 'column' => '5',
80
- 'transport' => 'postMessage',
81
- 'default' => '|',
82
- 'output' => [
83
- [
84
- 'element' => '.single-post .jupiterx-post-meta .list-inline-item + .list-inline-item:before',
85
- 'property' => 'content',
86
- 'value_pattern' => '"$"',
87
- ],
88
- ],
89
- 'active_callback' => [
90
- [
91
- 'setting' => 'jupiterx_post_single_template',
92
- 'operator' => 'contains',
93
- 'value' => [ '1', '2' ],
94
- ],
95
- ],
96
- ] );
97
-
98
- // Divider color.
99
- JupiterX_Customizer::add_field( [
100
- 'type' => 'jupiterx-color',
101
- 'settings' => 'jupiterx_post_single_meta_meta_divider_color',
102
- 'section' => $section,
103
- 'css_var' => 'post-single-meta-divider-color',
104
- 'label' => __( 'Divider Color', 'jupiterx-core' ),
105
- 'column' => '3',
106
- 'transport' => 'postMessage',
107
- 'output' => [
108
- [
109
- 'element' => '.single-post .jupiterx-post-meta .list-inline-item + .list-inline-item:before',
110
- 'property' => 'color',
111
- ],
112
- ],
113
- 'active_callback' => [
114
- [
115
- 'setting' => 'jupiterx_post_single_template',
116
- 'operator' => 'contains',
117
- 'value' => [ '1', '2' ],
118
- ],
119
- ],
120
- ] );
121
-
122
- // Divider.
123
- JupiterX_Customizer::add_field( [
124
- 'type' => 'jupiterx-divider',
125
- 'settings' => 'jupiterx_post_single_meta_divider',
126
- 'section' => $section,
127
- ] );
128
-
129
- // Label.
130
- JupiterX_Customizer::add_field( [
131
- 'type' => 'jupiterx-label',
132
- 'label' => __( 'Links', 'jupiterx-core' ),
133
- 'settings' => 'jupiterx_post_single_meta_label',
134
- 'section' => $section,
135
- ] );
136
-
137
- // Links color.
138
- JupiterX_Customizer::add_field( [
139
- 'type' => 'jupiterx-color',
140
- 'settings' => 'jupiterx_post_single_meta_links_color',
141
- 'section' => $section,
142
- 'css_var' => 'post-single-meta-links-color',
143
- 'column' => '3',
144
- 'icon' => 'font-color',
145
- 'transport' => 'postMessage',
146
- 'output' => [
147
- [
148
- 'element' => '.single-post .jupiterx-post-meta a',
149
- 'property' => 'color',
150
- ],
151
- ],
152
- ] );
153
-
154
- // Divider.
155
- JupiterX_Customizer::add_field( [
156
- 'type' => 'jupiterx-divider',
157
- 'settings' => 'jupiterx_post_single_meta_divider_2',
158
- 'section' => $section,
159
- ] );
160
-
161
- // Spacing.
162
- JupiterX_Customizer::add_responsive_field( [
163
- 'type' => 'jupiterx-box-model',
164
- 'settings' => 'jupiterx_post_single_meta_spacing',
165
- 'section' => $section,
166
- 'css_var' => 'post-single-meta',
167
- 'transport' => 'postMessage',
168
- 'exclude' => [ 'padding' ],
169
- 'default' => [
170
- 'desktop' => [
171
- 'margin_bottom' => 1,
172
- ],
173
- ],
174
- 'output' => [
175
- [
176
- 'element' => '.single-post .jupiterx-post-meta',
177
- ],
178
- ],
179
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Blog Single > Styles > Meta tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_blog_pages';
11
+
12
+ $meta_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_post_single_template_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ $meta_templates_1_2_condition = [
21
+ [
22
+ 'setting' => 'jupiterx_post_single_template',
23
+ 'operator' => 'contains',
24
+ 'value' => [ '1', '2' ],
25
+ ],
26
+ ];
27
+
28
+ $meta_templates_2_3_condition = [
29
+ [
30
+ 'setting' => 'jupiterx_post_single_template',
31
+ 'operator' => 'contains',
32
+ 'value' => [ '2', '3' ],
33
+ ],
34
+ ];
35
+
36
+ $meta_templates_1_2_condition = array_merge( $meta_condition, $meta_templates_1_2_condition );
37
+ $meta_templates_2_3_condition = array_merge( $meta_condition, $meta_templates_2_3_condition );
38
+
39
+ // Align.
40
+ JupiterX_Customizer::add_responsive_field( [
41
+ 'type' => 'jupiterx-choose',
42
+ 'settings' => 'jupiterx_post_single_meta_align',
43
+ 'section' => $section,
44
+ 'box' => 'meta',
45
+ 'css_var' => 'post-single-meta-align',
46
+ 'label' => __( 'Alignment', 'jupiterx-core' ),
47
+ 'inline' => true,
48
+ 'transport' => 'postMessage',
49
+ 'choices' => JupiterX_Customizer_Utils::get_align(),
50
+ 'output' => [
51
+ [
52
+ 'element' => '.single-post .jupiterx-post-meta',
53
+ 'property' => 'text-align',
54
+ ],
55
+ ],
56
+ 'active_callback' => $meta_templates_1_2_condition,
57
+ ] );
58
+
59
+ // Avatar.
60
+ JupiterX_Customizer::add_field( [
61
+ 'type' => 'jupiterx-toggle',
62
+ 'settings' => 'jupiterx_post_single_meta_avatar',
63
+ 'section' => $section,
64
+ 'box' => 'meta',
65
+ 'label' => __( 'Avatar', 'jupiterx-core' ),
66
+ 'default' => true,
67
+ 'active_callback' => $meta_templates_2_3_condition,
68
+ ] );
69
+
70
+ // Typography.
71
+ JupiterX_Customizer::add_responsive_field( [
72
+ 'type' => 'jupiterx-typography',
73
+ 'settings' => 'jupiterx_post_single_meta_typography',
74
+ 'section' => $section,
75
+ 'box' => 'meta',
76
+ 'css_var' => 'post-single-meta',
77
+ 'transport' => 'postMessage',
78
+ 'exclude' => [ 'line_height', 'text_transform' ],
79
+ 'output' => [
80
+ [
81
+ 'element' => '.single-post .jupiterx-post-meta',
82
+ ],
83
+ ],
84
+ 'active_callback' => $meta_condition,
85
+ ] );
86
+
87
+ // Meta divider.
88
+ JupiterX_Customizer::add_field( [
89
+ 'type' => 'jupiterx-text',
90
+ 'settings' => 'jupiterx_post_single_meta_meta_divider',
91
+ 'section' => $section,
92
+ 'box' => 'meta',
93
+ 'css_var' => [
94
+ 'name' => 'post-single-meta-breadcrumb-divider',
95
+ 'value' => '"$"',
96
+ ],
97
+ 'label' => __( 'Meta Divider', 'jupiterx-core' ),
98
+ 'transport' => 'postMessage',
99
+ 'default' => '|',
100
+ 'output' => [
101
+ [
102
+ 'element' => '.single-post .jupiterx-post-meta .list-inline-item + .list-inline-item:before',
103
+ 'property' => 'content',
104
+ 'value_pattern' => '"$"',
105
+ ],
106
+ ],
107
+ 'active_callback' => $meta_templates_1_2_condition,
108
+ ] );
109
+
110
+ // Divider color.
111
+ JupiterX_Customizer::add_field( [
112
+ 'type' => 'jupiterx-color',
113
+ 'settings' => 'jupiterx_post_single_meta_meta_divider_color',
114
+ 'section' => $section,
115
+ 'box' => 'meta',
116
+ 'css_var' => 'post-single-meta-divider-color',
117
+ 'label' => __( 'Divider Color', 'jupiterx-core' ),
118
+ 'transport' => 'postMessage',
119
+ 'output' => [
120
+ [
121
+ 'element' => '.single-post .jupiterx-post-meta .list-inline-item + .list-inline-item:before',
122
+ 'property' => 'color',
123
+ ],
124
+ ],
125
+ 'active_callback' => $meta_templates_1_2_condition,
126
+ ] );
127
+
128
+ // Divider.
129
+ JupiterX_Customizer::add_field( [
130
+ 'type' => 'jupiterx-divider',
131
+ 'settings' => 'jupiterx_post_single_meta_divider',
132
+ 'section' => $section,
133
+ 'box' => 'meta',
134
+ 'active_callback' => $meta_condition,
135
+ ] );
136
+
137
+ // Label.
138
+ JupiterX_Customizer::add_field( [
139
+ 'type' => 'jupiterx-label',
140
+ 'label' => __( 'Links', 'jupiterx-core' ),
141
+ 'settings' => 'jupiterx_post_single_meta_label',
142
+ 'section' => $section,
143
+ 'box' => 'meta',
144
+ 'active_callback' => $meta_condition,
145
+ ] );
146
+
147
+ // Links color.
148
+ JupiterX_Customizer::add_field( [
149
+ 'type' => 'jupiterx-color',
150
+ 'settings' => 'jupiterx_post_single_meta_links_color',
151
+ 'section' => $section,
152
+ 'box' => 'meta',
153
+ 'css_var' => 'post-single-meta-links-color',
154
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
155
+ 'transport' => 'postMessage',
156
+ 'output' => [
157
+ [
158
+ 'element' => '.single-post .jupiterx-post-meta a',
159
+ 'property' => 'color',
160
+ ],
161
+ ],
162
+ 'active_callback' => $meta_condition,
163
+ ] );
164
+
165
+ // Divider.
166
+ JupiterX_Customizer::add_field( [
167
+ 'type' => 'jupiterx-divider',
168
+ 'settings' => 'jupiterx_post_single_meta_divider_2',
169
+ 'section' => $section,
170
+ 'box' => 'meta',
171
+ 'active_callback' => $meta_condition,
172
+ ] );
173
+
174
+ // Spacing.
175
+ JupiterX_Customizer::add_responsive_field( [
176
+ 'type' => 'jupiterx-box-model',
177
+ 'settings' => 'jupiterx_post_single_meta_spacing',
178
+ 'section' => $section,
179
+ 'box' => 'meta',
180
+ 'css_var' => 'post-single-meta',
181
+ 'transport' => 'postMessage',
182
+ 'exclude' => [ 'padding' ],
183
+ 'default' => [
184
+ 'desktop' => [
185
+ 'margin_bottom' => 1,
186
+ ],
187
+ ],
188
+ 'output' => [
189
+ [
190
+ 'element' => '.single-post .jupiterx-post-meta',
191
+ ],
192
+ ],
193
+ 'active_callback' => $meta_condition,
194
+ ] );
includes/customizer/settings/blog-single/navigation.php CHANGED
@@ -1,15 +1,16 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Blog Single > Styles > Navigation tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Pro Box.
11
- JupiterX_Customizer::add_field( [
12
- 'type' => 'jupiterx-pro-box',
13
- 'settings' => 'jupiterx_post_single_navigation_pro_box',
14
- 'section' => 'jupiterx_post_single_navigation',
15
- ] );
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Blog Single > Styles > Navigation tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Pro Box.
11
+ JupiterX_Customizer::add_field( [
12
+ 'type' => 'jupiterx-pro-box',
13
+ 'settings' => 'jupiterx_post_single_navigation_pro_box',
14
+ 'section' => 'jupiterx_blog_pages',
15
+ 'box' => 'navigation',
16
+ ] );
includes/customizer/settings/blog-single/popup.php CHANGED
@@ -1,134 +1,13 @@
1
- <?php
2
- /**
3
- * Add Jupiter blog archive popup and tabs to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $blog_popups = [
11
- 'featured_image' => __( 'Featured Image', 'jupiterx-core' ),
12
- 'title' => __( 'Title', 'jupiterx-core' ),
13
- 'meta' => __( 'Meta', 'jupiterx-core' ),
14
- 'post_content' => __( 'Post Content', 'jupiterx-core' ),
15
- 'tags' => __( 'Tags', 'jupiterx-core' ),
16
- 'social_share' => __( 'Social Share', 'jupiterx-core' ),
17
- 'navigation' => __( 'Navigation', 'jupiterx-core' ),
18
- 'author_box' => __( 'Author Box', 'jupiterx-core' ),
19
- 'related_posts' => __( 'Recommended Posts', 'jupiterx-core' ),
20
- ];
21
-
22
- $template2_popups = [
23
- 'avatar' => __( 'Avatar', 'jupiterx-core' ),
24
- ];
25
-
26
- $popups = $template2_popups + $blog_popups;
27
-
28
- // Blog single popup.
29
- JupiterX_Customizer::add_section( 'jupiterx_post_single', [
30
- 'panel' => 'jupiterx_blog_panel',
31
- 'title' => __( 'Blog Single', 'jupiterx-core' ),
32
- 'type' => 'popup',
33
- 'tabs' => [
34
- 'settings' => __( 'Settings', 'jupiterx-core' ),
35
- 'styles' => __( 'Styles', 'jupiterx-core' ),
36
- ],
37
- 'popups' => $popups,
38
- 'preview' => true,
39
- 'help' => [
40
- 'url' => 'https://themes.artbees.net/docs/display-settings-for-blog-shop-single-pages',
41
- 'title' => __( 'Display settings for Blog, Shop single pages', 'jupiterx-core' ),
42
- ],
43
- ] );
44
-
45
- // Settings tab.
46
- JupiterX_Customizer::add_section( 'jupiterx_post_single_settings', [
47
- 'popup' => 'jupiterx_post_single',
48
- 'type' => 'pane',
49
- 'pane' => [
50
- 'type' => 'tab',
51
- 'id' => 'settings',
52
- ],
53
- ] );
54
-
55
- // Styles tab.
56
- JupiterX_Customizer::add_section( 'jupiterx_post_single_styles', [
57
- 'popup' => 'jupiterx_post_single',
58
- 'type' => 'pane',
59
- 'pane' => [
60
- 'type' => 'tab',
61
- 'id' => 'styles',
62
- ],
63
- ] );
64
-
65
- // Styles tab > Child popups.
66
- JupiterX_Customizer::add_field( [
67
- 'type' => 'jupiterx-child-popup',
68
- 'settings' => 'jupiterx_post_single_styles_popups_avatar',
69
- 'section' => 'jupiterx_post_single_styles',
70
- 'target' => 'jupiterx_post_single',
71
- 'choices' => $template2_popups,
72
- 'active_callback' => [
73
- [
74
- 'setting' => 'jupiterx_post_single_template',
75
- 'operator' => '==',
76
- 'value' => '2',
77
- ],
78
- ],
79
- ] );
80
-
81
- // Styles tab > Child popups.
82
- JupiterX_Customizer::add_field( [
83
- 'type' => 'jupiterx-child-popup',
84
- 'settings' => 'jupiterx_post_single_styles_popups',
85
- 'section' => 'jupiterx_post_single_styles',
86
- 'target' => 'jupiterx_post_single',
87
- 'choices' => [
88
- 'featured_image' => __( 'Featured Image', 'jupiterx-core' ),
89
- 'title' => __( 'Title', 'jupiterx-core' ),
90
- 'meta' => __( 'Meta', 'jupiterx-core' ),
91
- 'post_content' => __( 'Post Content', 'jupiterx-core' ),
92
- 'tags' => __( 'Tags', 'jupiterx-core' ),
93
- 'social_share' => [
94
- 'label' => __( 'Social Share', 'jupiterx-core' ),
95
- 'pro' => true,
96
- ],
97
- 'navigation' => [
98
- 'label' => __( 'Navigation', 'jupiterx-core' ),
99
- 'pro' => true,
100
- ],
101
- 'author_box' => [
102
- 'label' => __( 'Author Box', 'jupiterx-core' ),
103
- 'pro' => true,
104
- ],
105
- 'related_posts' => [
106
- 'label' => __( 'Recommended Posts', 'jupiterx-core' ),
107
- 'pro' => true,
108
- ],
109
- ],
110
- 'active_callback' => [
111
- [
112
- 'setting' => 'jupiterx_post_single_template_type',
113
- 'operator' => '===',
114
- 'value' => '',
115
- ],
116
- ],
117
- ] );
118
-
119
- // Create popup children.
120
- foreach ( $popups as $popup_id => $label ) {
121
- JupiterX_Customizer::add_section( 'jupiterx_post_single_' . $popup_id, [
122
- 'popup' => 'jupiterx_post_single',
123
- 'type' => 'pane',
124
- 'pane' => [
125
- 'type' => 'popup',
126
- 'id' => $popup_id,
127
- ],
128
- ] );
129
- }
130
-
131
- // Load all the settings.
132
- foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
133
- require_once $setting;
134
- }
1
+ <?php
2
+ /**
3
+ * Add Jupiter blog archive popup and tabs to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Load all the settings.
11
+ foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
12
+ require_once $setting;
13
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/customizer/settings/blog-single/post-content.php CHANGED
@@ -1,66 +1,82 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Blog Single > Styles > Post Content tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- $section = 'jupiterx_post_single_post_content';
11
-
12
- // Align.
13
- JupiterX_Customizer::add_responsive_field( [
14
- 'type' => 'jupiterx-choose',
15
- 'settings' => "{$section}_align",
16
- 'section' => $section,
17
- 'css_var' => 'post-single-post-content-align',
18
- 'label' => __( 'Align', 'jupiterx-core' ),
19
- 'column' => '4',
20
- 'transport' => 'postMessage',
21
- 'choices' => JupiterX_Customizer_Utils::get_align(),
22
- 'output' => [
23
- [
24
- 'element' => '.single-post .jupiterx-post-content',
25
- 'property' => 'text-align',
26
- ],
27
- ],
28
- ] );
29
-
30
- // Typography.
31
- JupiterX_Customizer::add_field( [
32
- 'type' => 'jupiterx-typography',
33
- 'settings' => "{$section}_typography",
34
- 'section' => $section,
35
- 'responsive' => true,
36
- 'css_var' => 'post-single-post-content',
37
- 'transport' => 'postMessage',
38
- 'exclude' => [ 'text_transform' ],
39
- 'output' => [
40
- [
41
- 'element' => '.single-post .jupiterx-post-content',
42
- ],
43
- ],
44
- ] );
45
-
46
- // Divider.
47
- JupiterX_Customizer::add_field( [
48
- 'type' => 'jupiterx-divider',
49
- 'settings' => "{$section}_divider",
50
- 'section' => $section,
51
- ] );
52
-
53
- // Spacing.
54
- JupiterX_Customizer::add_responsive_field( [
55
- 'type' => 'jupiterx-box-model',
56
- 'settings' => "{$section}_spacing",
57
- 'section' => $section,
58
- 'css_var' => 'post-single-post-content',
59
- 'transport' => 'postMessage',
60
- 'exclude' => [ 'padding' ],
61
- 'output' => [
62
- [
63
- 'element' => '.single-post .jupiterx-post-content',
64
- ],
65
- ],
66
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Blog Single > Styles > Post Content tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ $section = 'jupiterx_blog_pages';
11
+
12
+ $post_content_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_post_single_template_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ // Align.
21
+ JupiterX_Customizer::add_responsive_field( [
22
+ 'type' => 'jupiterx-choose',
23
+ 'settings' => "{$section}_content_align",
24
+ 'section' => $section,
25
+ 'box' => 'post_content',
26
+ 'css_var' => 'post-single-post-content-align',
27
+ 'label' => __( 'Alignment', 'jupiterx-core' ),
28
+ 'inline' => true,
29
+ 'transport' => 'postMessage',
30
+ 'choices' => JupiterX_Customizer_Utils::get_align(),
31
+ 'output' => [
32
+ [
33
+ 'element' => '.single-post .jupiterx-post-content',
34
+ 'property' => 'text-align',
35
+ ],
36
+ ],
37
+ 'active_callback' => $post_content_condition,
38
+ ] );
39
+
40
+ // Typography.
41
+ JupiterX_Customizer::add_field( [
42
+ 'type' => 'jupiterx-typography',
43
+ 'settings' => "{$section}_content_typography",
44
+ 'section' => $section,
45
+ 'box' => 'post_content',
46
+ 'responsive' => true,
47
+ 'css_var' => 'post-single-post-content',
48
+ 'transport' => 'postMessage',
49
+ 'exclude' => [ 'text_transform' ],
50
+ 'output' => [
51
+ [
52
+ 'element' => '.single-post .jupiterx-post-content',
53
+ ],
54
+ ],
55
+ 'active_callback' => $post_content_condition,
56
+ ] );
57
+
58
+ // Divider.
59
+ JupiterX_Customizer::add_field( [
60
+ 'type' => 'jupiterx-divider',
61
+ 'settings' => "{$section}_content_divider",
62
+ 'section' => $section,
63
+ 'box' => 'post_content',
64
+ 'active_callback' => $post_content_condition,
65
+ ] );
66
+
67
+ // Spacing.
68
+ JupiterX_Customizer::add_responsive_field( [
69
+ 'type' => 'jupiterx-box-model',
70
+ 'settings' => "{$section}_content_spacing",
71
+ 'section' => $section,
72
+ 'box' => 'post_content',
73
+ 'css_var' => 'post-single-post-content',
74
+ 'transport' => 'postMessage',
75
+ 'exclude' => [ 'padding' ],
76
+ 'output' => [
77
+ [
78
+ 'element' => '.single-post .jupiterx-post-content',
79
+ ],
80
+ ],
81
+ 'active_callback' => $post_content_condition,
82
+ ] );
includes/customizer/settings/blog-single/related-posts.php CHANGED
@@ -1,15 +1,16 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Blog Single > Styles > Recommended Posts tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Pro Box.
11
- JupiterX_Customizer::add_field( [
12
- 'type' => 'jupiterx-pro-box',
13
- 'settings' => 'jupiterx_post_single_related_posts_pro_box',
14
- 'section' => 'jupiterx_post_single_related_posts',
15
- ] );
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Blog Single > Styles > Recommended Posts tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Pro Box.
11
+ JupiterX_Customizer::add_field( [
12
+ 'type' => 'jupiterx-pro-box',
13
+ 'settings' => 'jupiterx_post_single_related_posts_pro_box',
14
+ 'section' => 'jupiterx_blog_pages',
15
+ 'box' => 'recommended_posts',
16
+ ] );
includes/customizer/settings/blog-single/settings.php CHANGED
@@ -1,144 +1,151 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Blog Single > Settings tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_post_single_settings';
11
-
12
- // Type.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-choose',
15
- 'settings' => 'jupiterx_post_single_template_type',
16
- 'section' => $section,
17
- 'label' => __( 'Type', 'jupiterx-core' ),
18
- 'default' => '',
19
- 'choices' => [
20
- '' => [
21
- 'label' => __( 'Default', 'jupiterx-core' ),
22
- ],
23
- '_custom' => [
24
- 'label' => __( 'Custom', 'jupiterx-core' ),
25
- 'pro' => true,
26
- ],
27
- ],
28
- ] );
29
-
30
- // Type.
31
- JupiterX_Customizer::add_field( [
32
- 'type' => 'jupiterx-choose',
33
- 'settings' => 'jupiterx_post_single_template_type',
34
- 'section' => $section,
35
- 'label' => __( 'Type', 'jupiterx-core' ),
36
- 'default' => '',
37
- 'choices' => [
38
- '' => [
39
- 'label' => __( 'Default', 'jupiterx-core' ),
40
- ],
41
- '_custom' => [
42
- 'label' => __( 'Custom', 'jupiterx-core' ),
43
- 'pro' => true,
44
- ],
45
- ],
46
- ] );
47
-
48
- // Template.
49
- JupiterX_Customizer::add_field( [
50
- 'type' => 'jupiterx-radio-image',
51
- 'settings' => 'jupiterx_post_single_template',
52
- 'section' => $section,
53
- 'default' => '1',
54
- 'choices' => [
55
- '1' => 'blog-single-01',
56
- '2' => [
57
- 'name' => 'blog-single-02',
58
- 'pro' => true,
59
- 'preview' => JUPITERX_ADMIN_ASSETS_URL . '/images/blog-single-2.jpg',
60
- ],
61
- '3' => [
62
- 'name' => 'blog-single-03',
63
- 'pro' => true,
64
- 'preview' => JUPITERX_ADMIN_ASSETS_URL . '/images/blog-single-3.jpg',
65
- ],
66
- ],
67
- 'active_callback' => [
68
- [
69
- 'setting' => 'jupiterx_post_single_template_type',
70
- 'operator' => '===',
71
- 'value' => '',
72
- ],
73
- ],
74
- ] );
75
-
76
- // Pro Box.
77
- JupiterX_Customizer::add_field( [
78
- 'type' => 'jupiterx-pro-box',
79
- 'settings' => 'jupiterx_post_single_custom_pro_box',
80
- 'section' => $section,
81
- 'active_callback' => [
82
- [
83
- 'setting' => 'jupiterx_post_single_template_type',
84
- 'operator' => '===',
85
- 'value' => '_custom',
86
- ],
87
- ],
88
- ] );
89
-
90
-
91
- // Label.
92
- JupiterX_Customizer::add_field( [
93
- 'type' => 'jupiterx-label',
94
- 'settings' => 'jupiterx_post_single_label_2',
95
- 'section' => $section,
96
- 'label' => __( 'Display Elements', 'jupiterx-core' ),
97
- 'active_callback' => [
98
- [
99
- 'setting' => 'jupiterx_post_single_template_type',
100
- 'operator' => '===',
101
- 'value' => '',
102
- ],
103
- ],
104
- ] );
105
-
106
- // Display elements.
107
- JupiterX_Customizer::add_field( [
108
- 'type' => 'jupiterx-multicheck',
109
- 'settings' => 'jupiterx_post_single_elements',
110
- 'section' => $section,
111
- 'css_var' => 'post-single-elements',
112
- 'default' => [
113
- 'featured_image',
114
- 'date',
115
- 'author',
116
- 'categories',
117
- 'tags',
118
- 'social_share',
119
- 'navigation',
120
- 'author_box',
121
- 'related_posts',
122
- 'comments',
123
- ],
124
- 'choices' => [
125
- 'featured_image' => __( 'Featured Image', 'jupiterx-core' ),
126
- 'title' => __( 'Title', 'jupiterx-core' ),
127
- 'date' => __( 'Date', 'jupiterx-core' ),
128
- 'author' => __( 'Author', 'jupiterx-core' ),
129
- 'categories' => __( 'Categories', 'jupiterx-core' ),
130
- 'tags' => __( 'Tags', 'jupiterx-core' ),
131
- 'social_share' => __( 'Social Share', 'jupiterx-core' ),
132
- 'navigation' => __( 'Navigation', 'jupiterx-core' ),
133
- 'author_box' => __( 'Author Box', 'jupiterx-core' ),
134
- 'related_posts' => __( 'Recommended Posts', 'jupiterx-core' ),
135
- 'comments' => __( 'Comments', 'jupiterx-core' ),
136
- ],
137
- 'active_callback' => [
138
- [
139
- 'setting' => 'jupiterx_post_single_template_type',
140
- 'operator' => '===',
141
- 'value' => '',
142
- ],
143
- ],
144
- ] );
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Blog Single > Settings tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_blog_pages';
11
+
12
+ // Type.
13
+ JupiterX_Customizer::add_field( [
14
+ 'type' => 'jupiterx-choose',
15
+ 'settings' => 'jupiterx_post_single_template_type',
16
+ 'section' => $section,
17
+ 'box' => 'settings_single',
18
+ 'label' => __( 'Type', 'jupiterx-core' ),
19
+ 'default' => '',
20
+ 'choices' => [
21
+ '' => [
22
+ 'label' => __( 'Default', 'jupiterx-core' ),
23
+ ],
24
+ '_custom' => [
25
+ 'label' => __( 'Custom', 'jupiterx-core' ),
26
+ 'pro' => true,
27
+ ],
28
+ ],
29
+ ] );
30
+
31
+ // Type.
32
+ JupiterX_Customizer::add_field( [
33
+ 'type' => 'jupiterx-choose',
34
+ 'settings' => 'jupiterx_post_single_template_type',
35
+ 'section' => $section,
36
+ 'box' => 'settings_single',
37
+ 'label' => __( 'Type', 'jupiterx-core' ),
38
+ 'default' => '',
39
+ 'choices' => [
40
+ '' => [
41
+ 'label' => __( 'Default', 'jupiterx-core' ),
42
+ ],
43
+ '_custom' => [
44
+ 'label' => __( 'Custom', 'jupiterx-core' ),
45
+ 'pro' => true,
46
+ ],
47
+ ],
48
+ ] );
49
+
50
+ // Template.
51
+ JupiterX_Customizer::add_field( [
52
+ 'type' => 'jupiterx-radio-image',
53
+ 'settings' => 'jupiterx_post_single_template',
54
+ 'section' => $section,
55
+ 'box' => 'settings_single',
56
+ 'default' => '1',
57
+ 'choices' => [
58
+ '1' => 'blog-single-01',
59
+ '2' => [
60
+ 'name' => 'blog-single-02',
61
+ 'pro' => true,
62
+ 'preview' => JUPITERX_ADMIN_ASSETS_URL . '/images/blog-single-2.jpg',
63
+ ],
64
+ '3' => [
65
+ 'name' => 'blog-single-03',
66
+ 'pro' => true,
67
+ 'preview' => JUPITERX_ADMIN_ASSETS_URL . '/images/blog-single-3.jpg',
68
+ ],
69
+ ],
70
+ 'active_callback' => [
71
+ [
72
+ 'setting' => 'jupiterx_post_single_template_type',
73
+ 'operator' => '===',
74
+ 'value' => '',
75
+ ],
76
+ ],
77
+ ] );
78
+
79
+ // Pro Box.
80
+ JupiterX_Customizer::add_field( [
81
+ 'type' => 'jupiterx-pro-box',
82
+ 'settings' => 'jupiterx_post_single_custom_pro_box',
83
+ 'section' => $section,
84
+ 'box' => 'settings_single',
85
+ 'active_callback' => [
86
+ [
87
+ 'setting' => 'jupiterx_post_single_template_type',
88
+ 'operator' => '===',
89
+ 'value' => '_custom',
90
+ ],
91
+ ],
92
+ ] );
93
+
94
+ // Display elements.
95
+ JupiterX_Customizer::add_field( [
96
+ 'type' => 'jupiterx-multicheck',
97
+ 'settings' => 'jupiterx_post_single_elements',
98
+ 'section' => $section,
99
+ 'box' => 'settings_single',
100
+ 'label' => __( 'Display Elements', 'jupiterx-core' ),
101
+ 'css_var' => 'post-single-elements',
102
+ 'default' => [
103
+ 'featured_image',
104
+ 'date',
105
+ 'author',
106
+ 'categories',
107
+ 'tags',
108
+ 'social_share',
109
+ 'navigation',
110
+ 'author_box',
111
+ 'related_posts',
112
+ 'comments',
113
+ ],
114
+ 'choices' => [
115
+ 'featured_image' => __( 'Featured Image', 'jupiterx-core' ),
116
+ 'title' => __( 'Title', 'jupiterx-core' ),
117
+ 'date' => __( 'Date', 'jupiterx-core' ),
118
+ 'author' => __( 'Author', 'jupiterx-core' ),
119
+ 'categories' => __( 'Categories', 'jupiterx-core' ),
120
+ 'tags' => __( 'Tags', 'jupiterx-core' ),
121
+ 'social_share' => __( 'Social Share', 'jupiterx-core' ),
122
+ 'navigation' => __( 'Navigation', 'jupiterx-core' ),
123
+ 'author_box' => __( 'Author Box', 'jupiterx-core' ),
124
+ 'related_posts' => __( 'Recommended Posts', 'jupiterx-core' ),
125
+ 'comments' => __( 'Comments', 'jupiterx-core' ),
126
+ ],
127
+ 'active_callback' => [
128
+ [
129
+ 'setting' => 'jupiterx_post_single_template_type',
130
+ 'operator' => '===',
131
+ 'value' => '',
132
+ ],
133
+ ],
134
+ ] );
135
+
136
+ // Warning.
137
+ JupiterX_Customizer::add_field( [
138
+ 'type' => 'jupiterx-alert',
139
+ 'settings' => 'jupiterx_post_single_empty_notice',
140
+ 'section' => $section,
141
+ 'box' => 'empty_notice',
142
+ 'label' => __( 'There are no style settings available for custom templates.', 'jupiterx-core' ),
143
+ 'priority' => 10,
144
+ 'active_callback' => [
145
+ [
146
+ 'setting' => 'jupiterx_post_single_template_type',
147
+ 'operator' => '===',
148
+ 'value' => '_custom',
149
+ ],
150
+ ],
151
+ ] );
includes/customizer/settings/blog-single/social-share.php CHANGED
@@ -1,15 +1,16 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Blog Single > Styles > Featured Image tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Pro Box.
11
- JupiterX_Customizer::add_field( [
12
- 'type' => 'jupiterx-pro-box',
13
- 'settings' => 'jupiterx_post_single_social_share_pro_box',
14
- 'section' => 'jupiterx_post_single_social_share',
15
- ] );
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Blog Single > Styles > Featured Image tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Pro Box.
11
+ JupiterX_Customizer::add_field( [
12
+ 'type' => 'jupiterx-pro-box',
13
+ 'settings' => 'jupiterx_post_single_social_share_pro_box',
14
+ 'section' => 'jupiterx_blog_pages',
15
+ 'box' => 'social_share',
16
+ ] );
includes/customizer/settings/blog-single/tags.php CHANGED
@@ -1,219 +1,278 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Blog Single > Styles > Tags tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_post_single_tags';
11
-
12
- // Align.
13
- JupiterX_Customizer::add_responsive_field( [
14
- 'type' => 'jupiterx-choose',
15
- 'settings' => 'jupiterx_post_single_tags_align',
16
- 'section' => $section,
17
- 'css_var' => 'post-single-tags-align',
18
- 'label' => __( 'Align', 'jupiterx-core' ),
19
- 'column' => '4',
20
- 'transport' => 'postMessage',
21
- 'default' => [
22
- 'desktop' => '',
23
- 'tablet' => 'center',
24
- 'mobile' => 'center',
25
- ],
26
- 'choices' => JupiterX_Customizer_Utils::get_align(),
27
- 'output' => [
28
- [
29
- 'element' => '.single-post .jupiterx-post-tags',
30
- 'property' => 'text-align',
31
- ],
32
- ],
33
- 'active_callback' => [
34
- [
35
- 'setting' => 'jupiterx_post_single_template',
36
- 'operator' => 'contains',
37
- 'value' => [ '1', '2' ],
38
- ],
39
- ],
40
- ] );
41
-
42
- // Typography.
43
- JupiterX_Customizer::add_field( [
44
- 'type' => 'jupiterx-typography',
45
- 'settings' => 'jupiterx_post_single_tags_links_typography',
46
- 'section' => $section,
47
- 'responsive' => true,
48
- 'css_var' => 'post-single-tags-links',
49
- 'transport' => 'postMessage',
50
- 'output' => [
51
- [
52
- 'element' => '.single-post .jupiterx-post-tags .btn',
53
- ],
54
- ],
55
- ] );
56
-
57
- // Background color.
58
- JupiterX_Customizer::add_field( [
59
- 'type' => 'jupiterx-color',
60
- 'settings' => 'jupiterx_post_single_tags_links_background_color',
61
- 'section' => $section,
62
- 'css_var' => 'post-single-tags-links-background-color',
63
- 'column' => '3',
64
- 'icon' => 'background-color',
65
- 'transport' => 'postMessage',
66
- 'output' => [
67
- [
68
- 'element' => '.single-post .jupiterx-post-tags .btn',
69
- 'property' => 'background-color',
70
- ],
71
- ],
72
- ] );
73
-
74
- // Column gap.
75
- JupiterX_Customizer::add_field( [
76
- 'type' => 'jupiterx-input',
77
- 'settings' => 'jupiterx_post_single_tags_links_gap',
78
- 'section' => $section,
79
- 'css_var' => 'post-single-tags-links-gap',
80
- 'column' => '4',
81
- 'icon' => 'space-between',
82
- 'units' => [ 'px', 'em', 'rem' ],
83
- 'transport' => 'postMessage',
84
- 'output' => [
85
- [
86
- 'element' => '.single-post .jupiterx-post-tags .jupiterx-post-tags-row',
87
- 'property' => 'margin-left',
88
- 'value_pattern' => 'calc(-$ / 2)',
89
- ],
90
- [
91
- 'element' => '.single-post .jupiterx-post-tags .jupiterx-post-tags-row',
92
- 'property' => 'margin-right',
93
- 'value_pattern' => 'calc(-$ / 2)',
94
- ],
95
- [
96
- 'element' => '.single-post .jupiterx-post-tags .btn',
97
- 'property' => 'margin-left',
98
- 'value_pattern' => 'calc($ / 2)',
99
- ],
100
- [
101
- 'element' => '.single-post .jupiterx-post-tags .btn',
102
- 'property' => 'margin-right',
103
- 'value_pattern' => 'calc($ / 2)',
104
- ],
105
- ],
106
- ] );
107
-
108
- // Border.
109
- JupiterX_Customizer::add_field( [
110
- 'type' => 'jupiterx-border',
111
- 'settings' => 'jupiterx_post_single_tags_links_border',
112
- 'section' => $section,
113
- 'css_var' => 'post-single-tags-links-border',
114
- 'transport' => 'postMessage',
115
- 'exclude' => [ 'style', 'size' ],
116
- 'output' => [
117
- [
118
- 'element' => '.single-post .jupiterx-post-tags .btn',
119
- ],
120
- ],
121
- ] );
122
-
123
- // Hover label.
124
- JupiterX_Customizer::add_field( [
125
- 'type' => 'jupiterx-label',
126
- 'label' => __( 'Hover', 'jupiterx-core' ),
127
- 'label_type' => 'fancy',
128
- 'color' => 'orange',
129
- 'settings' => 'jupiterx_post_single_tags_label',
130
- 'section' => $section,
131
- ] );
132
-
133
- // Text color.
134
- JupiterX_Customizer::add_field( [
135
- 'type' => 'jupiterx-color',
136
- 'settings' => 'jupiterx_post_single_tags_links_color_hover',
137
- 'section' => $section,
138
- 'css_var' => 'post-single-tags-links-color-hover',
139
- 'column' => '3',
140
- 'icon' => 'font-color',
141
- 'transport' => 'postMessage',
142
- 'output' => [
143
- [
144
- 'element' => '.single-post .jupiterx-post-tags .btn:hover',
145
- 'property' => 'color',
146
- ],
147
- ],
148
- ] );
149
-
150
- // Background color.
151
- JupiterX_Customizer::add_field( [
152
- 'type' => 'jupiterx-color',
153
- 'settings' => 'jupiterx_post_single_tags_links_background_color_hover',
154
- 'section' => $section,
155
- 'css_var' => 'post-single-tags-links-background-color-hover',
156
- 'column' => '3',
157
- 'icon' => 'background-color',
158
- 'transport' => 'postMessage',
159
- 'output' => [
160
- [
161
- 'element' => '.single-post .jupiterx-post-tags .btn:hover',
162
- 'property' => 'background-color',
163
- ],
164
- ],
165
- ] );
166
-
167
- // Border color.
168
- JupiterX_Customizer::add_field( [
169
- 'type' => 'jupiterx-color',
170
- 'settings' => 'jupiterx_post_single_tags_links_border_color_hover',
171
- 'section' => $section,
172
- 'css_var' => 'post-single-tags-links-border-color-hover',
173
- 'column' => '3',
174
- 'icon' => 'border-color',
175
- 'transport' => 'postMessage',
176
- 'output' => [
177
- [
178
- 'element' => '.single-post .jupiterx-post-tags .btn:hover',
179
- 'property' => 'border-color',
180
- ],
181
- ],
182
- ] );
183
-
184
- // Divider.
185
- JupiterX_Customizer::add_field( [
186
- 'type' => 'jupiterx-divider',
187
- 'settings' => 'jupiterx_post_single_tags_divider_2',
188
- 'section' => $section,
189
- ] );
190
-
191
- // Padding.
192
- JupiterX_Customizer::add_responsive_field( [
193
- 'type' => 'jupiterx-box-model',
194
- 'settings' => 'jupiterx_post_single_tags_links_spacing',
195
- 'section' => $section,
196
- 'css_var' => 'post-single-tags-links',
197
- 'transport' => 'postMessage',
198
- 'exclude' => [ 'margin' ],
199
- 'output' => [
200
- [
201
- 'element' => '.single-post .jupiterx-post-tags .btn',
202
- ],
203
- ],
204
- ] );
205
-
206
- // Margin.
207
- JupiterX_Customizer::add_responsive_field( [
208
- 'type' => 'jupiterx-box-model',
209
- 'settings' => 'jupiterx_post_single_tags_spacing',
210
- 'section' => $section,
211
- 'css_var' => 'post-single-tags',
212
- 'transport' => 'postMessage',
213
- 'exclude' => [ 'padding' ],
214
- 'output' => [
215
- [
216
- 'element' => '.single-post .jupiterx-post-tags',
217
- ],
218
- ],
219
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Blog Single > Styles > Tags tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_blog_pages';
11
+
12
+ $tags_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_post_single_template_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ [
19
+ 'setting' => 'jupiterx_post_single_elements',
20
+ 'operator' => 'contains',
21
+ 'value' => 'tags',
22
+ ],
23
+ ];
24
+
25
+ $tags_templates_1_2_condition = [
26
+ [
27
+ 'setting' => 'jupiterx_post_single_template',
28
+ 'operator' => 'contains',
29
+ 'value' => [ '1', '2' ],
30
+ ],
31
+ ];
32
+
33
+ $tags_choose_normal_condition = [
34
+ [
35
+ 'setting' => 'jupiterx_post_single_tags_label',
36
+ 'operator' => '===',
37
+ 'value' => 'normal',
38
+ ],
39
+ ];
40
+
41
+ $tags_choose_hover_condition = [
42
+ [
43
+ 'setting' => 'jupiterx_post_single_tags_label',
44
+ 'operator' => '===',
45
+ 'value' => 'hover',
46
+ ],
47
+ ];
48
+
49
+ $tags_templates_1_2_condition = array_merge( $tags_condition, $tags_templates_1_2_condition );
50
+ $tags_choose_normal_condition = array_merge( $tags_condition, $tags_choose_normal_condition );
51
+ $tags_choose_hover_condition = array_merge( $tags_condition, $tags_choose_hover_condition );
52
+
53
+ // Align.
54
+ JupiterX_Customizer::add_responsive_field( [
55
+ 'type' => 'jupiterx-choose',
56
+ 'settings' => 'jupiterx_post_single_tags_align',
57
+ 'section' => $section,
58
+ 'box' => 'tags',
59
+ 'css_var' => 'post-single-tags-align',
60
+ 'label' => __( 'Alignment', 'jupiterx-core' ),
61
+ 'inline' => true,
62
+ 'transport' => 'postMessage',
63
+ 'default' => [
64
+ 'desktop' => '',
65
+ 'tablet' => 'center',
66
+ 'mobile' => 'center',
67
+ ],
68
+ 'choices' => JupiterX_Customizer_Utils::get_align(),
69
+ 'output' => [
70
+ [
71
+ 'element' => '.single-post .jupiterx-post-tags',
72
+ 'property' => 'text-align',
73
+ ],
74
+ ],
75
+ 'active_callback' => $meta_templates_1_2_condition,
76
+ ] );
77
+
78
+ // Typography.
79
+ JupiterX_Customizer::add_field( [
80
+ 'type' => 'jupiterx-typography',
81
+ 'settings' => 'jupiterx_post_single_tags_links_typography',
82
+ 'section' => $section,
83
+ 'box' => 'tags',
84
+ 'responsive' => true,
85
+ 'css_var' => 'post-single-tags-links',
86
+ 'transport' => 'postMessage',
87
+ 'output' => [
88
+ [
89
+ 'element' => '.single-post .jupiterx-post-tags .btn',
90
+ ],
91
+ ],
92
+ 'active_callback' => $tags_condition,
93
+ ] );
94
+
95
+ // Column gap.
96
+ JupiterX_Customizer::add_field( [
97
+ 'type' => 'jupiterx-input',
98
+ 'settings' => 'jupiterx_post_single_tags_links_gap',
99
+ 'section' => $section,
100
+ 'box' => 'tags',
101
+ 'css_var' => 'post-single-tags-links-gap',
102
+ 'label' => __( 'Space Between', 'jupiterx-core' ),
103
+ 'units' => [ 'px', 'em', 'rem' ],
104
+ 'transport' => 'postMessage',
105
+ 'output' => [
106
+ [
107
+ 'element' => '.single-post .jupiterx-post-tags .jupiterx-post-tags-row',
108
+ 'property' => 'margin-left',
109
+ 'value_pattern' => 'calc(-$ / 2)',
110
+ ],
111
+ [
112
+ 'element' => '.single-post .jupiterx-post-tags .jupiterx-post-tags-row',
113
+ 'property' => 'margin-right',
114
+ 'value_pattern' => 'calc(-$ / 2)',
115
+ ],
116
+ [
117
+ 'element' => '.single-post .jupiterx-post-tags .btn',
118
+ 'property' => 'margin-left',
119
+ 'value_pattern' => 'calc($ / 2)',
120
+ ],
121
+ [
122
+ 'element' => '.single-post .jupiterx-post-tags .btn',
123
+ 'property' => 'margin-right',
124
+ 'value_pattern' => 'calc($ / 2)',
125
+ ],
126
+ ],
127
+ 'active_callback' => $tags_condition,
128
+ ] );
129
+
130
+ // Hover label.
131
+ JupiterX_Customizer::add_field( [
132
+ 'type' => 'jupiterx-choose',
133
+ 'settings' => 'jupiterx_post_single_tags_label',
134
+ 'section' => $section,
135
+ 'transport' => 'postMessage',
136
+ 'box' => 'tags',
137
+ 'choices' => [
138
+ 'normal' => [
139
+ 'label' => __( 'Normal', 'jupiterx-core' ),
140
+ ],
141
+ 'hover' => [
142
+ 'label' => __( 'Hover', 'jupiterx-core' ),
143
+ ],
144
+ ],
145
+ 'active_callback' => $tags_condition,
146
+ ] );
147
+
148
+ // Background color.
149
+ JupiterX_Customizer::add_field( [
150
+ 'type' => 'jupiterx-color',
151
+ 'settings' => 'jupiterx_post_single_tags_links_background_color',
152
+ 'section' => $section,
153
+ 'box' => 'tags',
154
+ 'css_var' => 'post-single-tags-links-background-color',
155
+ 'label' => __( 'Background Color', 'jupiterx-core' ),
156
+ 'transport' => 'postMessage',
157
+ 'output' => [
158
+ [
159
+ 'element' => '.single-post .jupiterx-post-tags .btn',
160
+ 'property' => 'background-color',
161
+ ],
162
+ ],
163
+ 'active_callback' => $tags_choose_normal_condition,
164
+ ] );
165
+
166
+ // Border.
167
+ JupiterX_Customizer::add_field( [
168
+ 'type' => 'jupiterx-border',
169
+ 'settings' => 'jupiterx_post_single_tags_links_border',
170
+ 'section' => $section,
171
+ 'box' => 'tags',
172
+ 'css_var' => 'post-single-tags-links-border',
173
+ 'transport' => 'postMessage',
174
+ 'exclude' => [ 'style', 'size' ],
175
+ 'output' => [
176
+ [
177
+ 'element' => '.single-post .jupiterx-post-tags .btn',
178
+ ],
179
+ ],
180
+ 'active_callback' => $tags_choose_normal_condition,
181
+ ] );
182
+
183
+ // Text color.
184
+ JupiterX_Customizer::add_field( [
185
+ 'type' => 'jupiterx-color',
186
+ 'settings' => 'jupiterx_post_single_tags_links_color_hover',
187
+ 'section' => $section,
188
+ 'box' => 'tags',
189
+ 'css_var' => 'post-single-tags-links-color-hover',
190
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
191
+ 'transport' => 'postMessage',
192
+ 'output' => [
193
+ [
194
+ 'element' => '.single-post .jupiterx-post-tags .btn:hover',
195
+ 'property' => 'color',
196
+ ],
197
+ ],
198
+ 'active_callback' => $tags_choose_hover_condition,
199
+ ] );
200
+
201
+ // Background color.
202
+ JupiterX_Customizer::add_field( [
203
+ 'type' => 'jupiterx-color',
204
+ 'settings' => 'jupiterx_post_single_tags_links_background_color_hover',
205
+ 'section' => $section,
206
+ 'css_var' => 'post-single-tags-links-background-color-hover',
207
+ 'box' => 'tags',
208
+ 'label' => __( 'Background Color', 'jupiterx-core' ),
209
+ 'transport' => 'postMessage',
210
+ 'output' => [
211
+ [
212
+ 'element' => '.single-post .jupiterx-post-tags .btn:hover',
213
+ 'property' => 'background-color',
214
+ ],
215
+ ],
216
+ 'active_callback' => $tags_choose_hover_condition,
217
+ ] );
218
+
219
+ // Border color.
220
+ JupiterX_Customizer::add_field( [
221
+ 'type' => 'jupiterx-color',
222
+ 'settings' => 'jupiterx_post_single_tags_links_border_color_hover',
223
+ 'section' => $section,
224
+ 'box' => 'tags',
225
+ 'css_var' => 'post-single-tags-links-border-color-hover',
226
+ 'label' => __( 'Border Color', 'jupiterx-core' ),
227
+ 'transport' => 'postMessage',
228
+ 'output' => [
229
+ [
230
+ 'element' => '.single-post .jupiterx-post-tags .btn:hover',
231
+ 'property' => 'border-color',
232
+ ],
233
+ ],
234
+ 'active_callback' => $tags_choose_hover_condition,
235
+ ] );
236
+
237
+ // Divider.
238
+ JupiterX_Customizer::add_field( [
239
+ 'type' => 'jupiterx-divider',
240
+ 'settings' => 'jupiterx_post_single_tags_divider_2',
241
+ 'section' => $section,
242
+ 'box' => 'tags',
243
+ 'active_callback' => $tags_condition,
244
+ ] );
245
+
246
+ // Padding.
247
+ JupiterX_Customizer::add_responsive_field( [
248
+ 'type' => 'jupiterx-box-model',
249
+ 'settings' => 'jupiterx_post_single_tags_links_spacing',
250
+ 'section' => $section,
251
+ 'box' => 'tags',
252
+ 'css_var' => 'post-single-tags-links',
253
+ 'transport' => 'postMessage',
254
+ 'exclude' => [ 'margin' ],
255
+ 'output' => [
256
+ [
257
+ 'element' => '.single-post .jupiterx-post-tags .btn',
258
+ ],
259
+ ],
260
+ 'active_callback' => $tags_condition,
261
+ ] );
262
+
263
+ // Margin.
264
+ JupiterX_Customizer::add_responsive_field( [
265
+ 'type' => 'jupiterx-box-model',
266
+ 'settings' => 'jupiterx_post_single_tags_spacing',
267
+ 'section' => $section,
268
+ 'box' => 'tags',
269
+ 'css_var' => 'post-single-tags',
270
+ 'transport' => 'postMessage',
271
+ 'exclude' => [ 'padding' ],
272
+ 'output' => [
273
+ [
274
+ 'element' => '.single-post .jupiterx-post-tags',
275
+ ],
276
+ ],
277
+ 'active_callback' => $tags_condition,
278
+ ] );
includes/customizer/settings/blog-single/title.php CHANGED
@@ -1,66 +1,87 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Blog Single > Styles > Title tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_post_single_title';
11
-
12
- // Align.
13
- JupiterX_Customizer::add_responsive_field( [
14
- 'type' => 'jupiterx-choose',
15
- 'settings' => "{$section}_align",
16
- 'section' => $section,
17
- 'css_var' => 'post-single-title-align',
18
- 'label' => __( 'Align', 'jupiterx-core' ),
19
- 'column' => '4',
20
- 'transport' => 'postMessage',
21
- 'choices' => JupiterX_Customizer_Utils::get_align(),
22
- 'output' => [
23
- [
24
- 'element' => '.single-post .jupiterx-post-title',
25
- 'property' => 'text-align',
26
- ],
27
- ],
28
- ] );
29
-
30
- // Typography.
31
- JupiterX_Customizer::add_field( [
32
- 'type' => 'jupiterx-typography',
33
- 'settings' => "{$section}_typography",
34
- 'section' => $section,
35
- 'responsive' => true,
36
- 'css_var' => 'post-single-title',
37
- 'transport' => 'postMessage',
38
- 'exclude' => [ 'text_transform' ],
39
- 'output' => [
40
- [
41
- 'element' => '.single-post .jupiterx-post-title',
42
- ],
43
- ],
44
- ] );
45
-
46
- // Divider.
47
- JupiterX_Customizer::add_field( [
48
- 'type' => 'jupiterx-divider',
49
- 'settings' => "{$section}_divider",
50
- 'section' => $section,
51
- ] );
52
-
53
- // Spacing.
54
- JupiterX_Customizer::add_responsive_field( [
55
- 'type' => 'jupiterx-box-model',
56
- 'settings' => "{$section}_spacing",
57
- 'section' => $section,
58
- 'css_var' => 'post-single-title',
59
- 'transport' => 'postMessage',
60
- 'exclude' => [ 'padding' ],
61
- 'output' => [
62
- [
63
- 'element' => '.single-post .jupiterx-post-title',
64
- ],
65
- ],
66
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Blog Single > Styles > Title tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_blog_pages';
11
+
12
+ $title_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_post_single_template_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ [
19
+ 'setting' => 'jupiterx_post_single_elements',
20
+ 'operator' => 'contains',
21
+ 'value' => 'title',
22
+ ],
23
+ ];
24
+
25
+ // Align.
26
+ JupiterX_Customizer::add_responsive_field( [
27
+ 'type' => 'jupiterx-choose',
28
+ 'settings' => "{$section}_title_align",
29
+ 'section' => $section,
30
+ 'box' => 'title',
31
+ 'css_var' => 'post-single-title-align',
32
+ 'label' => __( 'Alignment', 'jupiterx-core' ),
33
+ 'inline' => true,
34
+ 'transport' => 'postMessage',
35
+ 'choices' => JupiterX_Customizer_Utils::get_align(),
36
+ 'output' => [
37
+ [
38
+ 'element' => '.single-post .jupiterx-post-title',
39
+ 'property' => 'text-align',
40
+ ],
41
+ ],
42
+ 'active_callback' => $title_condition,
43
+ ] );
44
+
45
+ // Typography.
46
+ JupiterX_Customizer::add_field( [
47
+ 'type' => 'jupiterx-typography',
48
+ 'settings' => "{$section}_title_typography",
49
+ 'section' => $section,
50
+ 'box' => 'title',
51
+ 'responsive' => true,
52
+ 'css_var' => 'post-single-title',
53
+ 'transport' => 'postMessage',
54
+ 'exclude' => [ 'text_transform' ],
55
+ 'output' => [
56
+ [
57
+ 'element' => '.single-post .jupiterx-post-title',
58
+ ],
59
+ ],
60
+ 'active_callback' => $title_condition,
61
+ ] );
62
+
63
+ // Divider.
64
+ JupiterX_Customizer::add_field( [
65
+ 'type' => 'jupiterx-divider',
66
+ 'settings' => "{$section}_title_divider",
67
+ 'section' => $section,
68
+ 'box' => 'title',
69
+ 'active_callback' => $title_condition,
70
+ ] );
71
+
72
+ // Spacing.
73
+ JupiterX_Customizer::add_responsive_field( [
74
+ 'type' => 'jupiterx-box-model',
75
+ 'settings' => "{$section}_title_spacing",
76
+ 'section' => $section,
77
+ 'box' => 'title',
78
+ 'css_var' => 'post-single-title',
79
+ 'transport' => 'postMessage',
80
+ 'exclude' => [ 'padding' ],
81
+ 'output' => [
82
+ [
83
+ 'element' => '.single-post .jupiterx-post-title',
84
+ ],
85
+ ],
86
+ 'active_callback' => $title_condition,
87
+ ] );
includes/customizer/settings/cart-quick-view/popup.php CHANGED
@@ -1,48 +1,44 @@
1
- <?php
2
- /**
3
- * Add Jupiter elements popup and tabs to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Elements popup.
11
- JupiterX_Customizer::add_section( 'jupiterx_cart_quick_view', [
12
- 'panel' => 'jupiterx_shop_panel',
13
- 'title' => __( 'Cart Quick View', 'jupiterx-core' ),
14
- 'type' => 'popup',
15
- 'tabs' => [
16
- 'settings' => __( 'Settings', 'jupiterx-core' ),
17
- 'styles' => __( 'Styles', 'jupiterx-core' ),
18
- ],
19
- 'help' => [
20
- 'url' => 'https://themes.artbees.net/docs/checkout-cart-pages-in-shop-customizer',
21
- 'title' => __( 'Checkout & Cart Pages in Shop Customizer', 'jupiterx-core' ),
22
- ],
23
- ] );
24
-
25
- // Setting tab.
26
- JupiterX_Customizer::add_section( 'jupiterx_cart_quick_view_styles', [
27
- 'popup' => 'jupiterx_cart_quick_view',
28
- 'type' => 'pane',
29
- 'pane' => [
30
- 'type' => 'tab',
31
- 'id' => 'styles',
32
- ],
33
- ] );
34
-
35
- // Styles tab.
36
- JupiterX_Customizer::add_section( 'jupiterx_cart_quick_view_settings', [
37
- 'popup' => 'jupiterx_cart_quick_view',
38
- 'type' => 'pane',
39
- 'pane' => [
40
- 'type' => 'tab',
41
- 'id' => 'settings',
42
- ],
43
- ] );
44
-
45
- // Load all the settings.
46
- foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
47
- require_once $setting;
48
- }
1
+ <?php
2
+ /**
3
+ * Add Jupiter elements popup and tabs to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Elements popup.
11
+ JupiterX_Customizer::add_section( 'jupiterx_cart_quick_view', [
12
+ 'title' => __( 'Cart Quick View', 'jupiterx-core' ),
13
+ 'type' => 'container',
14
+ 'tabs' => [
15
+ 'settings' => __( 'Settings', 'jupiterx-core' ),
16
+ 'styles' => __( 'Styles', 'jupiterx-core' ),
17
+ ],
18
+ 'boxes' => [
19
+ 'settings' => [
20
+ 'label' => __( 'Settings', 'jupiterx-core' ),
21
+ 'tab' => 'settings',
22
+ ],
23
+ 'style_cart' => [
24
+ 'label' => __( 'Styles', 'jupiterx-core' ),
25
+ 'tab' => 'styles',
26
+ ],
27
+ 'empty_notice' => [
28
+ 'label' => __( 'Notice', 'jupiterx-core' ),
29
+ 'tab' => 'styles',
30
+ ],
31
+ ],
32
+ 'help' => [
33
+ 'url' => 'https://themes.artbees.net/docs/checkout-cart-pages-in-shop-customizer',
34
+ 'title' => __( 'Checkout & Cart Pages in Shop Customizer', 'jupiterx-core' ),
35
+ ],
36
+ 'group' => 'shop',
37
+ 'icon' => 'cart-quick-view',
38
+ ] );
39
+
40
+
41
+ // Load all the settings.
42
+ foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
43
+ require_once $setting;
44
+ }
 
 
 
 
includes/customizer/settings/cart-quick-view/settings.php CHANGED
@@ -1,45 +1,62 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Product page > Settings tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section_settings = 'jupiterx_cart_quick_view_settings';
11
-
12
- // Cart quick view.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-toggle',
15
- 'settings' => 'jupiterx_header_shopping_cart',
16
- 'section' => $section_settings,
17
- 'label' => __( 'Cart Quick View', 'jupiterx-core' ),
18
- 'column' => '6',
19
- ] );
20
-
21
- // Align.
22
- JupiterX_Customizer::add_field( [
23
- 'type' => 'jupiterx-choose',
24
- 'settings' => 'jupiterx_header_shopping_cart_position',
25
- 'section' => $section_settings,
26
- 'label' => __( 'Position', 'jupiterx-core' ),
27
- 'column' => '6',
28
- 'default' => jupiterx_get_direction( 'left' ),
29
- 'choices' => [
30
- 'left' => [
31
- 'icon' => jupiterx_get_direction( 'alignment-left' ),
32
- ],
33
- 'right' => [
34
- 'icon' => jupiterx_get_direction( 'alignment-right' ),
35
- ],
36
- ],
37
- 'active_callback' => [
38
- [
39
- 'setting' => 'jupiterx_header_shopping_cart',
40
- 'operator' => '==',
41
- 'value' => true,
42
- ],
43
- ],
44
- ] );
45
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Product page > Settings tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section_settings = 'jupiterx_cart_quick_view';
11
+
12
+ // Cart quick view.
13
+ JupiterX_Customizer::add_field( [
14
+ 'type' => 'jupiterx-toggle',
15
+ 'settings' => 'jupiterx_header_shopping_cart',
16
+ 'section' => $section_settings,
17
+ 'box' => 'settings',
18
+ 'label' => __( 'Cart Quick View', 'jupiterx-core' ),
19
+ ] );
20
+
21
+ // Align.
22
+ JupiterX_Customizer::add_field( [
23
+ 'type' => 'jupiterx-choose',
24
+ 'settings' => 'jupiterx_header_shopping_cart_position',
25
+ 'section' => $section_settings,
26
+ 'box' => 'settings',
27
+ 'label' => __( 'Position', 'jupiterx-core' ),
28
+ 'inline' => true,
29
+ 'default' => jupiterx_get_direction( 'left' ),
30
+ 'choices' => [
31
+ 'left' => [
32
+ 'icon' => jupiterx_get_direction( 'alignment-left' ),
33
+ ],
34
+ 'right' => [
35
+ 'icon' => jupiterx_get_direction( 'alignment-right' ),
36
+ ],
37
+ ],
38
+ 'active_callback' => [
39
+ [
40
+ 'setting' => 'jupiterx_header_shopping_cart',
41
+ 'operator' => '==',
42
+ 'value' => true,
43
+ ],
44
+ ],
45
+ ] );
46
+
47
+ // Warning.
48
+ JupiterX_Customizer::add_field( [
49
+ 'type' => 'jupiterx-alert',
50
+ 'settings' => 'jupiterx_header_shopping_cart_empty_notice',
51
+ 'section' => $section_settings,
52
+ 'box' => 'empty_notice',
53
+ 'label' => __( 'There are no style settings available when Cart Quick View is disabled.', 'jupiterx-core' ),
54
+ 'priority' => 10,
55
+ 'active_callback' => [
56
+ [
57
+ 'setting' => 'jupiterx_header_shopping_cart',
58
+ 'operator' => '!=',
59
+ 'value' => true,
60
+ ],
61
+ ],
62
+ ] );
includes/customizer/settings/cart-quick-view/styles.php CHANGED
@@ -1,134 +1,179 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Product page > Settings tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section_styles = 'jupiterx_cart_quick_view_styles';
11
-
12
- // Icon size.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-input',
15
- 'settings' => 'jupiterx_header_shopping_cart_icon_size',
16
- 'css_var' => 'header-shopping-cart-icon-size',
17
- 'section' => $section_styles,
18
- 'column' => '4',
19
- 'icon' => 'font-size',
20
- 'units' => [ 'px', 'em', 'rem' ],
21
- 'transport' => 'postMessage',
22
- 'default' => [
23
- 'size' => 1.5,
24
- 'unit' => 'rem',
25
- ],
26
- 'output' => [
27
- [
28
- 'element' => '.jupiterx-site-navbar .jupiterx-navbar-cart-icon',
29
- 'property' => 'font-size',
30
- ],
31
- ],
32
- ] );
33
-
34
- // Icon color.
35
- JupiterX_Customizer::add_field( [
36
- 'type' => 'jupiterx-color',
37
- 'settings' => 'jupiterx_header_shopping_cart_icon_color',
38
- 'css_var' => 'header-shopping-cart-icon-color',
39
- 'section' => $section_styles,
40
- 'column' => '3',
41
- 'icon' => 'icon-color',
42
- 'transport' => 'postMessage',
43
- 'default' => '#6c757d',
44
- 'output' => [
45
- [
46
- 'element' => '.jupiterx-site-navbar .jupiterx-navbar-cart-icon',
47
- 'property' => 'color',
48
- ],
49
- ],
50
- ] );
51
-
52
- // Text color.
53
- JupiterX_Customizer::add_field( [
54
- 'type' => 'jupiterx-color',
55
- 'settings' => 'jupiterx_header_shopping_cart_text_color',
56
- 'css_var' => 'header-shopping-cart-text-color',
57
- 'section' => $section_styles,
58
- 'column' => '3',
59
- 'icon' => 'font-color',
60
- 'transport' => 'postMessage',
61
- 'default' => '#6c757d',
62
- 'output' => [
63
- [
64
- 'element' => '.jupiterx-site-navbar .jupiterx-navbar-cart',
65
- 'property' => 'color',
66
- ],
67
- ],
68
- ] );
69
-
70
- // Hover label.
71
- JupiterX_Customizer::add_field( [
72
- 'type' => 'jupiterx-label',
73
- 'label' => __( 'Hover', 'jupiterx-core' ),
74
- 'label_type' => 'fancy',
75
- 'color' => 'orange',
76
- 'settings' => 'jupiterx_header_shopping_cart_label',
77
- 'section' => $section_styles,
78
- ] );
79
-
80
- // Icon color hover.
81
- JupiterX_Customizer::add_field( [
82
- 'type' => 'jupiterx-color',
83
- 'settings' => 'jupiterx_header_shopping_cart_icon_color_hover',
84
- 'css_var' => 'header-shopping-cart-icon-color-hover',
85
- 'section' => $section_styles,
86
- 'column' => '3',
87
- 'icon' => 'icon-color',
88
- 'transport' => 'postMessage',
89
- 'output' => [
90
- [
91
- 'element' => '.jupiterx-site-navbar .jupiterx-navbar-cart:hover .jupiterx-navbar-cart-icon',
92
- 'property' => 'color',
93
- ],
94
- ],
95
- ] );
96
-
97
- // Text color hover.
98
- JupiterX_Customizer::add_field( [
99
- 'type' => 'jupiterx-color',
100
- 'settings' => 'jupiterx_header_shopping_cart_text_color_hover',
101
- 'css_var' => 'header-shopping-cart-text-color-hover',
102
- 'section' => $section_styles,
103
- 'column' => '3',
104
- 'icon' => 'font-color',
105
- 'transport' => 'postMessage',
106
- 'output' => [
107
- [
108
- 'element' => '.jupiterx-site-navbar .jupiterx-navbar-cart:hover',
109
- 'property' => 'color',
110
- ],
111
- ],
112
- ] );
113
-
114
- // Divider.
115
- JupiterX_Customizer::add_field( [
116
- 'type' => 'jupiterx-divider',
117
- 'settings' => 'jupiterx_header_shopping_cart_divider_2',
118
- 'section' => $section_styles,
119
- ] );
120
-
121
- // Spacing.
122
- JupiterX_Customizer::add_responsive_field( [
123
- 'type' => 'jupiterx-box-model',
124
- 'settings' => 'jupiterx_header_shopping_cart_spacing',
125
- 'css_var' => 'header-shopping-cart',
126
- 'section' => $section_styles,
127
- 'transport' => 'postMessage',
128
- 'exclude' => [ 'padding' ],
129
- 'output' => [
130
- [
131
- 'element' => '.jupiterx-site-navbar .jupiterx-navbar-cart',
132
- ],
133
- ],
134
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Product page > Settings tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section_styles = 'jupiterx_cart_quick_view';
11
+
12
+ $cart_quick_view_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_header_shopping_cart',
15
+ 'operator' => '==',
16
+ 'value' => true,
17
+ ],
18
+ ];
19
+
20
+ $cart_quick_view_normal_condition = [
21
+ [
22
+ 'setting' => 'jupiterx_header_shopping_cart_icon_tabs',
23
+ 'operator' => '===',
24
+ 'value' => 'normal',
25
+ ],
26
+ ];
27
+
28
+ $cart_quick_view_hover_condition = [
29
+ [
30
+ 'setting' => 'jupiterx_header_shopping_cart_icon_tabs',
31
+ 'operator' => '===',
32
+ 'value' => 'hover',
33
+ ],
34
+ ];
35
+
36
+ $cart_quick_view_normal_condition = array_merge( $cart_quick_view_condition, $cart_quick_view_normal_condition );
37
+ $cart_quick_view_hover_condition = array_merge( $cart_quick_view_condition, $cart_quick_view_hover_condition );
38
+
39
+ // Icon size.
40
+ JupiterX_Customizer::add_field( [
41
+ 'type' => 'jupiterx-input',
42
+ 'settings' => 'jupiterx_header_shopping_cart_icon_size',
43
+ 'css_var' => 'header-shopping-cart-icon-size',
44
+ 'section' => $section_styles,
45
+ 'box' => 'style_cart',
46
+ 'label' => __( 'Font Size', 'jupiterx-core' ),
47
+ 'units' => [ 'px', 'em', 'rem' ],
48
+ 'transport' => 'postMessage',
49
+ 'default' => [
50
+ 'size' => 1.5,
51
+ 'unit' => 'rem',
52
+ ],
53
+ 'output' => [
54
+ [
55
+ 'element' => '.jupiterx-site-navbar .jupiterx-navbar-cart-icon',
56
+ 'property' => 'font-size',
57
+ ],
58
+ ],
59
+ 'active_callback' => $cart_quick_view_condition,
60
+ ] );
61
+
62
+ // Hover label.
63
+ JupiterX_Customizer::add_field( [
64
+ 'type' => 'jupiterx-choose',
65
+ 'settings' => 'jupiterx_header_shopping_cart_icon_tabs',
66
+ 'section' => $section_styles,
67
+ 'box' => 'style_cart',
68
+ 'transport' => 'postMessage',
69
+ 'choices' => [
70
+ 'normal' => [
71
+ 'label' => __( 'Normal', 'jupiterx-core' ),
72
+ ],
73
+ 'hover' => [
74
+ 'label' => __( 'Hover', 'jupiterx-core' ),
75
+ ],
76
+ ],
77
+ 'default' => 'normal',
78
+ 'active_callback' => $cart_quick_view_condition,
79
+ ] );
80
+
81
+ // Icon color.
82
+ JupiterX_Customizer::add_field( [
83
+ 'type' => 'jupiterx-color',
84
+ 'settings' => 'jupiterx_header_shopping_cart_icon_color',
85
+ 'css_var' => 'header-shopping-cart-icon-color',
86
+ 'section' => $section_styles,
87
+ 'box' => 'style_cart',
88
+ 'label' => __( 'Icon Color', 'jupiterx-core' ),
89
+ 'transport' => 'postMessage',
90
+ 'default' => '#6c757d',
91
+ 'output' => [
92
+ [
93
+ 'element' => '.jupiterx-site-navbar .jupiterx-navbar-cart-icon',
94
+ 'property' => 'color',
95
+ ],
96
+ ],
97
+ 'active_callback' => $cart_quick_view_normal_condition,
98
+ ] );
99
+
100
+ // Text color.
101
+ JupiterX_Customizer::add_field( [
102
+ 'type' => 'jupiterx-color',
103
+ 'settings' => 'jupiterx_header_shopping_cart_text_color',
104
+ 'css_var' => 'header-shopping-cart-text-color',
105
+ 'section' => $section_styles,
106
+ 'box' => 'style_cart',
107
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
108
+ 'transport' => 'postMessage',
109
+ 'default' => '#6c757d',
110
+ 'output' => [
111
+ [
112
+ 'element' => '.jupiterx-site-navbar .jupiterx-navbar-cart',
113
+ 'property' => 'color',
114
+ ],
115
+ ],
116
+ 'active_callback' => $cart_quick_view_normal_condition,
117
+ ] );
118
+
119
+ // Icon color hover.
120
+ JupiterX_Customizer::add_field( [
121
+ 'type' => 'jupiterx-color',
122
+ 'settings' => 'jupiterx_header_shopping_cart_icon_color_hover',
123
+ 'css_var' => 'header-shopping-cart-icon-color-hover',
124
+ 'section' => $section_styles,
125
+ 'box' => 'style_cart',
126
+ 'label' => __( 'Icon Color', 'jupiterx-core' ),
127
+ 'transport' => 'postMessage',
128
+ 'output' => [
129
+ [
130
+ 'element' => '.jupiterx-site-navbar .jupiterx-navbar-cart:hover .jupiterx-navbar-cart-icon',
131
+ 'property' => 'color',
132
+ ],
133
+ ],
134
+ 'active_callback' => $cart_quick_view_hover_condition,
135
+ ] );
136
+
137
+ // Text color hover.
138
+ JupiterX_Customizer::add_field( [
139
+ 'type' => 'jupiterx-color',
140
+ 'settings' => 'jupiterx_header_shopping_cart_text_color_hover',
141
+ 'css_var' => 'header-shopping-cart-text-color-hover',
142
+ 'section' => $section_styles,
143
+ 'box' => 'style_cart',
144
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
145
+ 'transport' => 'postMessage',
146
+ 'output' => [
147
+ [
148
+ 'element' => '.jupiterx-site-navbar .jupiterx-navbar-cart:hover',
149
+ 'property' => 'color',
150
+ ],
151
+ ],
152
+ 'active_callback' => $cart_quick_view_hover_condition,
153
+ ] );
154
+
155
+ // Divider.
156
+ JupiterX_Customizer::add_field( [
157
+ 'type' => 'jupiterx-divider',
158
+ 'settings' => 'jupiterx_header_shopping_cart_divider_2',
159
+ 'section' => $section_styles,
160
+ 'box' => 'style_cart',
161
+ 'active_callback' => $cart_quick_view_condition,
162
+ ] );
163
+
164
+ // Spacing.
165
+ JupiterX_Customizer::add_responsive_field( [
166
+ 'type' => 'jupiterx-box-model',
167
+ 'settings' => 'jupiterx_header_shopping_cart_spacing',
168
+ 'css_var' => 'header-shopping-cart',
169
+ 'section' => $section_styles,
170
+ 'box' => 'style_cart',
171
+ 'transport' => 'postMessage',
172
+ 'exclude' => [ 'padding' ],
173
+ 'output' => [
174
+ [
175
+ 'element' => '.jupiterx-site-navbar .jupiterx-navbar-cart',
176
+ ],
177
+ ],
178
+ 'active_callback' => $cart_quick_view_condition,
179
+ ] );
includes/customizer/settings/checkout-cart/popup.php CHANGED
@@ -1,57 +1,90 @@
1
- <?php
2
- /**
3
- * Add Jupiter elements popup and tabs to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- // Elements popup.
11
- JupiterX_Customizer::add_section( 'jupiterx_checkout_cart', [
12
- 'panel' => 'jupiterx_shop_panel',
13
- 'title' => __( 'Checkout & Cart', 'jupiterx-core' ),
14
- 'type' => 'popup',
15
- 'tabs' => [
16
- 'settings' => __( 'Settings', 'jupiterx-core' ),
17
- 'styles' => __( 'Styles', 'jupiterx-core' ),
18
- ],
19
- 'preview' => true,
20
- 'pro' => true,
21
- 'help' => [
22
- 'url' => 'https://themes.artbees.net/docs/checkout-cart-pages-in-shop-customizer',
23
- 'title' => __( 'Checkout & Cart Pages in Shop Customizer', 'jupiterx-core' ),
24
- ],
25
- ] );
26
-
27
- // Styles tab.
28
- JupiterX_Customizer::add_section( 'jupiterx_checkout_cart_styles', [
29
- 'popup' => 'jupiterx_checkout_cart',
30
- 'type' => 'pane',
31
- 'pane' => [
32
- 'type' => 'tab',
33
- 'id' => 'styles',
34
- ],
35
- ] );
36
-
37
- // Settings tab.
38
- JupiterX_Customizer::add_section( 'jupiterx_checkout_cart_settings', [
39
- 'popup' => 'jupiterx_checkout_cart',
40
- 'type' => 'pane',
41
- 'pane' => [
42
- 'type' => 'tab',
43
- 'id' => 'settings',
44
- ],
45
- ] );
46
-
47
- // Pro Box.
48
- JupiterX_Customizer::add_field( [
49
- 'type' => 'jupiterx-pro-box',
50
- 'settings' => 'jupiterx_checkout_cart_styles_pro_box',
51
- 'section' => 'jupiterx_checkout_cart_styles',
52
- ] );
53
-
54
- // Load all the settings.
55
- foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
56
- require_once $setting;
57
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter elements popup and tabs to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ // Elements popup.
11
+ JupiterX_Customizer::add_section( 'jupiterx_checkout_cart', [
12
+ 'title' => __( 'Checkout & Cart', 'jupiterx-core' ),
13
+ 'type' => 'container',
14
+ 'tabs' => [
15
+ 'settings' => __( 'Settings', 'jupiterx-core' ),
16
+ 'styles' => __( 'Styles', 'jupiterx-core' ),
17
+ ],
18
+ 'boxes' => [
19
+ 'settings' => [
20
+ 'label' => __( 'Settings', 'jupiterx-core' ),
21
+ 'tab' => 'settings',
22
+ ],
23
+ 'steps' => [
24
+ 'label' => __( 'Steps', 'jupiterx-core' ),
25
+ 'tab' => 'styles',
26
+ ],
27
+ 'boxes' => [
28
+ 'label' => __( 'Boxes', 'jupiterx-core' ),
29
+ 'tab' => 'styles',
30
+ ],
31
+ 'heading' => [
32
+ 'label' => __( 'Heading', 'jupiterx-core' ),
33
+ 'tab' => 'styles',
34
+ ],
35
+ 'field_label' => [
36
+ 'label' => __( 'Field Label', 'jupiterx-core' ),
37
+ 'tab' => 'styles',
38
+ ],
39
+ 'field' => [
40
+ 'label' => __( 'Field', 'jupiterx-core' ),
41
+ 'tab' => 'styles',
42
+ ],
43
+ 'button' => [
44
+ 'label' => __( 'Button', 'jupiterx-core' ),
45
+ 'tab' => 'styles',
46
+ ],
47
+ 'back_button' => [
48
+ 'label' => __( 'Back Button', 'jupiterx-core' ),
49
+ 'tab' => 'styles',
50
+ ],
51
+ 'body_text' => [
52
+ 'label' => __( 'Body Text', 'jupiterx-core' ),
53
+ 'tab' => 'styles',
54
+ ],
55
+ 'remove_icon' => [
56
+ 'label' => __( 'Remove Icon', 'jupiterx-core' ),
57
+ 'tab' => 'styles',
58
+ ],
59
+ 'thumbnail' => [
60
+ 'label' => __( 'Thumbnail', 'jupiterx-core' ),
61
+ 'tab' => 'styles',
62
+ ],
63
+ 'table' => [
64
+ 'label' => __( 'Table', 'jupiterx-core' ),
65
+ 'tab' => 'styles',
66
+ ],
67
+ ],
68
+ 'preview' => true,
69
+ 'pro' => true,
70
+ 'help' => [
71
+ 'url' => 'https://themes.artbees.net/docs/checkout-cart-pages-in-shop-customizer',
72
+ 'title' => __( 'Checkout & Cart Pages in Shop Customizer', 'jupiterx-core' ),
73
+ ],
74
+ 'group' => 'shop',
75
+ 'icon' => 'checkout-cart',
76
+ 'front_icon' => true,
77
+ ] );
78
+
79
+ // Pro Box.
80
+ JupiterX_Customizer::add_field( [
81
+ 'type' => 'jupiterx-pro-box',
82
+ 'settings' => 'jupiterx_checkout_cart_styles_pro_box',
83
+ 'section' => 'jupiterx_checkout_cart',
84
+ 'box' => 'steps',
85
+ ] );
86
+
87
+ // Load all the settings.
88
+ foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
89
+ require_once $setting;
90
+ }
includes/customizer/settings/checkout-cart/settings.php CHANGED
@@ -1,27 +1,28 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Element > Comment > Settings tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- $section = 'jupiterx_checkout_cart_settings';
11
-
12
- // Display elements.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-multicheck',
15
- 'settings' => 'jupiterx_jupiterx_checkout_cart_elements',
16
- 'section' => $section,
17
- 'label' => __( 'Display Elements', 'jupiterx-core' ),
18
- 'css_var' => 'checkout-cart-elements',
19
- 'default' => [
20
- 'steps',
21
- ],
22
- 'choices' => [
23
- 'steps' => __( 'Steps', 'jupiterx-core' ),
24
- ],
25
- ] );
26
-
27
-
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Element > Comment > Settings tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ $section = 'jupiterx_checkout_cart';
11
+
12
+ // Display elements.
13
+ JupiterX_Customizer::add_field( [
14
+ 'type' => 'jupiterx-multicheck',
15
+ 'settings' => 'jupiterx_jupiterx_checkout_cart_elements',
16
+ 'section' => $section,
17
+ 'box' => 'settings',
18
+ 'label' => __( 'Display Elements', 'jupiterx-core' ),
19
+ 'css_var' => 'checkout-cart-elements',
20
+ 'default' => [
21
+ 'steps',
22
+ ],
23
+ 'choices' => [
24
+ 'steps' => __( 'Steps', 'jupiterx-core' ),
25
+ ],
26
+ ] );
27
+
28
+
includes/customizer/settings/comment/action-link.php CHANGED
@@ -1,93 +1,129 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Elementor > Comment > Styles > Action Link tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- $section = 'jupiterx_comment_action_link';
11
-
12
- // Color.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-color',
15
- 'settings' => 'jupiterx_comment_action_link_color',
16
- 'section' => $section,
17
- 'css_var' => 'comment-action-link-color',
18
- 'column' => '3',
19
- 'icon' => 'font-color',
20
- 'transport' => 'postMessage',
21
- 'output' => [
22
- [
23
- 'element' => '.jupiterx-comments .jupiterx-comment-links a, .jupiterx-comments .logged-in-as a, .comment-respond a',
24
- 'property' => 'color',
25
- ],
26
- ],
27
- ] );
28
-
29
- // Text decoration.
30
- JupiterX_Customizer::add_field( [
31
- 'type' => 'jupiterx-select',
32
- 'settings' => 'jupiterx_comment_action_link_text_decoration',
33
- 'section' => $section,
34
- 'css_var' => 'comment-action-link-decoration',
35
- 'column' => '6',
36
- 'icon' => 'text-decoration',
37
- 'default' => 'none',
38
- 'choices' => JupiterX_Customizer_Utils::get_text_decoration_choices(),
39
- 'transport' => 'postMessage',
40
- 'output' => [
41
- [
42
- 'element' => '.jupiterx-comments .jupiterx-comment-links a, .jupiterx-comments .logged-in-as a, .comment-respond a',
43
- 'property' => 'text-decoration',
44
- ],
45
- ],
46
- ] );
47
-
48
- // Hover label.
49
- JupiterX_Customizer::add_field( [
50
- 'type' => 'jupiterx-label',
51
- 'settings' => 'jupiterx_comment_action_link_label_hover',
52
- 'section' => $section,
53
- 'label' => __( 'Hover', 'jupiterx-core' ),
54
- 'label_type' => 'fancy',
55
- 'color' => 'orange',
56
- ] );
57
-
58
- // Hover color.
59
- JupiterX_Customizer::add_field( [
60
- 'type' => 'jupiterx-color',
61
- 'settings' => 'jupiterx_comment_action_link_color_hover',
62
- 'section' => $section,
63
- 'css_var' => 'comment-action-link-hover-color',
64
- 'column' => '3',
65
- 'icon' => 'font-color',
66
- 'transport' => 'postMessage',
67
- 'output' => [
68
- [
69
- 'element' => '.jupiterx-comments .jupiterx-comment-links a:hover, .jupiterx-comments .logged-in-as a:hover, .comment-respond a:hover',
70
- 'property' => 'color',
71
- ],
72
- ],
73
- ] );
74
-
75
- // Hover text decoration.
76
- JupiterX_Customizer::add_field( [
77
- 'type' => 'jupiterx-select',
78
- 'settings' => 'jupiterx_comment_action_link_text_decoration_hover',
79
- 'section' => $section,
80
- 'css_var' => 'comment-action-link-hover-decoration',
81
- 'column' => '6',
82
- 'icon' => 'text-decoration',
83
- 'default' => 'underline',
84
- 'choices' => JupiterX_Customizer_Utils::get_text_decoration_choices(),
85
- 'transport' => 'postMessage',
86
- 'output' => [
87
- [
88
- 'element' => '.jupiterx-comments .jupiterx-comment-links a:hover, .jupiterx-comments .logged-in-as a:hover, .comment-respond a:hover',
89
- 'property' => 'text-decoration',
90
- ],
91
- ],
92
- ] );
93
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Elementor > Comment > Styles > Action Link tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ $section = 'jupiterx_comment';
11
+
12
+ // Tabs.
13
+ JupiterX_Customizer::add_field( [
14
+ 'type' => 'jupiterx-choose',
15
+ 'settings' => 'jupiterx_comment_action_link_tabs',
16
+ 'section' => $section,
17
+ 'transport' => 'postMessage',
18
+ 'box' => 'action_link',
19
+ 'choices' => [
20
+ 'normal' => [
21
+ 'label' => __( 'Normal', 'jupiterx-core' ),
22
+ ],
23
+ 'hover' => [
24
+ 'label' => __( 'Hover', 'jupiterx-core' ),
25
+ ],
26
+ ],
27
+ 'default' => 'normal',
28
+ ] );
29
+
30
+ // Color.
31
+ JupiterX_Customizer::add_field( [
32
+ 'type' => 'jupiterx-color',
33
+ 'settings' => 'jupiterx_comment_action_link_color',
34
+ 'section' => $section,
35
+ 'box' => 'action_link',
36
+ 'css_var' => 'comment-action-link-color',
37
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
38
+ 'transport' => 'postMessage',
39
+ 'output' => [
40
+ [
41
+ 'element' => '.jupiterx-comments .jupiterx-comment-links a, .jupiterx-comments .logged-in-as a, .comment-respond a',
42
+ 'property' => 'color',
43
+ ],
44
+ ],
45
+ 'active_callback' => [
46
+ [
47
+ 'setting' => 'jupiterx_comment_action_link_tabs',
48
+ 'operator' => '===',
49
+ 'value' => 'normal',
50
+ ],
51
+ ],
52
+ ] );
53
+
54
+ // Text decoration.
55
+ JupiterX_Customizer::add_field( [
56
+ 'type' => 'jupiterx-select',
57
+ 'settings' => 'jupiterx_comment_action_link_text_decoration',
58
+ 'section' => $section,
59
+ 'box' => 'action_link',
60
+ 'css_var' => 'comment-action-link-decoration',
61
+ 'label' => __( 'Text Decortion', 'jupiterx-core' ),
62
+ 'default' => 'none',
63
+ 'choices' => JupiterX_Customizer_Utils::get_text_decoration_choices(),
64
+ 'transport' => 'postMessage',
65
+ 'output' => [
66
+ [
67
+ 'element' => '.jupiterx-comments .jupiterx-comment-links a, .jupiterx-comments .logged-in-as a, .comment-respond a',
68
+ 'property' => 'text-decoration',
69
+ ],
70
+ ],
71
+ 'active_callback' => [
72
+ [
73
+ 'setting' => 'jupiterx_comment_action_link_tabs',
74
+ 'operator' => '===',
75
+ 'value' => 'normal',
76
+ ],
77
+ ],
78
+ ] );
79
+
80
+ // Hover color.
81
+ JupiterX_Customizer::add_field( [
82
+ 'type' => 'jupiterx-color',
83
+ 'settings' => 'jupiterx_comment_action_link_color_hover',
84
+ 'section' => $section,
85
+ 'box' => 'action_link',
86
+ 'css_var' => 'comment-action-link-hover-color',
87
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
88
+ 'transport' => 'postMessage',
89
+ 'output' => [
90
+ [
91
+ 'element' => '.jupiterx-comments .jupiterx-comment-links a:hover, .jupiterx-comments .logged-in-as a:hover, .comment-respond a:hover',
92
+ 'property' => 'color',
93
+ ],
94
+ ],
95
+ 'active_callback' => [
96
+ [
97
+ 'setting' => 'jupiterx_comment_action_link_tabs',
98
+ 'operator' => '===',
99
+ 'value' => 'hover',
100
+ ],
101
+ ],
102
+ ] );
103
+
104
+ // Hover text decoration.
105
+ JupiterX_Customizer::add_field( [
106
+ 'type' => 'jupiterx-select',
107
+ 'settings' => 'jupiterx_comment_action_link_text_decoration_hover',
108
+ 'section' => $section,
109
+ 'box' => 'action_link',
110
+ 'css_var' => 'comment-action-link-hover-decoration',
111
+ 'label' => __( 'Text Decoration', 'jupiterx-core' ),
112
+ 'default' => 'underline',
113
+ 'choices' => JupiterX_Customizer_Utils::get_text_decoration_choices(),
114
+ 'transport' => 'postMessage',
115
+ 'output' => [
116
+ [
117
+ 'element' => '.jupiterx-comments .jupiterx-comment-links a:hover, .jupiterx-comments .logged-in-as a:hover, .comment-respond a:hover',
118
+ 'property' => 'text-decoration',
119
+ ],
120
+ ],
121
+ 'active_callback' => [
122
+ [
123
+ 'setting' => 'jupiterx_comment_action_link_tabs',
124
+ 'operator' => '===',
125
+ 'value' => 'hover',
126
+ ],
127
+ ],
128
+ ] );
129
+
includes/customizer/settings/comment/avatar.php CHANGED
@@ -1,54 +1,68 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Elementor > Comment > Styles > Avatar tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- $section = 'jupiterx_comment_avatar';
11
-
12
- // Avatar Border.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-border',
15
- 'settings' => 'jupiterx_comment_avatar_border',
16
- 'section' => $section,
17
- 'css_var' => 'comment-avatar-border',
18
- 'transport' => 'postMessage',
19
- 'exclude' => [ 'style', 'size' ],
20
- 'default' => [
21
- 'width' => [
22
- 'size' => '0',
23
- 'unit' => 'px',
24
- ],
25
- ],
26
- 'output' => [
27
- [
28
- 'element' => '.jupiterx-comments .jupiterx-comment-avatar .avatar',
29
- ],
30
- ],
31
- ] );
32
-
33
- // Divider.
34
- JupiterX_Customizer::add_field( [
35
- 'type' => 'jupiterx-divider',
36
- 'settings' => 'jupiterx_comment_avatar_divider',
37
- 'section' => $section,
38
- ] );
39
-
40
- // Spacing.
41
- JupiterX_Customizer::add_responsive_field( [
42
- 'type' => 'jupiterx-box-model',
43
- 'settings' => 'jupiterx_comment_avatar_spacing',
44
- 'section' => $section,
45
- 'css_var' => 'comment-avatar-spacing',
46
- 'transport' => 'postMessage',
47
- 'exclude' => [ 'padding' ],
48
- 'output' => [
49
- [
50
- 'element' => '.jupiterx-comments .jupiterx-comment-avatar .avatar',
51
- ],
52
- ],
53
- ] );
54
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Elementor > Comment > Styles > Avatar tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ $section = 'jupiterx_comment';
11
+
12
+ $comments_avatar_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_comment_elements',
15
+ 'operator' => 'contains',
16
+ 'value' => 'avatar',
17
+ ],
18
+ ];
19
+
20
+ // Avatar Border.
21
+ JupiterX_Customizer::add_field( [
22
+ 'type' => 'jupiterx-border',
23
+ 'settings' => 'jupiterx_comment_avatar_border',
24
+ 'section' => $section,
25
+ 'box' => 'avatar',
26
+ 'css_var' => 'comment-avatar-border',
27
+ 'transport' => 'postMessage',
28
+ 'exclude' => [ 'style', 'size' ],
29
+ 'default' => [
30
+ 'width' => [
31
+ 'size' => '0',
32
+ 'unit' => 'px',
33
+ ],
34
+ ],
35
+ 'output' => [
36
+ [
37
+ 'element' => '.jupiterx-comments .jupiterx-comment-avatar .avatar',
38
+ ],
39
+ ],
40
+ 'active_callback' => $comments_avatar_condition,
41
+ ] );
42
+
43
+ // Divider.
44
+ JupiterX_Customizer::add_field( [
45
+ 'type' => 'jupiterx-divider',
46
+ 'settings' => 'jupiterx_comment_avatar_divider',
47
+ 'section' => $section,
48
+ 'box' => 'avatar',
49
+ 'active_callback' => $comments_avatar_condition,
50
+ ] );
51
+
52
+ // Spacing.
53
+ JupiterX_Customizer::add_responsive_field( [
54
+ 'type' => 'jupiterx-box-model',
55
+ 'settings' => 'jupiterx_comment_avatar_spacing',
56
+ 'section' => $section,
57
+ 'box' => 'avatar',
58
+ 'css_var' => 'comment-avatar-spacing',
59
+ 'transport' => 'postMessage',
60
+ 'exclude' => [ 'padding' ],
61
+ 'output' => [
62
+ [
63
+ 'element' => '.jupiterx-comments .jupiterx-comment-avatar .avatar',
64
+ ],
65
+ ],
66
+ 'active_callback' => $comments_avatar_condition,
67
+ ] );
68
+
includes/customizer/settings/comment/button.php CHANGED
@@ -1,180 +1,235 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Elementor > Comment > Styles > Button tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- $section = 'jupiterx_comment_button';
11
-
12
- // Align.
13
- JupiterX_Customizer::add_responsive_field( [
14
- 'type' => 'jupiterx-choose',
15
- 'settings' => 'jupiterx_comment_button_align',
16
- 'section' => $section,
17
- 'label' => __( 'Align', 'jupiterx-core' ),
18
- 'choices' => JupiterX_Customizer_Utils::get_align(),
19
- 'css_var' => 'comment-button-align',
20
- 'transport' => 'postMessage',
21
- 'column' => 6,
22
- 'output' => [
23
- [
24
- 'element' => '.jupiterx-comments .form-submit',
25
- 'property' => 'text-align',
26
- ],
27
- ],
28
- ] );
29
-
30
- JupiterX_Customizer::add_field( [
31
- 'type' => 'jupiterx-toggle',
32
- 'settings' => 'jupiterx_comment_button_full_width',
33
- 'section' => $section,
34
- 'label' => __( 'Full Width', 'jupiterx-core' ),
35
- 'column' => '6',
36
- 'default' => false,
37
- 'output' => [
38
- [
39
- 'element' => '.jupiterx-comments .form-submit button.btn',
40
- 'property' => 'width',
41
- ],
42
- ],
43
- ] );
44
-
45
- // Typography.
46
- JupiterX_Customizer::add_field( [
47
- 'type' => 'jupiterx-typography',
48
- 'settings' => 'jupiterx_comment_button_typography',
49
- 'section' => $section,
50
- 'responsive' => true,
51
- 'css_var' => 'comment-button-typography',
52
- 'transport' => 'postMessage',
53
- 'exclude' => [ 'line_height' ],
54
- 'output' => [
55
- [
56
- 'element' => '.jupiterx-comments .form-submit button.btn',
57
- ],
58
- ],
59
- ] );
60
-
61
- // Button Background Color Normal.
62
- JupiterX_Customizer::add_field( [
63
- 'type' => 'jupiterx-color',
64
- 'settings' => 'jupiterx_comment_button_background_color',
65
- 'css_var' => 'comment-button-background-color',
66
- 'section' => $section,
67
- 'icon' => 'background-color',
68
- 'transport' => 'postMessage',
69
- 'column' => '1',
70
- 'output' => [
71
- [
72
- 'element' => '.jupiterx-comments .form-submit button.btn',
73
- 'property' => 'background-color',
74
- ],
75
- ],
76
- ] );
77
-
78
- // Button Border.
79
- JupiterX_Customizer::add_field( [
80
- 'type' => 'jupiterx-border',
81
- 'settings' => 'jupiterx_comment_button_border',
82
- 'section' => $section,
83
- 'css_var' => 'comment-button-border',
84
- 'transport' => 'postMessage',
85
- 'exclude' => [ 'style', 'size' ],
86
- 'default' => [
87
- 'width' => [
88
- 'size' => '0',
89
- 'unit' => 'px',
90
- ],
91
- ],
92
- 'output' => [
93
- [
94
- 'element' => '.jupiterx-comments .form-submit button.btn',
95
- ],
96
- ],
97
- ] );
98
-
99
- // Hover Label.
100
- JupiterX_Customizer::add_field( [
101
- 'type' => 'jupiterx-label',
102
- 'label' => __( 'hover', 'jupiterx-core' ),
103
- 'label_type' => 'fancy',
104
- 'color' => 'orange',
105
- 'settings' => 'jupiterx_comment_button_label_hover',
106
- 'section' => $section,
107
- ] );
108
-
109
- // Button Color hover.
110
- JupiterX_Customizer::add_field( [
111
- 'type' => 'jupiterx-color',
112
- 'settings' => 'jupiterx_comment_button_color_hover',
113
- 'section' => $section,
114
- 'css_var' => 'comment-button-color-hover',
115
- 'icon' => 'font-color',
116
- 'column' => '3',
117
- 'transport' => 'postMessage',
118
- 'output' => [
119
- [
120
- 'element' => '.jupiterx-comments .form-submit button.btn:hover',
121
- 'property' => 'color',
122
- ],
123
- ],
124
- ] );
125
-
126
- // Button Background Color hover.
127
- JupiterX_Customizer::add_field( [
128
- 'type' => 'jupiterx-color',
129
- 'settings' => 'jupiterx_comment_button_background_color_hover',
130
- 'css_var' => 'comment-button-background-color-hover',
131
- 'section' => $section,
132
- 'icon' => 'background-color',
133
- 'transport' => 'postMessage',
134
- 'column' => '3',
135
- 'output' => [
136
- [
137
- 'element' => '.jupiterx-comments .form-submit button.btn:hover',
138
- 'property' => 'background-color',
139
- ],
140
- ],
141
- ] );
142
-
143
- JupiterX_Customizer::add_field( [
144
- 'type' => 'jupiterx-color',
145
- 'settings' => 'jupiterx_comment_button_border_color_hover',
146
- 'section' => $section,
147
- 'css_var' => 'comment-button-border-hover',
148
- 'column' => '3',
149
- 'icon' => 'border-color',
150
- 'transport' => 'postMessage',
151
- 'output' => [
152
- [
153
- 'element' => '.jupiterx-comments .form-submit button.btn:hover',
154
- 'property' => 'border-color',
155
- ],
156
- ],
157
- ] );
158
-
159
-
160
- // Divider.
161
- JupiterX_Customizer::add_field( [
162
- 'type' => 'jupiterx-divider',
163
- 'settings' => 'jupiterx_comment_button_divider',
164
- 'section' => $section,
165
- ] );
166
-
167
- // Spacing.
168
- JupiterX_Customizer::add_responsive_field( [
169
- 'type' => 'jupiterx-box-model',
170
- 'settings' => 'jupiterx_comment_button_spacing',
171
- 'section' => $section,
172
- 'css_var' => 'comment-button-box-model',
173
- 'transport' => 'postMessage',
174
- 'output' => [
175
- [
176
- 'element' => '.jupiterx-comments .form-submit button.btn',
177
- ],
178
- ],
179
- ] );
180
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Elementor > Comment > Styles > Button tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ $section = 'jupiterx_comment';
11
+
12
+ // Align.
13
+ JupiterX_Customizer::add_responsive_field( [
14
+ 'type' => 'jupiterx-choose',
15
+ 'settings' => 'jupiterx_comment_button_align',
16
+ 'section' => $section,
17
+ 'box' => 'button',
18
+ 'label' => __( 'Alignment', 'jupiterx-core' ),
19
+ 'inline' => true,
20
+ 'choices' => JupiterX_Customizer_Utils::get_align(),
21
+ 'css_var' => 'comment-button-align',
22
+ 'transport' => 'postMessage',
23
+ 'output' => [
24
+ [
25
+ 'element' => '.jupiterx-comments .form-submit',
26
+ 'property' => 'text-align',
27
+ ],
28
+ ],
29
+ ] );
30
+
31
+ JupiterX_Customizer::add_field( [
32
+ 'type' => 'jupiterx-toggle',
33
+ 'settings' => 'jupiterx_comment_button_full_width',
34
+ 'section' => $section,
35
+ 'box' => 'button',
36
+ 'label' => __( 'Full Width', 'jupiterx-core' ),
37
+ 'default' => false,
38
+ 'output' => [
39
+ [
40
+ 'element' => '.jupiterx-comments .form-submit button.btn',
41
+ 'property' => 'width',
42
+ ],
43
+ ],
44
+ ] );
45
+
46
+ // Tabs.
47
+ JupiterX_Customizer::add_field( [
48
+ 'type' => 'jupiterx-choose',
49
+ 'settings' => 'jupiterx_comment_button_tabs',
50
+ 'section' => $section,
51
+ 'transport' => 'postMessage',
52
+ 'box' => 'button',
53
+ 'choices' => [
54
+ 'normal' => [
55
+ 'label' => __( 'Normal', 'jupiterx-core' ),
56
+ ],
57
+ 'hover' => [
58
+ 'label' => __( 'Hover', 'jupiterx-core' ),
59
+ ],
60
+ ],
61
+ 'default' => 'normal',
62
+ ] );
63
+
64
+ // Typography.
65
+ JupiterX_Customizer::add_field( [
66
+ 'type' => 'jupiterx-typography',
67
+ 'settings' => 'jupiterx_comment_button_typography',
68
+ 'section' => $section,
69
+ 'box' => 'button',
70
+ 'responsive' => true,
71
+ 'css_var' => 'comment-button-typography',
72
+ 'transport' => 'postMessage',
73
+ 'exclude' => [ 'line_height' ],
74
+ 'output' => [
75
+ [
76
+ 'element' => '.jupiterx-comments .form-submit button.btn',
77
+ ],
78
+ ],
79
+ 'active_callback' => [
80
+ [
81
+ 'setting' => 'jupiterx_comment_button_tabs',
82
+ 'operator' => '===',
83
+ 'value' => 'normal',
84
+ ],
85
+ ],
86
+ ] );
87
+
88
+ // Button Background Color Normal.
89
+ JupiterX_Customizer::add_field( [
90
+ 'type' => 'jupiterx-color',
91
+ 'settings' => 'jupiterx_comment_button_background_color',
92
+ 'css_var' => 'comment-button-background-color',
93
+ 'section' => $section,
94
+ 'box' => 'button',
95
+ 'label' => __( 'Background Color', 'jupiterx-core' ),
96
+ 'transport' => 'postMessage',
97
+ 'output' => [
98
+ [
99
+ 'element' => '.jupiterx-comments .form-submit button.btn',
100
+ 'property' => 'background-color',
101
+ ],
102
+ ],
103
+ 'active_callback' => [
104
+ [
105
+ 'setting' => 'jupiterx_comment_button_tabs',
106
+ 'operator' => '===',
107
+ 'value' => 'normal',
108
+ ],
109
+ ],
110
+ ] );
111
+
112
+ // Button Border.
113
+ JupiterX_Customizer::add_field( [
114
+ 'type' => 'jupiterx-border',
115
+ 'settings' => 'jupiterx_comment_button_border',
116
+ 'section' => $section,
117
+ 'box' => 'button',
118
+ 'css_var' => 'comment-button-border',
119
+ 'transport' => 'postMessage',
120
+ 'exclude' => [ 'style', 'size' ],
121
+ 'default' => [
122
+ 'width' => [
123
+ 'size' => '0',
124
+ 'unit' => 'px',
125
+ ],
126
+ ],
127
+ 'output' => [
128
+ [
129
+ 'element' => '.jupiterx-comments .form-submit button.btn',
130
+ ],
131
+ ],
132
+ 'active_callback' => [
133
+ [
134
+ 'setting' => 'jupiterx_comment_button_tabs',
135
+ 'operator' => '===',
136
+ 'value' => 'normal',
137
+ ],
138
+ ],
139
+ ] );
140
+
141
+ // Button Color hover.
142
+ JupiterX_Customizer::add_field( [
143
+ 'type' => 'jupiterx-color',
144
+ 'settings' => 'jupiterx_comment_button_color_hover',
145
+ 'section' => $section,
146
+ 'box' => 'button',
147
+ 'css_var' => 'comment-button-color-hover',
148
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
149
+ 'transport' => 'postMessage',
150
+ 'output' => [
151
+ [
152
+ 'element' => '.jupiterx-comments .form-submit button.btn:hover',
153
+ 'property' => 'color',
154
+ ],
155
+ ],
156
+ 'active_callback' => [
157
+ [
158
+ 'setting' => 'jupiterx_comment_button_tabs',
159
+ 'operator' => '===',
160
+ 'value' => 'hover',
161
+ ],
162
+ ],
163
+ ] );
164
+
165
+ // Button Background Color hover.
166
+ JupiterX_Customizer::add_field( [
167
+ 'type' => 'jupiterx-color',
168
+ 'settings' => 'jupiterx_comment_button_background_color_hover',
169
+ 'css_var' => 'comment-button-background-color-hover',
170
+ 'section' => $section,
171
+ 'box' => 'button',
172
+ 'label' => __( 'Background Color', 'jupiterx-core' ),
173
+ 'transport' => 'postMessage',
174
+ 'output' => [
175
+ [
176
+ 'element' => '.jupiterx-comments .form-submit button.btn:hover',
177
+ 'property' => 'background-color',
178
+ ],
179
+ ],
180
+ 'active_callback' => [
181
+ [
182
+ 'setting' => 'jupiterx_comment_button_tabs',
183
+ 'operator' => '===',
184
+ 'value' => 'hover',
185
+ ],
186
+ ],
187
+ ] );
188
+
189
+ JupiterX_Customizer::add_field( [
190
+ 'type' => 'jupiterx-color',
191
+ 'settings' => 'jupiterx_comment_button_border_color_hover',
192
+ 'section' => $section,
193
+ 'box' => 'button',
194
+ 'css_var' => 'comment-button-border-hover',
195
+ 'label' => __( 'Border Color', 'jupiterx-core' ),
196
+ 'transport' => 'postMessage',
197
+ 'output' => [
198
+ [
199
+ 'element' => '.jupiterx-comments .form-submit button.btn:hover',
200
+ 'property' => 'border-color',
201
+ ],
202
+ ],
203
+ 'active_callback' => [
204
+ [
205
+ 'setting' => 'jupiterx_comment_button_tabs',
206
+ 'operator' => '===',
207
+ 'value' => 'hover',
208
+ ],
209
+ ],
210
+ ] );
211
+
212
+
213
+ // Divider.
214
+ JupiterX_Customizer::add_field( [
215
+ 'type' => 'jupiterx-divider',
216
+ 'settings' => 'jupiterx_comment_button_divider',
217
+ 'section' => $section,
218
+ 'box' => 'button',
219
+ ] );
220
+
221
+ // Spacing.
222
+ JupiterX_Customizer::add_responsive_field( [
223
+ 'type' => 'jupiterx-box-model',
224
+ 'settings' => 'jupiterx_comment_button_spacing',
225
+ 'section' => $section,
226
+ 'box' => 'button',
227
+ 'css_var' => 'comment-button-box-model',
228
+ 'transport' => 'postMessage',
229
+ 'output' => [
230
+ [
231
+ 'element' => '.jupiterx-comments .form-submit button.btn',
232
+ ],
233
+ ],
234
+ ] );
235
+
includes/customizer/settings/comment/comment-text.php CHANGED
@@ -1,49 +1,52 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Elementor > Comment > Styles > Comment Text tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- $section = 'jupiterx_comment_comment_text';
11
-
12
- // Typography.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-typography',
15
- 'settings' => 'jupiterx_comment_comment_text_typography',
16
- 'section' => $section,
17
- 'responsive' => true,
18
- 'css_var' => 'comment-comment-text',
19
- 'transport' => 'postMessage',
20
- 'exclude' => [ 'line_height', 'text_transform' ],
21
- 'output' => [
22
- [
23
- 'element' => '.jupiterx-comments .jupiterx-comment-body-wrapper',
24
- ],
25
- ],
26
- ] );
27
-
28
- // Divider.
29
- JupiterX_Customizer::add_field( [
30
- 'type' => 'jupiterx-divider',
31
- 'settings' => 'jupiterx_comment_comment_text_divider',
32
- 'section' => $section,
33
- ] );
34
-
35
- // Spacing.
36
- JupiterX_Customizer::add_responsive_field( [
37
- 'type' => 'jupiterx-box-model',
38
- 'settings' => 'jupiterx_comment_comment_text_spacing',
39
- 'section' => $section,
40
- 'css_var' => 'comment-comment-text-box-model',
41
- 'transport' => 'postMessage',
42
- 'exclude' => [ 'padding' ],
43
- 'output' => [
44
- [
45
- 'element' => '.jupiterx-comments .jupiterx-comment-body-wrapper',
46
- ],
47
- ],
48
- ] );
49
-
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Elementor > Comment > Styles > Comment Text tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ $section = 'jupiterx_comment';
11
+
12
+ // Typography.
13
+ JupiterX_Customizer::add_field( [
14
+ 'type' => 'jupiterx-typography',
15
+ 'settings' => 'jupiterx_comment_comment_text_typography',
16
+ 'section' => $section,
17
+ 'box' => 'comment_text',
18
+ 'responsive' => true,
19
+ 'css_var' => 'comment-comment-text',
20
+ 'transport' => 'postMessage',
21
+ 'exclude' => [ 'line_height', 'text_transform' ],
22
+ 'output' => [
23
+ [
24
+ 'element' => '.jupiterx-comments .jupiterx-comment-body-wrapper',
25
+ ],
26
+ ],
27
+ ] );
28
+
29
+ // Divider.
30
+ JupiterX_Customizer::add_field( [
31
+ 'type' => 'jupiterx-divider',
32
+ 'settings' => 'jupiterx_comment_comment_text_divider',
33
+ 'section' => $section,
34
+ 'box' => 'comment_text',
35
+ ] );
36
+
37
+ // Spacing.
38
+ JupiterX_Customizer::add_responsive_field( [
39
+ 'type' => 'jupiterx-box-model',
40
+ 'settings' => 'jupiterx_comment_comment_text_spacing',
41
+ 'section' => $section,
42
+ 'box' => 'comment_text',
43
+ 'css_var' => 'comment-comment-text-box-model',
44
+ 'transport' => 'postMessage',
45
+ 'exclude' => [ 'padding' ],
46
+ 'output' => [
47
+ [
48
+ 'element' => '.jupiterx-comments .jupiterx-comment-body-wrapper',
49
+ ],
50
+ ],
51
+ ] );
52
+
includes/customizer/settings/comment/date.php CHANGED
@@ -1,27 +1,37 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Elementor > Comment > Styles > Date tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- $section = 'jupiterx_comment_date';
11
-
12
- // Typography.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-typography',
15
- 'settings' => 'jupiterx_comment_date_typography',
16
- 'section' => $section,
17
- 'responsive' => true,
18
- 'css_var' => 'comment-date-typography',
19
- 'transport' => 'postMessage',
20
- 'exclude' => [ 'line_height' ],
21
- 'output' => [
22
- [
23
- 'element' => '.jupiterx-comments .jupiterx-comment-meta time',
24
- ],
25
- ],
26
- ] );
27
-
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Elementor > Comment > Styles > Date tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ $section = 'jupiterx_comment';
11
+
12
+ $comments_date_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_comment_elements',
15
+ 'operator' => 'contains',
16
+ 'value' => 'date',
17
+ ],
18
+ ];
19
+
20
+ // Typography.
21
+ JupiterX_Customizer::add_field( [
22
+ 'type' => 'jupiterx-typography',
23
+ 'settings' => 'jupiterx_comment_date_typography',
24
+ 'section' => $section,
25
+ 'box' => 'date',
26
+ 'responsive' => true,
27
+ 'css_var' => 'comment-date-typography',
28
+ 'transport' => 'postMessage',
29
+ 'exclude' => [ 'line_height' ],
30
+ 'output' => [
31
+ [
32
+ 'element' => '.jupiterx-comments .jupiterx-comment-meta time',
33
+ ],
34
+ ],
35
+ 'active_callback' => $comments_date_condition,
36
+ ] );
37
+
includes/customizer/settings/comment/field.php CHANGED
@@ -1,163 +1,218 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Elementor > Comment > Styles > Field tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- $section = 'jupiterx_comment_field';
11
-
12
- // Field Typography.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-typography',
15
- 'settings' => 'jupiterx_comment_field_typography',
16
- 'section' => $section,
17
- 'responsive' => true,
18
- 'css_var' => 'comment-field-typography',
19
- 'transport' => 'postMessage',
20
- 'exclude' => [ 'line_height', 'text_transform', 'letter_spacing' ],
21
- 'output' => [
22
- [
23
- 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control',
24
- ],
25
- ],
26
- ] );
27
-
28
- // Field Background Color Normal.
29
- JupiterX_Customizer::add_field( [
30
- 'type' => 'jupiterx-color',
31
- 'settings' => 'jupiterx_comment_field_background_color',
32
- 'css_var' => 'comment-field-background-color',
33
- 'section' => $section,
34
- 'icon' => 'background-color',
35
- 'transport' => 'postMessage',
36
- 'column' => '1',
37
- 'output' => [
38
- [
39
- 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control',
40
- 'property' => 'background-color',
41
- ],
42
- ],
43
- ] );
44
-
45
- // Field Border.
46
- JupiterX_Customizer::add_field( [
47
- 'type' => 'jupiterx-border',
48
- 'settings' => 'jupiterx_comment_field_border',
49
- 'section' => $section,
50
- 'css_var' => 'comment-field-border',
51
- 'transport' => 'postMessage',
52
- 'exclude' => [ 'style', 'size' ],
53
- 'output' => [
54
- [
55
- 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control',
56
- ],
57
- ],
58
- ] );
59
-
60
- // Hover Label.
61
- JupiterX_Customizer::add_field( [
62
- 'type' => 'jupiterx-label',
63
- 'label' => __( 'Focus', 'jupiterx-core' ),
64
- 'label_type' => 'fancy',
65
- 'color' => 'orange',
66
- 'settings' => 'jupiterx_comment_field_label_focus',
67
- 'section' => $section,
68
- ] );
69
-
70
- // Field Color Focus.
71
- JupiterX_Customizer::add_field( [
72
- 'type' => 'jupiterx-color',
73
- 'settings' => 'jupiterx_comment_field_color_focus',
74
- 'section' => $section,
75
- 'css_var' => 'comment-field-color-focus',
76
- 'icon' => 'font-color',
77
- 'column' => '3',
78
- 'transport' => 'postMessage',
79
- 'output' => [
80
- [
81
- 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control:focus',
82
- 'property' => 'color',
83
- ],
84
- ],
85
- ] );
86
-
87
- // Field Background Color Focus.
88
- JupiterX_Customizer::add_field( [
89
- 'type' => 'jupiterx-color',
90
- 'settings' => 'jupiterx_comment_field_background_color_focus',
91
- 'css_var' => 'comment-field-background-color-focus',
92
- 'section' => $section,
93
- 'icon' => 'background-color',
94
- 'transport' => 'postMessage',
95
- 'column' => '3',
96
- 'output' => [
97
- [
98
- 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control:focus',
99
- 'property' => 'background-color',
100
- ],
101
- ],
102
- ] );
103
-
104
- // Field Border Color Focus.
105
- JupiterX_Customizer::add_field( [
106
- 'type' => 'jupiterx-color',
107
- 'settings' => 'jupiterx_comment_field_border_color_focus',
108
- 'section' => $section,
109
- 'css_var' => 'post-single-avatar-border-focus',
110
- 'column' => '3',
111
- 'icon' => 'border-color',
112
- 'transport' => 'postMessage',
113
- 'output' => [
114
- [
115
- 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control:focus',
116
- 'property' => 'border-color',
117
- ],
118
- ],
119
- ] );
120
-
121
- // Divider.
122
- JupiterX_Customizer::add_field( [
123
- 'type' => 'jupiterx-divider',
124
- 'settings' => 'jupiterx_comment_field_divider',
125
- 'section' => $section,
126
- ] );
127
-
128
- // Spacing Margin.
129
- JupiterX_Customizer::add_responsive_field( [
130
- 'type' => 'jupiterx-box-model',
131
- 'settings' => 'jupiterx_comment_field_spacing_margin',
132
- 'section' => $section,
133
- 'css_var' => 'comment-field-margin',
134
- 'exclude' => [ 'padding' ],
135
- 'transport' => 'postMessage',
136
- 'output' => [
137
- [
138
- 'element' => '.jupiterx-comments .comment-form .jupiterx-comment-field-wrapper',
139
- ],
140
- [
141
- 'element' => '.jupiterx-comments .comment-form .form-group',
142
- ],
143
- [
144
- 'element' => '.jupiterx-comments .comment-form input[name=wp-comment-cookies-consent]',
145
- ],
146
- ],
147
- ] );
148
-
149
- // Spacing Padding.
150
- JupiterX_Customizer::add_responsive_field( [
151
- 'type' => 'jupiterx-box-model',
152
- 'settings' => 'jupiterx_comment_field_spacing_padding',
153
- 'section' => $section,
154
- 'css_var' => 'comment-field-padding',
155
- 'exclude' => [ 'margin' ],
156
- 'transport' => 'postMessage',
157
- 'output' => [
158
- [
159
- 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control',
160
- ],
161
- ],
162
- ] );
163
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Elementor > Comment > Styles > Field tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ $section = 'jupiterx_comment';
11
+
12
+ // Tabs.
13
+ JupiterX_Customizer::add_field( [
14
+ 'type' => 'jupiterx-choose',
15
+ 'settings' => 'jupiterx_comment_field_tabs',
16
+ 'section' => $section,
17
+ 'transport' => 'postMessage',
18
+ 'box' => 'field',
19
+ 'choices' => [
20
+ 'normal' => [
21
+ 'label' => __( 'Normal', 'jupiterx-core' ),
22
+ ],
23
+ 'focus' => [
24
+ 'label' => __( 'Focus', 'jupiterx-core' ),
25
+ ],
26
+ ],
27
+ 'default' => 'normal',
28
+ ] );
29
+
30
+ // Field Typography.
31
+ JupiterX_Customizer::add_field( [
32
+ 'type' => 'jupiterx-typography',
33
+ 'settings' => 'jupiterx_comment_field_typography',
34
+ 'section' => $section,
35
+ 'box' => 'field',
36
+ 'responsive' => true,
37
+ 'css_var' => 'comment-field-typography',
38
+ 'transport' => 'postMessage',
39
+ 'exclude' => [ 'line_height', 'text_transform', 'letter_spacing' ],
40
+ 'output' => [
41
+ [
42
+ 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control',
43
+ ],
44
+ ],
45
+ 'active_callback' => [
46
+ [
47
+ 'setting' => 'jupiterx_comment_field_tabs',
48
+ 'operator' => '===',
49
+ 'value' => 'normal',
50
+ ],
51
+ ],
52
+ ] );
53
+
54
+ // Field Background Color Normal.
55
+ JupiterX_Customizer::add_field( [
56
+ 'type' => 'jupiterx-color',
57
+ 'settings' => 'jupiterx_comment_field_background_color',
58
+ 'css_var' => 'comment-field-background-color',
59
+ 'section' => $section,
60
+ 'box' => 'field',
61
+ 'label' => __( 'Background Color', 'jupiterx-core' ),
62
+ 'transport' => 'postMessage',
63
+ 'output' => [
64
+ [
65
+ 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control',
66
+ 'property' => 'background-color',
67
+ ],
68
+ ],
69
+ 'active_callback' => [
70
+ [
71
+ 'setting' => 'jupiterx_comment_field_tabs',
72
+ 'operator' => '===',
73
+ 'value' => 'normal',
74
+ ],
75
+ ],
76
+ ] );
77
+
78
+ // Field Border.
79
+ JupiterX_Customizer::add_field( [
80
+ 'type' => 'jupiterx-border',
81
+ 'settings' => 'jupiterx_comment_field_border',
82
+ 'section' => $section,
83
+ 'box' => 'field',
84
+ 'css_var' => 'comment-field-border',
85
+ 'transport' => 'postMessage',
86
+ 'exclude' => [ 'style', 'size' ],
87
+ 'output' => [
88
+ [
89
+ 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control',
90
+ ],
91
+ ],
92
+ 'active_callback' => [
93
+ [
94
+ 'setting' => 'jupiterx_comment_field_tabs',
95
+ 'operator' => '===',
96
+ 'value' => 'normal',
97
+ ],
98
+ ],
99
+ ] );
100
+
101
+ // Field Color Focus.
102
+ JupiterX_Customizer::add_field( [
103
+ 'type' => 'jupiterx-color',
104
+ 'settings' => 'jupiterx_comment_field_color_focus',
105
+ 'section' => $section,
106
+ 'box' => 'field',
107
+ 'css_var' => 'comment-field-color-focus',
108
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
109
+ 'transport' => 'postMessage',
110
+ 'output' => [
111
+ [
112
+ 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control:focus',
113
+ 'property' => 'color',
114
+ ],
115
+ ],
116
+ 'active_callback' => [
117
+ [
118
+ 'setting' => 'jupiterx_comment_field_tabs',
119
+ 'operator' => '===',
120
+ 'value' => 'focus',
121
+ ],
122
+ ],
123
+ ] );
124
+
125
+ // Field Background Color Focus.
126
+ JupiterX_Customizer::add_field( [
127
+ 'type' => 'jupiterx-color',
128
+ 'settings' => 'jupiterx_comment_field_background_color_focus',
129
+ 'css_var' => 'comment-field-background-color-focus',
130
+ 'section' => $section,
131
+ 'box' => 'field',
132
+ 'label' => __( 'Background Color', 'jupiterx-core' ),
133
+ 'transport' => 'postMessage',
134
+ 'output' => [
135
+ [
136
+ 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control:focus',
137
+ 'property' => 'background-color',
138
+ ],
139
+ ],
140
+ 'active_callback' => [
141
+ [
142
+ 'setting' => 'jupiterx_comment_field_tabs',
143
+ 'operator' => '===',
144
+ 'value' => 'focus',
145
+ ],
146
+ ],
147
+ ] );
148
+
149
+ // Field Border Color Focus.
150
+ JupiterX_Customizer::add_field( [
151
+ 'type' => 'jupiterx-color',
152
+ 'settings' => 'jupiterx_comment_field_border_color_focus',
153
+ 'section' => $section,
154
+ 'box' => 'field',
155
+ 'css_var' => 'post-single-avatar-border-focus',
156
+ 'label' => __( 'Border Color', 'jupiterx-core' ),
157
+ 'transport' => 'postMessage',
158
+ 'output' => [
159
+ [
160
+ 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control:focus',
161
+ 'property' => 'border-color',
162
+ ],
163
+ ],
164
+ 'active_callback' => [
165
+ [
166
+ 'setting' => 'jupiterx_comment_field_tabs',
167
+ 'operator' => '===',
168
+ 'value' => 'focus',
169
+ ],
170
+ ],
171
+ ] );
172
+
173
+ // Divider.
174
+ JupiterX_Customizer::add_field( [
175
+ 'type' => 'jupiterx-divider',
176
+ 'settings' => 'jupiterx_comment_field_divider',
177
+ 'section' => $section,
178
+ 'box' => 'field',
179
+ ] );
180
+
181
+ // Spacing Margin.
182
+ JupiterX_Customizer::add_responsive_field( [
183
+ 'type' => 'jupiterx-box-model',
184
+ 'settings' => 'jupiterx_comment_field_spacing_margin',
185
+ 'section' => $section,
186
+ 'box' => 'field',
187
+ 'css_var' => 'comment-field-margin',
188
+ 'exclude' => [ 'padding' ],
189
+ 'transport' => 'postMessage',
190
+ 'output' => [
191
+ [
192
+ 'element' => '.jupiterx-comments .comment-form .jupiterx-comment-field-wrapper',
193
+ ],
194
+ [
195
+ 'element' => '.jupiterx-comments .comment-form .form-group',
196
+ ],
197
+ [
198
+ 'element' => '.jupiterx-comments .comment-form input[name=wp-comment-cookies-consent]',
199
+ ],
200
+ ],
201
+ ] );
202
+
203
+ // Spacing Padding.
204
+ JupiterX_Customizer::add_responsive_field( [
205
+ 'type' => 'jupiterx-box-model',
206
+ 'settings' => 'jupiterx_comment_field_spacing_padding',
207
+ 'section' => $section,
208
+ 'box' => 'field',
209
+ 'css_var' => 'comment-field-padding',
210
+ 'exclude' => [ 'margin' ],
211
+ 'transport' => 'postMessage',
212
+ 'output' => [
213
+ [
214
+ 'element' => '.jupiterx-comments .jupiterx-comment-field-wrapper .form-control',
215
+ ],
216
+ ],
217
+ ] );
218
+
includes/customizer/settings/comment/name.php CHANGED
@@ -1,27 +1,28 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Elementor > Comment > Styles > Name tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- $section = 'jupiterx_comment_name';
11
-
12
- // Typography.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-typography',
15
- 'settings' => 'jupiterx_comment_name_typography',
16
- 'section' => $section,
17
- 'responsive' => true,
18
- 'css_var' => 'comment-name-typography',
19
- 'transport' => 'postMessage',
20
- 'exclude' => [ 'line_height' ],
21
- 'output' => [
22
- [
23
- 'element' => '.jupiterx-comments .jupiterx-comment-title .url, .jupiterx-comments .jupiterx-comment-title .jupiterx-comment-username',
24
- ],
25
- ],
26
- ] );
27
-
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Elementor > Comment > Styles > Name tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ $section = 'jupiterx_comment';
11
+
12
+ // Typography.
13
+ JupiterX_Customizer::add_field( [
14
+ 'type' => 'jupiterx-typography',
15
+ 'settings' => 'jupiterx_comment_name_typography',
16
+ 'section' => $section,
17
+ 'box' => 'name',
18
+ 'responsive' => true,
19
+ 'css_var' => 'comment-name-typography',
20
+ 'transport' => 'postMessage',
21
+ 'exclude' => [ 'line_height' ],
22
+ 'output' => [
23
+ [
24
+ 'element' => '.jupiterx-comments .jupiterx-comment-title .url, .jupiterx-comments .jupiterx-comment-title .jupiterx-comment-username',
25
+ ],
26
+ ],
27
+ ] );
28
+
includes/customizer/settings/comment/popup.php CHANGED
@@ -1,91 +1,64 @@
1
- <?php
2
- /**
3
- * Add Jupiter Comment popup and tabs to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- $popups = [
11
- 'title' => __( 'Title', 'jupiterx-core' ),
12
- 'field' => __( 'Field', 'jupiterx-core' ),
13
- 'button' => __( 'Button', 'jupiterx-core' ),
14
- 'avatar' => __( 'Avater', 'jupiterx-core' ),
15
- 'name' => __( 'Name', 'jupiterx-core' ),
16
- 'date' => __( 'Date', 'jupiterx-core' ),
17
- 'comment_text' => __( 'Comment Text', 'jupiterx-core' ),
18
- 'action_link' => __( 'Action Link', 'jupiterx-core' ),
19
- ];
20
-
21
- // Comment popup.
22
- JupiterX_Customizer::add_section( 'jupiterx_comment', [
23
- 'panel' => 'jupiterx_elements',
24
- 'title' => __( 'Comment', 'jupiterx-core' ),
25
- 'type' => 'popup',
26
- 'tabs' => [
27
- 'settings' => __( 'Settings', 'jupiterx-core' ),
28
- 'styles' => __( 'Styles', 'jupiterx-core' ),
29
- ],
30
- 'popups' => $popups,
31
- 'preview' => true,
32
- 'help' => [
33
- 'url' => 'https://themes.artbees.net/docs/display-settings-for-blog-shop-single-pages',
34
- 'title' => __( 'Display settings for Blog, Shop single pages', 'jupiterx-core' ),
35
- ],
36
- ] );
37
-
38
- // Settings tab.
39
- JupiterX_Customizer::add_section( 'jupiterx_comment_settings', [
40
- 'popup' => 'jupiterx_comment',
41
- 'type' => 'pane',
42
- 'pane' => [
43
- 'type' => 'tab',
44
- 'id' => 'settings',
45
- ],
46
- ] );
47
-
48
- // Styles tab.
49
- JupiterX_Customizer::add_section( 'jupiterx_comment_styles', [
50
- 'popup' => 'jupiterx_comment',
51
- 'type' => 'pane',
52
- 'pane' => [
53
- 'type' => 'tab',
54
- 'id' => 'styles',
55
- ],
56
- ] );
57
-
58
- // Styles tab > Child popups.
59
- JupiterX_Customizer::add_field( [
60
- 'type' => 'jupiterx-child-popup',
61
- 'settings' => 'jupiterx_comment_styles_popups',
62
- 'section' => 'jupiterx_comment_styles',
63
- 'target' => 'jupiterx_comment',
64
- 'choices' => [
65
- 'title' => __( 'Title', 'jupiterx-core' ),
66
- 'field' => __( 'Field', 'jupiterx-core' ),
67
- 'button' => __( 'Button', 'jupiterx-core' ),
68
- 'avatar' => __( 'Avatar', 'jupiterx-core' ),
69
- 'name' => __( 'Name', 'jupiterx-core' ),
70
- 'date' => __( 'Date', 'jupiterx-core' ),
71
- 'comment_text' => __( 'Comment Text', 'jupiterx-core' ),
72
- 'action_link' => __( 'Action Links', 'jupiterx-core' ),
73
- ],
74
- ] );
75
-
76
- // Create popup children.
77
- foreach ( $popups as $popup_id => $label ) {
78
- JupiterX_Customizer::add_section( 'jupiterx_comment_' . $popup_id, [
79
- 'popup' => 'jupiterx_comment',
80
- 'type' => 'pane',
81
- 'pane' => [
82
- 'type' => 'popup',
83
- 'id' => $popup_id,
84
- ],
85
- ] );
86
- }
87
-
88
- // Load all the settings.
89
- foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
90
- require_once $setting;
91
- }
1
+ <?php
2
+ /**
3
+ * Add Jupiter Comment popup and tabs to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ // Comment popup.
11
+ JupiterX_Customizer::add_section( 'jupiterx_comment', [
12
+ 'title' => __( 'Comment', 'jupiterx-core' ),
13
+ 'type' => 'container',
14
+ 'tabs' => [
15
+ 'settings' => __( 'Settings', 'jupiterx-core' ),
16
+ 'styles' => __( 'Styles', 'jupiterx-core' ),
17
+ ],
18
+ 'boxes' => [
19
+ 'settings' => [
20
+ 'label' => __( 'Settings', 'jupiterx-core' ),
21
+ 'tab' => 'settings',
22
+ ],
23
+ 'title' => [
24
+ 'label' => __( 'Title', 'jupiterx-core' ),
25
+ 'tab' => 'styles',
26
+ ],
27
+ 'field' => [
28
+ 'label' => __( 'Field', 'jupiterx-core' ),
29
+ 'tab' => 'styles',
30
+ ],
31
+ 'button' => [
32
+ 'label' => __( 'Button', 'jupiterx-core' ),
33
+ 'tab' => 'styles',
34
+ ],
35
+ 'avatar' => [
36
+ 'label' => __( 'Avater', 'jupiterx-core' ),
37
+ 'tab' => 'styles',
38
+ ],
39
+ 'name' => [
40
+ 'label' => __( 'Name', 'jupiterx-core' ),
41
+ 'tab' => 'styles',
42
+ ],
43
+ 'date' => [
44
+ 'label' => __( 'Date', 'jupiterx-core' ),
45
+ 'tab' => 'styles',
46
+ ],
47
+ 'comment_text' => [
48
+ 'label' => __( 'Comment Text', 'jupiterx-core' ),
49
+ 'tab' => 'styles',
50
+ ],
51
+ 'action_link' => [
52
+ 'label' => __( 'Action Link', 'jupiterx-core' ),
53
+ 'tab' => 'styles',
54
+ ],
55
+ ],
56
+ 'preview' => true,
57
+ 'group' => 'elements',
58
+ 'icon' => 'comment',
59
+ ] );
60
+
61
+ // Load all the settings.
62
+ foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
63
+ require_once $setting;
64
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/customizer/settings/comment/settings.php CHANGED
@@ -1,37 +1,31 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Element > Comment > Settings tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- $section = 'jupiterx_comment_settings';
11
-
12
- // Label.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-label',
15
- 'settings' => 'jupiterx_comment_label_1',
16
- 'section' => $section,
17
- 'label' => __( 'Display Contents', 'jupiterx-core' ),
18
- ] );
19
-
20
- // Display elements.
21
- JupiterX_Customizer::add_field( [
22
- 'type' => 'jupiterx-multicheck',
23
- 'settings' => 'jupiterx_comment_elements',
24
- 'section' => $section,
25
- 'css_var' => 'comment-elements',
26
- 'default' => [
27
- 'avatar',
28
- 'date',
29
- 'role',
30
- ],
31
- 'choices' => [
32
- 'avatar' => __( 'Avatar', 'jupiterx-core' ),
33
- 'role' => __( 'Role', 'jupiterx-core' ),
34
- 'date' => __( 'Date', 'jupiterx-core' ),
35
- ],
36
- ] );
37
-
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Element > Comment > Settings tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ $section = 'jupiterx_comment';
11
+
12
+ // Display elements.
13
+ JupiterX_Customizer::add_field( [
14
+ 'type' => 'jupiterx-multicheck',
15
+ 'settings' => 'jupiterx_comment_elements',
16
+ 'section' => $section,
17
+ 'box' => 'settings',
18
+ 'label' => __( 'Display Contents', 'jupiterx-core' ),
19
+ 'css_var' => 'comment-elements',
20
+ 'default' => [
21
+ 'avatar',
22
+ 'date',
23
+ 'role',
24
+ ],
25
+ 'choices' => [
26
+ 'avatar' => __( 'Avatar', 'jupiterx-core' ),
27
+ 'role' => __( 'Role', 'jupiterx-core' ),
28
+ 'date' => __( 'Date', 'jupiterx-core' ),
29
+ ],
30
+ ] );
31
+
 
 
 
 
 
 
includes/customizer/settings/comment/title.php CHANGED
@@ -1,49 +1,52 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Elementor > Comment > Styles > Title tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.9.0
8
- */
9
-
10
- $section = 'jupiterx_comment_title';
11
-
12
- // Comment Title Typography.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-typography',
15
- 'settings' => 'jupiterx_comment_title_typography',
16
- 'section' => $section,
17
- 'responsive' => true,
18
- 'css_var' => 'comment-title-typography',
19
- 'transport' => 'postMessage',
20
- 'exclude' => [ 'line_height' ],
21
- 'output' => [
22
- [
23
- 'element' => '.jupiterx-comments .jupiterx-comments-title, .jupiterx-comments .comment-reply-title',
24
- ],
25
- ],
26
- ] );
27
-
28
- // Divider.
29
- JupiterX_Customizer::add_field( [
30
- 'type' => 'jupiterx-divider',
31
- 'settings' => 'jupiterx_comment_title_divider',
32
- 'section' => $section,
33
- ] );
34
-
35
- // Spacing.
36
- JupiterX_Customizer::add_responsive_field( [
37
- 'type' => 'jupiterx-box-model',
38
- 'settings' => 'jupiterx_comment_title_spacing',
39
- 'section' => $section,
40
- 'css_var' => 'comment-title-margin',
41
- 'transport' => 'postMessage',
42
- 'exclude' => [ 'padding' ],
43
- 'output' => [
44
- [
45
- 'element' => '.jupiterx-comments .jupiterx-comments-title, .jupiterx-comments .comment-reply-title',
46
- ],
47
- ],
48
- ] );
49
-
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Elementor > Comment > Styles > Title tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.9.0
8
+ */
9
+
10
+ $section = 'jupiterx_comment';
11
+
12
+ // Comment Title Typography.
13
+ JupiterX_Customizer::add_field( [
14
+ 'type' => 'jupiterx-typography',
15
+ 'settings' => 'jupiterx_comment_title_typography',
16
+ 'section' => $section,
17
+ 'box' => 'title',
18
+ 'responsive' => true,
19
+ 'css_var' => 'comment-title-typography',
20
+ 'transport' => 'postMessage',
21
+ 'exclude' => [ 'line_height' ],
22
+ 'output' => [
23
+ [
24
+ 'element' => '.jupiterx-comments .jupiterx-comments-title, .jupiterx-comments .comment-reply-title',
25
+ ],
26
+ ],
27
+ ] );
28
+
29
+ // Divider.
30
+ JupiterX_Customizer::add_field( [
31
+ 'type' => 'jupiterx-divider',
32
+ 'settings' => 'jupiterx_comment_title_divider',
33
+ 'section' => $section,
34
+ 'box' => 'title',
35
+ ] );
36
+
37
+ // Spacing.
38
+ JupiterX_Customizer::add_responsive_field( [
39
+ 'type' => 'jupiterx-box-model',
40
+ 'settings' => 'jupiterx_comment_title_spacing',
41
+ 'section' => $section,
42
+ 'box' => 'title',
43
+ 'css_var' => 'comment-title-margin',
44
+ 'transport' => 'postMessage',
45
+ 'exclude' => [ 'padding' ],
46
+ 'output' => [
47
+ [
48
+ 'element' => '.jupiterx-comments .jupiterx-comments-title, .jupiterx-comments .comment-reply-title',
49
+ ],
50
+ ],
51
+ ] );
52
+
includes/customizer/settings/footer/popup.php CHANGED
@@ -1,164 +1,94 @@
1
- <?php
2
- /**
3
- * Add Jupiter Footer popup and tabs to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $popups = [
11
- 'widgets_title' => __( 'Widgets Title', 'jupiterx-core' ),
12
- 'widgets_text' => __( 'Widgets Text', 'jupiterx-core' ),
13
- 'widgets_link' => __( 'Widgets Link', 'jupiterx-core' ),
14
- 'widgets_thumbnail' => __( 'Widgets Thumbnail', 'jupiterx-core' ),
15
- 'widgets_container' => __( 'Widgets Container', 'jupiterx-core' ),
16
- 'widgets_divider' => __( 'Widgets Divider', 'jupiterx-core' ),
17
- 'widget_area_container' => __( 'Widget Area Container', 'jupiterx-core' ),
18
- 'sub_copyright' => __( 'Sub Footer Copyright', 'jupiterx-core' ),
19
- 'sub_menu' => __( 'Sub Footer Menu', 'jupiterx-core' ),
20
- 'sub_container' => __( 'Sub Footer Container', 'jupiterx-core' ),
21
- ];
22
-
23
- // Popup.
24
- JupiterX_Customizer::add_section( 'jupiterx_footer', [
25
- 'title' => __( 'Footer', 'jupiterx-core' ),
26
- 'type' => 'popup',
27
- 'priority' => 135,
28
- 'tabs' => [
29
- 'settings' => __( 'Settings', 'jupiterx-core' ),
30
- 'styles' => __( 'Styles', 'jupiterx-core' ),
31
- ],
32
- 'popups' => $popups,
33
- 'help' => [
34
- 'url' => 'https://themes.artbees.net/docs/assigning-the-footer-globally',
35
- 'title' => __( 'Assigning the Footer Globally', 'jupiterx-core' ),
36
- ],
37
- ] );
38
-
39
- // Settings tab.
40
- JupiterX_Customizer::add_section( 'jupiterx_footer_settings', [
41
- 'popup' => 'jupiterx_footer',
42
- 'type' => 'pane',
43
- 'pane' => [
44
- 'type' => 'tab',
45
- 'id' => 'settings',
46
- ],
47
- ] );
48
-
49
- // Styles tab.
50
- JupiterX_Customizer::add_section( 'jupiterx_footer_styles', [
51
- 'popup' => 'jupiterx_footer',
52
- 'type' => 'pane',
53
- 'pane' => [
54
- 'type' => 'tab',
55
- 'id' => 'styles',
56
- ],
57
- ] );
58
-
59
- // Styles warning.
60
- JupiterX_Customizer::add_field( [
61
- 'type' => 'jupiterx-alert',
62
- 'settings' => 'jupiterx_footer_styles_warning',
63
- 'section' => 'jupiterx_footer_styles',
64
- 'label' => __( 'Learn how to use the following settings properly.', 'jupiterx-core' ),
65
- 'jupiterx_url' => 'https://themes.artbees.net/docs/plugin-conflicts-with-jupiter-x',
66
- 'active_callback' => function() {
67
- return class_exists( '\ElementorPro\Plugin' ) && jupiterx_is_help_links();
68
- },
69
- ] );
70
-
71
- // Styles tab > Widgets child popups.
72
- JupiterX_Customizer::add_field( [
73
- 'type' => 'jupiterx-child-popup',
74
- 'settings' => 'jupiterx_footer_styles_popups',
75
- 'section' => 'jupiterx_footer_styles',
76
- 'target' => 'jupiterx_footer',
77
- 'choices' => [
78
- 'widgets_title' => __( 'Widgets Title', 'jupiterx-core' ),
79
- 'widgets_text' => __( 'Widgets Text', 'jupiterx-core' ),
80
- 'widgets_link' => __( 'Widgets Link', 'jupiterx-core' ),
81
- 'widgets_thumbnail' => __( 'Widgets Thumbnail', 'jupiterx-core' ),
82
- 'widgets_container' => __( 'Widgets Container', 'jupiterx-core' ),
83
- 'widgets_divider' => __( 'Widgets Divider', 'jupiterx-core' ),
84
- 'widget_area_container' => __( 'Widget Area Container', 'jupiterx-core' ),
85
- ],
86
- 'active_callback' => [
87
- [
88
- 'setting' => 'jupiterx_footer_widget_area',
89
- 'operator' => '===',
90
- 'value' => true,
91
- ],
92
- [
93
- 'setting' => 'jupiterx_footer_type',
94
- 'operator' => '!=',
95
- 'value' => '_custom',
96
- ],
97
- ],
98
- ] );
99
-
100
- // Styles tab > Subfooter child popups (sortable).
101
- JupiterX_Customizer::add_field( [
102
- 'type' => 'jupiterx-child-popup',
103
- 'settings' => 'jupiterx_footer_sub_sort_content',
104
- 'section' => 'jupiterx_footer_styles',
105
- 'target' => 'jupiterx_footer',
106
- 'sortable' => true,
107
- 'default' => [ 'sub_menu', 'sub_copyright' ],
108
- 'choices' => [
109
- 'sub_copyright' => __( 'Sub Footer Copyright', 'jupiterx-core' ),
110
- 'sub_menu' => __( 'Sub Footer Menu', 'jupiterx-core' ),
111
- ],
112
- 'active_callback' => [
113
- [
114
- 'setting' => 'jupiterx_footer_sub',
115
- 'operator' => '===',
116
- 'value' => true,
117
- ],
118
- [
119
- 'setting' => 'jupiterx_footer_type',
120
- 'operator' => '!=',
121
- 'value' => '_custom',
122
- ],
123
- ],
124
- ] );
125
-
126
- // Styles tab > Subfooter child popups (static).
127
- JupiterX_Customizer::add_field( [
128
- 'type' => 'jupiterx-child-popup',
129
- 'settings' => 'jupiterx_footer_sub_styles_popups',
130
- 'section' => 'jupiterx_footer_styles',
131
- 'target' => 'jupiterx_footer',
132
- 'choices' => [
133
- 'sub_container' => __( 'Sub Footer Container', 'jupiterx-core' ),
134
- ],
135
- 'active_callback' => [
136
- [
137
- 'setting' => 'jupiterx_footer_sub',
138
- 'operator' => '===',
139
- 'value' => true,
140
- ],
141
- [
142
- 'setting' => 'jupiterx_footer_type',
143
- 'operator' => '!=',
144
- 'value' => '_custom',
145
- ],
146
- ],
147
- ] );
148
-
149
- // Create popup children.
150
- foreach ( $popups as $popup_id => $label ) {
151
- JupiterX_Customizer::add_section( 'jupiterx_footer_' . $popup_id, [
152
- 'popup' => 'jupiterx_footer',
153
- 'type' => 'pane',
154
- 'pane' => [
155
- 'type' => 'popup',
156
- 'id' => $popup_id,
157
- ],
158
- ] );
159
- }
160
-
161
- // Load all the settings.
162
- foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
163
- require_once $setting;
164
- }
1
+ <?php
2
+ /**
3
+ * Add Jupiter Footer popup and tabs to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ add_action( 'jupiterx_footer_settings_after_section', 'jupiterx_dependency_notice_handler', 10 );
11
+
12
+ // Popup.
13
+ JupiterX_Customizer::add_section( 'jupiterx_footer', [
14
+ 'title' => __( 'Footer', 'jupiterx-core' ),
15
+ 'type' => 'container',
16
+ 'priority' => 130,
17
+ 'tabs' => [
18
+ 'settings' => __( 'Settings', 'jupiterx-core' ),
19
+ 'styles' => __( 'Styles', 'jupiterx-core' ),
20
+ ],
21
+ 'boxes' => [
22
+ 'settings' => [
23
+ 'label' => __( 'Settings', 'jupiterx-core' ),
24
+ 'tab' => 'settings',
25
+ ],
26
+ 'widgets_title' => [
27
+ 'label' => __( 'Widgets Title', 'jupiterx-core' ),
28
+ 'tab' => 'styles',
29
+ ],
30
+ 'widgets_text' => [
31
+ 'label' => __( 'Widgets Text', 'jupiterx-core' ),
32
+ 'tab' => 'styles',
33
+ ],
34
+ 'widgets_link' => [
35
+ 'label' => __( 'Widgets Link', 'jupiterx-core' ),
36
+ 'tab' => 'styles',
37
+ ],
38
+ 'widgets_thumbnail' => [
39
+ 'label' => __( 'Widgets Thumbnail', 'jupiterx-core' ),
40
+ 'tab' => 'styles',
41
+ ],
42
+ 'widgets_container' => [
43
+ 'label' => __( 'Widgets Container', 'jupiterx-core' ),
44
+ 'tab' => 'styles',
45
+ ],
46
+ 'widgets_divider' => [
47
+ 'label' => __( 'Widgets Divider', 'jupiterx-core' ),
48
+ 'tab' => 'styles',
49
+ ],
50
+ 'widget_area_container' => [
51
+ 'label' => __( 'Widget Area Container', 'jupiterx-core' ),
52
+ 'tab' => 'styles',
53
+ ],
54
+ 'sub_copyright' => [
55
+ 'label' => __( 'Sub Footer Copyright', 'jupiterx-core' ),
56
+ 'tab' => 'styles',
57
+ ],
58
+ 'sub_menu' => [
59
+ 'label' => __( 'Sub Footer Menu', 'jupiterx-core' ),
60
+ 'tab' => 'styles',
61
+ ],
62
+ 'sub_container' => [
63
+ 'label' => __( 'Sub Footer Container', 'jupiterx-core' ),
64
+ 'tab' => 'styles',
65
+ ],
66
+ 'empty_notice' => array(
67
+ 'label' => __( 'Notice', 'jupiterx-core' ),
68
+ 'tab' => 'styles',
69
+ ),
70
+ ],
71
+ 'help' => [
72
+ 'url' => 'https://themes.artbees.net/docs/assigning-the-footer-globally',
73
+ 'title' => __( 'Assigning the Footer Globally', 'jupiterx-core' ),
74
+ ],
75
+ 'group' => 'template_parts',
76
+ 'icon' => 'footer',
77
+ ] );
78
+
79
+ // Styles warning.
80
+ JupiterX_Customizer::add_field( [
81
+ 'type' => 'jupiterx-alert',
82
+ 'settings' => 'jupiterx_footer_styles_warning',
83
+ 'section' => 'jupiterx_footer_styles',
84
+ 'label' => __( 'Learn how to use the following settings properly.', 'jupiterx-core' ),
85
+ 'jupiterx_url' => 'https://themes.artbees.net/docs/plugin-conflicts-with-jupiter-x',
86
+ 'active_callback' => function() {
87
+ return class_exists( '\ElementorPro\Plugin' ) && jupiterx_is_help_links();
88
+ },
89
+ ] );
90
+
91
+ // Load all the settings.
92
+ foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
93
+ require_once $setting;
94
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/customizer/settings/footer/settings.php CHANGED
@@ -1,264 +1,359 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Footer > Settings tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_footer_settings';
11
-
12
- // Warning.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-alert',
15
- 'settings' => 'jupiterx_footer_warning',
16
- 'section' => $section,
17
- 'label' => __( 'Learn how to use the following settings properly.', 'jupiterx-core' ),
18
- 'jupiterx_url' => 'https://themes.artbees.net/docs/plugin-conflicts-with-jupiter-x',
19
- 'active_callback' => function() {
20
- return class_exists( '\ElementorPro\Plugin' ) && jupiterx_is_help_links();
21
- },
22
- ] );
23
-
24
- // Type.
25
- JupiterX_Customizer::add_field( [
26
- 'type' => 'jupiterx-choose',
27
- 'settings' => 'jupiterx_footer_type',
28
- 'section' => $section,
29
- 'label' => __( 'Type', 'jupiterx-core' ),
30
- 'column' => '6',
31
- 'default' => '',
32
- 'choices' => [
33
- '' => [
34
- 'label' => __( 'Default', 'jupiterx-core' ),
35
- ],
36
- '_custom' => [
37
- 'label' => __( 'Custom', 'jupiterx-core' ),
38
- 'pro' => true,
39
- ],
40
- ],
41
- ] );
42
-
43
- // Behavior.
44
- JupiterX_Customizer::add_field( [
45
- 'type' => 'jupiterx-choose',
46
- 'settings' => 'jupiterx_footer_behavior',
47
- 'section' => $section,
48
- 'label' => __( 'Behavior', 'jupiterx-core' ),
49
- 'default' => 'static',
50
- 'column' => '6',
51
- 'choices' => [
52
- 'static' => __( 'Static', 'jupiterx-core' ),
53
- 'fixed' => __( 'Fixed', 'jupiterx-core' ),
54
- ],
55
- 'active_callback' => [
56
- [
57
- 'setting' => 'jupiterx_footer_type',
58
- 'operator' => '===',
59
- 'value' => '',
60
- ],
61
- ],
62
- ] );
63
-
64
- // Widget area.
65
- JupiterX_Customizer::add_field( [
66
- 'type' => 'jupiterx-toggle',
67
- 'settings' => 'jupiterx_footer_widget_area',
68
- 'section' => $section,
69
- 'label' => __( 'Widget Area', 'jupiterx-core' ),
70
- 'column' => '6',
71
- 'default' => false,
72
- 'active_callback' => [
73
- [
74
- 'setting' => 'jupiterx_footer_type',
75
- 'operator' => '===',
76
- 'value' => '',
77
- ],
78
- ],
79
- ] );
80
-
81
- $widget_area_enabled = [
82
- [
83
- 'setting' => 'jupiterx_footer_type',
84
- 'operator' => '===',
85
- 'value' => '',
86
- ],
87
- [
88
- 'setting' => 'jupiterx_footer_widget_area',
89
- 'operator' => '===',
90
- 'value' => true,
91
- ],
92
- ];
93
-
94
- // Full width.
95
- JupiterX_Customizer::add_field( [
96
- 'type' => 'jupiterx-toggle',
97
- 'settings' => 'jupiterx_footer_widgets_full_width',
98
- 'section' => $section,
99
- 'label' => __( 'Full Width', 'jupiterx-core' ),
100
- 'column' => '6',
101
- 'default' => false,
102
- 'active_callback' => $widget_area_enabled,
103
- ] );
104
-
105
- // Layout columns.
106
- JupiterX_Customizer::add_field( [
107
- 'type' => 'jupiterx-radio-image',
108
- 'settings' => 'jupiterx_footer_widgets_layout',
109
- 'section' => $section,
110
- 'label' => __( 'Layout', 'jupiterx-core' ),
111
- 'default' => 'footer_layout_01',
112
- 'choices' => [
113
- 'footer_layout_01' => 'footer-layout-01',
114
- 'footer_layout_02' => 'footer-layout-02',
115
- 'footer_layout_03' => 'footer-layout-03',
116
- 'footer_layout_04' => 'footer-layout-04',
117
- 'footer_layout_05' => 'footer-layout-05',
118
- 'footer_layout_06' => 'footer-layout-06',
119
- 'footer_layout_07' => 'footer-layout-07',
120
- 'footer_layout_08' => 'footer-layout-08',
121
- 'footer_layout_09' => 'footer-layout-09',
122
- 'footer_layout_10' => 'footer-layout-10',
123
- 'footer_layout_11' => 'footer-layout-11',
124
- 'footer_layout_12' => 'footer-layout-12',
125
- 'footer_layout_13' => 'footer-layout-13',
126
- 'footer_layout_14' => 'footer-layout-14',
127
- 'footer_layout_15' => 'footer-layout-15',
128
- 'footer_layout_16' => 'footer-layout-16',
129
- 'footer_layout_17' => 'footer-layout-17',
130
- ],
131
- 'active_callback' => $widget_area_enabled,
132
- ] );
133
-
134
- // Enable on tablet (widget area).
135
- JupiterX_Customizer::add_field( [
136
- 'type' => 'jupiterx-toggle',
137
- 'settings' => 'jupiterx_footer_widget_area_tablet',
138
- 'css_var' => 'footer-widget-area-tablet',
139
- 'section' => $section,
140
- 'label' => __( 'Enable on Tablet', 'jupiterx-core' ),
141
- 'column' => '6',
142
- 'default' => true,
143
- 'active_callback' => $widget_area_enabled,
144
- ] );
145
-
146
- // Enable on mobile (widget area).
147
- JupiterX_Customizer::add_field( [
148
- 'type' => 'jupiterx-toggle',
149
- 'settings' => 'jupiterx_footer_widget_area_mobile',
150
- 'css_var' => 'footer-widget-area-mobile',
151
- 'section' => $section,
152
- 'label' => __( 'Enable on Mobile', 'jupiterx-core' ),
153
- 'column' => '6',
154
- 'default' => true,
155
- 'active_callback' => $widget_area_enabled,
156
- ] );
157
-
158
- // Pro Box.
159
- JupiterX_Customizer::add_field( [
160
- 'type' => 'jupiterx-pro-box',
161
- 'settings' => 'jupiterx_footer_custom_pro_box',
162
- 'section' => $section,
163
- 'active_callback' => [
164
- [
165
- 'setting' => 'jupiterx_footer_type',
166
- 'operator' => '===',
167
- 'value' => '_custom',
168
- ],
169
- ],
170
- ] );
171
-
172
- // Divider.
173
- JupiterX_Customizer::add_field( [
174
- 'type' => 'jupiterx-divider',
175
- 'settings' => 'jupiterx_footer_divider',
176
- 'column' => '12',
177
- 'section' => $section,
178
- 'active_callback' => [
179
- [
180
- 'setting' => 'jupiterx_footer_type',
181
- 'operator' => '===',
182
- 'value' => '',
183
- ],
184
- ],
185
- ] );
186
-
187
- // Enable sub footer.
188
- JupiterX_Customizer::add_field( [
189
- 'type' => 'jupiterx-toggle',
190
- 'settings' => 'jupiterx_footer_sub',
191
- 'section' => $section,
192
- 'label' => __( 'Sub Footer', 'jupiterx-core' ),
193
- 'column' => '6',
194
- 'default' => true,
195
- 'active_callback' => [
196
- [
197
- 'setting' => 'jupiterx_footer_type',
198
- 'operator' => '===',
199
- 'value' => '',
200
- ],
201
- ],
202
- ] );
203
-
204
- $footer_sub_enabled = [
205
- [
206
- 'setting' => 'jupiterx_footer_sub',
207
- 'operator' => '===',
208
- 'value' => true,
209
- ],
210
- [
211
- 'setting' => 'jupiterx_footer_type',
212
- 'operator' => '===',
213
- 'value' => '',
214
- ],
215
- ];
216
-
217
- // Full width.
218
- JupiterX_Customizer::add_field( [
219
- 'type' => 'jupiterx-toggle',
220
- 'settings' => 'jupiterx_footer_sub_full_width',
221
- 'section' => $section,
222
- 'label' => __( 'Full Width', 'jupiterx-core' ),
223
- 'column' => '6',
224
- 'default' => false,
225
- 'active_callback' => $footer_sub_enabled,
226
- ] );
227
-
228
- // Display elements.
229
- JupiterX_Customizer::add_field( [
230
- 'type' => 'jupiterx-multicheck',
231
- 'settings' => 'jupiterx_footer_sub_elements',
232
- 'section' => $section,
233
- 'label' => __( 'Display Elements', 'jupiterx-core' ),
234
- 'default' => [ 'copyright', 'menu' ],
235
- 'choices' => [
236
- 'copyright' => __( 'Copyright Text', 'jupiterx-core' ),
237
- 'menu' => __( 'Menu', 'jupiterx-core' ),
238
- ],
239
- 'active_callback' => $footer_sub_enabled,
240
- ] );
241
-
242
- // Enable on tablet (sub footer).
243
- JupiterX_Customizer::add_field( [
244
- 'type' => 'jupiterx-toggle',
245
- 'settings' => 'jupiterx_footer_sub_tablet',
246
- 'css_var' => 'footer-sub-tablet',
247
- 'section' => $section,
248
- 'label' => __( 'Enable on Tablet', 'jupiterx-core' ),
249
- 'column' => '6',
250
- 'default' => true,
251
- 'active_callback' => $footer_sub_enabled,
252
- ] );
253
-
254
- // Enable on mobile (sub footer).
255
- JupiterX_Customizer::add_field( [
256
- 'type' => 'jupiterx-toggle',
257
- 'settings' => 'jupiterx_footer_sub_mobile',
258
- 'css_var' => 'footer-sub-mobile',
259
- 'section' => $section,
260
- 'label' => __( 'Enable on Mobile', 'jupiterx-core' ),
261
- 'column' => '6',
262
- 'default' => true,
263
- 'active_callback' => $footer_sub_enabled,
264
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Footer > Settings tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_footer';
11
+
12
+ // Warning.
13
+ JupiterX_Customizer::add_field( [
14
+ 'type' => 'jupiterx-alert',
15
+ 'settings' => 'jupiterx_footer_warning',
16
+ 'section' => $section,
17
+ 'box' => 'settings',
18
+ 'label' => __( 'Learn how to use the following settings properly.', 'jupiterx-core' ),
19
+ 'jupiterx_url' => 'https://themes.artbees.net/docs/plugin-conflicts-with-jupiter-x',
20
+ 'active_callback' => function() {
21
+ return class_exists( '\ElementorPro\Plugin' ) && jupiterx_is_help_links();
22
+ },
23
+ ] );
24
+
25
+ // Type.
26
+ JupiterX_Customizer::add_field( [
27
+ 'type' => 'jupiterx-choose',
28
+ 'settings' => 'jupiterx_footer_type',
29
+ 'section' => $section,
30
+ 'box' => 'settings',
31
+ 'label' => __( 'Type', 'jupiterx-core' ),
32
+ 'priority' => 5,
33
+ 'default' => '',
34
+ 'choices' => [
35
+ '' => [
36
+ 'label' => __( 'Default', 'jupiterx-core' ),
37
+ ],
38
+ '_custom' => [
39
+ 'label' => __( 'Custom', 'jupiterx-core' ),
40
+ 'pro' => true,
41
+ ],
42
+ ],
43
+ ] );
44
+
45
+ // Behavior.
46
+ JupiterX_Customizer::add_field( [
47
+ 'type' => 'jupiterx-choose',
48
+ 'settings' => 'jupiterx_footer_behavior',
49
+ 'section' => $section,
50
+ 'box' => 'settings',
51
+ 'label' => __( 'Behavior', 'jupiterx-core' ),
52
+ 'default' => 'static',
53
+ 'priority' => 15,
54
+ 'choices' => [
55
+ 'static' => __( 'Static', 'jupiterx-core' ),
56
+ 'fixed' => __( 'Fixed', 'jupiterx-core' ),
57
+ ],
58
+ 'active_callback' => [
59
+ [
60
+ 'setting' => 'jupiterx_footer_type',
61
+ 'operator' => '===',
62
+ 'value' => '',
63
+ ],
64
+ ],
65
+ ] );
66
+
67
+ // Widget area.
68
+ JupiterX_Customizer::add_field( [
69
+ 'type' => 'jupiterx-toggle',
70
+ 'settings' => 'jupiterx_footer_widget_area',
71
+ 'section' => $section,
72
+ 'box' => 'settings',
73
+ 'label' => __( 'Widget Area', 'jupiterx-core' ),
74
+ 'default' => false,
75
+ 'active_callback' => [
76
+ [
77
+ 'setting' => 'jupiterx_footer_type',
78
+ 'operator' => '===',
79
+ 'value' => '',
80
+ ],
81
+ ],
82
+ ] );
83
+
84
+ $widget_area_enabled = [
85
+ [
86
+ 'setting' => 'jupiterx_footer_type',
87
+ 'operator' => '===',
88
+ 'value' => '',
89
+ ],
90
+ [
91
+ 'setting' => 'jupiterx_footer_widget_area',
92
+ 'operator' => '===',
93
+ 'value' => true,
94
+ ],
95
+ ];
96
+
97
+ // Full width.
98
+ JupiterX_Customizer::add_field( [
99
+ 'type' => 'jupiterx-toggle',
100
+ 'settings' => 'jupiterx_footer_widgets_full_width',
101
+ 'section' => $section,
102
+ 'box' => 'settings',
103
+ 'label' => __( 'Full Width', 'jupiterx-core' ),
104
+ 'default' => false,
105
+ 'active_callback' => $widget_area_enabled,
106
+ ] );
107
+
108
+ // Layout columns.
109
+ JupiterX_Customizer::add_field( [
110
+ 'type' => 'jupiterx-radio-image',
111
+ 'settings' => 'jupiterx_footer_widgets_layout',
112
+ 'section' => $section,
113
+ 'box' => 'settings',
114
+ 'label' => __( 'Layout', 'jupiterx-core' ),
115
+ 'default' => 'footer_layout_01',
116
+ 'choices' => [
117
+ 'footer_layout_01' => 'footer-layout-01',
118
+ 'footer_layout_02' => 'footer-layout-02',
119
+ 'footer_layout_03' => 'footer-layout-03',
120
+ 'footer_layout_04' => 'footer-layout-04',
121
+ 'footer_layout_05' => 'footer-layout-05',
122
+ 'footer_layout_06' => 'footer-layout-06',
123
+ 'footer_layout_07' => 'footer-layout-07',
124
+ 'footer_layout_08' => 'footer-layout-08',
125
+ 'footer_layout_09' => 'footer-layout-09',
126
+ 'footer_layout_10' => 'footer-layout-10',
127
+ 'footer_layout_11' => 'footer-layout-11',
128
+ 'footer_layout_12' => 'footer-layout-12',
129
+ 'footer_layout_13' => 'footer-layout-13',
130
+ 'footer_layout_14' => 'footer-layout-14',
131
+ 'footer_layout_15' => 'footer-layout-15',
132
+ 'footer_layout_16' => 'footer-layout-16',
133
+ 'footer_layout_17' => 'footer-layout-17',
134
+ ],
135
+ 'active_callback' => $widget_area_enabled,
136
+ ] );
137
+
138
+ // Enable on tablet (widget area).
139
+ JupiterX_Customizer::add_field( [
140
+ 'type' => 'jupiterx-toggle',
141
+ 'settings' => 'jupiterx_footer_widget_area_tablet',
142
+ 'css_var' => 'footer-widget-area-tablet',
143
+ 'section' => $section,
144
+ 'box' => 'settings',
145
+ 'label' => __( 'Enable on Tablet', 'jupiterx-core' ),
146
+ 'default' => true,
147
+ 'active_callback' => $widget_area_enabled,
148
+ ] );
149
+
150
+ // Enable on mobile (widget area).
151
+ JupiterX_Customizer::add_field( [
152
+ 'type' => 'jupiterx-toggle',
153
+ 'settings' => 'jupiterx_footer_widget_area_mobile',
154
+ 'css_var' => 'footer-widget-area-mobile',
155
+ 'section' => $section,
156
+ 'box' => 'settings',
157
+ 'label' => __( 'Enable on Mobile', 'jupiterx-core' ),
158
+ 'column' => '6',
159
+ 'default' => true,
160
+ 'active_callback' => $widget_area_enabled,
161
+ ] );
162
+
163
+ // Pro Box.
164
+ JupiterX_Customizer::add_field( [
165
+ 'type' => 'jupiterx-pro-box',
166
+ 'settings' => 'jupiterx_footer_custom_pro_box',
167
+ 'section' => $section,
168
+ 'box' => 'settings',
169
+ 'active_callback' => [
170
+ [
171
+ 'setting' => 'jupiterx_footer_type',
172
+ 'operator' => '===',
173
+ 'value' => '_custom',
174
+ ],
175
+ ],
176
+ ] );
177
+
178
+ // Divider.
179
+ JupiterX_Customizer::add_field( [
180
+ 'type' => 'jupiterx-divider',
181
+ 'settings' => 'jupiterx_footer_divider',
182
+ 'column' => '12',
183
+ 'section' => $section,
184
+ 'box' => 'settings',
185
+ 'active_callback' => [
186
+ [
187
+ 'setting' => 'jupiterx_footer_type',
188
+ 'operator' => '===',
189
+ 'value' => '',
190
+ ],
191
+ ],
192
+ ] );
193
+
194
+ // Enable sub footer.
195
+ JupiterX_Customizer::add_field( [
196
+ 'type' => 'jupiterx-toggle',
197
+ 'settings' => 'jupiterx_footer_sub',
198
+ 'section' => $section,
199
+ 'box' => 'settings',
200
+ 'label' => __( 'Sub Footer', 'jupiterx-core' ),
201
+ 'column' => '6',
202
+ 'default' => true,
203
+ 'active_callback' => [
204
+ [
205
+ 'setting' => 'jupiterx_footer_type',
206
+ 'operator' => '===',
207
+ 'value' => '',
208
+ ],
209
+ ],
210
+ ] );
211
+
212
+ $footer_sub_enabled = [
213
+ [
214
+ 'setting' => 'jupiterx_footer_sub',
215
+ 'operator' => '===',
216
+ 'value' => true,
217
+ ],
218
+ [
219
+ 'setting' => 'jupiterx_footer_type',
220
+ 'operator' => '===',
221
+ 'value' => '',
222
+ ],
223
+ ];
224
+
225
+ // Label.
226
+ JupiterX_Customizer::add_field( [
227
+ 'type' => 'jupiterx-label',
228
+ 'settings' => 'jupiterx_footer_sub_sort_content_label_1',
229
+ 'section' => $section,
230
+ 'box' => 'settings',
231
+ 'label' => __( 'Sortable Elements', 'jupiterx-core' ),
232
+ 'active_callback' => [
233
+ [
234
+ 'setting' => 'jupiterx_footer_sub',
235
+ 'operator' => '===',
236
+ 'value' => true,
237
+ ],
238
+ [
239
+ 'setting' => 'jupiterx_footer_type',
240
+ 'operator' => '!=',
241
+ 'value' => '_custom',
242
+ ],
243
+ ],
244
+ ] );
245
+
246
+ // Subfooter child popups (sortable).
247
+ JupiterX_Customizer::add_field( [
248
+ 'type' => 'jupiterx-child-popup',
249
+ 'settings' => 'jupiterx_footer_sub_sort_content',
250
+ 'section' => $section,
251
+ 'box' => 'settings',
252
+ 'target' => 'jupiterx_footer',
253
+ 'sortable' => true,
254
+ 'default' => [ 'sub_menu', 'sub_copyright' ],
255
+ 'choices' => [
256
+ 'sub_copyright' => __( 'Sub Footer Copyright', 'jupiterx-core' ),
257
+ 'sub_menu' => __( 'Sub Footer Menu', 'jupiterx-core' ),
258
+ ],
259
+ 'active_callback' => [
260
+ [
261
+ 'setting' => 'jupiterx_footer_sub',
262
+ 'operator' => '===',
263
+ 'value' => true,
264
+ ],
265
+ [
266
+ 'setting' => 'jupiterx_footer_type',
267
+ 'operator' => '!=',
268
+ 'value' => '_custom',
269
+ ],
270
+ ],
271
+ ] );
272
+
273
+ // Divider.
274
+ JupiterX_Customizer::add_field( [
275
+ 'type' => 'jupiterx-divider',
276
+ 'settings' => 'jupiterx_footer_sub_sort_content_divider_1',
277
+ 'section' => $section,
278
+ 'box' => 'settings',
279
+ 'active_callback' => [
280
+ [
281
+ 'setting' => 'jupiterx_footer_sub',
282
+ 'operator' => '===',
283
+ 'value' => true,
284
+ ],
285
+ [
286
+ 'setting' => 'jupiterx_footer_type',
287
+ 'operator' => '!=',
288
+ 'value' => '_custom',
289
+ ],
290
+ ],
291
+ ] );
292
+
293
+ // Full width.
294
+ JupiterX_Customizer::add_field( [
295
+ 'type' => 'jupiterx-toggle',
296
+ 'settings' => 'jupiterx_footer_sub_full_width',
297
+ 'section' => $section,
298
+ 'box' => 'settings',
299
+ 'label' => __( 'Full Width', 'jupiterx-core' ),
300
+ 'column' => '6',
301
+ 'default' => false,
302
+ 'active_callback' => $footer_sub_enabled,
303
+ ] );
304
+
305
+ // Display elements.
306
+ JupiterX_Customizer::add_field( [
307
+ 'type' => 'jupiterx-multicheck',
308
+ 'settings' => 'jupiterx_footer_sub_elements',
309
+ 'section' => $section,
310
+ 'box' => 'settings',
311
+ 'label' => __( 'Display Elements', 'jupiterx-core' ),
312
+ 'default' => [ 'copyright', 'menu' ],
313
+ 'choices' => [
314
+ 'copyright' => __( 'Copyright Text', 'jupiterx-core' ),
315
+ 'menu' => __( 'Menu', 'jupiterx-core' ),
316
+ ],
317
+ 'active_callback' => $footer_sub_enabled,
318
+ ] );
319
+
320
+ // Enable on tablet (sub footer).
321
+ JupiterX_Customizer::add_field( [
322
+ 'type' => 'jupiterx-toggle',
323
+ 'settings' => 'jupiterx_footer_sub_tablet',
324
+ 'css_var' => 'footer-sub-tablet',
325
+ 'section' => $section,
326
+ 'box' => 'settings',
327
+ 'label' => __( 'Enable on Tablet', 'jupiterx-core' ),
328
+ 'default' => true,
329
+ 'active_callback' => $footer_sub_enabled,
330
+ ] );
331
+
332
+ // Enable on mobile (sub footer).
333
+ JupiterX_Customizer::add_field( [
334
+ 'type' => 'jupiterx-toggle',
335
+ 'settings' => 'jupiterx_footer_sub_mobile',
336
+ 'css_var' => 'footer-sub-mobile',
337
+ 'section' => $section,
338
+ 'box' => 'settings',
339
+ 'label' => __( 'Enable on Mobile', 'jupiterx-core' ),
340
+ 'default' => true,
341
+ 'active_callback' => $footer_sub_enabled,
342
+ ] );
343
+
344
+ // Warning.
345
+ JupiterX_Customizer::add_field( [
346
+ 'type' => 'jupiterx-alert',
347
+ 'settings' => 'jupiterx_footer_empty_notice',
348
+ 'section' => $section,
349
+ 'box' => 'empty_notice',
350
+ 'label' => __( 'There are no style settings available for custom templates.', 'jupiterx-core' ),
351
+ 'priority' => 10,
352
+ 'active_callback' => [
353
+ [
354
+ 'setting' => 'jupiterx_footer_type',
355
+ 'operator' => '===',
356
+ 'value' => '_custom',
357
+ ],
358
+ ],
359
+ ] );
includes/customizer/settings/footer/subfooter-container.php CHANGED
@@ -1,77 +1,102 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Footer > Sub Footer > Styles > Container popup to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_footer_sub_container';
11
-
12
- // Background.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-background',
15
- 'settings' => 'jupiterx_footer_sub_container_background',
16
- 'section' => $section,
17
- 'css_var' => 'subfooter-container-background',
18
- 'transport' => 'postMessage',
19
- 'default' => [
20
- 'color' => '#343a40',
21
- ],
22
- 'output' => [
23
- [
24
- 'element' => '.jupiterx-subfooter',
25
- ],
26
- ],
27
- ] );
28
-
29
- // Border.
30
- JupiterX_Customizer::add_field( [
31
- 'type' => 'jupiterx-border',
32
- 'settings' => 'jupiterx_footer_sub_container_border',
33
- 'section' => $section,
34
- 'css_var' => 'subfooter-container-border',
35
- 'exclude' => [ 'style', 'size', 'radius' ],
36
- 'label' => __( 'Border', 'jupiterx-core' ),
37
- 'transport' => 'postMessage',
38
- 'default' => [
39
- 'width' => [
40
- 'size' => 1,
41
- 'unit' => 'px',
42
- ],
43
- ],
44
- 'output' => [
45
- [
46
- 'element' => '.jupiterx-subfooter',
47
- 'property' => 'border-top',
48
- ],
49
- ],
50
- ] );
51
-
52
- // Divider.
53
- JupiterX_Customizer::add_field( [
54
- 'type' => 'jupiterx-divider',
55
- 'settings' => 'jupiterx_footer_sub_container_divider',
56
- 'section' => $section,
57
- ] );
58
-
59
- // Spacing.
60
- JupiterX_Customizer::add_responsive_field( [
61
- 'type' => 'jupiterx-box-model',
62
- 'settings' => 'jupiterx_footer_sub_container_spacing',
63
- 'section' => $section,
64
- 'css_var' => 'subfooter-container',
65
- 'transport' => 'postMessage',
66
- 'default' => [
67
- 'desktop' => [
68
- 'padding_top' => 1.5,
69
- 'padding_bottom' => 1.5,
70
- ],
71
- ],
72
- 'output' => [
73
- [
74
- 'element' => '.jupiterx-subfooter',
75
- ],
76
- ],
77
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Footer > Sub Footer > Styles > Container popup to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_footer';
11
+
12
+ $subfooter_container_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_footer_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ // Background.
21
+ JupiterX_Customizer::add_field( [
22
+ 'type' => 'jupiterx-background',
23
+ 'settings' => 'jupiterx_footer_sub_container_background',
24
+ 'section' => $section,
25
+ 'box' => 'sub_container',
26
+ 'css_var' => 'subfooter-container-background',
27
+ 'transport' => 'postMessage',
28
+ 'default' => [
29
+ 'color' => '#343a40',
30
+ ],
31
+ 'output' => [
32
+ [
33
+ 'element' => '.jupiterx-subfooter',
34
+ ],
35
+ ],
36
+ 'active_callback' => $subfooter_container_condition,
37
+ ] );
38
+
39
+ // Label.
40
+ JupiterX_Customizer::add_field( [
41
+ 'type' => 'jupiterx-label',
42
+ 'label' => __( 'Border', 'jupiterx-core' ),
43
+ 'settings' => 'jupiterx_footer_sub_container_label',
44
+ 'section' => $section,
45
+ 'box' => 'sub_container',
46
+ 'active_callback' => $subfooter_container_condition,
47
+ ] );
48
+
49
+ // Border.
50
+ JupiterX_Customizer::add_field( [
51
+ 'type' => 'jupiterx-border',
52
+ 'settings' => 'jupiterx_footer_sub_container_border',
53
+ 'section' => $section,
54
+ 'box' => 'sub_container',
55
+ 'css_var' => 'subfooter-container-border',
56
+ 'exclude' => [ 'style', 'size', 'radius' ],
57
+ 'transport' => 'postMessage',
58
+ 'default' => [
59
+ 'width' => [
60
+ 'size' => 1,
61
+ 'unit' => 'px',
62
+ ],
63
+ ],
64
+ 'output' => [
65
+ [
66
+ 'element' => '.jupiterx-subfooter',
67
+ 'property' => 'border-top',
68
+ ],
69
+ ],
70
+ 'active_callback' => $subfooter_container_condition,
71
+ ] );
72
+
73
+ // Divider.
74
+ JupiterX_Customizer::add_field( [
75
+ 'type' => 'jupiterx-divider',
76
+ 'settings' => 'jupiterx_footer_sub_container_divider',
77
+ 'section' => $section,
78
+ 'box' => 'sub_container',
79
+ 'active_callback' => $subfooter_container_condition,
80
+ ] );
81
+
82
+ // Spacing.
83
+ JupiterX_Customizer::add_responsive_field( [
84
+ 'type' => 'jupiterx-box-model',
85
+ 'settings' => 'jupiterx_footer_sub_container_spacing',
86
+ 'section' => $section,
87
+ 'box' => 'sub_container',
88
+ 'css_var' => 'subfooter-container',
89
+ 'transport' => 'postMessage',
90
+ 'default' => [
91
+ 'desktop' => [
92
+ 'padding_top' => 1.5,
93
+ 'padding_bottom' => 1.5,
94
+ ],
95
+ ],
96
+ 'output' => [
97
+ [
98
+ 'element' => '.jupiterx-subfooter',
99
+ ],
100
+ ],
101
+ 'active_callback' => $subfooter_container_condition,
102
+ ] );
includes/customizer/settings/footer/subfooter-copyright.php CHANGED
@@ -1,52 +1,71 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Footer > Sub Footer > Styles > Copyright popup to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_footer_sub_copyright';
11
-
12
- // Typography.
13
- JupiterX_Customizer::add_responsive_field( [
14
- 'type' => 'jupiterx-typography',
15
- 'settings' => 'jupiterx_footer_sub_copyright_typography',
16
- 'section' => $section,
17
- 'css_var' => 'subfooter-copyright',
18
- 'transport' => 'postMessage',
19
- 'exclude' => [ 'line_height', 'text_transform' ],
20
- 'default' => [
21
- 'desktop' => [
22
- 'color' => '#f8f9fa',
23
- ],
24
- ],
25
- 'output' => [
26
- [
27
- 'element' => '.jupiterx-subfooter-copyright',
28
- ],
29
- ],
30
- ] );
31
-
32
- // Divider.
33
- JupiterX_Customizer::add_field( [
34
- 'type' => 'jupiterx-divider',
35
- 'settings' => 'jupiterx_footer_sub_copyright_divider',
36
- 'section' => $section,
37
- ] );
38
-
39
- // Spacing.
40
- JupiterX_Customizer::add_responsive_field( [
41
- 'type' => 'jupiterx-box-model',
42
- 'settings' => 'jupiterx_footer_sub_copyright_spacing',
43
- 'section' => $section,
44
- 'css_var' => 'subfooter-copyright',
45
- 'transport' => 'postMessage',
46
- 'exclude' => [ 'padding' ],
47
- 'output' => [
48
- [
49
- 'element' => '.jupiterx-subfooter-copyright',
50
- ],
51
- ],
52
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Footer > Sub Footer > Styles > Copyright popup to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_footer';
11
+
12
+ $subfooter_copyright_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_footer_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ [
19
+ 'setting' => 'jupiterx_footer_sub_elements',
20
+ 'operator' => 'contains',
21
+ 'value' => 'copyright',
22
+ ],
23
+ ];
24
+
25
+ // Typography.
26
+ JupiterX_Customizer::add_responsive_field( [
27
+ 'type' => 'jupiterx-typography',
28
+ 'settings' => 'jupiterx_footer_sub_copyright_typography',
29
+ 'section' => $section,
30
+ 'box' => 'sub_copyright',
31
+ 'css_var' => 'subfooter-copyright',
32
+ 'transport' => 'postMessage',
33
+ 'exclude' => [ 'line_height', 'text_transform' ],
34
+ 'default' => [
35
+ 'desktop' => [
36
+ 'color' => '#f8f9fa',
37
+ ],
38
+ ],
39
+ 'output' => [
40
+ [
41
+ 'element' => '.jupiterx-subfooter-copyright',
42
+ ],
43
+ ],
44
+ 'active_callback' => $subfooter_copyright_condition,
45
+ ] );
46
+
47
+ // Divider.
48
+ JupiterX_Customizer::add_field( [
49
+ 'type' => 'jupiterx-divider',
50
+ 'settings' => 'jupiterx_footer_sub_copyright_divider',
51
+ 'section' => $section,
52
+ 'box' => 'sub_copyright',
53
+ 'active_callback' => $subfooter_copyright_condition,
54
+ ] );
55
+
56
+ // Spacing.
57
+ JupiterX_Customizer::add_responsive_field( [
58
+ 'type' => 'jupiterx-box-model',
59
+ 'settings' => 'jupiterx_footer_sub_copyright_spacing',
60
+ 'section' => $section,
61
+ 'box' => 'sub_copyright',
62
+ 'css_var' => 'subfooter-copyright',
63
+ 'transport' => 'postMessage',
64
+ 'exclude' => [ 'padding' ],
65
+ 'output' => [
66
+ [
67
+ 'element' => '.jupiterx-subfooter-copyright',
68
+ ],
69
+ ],
70
+ 'active_callback' => $subfooter_copyright_condition,
71
+ ] );
includes/customizer/settings/footer/subfooter-menu.php CHANGED
@@ -1,137 +1,206 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Footer > Sub Footer > Styles > Menu popup to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_footer_sub_menu';
11
-
12
- // Typography.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-typography',
15
- 'settings' => 'jupiterx_footer_sub_menu_links_typography',
16
- 'section' => $section,
17
- 'responsive' => true,
18
- 'css_var' => 'subfooter-menu-links',
19
- 'transport' => 'postMessage',
20
- 'exclude' => [ 'line_height', 'text_transform' ],
21
- 'default' => [
22
- 'desktop' => [
23
- 'color' => '#f8f9fa',
24
- ],
25
- ],
26
- 'output' => [
27
- [
28
- 'element' => '.jupiterx-subfooter-menu li a',
29
- ],
30
- ],
31
- ] );
32
-
33
- // Space between.
34
- JupiterX_Customizer::add_field( [
35
- 'type' => 'jupiterx-input',
36
- 'settings' => 'jupiterx_footer_sub_menu_links_space_between',
37
- 'section' => $section,
38
- 'css_var' => 'subfooter-menu-links-space-between',
39
- 'column' => '4',
40
- 'icon' => 'space-between',
41
- 'units' => [ 'px' ],
42
- 'transport' => 'postMessage',
43
- 'default' => [
44
- 'size' => 9,
45
- 'unit' => 'px',
46
- ],
47
- 'output' => [
48
- [
49
- 'element' => '.jupiterx-subfooter-menu-container ul',
50
- 'property' => 'margin-left',
51
- 'value_pattern' => 'calc(-$ / 2)',
52
- ],
53
- [
54
- 'element' => '.jupiterx-subfooter-menu-container ul',
55
- 'property' => 'margin-right',
56
- 'value_pattern' => 'calc(-$ / 2)',
57
- ],
58
- [
59
- 'element' => '.jupiterx-subfooter-menu-container ul > li',
60
- 'property' => 'padding-left',
61
- 'value_pattern' => 'calc($ / 2)',
62
- ],
63
- [
64
- 'element' => '.jupiterx-subfooter-menu-container ul > li',
65
- 'property' => 'padding-right',
66
- 'value_pattern' => 'calc($ / 2)',
67
- ],
68
- ],
69
- ] );
70
-
71
- // Hover.
72
- JupiterX_Customizer::add_field( [
73
- 'type' => 'jupiterx-label',
74
- 'settings' => 'jupiterx_footer_sub_menu_label',
75
- 'section' => $section,
76
- 'label' => __( 'Hover', 'jupiterx-core' ),
77
- 'label_type' => 'fancy',
78
- 'color' => 'orange',
79
- ] );
80
-
81
- // Hover color.
82
- JupiterX_Customizer::add_field( [
83
- 'type' => 'jupiterx-color',
84
- 'settings' => 'jupiterx_footer_sub_menu_links_hover_color',
85
- 'section' => $section,
86
- 'css_var' => 'subfooter-menu-links-hover-color',
87
- 'column' => '3',
88
- 'icon' => 'font-color',
89
- 'transport' => 'postMessage',
90
- 'output' => [
91
- [
92
- 'element' => '.jupiterx-subfooter-menu li a:hover',
93
- 'property' => 'color',
94
- ],
95
- ],
96
- ] );
97
-
98
- // Hover text decoration.
99
- JupiterX_Customizer::add_field( [
100
- 'type' => 'jupiterx-select',
101
- 'settings' => 'jupiterx_footer_sub_menu_links_hover_text_decoration',
102
- 'section' => $section,
103
- 'css_var' => 'subfooter-menu-links-hover-text-decoration',
104
- 'column' => '6',
105
- 'icon' => 'text-decoration',
106
- 'placeholder' => __( 'Default', 'jupiterx-core' ),
107
- 'choices' => JupiterX_Customizer_Utils::get_text_decoration_choices(),
108
- 'transport' => 'postMessage',
109
- 'output' => [
110
- [
111
- 'element' => '.jupiterx-subfooter-menu li a:hover',
112
- 'property' => 'text-decoration',
113
- ],
114
- ],
115
- ] );
116
-
117
- // Divider.
118
- JupiterX_Customizer::add_field( [
119
- 'type' => 'jupiterx-divider',
120
- 'settings' => 'jupiterx_footer_sub_menu_divider',
121
- 'section' => $section,
122
- ] );
123
-
124
- // Spacing.
125
- JupiterX_Customizer::add_responsive_field( [
126
- 'type' => 'jupiterx-box-model',
127
- 'settings' => 'jupiterx_footer_sub_menu_spacing',
128
- 'section' => $section,
129
- 'css_var' => 'subfooter-menu',
130
- 'transport' => 'postMessage',
131
- 'exclude' => [ 'padding' ],
132
- 'output' => [
133
- [
134
- 'element' => '.jupiterx-subfooter-menu-container',
135
- ],
136
- ],
137
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Footer > Sub Footer > Styles > Menu popup to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_footer';
11
+
12
+ $subfooter_menu_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_footer_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ [
19
+ 'setting' => 'jupiterx_footer_sub_elements',
20
+ 'operator' => 'contains',
21
+ 'value' => 'menu',
22
+ ],
23
+ ];
24
+
25
+ $subfooter_menu_normal_condition = [
26
+ [
27
+ 'setting' => 'jupiterx_footer_type',
28
+ 'operator' => '===',
29
+ 'value' => '',
30
+ ],
31
+ [
32
+ 'setting' => 'jupiterx_footer_sub_menu_links_label',
33
+ 'operator' => '===',
34
+ 'value' => 'normal',
35
+ ],
36
+ [
37
+ 'setting' => 'jupiterx_footer_sub_elements',
38
+ 'operator' => 'contains',
39
+ 'value' => 'menu',
40
+ ],
41
+ ];
42
+
43
+ $subfooter_menu_hover_condition = [
44
+ [
45
+ 'setting' => 'jupiterx_footer_type',
46
+ 'operator' => '===',
47
+ 'value' => '',
48
+ ],
49
+ [
50
+ 'setting' => 'jupiterx_footer_sub_menu_links_label',
51
+ 'operator' => '===',
52
+ 'value' => 'hover',
53
+ ],
54
+ [
55
+ 'setting' => 'jupiterx_footer_sub_elements',
56
+ 'operator' => 'contains',
57
+ 'value' => 'menu',
58
+ ],
59
+ ];
60
+
61
+ // Space between.
62
+ JupiterX_Customizer::add_field( [
63
+ 'type' => 'jupiterx-input',
64
+ 'settings' => 'jupiterx_footer_sub_menu_links_space_between',
65
+ 'section' => $section,
66
+ 'box' => 'sub_menu',
67
+ 'css_var' => 'subfooter-menu-links-space-between',
68
+ 'label' => __( 'Space Between', 'jupiterx-core' ),
69
+ 'units' => [ 'px' ],
70
+ 'transport' => 'postMessage',
71
+ 'default' => [
72
+ 'size' => 9,
73
+ 'unit' => 'px',
74
+ ],
75
+ 'output' => [
76
+ [
77
+ 'element' => '.jupiterx-subfooter-menu-container ul',
78
+ 'property' => 'margin-left',
79
+ 'value_pattern' => 'calc(-$ / 2)',
80
+ ],
81
+ [
82
+ 'element' => '.jupiterx-subfooter-menu-container ul',
83
+ 'property' => 'margin-right',
84
+ 'value_pattern' => 'calc(-$ / 2)',
85
+ ],
86
+ [
87
+ 'element' => '.jupiterx-subfooter-menu-container ul > li',
88
+ 'property' => 'padding-left',
89
+ 'value_pattern' => 'calc($ / 2)',
90
+ ],
91
+ [
92
+ 'element' => '.jupiterx-subfooter-menu-container ul > li',
93
+ 'property' => 'padding-right',
94
+ 'value_pattern' => 'calc($ / 2)',
95
+ ],
96
+ ],
97
+ 'active_callback' => $subfooter_menu_condition,
98
+ ] );
99
+
100
+ // Hover label.
101
+ JupiterX_Customizer::add_field( [
102
+ 'type' => 'jupiterx-choose',
103
+ 'color' => 'orange',
104
+ 'settings' => 'jupiterx_footer_sub_menu_links_label',
105
+ 'section' => $section,
106
+ 'box' => 'sub_menu',
107
+ 'transport' => 'postMessage',
108
+ 'default' => 'normal',
109
+ 'choices' => [
110
+ 'normal' => [
111
+ 'label' => __( 'Normal', 'jupiterx-core' ),
112
+ ],
113
+ 'hover' => [
114
+ 'label' => __( 'Hover', 'jupiterx-core' ),
115
+ ],
116
+ ],
117
+ 'active_callback' => $subfooter_menu_condition,
118
+ ] );
119
+
120
+
121
+ // Typography.
122
+ JupiterX_Customizer::add_field( [
123
+ 'type' => 'jupiterx-typography',
124
+ 'settings' => 'jupiterx_footer_sub_menu_links_typography',
125
+ 'section' => $section,
126
+ 'box' => 'sub_menu',
127
+ 'responsive' => true,
128
+ 'css_var' => 'subfooter-menu-links',
129
+ 'transport' => 'postMessage',
130
+ 'exclude' => [ 'line_height', 'text_transform' ],
131
+ 'default' => [
132
+ 'desktop' => [
133
+ 'color' => '#f8f9fa',
134
+ ],
135
+ ],
136
+ 'output' => [
137
+ [
138
+ 'element' => '.jupiterx-subfooter-menu li a',
139
+ ],
140
+ ],
141
+ 'active_callback' => $subfooter_menu_normal_condition,
142
+ ] );
143
+
144
+ // Hover color.
145
+ JupiterX_Customizer::add_field( [
146
+ 'type' => 'jupiterx-color',
147
+ 'settings' => 'jupiterx_footer_sub_menu_links_hover_color',
148
+ 'section' => $section,
149
+ 'box' => 'sub_menu',
150
+ 'css_var' => 'subfooter-menu-links-hover-color',
151
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
152
+ 'transport' => 'postMessage',
153
+ 'output' => [
154
+ [
155
+ 'element' => '.jupiterx-subfooter-menu li a:hover',
156
+ 'property' => 'color',
157
+ ],
158
+ ],
159
+ 'active_callback' => $subfooter_menu_hover_condition,
160
+ ] );
161
+
162
+ // Hover text decoration.
163
+ JupiterX_Customizer::add_field( [
164
+ 'type' => 'jupiterx-select',
165
+ 'settings' => 'jupiterx_footer_sub_menu_links_hover_text_decoration',
166
+ 'section' => $section,
167
+ 'box' => 'sub_menu',
168
+ 'css_var' => 'subfooter-menu-links-hover-text-decoration',
169
+ 'label' => __( 'Text Decoration', 'jupiterx-core' ),
170
+ 'placeholder' => __( 'Default', 'jupiterx-core' ),
171
+ 'choices' => JupiterX_Customizer_Utils::get_text_decoration_choices(),
172
+ 'transport' => 'postMessage',
173
+ 'output' => [
174
+ [
175
+ 'element' => '.jupiterx-subfooter-menu li a:hover',
176
+ 'property' => 'text-decoration',
177
+ ],
178
+ ],
179
+ 'active_callback' => $subfooter_menu_hover_condition,
180
+ ] );
181
+
182
+ // Divider.
183
+ JupiterX_Customizer::add_field( [
184
+ 'type' => 'jupiterx-divider',
185
+ 'settings' => 'jupiterx_footer_sub_menu_divider',
186
+ 'section' => $section,
187
+ 'box' => 'sub_menu',
188
+ 'active_callback' => $subfooter_menu_condition,
189
+ ] );
190
+
191
+ // Spacing.
192
+ JupiterX_Customizer::add_responsive_field( [
193
+ 'type' => 'jupiterx-box-model',
194
+ 'settings' => 'jupiterx_footer_sub_menu_spacing',
195
+ 'section' => $section,
196
+ 'box' => 'sub_menu',
197
+ 'css_var' => 'subfooter-menu',
198
+ 'transport' => 'postMessage',
199
+ 'exclude' => [ 'padding' ],
200
+ 'output' => [
201
+ [
202
+ 'element' => '.jupiterx-subfooter-menu-container',
203
+ ],
204
+ ],
205
+ 'active_callback' => $subfooter_menu_condition,
206
+ ] );
includes/customizer/settings/footer/widget-area-container.php CHANGED
@@ -1,98 +1,115 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Layout > Styles > Footer Container popup to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_footer_widget_area_container';
11
-
12
- // Background.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-background',
15
- 'settings' => 'jupiterx_footer_widget_area_container_background',
16
- 'section' => $section,
17
- 'transport' => 'postMessage',
18
- 'css_var' => 'footer-widget-area-container-background',
19
- 'output' => [
20
- [
21
- 'element' => '.jupiterx-footer-widgets',
22
- ],
23
- ],
24
- ] );
25
-
26
- // Column gap.
27
- JupiterX_Customizer::add_field( [
28
- 'type' => 'jupiterx-input',
29
- 'settings' => 'jupiterx_footer_widget_area_container_column_gap',
30
- 'section' => $section,
31
- 'css_var' => 'footer-widget-area-container-column-gap',
32
- 'label' => __( 'Column Gap', 'jupiterx-core' ),
33
- 'column' => '3',
34
- 'units' => [ 'px', 'em', 'rem' ],
35
- 'transport' => 'postMessage',
36
- 'output' => [
37
- [
38
- 'element' => '.jupiterx-footer-widgets .row',
39
- 'property' => 'margin',
40
- 'value_pattern' => 'auto calc(-$ / 2)',
41
- ],
42
- [
43
- 'element' => '.jupiterx-footer-widgets [class^="col"]',
44
- 'property' => 'padding',
45
- 'value_pattern' => '0 calc($ / 2)',
46
- ],
47
- ],
48
- ] );
49
-
50
- // Border.
51
- JupiterX_Customizer::add_field( [
52
- 'type' => 'jupiterx-border',
53
- 'settings' => 'jupiterx_footer_widget_area_container_border',
54
- 'section' => $section,
55
- 'label' => __( 'Border', 'jupiterx-core' ),
56
- 'css_var' => 'footer-widget-area-container-border',
57
- 'exclude' => [ 'style', 'size', 'radius' ],
58
- 'transport' => 'postMessage',
59
- 'default' => [
60
- 'width' => [
61
- 'size' => 1,
62
- 'unit' => 'px',
63
- ],
64
- 'color' => '#e9ecef',
65
- ],
66
- 'output' => [
67
- [
68
- 'element' => '.jupiterx-footer-widgets:not(.elementor-widget-sidebar)',
69
- 'property' => 'border-top',
70
- ],
71
- ],
72
- ] );
73
-
74
- // Divider.
75
- JupiterX_Customizer::add_field( [
76
- 'type' => 'jupiterx-divider',
77
- 'settings' => 'jupiterx_footer_widget_area_container_divider',
78
- 'section' => $section,
79
- ] );
80
-
81
- // Spacing.
82
- JupiterX_Customizer::add_responsive_field( [
83
- 'type' => 'jupiterx-box-model',
84
- 'settings' => 'jupiterx_footer_widget_area_container_spacing',
85
- 'section' => $section,
86
- 'transport' => 'postMessage',
87
- 'css_var' => 'footer-widget-area-container',
88
- 'default' => [
89
- 'desktop' => [
90
- 'padding_top' => 1.5,
91
- ],
92
- ],
93
- 'output' => [
94
- [
95
- 'element' => '.jupiterx-footer-widgets',
96
- ],
97
- ],
98
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Layout > Styles > Footer Container popup to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_footer';
11
+
12
+ $widgets_area_container_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_footer_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ // Background.
21
+ JupiterX_Customizer::add_field( [
22
+ 'type' => 'jupiterx-background',
23
+ 'settings' => 'jupiterx_footer_widget_area_container_background',
24
+ 'section' => $section,
25
+ 'box' => 'widget_area_container',
26
+ 'transport' => 'postMessage',
27
+ 'css_var' => 'footer-widget-area-container-background',
28
+ 'output' => [
29
+ [
30
+ 'element' => '.jupiterx-footer-widgets',
31
+ ],
32
+ ],
33
+ 'active_callback' => $widgets_area_container_condition,
34
+ ] );
35
+
36
+ // Column gap.
37
+ JupiterX_Customizer::add_field( [
38
+ 'type' => 'jupiterx-input',
39
+ 'settings' => 'jupiterx_footer_widget_area_container_column_gap',
40
+ 'section' => $section,
41
+ 'box' => 'widget_area_container',
42
+ 'css_var' => 'footer-widget-area-container-column-gap',
43
+ 'label' => __( 'Column Gap', 'jupiterx-core' ),
44
+ 'units' => [ 'px', 'em', 'rem' ],
45
+ 'transport' => 'postMessage',
46
+ 'output' => [
47
+ [
48
+ 'element' => '.jupiterx-footer-widgets .row',
49
+ 'property' => 'margin',
50
+ 'value_pattern' => 'auto calc(-$ / 2)',
51
+ ],
52
+ [
53
+ 'element' => '.jupiterx-footer-widgets [class^="col"]',
54
+ 'property' => 'padding',
55
+ 'value_pattern' => '0 calc($ / 2)',
56
+ ],
57
+ ],
58
+ 'active_callback' => $widgets_area_container_condition,
59
+ ] );
60
+
61
+ // Border.
62
+ JupiterX_Customizer::add_field( [
63
+ 'type' => 'jupiterx-border',
64
+ 'settings' => 'jupiterx_footer_widget_area_container_border',
65
+ 'section' => $section,
66
+ 'box' => 'widget_area_container',
67
+ 'label' => __( 'Border', 'jupiterx-core' ),
68
+ 'css_var' => 'footer-widget-area-container-border',
69
+ 'exclude' => [ 'style', 'size', 'radius' ],
70
+ 'transport' => 'postMessage',
71
+ 'default' => [
72
+ 'width' => [
73
+ 'size' => 1,
74
+ 'unit' => 'px',
75
+ ],
76
+ 'color' => '#e9ecef',
77
+ ],
78
+ 'output' => [
79
+ [
80
+ 'element' => '.jupiterx-footer-widgets:not(.elementor-widget-sidebar)',
81
+ 'property' => 'border-top',
82
+ ],
83
+ ],
84
+ 'active_callback' => $widgets_area_container_condition,
85
+ ] );
86
+
87
+ // Divider.
88
+ JupiterX_Customizer::add_field( [
89
+ 'type' => 'jupiterx-divider',
90
+ 'settings' => 'jupiterx_footer_widget_area_container_divider',
91
+ 'section' => $section,
92
+ 'box' => 'widget_area_container',
93
+ 'active_callback' => $widgets_area_container_condition,
94
+ ] );
95
+
96
+ // Spacing.
97
+ JupiterX_Customizer::add_responsive_field( [
98
+ 'type' => 'jupiterx-box-model',
99
+ 'settings' => 'jupiterx_footer_widget_area_container_spacing',
100
+ 'section' => $section,
101
+ 'box' => 'widget_area_container',
102
+ 'transport' => 'postMessage',
103
+ 'css_var' => 'footer-widget-area-container',
104
+ 'default' => [
105
+ 'desktop' => [
106
+ 'padding_top' => 1.5,
107
+ ],
108
+ ],
109
+ 'output' => [
110
+ [
111
+ 'element' => '.jupiterx-footer-widgets',
112
+ ],
113
+ ],
114
+ 'active_callback' => $widgets_area_container_condition,
115
+ ] );
includes/customizer/settings/footer/widgets-container.php CHANGED
@@ -1,87 +1,115 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Footer > Styles > Widgets Container popup to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_footer_widgets_container';
11
-
12
- // Align.
13
- JupiterX_Customizer::add_responsive_field( [
14
- 'type' => 'jupiterx-choose',
15
- 'settings' => 'jupiterx_footer_widgets_container_align',
16
- 'section' => $section,
17
- 'label' => __( 'Align', 'jupiterx-core' ),
18
- 'default' => jupiterx_get_direction( 'left' ),
19
- 'choices' => JupiterX_Customizer_Utils::get_align(),
20
- 'css_var' => 'footer-widgets-container-align',
21
- 'transport' => 'postMessage',
22
- 'output' => [
23
- [
24
- 'element' => '.jupiterx-footer-widgets .jupiterx-widget',
25
- 'property' => 'text-align',
26
- ],
27
- ],
28
- ] );
29
-
30
- // Background.
31
- JupiterX_Customizer::add_field( [
32
- 'type' => 'jupiterx-background',
33
- 'settings' => 'jupiterx_footer_widgets_container_background',
34
- 'section' => $section,
35
- 'css_var' => 'footer-widgets-container-background',
36
- 'transport' => 'postMessage',
37
- 'exclude' => [ 'image', 'position', 'repeat', 'attachment', 'size' ],
38
- 'output' => [
39
- [
40
- 'element' => '.jupiterx-footer-widgets .jupiterx-widget',
41
- ],
42
- ],
43
- ] );
44
-
45
- // Border.
46
- JupiterX_Customizer::add_field( [
47
- 'type' => 'jupiterx-border',
48
- 'settings' => 'jupiterx_footer_widgets_container_border',
49
- 'section' => $section,
50
- 'label' => __( 'Border', 'jupiterx-core' ),
51
- 'css_var' => 'footer-widgets-container-border',
52
- 'transport' => 'postMessage',
53
- 'exclude' => [ 'style', 'size' ],
54
- 'default' => [
55
- 'width' => [
56
- 'size' => '0',
57
- 'unit' => 'px',
58
- ],
59
- ],
60
- 'output' => [
61
- [
62
- 'element' => '.jupiterx-footer-widgets .jupiterx-widget',
63
- ],
64
- ],
65
- ] );
66
-
67
- // Divider.
68
- JupiterX_Customizer::add_field( [
69
- 'type' => 'jupiterx-divider',
70
- 'settings' => 'jupiterx_footer_widgets_container_divider',
71
- 'section' => $section,
72
- ] );
73
-
74
- // Spacing.
75
- JupiterX_Customizer::add_responsive_field( [
76
- 'type' => 'jupiterx-box-model',
77
- 'settings' => 'jupiterx_footer_widgets_container_spacing',
78
- 'section' => $section,
79
- 'responsive' => true,
80
- 'transport' => 'postMessage',
81
- 'css_var' => 'footer-widgets-container',
82
- 'output' => [
83
- [
84
- 'element' => '.jupiterx-footer-widgets .jupiterx-widget',
85
- ],
86
- ],
87
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Footer > Styles > Widgets Container popup to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_footer';
11
+
12
+ $widgets_container_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_footer_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ // Align.
21
+ JupiterX_Customizer::add_responsive_field( [
22
+ 'type' => 'jupiterx-choose',
23
+ 'settings' => 'jupiterx_footer_widgets_container_align',
24
+ 'section' => $section,
25
+ 'box' => 'widgets_container',
26
+ 'label' => __( 'Alignment', 'jupiterx-core' ),
27
+ 'inline' => true,
28
+ 'default' => jupiterx_get_direction( 'left' ),
29
+ 'choices' => JupiterX_Customizer_Utils::get_align(),
30
+ 'css_var' => 'footer-widgets-container-align',
31
+ 'transport' => 'postMessage',
32
+ 'output' => [
33
+ [
34
+ 'element' => '.jupiterx-footer-widgets .jupiterx-widget',
35
+ 'property' => 'text-align',
36
+ ],
37
+ ],
38
+ 'active_callback' => $widgets_container_condition,
39
+ ] );
40
+
41
+ // Background.
42
+ JupiterX_Customizer::add_field( [
43
+ 'type' => 'jupiterx-background',
44
+ 'settings' => 'jupiterx_footer_widgets_container_background',
45
+ 'section' => $section,
46
+ 'box' => 'widgets_container',
47
+ 'css_var' => 'footer-widgets-container-background',
48
+ 'transport' => 'postMessage',
49
+ 'exclude' => [ 'image', 'position', 'repeat', 'attachment', 'size' ],
50
+ 'output' => [
51
+ [
52
+ 'element' => '.jupiterx-footer-widgets .jupiterx-widget',
53
+ ],
54
+ ],
55
+ 'active_callback' => $widgets_container_condition,
56
+ ] );
57
+
58
+ // Label.
59
+ JupiterX_Customizer::add_field( [
60
+ 'type' => 'jupiterx-label',
61
+ 'label' => __( 'Border', 'jupiterx-core' ),
62
+ 'settings' => 'jupiterx_footer_widgets_container_label',
63
+ 'section' => $section,
64
+ 'box' => 'widgets_container',
65
+ 'active_callback' => $widgets_container_condition,
66
+ ] );
67
+
68
+ // Border.
69
+ JupiterX_Customizer::add_field( [
70
+ 'type' => 'jupiterx-border',
71
+ 'settings' => 'jupiterx_footer_widgets_container_border',
72
+ 'section' => $section,
73
+ 'box' => 'widgets_container',
74
+ 'css_var' => 'footer-widgets-container-border',
75
+ 'transport' => 'postMessage',
76
+ 'exclude' => [ 'style', 'size' ],
77
+ 'default' => [
78
+ 'width' => [
79
+ 'size' => '0',
80
+ 'unit' => 'px',
81
+ ],
82
+ ],
83
+ 'output' => [
84
+ [
85
+ 'element' => '.jupiterx-footer-widgets .jupiterx-widget',
86
+ ],
87
+ ],
88
+ 'active_callback' => $widgets_container_condition,
89
+ ] );
90
+
91
+ // Divider.
92
+ JupiterX_Customizer::add_field( [
93
+ 'type' => 'jupiterx-divider',
94
+ 'settings' => 'jupiterx_footer_widgets_container_divider',
95
+ 'section' => $section,
96
+ 'box' => 'widgets_container',
97
+ 'active_callback' => $widgets_container_condition,
98
+ ] );
99
+
100
+ // Spacing.
101
+ JupiterX_Customizer::add_responsive_field( [
102
+ 'type' => 'jupiterx-box-model',
103
+ 'settings' => 'jupiterx_footer_widgets_container_spacing',
104
+ 'section' => $section,
105
+ 'box' => 'widgets_container',
106
+ 'responsive' => true,
107
+ 'transport' => 'postMessage',
108
+ 'css_var' => 'footer-widgets-container',
109
+ 'output' => [
110
+ [
111
+ 'element' => '.jupiterx-footer-widgets .jupiterx-widget',
112
+ ],
113
+ ],
114
+ 'active_callback' => $widgets_container_condition,
115
+ ] );
includes/customizer/settings/footer/widgets-divider.php CHANGED
@@ -1,71 +1,96 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Footer > Styles > Divider popup to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_footer_widgets_divider';
11
-
12
- // Widget divider.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-border',
15
- 'settings' => 'jupiterx_footer_widgets_divider',
16
- 'section' => $section,
17
- 'css_var' => 'footer-widgets-divider',
18
- 'exclude' => [ 'radius' ],
19
- 'transport' => 'postMessage',
20
- 'output' => [
21
- [
22
- 'element' => '.jupiterx-footer-widgets .jupiterx-widget-divider',
23
- 'property' => 'border-top',
24
- ],
25
- ],
26
- ] );
27
-
28
- // Divider.
29
- JupiterX_Customizer::add_field( [
30
- 'type' => 'jupiterx-divider',
31
- 'settings' => 'jupiterx_footer_divider_line',
32
- 'section' => $section,
33
- ] );
34
-
35
- // Items.
36
- JupiterX_Customizer::add_field( [
37
- 'type' => 'jupiterx-border',
38
- 'settings' => 'jupiterx_footer_widgets_items_divider',
39
- 'section' => $section,
40
- 'css_var' => 'footer-widgets-divider-items',
41
- 'label' => esc_html__( 'Items', 'jupiterx-core' ),
42
- 'exclude' => [ 'size', 'radius' ],
43
- 'transport' => 'postMessage',
44
- 'default' => [
45
- 'width' => [
46
- 'size' => '0',
47
- 'unit' => 'px',
48
- ],
49
- ],
50
- 'output' => [
51
- [
52
- 'element' => '.jupiterx-footer-widgets .jupiterx-widget ul li, .jupiterx-footer-widgets .jupiterx-widget .jupiterx-widget-posts-item',
53
- 'property' => 'border-bottom',
54
- ],
55
- ],
56
- ] );
57
-
58
- // Items spacing.
59
- JupiterX_Customizer::add_responsive_field( [
60
- 'type' => 'jupiterx-box-model',
61
- 'settings' => 'jupiterx_footer_widgets_items_spacing',
62
- 'section' => $section,
63
- 'css_var' => 'footer-widgets-divider-items',
64
- 'transport' => 'postMessage',
65
- 'exclude' => [ 'margin' ],
66
- 'output' => [
67
- [
68
- 'element' => '.jupiterx-footer-widgets .jupiterx-widget ul li, .jupiterx-footer-widgets .jupiterx-widget .jupiterx-widget-posts-item',
69
- ],
70
- ],
71
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Footer > Styles > Divider popup to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_footer';
11
+
12
+ $widgets_divider_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_footer_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ // Widget divider.
21
+ JupiterX_Customizer::add_field( [
22
+ 'type' => 'jupiterx-border',
23
+ 'settings' => 'jupiterx_footer_widgets_divider',
24
+ 'section' => $section,
25
+ 'box' => 'widgets_divider',
26
+ 'css_var' => 'footer-widgets-divider',
27
+ 'exclude' => [ 'radius' ],
28
+ 'transport' => 'postMessage',
29
+ 'output' => [
30
+ [
31
+ 'element' => '.jupiterx-footer-widgets .jupiterx-widget-divider',
32
+ 'property' => 'border-top',
33
+ ],
34
+ ],
35
+ 'active_callback' => $widgets_divider_condition,
36
+ ] );
37
+
38
+ // Divider.
39
+ JupiterX_Customizer::add_field( [
40
+ 'type' => 'jupiterx-divider',
41
+ 'settings' => 'jupiterx_footer_divider_line',
42
+ 'section' => $section,
43
+ 'box' => 'widgets_divider',
44
+ 'active_callback' => $widgets_divider_condition,
45
+ ] );
46
+
47
+ // Label.
48
+ JupiterX_Customizer::add_field( [
49
+ 'type' => 'jupiterx-label',
50
+ 'label' => __( 'Items', 'jupiterx-core' ),
51
+ 'settings' => 'jupiterx_footer_widgets_items_divider_label',
52
+ 'section' => $section,
53
+ 'box' => 'widgets_divider',
54
+ 'active_callback' => $widgets_divider_condition,
55
+ ] );
56
+
57
+ // Items.
58
+ JupiterX_Customizer::add_field( [
59
+ 'type' => 'jupiterx-border',
60
+ 'settings' => 'jupiterx_footer_widgets_items_divider',
61
+ 'section' => $section,
62
+ 'box' => 'widgets_divider',
63
+ 'css_var' => 'footer-widgets-divider-items',
64
+ 'exclude' => [ 'size', 'radius' ],
65
+ 'transport' => 'postMessage',
66
+ 'default' => [
67
+ 'width' => [
68
+ 'size' => '0',
69
+ 'unit' => 'px',
70
+ ],
71
+ ],
72
+ 'output' => [
73
+ [
74
+ 'element' => '.jupiterx-footer-widgets .jupiterx-widget ul li, .jupiterx-footer-widgets .jupiterx-widget .jupiterx-widget-posts-item',
75
+ 'property' => 'border-bottom',
76
+ ],
77
+ ],
78
+ 'active_callback' => $widgets_divider_condition,
79
+ ] );
80
+
81
+ // Items spacing.
82
+ JupiterX_Customizer::add_responsive_field( [
83
+ 'type' => 'jupiterx-box-model',
84
+ 'settings' => 'jupiterx_footer_widgets_items_spacing',
85
+ 'section' => $section,
86
+ 'box' => 'widgets_divider',
87
+ 'css_var' => 'footer-widgets-divider-items',
88
+ 'transport' => 'postMessage',
89
+ 'exclude' => [ 'margin' ],
90
+ 'output' => [
91
+ [
92
+ 'element' => '.jupiterx-footer-widgets .jupiterx-widget ul li, .jupiterx-footer-widgets .jupiterx-widget .jupiterx-widget-posts-item',
93
+ ],
94
+ ],
95
+ 'active_callback' => $widgets_divider_condition,
96
+ ] );
includes/customizer/settings/footer/widgets-link.php CHANGED
@@ -1,92 +1,140 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Footer > Styles > Widgets Link popup to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_footer_widgets_link';
11
-
12
- // Color.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-color',
15
- 'settings' => 'jupiterx_footer_widgets_link_color',
16
- 'section' => $section,
17
- 'css_var' => 'footer-widgets-link-color',
18
- 'column' => '3',
19
- 'icon' => 'font-color',
20
- 'transport' => 'postMessage',
21
- 'output' => [
22
- [
23
- 'element' => '.jupiterx-footer-widgets a, .jupiterx-footer-widgets .jupiterx-recent-comment .comment-author-link:before',
24
- 'property' => 'color',
25
- ],
26
- ],
27
- ] );
28
-
29
- // Text decoration.
30
- JupiterX_Customizer::add_field( [
31
- 'type' => 'jupiterx-select',
32
- 'settings' => 'jupiterx_footer_widgets_link_text_decoration',
33
- 'section' => $section,
34
- 'css_var' => 'footer-widgets-link-text-decoration',
35
- 'column' => '6',
36
- 'icon' => 'text-decoration',
37
- 'placeholder' => __( 'Default', 'jupiterx-core' ),
38
- 'choices' => JupiterX_Customizer_Utils::get_text_decoration_choices(),
39
- 'transport' => 'postMessage',
40
- 'output' => [
41
- [
42
- 'element' => '.jupiterx-footer-widgets a',
43
- 'property' => 'text-decoration',
44
- ],
45
- ],
46
- ] );
47
-
48
- // Divider.
49
- JupiterX_Customizer::add_field( [
50
- 'type' => 'jupiterx-label',
51
- 'settings' => 'jupiterx_footer_widgets_link_label_hover',
52
- 'section' => $section,
53
- 'label' => __( 'Hover', 'jupiterx-core' ),
54
- 'label_type' => 'fancy',
55
- 'color' => 'orange',
56
- ] );
57
-
58
- // Hover color.
59
- JupiterX_Customizer::add_field( [
60
- 'type' => 'jupiterx-color',
61
- 'settings' => 'jupiterx_footer_widgets_link_color_hover',
62
- 'section' => $section,
63
- 'css_var' => 'footer-widgets-link-color-hover',
64
- 'column' => '3',
65
- 'icon' => 'font-color',
66
- 'transport' => 'postMessage',
67
- 'output' => [
68
- [
69
- 'element' => '.jupiterx-footer-widgets a:hover, .jupiterx-footer-widgets .jupiterx-recent-comment:hover .comment-author-link:before',
70
- 'property' => 'color',
71
- ],
72
- ],
73
- ] );
74
-
75
- // Hover text decoration.
76
- JupiterX_Customizer::add_field( [
77
- 'type' => 'jupiterx-select',
78
- 'settings' => 'jupiterx_footer_widgets_link_text_decoration_hover',
79
- 'section' => $section,
80
- 'css_var' => 'footer-widgets-link-text-decoration-hover',
81
- 'column' => '6',
82
- 'icon' => 'text-decoration',
83
- 'placeholder' => __( 'Default', 'jupiterx-core' ),
84
- 'choices' => JupiterX_Customizer_Utils::get_text_decoration_choices(),
85
- 'transport' => 'postMessage',
86
- 'output' => [
87
- [
88
- 'element' => '.jupiterx-footer-widgets a:hover',
89
- 'property' => 'text-decoration',
90
- ],
91
- ],
92
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Footer > Styles > Widgets Link popup to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_footer';
11
+
12
+ $widgets_link_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_footer_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ $widgets_link_normal_condition = [
21
+ [
22
+ 'setting' => 'jupiterx_footer_type',
23
+ 'operator' => '===',
24
+ 'value' => '',
25
+ ],
26
+ [
27
+ 'setting' => 'jupiterx_footer_widgets_link_label',
28
+ 'operator' => '===',
29
+ 'value' => 'normal',
30
+ ],
31
+ ];
32
+
33
+ $widgets_link_hover_condition = [
34
+ [
35
+ 'setting' => 'jupiterx_footer_type',
36
+ 'operator' => '===',
37
+ 'value' => '',
38
+ ],
39
+ [
40
+ 'setting' => 'jupiterx_footer_widgets_link_label',
41
+ 'operator' => '===',
42
+ 'value' => 'hover',
43
+ ],
44
+ ];
45
+
46
+ // Hover label.
47
+ JupiterX_Customizer::add_field( [
48
+ 'type' => 'jupiterx-choose',
49
+ 'color' => 'orange',
50
+ 'settings' => 'jupiterx_footer_widgets_link_label',
51
+ 'section' => $section,
52
+ 'box' => 'widgets_link',
53
+ 'transport' => 'postMessage',
54
+ 'default' => 'normal',
55
+ 'choices' => [
56
+ 'normal' => [
57
+ 'label' => __( 'Normal', 'jupiterx-core' ),
58
+ ],
59
+ 'hover' => [
60
+ 'label' => __( 'Hover', 'jupiterx-core' ),
61
+ ],
62
+ ],
63
+ 'active_callback' => $widgets_link_condition,
64
+ ] );
65
+
66
+ // Color.
67
+ JupiterX_Customizer::add_field( [
68
+ 'type' => 'jupiterx-color',
69
+ 'settings' => 'jupiterx_footer_widgets_link_color',
70
+ 'section' => $section,
71
+ 'box' => 'widgets_link',
72
+ 'css_var' => 'footer-widgets-link-color',
73
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
74
+ 'transport' => 'postMessage',
75
+ 'output' => [
76
+ [
77
+ 'element' => '.jupiterx-footer-widgets a, .jupiterx-footer-widgets .jupiterx-recent-comment .comment-author-link:before',
78
+ 'property' => 'color',
79
+ ],
80
+ ],
81
+ 'active_callback' => $widgets_link_normal_condition,
82
+ ] );
83
+
84
+ // Text decoration.
85
+ JupiterX_Customizer::add_field( [
86
+ 'type' => 'jupiterx-select',
87
+ 'settings' => 'jupiterx_footer_widgets_link_text_decoration',
88
+ 'section' => $section,
89
+ 'box' => 'widgets_link',
90
+ 'css_var' => 'footer-widgets-link-text-decoration',
91
+ 'label' => __( 'Text Decoration', 'jupiterx-core' ),
92
+ 'placeholder' => __( 'Default', 'jupiterx-core' ),
93
+ 'choices' => JupiterX_Customizer_Utils::get_text_decoration_choices(),
94
+ 'transport' => 'postMessage',
95
+ 'output' => [
96
+ [
97
+ 'element' => '.jupiterx-footer-widgets a',
98
+ 'property' => 'text-decoration',
99
+ ],
100
+ ],
101
+ 'active_callback' => $widgets_link_normal_condition,
102
+ ] );
103
+
104
+ // Hover color.
105
+ JupiterX_Customizer::add_field( [
106
+ 'type' => 'jupiterx-color',
107
+ 'settings' => 'jupiterx_footer_widgets_link_color_hover',
108
+ 'section' => $section,
109
+ 'box' => 'widgets_link',
110
+ 'css_var' => 'footer-widgets-link-color-hover',
111
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
112
+ 'transport' => 'postMessage',
113
+ 'output' => [
114
+ [
115
+ 'element' => '.jupiterx-footer-widgets a:hover, .jupiterx-footer-widgets .jupiterx-recent-comment:hover .comment-author-link:before',
116
+ 'property' => 'color',
117
+ ],
118
+ ],
119
+ 'active_callback' => $widgets_link_hover_condition,
120
+ ] );
121
+
122
+ // Hover text decoration.
123
+ JupiterX_Customizer::add_field( [
124
+ 'type' => 'jupiterx-select',
125
+ 'settings' => 'jupiterx_footer_widgets_link_text_decoration_hover',
126
+ 'section' => $section,
127
+ 'box' => 'widgets_link',
128
+ 'css_var' => 'footer-widgets-link-text-decoration-hover',
129
+ 'label' => __( 'Text Decoration', 'jupiterx-core' ),
130
+ 'placeholder' => __( 'Default', 'jupiterx-core' ),
131
+ 'choices' => JupiterX_Customizer_Utils::get_text_decoration_choices(),
132
+ 'transport' => 'postMessage',
133
+ 'output' => [
134
+ [
135
+ 'element' => '.jupiterx-footer-widgets a:hover',
136
+ 'property' => 'text-decoration',
137
+ ],
138
+ ],
139
+ 'active_callback' => $widgets_link_hover_condition,
140
+ ] );
includes/customizer/settings/footer/widgets-text.php CHANGED
@@ -1,26 +1,36 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Footer > Styles > Widgets Text popup to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_footer_widgets_text';
11
-
12
- // Typography.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-typography',
15
- 'settings' => 'jupiterx_footer_widgets_text_typography',
16
- 'section' => $section,
17
- 'responsive' => true,
18
- 'css_var' => 'footer-widgets-text',
19
- 'transport' => 'postMessage',
20
- 'exclude' => [ 'letter_spacing', 'text_transform' ],
21
- 'output' => [
22
- [
23
- 'element' => '.jupiterx-footer-widgets .jupiterx-widget-content, .jupiterx-footer-widgets .jupiterx-widget-content p',
24
- ],
25
- ],
26
- ] );
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Footer > Styles > Widgets Text popup to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_footer';
11
+
12
+ $widgets_text_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_footer_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ // Typography.
21
+ JupiterX_Customizer::add_field( [
22
+ 'type' => 'jupiterx-typography',
23
+ 'settings' => 'jupiterx_footer_widgets_text_typography',
24
+ 'section' => $section,
25
+ 'box' => 'widgets_text',
26
+ 'responsive' => true,
27
+ 'css_var' => 'footer-widgets-text',
28
+ 'transport' => 'postMessage',
29
+ 'exclude' => [ 'letter_spacing', 'text_transform' ],
30
+ 'output' => [
31
+ [
32
+ 'element' => '.jupiterx-footer-widgets .jupiterx-widget-content, .jupiterx-footer-widgets .jupiterx-widget-content p',
33
+ ],
34
+ ],
35
+ 'active_callback' => $widgets_text_condition,
36
+ ] );
includes/customizer/settings/footer/widgets-thumbnail.php CHANGED
@@ -1,77 +1,92 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Footer > Styles > Widgets Thumbnail popup to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_footer_widgets_thumbnail';
11
-
12
- // Size.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-input',
15
- 'settings' => 'jupiterx_footer_widgets_thumbnail_size',
16
- 'section' => $section,
17
- 'label' => esc_html__( 'Size', 'jupiterx-core' ),
18
- 'css_var' => 'footer-widgets-thumbnail-size',
19
- 'column' => '4',
20
- 'units' => [ 'px' ],
21
- 'transport' => 'postMessage',
22
- 'output' => [
23
- [
24
- 'element' => '.jupiterx-footer .jupiterx-widget-posts-image img, .jupiterx-footer .woocommerce ul.product_list_widget li img',
25
- 'property' => 'width',
26
- ],
27
- [
28
- 'element' => '.jupiterx-footer .jupiterx-widget-posts-image img, .jupiterx-footer .woocommerce ul.product_list_widget li img',
29
- 'property' => 'height',
30
- ],
31
- ],
32
- ] );
33
-
34
- // Border.
35
- JupiterX_Customizer::add_field( [
36
- 'type' => 'jupiterx-border',
37
- 'settings' => 'jupiterx_footer_widgets_thumbnail_border',
38
- 'section' => $section,
39
- 'css_var' => 'footer-widgets-thumbnail-border',
40
- 'transport' => 'postMessage',
41
- 'exclude' => [ 'style', 'size' ],
42
- 'default' => [
43
- 'width' => [
44
- 'size' => '0',
45
- 'unit' => 'px',
46
- ],
47
- ],
48
- 'output' => [
49
- [
50
- 'element' => '.jupiterx-footer .jupiterx-widget-posts-image img, .jupiterx-footer .woocommerce ul.product_list_widget li img',
51
- ],
52
- ],
53
- ] );
54
-
55
- // Divider.
56
- JupiterX_Customizer::add_field( [
57
- 'type' => 'jupiterx-divider',
58
- 'settings' => 'jupiterx_footer_widgets_thumbnail_divider',
59
- 'section' => $section,
60
- ] );
61
-
62
- // Spacing.
63
- JupiterX_Customizer::add_responsive_field( [
64
- 'type' => 'jupiterx-box-model',
65
- 'settings' => 'jupiterx_footer_widgets_thumbnail_spacing',
66
- 'section' => $section,
67
- 'responsive' => true,
68
- 'css_var' => 'footer-widgets-thumbnail',
69
- 'exclude' => [ 'padding' ],
70
- 'disable' => [ jupiterx_get_direction( 'margin-left' ) ],
71
- 'transport' => 'postMessage',
72
- 'output' => [
73
- [
74
- 'element' => '.jupiterx-footer .jupiterx-widget-posts-image img, .jupiterx-footer .woocommerce ul.product_list_widget li img',
75
- ],
76
- ],
77
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Footer > Styles > Widgets Thumbnail popup to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_footer';
11
+
12
+ $widgets_thumbnail_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_footer_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ // Size.
21
+ JupiterX_Customizer::add_field( [
22
+ 'type' => 'jupiterx-input',
23
+ 'settings' => 'jupiterx_footer_widgets_thumbnail_size',
24
+ 'section' => $section,
25
+ 'box' => 'widgets_thumbnail',
26
+ 'label' => esc_html__( 'Size', 'jupiterx-core' ),
27
+ 'css_var' => 'footer-widgets-thumbnail-size',
28
+ 'units' => [ 'px' ],
29
+ 'transport' => 'postMessage',
30
+ 'output' => [
31
+ [
32
+ 'element' => '.jupiterx-footer .jupiterx-widget-posts-image img, .jupiterx-footer .woocommerce ul.product_list_widget li img',
33
+ 'property' => 'width',
34
+ ],
35
+ [
36
+ 'element' => '.jupiterx-footer .jupiterx-widget-posts-image img, .jupiterx-footer .woocommerce ul.product_list_widget li img',
37
+ 'property' => 'height',
38
+ ],
39
+ ],
40
+ 'active_callback' => $widgets_thumbnail_condition,
41
+ ] );
42
+
43
+ // Border.
44
+ JupiterX_Customizer::add_field( [
45
+ 'type' => 'jupiterx-border',
46
+ 'settings' => 'jupiterx_footer_widgets_thumbnail_border',
47
+ 'section' => $section,
48
+ 'box' => 'widgets_thumbnail',
49
+ 'css_var' => 'footer-widgets-thumbnail-border',
50
+ 'transport' => 'postMessage',
51
+ 'exclude' => [ 'style', 'size' ],
52
+ 'default' => [
53
+ 'width' => [
54
+ 'size' => '0',
55
+ 'unit' => 'px',
56
+ ],
57
+ ],
58
+ 'output' => [
59
+ [
60
+ 'element' => '.jupiterx-footer .jupiterx-widget-posts-image img, .jupiterx-footer .woocommerce ul.product_list_widget li img',
61
+ ],
62
+ ],
63
+ 'active_callback' => $widgets_thumbnail_condition,
64
+ ] );
65
+
66
+ // Divider.
67
+ JupiterX_Customizer::add_field( [
68
+ 'type' => 'jupiterx-divider',
69
+ 'settings' => 'jupiterx_footer_widgets_thumbnail_divider',
70
+ 'section' => $section,
71
+ 'box' => 'widgets_thumbnail',
72
+ 'active_callback' => $widgets_thumbnail_condition,
73
+ ] );
74
+
75
+ // Spacing.
76
+ JupiterX_Customizer::add_responsive_field( [
77
+ 'type' => 'jupiterx-box-model',
78
+ 'settings' => 'jupiterx_footer_widgets_thumbnail_spacing',
79
+ 'section' => $section,
80
+ 'box' => 'widgets_thumbnail',
81
+ 'responsive' => true,
82
+ 'css_var' => 'footer-widgets-thumbnail',
83
+ 'exclude' => [ 'padding' ],
84
+ 'disable' => [ jupiterx_get_direction( 'margin-left' ) ],
85
+ 'transport' => 'postMessage',
86
+ 'output' => [
87
+ [
88
+ 'element' => '.jupiterx-footer .jupiterx-widget-posts-image img, .jupiterx-footer .woocommerce ul.product_list_widget li img',
89
+ ],
90
+ ],
91
+ 'active_callback' => $widgets_thumbnail_condition,
92
+ ] );
includes/customizer/settings/footer/widgets-title.php CHANGED
@@ -1,66 +1,82 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Footer > Styles > Widgets Title popup to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_footer_widgets_title';
11
-
12
- // Align.
13
- JupiterX_Customizer::add_responsive_field( [
14
- 'type' => 'jupiterx-choose',
15
- 'settings' => 'jupiterx_footer_widgets_title_align',
16
- 'section' => $section,
17
- 'label' => esc_html__( 'Align', 'jupiterx-core' ),
18
- 'css_var' => 'footer-widgets-title-align',
19
- 'column' => '4',
20
- 'transport' => 'postMessage',
21
- 'choices' => JupiterX_Customizer_Utils::get_align(),
22
- 'output' => [
23
- [
24
- 'element' => '.jupiterx-footer-widgets .card-title',
25
- 'property' => 'text-align',
26
- ],
27
- ],
28
- ] );
29
-
30
- // Typography.
31
- JupiterX_Customizer::add_field( [
32
- 'type' => 'jupiterx-typography',
33
- 'settings' => 'jupiterx_footer_widgets_title_typography',
34
- 'section' => $section,
35
- 'responsive' => true,
36
- 'css_var' => 'footer-widgets-title',
37
- 'transport' => 'postMessage',
38
- 'exclude' => [ 'text_transform' ],
39
- 'output' => [
40
- [
41
- 'element' => '.jupiterx-footer-widgets .card-title',
42
- ],
43
- ],
44
- ] );
45
-
46
- // Divider.
47
- JupiterX_Customizer::add_field( [
48
- 'type' => 'jupiterx-divider',
49
- 'settings' => 'jupiterx_footer_widgets_title_divider',
50
- 'section' => $section,
51
- ] );
52
-
53
- // Spacing.
54
- JupiterX_Customizer::add_responsive_field( [
55
- 'type' => 'jupiterx-box-model',
56
- 'settings' => 'jupiterx_footer_widgets_title_spacing',
57
- 'section' => $section,
58
- 'css_var' => 'footer-widgets-title',
59
- 'transport' => 'postMessage',
60
- 'exclude' => [ 'padding' ],
61
- 'output' => [
62
- [
63
- 'element' => '.jupiterx-footer-widgets .card-title',
64
- ],
65
- ],
66
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Footer > Styles > Widgets Title popup to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_footer';
11
+
12
+ $widgets_title_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_footer_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ // Align.
21
+ JupiterX_Customizer::add_responsive_field( [
22
+ 'type' => 'jupiterx-choose',
23
+ 'settings' => 'jupiterx_footer_widgets_title_align',
24
+ 'section' => $section,
25
+ 'box' => 'widgets_title',
26
+ 'label' => esc_html__( 'Alignment', 'jupiterx-core' ),
27
+ 'inline' => true,
28
+ 'css_var' => 'footer-widgets-title-align',
29
+ 'transport' => 'postMessage',
30
+ 'choices' => JupiterX_Customizer_Utils::get_align(),
31
+ 'output' => [
32
+ [
33
+ 'element' => '.jupiterx-footer-widgets .card-title',
34
+ 'property' => 'text-align',
35
+ ],
36
+ ],
37
+ 'active_callback' => $widgets_title_condition,
38
+ ] );
39
+
40
+ // Typography.
41
+ JupiterX_Customizer::add_field( [
42
+ 'type' => 'jupiterx-typography',
43
+ 'settings' => 'jupiterx_footer_widgets_title_typography',
44
+ 'section' => $section,
45
+ 'box' => 'widgets_title',
46
+ 'responsive' => true,
47
+ 'css_var' => 'footer-widgets-title',
48
+ 'transport' => 'postMessage',
49
+ 'exclude' => [ 'text_transform' ],
50
+ 'output' => [
51
+ [
52
+ 'element' => '.jupiterx-footer-widgets .card-title',
53
+ ],
54
+ ],
55
+ 'active_callback' => $widgets_title_condition,
56
+ ] );
57
+
58
+ // Divider.
59
+ JupiterX_Customizer::add_field( [
60
+ 'type' => 'jupiterx-divider',
61
+ 'settings' => 'jupiterx_footer_widgets_title_divider',
62
+ 'section' => $section,
63
+ 'box' => 'widgets_title',
64
+ 'active_callback' => $widgets_title_condition,
65
+ ] );
66
+
67
+ // Spacing.
68
+ JupiterX_Customizer::add_responsive_field( [
69
+ 'type' => 'jupiterx-box-model',
70
+ 'settings' => 'jupiterx_footer_widgets_title_spacing',
71
+ 'section' => $section,
72
+ 'box' => 'widgets_title',
73
+ 'css_var' => 'footer-widgets-title',
74
+ 'transport' => 'postMessage',
75
+ 'exclude' => [ 'padding' ],
76
+ 'output' => [
77
+ [
78
+ 'element' => '.jupiterx-footer-widgets .card-title',
79
+ ],
80
+ ],
81
+ 'active_callback' => $widgets_title_condition,
82
+ ] );
includes/customizer/settings/header/container.php CHANGED
@@ -1,84 +1,99 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Header > Styles tab > Container to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_header_container';
11
-
12
- // Background color.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-color',
15
- 'settings' => 'jupiterx_header_container_background_color',
16
- 'css_var' => 'header-container-background',
17
- 'section' => $section,
18
- 'column' => '3',
19
- 'icon' => 'background-color',
20
- 'responsive' => true,
21
- 'transport' => 'postMessage',
22
- 'default' => [
23
- 'desktop' => '#fff',
24
- ],
25
- 'output' => [
26
- [
27
- 'element' => '.jupiterx-site-navbar',
28
- 'property' => 'background-color',
29
- ],
30
- ],
31
- ] );
32
-
33
- // Border.
34
- JupiterX_Customizer::add_responsive_field( [
35
- 'type' => 'jupiterx-border',
36
- 'settings' => 'jupiterx_header_container_border',
37
- 'css_var' => 'header-container-border',
38
- 'section' => $section,
39
- 'exclude' => [ 'style', 'size', 'radius' ],
40
- 'transport' => 'postMessage',
41
- 'default' => [
42
- 'desktop' => [
43
- 'width' => [
44
- 'size' => 1,
45
- 'unit' => 'px',
46
- ],
47
- 'color' => '#e9ecef',
48
- ],
49
- ],
50
- 'output' => [
51
- [
52
- 'element' => '.jupiterx-site-navbar',
53
- 'property' => 'border-bottom',
54
- ],
55
- ],
56
- ] );
57
-
58
- // Divider.
59
- JupiterX_Customizer::add_field( [
60
- 'type' => 'jupiterx-divider',
61
- 'settings' => 'jupiterx_header_container_divider',
62
- 'section' => $section,
63
- ] );
64
-
65
- // Spacing.
66
- JupiterX_Customizer::add_responsive_field( [
67
- 'type' => 'jupiterx-box-model',
68
- 'settings' => 'jupiterx_header_container_spacing',
69
- 'css_var' => 'header-container',
70
- 'section' => $section,
71
- 'exclude' => [ 'margin' ],
72
- 'transport' => 'postMessage',
73
- 'default' => [
74
- 'desktop' => [
75
- 'padding_top' => 1.75,
76
- 'padding_bottom' => 1.75,
77
- ],
78
- ],
79
- 'output' => [
80
- [
81
- 'element' => '.jupiterx-site-navbar',
82
- ],
83
- ],
84
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Header > Styles tab > Container to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_header';
11
+
12
+ $container_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_header_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ // Background color.
21
+ JupiterX_Customizer::add_field( [
22
+ 'type' => 'jupiterx-color',
23
+ 'settings' => 'jupiterx_header_container_background_color',
24
+ 'css_var' => 'header-container-background',
25
+ 'section' => $section,
26
+ 'box' => 'container',
27
+ 'label' => __( 'Background Color', 'jupiterx-core' ),
28
+ 'responsive' => true,
29
+ 'transport' => 'postMessage',
30
+ 'default' => [
31
+ 'desktop' => '#fff',
32
+ ],
33
+ 'output' => [
34
+ [
35
+ 'element' => '.jupiterx-site-navbar',
36
+ 'property' => 'background-color',
37
+ ],
38
+ ],
39
+ 'active_callback' => $container_condition,
40
+ ] );
41
+
42
+ // Border.
43
+ JupiterX_Customizer::add_responsive_field( [
44
+ 'type' => 'jupiterx-border',
45
+ 'settings' => 'jupiterx_header_container_border',
46
+ 'css_var' => 'header-container-border',
47
+ 'section' => $section,
48
+ 'box' => 'container',
49
+ 'exclude' => [ 'style', 'size', 'radius' ],
50
+ 'transport' => 'postMessage',
51
+ 'default' => [
52
+ 'desktop' => [
53
+ 'width' => [
54
+ 'size' => 1,
55
+ 'unit' => 'px',
56
+ ],
57
+ 'color' => '#e9ecef',
58
+ ],
59
+ ],
60
+ 'output' => [
61
+ [
62
+ 'element' => '.jupiterx-site-navbar',
63
+ 'property' => 'border-bottom',
64
+ ],
65
+ ],
66
+ 'active_callback' => $container_condition,
67
+ ] );
68
+
69
+ // Divider.
70
+ JupiterX_Customizer::add_field( [
71
+ 'type' => 'jupiterx-divider',
72
+ 'settings' => 'jupiterx_header_container_divider',
73
+ 'section' => $section,
74
+ 'box' => 'container',
75
+ 'active_callback' => $container_condition,
76
+ ] );
77
+
78
+ // Spacing.
79
+ JupiterX_Customizer::add_responsive_field( [
80
+ 'type' => 'jupiterx-box-model',
81
+ 'settings' => 'jupiterx_header_container_spacing',
82
+ 'css_var' => 'header-container',
83
+ 'section' => $section,
84
+ 'box' => 'container',
85
+ 'exclude' => [ 'margin' ],
86
+ 'transport' => 'postMessage',
87
+ 'default' => [
88
+ 'desktop' => [
89
+ 'padding_top' => 1.75,
90
+ 'padding_bottom' => 1.75,
91
+ ],
92
+ ],
93
+ 'output' => [
94
+ [
95
+ 'element' => '.jupiterx-site-navbar',
96
+ ],
97
+ ],
98
+ 'active_callback' => $container_condition,
99
+ ] );
includes/customizer/settings/header/logo.php CHANGED
@@ -1,64 +1,105 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Header > Styles tab > Logo to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_header_logo';
11
-
12
- // Logo.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-select',
15
- 'settings' => 'jupiterx_header_logo',
16
- 'section' => $section,
17
- 'column' => '6',
18
- 'label' => __( 'Logo', 'jupiterx-core' ),
19
- 'default' => 'jupiterx_logo',
20
- 'choices' => [
21
- 'jupiterx_logo' => __( 'Primary', 'jupiterx-core' ),
22
- 'jupiterx_logo_secondary' => __( 'Secondary', 'jupiterx-core' ),
23
- ],
24
- ] );
25
-
26
- // Width.
27
- JupiterX_Customizer::add_responsive_field( [
28
- 'type' => 'jupiterx-input',
29
- 'settings' => 'jupiterx_header_logo_max_width',
30
- 'css_var' => 'header-logo-max-width',
31
- 'section' => $section,
32
- 'label' => __( 'Max Width', 'jupiterx-core' ),
33
- 'column' => '3-alt',
34
- 'units' => [ 'px', '%', 'vw' ],
35
- 'transport' => 'postMessage',
36
- 'output' => [
37
- [
38
- 'element' => '.jupiterx-site-navbar .jupiterx-navbar-brand-img',
39
- 'property' => 'max-width',
40
- ],
41
- ],
42
- ] );
43
-
44
- // Divider.
45
- JupiterX_Customizer::add_field( [
46
- 'type' => 'jupiterx-divider',
47
- 'settings' => 'jupiterx_header_logo_divider',
48
- 'section' => $section,
49
- ] );
50
-
51
- // Spacing.
52
- JupiterX_Customizer::add_responsive_field( [
53
- 'type' => 'jupiterx-box-model',
54
- 'settings' => 'jupiterx_header_logo_spacing',
55
- 'css_var' => 'header-logo',
56
- 'section' => $section,
57
- 'transport' => 'postMessage',
58
- 'exclude' => [ 'padding' ],
59
- 'output' => [
60
- [
61
- 'element' => '.jupiterx-site-navbar .jupiterx-navbar-brand',
62
- ],
63
- ],
64
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Header > Styles tab > Logo to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_header';
11
+
12
+ $logo_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_header_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ // Logo.
21
+ JupiterX_Customizer::add_field( [
22
+ 'type' => 'jupiterx-select',
23
+ 'settings' => 'jupiterx_header_logo',
24
+ 'section' => $section,
25
+ 'box' => 'logo',
26
+ 'label' => __( 'Logo', 'jupiterx-core' ),
27
+ 'default' => 'jupiterx_logo',
28
+ 'choices' => [
29
+ 'jupiterx_logo' => __( 'Primary', 'jupiterx-core' ),
30
+ 'jupiterx_logo_secondary' => __( 'Secondary', 'jupiterx-core' ),
31
+ ],
32
+ 'active_callback' => $logo_condition,
33
+ ] );
34
+
35
+ // Width.
36
+ JupiterX_Customizer::add_responsive_field( [
37
+ 'type' => 'jupiterx-input',
38
+ 'settings' => 'jupiterx_header_logo_width',
39
+ 'css_var' => 'header-logo-width',
40
+ 'section' => $section,
41
+ 'box' => 'logo',
42
+ 'label' => __( 'Width', 'jupiterx-core' ),
43
+ 'units' => [ 'px', '%', 'vw' ],
44
+ 'transport' => 'postMessage',
45
+ 'input_attrs' => [
46
+ 'min' => 0,
47
+ 'max' => 1000,
48
+ ],
49
+ 'output' => [
50
+ [
51
+ 'element' => '.jupiterx-site-navbar .jupiterx-navbar-brand-img',
52
+ 'property' => 'width',
53
+ ],
54
+ ],
55
+ 'active_callback' => $logo_condition,
56
+ ] );
57
+
58
+ // Max Width.
59
+ JupiterX_Customizer::add_responsive_field( [
60
+ 'type' => 'jupiterx-input',
61
+ 'settings' => 'jupiterx_header_logo_max_width',
62
+ 'css_var' => 'header-logo-max-width',
63
+ 'section' => $section,
64
+ 'box' => 'logo',
65
+ 'label' => __( 'Max Width', 'jupiterx-core' ),
66
+ 'units' => [ 'px', '%', 'vw' ],
67
+ 'transport' => 'postMessage',
68
+ 'input_attrs' => [
69
+ 'min' => 0,
70
+ 'max' => 1000,
71
+ ],
72
+ 'output' => [
73
+ [
74
+ 'element' => '.jupiterx-site-navbar .jupiterx-navbar-brand-img',
75
+ 'property' => 'max-width',
76
+ ],
77
+ ],
78
+ 'active_callback' => $logo_condition,
79
+ ] );
80
+
81
+ // Divider.
82
+ JupiterX_Customizer::add_field( [
83
+ 'type' => 'jupiterx-divider',
84
+ 'settings' => 'jupiterx_header_logo_divider',
85
+ 'section' => $section,
86
+ 'box' => 'logo',
87
+ 'active_callback' => $logo_condition,
88
+ ] );
89
+
90
+ // Spacing.
91
+ JupiterX_Customizer::add_responsive_field( [
92
+ 'type' => 'jupiterx-box-model',
93
+ 'settings' => 'jupiterx_header_logo_spacing',
94
+ 'css_var' => 'header-logo',
95
+ 'section' => $section,
96
+ 'box' => 'logo',
97
+ 'transport' => 'postMessage',
98
+ 'exclude' => [ 'padding' ],
99
+ 'output' => [
100
+ [
101
+ 'element' => '.jupiterx-site-navbar .jupiterx-navbar-brand',
102
+ ],
103
+ ],
104
+ 'active_callback' => $logo_condition,
105
+ ] );
includes/customizer/settings/header/menu.php CHANGED
@@ -1,222 +1,278 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Header > Styles tab > Menu to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_header_menu';
11
-
12
- // Typography.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-typography',
15
- 'settings' => 'jupiterx_header_menu_link_typography',
16
- 'css_var' => 'header-menu-link',
17
- 'section' => 'jupiterx_header_menu',
18
- 'exclude' => [ 'line_height' ],
19
- 'responsive' => true,
20
- 'transport' => 'postMessage',
21
- 'output' => [
22
- [
23
- 'element' => '.jupiterx-site-navbar .navbar-nav .nav-link',
24
- ],
25
- ],
26
- ] );
27
-
28
- // Spacing between.
29
- JupiterX_Customizer::add_field( [
30
- 'type' => 'jupiterx-input',
31
- 'settings' => 'jupiterx_header_menu_item_spacing_between',
32
- 'css_var' => 'header-menu-item-spacing-between',
33
- 'section' => $section,
34
- 'column' => '4',
35
- 'icon' => 'space-between',
36
- 'units' => [ 'px', 'em', 'rem' ],
37
- 'transport' => 'postMessage',
38
- 'output' => [
39
- [
40
- 'element' => '.jupiterx-site-navbar .navbar-nav > .nav-item',
41
- 'property' => 'margin-left',
42
- 'value_pattern' => 'calc( $ / 2)',
43
- 'media_query' => '@media (min-width: 768px)',
44
- ],
45
- [
46
- 'element' => '.jupiterx-site-navbar .navbar-nav > .nav-item',
47
- 'property' => 'margin-right',
48
- 'value_pattern' => 'calc( $ / 2)',
49
- 'media_query' => '@media (min-width: 768px)',
50
- ],
51
- ],
52
- ] );
53
-
54
- // Background color.
55
- JupiterX_Customizer::add_field( [
56
- 'type' => 'jupiterx-color',
57
- 'settings' => 'jupiterx_header_menu_link_background_color',
58
- 'css_var' => 'header-menu-link-background-color',
59
- 'section' => $section,
60
- 'column' => '3',
61
- 'icon' => 'background-color',
62
- 'transport' => 'postMessage',
63
- 'output' => [
64
- [
65
- 'element' => '.jupiterx-site-navbar .navbar-nav .nav-link',
66
- 'property' => 'background-color',
67
- ],
68
- ],
69
- ] );
70
-
71
- // Border.
72
- JupiterX_Customizer::add_field( [
73
- 'type' => 'jupiterx-border',
74
- 'settings' => 'jupiterx_header_menu_link_border',
75
- 'css_var' => 'header-menu-link-border',
76
- 'section' => $section,
77
- 'transport' => 'postMessage',
78
- 'exclude' => [ 'style', 'size' ],
79
- 'default' => [
80
- 'width' => [
81
- 'size' => '0',
82
- 'unit' => 'px',
83
- ],
84
- ],
85
- 'output' => [
86
- [
87
- 'element' => '.jupiterx-site-navbar .navbar-nav .nav-link',
88
- ],
89
- ],
90
- ] );
91
-
92
- // Hover label.
93
- JupiterX_Customizer::add_field( [
94
- 'type' => 'jupiterx-label',
95
- 'label' => __( 'Hover', 'jupiterx-core' ),
96
- 'label_type' => 'fancy',
97
- 'color' => 'orange',
98
- 'settings' => 'jupiterx_header_menu_label',
99
- 'section' => $section,
100
- ] );
101
-
102
- // Text color hover.
103
- JupiterX_Customizer::add_field( [
104
- 'type' => 'jupiterx-color',
105
- 'settings' => 'jupiterx_header_menu_link_color_hover',
106
- 'css_var' => 'header-menu-link-color-hover',
107
- 'section' => $section,
108
- 'column' => '3',
109
- 'icon' => 'font-color',
110
- 'transport' => 'postMessage',
111
- 'output' => [
112
- [
113
- 'element' => '.jupiterx-site-navbar .navbar-nav .nav-link:hover',
114
- 'property' => 'color',
115
- ],
116
- ],
117
- ] );
118
-
119
- // Background color hover.
120
- JupiterX_Customizer::add_field( [
121
- 'type' => 'jupiterx-color',
122
- 'settings' => 'jupiterx_header_menu_link_background_color_hover',
123
- 'css_var' => 'header-menu-link-background-color-hover',
124
- 'section' => $section,
125
- 'column' => '3',
126
- 'icon' => 'background-color',
127
- 'transport' => 'postMessage',
128
- 'output' => [
129
- [
130
- 'element' => '.jupiterx-site-navbar .navbar-nav .nav-link:hover',
131
- 'property' => 'background-color',
132
- ],
133
- ],
134
- ] );
135
-
136
- // Active label.
137
- JupiterX_Customizer::add_field( [
138
- 'type' => 'jupiterx-label',
139
- 'label' => __( 'Active', 'jupiterx-core' ),
140
- 'label_type' => 'fancy',
141
- 'color' => 'blue',
142
- 'settings' => 'jupiterx_header_menu_label_2',
143
- 'section' => $section,
144
- ] );
145
-
146
- // Text color active.
147
- JupiterX_Customizer::add_field( [
148
- 'type' => 'jupiterx-color',
149
- 'settings' => 'jupiterx_header_menu_link_color_active',
150
- 'css_var' => 'header-menu-link-color-active',
151
- 'section' => $section,
152
- 'column' => '3',
153
- 'icon' => 'font-color',
154
- 'transport' => 'postMessage',
155
- 'output' => [
156
- [
157
- 'element' => '.jupiterx-site-navbar .navbar-nav .active .nav-link',
158
- 'property' => 'color',
159
- ],
160
- ],
161
- ] );
162
-
163
- // Background color active.
164
- JupiterX_Customizer::add_field( [
165
- 'type' => 'jupiterx-color',
166
- 'settings' => 'jupiterx_header_menu_link_background_color_active',
167
- 'css_var' => 'header-menu-link-background-color-active',
168
- 'section' => $section,
169
- 'column' => '3',
170
- 'icon' => 'background-color',
171
- 'transport' => 'postMessage',
172
- 'output' => [
173
- [
174
- 'element' => '.jupiterx-site-navbar .navbar-nav .active .nav-link',
175
- 'property' => 'background-color',
176
- ],
177
- ],
178
- ] );
179
-
180
- // Divider.
181
- JupiterX_Customizer::add_field( [
182
- 'type' => 'jupiterx-divider',
183
- 'settings' => 'jupiterx_header_menu_divider_2',
184
- 'section' => $section,
185
- ] );
186
-
187
- // Menu spacing.
188
- JupiterX_Customizer::add_responsive_field( [
189
- 'type' => 'jupiterx-box-model',
190
- 'settings' => 'jupiterx_header_menu_spacing',
191
- 'css_var' => 'header-menu',
192
- 'section' => $section,
193
- 'transport' => 'postMessage',
194
- 'exclude' => [ 'padding' ],
195
- 'output' => [
196
- [
197
- 'element' => '.jupiterx-site-navbar .navbar-nav',
198
- ],
199
- ],
200
- ] );
201
-
202
- // Divider.
203
- JupiterX_Customizer::add_field( [
204
- 'type' => 'jupiterx-divider',
205
- 'settings' => 'jupiterx_header_menu_divider_3',
206
- 'section' => $section,
207
- ] );
208
-
209
- // Menu link spacing.
210
- JupiterX_Customizer::add_responsive_field( [
211
- 'type' => 'jupiterx-box-model',
212
- 'settings' => 'jupiterx_header_menu_link_spacing',
213
- 'css_var' => 'header-menu-link',
214
- 'section' => $section,
215
- 'transport' => 'postMessage',
216
- 'exclude' => [ 'margin' ],
217
- 'output' => [
218
- [
219
- 'element' => '.jupiterx-site-navbar .navbar-nav .nav-link',
220
- ],
221
- ],
222
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Header > Styles tab > Menu to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_header';
11
+
12
+ $menu_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_header_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ $menu_hover_condition = [
21
+ [
22
+ 'setting' => 'jupiterx_header_type',
23
+ 'operator' => '===',
24
+ 'value' => '',
25
+ ],
26
+ [
27
+ 'setting' => 'jupiterx_header_menu_label',
28
+ 'operator' => '===',
29
+ 'value' => 'hover',
30
+ ],
31
+ ];
32
+
33
+ $menu_active_condition = [
34
+ [
35
+ 'setting' => 'jupiterx_header_type',
36
+ 'operator' => '===',
37
+ 'value' => '',
38
+ ],
39
+ [
40
+ 'setting' => 'jupiterx_header_menu_label',
41
+ 'operator' => '===',
42
+ 'value' => 'active',
43
+ ],
44
+ ];
45
+
46
+ // Typography.
47
+ JupiterX_Customizer::add_field( [
48
+ 'type' => 'jupiterx-typography',
49
+ 'settings' => 'jupiterx_header_menu_link_typography',
50
+ 'css_var' => 'header-menu-link',
51
+ 'section' => $section,
52
+ 'box' => 'menu',
53
+ 'exclude' => [ 'line_height' ],
54
+ 'responsive' => true,
55
+ 'transport' => 'postMessage',
56
+ 'output' => [
57
+ [
58
+ 'element' => '.jupiterx-site-navbar .navbar-nav .nav-link',
59
+ ],
60
+ ],
61
+ 'active_callback' => $menu_condition,
62
+ ] );
63
+
64
+ // Spacing between.
65
+ JupiterX_Customizer::add_field( [
66
+ 'type' => 'jupiterx-input',
67
+ 'settings' => 'jupiterx_header_menu_item_spacing_between',
68
+ 'css_var' => 'header-menu-item-spacing-between',
69
+ 'section' => $section,
70
+ 'box' => 'menu',
71
+ 'label' => __( 'Space Between', 'jupiterx-core' ),
72
+ 'units' => [ 'px', 'em', 'rem' ],
73
+ 'input_attrs' => [
74
+ 'min' => 0,
75
+ 'max' => 500,
76
+ ],
77
+ 'transport' => 'postMessage',
78
+ 'output' => [
79
+ [
80
+ 'element' => '.jupiterx-site-navbar .navbar-nav > .nav-item',
81
+ 'property' => 'margin-left',
82
+ 'value_pattern' => 'calc( $ / 2)',
83
+ 'media_query' => '@media (min-width: 768px)',
84
+ ],
85
+ [
86
+ 'element' => '.jupiterx-site-navbar .navbar-nav > .nav-item',
87
+ 'property' => 'margin-right',
88
+ 'value_pattern' => 'calc( $ / 2)',
89
+ 'media_query' => '@media (min-width: 768px)',
90
+ ],
91
+ ],
92
+ 'active_callback' => $menu_condition,
93
+ ] );
94
+
95
+ // Background color.
96
+ JupiterX_Customizer::add_field( [
97
+ 'type' => 'jupiterx-color',
98
+ 'settings' => 'jupiterx_header_menu_link_background_color',
99
+ 'css_var' => 'header-menu-link-background-color',
100
+ 'section' => $section,
101
+ 'box' => 'menu',
102
+ 'label' => __( 'Background Color', 'jupiterx-core' ),
103
+ 'transport' => 'postMessage',
104
+ 'output' => [
105
+ [
106
+ 'element' => '.jupiterx-site-navbar .navbar-nav .nav-link',
107
+ 'property' => 'background-color',
108
+ ],
109
+ ],
110
+ 'active_callback' => $menu_condition,
111
+ ] );
112
+
113
+ // Border.
114
+ JupiterX_Customizer::add_field( [
115
+ 'type' => 'jupiterx-border',
116
+ 'settings' => 'jupiterx_header_menu_link_border',
117
+ 'css_var' => 'header-menu-link-border',
118
+ 'section' => $section,
119
+ 'box' => 'menu',
120
+ 'transport' => 'postMessage',
121
+ 'exclude' => [ 'size' ],
122
+ 'default' => [
123
+ 'width' => [
124
+ 'size' => '0',
125
+ 'unit' => 'px',
126
+ ],
127
+ ],
128
+ 'output' => [
129
+ [
130
+ 'element' => '.jupiterx-site-navbar .navbar-nav .nav-link',
131
+ ],
132
+ ],
133
+ 'active_callback' => $menu_condition,
134
+ ] );
135
+
136
+ // Hover label.
137
+ JupiterX_Customizer::add_field( [
138
+ 'type' => 'jupiterx-choose',
139
+ 'color' => 'orange',
140
+ 'settings' => 'jupiterx_header_menu_label',
141
+ 'section' => $section,
142
+ 'box' => 'menu',
143
+ 'transport' => 'postMessage',
144
+ 'default' => '',
145
+ 'choices' => [
146
+ 'hover' => [
147
+ 'label' => __( 'Hover', 'jupiterx-core' ),
148
+ ],
149
+ 'active' => [
150
+ 'label' => __( 'Active', 'jupiterx-core' ),
151
+ ],
152
+ ],
153
+ 'active_callback' => $menu_condition,
154
+ ] );
155
+
156
+ // Text color hover.
157
+ JupiterX_Customizer::add_field( [
158
+ 'type' => 'jupiterx-color',
159
+ 'settings' => 'jupiterx_header_menu_link_color_hover',
160
+ 'css_var' => 'header-menu-link-color-hover',
161
+ 'section' => $section,
162
+ 'box' => 'menu',
163
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
164
+ 'transport' => 'postMessage',
165
+ 'output' => [
166
+ [
167
+ 'element' => '.jupiterx-site-navbar .navbar-nav .nav-link:hover',
168
+ 'property' => 'color',
169
+ ],
170
+ ],
171
+ 'active_callback' => $menu_hover_condition,
172
+ ] );
173
+
174
+ // Background color hover.
175
+ JupiterX_Customizer::add_field( [
176
+ 'type' => 'jupiterx-color',
177
+ 'settings' => 'jupiterx_header_menu_link_background_color_hover',
178
+ 'css_var' => 'header-menu-link-background-color-hover',
179
+ 'section' => $section,
180
+ 'box' => 'menu',
181
+ 'label' => __( 'Background Color', 'jupiterx-core' ),
182
+ 'transport' => 'postMessage',
183
+ 'output' => [
184
+ [
185
+ 'element' => '.jupiterx-site-navbar .navbar-nav .nav-link:hover',
186
+ 'property' => 'background-color',
187
+ ],
188
+ ],
189
+ 'active_callback' => $menu_hover_condition,
190
+ ] );
191
+
192
+ // Text color active.
193
+ JupiterX_Customizer::add_field( [
194
+ 'type' => 'jupiterx-color',
195
+ 'settings' => 'jupiterx_header_menu_link_color_active',
196
+ 'css_var' => 'header-menu-link-color-active',
197
+ 'section' => $section,
198
+ 'box' => 'menu',
199
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
200
+ 'transport' => 'postMessage',
201
+ 'output' => [
202
+ [
203
+ 'element' => '.jupiterx-site-navbar .navbar-nav .active .nav-link',
204
+ 'property' => 'color',
205
+ ],
206
+ ],
207
+ 'active_callback' => $menu_active_condition,
208
+ ] );
209
+
210
+ // Background color active.
211
+ JupiterX_Customizer::add_field( [
212
+ 'type' => 'jupiterx-color',
213
+ 'settings' => 'jupiterx_header_menu_link_background_color_active',
214
+ 'css_var' => 'header-menu-link-background-color-active',
215
+ 'section' => $section,
216
+ 'box' => 'menu',
217
+ 'label' => __( 'Background Color', 'jupiterx-core' ),
218
+ 'transport' => 'postMessage',
219
+ 'output' => [
220
+ [
221
+ 'element' => '.jupiterx-site-navbar .navbar-nav .active .nav-link',
222
+ 'property' => 'background-color',
223
+ ],
224
+ ],
225
+ 'active_callback' => $menu_active_condition,
226
+ ] );
227
+
228
+ // Divider.
229
+ JupiterX_Customizer::add_field( [
230
+ 'type' => 'jupiterx-divider',
231
+ 'settings' => 'jupiterx_header_menu_divider_2',
232
+ 'section' => $section,
233
+ 'box' => 'menu',
234
+ 'active_callback' => $menu_condition,
235
+ ] );
236
+
237
+ // Menu spacing.
238
+ JupiterX_Customizer::add_responsive_field( [
239
+ 'type' => 'jupiterx-box-model',
240
+ 'settings' => 'jupiterx_header_menu_spacing',
241
+ 'css_var' => 'header-menu',
242
+ 'section' => $section,
243
+ 'box' => 'menu',
244
+ 'transport' => 'postMessage',
245
+ 'exclude' => [ 'padding' ],
246
+ 'output' => [
247
+ [
248
+ 'element' => '.jupiterx-site-navbar .navbar-nav',
249
+ ],
250
+ ],
251
+ 'active_callback' => $menu_condition,
252
+ ] );
253
+
254
+ // Divider.
255
+ JupiterX_Customizer::add_field( [
256
+ 'type' => 'jupiterx-divider',
257
+ 'settings' => 'jupiterx_header_menu_divider_3',
258
+ 'section' => $section,
259
+ 'box' => 'menu',
260
+ 'active_callback' => $menu_condition,
261
+ ] );
262
+
263
+ // Menu link spacing.
264
+ JupiterX_Customizer::add_responsive_field( [
265
+ 'type' => 'jupiterx-box-model',
266
+ 'settings' => 'jupiterx_header_menu_link_spacing',
267
+ 'css_var' => 'header-menu-link',
268
+ 'section' => $section,
269
+ 'box' => 'menu',
270
+ 'transport' => 'postMessage',
271
+ 'exclude' => [ 'margin' ],
272
+ 'output' => [
273
+ [
274
+ 'element' => '.jupiterx-site-navbar .navbar-nav .nav-link',
275
+ ],
276
+ ],
277
+ 'active_callback' => $menu_condition,
278
+ ] );
includes/customizer/settings/header/popup.php CHANGED
@@ -1,129 +1,87 @@
1
- <?php
2
- /**
3
- * Add Jupiter elements popup and tabs to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $popups = [
11
- 'logo' => __( 'Logo', 'jupiterx-core' ),
12
- 'Menu' => __( 'Menu', 'jupiterx-core' ),
13
- 'Submenu' => __( 'Submenu', 'jupiterx-core' ),
14
- 'search' => __( 'Search', 'jupiterx-core' ),
15
- 'container' => __( 'Container', 'jupiterx-core' ),
16
- 'sticky_container' => __( 'Sticky Container', 'jupiterx-core' ),
17
- 'sticky_logo' => __( 'Sticky Logo', 'jupiterx-core' ),
18
- ];
19
-
20
- // Header popup.
21
- JupiterX_Customizer::add_section( 'jupiterx_header', [
22
- 'title' => __( 'Header', 'jupiterx-core' ),
23
- 'type' => 'popup',
24
- 'priority' => 120,
25
- 'tabs' => [
26
- 'settings' => __( 'Settings', 'jupiterx-core' ),
27
- 'styles' => __( 'Styles', 'jupiterx-core' ),
28
- ],
29
- 'popups' => $popups,
30
- 'help' => [
31
- 'url' => 'https://themes.artbees.net/docs/assigning-the-header-globally',
32
- 'title' => __( 'Assigning the Header Globally', 'jupiterx-core' ),
33
- ],
34
- ] );
35
-
36
- // Settings tab.
37
- JupiterX_Customizer::add_section( 'jupiterx_header_settings', [
38
- 'popup' => 'jupiterx_header',
39
- 'type' => 'pane',
40
- 'pane' => [
41
- 'type' => 'tab',
42
- 'id' => 'settings',
43
- ],
44
- ] );
45
-
46
- // Styles tab.
47
- JupiterX_Customizer::add_section( 'jupiterx_header_styles', [
48
- 'popup' => 'jupiterx_header',
49
- 'type' => 'pane',
50
- 'pane' => [
51
- 'type' => 'tab',
52
- 'id' => 'styles',
53
- ],
54
- ] );
55
-
56
- // Styles warning.
57
- JupiterX_Customizer::add_field( [
58
- 'type' => 'jupiterx-alert',
59
- 'settings' => 'jupiterx_header_styles_warning',
60
- 'section' => 'jupiterx_header_styles',
61
- 'label' => __( 'Learn how to use the following settings properly.', 'jupiterx-core' ),
62
- 'jupiterx_url' => 'https://themes.artbees.net/docs/plugin-conflicts-with-jupiter-x',
63
- 'active_callback' => function() {
64
- return class_exists( '\ElementorPro\Plugin' ) && jupiterx_is_help_links();
65
- },
66
- ] );
67
-
68
- // Styles tab > Child popups.
69
- JupiterX_Customizer::add_field( [
70
- 'type' => 'jupiterx-child-popup',
71
- 'settings' => 'jupiterx_header_styles_popups',
72
- 'section' => 'jupiterx_header_styles',
73
- 'target' => 'jupiterx_header',
74
- 'choices' => [
75
- 'logo' => __( 'Logo', 'jupiterx-core' ),
76
- 'Menu' => __( 'Menu', 'jupiterx-core' ),
77
- 'Submenu' => __( 'Submenu', 'jupiterx-core' ),
78
- 'search' => __( 'Search', 'jupiterx-core' ),
79
- 'container' => __( 'Container', 'jupiterx-core' ),
80
- ],
81
- 'active_callback' => [
82
- [
83
- 'setting' => 'jupiterx_header_type',
84
- 'operator' => '!=',
85
- 'value' => '_custom',
86
- ],
87
- ],
88
- ] );
89
-
90
- // Styles tab > Child popups.
91
- JupiterX_Customizer::add_field( [
92
- 'type' => 'jupiterx-child-popup',
93
- 'settings' => 'jupiterx_header_styles_popups_sticky',
94
- 'section' => 'jupiterx_header_styles',
95
- 'target' => 'jupiterx_header',
96
- 'choices' => [
97
- 'sticky_logo' => __( 'Sticky Logo', 'jupiterx-core' ),
98
- 'sticky_container' => __( 'Sticky Container', 'jupiterx-core' ),
99
- ],
100
- 'active_callback' => [
101
- [
102
- 'setting' => 'jupiterx_header_behavior',
103
- 'operator' => '==',
104
- 'value' => 'sticky',
105
- ],
106
- [
107
- 'setting' => 'jupiterx_header_type',
108
- 'operator' => '!=',
109
- 'value' => '_custom',
110
- ],
111
- ],
112
- ] );
113
-
114
- // Create popup children.
115
- foreach ( $popups as $popup_id => $label ) {
116
- JupiterX_Customizer::add_section( 'jupiterx_header_' . $popup_id, [
117
- 'popup' => 'jupiterx_header',
118
- 'type' => 'pane',
119
- 'pane' => [
120
- 'type' => 'popup',
121
- 'id' => $popup_id,
122
- ],
123
- ] );
124
- }
125
-
126
- // Load all the settings.
127
- foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
128
- require_once $setting;
129
- }
1
+ <?php
2
+ /**
3
+ * Add Jupiter elements popup and tabs to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ add_action( 'jupiterx_header_settings_after_section', 'jupiterx_dependency_notice_handler', 10 );
11
+
12
+ // Header popup.
13
+ JupiterX_Customizer::add_section(
14
+ 'jupiterx_header',
15
+ array(
16
+ 'priority' => 50,
17
+ 'title' => __( 'Header', 'jupiterx-core' ),
18
+ 'type' => 'container',
19
+ 'tabs' => array(
20
+ 'settings' => __( 'Settings', 'jupiterx-core' ),
21
+ 'styles' => __( 'Styles', 'jupiterx-core' ),
22
+ ),
23
+ 'boxes' => array(
24
+ 'settings' => array(
25
+ 'label' => __( 'Settings', 'jupiterx-core' ),
26
+ 'tab' => 'settings',
27
+ ),
28
+ 'logo' => array(
29
+ 'label' => __( 'Logo', 'jupiterx-core' ),
30
+ 'tab' => 'styles',
31
+ ),
32
+ 'menu' => array(
33
+ 'label' => __( 'Menu', 'jupiterx-core' ),
34
+ 'tab' => 'styles',
35
+ ),
36
+ 'submenu' => array(
37
+ 'label' => __( 'Submenu', 'jupiterx-core' ),
38
+ 'tab' => 'styles',
39
+ ),
40
+ 'search' => array(
41
+ 'label' => __( 'Search', 'jupiterx-core' ),
42
+ 'tab' => 'styles',
43
+ ),
44
+ 'container' => array(
45
+ 'label' => __( 'Container', 'jupiterx-core' ),
46
+ 'tab' => 'styles',
47
+ ),
48
+ 'sticky_container' => array(
49
+ 'label' => __( 'Sticky Container', 'jupiterx-core' ),
50
+ 'tab' => 'styles',
51
+ ),
52
+ 'sticky_logo' => array(
53
+ 'label' => __( 'Sticky Logo', 'jupiterx-core' ),
54
+ 'tab' => 'styles',
55
+ ),
56
+ 'empty_notice' => array(
57
+ 'label' => __( 'Notice', 'jupiterx-core' ),
58
+ 'tab' => 'styles',
59
+ ),
60
+ ),
61
+ 'help' => array(
62
+ 'url' => 'https://themes.artbees.net/docs/assigning-the-header-globally',
63
+ 'title' => __( 'Assigning the Header Globally', 'jupiterx-core' ),
64
+ ),
65
+ 'group' => 'template_parts',
66
+ 'icon' => 'header',
67
+ )
68
+ );
69
+
70
+ // Styles warning.
71
+ JupiterX_Customizer::add_field(
72
+ array(
73
+ 'type' => 'jupiterx-alert',
74
+ 'settings' => 'jupiterx_header_styles_warning',
75
+ 'section' => 'jupiterx_header_styles',
76
+ 'label' => __( 'Learn how to use the following settings properly.', 'jupiterx-core' ),
77
+ 'jupiterx_url' => 'https://themes.artbees.net/docs/plugin-conflicts-with-jupiter-x',
78
+ 'active_callback' => function() {
79
+ return class_exists( '\ElementorPro\Plugin' ) && jupiterx_is_help_links();
80
+ },
81
+ )
82
+ );
83
+
84
+ // Load all the settings.
85
+ foreach ( glob( dirname( __FILE__ ) . '/*.php' ) as $setting ) {
86
+ require_once $setting;
87
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/customizer/settings/header/search.php CHANGED
@@ -1,148 +1,170 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Header > Styles tab > Search to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_header_search';
11
-
12
- // Width.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-input',
15
- 'settings' => 'jupiterx_header_search_width',
16
- 'css_var' => 'header-search-width',
17
- 'section' => $section,
18
- 'column' => '4',
19
- 'icon' => 'border-size',
20
- 'units' => [ 'px', '%', 'em', 'rem' ],
21
- 'transport' => 'postMessage',
22
- 'default' => [
23
- 'size' => 150,
24
- 'unit' => 'px',
25
- ],
26
- 'output' => [
27
- [
28
- 'element' => '.jupiterx-site-navbar .jupiterx-search-form .form-control',
29
- 'property' => 'width',
30
- ],
31
- ],
32
- ] );
33
-
34
- // Border.
35
- JupiterX_Customizer::add_field( [
36
- 'type' => 'jupiterx-border',
37
- 'settings' => 'jupiterx_header_search_border',
38
- 'css_var' => 'header-search-border',
39
- 'section' => $section,
40
- 'transport' => 'postMessage',
41
- 'exclude' => [ 'style', 'size' ],
42
- 'default' => [
43
- 'radius' => [
44
- 'size' => 4,
45
- 'unit' => 'px',
46
- ],
47
- ],
48
- 'output' => [
49
- [
50
- 'element' => '.jupiterx-site-navbar .jupiterx-search-form .form-control',
51
- ],
52
- ],
53
- ] );
54
-
55
- // Background color.
56
- JupiterX_Customizer::add_field( [
57
- 'type' => 'jupiterx-color',
58
- 'settings' => 'jupiterx_header_search_background_color',
59
- 'css_var' => 'header-search-background-color',
60
- 'section' => $section,
61
- 'column' => '3',
62
- 'icon' => 'background-color',
63
- 'transport' => 'postMessage',
64
- 'output' => [
65
- [
66
- 'element' => '.jupiterx-site-navbar .jupiterx-search-form .form-control',
67
- 'property' => 'background-color',
68
- ],
69
- ],
70
- ] );
71
-
72
- // Text color.
73
- JupiterX_Customizer::add_field( [
74
- 'type' => 'jupiterx-color',
75
- 'settings' => 'jupiterx_header_search_text_color',
76
- 'css_var' => 'header-search-text-color',
77
- 'section' => $section,
78
- 'column' => '3',
79
- 'icon' => 'font-color',
80
- 'transport' => 'postMessage',
81
- 'output' => [
82
- [
83
- 'element' => '.jupiterx-site-navbar .jupiterx-search-form .form-control, .jupiterx-site-navbar .jupiterx-search-form .form-control::placeholder',
84
- 'property' => 'color',
85
- ],
86
- ],
87
- ] );
88
-
89
- // Icon color.
90
- JupiterX_Customizer::add_field( [
91
- 'type' => 'jupiterx-color',
92
- 'settings' => 'jupiterx_header_search_icon_color',
93
- 'css_var' => 'header-search-icon-color',
94
- 'section' => $section,
95
- 'column' => '3',
96
- 'icon' => 'icon-color',
97
- 'transport' => 'postMessage',
98
- 'output' => [
99
- [
100
- 'element' => '.jupiterx-site-navbar .jupiterx-search-form .btn',
101
- 'property' => 'color',
102
- ],
103
- ],
104
- ] );
105
-
106
- // Divider.
107
- JupiterX_Customizer::add_field( [
108
- 'type' => 'jupiterx-divider',
109
- 'settings' => 'jupiterx_header_search_divider',
110
- 'section' => $section,
111
- ] );
112
-
113
- // Form spacing.
114
- JupiterX_Customizer::add_responsive_field( [
115
- 'type' => 'jupiterx-box-model',
116
- 'settings' => 'jupiterx_header_search_spacing',
117
- 'css_var' => 'header-search',
118
- 'section' => $section,
119
- 'transport' => 'postMessage',
120
- 'exclude' => [ 'padding' ],
121
- 'output' => [
122
- [
123
- 'element' => '.jupiterx-site-navbar .jupiterx-search-form',
124
- ],
125
- ],
126
- ] );
127
-
128
- // Divider.
129
- JupiterX_Customizer::add_field( [
130
- 'type' => 'jupiterx-divider',
131
- 'settings' => 'header_search_divider_2',
132
- 'section' => $section,
133
- ] );
134
-
135
- // Field spacing.
136
- JupiterX_Customizer::add_responsive_field( [
137
- 'type' => 'jupiterx-box-model',
138
- 'settings' => 'jupiterx_header_search_field_spacing',
139
- 'css_var' => 'header-search-field',
140
- 'section' => $section,
141
- 'transport' => 'postMessage',
142
- 'exclude' => [ 'margin' ],
143
- 'output' => [
144
- [
145
- 'element' => '.jupiterx-site-navbar .jupiterx-search-form .form-control',
146
- ],
147
- ],
148
- ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Header > Styles tab > Search to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_header';
11
+
12
+ $search_condition = [
13
+ [
14
+ 'setting' => 'jupiterx_header_type',
15
+ 'operator' => '===',
16
+ 'value' => '',
17
+ ],
18
+ ];
19
+
20
+ // Width.
21
+ JupiterX_Customizer::add_field( [
22
+ 'type' => 'jupiterx-input',
23
+ 'settings' => 'jupiterx_header_search_width',
24
+ 'css_var' => 'header-search-width',
25
+ 'section' => $section,
26
+ 'box' => 'search',
27
+ 'label' => __( 'Width', 'jupiterx-core' ),
28
+ 'units' => [ 'px', '%', 'em', 'rem' ],
29
+ 'transport' => 'postMessage',
30
+ 'default' => [
31
+ 'size' => 150,
32
+ 'unit' => 'px',
33
+ ],
34
+ 'output' => [
35
+ [
36
+ 'element' => '.jupiterx-site-navbar .jupiterx-search-form .form-control',
37
+ 'property' => 'width',
38
+ ],
39
+ ],
40
+ 'active_callback' => $search_condition,
41
+ ] );
42
+
43
+ // Border.
44
+ JupiterX_Customizer::add_field( [
45
+ 'type' => 'jupiterx-border',
46
+ 'settings' => 'jupiterx_header_search_border',
47
+ 'css_var' => 'header-search-border',
48
+ 'section' => $section,
49
+ 'box' => 'search',
50
+ 'transport' => 'postMessage',
51
+ 'exclude' => [ 'style', 'size' ],
52
+ 'default' => [
53
+ 'radius' => [
54
+ 'size' => 4,
55
+ 'unit' => 'px',
56
+ ],
57
+ ],
58
+ 'output' => [
59
+ [
60
+ 'element' => '.jupiterx-site-navbar .jupiterx-search-form .form-control',
61
+ ],
62
+ ],
63
+ 'active_callback' => $search_condition,
64
+ ] );
65
+
66
+ // Background color.
67
+ JupiterX_Customizer::add_field( [
68
+ 'type' => 'jupiterx-color',
69
+ 'settings' => 'jupiterx_header_search_background_color',
70
+ 'css_var' => 'header-search-background-color',
71
+ 'section' => $section,
72
+ 'box' => 'search',
73
+ 'label' => __( 'Background Color', 'jupiterx-core' ),
74
+ 'transport' => 'postMessage',
75
+ 'output' => [
76
+ [
77
+ 'element' => '.jupiterx-site-navbar .jupiterx-search-form .form-control',
78
+ 'property' => 'background-color',
79
+ ],
80
+ ],
81
+ 'active_callback' => $search_condition,
82
+ ] );
83
+
84
+ // Text color.
85
+ JupiterX_Customizer::add_field( [
86
+ 'type' => 'jupiterx-color',
87
+ 'settings' => 'jupiterx_header_search_text_color',
88
+ 'css_var' => 'header-search-text-color',
89
+ 'section' => $section,
90
+ 'box' => 'search',
91
+ 'label' => __( 'Font Color', 'jupiterx-core' ),
92
+ 'transport' => 'postMessage',
93
+ 'output' => [
94
+ [
95
+ 'element' => '.jupiterx-site-navbar .jupiterx-search-form .form-control, .jupiterx-site-navbar .jupiterx-search-form .form-control::placeholder',
96
+ 'property' => 'color',
97
+ ],
98
+ ],
99
+ 'active_callback' => $search_condition,
100
+ ] );
101
+
102
+ // Icon color.
103
+ JupiterX_Customizer::add_field( [
104
+ 'type' => 'jupiterx-color',
105
+ 'settings' => 'jupiterx_header_search_icon_color',
106
+ 'css_var' => 'header-search-icon-color',
107
+ 'section' => $section,
108
+ 'box' => 'search',
109
+ 'label' => __( 'Icon Color', 'jupiterx-core' ),
110
+ 'transport' => 'postMessage',
111
+ 'output' => [
112
+ [
113
+ 'element' => '.jupiterx-site-navbar .jupiterx-search-form .btn',
114
+ 'property' => 'color',
115
+ ],
116
+ ],
117
+ 'active_callback' => $search_condition,
118
+ ] );
119
+
120
+ // Divider.
121
+ JupiterX_Customizer::add_field( [
122
+ 'type' => 'jupiterx-divider',
123
+ 'settings' => 'jupiterx_header_search_divider',
124
+ 'section' => $section,
125
+ 'box' => 'search',
126
+ 'active_callback' => $search_condition,
127
+ ] );
128
+
129
+ // Form spacing.
130
+ JupiterX_Customizer::add_responsive_field( [
131
+ 'type' => 'jupiterx-box-model',
132
+ 'settings' => 'jupiterx_header_search_spacing',
133
+ 'css_var' => 'header-search',
134
+ 'section' => $section,
135
+ 'box' => 'search',
136
+ 'transport' => 'postMessage',
137
+ 'exclude' => [ 'padding' ],
138
+ 'output' => [
139
+ [
140
+ 'element' => '.jupiterx-site-navbar .jupiterx-search-form',
141
+ ],
142
+ ],
143
+ 'active_callback' => $search_condition,
144
+ ] );
145
+
146
+ // Divider.
147
+ JupiterX_Customizer::add_field( [
148
+ 'type' => 'jupiterx-divider',
149
+ 'settings' => 'header_search_divider_2',
150
+ 'section' => $section,
151
+ 'box' => 'search',
152
+ 'active_callback' => $search_condition,
153
+ ] );
154
+
155
+ // Field spacing.
156
+ JupiterX_Customizer::add_responsive_field( [
157
+ 'type' => 'jupiterx-box-model',
158
+ 'settings' => 'jupiterx_header_search_field_spacing',
159
+ 'css_var' => 'header-search-field',
160
+ 'section' => $section,
161
+ 'box' => 'search',
162
+ 'transport' => 'postMessage',
163
+ 'exclude' => [ 'margin' ],
164
+ 'output' => [
165
+ [
166
+ 'element' => '.jupiterx-site-navbar .jupiterx-search-form .form-control',
167
+ ],
168
+ ],
169
+ 'active_callback' => $search_condition,
170
+ ] );
includes/customizer/settings/header/settings.php CHANGED
@@ -1,274 +1,298 @@
1
- <?php
2
- /**
3
- * Add Jupiter settings for Header > Settings tab to the WordPress Customizer.
4
- *
5
- * @package JupiterX\Framework\Admin\Customizer
6
- *
7
- * @since 1.0.0
8
- */
9
-
10
- $section = 'jupiterx_header_settings';
11
-
12
- // Warning.
13
- JupiterX_Customizer::add_field( [
14
- 'type' => 'jupiterx-alert',
15
- 'settings' => 'jupiterx_header_warning',
16
- 'section' => $section,
17
- 'label' => __( 'Learn how to use the following settings properly.', 'jupiterx-core' ),
18
- 'jupiterx_url' => 'https://themes.artbees.net/docs/plugin-conflicts-with-jupiter-x',
19
- 'active_callback' => function() {
20
- return class_exists( '\ElementorPro\Plugin' ) && jupiterx_is_help_links();
21
- },
22
- ] );
23
-
24
- // Type.
25
- JupiterX_Customizer::add_field( [
26
- 'type' => 'jupiterx-choose',
27
- 'settings' => 'jupiterx_header_type',
28
- 'section' => $section,
29
- 'label' => __( 'Type', 'jupiterx-core' ),
30
- 'default' => '',
31
- 'choices' => [
32
- '' => [
33
- 'label' => __( 'Default', 'jupiterx-core' ),
34
- ],
35
- '_custom' => [
36
- 'label' => __( 'Custom', 'jupiterx-core' ),
37
- 'pro' => true,
38
- ],
39
- ],
40
- ] );
41
-
42
- // Align.
43
- JupiterX_Customizer::add_responsive_field( [
44
- 'type' => 'jupiterx-choose',
45
- 'settings' => 'jupiterx_header_align',
46
- 'css_var' => 'header-align',
47
- 'section' => $section,
48
- 'label' => __( 'Align', 'jupiterx-core' ),
49
- 'column' => '4',
50
- 'default' => [
51
- 'desktop' => 'row',
52
- 'tablet' => 'row',
53
- 'mobile' => 'row',
54
- ],
55
- 'choices' => JupiterX_Customizer_Utils::get_align( 'flex-direction', [ 'center' ] ),
56
- 'output' => [
57
- [
58
- 'element' => '.jupiterx-site-navbar > div',
59
- 'property' => 'flex-direction',
60
- ],
61
- ],
62
- 'active_callback' => [
63
- [
64
- 'setting' => 'jupiterx_header_type',
65
- 'operator' => '===',
66
- 'value' => '',
67
- ],
68
- ],
69
- ] );
70
-
71
- // Overlap content.
72
- JupiterX_Customizer::add_responsive_field( [
73
- 'type' => 'jupiterx-toggle',
74
- 'settings' => 'jupiterx_header_overlap',
75
- 'css_var' => 'header-overlap',
76
- 'section' => $section,
77
- 'label' => __( 'Overlap Content', 'jupiterx-core' ),
78
- 'column' => '4',
79
- 'active_callback' => [
80
- [
81
- 'setting' => 'jupiterx_header_type',
82
- 'operator' => '===',
83
- 'value' => '',
84
- ],
85
- ],
86
- ] );
87
-
88
- // Full width.
89
- JupiterX_Customizer::add_field( [
90
- 'type' => 'jupiterx-toggle',
91
- 'settings' => 'jupiterx_header_full_width',
92
- 'section' => $section,
93
- 'label' => __( 'Full Width', 'jupiterx-core' ),
94
- 'column' => '4',
95
- 'active_callback' => [
96
- [
97
- 'setting' => 'jupiterx_header_type',
98
- 'operator' => '===',
99
- 'value' => '',
100
- ],
101
- ],
102
- ] );
103
-
104
- // Display elements.
105
- JupiterX_Customizer::add_responsive_field( [
106
- 'type' => 'jupiterx-multicheck',
107
- 'settings' => 'jupiterx_header_elements',
108
- 'section' => $section,
109
- 'css_var' => 'header_elements',
110
- 'label' => __( 'Display Elements', 'jupiterx-core' ),
111
- 'default' => [
112
- 'desktop' => [ 'logo', 'menu', 'search', 'cart' ],
113
- 'tablet' => [ 'logo', 'menu', 'search', 'cart' ],
114
- 'mobile' => [ 'logo', 'menu', 'search', 'cart' ],
115
- ],
116
- 'choices' => [
117
- 'logo' => __( 'Logo', 'jupiterx-core' ),
118
- 'menu' => __( 'Menu', 'jupiterx-core' ),
119
- 'search' => __( 'Search', 'jupiterx-core' ),
120
- 'cart' => __( 'Cart', 'jupiterx-core' ),
121
- ],
122
- 'active_callback' => [
123
- [
124
- 'setting' => 'jupiterx_header_type',
125
- 'operator' => '===',
126
- 'value' => '',
127
- ],
128
- ],
129
- ] );
130
-
131
- // Behavior.
132
- JupiterX_Customizer::add_field( [
133
- 'type' => 'jupiterx-choose',
134
- 'settings' => 'jupiterx_header_behavior',
135
- 'css_var' => 'header-behavior',
136
- 'section' => $section,
137
- 'label' => __( 'Behavior', 'jupiterx-core' ),
138
- 'column' => '5',
139
- 'default' => 'static',
140
- 'choices' => [
141
- 'static' => [
142
- 'label' => __( 'Static', 'jupiterx-core' ),
143
- ],
144
- 'fixed' => [
145
- 'label' => __( 'Fixed', 'jupiterx-core' ),
146
- ],
147
- 'sticky' => [
148
- 'label' => __( 'Sticky', 'jupiterx-core' ),
149
- ],
150
- ],
151
- 'active_callback' => [
152
- [
153
- 'setting' => 'jupiterx_header_type',
154
- 'operator' => '===',
155
- 'value' => '',
156
- ],
157
- ],
158
- ] );
159
-
160
- // Position.
161
- JupiterX_Customizer::add_field( [
162
- 'type' => 'jupiterx-choose',
163
- 'settings' => 'jupiterx_header_position',
164
- 'css_var' => 'header-position',
165
- 'section' => $section,
166
- 'label' => __( 'Position', 'jupiterx-core' ),
167
- 'column' => '3',
168
- 'default' => 'top',
169
- 'choices' => [
170
- 'top' => [
171
- 'label' => __( 'Top', 'jupiterx-core' ),
172
- ],
173
- 'bottom' => [
174
- 'label' => __( 'Bottom', 'jupiterx-core' ),
175
- ],
176
- ],
177
- 'active_callback' => [
178
- [
179
- 'setting' => 'jupiterx_header_type',
180
- 'operator' => '===',
181
- 'value' => '',
182
- ],
183
- [
184
- 'setting' => 'jupiterx_header_behavior',
185
- 'operator' => '===',
186
- 'value' => 'fixed',
187
- ],
188
- ],
189
- ] );
190
-
191
- // Offset.
192
- JupiterX_Customizer::add_field( [
193
- 'type' => 'jupiterx-text',
194
- 'settings' => 'jupiterx_header_offset',
195
- 'css_var' => 'header-offset',
196
- 'section' => $section,
197
- 'label' => __( 'Offset', 'jupiterx-core' ),
198
- 'column' => '3',
199
- 'inputType' => 'number',
200
- 'unit' => 'px',
201
- 'default' => 500,
202
- 'active_callback' => [
203
- [
204
- 'setting' => 'jupiterx_header_type',
205
- 'operator' => '===',
206
- 'value' => '',
207
- ],
208
- [
209
- 'setting' => 'jupiterx_header_behavior',
210
- 'operator' => '===',
211
- 'value' => 'sticky',
212
- ],
213
- ],
214
- ] );
215
-
216
- // Behavior tablet.
217
- JupiterX_Customizer::add_field( [
218
- 'type' => 'jupiterx-toggle',
219
- 'settings' => 'jupiterx_header_behavior_tablet',
220
- 'css_var' => 'header-behavior-tablet',
221
- 'section' => $section,
222
- 'label' => __( 'Enable on Tablet', 'jupiterx-core' ),
223
- 'column' => '6',
224
- 'default' => true,
225
- 'active_callback' => [
226
- [
227
- 'setting' => 'jupiterx_header_type',
228
- 'operator' => '===',
229
- 'value' => '',
230
- ],
231
- [
232
- 'setting' => 'jupiterx_header_behavior',
233
- 'operator' => '!==',
234
- 'value' => 'static',
235
- ],
236
- ],
237
- ] );
238
-
239
- // Behavior mobile.
240
- JupiterX_Customizer::add_field( [
241
- 'type' => 'jupiterx-toggle',
242
- 'settings' => 'jupiterx_header_behavior_mobile',
243
- 'css_var' => 'header-behavior-mobile',
244
- 'section' => $section,
245
- 'label' => __( 'Enable on Mobile', 'jupiterx-core' ),
246
- 'column' => '6',
247
- 'default' => true,
248
- 'active_callback' => [
249
- [
250
- 'setting' => 'jupiterx_header_type',
251
- 'operator' => '===',
252
- 'value' => '',
253
- ],
254
- [
255
- 'setting' => 'jupiterx_header_behavior',
256
- 'operator' => '!==',
257
- 'value' => 'static',
258
- ],
259
- ],
260
- ] );
261
-
262
- // Pro Box.
263
- JupiterX_Customizer::add_field( [
264
- 'type' => 'jupiterx-pro-box',
265
- 'settings' => 'jupiterx_header_custom_pro_box',
266
- 'section' => $section,
267
- 'active_callback' => [
268
- [
269
- 'setting' => 'jupiterx_header_type',
270
- 'operator' => '===',
271
- 'value' => '_custom',
272
- ],
273
- ],
274
- ] );
1
+ <?php
2
+ /**
3
+ * Add Jupiter settings for Header > Settings tab to the WordPress Customizer.
4
+ *
5
+ * @package JupiterX\Framework\Admin\Customizer
6
+ *
7
+ * @since 1.0.0
8
+ */
9
+
10
+ $section = 'jupiterx_header';
11
+
12
+ // Warning.
13
+ JupiterX_Customizer::add_field( [
14
+ 'type' => 'jupiterx-alert',
15
+ 'settings' => 'jupiterx_header_warning',
16
+ 'section' => $section,
17
+ 'box' => 'settings',
18
+ 'label' => __( 'Learn how to use the following settings properly.', 'jupiterx-core' ),
19
+ 'jupiterx_url' => 'https://themes.artbees.net/docs/plugin-conflicts-with-jupiter-x',
20
+ 'active_callback' => function() {
21
+ return class_exists( '\ElementorPro\Plugin' ) && jupiterx_is_help_links();
22
+ },
23
+ ] );
24
+
25
+ // Type.
26
+ JupiterX_Customizer::add_field( [
27
+ 'type' => 'jupiterx-choose',
28
+ 'settings' => 'jupiterx_header_type',
29
+ 'section' => $section,
30
+ 'box' => 'settings',
31
+ 'priority' => 5,
32
+ 'label' => __( 'Type', 'jupiterx-core' ),
33
+ 'default' => '',
34
+ 'choices' => [
35
+ '' => [
36
+ 'label' => __( 'Default', 'jupiterx-core' ),
37
+ ],
38
+ '_custom' => [
39
+ 'label' => __( 'Custom', 'jupiterx-core' ),
40
+ 'pro' => true,
41
+ ],
42
+ ],
43
+ ] );
44
+
45
+ // Align.
46
+ JupiterX_Customizer::add_responsive_field( [
47
+ 'type' => 'jupiterx-choose',
48
+ 'settings' => 'jupiterx_header_align',
49
+ 'css_var' => 'header-align',
50
+ 'section' => $section,
51
+ 'box' => 'settings',
52
+ 'inline' => true,
53
+ 'label' => __( 'Alignment', 'jupiterx-core' ),
54
+ 'inline' => true,
55
+ 'default' => [
56
+ 'desktop' => 'row',
57
+ 'tablet' => 'row',
58
+ 'mobile' => 'row',
59
+ ],
60
+ 'choic