SiteOrigin Widgets Bundle - Version 1.6.3

Version Description

  • 19 July 2016 =
  • Added image search functionality to media field.
  • Moved actions into their own file.
  • Allow widgets to provide their own LESS/HTML.
  • Added very simple code field.
  • Multiple widgets can have the same class. Allowing widget functionality to come from configuration.
  • Various tweaks for upcoming Widgets Builder plugin.
Download this release

Release Info

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

Code changes from version 1.6.2 to 1.6.3

base/base.php CHANGED
@@ -8,6 +8,7 @@ include plugin_dir_path(__FILE__).'inc/meta-box-manager.php';
8
include plugin_dir_path(__FILE__).'inc/post-selector.php';
9
include plugin_dir_path(__FILE__).'inc/string-utils.php';
10
include plugin_dir_path(__FILE__).'inc/attachments.php';
11
12
/**
13
* @param $css
@@ -114,97 +115,6 @@ function siteorigin_widget_get_font($font_value) {
114
return $font;
115
}
116
117
- /**
118
- * Action for displaying the widget preview.
119
- */
120
- function siteorigin_widget_preview_widget_action(){
121
- if( !class_exists($_POST['class']) ) exit();
122
- if ( empty( $_REQUEST['_widgets_nonce'] ) || !wp_verify_nonce( $_REQUEST['_widgets_nonce'], 'widgets_action' ) ) return;
123
- $widget = new $_POST['class'];
124
- if(!is_a($widget, 'SiteOrigin_Widget')) exit();
125
-
126
- $instance = json_decode( stripslashes_deep($_POST['data']), true);
127
- /* @var $widget SiteOrigin_Widget */
128
- $instance = $widget->update( $instance, $instance );
129
- $instance['is_preview'] = true;
130
-
131
- // The theme stylesheet will change how the button looks
132
- wp_enqueue_style( 'theme-css', get_stylesheet_uri(), array(), rand(0,65536) );
133
- wp_enqueue_style( 'so-widget-preview', plugin_dir_url(__FILE__).'/css/preview.css', array(), rand(0,65536) );
134
-
135
- ob_start();
136
- $widget->widget(array(
137
- 'before_widget' => '',
138
- 'after_widget' => '',
139
- 'before_title' => '',
140
- 'after_title' => '',
141
- ), $instance);
142
- $widget_html = ob_get_clean();
143
-
144
- // Print all the scripts and styles
145
- ?>
146
- <html>
147
- <head>
148
- <title><?php _e('Widget Preview', 'so-widgets-bundle') ?></title>
149
- <?php
150
- wp_print_scripts();
151
- wp_print_styles();
152
- siteorigin_widget_print_styles();
153
- ?>
154
- </head>
155
- <body>
156
- <?php // A lot of themes use entry-content as their main content wrapper ?>
157
- <div class="entry-content">
158
- <?php echo $widget_html ?>
159
- </div>
160
- </body>
161
- </html>
162
-
163
- <?php
164
- exit();
165
- }
166
- add_action('wp_ajax_so_widgets_preview', 'siteorigin_widget_preview_widget_action');
167
-
168
- /**
169
- * Action to handle searching
170
- */
171
- function siteorigin_widget_search_posts_action(){
172
- if ( empty( $_REQUEST['_widgets_nonce'] ) || !wp_verify_nonce( $_REQUEST['_widgets_nonce'], 'widgets_action' ) ) return;
173
-
174
- header('content-type: application/json');
175
-
176
- // Get all public post types, besides attachments
177
- $post_types = (array) get_post_types( array(
178
- 'public' => true
179
- ) );
180
- unset($post_types['attachment']);
181
-
182
- $post_types = apply_filters( 'siteorigin_widgets_search_posts_post_types', $post_types );
183
-
184
- global $wpdb;
185
- if( !empty($_GET['query']) ) {
186
- $query = "AND post_title LIKE '%" . esc_sql( $_GET['query'] ) . "%'";
187
- }
188
- else {
189
- $query = '';
190
- }
191
-
192
- $post_types = "'" . implode("', '", array_map( 'esc_sql', $post_types ) ) . "'";
193
-
194
- $results = $wpdb->get_results( "
195
- SELECT ID, post_title, post_type
196
- FROM {$wpdb->posts}
197
- WHERE
198
- post_type IN ( {$post_types} ) AND post_status = 'publish' {$query}
199
- ORDER BY post_modified DESC
200
- LIMIT 20
201
- ", ARRAY_A );
202
-
203
- echo json_encode( apply_filters( 'siteorigin_widgets_search_posts_results', $results ) );
204
- wp_die();
205
- }
206
- add_action('wp_ajax_so_widgets_search_posts', 'siteorigin_widget_search_posts_action');
207
-
208
/**
209
* Compatibility with Page Builder, add the groups and icons.
210
*
8
include plugin_dir_path(__FILE__).'inc/post-selector.php';
9
include plugin_dir_path(__FILE__).'inc/string-utils.php';
10
include plugin_dir_path(__FILE__).'inc/attachments.php';
11
+ include plugin_dir_path(__FILE__).'inc/actions.php';
12
13
/**
14
* @param $css
115
return $font;
116
}
117
118
/**
119
* Compatibility with Page Builder, add the groups and icons.
120
*
base/css/admin.css CHANGED
@@ -30,7 +30,7 @@
30
-ms-user-select: none;
31
user-select: none;
32
}
33
- .siteorigin-widget-form .siteorigin-widget-field .siteorigin-widget-field-description {
34
font-size: 0.9em;
35
margin-top: 0.2em;
36
color: #999;
@@ -53,6 +53,9 @@
53
.siteorigin-widget-form .siteorigin-widget-field input.siteorigin-widget-input-color {
54
width: auto;
55
}
56
.siteorigin-widget-form .siteorigin-widget-field-type-slider .siteorigin-widget-slider-wrapper {
57
margin: 10px 0;
58
border: 1px solid #E0E0E0;
@@ -251,123 +254,6 @@
251
.siteorigin-widget-form .siteorigin-widget-field-repeater .siteorigin-widget-field-repeater .siteorigin-widget-field-repeater-add:hover {
252
background: #edf5f9;
253
}
254
- .siteorigin-widget-form .media-field-wrapper {
255
- position: relative;
256
- display: block;
257
- float: left;
258
- background: #f9f9f9;
259
- background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #f2f2f2), color-stop(1, #f9f9f9));
260
- background: -ms-linear-gradient(bottom, #f2f2f2, #f9f9f9);
261
- background: -moz-linear-gradient(center bottom, #f2f2f2 0%, #f9f9f9 100%);
262
- background: -o-linear-gradient(#f9f9f9, #f2f2f2);
263
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#f2f2f2', GradientType=0);
264
- -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.1);
265
- -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.1);
266
- box-shadow: 0 1px 2px rgba(0,0,0,0.1);
267
- -webkit-border-radius: 3px;
268
- -moz-border-radius: 3px;
269
- border-radius: 3px;
270
- border: 1px solid #bbbbbb;
271
- height: 32px;
272
- }
273
- .siteorigin-widget-form .media-field-wrapper:hover {
274
- background: #ffffff;
275
- background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #f7f7f7), color-stop(1, #ffffff));
276
- background: -ms-linear-gradient(bottom, #f7f7f7, #ffffff);
277
- background: -moz-linear-gradient(center bottom, #f7f7f7 0%, #ffffff 100%);
278
- background: -o-linear-gradient(#ffffff, #f7f7f7);
279
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f7f7f7', GradientType=0);
280
- -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.15);
281
- -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.15);
282
- box-shadow: 0 1px 2px rgba(0,0,0,0.15);
283
- }
284
- .siteorigin-widget-form .media-field-wrapper .current {
285
- -ms-box-sizing: border-box;
286
- -moz-box-sizing: border-box;
287
- -webkit-box-sizing: border-box;
288
- box-sizing: border-box;
289
- float: left;
290
- height: 32px;
291
- padding: 4px;
292
- border-right: 1px solid #bbb;
293
- position: relative;
294
- box-shadow: 1px 0 0 #FFF;
295
- }
296
- .siteorigin-widget-form .media-field-wrapper .current .title {
297
- display: none;
298
- position: absolute;
299
- bottom: 34px;
300
- left: 0;
301
- padding: 4px 12px;
302
- background: #333;
303
- color: #CCC;
304
- font-weight: bold;
305
- width: auto;
306
- white-space: nowrap;
307
- }
308
- .siteorigin-widget-form .media-field-wrapper .current .thumbnail-wrapper {
309
- border: 1px solid #999;
310
- line-height: 0;
311
- box-shadow: 0px 1px 1px #FFF;
312
- width: 22px;
313
- height: 22px;
314
- background: #cfcfcf;
315
- background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #cccccc), color-stop(1, #cfcfcf));
316
- background: -ms-linear-gradient(bottom, #cccccc, #cfcfcf);
317
- background: -moz-linear-gradient(center bottom, #cccccc 0%, #cfcfcf 100%);
318
- background: -o-linear-gradient(#cfcfcf, #cccccc);
319
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cfcfcf', endColorstr='#cccccc', GradientType=0);
320
- box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
321
- }
322
- .siteorigin-widget-form .media-field-wrapper .current .thumbnail-wrapper img {
323
- height: 100%;
324
- width: 100%;
325
- box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
326
- }
327
- .siteorigin-widget-form .media-field-wrapper .media-upload-button {
328
- display: block;
329
- float: left;
330
- color: #666;
331
- text-decoration: none;
332
- text-shadow: 0 1px 0 #FFF;
333
- font-weight: 600;
334
- font-size: 11px;
335
- padding: 7px 8px 7px 6px;
336
- outline: none;
337
- cursor: pointer;
338
- }
339
- .siteorigin-widget-form .media-field-wrapper:hover .media-upload-button {
340
- color: #707070;
341
- }
342
- .siteorigin-widget-form .media-remove-button {
343
- display: block;
344
- text-decoration: none;
345
- float: left;
346
- color: #AAA;
347
- font-size: 11px;
348
- line-height: 1em;
349
- padding: 11px 0 11px 6px;
350
- -webkit-transition: all 0.25s ease;
351
- -moz-transition: all 0.25s ease;
352
- -o-transition: all 0.25s ease;
353
- transition: all 0.25s ease;
354
- position: static;
355
- opacity: 1;
356
- }
357
- .siteorigin-widget-form .media-remove-button.remove-hide {
358
- pointer-events: none;
359
- opacity: 0;
360
- }
361
- .siteorigin-widget-form .media-remove-button:hover {
362
- color: #BC0B0B;
363
- }
364
- .siteorigin-widget-form .media-fallback-external {
365
- float: left;
366
- padding: 4px 8px;
367
- margin-top: 2px !important;
368
- margin-left: 25px !important;
369
- width: 320px !important;
370
- }
371
.siteorigin-widget-form .siteorigin-widget-field-type-widget > label,
372
.siteorigin-widget-form .siteorigin-widget-field-type-section > label {
373
background: #F0F0F0;
@@ -586,7 +472,7 @@
586
-moz-box-shadow: 0 1px 2px rgba(0,0,0,0.25);
587
box-shadow: 0 1px 2px rgba(0,0,0,0.25);
588
}
589
- .siteorigin-widget-form .siteorigin-widget-field-description {
590
clear: both;
591
}
592
.siteorigin-widgets-query-builder .query-builder-content {
@@ -756,7 +642,7 @@
756
display: block;
757
margin: 1em 0;
758
}
759
- .siteorigin-widget-preview-dialog .siteorigin-widgets-preview-modal-overlay {
760
position: fixed;
761
z-index: 100000;
762
top: 0;
@@ -765,8 +651,8 @@
765
bottom: 0;
766
background: rgba(0, 0, 0, 0.7);
767
}
768
- .siteorigin-widget-preview-dialog .so-widget-toolbar,
769
- .siteorigin-widget-preview-dialog .so-widget-iframe {
770
position: fixed;
771
z-index: 500001;
772
-ms-box-sizing: border-box;
@@ -774,7 +660,7 @@
774
-webkit-box-sizing: border-box;
775
box-sizing: border-box;
776
}
777
- .siteorigin-widget-preview-dialog .so-widget-toolbar {
778
left: 30px;
779
right: 30px;
780
top: 30px;
@@ -782,10 +668,10 @@
782
background: #fafafa;
783
border-bottom: 1px solid #D8D8D8;
784
}
785
- .siteorigin-widget-preview-dialog .so-widget-toolbar h3 {
786
margin: 15px 0 15px 20px;
787
}
788
- .siteorigin-widget-preview-dialog .so-widget-toolbar .close {
789
position: absolute;
790
box-sizing: border-box;
791
width: 50px;
@@ -802,13 +688,13 @@
802
border-left: 1px solid #d8d8d8;
803
border-bottom: 1px solid #d8d8d8;
804
}
805
- .siteorigin-widget-preview-dialog .so-widget-toolbar .close:hover {
806
background: #e9e9e9;
807
}
808
- .siteorigin-widget-preview-dialog .so-widget-toolbar .close:hover .so-dialog-icon {
809
color: #333333;
810
}
811
- .siteorigin-widget-preview-dialog .so-widget-toolbar .close .dashicons {
812
position: absolute;
813
top: 50%;
814
left: 50%;
@@ -821,7 +707,7 @@
821
color: #666666;
822
text-align: center;
823
}
824
- .siteorigin-widget-preview-dialog .so-widget-iframe {
825
top: 80px;
826
left: 30px;
827
right: 30px;
@@ -829,12 +715,12 @@
829
background: #FFFFFF url("img/wpspin_light.gif") center center no-repeat;
830
}
831
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
832
- .siteorigin-widget-preview-dialog .so-widget-iframe {
833
background-image: url("img/wpspin_light-2x.gif");
834
background-size: 16px 16px;
835
}
836
}
837
- .siteorigin-widget-preview-dialog .so-widget-iframe iframe {
838
width: 100%;
839
height: 100%;
840
}
30
-ms-user-select: none;
31
user-select: none;
32
}
33
+ .siteorigin-widget-form .siteorigin-widget-field .siteorigin-widget-description {
34
font-size: 0.9em;
35
margin-top: 0.2em;
36
color: #999;
53
.siteorigin-widget-form .siteorigin-widget-field input.siteorigin-widget-input-color {
54
width: auto;
55
}
56
+ .siteorigin-widget-form .siteorigin-widget-field textarea.siteorigin-widget-code-input {
57
+ font-family: "Courier New", Courier, monospace;
58
+ }
59
.siteorigin-widget-form .siteorigin-widget-field-type-slider .siteorigin-widget-slider-wrapper {
60
margin: 10px 0;
61
border: 1px solid #E0E0E0;
254
.siteorigin-widget-form .siteorigin-widget-field-repeater .siteorigin-widget-field-repeater .siteorigin-widget-field-repeater-add:hover {
255
background: #edf5f9;
256
}
257
.siteorigin-widget-form .siteorigin-widget-field-type-widget > label,
258
.siteorigin-widget-form .siteorigin-widget-field-type-section > label {
259
background: #F0F0F0;
472
-moz-box-shadow: 0 1px 2px rgba(0,0,0,0.25);
473
box-shadow: 0 1px 2px rgba(0,0,0,0.25);
474
}
475
+ .siteorigin-widget-form .siteorigin-widget-description {
476
clear: both;
477
}
478
.siteorigin-widgets-query-builder .query-builder-content {
642
display: block;
643
margin: 1em 0;
644
}
645
+ .so-widgets-dialog .so-widgets-dialog-overlay {
646
position: fixed;
647
z-index: 100000;
648
top: 0;
651
bottom: 0;
652
background: rgba(0, 0, 0, 0.7);
653
}
654
+ .so-widgets-dialog .so-widgets-toolbar,
655
+ .so-widgets-dialog .so-widgets-dialog-frame {
656
position: fixed;
657
z-index: 500001;
658
-ms-box-sizing: border-box;
660
-webkit-box-sizing: border-box;
661
box-sizing: border-box;
662
}
663
+ .so-widgets-dialog .so-widgets-toolbar {
664
left: 30px;
665
right: 30px;
666
top: 30px;
668
background: #fafafa;
669
border-bottom: 1px solid #D8D8D8;
670
}
671
+ .so-widgets-dialog .so-widgets-toolbar h3 {
672
margin: 15px 0 15px 20px;
673
}
674
+ .so-widgets-dialog .so-widgets-toolbar .close {
675
position: absolute;
676
box-sizing: border-box;
677
width: 50px;
688
border-left: 1px solid #d8d8d8;
689
border-bottom: 1px solid #d8d8d8;
690
}
691
+ .so-widgets-dialog .so-widgets-toolbar .close:hover {
692
background: #e9e9e9;
693
}
694
+ .so-widgets-dialog .so-widgets-toolbar .close:hover .so-dialog-icon {
695
color: #333333;
696
}
697
+ .so-widgets-dialog .so-widgets-toolbar .close .dashicons {
698
position: absolute;
699
top: 50%;
700
left: 50%;
707
color: #666666;
708
text-align: center;
709
}
710
+ .so-widgets-dialog .so-widgets-dialog-frame {
711
top: 80px;
712
left: 30px;
713
right: 30px;
715
background: #FFFFFF url("img/wpspin_light.gif") center center no-repeat;
716
}
717
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
718
+ .so-widgets-dialog .so-widgets-dialog-frame {
719
background-image: url("img/wpspin_light-2x.gif");
720
background-size: 16px 16px;
721
}
722
}
723
+ .so-widgets-dialog .so-widgets-dialog-frame iframe {
724
width: 100%;
725
height: 100%;
726
}
base/css/preview.css CHANGED
@@ -3,3 +3,6 @@ body {
3
background: #FFFFFF !important;
4
background-image: none !important;
5
}
3
background: #FFFFFF !important;
4
background-image: none !important;
5
}
6
+ h3.widget-title {
7
+ margin-top: 0;
8
+ }
base/inc/actions.php ADDED
@@ -0,0 +1,185 @@
1
+ <?php
2
+
3
+ /**
4
+ * Action for displaying the widget preview.
5
+ */
6
+ function siteorigin_widget_preview_widget_action(){
7
+ if( empty( $_POST['class'] ) ) exit();
8
+ if ( empty( $_REQUEST['_widgets_nonce'] ) || !wp_verify_nonce( $_REQUEST['_widgets_nonce'], 'widgets_action' ) ) return;
9
+
10
+ // Get the widget from the widget factory
11
+ global $wp_widget_factory;
12
+ $widget = ! empty( $wp_widget_factory->widgets[ $_POST['class'] ] ) ? $wp_widget_factory->widgets[ $_POST['class'] ] : false;
13
+
14
+ if( !is_a($widget, 'SiteOrigin_Widget') ) exit();
15
+
16
+ $instance = json_decode( stripslashes_deep($_POST['data']), true);
17
+ /* @var $widget SiteOrigin_Widget */
18
+ $instance = $widget->update( $instance, $instance );
19
+ $instance['is_preview'] = true;
20
+
21
+ // The theme stylesheet will change how the button looks
22
+ wp_enqueue_style( 'theme-css', get_stylesheet_uri(), array(), rand( 0, 65536 ) );
23
+ wp_enqueue_style( 'so-widget-preview', plugin_dir_url( __FILE__ ) . '../css/preview.css', array(), rand( 0,65536 ) );
24
+
25
+ ob_start();
26
+ $widget->widget( array(
27
+ 'before_widget' => '',
28
+ 'after_widget' => '',
29
+ 'before_title' => '<h3 class="widget-title">',
30
+ 'after_title' => '</h3>',
31
+ ), $instance);
32
+ $widget_html = ob_get_clean();
33
+
34
+ // Print all the scripts and styles
35
+ ?>
36
+ <html>
37
+ <head>
38
+ <title><?php _e('Widget Preview', 'so-widgets-bundle') ?></title>
39
+ <?php
40
+ wp_print_scripts();
41
+ wp_print_styles();
42
+ siteorigin_widget_print_styles();
43
+ ?>
44
+ </head>
45
+ <body>
46
+ <?php // A lot of themes use entry-content as their main content wrapper ?>
47
+ <div class="entry-content">
48
+ <?php echo $widget_html ?>
49
+ </div>
50
+ </body>
51
+ </html>
52
+
53
+ <?php
54
+ exit();
55
+ }
56
+ add_action('wp_ajax_so_widgets_preview', 'siteorigin_widget_preview_widget_action');
57
+
58
+ /**
59
+ * Action to handle searching
60
+ */
61
+ function siteorigin_widget_search_posts_action(){
62
+ if ( empty( $_REQUEST['_widgets_nonce'] ) || !wp_verify_nonce( $_REQUEST['_widgets_nonce'], 'widgets_action' ) ) return;
63
+
64
+ header('content-type: application/json');
65
+
66
+ // Get all public post types, besides attachments
67
+ $post_types = (array) get_post_types( array(
68
+ 'public' => true
69
+ ) );
70
+ unset($post_types['attachment']);
71
+
72
+ $post_types = apply_filters( 'siteorigin_widgets_search_posts_post_types', $post_types );
73
+
74
+ global $wpdb;
75
+ if( !empty($_GET['query']) ) {
76
+ $query = "AND post_title LIKE '%" . esc_sql( $_GET['query'] ) . "%'";
77
+ }
78
+ else {
79
+ $query = '';
80
+ }
81
+
82
+ $post_types = "'" . implode("', '", array_map( 'esc_sql', $post_types ) ) . "'";
83
+
84
+ $results = $wpdb->get_results( "
85
+ SELECT ID, post_title, post_type
86
+ FROM {$wpdb->posts}
87
+ WHERE
88
+ post_type IN ( {$post_types} ) AND post_status = 'publish' {$query}
89
+ ORDER BY post_modified DESC
90
+ LIMIT 20
91
+ ", ARRAY_A );
92
+
93
+ echo json_encode( apply_filters( 'siteorigin_widgets_search_posts_results', $results ) );
94
+ exit();
95
+ }
96
+ add_action('wp_ajax_so_widgets_search_posts', 'siteorigin_widget_search_posts_action');
97
+
98
+ function siteorigin_widget_remote_image_search(){
99
+ if( empty( $_GET[ '_sononce' ] ) || ! wp_verify_nonce( $_GET[ '_sononce' ], 'so-image' ) ) {
100
+ exit();
101
+ }
102
+
103
+ if( empty( $_GET['q'] ) ) {
104
+ exit();
105
+ }
106
+
107
+ // Send the query to stock search server
108
+ $url = add_query_arg( array(
109
+ 'q' => $_GET[ 'q' ],
110
+ 'page' => !empty( $_GET[ 'page' ] ) ? intval( $_GET[ 'page' ] ) : 1,
111
+ ), 'http://stock.siteorigin.com/wp-admin/admin-ajax.php?action=image_search' );
112
+
113
+ $result = wp_remote_get( $url, array(
114
+ 'timeout' => 20,
115
+ ) );
116
+
117
+ if( ! is_wp_error( $result ) ) {
118
+ $result = json_decode( $result['body'], true );
119
+ foreach( $result as & $r ) {
120
+ if( !empty( $r['full_url'] ) ) {
121
+ $r['import_signature'] = md5( $r['full_url'] . '::' . NONCE_SALT );
122
+ }
123
+ }
124
+ }
125
+ else {
126
+ $result = array(
127
+ 'error' => true,
128
+ 'message' => $result->get_error_message()
129
+ );
130
+ }
131
+
132
+ header( 'content-type:application/json' );
133
+ echo json_encode( $result );
134
+ exit();
135
+ }
136
+ add_action('wp_ajax_so_widgets_image_search', 'siteorigin_widget_remote_image_search');
137
+
138
+ function siteorigin_widget_image_import(){
139
+ if( empty( $_GET[ '_sononce' ] ) || ! wp_verify_nonce( $_GET[ '_sononce' ], 'so-image' ) ) {
140
+ $result = array(
141
+ 'error' => true,
142
+ 'message' => __( 'Nonce error', 'so-widgets-bundle' ),
143
+ );
144
+ }
145
+ else if( empty( $_GET['import_signature'] ) || empty( $_GET['full_url'] ) || md5( $_GET['full_url'] . '::' . NONCE_SALT ) !== $_GET['import_signature'] ) {
146
+ $result = array(
147
+ 'error' => true,
148
+ 'message' => __( 'Signature error', 'so-widgets-bundle' ),
149
+ );
150
+ }
151
+ else {
152
+ // Fetch the image
153
+ $src = media_sideload_image( $_GET['full_url'], $_GET['post_id'], null, 'src' );
154
+ if( is_wp_error( $src ) ) {
155
+ $result = array(
156
+ 'error' => true,
157
+ 'message' => $src->get_error_code(),
158
+ );
159
+ }
160
+ else {
161
+ global $wpdb;
162
+ $attachment = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE guid='%s';", $src ) );
163
+ if( !empty( $attachment ) ) {
164
+ $thumb_src = wp_get_attachment_image_src( $attachment[0], 'thumbnail' );
165
+ $result = array(
166
+ 'error' => false,
167
+ 'attachment_id' => $attachment[0],
168
+ 'thumb' => $thumb_src[0]
169
+ );
170
+ }
171
+ else {
172
+ $result = array(
173
+ 'error' => true,
174
+ 'message' => __( 'Attachment error', 'so-widgets-bundle' ),
175
+ );
176
+ }
177
+ }
178
+ }
179
+
180
+ // Return the result
181
+ header( 'content-type:application/json' );
182
+ echo json_encode( $result );
183
+ exit();
184
+ }
185
+ add_action('wp_ajax_so_widgets_image_import', 'siteorigin_widget_image_import');
base/inc/fields/base.class.php CHANGED
@@ -244,7 +244,7 @@ abstract class SiteOrigin_Widget_Field_Base {
244
* @return array The modified array of description text CSS classes.
245
*/
246
protected function get_description_classes() {
247
- return array( 'siteorigin-widget-field-description' );
248
}
249
250
/**
@@ -409,6 +409,7 @@ abstract class SiteOrigin_Widget_Field_Base {
409
* necessary to perform additional sanitization on the widget instance, which should be done here.
410
*
411
* @param $instance
412
*/
413
public function sanitize_instance( $instance ) {
414
//Stub: This function may be overridden by subclasses wishing to sanitize additional instance fields.
244
* @return array The modified array of description text CSS classes.
245
*/
246
protected function get_description_classes() {
247
+ return array( 'siteorigin-widget-description' );
248
}
249
250
/**
409
* necessary to perform additional sanitization on the widget instance, which should be done here.
410
*
411
* @param $instance
412
+ * @return mixed
413
*/
414
public function sanitize_instance( $instance ) {
415
//Stub: This function may be overridden by subclasses wishing to sanitize additional instance fields.
base/inc/fields/code.class.php ADDED
@@ -0,0 +1,36 @@
1
+ <?php
2
+
3
+ /**
4
+ * Class SiteOrigin_Widget_Field_Textarea
5
+ */
6
+ class SiteOrigin_Widget_Field_Code extends SiteOrigin_Widget_Field_Text_Input_Base {
7
+ /**
8
+ * The number of visible rows in the textarea.
9
+ *
10
+ * @access protected
11
+ * @var int
12
+ */
13
+ protected $rows;
14
+
15
+ protected function render_field( $value, $instance ) {
16
+ ?>
17
+ <textarea type="text" name="<?php echo esc_attr( $this->element_name ) ?>" id="<?php echo esc_attr( $this->element_id ) ?>"
18
+ autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
19
+ <?php if ( ! empty( $this->placeholder ) ) echo 'placeholder="' . esc_attr( $this->placeholder ) . '"' ?>
20
+ <?php $this->render_CSS_classes( $this->get_input_classes() ) ?>
21
+ rows="<?php echo ! empty( $this->rows ) ? intval( $this->rows ) : 4 ?>"
22
+ <?php if( ! empty( $this->readonly ) ) echo 'readonly' ?>><?php echo esc_textarea( $value ) ?></textarea>
23
+ <?php
24
+ }
25
+
26
+ /**
27
+ * The CSS classes to be applied to the rendered text input.
28
+ */
29
+ protected function get_input_classes() {
30
+ return array( 'widefat', 'siteorigin-widget-input', 'siteorigin-widget-code-input' );
31
+ }
32
+
33
+ function enqueue_scripts(){
34
+ wp_enqueue_script( 'so-code-field', plugin_dir_url( __FILE__ ) . '/js/code-field' . SOW_BUNDLE_JS_SUFFIX . '.js', array( 'jquery' ), SOW_BUNDLE_VERSION );
35
+ }
36
+ }
base/inc/fields/css/images/wpspin_light-2x.gif ADDED
Binary file
base/inc/fields/css/images/wpspin_light.gif ADDED
Binary file
base/inc/fields/css/media-field.css ADDED
@@ -0,0 +1,275 @@
1
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-field-wrapper {
2
+ position: relative;
3
+ display: block;
4
+ float: left;
5
+ background: #f9f9f9;
6
+ background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #f2f2f2), color-stop(1, #f9f9f9));
7
+ background: -ms-linear-gradient(bottom, #f2f2f2, #f9f9f9);
8
+ background: -moz-linear-gradient(center bottom, #f2f2f2 0%, #f9f9f9 100%);
9
+ background: -o-linear-gradient(#f9f9f9, #f2f2f2);
10
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f9f9f9', endColorstr='#f2f2f2', GradientType=0);
11
+ -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.1);
12
+ -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.1);
13
+ box-shadow: 0 1px 2px rgba(0,0,0,0.1);
14
+ -webkit-border-radius: 3px;
15
+ -moz-border-radius: 3px;
16
+ border-radius: 3px;
17
+ border: 1px solid #bbbbbb;
18
+ height: 32px;
19
+ }
20
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-field-wrapper:hover {
21
+ -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.15);
22
+ -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.15);
23
+ box-shadow: 0 1px 2px rgba(0,0,0,0.15);
24
+ }
25
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-field-wrapper .current {
26
+ -ms-box-sizing: border-box;
27
+ -moz-box-sizing: border-box;
28
+ -webkit-box-sizing: border-box;
29
+ box-sizing: border-box;
30
+ float: left;
31
+ height: 32px;
32
+ padding: 4px;
33
+ border-right: 1px solid #bbb;
34
+ position: relative;
35
+ box-shadow: 1px 0 0 #FFF;
36
+ }
37
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-field-wrapper .current .title {
38
+ display: none;
39
+ position: absolute;
40
+ bottom: 34px;
41
+ left: 0;
42
+ padding: 4px 12px;
43
+ background: #333;
44
+ color: #CCC;
45
+ font-weight: bold;
46
+ width: auto;
47
+ white-space: nowrap;
48
+ }
49
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-field-wrapper .current .thumbnail-wrapper {
50
+ border: 1px solid #999;
51
+ line-height: 0;
52
+ box-shadow: 0px 1px 1px #FFF;
53
+ width: 22px;
54
+ height: 22px;
55
+ background: #cfcfcf;
56
+ background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #cccccc), color-stop(1, #cfcfcf));
57
+ background: -ms-linear-gradient(bottom, #cccccc, #cfcfcf);
58
+ background: -moz-linear-gradient(center bottom, #cccccc 0%, #cfcfcf 100%);
59
+ background: -o-linear-gradient(#cfcfcf, #cccccc);
60
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cfcfcf', endColorstr='#cccccc', GradientType=0);
61
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
62
+ }
63
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-field-wrapper .current .thumbnail-wrapper img {
64
+ height: 100%;
65
+ width: 100%;
66
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
67
+ }
68
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-field-wrapper .media-upload-button,
69
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-field-wrapper .find-image-button {
70
+ display: block;
71
+ float: left;
72
+ color: #666;
73
+ text-decoration: none;
74
+ text-shadow: 0 1px 0 #FFF;
75
+ font-weight: 600;
76
+ font-size: 11px;
77
+ padding: 7px 8px;
78
+ outline: none;
79
+ cursor: pointer;
80
+ -webkit-border-radius: 2px;
81
+ -moz-border-radius: 2px;
82
+ border-radius: 2px;
83
+ }
84
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-field-wrapper .media-upload-button:hover,
85
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-field-wrapper .find-image-button:hover {
86
+ background: rgba(255, 255, 255, 0.75);
87
+ }
88
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-field-wrapper .find-image-button {
89
+ border-left: 1px solid #bbbbbb;
90
+ }
91
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-field-wrapper:hover .media-upload-button {
92
+ color: #707070;
93
+ }
94
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-remove-button {
95
+ display: block;
96
+ text-decoration: none;
97
+ float: left;
98
+ color: #AAA;
99
+ font-size: 11px;
100
+ line-height: 1em;
101
+ padding: 11px 0 11px 6px;
102
+ -webkit-transition: all 0.25s ease;
103
+ -moz-transition: all 0.25s ease;
104
+ -o-transition: all 0.25s ease;
105
+ transition: all 0.25s ease;
106
+ position: static;
107
+ opacity: 1;
108
+ }
109
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-remove-button.remove-hide {
110
+ pointer-events: none;
111
+ opacity: 0;
112
+ }
113
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-remove-button:hover {
114
+ color: #BC0B0B;
115
+ }
116
+ .siteorigin-widget-form .siteorigin-widget-field-type-media .media-fallback-external {
117
+ float: left;
118
+ padding: 4px 8px;
119
+ margin-top: 2px !important;
120
+ margin-left: 25px !important;
121
+ width: 320px !important;
122
+ }
123
+ #so-widgets-image-search-frame {
124
+ position: absolute;
125
+ top: 0;
126
+ left: 0;
127
+ right: 0;
128
+ bottom: 0;
129
+ background-color: #fff;
130
+ padding: 25px;
131
+ overflow-y: scroll;
132
+ }
133
+ #so-widgets-image-search-frame #so-widgets-image-search-form {
134
+ display: inline-block;
135
+ max-width: 420px;
136
+ width: 100%;
137
+ position: relative;
138
+ padding-right: 48px;
139
+ margin-bottom: 2px;
140
+ }
141
+ #so-widgets-image-search-frame #so-widgets-image-search-form .so-widgets-search-input {
142
+ padding: 9px 12px;
143
+ margin-bottom: 0px;
144
+ box-shadow: none;
145
+ }
146
+ #so-widgets-image-search-frame #so-widgets-image-search-form .so-widgets-search-input:focus {
147
+ box-shadow: none;
148
+ }
149
+ #so-widgets-image-search-frame #so-widgets-image-search-form .so-widgets-search-button {
150
+ position: absolute;
151
+ padding: 9px 14px;
152
+ font-size: 1.2em;
153
+ height: 100%;
154
+ top: 0;
155
+ right: 0;
156
+ border-width: 1px;
157
+ box-shadow: none;
158
+ }
159
+ #so-widgets-image-search-frame #so-widgets-image-search-suggestions {
160
+ display: none;
161
+ float: right;
162
+ font-size: 1.1em;
163
+ margin-top: 15px;
164
+ }
165
+ #so-widgets-image-search-frame #so-widgets-image-search-suggestions strong {
166
+ margin-right: 0.5em;
167
+ }
168
+ #so-widgets-image-search-frame #so-widgets-image-search-suggestions ul {
169
+ display: inline-block;
170
+ list-style: none;
171
+ margin: 0;
172
+ padding: 0;
173
+ }
174
+ #so-widgets-image-search-frame #so-widgets-image-search-suggestions ul li {
175
+ display: inline-block;
176
+ margin-right: 4px;
177
+ }
178
+ #so-widgets-image-search-frame #so-widgets-image-search-powered {
179
+ font-size: 0.85em;
180
+ margin-bottom: 15px;
181
+ color: #888;
182
+ }
183
+ #so-widgets-image-search-frame .so-widgets-image-results {
184
+ zoom: 1;
185
+ margin: 0 -8px;
186
+ }
187
+ #so-widgets-image-search-frame .so-widgets-image-results:before {
188
+ content: '';
189
+ display: block;
190
+ }
191
+ #so-widgets-image-search-frame .so-widgets-image-results:after {
192
+ content: '';
193
+ display: table;
194
+ clear: both;
195
+ }
196
+ #so-widgets-image-search-frame .so-widgets-image-results .so-widgets-result {
197
+ -ms-box-sizing: border-box;
198
+ -moz-box-sizing: border-box;
199
+ -webkit-box-sizing: border-box;
200
+ box-sizing: border-box;
201
+ float: left;
202
+ margin: 8px;
203
+ }
204
+ #so-widgets-image-search-frame .so-widgets-image-results .so-widgets-result a {
205
+ position: relative;
206
+ background-repeat: no-repeat;
207
+ background-size: cover;
208
+ display: block;
209
+ width: 260px;
210
+ height: 180px;
211
+ background-color: #e8e8e8;
212
+ }
213
+ #so-widgets-image-search-frame .so-widgets-image-results .so-widgets-result a .so-widgets-result-sponsored {
214
+ font-size: 0.8em;
215
+ position: absolute;
216
+ top: 5px;
217
+ right: 5px;
218
+ color: #fff;
219
+ background: #59946B;
220
+ line-height: 1em;
221
+ padding: 5px;
222
+ border-radius: 2px;
223
+ }
224
+ #so-widgets-image-search-frame .so-widgets-results-loading {
225
+ display: none;
226
+ font-size: 1.1em;
227
+ padding: 15px 5px;
228
+ background-color: #f7f7f7;
229
+ text-align: center;
230
+ margin-top: 20px;
231
+ }
232
+ #so-widgets-image-search-frame .so-widgets-results-loading .so-widgets-loading-icon {
233
+ margin: 0 6px -3px 0;
234
+ display: inline-block;
235
+ width: 16px;
236
+ height: 16px;
237
+ background-image: url("images/wpspin_light.gif");
238
+ background-position: center center;
239
+ background-repeat: no-repeat;
240
+ }
241
+ @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
242
+ #so-widgets-image-search-frame .so-widgets-results-loading .so-widgets-loading-icon {
243
+ background-image: url(images/wpspin_light-2x.gif);
244
+ background-size: 16px 16px;
245
+ }
246
+ }
247
+ #so-widgets-image-search-frame .so-widgets-results-more {
248
+ display: none;
249
+ text-align: center;
250
+ margin-top: 20px;
251
+ padding-bottom: 20px;
252
+ }
253
+ #so-widgets-image-search-frame .so-widgets-preview-window {
254
+ display: none;
255
+ position: fixed;
256
+ background-color: #ffffff;
257
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
258
+ padding: 10px;
259
+ pointer-events: none;
260
+ }
261
+ #so-widgets-image-search-frame .so-widgets-preview-window .so-widgets-preview-window-inside {
262
+ background-size: cover;
263
+ overflow: hidden;
264
+ }
265
+ #so-widgets-image-search-frame .so-widgets-preview-window img {
266
+ width: 100%;
267
+ height: auto;
268
+ }
269
+ #so-widgets-image-search-frame.so-widgets-importing .so-widgets-preview-window,
270
+ #so-widgets-image-search-frame.so-widgets-importing #so-widgets-image-search-form,
271
+ #so-widgets-image-search-frame.so-widgets-importing #so-widgets-image-search-powered,
272
+ #so-widgets-image-search-frame.so-widgets-importing .so-widgets-image-results {
273
+ visibility: hidden !important;
274
+ display: none !important;
275
+ }
base/inc/fields/editor.class.php CHANGED
@@ -5,28 +5,6 @@
5
*
6
* Class SiteOrigin_Widget_Field_Editor
7
*/
8
- class SiteOrigin_Widget_Field_Editor extends SiteOrigin_Widget_Field_Text_Input_Base {
9
- /**
10
- * The number of visible rows in the textarea.
11
- *
12
- * @access protected
13
- * @var int
14
- */
15
- protected $rows;
16
-
17
- protected function get_input_classes() {
18
- $input_classes = parent::get_input_classes();
19
- $input_classes[] = 'siteorigin-widget-input-editor';
20
- return $input_classes;
21
- }
22
-
23
- protected function render_field( $value, $instance ) {
24
- ?>
25
- <textarea type="text" name="<?php echo esc_attr( $this->element_name ) ?>" id="<?php echo esc_attr( $this->element_id ) ?>"
26
- <?php if ( ! empty( $this->placeholder ) ) echo 'placeholder="' . esc_attr( $this->placeholder ) . '"' ?>
27
- <?php $this->render_CSS_classes( $this->get_input_classes() ) ?>
28
- rows="<?php echo ! empty( $this->rows ) ? intval( $this->rows ) : 4 ?>"
29
- <?php if( ! empty( $this->readonly ) ) echo 'readonly' ?>><?php echo esc_textarea( $value ) ?></textarea>
30
- <?php
31
- }
32
}
5
*
6
* Class SiteOrigin_Widget_Field_Editor
7
*/
8
+ class SiteOrigin_Widget_Field_Editor extends SiteOrigin_Widget_Field_TinyMCE {
9
+
10
}
base/inc/fields/js/code-field.js ADDED
@@ -0,0 +1,645 @@
1
+ /*
2
+ * Behave.js
3
+ *
4
+ * Copyright 2013, Jacob Kelley - http://jakiestfu.com/
5
+ * Released under the MIT Licence
6
+ * http://opensource.org/licenses/MIT
7
+ *
8
+ * Github: http://github.com/jakiestfu/Behave.js/
9
+ * Version: 1.5
10
+ */
11
+
12
+
13
+ (function(undefined){
14
+
15
+ 'use strict';
16
+
17
+ var BehaveHooks = BehaveHooks || (function(){
18
+ var hooks = {};
19
+
20
+ return {
21
+ add: function(hookName, fn){
22
+ if(typeof hookName == "object"){
23
+ var i;
24
+ for(i=0; i<hookName.length; i++){
25
+ var theHook = hookName[i];
26
+ if(!hooks[theHook]){
27
+ hooks[theHook] = [];
28
+ }
29
+ hooks[theHook].push(fn);
30
+ }
31
+ } else {
32
+ if(!hooks[hookName]){
33
+ hooks[hookName] = [];
34
+ }
35
+ hooks[hookName].push(fn);
36
+ }
37
+ },
38
+ get: function(hookName){
39
+ if(hooks[hookName]){
40
+ return hooks[hookName];
41
+ }
42
+ }
43
+ };
44
+
45
+ })(),
46
+ Behave = Behave || function (userOpts) {
47
+
48
+ if (typeof String.prototype.repeat !== 'function') {
49
+ String.prototype.repeat = function(times) {
50
+ if(times < 1){
51
+ return '';
52
+ }
53
+ if(times % 2){
54
+ return this.repeat(times - 1) + this;
55
+ }
56
+ var half = this.repeat(times / 2);
57
+ return half + half;
58
+ };
59
+ }
60
+
61
+ if (typeof Array.prototype.filter !== 'function') {
62
+ Array.prototype.filter = function(func /*, thisp */) {
63
+ if (this === null) {
64
+ throw new TypeError();
65
+ }
66
+
67
+ var t = Object(this),
68
+ len = t.length >>> 0;
69
+ if (typeof func != "function"){
70
+ throw new TypeError();
71
+ }
72
+ var res = [],
73
+ thisp = arguments[1];
74
+ for (var i = 0; i < len; i++) {
75
+ if (i in t) {
76
+ var val = t[i];
77
+ if (func.call(thisp, val, i, t)) {
78
+ res.push(val);
79
+ }
80
+ }
81
+ }
82
+ return res;
83
+ };
84
+ }
85
+
86
+ var defaults = {
87
+ textarea: null,
88
+ replaceTab: true,
89
+ softTabs: true,
90
+ tabSize: 4,
91
+ autoOpen: true,
92
+ overwrite: true,
93
+ autoStrip: true,
94
+ autoIndent: true,
95
+ fence: false
96
+ },
97
+ tab,
98
+ newLine,
99
+ charSettings = {
100
+
101
+ keyMap: [
102
+ { open: "\"", close: "\"", canBreak: false },
103
+ { open: "'", close: "'", canBreak: false },
104
+ { open: "(", close: ")", canBreak: false },
105
+ { open: "[", close: "]", canBreak: true },
106
+ { open: "{", close: "}", canBreak: true }
107
+ ]
108
+
109
+ },
110
+ utils = {
111
+
112
+ _callHook: function(hookName, passData){
113
+ var hooks = BehaveHooks.get(hookName);
114
+ passData = typeof passData=="boolean" && passData === false ? false : true;
115
+
116
+ if(hooks){
117
+ if(passData){
118
+ var theEditor = defaults.textarea,
119
+ textVal = theEditor.value,
120
+ caretPos = utils.cursor.get(),
121
+ i;
122
+
123
+ for(i=0; i<hooks.length; i++){
124
+ hooks[i].call(undefined, {
125
+ editor: {
126
+ element: theEditor,
127
+ text: textVal,
128
+ levelsDeep: utils.levelsDeep()
129
+ },
130
+ caret: {
131
+ pos: caretPos
132
+ },
133
+ lines: {
134
+ current: utils.cursor.getLine(textVal, caretPos),
135
+ total: utils.editor.getLines(textVal)
136
+ }
137
+ });
138
+ }
139
+ } else {
140
+ for(i=0; i<hooks.length; i++){
141
+ hooks[i].call(undefined);
142
+ }
143
+ }
144
+ }
145
+ },
146
+
147
+ defineNewLine: function(){
148
+ var ta = document.createElement('textarea');
149
+ ta.value = "\n";
150
+
151
+ if(ta.value.length==2){
152
+ newLine = "\r\n";
153
+ } else {
154
+ newLine = "\n";
155
+ }
156
+ },
157
+ defineTabSize: function(tabSize){
158
+ if(typeof defaults.textarea.style.OTabSize != "undefined"){
159
+ defaults.textarea.style.OTabSize = tabSize; return;
160
+ }
161
+ if(typeof defaults.textarea.style.MozTabSize != "undefined"){
162
+ defaults.textarea.style.MozTabSize = tabSize; return;
163
+ }
164
+ if(typeof defaults.textarea.style.tabSize != "undefined"){
165
+ defaults.textarea.style.tabSize = tabSize; return;
166
+ }
167
+ },
168
+ cursor: {
169
+ getLine: function(textVal, pos){
170
+ return ((textVal.substring(0,pos)).split("\n")).length;
171
+ },
172
+ get: function() {
173
+
174
+ if (typeof document.createElement('textarea').selectionStart==="number") {
175
+ return defaults.textarea.selectionStart;
176
+ } else if (document.selection) {
177
+ var caretPos = 0,
178
+ range = defaults.textarea.createTextRange(),
179
+ rangeDupe = document.selection.createRange().duplicate(),
180
+ rangeDupeBookmark = rangeDupe.getBookmark();
181
+ range.moveToBookmark(rangeDupeBookmark);
182
+
183
+ while (range.moveStart('character' , -1) !== 0) {
184
+ caretPos++;
185
+ }
186
+ return caretPos;
187
+ }
188
+ },
189
+ set: function (start, end) {
190
+ if(!end){
191
+ end = start;
192
+ }
193
+ if (defaults.textarea.setSelectionRange) {
194
+ defaults.textarea.focus();
195
+ defaults.textarea.setSelectionRange(start, end);
196
+ } else if (defaults.textarea.createTextRange) {
197
+ var range = defaults.textarea.createTextRange();
198
+ range.collapse(true);
199
+ range.moveEnd('character', end);
200
+ range.moveStart('character', start);
201
+ range.select();
202
+ }
203
+ },
204
+ selection: function(){
205
+ var textAreaElement = defaults.textarea,
206
+ start = 0,
207
+ end = 0,
208
+ normalizedValue,
209
+ range,
210
+ textInputRange,
211
+ len,
212
+ endRange;
213
+
214
+ if (typeof textAreaElement.selectionStart == "number" && typeof textAreaElement.selectionEnd == "number") {
215
+ start = textAreaElement.selectionStart;
216
+ end = textAreaElement.selectionEnd;
217
+ } else {
218
+ range = document.selection.createRange();
219
+
220
+ if (range && range.parentElement() == textAreaElement) {
221
+
222
+ normalizedValue = utils.editor.get();
223
+ len = normalizedValue.length;
224
+
225
+ textInputRange = textAreaElement.createTextRange();
226
+ textInputRange.moveToBookmark(range.getBookmark());
227
+
228
+ endRange = textAreaElement.createTextRange();
229
+ endRange.collapse(false);
230
+
231
+ if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
232
+ start = end = len;
233
+ } else {
234
+ start = -textInputRange.moveStart("character", -len);
235
+ start += normalizedValue.slice(0, start).split(newLine).length - 1;
236
+
237
+ if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
238
+ end = len;
239
+ } else {
240
+ end = -textInputRange.moveEnd("character", -len);
241
+ end += normalizedValue.slice(0, end).split(newLine).length - 1;
242
+ }
243
+ }
244
+ }
245
+ }
246
+
247
+ return start==end ? false : {
248
+ start: start,
249
+ end: end
250
+ };
251
+ }
252
+ },
253
+ editor: {
254
+ getLines: function(textVal){
255
+ return (textVal).split("\n").length;
256
+ },
257
+ get: function(){
258
+ return defaults.textarea.value.replace(/\r/g,'');
259
+ },
260
+ set: function(data){
261
+ defaults.textarea.value = data;
262
+ }
263
+ },
264
+ fenceRange: function(){
265
+ if(typeof defaults.fence == "string"){
266
+
267
+ var data = utils.editor.get(),
268
+ pos = utils.cursor.get(),
269
+ hacked = 0,
270
+ matchedFence = data.indexOf(defaults.fence),
271
+ matchCase = 0;
272
+
273
+ while(matchedFence>=0){
274
+ matchCase++;
275
+ if( pos < (matchedFence+hacked) ){
276
+ break;
277
+ }
278
+
279
+ hacked += matchedFence+defaults.fence.length;
280
+ data = data.substring(matchedFence+defaults.fence.length);
281
+ matchedFence = data.indexOf(defaults.fence);
282
+
283
+ }
284
+
285
+ if( (hacked) < pos && ( (matchedFence+hacked) > pos ) && matchCase%2===0){
286
+ return true;
287
+ }
288
+ return false;
289
+ } else {
290
+ return true;
291
+ }
292
+ },
293
+ isEven: function(_this,i){
294
+ return i%2;
295
+ },
296
+ levelsDeep: function(){
297
+ var pos = utils.cursor.get(),
298
+ val = utils.editor.get();
299
+
300
+ var left = val.substring(0, pos),
301
+ levels = 0,
302
+ i, j;
303
+
304
+ for(i=0; i<left.length; i++){
305
+ for (j=0; j<charSettings.keyMap.length; j++) {
306
+ if(charSettings.keyMap[j].canBreak){
307
+ if(charSettings.keyMap[j].open == left.charAt(i)){
308
+ levels++;
309
+ }
310
+
311
+ if(charSettings.keyMap[j].close == left.charAt(i)){
312
+ levels--;
313
+ }
314
+ }
315
+ }
316
+ }
317
+
318
+ var toDecrement = 0,
319
+ quoteMap = ["'", "\""];
320
+ for(i=0; i<charSettings.keyMap.length; i++) {
321
+ if(charSettings.keyMap[i].canBreak){
322
+ for(j in quoteMap){
323
+ toDecrement += left.split(quoteMap[j]).filter(utils.isEven).join('').split(charSettings.keyMap[i].open).length - 1;
324
+ }
325
+ }
326
+ }
327
+
328
+ var finalLevels = levels - toDecrement;
329
+
330
+ return finalLevels >=0 ? finalLevels : 0;
331
+ },
332
+ deepExtend: function(destination, source) {
333
+ for (var property in source) {
334
+ if (source[property] && source[property].constructor &&
335
+ source[property].constructor === Object) {
336
+ destination[property] = destination[property] || {};
337
+ utils.deepExtend(destination[property], source[property]);
338
+ } else {
339
+ destination[property] = source[property];
340
+ }
341
+ }
342
+ return destination;
343
+ },
344
+ addEvent: function addEvent(element, eventName, func) {
345
+ if (element.addEventListener){
346
+ element.addEventListener(eventName,func,false);
347
+ } else if (element.attachEvent) {
348
+ element.attachEvent("on"+eventName, func);
349
+ }
350
+ },
351
+ removeEvent: function addEvent(element, eventName, func){
352
+ if (element.addEventListener){
353
+ element.removeEventListener(eventName,func,false);
354
+ } else if (element.attachEvent) {
355
+ element.detachEvent("on"+eventName, func);
356
+ }
357
+ },
358
+
359
+ preventDefaultEvent: function(e){
360
+ if(e.preventDefault){
361
+ e.preventDefault();
362
+ } else {
363
+ e.returnValue = false;
364
+ }
365
+ }
366
+ },
367
+ intercept = {
368
+ tabKey: function (e) {
369
+
370
+ if(!utils.fenceRange()){ return; }
371
+
372
+ if (e.keyCode == 9) {
373
+ utils.preventDefaultEvent(e);
374
+
375
+ var toReturn = true;
376
+ utils._callHook('tab:before');
377
+
378
+ var selection = utils.cursor.selection(),
379
+ pos = utils.cursor.get(),
380
+ val = utils.editor.get();
381
+
382
+ if(selection){
383
+
384
+ var tempStart = selection.start;
385
+ while(tempStart--){
386
+ if(val.charAt(tempStart)=="\n"){
387
+ selection.start = tempStart + 1;
388
+ break;
389
+ }
390
+ }
391
+
392
+ var toIndent = val.substring(selection.start, selection.end),
393
+ lines = toIndent.split("\n"),
394
+ i;
395
+
396
+ if(e.shiftKey){
397
+ for(i = 0; i<lines.length; i++){
398
+ if(lines[i].substring(0,tab.length) == tab){
399
+ lines[i] = lines[i].substring(tab.length);
400
+ }
401
+ }
402
+ toIndent = lines.join("\n");
403
+
404
+ utils.editor.set( val.substring(0,selection.start) + toIndent + val.substring(selection.end) );
405
+ utils.cursor.set(selection.start, selection.start+toIndent.length);
406
+
407
+ } else {
408
+ for(i in lines){
409
+ lines[i] = tab + lines[i];
410
+ }
411
+ toIndent = lines.join("\n");
412
+
413
+ utils.editor.set( val.substring(0,selection.start) + toIndent + val.substring(selection.end) );
414
+ utils.cursor.set(selection.start, selection.start+toIndent.length);
415
+ }
416
+ } else {
417
+ var left = val.substring(0, pos),
418
+ right = val.substring(pos),
419
+ edited = left + tab + right;
420
+
421
+ if(e.shiftKey){
422
+ if(val.substring(pos-tab.length, pos) == tab){
423
+ edited = val.substring(0, pos-tab.length) + right;
424
+ utils.editor.set(edited);
425
+ utils.cursor.set(pos-tab.length);
426
+ }
427
+ } else {
428
+ utils.editor.set(edited);
429
+ utils.cursor.set(pos + tab.length);
430
+ toReturn = false;
431
+ }
432
+ }
433
+ utils._callHook('tab:after');
434
+ }
435
+ return toReturn;
436
+ },
437
+ enterKey: function (e) {
438
+
439
+ if(!utils.fenceRange()){ return; }
440
+
441
+ if (e.keyCode == 13) {
442
+
443
+ utils.preventDefaultEvent(e);
444
+ utils._callHook('enter:before');
445
+
446
+ var pos = utils.cursor.get(),
447
+ val = utils.editor.get(),
448
+ left = val.substring(0, pos),
449
+ right = val.substring(pos),
450
+ leftChar = left.charAt(left.length - 1),
451
+ rightChar = right.charAt(0),
452
+ numTabs = utils.levelsDeep(),
453
+ ourIndent = "",
454
+ closingBreak = "",
455
+ finalCursorPos,
456
+ i;
457
+ if(!numTabs){
458
+ finalCursorPos = 1;
459
+ } else {
460
+ while(numTabs--){
461
+ ourIndent+=tab;
462
+ }
463
+ ourIndent = ourIndent;
464
+ finalCursorPos = ourIndent.length + 1;
465
+
466
+ for(i=0; i<charSettings.keyMap.length; i++) {
467
+ if (charSettings.keyMap[i].open == leftChar && charSettings.keyMap[i].close == rightChar){
468
+ closingBreak = newLine;
469
+ }
470
+ }
471
+
472
+ }
473
+
474
+ var edited = left + newLine + ourIndent + closingBreak + (ourIndent.substring(0, ourIndent.length-tab.length) ) + right;
475
+ utils.editor.set(edited);
476
+ utils.cursor.set(pos + finalCursorPos);
477
+ utils._callHook('enter:after');
478
+ }
479
+ },
480
+ deleteKey: function (e) {
481
+
482
+ if(!utils.fenceRange()){ return; }
483
+
484
+ if(e.keyCode == 8){
485
+ utils.preventDefaultEvent(e);
486
+
487
+ utils._callHook('delete:before');
488
+
489
+ var pos = utils.cursor.get(),
490
+ val = utils.editor.get(),
491
+ left = val.substring(0, pos),
492
+ right = val.substring(pos),
493
+ leftChar = left.charAt(left.length - 1),
494
+ rightChar = right.charAt(0),
495
+ i;
496
+
497
+ if( utils.cursor.selection() === false ){
498
+ for(i=0; i<charSettings.keyMap.length; i++) {
499
+ if (charSettings.keyMap[i].open == leftChar && charSettings.keyMap[i].close == rightChar) {
500
+ var edited = val.substring(0,pos-1) + val.substring(pos+1);
501
+ utils.editor.set(edited);
502
+ utils.cursor.set(pos - 1);
503
+ return;
504
+ }
505
+ }
506
+ var edited = val.substring(0,pos-1) + val.substring(pos);
507
+ utils.editor.set(edited);
508
+ utils.cursor.set(pos - 1);
509
+ } else {
510
+ var sel = utils.cursor.selection(),
511
+ edited = val.substring(0,sel.start) + val.substring(sel.end);
512
+ utils.editor.set(edited);
513
+ utils.cursor.set(pos);
514
+ }
515
+
516
+ utils._callHook('delete:after');
517
+
518
+ }
519
+ }
520
+ },
521
+ charFuncs = {
522
+ openedChar: function (_char, e) {
523
+ utils.preventDefaultEvent(e);
524
+ utils._callHook('openChar:before');
525
+ var pos = utils.cursor.get(),
526
+ val = utils.editor.get(),
527
+ left = val.substring(0, pos),
528
+ right = val.substring(pos),
529
+ edited = left + _char.open + _char.close + right;
530
+
531
+ defaults.textarea.value = edited;
532
+ utils.cursor.set(pos + 1);
533
+ utils._callHook('openChar:after');
534
+ },
535
+ closedChar: function (_char, e) {
536
+ var pos = utils.cursor.get(),
537
+ val = utils.editor.get(),
538
+ toOverwrite = val.substring(pos, pos + 1);
539
+ if (toOverwrite == _char.close) {
540
+ utils.preventDefaultEvent(e);
541
+ utils._callHook('closeChar:before');
542
+ utils.cursor.set(utils.cursor.get() + 1);
543
+ utils._callHook('closeChar:after');
544
+ return true;
545
+ }
546
+ return false;
547
+ }
548
+ },
549
+ action = {
550
+ filter: function (e) {
551
+
552
+ if(!utils.fenceRange()){ return; }
553
+
554
+ var theCode = e.which || e.keyCode;
555
+
556
+ if(theCode == 39 || theCode == 40 && e.which===0){ return; }
557
+
558
+ var _char = String.fromCharCode(theCode),
559
+ i;
560
+
561
+ for(i=0; i<charSettings.keyMap.length; i++) {
562
+
563
+ if (charSettings.keyMap[i].close == _char) {
564
+ var didClose = defaults.overwrite && charFuncs.closedChar(charSettings.keyMap[i], e);
565
+
566
+ if (!didClose && charSettings.keyMap[i].open == _char && defaults.autoOpen) {
567
+ charFuncs.openedChar(charSettings.keyMap[i], e);
568
+ }
569
+ } else if (charSettings.keyMap[i].open == _char && defaults.autoOpen) {
570
+ charFuncs.openedChar(charSettings.keyMap[i], e);
571
+ }
572
+ }
573
+ },
574
+ listen: function () {
575
+
576
+ if(defaults.replaceTab){ utils.addEvent(defaults.textarea, 'keydown', intercept.tabKey); }
577
+ if(defaults.autoIndent){ utils.addEvent(defaults.textarea, 'keydown', intercept.enterKey); }
578
+ if(defaults.autoStrip){ utils.addEvent(defaults.textarea, 'keydown', intercept.deleteKey); }
579
+
580
+ utils.addEvent(defaults.textarea, 'keypress', action.filter);
581
+
582
+ utils.addEvent(defaults.textarea, 'keydown', function(){ utils._callHook('keydown'); });
583
+ utils.addEvent(defaults.textarea, 'keyup', function(){ utils._callHook('keyup'); });
584
+ }
585
+ },
586
+ init = function (opts) {
587
+
588
+ if(opts.textarea){
589
+ utils._callHook('init:before', false);
590
+ utils.deepExtend(defaults, opts);
591
+ utils.defineNewLine();
592
+
593
+ if (defaults.softTabs) {
594
+ tab = " ".repeat(defaults.tabSize);
595
+ } else {
596
+ tab = "\t";
597
+
598
+ utils.defineTabSize(defaults.tabSize);
599
+ }
600
+
601
+ action.listen();
602
+ utils._callHook('init:after', false);
603
+ }
604
+
605
+ };
606
+
607
+ this.destroy = function(){
608
+ utils.removeEvent(defaults.textarea, 'keydown', intercept.tabKey);
609
+ utils.removeEvent(defaults.textarea, 'keydown', intercept.enterKey);
610
+ utils.removeEvent(defaults.textarea, 'keydown', intercept.deleteKey);
611
+ utils.removeEvent(defaults.textarea, 'keypress', action.filter);
612
+ };
613
+
614
+ init(userOpts);
615
+
616
+ };
617
+
618
+ if (typeof module !== 'undefined' && module.exports) {
619
+ module.exports = Behave;
620
+ }
621
+
622
+ if (typeof ender === 'undefined') {
623
+ this.Behave = Behave;
624
+ this.BehaveHooks = BehaveHooks;
625
+ }
626
+
627
+ if (typeof define === "function" && define.amd) {
628
+ define("behave", [], function () {
629
+ return Behave;
630
+ });
631
+ }
632
+
633
+ }).call(this);
634
+
635
+
636
+ ( function( $ ) {
637
+
638
+ $(document).on( 'sowsetupformfield', '.siteorigin-widget-field-type-code', function(e) {
639
+ var $ = $(this);
640
+ var editor = new Behave({
641
+ textarea: $.find( '.siteorigin-widget-code-input' ).get( 0 ),
642
+ });
643
+ } );
644
+
645
+ } )( jQuery );
base/inc/fields/js/code-field.min.js ADDED
@@ -0,0 +1 @@
1
+ (function(e){"use strict";var t=t||function(){var e={};return{add:function(t,r){if("object"==typeof t){var n;for(n=0;n<t.length;n++){var a=t[n];e[a]||(e[a]=[]),e[a].push(r)}}else e[t]||(e[t]=[]),e[t].push(r)},get:function(t){if(e[t])return e[t]}}}(),r=r||function(r){"function"!=typeof String.prototype.repeat&&(String.prototype.repeat=function(e){if(e<1)return"";if(e%2)return this.repeat(e-1)+this;var t=this.repeat(e/2);return t+t}),"function"!=typeof Array.prototype.filter&&(Array.prototype.filter=function(e){if(null===this)throw new TypeError;var t=Object(this),r=t.length>>>0;if("function"!=typeof e)throw new TypeError;for(var n=[],a=arguments[1],o=0;o<r;o++)if(o in t){var i=t[o];e.call(a,i,o,t)&&n.push(i)}return n});var n,a,o={textarea:null,replaceTab:!0,softTabs:!0,tabSize:4,autoOpen:!0,overwrite:!0,autoStrip:!0,autoIndent:!0,fence:!1},i={keyMap:[{open:'"',close:'"',canBreak:!1},{open:"'",close:"'",canBreak:!1},{open:"(",close:")",canBreak:!1},{open:"[",close:"]",canBreak:!0},{open:"{",close:"}",canBreak:!0}]},s={_callHook:function(r,n){var a=t.get(r);if(n="boolean"!=typeof n||n!==!1,a)if(n){var i,c=o.textarea,l=c.value,u=s.cursor.get();for(i=0;i<a.length;i++)a[i].call(e,{editor:{element:c,text:l,levelsDeep:s.levelsDeep()},caret:{pos:u},lines:{current:s.cursor.getLine(l,u),total:s.editor.getLines(l)}})}else for(i=0;i<a.length;i++)a[i].call(e)},defineNewLine:function(){var e=document.createElement("textarea");e.value="\n",a=2==e.value.length?"\r\n":"\n"},defineTabSize:function(e){return"undefined"!=typeof o.textarea.style.OTabSize?void(o.textarea.style.OTabSize=e):"undefined"!=typeof o.textarea.style.MozTabSize?void(o.textarea.style.MozTabSize=e):"undefined"!=typeof o.textarea.style.tabSize?void(o.textarea.style.tabSize=e):void 0},cursor:{getLine:function(e,t){return e.substring(0,t).split("\n").length},get:function(){if("number"==typeof document.createElement("textarea").selectionStart)return o.textarea.selectionStart;if(document.selection){var e=0,t=o.textarea.createTextRange(),r=document.selection.createRange().duplicate(),n=r.getBookmark();for(t.moveToBookmark(n);0!==t.moveStart("character",-1);)e++;return e}},set:function(e,t){if(t||(t=e),o.textarea.setSelectionRange)o.textarea.focus(),o.textarea.setSelectionRange(e,t);else if(o.textarea.createTextRange){var r=o.textarea.createTextRange();r.collapse(!0),r.moveEnd("character",t),r.moveStart("character",e),r.select()}},selection:function(){var e,t,r,n,i,c=o.textarea,l=0,u=0;return"number"==typeof c.selectionStart&&"number"==typeof c.selectionEnd?(l=c.selectionStart,u=c.selectionEnd):(t=document.selection.createRange(),t&&t.parentElement()==c&&(e=s.editor.get(),n=e.length,r=c.createTextRange(),r.moveToBookmark(t.getBookmark()),i=c.createTextRange(),i.collapse(!1),r.compareEndPoints("StartToEnd",i)>-1?l=u=n:(l=-r.moveStart("character",-n),l+=e.slice(0,l).split(a).length-1,r.compareEndPoints("EndToEnd",i)>-1?u=n:(u=-r.moveEnd("character",-n),u+=e.slice(0,u).split(a).length-1)))),l!=u&&{start:l,end:u}}},editor:{getLines:function(e){return e.split("\n").length},get:function(){return o.textarea.value.replace(/\r/g,"")},set:function(e){o.textarea.value=e}},fenceRange:function(){if("string"==typeof o.fence){for(var e=s.editor.get(),t=s.cursor.get(),r=0,n=e.indexOf(o.fence),a=0;n>=0&&(a++,!(t<n+r));)r+=n+o.fence.length,e=e.substring(n+o.fence.length),n=e.indexOf(o.fence);return r<t&&n+r>t&&a%2===0}return!0},isEven:function(e,t){return t%2},levelsDeep:function(){var e,t,r=s.cursor.get(),n=s.editor.get(),a=n.substring(0,r),o=0;for(e=0;e<a.length;e++)for(t=0;t<i.keyMap.length;t++)i.keyMap[t].canBreak&&(i.keyMap[t].open==a.charAt(e)&&o++,i.keyMap[t].close==a.charAt(e)&&o--);var c=0,l=["'",'"'];for(e=0;e<i.keyMap.length;e++)if(i.keyMap[e].canBreak)for(t in l)c+=a.split(l[t]).filter(s.isEven).join("").split(i.keyMap[e].open).length-1;var u=o-c;return u>=0?u:0},deepExtend:function(e,t){for(var r in t)t[r]&&t[r].constructor&&t[r].constructor===Object?(e[r]=e[r]||{},s.deepExtend(e[r],t[r])):e[r]=t[r];return e},addEvent:function(e,t,r){e.addEventListener?e.addEventListener(t,r,!1):e.attachEvent&&e.attachEvent("on"+t,r)},removeEvent:function(e,t,r){e.addEventListener?e.removeEventListener(t,r,!1):e.attachEvent&&e.detachEvent("on"+t,r)},preventDefaultEvent:function(e){e.preventDefault?e.preventDefault():e.returnValue=!1}},c={tabKey:function(e){if(s.fenceRange()){if(9==e.keyCode){s.preventDefaultEvent(e);var t=!0;s._callHook("tab:before");var r=s.cursor.selection(),a=s.cursor.get(),o=s.editor.get();if(r){for(var i=r.start;i--;)if("\n"==o.charAt(i)){r.start=i+1;break}var c,l=o.substring(r.start,r.end),u=l.split("\n");if(e.shiftKey){for(c=0;c<u.length;c++)u[c].substring(0,n.length)==n&&(u[c]=u[c].substring(n.length));l=u.join("\n"),s.editor.set(o.substring(0,r.start)+l+o.substring(r.end)),s.cursor.set(r.start,r.start+l.length)}else{for(c in u)u[c]=n+u[c];l=u.join("\n"),s.editor.set(o.substring(0,r.start)+l+o.substring(r.end)),s.cursor.set(r.start,r.start+l.length)}}else{var f=o.substring(0,a),d=o.substring(a),p=f+n+d;e.shiftKey?o.substring(a-n.length,a)==n&&(p=o.substring(0,a-n.length)+d,s.editor.set(p),s.cursor.set(a-n.length)):(s.editor.set(p),s.cursor.set(a+n.length),t=!1)}s._callHook("tab:after")}return t}},enterKey:function(e){if(s.fenceRange()&&13==e.keyCode){s.preventDefaultEvent(e),s._callHook("enter:before");var t,r,o=s.cursor.get(),c=s.editor.get(),l=c.substring(0,o),u=c.substring(o),f=l.charAt(l.length-1),d=u.charAt(0),p=s.levelsDeep(),g="",v="";if(p){for(;p--;)g+=n;for(g=g,t=g.length+1,r=0;r<i.keyMap.length;r++)i.keyMap[r].open==f&&i.keyMap[r].close==d&&(v=a)}else t=1;var h=l+a+g+v+g.substring(0,g.length-n.length)+u;s.editor.set(h),s.cursor.set(o+t),s._callHook("enter:after")}},deleteKey:function(e){if(s.fenceRange()&&8==e.keyCode){s.preventDefaultEvent(e),s._callHook("delete:before");var t,r=s.cursor.get(),n=s.editor.get(),a=n.substring(0,r),o=n.substring(r),c=a.charAt(a.length-1),l=o.charAt(0);if(s.cursor.selection()===!1){for(t=0;t<i.keyMap.length;t++)if(i.keyMap[t].open==c&&i.keyMap[t].close==l){var u=n.substring(0,r-1)+n.substring(r+1);return s.editor.set(u),void s.cursor.set(r-1)}var u=n.substring(0,r-1)+n.substring(r);s.editor.set(u),s.cursor.set(r-1)}else{var f=s.cursor.selection(),u=n.substring(0,f.start)+n.substring(f.end);s.editor.set(u),s.cursor.set(r)}s._callHook("delete:after")}}},l={openedChar:function(e,t){s.preventDefaultEvent(t),s._callHook("openChar:before");var r=s.cursor.get(),n=s.editor.get(),a=n.substring(0,r),i=n.substring(r),c=a+e.open+e.close+i;o.textarea.value=c,s.cursor.set(r+1),s._callHook("openChar:after")},closedChar:function(e,t){var r=s.cursor.get(),n=s.editor.get(),a=n.substring(r,r+1);return a==e.close&&(s.preventDefaultEvent(t),s._callHook("closeChar:before"),s.cursor.set(s.cursor.get()+1),s._callHook("closeChar:after"),!0)}},u={filter:function(e){if(s.fenceRange()){var t=e.which||e.keyCode;if(39!=t&&(40!=t||0!==e.which)){var r,n=String.fromCharCode(t);for(r=0;r<i.keyMap.length;r++)if(i.keyMap[r].close==n){var a=o.overwrite&&l.closedChar(i.keyMap[r],e);!a&&i.keyMap[r].open==n&&o.autoOpen&&l.openedChar(i.keyMap[r],e)}else i.keyMap[r].open==n&&o.autoOpen&&l.openedChar(i.keyMap[r],e)}}},listen:function(){o.replaceTab&&s.addEvent(o.textarea,"keydown",c.tabKey),o.autoIndent&&s.addEvent(o.textarea,"keydown",c.enterKey),o.autoStrip&&s.addEvent(o.textarea,"keydown",c.deleteKey),s.addEvent(o.textarea,"keypress",u.filter),s.addEvent(o.textarea,"keydown",function(){s._callHook("keydown")}),s.addEvent(o.textarea,"keyup",function(){s._callHook("keyup")})}},f=function(e){e.textarea&&(s._callHook("init:before",!1),s.deepExtend(o,e),s.defineNewLine(),o.softTabs?n=" ".repeat(o.tabSize):(n="\t",s.defineTabSize(o.tabSize)),u.listen(),s._callHook("init:after",!1))};this.destroy=function(){s.removeEvent(o.textarea,"keydown",c.tabKey),s.removeEvent(o.textarea,"keydown",c.enterKey),s.removeEvent(o.textarea,"keydown",c.deleteKey),s.removeEvent(o.textarea,"keypress",u.filter)},f(r)};"undefined"!=typeof module&&module.exports&&(module.exports=r),"undefined"==typeof ender&&(this.Behave=r,this.BehaveHooks=t),"function"==typeof define&&define.amd&&define("behave",[],function(){return r})}).call(this),function(e){e(document).on("sowsetupformfield",".siteorigin-widget-field-type-code",function(t){var r=e(this);new Behave({textarea:r.find(".siteorigin-widget-code-input").get(0)})})}(jQuery);
base/inc/fields/js/media-field.js ADDED
@@ -0,0 +1,371 @@
1
+ ( function( $ ) {
2
+
3
+ $(document).on( 'sowsetupformfield', '.siteorigin-widget-field-type-media', function(e) {
4
+ var $media = $(this).find('> .media-field-wrapper');
5
+ var $field = $media.closest('.siteorigin-widget-field');
6
+
7
+ // Handle the media uploader
8
+ $media.find( '.media-upload-button' ).click(function(e){
9
+ e.preventDefault();
10
+ if( typeof wp.media === 'undefined' ) {
11
+ return;
12
+ }
13
+
14
+ var $ = $(this);
15
+ var $c = $(this ).closest('.siteorigin-widget-field');
16
+ var frame = $(this ).data('frame');
17
+
18
+ // If the media frame already exists, reopen it.
19
+ if ( frame ) {
20
+ frame.open();
21
+ return false;
22
+ }
23
+
24
+ // Create the media frame.
25
+ frame = wp.media( {
26
+ // Set the title of the modal.
27
+ title: $.data('choose'),
28
+
29
+ // Tell the modal to show only images.
30
+ library: {
31
+ type: $.data('library').split(',').map(function(v){ return v.trim(); })
32
+ },
33
+
34
+ // Customize the submit button.
35
+ button: {
36
+ // Set the text of the button.
37
+ text: $.data('update'),
38
+ // Tell the button not to close the modal, since we're
39
+ // going to refresh the page when the image is selected.
40
+ close: false
41
+ }
42
+ } );
43
+
44
+ // Store the frame
45
+ $.data('frame', frame);
46
+
47
+ // When an image is selected, run a callback.
48
+ frame.on( 'select', function() {
49
+ // Grab the selected attachment.
50
+ var attachment = frame.state().get('selection').first().attributes;
51
+
52
+ $c.find('.current .title' ).html(attachment.title);
53
+ var $inputField = $c.find( 'input[type=hidden]' );
54
+ $inputField.val(attachment.id);
55
+ $inputField.trigger('change');
56
+
57
+ if(typeof attachment.sizes !== 'undefined'){
58
+ if(typeof attachment.sizes.thumbnail !== 'undefined'){
59
+ $c.find('.current .thumbnail' ).attr('src', attachment.sizes.thumbnail.url).fadeIn();
60
+ }
61
+ else {
62
+ $c.find('.current .thumbnail' ).attr('src', attachment.sizes.full.url).fadeIn();
63
+ }
64
+ }
65
+ else{
66
+ $c.find('.current .thumbnail' ).attr('src', attachment.icon).fadeIn();
67
+ }
68
+
69
+ $field.find('.media-remove-button').removeClass('remove-hide');
70
+
71
+ frame.close();
72
+ } );
73
+
74
+ // Finally, open the modal.
75
+ frame.open();
76
+ });
77
+
78
+ $media.find('.current' )
79
+ .mouseenter(function(){
80
+ var t = $(this ).find('.title' );
81
+ if( t.html() !== ''){
82
+ t.fadeIn('fast');
83
+ }
84
+ })
85
+ .mouseleave(function(){
86
+ $(this ).find('.title' ).clearQueue().fadeOut('fast');
87
+ });
88
+
89
+ $field.find('a.media-remove-button' )
90
+ .click( function( e ){
91
+ e.preventDefault();
92
+ $field.find('.current .title' ).html('');
93
+ $field.find('input[type=hidden]' ).val('');
94
+ $field.find('.current .thumbnail' ).fadeOut('fast');
95
+ $(this).addClass('remove-hide');
96
+ } );
97
+
98
+ // Everything for the dialog
99
+ var dialog = false;
100
+
101
+ var reflowDialog = function() {
102
+ if( ! dialog ) return;
103
+
104
+ var results = dialog.find('.so-widgets-image-results');
105
+ if( results.length === 0 ) return;
106
+
107
+ var width = results.width(),
108
+ perRow = Math.floor( width / 276 ),
109
+ spare = ( width - perRow * 276 ),
110
+ resultWidth = spare / perRow + 260;
111
+
112
+ results.find( '.so-widgets-result-image' ).css( {
113
+ 'width' : resultWidth,
114
+ 'height' : resultWidth / 1.4
115
+ } );
116
+ };
117
+ $(window).resize( reflowDialog );
118
+
119
+ var setupDialog = function(){
120
+ if( ! dialog ) {
121
+ // Create the dialog
122
+ dialog = $( $('#so-widgets-bundle-tpl-image-search-dialog').html().trim() ).appendTo( 'body' );
123
+ dialog.find( '.close' ).click( function(){
124
+ dialog.hide();
125
+ } );
126
+
127
+ var results = dialog.find( '.so-widgets-image-results' );
128
+
129
+ var fetchImages = function( query, page ){
130
+ dialog.find( '.so-widgets-results-loading' ).fadeIn('fast');
131
+ dialog.find( '.so-widgets-results-loading strong' ).html(
132
+ dialog.find( '.so-widgets-results-loading strong' ).data( 'loading' )
133
+ );
134
+ dialog.find( '.so-widgets-results-more' ).hide();
135
+
136
+ $.get(
137
+ ajaxurl,
138
+ {
139
+ 'action' : 'so_widgets_image_search',
140
+ 'q' : query,
141
+ 'page' : page,
142
+ '_sononce' : dialog.find('input[name="_sononce"]').val()
143
+ },
144
+ function( response ){
145
+ if( response.error ) {
146
+ alert( response.message );
147
+ return;
148
+ }
149
+
150
+ results.removeClass( 'so-loading' );
151
+ $.each( response.items, function( i, r ){
152
+ var result = $( $('#so-widgets-bundle-tpl-image-search-result').html().trim() )
153
+ .appendTo( results )
154
+ .addClass( 'source-' + r.source );
155
+ var img = result.find('.so-widgets-result-image');
156
+
157
+ // Preload the image
158
+ img.css( 'background-image', 'url(' + r.thumbnail + ')' );
159
+ img.data( 'thumbnail', r.thumbnail );
160
+ img.data( 'preview', r.preview );
161
+
162
+ if( r.url ) {
163
+ img.attr( {
164
+ 'href': r.url,
165
+ 'target': '_blank'
166
+ } );
167
+ }
168
+
169
+ if( r.full_url ) {
170
+ img.data( {
171
+ 'full_url' : r.full_url,
172
+ 'import_signature' : r.import_signature
173
+ } );
174
+ img.attr( 'href', r.full_url );
175
+ }
176
+
177
+ if( r.source === 'shutterstock' ) {
178
+ img.append( $('#so-widgets-bundle-tpl-image-search-result-sponsored').html() );
179
+ }
180
+ } );
181
+
182
+ if( page === 1 ) {
183
+ dialog.find('#so-widgets-image-search-suggestions ul').empty();
184
+ $.each( response.keywords, function( i, r ){
185
+ dialog.find('#so-widgets-image-search-suggestions').show();
186
+ dialog.find('#so-widgets-image-search-suggestions ul').append(
187
+ $('<li></li>') . append( $('<a href="#"></a>').html( r ).data( 'keyword', r ) )
188
+ );
189
+ } );
190
+ }
191
+
192
+ dialog.find( '.so-widgets-results-loading' ).fadeOut('fast');
193
+
194
+ reflowDialog();
195
+ dialog
196
+ .find( '.so-widgets-results-more' ).show()
197
+ .find( 'button' ).data( { 'query': query, 'page' : page+1 } );
198
+ }
199
+ );
200
+
201
+ }
202
+
203
+ // Setup the search
204
+ dialog.find('#so-widgets-image-search-form').submit( function( e ){
205
+ e.preventDefault();
206
+
207
+ // Perform the search
208
+ var q = dialog.find('.so-widgets-search-input').val();
209
+ results.empty();
210
+
211
+ if( q !== '' ) {
212
+ // Send the query to the server
213
+ fetchImages( q, 1 );
214
+ }
215
+ } );
216
+
217
+ // Clicking on the related search buttons
218
+ dialog.on( 'click', '.so-keywords-list a', function( e ){
219
+ e.preventDefault();
220
+ var $ = $(this).blur();
221
+ dialog.find('.so-widgets-search-input').val( $.data( 'keyword' ) );
222
+ dialog.find('#so-widgets-image-search-form').submit();
223
+ } );
224
+
225
+ // Clicking on the more button
226
+ dialog.find('.so-widgets-results-more button').click( function(){
227
+ var $ = $(this);
228
+ fetchImages( $.data( 'query' ), $.data( 'page' ) );
229
+ } );
230
+
231
+ var hoverTimeout;
232
+
233
+ // Clicking on an image to import it
234
+ dialog.on( 'click', '.so-widgets-result-image', function( e ){
235
+ var $ = $(this);
236
+ if( ! $.data( 'full_url' ) ) {
237
+ return;
238
+ }
239
+
240
+ e.preventDefault();
241
+
242
+ if( confirm( dialog.data('confirm-import') ) ) {
243
+ dialog.addClass( 'so-widgets-importing' );
244
+
245
+ var postId = $( '#post_ID' ).val();
246
+ if( postId === null ) {
247
+ postId = '';
248
+ }
249
+
250
+ // Send the message to import the URL
251
+ $.get(
252
+ ajaxurl,
253
+ {
254
+ 'action' : 'so_widgets_image_import',
255
+ 'full_url' : $.data( 'full_url' ),
256
+ 'import_signature' : $.data( 'import_signature' ),
257
+ 'post_id' : postId,
258
+ '_sononce' : dialog.find('input[name="_sononce"]').val()
259
+ },
260
+ function( response ) {
261
+ dialog.find('#so-widgets-image-search-frame').removeClass( 'so-widgets-importing' );
262
+
263
+ if( response.error === false ) {
264
+ // This was a success
265
+ dialog.hide();
266
+ dialog.find( '.so-widgets-results-loading' ).hide();
267
+ $field.find( 'input[type=hidden]' ).val( response.attachment_id );
268
+ $field.find('.current .thumbnail' ).attr('src', response.thumb ).fadeIn();
269
+ }
270
+ else {
271
+ alert( response.message );
272
+ dialog.find( '.so-widgets-results-loading' ).hide();
273
+ }
274
+ }
275
+ );
276
+
277
+ // Clear the dialog
278
+ dialog.find( '.so-widgets-results-loading' ).fadeIn('fast');
279
+ dialog.find( '.so-widgets-results-loading strong' ).html(
280
+ dialog.find( '.so-widgets-results-loading strong' ).data( 'importing' )
281
+ );
282
+ dialog.find( '.so-widgets-results-more' ).hide();
283
+ dialog.find('#so-widgets-image-search-frame').addClass( 'so-widgets-importing' );
284
+ }
285
+ } );
286
+
287
+ // Hovering over an image to preview it
288
+ var previewWindow = dialog.find('.so-widgets-preview-window');
289
+ dialog
290
+ .on( 'mouseenter', '.so-widgets-result-image', function(){
291
+ var $ = $(this),
292
+ preview = $.data('preview');
293
+
294
+ clearTimeout( hoverTimeout );
295
+
296
+ hoverTimeout = setTimeout( function(){
297
+ // Scale the preview sizes
298
+ var scalePreviewX = 1, scalePreviewY = 1;
299
+ if( preview[1] > $( window ).outerWidth() *0.33 ) {
300
+ scalePreviewX = $( window ).outerWidth() *0.33 / preview[1];
301
+ }
302
+ if( preview[2] > $( window ).outerHeight() *0.5 ) {
303
+ scalePreviewY = $( window ).outerHeight() *0.5 / preview[2];
304
+ }
305
+ var scalePreview = Math.min( scalePreviewX, scalePreviewY );
306
+ // Never upscale
307
+ if( scalePreview > 1 ) {
308
+ scalePreview = 1;
309
+ }
310
+
311
+ previewWindow.show()
312
+ .find('.so-widgets-preview-window-inside')
313
+ .css( {
314
+ 'background-image' : 'url(' + $.data('thumbnail') + ')',
315
+ 'width' : preview[1] * scalePreview,
316
+ 'height' : preview[2] * scalePreview
317
+ } )
318
+ .append( $( '<img />' ).attr( 'src', preview[0] ) );
319
+
320
+ dialog.trigger('mousemove');
321
+ }, 1000 );
322
+
323
+ } )
324
+ .on( 'mouseleave', '.so-widgets-result-image', function(){
325
+ previewWindow.hide().find('img').remove();
326
+ clearTimeout( hoverTimeout );
327
+ } );
328
+
329
+ var lastX, lastY;
330
+ dialog.on( 'mousemove', function( e ){
331
+ if( e.clientX ) lastX = e.clientX;
332
+ if( e.clientY ) lastY = e.clientY;
333
+
334
+ if( previewWindow.is( ':visible' ) ) {
335
+ var ph = previewWindow.outerHeight(),
336
+ pw = previewWindow.outerWidth(),
337
+ wh = $( window ).outerHeight(),
338
+ ww = $( window ).outerWidth();
339
+
340
+
341
+ // Calculate the top position
342
+ var top = lastY - ph/2;
343
+ top = Math.max( top, 10 );
344
+ top = Math.min( top, wh - 10 - ph );
345
+
346
+ // Calculate the left position
347
+ var left = (lastX < ww/2) ? lastX + 15 : lastX - 15 - pw;
348
+
349
+ // Figure out where the preview needs to go
350
+ previewWindow.css({
351
+ 'top': top,
352
+ 'left': left
353
+ });
354
+
355
+ }