SiteOrigin Widgets Bundle - Version 1.20.0

Version Description

  • 01 June 2021 =
  • Added integration for WP Super Cache and Swift Performance plugins.
  • Button: Added a Mobile align setting and global Button Responsive Breakpoint setting at Plugins > SiteOrigin Widgets > Button: Settings.
  • Contact Form: Allowed whitelisted HTML in checkbox option fields.
  • Headline: Fixed invalid font property when multiple font variants in use.
  • Image: Added native lazy loading attribute.
  • Image Grid: Added native lazy loading attribute for external images.
  • Image Grid: Changed Spacing setting to a multi-measurement field and renamed it to Image padding.
  • Sliders: Added Loop slide background videos setting.
  • Sliders: Improved background video autoplay setting description.
  • Sliders: Removed wp_is_mobile dependency to improve caching.
  • Video Player: Added Loop setting for YouTube videos.
  • Widget Block: Resolved Contact Form nonce error.
  • Widget Block: Resolved Only variables should be passed by reference notice.
  • Developer: Cleared the Icon Widget default icon if the icon font family doesn't exist.
  • Developer: Fixed multiple media remove link detection.
Download this release

Release Info

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

Code changes from version 1.19.0 to 1.20.0

base/base.php CHANGED
@@ -142,6 +142,8 @@ function siteorigin_widget_get_font($font_value) {
142
  if ( count( $font_parts ) > 1 ) {
143
  $font['weight'] = $font_parts[1];
144
  $font_url_param .= ':' . $font_parts[1];
 
 
145
  }
146
  $font['url'] = 'https://fonts.googleapis.com/css?family=' . $font_url_param;
147
  $style_name = 'sow-google-font-' . strtolower( $font['family'] );
@@ -270,9 +272,9 @@ function siteorigin_widgets_font_families( ){
270
  foreach ( $variants as $variant ) {
271
  if ( $variant == 'regular' || $variant == 400 ) {
272
  $font_families[ $font ] = $font;
273
- }
274
- else {
275
- $font_families[ $font . ':' . $variant ] = $font . ' (' . $variant . ')';
276
  }
277
  }
278
  }
142
  if ( count( $font_parts ) > 1 ) {
143
  $font['weight'] = $font_parts[1];
144
  $font_url_param .= ':' . $font_parts[1];
145
+ $font['weight_raw'] = filter_var( $font['weight'], FILTER_SANITIZE_NUMBER_INT );
146
+ $font['style'] = ! is_numeric( $font['weight'] ) || $font['weight'] == 'italic' ? 'italic' : '';
147
  }
148
  $font['url'] = 'https://fonts.googleapis.com/css?family=' . $font_url_param;
149
  $style_name = 'sow-google-font-' . strtolower( $font['family'] );
272
  foreach ( $variants as $variant ) {
273
  if ( $variant == 'regular' || $variant == 400 ) {
274
  $font_families[ $font ] = $font;
275
+ } else {
276
+ $label_variant = is_numeric( $variant ) && $variant != 'italic'? $variant : filter_var( $variant, FILTER_SANITIZE_NUMBER_INT ) . ' italic';
277
+ $font_families[ $font . ':' . $variant ] = $font . ' (' . $label_variant . ')';
278
  }
279
  }
280
  }
base/inc/fields/icon.class.php CHANGED
@@ -15,6 +15,30 @@ class SiteOrigin_Widget_Field_Icon extends SiteOrigin_Widget_Field_Base {
15
 
16
  protected $icons_callback;
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  protected function render_field( $value, $instance ) {
19
  $widget_icon_families = $this->get_widget_icon_families();
20
 
15
 
16
  protected $icons_callback;
17
 
18
+
19
+ protected function initialize() {
20
+ if ( ! empty( $this->default ) ) {
21
+ $widget_icon_families = $this->get_widget_icon_families();
22
+ // If there are no icon families, don't proceed.
23
+ if ( empty( $widget_icon_families ) ) {
24
+ return;
25
+ }
26
+
27
+ $icon_families_styles = self::get_icon_families_styles( $widget_icon_families );
28
+ $value_parts = self::get_value_parts( $this->default, $icon_families_styles );
29
+
30
+ // Check if the font family of the default icon, and the icon exists.
31
+ // The last check accounts for the Font Awesome Migration code that adds a default style.
32
+ if (
33
+ ! isset( $widget_icon_families[ $value_parts['family'] ] ) ||
34
+ ! isset( $widget_icon_families[ $value_parts['family'] ]['icons'] ) ||
35
+ empty( $widget_icon_families[ $value_parts['family'] ]['icons'][ $value_parts['icon'] ] )
36
+ ) {
37
+ $this->default = null;
38
+ }
39
+ }
40
+ }
41
+
42
  protected function render_field( $value, $instance ) {
43
  $widget_icon_families = $this->get_widget_icon_families();
44
 
base/inc/fields/js/multi-measurement-field.js CHANGED
@@ -23,7 +23,7 @@
23
  var valueResult = values[ index ].match( /(\d+\.?\d*)([a-z%]+)*/ );
24
  if ( valueResult && valueResult.length ) {
25
  var amount = valueResult[ 1 ];
26
- var unit = valueResult[ 2 ];
27
  $( element ).val( amount );
28
  $( element ).find( '+ .sow-multi-measurement-select-unit' ).val( unit );
29
  }
23
  var valueResult = values[ index ].match( /(\d+\.?\d*)([a-z%]+)*/ );
24
  if ( valueResult && valueResult.length ) {
25
  var amount = valueResult[ 1 ];
26
+ var unit = typeof valueResult[ 2 ] != 'undefined' ? valueResult[ 2 ] : 'px';
27
  $( element ).val( amount );
28
  $( element ).find( '+ .sow-multi-measurement-select-unit' ).val( unit );
29
  }
base/inc/fields/js/multi-measurement-field.min.js CHANGED
@@ -1 +1 @@
1
- !function(t){t(document).on("sowsetupformfield",".siteorigin-widget-field-type-multi-measurement",(function(i){var e=t(this).find('input[type="hidden"][class="siteorigin-widget-input"]'),n=e.data("separator"),a=e.data("autofill"),l=""===e.val()?[]:e.val().split(n),u=t(this).find(".sow-multi-measurement-input"),s=t(this).find(".sow-multi-measurement-input-container"),o=function(t){var i=""===e.val()?[]:e.val().split(n),a=t.find("+ .sow-multi-measurement-select-unit");i[u.index(t)]=t.val()+(""===t.val()?"":a.val()),e.val(i.join(n))};u.each((function(i,e){if(l.length>i){var n=l[i].match(/(\d+\.?\d*)([a-z%]+)*/);if(n&&n.length){var a=n[1],u=n[2];t(e).val(a),t(e).find("+ .sow-multi-measurement-select-unit").val(u)}}else o(t(e))})),s.on("change",(function(i){var e=t(i.currentTarget).find("> .sow-multi-measurement-input"),n=a;a&&u.each((function(i,a){t(a).attr("id")!==e.eq(0).attr("id")&&(n=n&&!t(a).val())})),n?u.each((function(i,n){t(n).val(e.val()),o(t(n))})):o(e)}))}))}(jQuery);
1
+ !function(t){t(document).on("sowsetupformfield",".siteorigin-widget-field-type-multi-measurement",(function(i){var e=t(this).find('input[type="hidden"][class="siteorigin-widget-input"]'),n=e.data("separator"),a=e.data("autofill"),l=""===e.val()?[]:e.val().split(n),u=t(this).find(".sow-multi-measurement-input"),s=t(this).find(".sow-multi-measurement-input-container"),o=function(t){var i=""===e.val()?[]:e.val().split(n),a=t.find("+ .sow-multi-measurement-select-unit");i[u.index(t)]=t.val()+(""===t.val()?"":a.val()),e.val(i.join(n))};u.each((function(i,e){if(l.length>i){var n=l[i].match(/(\d+\.?\d*)([a-z%]+)*/);if(n&&n.length){var a=n[1],u=void 0!==n[2]?n[2]:"px";t(e).val(a),t(e).find("+ .sow-multi-measurement-select-unit").val(u)}}else o(t(e))})),s.on("change",(function(i){var e=t(i.currentTarget).find("> .sow-multi-measurement-input"),n=a;a&&u.each((function(i,a){t(a).attr("id")!==e.eq(0).attr("id")&&(n=n&&!t(a).val())})),n?u.each((function(i,n){t(n).val(e.val()),o(t(n))})):o(e)}))}))}(jQuery);
base/inc/fields/js/multiple-media-field.js CHANGED
@@ -113,7 +113,7 @@
113
  frame.open();
114
  });
115
 
116
- $field.find( 'a.media-remove-button' ).on( 'click', function( e ) {
117
  e.preventDefault();
118
  var $currentItem = $( this ).parent();
119
 
113
  frame.open();
114
  });
115
 
116
+ $( document ).on( 'click','.siteorigin-widget-field-type-multiple_media a.media-remove-button', function( e ) {
117
  e.preventDefault();
118
  var $currentItem = $( this ).parent();
119
 
base/inc/fields/js/multiple-media-field.min.js CHANGED
@@ -1 +1 @@
1
- !function(i){i(document).on("sowsetupformfield",".siteorigin-widget-field-type-multiple_media",(function(t){var e=i(this),a=e.find(".siteorigin-widget-input"),n=a.val().split(",");e.data("initialized")||(e.find(".button").on("click",(function(t){if(t.preventDefault(),void 0!==wp.media){var l=i(this),d=i(this).data("frame");if(d)return d.open(),!1;(d=wp.media({title:l.data("choose"),library:{type:l.data("library").split(",").map((function(i){return i.trim()}))},multiple:!0,button:{text:l.data("update"),close:!1}})).on("open",(function(){if(n.length){var t=d.state().get("selection");i.each(n,(function(){t.add(wp.media.attachment(this))}))}})),l.data("frame",d),d.on("select",(function(){var t,l,o,m,f=[];i.each(d.state().get("selection").models,(function(){t=this.attributes,-1==n.indexOf(t.id.toString())&&(e.find(".multiple-media-field-template .multiple-media-field-item").clone().appendTo(e.find(".multiple-media-field-items")),o=e.find(".multiple-media-field-items .multiple-media-field-item").last(),(m=o.find(".thumbnail")).attr("title",t.title),o.attr("data-id",t.id),l=void 0!==t.sizes?void 0!==t.sizes.thumbnail?t.sizes.thumbnail.url:t.sizes.full.url:t.icon,m.attr("src",l)),f.push(t.id)})),e.find(".multiple-media-field-items .multiple-media-field-item").each((function(){-1==f.indexOf(i(this).data("id"))&&i(this).remove()})),f.length?(n=f,a.val(f.join(","))):(n=[],a.val("")),d.close()})),d.open()}})),e.find("a.media-remove-button").on("click",(function(t){t.preventDefault();var e=i(this).parent();n.splice(n.indexOf(e.data("id"))),a.val(n.join(",")),e.remove()})),e.data("initialized",!0))}))}(jQuery);
1
+ !function(i){i(document).on("sowsetupformfield",".siteorigin-widget-field-type-multiple_media",(function(t){var e=i(this),a=e.find(".siteorigin-widget-input"),n=a.val().split(",");e.data("initialized")||(e.find(".button").on("click",(function(t){if(t.preventDefault(),void 0!==wp.media){var l=i(this),d=i(this).data("frame");if(d)return d.open(),!1;(d=wp.media({title:l.data("choose"),library:{type:l.data("library").split(",").map((function(i){return i.trim()}))},multiple:!0,button:{text:l.data("update"),close:!1}})).on("open",(function(){if(n.length){var t=d.state().get("selection");i.each(n,(function(){t.add(wp.media.attachment(this))}))}})),l.data("frame",d),d.on("select",(function(){var t,l,o,m,u=[];i.each(d.state().get("selection").models,(function(){t=this.attributes,-1==n.indexOf(t.id.toString())&&(e.find(".multiple-media-field-template .multiple-media-field-item").clone().appendTo(e.find(".multiple-media-field-items")),o=e.find(".multiple-media-field-items .multiple-media-field-item").last(),(m=o.find(".thumbnail")).attr("title",t.title),o.attr("data-id",t.id),l=void 0!==t.sizes?void 0!==t.sizes.thumbnail?t.sizes.thumbnail.url:t.sizes.full.url:t.icon,m.attr("src",l)),u.push(t.id)})),e.find(".multiple-media-field-items .multiple-media-field-item").each((function(){-1==u.indexOf(i(this).data("id"))&&i(this).remove()})),u.length?(n=u,a.val(u.join(","))):(n=[],a.val("")),d.close()})),d.open()}})),i(document).on("click",".siteorigin-widget-field-type-multiple_media a.media-remove-button",(function(t){t.preventDefault();var e=i(this).parent();n.splice(n.indexOf(e.data("id"))),a.val(n.join(",")),e.remove()})),e.data("initialized",!0))}))}(jQuery);
base/inc/video.php CHANGED
@@ -7,6 +7,7 @@
7
  */
8
 
9
  class SiteOrigin_Video {
 
10
 
11
  /**
12
  * Check whether it's possible to oEmbed by testing if a provider URL can be obtained.
@@ -31,7 +32,7 @@ class SiteOrigin_Video {
31
  *
32
  * @return false|mixed|null|string|string[]
33
  */
34
- function get_video_oembed( $src, $autoplay = false, $related_videos = true ) {
35
  if ( empty( $src ) ) {
36
  return '';
37
  }
@@ -44,22 +45,30 @@ class SiteOrigin_Video {
44
  'src' => $src,
45
  'width' => $video_width,
46
  'autoplay' => $autoplay,
 
47
  ) ) );
48
 
49
  // Convert embed format to standard format to be compatible with wp_oembed_get
50
- $src = preg_replace('/https?:\/\/www.youtube.com\/embed\/([^\/]+)/', 'https://www.youtube.com/watch?v=$1', $src);
51
 
52
  $html = get_transient( 'sow-vid-embed[' . $hash . ']' );
53
  if ( empty( $html ) ) {
54
- $html = wp_oembed_get( $src, array( 'width' => $video_width ) );
55
-
56
  if ( $autoplay ) {
57
  $html = preg_replace_callback( '/src=["\'](http[^"\']*)["\']/', array(
58
  $this,
59
  'autoplay_callback'
60
  ), $html );
61
  }
62
-
 
 
 
 
 
 
 
63
  if ( empty( $related_videos ) ) {
64
  $html = preg_replace_callback( '/src=["\'](http[^"\']*)["\']/', array(
65
  $this,
@@ -85,7 +94,29 @@ class SiteOrigin_Video {
85
  function autoplay_callback( $match ) {
86
  return str_replace( $match[1], add_query_arg( 'autoplay', 1, $match[1] ), $match[0] );
87
  }
88
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  /**
90
  * The preg_replace callback that adds the rel param for YouTube videos.
91
  *
7
  */
8
 
9
  class SiteOrigin_Video {
10
+ var $src;
11
 
12
  /**
13
  * Check whether it's possible to oEmbed by testing if a provider URL can be obtained.
32
  *
33
  * @return false|mixed|null|string|string[]
34
  */
35
+ function get_video_oembed( $src, $autoplay = false, $related_videos = true, $loop = false ) {
36
  if ( empty( $src ) ) {
37
  return '';
38
  }
45
  'src' => $src,
46
  'width' => $video_width,
47
  'autoplay' => $autoplay,
48
+ 'loop' => $loop,
49
  ) ) );
50
 
51
  // Convert embed format to standard format to be compatible with wp_oembed_get
52
+ $this->src = preg_replace( '/https?:\/\/www.youtube.com\/embed\/([^\/]+)/', 'https://www.youtube.com/watch?v=$1', $src );
53
 
54
  $html = get_transient( 'sow-vid-embed[' . $hash . ']' );
55
  if ( empty( $html ) ) {
56
+ $html = wp_oembed_get( $this->src, array( 'width' => $video_width ) );
57
+
58
  if ( $autoplay ) {
59
  $html = preg_replace_callback( '/src=["\'](http[^"\']*)["\']/', array(
60
  $this,
61
  'autoplay_callback'
62
  ), $html );
63
  }
64
+
65
+ if ( $loop ) {
66
+ $html = preg_replace_callback( '/src=["\'](http[^"\']*)["\']/', array(
67
+ $this,
68
+ 'loop_callback'
69
+ ), $html );
70
+ }
71
+
72
  if ( empty( $related_videos ) ) {
73
  $html = preg_replace_callback( '/src=["\'](http[^"\']*)["\']/', array(
74
  $this,
94
  function autoplay_callback( $match ) {
95
  return str_replace( $match[1], add_query_arg( 'autoplay', 1, $match[1] ), $match[0] );
96
  }
97
+
98
+ /**
99
+ * The preg_replace callback that adds loop and playlist.
100
+ *
101
+ * @param $match
102
+ *
103
+ * @return mixed
104
+ */
105
+ function loop_callback( $match ) {
106
+ // Extract video id.
107
+ parse_str( parse_url( $this->src, PHP_URL_QUERY ), $vars );
108
+
109
+ $new_url = add_query_arg(
110
+ array(
111
+ 'loop' => 1,
112
+ // Adding the current video in a playlist allows for YouTube to loop the video.
113
+ 'playlist' => ! empty( $vars['v'] ) ? $vars['v'] : '',
114
+ ),
115
+ $match[1]
116
+ );
117
+ return str_replace( $match[1], $new_url, $match[0] );
118
+ }
119
+
120
  /**
121
  * The preg_replace callback that adds the rel param for YouTube videos.
122
  *
base/inc/widgets/base-slider.class.php CHANGED
@@ -14,14 +14,7 @@ abstract class SiteOrigin_Widget_Base_Slider extends SiteOrigin_Widget {
14
  array( 'jquery' ),
15
  SOW_BUNDLE_VERSION
16
  );
17
- if( function_exists('wp_is_mobile') && wp_is_mobile() ) {
18
- $frontend_scripts[] = array(
19
- 'sow-slider-slider-cycle2-swipe',
20
- plugin_dir_url( SOW_BUNDLE_BASE_FILE ) . 'js/jquery.cycle.swipe' . SOW_BUNDLE_JS_SUFFIX . '.js',
21
- array( 'jquery' ),
22
- SOW_BUNDLE_VERSION
23
- );
24
- }
25
  $frontend_scripts[] = array(
26
  'sow-slider-slider',
27
  plugin_dir_url( SOW_BUNDLE_BASE_FILE ) . 'js/slider/jquery.slider' . SOW_BUNDLE_JS_SUFFIX . '.js',
@@ -40,6 +33,16 @@ abstract class SiteOrigin_Widget_Base_Slider extends SiteOrigin_Widget {
40
  )
41
  )
42
  );
 
 
 
 
 
 
 
 
 
 
43
  }
44
 
45
  /**
@@ -139,7 +142,13 @@ abstract class SiteOrigin_Widget_Base_Slider extends SiteOrigin_Widget {
139
  'type' => 'checkbox',
140
  'label' => __( 'Show slide background videos on mobile', 'so-widgets-bundle' ),
141
  'description' => __( 'Allow slide background videos to appear on mobile devices that support autoplay.', 'so-widgets-bundle' ),
142
- )
 
 
 
 
 
 
143
  );
144
  }
145
 
@@ -163,7 +172,7 @@ abstract class SiteOrigin_Widget_Base_Slider extends SiteOrigin_Widget {
163
  'type' => 'checkbox',
164
  'label' => __( 'Autoplay', 'so-widgets-bundle' ),
165
  'default' => false,
166
- 'description' => __( 'Currently only for YouTube videos.', 'so-widgets-bundle' ),
167
  ),
168
 
169
  'format' => array(
@@ -219,10 +228,13 @@ abstract class SiteOrigin_Widget_Base_Slider extends SiteOrigin_Widget {
219
  function render_template_part( $part, $controls, $frames ) {
220
  switch( $part ) {
221
  case 'before_slider':
222
- ?><div class="sow-slider-base <?php if( wp_is_mobile() ) echo 'sow-slider-is-mobile' ?>" style="display: none"><?php
223
  break;
224
  case 'before_slides':
225
  $settings = $this->slider_settings( $controls );
 
 
 
226
  ?><ul class="sow-slider-images" data-settings="<?php echo esc_attr( json_encode($settings) ) ?>"><?php
227
  break;
228
  case 'after_slides':
@@ -332,7 +344,7 @@ abstract class SiteOrigin_Widget_Base_Slider extends SiteOrigin_Widget {
332
  $classes[] = 'sow-mobile-video_enabled';
333
  }
334
 
335
- $this->video_code( $background['videos'], $classes );
336
  }
337
 
338
  if( $background['opacity'] < 1 && !empty($background['image']) ) {
@@ -371,10 +383,11 @@ abstract class SiteOrigin_Widget_Base_Slider extends SiteOrigin_Widget {
371
  * @param $videos
372
  * @param array $classes
373
  */
374
- function video_code( $videos, $classes = array() ){
375
  if( empty( $videos ) ) return;
376
- $video_element = '<video class="' . esc_attr( implode( ' ', $classes ) ) . '" autoplay loop muted playsinline>';
377
 
 
378
  $so_video = new SiteOrigin_Video();
379
  foreach( $videos as $video ) {
380
  if( empty( $video['file'] ) && empty ( $video['url'] ) ) continue;
@@ -387,7 +400,7 @@ abstract class SiteOrigin_Widget_Base_Slider extends SiteOrigin_Widget {
387
  if( ! $can_oembed ) {
388
  $video_file = sow_esc_url( $video['url'] );
389
  } else {
390
- echo $so_video->get_video_oembed( $video['url'], ! empty( $video['autoplay'] ) );
391
  continue;
392
  }
393
  }
14
  array( 'jquery' ),
15
  SOW_BUNDLE_VERSION
16
  );
17
+
 
 
 
 
 
 
 
18
  $frontend_scripts[] = array(
19
  'sow-slider-slider',
20
  plugin_dir_url( SOW_BUNDLE_BASE_FILE ) . 'js/slider/jquery.slider' . SOW_BUNDLE_JS_SUFFIX . '.js',
33
  )
34
  )
35
  );
36
+ add_action( 'wp_enqueue_scripts', array( $this, 'register_cycle_swipe' ) );
37
+ }
38
+
39
+ function register_cycle_swipe() {
40
+ wp_register_script(
41
+ 'sow-slider-slider-cycle2-swipe',
42
+ plugin_dir_url( SOW_BUNDLE_BASE_FILE ) . 'js/jquery.cycle.swipe' . SOW_BUNDLE_JS_SUFFIX . '.js',
43
+ array( 'jquery' ),
44
+ SOW_BUNDLE_VERSION
45
+ );
46
  }
47
 
48
  /**
142
  'type' => 'checkbox',
143
  'label' => __( 'Show slide background videos on mobile', 'so-widgets-bundle' ),
144
  'description' => __( 'Allow slide background videos to appear on mobile devices that support autoplay.', 'so-widgets-bundle' ),
145
+ ),
146
+
147
+ 'loop_background_videos' => array(
148
+ 'type' => 'checkbox',
149
+ 'label' => __( 'Loop slide background videos', 'so-widgets-bundle' ),
150
+ 'default' => false,
151
+ ),
152
  );
153
  }
154
 
172
  'type' => 'checkbox',
173
  'label' => __( 'Autoplay', 'so-widgets-bundle' ),
174
  'default' => false,
175
+ 'description' => __( 'Autoplay can only be disabled for YouTube videos.', 'so-widgets-bundle' ),
176
  ),
177
 
178
  'format' => array(
228
  function render_template_part( $part, $controls, $frames ) {
229
  switch( $part ) {
230
  case 'before_slider':
231
+ ?><div class="sow-slider-base" style="display: none"><?php
232
  break;
233
  case 'before_slides':
234
  $settings = $this->slider_settings( $controls );
235
+ if ( $settings['swipe'] ) {
236
+ wp_enqueue_script( 'sow-slider-slider-cycle2-swipe' );
237
+ }
238
  ?><ul class="sow-slider-images" data-settings="<?php echo esc_attr( json_encode($settings) ) ?>"><?php
239
  break;
240
  case 'after_slides':
344
  $classes[] = 'sow-mobile-video_enabled';
345
  }
346
 
347
+ $this->video_code( $background['videos'], $classes, $controls );
348
  }
349
 
350
  if( $background['opacity'] < 1 && !empty($background['image']) ) {
383
  * @param $videos
384
  * @param array $classes
385
  */
386
+ function video_code( $videos, $classes = array(), $controls = array() ){
387
  if( empty( $videos ) ) return;
388
+ $loop = ! empty( $controls['loop_background_videos'] ) && $controls['loop_background_videos'] ? 'loop' : '';
389
 
390
+ $video_element = '<video class="' . esc_attr( implode( ' ', $classes ) ) . '" autoplay ' . $loop . ' muted playsinline>';
391
  $so_video = new SiteOrigin_Video();
392
  foreach( $videos as $video ) {
393
  if( empty( $video['file'] ) && empty ( $video['url'] ) ) continue;
400
  if( ! $can_oembed ) {
401
  $video_file = sow_esc_url( $video['url'] );
402
  } else {
403
+ echo $so_video->get_video_oembed( $video['url'], ! empty( $video['autoplay'] ), false, $loop );
404
  continue;
405
  }
406
  }
base/siteorigin-widget.class.php CHANGED
@@ -292,11 +292,10 @@ abstract class SiteOrigin_Widget extends WP_Widget {
292
  $style = $this->get_style_name( $instance );
293
 
294
  $upload_dir = wp_upload_dir();
295
- $this->clear_file_cache();
296
 
297
  if( !empty($style) ) {
298
  $hash = $this->get_style_hash( $instance );
299
- $css_name = $this->id_base.'-'.$style.'-'.$hash;
300
 
301
  //Ensure styles aren't generated and enqueued more than once.
302
  $in_preview = $this->is_preview( $instance ) || ( isset( $_POST['action'] ) && $_POST['action'] == 'so_widgets_preview' );
@@ -734,7 +733,10 @@ abstract class SiteOrigin_Widget extends WP_Widget {
734
  }
735
 
736
  // Remove the old CSS, it'll be regenerated on page load.
737
- $this->delete_css( $this->modify_instance( $old_instance ) );
 
 
 
738
  return $new_instance;
739
  }
740
 
@@ -749,7 +751,7 @@ abstract class SiteOrigin_Widget extends WP_Widget {
749
 
750
  $style = $this->get_style_name($instance);
751
  $hash = $this->get_style_hash( $instance );
752
- $name = $this->id_base.'-'.$style.'-'.$hash.'.css';
753
 
754
  $css = $this->get_instance_css($instance);
755
 
@@ -801,7 +803,7 @@ abstract class SiteOrigin_Widget extends WP_Widget {
801
 
802
  $style = $this->get_style_name($instance);
803
  $hash = $this->get_style_hash( $instance );
804
- $name = $this->id_base.'-'.$style.'-'.$hash;
805
 
806
  $wp_filesystem->delete($upload_dir['basedir'] . '/siteorigin-widgets/' . $name . '.css');
807
  if ( in_array( $name, $this->generated_css ) ) {
@@ -817,38 +819,12 @@ abstract class SiteOrigin_Widget extends WP_Widget {
817
  }
818
 
819
  /**
820
- * Clear all old CSS files
821
  *
822
- * @var bool $force Must we force a cache refresh.
823
  */
824
  public static function clear_file_cache( $force_delete = false ){
825
- // Use this variable to ensure this only runs once per request
826
- static $done = false;
827
- if ( $done && !$force_delete ) return;
828
-
829
- if( !get_transient('sow:cleared') || $force_delete ) {
830
-
831
- require_once ABSPATH . 'wp-admin/includes/file.php';
832
- if( WP_Filesystem() ) {
833
- global $wp_filesystem;
834
- $upload_dir = wp_upload_dir();
835
-
836
- $list = $wp_filesystem->dirlist( $upload_dir['basedir'] . '/siteorigin-widgets/' );
837
- if ( ! empty( $list ) ) {
838
- foreach($list as $file) {
839
- if( $file['lastmodunix'] < time() - self::$css_expire || $force_delete ) {
840
- // Delete the file
841
- $wp_filesystem->delete( $upload_dir['basedir'] . '/siteorigin-widgets/' . $file['name'] );
842
- }
843
- }
844
- }
845
- }
846
-
847
- // Set this transient so we know when to clear all the generated CSS.
848
- set_transient('sow:cleared', true, self::$css_expire);
849
- }
850
-
851
- $done = true;
852
  }
853
 
854
  /**
@@ -906,7 +882,7 @@ abstract class SiteOrigin_Widget extends WP_Widget {
906
  if( ! empty( $less ) ) {
907
  $style = $this->get_style_name( $instance );
908
  $hash = $this->get_style_hash( $instance );
909
- $css_name = $this->id_base . '-' . $style . '-' . $hash;
910
 
911
  //we assume that any remaining @imports are plain css imports and should be kept outside selectors
912
  $css_imports = '';
292
  $style = $this->get_style_name( $instance );
293
 
294
  $upload_dir = wp_upload_dir();
 
295
 
296
  if( !empty($style) ) {
297
  $hash = $this->get_style_hash( $instance );
298
+ $css_name = $this->id_base . '-' . $style . '-' . $hash . ( ! empty( $instance['panels_info'] ) ? '-' . get_the_id() : '' );
299
 
300
  //Ensure styles aren't generated and enqueued more than once.
301
  $in_preview = $this->is_preview( $instance ) || ( isset( $_POST['action'] ) && $_POST['action'] == 'so_widgets_preview' );
733
  }
734
 
735
  // Remove the old CSS, it'll be regenerated on page load.
736
+ if ( $form_type == 'widget' ) {
737
+ $this->delete_css( $this->modify_instance( $old_instance ) );
738
+ }
739
+
740
  return $new_instance;
741
  }
742
 
751
 
752
  $style = $this->get_style_name($instance);
753
  $hash = $this->get_style_hash( $instance );
754
+ $name = $this->id_base . '-' . $style . '-' . $hash . ( ! empty( $instance['panels_info'] ) ? '-' . get_the_id() : '' ) . '.css';
755
 
756
  $css = $this->get_instance_css($instance);
757
 
803
 
804
  $style = $this->get_style_name($instance);
805
  $hash = $this->get_style_hash( $instance );
806
+ $name = $this->id_base . '-' . $style . '-' . $hash . ( ! empty( $instance['panels_info'] ) ? '-' . get_the_id() : '' );
807
 
808
  $wp_filesystem->delete($upload_dir['basedir'] . '/siteorigin-widgets/' . $name . '.css');
809
  if ( in_array( $name, $this->generated_css ) ) {
819
  }
820
 
821
  /**
822
+ * Clear all old CSS files.
823
  *
824
+ * @var bool $force_delete Whether to forcefully clear the file cache.
825
  */
826
  public static function clear_file_cache( $force_delete = false ){
827
+ SiteOrigin_Widgets_Bundle::single()->clear_file_cache( $force_delete, self::$css_expire );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
828
  }
829
 
830
  /**
882
  if( ! empty( $less ) ) {
883
  $style = $this->get_style_name( $instance );
884
  $hash = $this->get_style_hash( $instance );
885
+ $css_name = $this->id_base . '-' . $style . '-' . $hash . ( ! empty( $instance['panels_info'] ) ? '-' . get_the_id() : '' );
886
 
887
  //we assume that any remaining @imports are plain css imports and should be kept outside selectors
888
  $css_imports = '';
compat/block-editor/widget-block.js CHANGED
@@ -11,6 +11,17 @@
11
  var Spinner = components.Spinner;
12
  var __ = i18n.__;
13
 
 
 
 
 
 
 
 
 
 
 
 
14
  registerBlockType( 'sowb/widget-block', {
15
  title: __( 'SiteOrigin Widget', 'so-widgets-bundle' ),
16
 
@@ -79,6 +90,33 @@
79
  }
80
  }
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  function switchToEditing() {
83
  props.setState( { editing: true, formInitialized: false } );
84
  }
@@ -105,12 +143,16 @@
105
  props.setAttributes( { widgetData: sowbForms.getWidgetFormValues( $mainForm ) } );
106
  }
107
  $mainForm.on( 'change', function () {
108
- props.setAttributes( { widgetData: sowbForms.getWidgetFormValues( $mainForm ) } );
109
  props.setState( {
110
  widgetSettingsChanged: true,
111
  widgetPreviewHtml: null,
112
  previewInitialized: false
113
  } );
 
 
 
 
 
114
  } );
115
  props.setState( { formInitialized: true } );
116
  }
@@ -146,17 +188,7 @@
146
  .done( function( widgetForm ) {
147
  props.setState( { widgetFormHtml: widgetForm } );
148
  } )
149
- .fail( function ( response ) {
150
-
151
- var errorMessage = '';
152
- if ( response.hasOwnProperty( 'responseJSON' ) ) {
153
- errorMessage = response.responseJSON.message;
154
- } else if ( response.hasOwnProperty( 'responseText' ) ) {
155
- errorMessage = response.responseText;
156
- }
157
-
158
- props.setState( { widgetFormHtml: '<div>' + errorMessage + '</div>', } );
159
- });
160
  }
161
 
162
  var widgetForm = props.widgetFormHtml ? props.widgetFormHtml : '';
@@ -229,40 +261,7 @@
229
  widgetHtml: null,
230
  widgetIcons: null
231
  } );
232
- jQuery.post( {
233
- url: sowbBlockEditorAdmin.restUrl + 'sowb/v1/widgets/previews',
234
- beforeSend: function ( xhr ) {
235
- xhr.setRequestHeader( 'X-WP-Nonce', sowbBlockEditorAdmin.nonce );
236
- },
237
- data: {
238
- widgetClass: props.attributes.widgetClass,
239
- widgetData: props.attributes.widgetData || {}
240
- }
241
- } )
242
- .done( function( widgetPreview ) {
243
- props.setState( {
244
- widgetPreviewHtml: widgetPreview.html,
245
- previewInitialized: false,
246
- } );
247
-
248
- props.setAttributes( {
249
- widgetHtml: widgetPreview.html,
250
- widgetIcons: widgetPreview.icons
251
- } );
252
- } )
253
- .fail( function ( response ) {
254
-
255
- var errorMessage = '';
256
- if ( response.hasOwnProperty( 'responseJSON' ) ) {
257
- errorMessage = response.responseJSON.message;
258
- } else if ( response.hasOwnProperty( 'responseText' ) ) {
259
- errorMessage = response.responseText;
260
- }
261
-
262
- props.setState( {
263
- widgetPreviewHtml: '<div>' + errorMessage + '</div>',
264
- } );
265
- });
266
  }
267
  var widgetPreview = props.widgetPreviewHtml ? props.widgetPreviewHtml : '';
268
  return [
11
  var Spinner = components.Spinner;
12
  var __ = i18n.__;
13
 
14
+ var ajaxErrorHandler = function( response ) {
15
+ var errorMessage = '';
16
+ if ( response.hasOwnProperty( 'responseJSON' ) ) {
17
+ errorMessage = response.responseJSON.message;
18
+ } else if ( response.hasOwnProperty( 'responseText' ) ) {
19
+ errorMessage = response.responseText;
20
+ }
21
+
22
+ props.setState( { widgetFormHtml: '<div>' + errorMessage + '</div>', } );
23
+ }
24
+
25
  registerBlockType( 'sowb/widget-block', {
26
  title: __( 'SiteOrigin Widget', 'so-widgets-bundle' ),
27
 
90
  }
91
  }
92
 
93
+ function generateWidgetPreview( widgetData = false) {
94
+ wp.data.dispatch( 'core/editor' ).lockPostSaving();
95
+ jQuery.post( {
96
+ url: sowbBlockEditorAdmin.restUrl + 'sowb/v1/widgets/previews',
97
+ beforeSend: function( xhr ) {
98
+ xhr.setRequestHeader( 'X-WP-Nonce', sowbBlockEditorAdmin.nonce );
99
+ },
100
+ data: {
101
+ widgetClass: props.attributes.widgetClass,
102
+ widgetData: widgetData ? widgetData : props.attributes.widgetData || {}
103
+ }
104
+ } )
105
+ .done( function( widgetPreview ) {
106
+ props.setState( {
107
+ widgetPreviewHtml: widgetPreview.html,
108
+ previewInitialized: false,
109
+ } );
110
+
111
+ props.setAttributes( {
112
+ widgetHtml: widgetPreview.html,
113
+ widgetIcons: widgetPreview.icons
114
+ } );
115
+ wp.data.dispatch( 'core/editor' ).unlockPostSaving();
116
+ } )
117
+ .fail( ajaxErrorHandler );
118
+ }
119
+
120
  function switchToEditing() {
121
  props.setState( { editing: true, formInitialized: false } );
122
  }
143
  props.setAttributes( { widgetData: sowbForms.getWidgetFormValues( $mainForm ) } );
144
  }
145
  $mainForm.on( 'change', function () {
 
146
  props.setState( {
147
  widgetSettingsChanged: true,
148
  widgetPreviewHtml: null,
149
  previewInitialized: false
150
  } );
151
+
152
+ // As setAttributes doesn't support callbacks, we have to manully pass the widgetData to the preview.
153
+ var widgetData = sowbForms.getWidgetFormValues( $mainForm );
154
+ props.setAttributes( { widgetData: widgetData } );
155
+ generateWidgetPreview( widgetData );
156
  } );
157
  props.setState( { formInitialized: true } );
158
  }
188
  .done( function( widgetForm ) {
189
  props.setState( { widgetFormHtml: widgetForm } );
190
  } )
191
+ .fail( ajaxErrorHandler );
 
 
 
 
 
 
 
 
 
 
192
  }
193
 
194
  var widgetForm = props.widgetFormHtml ? props.widgetFormHtml : '';
261
  widgetHtml: null,
262
  widgetIcons: null
263
  } );
264
+ generateWidgetPreview();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  }
266
  var widgetPreview = props.widgetPreviewHtml ? props.widgetPreviewHtml : '';
267
  return [
compat/block-editor/widget-block.min.js CHANGED
@@ -1 +1 @@
1
- !function(e,t,i,o,n,s,d){var r=o.createElement,a=t.registerBlockType,l=d.BlockControls,w=n.ComboboxControl,g=s.withState,c=n.Toolbar,u=n.ToolbarButton,m=n.Placeholder,b=n.Spinner,p=i.__;a("sowb/widget-block",{title:p("SiteOrigin Widget","so-widgets-bundle"),description:p("Select a SiteOrigin widget from the dropdown.","so-widgets-bundle"),icon:function(){return r("span",{className:"widget-icon so-widget-icon so-block-editor-icon"})},category:"widgets",keywords:[sowbBlockEditorAdmin.widgets.reduce((function(e,t){return e.length>0&&(e+=","),e+t.name}),"")],supports:{html:!1},attributes:{widgetClass:{type:"string"},widgetData:{type:"object"},widgetHtml:{type:"string"},widgetIcons:{type:"array"}},edit:g({editing:!1,formInitialized:!1,previewInitialized:!1,widgetFormHtml:"",widgetSettingsChanged:!1,widgetPreviewHtml:""})((function(e){function t(){e.setState({editing:!1,previewInitialized:!1})}if(!e.editing&&e.attributes.widgetClass&&e.attributes.widgetData){var i=!e.loadingWidgets&&!e.editing&&!e.widgetPreviewHtml&&e.attributes.widgetClass&&e.attributes.widgetData;i&&(e.setAttributes({widgetHtml:null,widgetIcons:null}),jQuery.post({url:sowbBlockEditorAdmin.restUrl+"sowb/v1/widgets/previews",beforeSend:function(e){e.setRequestHeader("X-WP-Nonce",sowbBlockEditorAdmin.nonce)},data:{widgetClass:e.attributes.widgetClass,widgetData:e.attributes.widgetData||{}}}).done((function(t){e.setState({widgetPreviewHtml:t.html,previewInitialized:!1}),e.setAttributes({widgetHtml:t.html,widgetIcons:t.icons})})).fail((function(t){var i="";t.hasOwnProperty("responseJSON")?i=t.responseJSON.message:t.hasOwnProperty("responseText")&&(i=t.responseText),e.setState({widgetPreviewHtml:"<div>"+i+"</div>"})})));var o=e.widgetPreviewHtml?e.widgetPreviewHtml:"";return[r(l,{key:"controls"},r(c,{label:p("Preview widget.","so-widgets-bundle")},r(u,{className:"components-icon-button components-toolbar__control",label:p("Edit widget.","so-widgets-bundle"),onClick:function(){e.setState({editing:!0,formInitialized:!1})},icon:"edit"}))),r("div",{key:"preview",className:"so-widget-preview-container"},i?r("div",{className:"so-widgets-spinner-container"},r("span",null,r(b))):r("div",{dangerouslySetInnerHTML:{__html:o},ref:function(){e.previewInitialized||(jQuery(window.sowb).trigger("setup_widgets",{preview:!0}),e.setState({previewInitialized:!0}))}}))]}var n=[];sowbBlockEditorAdmin.widgets&&(n=sowbBlockEditorAdmin.widgets.map((function(e){return{value:e.class,label:e.name}})));var s=e.attributes.widgetClass&&!e.widgetFormHtml;s&&jQuery.post({url:sowbBlockEditorAdmin.restUrl+"sowb/v1/widgets/forms",beforeSend:function(e){e.setRequestHeader("X-WP-Nonce",sowbBlockEditorAdmin.nonce)},data:{widgetClass:e.attributes.widgetClass,widgetData:e.attributes.widgetData}}).done((function(t){e.setState({widgetFormHtml:t})})).fail((function(t){var i="";t.hasOwnProperty("responseJSON")?i=t.responseJSON.message:t.hasOwnProperty("responseText")&&(i=t.responseText),e.setState({widgetFormHtml:"<div>"+i+"</div>"})}));var d=e.widgetFormHtml?e.widgetFormHtml:"";return[!!d&&r(l,{key:"controls"},r(c,{label:p("Preview widget.","so-widgets-bundle")},r(u,{className:"components-icon-button components-toolbar__control",label:p("Preview widget.","so-widgets-bundle"),onClick:t,icon:"visibility"}))),r(m,{key:"placeholder",className:"so-widget-placeholder",label:p("SiteOrigin Widget","so-widgets-bundle"),instructions:p("Select the type of widget you want to use:","so-widgets-bundle")},e.loadingWidgets||s?r(b):r("div",{className:"so-widget-block-container"},r(w,{className:"so-widget-autocomplete-field",label:p("Widget type","so-widgets-bundle"),value:e.attributes.widgetClass,onFilterValueChange:function(e){},onChange:function(t){if(""!==t){if(e.widgetSettingsChanged&&!confirm(sowbBlockEditorAdmin.confirmChangeWidget))return!1;e.setAttributes({widgetClass:t,widgetData:null}),e.setState({editing:!0,widgetFormHtml:null,formInitialized:!1,widgetSettingsChanged:!1,widgetPreviewHtml:null,previewInitialized:!1})}},options:n}),r("div",{className:"so-widget-block-form-container",dangerouslySetInnerHTML:{__html:d},ref:function(i){var o=jQuery(i).find(".siteorigin-widget-form-main");o.length>0&&!e.formInitialized&&(o.siblings(".siteorigin-widget-preview").find("> a").on("click",(function(e){e.stopImmediatePropagation(),t()})),o.data("backupDisabled",!0),o.sowSetupForm(),e.attributes.widgetData?sowbForms.setWidgetFormValues(o,e.attributes.widgetData):e.setAttributes({widgetData:sowbForms.getWidgetFormValues(o)}),o.on("change",(function(){e.setAttributes({widgetData:sowbForms.getWidgetFormValues(o)}),e.setState({widgetSettingsChanged:!0,widgetPreviewHtml:null,previewInitialized:!1})})),e.setState({formInitialized:!0}))}})))]})),save:function(e){return null}})}(window.wp.editor,window.wp.blocks,window.wp.i18n,window.wp.element,window.wp.components,window.wp.compose,window.wp.blockEditor);
1
+ !function(e,t,i,o,n,s,d){var a=o.createElement,r=t.registerBlockType,l=d.BlockControls,w=n.ComboboxControl,g=s.withState,c=n.Toolbar,u=n.ToolbarButton,m=n.Placeholder,b=n.Spinner,p=i.__,v=function(e){var t="";e.hasOwnProperty("responseJSON")?t=e.responseJSON.message:e.hasOwnProperty("responseText")&&(t=e.responseText),props.setState({widgetFormHtml:"<div>"+t+"</div>"})};r("sowb/widget-block",{title:p("SiteOrigin Widget","so-widgets-bundle"),description:p("Select a SiteOrigin widget from the dropdown.","so-widgets-bundle"),icon:function(){return a("span",{className:"widget-icon so-widget-icon so-block-editor-icon"})},category:"widgets",keywords:[sowbBlockEditorAdmin.widgets.reduce((function(e,t){return e.length>0&&(e+=","),e+t.name}),"")],supports:{html:!1},attributes:{widgetClass:{type:"string"},widgetData:{type:"object"},widgetHtml:{type:"string"},widgetIcons:{type:"array"}},edit:g({editing:!1,formInitialized:!1,previewInitialized:!1,widgetFormHtml:"",widgetSettingsChanged:!1,widgetPreviewHtml:""})((function(e){function t(t=!1){wp.data.dispatch("core/editor").lockPostSaving(),jQuery.post({url:sowbBlockEditorAdmin.restUrl+"sowb/v1/widgets/previews",beforeSend:function(e){e.setRequestHeader("X-WP-Nonce",sowbBlockEditorAdmin.nonce)},data:{widgetClass:e.attributes.widgetClass,widgetData:t||(e.attributes.widgetData||{})}}).done((function(t){e.setState({widgetPreviewHtml:t.html,previewInitialized:!1}),e.setAttributes({widgetHtml:t.html,widgetIcons:t.icons}),wp.data.dispatch("core/editor").unlockPostSaving()})).fail(v)}function i(){e.setState({editing:!1,previewInitialized:!1})}if(!e.editing&&e.attributes.widgetClass&&e.attributes.widgetData){var o=!e.loadingWidgets&&!e.editing&&!e.widgetPreviewHtml&&e.attributes.widgetClass&&e.attributes.widgetData;o&&(e.setAttributes({widgetHtml:null,widgetIcons:null}),t());var n=e.widgetPreviewHtml?e.widgetPreviewHtml:"";return[a(l,{key:"controls"},a(c,{label:p("Preview widget.","so-widgets-bundle")},a(u,{className:"components-icon-button components-toolbar__control",label:p("Edit widget.","so-widgets-bundle"),onClick:function(){e.setState({editing:!0,formInitialized:!1})},icon:"edit"}))),a("div",{key:"preview",className:"so-widget-preview-container"},o?a("div",{className:"so-widgets-spinner-container"},a("span",null,a(b))):a("div",{dangerouslySetInnerHTML:{__html:n},ref:function(){e.previewInitialized||(jQuery(window.sowb).trigger("setup_widgets",{preview:!0}),e.setState({previewInitialized:!0}))}}))]}var s=[];sowbBlockEditorAdmin.widgets&&(s=sowbBlockEditorAdmin.widgets.map((function(e){return{value:e.class,label:e.name}})));var d=e.attributes.widgetClass&&!e.widgetFormHtml;d&&jQuery.post({url:sowbBlockEditorAdmin.restUrl+"sowb/v1/widgets/forms",beforeSend:function(e){e.setRequestHeader("X-WP-Nonce",sowbBlockEditorAdmin.nonce)},data:{widgetClass:e.attributes.widgetClass,widgetData:e.attributes.widgetData}}).done((function(t){e.setState({widgetFormHtml:t})})).fail(v);var r=e.widgetFormHtml?e.widgetFormHtml:"";return[!!r&&a(l,{key:"controls"},a(c,{label:p("Preview widget.","so-widgets-bundle")},a(u,{className:"components-icon-button components-toolbar__control",label:p("Preview widget.","so-widgets-bundle"),onClick:i,icon:"visibility"}))),a(m,{key:"placeholder",className:"so-widget-placeholder",label:p("SiteOrigin Widget","so-widgets-bundle"),instructions:p("Select the type of widget you want to use:","so-widgets-bundle")},e.loadingWidgets||d?a(b):a("div",{className:"so-widget-block-container"},a(w,{className:"so-widget-autocomplete-field",label:p("Widget type","so-widgets-bundle"),value:e.attributes.widgetClass,onFilterValueChange:function(e){},onChange:function(t){if(""!==t){if(e.widgetSettingsChanged&&!confirm(sowbBlockEditorAdmin.confirmChangeWidget))return!1;e.setAttributes({widgetClass:t,widgetData:null}),e.setState({editing:!0,widgetFormHtml:null,formInitialized:!1,widgetSettingsChanged:!1,widgetPreviewHtml:null,previewInitialized:!1})}},options:s}),a("div",{className:"so-widget-block-form-container",dangerouslySetInnerHTML:{__html:r},ref:function(o){var n=jQuery(o).find(".siteorigin-widget-form-main");n.length>0&&!e.formInitialized&&(n.siblings(".siteorigin-widget-preview").find("> a").on("click",(function(e){e.stopImmediatePropagation(),i()})),n.data("backupDisabled",!0),n.sowSetupForm(),e.attributes.widgetData?sowbForms.setWidgetFormValues(n,e.attributes.widgetData):e.setAttributes({widgetData:sowbForms.getWidgetFormValues(n)}),n.on("change",(function(){e.setState({widgetSettingsChanged:!0,widgetPreviewHtml:null,previewInitialized:!1});var i=sowbForms.getWidgetFormValues(n);e.setAttributes({widgetData:i}),t(i)})),e.setState({formInitialized:!0}))}})))]})),save:function(e){return null}})}(window.wp.editor,window.wp.blocks,window.wp.i18n,window.wp.element,window.wp.components,window.wp.compose,window.wp.blockEditor);
compat/block-editor/widget-block.php CHANGED
@@ -45,7 +45,8 @@ class SiteOrigin_Widgets_Bundle_Widget_Block {
45
  if ( ! $widget['Active'] ) {
46
  include_once wp_normalize_path( $widget['File'] );
47
  // The last class will always be from the widget file we just loaded.
48
- $widget_class = end( get_declared_classes() );
 
49
 
50
  $so_widgets[] = array(
51
  'name' => $widget['Name'],
@@ -143,7 +144,10 @@ class SiteOrigin_Widgets_Bundle_Widget_Block {
143
  add_filter( 'siteorigin_widgets_wrapper_classes_' . $widget->id_base, $add_custom_class_name );
144
  ob_start();
145
 
146
- if ( empty( $attributes['widgetHtml'] ) ) {
 
 
 
147
  /* @var $widget SiteOrigin_Widget */
148
  $instance = $widget->update( $instance, $instance );
149
  $widget->widget( array(
45
  if ( ! $widget['Active'] ) {
46
  include_once wp_normalize_path( $widget['File'] );
47
  // The last class will always be from the widget file we just loaded.
48
+ $classes = get_declared_classes();
49
+ $widget_class = end( $classes );
50
 
51
  $so_widgets[] = array(
52
  'name' => $widget['Name'],
144
  add_filter( 'siteorigin_widgets_wrapper_classes_' . $widget->id_base, $add_custom_class_name );
145
  ob_start();
146
 
147
+ // If we have pre-generated widgetHTML or there's a valid $_POST, generate the widget.
148
+ // We don't show the pre-generated widget when there's a valid $_POST
149
+ // as widgets will likely change when that happens.
150
+ if ( empty( $attributes['widgetHtml'] ) || ! empty( $_POST ) ) {
151
  /* @var $widget SiteOrigin_Widget */
152
  $instance = $widget->update( $instance, $instance );
153
  $widget->widget( array(
compat/compat.php CHANGED
@@ -25,6 +25,11 @@ class SiteOrigin_Widgets_Bundle_Compatibility {
25
  if ( function_exists( 'register_block_type' ) ) {
26
  require_once plugin_dir_path( __FILE__ ) . 'block-editor/widget-block.php';
27
  }
 
 
 
 
 
28
  }
29
 
30
  function get_active_builder() {
@@ -32,7 +37,7 @@ class SiteOrigin_Widgets_Bundle_Compatibility {
32
  $builders = include_once 'builders.php';
33
 
34
  foreach ( $builders as $builder ) {
35
- if ( $this->is_active( $builder ) ) {
36
  return $builder;
37
  }
38
  }
@@ -40,7 +45,7 @@ class SiteOrigin_Widgets_Bundle_Compatibility {
40
  return null;
41
  }
42
 
43
- function is_active( $builder ) {
44
  switch ( $builder[ 'name' ] ) {
45
  case self::BEAVER_BUILDER:
46
  return class_exists( 'FLBuilderModel', false );
@@ -54,6 +59,43 @@ class SiteOrigin_Widgets_Bundle_Compatibility {
54
  }
55
  }
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  }
58
 
59
  SiteOrigin_Widgets_Bundle_Compatibility::single();
25
  if ( function_exists( 'register_block_type' ) ) {
26
  require_once plugin_dir_path( __FILE__ ) . 'block-editor/widget-block.php';
27
  }
28
+
29
+ // These actions handle alerting cache plugins that they need to regenerate a page cache.
30
+ add_action( 'siteorigin_widgets_stylesheet_deleted', array( $this, 'clear_page_cache' ) );
31
+ add_action( 'siteorigin_widgets_stylesheet_added', array( $this, 'clear_page_cache' ) );
32
+ add_action( 'siteorigin_widgets_stylesheet_cleared', array( $this, 'clear_all_cache' ) );
33
  }
34
 
35
  function get_active_builder() {
37
  $builders = include_once 'builders.php';
38
 
39
  foreach ( $builders as $builder ) {
40
+ if ( $this->is_builder_active( $builder ) ) {
41
  return $builder;
42
  }
43
  }
45
  return null;
46
  }
47
 
48
+ function is_builder_active( $builder ) {
49
  switch ( $builder[ 'name' ] ) {
50
  case self::BEAVER_BUILDER:
51
  return class_exists( 'FLBuilderModel', false );
59
  }
60
  }
61
 
62
+
63
+ /**
64
+ * Tell cache plugins that they need to regenerate a page cache.
65
+ *
66
+ * @param $name The name of the file that's been deleted.
67
+ * @param $instance The current instance of the related widget.
68
+ *
69
+ */
70
+ public function clear_page_cache( $name, $instance = array() ) {
71
+ $id = explode( '-', $name );
72
+ $id = end( $id );
73
+
74
+ if ( is_numeric( $id ) ) {
75
+
76
+ if ( function_exists( 'w3tc_flush_post' ) ) {
77
+ w3tc_flush_post( $id );
78
+ }
79
+
80
+ if ( class_exists( 'Swift_Performance_Cache' ) ) {
81
+ Swift_Performance_Cache::clear_post_cache( $id );
82
+ }
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Tell cache plugins that they need to regenerate their all page cache.
88
+ */
89
+ public function clear_all_cache() {
90
+ if ( function_exists( 'w3tc_flush_all' ) ) {
91
+ w3tc_flush_all();
92
+ }
93
+
94
+ if ( class_exists( 'Swift_Performance_Cache' ) ) {
95
+ Swift_Performance_Cache::clear_all_cache();
96
+ }
97
+ }
98
+
99
  }
100
 
101
  SiteOrigin_Widgets_Bundle_Compatibility::single();
js/slider/jquery.slider.js CHANGED
@@ -82,6 +82,17 @@ jQuery( function($){
82
  var $slides = $$.find('.sow-slider-image');
83
  var settings = $$.data('settings');
84
 
 
 
 
 
 
 
 
 
 
 
 
85
  $slides.each(function( index, el) {
86
  var $slide = $(el);
87
  var urlData = $slide.data('url');
82
  var $slides = $$.find('.sow-slider-image');
83
  var settings = $$.data('settings');
84
 
85
+ // Add mobile identifer to slider.
86
+ if ( settings.breakpoint ) {
87
+ $( window ).on( 'load resize', function() {
88
+ if ( window.matchMedia( '(max-width: ' + settings.breakpoint + ')' ).matches ) {
89
+ $base.addClass( 'sow-slider-is-mobile' );
90
+ } else {
91
+ $base.removeClass( 'sow-slider-is-mobile' );
92
+ }
93
+ } );
94
+ }
95
+
96
  $slides.each(function( index, el) {
97
  var $slide = $(el);
98
  var urlData = $slide.data('url');
js/slider/jquery.slider.min.js CHANGED
@@ -1 +1 @@
1
- var sowb=window.sowb||{};sowb.SiteOriginSlider=function(e){return{playSlideVideo:function(i){e(i).find("video").each((function(){void 0!==this.play&&this.play()}))},pauseSlideVideo:function(i){e(i).find("video").each((function(){void 0!==this.pause&&this.pause()}))},setupActiveSlide:function(i,t,s){var o=e(i).find(".cycle-sentinel"),n=e(t),d=n.find("video.sow-background-element");(void 0===s?o.css("height",n.outerHeight()+"px"):o.animate({height:n.outerHeight()},s),d.length)&&(n.outerWidth()/n.outerHeight()>d.outerWidth()/d.outerHeight()?d.css({width:"100%",height:"auto"}):d.css({width:"auto",height:"100%"}),d.css({"margin-left":-Math.ceil(d.width()/2),"margin-top":-Math.ceil(d.height()/2)}))}}},jQuery((function(e){sowb.setupSliders=sowb.setupSlider=function(){var i=new sowb.SiteOriginSlider(e);e(".sow-slider-images").each((function(){var t=e(this);if(t.data("initialized"))return t;var s=t.siblings(".sow-slider-pagination"),o=t.closest(".sow-slider-base"),n=o.find(".sow-slide-nav"),d=t.find(".sow-slider-image"),a=t.data("settings");d.each((function(i,t){var s=e(t),o=s.data("url");void 0!==o&&o.hasOwnProperty("url")&&(s.on("click",(function(e){e.preventDefault(),window.open(o.url,o.hasOwnProperty("new_window")&&o.new_window?"_blank":"_self").opener=null})),s.find("a").on("click",(function(e){e.stopPropagation()})))}));var l=function(){var c=t.closest(".so-widget-fittext-wrapper");if(c.length>0&&!c.data("fitTextDone"))c.on("fitTextDone",(function(){l()}));else{o.show();var r=function(){t.find(".sow-slider-image").each((function(){var i=e(this);i.css("height",i.find(".sow-slider-image-wrapper").outerHeight()+"px")}))};if(e(window).on("resize panelsStretchRows",r).trigger("resize"),e(sowb).on("setup_widgets",r),t.on({"cycle-after":function(t,s,o,n,d){var a=e(this);i.playSlideVideo(n),i.setupActiveSlide(a,n),e(n).trigger("sowSlideCycleAfter")},"cycle-before":function(t,o,n,d,a){var l=e(this);s.find("> li").removeClass("sow-active").eq(o.slideNum-1).addClass("sow-active"),i.pauseSlideVideo(n),i.setupActiveSlide(l,d,o.speed),e(d).trigger("sowSlideCycleBefore")},"cycle-initialized":function(o,d){i.playSlideVideo(e(this).find(".cycle-slide-active")),i.setupActiveSlide(t,d.slides[0]),s.find(">li").removeClass("sow-active").eq(0).addClass("sow-active"),e(this).find(".cycle-slide-active").trigger("sowSlideInitial"),d.slideCount<=1&&(s.hide(),n.hide()),e(window).trigger("resize"),setTimeout((function(){r(),i.setupActiveSlide(t,d.slides[0]),t.find(".cycle-sentinel").empty()}),200)}}).cycle({slides:"> .sow-slider-image",speed:a.speed,timeout:a.timeout,swipe:a.swipe,paused:a.paused,pauseOnHover:a.pause_on_hover,"swipe-fx":"scrollHorz",log:!1}),t.find("video.sow-background-element").on("loadeddata",(function(){i.setupActiveSlide(t,t.find(".cycle-slide-active"))})),s.add(n).hide(),d.length>1)if(o.hasClass("sow-slider-is-mobile"))a.nav_always_show_mobile&&window.matchMedia("(max-width: "+a.breakpoint+")").matches&&(s.show(),n.show());else if(a.nav_always_show_desktop&&window.matchMedia("(min-width: "+a.breakpoint+")").matches)s.show(),n.show();else{var u=!1;o.on("mouseenter",(function(){s.add(n).clearQueue().fadeIn(150),u=!1})).on("mouseleave",(function(){u=!0,setTimeout((function(){u&&s.add(n).clearQueue().fadeOut(150),u=!1}),750)}))}var w=function(){i.setupActiveSlide(t,t.find(".cycle-slide-active"))};e(window).on("resize",w),e(sowb).on("setup_widgets",w),s.find("> li > a").on("click",(function(i){i.preventDefault(),t.cycle("goto",e(this).data("goto"))})),n.find("> a").on("click",(function(i){i.preventDefault(),t.cycle(e(this).data("action"))})),o.on("keydown",(function(e){37===e.which?t.cycle("prev"):39===e.which&&t.cycle("next")}))}},c=t.find("img.sow-slider-background-image, img.sow-slider-foreground-image"),r=0,u=!1;c.each((function(){e(this);this.complete?r++:e(this).one("load",(function(){++r!==c.length||u||(l(),u=!0)})).attr("src",e(this).attr("src")),r!==c.length||u||(l(),u=!0)})),0===c.length&&l(),t.data("initialized",!0)}))},sowb.setupSliders(),e(sowb).on("setup_widgets",sowb.setupSliders)})),window.sowb=sowb;
1
+ var sowb=window.sowb||{};sowb.SiteOriginSlider=function(e){return{playSlideVideo:function(i){e(i).find("video").each((function(){void 0!==this.play&&this.play()}))},pauseSlideVideo:function(i){e(i).find("video").each((function(){void 0!==this.pause&&this.pause()}))},setupActiveSlide:function(i,t,s){var o=e(i).find(".cycle-sentinel"),n=e(t),d=n.find("video.sow-background-element");(void 0===s?o.css("height",n.outerHeight()+"px"):o.animate({height:n.outerHeight()},s),d.length)&&(n.outerWidth()/n.outerHeight()>d.outerWidth()/d.outerHeight()?d.css({width:"100%",height:"auto"}):d.css({width:"auto",height:"100%"}),d.css({"margin-left":-Math.ceil(d.width()/2),"margin-top":-Math.ceil(d.height()/2)}))}}},jQuery((function(e){sowb.setupSliders=sowb.setupSlider=function(){var i=new sowb.SiteOriginSlider(e);e(".sow-slider-images").each((function(){var t=e(this);if(t.data("initialized"))return t;var s=t.siblings(".sow-slider-pagination"),o=t.closest(".sow-slider-base"),n=o.find(".sow-slide-nav"),d=t.find(".sow-slider-image"),a=t.data("settings");a.breakpoint&&e(window).on("load resize",(function(){window.matchMedia("(max-width: "+a.breakpoint+")").matches?o.addClass("sow-slider-is-mobile"):o.removeClass("sow-slider-is-mobile")})),d.each((function(i,t){var s=e(t),o=s.data("url");void 0!==o&&o.hasOwnProperty("url")&&(s.on("click",(function(e){e.preventDefault(),window.open(o.url,o.hasOwnProperty("new_window")&&o.new_window?"_blank":"_self").opener=null})),s.find("a").on("click",(function(e){e.stopPropagation()})))}));var l=function(){var c=t.closest(".so-widget-fittext-wrapper");if(c.length>0&&!c.data("fitTextDone"))c.on("fitTextDone",(function(){l()}));else{o.show();var r=function(){t.find(".sow-slider-image").each((function(){var i=e(this);i.css("height",i.find(".sow-slider-image-wrapper").outerHeight()+"px")}))};if(e(window).on("resize panelsStretchRows",r).trigger("resize"),e(sowb).on("setup_widgets",r),t.on({"cycle-after":function(t,s,o,n,d){var a=e(this);i.playSlideVideo(n),i.setupActiveSlide(a,n),e(n).trigger("sowSlideCycleAfter")},"cycle-before":function(t,o,n,d,a){var l=e(this);s.find("> li").removeClass("sow-active").eq(o.slideNum-1).addClass("sow-active"),i.pauseSlideVideo(n),i.setupActiveSlide(l,d,o.speed),e(d).trigger("sowSlideCycleBefore")},"cycle-initialized":function(o,d){i.playSlideVideo(e(this).find(".cycle-slide-active")),i.setupActiveSlide(t,d.slides[0]),s.find(">li").removeClass("sow-active").eq(0).addClass("sow-active"),e(this).find(".cycle-slide-active").trigger("sowSlideInitial"),d.slideCount<=1&&(s.hide(),n.hide()),e(window).trigger("resize"),setTimeout((function(){r(),i.setupActiveSlide(t,d.slides[0]),t.find(".cycle-sentinel").empty()}),200)}}).cycle({slides:"> .sow-slider-image",speed:a.speed,timeout:a.timeout,swipe:a.swipe,paused:a.paused,pauseOnHover:a.pause_on_hover,"swipe-fx":"scrollHorz",log:!1}),t.find("video.sow-background-element").on("loadeddata",(function(){i.setupActiveSlide(t,t.find(".cycle-slide-active"))})),s.add(n).hide(),d.length>1)if(o.hasClass("sow-slider-is-mobile"))a.nav_always_show_mobile&&window.matchMedia("(max-width: "+a.breakpoint+")").matches&&(s.show(),n.show());else if(a.nav_always_show_desktop&&window.matchMedia("(min-width: "+a.breakpoint+")").matches)s.show(),n.show();else{var w=!1;o.on("mouseenter",(function(){s.add(n).clearQueue().fadeIn(150),w=!1})).on("mouseleave",(function(){w=!0,setTimeout((function(){w&&s.add(n).clearQueue().fadeOut(150),w=!1}),750)}))}var u=function(){i.setupActiveSlide(t,t.find(".cycle-slide-active"))};e(window).on("resize",u),e(sowb).on("setup_widgets",u),s.find("> li > a").on("click",(function(i){i.preventDefault(),t.cycle("goto",e(this).data("goto"))})),n.find("> a").on("click",(function(i){i.preventDefault(),t.cycle(e(this).data("action"))})),o.on("keydown",(function(e){37===e.which?t.cycle("prev"):39===e.which&&t.cycle("next")}))}},c=t.find("img.sow-slider-background-image, img.sow-slider-foreground-image"),r=0,w=!1;c.each((function(){e(this);this.complete?r++:e(this).one("load",(function(){++r!==c.length||w||(l(),w=!0)})).attr("src",e(this).attr("src")),r!==c.length||w||(l(),w=!0)})),0===c.length&&l(),t.data("initialized",!0)}))},sowb.setupSliders(),e(sowb).on("setup_widgets",sowb.setupSliders)})),window.sowb=sowb;
lang/so-widgets-bundle.pot CHANGED
@@ -36,79 +36,79 @@ msgstr ""
36
  msgid "https://siteorigin.com/widgets-bundle/"
37
  msgstr ""
38
 
39
- #: so-widgets-bundle.php:340, so-widgets-bundle.php:364, so-widgets-bundle.php:377, so-widgets-bundle.php:407, so-widgets-bundle.php:418, so-widgets-bundle.php:485, so-widgets-bundle.php:496, base/base.php:51, base/base.php:55, base/inc/actions.php:11, base/inc/actions.php:77, base/inc/actions.php:121, base/inc/actions.php:157, base/inc/actions.php:170, base/inc/actions.php:174, base/inc/actions.php:265, base/inc/actions.php:268
40
  msgid "Invalid request."
41
  msgstr ""
42
 
43
- #: so-widgets-bundle.php:344, so-widgets-bundle.php:367, so-widgets-bundle.php:410, base/inc/routes/siteorigin-widgets-resource.class.php:55
44
  msgid "Insufficient permissions."
45
  msgstr ""
46
 
47
- #: so-widgets-bundle.php:347, so-widgets-bundle.php:491, base/inc/actions.php:23
48
  msgid "Invalid post."
49
  msgstr ""
50
 
51
- #: so-widgets-bundle.php:435, so-widgets-bundle.php:436, compat/visual-composer/visual-composer.php:40
52
  msgid "SiteOrigin Widgets"
53
  msgstr ""
54
 
55
- #: so-widgets-bundle.php:461
56
  msgid "%s was %s"
57
  msgstr ""
58
 
59
- #: so-widgets-bundle.php:463
60
  msgid "Activated"
61
  msgstr ""
62
 
63
- #: so-widgets-bundle.php:463
64
  msgid "Deactivated"
65
  msgstr ""
66
 
67
- #: so-widgets-bundle.php:726
68
  msgid "Manage Widgets"
69
  msgstr ""
70
 
71
- #: so-widgets-bundle.php:727
72
  msgid "Support"
73
  msgstr ""
74
 
75
- #: base/siteorigin-widget.class.php:512
76
  msgid "Preview"
77
  msgstr ""
78
 
79
- #: base/siteorigin-widget.class.php:517
80
  msgid "Help"
81
  msgstr ""
82
 
83
- #: base/siteorigin-widget.class.php:583
84
  msgid "This widget has scripts and styles that need to be loaded before you can use it. Please save and reload your current page."
85
  msgstr ""
86
 
87
- #: base/siteorigin-widget.class.php:584
88
  msgid "You will only need to do this once."
89
  msgstr ""
90
 
91
- #: base/siteorigin-widget.class.php:611
92
  msgid "Are you sure?"
93
  msgstr ""
94
 
95
- #: base/siteorigin-widget.class.php:613
96
  msgid "There is a newer version of this widget's content available."
97
  msgstr ""
98
 
99
- #: base/siteorigin-widget.class.php:614, base/siteorigin-widget.class.php:618
100
  msgid "Restore"
101
  msgstr ""
102
 
103
- #: base/siteorigin-widget.class.php:615
104
  msgid "Dismiss"
105
  msgstr ""
106
 
107
- #: base/siteorigin-widget.class.php:617
108
  msgid "Clicking %s will replace the current widget contents. You can revert by refreshing the page before updating."
109
  msgstr ""
110
 
111
- #: base/siteorigin-widget.class.php:668, base/inc/actions.php:53
112
  msgid "Widget Preview"
113
  msgstr ""
114
 
@@ -240,19 +240,19 @@ msgstr ""
240
  msgid "Current Color"
241
  msgstr ""
242
 
243
- #: compat/block-editor/widget-block.php:81
244
  msgid "%s by %s"
245
  msgstr ""
246
 
247
- #: compat/block-editor/widget-block.php:101, compat/visual-composer/visual-composer.php:77
248
  msgid "Selecting a different widget will revert any changes. Continue?"
249
  msgstr ""
250
 
251
- #: compat/block-editor/widget-block.php:117
252
  msgid "You need to select a widget type before you'll see anything here. :)"
253
  msgstr ""
254
 
255
- #: compat/block-editor/widget-block.php:178
256
  msgid "Invalid widget class %s. Please make sure the widget has been activated in %sSiteOrigin Widgets%s."
257
  msgstr ""
258
 
@@ -380,223 +380,235 @@ msgstr ""
380
  msgid "SiteOrigin Button"
381
  msgstr ""
382
 
383
- #: widgets/button/button.php:46, widgets/price-table/price-table.php:93
 
 
 
 
 
 
 
 
384
  msgid "Button text"
385
  msgstr ""
386
 
387
- #: widgets/button/button.php:51, widgets/google-map/google-map.php:103, widgets/headline/headline.php:47, widgets/headline/headline.php:118, widgets/hero/hero.php:128, widgets/icon/icon.php:57, widgets/image/image.php:90, widgets/layout-slider/layout-slider.php:98, widgets/simple-masonry/simple-masonry.php:89, widgets/slider/slider.php:103
388
  msgid "Destination URL"
389
  msgstr ""
390
 
391
- #: widgets/button/button.php:58, widgets/google-map/google-map.php:114, widgets/headline/headline.php:52, widgets/headline/headline.php:123, widgets/icon/icon.php:63, widgets/simple-masonry/simple-masonry.php:94, widgets/social-media-buttons/social-media-buttons.php:97, widgets/taxonomy/taxonomy.php:65, widgets/testimonial/testimonial.php:94
392
  msgid "Open in a new window"
393
  msgstr ""
394
 
395
- #: widgets/button/button.php:64
396
  msgid "Download"
397
  msgstr ""
398
 
399
- #: widgets/button/button.php:65
400
  msgid "The button destination URL will be downloaded when a user clicks on the button."
401
  msgstr ""
402
 
403
- #: widgets/button/button.php:70, widgets/button/button.php:74, widgets/features/features.php:78, widgets/icon/icon.php:31, widgets/price-table/price-table.php:119
404
  msgid "Icon"
405
  msgstr ""
406
 
407
- #: widgets/button/button.php:79, widgets/features/features.php:88, widgets/price-table/price-table.php:123, widgets/social-media-buttons/social-media-buttons.php:82
408
  msgid "Icon color"
409
  msgstr ""
410
 
411
- #: widgets/button/button.php:84
412
  msgid "Image icon"
413
  msgstr ""
414
 
415
- #: widgets/button/button.php:85
416
  msgid "Replaces the icon with your own image icon."
417
  msgstr ""
418
 
419
- #: widgets/button/button.php:90
420
  msgid "Icon Placement"
421
  msgstr ""
422
 
423
- #: widgets/button/button.php:93, widgets/features/features.php:66
424
  msgid "Top"
425
  msgstr ""
426
 
427
- #: widgets/button/button.php:94, widgets/button/button.php:120, widgets/contact/contact.php:403, widgets/contact/contact.php:418, widgets/contact/contact.php:647, widgets/cta/cta.php:103, widgets/features/features.php:67, widgets/headline/headline.php:92, widgets/headline/headline.php:163, widgets/headline/headline.php:218, widgets/icon/icon.php:50, widgets/image/image.php:50, widgets/image/image.php:62, widgets/simple-masonry/simple-masonry.php:216, widgets/social-media-buttons/social-media-buttons.php:153, widgets/social-media-buttons/social-media-buttons.php:164, widgets/testimonial/testimonial.php:256
428
  msgid "Right"
429
  msgstr ""
430
 
431
- #: widgets/button/button.php:95, widgets/features/features.php:68
432
  msgid "Bottom"
433
  msgstr ""
434
 
435
- #: widgets/button/button.php:96, widgets/button/button.php:119, widgets/contact/contact.php:402, widgets/contact/contact.php:417, widgets/contact/contact.php:646, widgets/cta/cta.php:102, widgets/features/features.php:69, widgets/headline/headline.php:91, widgets/headline/headline.php:162, widgets/headline/headline.php:217, widgets/icon/icon.php:49, widgets/image/image.php:49, widgets/image/image.php:61, widgets/simple-masonry/simple-masonry.php:215, widgets/social-media-buttons/social-media-buttons.php:152, widgets/social-media-buttons/social-media-buttons.php:163, widgets/testimonial/testimonial.php:255
436
  msgid "Left"
437
  msgstr ""
438
 
439
- #: widgets/button/button.php:104, widgets/social-media-buttons/social-media-buttons.php:92
440
  msgid "Design and layout"
441
  msgstr ""
442
 
443
- #: widgets/button/button.php:110, widgets/contact/contact.php:409, widgets/contact/contact.php:639, widgets/contact/contact.php:690, widgets/google-map/google-map.php:94, base/inc/fields/image-size.class.php:57
444
  msgid "Width"
445
  msgstr ""
446
 
447
- #: widgets/button/button.php:111
448
  msgid "Leave blank to let the button resize according to content."
449
  msgstr ""
450
 
451
- #: widgets/button/button.php:116, widgets/contact/contact.php:414, widgets/contact/contact.php:643, widgets/social-media-buttons/social-media-buttons.php:149
452
  msgid "Align"
453
  msgstr ""
454
 
455
- #: widgets/button/button.php:121, widgets/contact/contact.php:419, widgets/contact/contact.php:648, widgets/headline/headline.php:90, widgets/headline/headline.php:161, widgets/headline/headline.php:216, widgets/icon/icon.php:48, widgets/image/image.php:51, widgets/image/image.php:63, widgets/social-media-buttons/social-media-buttons.php:154, widgets/social-media-buttons/social-media-buttons.php:165
456
  msgid "Center"
457
  msgstr ""
458
 
459
- #: widgets/button/button.php:122, widgets/contact/contact.php:420, widgets/headline/headline.php:93, widgets/headline/headline.php:164, widgets/social-media-buttons/social-media-buttons.php:155, widgets/social-media-buttons/social-media-buttons.php:166
460
  msgid "Justify"
461
  msgstr ""
462
 
463
- #: widgets/button/button.php:128, widgets/social-media-buttons/social-media-buttons.php:102
 
 
 
 
464
  msgid "Button theme"
465
  msgstr ""
466
 
467
- #: widgets/button/button.php:131, widgets/price-table/price-table.php:134, widgets/social-media-buttons/social-media-buttons.php:105
468
  msgid "Atom"
469
  msgstr ""
470
 
471
- #: widgets/button/button.php:132, widgets/social-media-buttons/social-media-buttons.php:106
472
  msgid "Flat"
473
  msgstr ""
474
 
475
- #: widgets/button/button.php:133, widgets/social-media-buttons/social-media-buttons.php:107
476
  msgid "Wire"
477
  msgstr ""
478
 
479
- #: widgets/button/button.php:140, widgets/price-table/price-table.php:150
480
  msgid "Button color"
481
  msgstr ""
482
 
483
- #: widgets/button/button.php:145, widgets/contact/contact.php:441, widgets/contact/contact.php:614, widgets/hero/hero.php:261, widgets/layout-slider/layout-slider.php:208, widgets/testimonial/testimonial.php:227
484
  msgid "Text color"
485
  msgstr ""
486
 
487
- #: widgets/button/button.php:151, widgets/social-media-buttons/social-media-buttons.php:112
488
  msgid "Use hover effects"
489
  msgstr ""
490
 
491
- #: widgets/button/button.php:163
492
  msgid "Hover background color"
493
  msgstr ""
494
 
495
- #: widgets/button/button.php:172
496
  msgid "Hover text color"
497
  msgstr ""
498
 
499
- #: widgets/button/button.php:182, widgets/contact/contact.php:382, widgets/contact/contact.php:432, widgets/features/features.php:141, widgets/features/features.php:162, widgets/features/features.php:183, widgets/headline/headline.php:78, widgets/headline/headline.php:149
500
  msgid "Font"
501
  msgstr ""
502
 
503
- #: widgets/button/button.php:188, widgets/contact/contact.php:387, widgets/contact/contact.php:437, widgets/contact/contact.php:619
504
  msgid "Font size"
505
  msgstr ""
506
 
507
- #: widgets/button/button.php:190, widgets/contact/contact.php:291, widgets/contact/contact.php:525, widgets/contact/contact.php:627, widgets/social-media-buttons/social-media-buttons.php:119
508
  msgid "Normal"
509
  msgstr ""
510
 
511
- #: widgets/button/button.php:191, widgets/button/button.php:215, widgets/social-media-buttons/social-media-buttons.php:120, widgets/social-media-buttons/social-media-buttons.php:142, widgets/social-media-buttons/social-media-buttons.php:175, base/inc/widgets/base-slider.class.php:106
512
  msgid "Medium"
513
  msgstr ""
514
 
515
- #: widgets/button/button.php:192, widgets/social-media-buttons/social-media-buttons.php:121
516
  msgid "Large"
517
  msgstr ""
518
 
519
- #: widgets/button/button.php:193, widgets/social-media-buttons/social-media-buttons.php:122
520
  msgid "Extra large"
521
  msgstr ""
522
 
523
- #: widgets/button/button.php:199, widgets/social-media-buttons/social-media-buttons.php:127
524
  msgid "Rounding"
525
  msgstr ""
526
 
527
- #: widgets/button/button.php:202, widgets/contact/contact.php:361, widgets/contact/contact.php:483, widgets/contact/contact.php:594, widgets/contact/contact.php:679, widgets/google-map/google-map.php:158, widgets/headline/headline.php:188, widgets/social-media-buttons/social-media-buttons.php:130
528
  msgid "None"
529
  msgstr ""
530
 
531
- #: widgets/button/button.php:203, widgets/social-media-buttons/social-media-buttons.php:131
532
  msgid "Slightly rounded"
533
  msgstr ""
534
 
535
- #: widgets/button/button.php:204, widgets/social-media-buttons/social-media-buttons.php:132
536
  msgid "Very rounded"
537
  msgstr ""
538
 
539
- #: widgets/button/button.php:205, widgets/social-media-buttons/social-media-buttons.php:133
540
  msgid "Completely rounded"
541
  msgstr ""
542
 
543
- #: widgets/button/button.php:211, widgets/contact/contact.php:343, widgets/contact/contact.php:449, widgets/contact/contact.php:634, widgets/social-media-buttons/social-media-buttons.php:138, widgets/testimonial/testimonial.php:235
544
  msgid "Padding"
545
  msgstr ""
546
 
547
- #: widgets/button/button.php:214, widgets/social-media-buttons/social-media-buttons.php:141, widgets/social-media-buttons/social-media-buttons.php:174
548
  msgid "Low"
549
  msgstr ""
550
 
551
- #: widgets/button/button.php:216, widgets/social-media-buttons/social-media-buttons.php:143, widgets/social-media-buttons/social-media-buttons.php:176
552
  msgid "High"
553
  msgstr ""
554
 
555
- #: widgets/button/button.php:217, widgets/social-media-buttons/social-media-buttons.php:144, widgets/social-media-buttons/social-media-buttons.php:177
556
  msgid "Very high"
557
  msgstr ""
558
 
559
- #: widgets/button/button.php:226
560
  msgid "Other attributes and SEO"
561
  msgstr ""
562
 
563
- #: widgets/button/button.php:231, widgets/contact/contact.php:97
564
  msgid "Button ID"
565
  msgstr ""
566
 
567
- #: widgets/button/button.php:232
568
  msgid "An ID attribute allows you to target this button in Javascript."
569
  msgstr ""
570
 
571
- #: widgets/button/button.php:237
572
- msgid "Button Classes"
573
  msgstr ""
574
 
575
- #: widgets/button/button.php:238
576
  msgid "Additional CSS classes added to the button link."
577
  msgstr ""
578
 
579
- #: widgets/button/button.php:243
580
  msgid "Title attribute"
581
  msgstr ""
582
 
583
- #: widgets/button/button.php:244
584
  msgid "Adds a title attribute to the button link."
585
  msgstr ""
586
 
587
- #: widgets/button/button.php:249, widgets/contact/contact.php:102
588
  msgid "Onclick"
589
  msgstr ""
590
 
591
- #: widgets/button/button.php:250
592
  msgid "Run this Javascript when the button is clicked. Ideal for tracking."
593
  msgstr ""
594
 
595
- #: widgets/button/button.php:255
596
  msgid "Rel attribute"
597
  msgstr ""
598
 
599
- #: widgets/button/button.php:256
600
  msgid "Adds a rel attribute to the button link."
601
  msgstr ""
602
 
@@ -1076,10 +1088,6 @@ msgstr ""
1076
  msgid "Please write something"
1077
  msgstr ""
1078
 
1079
- #: widgets/contact/contact.php:801, widgets/features/features.php:320, widgets/social-media-buttons/social-media-buttons.php:33, base/inc/widgets/base-slider.class.php:185
1080
- msgid "Responsive Breakpoint"
1081
- msgstr ""
1082
-
1083
  #: widgets/contact/contact.php:803
1084
  msgid "This setting controls when the field max width will be disabled. The default value is 780px"
1085
  msgstr ""
@@ -2040,7 +2048,7 @@ msgstr ""
2040
  msgid "Resize image to fit its container."
2041
  msgstr ""
2042
 
2043
- #: widgets/image/image.php:238, widgets/image-grid/image-grid.php:230
2044
  msgid "Add a Lightbox to your images with %sSiteOrigin Premium%s"
2045
  msgstr ""
2046
 
@@ -2077,11 +2085,7 @@ msgid "Maximum image width"
2077
  msgstr ""
2078
 
2079
  #: widgets/image-grid/image-grid.php:114
2080
- msgid "Spacing"
2081
- msgstr ""
2082
-
2083
- #: widgets/image-grid/image-grid.php:115
2084
- msgid "Amount of spacing between images."
2085
  msgstr ""
2086
 
2087
  #: widgets/layout-slider/layout-slider.php:4, widgets/layout-slider/layout-slider.php:21
@@ -2680,7 +2684,7 @@ msgstr ""
2680
  msgid "Select cover image"
2681
  msgstr ""
2682
 
2683
- #: widgets/video/video.php:85, base/inc/widgets/base-slider.class.php:157
2684
  msgid "Video URL"
2685
  msgstr ""
2686
 
@@ -2688,7 +2692,7 @@ msgstr ""
2688
  msgid "Video Playback"
2689
  msgstr ""
2690
 
2691
- #: widgets/video/video.php:101, base/inc/widgets/base-slider.class.php:54, base/inc/widgets/base-slider.class.php:164
2692
  msgid "Autoplay"
2693
  msgstr ""
2694
 
@@ -2696,27 +2700,27 @@ msgstr ""
2696
  msgid "Loop"
2697
  msgstr ""
2698
 
2699
- #: widgets/video/video.php:115
2700
  msgid "Use FitVids"
2701
  msgstr ""
2702
 
2703
- #: widgets/video/video.php:116
2704
  msgid "FitVids will scale the video to fill the width of the widget area while maintaining aspect ratio."
2705
  msgstr ""
2706
 
2707
- #: widgets/video/video.php:121
2708
  msgid "Use oEmbed"
2709
  msgstr ""
2710
 
2711
- #: widgets/video/video.php:122
2712
  msgid "Always use the embedded video rather than the MediaElement player."
2713
  msgstr ""
2714
 
2715
- #: widgets/video/video.php:131
2716
  msgid "Show related videos."
2717
  msgstr ""
2718
 
2719
- #: widgets/video/video.php:132
2720
  msgid "If the external host supports it."
2721
  msgstr ""
2722
 
@@ -2785,11 +2789,11 @@ msgstr ""
2785
  msgid "Use theme font"
2786
  msgstr ""
2787
 
2788
- #: base/inc/fields/icon.class.php:38
2789
  msgid "Choose Icon"
2790
  msgstr ""
2791
 
2792
- #: base/inc/fields/icon.class.php:41, base/inc/fields/media.class.php:111, base/inc/fields/multiple-media.class.php:74, base/inc/fields/multiple-media.class.php:92
2793
  msgid "Remove"
2794
  msgstr ""
2795
 
@@ -3017,123 +3021,127 @@ msgstr ""
3017
  msgid "%s is not a SiteOrigin Widget"
3018
  msgstr ""
3019
 
3020
- #: base/inc/widgets/base-slider.class.php:55
3021
  msgid "Change slides automatically without user interaction."
3022
  msgstr ""
3023
 
3024
- #: base/inc/widgets/base-slider.class.php:68
3025
  msgid "Autoplay pause on hover"
3026
  msgstr ""
3027
 
3028
- #: base/inc/widgets/base-slider.class.php:77
3029
  msgid "Animation speed"
3030
  msgstr ""
3031
 
3032
- #: base/inc/widgets/base-slider.class.php:78
3033
  msgid "Animation speed in milliseconds."
3034
  msgstr ""
3035
 
3036
- #: base/inc/widgets/base-slider.class.php:84
3037
  msgid "Timeout"
3038
  msgstr ""
3039
 
3040
- #: base/inc/widgets/base-slider.class.php:85
3041
  msgid "How long each frame is displayed for in milliseconds."
3042
  msgstr ""
3043
 
3044
- #: base/inc/widgets/base-slider.class.php:95
3045
  msgid "Navigation color"
3046
  msgstr ""
3047
 
3048
- #: base/inc/widgets/base-slider.class.php:101
3049
  msgid "Navigation style"
3050
  msgstr ""
3051
 
3052
- #: base/inc/widgets/base-slider.class.php:104
3053
  msgid "Ultra thin"
3054
  msgstr ""
3055
 
3056
- #: base/inc/widgets/base-slider.class.php:105
3057
  msgid "Thin"
3058
  msgstr ""
3059
 
3060
- #: base/inc/widgets/base-slider.class.php:107
3061
  msgid "Thick"
3062
  msgstr ""
3063
 
3064
- #: base/inc/widgets/base-slider.class.php:108
3065
  msgid "Rounded ultra thin"
3066
  msgstr ""
3067
 
3068
- #: base/inc/widgets/base-slider.class.php:109
3069
  msgid "Rounded thin"
3070
  msgstr ""
3071
 
3072
- #: base/inc/widgets/base-slider.class.php:110
3073
  msgid "Rounded medium"
3074
  msgstr ""
3075
 
3076
- #: base/inc/widgets/base-slider.class.php:111
3077
  msgid "Rounded thick"
3078
  msgstr ""
3079
 
3080
- #: base/inc/widgets/base-slider.class.php:117
3081
  msgid "Navigation size"
3082
  msgstr ""
3083
 
3084
- #: base/inc/widgets/base-slider.class.php:123
3085
  msgid "Always show navigation on desktop"
3086
  msgstr ""
3087
 
3088
- #: base/inc/widgets/base-slider.class.php:128
3089
  msgid "Always show navigation on mobile"
3090
  msgstr ""
3091
 
3092
- #: base/inc/widgets/base-slider.class.php:133
3093
  msgid "Swipe control"
3094
  msgstr ""
3095
 
3096
- #: base/inc/widgets/base-slider.class.php:134
3097
  msgid "Allow users to swipe through frames on mobile devices."
3098
  msgstr ""
3099
 
3100
- #: base/inc/widgets/base-slider.class.php:140
3101
  msgid "Show slide background videos on mobile"
3102
  msgstr ""
3103
 
3104
- #: base/inc/widgets/base-slider.class.php:141
3105
  msgid "Allow slide background videos to appear on mobile devices that support autoplay."
3106
  msgstr ""
3107
 
3108
- #: base/inc/widgets/base-slider.class.php:151
 
 
 
 
3109
  msgid "Video file"
3110
  msgstr ""
3111
 
3112
- #: base/inc/widgets/base-slider.class.php:159
3113
  msgid "An external URL of the video. Overrides video file."
3114
  msgstr ""
3115
 
3116
- #: base/inc/widgets/base-slider.class.php:166
3117
- msgid "Currently only for YouTube videos."
3118
  msgstr ""
3119
 
3120
- #: base/inc/widgets/base-slider.class.php:171
3121
  msgid "Video format"
3122
  msgstr ""
3123
 
3124
- #: base/inc/widgets/base-slider.class.php:187
3125
  msgid "This setting controls when the Slider will switch to the responsive mode. This breakpoint will only be used if always show navigation on mobile is enabled. The default value is 780px."
3126
  msgstr ""
3127
 
3128
- #: base/inc/widgets/base-slider.class.php:235
3129
  msgid "display slide %s"
3130
  msgstr ""
3131
 
3132
- #: base/inc/widgets/base-slider.class.php:240
3133
  msgid "next slide"
3134
  msgstr ""
3135
 
3136
- #: base/inc/widgets/base-slider.class.php:246
3137
  msgid "previous slide"
3138
  msgstr ""
3139
 
36
  msgid "https://siteorigin.com/widgets-bundle/"
37
  msgstr ""
38
 
39
+ #: so-widgets-bundle.php:387, so-widgets-bundle.php:411, so-widgets-bundle.php:424, so-widgets-bundle.php:454, so-widgets-bundle.php:465, so-widgets-bundle.php:532, so-widgets-bundle.php:543, base/base.php:51, base/base.php:55, base/inc/actions.php:11, base/inc/actions.php:77, base/inc/actions.php:121, base/inc/actions.php:157, base/inc/actions.php:170, base/inc/actions.php:174, base/inc/actions.php:265, base/inc/actions.php:268
40
  msgid "Invalid request."
41
  msgstr ""
42
 
43
+ #: so-widgets-bundle.php:391, so-widgets-bundle.php:414, so-widgets-bundle.php:457, base/inc/routes/siteorigin-widgets-resource.class.php:55
44
  msgid "Insufficient permissions."
45
  msgstr ""
46
 
47
+ #: so-widgets-bundle.php:394, so-widgets-bundle.php:538, base/inc/actions.php:23
48
  msgid "Invalid post."
49
  msgstr ""
50
 
51
+ #: so-widgets-bundle.php:482, so-widgets-bundle.php:483, compat/visual-composer/visual-composer.php:40
52
  msgid "SiteOrigin Widgets"
53
  msgstr ""
54
 
55
+ #: so-widgets-bundle.php:508
56
  msgid "%s was %s"
57
  msgstr ""
58
 
59
+ #: so-widgets-bundle.php:510
60
  msgid "Activated"
61
  msgstr ""
62
 
63
+ #: so-widgets-bundle.php:510
64
  msgid "Deactivated"
65
  msgstr ""
66
 
67
+ #: so-widgets-bundle.php:773
68
  msgid "Manage Widgets"
69
  msgstr ""
70
 
71
+ #: so-widgets-bundle.php:774
72
  msgid "Support"
73
  msgstr ""
74
 
75
+ #: base/siteorigin-widget.class.php:511
76
  msgid "Preview"
77
  msgstr ""
78
 
79
+ #: base/siteorigin-widget.class.php:516
80
  msgid "Help"
81
  msgstr ""
82
 
83
+ #: base/siteorigin-widget.class.php:582
84
  msgid "This widget has scripts and styles that need to be loaded before you can use it. Please save and reload your current page."
85
  msgstr ""
86
 
87
+ #: base/siteorigin-widget.class.php:583
88
  msgid "You will only need to do this once."
89
  msgstr ""
90
 
91
+ #: base/siteorigin-widget.class.php:610
92
  msgid "Are you sure?"
93
  msgstr ""
94
 
95
+ #: base/siteorigin-widget.class.php:612
96
  msgid "There is a newer version of this widget's content available."
97
  msgstr ""
98
 
99
+ #: base/siteorigin-widget.class.php:613, base/siteorigin-widget.class.php:617
100
  msgid "Restore"
101
  msgstr ""
102
 
103
+ #: base/siteorigin-widget.class.php:614
104
  msgid "Dismiss"
105
  msgstr ""
106
 
107
+ #: base/siteorigin-widget.class.php:616
108
  msgid "Clicking %s will replace the current widget contents. You can revert by refreshing the page before updating."
109
  msgstr ""
110
 
111
+ #: base/siteorigin-widget.class.php:667, base/inc/actions.php:53
112
  msgid "Widget Preview"
113
  msgstr ""
114
 
240
  msgid "Current Color"
241
  msgstr ""
242
 
243
+ #: compat/block-editor/widget-block.php:82
244
  msgid "%s by %s"
245
  msgstr ""
246
 
247
+ #: compat/block-editor/widget-block.php:102, compat/visual-composer/visual-composer.php:77
248
  msgid "Selecting a different widget will revert any changes. Continue?"
249
  msgstr ""
250
 
251
+ #: compat/block-editor/widget-block.php:118
252
  msgid "You need to select a widget type before you'll see anything here. :)"
253
  msgstr ""
254
 
255
+ #: compat/block-editor/widget-block.php:182
256
  msgid "Invalid widget class %s. Please make sure the widget has been activated in %sSiteOrigin Widgets%s."
257
  msgstr ""
258
 
380
  msgid "SiteOrigin Button"
381
  msgstr ""
382
 
383
+ #: widgets/button/button.php:33, widgets/contact/contact.php:801, widgets/features/features.php:320, widgets/social-media-buttons/social-media-buttons.php:33, base/inc/widgets/base-slider.class.php:194
384
+ msgid "Responsive Breakpoint"
385
+ msgstr ""
386
+
387
+ #: widgets/button/button.php:35
388
+ msgid "This setting controls when the Mobile align setting will be used. The default value is 780px."
389
+ msgstr ""
390
+
391
+ #: widgets/button/button.php:57, widgets/price-table/price-table.php:93
392
  msgid "Button text"
393
  msgstr ""
394
 
395
+ #: widgets/button/button.php:62, widgets/google-map/google-map.php:103, widgets/headline/headline.php:47, widgets/headline/headline.php:118, widgets/hero/hero.php:128, widgets/icon/icon.php:57, widgets/image/image.php:90, widgets/layout-slider/layout-slider.php:98, widgets/simple-masonry/simple-masonry.php:89, widgets/slider/slider.php:103
396
  msgid "Destination URL"
397
  msgstr ""
398
 
399
+ #: widgets/button/button.php:69, widgets/google-map/google-map.php:114, widgets/headline/headline.php:52, widgets/headline/headline.php:123, widgets/icon/icon.php:63, widgets/simple-masonry/simple-masonry.php:94, widgets/social-media-buttons/social-media-buttons.php:97, widgets/taxonomy/taxonomy.php:65, widgets/testimonial/testimonial.php:94
400
  msgid "Open in a new window"
401
  msgstr ""
402
 
403
+ #: widgets/button/button.php:75
404
  msgid "Download"
405
  msgstr ""
406
 
407
+ #: widgets/button/button.php:76
408
  msgid "The button destination URL will be downloaded when a user clicks on the button."
409
  msgstr ""
410
 
411
+ #: widgets/button/button.php:81, widgets/button/button.php:85, widgets/features/features.php:78, widgets/icon/icon.php:31, widgets/price-table/price-table.php:119
412
  msgid "Icon"
413
  msgstr ""
414
 
415
+ #: widgets/button/button.php:90, widgets/features/features.php:88, widgets/price-table/price-table.php:123, widgets/social-media-buttons/social-media-buttons.php:82
416
  msgid "Icon color"
417
  msgstr ""
418
 
419
+ #: widgets/button/button.php:95
420
  msgid "Image icon"
421
  msgstr ""
422
 
423
+ #: widgets/button/button.php:96
424
  msgid "Replaces the icon with your own image icon."
425
  msgstr ""
426
 
427
+ #: widgets/button/button.php:101
428
  msgid "Icon Placement"
429
  msgstr ""
430
 
431
+ #: widgets/button/button.php:104, widgets/features/features.php:66, widgets/image-grid/image-grid.php:120
432
  msgid "Top"
433
  msgstr ""
434
 
435
+ #: widgets/button/button.php:105, widgets/button/button.php:131, widgets/button/button.php:142, widgets/contact/contact.php:403, widgets/contact/contact.php:418, widgets/contact/contact.php:647, widgets/cta/cta.php:103, widgets/features/features.php:67, widgets/headline/headline.php:92, widgets/headline/headline.php:163, widgets/headline/headline.php:218, widgets/icon/icon.php:50, widgets/image/image.php:50, widgets/image/image.php:62, widgets/image-grid/image-grid.php:123, widgets/simple-masonry/simple-masonry.php:216, widgets/social-media-buttons/social-media-buttons.php:153, widgets/social-media-buttons/social-media-buttons.php:164, widgets/testimonial/testimonial.php:256
436
  msgid "Right"
437
  msgstr ""
438
 
439
+ #: widgets/button/button.php:106, widgets/features/features.php:68, widgets/image-grid/image-grid.php:126
440
  msgid "Bottom"
441
  msgstr ""
442
 
443
+ #: widgets/button/button.php:107, widgets/button/button.php:130, widgets/button/button.php:141, widgets/contact/contact.php:402, widgets/contact/contact.php:417, widgets/contact/contact.php:646, widgets/cta/cta.php:102, widgets/features/features.php:69, widgets/headline/headline.php:91, widgets/headline/headline.php:162, widgets/headline/headline.php:217, widgets/icon/icon.php:49, widgets/image/image.php:49, widgets/image/image.php:61, widgets/image-grid/image-grid.php:129, widgets/simple-masonry/simple-masonry.php:215, widgets/social-media-buttons/social-media-buttons.php:152, widgets/social-media-buttons/social-media-buttons.php:163, widgets/testimonial/testimonial.php:255
444
  msgid "Left"
445
  msgstr ""
446
 
447
+ #: widgets/button/button.php:115, widgets/social-media-buttons/social-media-buttons.php:92
448
  msgid "Design and layout"
449
  msgstr ""
450
 
451
+ #: widgets/button/button.php:121, widgets/contact/contact.php:409, widgets/contact/contact.php:639, widgets/contact/contact.php:690, widgets/google-map/google-map.php:94, base/inc/fields/image-size.class.php:57
452
  msgid "Width"
453
  msgstr ""
454
 
455
+ #: widgets/button/button.php:122
456
  msgid "Leave blank to let the button resize according to content."
457
  msgstr ""
458
 
459
+ #: widgets/button/button.php:127, widgets/contact/contact.php:414, widgets/contact/contact.php:643, widgets/social-media-buttons/social-media-buttons.php:149
460
  msgid "Align"
461
  msgstr ""
462
 
463
+ #: widgets/button/button.php:132, widgets/button/button.php:143, widgets/contact/contact.php:419, widgets/contact/contact.php:648, widgets/headline/headline.php:90, widgets/headline/headline.php:161, widgets/headline/headline.php:216, widgets/icon/icon.php:48, widgets/image/image.php:51, widgets/image/image.php:63, widgets/social-media-buttons/social-media-buttons.php:154, widgets/social-media-buttons/social-media-buttons.php:165
464
  msgid "Center"
465
  msgstr ""
466
 
467
+ #: widgets/button/button.php:133, widgets/button/button.php:144, widgets/contact/contact.php:420, widgets/headline/headline.php:93, widgets/headline/headline.php:164, widgets/social-media-buttons/social-media-buttons.php:155, widgets/social-media-buttons/social-media-buttons.php:166
468
  msgid "Justify"
469
  msgstr ""
470
 
471
+ #: widgets/button/button.php:138
472
+ msgid "Mobile align"
473
+ msgstr ""
474
+
475
+ #: widgets/button/button.php:149, widgets/social-media-buttons/social-media-buttons.php:102
476
  msgid "Button theme"
477
  msgstr ""
478
 
479
+ #: widgets/button/button.php:152, widgets/price-table/price-table.php:134, widgets/social-media-buttons/social-media-buttons.php:105
480
  msgid "Atom"
481
  msgstr ""
482
 
483
+ #: widgets/button/button.php:153, widgets/social-media-buttons/social-media-buttons.php:106
484
  msgid "Flat"
485
  msgstr ""
486
 
487
+ #: widgets/button/button.php:154, widgets/social-media-buttons/social-media-buttons.php:107
488
  msgid "Wire"
489
  msgstr ""
490
 
491
+ #: widgets/button/button.php:161, widgets/price-table/price-table.php:150
492
  msgid "Button color"
493
  msgstr ""
494
 
495
+ #: widgets/button/button.php:166, widgets/contact/contact.php:441, widgets/contact/contact.php:614, widgets/hero/hero.php:261, widgets/layout-slider/layout-slider.php:208, widgets/testimonial/testimonial.php:227
496
  msgid "Text color"
497
  msgstr ""
498
 
499
+ #: widgets/button/button.php:172, widgets/social-media-buttons/social-media-buttons.php:112
500
  msgid "Use hover effects"
501
  msgstr ""
502
 
503
+ #: widgets/button/button.php:184
504
  msgid "Hover background color"
505
  msgstr ""
506
 
507
+ #: widgets/button/button.php:193
508
  msgid "Hover text color"
509
  msgstr ""
510
 
511
+ #: widgets/button/button.php:203, widgets/contact/contact.php:382, widgets/contact/contact.php:432, widgets/features/features.php:141, widgets/features/features.php:162, widgets/features/features.php:183, widgets/headline/headline.php:78, widgets/headline/headline.php:149
512
  msgid "Font"
513
  msgstr ""
514
 
515
+ #: widgets/button/button.php:209, widgets/contact/contact.php:387, widgets/contact/contact.php:437, widgets/contact/contact.php:619
516
  msgid "Font size"
517
  msgstr ""
518
 
519
+ #: widgets/button/button.php:211, widgets/contact/contact.php:291, widgets/contact/contact.php:525, widgets/contact/contact.php:627, widgets/social-media-buttons/social-media-buttons.php:119
520
  msgid "Normal"
521
  msgstr ""
522
 
523
+ #: widgets/button/button.php:212, widgets/button/button.php:236, widgets/social-media-buttons/social-media-buttons.php:120, widgets/social-media-buttons/social-media-buttons.php:142, widgets/social-media-buttons/social-media-buttons.php:175, base/inc/widgets/base-slider.class.php:109
524
  msgid "Medium"
525
  msgstr ""
526
 
527
+ #: widgets/button/button.php:213, widgets/social-media-buttons/social-media-buttons.php:121
528
  msgid "Large"
529
  msgstr ""
530
 
531
+ #: widgets/button/button.php:214, widgets/social-media-buttons/social-media-buttons.php:122
532
  msgid "Extra large"
533
  msgstr ""
534
 
535
+ #: widgets/button/button.php:220, widgets/social-media-buttons/social-media-buttons.php:127
536
  msgid "Rounding"
537
  msgstr ""
538
 
539
+ #: widgets/button/button.php:223, widgets/contact/contact.php:361, widgets/contact/contact.php:483, widgets/contact/contact.php:594, widgets/contact/contact.php:679, widgets/google-map/google-map.php:158, widgets/headline/headline.php:188, widgets/social-media-buttons/social-media-buttons.php:130
540
  msgid "None"
541
  msgstr ""
542
 
543
+ #: widgets/button/button.php:224, widgets/social-media-buttons/social-media-buttons.php:131
544
  msgid "Slightly rounded"
545
  msgstr ""
546
 
547
+ #: widgets/button/button.php:225, widgets/social-media-buttons/social-media-buttons.php:132
548
  msgid "Very rounded"
549
  msgstr ""
550
 
551
+ #: widgets/button/button.php:226, widgets/social-media-buttons/social-media-buttons.php:133
552
  msgid "Completely rounded"
553
  msgstr ""
554
 
555
+ #: widgets/button/button.php:232, widgets/contact/contact.php:343, widgets/contact/contact.php:449, widgets/contact/contact.php:634, widgets/social-media-buttons/social-media-buttons.php:138, widgets/testimonial/testimonial.php:235
556
  msgid "Padding"
557
  msgstr ""
558
 
559
+ #: widgets/button/button.php:235, widgets/social-media-buttons/social-media-buttons.php:141, widgets/social-media-buttons/social-media-buttons.php:174
560
  msgid "Low"
561
  msgstr ""
562
 
563
+ #: widgets/button/button.php:237, widgets/social-media-buttons/social-media-buttons.php:143, widgets/social-media-buttons/social-media-buttons.php:176
564
  msgid "High"
565
  msgstr ""
566
 
567
+ #: widgets/button/button.php:238, widgets/social-media-buttons/social-media-buttons.php:144, widgets/social-media-buttons/social-media-buttons.php:177
568
  msgid "Very high"
569
  msgstr ""
570
 
571
+ #: widgets/button/button.php:247
572
  msgid "Other attributes and SEO"
573
  msgstr ""
574
 
575
+ #: widgets/button/button.php:252, widgets/contact/contact.php:97
576
  msgid "Button ID"
577
  msgstr ""
578
 
579
+ #: widgets/button/button.php:253
580
  msgid "An ID attribute allows you to target this button in Javascript."
581
  msgstr ""
582
 
583
+ #: widgets/button/button.php:258
584
+ msgid "Button classes"
585
  msgstr ""
586
 
587
+ #: widgets/button/button.php:259
588
  msgid "Additional CSS classes added to the button link."
589
  msgstr ""
590
 
591
+ #: widgets/button/button.php:264
592
  msgid "Title attribute"
593
  msgstr ""
594
 
595
+ #: widgets/button/button.php:265
596
  msgid "Adds a title attribute to the button link."
597
  msgstr ""
598
 
599
+ #: widgets/button/button.php:270, widgets/contact/contact.php:102
600
  msgid "Onclick"
601
  msgstr ""
602
 
603
+ #: widgets/button/button.php:271
604
  msgid "Run this Javascript when the button is clicked. Ideal for tracking."
605
  msgstr ""
606
 
607
+ #: widgets/button/button.php:276
608
  msgid "Rel attribute"
609
  msgstr ""
610
 
611
+ #: widgets/button/button.php:277
612
  msgid "Adds a rel attribute to the button link."
613
  msgstr ""
614
 
1088
  msgid "Please write something"
1089
  msgstr ""
1090
 
 
 
 
 
1091
  #: widgets/contact/contact.php:803
1092
  msgid "This setting controls when the field max width will be disabled. The default value is 780px"
1093
  msgstr ""
2048
  msgid "Resize image to fit its container."
2049
  msgstr ""
2050
 
2051
+ #: widgets/image/image.php:242, widgets/image-grid/image-grid.php:256
2052
  msgid "Add a Lightbox to your images with %sSiteOrigin Premium%s"
2053
  msgstr ""
2054
 
2085
  msgstr ""
2086
 
2087
  #: widgets/image-grid/image-grid.php:114
2088
+ msgid "Image padding"
 
 
 
 
2089
  msgstr ""
2090
 
2091
  #: widgets/layout-slider/layout-slider.php:4, widgets/layout-slider/layout-slider.php:21
2684
  msgid "Select cover image"
2685
  msgstr ""
2686
 
2687
+ #: widgets/video/video.php:85, base/inc/widgets/base-slider.class.php:166
2688
  msgid "Video URL"
2689
  msgstr ""
2690
 
2692
  msgid "Video Playback"
2693
  msgstr ""
2694
 
2695
+ #: widgets/video/video.php:101, base/inc/widgets/base-slider.class.php:57, base/inc/widgets/base-slider.class.php:173
2696
  msgid "Autoplay"
2697
  msgstr ""
2698
 
2700
  msgid "Loop"
2701
  msgstr ""
2702
 
2703
+ #: widgets/video/video.php:111
2704
  msgid "Use FitVids"
2705
  msgstr ""
2706
 
2707
+ #: widgets/video/video.php:112
2708
  msgid "FitVids will scale the video to fill the width of the widget area while maintaining aspect ratio."
2709
  msgstr ""
2710
 
2711
+ #: widgets/video/video.php:117
2712
  msgid "Use oEmbed"
2713
  msgstr ""
2714
 
2715
+ #: widgets/video/video.php:118
2716
  msgid "Always use the embedded video rather than the MediaElement player."
2717
  msgstr ""
2718
 
2719
+ #: widgets/video/video.php:127
2720
  msgid "Show related videos."
2721
  msgstr ""
2722
 
2723
+ #: widgets/video/video.php:128
2724
  msgid "If the external host supports it."
2725
  msgstr ""
2726
 
2789
  msgid "Use theme font"
2790
  msgstr ""
2791
 
2792
+ #: base/inc/fields/icon.class.php:62
2793
  msgid "Choose Icon"
2794
  msgstr ""
2795
 
2796
+ #: base/inc/fields/icon.class.php:65, base/inc/fields/media.class.php:111, base/inc/fields/multiple-media.class.php:74, base/inc/fields/multiple-media.class.php:92
2797
  msgid "Remove"
2798
  msgstr ""
2799
 
3021
  msgid "%s is not a SiteOrigin Widget"
3022
  msgstr ""
3023
 
3024
+ #: base/inc/widgets/base-slider.class.php:58
3025
  msgid "Change slides automatically without user interaction."
3026
  msgstr ""
3027
 
3028
+ #: base/inc/widgets/base-slider.class.php:71
3029
  msgid "Autoplay pause on hover"
3030
  msgstr ""
3031
 
3032
+ #: base/inc/widgets/base-slider.class.php:80
3033
  msgid "Animation speed"
3034
  msgstr ""
3035
 
3036
+ #: base/inc/widgets/base-slider.class.php:81
3037
  msgid "Animation speed in milliseconds."
3038
  msgstr ""
3039
 
3040
+ #: base/inc/widgets/base-slider.class.php:87
3041
  msgid "Timeout"
3042
  msgstr ""
3043
 
3044
+ #: base/inc/widgets/base-slider.class.php:88
3045
  msgid "How long each frame is displayed for in milliseconds."
3046
  msgstr ""
3047
 
3048
+ #: base/inc/widgets/base-slider.class.php:98
3049
  msgid "Navigation color"
3050
  msgstr ""
3051
 
3052
+ #: base/inc/widgets/base-slider.class.php:104
3053
  msgid "Navigation style"
3054
  msgstr ""
3055
 
3056
+ #: base/inc/widgets/base-slider.class.php:107
3057
  msgid "Ultra thin"
3058
  msgstr ""
3059
 
3060
+ #: base/inc/widgets/base-slider.class.php:108
3061
  msgid "Thin"
3062
  msgstr ""
3063
 
3064
+ #: base/inc/widgets/base-slider.class.php:110
3065
  msgid "Thick"
3066
  msgstr ""
3067
 
3068
+ #: base/inc/widgets/base-slider.class.php:111
3069
  msgid "Rounded ultra thin"
3070
  msgstr ""
3071
 
3072
+ #: base/inc/widgets/base-slider.class.php:112
3073
  msgid "Rounded thin"
3074
  msgstr ""
3075
 
3076
+ #: base/inc/widgets/base-slider.class.php:113
3077
  msgid "Rounded medium"
3078
  msgstr ""
3079
 
3080
+ #: base/inc/widgets/base-slider.class.php:114
3081
  msgid "Rounded thick"
3082
  msgstr ""
3083
 
3084
+ #: base/inc/widgets/base-slider.class.php:120
3085
  msgid "Navigation size"
3086
  msgstr ""
3087
 
3088
+ #: base/inc/widgets/base-slider.class.php:126
3089
  msgid "Always show navigation on desktop"
3090
  msgstr ""
3091
 
3092
+ #: base/inc/widgets/base-slider.class.php:131
3093
  msgid "Always show navigation on mobile"
3094
  msgstr ""
3095
 
3096
+ #: base/inc/widgets/base-slider.class.php:136
3097
  msgid "Swipe control"
3098
  msgstr ""
3099
 
3100
+ #: base/inc/widgets/base-slider.class.php:137
3101
  msgid "Allow users to swipe through frames on mobile devices."
3102
  msgstr ""
3103
 
3104
+ #: base/inc/widgets/base-slider.class.php:143
3105
  msgid "Show slide background videos on mobile"
3106
  msgstr ""
3107
 
3108
+ #: base/inc/widgets/base-slider.class.php:144
3109
  msgid "Allow slide background videos to appear on mobile devices that support autoplay."
3110
  msgstr ""
3111
 
3112
+ #: base/inc/widgets/base-slider.class.php:149
3113
+ msgid "Loop slide background videos"
3114
+ msgstr ""
3115
+
3116
+ #: base/inc/widgets/base-slider.class.php:160
3117
  msgid "Video file"
3118
  msgstr ""
3119
 
3120
+ #: base/inc/widgets/base-slider.class.php:168
3121
  msgid "An external URL of the video. Overrides video file."
3122
  msgstr ""
3123
 
3124
+ #: base/inc/widgets/base-slider.class.php:175
3125
+ msgid "Autoplay can only be disabled for YouTube videos."
3126
  msgstr ""
3127
 
3128
+ #: base/inc/widgets/base-slider.class.php:180
3129
  msgid "Video format"
3130
  msgstr ""
3131
 
3132
+ #: base/inc/widgets/base-slider.class.php:196
3133
  msgid "This setting controls when the Slider will switch to the responsive mode. This breakpoint will only be used if always show navigation on mobile is enabled. The default value is 780px."
3134
  msgstr ""
3135
 
3136
+ #: base/inc/widgets/base-slider.class.php:247
3137
  msgid "display slide %s"
3138
  msgstr ""
3139
 
3140
+ #: base/inc/widgets/base-slider.class.php:252
3141
  msgid "next slide"
3142
  msgstr ""
3143
 
3144
+ #: base/inc/widgets/base-slider.class.php:258
3145
  msgid "previous slide"
3146
  msgstr ""
3147
 
readme.txt CHANGED
@@ -3,23 +3,23 @@ Tags: widget, button, slider, hero, google maps, image, carousel, features, icon
3
  Requires at least: 4.2
4
  Tested up to: 5.7
5
  Requires PHP: 5.6.20
6
- Stable tag: 1.19.0
7
- Build time: 2021-05-19T10:11:06+02:00
8
  License: GPLv3 or later
9
  Contributors: gpriday, braam-genis, alexgso
10
  Donate link: https://siteorigin.com/downloads/premium/
11
 
12
- The SiteOrigin Widgets Bundle gives you a collection of widgets that you can use and customize. All the widgets are built on our powerful framework, giving you advanced forms, unlimited colors, and 1500+ icons.
13
 
14
  == Description ==
15
 
16
- The SiteOrigin Widgets Bundle gives you a collection of widgets that you can use and customize. All the widgets are built on our powerful framework, giving you advanced forms, unlimited colors, and 1500+ icons.
17
 
18
- Widgets are great, no matter where you're using them. In [Page Builder](https://siteorigin.com/page-builder/), in the Block Editor using the SiteOrigin Layout Block or SiteOrigin Widget Block or in your theme's widget areas. The Widgets Bundle is even compatible with other popular page-building plugins.
19
 
20
  [vimeo https://vimeo.com/102103379]
21
 
22
- The collection is growing, but here's what we have so far:
23
 
24
  - **Accordion:** Squeeze a lot of content into a small space.
25
  - **Button:** A simple button widget with a variety of styling options.
@@ -44,7 +44,32 @@ The collection is growing, but here's what we have so far:
44
  - **Testimonials:** Share your product or service testimonials in a variety of different layouts.
45
  - **Video:** Play your self or externally hosted videos in a customizable player.
46
 
47
- Once you enable a widget, you'll be able to use it in Page Builder, the Block Editor using the SiteOrigin Layout Block or SiteOrigin Widget Block, or in any theme widget area. You can manage your widgets by going to Plugins > SiteOrigin Widgets in WordPress.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
  == Documentation ==
50
 
@@ -52,27 +77,46 @@ Once you enable a widget, you'll be able to use it in Page Builder, the Block Ed
52
 
53
  == Support ==
54
 
55
- We offer free support on the [SiteOrigin support forums](https://siteorigin.com/thread/).
56
 
57
  == SiteOrigin Premium ==
58
 
59
- [SiteOrigin Premium](https://siteorigin.com/downloads/premium/) enhances the Widgets Bundle with a vast array of additional features and settings. Take your layouts to the next level.
60
 
61
- SiteOrigin Premium also includes access to our next-level email support service, perfect for those times when you need fast and effective technical support.
62
 
63
- = Create Custom Widgets =
64
 
65
- The SiteOrigin Widgets Bundle is the perfect platform to build widgets for your theme or plugin. Read more in our [developer docs](https://siteorigin.com/docs/widgets-bundle/).
 
 
66
 
67
- == Screenshots ==
68
 
69
- 1. Manage which widgets you want enabled or disabled.
70
- 2. The button widget shows the clean, standard interface all the widgets use.
71
- 3. An example of the button widget.
72
 
 
73
  == Changelog ==
74
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  = 1.19.0 - 19 May 2021 =
 
76
  * Contact Form: Added a new `Number` field type.
77
  * Image Grid: Changed vertical align to baseline.
78
  * Layout Slider: Added a `slider_control` shortcode.
@@ -111,6 +155,7 @@ The SiteOrigin Widgets Bundle is the perfect platform to build widgets for your
111
  * Social Media Buttons: Added Discord.
112
  * Video: Added a `Loop` setting for self-hosted videos.
113
  * Video: If `autoplay` is enabled, `playsinline` will be added.
 
114
  * Developer: Post Carousel: Added `siteorigin_widgets_post_carousel_post_limit` filter
115
  * Developer: Google Maps: Corrected marker JavaScript property names.
116
  * Developer: Block Editor: Store and serve rendered widget.
3
  Requires at least: 4.2
4
  Tested up to: 5.7
5
  Requires PHP: 5.6.20
6
+ Stable tag: 1.20.0
7
+ Build time: 2021-06-01T20:59:59+02:00
8
  License: GPLv3 or later
9
  Contributors: gpriday, braam-genis, alexgso
10
  Donate link: https://siteorigin.com/downloads/premium/
11
 
12
+ The SiteOrigin Widgets Bundle gives you all the elements you need to build modern, responsive, and engaging website pages. Using the Widgets Bundle, you can quickly and effortlessly add buttons, sliders, heroes, maps, images, carousels, features, icons, and so much more.
13
 
14
  == Description ==
15
 
16
+ The SiteOrigin Widgets Bundle gives you all the elements you need to build modern, responsive, and engaging website pages. Using the Widgets Bundle, you can quickly and effortlessly add buttons, sliders, heroes, maps, images, carousels, features, icons, and so much more.
17
 
18
+ SiteOrigin Widgets are ready to be used **anywhere**, in [Page Builder by SiteOrigin](https://siteorigin.com/page-builder/), in the Block Editor or your theme's widget areas. The Widgets Bundle is even compatible with other popular page-building plugins.
19
 
20
  [vimeo https://vimeo.com/102103379]
21
 
22
+ Our collection is growing; here's what we have so far:
23
 
24
  - **Accordion:** Squeeze a lot of content into a small space.
25
  - **Button:** A simple button widget with a variety of styling options.
44
  - **Testimonials:** Share your product or service testimonials in a variety of different layouts.
45
  - **Video:** Play your self or externally hosted videos in a customizable player.
46
 
47
+ = Ready to Be Used Anywhere =
48
+
49
+ - **Page Builder by SiteOrigin:** Insert widgets in Page Builder by SiteOrigin in either the Classic Editor or Page Builder Layout Block in the Block Editor.
50
+ - **Block Editor:** The Widgets Bundle is 100% Block Editor compatible. Insert widgets using the SiteOrigin Widgets Block featuring a live widget search form.
51
+ - **Theme and Plugin Widget Areas:** Insert widgets in any theme or plugin widget area.
52
+ - **In Other Popular Page Builder Plugins:** Insert widgets in Elementor or Beaver Builder.
53
+
54
+ = Built for Speed =
55
+
56
+ We carefully built each widget for the best possible page size and load time. The Widgets Bundle is perfectly compatible with [Autoptimize](https://wordpress.org/plugins/autoptimize/) and all other major performance plugins.
57
+
58
+ = SEO Optimized =
59
+
60
+ The Widgets Bundle uses modern SEO best practices and seamlessly integrates with all major SEO plugins.
61
+
62
+ = Accessibility Ready =
63
+
64
+ The Widgets Bundle is accessibility-ready. Tab through all form fields and settings, make changes without using a mouse.
65
+
66
+ = Actively Developed =
67
+
68
+ SiteOrigin has been creating magical tools for your WordPress website since 2011. We actively develop the Widgets Bundle with updates released several times a month, including new features and fixes as required. View our Widgets Bundle work on [GitHub](https://github.com/siteorigin/so-widgets-bundle).
69
+
70
+ = Create Custom Widgets =
71
+
72
+ Access a huge array of features and save time by developing custom widgets for your theme or plugin on the Widgets Bundle Framework. Read more in our extensive [developer documentation](https://siteorigin.com/docs/widgets-bundle/).
73
 
74
  == Documentation ==
75
 
77
 
78
  == Support ==
79
 
80
+ Free support is available on the [SiteOrigin support forums](https://siteorigin.com/thread/).
81
 
82
  == SiteOrigin Premium ==
83
 
84
+ [SiteOrigin Premium](https://siteorigin.com/downloads/premium/) enhances the Widgets Bundle with a vast array of additional features and settings. Take your layouts to the next level with SiteOrigin Premium addons.
85
 
86
+ SiteOrigin Premium includes access to our professional email support service, perfect for those times when you need fast and effective technical support. We're standing by to assist you in any way we can.
87
 
88
+ == Screenshots ==
89
 
90
+ 1. Manage which widgets you want to be enabled or disabled.
91
+ 2. The Button Widget shows the clean, standard interface all the widgets use.
92
+ 3. An example of the Button Widget.
93
 
94
+ == Frequently Asked Questions ==
95
 
96
+ = The widget I'd like to add isn't available; where can I enable it? =
 
 
97
 
98
+ The Widgets Bundle global interface is available at Plugins > SiteOrigin Widgets. Widgets can be enabled or disabled as needed. If a widget offers global settings, you can access those via the Settings button next to each applicable widget.
99
  == Changelog ==
100
 
101
+ = 1.20.0 - 01 June 2021 =
102
+ * Added integration for WP Super Cache and Swift Performance plugins.
103
+ * Button: Added a `Mobile align` setting and global Button `Responsive Breakpoint` setting at `Plugins > SiteOrigin Widgets > Button: Settings`.
104
+ * Contact Form: Allowed whitelisted HTML in checkbox option fields.
105
+ * Headline: Fixed invalid font property when multiple font variants in use.
106
+ * Image: Added native lazy `loading` attribute.
107
+ * Image Grid: Added native lazy `loading` attribute for external images.
108
+ * Image Grid: Changed `Spacing` setting to a multi-measurement field and renamed it to `Image padding`.
109
+ * Sliders: Added `Loop slide background videos` setting.
110
+ * Sliders: Improved background video autoplay setting description.
111
+ * Sliders: Removed `wp_is_mobile` dependency to improve caching.
112
+ * Video Player: Added `Loop` setting for YouTube videos.
113
+ * Widget Block: Resolved Contact Form nonce error.
114
+ * Widget Block: Resolved `Only variables should be passed by reference` notice.
115
+ * Developer: Cleared the Icon Widget default icon if the icon font family doesn't exist.
116
+ * Developer: Fixed multiple media remove link detection.
117
+
118
  = 1.19.0 - 19 May 2021 =
119
+ * Button: Allow shortcodes in `Destination URL` field. Only shortcodes that return a URL are suitable.
120
  * Contact Form: Added a new `Number` field type.
121
  * Image Grid: Changed vertical align to baseline.
122
  * Layout Slider: Added a `slider_control` shortcode.
155
  * Social Media Buttons: Added Discord.
156
  * Video: Added a `Loop` setting for self-hosted videos.
157
  * Video: If `autoplay` is enabled, `playsinline` will be added.
158
+ * Accessibility: Implemented keyboard navigation for the Widgets Bundle admin interface. You can now tab through all fields and settings, and make changes without a mouse.
159
  * Developer: Post Carousel: Added `siteorigin_widgets_post_carousel_post_limit` filter
160
  * Developer: Google Maps: Corrected marker JavaScript property names.
161
  * Developer: Block Editor: Store and serve rendered widget.
so-widgets-bundle.php CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
  Plugin Name: SiteOrigin Widgets Bundle
4
  Description: A collection of all widgets, neatly bundled into a single plugin. It's also a framework to code your own widgets on top of.
5
- Version: 1.19.0
6
  Text Domain: so-widgets-bundle
7
  Domain Path: /lang
8
  Author: SiteOrigin
@@ -12,7 +12,7 @@ License: GPL3
12
  License URI: https://www.gnu.org/licenses/gpl-3.0.txt
13
  */
14
 
15
- define('SOW_BUNDLE_VERSION', '1.19.0');
16
  define('SOW_BUNDLE_BASE_FILE', __FILE__);
17
 
18
  // Allow JS suffix to be pre-set
@@ -47,6 +47,7 @@ class SiteOrigin_Widgets_Bundle {
47
  function __construct(){
48
  add_action('admin_init', array($this, 'admin_activate_widget') );
49
  add_action('admin_menu', array($this, 'admin_menu_init') );
 
50
  add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts') );
51
  add_action('admin_enqueue_scripts', array($this, 'admin_register_scripts') );
52
 
@@ -158,6 +159,8 @@ class SiteOrigin_Widgets_Bundle {
158
  */
159
  function clear_widget_cache() {
160
  // Remove all cached CSS for SiteOrigin Widgets
 
 
161
  if( function_exists('WP_Filesystem') && WP_Filesystem() ) {
162
  global $wp_filesystem;
163
  $upload_dir = wp_upload_dir();
@@ -170,6 +173,9 @@ class SiteOrigin_Widgets_Bundle {
170
  $wp_filesystem->delete( $upload_dir['basedir'] . '/siteorigin-widgets/' . $file['name'] );
171
  }
172
  }
 
 
 
173
  }
174
  }
175
 
@@ -313,7 +319,48 @@ class SiteOrigin_Widgets_Bundle {
313
 
314
  }
315
  }
316
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  /**
318
  * Register some common scripts used in forms.
319
  */
2
  /*
3
  Plugin Name: SiteOrigin Widgets Bundle
4
  Description: A collection of all widgets, neatly bundled into a single plugin. It's also a framework to code your own widgets on top of.
5
+ Version: 1.20.0
6
  Text Domain: so-widgets-bundle
7
  Domain Path: /lang
8
  Author: SiteOrigin
12
  License URI: https://www.gnu.org/licenses/gpl-3.0.txt
13
  */
14
 
15
+ define('SOW_BUNDLE_VERSION', '1.20.0');
16
  define('SOW_BUNDLE_BASE_FILE', __FILE__);
17
 
18
  // Allow JS suffix to be pre-set
47
  function __construct(){
48
  add_action('admin_init', array($this, 'admin_activate_widget') );
49
  add_action('admin_menu', array($this, 'admin_menu_init') );
50
+ add_action('admin_init', array( $this, 'clear_file_cache' ) );
51
  add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts') );
52
  add_action('admin_enqueue_scripts', array($this, 'admin_register_scripts') );
53
 
159
  */
160
  function clear_widget_cache() {
161
  // Remove all cached CSS for SiteOrigin Widgets
162
+
163
+ require_once ABSPATH . 'wp-admin/includes/file.php';
164
  if( function_exists('WP_Filesystem') && WP_Filesystem() ) {
165
  global $wp_filesystem;
166
  $upload_dir = wp_upload_dir();
173
  $wp_filesystem->delete( $upload_dir['basedir'] . '/siteorigin-widgets/' . $file['name'] );
174
  }
175
  }
176
+
177
+ // Alert other plugins that we've deleted all CSS files.
178
+ do_action( 'siteorigin_widgets_stylesheet_cleared' );
179
  }
180
  }
181
 
319
 
320
  }
321
  }
322
+
323
+ /**
324
+ * Clear all old CSS files.
325
+ *
326
+ * @var bool $force_delete Whether to forcefully clear the file cache.
327
+ * @var int $css_expire The maximum age of a file before it's removed.
328
+ */
329
+ public static function clear_file_cache( $force_delete = false, $css_expire = 604800 ) {
330
+ // Use this variable to ensure this only runs once per request.
331
+ static $done = false;
332
+
333
+ if ( $done && ! $force_delete ) {
334
+ return;
335
+ }
336
+
337
+ if ( ! get_transient( 'sow:cleared' ) || $force_delete ) {
338
+ require_once ABSPATH . 'wp-admin/includes/file.php';
339
+ if ( WP_Filesystem() ) {
340
+ global $wp_filesystem;
341
+ $upload_dir = wp_upload_dir();
342
+
343
+ $list = $wp_filesystem->dirlist( $upload_dir['basedir'] . '/siteorigin-widgets/' );
344
+ if ( ! empty( $list ) ) {
345
+ foreach( $list as $file ) {
346
+ if ( $file['lastmodunix'] < time() - $css_expire || $force_delete ) {
347
+ // Delete the file.
348
+ $wp_filesystem->delete( $upload_dir['basedir'] . '/siteorigin-widgets/' . $file['name'] );
349
+
350
+ // Alert other plugins that we've deleted a CSS file.
351
+ do_action( 'siteorigin_widgets_stylesheet_deleted', $file['name'] );
352
+ }
353
+ }
354
+ }
355
+ }
356
+
357
+ // Set this transient so we know when to clear all the generated CSS.
358
+ set_transient( 'sow:cleared', true, $css_expire );
359
+ }
360
+
361
+ $done = true;
362
+ }
363
+
364
  /**
365
  * Register some common scripts used in forms.
366
  */
widgets/button/button.php CHANGED
@@ -26,6 +26,17 @@ class SiteOrigin_Widget_Button_Widget extends SiteOrigin_Widget {
26
 
27
  }
28
 
 
 
 
 
 
 
 
 
 
 
 
29
  function initialize() {
30
  $this->register_frontend_styles(
31
  array(
@@ -122,7 +133,17 @@ class SiteOrigin_Widget_Button_Widget extends SiteOrigin_Widget {
122
  'justify' => __('Justify', 'so-widgets-bundle'),
123
  ),
124
  ),
125
-
 
 
 
 
 
 
 
 
 
 
126
  'theme' => array(
127
  'type' => 'select',
128
  'label' => __('Button theme', 'so-widgets-bundle'),
@@ -234,7 +255,7 @@ class SiteOrigin_Widget_Button_Widget extends SiteOrigin_Widget {
234
 
235
  'classes' => array(
236
  'type' => 'text',
237
- 'label' => __('Button Classes', 'so-widgets-bundle'),
238
  'description' => __('Additional CSS classes added to the button link.', 'so-widgets-bundle'),
239
  ),
240
 
@@ -360,6 +381,9 @@ class SiteOrigin_Widget_Button_Widget extends SiteOrigin_Widget {
360
  'rounding' => isset($instance['design']['rounding']) ? $instance['design']['rounding'] . 'em' : '',
361
  'padding' => isset($instance['design']['padding']) ? $instance['design']['padding'] . 'em' : '',
362
  'has_text' => empty( $instance['text'] ) ? 'false' : 'true',
 
 
 
363
  );
364
 
365
  if ( ! empty( $instance['design']['font'] ) ) {
@@ -415,6 +439,15 @@ class SiteOrigin_Widget_Button_Widget extends SiteOrigin_Widget {
415
  }
416
  }
417
 
 
 
 
 
 
 
 
 
 
418
  return $instance;
419
  }
420
  }
26
 
27
  }
28
 
29
+ function get_settings_form() {
30
+ return array(
31
+ 'responsive_breakpoint' => array(
32
+ 'type' => 'measurement',
33
+ 'label' => __( 'Responsive Breakpoint', 'so-widgets-bundle' ),
34
+ 'default' => '780px',
35
+ 'description' => __( 'This setting controls when the Mobile align setting will be used. The default value is 780px.', 'so-widgets-bundle' ),
36
+ )
37
+ );
38
+ }
39
+
40
  function initialize() {
41
  $this->register_frontend_styles(
42
  array(
133
  'justify' => __('Justify', 'so-widgets-bundle'),
134
  ),
135
  ),
136
+ 'mobile_align' => array(
137
+ 'type' => 'select',
138
+ 'label' => __( 'Mobile align', 'so-widgets-bundle' ),
139
+ 'default' => 'center',
140
+ 'options' => array(
141
+ 'left' => __( 'Left', 'so-widgets-bundle' ),
142
+ 'right' => __( 'Right', 'so-widgets-bundle' ),
143
+ 'center' => __( 'Center', 'so-widgets-bundle' ),
144
+ 'justify' => __( 'Justify', 'so-widgets-bundle' ),
145
+ ),
146
+ ),
147
  'theme' => array(
148
  'type' => 'select',
149
  'label' => __('Button theme', 'so-widgets-bundle'),
255
 
256
  'classes' => array(
257
  'type' => 'text',
258
+ 'label' => __('Button classes', 'so-widgets-bundle'),
259
  'description' => __('Additional CSS classes added to the button link.', 'so-widgets-bundle'),
260
  ),
261
 
381
  'rounding' => isset($instance['design']['rounding']) ? $instance['design']['rounding'] . 'em' : '',
382
  'padding' => isset($instance['design']['padding']) ? $instance['design']['padding'] . 'em' : '',
383
  'has_text' => empty( $instance['text'] ) ? 'false' : 'true',
384
+ 'responsive_breakpoint' => $this->get_global_settings( 'responsive_breakpoint' ),
385
+ 'align' => $instance['design']['align'],
386
+ 'mobile_align' => $instance['design']['mobile_align'],
387
  );
388
 
389
  if ( ! empty( $instance['design']['font'] ) ) {
439
  }
440
  }
441
 
442
+ // If the mobile_align setting isn't set, set it to the same value as the align value.
443
+ if (
444
+ ! empty( $instance['design'] ) &&
445
+ ! empty( $instance['design']['align'] ) &&
446
+ empty( $instance['design']['mobile_align'] )
447
+ ) {
448
+ $instance['design']['mobile_align'] = $instance['design']['align'];
449
+ }
450
+
451
  return $instance;
452
  }
453
  }
widgets/button/styles/atom.less CHANGED
@@ -1,5 +1,9 @@
1
  @import "../../../base/less/mixins";
2
 
 
 
 
 
3
  @button_width: '';
4
  @button_color: #41a9d5;
5
  @border_color: darken(@button_color, 15%);
@@ -18,6 +22,24 @@
18
 
19
  .ow-button-base {
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  a {
22
  .box-sizing(border-box);
23
  & when( isnumber( @button_width ) ) {
1
  @import "../../../base/less/mixins";
2
 
3
+ @responsive_breakpoint: 780px;
4
+ @align: center;
5
+ @mobile_align: center;
6
+
7
  @button_width: '';
8
  @button_color: #41a9d5;
9
  @border_color: darken(@button_color, 15%);
22
 
23
  .ow-button-base {
24
 
25
+ @media (max-width: @responsive_breakpoint) {
26
+ &.ow-button-align-@{align} {
27
+ text-align: @mobile_align;
28
+
29
+ & when not ( @mobile_align = justify ) {
30
+ &.ow-button-align-justify a {
31
+ display: inline-block;
32
+ }
33
+ }
34
+
35
+ & when ( @mobile_align = justify ) {
36
+ a {
37
+ display: block;
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
  a {
44
  .box-sizing(border-box);
45
  & when( isnumber( @button_width ) ) {
widgets/button/styles/flat.less CHANGED
@@ -1,5 +1,9 @@
1
  @import "../../../base/less/mixins";
2
 
 
 
 
 
3
  @button_width: '';
4
  @button_color: #41a9d5;
5
  @border_color: darken(@button_color, 5%);
@@ -19,6 +23,24 @@
19
  .ow-button-base {
20
  .clearfix();
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  a {
23
  .box-sizing(border-box);
24
  & when( isnumber( @button_width ) ) {
1
  @import "../../../base/less/mixins";
2
 
3
+ @responsive_breakpoint: 780px;
4
+ @align: center;
5
+ @mobile_align: center;
6
+
7
  @button_width: '';
8
  @button_color: #41a9d5;
9
  @border_color: darken(@button_color, 5%);
23
  .ow-button-base {
24
  .clearfix();
25
 
26
+ @media (max-width: @responsive_breakpoint) {
27
+ &.ow-button-align-@{align} {
28
+ text-align: @mobile_align;
29
+
30
+ & when not ( @mobile_align = justify ) {
31
+ &.ow-button-align-justify a {
32
+ display: inline-block;
33
+ }
34
+ }
35
+
36
+ & when ( @mobile_align = justify ) {
37
+ a {
38
+ display: block;
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
  a {
45
  .box-sizing(border-box);
46
  & when( isnumber( @button_width ) ) {
widgets/button/styles/wire.less CHANGED
@@ -1,5 +1,9 @@
1
  @import "../../../base/less/mixins";
2
 
 
 
 
 
3
  @button_width: '';
4
  @button_color: #41a9d5;
5
  @text_color: #FFFFFF;
@@ -18,6 +22,24 @@
18
  .ow-button-base {
19
  .clearfix();
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  a {
22
  .box-sizing(border-box);
23
  & when( isnumber( @button_width ) ) {
1
  @import "../../../base/less/mixins";
2
 
3
+ @responsive_breakpoint: 780px;
4
+ @align: center;
5
+ @mobile_align: center;
6
+
7
  @button_width: '';
8
  @button_color: #41a9d5;
9
  @text_color: #FFFFFF;
22
  .ow-button-base {
23
  .clearfix();
24
 
25
+ @media (max-width: @responsive_breakpoint) {
26
+ &.ow-button-align-@{align} {
27
+ text-align: @mobile_align;
28
+
29
+ & when not ( @mobile_align = justify ) {
30
+ &.ow-button-align-justify a {
31
+ display: inline-block;
32
+ }
33
+ }
34
+
35
+ & when ( @mobile_align = justify ) {
36
+ a {
37
+ display: block;
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
  a {
44
  .box-sizing(border-box);
45
  & when( isnumber( @button_width ) ) {
widgets/contact/fields/checkboxes.class.php CHANGED
@@ -11,9 +11,9 @@ class SiteOrigin_Widget_ContactForm_Field_Checkboxes extends SiteOrigin_Widget_C
11
  <ul>
12
  <?php foreach ( $options['field']['options'] as $i => $option ): ?>
13
  <li>
14
- <label>
15
- <input type="checkbox" value="<?php echo esc_attr( $option['value'] ) ?>" name="<?php echo esc_attr( $options['field_name'] ) ?>[]" id="<?php echo esc_attr( $options['field_id'] ) . '-' . $i ?>"<?php echo checked( in_array( $option['value'], $options['value'] ), true, false ) ?>/>
16
- <?php echo esc_html( $option['value'] ); ?>
17
  </label>
18
  </li>
19
  <?php endforeach; ?>
11
  <ul>
12
  <?php foreach ( $options['field']['options'] as $i => $option ): ?>
13
  <li>
14
+ <input type="checkbox" value="<?php echo esc_attr( $option['value'] ) ?>" name="<?php echo esc_attr( $options['field_name'] ) ?>[]" id="<?php echo esc_attr( $options['field_id'] ) . '-' . $i ?>"<?php echo checked( in_array( $option['value'], $options['value'] ), true, false ) ?>/>
15
+ <label for="<?php echo esc_attr( $options['field_id'] ) . '-' . $i ?>">
16
+ <?php echo wp_kses_post( $option['value'] ); ?>
17
  </label>
18
  </li>
19
  <?php endforeach; ?>
widgets/contact/styles/default.less CHANGED
@@ -120,7 +120,7 @@
120
  .font(@field_font_family, @field_font_weight);
121
  }
122
 
123
- &.sow-form-field-checkboxes, &.sow-form-field-radio {
124
  ul {
125
  list-style: none;
126
  margin: 0;
@@ -144,6 +144,29 @@
144
  }
145
  }
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  @description_font_size: 0.9em;
148
  @description_font_color: #999999;
149
  @description_font_style: italic;
120
  .font(@field_font_family, @field_font_weight);
121
  }
122
 
123
+ &.sow-form-field-radio {
124
  ul {
125
  list-style: none;
126
  margin: 0;
144
  }
145
  }
146
 
147
+ &.sow-form-field-checkboxes {
148
+ ul {
149
+ list-style: none;
150
+ margin: 0;
151
+ padding: 0;
152
+
153
+ li {
154
+ align-items: center;
155
+ display: flex;
156
+ margin: 0;
157
+ }
158
+
159
+ label {
160
+ margin-bottom: 0;
161
+ }
162
+
163
+ input {
164
+ height: auto;
165
+ margin-right: 0.5em;
166
+ }
167
+ }
168
+ }
169
+
170
  @description_font_size: 0.9em;
171
  @description_font_color: #999999;
172
  @description_font_style: italic;
widgets/contact/tpl/default.php CHANGED
@@ -28,7 +28,7 @@ else {
28
  );
29
  }
30
  ?>
31
- <form action="<?php echo esc_url( add_query_arg( false, false ) ) ?>#contact-form-<?php echo esc_attr( $short_hash ) ?>"
32
  method="POST" class="sow-contact-form" id="contact-form-<?php echo esc_attr( $short_hash ) ?>">
33
 
34
  <?php if( !empty($result['errors']['_general']) ) : ?>
28
  );
29
  }
30
  ?>
31
+ <form action="#contact-form-<?php echo esc_attr( $short_hash ); ?>"
32
  method="POST" class="sow-contact-form" id="contact-form-<?php echo esc_attr( $short_hash ) ?>">
33
 
34
  <?php if( !empty($result['errors']['_general']) ) : ?>
widgets/headline/headline.php CHANGED
@@ -287,7 +287,8 @@ class SiteOrigin_Widget_Headline_Widget extends SiteOrigin_Widget {
287
  $font = siteorigin_widget_get_font( $instance['headline']['font'] );
288
  $less_vars['headline_font'] = $font['family'];
289
  if ( ! empty( $font['weight'] ) ) {
290
- $less_vars['headline_font_weight'] = $font['weight'];
 
291
  }
292
  }
293
 
@@ -305,7 +306,8 @@ class SiteOrigin_Widget_Headline_Widget extends SiteOrigin_Widget {
305
  $font = siteorigin_widget_get_font( $instance['sub_headline']['font'] );
306
  $less_vars['sub_headline_font'] = $font['family'];
307
  if ( ! empty( $font['weight'] ) ) {
308
- $less_vars['sub_headline_font_weight'] = $font['weight'];
 
309
  }
310
  }
311
 
287
  $font = siteorigin_widget_get_font( $instance['headline']['font'] );
288
  $less_vars['headline_font'] = $font['family'];
289
  if ( ! empty( $font['weight'] ) ) {
290
+ $less_vars['headline_font_style'] = $font['style'];
291
+ $less_vars['headline_font_weight'] = $font['weight_raw'];
292
  }
293
  }
294
 
306
  $font = siteorigin_widget_get_font( $instance['sub_headline']['font'] );
307
  $less_vars['sub_headline_font'] = $font['family'];
308
  if ( ! empty( $font['weight'] ) ) {
309
+ $less_vars['sub_headline_font_style'] = $font['style'];
310
+ $less_vars['sub_headline_font_weight'] = $font['weight_raw'];
311
  }
312
  }
313
 
widgets/headline/styles/default.less CHANGED
@@ -4,6 +4,7 @@
4
  @headline_font: default;
5
  @headline_font_weight: 400;
6
  @headline_font_size: default;
 
7
  @headline_line_height: 1.4em;
8
  @headline_margin: default;
9
  @headline_align: center;
@@ -14,6 +15,7 @@
14
  @sub_headline_font: default;
15
  @sub_headline_font_weight: 400;
16
  @sub_headline_font_size: default;
 
17
  @sub_headline_line_height: 1.4em;
18
  @sub_headline_margin: default;
19
  @sub_headline_align: center;
@@ -31,6 +33,7 @@
31
 
32
  @{headline_tag}.sow-headline {
33
  .font(@headline_font, @headline_font_weight);
 
34
  text-align: @headline_align;
35
  color: @headline_color;
36
  line-height: @headline_line_height;
@@ -49,6 +52,7 @@
49
 
50
  @{sub_headline_tag}.sow-sub-headline {
51
  .font(@sub_headline_font, @sub_headline_font_weight);
 
52
  text-align: @sub_headline_align;
53
  color: @sub_headline_color;
54
  line-height: @sub_headline_line_height;
4
  @headline_font: default;
5
  @headline_font_weight: 400;
6
  @headline_font_size: default;
7
+ @headline_font_style: default;
8
  @headline_line_height: 1.4em;
9
  @headline_margin: default;
10
  @headline_align: center;
15
  @sub_headline_font: default;
16
  @sub_headline_font_weight: 400;
17
  @sub_headline_font_size: default;
18
+ @sub_headline_font_style: default;
19
  @sub_headline_line_height: 1.4em;
20
  @sub_headline_margin: default;
21
  @sub_headline_align: center;
33
 
34
  @{headline_tag}.sow-headline {
35
  .font(@headline_font, @headline_font_weight);
36
+ font-style: @headline_font_style;
37
  text-align: @headline_align;
38
  color: @headline_color;
39
  line-height: @headline_line_height;
52
 
53
  @{sub_headline_tag}.sow-sub-headline {
54
  .font(@sub_headline_font, @sub_headline_font_weight);
55
+ font-style: @sub_headline_font_style;
56
  text-align: @sub_headline_align;
57
  color: @sub_headline_color;
58
  line-height: @sub_headline_line_height;
widgets/image-grid/image-grid.php CHANGED
@@ -110,11 +110,25 @@ class SiteOrigin_Widgets_ImageGrid_Widget extends SiteOrigin_Widget {
110
  'type' => 'number',
111
  ),
112
 
113
- 'spacing' => array(
114
- 'label' => __( 'Spacing', 'so-widgets-bundle' ),
115
- 'description' => __( 'Amount of spacing between images.', 'so-widgets-bundle' ),
116
- 'type' => 'measurement',
117
- 'default' => '10px',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  ),
119
  )
120
  )
@@ -123,7 +137,8 @@ class SiteOrigin_Widgets_ImageGrid_Widget extends SiteOrigin_Widget {
123
 
124
  function get_template_variables( $instance, $args ) {
125
  $images = isset( $instance['images'] ) ? $instance['images'] : array();
126
-
 
127
  foreach ( $images as $id => &$image ) {
128
  if ( empty( $image['image'] ) && empty( $image['image_fallback'] ) ) {
129
  unset( $images[$id] );
@@ -141,12 +156,13 @@ class SiteOrigin_Widgets_ImageGrid_Widget extends SiteOrigin_Widget {
141
 
142
  if ( empty( $image['image'] ) && ! empty( $image['image_fallback'] ) ) {
143
  $alt = ! empty ( $image['alt'] ) ? $image['alt'] .'"' : '';
144
- $image['image_html'] = '<img src="'. esc_url( $image['image_fallback'] ) .'" alt="'. esc_attr( $alt ) .'" title="'. esc_attr( $title ) .'" class="sow-image-grid-image_html">';
145
  } else {
146
  $image['image_html'] = wp_get_attachment_image( $image['image'], $instance['display']['attachment_size'], false, array(
147
  'title' => $title,
148
  'alt' => $image['alt'],
149
  'class' => 'sow-image-grid-image_html',
 
150
  ) );
151
  }
152
  }
@@ -196,9 +212,19 @@ class SiteOrigin_Widgets_ImageGrid_Widget extends SiteOrigin_Widget {
196
  $instance['display']['max_width'] = (int) $instance['display']['max_width'];
197
  }
198
 
199
- // Input for `spacing` changed from `number` to `measurement` field.
200
- if ( is_numeric( $instance['display']['spacing'] ) ) {
201
- $instance['display']['spacing'] = $instance['display']['spacing'] .'px';
 
 
 
 
 
 
 
 
 
 
202
  }
203
  }
204
 
@@ -214,8 +240,8 @@ class SiteOrigin_Widgets_ImageGrid_Widget extends SiteOrigin_Widget {
214
  */
215
  function get_less_variables( $instance ) {
216
  $less = array();
217
- if ( ! empty( $instance['display']['spacing'] ) ) {
218
- $less['spacing'] = $instance['display']['spacing'];
219
  }
220
 
221
  return $less;
110
  'type' => 'number',
111
  ),
112
 
113
+ 'padding' => array(
114
+ 'label' => __( 'Image padding', 'so-widgets-bundle' ),
115
+ 'type' => 'multi-measurement',
116
+ 'autofill' => true,
117
+ 'default' => '5px 5px 5px 5px',
118
+ 'measurements' => array(
119
+ 'top' => array(
120
+ 'label' => __( 'Top', 'so-widgets-bundle' ),
121
+ ),
122
+ 'right' => array(
123
+ 'label' => __( 'Right', 'so-widgets-bundle' ),
124
+ ),
125
+ 'bottom' => array(
126
+ 'label' => __( 'Bottom', 'so-widgets-bundle' ),
127
+ ),
128
+ 'left' => array(
129
+ 'label' => __( 'Left', 'so-widgets-bundle' ),
130
+ ),
131
+ ),
132
  ),
133
  )
134
  )
137
 
138
  function get_template_variables( $instance, $args ) {
139
  $images = isset( $instance['images'] ) ? $instance['images'] : array();
140
+ $lazy = function_exists( 'wp_lazy_loading_enabled' ) && wp_lazy_loading_enabled( 'img', 'sow-image-grid' );
141
+
142
  foreach ( $images as $id => &$image ) {
143
  if ( empty( $image['image'] ) && empty( $image['image_fallback'] ) ) {
144
  unset( $images[$id] );
156
 
157
  if ( empty( $image['image'] ) && ! empty( $image['image_fallback'] ) ) {
158
  $alt = ! empty ( $image['alt'] ) ? $image['alt'] .'"' : '';
159
+ $image['image_html'] = '<img src="' . esc_url( $image['image_fallback'] ) . '" alt="' . esc_attr( $alt ) . '" title="' . esc_attr( $title ) . '" class="sow-image-grid-image_html" ' . ( $lazy ? 'loading="lazy"' : '' ) . '>';
160
  } else {
161
  $image['image_html'] = wp_get_attachment_image( $image['image'], $instance['display']['attachment_size'], false, array(
162
  'title' => $title,
163
  'alt' => $image['alt'],
164
  'class' => 'sow-image-grid-image_html',
165
+ 'loading' => $lazy ? 'lazy' : '',
166
  ) );
167
  }
168
  }
212
  $instance['display']['max_width'] = (int) $instance['display']['max_width'];
213
  }
214
 
215
+ // Migrate the Spacing setting to the Padding setting.
216
+ if ( isset( $instance['display']['spacing'] ) ) {
217
+ // The Spacing setting was initially a `number` field.
218
+ if ( is_numeric( $instance['display']['spacing'] ) ) {
219
+ $spacing = $instance['display']['spacing'] . 'px';
220
+ } else if ( isset( $instance['display']['spacing_unit'] ) ) {
221
+ // Prior to the rename, it was a `measurement` field.
222
+ $spacing = $instance['display']['spacing'];
223
+ }
224
+
225
+ if ( isset( $spacing ) ) {
226
+ $instance['display']['padding'] = "0px $spacing $spacing $spacing";
227
+ }
228
  }
229
  }
230
 
240
  */
241
  function get_less_variables( $instance ) {
242
  $less = array();
243
+ if ( ! empty( $instance['display']['padding'] ) ) {
244
+ $less['padding'] = $instance['display']['padding'];
245
  }
246
 
247
  return $less;
widgets/image-grid/styles/default.less CHANGED
@@ -1,16 +1,15 @@
1
- @spacing: default;
2
 
3
  .sow-image-grid-wrapper {
4
  display: flex;
5
  flex-wrap: wrap;
6
  justify-content: center;
7
  align-items: baseline;
8
- padding-top: @spacing;
9
  line-height: 0;
10
- text-align:center;
11
 
12
  .sow-image-grid-image {
13
- padding: 0 @spacing @spacing @spacing;
14
  display: inline-block;
15
 
16
  img {
1
+ @padding: default;
2
 
3
  .sow-image-grid-wrapper {
4
  display: flex;
5
  flex-wrap: wrap;
6
  justify-content: center;
7
  align-items: baseline;
 
8
  line-height: 0;
9
+ text-align: center;
10
 
11
  .sow-image-grid-image {
12
+ padding: @padding;
13
  display: inline-block;
14
 
15
  img {
widgets/image/image.php CHANGED
@@ -126,7 +126,7 @@ class SiteOrigin_Widget_Image_Widget extends SiteOrigin_Widget {
126
  ) {
127
  $instance['size'] = array(
128
  (int) $instance['size_width'],
129
- (int) $instance['size_width'],
130
  );
131
  }
132
 
@@ -169,6 +169,10 @@ class SiteOrigin_Widget_Image_Widget extends SiteOrigin_Widget {
169
  } else {
170
  $attr['alt'] = get_post_meta( $instance['image'], '_wp_attachment_image_alt', true );
171
  }
 
 
 
 
172
 
173
  $link_atts = array();
174
  if ( ! empty( $instance['new_window'] ) ) {
126
  ) {
127
  $instance['size'] = array(
128
  (int) $instance['size_width'],
129
+ (int) $instance['size_height'],
130
  );
131
  }
132
 
169
  } else {
170
  $attr['alt'] = get_post_meta( $instance['image'], '_wp_attachment_image_alt', true );
171
  }
172
+
173
+ if ( function_exists( 'wp_lazy_loading_enabled' ) && wp_lazy_loading_enabled( 'img', 'sow-image' ) ) {
174
+ $attr['loading'] = 'lazy';
175
+ }
176
 
177
  $link_atts = array();
178
  if ( ! empty( $instance['new_window'] ) ) {
widgets/video/tpl/default.php CHANGED
@@ -58,7 +58,7 @@ do_action( 'siteorigin_widgets_sow-video_before_video', $instance );
58
  <?php endforeach; ?>
59
  </video>
60
  <?php else : ?>
61
- <?php echo $so_video->get_video_oembed( $src, $autoplay, $related_videos ); ?>
62
  <?php endif; ?>
63
  </div>
64
  <?php do_action( 'siteorigin_widgets_sow-video_after_video', $instance ); ?>
58
  <?php endforeach; ?>
59
  </video>
60
  <?php else : ?>
61
+ <?php echo $so_video->get_video_oembed( $src, $autoplay, $related_videos, $loop ); ?>
62
  <?php endif; ?>
63
  </div>
64
  <?php do_action( 'siteorigin_widgets_sow-video_after_video', $instance ); ?>
widgets/video/video.php CHANGED
@@ -104,10 +104,6 @@ class SiteOrigin_Widget_Video_Widget extends SiteOrigin_Widget {
104
  'type' => 'checkbox',
105
  'default' => false,
106
  'label' => __( 'Loop', 'so-widgets-bundle' ),
107
- 'state_handler' => array(
108
- 'video_type[self]' => array( 'show' ),
109
- 'video_type[external]' => array( 'hide' ),
110
- )
111
  ),
112
  'fitvids' => array(
113
  'type' => 'checkbox',
@@ -230,7 +226,7 @@ class SiteOrigin_Widget_Video_Widget extends SiteOrigin_Widget {
230
  'is_skinnable_video_host' => $this->is_skinnable_video_host( $video_host ),
231
  'poster' => $poster,
232
  'autoplay' => ! empty( $instance['playback']['autoplay'] ),
233
- 'loop' => $video_host == 'self' && ! empty( $instance['playback']['loop'] ),
234
  'related_videos' => ! empty( $instance['playback']['related_videos'] ),
235
  'skin_class' => 'default',
236
  'fitvids' => ! empty( $instance['playback']['fitvids'] ),
104
  'type' => 'checkbox',
105
  'default' => false,
106
  'label' => __( 'Loop', 'so-widgets-bundle' ),
 
 
 
 
107
  ),
108
  'fitvids' => array(
109
  'type' => 'checkbox',
226
  'is_skinnable_video_host' => $this->is_skinnable_video_host( $video_host ),
227
  'poster' => $poster,
228
  'autoplay' => ! empty( $instance['playback']['autoplay'] ),
229
+ 'loop' => ! empty( $instance['playback']['loop'] ),
230
  'related_videos' => ! empty( $instance['playback']['related_videos'] ),
231
  'skin_class' => 'default',
232
  'fitvids' => ! empty( $instance['playback']['fitvids'] ),