SiteOrigin Widgets Bundle - Version 1.11.5

Version Description

  • 13 March 2018 =
  • Features: Better feature padding removal on row ends.
  • Sliders: WCAG 2.4.4 compliance.
  • Tabs: Hide widget title when no title is set.
  • TinyMCE field: Added setting for wpautop processing which is on by default.
  • Contact: When Gradient disabled, set basic background.
  • Beaver Builder compat: Only set SOWB widget form values when editing a SOWB widget.
  • Contact: Option to log submitter's IP address.
  • Add random number and set more_entropy to increase chance of unique form ids.
  • Contact: Added 'tel' field type which should show numeric keyboard on mobile.
  • Media field: Trigger change event when removing selected image.
  • Renamed the PHP LESS parser to SiteOrigin_LessC to avoid conflicts.
  • Date range field: Prevent initializing date range fields multiple times and ensure date format consistent.
  • Register pikaday as common script and enqueue as needed in fields.
  • Google Map: Show satellite map type.
  • Translation: Add context to From strings.
  • Add missing semicolons to Ionicons codes.
Download this release

Release Info

Developer gpriday
Plugin Icon 128x128 SiteOrigin Widgets Bundle
Version 1.11.5
Comparing to
See all releases

Code changes from version 1.11.4 to 1.11.5

base/inc/actions.php CHANGED
@@ -1,278 +1,278 @@
1
- <?php
2
-
3
- /**
4
- * Action for displaying the widget preview.
5
- */
6
- function siteorigin_widget_preview_widget_action() {
7
- if ( empty( $_REQUEST['_widgets_nonce'] ) ||
8
- ! wp_verify_nonce( $_REQUEST['_widgets_nonce'], 'widgets_action' ) ) {
9
-
10
- wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 403 );
11
- } else if ( empty( $_POST['class'] ) ) {
12
- wp_die( __( 'Invalid post.', 'so-widgets-bundle' ), 400 );
13
- }
14
-
15
- // Get the widget from the widget factory
16
- global $wp_widget_factory;
17
- $widget = ! empty( $wp_widget_factory->widgets[ $_POST['class'] ] ) ? $wp_widget_factory->widgets[ $_POST['class'] ] : false;
18
-
19
- if( ! is_a( $widget, 'SiteOrigin_Widget' ) ) {
20
- wp_die( __( 'Invalid post.', 'so-widgets-bundle' ), 400 );
21
- }
22
-
23
- $instance = json_decode( stripslashes_deep($_POST['data']), true);
24
- /* @var $widget SiteOrigin_Widget */
25
- $instance = $widget->update( $instance, $instance );
26
- $instance['is_preview'] = true;
27
-
28
- // The theme stylesheet will change how the button looks
29
- wp_enqueue_style( 'theme-css', get_stylesheet_uri(), array(), rand( 0, 65536 ) );
30
- wp_enqueue_style( 'so-widget-preview', siteorigin_widgets_url( 'base/css/preview.css' ), array(), rand( 0,65536 ) );
31
-
32
- $sowb = SiteOrigin_Widgets_Bundle::single();
33
- $sowb->register_general_scripts();
34
-
35
- ob_start();
36
- $widget->widget( array(
37
- 'before_widget' => '',
38
- 'after_widget' => '',
39
- 'before_title' => '<h3 class="widget-title">',
40
- 'after_title' => '</h3>',
41
- ), $instance);
42
- $widget_html = ob_get_clean();
43
-
44
- // Print all the scripts and styles
45
- ?>
46
- <html>
47
- <head>
48
- <title><?php _e('Widget Preview', 'so-widgets-bundle') ?></title>
49
- <?php
50
- wp_print_scripts();
51
- wp_print_styles();
52
- siteorigin_widget_print_styles();
53
- ?>
54
- </head>
55
- <body>
56
- <?php // A lot of themes use entry-content as their main content wrapper ?>
57
- <div class="entry-content">
58
- <?php echo $widget_html ?>
59
- </div>
60
- </body>
61
- </html>
62
-
63
- <?php
64
- wp_die();
65
- }
66
- add_action('wp_ajax_so_widgets_preview', 'siteorigin_widget_preview_widget_action');
67
-
68
- /**
69
- * Action to handle searching posts
70
- */
71
- function siteorigin_widget_action_search_posts() {
72
- if ( empty( $_REQUEST['_widgets_nonce'] ) || ! wp_verify_nonce( $_REQUEST['_widgets_nonce'], 'widgets_action' ) ) {
73
- wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 403 );
74
- }
75
-
76
- // Get all public post types, besides attachments
77
- $post_types = (array) get_post_types( array(
78
- 'public' => true,
79
- ) );
80
-
81
- if ( ! empty( $_REQUEST['postTypes'] ) ) {
82
- $post_types = array_intersect( explode( ',', $_REQUEST['postTypes'] ), $post_types );
83
- } else {
84
- unset( $post_types['attachment'] );
85
- }
86
-
87
- $post_types = apply_filters( 'siteorigin_widgets_search_posts_post_types', $post_types );
88
-
89
- global $wpdb;
90
- if( !empty($_GET['query']) ) {
91
- $query = "AND post_title LIKE '%" . esc_sql( $_GET['query'] ) . "%'";
92
- }
93
- else {
94
- $query = '';
95
- }
96
-
97
- $post_types = "'" . implode("', '", array_map( 'esc_sql', $post_types ) ) . "'";
98
-
99
- $results = $wpdb->get_results( "
100
- SELECT ID AS 'value', post_title AS label, post_type AS 'type'
101
- FROM {$wpdb->posts}
102
- WHERE
103
- post_type IN ( {$post_types} ) AND post_status = 'publish' {$query}
104
- ORDER BY post_modified DESC
105
- LIMIT 20
106
- ", ARRAY_A );
107
-
108
- wp_send_json( apply_filters( 'siteorigin_widgets_search_posts_results', $results ) );
109
- }
110
- add_action('wp_ajax_so_widgets_search_posts', 'siteorigin_widget_action_search_posts');
111
-
112
- /**
113
- * Action to handle searching taxonomy terms.
114
- */
115
- function siteorigin_widget_action_search_terms() {
116
- if ( empty( $_REQUEST['_widgets_nonce'] ) || ! wp_verify_nonce( $_REQUEST['_widgets_nonce'], 'widgets_action' ) ) {
117
- wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 403 );
118
- }
119
-
120
- global $wpdb;
121
- $term = ! empty($_GET['term']) ? stripslashes($_GET['term']) : '';
122
- $term = trim($term, '%');
123
-
124
- $query = $wpdb->prepare("
125
- SELECT terms.term_id, terms.slug AS 'value', terms.name AS 'label', termtaxonomy.taxonomy AS 'type'
126
- FROM $wpdb->terms AS terms
127
- JOIN $wpdb->term_taxonomy AS termtaxonomy ON terms.term_id = termtaxonomy.term_id
128
- WHERE
129
- terms.name LIKE '%s'
130
- LIMIT 20
131
- ", '%' . esc_sql( $term ) . '%');
132
-
133
- $results = array();
134
-
135
- foreach ( $wpdb->get_results( $query ) as $result ) {
136
- $results[] = array(
137
- 'value' => $result->type . ':' . $result->value,
138
- 'label' => $result->label,
139
- 'type' => $result->type,
140
- );
141
- }
142
-
143
- wp_send_json( $results );
144
- }
145
- add_action('wp_ajax_so_widgets_search_terms', 'siteorigin_widget_action_search_terms');
146
-
147
- /**
148
- * Action for getting the number of posts returned by a query.
149
- */
150
- function siteorigin_widget_get_posts_count_action() {
151
-
152
- if ( empty( $_REQUEST['_widgets_nonce'] ) || ! wp_verify_nonce( $_REQUEST['_widgets_nonce'], 'widgets_action' ) ) {
153
- wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 403 );
154
- }
155
-
156
- $query = stripslashes( $_POST['query'] );
157
-
158
- wp_send_json( array( 'posts_count' => siteorigin_widget_post_selector_count_posts( $query ) ) );
159
- }
160
-
161
- add_action( 'wp_ajax_sow_get_posts_count', 'siteorigin_widget_get_posts_count_action' );
162
-
163
-
164
- function siteorigin_widget_remote_image_search(){
165
- if( empty( $_GET[ '_sononce' ] ) || ! wp_verify_nonce( $_GET[ '_sononce' ], 'so-image' ) ) {
166
- wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 403 );
167
- }
168
-
169
- if( empty( $_GET['q'] ) ) {
170
- wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 400 );
171
- }
172
-
173
- // Send the query to stock search server
174
- $url = add_query_arg( array(
175
- 'q' => $_GET[ 'q' ],
176
- 'page' => !empty( $_GET[ 'page' ] ) ? intval( $_GET[ 'page' ] ) : 1,
177
- ), 'http://stock.siteorigin.com/wp-admin/admin-ajax.php?action=image_search' );
178
-
179
- $result = wp_remote_get( $url, array(
180
- 'timeout' => 20,
181
- ) );
182
-
183
- if( ! is_wp_error( $result ) ) {
184
- $result = json_decode( $result['body'], true );
185
- if( !empty( $result['items'] ) ) {
186
- foreach( $result['items'] as & $r ) {
187
- if( !empty( $r['full_url'] ) ) {
188
- $r['import_signature'] = md5( $r['full_url'] . '::' . NONCE_SALT );
189
- }
190
- }
191
- }
192
- wp_send_json( $result );
193
- }
194
- else {
195
- $result = array(
196
- 'error' => true,
197
- 'message' => $result->get_error_message()
198
- );
199
- wp_send_json_error( $result );
200
- }
201
-
202
- }
203
- add_action('wp_ajax_so_widgets_image_search', 'siteorigin_widget_remote_image_search');
204
-
205
- function siteorigin_widget_image_import(){
206
- if( empty( $_GET[ '_sononce' ] ) || ! wp_verify_nonce( $_GET[ '_sononce' ], 'so-image' ) ) {
207
- $result = array(
208
- 'error' => true,
209
- 'message' => __( 'Nonce error', 'so-widgets-bundle' ),
210
- );
211
- }
212
- else if(
213
- empty( $_GET['import_signature'] ) ||
214
- empty( $_GET['full_url'] ) ||
215
- md5( $_GET['full_url'] . '::' . NONCE_SALT ) !== $_GET['import_signature']
216
- ) {
217
- $result = array(
218
- 'error' => true,
219
- 'message' => __( 'Signature error', 'so-widgets-bundle' ),
220
- );
221
- }
222
- else {
223
- // Fetch the image
224
- $src = media_sideload_image( $_GET['full_url'], $_GET['post_id'], null, 'src' );
225
- if( is_wp_error( $src ) ) {
226
- $result = array(
227
- 'error' => true,
228
- 'message' => $src->get_error_code(),
229
- );
230
- }
231
- else {
232
- global $wpdb;
233
- $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE guid='%s';", $src ) );
234
- if( !empty( $attachment ) ) {
235
- $thumb_src = wp_get_attachment_image_src( $attachment[0], 'thumbnail' );
236
- $result = array(
237
- 'error' => false,
238
- 'attachment_id' => $attachment[0],
239
- 'thumb' => $thumb_src[0]
240
- );
241
- }
242
- else {
243
- $result = array(
244
- 'error' => true,
245
- 'message' => __( 'Attachment error', 'so-widgets-bundle' ),
246
- );
247
- }
248
- }
249
- }
250
-
251
- // Return the result
252
- wp_send_json( $result );
253
- }
254
- add_action('wp_ajax_so_widgets_image_import', 'siteorigin_widget_image_import');
255
-
256
- /**
257
- * Action to handle a user dismissing a teaser notice.
258
- */
259
- function siteorigin_widgets_dismiss_widget_action(){
260
- if( empty( $_GET[ '_wpnonce' ] ) || ! wp_verify_nonce( $_GET[ '_wpnonce' ], 'dismiss-widget-teaser' ) ) {
261
- wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 403 );
262
- }
263
- if( empty( $_GET[ 'widget' ] ) ) {
264
- wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 400 );
265
- }
266
-
267
- $dismissed = get_user_meta( get_current_user_id(), 'teasers_dismissed', true );
268
- if( empty( $dismissed ) ) {
269
- $dismissed = array();
270
- }
271
-
272
- $dismissed[ $_GET[ 'widget' ] ] = true;
273
-
274
- update_user_meta( get_current_user_id(), 'teasers_dismissed', $dismissed );
275
-
276
- wp_die();
277
- }
278
- add_action( 'wp_ajax_so_dismiss_widget_teaser', 'siteorigin_widgets_dismiss_widget_action' );
1
+ <?php
2
+
3
+ /**
4
+ * Action for displaying the widget preview.
5
+ */
6
+ function siteorigin_widget_preview_widget_action() {
7
+ if ( empty( $_REQUEST['_widgets_nonce'] ) ||
8
+ ! wp_verify_nonce( $_REQUEST['_widgets_nonce'], 'widgets_action' ) ) {
9
+
10
+ wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 403 );
11
+ } else if ( empty( $_POST['class'] ) ) {
12
+ wp_die( __( 'Invalid post.', 'so-widgets-bundle' ), 400 );
13
+ }
14
+
15
+ // Get the widget from the widget factory
16
+ global $wp_widget_factory;
17
+ $widget = ! empty( $wp_widget_factory->widgets[ $_POST['class'] ] ) ? $wp_widget_factory->widgets[ $_POST['class'] ] : false;
18
+
19
+ if( ! is_a( $widget, 'SiteOrigin_Widget' ) ) {
20
+ wp_die( __( 'Invalid post.', 'so-widgets-bundle' ), 400 );
21
+ }
22
+
23
+ $instance = json_decode( stripslashes_deep($_POST['data']), true);
24
+ /* @var $widget SiteOrigin_Widget */
25
+ $instance = $widget->update( $instance, $instance );
26
+ $instance['is_preview'] = true;
27
+
28
+ // The theme stylesheet will change how the button looks
29
+ wp_enqueue_style( 'theme-css', get_stylesheet_uri(), array(), rand( 0, 65536 ) );
30
+ wp_enqueue_style( 'so-widget-preview', siteorigin_widgets_url( 'base/css/preview.css' ), array(), rand( 0,65536 ) );
31
+
32
+ $sowb = SiteOrigin_Widgets_Bundle::single();
33
+ $sowb->register_general_scripts();
34
+
35
+ ob_start();
36
+ $widget->widget( array(
37
+ 'before_widget' => '',
38
+ 'after_widget' => '',
39
+ 'before_title' => '<h3 class="widget-title">',
40
+ 'after_title' => '</h3>',
41
+ ), $instance);
42
+ $widget_html = ob_get_clean();
43
+
44
+ // Print all the scripts and styles
45
+ ?>
46
+ <html>
47
+ <head>
48
+ <title><?php _e('Widget Preview', 'so-widgets-bundle') ?></title>
49
+ <?php
50
+ wp_print_scripts();
51
+ wp_print_styles();
52
+ siteorigin_widget_print_styles();
53
+ ?>
54
+ </head>
55
+ <body>
56
+ <?php // A lot of themes use entry-content as their main content wrapper ?>
57
+ <div class="entry-content">
58
+ <?php echo $widget_html ?>
59
+ </div>
60
+ </body>
61
+ </html>
62
+
63
+ <?php
64
+ wp_die();
65
+ }
66
+ add_action('wp_ajax_so_widgets_preview', 'siteorigin_widget_preview_widget_action');
67
+
68
+ /**
69
+ * Action to handle searching posts
70
+ */
71
+ function siteorigin_widget_action_search_posts() {
72
+ if ( empty( $_REQUEST['_widgets_nonce'] ) || ! wp_verify_nonce( $_REQUEST['_widgets_nonce'], 'widgets_action' ) ) {
73
+ wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 403 );
74
+ }
75
+
76
+ // Get all public post types, besides attachments
77
+ $post_types = (array) get_post_types( array(
78
+ 'public' => true,
79
+ ) );
80
+
81
+ if ( ! empty( $_REQUEST['postTypes'] ) ) {
82
+ $post_types = array_intersect( explode( ',', $_REQUEST['postTypes'] ), $post_types );
83
+ } else {
84
+ unset( $post_types['attachment'] );
85
+ }
86
+
87
+ $post_types = apply_filters( 'siteorigin_widgets_search_posts_post_types', $post_types );
88
+
89
+ global $wpdb;
90
+ if( !empty($_GET['query']) ) {
91
+ $query = "AND post_title LIKE '%" . esc_sql( $_GET['query'] ) . "%'";
92
+ }
93
+ else {
94
+ $query = '';
95
+ }
96
+
97
+ $post_types = "'" . implode("', '", array_map( 'esc_sql', $post_types ) ) . "'";
98
+
99
+ $results = $wpdb->get_results( "
100
+ SELECT ID AS 'value', post_title AS label, post_type AS 'type'
101
+ FROM {$wpdb->posts}
102
+ WHERE
103
+ post_type IN ( {$post_types} ) AND post_status = 'publish' {$query}
104
+ ORDER BY post_modified DESC
105
+ LIMIT 20
106
+ ", ARRAY_A );
107
+
108
+ wp_send_json( apply_filters( 'siteorigin_widgets_search_posts_results', $results ) );
109
+ }
110
+ add_action('wp_ajax_so_widgets_search_posts', 'siteorigin_widget_action_search_posts');
111
+
112
+ /**
113
+ * Action to handle searching taxonomy terms.
114
+ */
115
+ function siteorigin_widget_action_search_terms() {
116
+ if ( empty( $_REQUEST['_widgets_nonce'] ) || ! wp_verify_nonce( $_REQUEST['_widgets_nonce'], 'widgets_action' ) ) {
117
+ wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 403 );
118
+ }
119
+
120
+ global $wpdb;
121
+ $term = ! empty($_GET['term']) ? stripslashes($_GET['term']) : '';
122
+ $term = trim($term, '%');
123
+
124
+ $query = $wpdb->prepare("
125
+ SELECT terms.term_id, terms.slug AS 'value', terms.name AS 'label', termtaxonomy.taxonomy AS 'type'
126
+ FROM $wpdb->terms AS terms
127
+ JOIN $wpdb->term_taxonomy AS termtaxonomy ON terms.term_id = termtaxonomy.term_id
128
+ WHERE
129
+ terms.name LIKE '%s'
130
+ LIMIT 20
131
+ ", '%' . esc_sql( $term ) . '%');
132
+
133
+ $results = array();
134
+
135
+ foreach ( $wpdb->get_results( $query ) as $result ) {
136
+ $results[] = array(
137
+ 'value' => $result->type . ':' . $result->value,
138
+ 'label' => $result->label,
139
+ 'type' => $result->type,
140
+ );
141
+ }
142
+
143
+ wp_send_json( $results );
144
+ }
145
+ add_action('wp_ajax_so_widgets_search_terms', 'siteorigin_widget_action_search_terms');
146
+
147
+ /**
148
+ * Action for getting the number of posts returned by a query.
149
+ */
150
+ function siteorigin_widget_get_posts_count_action() {
151
+
152
+ if ( empty( $_REQUEST['_widgets_nonce'] ) || ! wp_verify_nonce( $_REQUEST['_widgets_nonce'], 'widgets_action' ) ) {
153
+ wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 403 );
154
+ }
155
+
156
+ $query = stripslashes( $_POST['query'] );
157
+
158
+ wp_send_json( array( 'posts_count' => siteorigin_widget_post_selector_count_posts( $query ) ) );
159
+ }
160
+
161
+ add_action( 'wp_ajax_sow_get_posts_count', 'siteorigin_widget_get_posts_count_action' );
162
+
163
+
164
+ function siteorigin_widget_remote_image_search(){
165
+ if( empty( $_GET[ '_sononce' ] ) || ! wp_verify_nonce( $_GET[ '_sononce' ], 'so-image' ) ) {
166
+ wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 403 );
167
+ }
168
+
169
+ if( empty( $_GET['q'] ) ) {
170
+ wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 400 );
171
+ }
172
+
173
+ // Send the query to stock search server
174
+ $url = add_query_arg( array(
175
+ 'q' => $_GET[ 'q' ],
176
+ 'page' => !empty( $_GET[ 'page' ] ) ? intval( $_GET[ 'page' ] ) : 1,
177
+ ), 'http://stock.siteorigin.com/wp-admin/admin-ajax.php?action=image_search' );
178
+
179
+ $result = wp_remote_get( $url, array(
180
+ 'timeout' => 20,
181
+ ) );
182
+
183
+ if( ! is_wp_error( $result ) ) {
184
+ $result = json_decode( $result['body'], true );
185
+ if( !empty( $result['items'] ) ) {
186
+ foreach( $result['items'] as & $r ) {
187
+ if( !empty( $r['full_url'] ) ) {
188
+ $r['import_signature'] = md5( $r['full_url'] . '::' . NONCE_SALT );
189
+ }
190
+ }
191
+ }
192
+ wp_send_json( $result );
193
+ }
194
+ else {
195
+ $result = array(
196
+ 'error' => true,
197
+ 'message' => $result->get_error_message()
198
+ );
199
+ wp_send_json_error( $result );
200
+ }
201
+
202
+ }
203
+ add_action('wp_ajax_so_widgets_image_search', 'siteorigin_widget_remote_image_search');
204
+
205
+ function siteorigin_widget_image_import(){
206
+ if( empty( $_GET[ '_sononce' ] ) || ! wp_verify_nonce( $_GET[ '_sononce' ], 'so-image' ) ) {
207
+ $result = array(
208
+ 'error' => true,
209
+ 'message' => __( 'Nonce error', 'so-widgets-bundle' ),
210
+ );
211
+ }
212
+ else if(
213
+ empty( $_GET['import_signature'] ) ||
214
+ empty( $_GET['full_url'] ) ||
215
+ md5( $_GET['full_url'] . '::' . NONCE_SALT ) !== $_GET['import_signature']
216
+ ) {
217
+ $result = array(
218
+ 'error' => true,
219
+ 'message' => __( 'Signature error', 'so-widgets-bundle' ),
220
+ );
221
+ }
222
+ else {
223
+ // Fetch the image
224
+ $src = media_sideload_image( $_GET['full_url'], $_GET['post_id'], null, 'src' );
225
+ if( is_wp_error( $src ) ) {
226
+ $result = array(
227
+ 'error' => true,
228
+ 'message' => $src->get_error_code(),
229
+ );
230
+ }
231
+ else {
232
+ global $wpdb;
233
+ $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE guid='%s';", $src ) );
234
+ if( !empty( $attachment ) ) {
235
+ $thumb_src = wp_get_attachment_image_src( $attachment[0], 'thumbnail' );
236
+ $result = array(
237
+ 'error' => false,
238
+ 'attachment_id' => $attachment[0],
239
+ 'thumb' => $thumb_src[0]
240
+ );
241
+ }
242
+ else {
243
+ $result = array(
244
+ 'error' => true,
245
+ 'message' => __( 'Attachment error', 'so-widgets-bundle' ),
246
+ );
247
+ }
248
+ }
249
+ }
250
+
251
+ // Return the result
252
+ wp_send_json( $result );
253
+ }
254
+ add_action('wp_ajax_so_widgets_image_import', 'siteorigin_widget_image_import');
255
+
256
+ /**
257
+ * Action to handle a user dismissing a teaser notice.
258
+ */
259
+ function siteorigin_widgets_dismiss_widget_action(){
260
+ if( empty( $_GET[ '_wpnonce' ] ) || ! wp_verify_nonce( $_GET[ '_wpnonce' ], 'dismiss-widget-teaser' ) ) {
261
+ wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 403 );
262
+ }
263
+ if( empty( $_GET[ 'widget' ] ) ) {
264
+ wp_die( __( 'Invalid request.', 'so-widgets-bundle' ), 400 );
265
+ }
266
+
267
+ $dismissed = get_user_meta( get_current_user_id(), 'teasers_dismissed', true );
268
+ if( empty( $dismissed ) ) {
269
+ $dismissed = array();
270
+ }
271
+
272
+ $dismissed[ $_GET[ 'widget' ] ] = true;
273
+
274
+ update_user_meta( get_current_user_id(), 'teasers_dismissed', $dismissed );
275
+
276
+ wp_die();
277
+ }
278
+ add_action( 'wp_ajax_so_dismiss_widget_teaser', 'siteorigin_widgets_dismiss_widget_action' );
base/inc/fields/date-range.class.php CHANGED
@@ -1,123 +1,131 @@
1
- <?php
2
-
3
- /**
4
- * Class SiteOrigin_Widget_Field_Date_Range
5
- */
6
- class SiteOrigin_Widget_Field_Date_Range extends SiteOrigin_Widget_Field_Base {
7
-
8
- /**
9
- * Either 'relative' or 'specific'. Whether to allow relative or specific date selection.
10
- *
11
- * @access protected
12
- * @var array
13
- */
14
- protected $date_type;
15
-
16
- protected function render_field( $value, $instance ) {
17
-
18
- if ( $this->date_type == 'specific' ) {
19
- $this->render_specific_date_selector();
20
- } else {
21
- $this->render_relative_date_selector( $value );
22
- }
23
- ?><input type="hidden"
24
- class="siteorigin-widget-input"
25
- value="<?php echo esc_attr( $value ) ?>"
26
- name="<?php echo esc_attr( $this->element_name ) ?>" /><?php
27
- }
28
-
29
- private function render_specific_date_selector() {
30
- ?><div class="sowb-specific-date-after"><span><?php
31
- _e( 'From', 'so-widgets-bundle' );
32
- ?></span><input type="text" class="datepicker after-picker"/></div><?php
33
- ?><div class="sowb-specific-date-before"><span><?php
34
- _e( 'to', 'so-widgets-bundle' );
35
- ?></span><input type="text" class="datepicker before-picker"/></div><?php
36
- }
37
-
38
- private function render_relative_date_selector( $value ) {
39
- $value = json_decode(
40
- $value,
41
- true
42
- );
43
-
44
- $from = ! empty( $value['from'] ) ? $value['from'] : array();
45
- $this->render_relative_date_selector_part( 'from', __( 'From', 'so-widgets-bundle' ), $from );
46
-
47
- $to = ! empty( $value['to'] ) ? $value['to'] : array();
48
- $this->render_relative_date_selector_part( 'to', __( 'to', 'so-widgets-bundle' ), $to );
49
- }
50
-
51
- private function render_relative_date_selector_part( $name, $label, $value ) {
52
- $units = $this->get_units();
53
-
54
- $val = ! empty( $value['value'] ) ? $value['value'] : 0;
55
- $unit = ! empty( $value['unit'] ) ? $value['unit'] : 'days';
56
-
57
- ?><div class="sowb-relative-date" data-name="<?php echo esc_attr( $name ) ?>"><span><?php
58
- echo esc_html( $label );
59
- ?></span><input type="number" min="0" step="1" class="sowb-relative-date-value" value="<?php echo esc_attr( $val ) ?>"/>
60
- <select class="sowb-relative-date-unit">
61
- <?php foreach( $units as $value => $label) : ?>
62
- <option value="<?php echo esc_attr( $value ) ?>" <?php selected( $value, $unit ) ?>><?php echo $label ?></option>
63
- <?php endforeach; ?>
64
- </select><span><?php _e( 'ago', 'so-widgets-bundle' ); ?></span></div><?php
65
- }
66
-
67
- private function get_units() {
68
- return array(
69
- 'days' => __( 'days', 'so-widgets-bundle' ),
70
- 'weeks' => __( 'weeks', 'so-widgets-bundle' ),
71
- 'months' => __( 'months', 'so-widgets-bundle' ),
72
- 'years' => __( 'years', 'so-widgets-bundle' ),
73
- );
74
- }
75
-
76
- public function enqueue_scripts() {
77
- wp_register_style( 'sowb-pikaday', plugin_dir_url(__FILE__) . 'js/lib/pikaday/pikaday.css' );
78
- wp_register_script( 'sowb-pikaday', plugin_dir_url(__FILE__) . 'js/lib/pikaday/pikaday' . SOW_BUNDLE_JS_SUFFIX . '.js', array( ), '1.5.1' );
79
- wp_enqueue_style( 'so-date-range-field', plugin_dir_url(__FILE__) . 'css/date-range-field.css', array( 'sowb-pikaday' ), SOW_BUNDLE_VERSION );
80
- wp_enqueue_script( 'so-date-range-field', plugin_dir_url(__FILE__) . 'js/date-range-field' . SOW_BUNDLE_JS_SUFFIX . '.js', array( 'jquery', 'sowb-pikaday' ), SOW_BUNDLE_VERSION );
81
- }
82
-
83
- protected function sanitize_field_input( $value, $instance ) {
84
- if ( $this->date_type == 'specific' ) {
85
- if ( ! empty( $value ) ) {
86
- $value = json_decode(
87
- $value,
88
- true
89
- );
90
- if ( ! empty( $value['after'] ) ) {
91
- $value_after = new DateTime( $value['after'] );
92
- $value['after'] = $value_after->format( 'Y-m-d' );
93
- }
94
- if ( ! empty( $value['before'] ) ) {
95
- $value_before = new DateTime( $value['before'] );
96
- $value['before'] = $value_before->format( 'Y-m-d' );
97
- }
98
- } else {
99
- $value = array( 'after' => '', 'before' => '' );
100
- }
101
- } else if ( $this->date_type == 'relative' ) {
102
- if ( ! empty( $value ) ) {
103
- $value = json_decode(
104
- $value,
105
- true
106
- );
107
- $unit_keys = array_keys( $this->get_units() );
108
- foreach( array( 'from', 'to' ) as $key ) {
109
- if ( empty( $value[$key] ) ) {
110
- $value[$key] = array();
111
- }
112
- $item = $value[$key];
113
- $val = empty( $item['value'] ) ? 0 : intval( $item['value'] );
114
- $unit = ( ! empty( $item['unit'] ) && in_array( $item['unit'], $unit_keys ) ) ? $item['unit'] : $unit_keys[0];
115
- $value[$key] = array( 'value' => $val, 'unit' => $unit );
116
- }
117
- } else {
118
- $value = array( 'from' => array(), 'to' => array() );
119
- }
120
- }
121
- return json_encode( $value );
122
- }
123
- }
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class SiteOrigin_Widget_Field_Date_Range
5
+ */
6
+ class SiteOrigin_Widget_Field_Date_Range extends SiteOrigin_Widget_Field_Base {
7
+
8
+ /**
9
+ * Either 'relative' or 'specific'. Whether to allow relative or specific date selection.
10
+ *
11
+ * @access protected
12
+ * @var array
13
+ */
14
+ protected $date_type;
15
+
16
+ protected function render_field( $value, $instance ) {
17
+
18
+ if ( $this->date_type == 'specific' ) {
19
+ $this->render_specific_date_selector();
20
+ } else {
21
+ $this->render_relative_date_selector( $value );
22
+ }
23
+ ?><input type="hidden"
24
+ class="siteorigin-widget-input"
25
+ value="<?php echo esc_attr( $value ) ?>"
26
+ name="<?php echo esc_attr( $this->element_name ) ?>" /><?php
27
+ }
28
+
29
+ private function render_specific_date_selector() {
30
+ ?><div class="sowb-specific-date-after"><span><?php
31
+ _ex( 'From', 'From this date', 'so-widgets-bundle' );
32
+ ?></span><input type="text" class="datepicker after-picker"/></div><?php
33
+ ?><div class="sowb-specific-date-before"><span><?php
34
+ _e( 'to', 'so-widgets-bundle' );
35
+ ?></span><input type="text" class="datepicker before-picker"/></div><?php
36
+ }
37
+
38
+ private function render_relative_date_selector( $value ) {
39
+ $value = json_decode(
40
+ $value,
41
+ true
42
+ );
43
+
44
+ $from = ! empty( $value['from'] ) ? $value['from'] : array();
45
+ $this->render_relative_date_selector_part( 'from', __( 'From', 'so-widgets-bundle' ), $from );
46
+
47
+ $to = ! empty( $value['to'] ) ? $value['to'] : array();
48
+ $this->render_relative_date_selector_part( 'to', __( 'to', 'so-widgets-bundle' ), $to );
49
+ }
50
+
51
+ private function render_relative_date_selector_part( $name, $label, $value ) {
52
+ $units = $this->get_units();
53
+
54
+ $val = ! empty( $value['value'] ) ? $value['value'] : 0;
55
+ $unit = ! empty( $value['unit'] ) ? $value['unit'] : 'days';
56
+
57
+ ?><div class="sowb-relative-date" data-name="<?php echo esc_attr( $name ) ?>"><span><?php
58
+ echo esc_html( $label );
59
+ ?></span><input type="number" min="0" step="1" class="sowb-relative-date-value" value="<?php echo esc_attr( $val ) ?>"/>
60
+ <select class="sowb-relative-date-unit">
61
+ <?php foreach( $units as $value => $label) : ?>
62
+ <option value="<?php echo esc_attr( $value ) ?>" <?php selected( $value, $unit ) ?>><?php echo $label ?></option>
63
+ <?php endforeach; ?>
64
+ </select><span><?php _e( 'ago', 'so-widgets-bundle' ); ?></span></div><?php
65
+ }
66
+
67
+ private function get_units() {
68
+ return array(
69
+ 'days' => __( 'days', 'so-widgets-bundle' ),
70
+ 'weeks' => __( 'weeks', 'so-widgets-bundle' ),
71
+ 'months' => __( 'months', 'so-widgets-bundle' ),
72
+ 'years' => __( 'years', 'so-widgets-bundle' ),
73
+ );
74
+ }
75
+
76
+ public function enqueue_scripts() {
77
+ wp_enqueue_style(
78
+ 'so-date-range-field',
79
+ plugin_dir_url(__FILE__) . 'css/date-range-field.css',
80
+ array( 'sowb-pikaday' ),
81
+ SOW_BUNDLE_VERSION
82
+ );
83
+ wp_enqueue_script(
84
+ 'so-date-range-field',
85
+ plugin_dir_url(__FILE__) . 'js/date-range-field' . SOW_BUNDLE_JS_SUFFIX . '.js',
86
+ array( 'jquery', 'sowb-pikaday' ),
87
+ SOW_BUNDLE_VERSION
88
+ );
89
+ }
90
+
91
+ protected function sanitize_field_input( $value, $instance ) {
92
+ if ( $this->date_type == 'specific' ) {
93
+ if ( ! empty( $value ) ) {
94
+ $value = json_decode(
95
+ $value,
96
+ true
97
+ );
98
+ if ( ! empty( $value['after'] ) ) {
99
+ $value_after = new DateTime( $value['after'] );
100
+ $value['after'] = $value_after->format( 'Y-m-d' );
101
+ }
102
+ if ( ! empty( $value['before'] ) ) {
103
+ $value_before = new DateTime( $value['before'] );
104
+ $value['before'] = $value_before->format( 'Y-m-d' );
105
+ }
106
+ } else {
107
+ $value = array( 'after' => '', 'before' => '' );
108
+ }
109
+ } else if ( $this->date_type == 'relative' ) {
110
+ if ( ! empty( $value ) ) {
111
+ $value = json_decode(
112
+ $value,
113
+ true
114
+ );
115
+ $unit_keys = array_keys( $this->get_units() );
116
+ foreach( array( 'from', 'to' ) as $key ) {
117
+ if ( empty( $value[$key] ) ) {
118
+ $value[$key] = array();
119
+ }
120
+ $item = $value[$key];
121
+ $val = empty( $item['value'] ) ? 0 : intval( $item['value'] );
122
+ $unit = ( ! empty( $item['unit'] ) && in_array( $item['unit'], $unit_keys ) ) ? $item['unit'] : $unit_keys[0];
123
+ $value[$key] = array( 'value' => $val, 'unit' => $unit );
124
+ }
125
+ } else {
126
+ $value = array( 'from' => array(), 'to' => array() );
127
+ }
128
+ }
129
+ return json_encode( $value );
130
+ }
131
+ }
base/inc/fields/js/date-range-field.js CHANGED
@@ -1,83 +1,100 @@
1
- /* global jQuery, soWidgets */
2
-
3
- (function( $ ) {
4
- $( document ).on( 'sowsetupformfield', '.siteorigin-widget-field-type-date-range', function ( e ) {
5
-
6
- var valField = $( this ).find( 'input[type="hidden"][class="siteorigin-widget-input"]' );
7
-
8
- if ( $( this ).find( '[class*="sowb-specific-date"]' ).length > 0 ) {
9
- var createPikadayInput = function ( inputName, initVal ) {
10
- var $field = $( this ).find( '.' + inputName + '-picker' );
11
- var picker = new Pikaday( {
12
- field: $field[ 0 ],
13
- blurFieldOnSelect: false,
14
- onSelect: function ( date ) {
15
- var curVal = valField.val() === '' ? {} : JSON.parse( valField.val() );
16
- curVal[ inputName ] = date.toLocaleDateString( {}, {
17
- year: 'numeric',
18
- month: '2-digit',
19
- day: '2-digit'
20
- } );
21
- $field.val( curVal[ inputName ] );
22
- valField.val( JSON.stringify( curVal ) );
23
- valField.trigger( 'change', { silent: true } );
24
- },
25
- } );
26
-
27
- // We trigger the change event on the hidden value field, so prevent 'change' from individual date inputs.
28
- $field.change( function ( event ) {
29
- event.preventDefault();
30
- return false;
31
- } );
32
-
33
- if ( initVal ) {
34
- $field.val( initVal );
35
- }
36
- return picker;
37
- }.bind( this );
38
-
39
- var initRange = valField.val() === '' ? { after: '', before: '' } : JSON.parse( valField.val() );
40
- var afterPicker = createPikadayInput( 'after', initRange.after );
41
- var beforePicker = createPikadayInput( 'before', initRange.before );
42
-
43
- valField.change( function ( event, data ) {
44
- if ( ! ( data && data.silent ) ) {
45
- var newRange = valField.val() === '' ? { after: '', before: '' } : JSON.parse( valField.val() );
46
- afterPicker.setDate( newRange.after );
47
- beforePicker.setDate( newRange.before );
48
- }
49
- } );
50
- } else if ( $( this ).find( '.sowb-relative-date' ).length > 0 ) {
51
-
52
- $( this ).find( '.sowb-relative-date' ).each( function () {
53
- var $name = $( this ).data( 'name' );
54
-
55
- $( this ).change( function () {
56
- var range = valField.val() === '' ? {} : JSON.parse( valField.val() );
57
-
58
- if ( ! range.hasOwnProperty( $name ) ) {
59
- range[ $name ] = {};
60
- }
61
-
62
- range[ $name ][ 'value' ] = $( this ).find( '> input' ).val();
63
- range[ $name ][ 'unit' ] = $( this ).find( '> select' ).val();
64
-
65
- valField.val( JSON.stringify( range ) );
66
- valField.trigger( 'change', { silent: true } );
67
- }.bind( this ) );
68
-
69
- valField.change( function ( event, data ) {
70
- if ( ! ( data && data.silent ) ) {
71
- var range = valField.val() === '' ? { from: {}, to: {} } : JSON.parse( valField.val() );
72
-
73
- if ( range.hasOwnProperty( $name ) ) {
74
- $( this ).find( '> input' ).val( range[ $name ][ 'value' ] );
75
- $( this ).find( '> select' ).val( range[ $name ][ 'unit' ] );
76
- }
77
- }
78
- }.bind( this ) );
79
-
80
- } );
81
- }
82
- } );
83
- })( jQuery );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* global jQuery, pikaday */
2
+
3
+ (function( $ ) {
4
+ $( document ).on( 'sowsetupformfield', '.siteorigin-widget-field-type-date-range', function ( e ) {
5
+ var $dateRangeField = $( this );
6
+ var valField = $dateRangeField.find( 'input[type="hidden"][class="siteorigin-widget-input"]' );
7
+
8
+ if ( $dateRangeField.data( 'initialized' ) ) {
9
+ return;
10
+ }
11
+
12
+ if ( $dateRangeField.find( '[class*="sowb-specific-date"]' ).length > 0 ) {
13
+ var createPikadayInput = function ( inputName, initVal ) {
14
+ var $field = $dateRangeField.find( '.' + inputName + '-picker' );
15
+ var picker = new Pikaday( {
16
+ field: $field[ 0 ],
17
+ blurFieldOnSelect: false,
18
+ toString: function( date, format ) {
19
+ var day = date.getDate();
20
+ day = day < 10 ? '0' + day.toString() : day.toString();
21
+ var month = date.getMonth() + 1;
22
+ month = month < 10 ? '0' + month.toString() : month.toString();
23
+ var year = date.getFullYear();
24
+ return year + '-' + month + '-' + day;
25
+ },
26
+ parse: function( dateString, format ) {
27
+
28
+ var parts = dateString.split( '-' );
29
+ var day = parseInt( parts[2] );
30
+ var month = parseInt( parts[1] ) - 1;
31
+ var year = parseInt( parts[0] );
32
+ return new Date(year, month, day);
33
+ },
34
+ onSelect: function ( date ) {
35
+ var curVal = valField.val() === '' ? {} : JSON.parse( valField.val() );
36
+ curVal[ inputName ] = this.toString( date, this.format );
37
+ $field.val( curVal[ inputName ] );
38
+ valField.val( JSON.stringify( curVal ) );
39
+ valField.trigger( 'change', { silent: true } );
40
+ },
41
+ } );
42
+
43
+ // We trigger the change event on the hidden value field, so prevent 'change' from individual date inputs.
44
+ $field.change( function ( event ) {
45
+ event.preventDefault();
46
+ return false;
47
+ } );
48
+
49
+ if ( initVal ) {
50
+ $field.val( initVal );
51
+ }
52
+ return picker;
53
+ }.bind( this );
54
+
55
+ var initRange = valField.val() === '' ? { after: '', before: '' } : JSON.parse( valField.val() );
56
+ var afterPicker = createPikadayInput( 'after', initRange.after );
57
+ var beforePicker = createPikadayInput( 'before', initRange.before );
58
+
59
+ valField.change( function ( event, data ) {
60
+ if ( ! ( data && data.silent ) ) {
61
+ var newRange = valField.val() === '' ? { after: '', before: '' } : JSON.parse( valField.val() );
62
+ afterPicker.setDate( newRange.after );
63
+ beforePicker.setDate( newRange.before );
64
+ }
65
+ } );
66
+ } else if ( $dateRangeField.find( '.sowb-relative-date' ).length > 0 ) {
67
+
68
+ $dateRangeField.find( '.sowb-relative-date' ).each( function () {
69
+ var $name = $( this ).data( 'name' );
70
+
71
+ $( this ).change( function () {
72
+ var range = valField.val() === '' ? {} : JSON.parse( valField.val() );
73
+
74
+ if ( ! range.hasOwnProperty( $name ) ) {
75
+ range[ $name ] = {};
76
+ }
77
+
78
+ range[ $name ][ 'value' ] = $( this ).find( '> input' ).val();
79
+ range[ $name ][ 'unit' ] = $( this ).find( '> select' ).val();
80
+
81
+ valField.val( JSON.stringify( range ) );
82
+ valField.trigger( 'change', { silent: true } );
83
+ }.bind( this ) );
84
+
85
+ valField.change( function ( event, data ) {
86
+ if ( ! ( data && data.silent ) ) {
87
+ var range = valField.val() === '' ? { from: {}, to: {} } : JSON.parse( valField.val() );
88
+
89
+ if ( range.hasOwnProperty( $name ) ) {
90
+ $( this ).find( '> input' ).val( range[ $name ][ 'value' ] );
91
+ $( this ).find( '> select' ).val( range[ $name ][ 'unit' ] );
92
+ }
93
+ }
94
+ }.bind( this ) );
95
+
96
+ } );
97
+ }
98
+ $dateRangeField.data( 'initialized', true );
99
+ } );
100
+ })( jQuery );
base/inc/fields/js/date-range-field.min.js CHANGED
@@ -1 +1 @@
1
- !function(e){e(document).on("sowsetupformfield",".siteorigin-widget-field-type-date-range",function(t){var i=e(this).find('input[type="hidden"][class="siteorigin-widget-input"]');if(e(this).find('[class*="sowb-specific-date"]').length>0){var a=function(t,a){var n=e(this).find("."+t+"-picker"),r=new Pikaday({field:n[0],blurFieldOnSelect:!1,onSelect:function(e){var a=""===i.val()?{}:JSON.parse(i.val());a[t]=e.toLocaleDateString({},{year:"numeric",month:"2-digit",day:"2-digit"}),n.val(a[t]),i.val(JSON.stringify(a)),i.trigger("change",{silent:!0})}});return n.change(function(e){return e.preventDefault(),!1}),a&&n.val(a),r}.bind(this),n=""===i.val()?{after:"",before:""}:JSON.parse(i.val()),r=a("after",n.after),s=a("before",n.before);i.change(function(e,t){if(!t||!t.silent){var a=""===i.val()?{after:"",before:""}:JSON.parse(i.val());r.setDate(a.after),s.setDate(a.before)}})}else e(this).find(".sowb-relative-date").length>0&&e(this).find(".sowb-relative-date").each(function(){var t=e(this).data("name");e(this).change(function(){var a=""===i.val()?{}:JSON.parse(i.val());a.hasOwnProperty(t)||(a[t]={}),a[t].value=e(this).find("> input").val(),a[t].unit=e(this).find("> select").val(),i.val(JSON.stringify(a)),i.trigger("change",{silent:!0})}.bind(this)),i.change(function(a,n){if(!n||!n.silent){var r=""===i.val()?{from:{},to:{}}:JSON.parse(i.val());r.hasOwnProperty(t)&&(e(this).find("> input").val(r[t].value),e(this).find("> select").val(r[t].unit))}}.bind(this))})})}(jQuery);
1
+ !function(t){t(document).on("sowsetupformfield",".siteorigin-widget-field-type-date-range",function(e){var i=t(this),n=i.find('input[type="hidden"][class="siteorigin-widget-input"]');if(!i.data("initialized")){if(i.find('[class*="sowb-specific-date"]').length>0){var a=function(t,e){var a=i.find("."+t+"-picker"),r=new Pikaday({field:a[0],blurFieldOnSelect:!1,toString:function(t,e){var i=t.getDate();i=i<10?"0"+i.toString():i.toString();var n=t.getMonth()+1;return n=n<10?"0"+n.toString():n.toString(),t.getFullYear()+"-"+n+"-"+i},parse:function(t,e){var i=t.split("-"),n=parseInt(i[2]),a=parseInt(i[1])-1,r=parseInt(i[0]);return new Date(r,a,n)},onSelect:function(e){var i=""===n.val()?{}:JSON.parse(n.val());i[t]=this.toString(e,this.format),a.val(i[t]),n.val(JSON.stringify(i)),n.trigger("change",{silent:!0})}});return a.change(function(t){return t.preventDefault(),!1}),e&&a.val(e),r}.bind(this),r=""===n.val()?{after:"",before:""}:JSON.parse(n.val()),s=a("after",r.after),l=a("before",r.before);n.change(function(t,e){if(!e||!e.silent){var i=""===n.val()?{after:"",before:""}:JSON.parse(n.val());s.setDate(i.after),l.setDate(i.before)}})}else i.find(".sowb-relative-date").length>0&&i.find(".sowb-relative-date").each(function(){var e=t(this).data("name");t(this).change(function(){var i=""===n.val()?{}:JSON.parse(n.val());i.hasOwnProperty(e)||(i[e]={}),i[e].value=t(this).find("> input").val(),i[e].unit=t(this).find("> select").val(),n.val(JSON.stringify(i)),n.trigger("change",{silent:!0})}.bind(this)),n.change(function(i,a){if(!a||!a.silent){var r=""===n.val()?{from:{},to:{}}:JSON.parse(n.val());r.hasOwnProperty(e)&&(t(this).find("> input").val(r[e].value),t(this).find("> select").val(r[e].unit))}}.bind(this))});i.data("initialized",!0)}})}(jQuery);
base/inc/fields/js/media-field.js CHANGED
@@ -1,408 +1,409 @@
1
- /* global jQuery, soWidgets */
2
-
3
- ( function( $ ) {
4
-
5
- $(document).on( 'sowsetupformfield', '.siteorigin-widget-field-type-media', function(e) {
6
- var $field = $( this );
7
- var $media = $field.find('> .media-field-wrapper');
8
- var $inputField = $field.find( '.siteorigin-widget-input' ).not('.media-fallback-external');
9
-
10
- if ( $media.data( 'initialized' ) ) {
11
- return;
12
- }
13
-
14
- // Handle the media uploader
15
- $media.find( '.media-upload-button' ).click(function(e){
16
- e.preventDefault();
17
- if( typeof wp.media === 'undefined' ) {
18
- return;
19
- }
20
-
21
- var $$ = $(this);
22
- var frame = $(this ).data('frame');
23
-
24
- // If the media frame already exists, reopen it.
25
- if ( frame ) {
26
- frame.open();
27
- return false;
28
- }
29
-
30
- // Create the media frame.
31
- frame = wp.media( {
32
- // Set the title of the modal.
33
- title: $$.data('choose'),
34
-
35
- // Tell the modal to show only images.
36
- library: {
37
- type: $$.data('library').split(',').map(function(v){ return v.trim(); })
38
- },
39
-
40
- // Customize the submit button.
41
- button: {
42
- // Set the text of the button.
43
- text: $$.data('update'),
44
- // Tell the button not to close the modal, since we're
45
- // going to refresh the page when the image is selected.
46
- close: false
47
- }
48
- } );
49
-
50
- // Store the frame
51
- $$.data('frame', frame);
52
-
53
- // When an image is selected, run a callback.
54
- frame.on( 'select', function() {
55
- // Grab the selected attachment.
56
- var attachment = frame.state().get('selection').first().attributes;
57
-
58
- $field.find('.current .title' ).html(attachment.title);
59
- $inputField.val(attachment.id);
60
- $inputField.trigger( 'change', { silent: true } );
61
-
62
- var $thumbnail = $field.find( '.current .thumbnail' );
63
-
64
- if(typeof attachment.sizes !== 'undefined'){
65
- if(typeof attachment.sizes.thumbnail !== 'undefined'){
66
- $thumbnail.attr('src', attachment.sizes.thumbnail.url).fadeIn();
67
- }
68
- else {
69
- $thumbnail.attr('src', attachment.sizes.full.url).fadeIn();
70
- }
71
- }
72
- else{
73
- $thumbnail.attr('src', attachment.icon).fadeIn();
74
- }
75
-
76
- $field.find('.media-remove-button').removeClass('remove-hide');
77
-
78
- frame.close();
79
- } );
80
-
81
- // Finally, open the modal.
82
- frame.open();
83
- });
84
-
85
- $media.find('.current' )
86
- .mouseenter(function(){
87
- var t = $(this ).find('.title' );
88
- if( t.html() !== ''){
89
- t.fadeIn('fast');
90
- }
91
- })
92
- .mouseleave(function(){
93
- $(this ).find('.title' ).clearQueue().fadeOut('fast');
94
- });
95
-
96
- $field.find('a.media-remove-button' )
97
- .click( function( e ){
98
- e.preventDefault();
99
- $field.find('.current .title' ).html('');
100
- $inputField.val('');
101
- $field.find('.current .thumbnail' ).fadeOut('fast');
102
- $(this).addClass('remove-hide');
103
- } );
104
-
105
- // Everything for the dialog
106
- var dialog;
107
-
108
- var reflowDialog = function() {
109
- if( ! dialog ) return;
110
-
111
- var results = dialog.find('.so-widgets-image-results');
112
- if( results.length === 0 ) return;
113
-
114
- var width = results.width(),
115
- perRow = Math.floor( width / 276 ),
116
- spare = ( width - perRow * 276 ),
117
- resultWidth = spare / perRow + 260;
118
-
119
- results.find( '.so-widgets-result-image' ).css( {
120
- 'width' : resultWidth,
121
- 'height' : resultWidth / 1.4
122
- } );
123
- };
124
- $(window).resize( reflowDialog );
125
-
126
- var setupDialog = function(){
127
- if( ! dialog ) {
128
- // Create the dialog
129
- dialog = $( $('#so-widgets-bundle-tpl-image-search-dialog').html().trim() ).appendTo( 'body' );
130
- dialog.find( '.close' ).click( function(){
131
- dialog.hide();
132
- } );
133
-
134
- var results = dialog.find( '.so-widgets-image-results' );
135
-
136
- var fetchImages = function( query, page ){
137
- dialog.find( '.so-widgets-results-loading' ).fadeIn('fast');
138
- dialog.find( '.so-widgets-results-loading strong' ).html(
139
- dialog.find( '.so-widgets-results-loading strong' ).data( 'loading' )
140
- );
141
- dialog.find( '.so-widgets-results-more' ).hide();
142
-
143
- $.get(
144
- ajaxurl,
145
- {
146
- 'action' : 'so_widgets_image_search',
147
- 'q' : query,
148
- 'page' : page,
149
- '_sononce' : dialog.find('input[name="_sononce"]').val()
150
- },
151
- function( response ){
152
- if( response.error ) {
153
- alert( response.message );
154
- return;
155
- }
156
-
157
- results.removeClass( 'so-loading' );
158
- $.each( response.items, function( i, r ){
159
- var result = $( $('#so-widgets-bundle-tpl-image-search-result').html().trim() )
160
- .appendTo( results )
161
- .addClass( 'source-' + r.source );
162
- var img = result.find('.so-widgets-result-image');
163
-
164
- // Preload the image
165
- img.css( 'background-image', 'url(' + r.thumbnail + ')' );
166
- img.data( 'thumbnail', r.thumbnail );
167
- img.data( 'preview', r.preview );
168
-
169
- if( r.url ) {
170
- img.attr( {
171
- 'href': r.url,
172
- 'target': '_blank'
173
- } );
174
- }
175
-
176
- if( r.full_url ) {
177
- img.data( {
178
- 'full_url' : r.full_url,
179
- 'import_signature' : r.import_signature
180
- } );
181
- img.attr( 'href', r.full_url );
182
- }
183
-
184
- if( r.source === 'shutterstock' ) {
185
- img.append( $('#so-widgets-bundle-tpl-image-search-result-sponsored').html() );
186
- }
187
- } );
188
-
189
- if( page === 1 ) {
190
- dialog.find('#so-widgets-image-search-suggestions ul').empty();
191
- $.each( response.keywords, function( i, r ){
192
- dialog.find('#so-widgets-image-search-suggestions').show();
193
- dialog.find('#so-widgets-image-search-suggestions ul').append(
194
- $('<li></li>') . append( $('<a href="#"></a>').html( r ).data( 'keyword', r ) )
195
- );
196
- } );
197
- }
198
-
199
- dialog.find( '.so-widgets-results-loading' ).fadeOut('fast');
200
-
201
- reflowDialog();
202
- dialog
203
- .find( '.so-widgets-results-more' ).show()
204
- .find( 'button' ).data( { 'query': query, 'page' : page+1 } );
205
- }
206
- );
207
-
208
- };
209
-
210
- // Setup the search
211
- dialog.find('#so-widgets-image-search-form').submit( function( e ){
212
- e.preventDefault();
213
-
214
- // Perform the search
215
- var q = dialog.find('.so-widgets-search-input').val();
216
- results.empty();
217
-
218
- if( q !== '' ) {
219
- // Send the query to the server
220
- fetchImages( q, 1 );
221
- }
222
- } );
223
-
224
- // Clicking on the related search buttons
225
- dialog.on( 'click', '.so-keywords-list a', function( e ){
226
- e.preventDefault();
227
- var $$ = $(this).blur();
228
- dialog.find('.so-widgets-search-input').val( $$.data( 'keyword' ) );
229
- dialog.find('#so-widgets-image-search-form').submit();
230
- } );
231
-
232
- // Clicking on the more button
233
- dialog.find('.so-widgets-results-more button').click( function(){
234
- var $$ = $(this);
235
- fetchImages( $$.data( 'query' ), $$.data( 'page' ) );
236
- } );
237
-
238
- var hoverTimeout;
239
-
240
- // Clicking on an image to import it
241
- dialog.on( 'click', '.so-widgets-result-image', function( e ){
242
- var $$ = $(this);
243
- if( ! $$.data( 'full_url' ) ) {
244
- return;
245
- }
246
-
247
- e.preventDefault();
248
-
249
- if( confirm( dialog.data('confirm-import') ) ) {
250
- dialog.addClass( 'so-widgets-importing' );
251
-
252
- var postId = $( '#post_ID' ).val();
253
- if( postId === null ) {
254
- postId = '';
255
- }
256
-
257
- // Send the message to import the URL
258
- $.get(
259
- ajaxurl,
260
- {
261
- 'action' : 'so_widgets_image_import',
262
- 'full_url' : $$.data( 'full_url' ),
263
- 'import_signature' : $$.data( 'import_signature' ),
264
- 'post_id' : postId,
265
- '_sononce' : dialog.find('input[name="_sononce"]').val()
266
- },
267
- function( response ) {
268
- dialog.find('#so-widgets-image-search-frame').removeClass( 'so-widgets-importing' );
269
-
270
- if( response.error === false ) {
271
- // This was a success
272
- dialog.hide();
273
- dialog.find( '.so-widgets-results-loading' ).hide();
274
- $inputField.val( response.attachment_id ).trigger('change', { silent: true } );
275
- $field.find('.current .thumbnail' ).attr('src', response.thumb ).fadeIn();
276
-
277
- $field.find('.media-remove-button').removeClass('remove-hide');
278
- }
279
- else {
280
- alert( response.message );
281
- dialog.find( '.so-widgets-results-loading' ).hide();
282
- }
283
- }
284
- );
285
-
286
- // Clear the dialog
287
- dialog.find( '.so-widgets-results-loading' ).fadeIn('fast');
288
- dialog.find( '.so-widgets-results-loading strong' ).html(
289
- dialog.find( '.so-widgets-results-loading strong' ).data( 'importing' )
290
- );
291
- dialog.find( '.so-widgets-results-more' ).hide();
292
- dialog.find('#so-widgets-image-search-frame').addClass( 'so-widgets-importing' );
293
- }
294
- } );
295
-
296
- // Hovering over an image to preview it
297
- var previewWindow = dialog.find('.so-widgets-preview-window');
298
- dialog
299
- .on( 'mouseenter', '.so-widgets-result-image', function(){
300
- var $$ = $(this),
301
- preview = $$.data('preview');
302
-
303
- clearTimeout( hoverTimeout );
304
-
305
- hoverTimeout = setTimeout( function(){
306
- // Scale the preview sizes
307
- var scalePreviewX = 1, scalePreviewY = 1;
308
- if( preview[1] > $( window ).outerWidth() *0.33 ) {
309
- scalePreviewX = $( window ).outerWidth() *0.33 / preview[1];
310
- }
311
- if( preview[2] > $( window ).outerHeight() *0.5 ) {
312
- scalePreviewY = $( window ).outerHeight() *0.5 / preview[2];
313
- }
314
- var scalePreview = Math.min( scalePreviewX, scalePreviewY );
315
- // Never upscale
316
- if( scalePreview > 1 ) {
317
- scalePreview = 1;
318
- }
319
-
320
- previewWindow.show()
321
- .find('.so-widgets-preview-window-inside')
322
- .css( {
323
- 'background-image' : 'url(' + $$.data('thumbnail') + ')',
324
- 'width' : preview[1] * scalePreview,
325
- 'height' : preview[2] * scalePreview
326
- } )
327
- .append( $( '<img />' ).attr( 'src', preview[0] ) );
328
-
329
- dialog.trigger('mousemove');
330
- }, 1000 );
331
-
332
- } )
333
- .on( 'mouseleave', '.so-widgets-result-image', function(){
334
- previewWindow.hide().find('img').remove();
335
- clearTimeout( hoverTimeout );
336
- } );
337
-
338
- var lastX, lastY;
339
- dialog.on( 'mousemove', function( e ){
340
- if( e.clientX ) lastX = e.clientX;
341
- if( e.clientY ) lastY = e.clientY;
342
-
343
- if( previewWindow.is( ':visible' ) ) {
344
- var ph = previewWindow.outerHeight(),
345
- pw = previewWindow.outerWidth(),
346
- wh = $( window ).outerHeight(),
347
- ww = $( window ).outerWidth();
348
-
349
-
350
- // Calculate the top position
351
- var top = lastY - ph/2;
352
- top = Math.max( top, 10 );
353
- top = Math.min( top, wh - 10 - ph );
354
-
355
- // Calculate the left position
356
- var left = (lastX < ww/2) ? lastX + 15 : lastX - 15 - pw;
357
-
358
- // Figure out where the preview needs to go
359
- previewWindow.css({
360
- 'top': top,
361
- 'left': left
362
- });
363
-
364
- }
365
- } );
366
- }
367
-
368
- dialog.show();
369
- dialog.find( '.so-widgets-search-input' ).focus();
370
- };
371
-
372
- // Handle displaying the image search dialog
373
- $media.find( '.find-image-button' ).click( function(e){
374
- e.preventDefault();
375
- setupDialog();
376
- } );
377
-
378
- $inputField.change( function ( event, data ) {
379
- if ( ! ( data && data.silent ) ) {
380
- var newVal = $inputField.val();
381
- if ( newVal) {
382
- var $thumbnail = $field.find( '.current .thumbnail' );
383
- var attachment = wp.media.attachment( newVal );
384
- attachment.fetch().done( function () {
385
- if ( attachment.has( 'sizes' ) ) {
386
- var sizes = attachment.get( 'sizes' );
387
- if ( typeof sizes.thumbnail !== 'undefined' ) {
388
- $thumbnail.attr( 'src', sizes.thumbnail.url ).fadeIn();
389
- }
390
- else {
391
- $thumbnail.attr( 'src', sizes.full.url ).fadeIn();
392
- }
393
- }
394
- else {
395
- $thumbnail.attr( 'src', attachment.get('icon') ).fadeIn();
396
- }
397
- $field.find('.media-remove-button').removeClass('remove-hide');
398
- } );
399
- } else {
400
- $field.find( 'a.media-remove-button' ).click();
401
- }
402
- }
403
- } );
404
-
405
- $media.data( 'initialized', true );
406
- });
407
-
408
- } )( jQuery );
 
1
+ /* global jQuery, soWidgets */
2
+
3
+ ( function( $ ) {
4
+
5
+ $(document).on( 'sowsetupformfield', '.siteorigin-widget-field-type-media', function(e) {
6
+ var $field = $( this );
7
+ var $media = $field.find('> .media-field-wrapper');
8
+ var $inputField = $field.find( '.siteorigin-widget-input' ).not('.media-fallback-external');
9
+
10
+ if ( $media.data( 'initialized' ) ) {
11
+ return;
12
+ }
13
+
14
+ // Handle the media uploader
15
+ $media.find( '.media-upload-button' ).click(function(e){
16
+ e.preventDefault();
17
+ if( typeof wp.media === 'undefined' ) {
18
+ return;
19
+ }
20
+
21
+ var $$ = $(this);
22
+ var frame = $(this ).data('frame');
23
+
24
+ // If the media frame already exists, reopen it.
25
+ if ( frame ) {
26
+ frame.open();
27
+ return false;
28
+ }
29
+
30
+ // Create the media frame.
31
+ frame = wp.media( {
32
+ // Set the title of the modal.
33
+ title: $$.data('choose'),
34
+
35
+ // Tell the modal to show only images.
36
+ library: {
37
+ type: $$.data('library').split(',').map(function(v){ return v.trim(); })
38
+ },
39
+
40
+ // Customize the submit button.
41
+ button: {
42
+ // Set the text of the button.
43
+ text: $$.data('update'),
44
+ // Tell the button not to close the modal, since we're
45
+ // going to refresh the page when the image is selected.
46
+ close: false
47
+ }
48
+ } );
49
+
50
+ // Store the frame
51
+ $$.data('frame', frame);
52
+
53
+ // When an image is selected, run a callback.
54
+ frame.on( 'select', function() {
55
+ // Grab the selected attachment.
56
+ var attachment = frame.state().get('selection').first().attributes;
57
+
58
+ $field.find('.current .title' ).html(attachment.title);
59
+ $inputField.val(attachment.id);
60
+ $inputField.trigger( 'change', { silent: true } );
61
+
62
+ var $thumbnail = $field.find( '.current .thumbnail' );
63
+
64
+ if(typeof attachment.sizes !== 'undefined'){
65
+ if(typeof attachment.sizes.thumbnail !== 'undefined'){
66
+ $thumbnail.attr('src', attachment.sizes.thumbnail.url).fadeIn();
67
+ }
68
+ else {
69
+ $thumbnail.attr('src', attachment.sizes.full.url).fadeIn();
70
+ }
71
+ }
72
+ else{
73
+ $thumbnail.attr('src', attachment.icon).fadeIn();
74
+ }
75
+
76
+ $field.find('.media-remove-button').removeClass('remove-hide');
77
+
78
+ frame.close();
79
+ } );
80
+
81
+ // Finally, open the modal.
82
+ frame.open();
83
+ });
84
+
85
+ $media.find('.current' )
86
+ .mouseenter(function(){
87
+ var t = $(this ).find('.title' );
88
+ if( t.html() !== ''){
89
+ t.fadeIn('fast');
90
+ }
91
+ })
92
+ .mouseleave(function(){
93
+ $(this ).find('.title' ).clearQueue().fadeOut('fast');
94
+ });
95
+
96
+ $field.find('a.media-remove-button' )
97
+ .click( function( e ){
98
+ e.preventDefault();
99
+ $field.find('.current .title' ).html('');
100
+ $inputField.val('');
101
+ $inputField.trigger( 'change', { silent: true } );
102
+ $field.find('.current .thumbnail' ).fadeOut('fast');
103
+ $(this).addClass('remove-hide');
104
+ } );
105
+
106
+ // Everything for the dialog
107
+ var dialog;
108
+
109
+ var reflowDialog = function() {
110
+ if( ! dialog ) return;
111
+
112
+ var results = dialog.find('.so-widgets-image-results');
113
+ if( results.length === 0 ) return;
114
+
115
+ var width = results.width(),
116
+ perRow = Math.floor( width / 276 ),
117
+ spare = ( width - perRow * 276 ),
118
+ resultWidth = spare / perRow + 260;
119
+
120
+ results.find( '.so-widgets-result-image' ).css( {
121
+ 'width' : resultWidth,
122
+ 'height' : resultWidth / 1.4
123
+ } );
124
+ };
125
+ $(window).resize( reflowDialog );
126
+
127
+ var setupDialog = function(){
128
+ if( ! dialog ) {
129
+ // Create the dialog
130
+ dialog = $( $('#so-widgets-bundle-tpl-image-search-dialog').html().trim() ).appendTo( 'body' );
131
+ dialog.find( '.close' ).click( function(){
132
+ dialog.hide();
133
+ } );
134
+
135
+ var results = dialog.find( '.so-widgets-image-results' );
136
+
137
+ var fetchImages = function( query, page ){
138
+ dialog.find( '.so-widgets-results-loading' ).fadeIn('fast');
139
+ dialog.find( '.so-widgets-results-loading strong' ).html(
140
+ dialog.find( '.so-widgets-results-loading strong' ).data( 'loading' )
141
+ );
142
+ dialog.find( '.so-widgets-results-more' ).hide();
143
+
144
+ $.get(
145
+ ajaxurl,
146
+ {
147
+ 'action' : 'so_widgets_image_search',
148
+ 'q' : query,
149
+ 'page' : page,
150
+ '_sononce' : dialog.find('input[name="_sononce"]').val()
151
+ },
152
+ function( response ){
153
+ if( response.error ) {
154
+ alert( response.message );
155
+ return;
156
+ }
157
+
158
+ results.removeClass( 'so-loading' );
159
+ $.each( response.items, function( i, r ){
160
+ var result = $( $('#so-widgets-bundle-tpl-image-search-result').html().trim() )
161
+ .appendTo( results )
162
+ .addClass( 'source-' + r.source );
163
+ var img = result.find('.so-widgets-result-image');
164
+
165
+ // Preload the image
166
+ img.css( 'background-image', 'url(' + r.thumbnail + ')' );
167
+ img.data( 'thumbnail', r.thumbnail );
168
+ img.data( 'preview', r.preview );
169
+
170
+ if( r.url ) {
171
+ img.attr( {
172
+ 'href': r.url,
173
+ 'target': '_blank'
174
+ } );
175
+ }
176
+
177
+ if( r.full_url ) {
178
+ img.data( {
179
+ 'full_url' : r.full_url,
180
+ 'import_signature' : r.import_signature
181
+ } );
182
+ img.attr( 'href', r.full_url );
183
+ }
184
+
185
+ if( r.source === 'shutterstock' ) {
186
+ img.append( $('#so-widgets-bundle-tpl-image-search-result-sponsored').html() );
187
+ }
188
+ } );
189
+
190
+ if( page === 1 ) {
191
+ dialog.find('#so-widgets-image-search-suggestions ul').empty();
192
+ $.each( response.keywords, function( i, r ){
193
+ dialog.find('#so-widgets-image-search-suggestions').show();
194
+ dialog.find('#so-widgets-image-search-suggestions ul').append(
195
+ $('<li></li>') . append( $('<a href="#"></a>').html( r ).data( 'keyword', r ) )
196
+ );
197
+ } );
198
+ }
199
+
200
+ dialog.find( '.so-widgets-results-loading' ).fadeOut('fast');
201
+
202
+ reflowDialog();
203
+ dialog
204
+ .find( '.so-widgets-results-more' ).show()
205
+ .find( 'button' ).data( { 'query': query, 'page' : page+1 } );
206
+ }
207
+ );
208
+
209
+ };
210
+
211
+ // Setup the search
212
+ dialog.find('#so-widgets-image-search-form').submit( function( e ){
213
+ e.preventDefault();
214
+
215
+ // Perform the search
216
+ var q = dialog.find('.so-widgets-search-input').val();
217
+ results.empty();
218
+
219
+ if( q !== '' ) {
220
+ // Send the query to the server
221
+ fetchImages( q, 1 );
222
+ }
223
+ } );
224
+
225
+ // Clicking on the related search buttons
226
+ dialog.on( 'click', '.so-keywords-list a', function( e ){
227
+ e.preventDefault();
228
+ var $$ = $(this).blur();
229
+ dialog.find('.so-widgets-search-input').val( $$.data( 'keyword' ) );
230
+ dialog.find('#so-widgets-image-search-form').submit();
231
+ } );
232
+
233
+ // Clicking on the more button
234
+ dialog.find('.so-widgets-results-more button').click( function(){
235
+ var $$ = $(this);
236
+ fetchImages( $$.data( 'query' ), $$.data( 'page' ) );
237
+ } );
238
+
239
+ var hoverTimeout;
240
+
241
+ // Clicking on an image to import it
242
+ dialog.on( 'click', '.so-widgets-result-image', function( e ){
243
+ var $$ = $(this);
244
+ if( ! $$.data( 'full_url' ) ) {
245
+ return;
246
+ }
247
+
248
+ e.preventDefault();
249
+
250
+ if( confirm( dialog.data('confirm-import') ) ) {
251
+ dialog.addClass( 'so-widgets-importing' );
252
+
253
+ var postId = $( '#post_ID' ).val();
254
+ if( postId === null ) {
255
+ postId = '';
256
+ }
257
+
258
+ // Send the message to import the URL
259
+ $.get(
260
+ ajaxurl,
261
+ {
262
+ 'action' : 'so_widgets_image_import',
263
+ 'full_url' : $$.data( 'full_url' ),
264
+ 'import_signature' : $$.data( 'import_signature' ),
265
+ 'post_id' : postId,
266
+ '_sononce' : dialog.find('input[name="_sononce"]').val()
267
+ },
268
+ function( response ) {
269
+ dialog.find('#so-widgets-image-search-frame').removeClass( 'so-widgets-importing' );
270
+
271
+ if( response.error === false ) {
272
+ // This was a success
273
+ dialog.hide();
274
+ dialog.find( '.so-widgets-results-loading' ).hide();
275
+ $inputField.val( response.attachment_id ).trigger('change', { silent: true } );
276
+ $field.find('.current .thumbnail' ).attr('src', response.thumb ).fadeIn();
277
+
278
+ $field.find('.media-remove-button').removeClass('remove-hide');
279
+ }
280
+ else {
281
+ alert( response.message );
282
+ dialog.find( '.so-widgets-results-loading' ).hide();
283
+ }
284
+ }
285
+ );
286
+
287
+ // Clear the dialog
288
+ dialog.find( '.so-widgets-results-loading' ).fadeIn('fast');
289
+ dialog.find( '.so-widgets-results-loading strong' ).html(
290
+ dialog.find( '.so-widgets-results-loading strong' ).data( 'importing' )
291
+ );
292
+ dialog.find( '.so-widgets-results-more' ).hide();
293
+ dialog.find('#so-widgets-image-search-frame').addClass( 'so-widgets-importing' );
294
+ }
295
+ } );
296
+
297
+ // Hovering over an image to preview it
298
+ var previewWindow = dialog.find('.so-widgets-preview-window');
299
+ dialog
300
+ .on( 'mouseenter', '.so-widgets-result-image', function(){
301
+ var $$ = $(this),
302
+ preview = $$.data('preview');
303
+
304
+ clearTimeout( hoverTimeout );
305
+
306
+ hoverTimeout = setTimeout( function(){
307
+ // Scale the preview sizes
308
+ var scalePreviewX = 1, scalePreviewY = 1;
309
+ if( preview[1] > $( window ).outerWidth() *0.33 ) {
310
+ scalePreviewX = $( window ).outerWidth() *0.33 / preview[1];
311
+ }
312
+ if( preview[2] > $( window ).outerHeight() *0.5 ) {
313
+ scalePreviewY = $( window ).outerHeight() *0.5 / preview[2];
314
+ }
315
+ var scalePreview = Math.min( scalePreviewX, scalePreviewY );
316
+ // Never upscale
317
+ if( scalePreview > 1 ) {
318
+ scalePreview = 1;
319
+ }
320
+
321
+ previewWindow.show()
322
+ .find('.so-widgets-preview-window-inside')
323
+ .css( {
324
+ 'background-image' : 'url(' + $$.data('thumbnail') + ')',
325
+ 'width' : preview[1] * scalePreview,
326
+ 'height' : preview[2] * scalePreview
327
+ } )
328
+ .append( $( '<img />' ).attr( 'src', preview[0] ) );
329
+
330
+ dialog.trigger('mousemove');
331
+ }, 1000 );
332
+
333
+ } )
334
+ .on( 'mouseleave', '.so-widgets-result-image', function(){
335
+ previewWindow.hide().find('img').remove();
336
+ clearTimeout( hoverTimeout );
337
+ } );
338
+
339
+ var lastX, lastY;
340
+ dialog.on( 'mousemove', function( e ){
341
+ if( e.clientX ) lastX = e.clientX;
342
+ if( e.clientY ) lastY = e.clientY;
343
+
344
+ if( previewWindow.is( ':visible' ) ) {
345
+ var ph = previewWindow.outerHeight(),
346
+ pw = previewWindow.outerWidth(),
347
+ wh = $( window ).outerHeight(),
348
+ ww = $( window ).outerWidth();
349
+
350
+
351
+ // Calculate the top position
352
+ var top = lastY - ph/2;
353
+ top = Math.max( top, 10 );
354
+ top = Math.min( top, wh - 10 - ph );
355
+
356
+ // Calculate the left position
357
+ var left = (lastX < ww/2) ? lastX + 15 : lastX - 15 - pw;
358
+
359
+ // Figure out where the preview needs to go
360
+ previewWindow.css({
361
+ 'top': top,
362
+ 'left': left
363
+ });
364
+
365
+ }
366
+ } );
367
+ }
368
+
369
+ dialog.show();
370
+ dialog.find( '.so-widgets-search-input' ).focus();
371
+ };
372
+
373
+ // Handle displaying the image search dialog
374
+ $media.find( '.find-image-button' ).click( function(e){
375
+ e.preventDefault();
376
+ setupDialog();
377
+ } );
378
+
379
+ $inputField.change( function ( event, data ) {
380
+ if ( ! ( data && data.silent ) ) {
381
+ var newVal = $inputField.val();
382
+ if ( newVal) {
383
+ var $thumbnail = $field.find( '.current .thumbnail' );
384
+ var attachment = wp.media.attachment( newVal );
385
+ attachment.fetch().done( function () {
386
+ if ( attachment.has( 'sizes' ) ) {
387
+ var sizes = attachment.get( 'sizes' );
388
+ if ( typeof sizes.thumbnail !== 'undefined' ) {
389
+ $thumbnail.attr( 'src', sizes.thumbnail.url ).fadeIn();
390
+ }
391
+ else {
392
+ $thumbnail.attr( 'src', sizes.full.url ).fadeIn();
393
+ }
394
+ }
395
+ else {
396
+ $thumbnail.attr( 'src', attachment.get('icon') ).fadeIn();
397
+ }
398
+ $field.find('.media-remove-button').removeClass('remove-hide');
399
+ } );
400
+ } else {
401
+ $field.find( 'a.media-remove-button' ).click();
402
+ }
403
+ }
404
+ } );
405
+
406
+ $media.data( 'initialized', true );
407
+ });
408
+
409
+ } )( jQuery );
base/inc/fields/js/media-field.min.js CHANGED
@@ -1 +1 @@
1
- !function(e){e(document).on("sowsetupformfield",".siteorigin-widget-field-type-media",function(t){var i=e(this),a=i.find("> .media-field-wrapper"),s=i.find(".siteorigin-widget-input").not(".media-fallback-external");if(!a.data("initialized")){a.find(".media-upload-button").click(function(t){if(t.preventDefault(),void 0!==wp.media){var a=e(this),n=e(this).data("frame");if(n)return n.open(),!1;n=wp.media({title:a.data("choose"),library:{type:a.data("library").split(",").map(function(e){return e.trim()})},button:{text:a.data("update"),close:!1}}),a.data("frame",n),n.on("select",function(){var e=n.state().get("selection").first().attributes;i.find(".current .title").html(e.title),s.val(e.id),s.trigger("change",{silent:!0});var t=i.find(".current .thumbnail");void 0!==e.sizes?void 0!==e.sizes.thumbnail?t.attr("src",e.sizes.thumbnail.url).fadeIn():t.attr("src",e.sizes.full.url).fadeIn():t.attr("src",e.icon).fadeIn(),i.find(".media-remove-button").removeClass("remove-hide"),n.close()}),n.open()}}),a.find(".current").mouseenter(function(){var t=e(this).find(".title");""!==t.html()&&t.fadeIn("fast")}).mouseleave(function(){e(this).find(".title").clearQueue().fadeOut("fast")}),i.find("a.media-remove-button").click(function(t){t.preventDefault(),i.find(".current .title").html(""),s.val(""),i.find(".current .thumbnail").fadeOut("fast"),e(this).addClass("remove-hide")});var n,r=function(){if(n){var e=n.find(".so-widgets-image-results");if(0!==e.length){var t=e.width(),i=Math.floor(t/276),a=t-276*i,s=a/i+260;e.find(".so-widgets-result-image").css({width:s,height:s/1.4})}}};e(window).resize(r);var o=function(){if(!n){n=e(e("#so-widgets-bundle-tpl-image-search-dialog").html().trim()).appendTo("body"),n.find(".close").click(function(){n.hide()});var t=n.find(".so-widgets-image-results"),a=function(i,a){n.find(".so-widgets-results-loading").fadeIn("fast"),n.find(".so-widgets-results-loading strong").html(n.find(".so-widgets-results-loading strong").data("loading")),n.find(".so-widgets-results-more").hide(),e.get(ajaxurl,{action:"so_widgets_image_search",q:i,page:a,_sononce:n.find('input[name="_sononce"]').val()},function(s){if(s.error)return void alert(s.message);t.removeClass("so-loading"),e.each(s.items,function(i,a){var s=e(e("#so-widgets-bundle-tpl-image-search-result").html().trim()).appendTo(t).addClass("source-"+a.source),n=s.find(".so-widgets-result-image");n.css("background-image","url("+a.thumbnail+")"),n.data("thumbnail",a.thumbnail),n.data("preview",a.preview),a.url&&n.attr({href:a.url,target:"_blank"}),a.full_url&&(n.data({full_url:a.full_url,import_signature:a.import_signature}),n.attr("href",a.full_url)),"shutterstock"===a.source&&n.append(e("#so-widgets-bundle-tpl-image-search-result-sponsored").html())}),1===a&&(n.find("#so-widgets-image-search-suggestions ul").empty(),e.each(s.keywords,function(t,i){n.find("#so-widgets-image-search-suggestions").show(),n.find("#so-widgets-image-search-suggestions ul").append(e("<li></li>").append(e('<a href="#"></a>').html(i).data("keyword",i)))})),n.find(".so-widgets-results-loading").fadeOut("fast"),r(),n.find(".so-widgets-results-more").show().find("button").data({query:i,page:a+1})})};n.find("#so-widgets-image-search-form").submit(function(e){e.preventDefault();var i=n.find(".so-widgets-search-input").val();t.empty(),""!==i&&a(i,1)}),n.on("click",".so-keywords-list a",function(t){t.preventDefault();var i=e(this).blur();n.find(".so-widgets-search-input").val(i.data("keyword")),n.find("#so-widgets-image-search-form").submit()}),n.find(".so-widgets-results-more button").click(function(){var t=e(this);a(t.data("query"),t.data("page"))});var o;n.on("click",".so-widgets-result-image",function(t){var a=e(this);if(a.data("full_url")&&(t.preventDefault(),confirm(n.data("confirm-import")))){n.addClass("so-widgets-importing");var r=e("#post_ID").val();null===r&&(r=""),e.get(ajaxurl,{action:"so_widgets_image_import",full_url:a.data("full_url"),import_signature:a.data("import_signature"),post_id:r,_sononce:n.find('input[name="_sononce"]').val()},function(e){n.find("#so-widgets-image-search-frame").removeClass("so-widgets-importing"),!1===e.error?(n.hide(),n.find(".so-widgets-results-loading").hide(),s.val(e.attachment_id).trigger("change",{silent:!0}),i.find(".current .thumbnail").attr("src",e.thumb).fadeIn(),i.find(".media-remove-button").removeClass("remove-hide")):(alert(e.message),n.find(".so-widgets-results-loading").hide())}),n.find(".so-widgets-results-loading").fadeIn("fast"),n.find(".so-widgets-results-loading strong").html(n.find(".so-widgets-results-loading strong").data("importing")),n.find(".so-widgets-results-more").hide(),n.find("#so-widgets-image-search-frame").addClass("so-widgets-importing")}});var d=n.find(".so-widgets-preview-window");n.on("mouseenter",".so-widgets-result-image",function(){var t=e(this),i=t.data("preview");clearTimeout(o),o=setTimeout(function(){var a=1,s=1;i[1]>.33*e(window).outerWidth()&&(a=.33*e(window).outerWidth()/i[1]),i[2]>.5*e(window).outerHeight()&&(s=.5*e(window).outerHeight()/i[2]);var r=Math.min(a,s);r>1&&(r=1),d.show().find(".so-widgets-preview-window-inside").css({"background-image":"url("+t.data("thumbnail")+")",width:i[1]*r,height:i[2]*r}).append(e("<img />").attr("src",i[0])),n.trigger("mousemove")},1e3)}).on("mouseleave",".so-widgets-result-image",function(){d.hide().find("img").remove(),clearTimeout(o)});var l,u;n.on("mousemove",function(t){if(t.clientX&&(l=t.clientX),t.clientY&&(u=t.clientY),d.is(":visible")){var i=d.outerHeight(),a=d.outerWidth(),s=e(window).outerHeight(),n=e(window).outerWidth(),r=u-i/2;r=Math.max(r,10),r=Math.min(r,s-10-i);var o=l<n/2?l+15:l-15-a;d.css({top:r,left:o})}})}n.show(),n.find(".so-widgets-search-input").focus()};a.find(".find-image-button").click(function(e){e.preventDefault(),o()}),s.change(function(e,t){if(!t||!t.silent){var a=s.val();if(a){var n=i.find(".current .thumbnail"),r=wp.media.attachment(a);r.fetch().done(function(){if(r.has("sizes")){var e=r.get("sizes");void 0!==e.thumbnail?n.attr("src",e.thumbnail.url).fadeIn():n.attr("src",e.full.url).fadeIn()}else n.attr("src",r.get("icon")).fadeIn();i.find(".media-remove-button").removeClass("remove-hide")})}else i.find("a.media-remove-button").click()}}),a.data("initialized",!0)}})}(jQuery);
1
+ !function(e){e(document).on("sowsetupformfield",".siteorigin-widget-field-type-media",function(t){var i=e(this),a=i.find("> .media-field-wrapper"),s=i.find(".siteorigin-widget-input").not(".media-fallback-external");if(!a.data("initialized")){a.find(".media-upload-button").click(function(t){if(t.preventDefault(),void 0!==wp.media){var a=e(this),n=e(this).data("frame");if(n)return n.open(),!1;n=wp.media({title:a.data("choose"),library:{type:a.data("library").split(",").map(function(e){return e.trim()})},button:{text:a.data("update"),close:!1}}),a.data("frame",n),n.on("select",function(){var e=n.state().get("selection").first().attributes;i.find(".current .title").html(e.title),s.val(e.id),s.trigger("change",{silent:!0});var t=i.find(".current .thumbnail");void 0!==e.sizes?void 0!==e.sizes.thumbnail?t.attr("src",e.sizes.thumbnail.url).fadeIn():t.attr("src",e.sizes.full.url).fadeIn():t.attr("src",e.icon).fadeIn(),i.find(".media-remove-button").removeClass("remove-hide"),n.close()}),n.open()}}),a.find(".current").mouseenter(function(){var t=e(this).find(".title");""!==t.html()&&t.fadeIn("fast")}).mouseleave(function(){e(this).find(".title").clearQueue().fadeOut("fast")}),i.find("a.media-remove-button").click(function(t){t.preventDefault(),i.find(".current .title").html(""),s.val(""),s.trigger("change",{silent:!0}),i.find(".current .thumbnail").fadeOut("fast"),e(this).addClass("remove-hide")});var n,r=function(){if(n){var e=n.find(".so-widgets-image-results");if(0!==e.length){var t=e.width(),i=Math.floor(t/276),a=t-276*i,s=a/i+260;e.find(".so-widgets-result-image").css({width:s,height:s/1.4})}}};e(window).resize(r);var o=function(){if(!n){n=e(e("#so-widgets-bundle-tpl-image-search-dialog").html().trim()).appendTo("body"),n.find(".close").click(function(){n.hide()});var t=n.find(".so-widgets-image-results"),a=function(i,a){n.find(".so-widgets-results-loading").fadeIn("fast"),n.find(".so-widgets-results-loading strong").html(n.find(".so-widgets-results-loading strong").data("loading")),n.find(".so-widgets-results-more").hide(),e.get(ajaxurl,{action:"so_widgets_image_search",q:i,page:a,_sononce:n.find('input[name="_sononce"]').val()},function(s){if(s.error)return void alert(s.message);t.removeClass("so-loading"),e.each(s.items,function(i,a){var s=e(e("#so-widgets-bundle-tpl-image-search-result").html().trim()).appendTo(t).addClass("source-"+a.source),n=s.find(".so-widgets-result-image");n.css("background-image","url("+a.thumbnail+")"),n.data("thumbnail",a.thumbnail),n.data("preview",a.preview),a.url&&n.attr({href:a.url,target:"_blank"}),a.full_url&&(n.data({full_url:a.full_url,import_signature:a.import_signature}),n.attr("href",a.full_url)),"shutterstock"===a.source&&n.append(e("#so-widgets-bundle-tpl-image-search-result-sponsored").html())}),1===a&&(n.find("#so-widgets-image-search-suggestions ul").empty(),e.each(s.keywords,function(t,i){n.find("#so-widgets-image-search-suggestions").show(),n.find("#so-widgets-image-search-suggestions ul").append(e("<li></li>").append(e('<a href="#"></a>').html(i).data("keyword",i)))})),n.find(".so-widgets-results-loading").fadeOut("fast"),r(),n.find(".so-widgets-results-more").show().find("button").data({query:i,page:a+1})})};n.find("#so-widgets-image-search-form").submit(function(e){e.preventDefault();var i=n.find(".so-widgets-search-input").val();t.empty(),""!==i&&a(i,1)}),n.on("click",".so-keywords-list a",function(t){t.preventDefault();var i=e(this).blur();n.find(".so-widgets-search-input").val(i.data("keyword")),n.find("#so-widgets-image-search-form").submit()}),n.find(".so-widgets-results-more button").click(function(){var t=e(this);a(t.data("query"),t.data("page"))});var o;n.on("click",".so-widgets-result-image",function(t){var a=e(this);if(a.data("full_url")&&(t.preventDefault(),confirm(n.data("confirm-import")))){n.addClass("so-widgets-importing");var r=e("#post_ID").val();null===r&&(r=""),e.get(ajaxurl,{action:"so_widgets_image_import",full_url:a.data("full_url"),import_signature:a.data("import_signature"),post_id:r,_sononce:n.find('input[name="_sononce"]').val()},function(e){n.find("#so-widgets-image-search-frame").removeClass("so-widgets-importing"),!1===e.error?(n.hide(),n.find(".so-widgets-results-loading").hide(),s.val(e.attachment_id).trigger("change",{silent:!0}),i.find(".current .thumbnail").attr("src",e.thumb).fadeIn(),i.find(".media-remove-button").removeClass("remove-hide")):(alert(e.message),n.find(".so-widgets-results-loading").hide())}),n.find(".so-widgets-results-loading").fadeIn("fast"),n.find(".so-widgets-results-loading strong").html(n.find(".so-widgets-results-loading strong").data("importing")),n.find(".so-widgets-results-more").hide(),n.find("#so-widgets-image-search-frame").addClass("so-widgets-importing")}});var d=n.find(".so-widgets-preview-window");n.on("mouseenter",".so-widgets-result-image",function(){var t=e(this),i=t.data("preview");clearTimeout(o),o=setTimeout(function(){var a=1,s=1;i[1]>.33*e(window).outerWidth()&&(a=.33*e(window).outerWidth()/i[1]),i[2]>.5*e(window).outerHeight()&&(s=.5*e(window).outerHeight()/i[2]);var r=Math.min(a,s);r>1&&(r=1),d.show().find(".so-widgets-preview-window-inside").css({"background-image":"url("+t.data("thumbnail")+")",width:i[1]*r,height:i[2]*r}).append(e("<img />").attr("src",i[0])),n.trigger("mousemove")},1e3)}).on("mouseleave",".so-widgets-result-image",function(){d.hide().find("img").remove(),clearTimeout(o)});var l,u;n.on("mousemove",function(t){if(t.clientX&&(l=t.clientX),t.clientY&&(u=t.clientY),d.is(":visible")){var i=d.outerHeight(),a=d.outerWidth(),s=e(window).outerHeight(),n=e(window).outerWidth(),r=u-i/2;r=Math.max(r,10),r=Math.min(r,s-10-i);var o=l<n/2?l+15:l-15-a;d.css({top:r,left:o})}})}n.show(),n.find(".so-widgets-search-input").focus()};a.find(".find-image-button").click(function(e){e.preventDefault(),o()}),s.change(function(e,t){if(!t||!t.silent){var a=s.val();if(a){var n=i.find(".current .thumbnail"),r=wp.media.attachment(a);r.fetch().done(function(){if(r.has("sizes")){var e=r.get("sizes");void 0!==e.thumbnail?n.attr("src",e.thumbnail.url).fadeIn():n.attr("src",e.full.url).fadeIn()}else n.attr("src",r.get("icon")).fadeIn();i.find(".media-remove-button").removeClass("remove-hide")})}else i.find("a.media-remove-button").click()}}),a.data("initialized",!0)}})}(jQuery);
base/inc/fields/tinymce.class.php CHANGED
@@ -64,6 +64,13 @@ class SiteOrigin_Widget_Field_TinyMCE extends SiteOrigin_Widget_Field_Text_Input
64
  * @var array
65
  */
66
  protected $quicktags_buttons;
 
 
 
 
 
 
 
67
  /**
68
  * An array of filter callbacks to apply to the set of buttons which will be rendered for the editor.
69
  *
@@ -93,8 +100,17 @@ class SiteOrigin_Widget_Field_TinyMCE extends SiteOrigin_Widget_Field_Text_Input
93
  */
94
  private $wp_version_lt_4_8;
95
 
 
 
 
 
 
 
 
 
96
  protected function get_default_options() {
97
  return array(
 
98
  'mce_buttons' => array(
99
  'formatselect',
100
  'bold',
@@ -372,7 +388,7 @@ class SiteOrigin_Widget_Field_TinyMCE extends SiteOrigin_Widget_Field_Text_Input
372
  'tinymce' => array(
373
  'wp_skip_init' => strpos( $this->element_id, '__i__' ) != false ||
374
  strpos( $this->element_id, '_id_' ) != false,
375
- 'wpautop' => true,
376
  ),
377
  'quicktags' => array(
378
  'buttons' => $qt_settings['buttons'],
@@ -480,6 +496,9 @@ class SiteOrigin_Widget_Field_TinyMCE extends SiteOrigin_Widget_Field_Text_Input
480
  }
481
 
482
  protected function sanitize_field_input( $value, $instance ) {
 
 
 
483
  if( current_user_can( 'unfiltered_html' ) ) {
484
  $sanitized_value = $value;
485
  } else {
64
  * @var array
65
  */
66
  protected $quicktags_buttons;
67
+ /**
68
+ * Whether to apply `wpautop` processing. (Adds paragraphs for double linebreaks) Default is true.
69
+ *
70
+ * @access protected
71
+ * @var array
72
+ */
73
+ protected $wpautop;
74
  /**
75
  * An array of filter callbacks to apply to the set of buttons which will be rendered for the editor.
76
  *
100
  */
101
  private $wp_version_lt_4_8;
102
 
103
+ public static function unautop( $text ) {
104
+ $text = str_replace('<p>', '', $text);
105
+ $text = str_replace(array('<br />', '<br>', '<br/>'), "\n", $text);
106
+ $text = str_replace('</p>', "\n\n", $text);
107
+
108
+ return $text;
109
+ }
110
+
111
  protected function get_default_options() {
112
  return array(
113
+ 'wpautop' => true,
114
  'mce_buttons' => array(
115
  'formatselect',
116
  'bold',
388
  'tinymce' => array(
389
  'wp_skip_init' => strpos( $this->element_id, '__i__' ) != false ||
390
  strpos( $this->element_id, '_id_' ) != false,
391
+ 'wpautop' => ! empty( $this->wpautop ),
392
  ),
393
  'quicktags' => array(
394
  'buttons' => $qt_settings['buttons'],
496
  }
497
 
498
  protected function sanitize_field_input( $value, $instance ) {
499
+ if ( ! empty( $this->wpautop ) ) {
500
+ $value = wpautop( self::unautop( $value ) );
501
+ }
502
  if( current_user_can( 'unfiltered_html' ) ) {
503
  $sanitized_value = $value;
504
  } else {
base/inc/less-functions.php CHANGED
@@ -1,41 +1,41 @@
1
- <?php
2
-
3
- /**
4
- * Class siteorigin_lessc
5
- *
6
- * An extension to the lessc class that adds a few custom functions
7
- */
8
- class SiteOrigin_Widgets_Less_Functions {
9
-
10
- private $widget;
11
- private $widget_instance;
12
-
13
- function __construct($widget, $widget_instance){
14
- $this->widget = $widget;
15
- $this->widget_instance = $widget_instance;
16
- }
17
-
18
- /**
19
- * @param lessc $c
20
- *
21
- * Register less functions in a lessc object
22
- */
23
- function registerFunctions(&$c){
24
- if( method_exists( $c, 'registerFunction' ) ) {
25
- $c->registerFunction( 'length', array($this, 'length') );
26
- }
27
- }
28
-
29
- /**
30
- * Very basic length function that checks the length of a list. Might need some more checks for other types.
31
- *
32
- * @param $arg
33
- *
34
- * @return int
35
- */
36
- function length($arg){
37
- if(empty($arg[0]) || empty($arg[2]) || $arg[0] != 'list') return 1;
38
- return count($arg[2]);
39
- }
40
-
41
- }
1
+ <?php
2
+
3
+ /**
4
+ * Class siteorigin_lessc
5
+ *
6
+ * An extension to the SiteOrigin_LessC class that adds a few custom functions
7
+ */
8
+ class SiteOrigin_Widgets_Less_Functions {
9
+
10
+ private $widget;
11
+ private $widget_instance;
12
+
13
+ function __construct($widget, $widget_instance){
14
+ $this->widget = $widget;
15
+ $this->widget_instance = $widget_instance;
16
+ }
17
+
18
+ /**
19
+ * @param SiteOrigin_LessC $c
20
+ *
21
+ * Register less functions in a SiteOrigin_LessC object
22
+ */
23
+ function registerFunctions(&$c){
24
+ if( method_exists( $c, 'registerFunction' ) ) {
25
+ $c->registerFunction( 'length', array($this, 'length') );
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Very basic length function that checks the length of a list. Might need some more checks for other types.
31
+ *
32
+ * @param $arg
33
+ *
34
+ * @return int
35
+ */
36
+ function length($arg){
37
+ if(empty($arg[0]) || empty($arg[2]) || $arg[0] != 'list') return 1;
38
+ return count($arg[2]);
39
+ }
40
+
41
+ }
base/inc/lessc.inc.php CHANGED
@@ -1,283 +1,283 @@
1
- <?php
2
- /**
3
- * This file provides the part of lessphp API (https://github.com/leafo/lessphp)
4
- * to be a drop-in replacement for following products:
5
- * - Drupal 7, by the less module v3.0+ (https://drupal.org/project/less)
6
- * - Symfony 2
7
- *
8
- * @SiteOrigin: We originally used leafo/lessphp (https://github.com/leafo/lessphp), until we found it wasn't
9
- * maintained and missed some newer LESS features. We then migrated to a more recent and maintained repo
10
- * (https://github.com/oyejorge/less.php) simply replacing leafo's lessc.inc.php with the one from oyejorge. This
11
- * worked well until users started running PHP 7 compatibility checkers which found some issues, so now we have our own
12
- * fork here: https://github.com/siteorigin/less.php We have fixed the PHP 7 compatibility issues and will only make
13
- * more changes if there are severe issues.
14
- */
15
-
16
- // Register autoloader for non-composer installations
17
- if ( !class_exists( 'Less_Parser' ) ) {
18
- require_once dirname( __FILE__ ) . '/lib/Less/Autoloader.php';
19
- Less_Autoloader::register();
20
- }
21
-
22
- class lessc {
23
-
24
- static public $VERSION = Less_Version::less_version;
25
-
26
- public $importDir = '';
27
- protected $allParsedFiles = array();
28
- protected $libFunctions = array();
29
- protected $registeredVars = array();
30
- private $formatterName;
31
- private $options = array();
32
-
33
- public function __construct( $lessc=null, $sourceName=null ) {}
34
-
35
- public function setImportDir( $dirs ) {
36
- $this->importDir = (array)$dirs;
37
- }
38
-
39
- public function addImportDir( $dir ) {
40
- $this->importDir = (array)$this->importDir;
41
- $this->importDir[] = $dir;
42
- }
43
-
44
- public function setFormatter( $name ) {
45
- $this->formatterName = $name;
46
- }
47
-
48
- public function setPreserveComments( $preserve ) {}
49
-
50
- public function registerFunction( $name, $func ) {
51
- $this->libFunctions[$name] = $func;
52
- }
53
-
54
- public function unregisterFunction( $name ) {
55
- unset( $this->libFunctions[$name] );
56
- }
57
-
58
- public function setVariables( $variables ){
59
- foreach ( $variables as $name => $value ) {
60
- $this->setVariable( $name, $value );
61
- }
62
- }
63
-
64
- public function setVariable( $name, $value ) {
65
- $this->registeredVars[$name] = $value;
66
- }
67
-
68
- public function unsetVariable( $name ) {
69
- unset( $this->registeredVars[$name] );
70
- }
71
-
72
- public function setOptions( $options ) {
73
- foreach ( $options as $name => $value ) {
74
- $this->setOption( $name, $value);
75
- }
76
- }
77
-
78
- public function setOption( $name, $value ) {
79
- $this->options[$name] = $value;
80
- }
81
-
82
- public function parse( $buffer, $presets = array() ) {
83
-
84
- $this->setVariables( $presets );
85
-
86
- $parser = new Less_Parser( $this->getOptions() );
87
- $parser->setImportDirs( $this->getImportDirs() );
88
- foreach ( $this->libFunctions as $name => $func ) {
89
- $parser->registerFunction( $name, $func );
90
- }
91
- $parser->parse($buffer);
92
- if ( count( $this->registeredVars ) ) {
93
- $parser->ModifyVars( $this->registeredVars );
94
- }
95
-
96
- return $parser->getCss();
97
- }
98
-
99
- protected function getOptions() {
100
- $options = array( 'relativeUrls'=>false );
101
- switch( $this->formatterName ) {
102
- case 'compressed':
103
- $options['compress'] = true;
104
- break;
105
- }
106
- if (is_array($this->options))
107
- {
108
- $options = array_merge($options, $this->options);
109
- }
110
- return $options;
111
- }
112
-
113
- protected function getImportDirs() {
114
- $dirs_ = (array)$this->importDir;
115
- $dirs = array();
116
- foreach ( $dirs_ as $dir ) {
117
- $dirs[$dir] = '';
118
- }
119
- return $dirs;
120
- }
121
-
122
- public function compile( $string, $name = null ) {
123
-
124
- $oldImport = $this->importDir;
125
- $this->importDir = (array)$this->importDir;
126
-
127
- $this->allParsedFiles = array();
128
-
129
- $parser = new Less_Parser( $this->getOptions() );
130
- $parser->SetImportDirs( $this->getImportDirs() );
131
- if ( count( $this->registeredVars ) ) {
132
- $parser->ModifyVars( $this->registeredVars );
133
- }
134
- foreach ( $this->libFunctions as $name => $func ) {
135
- $parser->registerFunction( $name, $func );
136
- }
137
- $parser->parse( $string );
138
- $out = $parser->getCss();
139
-
140
- $parsed = Less_Parser::AllParsedFiles();
141
- foreach ( $parsed as $file ) {
142
- $this->addParsedFile( $file );
143
- }
144
-
145
- $this->importDir = $oldImport;
146
-
147
- return $out;
148
- }
149
-
150
- public function compileFile( $fname, $outFname = null ) {
151
- if ( !is_readable( $fname ) ) {
152
- throw new Exception( 'load error: failed to find '.$fname );
153
- }
154
-
155
- $pi = pathinfo( $fname );
156
-
157
- $oldImport = $this->importDir;
158
-
159
- $this->importDir = (array)$this->importDir;
160
- $this->importDir[] = Less_Parser::AbsPath( $pi['dirname'] ).'/';
161
-
162
- $this->allParsedFiles = array();
163
- $this->addParsedFile( $fname );
164
-
165
- $parser = new Less_Parser( $this->getOptions() );
166
- $parser->SetImportDirs( $this->getImportDirs() );
167
- if ( count( $this->registeredVars ) ) {
168
- $parser->ModifyVars( $this->registeredVars );
169
- }
170
- foreach ( $this->libFunctions as $name => $func ) {
171
- $parser->registerFunction( $name, $func );
172
- }
173
- $parser->parseFile( $fname );
174
- $out = $parser->getCss();
175
-
176
- $parsed = Less_Parser::AllParsedFiles();
177
- foreach ( $parsed as $file ) {
178
- $this->addParsedFile( $file );
179
- }
180
-
181
- $this->importDir = $oldImport;
182
-
183
- if ( $outFname !== null ) {
184
- return file_put_contents( $outFname, $out );
185
- }
186
-
187
- return $out;
188
- }
189
-
190
- public function checkedCompile( $in, $out ) {
191
- if ( !is_file( $out ) || filemtime( $in ) > filemtime( $out ) ) {
192
- $this->compileFile($in, $out);
193
- return true;
194
- }
195
- return false;
196
- }
197
-
198
-
199
- /**
200
- * Execute lessphp on a .less file or a lessphp cache structure
201
- *
202
- * The lessphp cache structure contains information about a specific
203
- * less file having been parsed. It can be used as a hint for future
204
- * calls to determine whether or not a rebuild is required.
205
- *
206
- * The cache structure contains two important keys that may be used
207
- * externally:
208
- *
209
- * compiled: The final compiled CSS
210
- * updated: The time (in seconds) the CSS was last compiled
211
- *
212
- * The cache structure is a plain-ol' PHP associative array and can
213
- * be serialized and unserialized without a hitch.
214
- *
215
- * @param mixed $in Input
216
- * @param bool $force Force rebuild?
217
- * @return array lessphp cache structure
218
- */
219
- public function cachedCompile( $in, $force = false ) {
220
- // assume no root
221
- $root = null;
222
-
223
- if ( is_string( $in ) ) {
224
- $root = $in;
225
- } elseif ( is_array( $in ) and isset( $in['root'] ) ) {
226
- if ( $force or ! isset( $in['files'] ) ) {
227
- // If we are forcing a recompile or if for some reason the
228
- // structure does not contain any file information we should
229
- // specify the root to trigger a rebuild.
230
- $root = $in['root'];
231
- } elseif ( isset( $in['files'] ) and is_array( $in['files'] ) ) {
232
- foreach ( $in['files'] as $fname => $ftime ) {
233
- if ( !file_exists( $fname ) or filemtime( $fname ) > $ftime ) {
234
- // One of the files we knew about previously has changed
235
- // so we should look at our incoming root again.
236
- $root = $in['root'];
237
- break;
238
- }
239
- }
240
- }
241
- } else {
242
- // TODO: Throw an exception? We got neither a string nor something
243
- // that looks like a compatible lessphp cache structure.
244
- return null;
245
- }
246
-
247
- if ( $root !== null ) {
248
- // If we have a root value which means we should rebuild.
249
- $out = array();
250
- $out['root'] = $root;
251
- $out['compiled'] = $this->compileFile($root);
252
- $out['files'] = $this->allParsedFiles();
253
- $out['updated'] = time();
254
- return $out;
255
- } else {
256
- // No changes, pass back the structure
257
- // we were given initially.
258
- return $in;
259
- }
260
- }
261
-
262
- public function ccompile( $in, $out, $less = null ) {
263
- if ( $less === null ) {
264
- $less = new self;
265
- }
266
- return $less->checkedCompile( $in, $out );
267
- }
268
-
269
- public static function cexecute( $in, $force = false, $less = null ) {
270
- if ( $less === null ) {
271
- $less = new self;
272
- }
273
- return $less->cachedCompile($in, $force);
274
- }
275
-
276
- public function allParsedFiles() {
277
- return $this->allParsedFiles;
278
- }
279
-
280
- protected function addParsedFile( $file ) {
281
- $this->allParsedFiles[Less_Parser::AbsPath( $file )] = filemtime( $file );
282
- }
283
- }
1
+ <?php
2
+ /**
3
+ * This file provides the part of lessphp API (https://github.com/leafo/lessphp)
4
+ * to be a drop-in replacement for following products:
5
+ * - Drupal 7, by the less module v3.0+ (https://drupal.org/project/less)
6
+ * - Symfony 2
7
+ *
8
+ * @SiteOrigin: We originally used leafo/lessphp (https://github.com/leafo/lessphp), until we found it wasn't
9
+ * maintained and missed some newer LESS features. We then migrated to a more recent and maintained repo
10
+ * (https://github.com/oyejorge/less.php) simply replacing leafo's lessc.inc.php with the one from oyejorge. This
11
+ * worked well until users started running PHP 7 compatibility checkers which found some issues, so now we have our own
12
+ * fork here: https://github.com/siteorigin/less.php We have fixed the PHP 7 compatibility issues and will only make
13
+ * more changes if there are severe issues.
14
+ */
15
+
16
+ // Register autoloader for non-composer installations
17
+ if ( !class_exists( 'Less_Parser' ) ) {
18
+ require_once dirname( __FILE__ ) . '/lib/Less/Autoloader.php';
19
+ Less_Autoloader::register();
20
+ }
21
+
22
+ class SiteOrigin_LessC {
23
+
24
+ static public $VERSION = Less_Version::less_version;
25
+
26
+ public $importDir = '';
27
+ protected $allParsedFiles = array();
28
+ protected $libFunctions = array();
29
+ protected $registeredVars = array();
30
+ private $formatterName;
31
+ private $options = array();
32
+
33
+ public function __construct( $lessc=null, $sourceName=null ) {}
34
+
35
+ public function setImportDir( $dirs ) {
36
+ $this->importDir = (array)$dirs;
37
+ }
38
+
39
+ public function addImportDir( $dir ) {
40
+ $this->importDir = (array)$this->importDir;
41
+ $this->importDir[] = $dir;
42
+ }
43
+
44
+ public function setFormatter( $name ) {
45
+ $this->formatterName = $name;
46
+ }
47
+
48
+ public function setPreserveComments( $preserve ) {}
49
+
50
+ public function registerFunction( $name, $func ) {
51
+ $this->libFunctions[$name] = $func;
52
+ }
53
+
54
+ public function unregisterFunction( $name ) {
55
+ unset( $this->libFunctions[$name] );
56
+ }
57
+
58
+ public function setVariables( $variables ){
59
+ foreach ( $variables as $name => $value ) {
60
+ $this->setVariable( $name, $value );
61
+ }
62
+ }
63
+
64
+ public function setVariable( $name, $value ) {
65
+ $this->registeredVars[$name] = $value;
66
+ }
67
+
68
+ public function unsetVariable( $name ) {
69
+ unset( $this->registeredVars[$name] );
70
+ }
71
+
72
+ public function setOptions( $options ) {
73
+ foreach ( $options as $name => $value ) {
74
+ $this->setOption( $name, $value);
75
+ }
76
+ }
77
+
78
+ public function setOption( $name, $value ) {
79
+ $this->options[$name] = $value;
80
+ }
81
+
82
+ public function parse( $buffer, $presets = array() ) {
83
+
84
+ $this->setVariables( $presets );
85
+
86
+ $parser = new Less_Parser( $this->getOptions() );
87
+ $parser->setImportDirs( $this->getImportDirs() );
88
+ foreach ( $this->libFunctions as $name => $func ) {
89
+ $parser->registerFunction( $name, $func );
90
+ }
91
+ $parser->parse($buffer);
92
+ if ( count( $this->registeredVars ) ) {
93
+ $parser->ModifyVars( $this->registeredVars );
94
+ }
95
+
96
+ return $parser->getCss();
97
+ }
98
+
99
+ protected function getOptions() {
100
+ $options = array( 'relativeUrls'=>false );
101
+ switch( $this->formatterName ) {
102
+ case 'compressed':
103
+ $options['compress'] = true;
104
+ break;
105
+ }
106
+ if (is_array($this->options))
107
+ {
108
+ $options = array_merge($options, $this->options);
109
+ }
110
+ return $options;
111
+ }
112
+
113
+ protected function getImportDirs() {
114
+ $dirs_ = (array)$this->importDir;
115
+ $dirs = array();
116
+ foreach ( $dirs_ as $dir ) {
117
+ $dirs[$dir] = '';
118
+ }
119
+ return $dirs;
120
+ }
121
+
122
+ public function compile( $string, $name = null ) {
123
+
124
+ $oldImport = $this->importDir;
125
+ $this->importDir = (array)$this->importDir;
126
+
127
+ $this->allParsedFiles = array();
128
+
129
+ $parser = new Less_Parser( $this->getOptions() );
130
+ $parser->SetImportDirs( $this->getImportDirs() );
131
+ if ( count( $this->registeredVars ) ) {
132
+ $parser->ModifyVars( $this->registeredVars );
133
+ }
134
+ foreach ( $this->libFunctions as $name => $func ) {
135
+ $parser->registerFunction( $name, $func );
136
+ }
137
+ $parser->parse( $string );
138
+ $out = $parser->getCss();
139
+
140
+ $parsed = Less_Parser::AllParsedFiles();
141
+ foreach ( $parsed as $file ) {
142
+ $this->addParsedFile( $file );
143
+ }
144
+
145
+ $this->importDir = $oldImport;
146
+
147
+ return $out;
148
+ }
149
+
150
+ public function compileFile( $fname, $outFname = null ) {
151
+ if ( !is_readable( $fname ) ) {
152
+ throw new Exception( 'load error: failed to find '.$fname );
153
+ }
154
+
155
+ $pi = pathinfo( $fname );
156
+
157
+ $oldImport = $this->importDir;
158
+
159
+ $this->importDir = (array)$this->importDir;
160
+ $this->importDir[] = Less_Parser::AbsPath( $pi['dirname'] ).'/';
161
+
162
+ $this->allParsedFiles = array();
163
+ $this->addParsedFile( $fname );
164
+
165
+ $parser = new Less_Parser( $this->getOptions() );
166
+ $parser->SetImportDirs( $this->getImportDirs() );
167
+ if ( count( $this->registeredVars ) ) {
168
+ $parser->ModifyVars( $this->registeredVars );
169
+ }
170
+ foreach ( $this->libFunctions as $name => $func ) {
171
+ $parser->registerFunction( $name, $func );
172
+ }
173
+ $parser->parseFile( $fname );
174
+ $out = $parser->getCss();
175
+
176
+ $parsed = Less_Parser::AllParsedFiles();
177
+ foreach ( $parsed as $file ) {
178
+ $this->addParsedFile( $file );
179
+ }
180
+
181
+ $this->importDir = $oldImport;
182
+
183
+ if ( $outFname !== null ) {
184
+ return file_put_contents( $outFname, $out );
185
+ }
186
+
187
+ return $out;
188
+ }
189
+
190
+ public function checkedCompile( $in, $out ) {
191
+ if ( !is_file( $out ) || filemtime( $in ) > filemtime( $out ) ) {
192
+ $this->compileFile($in, $out);
193
+ return true;
194
+ }
195
+ return false;
196
+ }
197
+
198
+
199
+ /**
200
+ * Execute lessphp on a .less file or a lessphp cache structure
201
+ *
202
+ * The lessphp cache structure contains information about a specific
203
+ * less file having been parsed. It can be used as a hint for future
204
+ * calls to determine whether or not a rebuild is required.
205
+ *
206
+ * The cache structure contains two important keys that may be used
207
+ * externally:
208
+ *
209
+ * compiled: The final compiled CSS
210
+ * updated: The time (in seconds) the CSS was last compiled
211
+ *
212
+ * The cache structure is a plain-ol' PHP associative array and can
213
+ * be serialized and unserialized without a hitch.
214
+ *
215
+ * @param mixed $in Input
216
+ * @param bool $force Force rebuild?
217
+ * @return array lessphp cache structure
218
+ */
219
+ public function cachedCompile( $in, $force = false ) {
220
+ // assume no root
221
+ $root = null;
222
+
223
+ if ( is_string( $in ) ) {
224
+ $root = $in;
225
+ } elseif ( is_array( $in ) and isset( $in['root'] ) ) {
226
+ if ( $force or ! isset( $in['files'] ) ) {
227
+ // If we are forcing a recompile or if for some reason the
228
+ // structure does not contain any file information we should
229
+ // specify the root to trigger a rebuild.
230
+ $root = $in['root'];
231
+ } elseif ( isset( $in['files'] ) and is_array( $in['files'] ) ) {
232
+ foreach ( $in['files'] as $fname => $ftime ) {
233
+ if ( !file_exists( $fname ) or filemtime( $fname ) > $ftime ) {
234
+ // One of the files we knew about previously has changed
235
+ // so we should look at our incoming root again.
236
+ $root = $in['root'];
237
+ break;
238
+ }
239
+ }
240
+ }
241
+ } else {
242
+ // TODO: Throw an exception? We got neither a string nor something
243
+ // that looks like a compatible lessphp cache structure.
244
+ return null;
245
+ }
246
+
247
+ if ( $root !== null ) {
248
+ // If we have a root value which means we should rebuild.
249
+ $out = array();
250
+ $out['root'] = $root;
251
+ $out['compiled'] = $this->compileFile($root);
252
+ $out['files'] = $this->allParsedFiles();
253
+ $out['updated'] = time();
254
+ return $out;
255
+ } else {
256
+ // No changes, pass back the structure
257
+ // we were given initially.
258
+ return $in;
259
+ }
260
+ }
261
+
262
+ public function ccompile( $in, $out, $less = null ) {
263
+ if ( $less === null ) {
264
+ $less = new self;
265
+ }
266
+ return $less->checkedCompile( $in, $out );
267
+ }
268
+
269
+ public static function cexecute( $in, $force = false, $less = null ) {
270
+ if ( $less === null ) {
271
+ $less = new self;
272
+ }
273
+ return $less->cachedCompile($in, $force);
274
+ }
275
+
276
+ public function allParsedFiles() {
277
+ return $this->allParsedFiles;
278
+ }
279
+
280
+ protected function addParsedFile( $file ) {
281
+ $this->allParsedFiles[Less_Parser::AbsPath( $file )] = filemtime( $file );
282
+ }
283
+ }
base/inc/widgets/base-slider.class.php CHANGED
@@ -172,18 +172,18 @@ abstract class SiteOrigin_Widget_Base_Slider extends SiteOrigin_Widget {
172
  ?>
173
  <ol class="sow-slider-pagination">
174
  <?php foreach($frames as $i => $frame) : ?>
175
- <li><a href="#" data-goto="<?php echo $i ?>"><?php echo $i+1 ?></a></li>
176
  <?php endforeach; ?>
177
  </ol>
178
 
179
  <div class="sow-slide-nav sow-slide-nav-next">
180
- <a href="#" data-goto="next" data-action="next">
181
  <em class="sow-sld-icon-<?php echo sanitize_html_class( $controls['nav_style'] ) ?>-right"></em>
182
  </a>
183
  </div>
184
 
185
  <div class="sow-slide-nav sow-slide-nav-prev">
186
- <a href="#" data-goto="previous" data-action="prev">
187
  <em class="sow-sld-icon-<?php echo sanitize_html_class( $controls['nav_style'] ) ?>-left"></em>
188
  </a>
189
  </div>
172
  ?>
173
  <ol class="sow-slider-pagination">
174
  <?php foreach($frames as $i => $frame) : ?>
175
+ <li><a href="#" data-goto="<?php echo $i ?>" aria-label="<?php printf( __( 'display slide %s', 'so-widgets-bundle' ), $i+1 ) ?>"><?php echo $i+1 ?></a></li>
176
  <?php endforeach; ?>
177
  </ol>
178
 
179
  <div class="sow-slide-nav sow-slide-nav-next">
180
+ <a href="#" data-goto="next" aria-label="<?php _e( 'next slide', 'so-widgets-bundle' ) ?>" data-action="next">
181
  <em class="sow-sld-icon-<?php echo sanitize_html_class( $controls['nav_style'] ) ?>-right"></em>
182
  </a>
183
  </div>
184
 
185
  <div class="sow-slide-nav sow-slide-nav-prev">
186
+ <a href="#" data-goto="previous" aria-label="<?php _e( 'previous slide', 'so-widgets-bundle' ) ?>" data-action="prev">
187
  <em class="sow-sld-icon-<?php echo sanitize_html_class( $controls['nav_style'] ) ?>-left"></em>
188
  </a>
189
  </div>
base/js/admin.js CHANGED
@@ -449,12 +449,14 @@ var sowbForms = window.sowbForms || {};
449
  };
450
 
451
  $fields.filter('[data-state-emitter]').each(function () {
452
-
 
 
453
  // Listen for any change events on an emitter field
454
- $(this).find('.siteorigin-widget-input').on('keyup change', stateEmitterChangeHandler);
455
 
456
  // Trigger initial state emitter changes
457
- $(this).find('.siteorigin-widget-input').each(function () {
458
  var $$ = $(this);
459
  if ($$.is(':radio')) {
460
  // Only checked radio inputs must have change events
449
  };
450
 
451
  $fields.filter('[data-state-emitter]').each(function () {
452
+
453
+ var $input = $( this ).find( '.siteorigin-widget-input' );
454
+
455
  // Listen for any change events on an emitter field
456
+ $input.on('keyup change', stateEmitterChangeHandler);
457
 
458
  // Trigger initial state emitter changes
459
+ $input.each(function () {
460
  var $$ = $(this);
461
  if ($$.is(':radio')) {
462
  // Only checked radio inputs must have change events
base/js/admin.min.js CHANGED
@@ -1 +1 @@
1
- var sowbForms=window.sowbForms||{};!function(e){e.fn.sowSetupForm=function(){return e(this).each(function(i,t){var r,n=e(t),a=!0,s=e("body"),o=n.find("input[name]");if(o.length&&-1!==o.attr("name").indexOf("__i__"))return this;if(n.is(".siteorigin-widget-form-main")){if(!0===n.data("sow-form-setup"))return!0;if(s.hasClass("widgets-php")&&!n.is(":visible")&&0===n.closest(".panel-dialog").length)return!0;n.on("sowstatechange",function(i,t,r){n.find("[data-state-handler]").each(function(){var i=e(this),n=e.extend({},i.data("state-handler"),a?i.data("state-handler-initial"):{});if(0===Object.keys(n).length)return!0;var s,o,d,l,g,f,c={},p=sowbForms.getContainerFieldId(i,"repeater",".siteorigin-widget-field-repeater-item");if(!1!==p){var u={};for(var m in n)u[m.replace("{$repeater}",p)]=n[m];n=u}var w=sowbForms.getContainerFieldId(i,"widget",".siteorigin-widget-widget");if(!1!==w){var v={};for(var h in n){var b=h.match(/_else\[(.*)\]|(.*)\[(.*)\]/),y="";y=b&&b.length&&void 0===b[1]?b[2]+"_"+w+"["+b[3]+"]":"_else["+b[1]+"_"+w+"]",v[y]=n[h]}n=v}for(var F in n)if(g=!1,null!==(s=F.match(/^([a-zA-Z0-9_-]+)(\[([a-zA-Z0-9_\-,]+)\])?(\[\])?$/))){if(o={group:"default",name:"",multi:!1},void 0!==s[2]?(o.group=s[1],o.name=s[3]):o.name=s[0],o.multi=void 0!==s[4],"_else"===o.group)o.group=o.name,o.name="",g=o.group===t&&void 0===c[o.group];else{f=o.name.split(",").map(function(e){return e.trim()});for(var k=0;k<f.length&&!(g=o.group===t&&f[k]===r);k++);}if(g){d=n[F],o.multi||(d=[d]);for(var k=0;k<d.length;k++)l=void 0!==d[k][1]&&Boolean(d[k][1])?i.find(d[k][1]):i,l[d[k][0]].apply(l,void 0!==d[k][2]?d[k][2]:[]);c[o.group]=!0}}})}),n.sowSetupPreview(),r=n;var d=n.find(".siteorigin-widget-teaser");d.find(".dashicons-dismiss").click(function(){var i=e(this);e.get(i.data("dismiss-url")),d.slideUp("normal",function(){d.remove()})});var l=n.find("> .siteorigin-widgets-form-id").val(),g=n.find("> .siteorigin-widgets-form-timestamp"),f=parseInt(g.val()||0),c=JSON.parse(sessionStorage.getItem(l));if(c)if(c._sow_form_timestamp>f){var p=e('<div class="siteorigin-widget-form-notification"><span>'+soWidgets.backup.newerVersion+'</span><a class="button button-small so-backup-restore">'+soWidgets.backup.restore+'</a><a class="button button-small so-backup-dismiss">'+soWidgets.backup.dismiss+"</a><div><small>"+soWidgets.backup.replaceWarning+"</small></div></div>");n.prepend(p),p.find(".so-backup-restore").click(function(){sowbForms.setWidgetFormValues(r,c),p.slideUp("fast",function(){p.remove()})}),p.find(".so-backup-dismiss").click(function(){p.slideUp("fast",function(){sessionStorage.removeItem(l),p.remove()})})}else sessionStorage.removeItem(l);n.change(function(){g.val((new Date).getTime());var e=sowbForms.getWidgetFormValues(n);sessionStorage.setItem(l,JSON.stringify(e))})}else r=n.closest(".siteorigin-widget-form-main");r.find("> .siteorigin-widgets-form-id").val();var u=n.find("> .siteorigin-widget-field");u.find("> .siteorigin-widget-section").sowSetupForm();var m=u.find("> .siteorigin-widget-widget");m.find("> .siteorigin-widget-section").sowSetupForm(),m.filter(":not(:has(> .siteorigin-widget-section))").sowSetupForm(),u.find(".siteorigin-widget-input").each(function(i,t){null===e(t).data("original-name")&&e(t).data("original-name",e(t).attr("name"))}),u.find("> .siteorigin-widget-field-repeater").sowSetupRepeater(),n.find(".siteorigin-widget-field-repeater-item").sowSetupRepeaterItems(),u.find("> .siteorigin-widget-input-color").each(function(){var i=e(this),t={change:function(i,t){setTimeout(function(){e(i.target).trigger("change")},100)}};i.data("defaultColor")&&(t.defaultColor=i.data("defaultColor")),i.wpColorPicker(t)});var w=function(){e(this).toggleClass("siteorigin-widget-section-visible"),e(this).parent().find("> .siteorigin-widget-section, > .siteorigin-widget-widget > .siteorigin-widget-section").slideToggle("fast",function(){if(e(window).resize(),e(this).find("> .siteorigin-widget-field-container-state").val(e(this).is(":visible")?"open":"closed"),e(this).is(":visible")){e(this).find("> .siteorigin-widget-field").trigger("sowsetupformfield")}})};u.filter(".siteorigin-widget-field-type-widget, .siteorigin-widget-field-type-section").find("> label").click(w),u.filter(".siteorigin-widget-field-type-posts").find(".posts-container-label-wrapper").click(w),u.filter(".siteorigin-widget-field-type-slider").each(function(){var i=e(this),t=i.find('input[type="number"]'),r=i.find(".siteorigin-widget-value-slider");r.slider({max:parseFloat(t.attr("max")),min:parseFloat(t.attr("min")),step:parseFloat(t.attr("step")),value:parseFloat(t.val()),slide:function(e,i){t.val(parseFloat(i.value)),t.trigger("change")},change:function(e,t){i.find(".siteorigin-widget-slider-value").html(t.value)}}),t.change(function(e,i){i&&i.silent||r.slider("value",parseFloat(t.val()))})}),u.filter(".siteorigin-widget-field-type-link").each(function(){var i=e(this),t=null,r=function(){null!==t&&t.abort();var r=i.find(".content-text-search"),n=r.val(),a=r.data("postTypes"),s=i.find("ul.posts").empty().addClass("loading");e.get(soWidgets.ajaxurl,{action:"so_widgets_search_posts",query:n,postTypes:a},function(i){for(var t=0;t<i.length;t++)""===i[t].label&&(i[t].label="&nbsp;"),s.append(e("<li>").addClass("post").html(i[t].label+"<span>("+i[t].type+")</span>").data(i[t]));s.removeClass("loading")})};i.find(".select-content-button, .button-close").click(function(t){t.preventDefault(),e(this).blur();var n=i.find(".existing-content-selector");n.toggle(),n.is(":visible")&&0===n.find("ul.posts li").length&&r()}),i.on("click",".posts li",function(t){t.preventDefault();var r=e(this);i.find("input.siteorigin-widget-input").val("post: "+r.data("value")),i.find(".existing-content-selector").toggle()});var n=null;i.find(".content-text-search").keyup(function(){null!==n&&clearTimeout(n),n=setTimeout(function(){r()},500)})}),void 0!==jQuery.fn.soPanelsSetupBuilderWidget&&u.filter(".siteorigin-widget-field-type-builder").each(function(){e(this).find("> .siteorigin-page-builder-field").each(function(){var i=e(this);i.soPanelsSetupBuilderWidget({builderType:i.data("type")})})});var v=function(){var i=e(this),t=i.closest("[data-state-emitter]").data("state-emitter");if(void 0!==t){var n={default:""};void 0===t.length&&(t=[t]);for(var a=0;a<t.length;a++)n=function(t,r){if(void 0===sowEmitters[t.callback]||"_"===t.callback.substr(0,1))return r;var n=sowbForms.getContainerFieldId(i,"repeater",".siteorigin-widget-field-repeater-item");!1!==n&&(t.args=t.args.map(function(e){return e.replace("{$repeater}",n)}));var a=sowbForms.getContainerFieldId(i,"widget",".siteorigin-widget-widget");!1===a||t.hasOwnProperty("widgetFieldId")||(t.widgetFieldId=a,t.args=t.args.map(function(e){return e+"_"+a}));var s=i.is('[type="checkbox"]')?i.is(":checked"):i.val();return e.extend(r,sowEmitters[t.callback](s,t.args))}(t[a],n);var s=r.data("states");void 0===s&&(s={default:""});for(var o in n)void 0!==s[o]&&n[o]===s[o]||(s[o]=n[o],r.trigger("sowstatechange",[o,n[o]]));r.data("states",s)}};u.filter("[data-state-emitter]").each(function(){e(this).find(".siteorigin-widget-input").on("keyup change",v),e(this).find(".siteorigin-widget-input").each(function(){var i=e(this);i.is(":radio")?i.is(":checked")&&v.call(i[0]):v.call(i[0])})}),n.trigger("sowsetupform",u).data("sow-form-setup",!0),u.trigger("sowsetupformfield"),n.find(".siteorigin-widget-field-repeater-item").trigger("updateFieldPositions"),(s.hasClass("wp-customizer")||s.hasClass("widgets-php"))&&n.closest(".ui-sortable").on("sortstop",function(e,i){i.item.find(".siteorigin-widget-form").find("> .siteorigin-widget-field").trigger("sowsetupformfield")}),a=!1})},e.fn.sowSetupPreview=function(){var i=e(this);i.siblings(".siteorigin-widget-preview").find("> a").click(function(t){t.preventDefault();var r=sowbForms.getWidgetFormValues(i),n=e(e("#so-widgets-bundle-tpl-preview-dialog").html().trim()).appendTo("body");n.find('input[name="data"]').val(JSON.stringify(r)),n.find('input[name="class"]').val(i.data("class")),n.find("iframe").on("load",function(){e(this).css("visibility","visible")}),n.find("form").submit(),n.find(".close").click(function(){n.remove()})})},e.fn.sowSetupRepeater=function(){return e(this).each(function(i,t){var r=e(t),n=r.find(".siteorigin-widget-field-repeater-items"),a=r.data("repeater-name");n.bind("updateFieldPositions",function(){var i=e(this),t=i.find("> .siteorigin-widget-field-repeater-item");t.each(function(i,t){e(t).find(".siteorigin-widget-input").each(function(t,r){var n=e(r).data("repeater-positions");void 0===n&&(n={}),n[a]=i,e(r).data("repeater-positions",n)})}),i.find(".siteorigin-widget-input").each(function(i,t){var r=e(t),n=r.data("repeater-positions");if(void 0!==n){var a=r.attr("data-original-name");if(a||(r.attr("data-original-name",r.attr("name")),a=r.attr("name")),!a)return;if(n)for(var s in n)a=a.replace("#"+s+"#",n[s]);r.attr("name",a)}}),i.data("initialSetup")||(i.find(".siteorigin-widget-input").each(function(i,t){var r=e(t);r.prop("checked",r.prop("defaultChecked"))}),i.data("initialSetup",!0));var n=r.data("scroll-count")?parseInt(r.data("scroll-count")):0;if(n>0&&t.length>n){var s=t.first().outerHeight();i.css("max-height",s*n).css("overflow","auto")}else i.css("max-height","").css("overflow","")}),n.sortable({handle:".siteorigin-widget-field-repeater-item-top",items:"> .siteorigin-widget-field-repeater-item",update:function(){n.find('input[type="radio"].siteorigin-widget-input').attr("name",""),n.trigger("updateFieldPositions"),r.trigger("change")},sortstop:function(i,t){if(t.item.is(".siteorigin-widget-field-repeater-item"))t.item.find("> .siteorigin-widget-field-repeater-item-form").each(function(){e(this).find("> .siteorigin-widget-field").trigger("sowsetupformfield")});else{t.item.find(".siteorigin-widget-form").find("> .siteorigin-widget-field").trigger("sowsetupformfield")}r.trigger("change")}}),n.trigger("updateFieldPositions"),r.find("> .siteorigin-widget-field-repeater-add").disableSelection().click(function(i){i.preventDefault(),r.closest(".siteorigin-widget-field-repeater").sowAddRepeaterItem().find("> .siteorigin-widget-field-repeater-items").slideDown("fast",function(){e(window).resize()})}),r.find("> .siteorigin-widget-field-repeater-top > .siteorigin-widget-field-repeater-expand").click(function(i){i.preventDefault(),r.closest(".siteorigin-widget-field-repeater").find("> .siteorigin-widget-field-repeateritems-").slideToggle("fast",function(){e(window).resize()})})})},e.fn.sowAddRepeaterItem=function(){return e(this).each(function(i,t){var r=e(t),n=r.find("> .siteorigin-widget-field-repeater-items").children().length+1,a=e("<div>"+r.find("> .siteorigin-widget-field-repeater-item-html").html()+"</div>");a.find(".siteorigin-widget-input[data-name]").each(function(){var i=e(this);0===i.closest(".siteorigin-widget-field-repeater-item-html").length&&i.attr("name",e(this).data("name"))});var s=a.html().replace(/_id_/g,n),o=void 0!==r.attr("readonly"),d=e('<div class="siteorigin-widget-field-repeater-item ui-draggable" />').append(e('<div class="siteorigin-widget-field-repeater-item-top" />').append(e('<div class="siteorigin-widget-field-expand" />')).append(o?"":e('<div class="siteorigin-widget-field-copy" />')).append(o?"":e('<div class="siteorigin-widget-field-remove" />')).append(e("<h4 />").html(r.data("item-name")))).append(e('<div class="siteorigin-widget-field-repeater-item-form" />').html(s));r.find("> .siteorigin-widget-field-repeater-items").append(d).sortable("refresh").trigger("updateFieldPositions"),d.sowSetupRepeaterItems(),d.hide().slideDown("fast",function(){e(window).resize()}),r.trigger("change")})},e.fn.sowRemoveRepeaterItem=function(){return e(this).each(function(i,t){var r=e(this).closest(".siteorigin-widget-field-repeater-items");e(this).remove(),r.sortable("refresh").trigger("updateFieldPositions"),e(t).trigger("change")})},e.fn.sowSetupRepeaterItems=function(){return e(this).each(function(i,t){var r=e(t);if(void 0===r.data("sowrepeater-actions-setup")){var n=r.closest(".siteorigin-widget-field-repeater"),a=r.find("> .siteorigin-widget-field-repeater-item-top"),s=n.data("item-label");if(s&&s.selector){var o=function(){var e=s.hasOwnProperty("valueMethod")&&s.valueMethod?s.valueMethod:"val",i=r.find(s.selector)[e]();i&&(i.length>80&&(i=i.substr(0,79)+"..."),a.find("h4").text(i))};o();var d=s.hasOwnProperty("updateEvent")&&s.updateEvent?s.updateEvent:"change";r.bind(d,o)}a.click(function(i){"siteorigin-widget-field-remove"!==i.target.className&&"siteorigin-widget-field-copy"!==i.target.className&&(i.preventDefault(),e(this).closest(".siteorigin-widget-field-repeater-item").find(".siteorigin-widget-field-repeater-item-form").eq(0).slideToggle("fast",function(){if(e(window).resize(),e(this).is(":visible")){e(this).trigger("slideToggleOpenComplete");e(this).find("> .siteorigin-widget-field").trigger("sowsetupformfield")}else e(this).trigger("slideToggleCloseComplete")}))}),a.find(".siteorigin-widget-field-remove").click(function(i,t){i.preventDefault();var n=e(this).closest(".siteorigin-widget-field-repeater-items"),a=e(this).closest(".siteorigin-widget-field-repeater-item"),s=function(){a.remove(),n.sortable("refresh").trigger("updateFieldPositions"),e(window).resize()};t&&t.silent?s():confirm(soWidgets.sure)&&a.slideUp("fast",s),r.trigger("change")}),a.find(".siteorigin-widget-field-copy").click(function(i){i.preventDefault();var t=e(this).closest(".siteorigin-widget-form-main"),n=e(this).closest(".siteorigin-widget-field-repeater-item"),a=n.clone(),s=n.closest(".siteorigin-widget-field-repeater-items"),o=s.children().length,d={};a.find("*[name]").each(function(){var i=e(this),s=i.attr("id"),l=i.attr("name");if(i.is("textarea")&&i.parent().is(".wp-editor-container")&&"undefined"!=typeof tinymce){i.parent().empty().append(i),i.css("display","");var g=tinymce.get(s);g&&i.val(g.getContent())}else if(i.is(".wp-color-picker")){var f=i.closest(".wp-picker-container"),c=i.closest(".siteorigin-widget-field");f.remove(),c.append(i.remove())}else{var p=s?n.find("#"+s):n.find('[name="'+l+'"]');p.length&&null!=p.val()&&i.val(p.val())}if(s){var u,m,w;if(i.is('[type="radio"]')){m=s.replace(/-\d+-\d+$/,"");var v=s.replace(/-\d+$/,"");if(!d[m]){var h={};d[m]=t.find(".siteorigin-widget-input[id^="+m+"]").not("[id*=_id_]").filter(function(i,t){var r=e(t).attr("name");return!h[r]&&(h[r]=!0,!0)}).length+1}var b=m+"-"+d[m];w=b+s.match(/-\d+$/)[0],a.find("label[for="+v+"]").attr("for",b)}else u=new RegExp("-\\d+$"),m=s.replace(u,""),d[m]||(d[m]=t.find(".siteorigin-widget-input[id^="+m+"]").not("[id*=_id_]").length+1),w=m+"-"+d[m]++;i.attr("id",w),a.find("label[for="+s+"]").attr("for",w),a.find("[id*="+s+"]").each(function(){var i=e(this).attr("id"),t=i.replace(s,w);e(this).attr("id",t)}),"undefined"!=typeof tinymce&&tinymce.get(w)&&tinymce.get(w).remove()}var y=n.parents(".siteorigin-widget-field-repeater").length,F=e("body");(F.hasClass("wp-customizer")||F.hasClass("widgets-php"))&&0===r.closest(".panel-dialog").length&&(y+=1);var k=l.replace(new RegExp("((?:.*?\\[\\d+\\]){"+(y-1).toString()+"})?(.*?\\[)\\d+(\\])"),"$1$2"+o.toString()+"$3");i.attr("name",k),i.data("original-name",k)}),s.append(a).sortable("refresh").trigger("updateFieldPositions"),a.sowSetupRepeaterItems(),a.hide().slideDown("fast",function(){e(window).resize()}),r.trigger("change")}),r.find("> .siteorigin-widget-field-repeater-item-form").sowSetupForm(),r.data("sowrepeater-actions-setup",!0)}})},sowbForms.getContainer