Premium Addons for Elementor - Version 3.7.1

Version Description

  • Tweak: Vertical Scroll performance enhanced on all devices.
  • Fixed: Security bugs fixed.
Download this release

Release Info

Developer leap13
Plugin Icon 128x128 Premium Addons for Elementor
Version 3.7.1
Comparing to
See all releases

Code changes from version 3.7.0 to 3.7.1

admin/assets/js/admin.js CHANGED
@@ -34,7 +34,8 @@
34
  url: settings.ajaxurl,
35
  type: 'post',
36
  data: {
37
- action: 'pa_save_admin_addons_settings',
 
38
  fields: $( 'form#pa-settings' ).serialize(),
39
  },
40
  success: function( response ) {
@@ -61,6 +62,7 @@
61
  type: 'post',
62
  data: {
63
  action: 'pa_maps_save_settings',
 
64
  fields: $('form#pa-maps').serialize(),
65
  },
66
  success: function (response){
@@ -87,6 +89,7 @@
87
  type: 'post',
88
  data: {
89
  action: 'pa_beta_save_settings',
 
90
  fields: $('form#pa-beta-form').serialize(),
91
  },
92
  success: function (response){
34
  url: settings.ajaxurl,
35
  type: 'post',
36
  data: {
37
+ action: 'pa_save_admin_addons_settings',
38
+ security: settings.nonce,
39
  fields: $( 'form#pa-settings' ).serialize(),
40
  },
41
  success: function( response ) {
62
  type: 'post',
63
  data: {
64
  action: 'pa_maps_save_settings',
65
+ security: settings.nonce,
66
  fields: $('form#pa-maps').serialize(),
67
  },
68
  success: function (response){
89
  type: 'post',
90
  data: {
91
  action: 'pa_beta_save_settings',
92
+ security: settings.nonce,
93
  fields: $('form#pa-beta-form').serialize(),
94
  },
95
  success: function (response){
admin/includes/version-control.php CHANGED
@@ -44,7 +44,8 @@ class Version_Control {
44
  public function pa_version_page() {
45
 
46
  $js_info = array(
47
- 'ajaxurl' => admin_url( 'admin-ajax.php' )
 
48
  );
49
 
50
  wp_localize_script( 'pa-admin-js', 'settings', $js_info );
@@ -91,7 +92,7 @@ class Version_Control {
91
  <tr class="pa-roll-row">
92
  <th><?php echo __('Rollback Version', 'premium-addons-for-elementor'); ?></th>
93
  <td>
94
- <div><?php echo sprintf( '<a target="_blank" href="%1$s" class="button pa-btn pa-rollback-button elementor-button-spinner">%2$s</a>', wp_nonce_url( admin_url( 'admin-post.php?action=premium_addons_rollback' ), 'premium_addons_rollback' ), __('Reinstall Version 3.6.9', 'premium-addons-for-elementor') ); ?></div>
95
  <p class="pa-roll-desc">
96
  <span><?php echo __('Warning: Please backup your database before making the rollback.', 'premium-addons-for-elementor'); ?></span>
97
  </p>
@@ -122,19 +123,21 @@ class Version_Control {
122
 
123
  public function pa_beta_save_settings() {
124
 
125
- if( isset( $_POST['fields'] ) ) {
126
- parse_str( $_POST['fields'], $settings );
127
- } else {
128
- return;
129
- }
130
-
131
- $this->pa_beta_settings = array(
132
- 'is-beta-tester' => intval( $settings['is-beta-tester'] ? 1 : 0 ),
133
- );
134
-
135
- update_option( 'pa_beta_save_settings', $this->pa_beta_settings );
136
-
137
- return true;
138
- die();
139
  }
 
 
 
 
 
 
 
 
 
 
140
  }
44
  public function pa_version_page() {
45
 
46
  $js_info = array(
47
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
48
+ 'nonce' => wp_create_nonce('premium-addons-for-elementor'),
49
  );
50
 
51
  wp_localize_script( 'pa-admin-js', 'settings', $js_info );
92
  <tr class="pa-roll-row">
93
  <th><?php echo __('Rollback Version', 'premium-addons-for-elementor'); ?></th>
94
  <td>
95
+ <div><?php echo sprintf( '<a target="_blank" href="%1$s" class="button pa-btn pa-rollback-button elementor-button-spinner">%2$s</a>', wp_nonce_url( admin_url( 'admin-post.php?action=premium_addons_rollback' ), 'premium_addons_rollback' ), __('Reinstall Version 3.7.0', 'premium-addons-for-elementor') ); ?></div>
96
  <p class="pa-roll-desc">
97
  <span><?php echo __('Warning: Please backup your database before making the rollback.', 'premium-addons-for-elementor'); ?></span>
98
  </p>
123
 
124
  public function pa_beta_save_settings() {
125
 
126
+ check_ajax_referer('premium-addons-for-elementor', 'security');
127
+
128
+ if( isset( $_POST['fields'] ) ) {
129
+ parse_str( $_POST['fields'], $settings );
130
+ } else {
131
+ return;
 
 
 
 
 
 
 
 
132
  }
133
+
134
+ $this->pa_beta_settings = array(
135
+ 'is-beta-tester' => intval( $settings['is-beta-tester'] ? 1 : 0 ),
136
+ );
137
+
138
+ update_option( 'pa_beta_save_settings', $this->pa_beta_settings );
139
+
140
+ return true;
141
+ die();
142
+ }
143
  }
admin/settings/maps.php CHANGED
@@ -40,7 +40,8 @@ class Maps {
40
  public function pa_maps_page() {
41
 
42
  $js_info = array(
43
- 'ajaxurl' => admin_url( 'admin-ajax.php' )
 
44
  );
45
 
46
  wp_localize_script( 'pa-admin-js', 'settings', $js_info );
@@ -91,7 +92,7 @@ class Maps {
91
  <h4 class="pa-api-title"><?php echo __('Google Maps API Key:', 'premium-addons-for-elementor'); ?></h4>
92
  </td>
93
  <td>
94
- <input name="premium-map-api" id="premium-map-api" type="text" placeholder="API Key" value="<?php echo $settings['premium-map-api']; ?>">
95
  </td>
96
  </tr>
97
  <tr>
@@ -108,7 +109,7 @@ class Maps {
108
  $selected = 'selected="selected" ';
109
  }
110
  ?>
111
- <option value="<?php echo $key; ?>" <?php echo $selected; ?>><?php echo esc_attr( $value ); ?></option>
112
  <?php } ?>
113
  </select>
114
  </td>
@@ -158,22 +159,24 @@ class Maps {
158
 
159
  public function pa_save_maps_settings() {
160
 
161
- if( isset( $_POST['fields'] ) ) {
162
- parse_str( $_POST['fields'], $settings );
163
- }else {
164
- return;
165
- }
166
-
167
- $this->pa_maps_settings = array(
168
- 'premium-map-api' => $settings['premium-map-api'],
169
- 'premium-map-disable-api' => intval( $settings['premium-map-disable-api'] ? 1 : 0 ),
170
- 'premium-map-cluster' => intval( $settings['premium-map-cluster'] ? 1 : 0 ),
171
- 'premium-map-locale' => $settings['premium-map-locale']
172
- );
173
-
174
- update_option( 'pa_maps_save_settings', $this->pa_maps_settings );
175
-
176
- return true;
177
- die();
178
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  }
40
  public function pa_maps_page() {
41
 
42
  $js_info = array(
43
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
44
+ 'nonce' => wp_create_nonce('premium-addons-for-elementor'),
45
  );
46
 
47
  wp_localize_script( 'pa-admin-js', 'settings', $js_info );
92
  <h4 class="pa-api-title"><?php echo __('Google Maps API Key:', 'premium-addons-for-elementor'); ?></h4>
93
  </td>
94
  <td>
95
+ <input name="premium-map-api" id="premium-map-api" type="text" placeholder="API Key" value="<?php echo esc_attr( $settings['premium-map-api'] ); ?>">
96
  </td>
97
  </tr>
98
  <tr>
109
  $selected = 'selected="selected" ';
110
  }
111
  ?>
112
+ <option value="<?php echo esc_attr( $key ); ?>" <?php echo $selected; ?>><?php echo esc_attr( $value ); ?></option>
113
  <?php } ?>
114
  </select>
115
  </td>
159
 
160
  public function pa_save_maps_settings() {
161
 
162
+ check_ajax_referer('premium-addons-for-elementor', 'security');
163
+
164
+ if( isset( $_POST['fields'] ) ) {
165
+ parse_str( $_POST['fields'], $settings );
166
+ }else {
167
+ return;
 
 
 
 
 
 
 
 
 
 
 
168
  }
169
+
170
+ $this->pa_maps_settings = array(
171
+ 'premium-map-api' => $settings['premium-map-api'],
172
+ 'premium-map-disable-api' => intval( $settings['premium-map-disable-api'] ? 1 : 0 ),
173
+ 'premium-map-cluster' => intval( $settings['premium-map-cluster'] ? 1 : 0 ),
174
+ 'premium-map-locale' => $settings['premium-map-locale']
175
+ );
176
+
177
+ update_option( 'pa_maps_save_settings', $this->pa_maps_settings );
178
+
179
+ return true;
180
+ die();
181
+ }
182
  }
admin/settings/modules-setting.php CHANGED
@@ -141,7 +141,8 @@ class Modules_Settings {
141
  $theme_slug = Helper_Functions::get_installed_theme();
142
 
143
  $js_info = array(
144
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
 
145
  'theme' => $theme_slug
146
  );
147
 
@@ -698,6 +699,8 @@ class Modules_Settings {
698
 
699
  public function pa_save_settings() {
700
 
 
 
701
  if( isset( $_POST['fields'] ) ) {
702
  parse_str( $_POST['fields'], $settings );
703
  } else {
141
  $theme_slug = Helper_Functions::get_installed_theme();
142
 
143
  $js_info = array(
144
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
145
+ 'nonce' => wp_create_nonce('premium-addons-for-elementor'),
146
  'theme' => $theme_slug
147
  );
148
 
699
 
700
  public function pa_save_settings() {
701
 
702
+ check_ajax_referer('premium-addons-for-elementor', 'security');
703
+
704
  if( isset( $_POST['fields'] ) ) {
705
  parse_str( $_POST['fields'], $settings );
706
  } else {
assets/frontend/css/premium-addons.css CHANGED
@@ -3526,6 +3526,9 @@
3526
  text-size-adjust: none;
3527
  */
3528
  }
 
 
 
3529
  /************ Premium Image Scroll ***************/
3530
  /*************************************************/
3531
  .premium-image-scroll-section, .premium-image-scroll-container {
3526
  text-size-adjust: none;
3527
  */
3528
  }
3529
+ .premium-vscroll-temp .slimScrollBar {
3530
+ visibility: hidden;
3531
+ }
3532
  /************ Premium Image Scroll ***************/
3533
  /*************************************************/
3534
  .premium-image-scroll-section, .premium-image-scroll-container {
assets/frontend/js/lib/iscroll.js ADDED
@@ -0,0 +1,2172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! iScroll v5.2.0-snapshot ~ (c) 2008-2017 Matteo Spinelli ~ http://cubiq.org/license */
2
+ (function (window, document, Math) {
3
+ var rAF = window.requestAnimationFrame ||
4
+ window.webkitRequestAnimationFrame ||
5
+ window.mozRequestAnimationFrame ||
6
+ window.oRequestAnimationFrame ||
7
+ window.msRequestAnimationFrame ||
8
+ function (callback) { window.setTimeout(callback, 1000 / 60); };
9
+
10
+ var utils = (function () {
11
+ var me = {};
12
+
13
+ var _elementStyle = document.createElement('div').style;
14
+ var _vendor = (function () {
15
+ var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'],
16
+ transform,
17
+ i = 0,
18
+ l = vendors.length;
19
+
20
+ for ( ; i < l; i++ ) {
21
+ transform = vendors[i] + 'ransform';
22
+ if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1);
23
+ }
24
+
25
+ return false;
26
+ })();
27
+
28
+ function _prefixStyle (style) {
29
+ if ( _vendor === false ) return false;
30
+ if ( _vendor === '' ) return style;
31
+ return _vendor + style.charAt(0).toUpperCase() + style.substr(1);
32
+ }
33
+
34
+ me.getTime = Date.now || function getTime () { return new Date().getTime(); };
35
+
36
+ me.extend = function (target, obj) {
37
+ for ( var i in obj ) {
38
+ target[i] = obj[i];
39
+ }
40
+ };
41
+
42
+ me.addEvent = function (el, type, fn, capture) {
43
+ el.addEventListener(type, fn, !!capture);
44
+ };
45
+
46
+ me.removeEvent = function (el, type, fn, capture) {
47
+ el.removeEventListener(type, fn, !!capture);
48
+ };
49
+
50
+ me.prefixPointerEvent = function (pointerEvent) {
51
+ return window.MSPointerEvent ?
52
+ 'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8):
53
+ pointerEvent;
54
+ };
55
+
56
+ me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) {
57
+ var distance = current - start,
58
+ speed = Math.abs(distance) / time,
59
+ destination,
60
+ duration;
61
+
62
+ deceleration = deceleration === undefined ? 0.0006 : deceleration;
63
+
64
+ destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );
65
+ duration = speed / deceleration;
66
+
67
+ if ( destination < lowerMargin ) {
68
+ destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin;
69
+ distance = Math.abs(destination - current);
70
+ duration = distance / speed;
71
+ } else if ( destination > 0 ) {
72
+ destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
73
+ distance = Math.abs(current) + destination;
74
+ duration = distance / speed;
75
+ }
76
+
77
+ return {
78
+ destination: Math.round(destination),
79
+ duration: duration
80
+ };
81
+ };
82
+
83
+ var _transform = _prefixStyle('transform');
84
+
85
+ me.extend(me, {
86
+ hasTransform: _transform !== false,
87
+ hasPerspective: _prefixStyle('perspective') in _elementStyle,
88
+ hasTouch: 'ontouchstart' in window,
89
+ hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed
90
+ hasTransition: _prefixStyle('transition') in _elementStyle
91
+ });
92
+
93
+ /*
94
+ This should find all Android browsers lower than build 535.19 (both stock browser and webview)
95
+ - galaxy S2 is ok
96
+ - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1`
97
+ - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
98
+ - galaxy S3 is badAndroid (stock brower, webview)
99
+ `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
100
+ - galaxy S4 is badAndroid (stock brower, webview)
101
+ `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
102
+ - galaxy S5 is OK
103
+ `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
104
+ - galaxy S6 is OK
105
+ `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
106
+ */
107
+ me.isBadAndroid = (function() {
108
+ var appVersion = window.navigator.appVersion;
109
+ // Android browser is not a chrome browser.
110
+ if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) {
111
+ var safariVersion = appVersion.match(/Safari\/(\d+.\d)/);
112
+ if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) {
113
+ return parseFloat(safariVersion[1]) < 535.19;
114
+ } else {
115
+ return true;
116
+ }
117
+ } else {
118
+ return false;
119
+ }
120
+ })();
121
+
122
+ me.extend(me.style = {}, {
123
+ transform: _transform,
124
+ transitionTimingFunction: _prefixStyle('transitionTimingFunction'),
125
+ transitionDuration: _prefixStyle('transitionDuration'),
126
+ transitionDelay: _prefixStyle('transitionDelay'),
127
+ transformOrigin: _prefixStyle('transformOrigin'),
128
+ touchAction: _prefixStyle('touchAction')
129
+ });
130
+
131
+ me.hasClass = function (e, c) {
132
+ var re = new RegExp("(^|\\s)" + c + "(\\s|$)");
133
+ return re.test(e.className);
134
+ };
135
+
136
+ me.addClass = function (e, c) {
137
+ if ( me.hasClass(e, c) ) {
138
+ return;
139
+ }
140
+
141
+ var newclass = e.className.split(' ');
142
+ newclass.push(c);
143
+ e.className = newclass.join(' ');
144
+ };
145
+
146
+ me.removeClass = function (e, c) {
147
+ if ( !me.hasClass(e, c) ) {
148
+ return;
149
+ }
150
+
151
+ var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g');
152
+ e.className = e.className.replace(re, ' ');
153
+ };
154
+
155
+ me.offset = function (el) {
156
+ var left = -el.offsetLeft,
157
+ top = -el.offsetTop;
158
+
159
+ // jshint -W084
160
+ while (el = el.offsetParent) {
161
+ left -= el.offsetLeft;
162
+ top -= el.offsetTop;
163
+ }
164
+ // jshint +W084
165
+
166
+ return {
167
+ left: left,
168
+ top: top
169
+ };
170
+ };
171
+
172
+ me.preventDefaultException = function (el, exceptions) {
173
+ for ( var i in exceptions ) {
174
+ if ( exceptions[i].test(el[i]) ) {
175
+ return true;
176
+ }
177
+ }
178
+
179
+ return false;
180
+ };
181
+
182
+ me.extend(me.eventType = {}, {
183
+ touchstart: 1,
184
+ touchmove: 1,
185
+ touchend: 1,
186
+
187
+ mousedown: 2,
188
+ mousemove: 2,
189
+ mouseup: 2,
190
+
191
+ pointerdown: 3,
192
+ pointermove: 3,
193
+ pointerup: 3,
194
+
195
+ MSPointerDown: 3,
196
+ MSPointerMove: 3,
197
+ MSPointerUp: 3
198
+ });
199
+
200
+ me.extend(me.ease = {}, {
201
+ quadratic: {
202
+ style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
203
+ fn: function (k) {
204
+ return k * ( 2 - k );
205
+ }
206
+ },
207
+ circular: {
208
+ style: 'cubic-bezier(0.1, 0.57, 0.1, 1)', // Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1)
209
+ fn: function (k) {
210
+ return Math.sqrt( 1 - ( --k * k ) );
211
+ }
212
+ },
213
+ back: {
214
+ style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
215
+ fn: function (k) {
216
+ var b = 4;
217
+ return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1;
218
+ }
219
+ },
220
+ bounce: {
221
+ style: '',
222
+ fn: function (k) {
223
+ if ( ( k /= 1 ) < ( 1 / 2.75 ) ) {
224
+ return 7.5625 * k * k;
225
+ } else if ( k < ( 2 / 2.75 ) ) {
226
+ return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
227
+ } else if ( k < ( 2.5 / 2.75 ) ) {
228
+ return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
229
+ } else {
230
+ return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
231
+ }
232
+ }
233
+ },
234
+ elastic: {
235
+ style: '',
236
+ fn: function (k) {
237
+ var f = 0.22,
238
+ e = 0.4;
239
+
240
+ if ( k === 0 ) { return 0; }
241
+ if ( k == 1 ) { return 1; }
242
+
243
+ return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 );
244
+ }
245
+ }
246
+ });
247
+
248
+ me.tap = function (e, eventName) {
249
+ var ev = document.createEvent('Event');
250
+ ev.initEvent(eventName, true, true);
251
+ ev.pageX = e.pageX;
252
+ ev.pageY = e.pageY;
253
+ e.target.dispatchEvent(ev);
254
+ };
255
+
256
+ me.click = function (e) {
257
+ var target = e.target,
258
+ ev;
259
+
260
+ if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) {
261
+ // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent
262
+ // initMouseEvent is deprecated.
263
+ ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event');
264
+ ev.initEvent('click', true, true);
265
+ ev.view = e.view || window;
266
+ ev.detail = 1;
267
+ ev.screenX = target.screenX || 0;
268
+ ev.screenY = target.screenY || 0;
269
+ ev.clientX = target.clientX || 0;
270
+ ev.clientY = target.clientY || 0;
271
+ ev.ctrlKey = !!e.ctrlKey;
272
+ ev.altKey = !!e.altKey;
273
+ ev.shiftKey = !!e.shiftKey;
274
+ ev.metaKey = !!e.metaKey;
275
+ ev.button = 0;
276
+ ev.relatedTarget = null;
277
+ ev._constructed = true;
278
+ target.dispatchEvent(ev);
279
+ }
280
+ };
281
+
282
+ me.getTouchAction = function(eventPassthrough, addPinch) {
283
+ var touchAction = 'none';
284
+ if ( eventPassthrough === 'vertical' ) {
285
+ touchAction = 'pan-y';
286
+ } else if (eventPassthrough === 'horizontal' ) {
287
+ touchAction = 'pan-x';
288
+ }
289
+ if (addPinch && touchAction != 'none') {
290
+ // add pinch-zoom support if the browser supports it, but if not (eg. Chrome <55) do nothing
291
+ touchAction += ' pinch-zoom';
292
+ }
293
+ return touchAction;
294
+ };
295
+
296
+ me.getRect = function(el) {
297
+ if (el instanceof SVGElement) {
298
+ var rect = el.getBoundingClientRect();
299
+ return {
300
+ top : rect.top,
301
+ left : rect.left,
302
+ width : rect.width,
303
+ height : rect.height
304
+ };
305
+ } else {
306
+ return {
307
+ top : el.offsetTop,
308
+ left : el.offsetLeft,
309
+ width : el.offsetWidth,
310
+ height : utils.hasTouch ? 650 : el.offsetHeight
311
+ };
312
+ }
313
+ };
314
+
315
+ return me;
316
+ })();
317
+ function IScroll (el, options) {
318
+ this.wrapper = typeof el == 'string' ? document.querySelector(el) : el;
319
+ this.scroller = this.wrapper.children[0];
320
+ this.scrollerStyle = this.scroller.style; // cache style for better performance
321
+
322
+ this.options = {
323
+
324
+ resizeScrollbars: true,
325
+
326
+ mouseWheelSpeed: 20,
327
+
328
+ snapThreshold: 0.334,
329
+
330
+ // INSERT POINT: OPTIONS
331
+ disablePointer : !utils.hasPointer,
332
+ disableTouch : utils.hasPointer || !utils.hasTouch,
333
+ disableMouse : utils.hasPointer || utils.hasTouch,
334
+ startX: 0,
335
+ startY: 0,
336
+ scrollY: true,
337
+ directionLockThreshold: 5,
338
+ momentum: true,
339
+
340
+ bounce: true,
341
+ bounceTime: 600,
342
+ bounceEasing: '',
343
+
344
+ preventDefault: true,
345
+ preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT)$/ },
346
+
347
+ HWCompositing: true,
348
+ useTransition: true,
349
+ useTransform: true,
350
+ bindToWrapper: typeof window.onmousedown === "undefined"
351
+ };
352
+
353
+ for ( var i in options ) {
354
+ this.options[i] = options[i];
355
+ }
356
+
357
+ // Normalize options
358
+ this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : '';
359
+
360
+ this.options.useTransition = utils.hasTransition && this.options.useTransition;
361
+ this.options.useTransform = utils.hasTransform && this.options.useTransform;
362
+
363
+ this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough;
364
+ this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault;
365
+
366
+ // If you want eventPassthrough I have to lock one of the axes
367
+ this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY;
368
+ this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX;
369
+
370
+ // With eventPassthrough we also need lockDirection mechanism
371
+ this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough;
372
+ this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold;
373
+
374
+ this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing;
375
+
376
+ this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling;
377
+
378
+ if ( this.options.tap === true ) {
379
+ this.options.tap = 'tap';
380
+ }
381
+
382
+ // https://github.com/cubiq/iscroll/issues/1029
383
+ if (!this.options.useTransition && !this.options.useTransform) {
384
+ if(!(/relative|absolute/i).test(this.scrollerStyle.position)) {
385
+ this.scrollerStyle.position = "relative";
386
+ }
387
+ }
388
+
389
+ if ( this.options.shrinkScrollbars == 'scale' ) {
390
+ this.options.useTransition = false;
391
+ }
392
+
393
+ this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1;
394
+
395
+ // INSERT POINT: NORMALIZATION
396
+
397
+ // Some defaults
398
+ this.x = 0;
399
+ this.y = 0;
400
+ this.directionX = 0;
401
+ this.directionY = 0;
402
+ this._events = {};
403
+
404
+ // INSERT POINT: DEFAULTS
405
+
406
+ this._init();
407
+ this.refresh();
408
+
409
+ this.scrollTo(this.options.startX, this.options.startY);
410
+ this.enable();
411
+ }
412
+
413
+ IScroll.prototype = {
414
+ version: '5.2.0-snapshot',
415
+
416
+ _init: function () {
417
+ this._initEvents();
418
+
419
+ if ( this.options.scrollbars || this.options.indicators ) {
420
+ this._initIndicators();
421
+ }
422
+
423
+ if ( this.options.mouseWheel ) {
424
+ this._initWheel();
425
+ }
426
+
427
+ if ( this.options.snap ) {
428
+ this._initSnap();
429
+ }
430
+
431
+ if ( this.options.keyBindings ) {
432
+ this._initKeys();
433
+ }
434
+
435
+ // INSERT POINT: _init
436
+
437
+ },
438
+
439
+ destroy: function () {
440
+ this._initEvents(true);
441
+ clearTimeout(this.resizeTimeout);
442
+ this.resizeTimeout = null;
443
+ this._execEvent('destroy');
444
+ },
445
+
446
+ _transitionEnd: function (e) {
447
+ if ( e.target != this.scroller || !this.isInTransition ) {
448
+ return;
449
+ }
450
+
451
+ this._transitionTime();
452
+ if ( !this.resetPosition(this.options.bounceTime) ) {
453
+ this.isInTransition = false;
454
+ this._execEvent('scrollEnd');
455
+ }
456
+ },
457
+
458
+ _start: function (e) {
459
+ // React to left mouse button only
460
+ if ( utils.eventType[e.type] != 1 ) {
461
+ // for button property
462
+ // http://unixpapa.com/js/mouse.html
463
+ var button;
464
+ if (!e.which) {
465
+ /* IE case */
466
+ button = (e.button < 2) ? 0 :
467
+ ((e.button == 4) ? 1 : 2);
468
+ } else {
469
+ /* All others */
470
+ button = e.button;
471
+ }
472
+ if ( button !== 0 ) {
473
+ return;
474
+ }
475
+ }
476
+
477
+ if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) {
478
+ return;
479
+ }
480
+
481
+ if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
482
+ e.preventDefault();
483
+ }
484
+
485
+ var point = e.touches ? e.touches[0] : e,
486
+ pos;
487
+
488
+ this.initiated = utils.eventType[e.type];
489
+ this.moved = false;
490
+ this.distX = 0;
491
+ this.distY = 0;
492
+ this.directionX = 0;
493
+ this.directionY = 0;
494
+ this.directionLocked = 0;
495
+
496
+ this.startTime = utils.getTime();
497
+
498
+ if ( this.options.useTransition && this.isInTransition ) {
499
+ this._transitionTime();
500
+ this.isInTransition = false;
501
+ pos = this.getComputedPosition();
502
+ this._translate(Math.round(pos.x), Math.round(pos.y));
503
+ this._execEvent('scrollEnd');
504
+ } else if ( !this.options.useTransition && this.isAnimating ) {
505
+ this.isAnimating = false;
506
+ this._execEvent('scrollEnd');
507
+ }
508
+
509
+ this.startX = this.x;
510
+ this.startY = this.y;
511
+ this.absStartX = this.x;
512
+ this.absStartY = this.y;
513
+ this.pointX = point.pageX;
514
+ this.pointY = point.pageY;
515
+
516
+ this._execEvent('beforeScrollStart');
517
+ },
518
+
519
+ _move: function (e) {
520
+ if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
521
+ return;
522
+ }
523
+
524
+ if ( this.options.preventDefault ) { // increases performance on Android? TODO: check!
525
+ e.preventDefault();
526
+ }
527
+
528
+ var point = e.touches ? e.touches[0] : e,
529
+ deltaX = point.pageX - this.pointX,
530
+ deltaY = point.pageY - this.pointY,
531
+ timestamp = utils.getTime(),
532
+ newX, newY,
533
+ absDistX, absDistY;
534
+
535
+ this.pointX = point.pageX;
536
+ this.pointY = point.pageY;
537
+
538
+ this.distX += deltaX;
539
+ this.distY += deltaY;
540
+ absDistX = Math.abs(this.distX);
541
+ absDistY = Math.abs(this.distY);
542
+
543
+ // We need to move at least 10 pixels for the scrolling to initiate
544
+ if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) {
545
+ return;
546
+ }
547
+
548
+ // If you are scrolling in one direction lock the other
549
+ if ( !this.directionLocked && !this.options.freeScroll ) {
550
+ if ( absDistX > absDistY + this.options.directionLockThreshold ) {
551
+ this.directionLocked = 'h'; // lock horizontally
552
+ } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) {
553
+ this.directionLocked = 'v'; // lock vertically
554
+ } else {
555
+ this.directionLocked = 'n'; // no lock
556
+ }
557
+ }
558
+
559
+ if ( this.directionLocked == 'h' ) {
560
+ if ( this.options.eventPassthrough == 'vertical' ) {
561
+ e.preventDefault();
562
+ } else if ( this.options.eventPassthrough == 'horizontal' ) {
563
+ this.initiated = false;
564
+ return;
565
+ }
566
+
567
+ deltaY = 0;
568
+ } else if ( this.directionLocked == 'v' ) {
569
+ if ( this.options.eventPassthrough == 'horizontal' ) {
570
+ e.preventDefault();
571
+ } else if ( this.options.eventPassthrough == 'vertical' ) {
572
+ this.initiated = false;
573
+ return;
574
+ }
575
+
576
+ deltaX = 0;
577
+ }
578
+
579
+ deltaX = this.hasHorizontalScroll ? deltaX : 0;
580
+ deltaY = this.hasVerticalScroll ? deltaY : 0;
581
+
582
+ newX = this.x + deltaX;
583
+ newY = this.y + deltaY;
584
+
585
+ // Slow down if outside of the boundaries
586
+ if ( newX > 0 || newX < this.maxScrollX ) {
587
+ newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
588
+ }
589
+ if ( newY > 0 || newY < this.maxScrollY ) {
590
+ newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
591
+ }
592
+
593
+ this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
594
+ this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
595
+
596
+ if ( !this.moved ) {
597
+ this._execEvent('scrollStart');
598
+ }
599
+
600
+ this.moved = true;
601
+
602
+ this._translate(newX, newY);
603
+
604
+ /* REPLACE START: _move */
605
+
606
+ if ( timestamp - this.startTime > 300 ) {
607
+ this.startTime = timestamp;
608
+ this.startX = this.x;
609
+ this.startY = this.y;
610
+ }
611
+
612
+ /* REPLACE END: _move */
613
+
614
+ },
615
+
616
+ _end: function (e) {
617
+ if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
618
+ return;
619
+ }
620
+
621
+ if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
622
+ e.preventDefault();
623
+ }
624
+
625
+ var point = e.changedTouches ? e.changedTouches[0] : e,
626
+ momentumX,
627
+ momentumY,
628
+ duration = utils.getTime() - this.startTime,
629
+ newX = Math.round(this.x),
630
+ newY = Math.round(this.y),
631
+ distanceX = Math.abs(newX - this.startX),
632
+ distanceY = Math.abs(newY - this.startY),
633
+ time = 0,
634
+ easing = '';
635
+
636
+ this.isInTransition = 0;
637
+ this.initiated = 0;
638
+ this.endTime = utils.getTime();
639
+
640
+ // reset if we are outside of the boundaries
641
+ if ( this.resetPosition(this.options.bounceTime) ) {
642
+ return;
643
+ }
644
+
645
+ this.scrollTo(newX, newY); // ensures that the last position is rounded
646
+
647
+ // we scrolled less than 10 pixels
648
+ if ( !this.moved ) {
649
+ if ( this.options.tap ) {
650
+ utils.tap(e, this.options.tap);
651
+ }
652
+
653
+ if ( this.options.click ) {
654
+ utils.click(e);
655
+ }
656
+
657
+ this._execEvent('scrollCancel');
658
+ return;
659
+ }
660
+
661
+ if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) {
662
+ this._execEvent('flick');
663
+ return;
664
+ }
665
+
666
+ // start momentum animation if needed
667
+ if ( this.options.momentum && duration < 300 ) {
668
+ momentumX = this.hasHorizontalScroll ? utils.momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { destination: newX, duration: 0 };
669
+ momentumY = this.hasVerticalScroll ? utils.momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { destination: newY, duration: 0 };
670
+ newX = momentumX.destination;
671
+ newY = momentumY.destination;
672
+ time = Math.max(momentumX.duration, momentumY.duration);
673
+ this.isInTransition = 1;
674
+ }
675
+
676
+
677
+ if ( this.options.snap ) {
678
+ var snap = this._nearestSnap(newX, newY);
679
+ this.currentPage = snap;
680
+ time = this.options.snapSpeed || Math.max(
681
+ Math.max(
682
+ Math.min(Math.abs(newX - snap.x), 1000),
683
+ Math.min(Math.abs(newY - snap.y), 1000)
684
+ ), 300);
685
+ newX = snap.x;
686
+ newY = snap.y;
687
+
688
+ this.directionX = 0;
689
+ this.directionY = 0;
690
+ easing = this.options.bounceEasing;
691
+ }
692
+
693
+ // INSERT POINT: _end
694
+
695
+ if ( newX != this.x || newY != this.y ) {
696
+ // change easing function when scroller goes out of the boundaries
697
+ if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) {
698
+ easing = utils.ease.quadratic;
699
+ }
700
+
701
+ this.scrollTo(newX, newY, time, easing);
702
+ return;
703
+ }
704
+
705
+ this._execEvent('scrollEnd');
706
+ },
707
+
708
+ _resize: function () {
709
+ var that = this;
710
+
711
+ clearTimeout(this.resizeTimeout);
712
+
713
+ this.resizeTimeout = setTimeout(function () {
714
+ that.refresh();
715
+ }, this.options.resizePolling);
716
+ },
717
+
718
+ resetPosition: function (time) {
719
+ var x = this.x,
720
+ y = this.y;
721
+
722
+ time = time || 0;
723
+
724
+ if ( !this.hasHorizontalScroll || this.x > 0 ) {
725
+ x = 0;
726
+ } else if ( this.x < this.maxScrollX ) {
727
+ x = this.maxScrollX;
728
+ }
729
+
730
+ if ( !this.hasVerticalScroll || this.y > 0 ) {
731
+ y = 0;
732
+ } else if ( this.y < this.maxScrollY ) {
733
+ y = this.maxScrollY;
734
+ }
735
+
736
+ if ( x == this.x && y == this.y ) {
737
+ return false;
738
+ }
739
+
740
+ this.scrollTo(x, y, time, this.options.bounceEasing);
741
+
742
+ return true;
743
+ },
744
+
745
+ disable: function () {
746
+ this.enabled = false;
747
+ },
748
+
749
+ enable: function () {
750
+ this.enabled = true;
751
+ },
752
+
753
+ refresh: function () {
754
+
755
+ utils.getRect(this.wrapper); // Force reflow
756
+
757
+ this.wrapperWidth = this.wrapper.clientWidth;
758
+ this.wrapperHeight = this.wrapper.clientHeight;
759
+
760
+ var rect = utils.getRect(this.scroller);
761
+ /* REPLACE START: refresh */
762
+
763
+ this.scrollerWidth = rect.width;
764
+ this.scrollerHeight = rect.height;
765
+
766
+ this.maxScrollX = this.wrapperWidth - this.scrollerWidth;
767
+ this.maxScrollY = this.wrapperHeight - this.scrollerHeight;
768
+
769
+ /* REPLACE END: refresh */
770
+
771
+ this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0;
772
+ this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0;
773
+
774
+ if ( !this.hasHorizontalScroll ) {
775
+ this.maxScrollX = 0;
776
+ this.scrollerWidth = this.wrapperWidth;
777
+ }
778
+
779
+ if ( !this.hasVerticalScroll ) {
780
+ this.maxScrollY = 0;
781
+ this.scrollerHeight = this.wrapperHeight;
782
+ }
783
+
784
+ this.endTime = 0;
785
+ this.directionX = 0;
786
+ this.directionY = 0;
787
+
788
+ if(utils.hasPointer && !this.options.disablePointer) {
789
+ // The wrapper should have `touchAction` property for using pointerEvent.
790
+ this.wrapper.style[utils.style.touchAction] = utils.getTouchAction(this.options.eventPassthrough, true);
791
+
792
+ // case. not support 'pinch-zoom'
793
+ // https://github.com/cubiq/iscroll/issues/1118#issuecomment-270057583
794
+ if (!this.wrapper.style[utils.style.touchAction]) {
795
+ this.wrapper.style[utils.style.touchAction] = utils.getTouchAction(this.options.eventPassthrough, false);
796
+ }
797
+ }
798
+ this.wrapperOffset = utils.offset(this.wrapper);
799
+
800
+ this._execEvent('refresh');
801
+
802
+ this.resetPosition();
803
+
804
+ // INSERT POINT: _refresh
805
+
806
+ },
807
+
808
+ on: function (type, fn) {
809
+ if ( !this._events[type] ) {
810
+ this._events[type] = [];
811
+ }
812
+
813
+ this._events[type].push(fn);
814
+ },
815
+
816
+ off: function (type, fn) {
817
+ if ( !this._events[type] ) {
818
+ return;
819
+ }
820
+
821
+ var index = this._events[type].indexOf(fn);
822
+
823
+ if ( index > -1 ) {
824
+ this._events[type].splice(index, 1);
825
+ }
826
+ },
827
+
828
+ _execEvent: function (type) {
829
+ if ( !this._events[type] ) {
830
+ return;
831
+ }
832
+
833
+ var i = 0,
834
+ l = this._events[type].length;
835
+
836
+ if ( !l ) {
837
+ return;
838
+ }
839
+
840
+ for ( ; i < l; i++ ) {
841
+ this._events[type][i].apply(this, [].slice.call(arguments, 1));
842
+ }
843
+ },
844
+
845
+ scrollBy: function (x, y, time, easing) {
846
+ x = this.x + x;
847
+ y = this.y + y;
848
+ time = time || 0;
849
+
850
+ this.scrollTo(x, y, time, easing);
851
+ },
852
+
853
+ scrollTo: function (x, y, time, easing) {
854
+ easing = easing || utils.ease.circular;
855
+
856
+ this.isInTransition = this.options.useTransition && time > 0;
857
+ var transitionType = this.options.useTransition && easing.style;
858
+ if ( !time || transitionType ) {
859
+ if(transitionType) {
860
+ this._transitionTimingFunction(easing.style);
861
+ this._transitionTime(time);
862
+ }
863
+ this._translate(x, y);
864
+ } else {
865
+ this._animate(x, y, time, easing.fn);
866
+ }
867
+ },
868
+
869
+ scrollToElement: function (el, time, offsetX, offsetY, easing) {
870
+ el = el.nodeType ? el : this.scroller.querySelector(el);
871
+
872
+ if ( !el ) {
873
+ return;
874
+ }
875
+
876
+ var pos = utils.offset(el);
877
+
878
+ pos.left -= this.wrapperOffset.left;
879
+ pos.top -= this.wrapperOffset.top;
880
+
881
+ // if offsetX/Y are true we center the element to the screen
882
+ var elRect = utils.getRect(el);
883
+ var wrapperRect = utils.getRect(this.wrapper);
884
+ if ( offsetX === true ) {
885
+ offsetX = Math.round(elRect.width / 2 - wrapperRect.width / 2);
886
+ }
887
+ if ( offsetY === true ) {
888
+ offsetY = Math.round(elRect.height / 2 - wrapperRect.height / 2);
889
+ }
890
+
891
+ pos.left -= offsetX || 0;
892
+ pos.top -= offsetY || 0;
893
+
894
+ pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left;
895
+ pos.top = pos.top > 0 ? 0 : pos.top < this.maxScrollY ? this.maxScrollY : pos.top;
896
+
897
+ time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time;
898
+
899
+ this.scrollTo(pos.left, pos.top, time, easing);
900
+ },
901
+
902
+ _transitionTime: function (time) {
903
+ if (!this.options.useTransition) {
904
+ return;
905
+ }
906
+ time = time || 0;
907
+ var durationProp = utils.style.transitionDuration;
908
+ if(!durationProp) {
909
+ return;
910
+ }
911
+
912
+ this.scrollerStyle[durationProp] = time + 'ms';
913
+
914
+ if ( !time && utils.isBadAndroid ) {
915
+ this.scrollerStyle[durationProp] = '0.0001ms';
916
+ // remove 0.0001ms
917
+ var self = this;
918
+ rAF(function() {
919
+ if(self.scrollerStyle[durationProp] === '0.0001ms') {
920
+ self.scrollerStyle[durationProp] = '0s';
921
+ }
922
+ });
923
+ }
924
+
925
+
926
+ if ( this.indicators ) {
927
+ for ( var i = this.indicators.length; i--; ) {
928
+ this.indicators[i].transitionTime(time);
929
+ }
930
+ }
931
+
932
+
933
+ // INSERT POINT: _transitionTime
934
+
935
+ },
936
+
937
+ _transitionTimingFunction: function (easing) {
938
+ this.scrollerStyle[utils.style.transitionTimingFunction] = easing;
939
+
940
+
941
+ if ( this.indicators ) {
942
+ for ( var i = this.indicators.length; i--; ) {
943
+ this.indicators[i].transitionTimingFunction(easing);
944
+ }
945
+ }
946
+
947
+
948
+ // INSERT POINT: _transitionTimingFunction
949
+
950
+ },
951
+
952
+ _translate: function (x, y) {
953
+ if ( this.options.useTransform ) {
954
+
955
+ /* REPLACE START: _translate */
956
+
957
+ this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ;
958
+
959
+ /* REPLACE END: _translate */
960
+
961
+ } else {
962
+ x = Math.round(x);
963
+ y = Math.round(y);
964
+ this.scrollerStyle.left = x + 'px';
965
+ this.scrollerStyle.top = y + 'px';
966
+ }
967
+
968
+ this.x = x;
969
+ this.y = y;
970
+
971
+
972
+ if ( this.indicators ) {
973
+ for ( var i = this.indicators.length; i--; ) {
974
+ this.indicators[i].updatePosition();
975
+ }
976
+ }
977
+
978
+
979
+ // INSERT POINT: _translate
980
+
981
+ },
982
+
983
+ _initEvents: function (remove) {
984
+ var eventType = remove ? utils.removeEvent : utils.addEvent,
985
+ target = this.options.bindToWrapper ? this.wrapper : window;
986
+
987
+ eventType(window, 'orientationchange', this);
988
+ eventType(window, 'resize', this);
989
+
990
+ if ( this.options.click ) {
991
+ eventType(this.wrapper, 'click', this, true);
992
+ }
993
+
994
+ if ( !this.options.disableMouse ) {
995
+ eventType(this.wrapper, 'mousedown', this);
996
+ eventType(target, 'mousemove', this);
997
+ eventType(target, 'mousecancel', this);
998
+ eventType(target, 'mouseup', this);
999
+ }
1000
+
1001
+ if ( utils.hasPointer && !this.options.disablePointer ) {
1002
+ eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this);
1003
+ eventType(target, utils.prefixPointerEvent('pointermove'), this);
1004
+ eventType(target, utils.prefixPointerEvent('pointercancel'), this);
1005
+ eventType(target, utils.prefixPointerEvent('pointerup'), this);
1006
+ }
1007
+
1008
+ if ( utils.hasTouch && !this.options.disableTouch ) {
1009
+ eventType(this.wrapper, 'touchstart', this);
1010
+ eventType(target, 'touchmove', this);
1011
+ eventType(target, 'touchcancel', this);
1012
+ eventType(target, 'touchend', this);
1013
+ }
1014
+
1015
+ eventType(this.scroller, 'transitionend', this);
1016
+ eventType(this.scroller, 'webkitTransitionEnd', this);
1017
+ eventType(this.scroller, 'oTransitionEnd', this);
1018
+ eventType(this.scroller, 'MSTransitionEnd', this);
1019
+ },
1020
+
1021
+ getComputedPosition: function () {
1022
+ var matrix = window.getComputedStyle(this.scroller, null),
1023
+ x, y;
1024
+
1025
+ if ( this.options.useTransform ) {
1026
+ matrix = matrix[utils.style.transform].split(')')[0].split(', ');
1027
+ x = +(matrix[12] || matrix[4]);
1028
+ y = +(matrix[13] || matrix[5]);
1029
+ } else {
1030
+ x = +matrix.left.replace(/[^-\d.]/g, '');
1031
+ y = +matrix.top.replace(/[^-\d.]/g, '');
1032
+ }
1033
+
1034
+ return { x: x, y: y };
1035
+ },
1036
+ _initIndicators: function () {
1037
+ var interactive = this.options.interactiveScrollbars,
1038
+ customStyle = typeof this.options.scrollbars != 'string',
1039
+ indicators = [],
1040
+ indicator;
1041
+
1042
+ var that = this;
1043
+
1044
+ this.indicators = [];
1045
+
1046
+ if ( this.options.scrollbars ) {
1047
+ // Vertical scrollbar
1048
+ if ( this.options.scrollY ) {
1049
+ indicator = {
1050
+ el: createDefaultScrollbar('v', interactive, this.options.scrollbars),
1051
+ interactive: interactive,
1052
+ defaultScrollbars: true,
1053
+ customStyle: customStyle,
1054
+ resize: this.options.resizeScrollbars,
1055
+ shrink: this.options.shrinkScrollbars,
1056
+ fade: this.options.fadeScrollbars,
1057
+ listenX: false
1058
+ };
1059
+
1060
+ this.wrapper.appendChild(indicator.el);
1061
+ indicators.push(indicator);
1062
+ }
1063
+
1064
+ // Horizontal scrollbar
1065
+ if ( this.options.scrollX ) {
1066
+ indicator = {
1067
+ el: createDefaultScrollbar('h', interactive, this.options.scrollbars),
1068
+ interactive: interactive,
1069
+ defaultScrollbars: true,
1070
+ customStyle: customStyle,
1071
+ resize: this.options.resizeScrollbars,
1072
+ shrink: this.options.shrinkScrollbars,
1073
+ fade: this.options.fadeScrollbars,
1074
+ listenY: false
1075
+ };
1076
+
1077
+ this.wrapper.appendChild(indicator.el);
1078
+ indicators.push(indicator);
1079
+ }
1080
+ }
1081
+
1082
+ if ( this.options.indicators ) {
1083
+ // TODO: check concat compatibility
1084
+ indicators = indicators.concat(this.options.indicators);
1085
+ }
1086
+
1087
+ for ( var i = indicators.length; i--; ) {
1088
+ this.indicators.push( new Indicator(this, indicators[i]) );
1089
+ }
1090
+
1091
+ // TODO: check if we can use array.map (wide compatibility and performance issues)
1092
+ function _indicatorsMap (fn) {
1093
+ if (that.indicators) {
1094
+ for ( var i = that.indicators.length; i--; ) {
1095
+ fn.call(that.indicators[i]);
1096
+ }
1097
+ }
1098
+ }
1099
+
1100
+ if ( this.options.fadeScrollbars ) {
1101
+ this.on('scrollEnd', function () {
1102
+ _indicatorsMap(function () {
1103
+ this.fade();
1104
+ });
1105
+ });
1106
+
1107
+ this.on('scrollCancel', function () {
1108
+ _indicatorsMap(function () {
1109
+ this.fade();
1110
+ });
1111
+ });
1112
+
1113
+ this.on('scrollStart', function () {
1114
+ _indicatorsMap(function () {
1115
+ this.fade(1);
1116
+ });
1117
+ });
1118
+
1119
+ this.on('beforeScrollStart', function () {
1120
+ _indicatorsMap(function () {
1121
+ this.fade(1, true);
1122
+ });
1123
+ });
1124
+ }
1125
+
1126
+
1127
+ this.on('refresh', function () {
1128
+ _indicatorsMap(function () {
1129
+ this.refresh();
1130
+ });
1131
+ });
1132
+
1133
+ this.on('destroy', function () {
1134
+ _indicatorsMap(function () {
1135
+ this.destroy();
1136
+ });
1137
+
1138
+ delete this.indicators;
1139
+ });
1140
+ },
1141
+
1142
+ _initWheel: function () {
1143
+ utils.addEvent(this.wrapper, 'wheel', this);
1144
+ utils.addEvent(this.wrapper, 'mousewheel', this);
1145
+ utils.addEvent(this.wrapper, 'DOMMouseScroll', this);
1146
+
1147
+ this.on('destroy', function () {
1148
+ clearTimeout(this.wheelTimeout);
1149
+ this.wheelTimeout = null;
1150
+ utils.removeEvent(this.wrapper, 'wheel', this);
1151
+ utils.removeEvent(this.wrapper, 'mousewheel', this);
1152
+ utils.removeEvent(this.wrapper, 'DOMMouseScroll', this);
1153
+ });
1154
+ },
1155
+
1156
+ _wheel: function (e) {
1157
+ if ( !this.enabled ) {
1158
+ return;
1159
+ }
1160
+
1161
+ e.preventDefault();
1162
+
1163
+ var wheelDeltaX, wheelDeltaY,
1164
+ newX, newY,
1165
+ that = this;
1166
+
1167
+ if ( this.wheelTimeout === undefined ) {
1168
+ that._execEvent('scrollStart');
1169
+ }
1170
+
1171
+ // Execute the scrollEnd event after 400ms the wheel stopped scrolling
1172
+ clearTimeout(this.wheelTimeout);
1173
+ this.wheelTimeout = setTimeout(function () {
1174
+ if(!that.options.snap) {
1175
+ that._execEvent('scrollEnd');
1176
+ }
1177
+ that.wheelTimeout = undefined;
1178
+ }, 400);
1179
+
1180
+ if ( 'deltaX' in e ) {
1181
+ if (e.deltaMode === 1) {
1182
+ wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed;
1183
+ wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed;
1184
+ } else {
1185
+ wheelDeltaX = -e.deltaX;
1186
+ wheelDeltaY = -e.deltaY;
1187
+ }
1188
+ } else if ( 'wheelDeltaX' in e ) {
1189
+ wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed;
1190
+ wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed;
1191
+ } else if ( 'wheelDelta' in e ) {
1192
+ wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed;
1193
+ } else if ( 'detail' in e ) {
1194
+ wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed;
1195
+ } else {
1196
+ return;
1197
+ }
1198
+
1199
+ wheelDeltaX *= this.options.invertWheelDirection;
1200
+ wheelDeltaY *= this.options.invertWheelDirection;
1201
+
1202
+ if ( !this.hasVerticalScroll ) {
1203
+ wheelDeltaX = wheelDeltaY;
1204
+ wheelDeltaY = 0;
1205
+ }
1206
+
1207
+ if ( this.options.snap ) {
1208
+ newX = this.currentPage.pageX;
1209
+ newY = this.currentPage.pageY;
1210
+
1211
+ if ( wheelDeltaX > 0 ) {
1212
+ newX--;
1213
+ } else if ( wheelDeltaX < 0 ) {
1214
+ newX++;
1215
+ }
1216
+
1217
+ if ( wheelDeltaY > 0 ) {
1218
+ newY--;
1219
+ } else if ( wheelDeltaY < 0 ) {
1220
+ newY++;
1221
+ }
1222
+
1223
+ this.goToPage(newX, newY);
1224
+
1225
+ return;
1226
+ }
1227
+
1228
+ newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0);
1229
+ newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0);
1230
+
1231
+ this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0;
1232
+ this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0;
1233
+
1234
+ if ( newX > 0 ) {
1235
+ newX = 0;
1236
+ } else if ( newX < this.maxScrollX ) {
1237
+ newX = this.maxScrollX;
1238
+ }
1239
+
1240
+ if ( newY > 0 ) {
1241
+ newY = 0;
1242
+ } else if ( newY < this.maxScrollY ) {
1243
+ newY = this.maxScrollY;
1244
+ }
1245
+
1246
+ this.scrollTo(newX, newY, 0);
1247
+
1248
+ // INSERT POINT: _wheel
1249
+ },
1250
+
1251
+ _initSnap: function () {
1252
+ this.currentPage = {};
1253
+
1254
+ if ( typeof this.options.snap == 'string' ) {
1255
+ this.options.snap = this.scroller.querySelectorAll(this.options.snap);
1256
+ }
1257
+
1258
+ this.on('refresh', function () {
1259
+ var i = 0, l,
1260
+ m = 0, n,
1261
+ cx, cy,
1262
+ x = 0, y,
1263
+ stepX = this.options.snapStepX || this.wrapperWidth,
1264
+ stepY = this.options.snapStepY || this.wrapperHeight,
1265
+ el,
1266
+ rect;
1267
+
1268
+ this.pages = [];
1269
+
1270
+ if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) {
1271
+ return;
1272
+ }
1273
+
1274
+ if ( this.options.snap === true ) {
1275
+ cx = Math.round( stepX / 2 );
1276
+ cy = Math.round( stepY / 2 );
1277
+
1278
+ while ( x > -this.scrollerWidth ) {
1279
+ this.pages[i] = [];
1280
+ l = 0;
1281
+ y = 0;
1282
+
1283
+ while ( y > -this.scrollerHeight ) {
1284
+ this.pages[i][l] = {
1285
+ x: Math.max(x, this.maxScrollX),
1286
+ y: Math.max(y, this.maxScrollY),
1287
+ width: stepX,
1288
+ height: stepY,
1289
+ cx: x - cx,
1290
+ cy: y - cy
1291
+ };
1292
+
1293
+ y -= stepY;
1294
+ l++;
1295
+ }
1296
+
1297
+ x -= stepX;
1298
+ i++;
1299
+ }
1300
+ } else {
1301
+ el = this.options.snap;
1302
+ l = el.length;
1303
+ n = -1;
1304
+
1305
+ for ( ; i < l; i++ ) {
1306
+ rect = utils.getRect(el[i]);
1307
+ if ( i === 0 || rect.left <= utils.getRect(el[i-1]).left ) {
1308
+ m = 0;
1309
+ n++;
1310
+ }
1311
+
1312
+ if ( !this.pages[m] ) {
1313
+ this.pages[m] = [];
1314
+ }
1315
+
1316
+ x = Math.max(-rect.left, this.maxScrollX);
1317
+ y = Math.max(-rect.top, this.maxScrollY);
1318
+ cx = x - Math.round(rect.width / 2);
1319
+ cy = y - Math.round(rect.height / 2);
1320
+
1321
+ this.pages[m][n] = {
1322
+ x: x,
1323
+ y: y,
1324
+ width: rect.width,
1325
+ height: rect.height,
1326
+ cx: cx,
1327
+ cy: cy
1328
+ };
1329
+
1330
+ if ( x > this.maxScrollX ) {
1331
+ m++;
1332
+ }
1333
+ }
1334
+ }
1335
+
1336
+ this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0);
1337
+
1338
+ // Update snap threshold if needed
1339
+ if ( this.options.snapThreshold % 1 === 0 ) {
1340
+ this.snapThresholdX = this.options.snapThreshold;
1341
+ this.snapThresholdY = this.options.snapThreshold;
1342
+ } else {
1343
+ this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold);
1344
+ this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold);
1345
+ }
1346
+ });
1347
+
1348
+ this.on('flick', function () {
1349
+ var time = this.options.snapSpeed || Math.max(
1350
+ Math.max(
1351
+ Math.min(Math.abs(this.x - this.startX), 1000),
1352
+ Math.min(Math.abs(this.y - this.startY), 1000)
1353
+ ), 300);
1354
+
1355
+ this.goToPage(
1356
+ this.currentPage.pageX + this.directionX,
1357
+ this.currentPage.pageY + this.directionY,
1358
+ time
1359
+ );
1360
+ });
1361
+ },
1362
+
1363
+ _nearestSnap: function (x, y) {
1364
+ if ( !this.pages.length ) {
1365
+ return { x: 0, y: 0, pageX: 0, pageY: 0 };
1366
+ }
1367
+
1368
+ var i = 0,
1369
+ l = this.pages.length,
1370
+ m = 0;
1371
+
1372
+ // Check if we exceeded the snap threshold
1373
+ if ( Math.abs(x - this.absStartX) < this.snapThresholdX &&
1374
+ Math.abs(y - this.absStartY) < this.snapThresholdY ) {
1375
+ return this.currentPage;
1376
+ }
1377
+
1378
+ if ( x > 0 ) {
1379
+ x = 0;
1380
+ } else if ( x < this.maxScrollX ) {
1381
+ x = this.maxScrollX;
1382
+ }
1383
+
1384
+ if ( y > 0 ) {
1385
+ y = 0;
1386
+ } else if ( y < this.maxScrollY ) {
1387
+ y = this.maxScrollY;
1388
+ }
1389
+
1390
+ for ( ; i < l; i++ ) {
1391
+ if ( x >= this.pages[i][0].cx ) {
1392
+ x = this.pages[i][0].x;
1393
+ break;
1394
+ }
1395
+ }
1396
+
1397
+ l = this.pages[i].length;
1398
+
1399
+ for ( ; m < l; m++ ) {
1400
+ if ( y >= this.pages[0][m].cy ) {
1401
+ y = this.pages[0][m].y;
1402
+ break;
1403
+ }
1404
+ }
1405
+
1406
+ if ( i == this.currentPage.pageX ) {
1407
+ i += this.directionX;
1408
+
1409
+ if ( i < 0 ) {
1410
+ i = 0;
1411
+ } else if ( i >= this.pages.length ) {
1412
+ i = this.pages.length - 1;
1413
+ }
1414
+
1415
+ x = this.pages[i][0].x;
1416
+ }
1417
+
1418
+ if ( m == this.currentPage.pageY ) {
1419
+ m += this.directionY;
1420
+
1421
+ if ( m < 0 ) {
1422
+ m = 0;
1423
+ } else if ( m >= this.pages[0].length ) {
1424
+ m = this.pages[0].length - 1;
1425
+ }
1426
+
1427
+ y = this.pages[0][m].y;
1428
+ }
1429
+
1430
+ return {
1431
+ x: x,
1432
+ y: y,
1433
+ pageX: i,
1434
+ pageY: m
1435
+ };
1436
+ },
1437
+
1438
+ goToPage: function (x, y, time, easing) {
1439
+ easing = easing || this.options.bounceEasing;
1440
+
1441
+ if ( x >= this.pages.length ) {
1442
+ x = this.pages.length - 1;
1443
+ } else if ( x < 0 ) {
1444
+ x = 0;
1445
+ }
1446
+
1447
+ if ( y >= this.pages[x].length ) {
1448
+ y = this.pages[x].length - 1;
1449
+ } else if ( y < 0 ) {
1450
+ y = 0;
1451
+ }
1452
+
1453
+ var posX = this.pages[x][y].x,
1454
+ posY = this.pages[x][y].y;
1455
+
1456
+ time = time === undefined ? this.options.snapSpeed || Math.max(
1457
+ Math.max(
1458
+ Math.min(Math.abs(posX - this.x), 1000),
1459
+ Math.min(Math.abs(posY - this.y), 1000)
1460
+ ), 300) : time;
1461
+
1462
+ this.currentPage = {
1463
+ x: posX,
1464
+ y: posY,
1465
+ pageX: x,
1466
+ pageY: y
1467
+ };
1468
+
1469
+ this.scrollTo(posX, posY, time, easing);
1470
+ },
1471
+
1472
+ next: function (time, easing) {
1473
+ var x = this.currentPage.pageX,
1474
+ y = this.currentPage.pageY;
1475
+
1476
+ x++;
1477
+
1478
+ if ( x >= this.pages.length && this.hasVerticalScroll ) {
1479
+ x = 0;
1480
+ y++;
1481
+ }
1482
+
1483
+ this.goToPage(x, y, time, easing);
1484
+ },
1485
+
1486
+ prev: function (time, easing) {
1487
+ var x = this.currentPage.pageX,
1488
+ y = this.currentPage.pageY;
1489
+
1490
+ x--;
1491
+
1492
+ if ( x < 0 && this.hasVerticalScroll ) {
1493
+ x = 0;
1494
+ y--;
1495
+ }
1496
+
1497
+ this.goToPage(x, y, time, easing);
1498
+ },
1499
+
1500
+ _initKeys: function (e) {
1501
+ // default key bindings
1502
+ var keys = {
1503
+ pageUp: 33,
1504
+ pageDown: 34,
1505
+ end: 35,
1506
+ home: 36,
1507
+ left: 37,
1508
+ up: 38,
1509
+ right: 39,
1510
+ down: 40
1511
+ };
1512
+ var i;
1513
+
1514
+ // if you give me characters I give you keycode
1515
+ if ( typeof this.options.keyBindings == 'object' ) {
1516
+ for ( i in this.options.keyBindings ) {
1517
+ if ( typeof this.options.keyBindings[i] == 'string' ) {
1518
+ this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCodeAt(0);
1519
+ }
1520
+ }
1521
+ } else {
1522
+ this.options.keyBindings = {};
1523
+ }
1524
+
1525
+ for ( i in keys ) {
1526
+ this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i];
1527
+ }
1528
+
1529
+ utils.addEvent(window, 'keydown', this);
1530
+
1531
+ this.on('destroy', function () {
1532
+ utils.removeEvent(window, 'keydown', this);
1533
+ });
1534
+ },
1535
+
1536
+ _key: function (e) {
1537
+ if ( !this.enabled ) {
1538
+ return;
1539
+ }
1540
+
1541
+ var snap = this.options.snap, // we are using this alot, better to cache it
1542
+ newX = snap ? this.currentPage.pageX : this.x,
1543
+ newY = snap ? this.currentPage.pageY : this.y,
1544
+ now = utils.getTime(),
1545
+ prevTime = this.keyTime || 0,
1546
+ acceleration = 0.250,
1547
+ pos;
1548
+
1549
+ if ( this.options.useTransition && this.isInTransition ) {
1550
+ pos = this.getComputedPosition();
1551
+
1552
+ this._translate(Math.round(pos.x), Math.round(pos.y));
1553
+ this.isInTransition = false;
1554
+ }
1555
+
1556
+ this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0;
1557
+
1558
+ switch ( e.keyCode ) {
1559
+ case this.options.keyBindings.pageUp:
1560
+ if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) {
1561
+ newX += snap ? 1 : this.wrapperWidth;
1562
+ } else {
1563
+ newY += snap ? 1 : this.wrapperHeight;
1564
+ }
1565
+ break;
1566
+ case this.options.keyBindings.pageDown:
1567
+ if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) {
1568
+ newX -= snap ? 1 : this.wrapperWidth;
1569
+ } else {
1570
+ newY -= snap ? 1 : this.wrapperHeight;
1571
+ }
1572
+ break;
1573
+ case this.options.keyBindings.end:
1574
+ newX = snap ? this.pages.length-1 : this.maxScrollX;
1575
+ newY = snap ? this.pages[0].length-1 : this.maxScrollY;
1576
+ break;
1577
+ case this.options.keyBindings.home:
1578
+ newX = 0;
1579
+ newY = 0;
1580
+ break;
1581
+ case this.options.keyBindings.left:
1582
+ newX += snap ? -1 : 5 + this.keyAcceleration>>0;
1583
+ break;
1584
+ case this.options.keyBindings.up:
1585
+ newY += snap ? 1 : 5 + this.keyAcceleration>>0;
1586
+ break;
1587
+ case this.options.keyBindings.right:
1588
+ newX -= snap ? -1 : 5 + this.keyAcceleration>>0;
1589
+ break;
1590
+ case this.options.keyBindings.down:
1591
+ newY -= snap ? 1 : 5 + this.keyAcceleration>>0;
1592
+ break;
1593
+ default:
1594
+ return;
1595
+ }
1596
+
1597
+ if ( snap ) {
1598
+ this.goToPage(newX, newY);
1599
+ return;
1600
+ }
1601
+
1602
+ if ( newX > 0 ) {
1603
+ newX = 0;
1604
+ this.keyAcceleration = 0;
1605
+ } else if ( newX < this.maxScrollX ) {
1606
+ newX = this.maxScrollX;
1607
+ this.keyAcceleration = 0;
1608
+ }
1609
+
1610
+ if ( newY > 0 ) {
1611
+ newY = 0;
1612
+ this.keyAcceleration = 0;
1613
+ } else if ( newY < this.maxScrollY ) {
1614
+ newY = this.maxScrollY;
1615
+ this.keyAcceleration = 0;
1616
+ }
1617
+
1618
+ this.scrollTo(newX, newY, 0);
1619
+
1620
+ this.keyTime = now;
1621
+ },
1622
+
1623
+ _animate: function (destX, destY, duration, easingFn) {
1624
+ var that = this,
1625
+ startX = this.x,
1626
+ startY = this.y,
1627
+ startTime = utils.getTime(),
1628
+ destTime = startTime + duration;
1629
+
1630
+ function step () {
1631
+ var now = utils.getTime(),
1632
+ newX, newY,
1633
+ easing;
1634
+
1635
+ if ( now >= destTime ) {
1636
+ that.isAnimating = false;
1637
+ that._translate(destX, destY);
1638
+
1639
+ if ( !that.resetPosition(that.options.bounceTime) ) {
1640
+ that._execEvent('scrollEnd');
1641
+ }
1642
+
1643
+ return;
1644
+ }
1645
+
1646
+ now = ( now - startTime ) / duration;
1647
+ easing = easingFn(now);
1648
+ newX = ( destX - startX ) * easing + startX;
1649
+ newY = ( destY - startY ) * easing + startY;
1650
+ that._translate(newX, newY);
1651
+
1652
+ if ( that.isAnimating ) {
1653
+ rAF(step);
1654
+ }
1655
+ }
1656
+
1657
+ this.isAnimating = true;
1658
+ step();
1659
+ },
1660
+ handleEvent: function (e) {
1661
+ switch ( e.type ) {
1662
+ case 'touchstart':
1663
+ case 'pointerdown':
1664
+ case 'MSPointerDown':
1665
+ case 'mousedown':
1666
+ this._start(e);
1667
+ break;
1668
+ case 'touchmove':
1669
+ case 'pointermove':
1670
+ case 'MSPointerMove':
1671
+ case 'mousemove':
1672
+ this._move(e);
1673
+ break;
1674
+ case 'touchend':
1675
+ case 'pointerup':
1676
+ case 'MSPointerUp':
1677
+ case 'mouseup':
1678
+ case 'touchcancel':
1679
+ case 'pointercancel':
1680
+ case 'MSPointerCancel':
1681
+ case 'mousecancel':
1682
+ this._end(e);
1683
+ break;
1684
+ case 'orientationchange':
1685
+ case 'resize':
1686
+ this._resize();
1687
+ break;
1688
+ case 'transitionend':
1689
+ case 'webkitTransitionEnd':
1690
+ case 'oTransitionEnd':
1691
+ case 'MSTransitionEnd':
1692
+ this._transitionEnd(e);
1693
+ break;
1694
+ case 'wheel':
1695
+ case 'DOMMouseScroll':
1696
+ case 'mousewheel':
1697
+ this._wheel(e);
1698
+ break;
1699
+ case 'keydown':
1700
+ this._key(e);
1701
+ break;
1702
+ case 'click':
1703
+ if ( this.enabled && !e._constructed ) {
1704
+ e.preventDefault();
1705
+ e.stopPropagation();
1706
+ }
1707
+ break;
1708
+ }
1709
+ }
1710
+ };
1711
+ function createDefaultScrollbar (direction, interactive, type) {
1712
+ var scrollbar = document.createElement('div'),
1713
+ indicator = document.createElement('div');
1714
+
1715
+ if ( type === true ) {
1716
+ scrollbar.style.cssText = 'position:absolute;z-index:9999';
1717
+ indicator.style.cssText = '-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px';
1718
+ }
1719
+
1720
+ indicator.className = 'iScrollIndicator';
1721
+
1722
+ if ( direction == 'h' ) {
1723
+ if ( type === true ) {
1724
+ scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0';
1725
+ indicator.style.height = '100%';
1726
+ }
1727
+ scrollbar.className = 'iScrollHorizontalScrollbar';
1728
+ } else {
1729
+ if ( type === true ) {
1730
+ scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px';
1731
+ indicator.style.width = '100%';
1732
+ }
1733
+ scrollbar.className = 'iScrollVerticalScrollbar';
1734
+ }
1735
+
1736
+ scrollbar.style.cssText += ';overflow:hidden';
1737
+
1738
+ if ( !interactive ) {
1739
+ scrollbar.style.pointerEvents = 'none';
1740
+ }
1741
+
1742
+ scrollbar.appendChild(indicator);
1743
+
1744
+ return scrollbar;
1745
+ }
1746
+
1747
+ function Indicator (scroller, options) {
1748
+ this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el;
1749
+ this.wrapperStyle = this.wrapper.style;
1750
+ this.indicator = this.wrapper.children[0];
1751
+ this.indicatorStyle = this.indicator.style;
1752
+ this.scroller = scroller;
1753
+
1754
+ this.options = {
1755
+ listenX: true,
1756
+ listenY: true,
1757
+ interactive: false,
1758
+ resize: true,
1759
+ defaultScrollbars: false,
1760
+ shrink: false,
1761
+ fade: false,
1762
+
1763
+ speedRatioX: 0,
1764
+ speedRatioY: 0
1765
+ };
1766
+
1767
+ for ( var i in options ) {
1768
+ this.options[i] = options[i];
1769
+ }
1770
+
1771
+ this.sizeRatioX = 1;
1772
+ this.sizeRatioY = 1;
1773
+ this.maxPosX = 0;
1774
+ this.maxPosY = 0;
1775
+
1776
+ if ( this.options.interactive ) {
1777
+ if ( !this.options.disableTouch ) {
1778
+ utils.addEvent(this.indicator, 'touchstart', this);
1779
+ utils.addEvent(window, 'touchend', this);
1780
+ }
1781
+ if ( !this.options.disablePointer ) {
1782
+ utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
1783
+ utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this);
1784
+ }
1785
+ if ( !this.options.disableMouse ) {
1786
+ utils.addEvent(this.indicator, 'mousedown', this);
1787
+ utils.addEvent(window, 'mouseup', this);
1788
+ }
1789
+ }
1790
+
1791
+ if ( this.options.fade ) {
1792
+ this.wrapperStyle[utils.style.transform] = this.scroller.translateZ;
1793
+ var durationProp = utils.style.transitionDuration;
1794
+ if(!durationProp) {
1795
+ return;
1796
+ }
1797
+ this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms';
1798
+ // remove 0.0001ms
1799
+ var self = this;
1800
+ if(utils.isBadAndroid) {
1801
+ rAF(function() {
1802
+ if(self.wrapperStyle[durationProp] === '0.0001ms') {
1803
+ self.wrapperStyle[durationProp] = '0s';
1804
+ }
1805
+ });
1806
+ }
1807
+ this.wrapperStyle.opacity = '0';
1808
+ }
1809
+ }
1810
+
1811
+ Indicator.prototype = {
1812
+ handleEvent: function (e) {
1813
+ switch ( e.type ) {
1814
+ case 'touchstart':
1815
+ case 'pointerdown':
1816
+ case 'MSPointerDown':
1817
+ case 'mousedown':
1818
+ this._start(e);
1819
+ break;
1820
+ case 'touchmove':
1821
+ case 'pointermove':
1822
+ case 'MSPointerMove':
1823
+ case 'mousemove':
1824
+ this._move(e);
1825
+ break;
1826
+ case 'touchend':
1827
+ case 'pointerup':
1828
+ case 'MSPointerUp':
1829
+ case 'mouseup':
1830
+ case 'touchcancel':
1831
+ case 'pointercancel':
1832
+ case 'MSPointerCancel':
1833
+ case 'mousecancel':
1834
+ this._end(e);
1835
+ break;
1836
+ }
1837
+ },
1838
+
1839
+ destroy: function () {
1840
+ if ( this.options.fadeScrollbars ) {
1841
+ clearTimeout(this.fadeTimeout);
1842
+ this.fadeTimeout = null;
1843
+ }
1844
+ if ( this.options.interactive ) {
1845
+ utils.removeEvent(this.indicator, 'touchstart', this);
1846
+ utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
1847
+ utils.removeEvent(this.indicator, 'mousedown', this);
1848
+
1849
+ utils.removeEvent(window, 'touchmove', this);
1850
+ utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
1851
+ utils.removeEvent(window, 'mousemove', this);
1852
+
1853
+ utils.removeEvent(window, 'touchend', this);
1854
+ utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this);
1855
+ utils.removeEvent(window, 'mouseup', this);
1856
+ }
1857
+
1858
+ if ( this.options.defaultScrollbars && this.wrapper.parentNode ) {
1859
+ this.wrapper.parentNode.removeChild(this.wrapper);
1860
+ }
1861
+ },
1862
+
1863
+ _start: function (e) {
1864
+ var point = e.touches ? e.touches[0] : e;
1865
+
1866
+ e.preventDefault();
1867
+ e.stopPropagation();
1868
+
1869
+ this.transitionTime();
1870
+
1871
+ this.initiated = true;
1872
+ this.moved = false;
1873
+ this.lastPointX = point.pageX;
1874
+ this.lastPointY = point.pageY;
1875
+
1876
+ this.startTime = utils.getTime();
1877
+
1878
+ if ( !this.options.disableTouch ) {
1879
+ utils.addEvent(window, 'touchmove', this);
1880
+ }
1881
+ if ( !this.options.disablePointer ) {
1882
+ utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this);
1883
+ }
1884
+ if ( !this.options.disableMouse ) {
1885
+ utils.addEvent(window, 'mousemove', this);
1886
+ }
1887
+
1888
+ this.scroller._execEvent('beforeScrollStart');
1889
+ },
1890
+
1891
+ _move: function (e) {
1892
+ var point = e.touches ? e.touches[0] : e,
1893
+ deltaX, deltaY,
1894
+ newX, newY,
1895
+ timestamp = utils.getTime();
1896
+
1897
+ if ( !this.moved ) {
1898
+ this.scroller._execEvent('scrollStart');
1899
+ }
1900
+
1901
+ this.moved = true;
1902
+
1903
+ deltaX = point.pageX - this.lastPointX;
1904
+ this.lastPointX = point.pageX;
1905
+
1906
+ deltaY = point.pageY - this.lastPointY;
1907
+ this.lastPointY = point.pageY;
1908
+
1909
+ newX = this.x + deltaX;
1910
+ newY = this.y + deltaY;
1911
+
1912
+ this._pos(newX, newY);
1913
+
1914
+ // INSERT POINT: indicator._move
1915
+
1916
+ e.preventDefault();
1917
+ e.stopPropagation();
1918
+ },
1919
+
1920
+ _end: function (e) {
1921
+ if ( !this.initiated ) {
1922
+ return;
1923
+ }
1924
+
1925
+ this.initiated = false;
1926
+
1927
+ e.preventDefault();
1928
+ e.stopPropagation();
1929
+
1930
+ utils.removeEvent(window, 'touchmove', this);
1931
+ utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
1932
+ utils.removeEvent(window, 'mousemove', this);
1933
+
1934
+ if ( this.scroller.options.snap ) {
1935
+ var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y);
1936
+
1937
+ var time = this.options.snapSpeed || Math.max(
1938
+ Math.max(
1939
+ Math.min(Math.abs(this.scroller.x - snap.x), 1000),
1940
+ Math.min(Math.abs(this.scroller.y - snap.y), 1000)
1941
+ ), 300);
1942
+
1943
+ if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) {
1944
+ this.scroller.directionX = 0;
1945
+ this.scroller.directionY = 0;
1946
+ this.scroller.currentPage = snap;
1947
+ this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing);
1948
+ }
1949
+ }
1950
+
1951
+ if ( this.moved ) {
1952
+ this.scroller._execEvent('scrollEnd');
1953
+ }
1954
+ },
1955
+
1956
+ transitionTime: function (time) {
1957
+ time = time || 0;
1958
+ var durationProp = utils.style.transitionDuration;
1959
+ if(!durationProp) {
1960
+ return;
1961
+ }
1962
+
1963
+ this.indicatorStyle[durationProp] = time + 'ms';
1964
+
1965
+ if ( !time && utils.isBadAndroid ) {
1966
+ this.indicatorStyle[durationProp] = '0.0001ms';
1967
+ // remove 0.0001ms
1968
+ var self = this;
1969
+ rAF(function() {
1970
+ if(self.indicatorStyle[durationProp] === '0.0001ms') {
1971
+ self.indicatorStyle[durationProp] = '0s';
1972
+ }
1973
+ });
1974
+ }
1975
+ },
1976
+
1977
+ transitionTimingFunction: function (easing) {
1978
+ this.indicatorStyle[utils.style.transitionTimingFunction] = easing;
1979
+ },
1980
+
1981
+ refresh: function () {
1982
+ this.transitionTime();
1983
+
1984
+ if ( this.options.listenX && !this.options.listenY ) {
1985
+ this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none';
1986
+ } else if ( this.options.listenY && !this.options.listenX ) {
1987
+ this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none';
1988
+ } else {
1989
+ this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none';
1990
+ }
1991
+
1992
+ if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) {
1993
+ utils.addClass(this.wrapper, 'iScrollBothScrollbars');
1994
+ utils.removeClass(this.wrapper, 'iScrollLoneScrollbar');
1995
+
1996
+ if ( this.options.defaultScrollbars && this.options.customStyle ) {
1997
+ if ( this.options.listenX ) {
1998
+ this.wrapper.style.right = '8px';
1999
+ } else {
2000
+ this.wrapper.style.bottom = '8px';
2001
+ }
2002
+ }
2003
+ } else {
2004
+ utils.removeClass(this.wrapper, 'iScrollBothScrollbars');
2005
+ utils.addClass(this.wrapper, 'iScrollLoneScrollbar');
2006
+
2007
+ if ( this.options.defaultScrollbars && this.options.customStyle ) {
2008
+ if ( this.options.listenX ) {
2009
+ this.wrapper.style.right = '2px';
2010
+ } else {
2011
+ this.wrapper.style.bottom = '2px';
2012
+ }
2013
+ }
2014
+ }
2015
+
2016
+ utils.getRect(this.wrapper); // force refresh
2017
+
2018
+ if ( this.options.listenX ) {
2019
+ this.wrapperWidth = this.wrapper.clientWidth;
2020
+ if ( this.options.resize ) {
2021
+ this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8);
2022
+ this.indicatorStyle.width = this.indicatorWidth + 'px';
2023
+ } else {
2024
+ this.indicatorWidth = this.indicator.clientWidth;
2025
+ }
2026
+
2027
+ this.maxPosX = this.wrapperWidth - this.indicatorWidth;
2028
+
2029
+ if ( this.options.shrink == 'clip' ) {
2030
+ this.minBoundaryX = -this.indicatorWidth + 8;
2031
+ this.maxBoundaryX = this.wrapperWidth - 8;
2032
+ } else {
2033
+ this.minBoundaryX = 0;
2034
+ this.maxBoundaryX = this.maxPosX;
2035
+ }
2036
+
2037
+ this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX));
2038
+ }
2039
+
2040
+ if ( this.options.listenY ) {
2041
+ this.wrapperHeight = this.wrapper.clientHeight;
2042
+ if ( this.options.resize ) {
2043
+ this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8);
2044
+ this.indicatorStyle.height = this.indicatorHeight + 'px';
2045
+ } else {
2046
+ this.indicatorHeight = this.indicator.clientHeight;
2047
+ }
2048
+
2049
+ this.maxPosY = this.wrapperHeight - this.indicatorHeight;
2050
+
2051
+ if ( this.options.shrink == 'clip' ) {
2052
+ this.minBoundaryY = -this.indicatorHeight + 8;
2053
+ this.maxBoundaryY = this.wrapperHeight - 8;
2054
+ } else {
2055
+ this.minBoundaryY = 0;
2056
+ this.maxBoundaryY = this.maxPosY;
2057
+ }
2058
+
2059
+ this.maxPosY = this.wrapperHeight - this.indicatorHeight;
2060
+ this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY));
2061
+ }
2062
+
2063
+ this.updatePosition();
2064
+ },
2065
+
2066
+ updatePosition: function () {
2067
+ var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0,
2068
+ y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0;
2069
+
2070
+ if ( !this.options.ignoreBoundaries ) {
2071
+ if ( x < this.minBoundaryX ) {
2072
+ if ( this.options.shrink == 'scale' ) {
2073
+ this.width = Math.max(this.indicatorWidth + x, 8);
2074
+ this.indicatorStyle.width = this.width + 'px';
2075
+ }
2076
+ x = this.minBoundaryX;
2077
+ } else if ( x > this.maxBoundaryX ) {
2078
+ if ( this.options.shrink == 'scale' ) {
2079
+ this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8);
2080
+ this.indicatorStyle.width = this.width + 'px';
2081
+ x = this.maxPosX + this.indicatorWidth - this.width;
2082
+ } else {
2083
+ x = this.maxBoundaryX;
2084
+ }
2085
+ } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) {
2086
+ this.width = this.indicatorWidth;
2087
+ this.indicatorStyle.width = this.width + 'px';
2088
+ }
2089
+
2090
+ if ( y < this.minBoundaryY ) {
2091
+ if ( this.options.shrink == 'scale' ) {
2092
+ this.height = Math.max(this.indicatorHeight + y * 3, 8);
2093
+ this.indicatorStyle.height = this.height + 'px';
2094
+ }
2095
+ y = this.minBoundaryY;
2096
+ } else if ( y > this.maxBoundaryY ) {
2097
+ if ( this.options.shrink == 'scale' ) {
2098
+ this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8);
2099
+ this.indicatorStyle.height = this.height + 'px';
2100
+ y = this.maxPosY + this.indicatorHeight - this.height;
2101
+ } else {
2102
+ y = this.maxBoundaryY;
2103
+ }
2104
+ } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) {
2105
+ this.height = this.indicatorHeight;
2106
+ this.indicatorStyle.height = this.height + 'px';
2107
+ }
2108
+ }
2109
+
2110
+ this.x = x;
2111
+ this.y = y;
2112
+
2113
+ if ( this.scroller.options.useTransform ) {
2114
+ this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ;
2115
+ } else {
2116
+ this.indicatorStyle.left = x + 'px';
2117
+ this.indicatorStyle.top = y + 'px';
2118
+ }
2119
+ },
2120
+
2121
+ _pos: function (x, y) {
2122
+ if ( x < 0 ) {
2123
+ x = 0;
2124
+ } else if ( x > this.maxPosX ) {
2125
+ x = this.maxPosX;
2126
+ }
2127
+
2128
+ if ( y < 0 ) {
2129
+ y = 0;
2130
+ } else if ( y > this.maxPosY ) {
2131
+ y = this.maxPosY;
2132
+ }
2133
+
2134
+ x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x;
2135
+ y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y;
2136
+
2137
+ this.scroller.scrollTo(x, y);
2138
+ },
2139
+
2140
+ fade: function (val, hold) {
2141
+ if ( hold && !this.visible ) {
2142
+ return;
2143
+ }
2144
+
2145
+ clearTimeout(this.fadeTimeout);
2146
+ this.fadeTimeout = null;
2147
+
2148
+ var time = val ? 250 : 500,
2149
+ delay = val ? 0 : 300;
2150
+
2151
+ val = val ? '1' : '0';
2152
+
2153
+ this.wrapperStyle[utils.style.transitionDuration] = time + 'ms';
2154
+
2155
+ this.fadeTimeout = setTimeout((function (val) {
2156
+ this.wrapperStyle.opacity = val;
2157
+ this.visible = +val;
2158
+ }).bind(this, val), delay);
2159
+ }
2160
+ };
2161
+
2162
+ IScroll.utils = utils;
2163
+
2164
+ if ( typeof module != 'undefined' && module.exports ) {
2165
+ module.exports = IScroll;
2166
+ } else if ( typeof define == 'function' && define.amd ) {
2167
+ define( function () { return IScroll; } );
2168
+ } else {
2169
+ window.IScroll = IScroll;
2170
+ }
2171
+
2172
+ })(window, document, Math);
assets/frontend/js/lib/jquery.slimscroll.js ADDED
@@ -0,0 +1,474 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! Copyright (c) 2011 Piotr Rochala (http://rocha.la)
2
+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
3
+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
4
+ *
5
+ * Version: 1.3.8
6
+ *
7
+ */
8
+ (function($) {
9
+
10
+ $.fn.extend({
11
+ slimScroll: function(options) {
12
+
13
+ var defaults = {
14
+
15
+ // width in pixels of the visible scroll area
16
+ width : 'auto',
17
+
18
+ // height in pixels of the visible scroll area
19
+ height : '250px',
20
+
21
+ // width in pixels of the scrollbar and rail
22
+ size : '7px',
23
+
24
+ // scrollbar color, accepts any hex/color value
25
+ color: '#000',
26
+
27
+ // scrollbar position - left/right
28
+ position : 'right',
29
+
30
+ // distance in pixels between the side edge and the scrollbar
31
+ distance : '1px',
32
+
33
+ // default scroll position on load - top / bottom / $('selector')
34
+ start : 'top',
35
+
36
+ // sets scrollbar opacity
37
+ opacity : .4,
38
+
39
+ // enables always-on mode for the scrollbar
40
+ alwaysVisible : false,
41
+
42
+ // check if we should hide the scrollbar when user is hovering over
43
+ disableFadeOut : false,
44
+
45
+ // sets visibility of the rail
46
+ railVisible : false,
47
+
48
+ // sets rail color
49
+ railColor : '#333',
50
+
51
+ // sets rail opacity
52
+ railOpacity : .2,
53
+
54
+ // whether we should use jQuery UI Draggable to enable bar dragging
55
+ railDraggable : true,
56
+
57
+ // defautlt CSS class of the slimscroll rail
58
+ railClass : 'slimScrollRail',
59
+
60
+ // defautlt CSS class of the slimscroll bar
61
+ barClass : 'slimScrollBar',
62
+
63
+ // defautlt CSS class of the slimscroll wrapper
64
+ wrapperClass : 'slimScrollDiv',
65
+
66
+ // check if mousewheel should scroll the window if we reach top/bottom
67
+ allowPageScroll : false,
68
+
69
+ // scroll amount applied to each mouse wheel step
70
+ wheelStep : 20,
71
+
72
+ // scroll amount applied when user is using gestures
73
+ touchScrollStep : 200,
74
+
75
+ // sets border radius
76
+ borderRadius: '7px',
77
+
78
+ // sets border radius of the rail
79
+ railBorderRadius : '7px'
80
+ };
81
+
82
+ var o = $.extend(defaults, options);
83
+
84
+ // do it for every element that matches selector
85
+ this.each(function(){
86
+
87
+ var isOverPanel, isOverBar, isDragg, queueHide, touchDif,
88
+ barHeight, percentScroll, lastScroll,
89
+ divS = '<div></div>',
90
+ minBarHeight = 30,
91
+ releaseScroll = false;
92
+
93
+ // used in event handlers and for better minification
94
+ var me = $(this);
95
+
96
+ // ensure we are not binding it again
97
+ if (me.parent().hasClass(o.wrapperClass))
98
+ {
99
+ // start from last bar position
100
+ var offset = me.scrollTop();
101
+
102
+ // find bar and rail
103
+ bar = me.siblings('.' + o.barClass);
104
+ rail = me.siblings('.' + o.railClass);
105
+
106
+ getBarHeight();
107
+
108
+ // check if we should scroll existing instance
109
+ if ($.isPlainObject(options))
110
+ {
111
+ // Pass height: auto to an existing slimscroll object to force a resize after contents have changed
112
+ if ( 'height' in options && options.height == 'auto' ) {
113
+ me.parent().css('height', 'auto');
114
+ me.css('height', 'auto');
115
+ var height = me.parent().parent().height();
116
+ me.parent().css('height', height);
117
+ me.css('height', height);
118
+ } else if ('height' in options) {
119
+ var h = options.height;
120
+ me.parent().css('height', h);
121
+ me.css('height', h);
122
+ }
123
+
124
+ if ('scrollTo' in options)
125
+ {
126
+ // jump to a static point
127
+ offset = parseInt(o.scrollTo);
128
+ }
129
+ else if ('scrollBy' in options)
130
+ {
131
+ // jump by value pixels
132
+ offset += parseInt(o.scrollBy);
133
+ }
134
+ else if ('destroy' in options)
135
+ {
136
+ // remove slimscroll elements
137
+ bar.remove();
138
+ rail.remove();
139
+ me.unwrap();
140
+ return;
141
+ }
142
+
143
+ // scroll content by the given offset
144
+ scrollContent(offset, false, true);
145
+ }
146
+
147
+ return;
148
+ }
149
+ else if ($.isPlainObject(options))
150
+ {
151
+ if ('destroy' in options)
152
+ {
153
+ return;
154
+ }
155
+ }
156
+
157
+ // optionally set height to the parent's height
158
+ o.height = (o.height == 'auto') ? me.parent().height() : o.height;
159
+
160
+ // wrap content
161
+ var wrapper = $(divS)
162
+ .addClass(o.wrapperClass)
163
+ .css({
164
+ position: 'relative',
165
+ overflow: 'hidden',
166
+ width: o.width,
167
+ height: o.height
168
+ });
169
+
170
+ // update style for the div
171
+ me.css({
172
+ overflow: 'hidden',
173
+ width: o.width,
174
+ height: o.height
175
+ });
176
+
177
+ // create scrollbar rail
178
+ var rail = $(divS)
179
+ .addClass(o.railClass)
180
+ .css({
181
+ width: o.size,
182
+ height: '100%',
183
+ position: 'absolute',
184
+ top: 0,
185
+ display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none',
186
+ 'border-radius': o.railBorderRadius,
187
+ background: o.railColor,
188
+ opacity: o.railOpacity,
189
+ zIndex: 90
190
+ });
191
+
192
+ // create scrollbar
193
+ var bar = $(divS)
194
+ .addClass(o.barClass)
195
+ .css({
196
+ background: o.color,
197
+ width: o.size,
198
+ position: 'absolute',
199
+ top: 0,
200
+ opacity: o.opacity,
201
+ display: o.alwaysVisible ? 'block' : 'none',
202
+ 'border-radius' : o.borderRadius,
203
+ BorderRadius: o.borderRadius,
204
+ MozBorderRadius: o.borderRadius,
205
+ WebkitBorderRadius: o.borderRadius,
206
+ zIndex: 99
207
+ });
208
+
209
+ // set position
210
+ var posCss = (o.position == 'right') ? { right: o.distance } : { left: o.distance };
211
+ rail.css(posCss);
212
+ bar.css(posCss);
213
+
214
+ // wrap it
215
+ me.wrap(wrapper);
216
+
217
+ // append to parent div
218
+ me.parent().append(bar);
219
+ me.parent().append(rail);
220
+
221
+ // make it draggable and no longer dependent on the jqueryUI
222
+ if (o.railDraggable){
223
+ bar.bind("mousedown", function(e) {
224
+ var $doc = $(document);
225
+ isDragg = true;
226
+ t = parseFloat(bar.css('top'));
227
+ pageY = e.pageY;
228
+
229
+ $doc.bind("mousemove.slimscroll", function(e){
230
+ currTop = t + e.pageY - pageY;
231
+ bar.css('top', currTop);
232
+ scrollContent(0, bar.position().top, false);// scroll content
233
+ });
234
+
235
+ $doc.bind("mouseup.slimscroll", function(e) {
236
+ isDragg = false;hideBar();
237
+ $doc.unbind('.slimscroll');
238
+ });
239
+ return false;
240
+ }).bind("selectstart.slimscroll", function(e){
241
+ e.stopPropagation();
242
+ e.preventDefault();
243
+ return false;
244
+ });
245
+ }
246
+
247
+ // on rail over
248
+ rail.hover(function(){
249
+ showBar();
250
+ }, function(){
251
+ hideBar();
252
+ });
253
+
254
+ // on bar over
255
+ bar.hover(function(){
256
+ isOverBar = true;
257
+ }, function(){
258
+ isOverBar = false;
259
+ });
260
+
261
+ // show on parent mouseover
262
+ me.hover(function(){
263
+ isOverPanel = true;
264
+ showBar();
265
+ hideBar();
266
+ }, function(){
267
+ isOverPanel = false;
268
+ hideBar();
269
+ });
270
+
271
+ // support for mobile
272
+ me.bind('touchstart', function(e,b){
273
+ if (e.originalEvent.touches.length)
274
+ {
275
+ // record where touch started
276
+ touchDif = e.originalEvent.touches[0].pageY;
277
+ }
278
+ });
279
+
280
+ me.bind('touchmove', function(e){
281
+ // prevent scrolling the page if necessary
282
+ if(!releaseScroll)
283
+ {
284
+ e.originalEvent.preventDefault();
285
+ }
286
+ if (e.originalEvent.touches.length)
287
+ {
288
+ // see how far user swiped
289
+ var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep;
290
+ // scroll content
291
+ scrollContent(diff, true);
292
+ touchDif = e.originalEvent.touches[0].pageY;
293
+ }
294
+ });
295
+
296
+ // set up initial height
297
+ getBarHeight();
298
+
299
+ // check start position
300
+ if (o.start === 'bottom')
301
+ {
302
+ // scroll content to bottom
303
+ bar.css({ top: me.outerHeight() - bar.outerHeight() });
304
+ scrollContent(0, true);
305
+ }
306
+ else if (o.start !== 'top')
307
+ {
308
+ // assume jQuery selector
309
+ scrollContent($(o.start).position().top, null, true);
310
+
311
+ // make sure bar stays hidden
312
+ if (!o.alwaysVisible) { bar.hide(); }
313
+ }
314
+
315
+ // attach scroll events
316
+ attachWheel(this);
317
+
318
+ function _onWheel(e)
319
+ {
320
+ // use mouse wheel only when mouse is over
321
+ if (!isOverPanel) { return; }
322
+
323
+ var e = e || window.event;
324
+
325
+ var delta = 0;
326
+ if (e.wheelDelta) { delta = -e.wheelDelta/120; }
327
+ if (e.detail) { delta = e.detail / 3; }
328
+
329
+ var target = e.target || e.srcTarget || e.srcElement;
330
+ if ($(target).closest('.' + o.wrapperClass).is(me.parent())) {
331
+ // scroll content
332
+ scrollContent(delta, true);
333
+ }
334
+
335
+ // stop window scroll
336
+ if (e.preventDefault && !releaseScroll) { e.preventDefault(); }
337
+ if (!releaseScroll) { e.returnValue = false; }
338
+ }
339
+
340
+ function scrollContent(y, isWheel, isJump)
341
+ {
342
+ releaseScroll = false;
343
+ var delta = y;
344
+ var maxTop = me.outerHeight() - bar.outerHeight();
345
+
346
+ if (isWheel)
347
+ {
348
+ // move bar with mouse wheel
349
+ delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight();
350
+
351
+ // move bar, make sure it doesn't go out
352
+ delta = Math.min(Math.max(delta, 0), maxTop);
353
+
354
+ // if scrolling down, make sure a fractional change to the
355
+ // scroll position isn't rounded away when the scrollbar's CSS is set
356
+ // this flooring of delta would happened automatically when
357
+ // bar.css is set below, but we floor here for clarity
358
+ delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta);
359
+
360
+ // scroll the scrollbar
361
+ bar.css({ top: delta + 'px' });
362
+ }
363
+
364
+ // calculate actual scroll amount
365
+ percentScroll = parseInt(bar.css('top')) / (me.outerHeight() - bar.outerHeight());
366
+ delta = percentScroll * (me[0].scrollHeight - me.outerHeight());
367
+
368
+ if (isJump)
369
+ {
370
+ delta = y;
371
+ var offsetTop = delta / me[0].scrollHeight * me.outerHeight();
372
+ offsetTop = Math.min(Math.max(offsetTop, 0), maxTop);
373
+ bar.css({ top: offsetTop + 'px' });
374
+ }
375
+
376
+ // scroll content
377
+ me.scrollTop(delta);
378
+
379
+ // fire scrolling event
380
+ me.trigger('slimscrolling', ~~delta);
381
+
382
+ // ensure bar is visible
383
+ showBar();
384
+
385
+ // trigger hide when scroll is stopped
386
+ hideBar();
387
+ }
388
+
389
+ function attachWheel(target)
390
+ {
391
+ if (window.addEventListener)
392
+ {
393
+ target.addEventListener('DOMMouseScroll', _onWheel, false );
394
+ target.addEventListener('mousewheel', _onWheel, false );
395
+ }
396
+ else
397
+ {
398
+ document.attachEvent("onmousewheel", _onWheel)
399
+ }
400
+ }
401
+
402
+ function getBarHeight()
403
+ {
404
+ // calculate scrollbar height and make sure it is not too small
405
+ barHeight = Math.max((me.outerHeight() / me[0].scrollHeight) * me.outerHeight(), minBarHeight);
406
+ bar.css({ height: barHeight + 'px' });
407
+
408
+ // hide scrollbar if content is not long enough
409
+ var display = barHeight == me.outerHeight() ? 'none' : 'block';
410
+ bar.css({ display: display });
411
+ }
412
+
413
+ function showBar()
414
+ {
415
+ // recalculate bar height
416
+ getBarHeight();
417
+ clearTimeout(queueHide);
418
+
419
+ // when bar reached top or bottom
420
+ if (percentScroll == ~~percentScroll)
421
+ {
422
+ //release wheel
423
+ releaseScroll = o.allowPageScroll;
424
+
425
+ // publish approporiate event
426
+ if (lastScroll != percentScroll)
427
+ {
428
+ var msg = (~~percentScroll == 0) ? 'top' : 'bottom';
429
+ me.trigger('slimscroll', msg);
430
+ }
431
+ }
432
+ else
433
+ {
434
+ releaseScroll = false;
435
+ }
436
+ lastScroll = percentScroll;
437
+
438
+ // show only when required
439
+ if(barHeight >= me.outerHeight()) {
440
+ //allow window scroll
441
+ releaseScroll = true;
442
+ return;
443
+ }
444
+ bar.stop(true,true).fadeIn('fast');
445
+ if (o.railVisible) { rail.stop(true,true).fadeIn('fast'); }
446
+ }
447
+
448
+ function hideBar()
449
+ {
450
+ // only hide when options allow it
451
+ if (!o.alwaysVisible)
452
+ {
453
+ queueHide = setTimeout(function(){
454
+ if (!(o.disableFadeOut && isOverPanel) && !isOverBar && !isDragg)
455
+ {
456
+ bar.fadeOut('slow');
457
+ rail.fadeOut('slow');
458
+ }
459
+ }, 1000);
460
+ }
461
+ }
462
+
463
+ });
464
+
465
+ // maintain chainability
466
+ return this;
467
+ }
468
+ });
469
+
470
+ $.fn.extend({
471
+ slimscroll: $.fn.slimScroll
472
+ });
473
+
474
+ })(jQuery);
assets/frontend/js/premium-addons.js CHANGED
@@ -666,7 +666,8 @@
666
  var PremiumBlogHandler = function ($scope, $) {
667
  var blogElement = $scope.find(".premium-blog-wrap"),
668
  colsNumber = blogElement.data("col"),
669
- carousel = blogElement.data("carousel");
 
670
 
671
  $scope.find(".premium-blog-cats-container li a").click(function (e) {
672
  e.preventDefault();
@@ -686,7 +687,7 @@
686
 
687
  var masonryBlog = blogElement.hasClass( "premium-blog-masonry" );
688
 
689
- if ( masonryBlog ) {
690
  blogElement.imagesLoaded( function () {
691
  blogElement.isotope({
692
  itemSelector: ".premium-blog-post-outer-container",
@@ -700,7 +701,7 @@
700
  });
701
  }
702
 
703
- if ( carousel && ! masonryBlog ) {
704
 
705
  var autoPlay = blogElement.data("play"),
706
  speed = blogElement.data("speed"),
666
  var PremiumBlogHandler = function ($scope, $) {
667
  var blogElement = $scope.find(".premium-blog-wrap"),
668
  colsNumber = blogElement.data("col"),
669
+ carousel = blogElement.data("carousel"),
670
+ grid = blogElement.data("grid");
671
 
672
  $scope.find(".premium-blog-cats-container li a").click(function (e) {
673
  e.preventDefault();
687
 
688
  var masonryBlog = blogElement.hasClass( "premium-blog-masonry" );
689
 
690
+ if ( masonryBlog && ! carousel ) {
691
  blogElement.imagesLoaded( function () {
692
  blogElement.isotope({
693
  itemSelector: ".premium-blog-post-outer-container",
701
  });
702
  }
703
 
704
+ if ( carousel && grid ) {
705
 
706
  var autoPlay = blogElement.data("play"),
707
  speed = blogElement.data("speed"),
assets/frontend/js/premium-vscroll.js CHANGED
@@ -45,6 +45,11 @@
45
  });
46
 
47
  self.init = function() {
 
 
 
 
 
48
  self.setSectionsData();
49
 
50
  isTouch = self.isTouchDevice();
@@ -70,36 +75,104 @@
70
  "resize.premiumVerticalScroll orientationchange.premiumVerticalScroll",
71
  self.debounce(50, self.onResize)
72
  );
 
73
  $window.on("load", function() {
74
  self.setSectionsData();
 
 
 
75
  });
76
 
77
  self.keyboardHandler();
78
 
79
  self.scrollHandler();
 
 
 
 
 
80
 
81
- self.fullSectionHandler();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  };
83
 
84
  self.setSectionsData = function() {
 
85
  $itemsList.each(function() {
86
- var $this = $(this),
87
- sectionId = $this.data("menuanchor"),
88
- $section = $("#" + sectionId);
89
- if ($section[0]) {
 
 
 
90
  sections[sectionId] = {
91
  selector: $section,
92
- offset: Math.round($section.offset().top),
93
- height: $section.outerHeight()
94
  };
95
  }
96
  });
 
97
  };
98
 
99
  self.fullSectionHandler = function() {
100
 
101
- if ( settings.fullSection ) {
102
-
103
  var vSection = document.getElementById( $instance.attr( "id" ) );
104
 
105
  if ( ! isTouch || ! settings.fullTouch ) {
@@ -124,8 +197,6 @@
124
 
125
  }
126
 
127
- }
128
-
129
  };
130
 
131
  self.scrollHandler = function() {
@@ -173,44 +244,24 @@
173
  }
174
  });
175
  };
176
-
177
- self.scrolling = function ( sectionID ) {
178
 
179
- if( self.atBottom( sectionID ) || sectionChanged ) {
180
- self.onAnchorChange( sectionID );
181
- sectionChanged = 0;
182
- } else {
183
-
184
- var ID = '#' + sectionID,
185
- offset = $window.scrollTop() + $( ID ).outerHeight() / 4;
186
-
187
- $htmlBody
188
- .stop()
189
- .clearQueue()
190
- .animate(
191
- { scrollTop: offset },
192
- 700,
193
- "easeInOutCirc",
194
- function() {
195
- isScrolling = false;
196
- }
197
- );
198
-
199
- }
200
- };
201
-
202
- self.atBottom = function( sectionID ) {
203
 
204
- var top = $window.scrollTop(),
205
- portHeight = window.innerHeight,
206
- ID = '#' + sectionID,
207
- height = parseInt ( $( ID ).offset().top );
208
-
209
- if( top < parseInt( height ) + ( $( ID ).outerHeight() - portHeight ) - 28 ) {
210
- return false;
 
 
211
  } else {
212
  return true;
213
  }
 
214
  };
215
 
216
  self.isTouchDevice = function() {
@@ -248,9 +299,7 @@
248
 
249
  self.onTouchMove = function( e ) {
250
 
251
- if ( ! settings.showOverflow ) {
252
- self.preventDefault( e );
253
- }
254
 
255
  if ( isScrolling ) {
256
  self.preventDefault( e );
@@ -323,12 +372,12 @@
323
 
324
  $( ".premium-vscroll-dots, .premium-vscroll-nav-menu" ).removeClass( "premium-vscroll-dots-hide" );
325
 
326
- if ( settings.showOverflow ) {
327
- if ( ! self.atBottom( sectionId ) )
328
- return;
 
 
329
  }
330
-
331
- self.onAnchorChange( newSectionId );
332
 
333
  } else {
334
 
@@ -606,18 +655,19 @@
606
  return t;
607
  }
608
 
609
- self.onWheel = function(event) {
 
 
610
 
611
  if ( isScrolling ) {
612
- event.preventDefault();
613
  return false;
614
  }
615
 
616
  var $target = $( event.target ),
617
  sectionSelector = checkTemps ? ".premium-vscroll-temp" : ".elementor-top-section",
618
  $section = $target.closest( sectionSelector ),
619
- $vTarget = self.visible($instance, true, false),
620
  sectionId = $section.attr("id"),
 
621
  newSectionId = false,
622
  prevSectionId = false,
623
  nextSectionId = false,
@@ -678,17 +728,16 @@
678
  newSectionId = nextSectionId;
679
  }
680
  }
681
-
682
  if ( newSectionId ) {
683
-
684
- if ( ! self.atBottom( sectionId ) )
685
  return;
 
686
 
687
  $( ".premium-vscroll-dots, .premium-vscroll-nav-menu" ).removeClass("premium-vscroll-dots-hide");
688
 
689
- event.preventDefault();
690
-
691
  self.onAnchorChange( newSectionId );
 
692
  } else {
693
  var $lastselector = checkTemps
694
  ? $instance
@@ -719,7 +768,7 @@
719
  }
720
  };
721
 
722
- function beforeCheck(event) {
723
  var windowScrollTop = $window.scrollTop(),
724
  firstSectionId = getFirstSection(sections),
725
  offset = sections[firstSectionId].offset,
@@ -734,10 +783,9 @@
734
  return false;
735
  }
736
 
737
- function afterCheck(event) {
738
  var windowScrollTop = $window.scrollTop(),
739
  lastSectionId = getLastSection(sections),
740
- offset = sections[lastSectionId].offset,
741
  bottomBorder =
742
  sections[lastSectionId].offset +
743
  sections[lastSectionId].height,
@@ -754,6 +802,7 @@
754
 
755
  self.onResize = function(event) {
756
  self.setSectionsData();
 
757
  };
758
 
759
  };
45
  });
46
 
47
  self.init = function() {
48
+
49
+ if( settings.fullSection ) {
50
+ self.setSectionsOverflow();
51
+ }
52
+
53
  self.setSectionsData();
54
 
55
  isTouch = self.isTouchDevice();
75
  "resize.premiumVerticalScroll orientationchange.premiumVerticalScroll",
76
  self.debounce(50, self.onResize)
77
  );
78
+
79
  $window.on("load", function() {
80
  self.setSectionsData();
81
+ if( settings.fullSection ) {
82
+ self.sectionsOverflowRefresh();
83
+ }
84
  });
85
 
86
  self.keyboardHandler();
87
 
88
  self.scrollHandler();
89
+
90
+ if( settings.fullSection ) {
91
+
92
+ self.fullSectionHandler();
93
+ }
94
 
95
+ };
96
+
97
+ self.setSectionsOverflow = function() {
98
+
99
+ $itemsList.each(function() {
100
+
101
+ var $this = $(this),
102
+ sectionId = $this.data("menuanchor"),
103
+ $section = $("#" + sectionId),
104
+ height = $section.outerHeight();
105
+
106
+ if( height > $window.outerHeight() && height - $window.outerHeight() >= 50 ) {
107
+
108
+ $section.find(".elementor").first().wrapInner("<div id='scroller-" + sectionId + "'></div>");
109
+
110
+ $( "#scroller-" + sectionId ).slimScroll({
111
+ height: $window.outerHeight(),
112
+ railVisible: false
113
+ });
114
+
115
+ var iScrollInstance = new IScroll( "#scroller-" + sectionId, {
116
+ mouseWheel: true,
117
+ scrollbars: true,
118
+ hideScrollbars: true,
119
+ fadeScrollbars: false,
120
+ disableMouse: true,
121
+ interactiveScrollbars: false
122
+ });
123
+
124
+ $( "#scroller-" + sectionId ).data( 'iscrollInstance', iScrollInstance );
125
+
126
+ setTimeout(function(){
127
+ iScrollInstance.refresh();
128
+ }, 1500);
129
+
130
+
131
+ }
132
+
133
+ });
134
+ };
135
+
136
+ self.sectionsOverflowRefresh = function() {
137
+
138
+ $itemsList.each(function() {
139
+ var $this = $(this),
140
+ sectionId = $this.data("menuanchor");
141
+
142
+ var $section = $( "#scroller-" + sectionId );
143
+
144
+ var scroller = $section.data('iscrollInstance');
145
+
146
+ if ( scroller ) {
147
+ scroller.refresh();
148
+ }
149
+
150
+ });
151
+
152
  };
153
 
154
  self.setSectionsData = function() {
155
+
156
  $itemsList.each(function() {
157
+ var $this = $(this),
158
+ sectionId = $this.data("menuanchor"),
159
+ $section = $("#" + sectionId),
160
+ height = $section.outerHeight();
161
+
162
+ if ( $section[0] ) {
163
+
164
  sections[sectionId] = {
165
  selector: $section,
166
+ offset: Math.round( $section.offset().top ),
167
+ height: height
168
  };
169
  }
170
  });
171
+
172
  };
173
 
174
  self.fullSectionHandler = function() {
175
 
 
 
176
  var vSection = document.getElementById( $instance.attr( "id" ) );
177
 
178
  if ( ! isTouch || ! settings.fullTouch ) {
197
 
198
  }
199
 
 
 
200
  };
201
 
202
  self.scrollHandler = function() {
244
  }
245
  });
246
  };
247
+
248
+ self.isScrolled = function( sectionID, direction ) {
249
 
250
+ var $section = $( "#scroller-" + sectionID );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
 
252
+ var scroller = $section.data('iscrollInstance');
253
+
254
+ if ( scroller ) {
255
+ if( 'down' === direction ) {
256
+ return ( 0 - scroller.y ) + $section.scrollTop() + 1 + $section.innerHeight() >= $section[0].scrollHeight;
257
+ } else if ( 'up' === direction ) {
258
+ return scroller.y >= 0 && !$section.scrollTop();
259
+ }
260
+
261
  } else {
262
  return true;
263
  }
264
+
265
  };
266
 
267
  self.isTouchDevice = function() {
299
 
300
  self.onTouchMove = function( e ) {
301
 
302
+ self.preventDefault( e );
 
 
303
 
304
  if ( isScrolling ) {
305
  self.preventDefault( e );
372
 
373
  $( ".premium-vscroll-dots, .premium-vscroll-nav-menu" ).removeClass( "premium-vscroll-dots-hide" );
374
 
375
+ if ( ! self.isScrolled( sectionId, direction ) ) {
376
+ return;
377
+ }
378
+ if ( Math.abs( touchStartY - touchEndY ) > ( window.innerHeight / 100 * 15 ) ) {
379
+ self.onAnchorChange( newSectionId );
380
  }
 
 
381
 
382
  } else {
383
 
655
  return t;
656
  }
657
 
658
+ self.onWheel = function( event ) {
659
+
660
+ self.preventDefault( event );
661
 
662
  if ( isScrolling ) {
 
663
  return false;
664
  }
665
 
666
  var $target = $( event.target ),
667
  sectionSelector = checkTemps ? ".premium-vscroll-temp" : ".elementor-top-section",
668
  $section = $target.closest( sectionSelector ),
 
669
  sectionId = $section.attr("id"),
670
+ $vTarget = self.visible( $instance, true, false ),
671
  newSectionId = false,
672
  prevSectionId = false,
673
  nextSectionId = false,
728
  newSectionId = nextSectionId;
729
  }
730
  }
731
+
732
  if ( newSectionId ) {
733
+ if ( ! self.isScrolled( sectionId, direction ) ) {
 
734
  return;
735
+ }
736
 
737
  $( ".premium-vscroll-dots, .premium-vscroll-nav-menu" ).removeClass("premium-vscroll-dots-hide");
738
 
 
 
739
  self.onAnchorChange( newSectionId );
740
+
741
  } else {
742
  var $lastselector = checkTemps
743
  ? $instance
768
  }
769
  };
770
 
771
+ function beforeCheck() {
772
  var windowScrollTop = $window.scrollTop(),
773
  firstSectionId = getFirstSection(sections),
774
  offset = sections[firstSectionId].offset,
783
  return false;
784
  }
785
 
786
+ function afterCheck() {
787
  var windowScrollTop = $window.scrollTop(),
788
  lastSectionId = getLastSection(sections),
 
789
  bottomBorder =
790
  sections[lastSectionId].offset +
791
  sections[lastSectionId].height,
802
 
803
  self.onResize = function(event) {
804
  self.setSectionsData();
805
+ self.sectionsOverflowRefresh();
806
  };
807
 
808
  };
includes/class-addons-integration.php CHANGED
@@ -254,21 +254,21 @@ class Addons_Integration {
254
  true
255
  );
256
 
257
- // wp_register_script(
258
- // 'slimscroll-js',
259
- // PREMIUM_ADDONS_URL . 'assets/frontend/js/lib/jquery.slimscroll.js',
260
- // array('jquery'),
261
- // PREMIUM_ADDONS_VERSION,
262
- // true
263
- // );
264
- //
265
- // wp_register_script(
266
- // 'iscroll-js',
267
- // PREMIUM_ADDONS_URL . 'assets/frontend/js/lib/iscroll.js',
268
- // array('jquery'),
269
- // PREMIUM_ADDONS_VERSION,
270
- // true
271
- // );
272
 
273
  }
274
 
254
  true
255
  );
256
 
257
+ wp_register_script(
258
+ 'slimscroll-js',
259
+ PREMIUM_ADDONS_URL . 'assets/frontend/js/lib/jquery.slimscroll.js',
260
+ array('jquery'),
261
+ PREMIUM_ADDONS_VERSION,
262
+ true
263
+ );
264
+
265
+ wp_register_script(
266
+ 'iscroll-js',
267
+ PREMIUM_ADDONS_URL . 'assets/frontend/js/lib/iscroll.js',
268
+ array('jquery'),
269
+ PREMIUM_ADDONS_VERSION,
270
+ true
271
+ );
272
 
273
  }
274
 
premium-addons-for-elementor.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Premium Addons for Elementor
4
  Description: Premium Addons Plugin Includes 22+ premium widgets for Elementor Page Builder.
5
  Plugin URI: https://premiumaddons.com
6
- Version: 3.7.0
7
  Author: Leap13
8
  Author URI: https://leap13.com/
9
  Text Domain: premium-addons-for-elementor
@@ -14,12 +14,12 @@ License: GNU General Public License v3.0
14
  if ( ! defined('ABSPATH') ) exit; // No access of directly access
15
 
16
  // Define Constants
17
- define('PREMIUM_ADDONS_VERSION', '3.7.0');
18
  define('PREMIUM_ADDONS_URL', plugins_url('/', __FILE__));
19
  define('PREMIUM_ADDONS_PATH', plugin_dir_path(__FILE__));
20
  define('PREMIUM_ADDONS_FILE', __FILE__);
21
  define('PREMIUM_ADDONS_BASENAME', plugin_basename( PREMIUM_ADDONS_FILE ) );
22
- define('PREMIUM_ADDONS_STABLE_VERSION', '3.6.9');
23
 
24
  if( ! class_exists('Premium_Addons_Elementor') ) {
25
 
3
  Plugin Name: Premium Addons for Elementor
4
  Description: Premium Addons Plugin Includes 22+ premium widgets for Elementor Page Builder.
5
  Plugin URI: https://premiumaddons.com
6
+ Version: 3.7.1
7
  Author: Leap13
8
  Author URI: https://leap13.com/
9
  Text Domain: premium-addons-for-elementor
14
  if ( ! defined('ABSPATH') ) exit; // No access of directly access
15
 
16
  // Define Constants
17
+ define('PREMIUM_ADDONS_VERSION', '3.7.1');
18
  define('PREMIUM_ADDONS_URL', plugins_url('/', __FILE__));
19
  define('PREMIUM_ADDONS_PATH', plugin_dir_path(__FILE__));
20
  define('PREMIUM_ADDONS_FILE', __FILE__);
21
  define('PREMIUM_ADDONS_BASENAME', plugin_basename( PREMIUM_ADDONS_FILE ) );
22
+ define('PREMIUM_ADDONS_STABLE_VERSION', '3.7.0');
23
 
24
  if( ! class_exists('Premium_Addons_Elementor') ) {
25
 
readme.txt CHANGED
@@ -5,7 +5,7 @@ Donate Link: https://premiumaddons.com/?utm_source=wp-repo&utm_medium=link&utm_c
5
  Requires at Least: 4.5
6
  Tested Up To: 5.2.2
7
  Requires PHP: 5.4
8
- Stable Tag: 3.7.0
9
  License: GPL v3.0
10
  License URI: https://opensource.org/licenses/GPL-3.0
11
 
@@ -174,6 +174,11 @@ Premium Addons for Elementor is 100% Ads Free, Ads can only be detected from You
174
 
175
  == Changelog ==
176
 
 
 
 
 
 
177
  = 3.7.0 =
178
 
179
  - Tweak: Media Grid widget now support videos.
5
  Requires at Least: 4.5
6
  Tested Up To: 5.2.2
7
  Requires PHP: 5.4
8
+ Stable Tag: 3.7.1
9
  License: GPL v3.0
10
  License URI: https://opensource.org/licenses/GPL-3.0
11
 
174
 
175
  == Changelog ==
176
 
177
+ = 3.7.1 =
178
+
179
+ - Tweak: Vertical Scroll performance enhanced on all devices.
180
+ - Fixed: Security bugs fixed.
181
+
182
  = 3.7.0 =
183
 
184
  - Tweak: Media Grid widget now support videos.
widgets/premium-blog.php CHANGED
@@ -427,6 +427,38 @@ class Premium_Blog extends Widget_Base {
427
  ]
428
  );
429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
430
  $this->add_control('premium_blog_categories',
431
  [
432
  'label' => __( 'Filter By Category', 'premium-addons-for-elementor' ),
@@ -610,45 +642,13 @@ class Premium_Blog extends Widget_Base {
610
  ]
611
  );
612
 
613
- $this->add_control('premium_blog_number_of_posts',
614
- [
615
- 'label' => __('Posts Per Page', 'premium-addons-for-elementor'),
616
- 'description' => __('Choose how many posts do you want to be displayed per page','premium-addons-for-elementor'),
617
- 'type' => Controls_Manager::NUMBER,
618
- 'min' => 1,
619
- 'default' => 3,
620
- ]
621
- );
622
-
623
- $this->add_control('premium_blog_total_posts_number',
624
- [
625
- 'label' => __('Total Number of Posts', 'premium-addons-for-elementor'),
626
- 'type' => Controls_Manager::NUMBER,
627
- 'default' => wp_count_posts()->publish,
628
- 'min' => 1,
629
- 'condition' => [
630
- 'premium_blog_paging' => 'yes',
631
- ]
632
- ]
633
- );
634
-
635
- $this->add_control('premium_blog_offset',
636
- [
637
- 'label' => __( 'Offset Count', 'premium-addons-for-elementor' ),
638
- 'description' => __('The index of post to start with','premium-addons-for-elementor'),
639
- 'type' => Controls_Manager::NUMBER,
640
- 'default' => '0',
641
- 'min' => '0',
642
- ]
643
- );
644
-
645
  $this->end_controls_section();
646
 
647
  $this->start_controls_section('premium_blog_carousel_settings',
648
  [
649
  'label' => __('Carousel', 'premium-addons-for-elementor'),
650
  'condition' => [
651
- 'premium_blog_layout!' => 'masonry'
652
  ]
653
  ]
654
  );
@@ -1826,11 +1826,15 @@ class Premium_Blog extends Widget_Base {
1826
  $play = 'yes' == $settings['premium_blog_carousel_play'] ? true : false;
1827
  $fade = 'yes' == $settings['premium_blog_carousel_fade'] ? 'true' : 'false';
1828
  $arrows = 'yes' == $settings['premium_blog_carousel_arrows'] ? 'true' : 'false';
 
 
1829
  $speed = ! empty( $settings['premium_blog_carousel_autoplay_speed'] ) ? $settings['premium_blog_carousel_autoplay_speed'] : 5000;
1830
  $dots = 'yes' == $settings['premium_blog_carousel_dots'] ? 'true' : 'false';
1831
 
1832
  $this->add_render_attribute('blog', 'data-carousel', $carousel );
1833
-
 
 
1834
  $this->add_render_attribute('blog', 'data-fade', $fade );
1835
 
1836
  $this->add_render_attribute('blog', 'data-play', $play );
427
  ]
428
  );
429
 
430
+ $this->add_control('premium_blog_number_of_posts',
431
+ [
432
+ 'label' => __('Posts Per Page', 'premium-addons-for-elementor'),
433
+ 'description' => __('Choose how many posts do you want to be displayed per page','premium-addons-for-elementor'),
434
+ 'type' => Controls_Manager::NUMBER,
435
+ 'min' => 1,
436
+ 'default' => 3,
437
+ ]
438
+ );
439
+
440
+ $this->add_control('premium_blog_total_posts_number',
441
+ [
442
+ 'label' => __('Total Number of Posts', 'premium-addons-for-elementor'),
443
+ 'type' => Controls_Manager::NUMBER,
444
+ 'default' => wp_count_posts()->publish,
445
+ 'min' => 1,
446
+ 'condition' => [
447
+ 'premium_blog_paging' => 'yes',
448
+ ]
449
+ ]
450
+ );
451
+
452
+ $this->add_control('premium_blog_offset',
453
+ [
454
+ 'label' => __( 'Offset Count', 'premium-addons-for-elementor' ),
455
+ 'description' => __('The index of post to start with','premium-addons-for-elementor'),
456
+ 'type' => Controls_Manager::NUMBER,
457
+ 'default' => '0',
458
+ 'min' => '0',
459
+ ]
460
+ );
461
+
462
  $this->add_control('premium_blog_categories',
463
  [
464
  'label' => __( 'Filter By Category', 'premium-addons-for-elementor' ),
642
  ]
643
  );
644
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
  $this->end_controls_section();
646
 
647
  $this->start_controls_section('premium_blog_carousel_settings',
648
  [
649
  'label' => __('Carousel', 'premium-addons-for-elementor'),
650
  'condition' => [
651
+ 'premium_blog_grid' => 'yes'
652
  ]
653
  ]
654
  );
1826
  $play = 'yes' == $settings['premium_blog_carousel_play'] ? true : false;
1827
  $fade = 'yes' == $settings['premium_blog_carousel_fade'] ? 'true' : 'false';
1828
  $arrows = 'yes' == $settings['premium_blog_carousel_arrows'] ? 'true' : 'false';
1829
+ $grid = 'yes' == $settings['premium_blog_grid'] ? 'true' : 'false';
1830
+
1831
  $speed = ! empty( $settings['premium_blog_carousel_autoplay_speed'] ) ? $settings['premium_blog_carousel_autoplay_speed'] : 5000;
1832
  $dots = 'yes' == $settings['premium_blog_carousel_dots'] ? 'true' : 'false';
1833
 
1834
  $this->add_render_attribute('blog', 'data-carousel', $carousel );
1835
+
1836
+ $this->add_render_attribute('blog', 'data-grid', $grid );
1837
+
1838
  $this->add_render_attribute('blog', 'data-fade', $fade );
1839
 
1840
  $this->add_render_attribute('blog', 'data-play', $play );
widgets/premium-grid.php CHANGED
@@ -703,7 +703,7 @@ class Premium_Grid extends Widget_Base {
703
  'options' => [
704
  'default' => __( 'PrettyPhoto', 'premium-addons-for-elementor' ),
705
  'yes' => __( 'Elementor', 'premium-addons-for-elementor' ),
706
- 'no' => __( 'Other Lightbox PLugin', 'premium-addons-for-elementor' ),
707
  ],
708
  'condition' => [
709
  'premium_gallery_light_box' => 'yes',
@@ -711,6 +711,14 @@ class Premium_Grid extends Widget_Base {
711
  ]
712
  );
713
 
 
 
 
 
 
 
 
 
714
  $this->add_control('premium_gallery_lightbox_theme',
715
  [
716
  'label' => __('Lightbox Theme', 'premium-addons-pro'),
@@ -834,8 +842,8 @@ class Premium_Grid extends Widget_Base {
834
 
835
  $this->add_control('doc_1',
836
  [
837
- 'type' => Controls_Manager::RAW_HTML,
838
  'raw' => sprintf( __( '%1$s Getting Started » %2$s', 'premium-addons-for-elementor' ), '<a href="https://premiumaddons.com/docs/grid-widget-tutorial/?utm_source=pa-dashboard&utm_medium=pa-editor&utm_campaign=pa-plugin" target="_blank" rel="noopener">', '</a>' ),
 
839
  'content_classes' => 'editor-pa-doc',
840
  ]
841
  );
703
  'options' => [
704
  'default' => __( 'PrettyPhoto', 'premium-addons-for-elementor' ),
705
  'yes' => __( 'Elementor', 'premium-addons-for-elementor' ),
706
+ 'no' => __( 'Other Lightbox Plugin', 'premium-addons-for-elementor' ),
707
  ],
708
  'condition' => [
709
  'premium_gallery_light_box' => 'yes',
711
  ]
712
  );
713
 
714
+ $this->add_control('premium_gallery_lightbox_doc',
715
+ [
716
+ 'raw' => __( 'Please note Elementor lightbox style is always applied on videos.', 'premium-addons-for-elementor' ),
717
+ 'type' => Controls_Manager::RAW_HTML,
718
+ 'content_classes' => 'editor-pa-doc',
719
+ ]
720
+ );
721
+
722
  $this->add_control('premium_gallery_lightbox_theme',
723
  [
724
  'label' => __('Lightbox Theme', 'premium-addons-pro'),
842
 
843
  $this->add_control('doc_1',
844
  [
 
845
  'raw' => sprintf( __( '%1$s Getting Started » %2$s', 'premium-addons-for-elementor' ), '<a href="https://premiumaddons.com/docs/grid-widget-tutorial/?utm_source=pa-dashboard&utm_medium=pa-editor&utm_campaign=pa-plugin" target="_blank" rel="noopener">', '</a>' ),
846
+ 'type' => Controls_Manager::RAW_HTML,
847
  'content_classes' => 'editor-pa-doc',
848
  ]
849
  );
widgets/premium-vscroll.php CHANGED
@@ -45,8 +45,8 @@ class Premium_Vscroll extends Widget_Base {
45
 
46
  public function get_script_depends() {
47
  return [
48
- // 'iscroll-js',
49
- // 'slimscroll-js',
50
  'vscroll-js'
51
  ];
52
  }
@@ -331,15 +331,15 @@ class Premium_Vscroll extends Widget_Base {
331
  ]
332
  );
333
 
334
- $this->add_control('overflow_touch',
335
- [
336
- 'label' => __('Show overflow content', 'premium-addons-for-elementor'),
337
- 'type' => Controls_Manager::SWITCHER,
338
- 'condition' => [
339
- 'full_section_touch' => 'yes'
340
- ]
341
- ]
342
- );
343
 
344
  $this->end_controls_section();
345
 
@@ -798,7 +798,7 @@ class Premium_Vscroll extends Widget_Base {
798
  'dotsVPos' => $settings['navigation_dots_v_pos'],
799
  'fullSection' => 'yes' == $settings['full_section'] ? true : false,
800
  'fullTouch' => 'yes' == $settings['full_section_touch'] ? true : false,
801
- 'showOverflow' => 'yes' == $settings['overflow_touch'] ? true : false,
802
  'addToHistory' => 'yes' == $settings['save_state'] ? true : false
803
  ];
804
 
45
 
46
  public function get_script_depends() {
47
  return [
48
+ 'iscroll-js',
49
+ 'slimscroll-js',
50
  'vscroll-js'
51
  ];
52
  }
331
  ]
332
  );
333
 
334
+ // $this->add_control('overflow_touch',
335
+ // [
336
+ // 'label' => __('Show overflow content', 'premium-addons-for-elementor'),
337
+ // 'type' => Controls_Manager::SWITCHER,
338
+ // 'condition' => [
339
+ // 'full_section_touch' => 'yes'
340
+ // ]
341
+ // ]
342
+ // );
343
 
344
  $this->end_controls_section();
345
 
798
  'dotsVPos' => $settings['navigation_dots_v_pos'],
799
  'fullSection' => 'yes' == $settings['full_section'] ? true : false,
800
  'fullTouch' => 'yes' == $settings['full_section_touch'] ? true : false,
801
+ // 'showOverflow' => 'yes' == $settings['overflow_touch'] ? true : false,
802
  'addToHistory' => 'yes' == $settings['save_state'] ? true : false
803
  ];
804