Unyson - Version 2.3.3

Version Description

  • Fixed #628, #649, #637, #358
  • Added option type typography-v2
  • Option type addable-option, addable-box and addable-popup: Added the add-button-text and sortable parameters #631
  • Optimized option type typography fonts select (now it loads faster)
  • Extension download improvement: Fetch only the latest release instead of all releases
  • Improved the fw.loading js helper. Changed the loading image.
  • Option type range-slider: fixed bug with default value
  • Option type checkbox and switch: Fix boolean values when the option is used in options modal inside other options
  • Call FW_Option_Type::_init() after the option type has been registered
  • fw.OptionsModal: Added html cache #
  • Added $old_value parameter in 'fw_post_options_update' action
  • Added the fw_get_image_sizes() function
  • Enabled the colorpicker and textcolor plugins for the wp-editor option type
  • Option type background-image and multi-picker: minor css fixes
  • Updated selectize.js to 0.12.1
Download this release

Release Info

Developer Unyson
Plugin Icon 128x128 Unyson
Version 2.3.3
Comparing to
See all releases

Code changes from version 2.3.2 to 2.3.3

Files changed (52) hide show
  1. README.md +0 -2
  2. framework/core/components/backend.php +34 -6
  3. framework/core/components/extensions/manager/class--fw-extensions-manager.php +4 -8
  4. framework/core/extends/class-fw-option-type.php +18 -4
  5. framework/extensions/blog/class-fw-extension-blog.php +0 -2
  6. framework/extensions/blog/manifest.php +1 -1
  7. framework/extensions/update/extensions/github-update/class-fw-extension-github-update.php +9 -27
  8. framework/extensions/update/manifest.php +1 -1
  9. framework/helpers/database.php +8 -1
  10. framework/helpers/general.php +50 -0
  11. framework/includes/option-types/addable-box/class-fw-option-type-addable-box.php +30 -1
  12. framework/includes/option-types/addable-box/static/js/scripts.js +10 -5
  13. framework/includes/option-types/addable-box/view.php +5 -1
  14. framework/includes/option-types/addable-option/class-fw-option-type-addable-option.php +9 -1
  15. framework/includes/option-types/addable-option/static/css/styles.css +3 -0
  16. framework/includes/option-types/addable-option/static/js/scripts.js +4 -0
  17. framework/includes/option-types/addable-option/view.php +5 -1
  18. framework/includes/option-types/addable-popup/class-fw-option-type-addable-popup.php +9 -1
  19. framework/includes/option-types/addable-popup/static/css/styles.css +8 -0
  20. framework/includes/option-types/addable-popup/static/js/addable-popup.js +12 -0
  21. framework/includes/option-types/addable-popup/views/view.php +7 -2
  22. framework/includes/option-types/background-image/static/css/styles.css +12 -3
  23. framework/includes/option-types/background-image/view.php +5 -1
  24. framework/includes/option-types/init.php +1 -0
  25. framework/includes/option-types/multi-picker/static/css/multi-picker.css +6 -6
  26. framework/includes/option-types/range-slider/class-fw-option-type-range-slider.php +58 -21
  27. framework/includes/option-types/simple.php +57 -24
  28. framework/includes/option-types/slider/class-fw-option-type-slider.php +1 -3
  29. framework/includes/option-types/slider/static/js/scripts.js +1 -2
  30. framework/includes/option-types/switch/class-fw-option-type-switch.php +59 -0
  31. framework/includes/option-types/typography-v2/class-fw-option-type-typography-v2.php +180 -0
  32. framework/includes/option-types/typography-v2/static/css/styles.css +303 -0
  33. framework/includes/option-types/typography-v2/static/js/scripts.js +226 -0
  34. framework/includes/option-types/typography-v2/view.php +182 -0
  35. framework/includes/option-types/typography/static/js/scripts.js +126 -32
  36. framework/includes/option-types/typography/view.php +1 -1
  37. framework/includes/option-types/wp-editor/class-fw-option-type-wp-editor.php +1 -1
  38. framework/includes/option-types/wp-editor/static/js/scripts.js +10 -6
  39. framework/manifest.php +1 -1
  40. framework/static/css/backend-options.css +41 -4
  41. framework/static/css/fw.css +125 -22
  42. framework/static/img/logo-100.png +0 -0
  43. framework/static/img/logo.svg +6 -0
  44. framework/static/js/backend-options.js +20 -11
  45. framework/static/js/fw-events.js +29 -25
  46. framework/static/js/fw-form-helpers.js +5 -5
  47. framework/static/js/fw.js +226 -105
  48. framework/static/libs/selectize/selectize.css +195 -211
  49. framework/static/libs/selectize/selectize.min.js +3 -3
  50. framework/views/backend-settings-form.php +52 -6
  51. readme.txt +19 -6
  52. unyson.php +1 -1
README.md CHANGED
@@ -60,8 +60,6 @@ Developers can contribute to the source code. Please read our [contributor guide
60
 
61
  Translators can contribute new languages to Unyson through [Transifex](https://www.transifex.com/projects/p/unyson/).
62
 
63
- If you have an idea for Unyson, see the [Trello board](https://trello.com/b/Xm9TxasH/unyson-development).
64
-
65
  Theme developers can test the compatibility of their themes with new extensions updates before they are going to be released on [Unyson Extensions Approval](https://github.com/ThemeFuse/Unyson-Extensions-Approval).
66
 
67
  ## Extensions
60
 
61
  Translators can contribute new languages to Unyson through [Transifex](https://www.transifex.com/projects/p/unyson/).
62
 
 
 
63
  Theme developers can test the compatibility of their themes with new extensions updates before they are going to be released on [Unyson Extensions Approval](https://github.com/ThemeFuse/Unyson-Extensions-Approval).
64
 
65
  ## Extensions
framework/core/components/backend.php CHANGED
@@ -38,6 +38,11 @@ final class _FW_Component_Backend {
38
 
39
  private $static_registered = false;
40
 
 
 
 
 
 
41
  /**
42
  * @internal
43
  */
@@ -117,7 +122,15 @@ final class _FW_Component_Backend {
117
  /**
118
  * @internal
119
  */
120
- public function _after_components_init() {
 
 
 
 
 
 
 
 
121
  }
122
 
123
  private function add_actions() {
@@ -181,6 +194,8 @@ final class _FW_Component_Backend {
181
  }
182
 
183
  $this->option_types[ $type ] = $option_type_class;
 
 
184
  }
185
  }
186
 
@@ -534,6 +549,10 @@ final class _FW_Component_Backend {
534
  $values = fw_get_db_post_option( $post->ID );
535
 
536
  foreach ( $boxes as $id => &$box ) {
 
 
 
 
537
  $context = isset( $box['context'] ) ? $box['context'] : 'normal';
538
  $priority = isset( $box['priority'] ) ? $box['priority'] : 'default';
539
 
@@ -1008,8 +1027,7 @@ final class _FW_Component_Backend {
1008
  */
1009
  if ( ! is_bool(
1010
  fw()->backend->option_type( $option['type'] )->get_value_from_input( $option, true )
1011
- )
1012
- ) {
1013
  continue;
1014
  }
1015
 
@@ -1232,9 +1250,13 @@ final class _FW_Component_Backend {
1232
  ) );
1233
  break;
1234
  case 'box':
1235
- $html .= '<div class="fw-backend-postboxes metabox-holder">';
1236
 
1237
  foreach ( $collected_type_options as $id => &$box ) {
 
 
 
 
1238
  // prepare attributes
1239
  {
1240
  $attr = isset( $box['attr'] ) ? $box['attr'] : array();
@@ -1242,7 +1264,7 @@ final class _FW_Component_Backend {
1242
  unset( $attr['id'] ); // do not allow id overwrite, it is sent in first argument of render_box()
1243
  }
1244
 
1245
- $html .= $this->render_box(
1246
  'fw-options-box-' . $id,
1247
  empty( $box['title'] ) ? ' ' : $box['title'],
1248
  $this->render_options( $box['options'], $values, $options_data ),
@@ -1253,7 +1275,13 @@ final class _FW_Component_Backend {
1253
  }
1254
  unset($box);
1255
 
1256
- $html .= '</div>';
 
 
 
 
 
 
1257
  break;
1258
  case 'group':
1259
  foreach ( $collected_type_options as $id => &$group ) {
38
 
39
  private $static_registered = false;
40
 
41
+ /**
42
+ * @var FW_Access_Key
43
+ */
44
+ private $access_key;
45
+
46
  /**
47
  * @internal
48
  */
122
  /**
123
  * @internal
124
  */
125
+ public function _after_components_init() {}
126
+
127
+ private function get_access_key()
128
+ {
129
+ if (!$this->access_key) {
130
+ $this->access_key = new FW_Access_Key('fw_backend');
131
+ }
132
+
133
+ return $this->access_key;
134
  }
135
 
136
  private function add_actions() {
194
  }
195
 
196
  $this->option_types[ $type ] = $option_type_class;
197
+
198
+ $this->option_types[ $type ]->_call_init($this->get_access_key());
199
  }
200
  }
201
 
549
  $values = fw_get_db_post_option( $post->ID );
550
 
551
  foreach ( $boxes as $id => &$box ) {
552
+ if (empty($box['options'])) {
553
+ continue;
554
+ }
555
+
556
  $context = isset( $box['context'] ) ? $box['context'] : 'normal';
557
  $priority = isset( $box['priority'] ) ? $box['priority'] : 'default';
558
 
1027
  */
1028
  if ( ! is_bool(
1029
  fw()->backend->option_type( $option['type'] )->get_value_from_input( $option, true )
1030
+ ) ) {
 
1031
  continue;
1032
  }
1033
 
1250
  ) );
1251
  break;
1252
  case 'box':
1253
+ $boxes_html = '';
1254
 
1255
  foreach ( $collected_type_options as $id => &$box ) {
1256
+ if (empty($box['options'])) {
1257
+ continue;
1258
+ }
1259
+
1260
  // prepare attributes
1261
  {
1262
  $attr = isset( $box['attr'] ) ? $box['attr'] : array();
1264
  unset( $attr['id'] ); // do not allow id overwrite, it is sent in first argument of render_box()
1265
  }
1266
 
1267
+ $boxes_html .= $this->render_box(
1268
  'fw-options-box-' . $id,
1269
  empty( $box['title'] ) ? ' ' : $box['title'],
1270
  $this->render_options( $box['options'], $values, $options_data ),
1275
  }
1276
  unset($box);
1277
 
1278
+ if (!empty($boxes_html)) {
1279
+ $html .= '<div class="fw-backend-postboxes metabox-holder">';
1280
+ $html .= $boxes_html;
1281
+ $html .= '</div>';
1282
+ }
1283
+
1284
+ unset($boxes_html);
1285
  break;
1286
  case 'group':
1287
  foreach ( $collected_type_options as $id => &$group ) {
framework/core/components/extensions/manager/class--fw-extensions-manager.php CHANGED
@@ -2356,7 +2356,7 @@ final class _FW_Extensions_Manager
2356
  }
2357
 
2358
  {
2359
- $transient_name = 'fw_ext_manager_gh_download';
2360
  $transient_ttl = HOUR_IN_SECONDS;
2361
 
2362
  $cache = get_site_transient($transient_name);
@@ -2373,7 +2373,7 @@ final class _FW_Extensions_Manager
2373
 
2374
  $response = $http->get(
2375
  apply_filters('fw_github_api_url', 'https://api.github.com')
2376
- . '/repos/'. $source_data['user_repo'] .'/releases'
2377
  );
2378
 
2379
  unset($http);
@@ -2409,11 +2409,11 @@ final class _FW_Extensions_Manager
2409
  }
2410
  }
2411
 
2412
- $releases = json_decode($response['body'], true);
2413
 
2414
  unset($response);
2415
 
2416
- if (empty($releases)) {
2417
  return new WP_Error(
2418
  $wp_error_id,
2419
  sprintf(
@@ -2423,10 +2423,6 @@ final class _FW_Extensions_Manager
2423
  );
2424
  }
2425
 
2426
- $release = reset($releases);
2427
-
2428
- unset($releases);
2429
-
2430
  {
2431
  $cache[ $source_data['user_repo'] ] = array(
2432
  'zipball_url' => 'https://github.com/'. $source_data['user_repo'] .'/archive/'. $release['tag_name'] .'.zip',
2356
  }
2357
 
2358
  {
2359
+ $transient_name = 'fw_ext_mngr_gh_dl';
2360
  $transient_ttl = HOUR_IN_SECONDS;
2361
 
2362
  $cache = get_site_transient($transient_name);
2373
 
2374
  $response = $http->get(
2375
  apply_filters('fw_github_api_url', 'https://api.github.com')
2376
+ . '/repos/'. $source_data['user_repo'] .'/releases/latest'
2377
  );
2378
 
2379
  unset($http);
2409
  }
2410
  }
2411
 
2412
+ $release = json_decode($response['body'], true);
2413
 
2414
  unset($response);
2415
 
2416
+ if (empty($release)) {
2417
  return new WP_Error(
2418
  $wp_error_id,
2419
  sprintf(
2423
  );
2424
  }
2425
 
 
 
 
 
2426
  {
2427
  $cache[ $source_data['user_repo'] ] = array(
2428
  'zipball_url' => 'https://github.com/'. $source_data['user_repo'] .'/archive/'. $release['tag_name'] .'.zip',
framework/core/extends/class-fw-option-type.php CHANGED
@@ -18,8 +18,8 @@ abstract class FW_Option_Type
18
  * and to prevent fatal errors from new option types created by users we can't make it abstract.
19
  *
20
  * @param string $id
21
- * @param array $option
22
- * @param array $data
23
  * @param bool Return true to call this method again on the next enqueue,
24
  * if you have some functionality in it that depends on option parameters.
25
  * By default this method is called only once for performance reasons.
@@ -31,8 +31,8 @@ abstract class FW_Option_Type
31
  /**
32
  * Generate option's html from option array
33
  * @param string $id
34
- * @param array $option Option array merged with _get_defaults()
35
- * @param array $data {value => _get_value_from_input(), id_prefix => ..., name_prefix => ...}
36
  * @return string HTML
37
  * @internal
38
  */
@@ -92,6 +92,20 @@ abstract class FW_Option_Type
92
  final public function __construct()
93
  {
94
  // does nothing at the moment, but maybe in the future will do something
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
  if (method_exists($this, '_init')) {
97
  $this->_init();
18
  * and to prevent fatal errors from new option types created by users we can't make it abstract.
19
  *
20
  * @param string $id
21
+ * @param array $option
22
+ * @param array $data
23
  * @param bool Return true to call this method again on the next enqueue,
24
  * if you have some functionality in it that depends on option parameters.
25
  * By default this method is called only once for performance reasons.
31
  /**
32
  * Generate option's html from option array
33
  * @param string $id
34
+ * @param array $option Option array merged with _get_defaults()
35
+ * @param array $data {value => _get_value_from_input(), id_prefix => ..., name_prefix => ...}
36
  * @return string HTML
37
  * @internal
38
  */
92
  final public function __construct()
93
  {
94
  // does nothing at the moment, but maybe in the future will do something
95
+ }
96
+
97
+ /**
98
+ * @param FW_Access_Key $access_key
99
+ * @internal
100
+ * This must be called right after an instance of option type has been created
101
+ * and was added to the registered array, so it is available through
102
+ * fw()->backend->option_type($this->get_type())
103
+ */
104
+ final public function _call_init($access_key)
105
+ {
106
+ if ($access_key->get_key() !== 'fw_backend') {
107
+ trigger_error('Method call not allowed', E_USER_ERROR);
108
+ }
109
 
110
  if (method_exists($this, '_init')) {
111
  $this->_init();
framework/extensions/blog/class-fw-extension-blog.php CHANGED
@@ -33,8 +33,6 @@ class FW_Extension_Blog extends FW_Extension {
33
  return;
34
  }
35
 
36
- $wp_post_types[ $p ]->has_archive = true;
37
-
38
  $wp_post_types[ $p ]->labels->name = __( 'Blog', 'fw' );
39
  $wp_post_types[ $p ]->labels->singular_name = __( 'Blog', 'fw' );
40
  $wp_post_types[ $p ]->labels->add_new = __( 'Add blog post', 'fw' );
33
  return;
34
  }
35
 
 
 
36
  $wp_post_types[ $p ]->labels->name = __( 'Blog', 'fw' );
37
  $wp_post_types[ $p ]->labels->singular_name = __( 'Blog', 'fw' );
38
  $wp_post_types[ $p ]->labels->add_new = __( 'Add blog post', 'fw' );
framework/extensions/blog/manifest.php CHANGED
@@ -6,7 +6,7 @@ $manifest = array();
6
 
7
  $manifest['name'] = __( 'Blog Posts', 'fw' );
8
  $manifest['description'] = __( 'Blog Posts', 'fw' );
9
- $manifest['version'] = '1.0.0';
10
  $manifest['display'] = false;
11
  $manifest['standalone'] = true;
12
 
6
 
7
  $manifest['name'] = __( 'Blog Posts', 'fw' );
8
  $manifest['description'] = __( 'Blog Posts', 'fw' );
9
+ $manifest['version'] = '1.0.1';
10
  $manifest['display'] = false;
11
  $manifest['standalone'] = true;
12
 
framework/extensions/update/extensions/github-update/class-fw-extension-github-update.php CHANGED
@@ -68,7 +68,7 @@ class FW_Extension_Github_Update extends FW_Ext_Update_Service
68
  $http = new WP_Http();
69
 
70
  $response = $http->get(
71
- $this->get_github_api_url('/repos/'. $user_slash_repo .'/releases')
72
  );
73
 
74
  unset($http);
@@ -112,18 +112,18 @@ class FW_Extension_Github_Update extends FW_Ext_Update_Service
112
  }
113
  }
114
 
115
- $releases = json_decode($response['body'], true);
116
 
117
  unset($response);
118
 
119
- if (empty($releases)) {
120
  return new WP_Error(
121
  'fw_ext_update_github_fetch_no_releases',
122
  sprintf(__('No releases found in repository "%s".', 'fw'), $user_slash_repo)
123
  );
124
  }
125
 
126
- return $releases[0]['tag_name'];
127
  }
128
 
129
  /**
@@ -215,7 +215,7 @@ class FW_Extension_Github_Update extends FW_Ext_Update_Service
215
  $http = new WP_Http();
216
 
217
  $response = $http->get(
218
- $this->get_github_api_url('/repos/'. $user_slash_repo .'/releases')
219
  );
220
 
221
  unset($http);
@@ -253,34 +253,16 @@ class FW_Extension_Github_Update extends FW_Ext_Update_Service
253
  }
254
  }
255
 
256
- $releases = json_decode($response['body'], true);
257
 
258
  unset($response);
259
 
260
- if (empty($releases)) {
261
- return new WP_Error(
262
- 'fw_ext_update_github_download_no_releases',
263
- sprintf(
264
- __('%s github repository "%s" has no releases.', 'fw'),
265
- $title, $user_slash_repo
266
- )
267
- );
268
- }
269
-
270
- $release = false;
271
-
272
- foreach ($releases as $_release) {
273
- if ($_release['tag_name'] === $version) {
274
- $release = $_release;
275
- }
276
- }
277
-
278
  if (empty($release)) {
279
  return new WP_Error(
280
- 'fw_ext_update_github_download_not_existing_release',
281
  sprintf(
282
- __('%s release "%s" does not exist.', 'fw'),
283
- $title, $version
284
  )
285
  );
286
  }
68
  $http = new WP_Http();
69
 
70
  $response = $http->get(
71
+ $this->get_github_api_url('/repos/'. $user_slash_repo .'/releases/latest')
72
  );
73
 
74
  unset($http);
112
  }
113
  }
114
 
115
+ $release = json_decode($response['body'], true);
116
 
117
  unset($response);
118
 
119
+ if (empty($release)) {
120
  return new WP_Error(
121
  'fw_ext_update_github_fetch_no_releases',
122
  sprintf(__('No releases found in repository "%s".', 'fw'), $user_slash_repo)
123
  );
124
  }
125
 
126
+ return $release['tag_name'];
127
  }
128
 
129
  /**
215
  $http = new WP_Http();
216
 
217
  $response = $http->get(
218
+ $this->get_github_api_url('/repos/'. $user_slash_repo .'/releases/tags/'. $version)
219
  );
220
 
221
  unset($http);
253
  }
254
  }
255
 
256
+ $release = json_decode($response['body'], true);
257
 
258
  unset($response);
259
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  if (empty($release)) {
261
  return new WP_Error(
262
+ 'fw_ext_update_github_download_no_release',
263
  sprintf(
264
+ __('%s github repository "%s" does not have the "%s" release.', 'fw'),
265
+ $title, $user_slash_repo, $version
266
  )
267
  );
268
  }
framework/extensions/update/manifest.php CHANGED
@@ -6,5 +6,5 @@ $manifest['name'] = __('Update', 'fw');
6
  $manifest['description'] = __('Keep you framework, extensions and theme up to date.', 'fw');
7
  $manifest['standalone'] = true;
8
 
9
- $manifest['version'] = '1.0.6';
10
  $manifest['github_update'] = 'ThemeFuse/Unyson-Update-Extension';
6
  $manifest['description'] = __('Keep you framework, extensions and theme up to date.', 'fw');
7
  $manifest['standalone'] = true;
8
 
9
+ $manifest['version'] = '1.0.7';
10
  $manifest['github_update'] = 'ThemeFuse/Unyson-Update-Extension';
framework/helpers/database.php CHANGED
@@ -118,6 +118,8 @@
118
  }
119
  }
120
 
 
 
121
  $sub_keys = explode('/', $option_id);
122
  $base_key = array_shift($sub_keys);
123
 
@@ -153,7 +155,12 @@
153
  * if $option_id is 'hello'
154
  * $option_id_keys will be array()
155
  */
156
- $sub_keys
 
 
 
 
 
157
  );
158
  }
159
  }
118
  }
119
  }
120
 
121
+ $old_value = fw_get_db_post_option($post_id, $option_id);
122
+
123
  $sub_keys = explode('/', $option_id);
124
  $base_key = array_shift($sub_keys);
125
 
155
  * if $option_id is 'hello'
156
  * $option_id_keys will be array()
157
  */
158
+ $sub_keys,
159
+ /**
160
+ * Old post option(s) value
161
+ * @since 2.3.3
162
+ */
163
+ $old_value
164
  );
165
  }
166
  }
framework/helpers/general.php CHANGED
@@ -1221,3 +1221,53 @@ function fw_make_stylesheet_portable($href, $contents = null) {
1221
 
1222
  return $contents;
1223
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1221
 
1222
  return $contents;
1223
  }
1224
+
1225
+ /**
1226
+ * Return all images sizes register by add_image_size() merged with
1227
+ * WordPress default image sizes.
1228
+ * @link https://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes
1229
+ * @param string $size
1230
+ *
1231
+ * @return array|bool
1232
+ */
1233
+ function fw_get_image_sizes( $size = '' ) {
1234
+
1235
+ global $_wp_additional_image_sizes;
1236
+
1237
+ $sizes = array();
1238
+ $get_intermediate_image_sizes = get_intermediate_image_sizes();
1239
+
1240
+ // Create the full array with sizes and crop info
1241
+ foreach( $get_intermediate_image_sizes as $_size ) {
1242
+
1243
+ if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) {
1244
+
1245
+ $sizes[ $_size ]['width'] = get_option( $_size . '_size_w' );
1246
+ $sizes[ $_size ]['height'] = get_option( $_size . '_size_h' );
1247
+ $sizes[ $_size ]['crop'] = (bool) get_option( $_size . '_crop' );
1248
+
1249
+ } elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
1250
+
1251
+ $sizes[ $_size ] = array(
1252
+ 'width' => $_wp_additional_image_sizes[ $_size ]['width'],
1253
+ 'height' => $_wp_additional_image_sizes[ $_size ]['height'],
1254
+ 'crop' => $_wp_additional_image_sizes[ $_size ]['crop']
1255
+ );
1256
+
1257
+ }
1258
+
1259
+ }
1260
+
1261
+ // Get only 1 size if found
1262
+ if ( $size ) {
1263
+
1264
+ if( isset( $sizes[ $size ] ) ) {
1265
+ return $sizes[ $size ];
1266
+ } else {
1267
+ return false;
1268
+ }
1269
+
1270
+ }
1271
+
1272
+ return $sizes;
1273
+ }
framework/includes/option-types/addable-box/class-fw-option-type-addable-box.php CHANGED
@@ -156,10 +156,39 @@ class FW_Option_Type_Addable_Box extends FW_Option_Type
156
  {
157
  return array(
158
  'value' => array(),
159
- 'box-controls' => array(),
 
 
 
 
 
 
 
 
 
160
  'box-options' => array(),
 
 
 
161
  'limit' => 0,
 
 
 
 
 
 
 
 
 
162
  'template' => '',
 
 
 
 
 
 
 
 
163
  );
164
  }
165
  }
156
  {
157
  return array(
158
  'value' => array(),
159
+ /**
160
+ * Buttons on box head ( near delete button X )
161
+ *
162
+ * On control click will be triggered a custom event 'fw:option-type:addable-box:control:click'
163
+ * on wrapper div (the one that has `.fw-option-type-addable-box` class)
164
+ * data about control will be in event data
165
+ */
166
+ 'box-controls' => array(
167
+ // 'control_id' => '<small class="dashicons dashicons-..." title="Some action"></small>'
168
+ ),
169
  'box-options' => array(),
170
+ /**
171
+ * Limit boxes that can be added
172
+ */
173
  'limit' => 0,
174
+ /**
175
+ * Box title backbonejs template
176
+ * All box options are available as variables {{- box_option_id }}
177
+ *
178
+ * Note: Ids with - (instead of underscore _ ) will throw errors
179
+ * because 'box-option-id' can't be converted to variable name
180
+ *
181
+ * Example: 'Hello {{- box_option_id }}'
182
+ */
183
  'template' => '',
184
+ 'add-button-text' => __('Add', 'fw'),
185
+ /**
186
+ * Makes the boxes sortable
187
+ *
188
+ * You can disable this in case the boxes order doesn't matter,
189
+ * to not confuse the user that if changing the order will affect something.
190
+ */
191
+ 'sortable' => true,
192
  );
193
  }
194
  }
framework/includes/option-types/addable-box/static/js/scripts.js CHANGED
@@ -28,6 +28,10 @@ jQuery(document).ready(function ($) {
28
  // happens when sortable was not initialized before
29
  }
30
 
 
 
 
 
31
  var isMobile = $(document.body).hasClass('mobile');
32
 
33
  $boxes.sortable({
@@ -77,7 +81,7 @@ jQuery(document).ready(function ($) {
77
  default:
78
  // custom control. trigger event for others to handle this
79
  $control.closest(optionTypeClass).trigger(
80
- methods.makeEventName('.fw-options-tabs-wrapper .fw-options-tabs-contents'), {
81
  controlId: controlId,
82
  $control: $control,
83
  box: methods.getBoxDataForEvent($control.closest('.box'))
@@ -239,12 +243,13 @@ jQuery(document).ready(function ($) {
239
  }, 300);
240
  }
241
 
242
- $boxes.append(
243
- $newBox
244
- );
245
 
246
  methods.initControls($newBox);
247
- methods.reInitSortable($boxes);
 
 
 
248
 
249
  // remove focus form "Add" button to prevent pressing space/enter to add easy many boxes
250
  $newBox.find('input,select,textarea').first().focus();
28
  // happens when sortable was not initialized before
29
  }
30
 
31
+ if (!$boxes.first().closest(optionTypeClass).hasClass('is-sortable')) {
32
+ return false;
33
+ }
34
+
35
  var isMobile = $(document.body).hasClass('mobile');
36
 
37
  $boxes.sortable({
81
  default:
82
  // custom control. trigger event for others to handle this
83
  $control.closest(optionTypeClass).trigger(
84
+ methods.makeEventName('control:click'), {
85
  controlId: controlId,
86
  $control: $control,
87
  box: methods.getBoxDataForEvent($control.closest('.box'))
243
  }, 300);
244
  }
245
 
246
+ $boxes.append($newBox);
 
 
247
 
248
  methods.initControls($newBox);
249
+
250
+ if ($option.hasClass('is-sortable')) {
251
+ methods.reInitSortable($boxes);
252
+ }
253
 
254
  // remove focus form "Add" button to prevent pressing space/enter to add easy many boxes
255
  $newBox.find('input,select,textarea').first().focus();
framework/includes/option-types/addable-box/view.php CHANGED
@@ -21,6 +21,10 @@ unset($attr['value']);
21
  </small>
22
  <?php $controls_html = ob_get_clean();
23
  }
 
 
 
 
24
  ?>
25
  <div <?php echo fw_attr_to_html($attr) ?>>
26
  <?php $i = 0; ?>
@@ -91,7 +95,7 @@ unset($attr['value']);
91
  'data-increment' => ++$i,
92
  'data-increment-placeholder' => $increment_placeholder,
93
  'data-limit' => intval($option['limit']),
94
- ), __('Add', 'fw'));
95
  ?>
96
  </div>
97
  </div>
21
  </small>
22
  <?php $controls_html = ob_get_clean();
23
  }
24
+
25
+ if ($option['sortable']) {
26
+ $attr['class'] .= ' is-sortable';
27
+ }
28
  ?>
29
  <div <?php echo fw_attr_to_html($attr) ?>>
30
  <?php $i = 0; ?>
95
  'data-increment' => ++$i,
96
  'data-increment-placeholder' => $increment_placeholder,
97
  'data-limit' => intval($option['limit']),
98
+ ), fw_htmlspecialchars($option['add-button-text']));
99
  ?>
100
  </div>
101
  </div>
framework/includes/option-types/addable-option/class-fw-option-type-addable-option.php CHANGED
@@ -16,7 +16,15 @@ class FW_Option_Type_Addable_Option extends FW_Option_Type
16
  'value' => array(),
17
  'option' => array(
18
  'type' => 'text',
19
- )
 
 
 
 
 
 
 
 
20
  );
21
  }
22
 
16
  'value' => array(),
17
  'option' => array(
18
  'type' => 'text',
19
+ ),
20
+ 'add-button-text' => __('Add', 'fw'),
21
+ /**
22
+ * Makes the options sortable
23
+ *
24
+ * You can disable this in case the options order doesn't matter,
25
+ * to not confuse the user that if changing the order will affect something.
26
+ */
27
+ 'sortable' => true,
28
  );
29
  }
30
 
framework/includes/option-types/addable-option/static/css/styles.css CHANGED
@@ -42,6 +42,9 @@ body.rtl #edittag .form-table .fw-option-type-addable-option .fw-option-type-add
42
  padding-top: 4px;
43
  }
44
 
 
 
 
45
 
46
  .fw-option-type-addable-option tr.fw-option-type-addable-option-option.ui-sortable-helper {
47
  display: block;
42
  padding-top: 4px;
43
  }
44
 
45
+ .fw-option-type-addable-option:not(.is-sortable) .fw-option-type-addable-option-option td.td-move {
46
+ display: none;
47
+ }
48
 
49
  .fw-option-type-addable-option tr.fw-option-type-addable-option-option.ui-sortable-helper {
50
  display: block;
framework/includes/option-types/addable-option/static/js/scripts.js CHANGED
@@ -8,6 +8,10 @@ jQuery(document).ready(function ($) {
8
  // happens when sortable was not initialized before
9
  }
10
 
 
 
 
 
11
  var isMobile = $(document.body).hasClass('mobile');
12
 
13
  $options.sortable({
8
  // happens when sortable was not initialized before
9
  }
10
 
11
+ if (!$options.first().closest(optionClass).hasClass('is-sortable')) {
12
+ return false;
13
+ }
14
+
15
  var isMobile = $(document.body).hasClass('mobile');
16
 
17
  $options.sortable({
framework/includes/option-types/addable-option/view.php CHANGED
@@ -11,6 +11,10 @@ $attr = $option['attr'];
11
  unset($attr['name']);
12
  unset($attr['value']);
13
 
 
 
 
 
14
  ?>
15
  <div <?php echo fw_attr_to_html($attr) ?>>
16
  <table class="fw-option-type-addable-option-options" width="100%" cellpadding="0" cellspacing="0" border="0">
@@ -87,7 +91,7 @@ unset($attr['value']);
87
  'onclick' => 'return false;',
88
  'data-increment' => $i,
89
  'data-increment-placeholder' => $increment_placeholder,
90
- ), __('Add', 'fw'));
91
  ?>
92
  </div>
93
  </div>
11
  unset($attr['name']);
12
  unset($attr['value']);
13
 
14
+ if ($option['sortable']) {
15
+ $attr['class'] .= ' is-sortable';
16
+ }
17
+
18
  ?>
19
  <div <?php echo fw_attr_to_html($attr) ?>>
20
  <table class="fw-option-type-addable-option-options" width="100%" cellpadding="0" cellspacing="0" border="0">
91
  'onclick' => 'return false;',
92
  'data-increment' => $i,
93
  'data-increment-placeholder' => $increment_placeholder,
94
+ ), fw_htmlspecialchars($option['add-button-text']));
95
  ?>
96
  </div>
97
  </div>
framework/includes/option-types/addable-popup/class-fw-option-type-addable-popup.php CHANGED
@@ -141,7 +141,15 @@ class FW_Option_Type_Addable_Popup extends FW_Option_Type
141
  'template' => '',
142
  'popup-title' => null,
143
  'limit' => 0,
144
- 'size' => 'small' // small, medium, large
 
 
 
 
 
 
 
 
145
  );
146
  }
147
 
141
  'template' => '',
142
  'popup-title' => null,
143
  'limit' => 0,
144
+ 'size' => 'small', // small, medium, large
145
+ 'add-button-text' => __('Add', 'fw'),
146
+ /**
147
+ * Makes the items sortable
148
+ *
149
+ * You can disable this in case the items order doesn't matter,
150
+ * to not confuse the user that if changing the order will affect something.
151
+ */
152
+ 'sortable' => true,
153
  );
154
  }
155
 
framework/includes/option-types/addable-popup/static/css/styles.css CHANGED
@@ -35,4 +35,12 @@
35
 
36
  .fw-option-type-addable-popup .item.default{
37
  display: none;
 
 
 
 
 
 
 
 
38
  }
35
 
36
  .fw-option-type-addable-popup .item.default{
37
  display: none;
38
+ }
39
+
40
+ .fw-option-type-addable-popup:not(.is-sortable) .sort-item {
41
+ display: none;
42
+ }
43
+
44
+ .fw-option-type-addable-popup:not(.is-sortable) .item .content {
45
+ padding-left: 15px;
46
  }
framework/includes/option-types/addable-popup/static/js/addable-popup.js CHANGED
@@ -49,6 +49,10 @@
49
  utils.initSortable();
50
  },
51
  initSortable: function () {
 
 
 
 
52
  nodes.$itemsWrapper.sortable({
53
  items: '.item:not(.default)',
54
  cursor: 'move',
@@ -57,6 +61,14 @@
57
  axis: 'y',
58
  update: function(){
59
  nodes.$optionWrapper.trigger('change'); // for customizer
 
 
 
 
 
 
 
 
60
  }
61
  });
62
  },
49
  utils.initSortable();
50
  },
51
  initSortable: function () {
52
+ if (!nodes.$optionWrapper.hasClass('is-sortable')) {
53
+ return false;
54
+ }
55
+
56
  nodes.$itemsWrapper.sortable({
57
  items: '.item:not(.default)',
58
  cursor: 'move',
61
  axis: 'y',
62
  update: function(){
63
  nodes.$optionWrapper.trigger('change'); // for customizer
64
+ },
65
+ start: function(e, ui){
66
+ // Update the height of the placeholder to match the moving item.
67
+ {
68
+ var height = ui.item.outerHeight() - 1;
69
+
70
+ ui.placeholder.height(height);
71
+ }
72
  }
73
  });
74
  },
framework/includes/option-types/addable-popup/views/view.php CHANGED
@@ -6,12 +6,17 @@
6
  * @var string $sortable_image url
7
  */
8
  $attr = $option['attr'];
 
 
 
 
 
 
9
 
10
  // must contain characters that will remain the same after htmlspecialchars()
11
  $increment_placeholder = '###-addable-popup-increment-'. fw_rand_md5() .'-###';
12
  ?>
13
  <div <?php echo fw_attr_to_html($attr); ?>>
14
-
15
  <div class="items-wrapper">
16
  <div class="item default">
17
  <div class="input-wrapper">
@@ -47,7 +52,7 @@ $increment_placeholder = '###-addable-popup-increment-'. fw_rand_md5() .'-###';
47
  'class' => 'button add-new-item',
48
  'onclick' => 'return false;',
49
  'data-increment-placeholder' => $increment_placeholder,
50
- ), __('Add', 'fw'));
51
  ?>
52
  </div>
53
 
6
  * @var string $sortable_image url
7
  */
8
  $attr = $option['attr'];
9
+ unset($attr['name']);
10
+ unset($attr['value']);
11
+
12
+ if ($option['sortable']) {
13
+ $attr['class'] .= ' is-sortable';
14
+ }
15
 
16
  // must contain characters that will remain the same after htmlspecialchars()
17
  $increment_placeholder = '###-addable-popup-increment-'. fw_rand_md5() .'-###';
18
  ?>
19
  <div <?php echo fw_attr_to_html($attr); ?>>
 
20
  <div class="items-wrapper">
21
  <div class="item default">
22
  <div class="input-wrapper">
52
  'class' => 'button add-new-item',
53
  'onclick' => 'return false;',
54
  'data-increment-placeholder' => $increment_placeholder,
55
+ ), fw_htmlspecialchars($option['add-button-text']));
56
  ?>
57
  </div>
58
 
framework/includes/option-types/background-image/static/css/styles.css CHANGED
@@ -1,10 +1,10 @@
1
- .fw-option-type-background-image .type .fw-option-type-radio div {
2
  display: inline-block;
3
  margin-left: 15px;
4
  }
5
 
6
- .fw-option-type-background-image .predefined,
7
- .fw-option-type-background-image .custom {
8
  margin-top: 15px;
9
  }
10
 
@@ -12,3 +12,12 @@
12
  margin: 0 0 9px -15px;
13
  font-size: 14px;
14
  }
 
 
 
 
 
 
 
 
 
1
+ .fw-option-type-background-image > .type .fw-option-type-radio div {
2
  display: inline-block;
3
  margin-left: 15px;
4
  }
5
 
6
+ .fw-option-type-background-image > .predefined,
7
+ .fw-option-type-background-image > .custom {
8
  margin-top: 15px;
9
  }
10
 
12
  margin: 0 0 9px -15px;
13
  font-size: 14px;
14
  }
15
+
16
+ .fw-option-type-background-image.no-choices > .type {
17
+ display: none;
18
+ }
19
+
20
+ .fw-option-type-background-image.no-choices > .predefined,
21
+ .fw-option-type-background-image.no-choices > .custom {
22
+ margin-top: 0;
23
+ }
framework/includes/option-types/background-image/view.php CHANGED
@@ -20,9 +20,13 @@ if ( empty( $option['choices'] ) ) {
20
  $option['choices'] = array();
21
  }
22
 
 
 
 
 
23
  ?>
24
  <div <?php echo fw_attr_to_html($wrapper_attr) ?>>
25
- <div class="type" <?php if (empty( $option['choices'] )): ?>style="display: none;"<?php endif; ?>>
26
  <?php
27
  echo fw()->backend->option_type( 'radio' )->render(
28
  'type',
20
  $option['choices'] = array();
21
  }
22
 
23
+ if (empty( $option['choices'] )) {
24
+ $wrapper_attr['class'] .= ' no-choices';
25
+ }
26
+
27
  ?>
28
  <div <?php echo fw_attr_to_html($wrapper_attr) ?>>
29
+ <div class="type">
30
  <?php
31
  echo fw()->backend->option_type( 'radio' )->render(
32
  'type',
framework/includes/option-types/init.php CHANGED
@@ -28,6 +28,7 @@ require $dir . '/popup/class-fw-option-type-popup.php';
28
  require $dir . '/slider/class-fw-option-type-slider.php';
29
  require $dir . '/range-slider/class-fw-option-type-range-slider.php';
30
  require $dir . '/rgba-color-picker/class-fw-option-type-rgba-color-picker.php';
 
31
  if (!class_exists('FW_Option_Type_Multi_Select')) {
32
  require $dir . '/multi-select/class-fw-option-type-multi-select.php';
33
  }
28
  require $dir . '/slider/class-fw-option-type-slider.php';
29
  require $dir . '/range-slider/class-fw-option-type-range-slider.php';
30
  require $dir . '/rgba-color-picker/class-fw-option-type-rgba-color-picker.php';
31
+ require $dir . '/typography-v2/class-fw-option-type-typography-v2.php';
32
  if (!class_exists('FW_Option_Type_Multi_Select')) {
33
  require $dir . '/multi-select/class-fw-option-type-multi-select.php';
34
  }
framework/includes/option-types/multi-picker/static/css/multi-picker.css CHANGED
@@ -1,7 +1,6 @@
1
  .fw-backend-option-type-multi-picker {
2
  padding-left: 0;
3
  padding-right: 0;
4
- padding-bottom: 0;
5
  }
6
 
7
  /* hide last inner option border */
@@ -32,6 +31,10 @@
32
  animation-duration: .5s;
33
  }
34
 
 
 
 
 
35
  .fw-option-type-multi-picker.fw-option-type-multi-picker-with-borders.has-choice > .picker-group,
36
  .fw-option-type-multi-picker.fw-option-type-multi-picker-with-borders > .choice-group > .fw-backend-option {
37
  border-bottom-width: 1px;
@@ -43,11 +46,8 @@
43
  }
44
 
45
  .fw-option-type-multi-picker > .picker-group > .fw-backend-option {
46
- padding-top: 0;
47
- }
48
-
49
- .fw-option-type-multi-picker.fw-option-type-multi-picker-without-borders.has-choice > .picker-group > .fw-backend-option {
50
- padding-bottom: 0;
51
  }
52
 
53
  .fw-backend-option-type-multi-picker.fw-backend-option-design-customizer .fw-option-type-multi-picker > .picker-group {
1
  .fw-backend-option-type-multi-picker {
2
  padding-left: 0;
3
  padding-right: 0;
 
4
  }
5
 
6
  /* hide last inner option border */
31
  animation-duration: .5s;
32
  }
33
 
34
+ .fw-option-type-multi-picker > .choice-group > .fw-backend-option > .fw-backend-option-input > .fw-inner > .fw-inner-option > .fw-option-type-multi > .fw-backend-option {
35
+ padding-bottom: 0; /* prevent backend-option double padding */
36
+ }
37
+
38
  .fw-option-type-multi-picker.fw-option-type-multi-picker-with-borders.has-choice > .picker-group,
39
  .fw-option-type-multi-picker.fw-option-type-multi-picker-with-borders > .choice-group > .fw-backend-option {
40
  border-bottom-width: 1px;
46
  }
47
 
48
  .fw-option-type-multi-picker > .picker-group > .fw-backend-option {
49
+ padding-top: 0; /* prevent backend-option double padding */
50
+ padding-bottom: 0; /* prevent backend-option double padding */
 
 
 
51
  }
52
 
53
  .fw-backend-option-type-multi-picker.fw-backend-option-design-customizer .fw-option-type-multi-picker > .picker-group {
framework/includes/option-types/range-slider/class-fw-option-type-range-slider.php CHANGED
@@ -55,40 +55,47 @@ class FW_Option_Type_Range_Slider extends FW_Option_Type {
55
  $option['properties']['to'] = ( isset( $data['value']['to'] ) ) ? $data['value']['to'] : $option['value']['to'];
56
 
57
  if ( isset( $option['properties']['values'] ) && is_array( $option['properties']['values'] ) ) {
58
- $option['properties']['from'] = array_search( $option['properties']['from'], $option['properties']['values'] );
59
- $option['properties']['to'] = array_search( $option['properties']['to'], $option['properties']['values'] );
 
 
60
  }
61
 
 
 
62
  $option['attr']['data-fw-irs-options'] = json_encode(
63
- $this->default_properties($option['properties'])
64
  );
65
 
66
- return fw_render_view( fw_get_framework_directory( '/includes/option-types/' . $this->get_type() . '/view.php' ), array(
67
- 'id' => $id,
68
- 'option' => $option,
69
- 'data' => $data,
70
- 'value' => implode(';', (array)$data['value'])
71
- ) );
 
72
  }
73
 
74
- private function default_properties($properties = array()) {
75
- return array_merge(array(
76
- 'min' => 0,
77
- 'max' => 100,
78
  'step' => 1,
79
- ), $properties);
80
  }
81
 
82
  /**
83
  * @internal
84
  */
85
  protected function _get_defaults() {
 
 
86
  return array(
87
- 'value' => array(
88
- 'from' => 0,
89
- 'to' => 0,
90
  ),
91
- 'properties' => $this->default_properties(), // https://github.com/IonDen/ion.rangeSlider#settings
92
  );
93
  }
94
 
@@ -96,18 +103,48 @@ class FW_Option_Type_Range_Slider extends FW_Option_Type {
96
  * @internal
97
  */
98
  protected function _get_value_from_input( $option, $input_value ) {
99
- if (is_null($input_value)) {
100
  return $option['value'];
101
  } else {
102
- $input_values = ( isset( $option['properties']['values'] ) && is_array( $option['properties']['values'] ) ) ? explode( ';', $input_value ) : array_map( 'intval', explode( ';', $input_value ) );
 
103
 
104
  return array(
105
  'from' => $input_values[0],
106
- 'to' => $input_values[1],
107
  );
108
  }
109
  }
110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  }
112
 
113
  FW_Option_Type::register( 'FW_Option_Type_Range_Slider' );
55
  $option['properties']['to'] = ( isset( $data['value']['to'] ) ) ? $data['value']['to'] : $option['value']['to'];
56
 
57
  if ( isset( $option['properties']['values'] ) && is_array( $option['properties']['values'] ) ) {
58
+ $option['properties']['from'] = array_search( $option['properties']['from'],
59
+ $option['properties']['values'] );
60
+ $option['properties']['to'] = array_search( $option['properties']['to'],
61
+ $option['properties']['values'] );
62
  }
63
 
64
+ $option = $this->update_option( $option );
65
+
66
  $option['attr']['data-fw-irs-options'] = json_encode(
67
+ $this->default_properties( $option['properties'] )
68
  );
69
 
70
+ return fw_render_view( fw_get_framework_directory( '/includes/option-types/' . $this->get_type() . '/view.php' ),
71
+ array(
72
+ 'id' => $id,
73
+ 'option' => $option,
74
+ 'data' => $data,
75
+ 'value' => implode( ';', (array) $data['value'] )
76
+ ) );
77
  }
78
 
79
+ private function default_properties( $properties = array() ) {
80
+ return array_merge( array(
81
+ 'min' => 0,
82
+ 'max' => 100,
83
  'step' => 1,
84
+ ), $properties );
85
  }
86
 
87
  /**
88
  * @internal
89
  */
90
  protected function _get_defaults() {
91
+ $defaults = $this->default_properties();
92
+
93
  return array(
94
+ 'value' => array(
95
+ 'from' => $defaults['min'],
96
+ 'to' => $defaults['max'],
97
  ),
98
+ 'properties' => $defaults, // https://github.com/IonDen/ion.rangeSlider#settings
99
  );
100
  }
101
 
103
  * @internal
104
  */
105
  protected function _get_value_from_input( $option, $input_value ) {
106
+ if ( is_null( $input_value ) ) {
107
  return $option['value'];
108
  } else {
109
+ $input_values = ( isset( $option['properties']['values'] ) && is_array( $option['properties']['values'] ) ) ? explode( ';',
110
+ $input_value ) : array_map( 'intval', explode( ';', $input_value ) );
111
 
112
  return array(
113
  'from' => $input_values[0],
114
+ 'to' => $input_values[1],
115
  );
116
  }
117
  }
118
 
119
+ /**
120
+ * Used to update option from and to value to be equal to max and min in case they are not defined
121
+ *
122
+ * @param array $option
123
+ *
124
+ * @return array
125
+ */
126
+ private function update_option( $option ) {
127
+ if (
128
+ $option['value']['from'] < $option['properties']['min']
129
+ ||
130
+ $option['value']['from'] > $option['properties']['max']
131
+ ) {
132
+ $option['value']['from'] = $option['properties']['min'];
133
+ $option['properties']['from'] = $option['properties']['min'];
134
+ }
135
+
136
+ if (
137
+ $option['value']['to'] > $option['properties']['max']
138
+ ||
139
+ $option['value']['to'] < $option['properties']['min']
140
+ ) {
141
+ $option['value']['to'] = $option['properties']['max'];
142
+ $option['properties']['to'] = $option['properties']['max'];
143
+ }
144
+
145
+ return $option;
146
+ }
147
+
148
  }
149
 
150
  FW_Option_Type::register( 'FW_Option_Type_Range_Slider' );
framework/includes/option-types/simple.php CHANGED
@@ -390,6 +390,25 @@ class FW_Option_Type_Checkbox extends FW_Option_Type {
390
  * @internal
391
  */
392
  protected function _render( $id, $option, $data ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
393
  $option['value'] = (bool) $data['value'];
394
 
395
  unset( $option['attr']['value'] );
@@ -479,16 +498,17 @@ class FW_Option_Type_Checkboxes extends FW_Option_Type {
479
  foreach ( $option['choices'] as $value => $text ) {
480
  $choice_id = $option['attr']['id'] . '-' . $value;
481
 
482
- $html .= '<div>' .
483
- '<label for="' . esc_attr( $choice_id ) . '">' .
484
- '<input type="checkbox" ' .
485
- 'name="' . esc_attr( $option['attr']['name'] ) . '[' . esc_attr( $value ) . ']" ' .
486
- 'value="true" ' .
487
- 'id="' . esc_attr( $choice_id ) . '" ' .
488
- ( isset( $option['value'][ $value ] ) && $option['value'][ $value ] ? 'checked="checked" ' : '' ) .
489
- '> ' . htmlspecialchars( $text, ENT_COMPAT, 'UTF-8' ) .
490
- '</label>' .
491
- '</div>';
 
492
  }
493
 
494
  $html .= '</div>';
@@ -539,8 +559,15 @@ class FW_Option_Type_Checkboxes extends FW_Option_Type {
539
  protected function _get_defaults() {
540
  return array(
541
  'inline' => false, // Set this parameter to true in case you want all checkbox inputs to be rendered inline
542
- 'value' => array(),
543
- 'choices' => array()
 
 
 
 
 
 
 
544
  );
545
  }
546
  }
@@ -587,16 +614,17 @@ class FW_Option_Type_Radio extends FW_Option_Type {
587
  foreach ( $option['choices'] as $value => $text ) {
588
  $choice_id = $option['attr']['id'] . '-' . $value;
589
 
590
- $html .= '<div>' .
591
- '<label for="' . esc_attr( $choice_id ) . '">' .
592
- '<input type="radio" ' .
593
- 'name="' . esc_attr( $option['attr']['name'] ) . '" ' .
594
- 'value="' . esc_attr( $value ) . '" ' .
595
- 'id="' . esc_attr( $choice_id ) . '" ' .
596
- ( $option['value'] == $value ? 'checked="checked" ' : '' ) .
597
- '> ' . htmlspecialchars( $text, ENT_COMPAT, 'UTF-8' ) .
598
- '</label>' .
599
- '</div>';
 
600
  }
601
 
602
  $html .= '</div>';
@@ -641,8 +669,13 @@ class FW_Option_Type_Radio extends FW_Option_Type {
641
  protected function _get_defaults() {
642
  return array(
643
  'inline' => false, // Set this parameter to true in case you want all radio inputs to be rendered inline
644
- 'value' => '',
645
- 'choices' => array()
 
 
 
 
 
646
  );
647
  }
648
  }
390
  * @internal
391
  */
392
  protected function _render( $id, $option, $data ) {
393
+ if (
394
+ defined('DOING_AJAX') && DOING_AJAX
395
+ &&
396
+ in_array($data['value'], array('false', 'true'))
397
+ ) {
398
+ /**
399
+ * This happens on fw.OptionsModal open/render
400
+ * When the checkbox is used by other option types
401
+ * then this script http://bit.ly/1QshDoS can't fix nested values
402
+ *
403
+ * Check if values is 'true' or 'false' then transform/fix it to boolean
404
+ */
405
+ if ($data['value'] === 'true') {
406
+ $data['value'] = true;
407
+ } else {
408
+ $data['value'] = false;
409
+ }
410
+ }
411
+
412
  $option['value'] = (bool) $data['value'];
413
 
414
  unset( $option['attr']['value'] );
498
  foreach ( $option['choices'] as $value => $text ) {
499
  $choice_id = $option['attr']['id'] . '-' . $value;
500
 
501
+ $html .=
502
+ '<div>' .
503
+ '<label for="' . esc_attr( $choice_id ) . '">' .
504
+ '<input type="checkbox" ' .
505
+ 'name="' . esc_attr( $option['attr']['name'] ) . '[' . esc_attr( $value ) . ']" ' .
506
+ 'value="true" ' .
507
+ 'id="' . esc_attr( $choice_id ) . '" ' .
508
+ ( isset( $option['value'][ $value ] ) && $option['value'][ $value ] ? 'checked="checked" ' : '' ) .
509
+ '> ' . htmlspecialchars( $text, ENT_COMPAT, 'UTF-8' ) .
510
+ '</label>' .
511
+ '</div>';
512
  }
513
 
514
  $html .= '</div>';
559
  protected function _get_defaults() {
560
  return array(
561
  'inline' => false, // Set this parameter to true in case you want all checkbox inputs to be rendered inline
562
+ 'value' => array(
563
+ // 'choice_id' => bool
564
+ ),
565
+ /**
566
+ * Avoid bool or int keys http://bit.ly/1cQgVzk
567
+ */
568
+ 'choices' => array(
569
+ // 'choice_id' => 'Choice Label'
570
+ ),
571
  );
572
  }
573
  }
614
  foreach ( $option['choices'] as $value => $text ) {
615
  $choice_id = $option['attr']['id'] . '-' . $value;
616
 
617
+ $html .=
618
+ '<div>' .
619
+ '<label for="' . esc_attr( $choice_id ) . '">' .
620
+ '<input type="radio" ' .
621
+ 'name="' . esc_attr( $option['attr']['name'] ) . '" ' .
622
+ 'value="' . esc_attr( $value ) . '" ' .
623
+ 'id="' . esc_attr( $choice_id ) . '" ' .
624
+ ( $option['value'] == $value ? 'checked="checked" ' : '' ) .
625
+ '> ' . htmlspecialchars( $text, ENT_COMPAT, 'UTF-8' ) .
626
+ '</label>' .
627
+ '</div>';
628
  }
629
 
630
  $html .= '</div>';
669
  protected function _get_defaults() {
670
  return array(
671
  'inline' => false, // Set this parameter to true in case you want all radio inputs to be rendered inline
672
+ 'value' => '', // 'choice_id'
673
+ /**
674
+ * Avoid bool or int keys http://bit.ly/1cQgVzk
675
+ */
676
+ 'choices' => array(
677
+ // 'choice_id' => 'Choice Label'
678
+ )
679
  );
680
  }
681
  }
framework/includes/option-types/slider/class-fw-option-type-slider.php CHANGED
@@ -94,9 +94,7 @@ class FW_Option_Type_Slider extends FW_Option_Type {
94
  if (is_null($input_value)) {
95
  return $option['value'];
96
  } else {
97
- $input_values = (isset($option['properties']['values']) && is_array($option['properties']['values'])) ? explode(';', $input_value) : array_map('intval', explode(';', $input_value));
98
-
99
- return $input_values[0];
100
  }
101
  }
102
 
94
  if (is_null($input_value)) {
95
  return $option['value'];
96
  } else {
97
+ return intval($input_value);
 
 
98
  }
99
  }
100
 
framework/includes/option-types/slider/static/js/scripts.js CHANGED
@@ -2,8 +2,7 @@
2
  var defaults = {
3
  onChange: function (data) {
4
  var from = (data.from_value) ? data.from_value : data.from;
5
- var to = (data.to_value) ? data.to_value : data.to;
6
- data.input.next('.fw-irs-range-slider-hidden-input').val(from + ';' + to);
7
  data.input.closest('.fw-option-type-slider').find('span span.irs-slider.single').html(from);
8
  },
9
  onStart: function (data) {
2
  var defaults = {
3
  onChange: function (data) {
4
  var from = (data.from_value) ? data.from_value : data.from;
5
+ data.input.next('.fw-irs-range-slider-hidden-input').val(from);
 
6
  data.input.closest('.fw-option-type-slider').find('span span.irs-slider.single').html(from);
7
  },
8
  onStart: function (data) {
framework/includes/option-types/switch/class-fw-option-type-switch.php CHANGED
@@ -74,6 +74,65 @@ class FW_Option_Type_Switch extends FW_Option_Type
74
  }
75
  }
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  if ($data['value'] === $option['right-choice']['value']) {
78
  // right choice means checked
79
  $input_attr['checked'] = 'checked';
74
  }
75
  }
76
 
77
+ if (
78
+ defined('DOING_AJAX') && DOING_AJAX
79
+ &&
80
+ in_array($data['value'], array('false', 'true'))
81
+ &&
82
+ // do not transform if there is an exact match with a choice
83
+ (
84
+ $option['left-choice']['value'] !== $data['value']
85
+ &&
86
+ $option['right-choice']['value'] !== $data['value']
87
+ )
88
+ ) {
89
+ /**
90
+ * This happens on fw.OptionsModal open/render
91
+ * When the switch is used by other option types
92
+ * then this script http://bit.ly/1QshDoS can't fix nested values
93
+ *
94
+ * Check if values is 'true' or 'false' and one of the choices values is a boolean that matches it
95
+ * then transform/fix it to boolean
96
+ */
97
+ if (
98
+ $data['value'] === 'true'
99
+ &&
100
+ (
101
+ (
102
+ is_bool($option['right-choice']['value'])
103
+ &&
104
+ $option['right-choice']['value'] === true
105
+ )
106
+ ||
107
+ (
108
+ is_bool($option['left-choice']['value'])
109
+ &&
110
+ $option['left-choice']['value'] === true
111
+ )
112
+ )
113
+ ) {
114
+ $data['value'] = true;
115
+ } elseif (
116
+ $data['value'] === 'false'
117
+ &&
118
+ (
119
+ (
120
+ is_bool($option['right-choice']['value'])
121
+ &&
122
+ $option['right-choice']['value'] === false
123
+ )
124
+ ||
125
+ (
126
+ is_bool($option['left-choice']['value'])
127
+ &&
128
+ $option['left-choice']['value'] === false
129
+ )
130
+ )
131
+ ) {
132
+ $data['value'] = false;
133
+ }
134
+ }
135
+
136
  if ($data['value'] === $option['right-choice']['value']) {
137
  // right choice means checked
138
  $input_attr['checked'] = 'checked';
framework/includes/option-types/typography-v2/class-fw-option-type-typography-v2.php ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if ( ! defined( 'FW' ) ) {
2
+ die( 'Forbidden' );
3
+ }
4
+
5
+ /**
6
+ * Typography
7
+ */
8
+ class FW_Option_Type_Typography_v2 extends FW_Option_Type {
9
+ /*
10
+ * Allowed fonts
11
+ */
12
+ private $fonts;
13
+
14
+ public function _get_backend_width_type() {
15
+ return 'full';
16
+ }
17
+
18
+ /**
19
+ * @internal
20
+ * {@inheritdoc}
21
+ */
22
+ protected function _enqueue_static( $id, $option, $data ) {
23
+ wp_enqueue_style(
24
+ 'fw-option-' . $this->get_type(),
25
+ fw_get_framework_directory_uri( '/includes/option-types/' . $this->get_type() . '/static/css/styles.css' ),
26
+ array( 'fw-selectize' ),
27
+ fw()->manifest->get_version()
28
+ );
29
+
30
+ fw()->backend->option_type( 'color-picker' )->enqueue_static();
31
+
32
+ wp_enqueue_script(
33
+ 'fw-option-' . $this->get_type(),
34
+ fw_get_framework_directory_uri( '/includes/option-types/' . $this->get_type() . '/static/js/scripts.js' ),
35
+ array( 'jquery', 'underscore', 'fw', 'fw-selectize' ),
36
+ fw()->manifest->get_version()
37
+ );
38
+
39
+ $fw_typography_v2_fonts = $this->get_fonts();
40
+ wp_localize_script( 'fw-option-' . $this->get_type(), 'fw_typography_v2_fonts', $fw_typography_v2_fonts );
41
+ }
42
+
43
+ public function get_type() {
44
+ return 'typography-v2';
45
+ }
46
+
47
+ /**
48
+ * Returns fonts
49
+ * @return array
50
+ */
51
+ public function get_fonts() {
52
+ if ( $this->fonts === null ) {
53
+ $this->fonts = array(
54
+ 'standard' => apply_filters( 'fw_option_type_typography_v2_standard_fonts', array(
55
+ "Arial",
56
+ "Verdana",
57
+ "Trebuchet",
58
+ "Georgia",
59
+ "Times New Roman",
60
+ "Tahoma",
61
+ "Palatino",
62
+ "Helvetica",
63
+ "Calibri",
64
+ "Myriad Pro",
65
+ "Lucida",
66
+ "Arial Black",
67
+ "Gill Sans",
68
+ "Geneva",
69
+ "Impact",
70
+ "Serif"
71
+ ) ),
72
+ 'google' => fw_get_google_fonts_v2()
73
+ );
74
+ }
75
+
76
+ return $this->fonts;
77
+ }
78
+
79
+ /**
80
+ * @internal
81
+ */
82
+ protected function _render( $id, $option, $data ) {
83
+ return fw_render_view( fw_get_framework_directory( '/includes/option-types/' . $this->get_type() . '/view.php' ), array(
84
+ 'typography_v2' => $this,
85
+ 'id' => $id,
86
+ 'option' => $option,
87
+ 'data' => $data,
88
+ 'fonts' => $this->get_fonts(),
89
+ 'defaults' => $this->get_defaults()
90
+ ) );
91
+ }
92
+
93
+ /**
94
+ * @internal
95
+ */
96
+ protected function _get_value_from_input( $option, $input_value ) {
97
+
98
+ $default = $this->get_defaults();
99
+ $values = array_merge( $default['value'], $option['value'], is_array($input_value) ? $input_value : array());
100
+
101
+ if ( ! preg_match( '/^#[a-f0-9]{6}$/i', $values['color'] ) ) {
102
+ $values = ( isset( $option['value']['color'] ) ) ? $option['value']['color'] : $default['value']['color'];
103
+ }
104
+
105
+ $components = array_merge( $default['components'], $option['components'] );
106
+ foreach ( $components as $component => $enabled ) {
107
+ if ( ! $enabled ) {
108
+ $values[ $component ] = false;
109
+ }
110
+ }
111
+
112
+ if ( $values['family'] === false ) {
113
+ $values = array_merge( $values, array(
114
+ 'google_font' => false,
115
+ 'style' => false,
116
+ 'weight' => false,
117
+ 'subset' => false,
118
+ 'variation' => false
119
+ ) );
120
+ } elseif ( $this->get_google_font( $values['family'] ) ) {
121
+ $values = array_merge( $values, array(
122
+ 'google_font' => true,
123
+ 'style' => false,
124
+ 'weight' => false
125
+ ) );
126
+ } else {
127
+ $values = array_merge( $values, array(
128
+ 'google_font' => false,
129
+ 'subset' => false,
130
+ 'variation' => false
131
+
132
+ ) );
133
+ }
134
+
135
+ return $values;
136
+
137
+ }
138
+
139
+ public function get_google_font( $font ) {
140
+ $google_fonts = fw_get_google_fonts_v2();
141
+ $google_fonts = ( false === $google_fonts ) ? array() : json_decode( $google_fonts );
142
+ foreach ( $google_fonts->items as $g_font ) {
143
+ if ( $font === $g_font->family ) {
144
+ return $g_font;
145
+ }
146
+ }
147
+
148
+ return false;
149
+ }
150
+
151
+ /**
152
+ * @internal
153
+ */
154
+ protected function _get_defaults() {
155
+ return array(
156
+ 'value' => array(
157
+ 'google_font' => false,
158
+ 'subset' => false,
159
+ 'variation' => false,
160
+ 'family' => 'Arial',
161
+ 'style' => 'normal',
162
+ 'weight' => '400',
163
+ 'size' => 12,
164
+ 'line-height' => 15,
165
+ 'letter-spacing' => - 1,
166
+ 'color' => '#000000'
167
+ ),
168
+ 'components' => array(
169
+ 'family' => true,
170
+ 'size' => true,
171
+ 'line-height' => true,
172
+ 'letter-spacing' => true,
173
+ 'color' => true
174
+ )
175
+ );
176
+ }
177
+
178
+ }
179
+
180
+ FW_Option_Type::register( 'FW_Option_Type_Typography_v2' );
framework/includes/option-types/typography-v2/static/css/styles.css ADDED
@@ -0,0 +1,303 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .fw-option.fw-option-type-typography-v2 .fw-option-typography-v2-option {
2
+ display: inline-block;
3
+ text-align: left;
4
+ float: inherit;
5
+ }
6
+ .fw-backend-option-input-type-typography-v2 .fw-option-help-in-input {
7
+ top: 4px !important;
8
+ }
9
+
10
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option {
11
+ padding-right: 5px;
12
+ width: 167px;
13
+ }
14
+ body.rtl .fw-option-type-typography-v2 .fw-option-typography-v2-option {
15
+ padding-right: 0;
16
+ padding-left: 5px;
17
+ }
18
+
19
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option:last-child,
20
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option {
21
+ padding-right: 0;
22
+ }
23
+ body.rtl .fw-option-type-typography-v2 .fw-option-typography-v2-option:last-child,
24
+ body.rtl .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option {
25
+ padding-left: 0;
26
+ }
27
+
28
+ @media (max-width: 782px) {
29
+ .fw-backend-option-input-type-typography-v2 {
30
+ width: 100%;
31
+ }
32
+
33
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option {
34
+ padding-top: 5px;
35
+ padding-right: 0;
36
+ }
37
+ body.rtl .fw-option-type-typography-v2 .fw-option-typography-v2-option {
38
+ padding-left: 0;
39
+ }
40
+
41
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option:first-child {
42
+ padding-top: 0;
43
+ }
44
+
45
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option.fw-option-typography-v2-option-size {
46
+ width: 100%;
47
+ }
48
+ }
49
+ .fw-force-xs .fw-backend-option-input-type-typography-v2 {
50
+ width: 100%;
51
+ }
52
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option {
53
+ padding-top: 5px;
54
+ padding-right: 0;
55
+ }
56
+ body.rtl .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option {
57
+ padding-left: 0;
58
+ }
59
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option:first-child {
60
+ padding-top: 0;
61
+ }
62
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option.fw-option-typography-v2-option-size {
63
+ width: 100%;
64
+ }
65
+
66
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option input,
67
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option select {
68
+ display: inline-block;
69
+ margin: 0;
70
+ width: 100%;
71
+ }
72
+
73
+
74
+ /* Color */
75
+
76
+ @media (min-width: 783px) {
77
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-color input {
78
+ height: 28px;
79
+ }
80
+ }
81
+
82
+ /* Family */
83
+
84
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-family-input {
85
+ background: #fff;
86
+ }
87
+
88
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-family-input .selectize-input {
89
+ height: 32px;
90
+ }
91
+
92
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-family-input .selectize-input.dropdown-active::before {
93
+ background: none;
94
+ height: 0;
95
+ }
96
+
97
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-family .selectize-control.single .selectize-input:after {
98
+ right: 8px;
99
+ margin-top: -2px;
100
+ border-width: 6px 3px 0 3px;
101
+ border-color: #000000 transparent transparent transparent;
102
+ }
103
+ body.rtl .fw-option-type-typography-v2 .fw-option-typography-v2-option-family .selectize-control.single .selectize-input:after {
104
+ right: auto;
105
+ left: 8px;
106
+ }
107
+
108
+ @media (max-width: 782px) {
109
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-family .selectize-control.single .selectize-input:after {
110
+ right: 6px;
111
+ }
112
+
113
+ .fw-option-typography-v2-option.fw-option-typography-v2-option-family,
114
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-family-input {
115
+ width: 100%;
116
+ margin-right: 0;
117
+ }
118
+ }
119
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option-family .selectize-control.single .selectize-input:after {
120
+ right: 6px;
121
+ }
122
+ .fw-force-xs .fw-option-typography-v2-option.fw-option-typography-v2-option-family,
123
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option-family-input {
124
+ width: 100%;
125
+ margin-right: 0;
126
+ }
127
+
128
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-family-input:focus,
129
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-family-input.single .selectize-input.focus {
130
+ /*border: 1px solid #5b9dd9;
131
+
132
+ -webkit-box-shadow: 0 0 2px rgba(30,140,190,.8);
133
+ box-shadow: 0 0 2px rgba(30,140,190,.8);*/
134
+
135
+ -webkit-transition: .05s border-color ease-in-out;
136
+ transition: .05s border-color ease-in-out;
137
+ }
138
+
139
+ /*.fw-option-type-typography-v2 .selectize-dropdown.fw-option-typography-v2-option-family-input {
140
+ width: 335px !important;
141
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .07);
142
+ border: 1px solid #ddd;
143
+ }*/
144
+
145
+ .fw-option-type-typography-v2 .selectize-dropdown .selectize-dropdown-content div {
146
+ height: 30px;
147
+ background-color: #fff;
148
+ cursor: pointer;
149
+ border-bottom: 1px solid #ddd;
150
+ line-height: 30px;
151
+ }
152
+
153
+ .fw-option-type-typography-v2 .selectize-dropdown .selectize-dropdown-content div.option span {
154
+ border: none;
155
+ background: none;
156
+ color: red;
157
+ }
158
+
159
+ .fw-option-type-typography-v2 .selectize-dropdown .selectize-dropdown-content div:hover{
160
+ background-color: #f0f0f0;
161
+ }
162
+
163
+ .fw-option-type-typography-v2 .selectize-dropdown.single {
164
+ border: 1px solid #ddd;
165
+ }
166
+
167
+ .fw-option-type-typography-v2 .selectize-control.single .selectize-input {
168
+ background: none;
169
+ margin: 0;
170
+ vertical-align: middle;
171
+ border: 1px solid #dddddd;
172
+ color: #333333;
173
+ height: 28px;
174
+ line-height: 27px;
175
+ font-size: 14px;
176
+ padding: 0 6px;
177
+
178
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, .07);
179
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .07);
180
+ -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .07);
181
+
182
+ border-radius: 0;
183
+ -webkit-border-radius: 0;
184
+ -moz-border-radius: 0;
185
+ }
186
+
187
+ @media (max-width: 782px) {
188
+ .fw-option-type-typography-v2 .selectize-dropdown.fw-option-typography-v2-option-family-input {
189
+ width: 100% !important;
190
+ }
191
+
192
+ .fw-option-type-typography-v2 .selectize-control.single .selectize-input {
193
+ font-size: 16px;
194
+ height: 36px;
195
+ line-height: 36px;
196
+ }
197
+
198
+ #edittag .fw-option-type-typography-v2 .selectize-control.single .selectize-input {
199
+ padding: 0 14px;
200
+ }
201
+ }
202
+ .fw-force-xs .fw-option-type-typography-v2 .selectize-dropdown.fw-option-typography-v2-option-family-input {
203
+ width: 100%!important;
204
+ }
205
+ .fw-force-xs .fw-option-type-typography-v2 .selectize-control.single .selectize-input {
206
+ font-size: 16px;
207
+ }
208
+ #edittag .fw-force-xs .fw-option-type-typography-v2 .selectize-control.single .selectize-input {
209
+ padding: 0 14px;
210
+ }
211
+
212
+ .fw-option-type-typography-v2 div.selectize-input.items.full.has-options.has-items {
213
+ background: none;
214
+ }
215
+
216
+ .fw-option-type-typography-v2 .selectize-dropdown .selectize-dropdown-content {
217
+ border: 1px solid #ddd;
218
+ }
219
+
220
+ .fw-option-type-typography-v2 .selectize-control .selectize-dropdown {
221
+ border: none;
222
+ top: 33px !important;
223
+ }
224
+ @media (max-width: 782px) {
225
+ .fw-option-type-typography-v2 .selectize-control .selectize-dropdown {
226
+ top: 42px !important;
227
+ }
228
+ }
229
+
230
+ @media (max-width: 782px) {
231
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-style,
232
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-subset,
233
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-variation,
234
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-weight,
235
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-size,
236
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-line-height,
237
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-letter-spacing,
238
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-color,
239
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-color .fw-option-type-color-picker {
240
+ width: 100% !important;
241
+ }
242
+ }
243
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option-subset,
244
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option-variation,
245
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option-weight,
246
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option-style,
247
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option-size,
248
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option-line-height,
249
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option-letter-spacing,
250
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option-color,
251
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option-color .fw-option-type-color-picker {
252
+ width: 100% !important;
253
+ }
254
+
255
+ /*
256
+ Fix: for color picker width too small or too big
257
+ Solution: Set color fixed size, and font-style to calculate its width
258
+
259
+ font-style: fw-col-sm-3 = 25%
260
+ color: fw-col-sm-2 = 16.66666667%
261
+
262
+ 25% + 16.66666667% = 41.66666667%
263
+ */
264
+
265
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-color {
266
+ width: 70px; /* should be same width as option type color-picker */
267
+ }
268
+
269
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-style,
270
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-weight,
271
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-variation,
272
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-subset {
273
+ width: 120px;
274
+ }
275
+
276
+
277
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-size,
278
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-line-height,
279
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-letter-spacing {
280
+ width: 86px;
281
+ }
282
+
283
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-letter-spacing {
284
+ width: 86px;
285
+ }
286
+
287
+ @media (max-width: 782px) {
288
+ .fw-option-type-typography-v2 .fw-option-typography-v2-option-size {
289
+ width: 100%;
290
+ }
291
+ }
292
+ .fw-force-xs .fw-option-type-typography-v2 .fw-option-typography-v2-option-size {
293
+ width: 100%;
294
+ }
295
+
296
+ .fw-option-type-typography-v2 .fw-inner {
297
+ font-size: 1em;
298
+ padding-top: 7px;
299
+ padding-left: 1px;
300
+ padding-bottom: 10px;
301
+ font-style: italic;
302
+ color: #666;
303
+ }
framework/includes/option-types/typography-v2/static/js/scripts.js ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*global fw_typography_v2_fonts, jQuery, _ */
2
+ ( function ($) {
3
+ $(document).ready(function () {
4
+ var optionTypeClass = '.fw-option-type-typography-v2',
5
+ googleFonts = JSON.parse(fw_typography_v2_fonts['google']),
6
+ /**
7
+ * [ {'value': 'Font Family', 'text': 'Font Family'} ]
8
+ */
9
+ fontsOptions = null,
10
+ /**
11
+ * { 'Font Family': '<option ...' }
12
+ */
13
+ fontsOptionsHTML = null,
14
+ getFontsOptions = function(){
15
+ if (fontsOptions === null) {
16
+ fontsOptions = [];
17
+ fontsOptionsHTML = {};
18
+
19
+ _.each(fw_typography_v2_fonts['standard'], function (item) {
20
+ fontsOptionsHTML[item] = '<option value="' + item + '">' + item + '</option>';
21
+ fontsOptions.push({
22
+ value: item,
23
+ text: item
24
+ });
25
+ });
26
+
27
+ _.each(googleFonts['items'], function (item) {
28
+ fontsOptionsHTML[item['family']] = '<option value="' + item['family'] + '">' + item['family'] + '</option>';
29
+ fontsOptions.push({
30
+ value: item['family'],
31
+ text: item['family']
32
+ });
33
+ });
34
+ }
35
+
36
+ return fontsOptions;
37
+ },
38
+ getFontsOptionHTML = function(fontFamily) {
39
+ if (fontsOptionsHTML === null) {
40
+ getFontsOptions();
41
+ }
42
+
43
+ return fontsOptionsHTML[fontFamily];
44
+ },
45
+ _to_ascii = {
46
+ '188': '44',
47
+ '109': '45',
48
+ '190': '46',
49
+ '191': '47',
50
+ '192': '96',
51
+ '220': '92',
52
+ '222': '39',
53
+ '221': '93',
54
+ '219': '91',
55
+ '173': '45',
56
+ '187': '61', //IE Key codes
57
+ '186': '59', //IE Key codes
58
+ '189': '45' //IE Key codes
59
+ },
60
+ shiftUps = {
61
+ "96": "~",
62
+ "49": "!",
63
+ "50": "@",
64
+ "51": "#",
65
+ "52": "$",
66
+ "53": "%",
67
+ "54": "^",
68
+ "55": "&",
69
+ "56": "*",
70
+ "57": "(",
71
+ "48": ")",
72
+ "45": "_",
73
+ "61": "+",
74
+ "91": "{",
75
+ "93": "}",
76
+ "92": "|",
77
+ "59": ":",
78
+ "39": "\"",
79
+ "44": "<",
80
+ "46": ">",
81
+ "47": "?"
82
+ };
83
+
84
+ fwEvents.on('fw:options:init', function (data) {
85
+ data.$elements.find(optionTypeClass +':not(.initialized)').each(function(){
86
+ var $option = $(this);
87
+
88
+ $option.find([
89
+ '.fw-option-typography-v2-option .fw-option-typography-v2-option-size-input',
90
+ '.fw-option-typography-v2-option .fw-option-typography-v2-option-line-height-input',
91
+ '.fw-option-typography-v2-option .fw-option-typography-v2-option-letter-spacing-input'
92
+ ].join(', ')).keydown(function (e) {
93
+ // Allow: backspace, delete, tab, escape, enter and .
94
+ if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 ||
95
+ // Allow: Ctrl+A
96
+ (e.keyCode == 65 && e.ctrlKey === true) ||
97
+ //Allow -
98
+ (e.keyCode == 109 ) ||
99
+ // Allow: Ctrl+C
100
+ (e.keyCode == 67 && e.ctrlKey === true) ||
101
+ // Allow: Ctrl+X
102
+ (e.keyCode == 88 && e.ctrlKey === true) ||
103
+ // Allow: home, end, left, right
104
+ (e.keyCode >= 35 && e.keyCode <= 39)) {
105
+ // let it happen, don't do anything
106
+ return;
107
+ }
108
+ // Ensure that it is a number and stop the keypress
109
+ if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
110
+ e.preventDefault();
111
+ }
112
+ });
113
+
114
+ {
115
+ var $fontFamilySelect = $option.find('.fw-option-typography-v2-option-family select[data-type="family"]');
116
+
117
+ $fontFamilySelect
118
+ .html(getFontsOptionHTML($fontFamilySelect.attr('data-value')))
119
+ .selectize({
120
+ onChange: function (selected) {
121
+ var results = $.grep(googleFonts['items'], function (font) {
122
+ return font['family'] === selected;
123
+ });
124
+ var $variations = this.$dropdown.closest(optionTypeClass).find('.fw-option-typography-v2-option-variation');
125
+ var $subsets = this.$dropdown.closest(optionTypeClass).find('.fw-option-typography-v2-option-subset');
126
+
127
+ var $style = this.$dropdown.closest(optionTypeClass).find('.fw-option-typography-v2-option-style');
128
+ var $weight = this.$dropdown.closest(optionTypeClass).find('.fw-option-typography-v2-option-weight');
129
+
130
+ if (results.length === 1) {
131
+ var variations = '';
132
+ var subsets = '';
133
+ _.each(results[0]['variants'], function (variation) {
134
+ variations += '<option value="' + variation + '">' + variation + '</option>';
135
+ });
136
+ _.each(results[0]['subsets'], function (subset) {
137
+ subsets += '<option value="' + subset + '">' + subset + '</option>';
138
+ });
139
+
140
+ $variations.find('select[data-type="variation"]').html(variations);
141
+ $variations.show();
142
+
143
+ $subsets.find('select[data-type="subset"]').html(subsets);
144
+ $subsets.show();
145
+ $style.hide();
146
+ $weight.hide();
147
+ } else {
148
+ $style.show();
149
+ $weight.show();
150
+
151
+ $variations.hide();
152
+ $subsets.hide();
153
+ }
154
+
155
+ this.$wrapper.find('input[type="text"]').attr('data-fw-pressed-backspace', 'false');
156
+ },
157
+ onInitialize: function () {
158
+ var self = this;
159
+ this.$wrapper.find('input[type="text"]').attr('data-fw-pressed-backspace', 'false');
160
+ this.$wrapper.find('input[type="text"]').on('keydown', function (e) {
161
+ if (e.keyCode === 40) {
162
+ $(this).attr('data-fw-pressed-backspace', 'true');
163
+ } else {
164
+ if ($(this).attr('data-fw-pressed-backspace') == 'false') {
165
+
166
+ self.clear(true);
167
+
168
+ var c = e.which;
169
+
170
+ if (_to_ascii.hasOwnProperty(c)) {
171
+ c = _to_ascii[c];
172
+ }
173
+
174
+ if (!e.shiftKey && (c >= 65 && c <= 90)) {
175
+ c = String.fromCharCode(c + 32);
176
+ } else if (e.shiftKey && shiftUps.hasOwnProperty(c)) {
177
+ c = shiftUps[c];
178
+ } else {
179
+ c = String.fromCharCode(c);
180
+ }
181
+ $(this).val(c);
182
+
183
+ $(this).attr('data-fw-pressed-backspace', 'true');
184
+ }
185
+ }
186
+ });
187
+
188
+ $fontFamilySelect.removeAttr('data-value');
189
+
190
+ $fontFamilySelect.trigger('selectizeLoaded', [$fontFamilySelect[0].selectize]);
191
+
192
+ },
193
+ onFocus: function() {
194
+ var selectize = $fontFamilySelect[0].selectize;
195
+ var selectedValue = selectize.getValue();
196
+ selectize.removeOption(selectedValue, true);
197
+
198
+ _.each(getFontsOptions(), function(option){
199
+ selectize.addOption({
200
+ value: option.value,
201
+ text: option.text
202
+ });
203
+ });
204
+
205
+ selectize.setValue(selectedValue, true);
206
+ selectize.refreshOptions(true);
207
+
208
+ },
209
+ onBlur: function() {
210
+ var selectize = $fontFamilySelect[0].selectize,
211
+ value = selectize.getValue();
212
+
213
+ _.each(getFontsOptions(), function(option){
214
+ if (value !== option.value) {
215
+ selectize.removeOption(option.value);
216
+ }
217
+ });
218
+
219
+ selectize.refreshOptions(false);
220
+ }
221
+ });
222
+ }
223
+ }).addClass('initialized');
224
+ });
225
+ });
226
+ }(jQuery));
framework/includes/option-types/typography-v2/view.php ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if ( ! defined( 'FW' ) ) {
2
+ die( 'Forbidden' );
3
+ }
4
+ /**
5
+ * @var FW_Option_Type_Typography_v2 $typography_v2
6
+ * @var string $id
7
+ * @var array $option
8
+ * @var array $data
9
+ * @var array $fonts
10
+ * @var array $defaults
11
+ */
12
+
13
+ {
14
+ $wrapper_attr = $option['attr'];
15
+
16
+ unset(
17
+ $wrapper_attr['value'],
18
+ $wrapper_attr['name']
19
+ );
20
+ }
21
+
22
+ {
23
+ $option['value'] = array_merge( $defaults['value'], (array) $option['value'] );
24
+ $data['value'] = array_merge( $option['value'], is_array($data['value']) ? $data['value'] : array() );
25
+ $google_font = $typography_v2->get_google_font( $data['value']['family'] );
26
+
27
+ /**
28
+ * This can be set manually as int and the below === verification will be false
29
+ * so make sure to transform: 600 -> '600'
30
+ */
31
+ $data['value']['variation'] = (string)$data['value']['variation'];
32
+ }
33
+
34
+ $components = (isset($option['components']) && is_array($option['components'])) ? array_merge($defaults['components'], $option['components']) : $defaults['components'];
35
+ ?>
36
+ <div <?php echo fw_attr_to_html( $wrapper_attr ) ?>>
37
+ <?php if ( $components['family'] ) : ?>
38
+ <div class="fw-option-typography-v2-option fw-option-typography-v2-option-family fw-border-box-sizing fw-col-sm-5">
39
+ <select data-type="family" data-value="<?php echo $data['value']['family']; ?>"
40
+ name="<?php echo esc_attr( $option['attr']['name'] ) ?>[family]"
41
+ class="fw-option-typography-v2-option-family-input">
42
+ </select>
43
+
44
+ <div class="fw-inner"><?php _e('Font face', 'fw'); ?></div>
45
+ </div>
46
+
47
+ <div class="fw-option-typography-v2-option fw-option-typography-v2-option-style fw-border-box-sizing fw-col-sm-3"
48
+ style="display: <?php echo ( $google_font ) ? 'none' : 'inline-block'; ?>;">
49
+ <select data-type="style" name="<?php echo esc_attr( $option['attr']['name'] ) ?>[style]"
50
+ class="fw-option-typography-v2-option-style-input">
51
+ <?php foreach (
52
+ array(
53
+ 'normal' => __('Normal', 'fw'),
54
+ 'italic' => __('Italic', 'fw'),
55
+ 'oblique' => __('Oblique', 'fw')
56
+ )
57
+ as $key => $style
58
+ ): ?>
59
+ <option value="<?php echo esc_attr( $key ) ?>"
60
+ <?php if ($data['value']['style'] === $key): ?>selected="selected"<?php endif; ?>><?php echo fw_htmlspecialchars( $style ) ?></option>
61
+ <?php endforeach; ?>
62
+ </select>
63
+
64
+ <div class="fw-inner"><?php _e( 'Style', 'fw' ); ?></div>
65
+ </div>
66
+
67
+ <div class="fw-option-typography-v2-option fw-option-typography-v2-option-weight fw-border-box-sizing fw-col-sm-3"
68
+ style="display: <?php echo ( $google_font ) ? 'none' : 'inline-block'; ?>;">
69
+ <select data-type="weight" name="<?php echo esc_attr( $option['attr']['name'] ) ?>[weight]"
70
+ class="fw-option-typography-v2-option-weight-input">
71
+ <?php foreach (
72
+ array(
73
+ 100 => 100,
74
+ 200 => 200,
75
+ 300 => 300,
76
+ 400 => 400,
77
+ 500 => 500,
78
+ 600 => 600,
79
+ 700 => 700,
80
+ 800 => 800,
81
+ 900 => 900
82
+ )
83
+ as $key => $style
84
+ ): ?>
85
+ <option value="<?php echo esc_attr( $key ) ?>"
86
+ <?php if ($data['value']['weight'] == $key): ?>selected="selected"<?php endif; ?>><?php echo fw_htmlspecialchars( $style ) ?></option>
87
+ <?php endforeach; ?>
88
+ </select>
89
+
90
+ <div class="fw-inner"><?php _e( 'Weight', 'fw' ); ?></div>
91
+ </div>
92
+
93
+ <div class="fw-option-typography-v2-option fw-option-typography-v2-option-subset fw-border-box-sizing fw-col-sm-2"
94
+ style="display: <?php echo ( $google_font ) ? 'inline-block' : 'none'; ?>;">
95
+ <select data-type="subset" name="<?php echo esc_attr( $option['attr']['name'] ) ?>[subset]"
96
+ class="fw-option-typography-v2-option-subset">
97
+ <?php if ( $google_font ) {
98
+ foreach ( $google_font->subsets as $subset ) { ?>
99
+ <option value="<?php echo esc_attr( $subset ) ?>"
100
+ <?php if ($data['value']['subset'] === $subset): ?>selected="selected"<?php endif; ?>><?php echo fw_htmlspecialchars( $subset ); ?></option>
101
+ <?php }
102
+ }
103
+ ?>
104
+ </select>
105
+
106
+ <div class="fw-inner"><?php _e( 'Script', 'fw' ); ?></div>
107
+ </div>
108
+
109
+ <div
110
+ class="fw-option-typography-v2-option fw-option-typography-v2-option-variation fw-border-box-sizing fw-col-sm-2"
111
+ style="display: <?php echo ( $google_font ) ? 'inline-block' : 'none'; ?>;">
112
+ <select data-type="variation" name="<?php echo esc_attr( $option['attr']['name'] ) ?>[variation]"
113
+ class="fw-option-typography-v2-option-variation">
114
+ <?php if ( $google_font ) {
115
+ foreach ( $google_font->variants as $variant ) { ?>
116
+ <option value="<?php echo esc_attr( $variant ) ?>"
117
+ <?php if ($data['value']['variation'] === $variant): ?>selected="selected"<?php endif; ?>><?php echo fw_htmlspecialchars( $variant ); ?></option>
118
+ <?php }
119
+ }
120
+ ?>
121
+ </select>
122
+
123
+ <div class="fw-inner"><?php _e( 'Style', 'fw' ); ?></div>
124
+ </div>
125
+ <?php endif; ?>
126
+
127
+ <?php if ( $components['size'] ) : ?>
128
+ <div class="fw-option-typography-v2-option fw-option-typography-v2-option-size fw-border-box-sizing fw-col-sm-2">
129
+ <input data-type="size" name="<?php echo esc_attr( $option['attr']['name'] ) ?>[size]"
130
+ class="fw-option-typography-v2-option-size-input" type="text"
131
+ value="<?php echo $data['value']['size']; ?>">
132
+
133
+ <div class="fw-inner"><?php _e( 'Size', 'fw' ); ?></div>
134
+ </div>
135
+ <?php endif; ?>
136
+
137
+ <?php if ( $components['line-height'] ) : ?>
138
+ <div
139
+ class="fw-option-typography-v2-option fw-option-typography-v2-option-line-height fw-border-box-sizing fw-col-sm-2">
140
+ <input data-type="line-height" name="<?php echo esc_attr( $option['attr']['name'] ) ?>[line-height]"
141
+ value="<?php echo $data['value']['line-height']; ?>"
142
+ class="fw-option-typography-v2-option-line-height-input" type="text">
143
+
144
+ <div class="fw-inner"><?php _e( 'Line height', 'fw' ); ?></div>
145
+ </div>
146
+ <?php endif; ?>
147
+
148
+ <?php if ( $components['letter-spacing'] ) : ?>
149
+ <div
150
+ class="fw-option-typography-v2-option fw-option-typography-v2-option-letter-spacing fw-border-box-sizing fw-col-sm-2">
151
+ <input data-type="letter-spacing" name="<?php echo esc_attr( $option['attr']['name'] ) ?>[letter-spacing]"
152
+ value="<?php echo $data['value']['letter-spacing']; ?>"
153
+ class="fw-option-typography-v2-option-letter-spacing-input" type="text">
154
+
155
+ <div class="fw-inner"><?php _e( 'Letter spacing', 'fw' ); ?></div>
156
+ </div>
157
+ <?php endif; ?>
158
+
159
+ <?php if ( $components['color'] ) : ?>
160
+ <div class="fw-option-typography-v2-option fw-option-typography-v2-option-color fw-border-box-sizing fw-col-sm-2"
161
+ data-type="color">
162
+ <?php
163
+ echo fw()->backend->option_type( 'color-picker' )->render(
164
+ 'color',
165
+ array(
166
+ 'label' => false,
167
+ 'desc' => false,
168
+ 'type' => 'color-picker',
169
+ 'value' => $option['value']['color']
170
+ ),
171
+ array(
172
+ 'value' => $data['value']['color'],
173
+ 'id_prefix' => 'fw-option-' . $id . '-typography-v2-option-',
174
+ 'name_prefix' => $data['name_prefix'] . '[' . $id . ']',
175
+ )
176
+ )
177
+ ?>
178
+ <div class="fw-inner"><?php _e( 'Color', 'fw' ); ?></div>
179
+ </div>
180
+ <?php endif; ?>
181
+
182
+ </div>
framework/includes/option-types/typography/static/js/scripts.js CHANGED
@@ -1,44 +1,138 @@
1
  /*global fw_typography_fonts */
2
  ( function ($) {
3
  $(document).ready(function () {
4
- var fontsHTML = '';
5
- _.each(fw_typography_fonts['standard'], function (item) {
6
- fontsHTML += '<option value="' + item + '">' + item + '</option>';
7
- });
8
- _.each(fw_typography_fonts['google'], function (item) {
9
- fontsHTML += '<option value="' + item['family'] + '">' + item['family'] + '</option>';
10
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  fwEvents.on('fw:options:init', function (data) {
13
- setTimeout(function () {
14
- data.$elements.find('.fw-option-typography-option-family select[data-type="family"]:not(.initialized)').each(function () {
15
- $(this).html(fontsHTML).val($(this).attr('data-value')).selectize({
16
- render: {
17
- option: function (item) {
18
- if (fw_typography_fonts['google'].hasOwnProperty(item.value)) {
19
- var background = (typeof fw_typography_fonts['google'][item.value].position === "number") ? 'style="background-position: 0 -' + fw_typography_fonts['google'][item.value].position + 'px;' : 'style="background: none;';
20
- return '<div data-value="' + item.value + '" data-selectable="" class="option">' + item.text + '<div class="preview" ' + background + '"></div></div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  } else {
22
- return '<div data-value="' + item.value + '" data-selectable="" class="option">' + item.text + '<div class="preview" style="background: none; font-family: ' + item.value + '">' + item.value + '</div></div>';
 
 
 
 
 
 
 
23
  }
24
- }
25
- },
26
- onChange: function (selected) {
27
- var html = '';
28
- if (fw_typography_fonts['google'].hasOwnProperty(selected)) {
29
- var font = fw_typography_fonts['google'][selected];
30
- _.each(font.variants, function (variant) {
31
- html += '<option value="' + variant + '">' + fw.capitalizeFirstLetter(variant) + '</option>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  });
33
- } else {
34
- html += '<option value="300">Thin</option><option value="300italic">Thin/Italic</option><option value="400" selected="selected">Normal</option><option value="italic">Italic</option><option value="700">Bold</option><option value="700italic">Bold/Italic</option>';
 
 
 
 
 
35
  }
36
- this.$dropdown.closest('.fw-option-typography-option-family').next('.fw-option-typography-option-style').find('select[data-type="style"]').html(html);
37
- }
38
- }).addClass('initialized');
39
- $(this).trigger('selectizeLoaded', [$(this)[0].selectize]);
40
- });
41
- }, 1500);
42
  });
43
  });
44
  }(jQuery));
1
  /*global fw_typography_fonts */
2
  ( function ($) {
3
  $(document).ready(function () {
4
+ var optionTypeClass = '.fw-option-type-typography',
5
+ /**
6
+ * [ {'value': 'Font Family', 'text': 'Font Family'} ]
7
+ */
8
+ fontsOptions = null,
9
+ /**
10
+ * { 'Font Family': '<option ...' }
11
+ */
12
+ fontsOptionsHTML = null,
13
+ getFontsOptions = function(){
14
+ if (fontsOptions === null) {
15
+ fontsOptions = [];
16
+ fontsOptionsHTML = {};
17
+
18
+ _.each(fw_typography_fonts['standard'], function (item) {
19
+ fontsOptionsHTML[item] = '<option value="' + item + '">' + item + '</option>';
20
+ fontsOptions.push({
21
+ value: item,
22
+ text: item
23
+ });
24
+ });
25
+
26
+ _.each(fw_typography_fonts['google'], function (item) {
27
+ fontsOptionsHTML[item['family']] = '<option value="' + item['family'] + '">' + item['family'] + '</option>';
28
+ fontsOptions.push({
29
+ value: item['family'],
30
+ text: item['family']
31
+ });
32
+ });
33
+ }
34
+
35
+ return fontsOptions;
36
+ },
37
+ getFontsOptionHTML = function(fontFamily) {
38
+ if (fontsOptionsHTML === null) {
39
+ getFontsOptions();
40
+ }
41
+
42
+ return fontsOptionsHTML[fontFamily];
43
+ };
44
 
45
  fwEvents.on('fw:options:init', function (data) {
46
+ data.$elements.find(optionTypeClass +':not(.initialized)').each(function(){
47
+ var $option = $(this);
48
+
49
+ {
50
+ var $fontFamilySelect = $option.find('.fw-option-typography-option-family select[data-type="family"]');
51
+
52
+ $fontFamilySelect
53
+ .html(getFontsOptionHTML($fontFamilySelect.attr('data-value')))
54
+ .selectize({
55
+ render: {
56
+ option: function (item) {
57
+ if (fw_typography_fonts['google'].hasOwnProperty(item.value)) {
58
+ var background = (typeof fw_typography_fonts['google'][item.value].position === "number")
59
+ ? 'style="background-position: 0 -' + fw_typography_fonts['google'][item.value].position + 'px;'
60
+ : 'style="background: none;';
61
+
62
+ return ''+
63
+ '<div data-value="' + item.value + '" data-selectable="" class="option">' +
64
+ item.text +
65
+ '<div class="preview" ' + background + '"></div>'+
66
+ '</div>';
67
+ } else {
68
+ return ''+
69
+ '<div data-value="' + item.value + '" data-selectable="" class="option">' +
70
+ item.text +
71
+ '<div class="preview" style="background: none; font-family: ' + item.value + '">' + item.value + '</div>'+
72
+ '</div>';
73
+ }
74
+ }
75
+ },
76
+ onChange: function (selected) {
77
+ var html = '';
78
+
79
+ if (fw_typography_fonts['google'].hasOwnProperty(selected)) {
80
+ var font = fw_typography_fonts['google'][selected];
81
+ _.each(font.variants, function (variant) {
82
+ html += '<option value="' + variant + '">' + fw.capitalizeFirstLetter(variant) + '</option>';
83
+ });
84
  } else {
85
+ html += [ // todo: translate these strings
86
+ '<option value="300">Thin</option>',
87
+ '<option value="300italic">Thin/Italic</option>',
88
+ '<option value="400" selected="selected">Normal</option>',
89
+ '<option value="italic">Italic</option>',
90
+ '<option value="700">Bold</option>',
91
+ '<option value="700italic">Bold/Italic</option>'
92
+ ].join("\n");
93
  }
94
+
95
+ this.$dropdown
96
+ .closest('.fw-option-typography-option-family')
97
+ .next('.fw-option-typography-option-style')
98
+ .find('select[data-type="style"]').html(html);
99
+ },
100
+ onFocus: function() {
101
+ var selectize = $fontFamilySelect[0].selectize;
102
+ var selectedValue = selectize.getValue();
103
+ selectize.removeOption(selectedValue, true);
104
+
105
+ _.each(getFontsOptions(), function(option){
106
+ selectize.addOption({
107
+ value: option.value,
108
+ text: option.text
109
+ });
110
+ });
111
+
112
+ selectize.setValue(selectedValue, true);
113
+ selectize.refreshOptions(true);
114
+
115
+ },
116
+ onBlur: function() {
117
+ var selectize = $fontFamilySelect[0].selectize,
118
+ value = selectize.getValue();
119
+
120
+ _.each(getFontsOptions(), function(option){
121
+ if (value !== option.value) {
122
+ selectize.removeOption(option.value);
123
+ }
124
  });
125
+
126
+ selectize.refreshOptions(false);
127
+ },
128
+ onInitialize: function(){
129
+ $fontFamilySelect.removeAttr('data-value');
130
+
131
+ $fontFamilySelect.trigger('selectizeLoaded', [$fontFamilySelect[0].selectize]);
132
  }
133
+ });
134
+ }
135
+ }).addClass('initialized');
 
 
 
136
  });
137
  });
138
  }(jQuery));
framework/includes/option-types/typography/view.php CHANGED
@@ -25,7 +25,7 @@
25
  'color' => '#000000',
26
  ), (array)$option['value']);
27
 
28
- $data['value'] = array_merge($option['value'], array_filter((array)$data['value']));
29
  }
30
  ?>
31
  <div <?php echo fw_attr_to_html($wrapper_attr) ?>>
25
  'color' => '#000000',
26
  ), (array)$option['value']);
27
 
28
+ $data['value'] = array_merge($option['value'], is_array($data['value']) ? $data['value'] : array());
29
  }
30
  ?>
31
  <div <?php echo fw_attr_to_html($wrapper_attr) ?>>
framework/includes/option-types/wp-editor/class-fw-option-type-wp-editor.php CHANGED
@@ -129,7 +129,7 @@ class FW_Option_Type_Wp_Editor extends FW_Option_Type {
129
  'preview_styles' => 'font-family font-size font-weight font-style text-decoration text-transform',
130
  'wpeditimage_disable_captions' => false,
131
  'wpeditimage_html5_captions' => true,
132
- 'plugins' => 'charmap,hr,media,paste,tabfocus,textcolor,fullscreen,wordpress,wpeditimage,wpgallery,wplink,wpdialogs,wpview',
133
  'resize' => 'vertical',
134
  'menubar' => false,
135
  'indent' => false,
129
  'preview_styles' => 'font-family font-size font-weight font-style text-decoration text-transform',
130
  'wpeditimage_disable_captions' => false,
131
  'wpeditimage_html5_captions' => true,
132
+ 'plugins' => 'charmap,hr,media,paste,tabfocus,textcolor,fullscreen,wordpress,wpeditimage,wpgallery,wplink,wpdialogs,wpview,colorpicker,textcolor',
133
  'resize' => 'vertical',
134
  'menubar' => false,
135
  'indent' => false,
framework/includes/option-types/wp-editor/static/js/scripts.js CHANGED
@@ -41,10 +41,11 @@
41
  };
42
 
43
  var reachTexEditorReinit = function($textarea){
44
- var parent = $textarea.parents('.wp-editor-wrap:eq(0)'),
45
- $btnTabs = parent.find('.wp-switch-editor').removeAttr("onclick"),
46
- id = $textarea.attr('id'),
47
- settings = {id: id , buttons: 'strong,em,link,block,del,ins,img,ul,ol,li,code,more,close'};
 
48
 
49
 
50
  var tmceCustomSettings = $textarea.parents('.fw-option-type-wp-editor').data('tinymce'),
@@ -95,6 +96,7 @@
95
  if (QTags != undefined) {
96
  QTags._buttonsInit();
97
  }
 
98
  }
99
  else
100
  {
@@ -107,8 +109,9 @@
107
 
108
  $textarea.val(value);
109
  }
110
- }).trigger('click');
111
 
 
112
  /**
113
  * adding Qtags buttons panel
114
  */
@@ -118,7 +121,8 @@
118
 
119
  fwe.on('fw:options:init', function(data) {
120
  data.$elements
121
- .find('.fw-option-type-wp-editor').each(init)
 
122
  .addClass('fw-option-initialized');
123
  });
124
 
41
  };
42
 
43
  var reachTexEditorReinit = function($textarea){
44
+ var parent = $textarea.parents('.wp-editor-wrap:eq(0)'),
45
+ $activeEditorBtn = parent.hasClass('tmce-active') ? parent.find('.switch-tmce') : parent.find('.switch-html'),
46
+ $btnTabs = parent.find('.wp-switch-editor').removeAttr("onclick"),
47
+ id = $textarea.attr('id'),
48
+ settings = {id: id , buttons: 'strong,em,link,block,del,ins,img,ul,ol,li,code,more,close'};
49
 
50
 
51
  var tmceCustomSettings = $textarea.parents('.fw-option-type-wp-editor').data('tinymce'),
96
  if (QTags != undefined) {
97
  QTags._buttonsInit();
98
  }
99
+
100
  }
101
  else
102
  {
109
 
110
  $textarea.val(value);
111
  }
112
+ });
113
 
114
+ $activeEditorBtn.trigger('click');
115
  /**
116
  * adding Qtags buttons panel
117
  */
121
 
122
  fwe.on('fw:options:init', function(data) {
123
  data.$elements
124
+ .find('.fw-option-type-wp-editor:not(.fw-option-initialized)')
125
+ .each(init)
126
  .addClass('fw-option-initialized');
127
  });
128
 
framework/manifest.php CHANGED
@@ -4,4 +4,4 @@ $manifest = array();
4
 
5
  $manifest['name'] = __('Unyson', 'fw');
6
 
7
- $manifest['version'] = '2.3.2';
4
 
5
  $manifest['name'] = __('Unyson', 'fw');
6
 
7
+ $manifest['version'] = '2.3.3';
framework/static/css/backend-options.css CHANGED
@@ -11,6 +11,17 @@ Included on pages where backend options are rendered
11
  position: relative;
12
  }
13
 
 
 
 
 
 
 
 
 
 
 
 
14
  .fw-backend-option .fw-backend-option-input input[type="text"],
15
  .fw-backend-option .fw-backend-option-input input[type="password"],
16
  .fw-backend-option .fw-backend-option-input select,
@@ -35,13 +46,13 @@ Included on pages where backend options are rendered
35
 
36
  .fw-options-tabs-wrapper {
37
  opacity: 0;
 
 
 
38
  }
39
 
40
  .fw-options-tabs-wrapper.ui-tabs {
41
  opacity: 1;
42
-
43
- transition: opacity ease 0.3s;
44
- -webkit-transition: opacity ease 0.3s;
45
  }
46
 
47
  .fw-options-tabs-wrapper > .fw-options-tabs-list {
@@ -203,6 +214,23 @@ body.rtl .fw-options-tabs-wrapper > .fw-options-tabs-contents > .fw-inner > .fw-
203
  }
204
  }
205
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  /* Side tabs */
207
 
208
  form.fw-settings-form.fw-backend-side-tabs {
@@ -495,6 +523,15 @@ form.fw-settings-form.fw-backend-side-tabs {
495
  .fw-backend-side-tabs .fw-settings-form-header {
496
  background: #0074a2;
497
  margin-top: 20px;
 
 
 
 
 
 
 
 
 
498
  }
499
 
500
  .fw-backend-side-tabs .fw-settings-form-header a:focus {
@@ -670,7 +707,7 @@ form#post .fw-options-tabs-wrapper > .fw-options-tabs-contents .fw-backend-postb
670
  cursor: pointer !important; /* to rewrite .js .postbox .hndle */
671
  }
672
 
673
- .fw-postbox:not(.fw-postbox-initialized) h3.hndle {
674
  display: none;
675
  }
676
 
11
  position: relative;
12
  }
13
 
14
+ .fw-backend-option {
15
+ opacity: 0;
16
+
17
+ transition: opacity ease 0.3s;
18
+ -webkit-transition: opacity ease 0.3s;
19
+ }
20
+
21
+ .fw-backend-option.initialized {
22
+ opacity: 1;
23
+ }
24
+
25
  .fw-backend-option .fw-backend-option-input input[type="text"],
26
  .fw-backend-option .fw-backend-option-input input[type="password"],
27
  .fw-backend-option .fw-backend-option-input select,
46
 
47
  .fw-options-tabs-wrapper {
48
  opacity: 0;
49
+
50
+ transition: opacity ease 0.3s;
51
+ -webkit-transition: opacity ease 0.3s;
52
  }
53
 
54
  .fw-options-tabs-wrapper.ui-tabs {
55
  opacity: 1;
 
 
 
56
  }
57
 
58
  .fw-options-tabs-wrapper > .fw-options-tabs-list {
214
  }
215
  }
216
 
217
+
218
+ /* Postbox */
219
+
220
+ .fw-postbox {
221
+ opacity: 0;
222
+
223
+ transition: opacity ease 0.3s;
224
+ -webkit-transition: opacity ease 0.3s;
225
+ }
226
+
227
+ .fw-postbox.initialized {
228
+ opacity: 1;
229
+ }
230
+
231
+ /* end: Postbox */
232
+
233
+
234
  /* Side tabs */
235
 
236
  form.fw-settings-form.fw-backend-side-tabs {
523
  .fw-backend-side-tabs .fw-settings-form-header {
524
  background: #0074a2;
525
  margin-top: 20px;
526
+
527
+ opacity: 0;
528
+
529
+ transition: opacity ease 0.3s;
530
+ -webkit-transition: opacity ease 0.3s;
531
+ }
532
+
533
+ .fw-backend-side-tabs .fw-settings-form-header.initialized {
534
+ opacity: 1;
535
  }
536
 
537
  .fw-backend-side-tabs .fw-settings-form-header a:focus {
707
  cursor: pointer !important; /* to rewrite .js .postbox .hndle */
708
  }
709
 
710
+ .fw-postbox:not(.initialized) h3.hndle {
711
  display: none;
712
  }
713
 
framework/static/css/fw.css CHANGED
@@ -2688,6 +2688,14 @@ a.fw-wp-link:hover {
2688
  }
2689
  }
2690
 
 
 
 
 
 
 
 
 
2691
  /* end: fwGrowIn */
2692
 
2693
  /* fwGrowOut */
@@ -2720,6 +2728,17 @@ a.fw-wp-link:hover {
2720
  }
2721
  }
2722
 
 
 
 
 
 
 
 
 
 
 
 
2723
  /* end: fwGrowOut */
2724
 
2725
  /* zoomIn */
@@ -2772,6 +2791,66 @@ a.fw-wp-link:hover {
2772
 
2773
  /* end: fadeIn */
2774
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2775
  /* end: Animations */
2776
 
2777
 
@@ -2815,20 +2894,11 @@ body.wp-customizer > div:not(.fw-modal) > .media-modal-backdrop {
2815
  }
2816
 
2817
  .fw-modal.fw-modal-open > .media-modal > .media-modal-content {
2818
- animation: fwGrowIn .3s ease-in-out;
2819
- animation-iteration-count: 1;
2820
-
2821
  -webkit-animation: fwGrowIn .3s ease-in-out;
2822
- -webkit-animation-iteration-count: 1;
2823
-
2824
  -moz-animation: fwGrowIn .3s ease-in-out;
2825
- -moz-animation-iteration-count: 1;
2826
-
2827
- -o-animation: fwGrowIn .3s ease-in-out;
2828
- -o-animation-iteration-count: 1;
2829
-
2830
  -ms-animation: fwGrowIn .3s ease-in-out;
2831
- -ms-animation-iteration-count: 1;
 
2832
  }
2833
 
2834
  .fw-modal > .media-modal > .media-modal-close {
@@ -2854,20 +2924,11 @@ body.wp-customizer > div:not(.fw-modal) > .media-modal-backdrop {
2854
  }
2855
 
2856
  .fw-modal.fw-modal-closing > .media-modal > .media-modal-content {
2857
- animation: fwGrowOut .3s ease-in-out;
2858
- animation-iteration-count: 1;
2859
-
2860
  -webkit-animation: fwGrowOut .3s ease-in-out;
2861
- -webkit-animation-iteration-count: 1;
2862
-
2863
  -moz-animation: fwGrowOut .3s ease-in-out;
2864
- -moz-animation-iteration-count: 1;
2865
-
2866
- -o-animation: fwGrowOut .3s ease-in-out;
2867
- -o-animation-iteration-count: 1;
2868
-
2869
  -ms-animation: fwGrowOut .3s ease-in-out;
2870
- -ms-animation-iteration-count: 1;
 
2871
 
2872
  -webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
2873
  animation-fill-mode: forwards;
@@ -3079,3 +3140,45 @@ body.rtl .fw-options-modal .media-frame-content > form .fw-options-tabs-contents
3079
  }
3080
 
3081
  /* end: qtip-fw (x) button */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2688
  }
2689
  }
2690
 
2691
+ .fw-animation-grow-in {
2692
+ -webkit-animation: fwGrowIn .3s ease-in-out;
2693
+ -moz-animation: fwGrowIn .3s ease-in-out;
2694
+ -ms-animation: fwGrowIn .3s ease-in-out;
2695
+ -o-animation: fwGrowIn .3s ease-in-out;
2696
+ animation: fwGrowIn .3s ease-in-out;
2697
+ }
2698
+
2699
  /* end: fwGrowIn */
2700
 
2701
  /* fwGrowOut */
2728
  }
2729
  }
2730
 
2731
+ .fw-animation-grow-out {
2732
+ -webkit-animation: fwGrowOut .3s ease-in-out;
2733
+ -moz-animation: fwGrowOut .3s ease-in-out;
2734
+ -ms-animation: fwGrowOut .3s ease-in-out;
2735
+ -o-animation: fwGrowOut .3s ease-in-out;
2736
+ animation: fwGrowOut .3s ease-in-out;
2737
+
2738
+ -webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
2739
+ animation-fill-mode: forwards;
2740
+ }
2741
+
2742
  /* end: fwGrowOut */
2743
 
2744
  /* zoomIn */
2791
 
2792
  /* end: fadeIn */
2793
 
2794
+ /* fwReverseRotate180 */
2795
+
2796
+ @-webkit-keyframes fwRotateReverse180 /* Safari and Chrome */ {
2797
+ 0% {
2798
+ -ms-transform: rotate(0deg);
2799
+ -moz-transform: rotate(0deg);
2800
+ -webkit-transform: rotate(0deg);
2801
+ -o-transform: rotate(0deg);
2802
+ transform: rotate(0deg);
2803
+ }
2804
+ 50% {
2805
+ -ms-transform: rotate(-180deg);
2806
+ -moz-transform: rotate(-180deg);
2807
+ -webkit-transform: rotate(-180deg);
2808
+ -o-transform: rotate(-180deg);
2809
+ transform: rotate(-180deg);
2810
+ }
2811
+ 100% {
2812
+ -ms-transform: rotate(-360deg);
2813
+ -moz-transform: rotate(-360deg);
2814
+ -webkit-transform: rotate(-360deg);
2815
+ -o-transform: rotate(-360deg);
2816
+ transform: rotate(-360deg);
2817
+ }
2818
+ }
2819
+
2820
+ @keyframes fwRotateReverse180 {
2821
+ 0% {
2822
+ -ms-transform: rotate(0deg);
2823
+ -moz-transform: rotate(0deg);
2824
+ -webkit-transform: rotate(0deg);
2825
+ -o-transform: rotate(0deg);
2826
+ transform: rotate(0deg);
2827
+ }
2828
+ 50% {
2829
+ -ms-transform: rotate(-180deg);
2830
+ -moz-transform: rotate(-180deg);
2831
+ -webkit-transform: rotate(-180deg);
2832
+ -o-transform: rotate(-180deg);
2833
+ transform: rotate(-180deg);
2834
+ }
2835
+ 100% {
2836
+ -ms-transform: rotate(-360deg);
2837
+ -moz-transform: rotate(-360deg);
2838
+ -webkit-transform: rotate(-360deg);
2839
+ -o-transform: rotate(-360deg);
2840
+ transform: rotate(-360deg);
2841
+ }
2842
+ }
2843
+
2844
+ .fw-animation-rotate-reverse-180 {
2845
+ -webkit-animation: fwRotateReverse180 2s ease infinite;
2846
+ -moz-animation: fwRotateReverse180 2s ease infinite;
2847
+ -ms-animation: fwRotateReverse180 2s ease infinite;
2848
+ -o-animation: fwRotateReverse180 2s ease infinite;
2849
+ animation: fwRotateReverse180 2s ease infinite;
2850
+ }
2851
+
2852
+ /* end: fwReverseRotate180 */
2853
+
2854
  /* end: Animations */
2855
 
2856
 
2894
  }
2895
 
2896
  .fw-modal.fw-modal-open > .media-modal > .media-modal-content {
 
 
 
2897
  -webkit-animation: fwGrowIn .3s ease-in-out;
 
 
2898
  -moz-animation: fwGrowIn .3s ease-in-out;
 
 
 
 
 
2899
  -ms-animation: fwGrowIn .3s ease-in-out;
2900
+ -o-animation: fwGrowIn .3s ease-in-out;
2901
+ animation: fwGrowIn .3s ease-in-out;
2902
  }
2903
 
2904
  .fw-modal > .media-modal > .media-modal-close {
2924
  }
2925
 
2926
  .fw-modal.fw-modal-closing > .media-modal > .media-modal-content {
 
 
 
2927
  -webkit-animation: fwGrowOut .3s ease-in-out;
 
 
2928
  -moz-animation: fwGrowOut .3s ease-in-out;
 
 
 
 
 
2929
  -ms-animation: fwGrowOut .3s ease-in-out;
2930
+ -o-animation: fwGrowOut .3s ease-in-out;
2931
+ animation: fwGrowOut .3s ease-in-out;
2932
 
2933
  -webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
2934
  animation-fill-mode: forwards;
3140
  }
3141
 
3142
  /* end: qtip-fw (x) button */
3143
+
3144
+
3145
+ /* fw.loading */
3146
+
3147
+ #fw-loading {
3148
+ position: fixed;
3149
+ top: 50px;
3150
+ right: 50px;
3151
+ bottom: 50px;
3152
+ left: 50px;
3153
+ z-index: 9999999;
3154
+ text-align: center;
3155
+ }
3156
+
3157
+ #fw-loading.opening {
3158
+ -webkit-animation: fwGrowIn .3s ease-in-out;
3159
+ -moz-animation: fwGrowIn .3s ease-in-out;
3160
+ -ms-animation: fwGrowIn .3s ease-in-out;
3161
+ -o-animation: fwGrowIn .3s ease-in-out;
3162
+ animation: fwGrowIn .3s ease-in-out;
3163
+ }
3164
+
3165
+ #fw-loading.closing {
3166
+ -webkit-animation: fwGrowOut .3s ease-in-out;
3167
+ -moz-animation: fwGrowOut .3s ease-in-out;
3168
+ -ms-animation: fwGrowOut .3s ease-in-out;
3169
+ -o-animation: fwGrowOut .3s ease-in-out;
3170
+ animation: fwGrowOut .3s ease-in-out;
3171
+
3172
+ -webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
3173
+ animation-fill-mode: forwards;
3174
+ }
3175
+
3176
+ #fw-loading.closed {
3177
+ display: none;
3178
+ }
3179
+
3180
+ #fw-loading img {
3181
+ opacity: .4;
3182
+ }
3183
+
3184
+ /* end: fw.loading */
framework/static/img/logo-100.png ADDED
Binary file
framework/static/img/logo.svg ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generated by IcoMoon.io -->
3
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="34" height="32" viewBox="0 0 34 32">
5
+ <path fill="#444444" d="M23.375 0c5.875 0 10.625 4.688 10.625 10.438v19.563l-4.969 2-5.031-2v-21.063c-0.031-1.188-0.281-1.563-1.188-2.188-0.906 0.594-0.75 1.063-0.813 2.188v13.063c-0.25 5.531-3.656 10-11.375 10-5.875 0-10.625-2.75-10.625-10v-20.031l4.969-1.969 5.031 2v19.469s-0.281 3.938 1.188 3.938c1.094-1.125 0.813-3.938 0.813-3.938v-11.469c0.25-5.531 5.688-10 11.375-10zM2.469 3.188l2.5 1.5 2.219-1.313-2.219-1.219zM9.281 30.031c6.688 0 6.5-8.156 6.5-8.156-0.031-0.281 0.219-11.563 0.219-11.875 0-3.781 1.688-6.094 3.75-7.719-2.875 1.438-5.594 4.375-5.75 7.719v13.75c-0.219 2.563-2.156 4.25-4.781 4.25-2.875 0-5.063-2.531-5.219-5.5v-15.875l-2-1.375v16.75s-0.188 6.813 5.75 7.875c0.5 0.094 1.031 0.156 1.531 0.156zM32 28.625v-18.625c0-4-2.125-6.063-5.781-7.281-0.469-0.094-1-0.156-1.5-0.156-4.219 0-6.719 3.281-6.719 7.438v12.219c0 3.094-1.344 6.969-4 7.781 4.531-1.344 6-4.938 6-8v-13.375c0.219-2.563 2.125-4.25 4.781-4.25s5 1.688 5.219 4.25v20.875zM8.938 26l0.375-0.031c-0.75-0.406-1.281-1.188-1.313-2.75v-17.969l-2 1.375v14.844s0.313 4.531 2.938 4.531zM28 29.5v-20.563c-0.125-1.813-1.313-2.781-3.219-2.781l-0.375 0.031c0.875 0.875 1.563 1.438 1.594 2.75v19.688z"></path>
6
+ </svg>
framework/static/js/backend-options.js CHANGED
@@ -36,7 +36,6 @@ jQuery(document).ready(function($){
36
  * (fork from /wp-admin/js/postbox.js)
37
  */
38
  function addPostboxToggles($boxes) {
39
-
40
  /** Remove events added by /wp-admin/js/postbox.js */
41
  $boxes.find('h3, .handlediv').off('click.postboxes');
42
 
@@ -81,11 +80,10 @@ jQuery(document).ready(function($){
81
 
82
  /** Init tabs */
83
  fwEvents.on('fw:options:init', function (data) {
84
- var $elements = data.$elements.find('.fw-options-tabs-wrapper:not(.fw-option-initialized)');
85
 
86
  if ($elements.length) {
87
  $elements.tabs();
88
- $elements.addClass('fw-option-initialized');
89
 
90
  $elements.each(function(){
91
  var $this = $(this);
@@ -95,19 +93,14 @@ jQuery(document).ready(function($){
95
  $this.addClass('fw-options-tabs-first-level');
96
  }
97
  });
 
 
98
  }
99
  });
100
 
101
  /** Init boxes */
102
  fwEvents.on('fw:options:init', function (data) {
103
- var $boxes = data.$elements.find('.fw-postbox:not(.fw-postbox-initialized)');
104
-
105
- /**
106
- * leave open only first boxes
107
- */
108
- $boxes.filter('.fw-backend-postboxes > .fw-postbox:not(:first-child):not(.prevent-auto-close)').addClass('closed');
109
-
110
- $boxes.addClass('fw-postbox-initialized');
111
 
112
  hideBoxEmptyTitles(
113
  $boxes.filter('.fw-backend-postboxes > .fw-postbox')
@@ -115,10 +108,26 @@ jQuery(document).ready(function($){
115
 
116
  addPostboxToggles($boxes);
117
 
 
 
 
 
 
 
 
 
 
118
  // trigger on box custom event for others to do something after box initialized
119
  $boxes.trigger('fw-options-box:initialized');
120
  });
121
 
 
 
 
 
 
 
 
122
  /** Fixes */
123
  fwEvents.on('fw:options:init', function (data) {
124
  /** add special class to first level postboxes that contains framework options */
36
  * (fork from /wp-admin/js/postbox.js)
37
  */
38
  function addPostboxToggles($boxes) {
 
39
  /** Remove events added by /wp-admin/js/postbox.js */
40
  $boxes.find('h3, .handlediv').off('click.postboxes');
41
 
80
 
81
  /** Init tabs */
82
  fwEvents.on('fw:options:init', function (data) {
83
+ var $elements = data.$elements.find('.fw-options-tabs-wrapper:not(.initialized)');
84
 
85
  if ($elements.length) {
86
  $elements.tabs();
 
87
 
88
  $elements.each(function(){
89
  var $this = $(this);
93
  $this.addClass('fw-options-tabs-first-level');
94
  }
95
  });
96
+
97
+ $elements.addClass('initialized');
98
  }
99
  });
100
 
101
  /** Init boxes */
102
  fwEvents.on('fw:options:init', function (data) {
103
+ var $boxes = data.$elements.find('.fw-postbox:not(.initialized)');
 
 
 
 
 
 
 
104
 
105
  hideBoxEmptyTitles(
106
  $boxes.filter('.fw-backend-postboxes > .fw-postbox')
108
 
109
  addPostboxToggles($boxes);
110
 
111
+ /**
112
+ * leave open only first boxes
113
+ */
114
+ $boxes
115
+ .filter('.fw-backend-postboxes > .fw-postbox:not(.fw-postbox-without-name):not(:first-child):not(.prevent-auto-close)')
116
+ .addClass('closed');
117
+
118
+ $boxes.addClass('initialized');
119
+
120
  // trigger on box custom event for others to do something after box initialized
121
  $boxes.trigger('fw-options-box:initialized');
122
  });
123
 
124
+ /** Init options */
125
+ fwEvents.on('fw:options:init', function (data) {
126
+ data.$elements.find('.fw-backend-option:not(.initialized)')
127
+ // do nothing, just a the initialized class to make the fadeIn css animation effect
128
+ .addClass('initialized');
129
+ });
130
+
131
  /** Fixes */
132
  fwEvents.on('fw:options:init', function (data) {
133
  /** add special class to first level postboxes that contains framework options */
framework/static/js/fw-events.js CHANGED
@@ -47,6 +47,8 @@ var fwEvents = new (function(){
47
  */
48
  this.debug = function(enabled) {
49
  debug = Boolean(enabled);
 
 
50
  };
51
 
52
  /**
@@ -55,19 +57,19 @@ var fwEvents = new (function(){
55
  this.on = function(event, callback, context) {
56
  eventsBox.on(event, callback, context);
57
 
58
- if (!debug) {
59
- return;
 
 
 
 
 
 
 
 
60
  }
61
 
62
- if (typeof event == 'string') {
63
- // .on('event:name', callback)
64
- log('✚ '+ event);
65
- } else {
66
- // .on({'event:name': callback})
67
- _.each(event, function(_callback, _event){
68
- log('✚ '+ _event);
69
- });
70
- }
71
  };
72
 
73
  /**
@@ -76,19 +78,19 @@ var fwEvents = new (function(){
76
  this.one = function(event, callback, context) {
77
  eventsBox.once(event, callback);
78
 
79
- if (!debug) {
80
- return;
 
 
 
 
 
 
 
 
81
  }
82
 
83
- if (typeof event == 'string') {
84
- // .one('event:name', callback)
85
- log('✚ ['+ event +']');
86
- } else {
87
- // .one({'event:name': callback})
88
- _.each(event, function(_callback, _event){
89
- log('✚ ['+ _event +']');
90
- });
91
- }
92
  };
93
 
94
  /**
@@ -97,11 +99,11 @@ var fwEvents = new (function(){
97
  this.off = function(event, callback, context) {
98
  eventsBox.off(event, callback, context);
99
 
100
- if (!debug) {
101
- return;
102
  }
103
 
104
- log('✖ '+ event);
105
  };
106
 
107
  /**
@@ -129,6 +131,8 @@ var fwEvents = new (function(){
129
  changeIndentation(-1);
130
 
131
  log('╰─ '+ event, data);
 
 
132
  };
133
 
134
  /**
47
  */
48
  this.debug = function(enabled) {
49
  debug = Boolean(enabled);
50
+
51
+ return this;
52
  };
53
 
54
  /**
57
  this.on = function(event, callback, context) {
58
  eventsBox.on(event, callback, context);
59
 
60
+ if (debug) {
61
+ if (typeof event == 'string') {
62
+ // .on('event:name', callback)
63
+ log('✚ '+ event);
64
+ } else {
65
+ // .on({'event:name': callback})
66
+ _.each(event, function(_callback, _event){
67
+ log('✚ '+ _event);
68
+ });
69
+ }
70
  }
71
 
72
+ return this;
 
 
 
 
 
 
 
 
73
  };
74
 
75
  /**
78
  this.one = function(event, callback, context) {
79
  eventsBox.once(event, callback);
80
 
81
+ if (debug) {
82
+ if (typeof event == 'string') {
83
+ // .one('event:name', callback)
84
+ log('✚ ['+ event +']');
85
+ } else {
86
+ // .one({'event:name': callback})
87
+ _.each(event, function(_callback, _event){
88
+ log('✚ ['+ _event +']');
89
+ });
90
+ }
91
  }
92
 
93
+ return this;
 
 
 
 
 
 
 
 
94
  };
95
 
96
  /**
99
  this.off = function(event, callback, context) {
100
  eventsBox.off(event, callback, context);
101
 
102
+ if (debug) {
103
+ log('✖ '+ event);
104
  }
105
 
106
+ return this;
107
  };
108
 
109
  /**
131
  changeIndentation(-1);
132
 
133
  log('╰─ '+ event, data);
134
+
135
+ return this;
136
  };
137
 
138
  /**
framework/static/js/fw-form-helpers.js CHANGED
@@ -82,28 +82,28 @@ var fwForm = {
82
  e.preventDefault();
83
 
84
  if (isBusy) {
85
- console.warn('Working... Try again later.')
86
  return;
87
  }
88
 
89
  var $form = jQuery(this);
90
 
91
  if (!$form.is('form[data-fw-form-id]')) {
92
- console.error('This is not a FW_Form');
93
  return;
94
  }
95
 
96
  // get submit button
97
  {
98
- var $submitButton = $form.find('input[type="submit"][name]:focus')
99
 
100
  if (!$submitButton.length) {
101
  // in case you use this solution http://stackoverflow.com/a/5721762
102
- $submitButton = $form.find('input[type="submit"][name][clicked]');
103
  }
104
 
105
  // make sure to remove the "clicked" attribute to prevent accidental settings reset
106
- $form.find('input[type="submit"][name][clicked]').removeAttr('clicked');
107
  }
108
 
109
  var elements = {
82
  e.preventDefault();
83
 
84
  if (isBusy) {
85
+ console.warn('Working... Try again later.');
86
  return;
87
  }
88
 
89
  var $form = jQuery(this);
90
 
91
  if (!$form.is('form[data-fw-form-id]')) {
92
+ console.error('This is not a FW_Form', 'Selector:'. opts.selector, 'Form:', $form);
93
  return;
94
  }
95
 
96
  // get submit button
97
  {
98
+ var $submitButton = $form.find(':submit:focus');
99
 
100
  if (!$submitButton.length) {
101
  // in case you use this solution http://stackoverflow.com/a/5721762
102
+ $submitButton = $form.find('[clicked]:submit');
103
  }
104
 
105
  // make sure to remove the "clicked" attribute to prevent accidental settings reset
106
+ $form.find('[clicked]:submit').removeAttr('clicked');
107
  }
108
 
109
  var elements = {
framework/static/js/fw.js CHANGED
@@ -21,7 +21,8 @@ fw.SITE_URI = _fw_localized.SITE_URI;
21
  * Useful images
22
  */
23
  fw.img = {
24
- loadingSpinner: fw.SITE_URI + '/wp-admin/images/spinner.gif'
 
25
  };
26
 
27
  /**
@@ -29,8 +30,7 @@ fw.img = {
29
  * Like intval() in php. Returns 0 on failure, not NaN
30
  * @param val
31
  */
32
- fw.intval = function(val)
33
- {
34
  val = parseInt(val);
35
 
36
  return !isNaN(val) ? val : 0;
@@ -225,108 +225,215 @@ fw.md5 = (function(){
225
  })();
226
 
227
  /**
228
- * Show/Hide loading on page
 
 
 
 
 
229
  */
230
- fw.loading = new (function()
231
- {
232
- var $ = jQuery;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
 
234
- /** DOM element */
235
- var $loading = $('<div></div>')
236
 
237
- /** Current state */
238
- var isLoading = false;
 
 
 
 
 
 
 
 
239
 
240
- /** Prevent infinite loading if some error */
241
- var loadingTimeoutId = 0;
 
 
242
 
243
- /** After that time, loading will hide automaticaly */
244
- var loadingTimeout = 30 * 1000;
245
 
246
- /**
247
- * How many times show() was called
248
- * This prevent this situation: 2 sripts called show(), first finishes execution and calls hide(),
249
- * but the loading needs to remain until the second script will tell it to hide()
250
- */
251
- var loadingStackSize = 0;
252
 
253
- var setAutoHideTimeout = function()
254
- {
255
- clearTimeout(loadingTimeoutId);
256
 
257
- loadingTimeoutId = setTimeout(function(){
258
- console.log('[Warning] Loading timeout. Auto hidding. Probably happend an error and hide cannot be done.');
259
 
260
- that.hide();
261
- }, loadingTimeout);
262
- };
263
 
264
- /** Public Methods */
265
- {
266
- this.show = function()
267
- {
268
- if (isLoading) {
269
- loadingStackSize++;
270
- return;
271
  }
272
 
273
- setAutoHideTimeout();
274
 
275
- $loading.stop(true);
276
- $loading.fadeIn();
 
 
 
 
 
 
 
 
 
277
 
278
- loadingStackSize++;
279
 
280
- isLoading = true;
281
- };
282
 
283
- this.hide = function()
284
- {
285
- if (!isLoading) {
286
- return;
 
 
 
 
 
 
 
 
 
287
  }
288
 
289
- loadingStackSize--;
290
 
291
- if (loadingStackSize < 0) {
292
- loadingStackSize = 0;
 
 
 
 
 
 
 
 
 
 
 
 
293
  }
294
 
295
- if (loadingStackSize == 0) {
296
- clearTimeout(loadingTimeoutId);
 
297
 
298
- $loading.stop(true);
299
- $loading.fadeOut('fast');
300
 
301
- isLoading = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
302
  } else {
303
- setAutoHideTimeout();
 
 
304
  }
305
- };
306
- }
307
 
308
- var that = this;
309
 
310
- /** Init */
311
- {
312
- $loading.css({
313
- 'position': 'fixed',
314
- 'top': '0',
315
- 'left': '0',
316
- 'height': '100%',
317
- 'width': '100%',
318
- 'z-index': '9999999',
319
- 'display': 'none',
320
- 'background-image': 'url('+ fw.img.loadingSpinner +')',
321
- 'background-repeat': 'no-repeat',
322
- 'background-position': 'center center'
323
- });
324
 
325
- $(document).ready(function(){
326
- $(document.body).prepend($loading);
327
- });
328
- }
329
- })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
 
331
  /**
332
  * Capitalizes the first letter of a string.
@@ -454,25 +561,27 @@ fw.getQueryString = function(name) {
454
  };
455
 
456
  (function(){
457
- /*
458
- * A stack-like structure to manage chains of modals
459
- * (modals that are opened one from another)
460
- */
461
- var modalsStack = {
462
- _stack: [],
463
- push: function(modal) {
464
- this._stack.push(modal);
465
- },
466
- pop: function() {
467
- return this._stack.pop();
468
- },
469
- peek: function() {
470
- return this._stack[this._stack.length - 1];
 
 
 
 
 
471
  },
472
- getSize: function() {
473
- return this._stack.length;
474
- }
475
- };
476
 
477
  var ContentView = Backbone.View.extend({
478
  tagName: 'form',
@@ -504,7 +613,7 @@ fw.getQueryString = function(name) {
504
  onSubmit: function(e) {
505
  e.preventDefault();
506
 
507
- fw.loading.show();
508
 
509
  jQuery.ajax({
510
  url: ajaxurl,
@@ -517,7 +626,7 @@ fw.getQueryString = function(name) {
517
  ].join('&'),
518
  dataType: 'json',
519
  success: _.bind(function (response, status, xhr) {
520
- fw.loading.hide();
521
 
522
  if (!response.success) {
523
  /**
@@ -535,7 +644,7 @@ fw.getQueryString = function(name) {
535
  this.model.frame.modal.$el.find('.media-modal-close').trigger('click');
536
  }, this),
537
  error: function (xhr, status, error) {
538
- fw.loading.hide();
539
 
540
  /**
541
  * do not replace html here
@@ -811,8 +920,20 @@ fw.getQueryString = function(name) {
811
 
812
  this.updateHtml();
813
  },
 
 
 
 
 
814
  updateHtml: function() {
815
- fw.loading.show();
 
 
 
 
 
 
 
816
 
817
  this.set('html', '');
818
 
@@ -832,17 +953,19 @@ fw.getQueryString = function(name) {
832
  },
833
  dataType: 'json',
834
  success: function (response, status, xhr) {
835
- fw.loading.hide();
836
 
837
  if (!response.success) {
838
  modal.set('html', 'Error: '+ response.data.message);
839
  return;
840
  }
841
 
 
 
842
  modal.set('html', response.data.html);
843
  },
844
  error: function (xhr, status, error) {
845
- fw.loading.hide();
846
 
847
  modal.set('html', status+ ': '+ error.message);
848
  }
@@ -852,7 +975,6 @@ fw.getQueryString = function(name) {
852
  * Resize .fw-options-tabs-contents to fit entire window
853
  */
854
  resizeTabsContent: function () {
855
-
856
  var $content, $frame;
857
 
858
  $content = this.frame.$el.find('.fw-options-tabs-first-level > .fw-options-tabs-contents');
@@ -876,7 +998,6 @@ fw.getQueryString = function(name) {
876
  $frame.css('overflow-y', 'hidden');
877
  }
878
  });
879
-
880
  })();
881
 
882
  /*!
@@ -1458,7 +1579,7 @@ fw.soleModal = (function(){
1458
 
1459
  if (!this.current) {
1460
  // nothing to hide
1461
- return this.runPendingMethod();;
1462
  }
1463
 
1464
  this.currentMethod = 'hide';
@@ -1562,4 +1683,4 @@ fw.soleModal = (function(){
1562
  return html.join('');
1563
  }
1564
  };
1565
- })();
21
  * Useful images
22
  */
23
  fw.img = {
24
+ loadingSpinner: fw.SITE_URI +'/wp-admin/images/spinner.gif',
25
+ logoSvg: fw.FW_URI +'/static/img/logo.svg'
26
  };
27
 
28
  /**
30
  * Like intval() in php. Returns 0 on failure, not NaN
31
  * @param val
32
  */
33
+ fw.intval = function(val) {
 
34
  val = parseInt(val);
35
 
36
  return !isNaN(val) ? val : 0;
225
  })();
226
 
227
  /**
228
+ * fw.loading
229
+ * Show/Hide loading on the page
230
+ *
231
+ * Usage:
232
+ * - fw.loading.show('unique-id');
233
+ * - fw.loading.hide('unique-id');
234
  */
235
+ (function($){
236
+ var inst = {
237
+ $el: null,
238
+ queue: [],
239
+ current: null,
240
+ timeoutId: 0,
241
+ pendingHide: false,
242
+ $getEl: function(){
243
+ if (this.$el === null) { // lazy init
244
+ this.$el = $(
245
+ '<div id="fw-loading" style="display: none;">'+
246
+ '<table width="100%" height="100%"><tbody><tr><td valign="middle" align="center">'+
247
+ '<img src="'+ fw.img.logoSvg +'"'+
248
+ ' width="30"'+
249
+ ' class="fw-animation-rotate-reverse-180"'+
250
+ ' alt="Loading"' +
251
+ ' onerror="this.onerror=null; this.src=\''+ fw.FW_URI +'/static/img/logo-100.png\';"'+
252
+ ' />'+
253
+ '</td></tr></tbody></table>'+
254
+ '</div>'
255
+ );
256
 
257
+ $(document.body).prepend(this.$el);
258
+ }
259
 
260
+ return this.$el;
261
+ },
262
+ removeFromQueue: function(id) {
263
+ this.queue = _.filter(this.queue, function (item) {
264
+ return item.id != id;
265
+ });
266
+ },
267
+ show: function(id, opts) {
268
+ if (typeof id != 'undefined') {
269
+ this.removeFromQueue(id);
270
 
271
+ {
272
+ opts = jQuery.extend({
273
+ autoClose: 30000
274
+ }, opts || {});
275
 
276
+ opts.id = id;
 
277
 
278
+ /**
279
+ * @type {string} pending|opening|open|closing
280
+ */
281
+ opts.state = 'pending';
282
+ }
 
283
 
284
+ this.queue.push(opts);
 
 
285
 
286
+ return this.show();
287
+ }
288
 
289
+ if (this.current) {
290
+ return false;
291
+ }
292
 
293
+ this.current = this.queue.shift();
294
+
295
+ if (!this.current) {
296
+ return false;
 
 
 
297
  }
298
 
299
+ this.current.state = 'opening';
300
 
301
+ {
302
+ clearTimeout(this.timeoutId);
303
+
304
+ this.timeoutId = setTimeout(_.bind(function(){
305
+ if (
306
+ !this.current
307
+ ||
308
+ this.current.state != 'opening'
309
+ ) {
310
+ return;
311
+ }
312
 
313
+ this.current.state = 'open';
314
 
315
+ this.$getEl().removeClass('opening closing closed').addClass('open');
 
316
 
317
+ if (this.current.autoClose) {
318
+ clearTimeout(this.timeoutId);
319
+
320
+ this.timeoutId = setTimeout(_.bind(function(){
321
+ this.hide();
322
+ }, this), this.current.autoClose);
323
+ }
324
+
325
+ if (this.pendingHide) {
326
+ this.pendingHide = false;
327
+ this.hide();
328
+ }
329
+ }, this), 300);
330
  }
331
 
332
+ this.$getEl().removeClass('open closing closed').addClass('opening').show();
333
 
334
+ return true;
335
+ },
336
+ hide: function(id) {
337
+ if (typeof id != 'undefined') {
338
+ if (
339
+ this.current
340
+ &&
341
+ this.current.id == id
342
+ ) {
343
+ // the script below will handle this
344
+ } else {
345
+ this.removeFromQueue(id);
346
+ return true;
347
+ }
348
  }
349
 
350
+ if (!this.current) {
351
+ return false;
352
+ }
353
 
354
+ var forceClose = false;
 
355
 
356
+ if (this.current.state == 'opening') {
357
+ if (this.current.id == id) {
358
+ /**
359
+ * If the currently opening loading was requested to hide
360
+ * hide it immediately, do not wait full open.
361
+ * Maybe the script that started the loading was executed so quickly
362
+ * so the user don't event need to see the loading.
363
+ */
364
+ // do nothing here, just allow the close script below to be executed
365
+ forceClose = true;
366
+ } else {
367
+ this.pendingHide = true;
368
+ return true;
369
+ }
370
  } else {
371
+ if (this.current.state != 'open') {
372
+ return false;
373
+ }
374
  }
 
 
375
 
376
+ this.current.state = 'closing';
377
 
378
+ {
379
+ clearTimeout(this.timeoutId);
380
+
381
+ this.timeoutId = setTimeout(_.bind(function () {
382
+ if (
383
+ !this.current
384
+ ||
385
+ this.current.state != 'closing'
386
+ ) {
387
+ return;
388
+ }
 
 
 
389
 
390
+ this.current.state = 'closed';
391
+
392
+ this.$getEl().hide().removeClass('opening open closing').addClass('closed');
393
+
394
+ this.current = null;
395
+
396
+ this.show();
397
+ }, this), 300);
398
+ }
399
+
400
+ if (forceClose) {
401
+ this.$getEl().fadeOut('fast', _.bind(function(){
402
+ this.$getEl().removeClass('force-closing').addClass('closed').removeAttr('style');
403
+ }, this));
404
+
405
+ this.$getEl().addClass('force-closing');
406
+ }
407
+
408
+ this.$getEl().removeClass('closed').addClass('closing');
409
+ }
410
+ };
411
+
412
+ fw.loading = {
413
+ show: function(id, opts) {
414
+ /**
415
+ * Compatibility with old version of fw.loading.show()
416
+ * which didn't had the (id,opts) parameters
417
+ */
418
+ if (typeof id == 'undefined') {
419
+ id = 'main';
420
+ }
421
+
422
+ return inst.show(id, opts);
423
+ },
424
+ hide: function(id) {
425
+ /**
426
+ * Compatibility with old version of fw.loading.hide()
427
+ * which didn't had the (id) parameter
428
+ */
429
+ if (typeof id == 'undefined') {
430
+ id = 'main';
431
+ }
432
+
433
+ return inst.hide(id);
434
+ }
435
+ };
436
+ })(jQuery);
437
 
438
  /**
439
  * Capitalizes the first letter of a string.
561
  };
562
 
563
  (function(){
564
+ var fwLoadingId = 'fw-options-modal',
565
+ /*
566
+ * A stack-like structure to manage chains of modals
567
+ * (modals that are opened one from another)
568
+ */
569
+ modalsStack = {
570
+ _stack: [],
571
+ push: function(modal) {
572
+ this._stack.push(modal);
573
+ },
574
+ pop: function() {
575
+ return this._stack.pop();
576
+ },
577
+ peek: function() {
578
+ return this._stack[this._stack.length - 1];
579
+ },
580
+ getSize: function() {
581
+ return this._stack.length;
582
+ }
583
  },
584
+ htmlCache = {};
 
 
 
585
 
586
  var ContentView = Backbone.View.extend({
587
  tagName: 'form',
613
  onSubmit: function(e) {
614
  e.preventDefault();
615
 
616
+ fw.loading.show(fwLoadingId);
617
 
618
  jQuery.ajax({
619
  url: ajaxurl,
626
  ].join('&'),
627
  dataType: 'json',
628
  success: _.bind(function (response, status, xhr) {
629
+ fw.loading.hide(fwLoadingId);
630
 
631
  if (!response.success) {
632
  /**
644
  this.model.frame.modal.$el.find('.media-modal-close').trigger('click');
645
  }, this),
646
  error: function (xhr, status, error) {
647
+ fw.loading.hide(fwLoadingId);
648
 
649
  /**
650
  * do not replace html here
920
 
921
  this.updateHtml();
922
  },
923
+ getHtmlCacheId: function() {
924
+ return fw.md5(
925
+ JSON.stringify(this.get('options')) +'~'+ JSON.stringify(this.get('values'))
926
+ );
927
+ },
928
  updateHtml: function() {
929
+ var cacheId = this.getHtmlCacheId();
930
+
931
+ if (typeof htmlCache[cacheId] != 'undefined') {
932
+ this.set('html', htmlCache[cacheId]);
933
+ return;
934
+ }
935
+
936
+ fw.loading.show(fwLoadingId);
937
 
938
  this.set('html', '');
939
 
953
  },
954
  dataType: 'json',
955
  success: function (response, status, xhr) {
956
+ fw.loading.hide(fwLoadingId);
957
 
958
  if (!response.success) {
959
  modal.set('html', 'Error: '+ response.data.message);
960
  return;
961
  }
962
 
963
+ htmlCache[cacheId] = response.data.html;
964
+
965
  modal.set('html', response.data.html);
966
  },
967
  error: function (xhr, status, error) {
968
+ fw.loading.hide(fwLoadingId);
969
 
970
  modal.set('html', status+ ': '+ error.message);
971
  }
975
  * Resize .fw-options-tabs-contents to fit entire window
976
  */
977
  resizeTabsContent: function () {
 
978
  var $content, $frame;
979
 
980
  $content = this.frame.$el.find('.fw-options-tabs-first-level > .fw-options-tabs-contents');
998
  $frame.css('overflow-y', 'hidden');
999
  }
1000
  });
 
1001
  })();
1002
 
1003
  /*!
1579
 
1580
  if (!this.current) {
1581
  // nothing to hide
1582
+ return this.runPendingMethod();
1583
  }
1584
 
1585
  this.currentMethod = 'hide';
1683
  return html.join('');
1684
  }
1685
  };
1686
+ })();
framework/static/libs/selectize/selectize.css CHANGED
@@ -1,6 +1,6 @@
1
  /**
2
- * selectize.css (v0.9.0)
3
- * Copyright (c) 2013 Brian Reavis & contributors
4
  *
5
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
6
  * file except in compliance with the License. You may obtain a copy of the License at:
@@ -15,319 +15,303 @@
15
  */
16
 
17
  .selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder {
18
- visibility: visible !important;
19
- background: #f2f2f2 !important;
20
- background: rgba(0, 0, 0, 0.06) !important;
21
- border: 0 none !important;
22
- -webkit-box-shadow: inset 0 0 12px 4px #ffffff;
23
- box-shadow: inset 0 0 12px 4px #ffffff;
24
  }
25
  .selectize-control.plugin-drag_drop .ui-sortable-placeholder::after {
26
- content: '!';
27
- visibility: hidden;
28
  }
29
  .selectize-control.plugin-drag_drop .ui-sortable-helper {
30
- -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
31
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
32
  }
33
  .selectize-dropdown-header {
34
- position: relative;
35
- padding: 5px 8px;
36
- border-bottom: 1px solid #d0d0d0;
37
- background: #f8f8f8;
38
- -webkit-border-radius: 3px 3px 0 0;
39
- -moz-border-radius: 3px 3px 0 0;
40
- border-radius: 3px 3px 0 0;
41
  }
42
  .selectize-dropdown-header-close {
43
- position: absolute;
44
- right: 8px;
45
- top: 50%;
46
- color: #303030;
47
- opacity: 0.4;
48
- margin-top: -12px;
49
- line-height: 20px;
50
- font-size: 20px !important;
51
  }
52
  .selectize-dropdown-header-close:hover {
53
- color: #000000;
54
  }
55
  .selectize-dropdown.plugin-optgroup_columns .optgroup {
56
- border-right: 1px solid #f2f2f2;
57
- border-top: 0 none;
58
- float: left;
59
- -webkit-box-sizing: border-box;
60
- -moz-box-sizing: border-box;
61
- box-sizing: border-box;
62
  }
63
  .selectize-dropdown.plugin-optgroup_columns .optgroup:last-child {
64
- border-right: 0 none;
65
  }
66
  .selectize-dropdown.plugin-optgroup_columns .optgroup:before {
67
- display: none;
68
  }
69
  .selectize-dropdown.plugin-optgroup_columns .optgroup-header {
70
- border-top: 0 none;
71
  }
72
  .selectize-control.plugin-remove_button [data-value] {
73
- position: relative;
74
- padding-right: 24px !important;
75
  }
76
  .selectize-control.plugin-remove_button [data-value] .remove {
77
- position: absolute;
78
- top: 0;
79
- right: 0;
80
- bottom: 0;
81
- width: 17px;
82
- text-align: center;
83
- font-weight: bold;
84
- font-size: 12px;
85
- color: inherit;
86
- text-decoration: none;
87
- vertical-align: middle;
88
- display: inline-block;
89
- padding: 2px 0 0 0;
90
- border-left: 1px solid #d0d0d0;
91
- -webkit-border-radius: 0 2px 2px 0;
92
- -moz-border-radius: 0 2px 2px 0;
93
- border-radius: 0 2px 2px 0;
94
- -webkit-box-sizing: border-box;
95
- -moz-box-sizing: border-box;
96
- box-sizing: border-box;
 
 
97
  }
98
  .selectize-control.plugin-remove_button [data-value] .remove:hover {
99
- background: rgba(0, 0, 0, 0.05);
100
  }
101
  .selectize-control.plugin-remove_button [data-value].active .remove {
102
- border-left-color: #cacaca;
103
  }
104
  .selectize-control.plugin-remove_button .disabled [data-value] .remove:hover {
105
- background: none;
106
  }
107
  .selectize-control.plugin-remove_button .disabled [data-value] .remove {
108
- border-left-color: #ffffff;
109
  }
110
  .selectize-control {
111
- position: relative;
112
  }
113
  .selectize-dropdown,
114
  .selectize-input,
115
  .selectize-input input {
116
- color: #303030;
117
- font-family: inherit;
118
- font-size: 13px;
119
- line-height: 16px;
120
- -webkit-font-smoothing: inherit;
121
  }
122
  .selectize-input,
123
  .selectize-control.single .selectize-input.input-active {
124
- background: #ffffff;
125
- cursor: text;
126
- display: inline-block;
127
  }
128
  .selectize-input {
129
- border: 1px solid #d0d0d0;
130
- padding: 8px 8px;
131
- display: inline-block;
132
- width: 100%;
133
- overflow: hidden;
134
- position: relative;
135
- z-index: 1;
136
- -webkit-box-sizing: border-box;
137
- -moz-box-sizing: border-box;
138
- box-sizing: border-box;
139
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
140
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
141
- -webkit-border-radius: 3px;
142
- -moz-border-radius: 3px;
143
- border-radius: 3px;
144
-
145
  }
146
  .selectize-control.multi .selectize-input.has-items {
147
- padding: 6px 8px 3px;
148
  }
149
  .selectize-input.full {
150
- background-color: #ffffff;
151
  }
152
  .selectize-input.disabled,
153
  .selectize-input.disabled * {
154
- cursor: default !important;
155
  }
156
  .selectize-input.focus {
157
- -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
158
- box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
159
  }
160
  .selectize-input.dropdown-active {
161
- -webkit-border-radius: 3px 3px 0 0;
162
- -moz-border-radius: 3px 3px 0 0;
163
- border-radius: 3px 3px 0 0;
164
  }
165
  .selectize-input > * {
166
- vertical-align: baseline;
167
- display: -moz-inline-stack;
168
- display: inline-block;
169
- zoom: 1;
170
- *display: inline;
171
  }
172
  .selectize-control.multi .selectize-input > div {
173
- cursor: pointer;
174
- margin: 0 3px 3px 0;
175
- padding: 2px 6px;
176
- background: #f2f2f2;
177
- color: #303030;
178
- border: 0 solid #d0d0d0;
179
  }
180
  .selectize-control.multi .selectize-input > div.active {
181
- background: #e8e8e8;
182
- color: #303030;
183
- border: 0 solid #cacaca;
184
  }
185
  .selectize-control.multi .selectize-input.disabled > div,
186
  .selectize-control.multi .selectize-input.disabled > div.active {
187
- color: #7d7d7d;
188
- background: #ffffff;
189
- border: 0 solid #ffffff;
190
  }
191
  .selectize-input > input {
192
- padding: 0 !important;
193
- min-height: 0 !important;
194
- max-height: none !important;
195
- max-width: 100% !important;
196
- margin: 0 2px 0 0 !important;
197
- text-indent: 0 !important;
198
- border: 0 none !important;
199
- background: none !important;
200
- line-height: inherit !important;
201
- -webkit-user-select: auto !important;
202
- -webkit-box-shadow: none !important;
203
- box-shadow: none !important;
 
 
 
 
204
  }
205
  .selectize-input > input:focus {
206
- outline: none !important;
207
  }
208
  .selectize-input::after {
209
- content: ' ';
210
- display: block;
211
- clear: left;
212
  }
213
  .selectize-input.dropdown-active::before {
214
- content: ' ';
215
- display: block;
216
- position: absolute;
217
- background: #f0f0f0;
218
- height: 1px;
219
- bottom: 0;
220
- left: 0;
221
- right: 0;
222
  }
223
  .selectize-dropdown {
224
- position: absolute;
225
- z-index: 10;
226
- border: 1px solid #d0d0d0;
227
- background: #ffffff;
228
- margin: -1px 0 0 0;
229
- border-top: 0 none;
230
- -webkit-box-sizing: border-box;
231
- -moz-box-sizing: border-box;
232
- box-sizing: border-box;
233
- -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
234
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
235
- -webkit-border-radius: 0 0 3px 3px;
236
- -moz-border-radius: 0 0 3px 3px;
237
- border-radius: 0 0 3px 3px;
238
  }
239
  .selectize-dropdown [data-selectable] {
240
- cursor: pointer;
241
- overflow: hidden;
242
  }
243
  .selectize-dropdown [data-selectable] .highlight {
244
- background: rgba(125, 168, 208, 0.2);
245
- -webkit-border-radius: 1px;
246
- -moz-border-radius: 1px;
247
- border-radius: 1px;
248
  }
249
  .selectize-dropdown [data-selectable],
250
  .selectize-dropdown .optgroup-header {
251
- padding: 5px 8px;
252
  }
253
  .selectize-dropdown .optgroup:first-child .optgroup-header {
254
- border-top: 0 none;
255
  }
256
  .selectize-dropdown .optgroup-header {
257
- color: #303030;
258
- background: #ffffff;
259
- cursor: default;
260
  }
261
  .selectize-dropdown .active {
262
- background-color: #f5fafd;
263
- color: #495c68;
264
  }
265
  .selectize-dropdown .active.create {
266
- color: #495c68;
267
  }
268
  .selectize-dropdown .create {
269
- color: rgba(48, 48, 48, 0.5);
270
  }
271
  .selectize-dropdown-content {
272
- overflow-y: auto;
273
- overflow-x: hidden;
274
- max-height: 200px;
275
  }
276
  .selectize-control.single .selectize-input,
277
  .selectize-control.single .selectize-input input {
278
- cursor: pointer;
279
  }
280
  .selectize-control.single .selectize-input.input-active,
281
  .selectize-control.single .selectize-input.input-active input {
282
- cursor: text;
283
  }
284
  .selectize-control.single .selectize-input:after {
285
- content: ' ';
286
- display: block;
287
- position: absolute;
288
- top: 50%;
289
- right: 15px;
290
- margin-top: -3px;
291
- width: 0;
292
- height: 0;
293
- border-style: solid;
294
- border-width: 5px 5px 0 5px;
295
- border-color: #808080 transparent transparent transparent;
296
  }
297
  .selectize-control.single .selectize-input.dropdown-active:after {
298
- margin-top: -4px;
299
- border-width: 0 5px 5px 5px;
300
- border-color: transparent transparent #808080 transparent;
301
  }
302
  .selectize-control.rtl.single .selectize-input:after {
303
- left: 15px;
304
- right: auto;
305
  }
306
  .selectize-control.rtl .selectize-input > input {
307
- margin: 0 4px 0 -2px !important;
308
  }
309
  .selectize-control .selectize-input.disabled {
310
- opacity: 0.5;
311
- background-color: #fafafa;
312
  }
313
-
314
- /* fw-selectize style */
315
- .fw-selectize .selectize-input {
316
- -webkit-border-radius: 0px;
317
- -moz-border-radius: 0px;
318
- border-radius: 0px;
319
- padding: 4px !important;
320
- }
321
- .fw-selectize .selectize-input.has-items{
322
- padding: 3px 3px 0px 3px !important;
323
- }
324
- .fw-selectize .selectize-dropdown-header{
325
- -webkit-border-radius: 0px;
326
- -moz-border-radius: 0px;
327
- border-radius: 0px;
328
- }
329
- .fw-selectize .selectize-input .item{
330
- margin: 0px 3px 3px 0px !important;
331
-
332
- }
333
-
1
  /**
2
+ * selectize.css (v0.12.1)
3
+ * Copyright (c) 2013–2015 Brian Reavis & contributors
4
  *
5
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
6
  * file except in compliance with the License. You may obtain a copy of the License at:
15
  */
16
 
17
  .selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder {
18
+ visibility: visible !important;
19
+ background: #f2f2f2 !important;
20
+ background: rgba(0, 0, 0, 0.06) !important;
21
+ border: 0 none !important;
22
+ -webkit-box-shadow: inset 0 0 12px 4px #ffffff;
23
+ box-shadow: inset 0 0 12px 4px #ffffff;
24
  }
25
  .selectize-control.plugin-drag_drop .ui-sortable-placeholder::after {
26
+ content: '!';
27
+ visibility: hidden;
28
  }
29
  .selectize-control.plugin-drag_drop .ui-sortable-helper {
30
+ -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
31
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
32
  }
33
  .selectize-dropdown-header {
34
+ position: relative;
35
+ padding: 5px 8px;
36
+ border-bottom: 1px solid #d0d0d0;
37
+ background: #f8f8f8;
38
+ -webkit-border-radius: 3px 3px 0 0;
39
+ -moz-border-radius: 3px 3px 0 0;
40
+ border-radius: 3px 3px 0 0;
41
  }
42
  .selectize-dropdown-header-close {
43
+ position: absolute;
44
+ right: 8px;
45
+ top: 50%;
46
+ color: #303030;
47
+ opacity: 0.4;
48
+ margin-top: -12px;
49
+ line-height: 20px;
50
+ font-size: 20px !important;
51
  }
52
  .selectize-dropdown-header-close:hover {
53
+ color: #000000;
54
  }
55
  .selectize-dropdown.plugin-optgroup_columns .optgroup {
56
+ border-right: 1px solid #f2f2f2;
57
+ border-top: 0 none;
58
+ float: left;
59
+ -webkit-box-sizing: border-box;
60
+ -moz-box-sizing: border-box;
61
+ box-sizing: border-box;
62
  }
63
  .selectize-dropdown.plugin-optgroup_columns .optgroup:last-child {
64
+ border-right: 0 none;
65
  }
66
  .selectize-dropdown.plugin-optgroup_columns .optgroup:before {
67
+ display: none;
68
  }
69
  .selectize-dropdown.plugin-optgroup_columns .optgroup-header {
70
+ border-top: 0 none;
71
  }
72
  .selectize-control.plugin-remove_button [data-value] {
73
+ position: relative;
74
+ padding-right: 24px !important;
75
  }
76
  .selectize-control.plugin-remove_button [data-value] .remove {
77
+ z-index: 1;
78
+ /* fixes ie bug (see #392) */
79
+ position: absolute;
80
+ top: 0;
81
+ right: 0;
82
+ bottom: 0;
83
+ width: 17px;
84
+ text-align: center;
85
+ font-weight: bold;
86
+ font-size: 12px;
87
+ color: inherit;
88
+ text-decoration: none;
89
+ vertical-align: middle;
90
+ display: inline-block;
91
+ padding: 2px 0 0 0;
92
+ border-left: 1px solid #d0d0d0;
93
+ -webkit-border-radius: 0 2px 2px 0;
94
+ -moz-border-radius: 0 2px 2px 0;
95
+ border-radius: 0 2px 2px 0;
96
+ -webkit-box-sizing: border-box;
97
+ -moz-box-sizing: border-box;
98
+ box-sizing: border-box;
99
  }
100
  .selectize-control.plugin-remove_button [data-value] .remove:hover {
101
+ background: rgba(0, 0, 0, 0.05);
102
  }
103
  .selectize-control.plugin-remove_button [data-value].active .remove {
104
+ border-left-color: #cacaca;
105
  }
106
  .selectize-control.plugin-remove_button .disabled [data-value] .remove:hover {
107
+ background: none;
108
  }
109
  .selectize-control.plugin-remove_button .disabled [data-value] .remove {
110
+ border-left-color: #ffffff;
111
  }
112
  .selectize-control {
113
+ position: relative;
114
  }
115
  .selectize-dropdown,
116
  .selectize-input,
117
  .selectize-input input {
118
+ color: #303030;
119
+ font-family: inherit;
120
+ font-size: 13px;
121
+ line-height: 18px;
122
+ -webkit-font-smoothing: inherit;
123
  }
124
  .selectize-input,
125
  .selectize-control.single .selectize-input.input-active {
126
+ background: #ffffff;
127
+ cursor: text;
128
+ display: inline-block;
129
  }
130
  .selectize-input {
131
+ border: 1px solid #d0d0d0;
132
+ padding: 8px 8px;
133
+ display: inline-block;
134
+ width: 100%;
135
+ overflow: hidden;
136
+ position: relative;
137
+ z-index: 1;
138
+ -webkit-box-sizing: border-box;
139
+ -moz-box-sizing: border-box;
140
+ box-sizing: border-box;
141
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
142
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
143
+ -webkit-border-radius: 3px;
144
+ -moz-border-radius: 3px;
145
+ border-radius: 3px;
 
146
  }
147
  .selectize-control.multi .selectize-input.has-items {
148
+ padding: 6px 8px 3px;
149
  }
150
  .selectize-input.full {
151
+ background-color: #ffffff;
152
  }
153
  .selectize-input.disabled,
154
  .selectize-input.disabled * {
155
+ cursor: default !important;
156
  }
157
  .selectize-input.focus {
158
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
159
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
160
  }
161
  .selectize-input.dropdown-active {
162
+ -webkit-border-radius: 3px 3px 0 0;
163
+ -moz-border-radius: 3px 3px 0 0;
164
+ border-radius: 3px 3px 0 0;
165
  }
166
  .selectize-input > * {
167
+ vertical-align: baseline;
168
+ display: -moz-inline-stack;
169
+ display: inline-block;
170
+ zoom: 1;
171
+ *display: inline;
172
  }
173
  .selectize-control.multi .selectize-input > div {
174
+ cursor: pointer;
175
+ margin: 0 3px 3px 0;
176
+ padding: 2px 6px;
177
+ background: #f2f2f2;
178
+ color: #303030;
179
+ border: 0 solid #d0d0d0;
180
  }
181
  .selectize-control.multi .selectize-input > div.active {
182
+ background: #e8e8e8;
183
+ color: #303030;
184
+ border: 0 solid #cacaca;
185
  }
186
  .selectize-control.multi .selectize-input.disabled > div,
187
  .selectize-control.multi .selectize-input.disabled > div.active {
188
+ color: #7d7d7d;
189
+ background: #ffffff;
190
+ border: 0 solid #ffffff;
191
  }
192
  .selectize-input > input {
193
+ display: inline-block !important;
194
+ padding: 0 !important;
195
+ min-height: 0 !important;
196
+ max-height: none !important;
197
+ max-width: 100% !important;
198
+ margin: 0 2px 0 0 !important;
199
+ text-indent: 0 !important;
200
+ border: 0 none !important;
201
+ background: none !important;
202
+ line-height: inherit !important;
203
+ -webkit-user-select: auto !important;
204
+ -webkit-box-shadow: none !important;
205
+ box-shadow: none !important;
206
+ }
207
+ .selectize-input > input::-ms-clear {
208
+ display: none;
209
  }
210
  .selectize-input > input:focus {
211
+ outline: none !important;
212
  }
213
  .selectize-input::after {
214
+ content: ' ';
215
+ display: block;
216
+ clear: left;
217
  }
218
  .selectize-input.dropdown-active::before {
219
+ content: ' ';
220
+ display: block;
221
+ position: absolute;
222
+ background: #f0f0f0;
223
+ height: 1px;
224
+ bottom: 0;
225
+ left: 0;
226
+ right: 0;
227
  }
228
  .selectize-dropdown {
229
+ position: absolute;
230
+ z-index: 10;
231
+ border: 1px solid #d0d0d0;
232
+ background: #ffffff;
233
+ margin: -1px 0 0 0;
234
+ border-top: 0 none;
235
+ -webkit-box-sizing: border-box;
236
+ -moz-box-sizing: border-box;
237
+ box-sizing: border-box;
238
+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
239
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
240
+ -webkit-border-radius: 0 0 3px 3px;
241
+ -moz-border-radius: 0 0 3px 3px;
242
+ border-radius: 0 0 3px 3px;
243
  }
244
  .selectize-dropdown [data-selectable] {
245
+ cursor: pointer;
246
+ overflow: hidden;
247
  }
248
  .selectize-dropdown [data-selectable] .highlight {
249
+ background: rgba(125, 168, 208, 0.2);
250
+ -webkit-border-radius: 1px;
251
+ -moz-border-radius: 1px;
252
+ border-radius: 1px;
253
  }
254
  .selectize-dropdown [data-selectable],
255
  .selectize-dropdown .optgroup-header {
256
+ padding: 5px 8px;
257
  }
258
  .selectize-dropdown .optgroup:first-child .optgroup-header {
259
+ border-top: 0 none;
260
  }
261
  .selectize-dropdown .optgroup-header {
262
+ color: #303030;
263
+ background: #ffffff;
264
+ cursor: default;
265
  }
266
  .selectize-dropdown .active {
267
+ background-color: #f5fafd;
268
+ color: #495c68;
269
  }
270
  .selectize-dropdown .active.create {
271
+ color: #495c68;
272
  }
273
  .selectize-dropdown .create {
274
+ color: rgba(48, 48, 48, 0.5);
275
  }
276
  .selectize-dropdown-content {
277
+ overflow-y: auto;
278
+ overflow-x: hidden;
279
+ max-height: 200px;
280
  }
281
  .selectize-control.single .selectize-input,
282
  .selectize-control.single .selectize-input input {
283
+ cursor: pointer;
284
  }
285
  .selectize-control.single .selectize-input.input-active,
286
  .selectize-control.single .selectize-input.input-active input {
287
+ cursor: text;
288
  }
289
  .selectize-control.single .selectize-input:after {
290
+ content: ' ';
291
+ display: block;
292
+ position: absolute;
293
+ top: 50%;
294
+ right: 15px;
295
+ margin-top: -3px;
296
+ width: 0;
297
+ height: 0;
298
+ border-style: solid;
299
+ border-width: 5px 5px 0 5px;
300
+ border-color: #808080 transparent transparent transparent;
301
  }
302
  .selectize-control.single .selectize-input.dropdown-active:after {
303
+ margin-top: -4px;
304
+ border-width: 0 5px 5px 5px;
305
+ border-color: transparent transparent #808080 transparent;
306
  }
307
  .selectize-control.rtl.single .selectize-input:after {
308
+ left: 15px;
309
+ right: auto;
310
  }
311
  .selectize-control.rtl .selectize-input > input {
312
+ margin: 0 4px 0 -2px !important;
313
  }
314
  .selectize-control .selectize-input.disabled {
315
+ opacity: 0.5;
316
+ background-color: #fafafa;
317
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
framework/static/libs/selectize/selectize.min.js CHANGED
@@ -1,3 +1,3 @@
1
- /*! selectize.js - v0.12.0 | https://github.com/brianreavis/selectize.js | Apache License (v2) */
2
- !function(a,b){"function"==typeof define&&define.amd?define("sifter",b):"object"==typeof exports?module.exports=b():a.Sifter=b()}(this,function(){var a=function(a,b){this.items=a,this.settings=b||{diacritics:!0}};a.prototype.tokenize=function(a){if(a=d(String(a||"").toLowerCase()),!a||!a.length)return[];var b,c,f,h,i=[],j=a.split(/ +/);for(b=0,c=j.length;c>b;b++){if(f=e(j[b]),this.settings.diacritics)for(h in g)g.hasOwnProperty(h)&&(f=f.replace(new RegExp(h,"g"),g[h]));i.push({string:j[b],regex:new RegExp(f,"i")})}return i},a.prototype.iterator=function(a,b){var c;c=f(a)?Array.prototype.forEach||function(a){for(var b=0,c=this.length;c>b;b++)a(this[b],b,this)}:function(a){for(var b in this)this.hasOwnProperty(b)&&a(this[b],b,this)},c.apply(a,[b])},a.prototype.getScoreFunction=function(a,b){var c,d,e,f;c=this,a=c.prepareSearch(a,b),e=a.tokens,d=a.options.fields,f=e.length;var g=function(a,b){var c,d;return a?(a=String(a||""),d=a.search(b.regex),-1===d?0:(c=b.string.length/a.length,0===d&&(c+=.5),c)):0},h=function(){var a=d.length;return a?1===a?function(a,b){return g(b[d[0]],a)}:function(b,c){for(var e=0,f=0;a>e;e++)f+=g(c[d[e]],b);return f/a}:function(){return 0}}();return f?1===f?function(a){return h(e[0],a)}:"and"===a.options.conjunction?function(a){for(var b,c=0,d=0;f>c;c++){if(b=h(e[c],a),0>=b)return 0;d+=b}return d/f}:function(a){for(var b=0,c=0;f>b;b++)c+=h(e[b],a);return c/f}:function(){return 0}},a.prototype.getSortFunction=function(a,c){var d,e,f,g,h,i,j,k,l,m,n;if(f=this,a=f.prepareSearch(a,c),n=!a.query&&c.sort_empty||c.sort,l=function(a,b){return"$score"===a?b.score:f.items[b.id][a]},h=[],n)for(d=0,e=n.length;e>d;d++)(a.query||"$score"!==n[d].field)&&h.push(n[d]);if(a.query){for(m=!0,d=0,e=h.length;e>d;d++)if("$score"===h[d].field){m=!1;break}m&&h.unshift({field:"$score",direction:"desc"})}else for(d=0,e=h.length;e>d;d++)if("$score"===h[d].field){h.splice(d,1);break}for(k=[],d=0,e=h.length;e>d;d++)k.push("desc"===h[d].direction?-1:1);return i=h.length,i?1===i?(g=h[0].field,j=k[0],function(a,c){return j*b(l(g,a),l(g,c))}):function(a,c){var d,e,f;for(d=0;i>d;d++)if(f=h[d].field,e=k[d]*b(l(f,a),l(f,c)))return e;return 0}:null},a.prototype.prepareSearch=function(a,b){if("object"==typeof a)return a;b=c({},b);var d=b.fields,e=b.sort,g=b.sort_empty;return d&&!f(d)&&(b.fields=[d]),e&&!f(e)&&(b.sort=[e]),g&&!f(g)&&(b.sort_empty=[g]),{options:b,query:String(a||"").toLowerCase(),tokens:this.tokenize(a),total:0,items:[]}},a.prototype.search=function(a,b){var c,d,e,f,g=this;return d=this.prepareSearch(a,b),b=d.options,a=d.query,f=b.score||g.getScoreFunction(d),a.length?g.iterator(g.items,function(a,e){c=f(a),(b.filter===!1||c>0)&&d.items.push({score:c,id:e})}):g.iterator(g.items,function(a,b){d.items.push({score:1,id:b})}),e=g.getSortFunction(d,b),e&&d.items.sort(e),d.total=d.items.length,"number"==typeof b.limit&&(d.items=d.items.slice(0,b.limit)),d};var b=function(a,b){return"number"==typeof a&&"number"==typeof b?a>b?1:b>a?-1:0:(a=h(String(a||"")),b=h(String(b||"")),a>b?1:b>a?-1:0)},c=function(a){var b,c,d,e;for(b=1,c=arguments.length;c>b;b++)if(e=arguments[b])for(d in e)e.hasOwnProperty(d)&&(a[d]=e[d]);return a},d=function(a){return(a+"").replace(/^\s+|\s+$|/g,"")},e=function(a){return(a+"").replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")},f=Array.isArray||$&&$.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},g={a:"[aÀÁÂÃÄÅàáâãäåĀāąĄ]",c:"[cÇçćĆčČ]",d:"[dđĐďĎ]",e:"[eÈÉÊËèéêëěĚĒēęĘ]",i:"[iÌÍÎÏìíîïĪī]",l:"[lłŁ]",n:"[nÑñňŇńŃ]",o:"[oÒÓÔÕÕÖØòóôõöøŌō]",r:"[rřŘ]",s:"[sŠšśŚ]",t:"[tťŤ]",u:"[uÙÚÛÜùúûüůŮŪū]",y:"[yŸÿýÝ]",z:"[zŽžżŻźŹ]"},h=function(){var a,b,c,d,e="",f={};for(c in g)if(g.hasOwnProperty(c))for(d=g[c].substring(2,g[c].length-1),e+=d,a=0,b=d.length;b>a;a++)f[d.charAt(a)]=c;var h=new RegExp("["+e+"]","g");return function(a){return a.replace(h,function(a){return f[a]}).toLowerCase()}}();return a}),function(a,b){"function"==typeof define&&define.amd?define("microplugin",b):"object"==typeof exports?module.exports=b():a.MicroPlugin=b()}(this,function(){var a={};a.mixin=function(a){a.plugins={},a.prototype.initializePlugins=function(a){var c,d,e,f=this,g=[];if(f.plugins={names:[],settings:{},requested:{},loaded:{}},b.isArray(a))for(c=0,d=a.length;d>c;c++)"string"==typeof a[c]?g.push(a[c]):(f.plugins.settings[a[c].name]=a[c].options,g.push(a[c].name));else if(a)for(e in a)a.hasOwnProperty(e)&&(f.plugins.settings[e]=a[e],g.push(e));for(;g.length;)f.require(g.shift())},a.prototype.loadPlugin=function(b){var c=this,d=c.plugins,e=a.plugins[b];if(!a.plugins.hasOwnProperty(b))throw new Error('Unable to find "'+b+'" plugin');d.requested[b]=!0,d.loaded[b]=e.fn.apply(c,[c.plugins.settings[b]||{}]),d.names.push(b)},a.prototype.require=function(a){var b=this,c=b.plugins;if(!b.plugins.loaded.hasOwnProperty(a)){if(c.requested[a])throw new Error('Plugin has circular dependency ("'+a+'")');b.loadPlugin(a)}return c.loaded[a]},a.define=function(b,c){a.plugins[b]={name:b,fn:c}}};var b={isArray:Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)}};return a}),function(a,b){"function"==typeof define&&define.amd?define("selectize",["jquery","sifter","microplugin"],b):"object"==typeof exports?module.exports=b(require("jquery"),require("sifter"),require("microplugin")):a.Selectize=b(a.jQuery,a.Sifter,a.MicroPlugin)}(this,function(a,b,c){"use strict";var d=function(a,b){if("string"!=typeof b||b.length){var c="string"==typeof b?new RegExp(b,"i"):b,d=function(a){var b=0;if(3===a.nodeType){var e=a.data.search(c);if(e>=0&&a.data.length>0){var f=a.data.match(c),g=document.createElement("span");g.className="highlight";var h=a.splitText(e),i=(h.splitText(f[0].length),h.cloneNode(!0));g.appendChild(i),h.parentNode.replaceChild(g,h),b=1}}else if(1===a.nodeType&&a.childNodes&&!/(script|style)/i.test(a.tagName))for(var j=0;j<a.childNodes.length;++j)j+=d(a.childNodes[j]);return b};return a.each(function(){d(this)})}},e=function(){};e.prototype={on:function(a,b){this._events=this._events||{},this._events[a]=this._events[a]||[],this._events[a].push(b)},off:function(a,b){var c=arguments.length;return 0===c?delete this._events:1===c?delete this._events[a]:(this._events=this._events||{},void(a in this._events!=!1&&this._events[a].splice(this._events[a].indexOf(b),1)))},trigger:function(a){if(this._events=this._events||{},a in this._events!=!1)for(var b=0;b<this._events[a].length;b++)this._events[a][b].apply(this,Array.prototype.slice.call(arguments,1))}},e.mixin=function(a){for(var b=["on","off","trigger"],c=0;c<b.length;c++)a.prototype[b[c]]=e.prototype[b[c]]};var f=/Mac/.test(navigator.userAgent),g=65,h=13,i=27,j=37,k=38,l=80,m=39,n=40,o=78,p=8,q=46,r=16,s=f?91:17,t=f?18:17,u=9,v=1,w=2,x=!/android/i.test(window.navigator.userAgent)&&!!document.createElement("form").validity,y=function(a){return"undefined"!=typeof a},z=function(a){return"undefined"==typeof a||null===a?null:"boolean"==typeof a?a?"1":"0":a+""},A=function(a){return(a+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},B=function(a){return(a+"").replace(/\$/g,"$$$$")},C={};C.before=function(a,b,c){var d=a[b];a[b]=function(){return c.apply(a,arguments),d.apply(a,arguments)}},C.after=function(a,b,c){var d=a[b];a[b]=function(){var b=d.apply(a,arguments);return c.apply(a,arguments),b}};var D=function(a){var b=!1;return function(){b||(b=!0,a.apply(this,arguments))}},E=function(a,b){var c;return function(){var d=this,e=arguments;window.clearTimeout(c),c=window.setTimeout(function(){a.apply(d,e)},b)}},F=function(a,b,c){var d,e=a.trigger,f={};a.trigger=function(){var c=arguments[0];return-1===b.indexOf(c)?e.apply(a,arguments):void(f[c]=arguments)},c.apply(a,[]),a.trigger=e;for(d in f)f.hasOwnProperty(d)&&e.apply(a,f[d])},G=function(a,b,c,d){a.on(b,c,function(b){for(var c=b.target;c&&c.parentNode!==a[0];)c=c.parentNode;return b.currentTarget=c,d.apply(this,[b])})},H=function(a){var b={};if("selectionStart"in a)b.start=a.selectionStart,b.length=a.selectionEnd-b.start;else if(document.selection){a.focus();var c=document.selection.createRange(),d=document.selection.createRange().text.length;c.moveStart("character",-a.value.length),b.start=c.text.length-d,b.length=d}return b},I=function(a,b,c){var d,e,f={};if(c)for(d=0,e=c.length;e>d;d++)f[c[d]]=a.css(c[d]);else f=a.css();b.css(f)},J=function(b,c){if(!b)return 0;var d=a("<test>").css({position:"absolute",top:-99999,left:-99999,width:"auto",padding:0,whiteSpace:"pre"}).text(b).appendTo("body");I(c,d,["letterSpacing","fontSize","fontFamily","fontWeight","textTransform"]);var e=d.width();return d.remove(),e},K=function(a){var b=null,c=function(c,d){var e,f,g,h,i,j,k,l;c=c||window.event||{},d=d||{},c.metaKey||c.altKey||(d.force||a.data("grow")!==!1)&&(e=a.val(),c.type&&"keydown"===c.type.toLowerCase()&&(f=c.keyCode,g=f>=97&&122>=f||f>=65&&90>=f||f>=48&&57>=f||32===f,f===q||f===p?(l=H(a[0]),l.length?e=e.substring(0,l.start)+e.substring(l.start+l.length):f===p&&l.start?e=e.substring(0,l.start-1)+e.substring(l.start+1):f===q&&"undefined"!=typeof l.start&&(e=e.substring(0,l.start)+e.substring(l.start+1))):g&&(j=c.shiftKey,k=String.fromCharCode(c.keyCode),k=j?k.toUpperCase():k.toLowerCase(),e+=k)),h=a.attr("placeholder"),!e&&h&&(e=h),i=J(e,a)+4,i!==b&&(b=i,a.width(i),a.triggerHandler("resize")))};a.on("keydown keyup update blur",c),c()},L=function(c,d){var e,f,g,h,i=this;h=c[0],h.selectize=i;var j=window.getComputedStyle&&window.getComputedStyle(h,null);if(g=j?j.getPropertyValue("direction"):h.currentStyle&&h.currentStyle.direction,g=g||c.parents("[dir]:first").attr("dir")||"",a.extend(i,{order:0,settings:d,$input:c,tabIndex:c.attr("tabindex")||"",tagType:"select"===h.tagName.toLowerCase()?v:w,rtl:/rtl/i.test(g),eventNS:".selectize"+ ++L.count,highlightedValue:null,isOpen:!1,isDisabled:!1,isRequired:c.is("[required]"),isInvalid:!1,isLocked:!1,isFocused:!1,isInputHidden:!1,isSetup:!1,isShiftDown:!1,isCmdDown:!1,isCtrlDown:!1,ignoreFocus:!1,ignoreBlur:!1,ignoreHover:!1,hasOptions:!1,currentResults:null,lastValue:"",caretPos:0,loading:0,loadedSearches:{},$activeOption:null,$activeItems:[],optgroups:{},options:{},userOptions:{},items:[],renderCache:{},onSearchChange:null===d.loadThrottle?i.onSearchChange:E(i.onSearchChange,d.loadThrottle)}),i.sifter=new b(this.options,{diacritics:d.diacritics}),i.settings.options){for(e=0,f=i.settings.options.length;f>e;e++)i.registerOption(i.settings.options[e]);delete i.settings.options}if(i.settings.optgroups){for(e=0,f=i.settings.optgroups.length;f>e;e++)i.registerOptionGroup(i.settings.optgroups[e]);delete i.settings.optgroups}i.settings.mode=i.settings.mode||(1===i.settings.maxItems?"single":"multi"),"boolean"!=typeof i.settings.hideSelected&&(i.settings.hideSelected="multi"===i.settings.mode),i.initializePlugins(i.settings.plugins),i.setupCallbacks(),i.setupTemplates(),i.setup()};return e.mixin(L),c.mixin(L),a.extend(L.prototype,{setup:function(){var b,c,d,e,g,h,i,j,k,l=this,m=l.settings,n=l.eventNS,o=a(window),p=a(document),q=l.$input;if(i=l.settings.mode,j=q.attr("class")||"",b=a("<div>").addClass(m.wrapperClass).addClass(j).addClass(i),c=a("<div>").addClass(m.inputClass).addClass("items").appendTo(b),d=a('<input type="text" autocomplete="off" />').appendTo(c).attr("tabindex",q.is(":disabled")?"-1":l.tabIndex),h=a(m.dropdownParent||b),e=a("<div>").addClass(m.dropdownClass).addClass(i).hide().appendTo(h),g=a("<div>").addClass(m.dropdownContentClass).appendTo(e),l.settings.copyClassesToDropdown&&e.addClass(j),b.css({width:q[0].style.width}),l.plugins.names.length&&(k="plugin-"+l.plugins.names.join(" plugin-"),b.addClass(k),e.addClass(k)),(null===m.maxItems||m.maxItems>1)&&l.tagType===v&&q.attr("multiple","multiple"),l.settings.placeholder&&d.attr("placeholder",m.placeholder),!l.settings.splitOn&&l.settings.delimiter){var u=l.settings.delimiter.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&");l.settings.splitOn=new RegExp("\\s*"+u+"+\\s*")}q.attr("autocorrect")&&d.attr("autocorrect",q.attr("autocorrect")),q.attr("autocapitalize")&&d.attr("autocapitalize",q.attr("autocapitalize")),l.$wrapper=b,l.$control=c,l.$control_input=d,l.$dropdown=e,l.$dropdown_content=g,e.on("mouseenter","[data-selectable]",function(){return l.onOptionHover.apply(l,arguments)}),e.on("mousedown click","[data-selectable]",function(){return l.onOptionSelect.apply(l,arguments)}),G(c,"mousedown","*:not(input)",function(){return l.onItemSelect.apply(l,arguments)}),K(d),c.on({mousedown:function(){return l.onMouseDown.apply(l,arguments)},click:function(){return l.onClick.apply(l,arguments)}}),d.on({mousedown:function(a){a.stopPropagation()},keydown:function(){return l.onKeyDown.apply(l,arguments)},keyup:function(){return l.onKeyUp.apply(l,arguments)},keypress:function(){return l.onKeyPress.apply(l,arguments)},resize:function(){l.positionDropdown.apply(l,[])},blur:function(){return l.onBlur.apply(l,arguments)},focus:function(){return l.ignoreBlur=!1,l.onFocus.apply(l,arguments)},paste:function(){return l.onPaste.apply(l,arguments)}}),p.on("keydown"+n,function(a){l.isCmdDown=a[f?"metaKey":"ctrlKey"],l.isCtrlDown=a[f?"altKey":"ctrlKey"],l.isShiftDown=a.shiftKey}),p.on("keyup"+n,function(a){a.keyCode===t&&(l.isCtrlDown=!1),a.keyCode===r&&(l.isShiftDown=!1),a.keyCode===s&&(l.isCmdDown=!1)}),p.on("mousedown"+n,function(a){if(l.isFocused){if(a.target===l.$dropdown[0]||a.target.parentNode===l.$dropdown[0])return!1;l.$control.has(a.target).length||a.target===l.$control[0]||l.blur(a.target)}}),o.on(["scroll"+n,"resize"+n].join(" "),function(){l.isOpen&&l.positionDropdown.apply(l,arguments)}),o.on("mousemove"+n,function(){l.ignoreHover=!1}),this.revertSettings={$children:q.children().detach(),tabindex:q.attr("tabindex")},q.attr("tabindex",-1).hide().after(l.$wrapper),a.isArray(m.items)&&(l.setValue(m.items),delete m.items),x&&q.on("invalid"+n,function(a){a.preventDefault(),l.isInvalid=!0,l.refreshState()}),l.updateOriginalInput(),l.refreshItems(),l.refreshState(),l.updatePlaceholder(),l.isSetup=!0,q.is(":disabled")&&l.disable(),l.on("change",this.onChange),q.data("selectize",l),q.addClass("selectized"),l.trigger("initialize"),m.preload===!0&&l.onSearchChange("")},setupTemplates:function(){var b=this,c=b.settings.labelField,d=b.settings.optgroupLabelField,e={optgroup:function(a){return'<div class="optgroup">'+a.html+"</div>"},optgroup_header:function(a,b){return'<div class="optgroup-header">'+b(a[d])+"</div>"},option:function(a,b){return'<div class="option">'+b(a[c])+"</div>"},item:function(a,b){return'<div class="item">'+b(a[c])+"</div>"},option_create:function(a,b){return'<div class="create">Add <strong>'+b(a.input)+"</strong>&hellip;</div>"}};b.settings.render=a.extend({},e,b.settings.render)},setupCallbacks:function(){var a,b,c={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",optgroup_add:"onOptionGroupAdd",optgroup_remove:"onOptionGroupRemove",optgroup_clear:"onOptionGroupClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType",load:"onLoad",focus:"onFocus",blur:"onBlur"};for(a in c)c.hasOwnProperty(a)&&(b=this.settings[c[a]],b&&this.on(a,b))},onClick:function(a){var b=this;b.isFocused||(b.focus(),a.preventDefault())},onMouseDown:function(b){{var c=this,d=b.isDefaultPrevented();a(b.target)}if(c.isFocused){if(b.target!==c.$control_input[0])return"single"===c.settings.mode?c.isOpen?c.close():c.open():d||c.setActiveItem(null),!1}else d||window.setTimeout(function(){c.focus()},0)},onChange:function(){this.$input.trigger("change")},onPaste:function(b){var c=this;c.isFull()||c.isInputHidden||c.isLocked?b.preventDefault():c.settings.splitOn&&setTimeout(function(){for(var b=a.trim(c.$control_input.val()||"").split(c.settings.splitOn),d=0,e=b.length;e>d;d++)c.createItem(b[d])},0)},onKeyPress:function(a){if(this.isLocked)return a&&a.preventDefault();var b=String.fromCharCode(a.keyCode||a.which);return this.settings.create&&"multi"===this.settings.mode&&b===this.settings.delimiter?(this.createItem(),a.preventDefault(),!1):void 0},onKeyDown:function(a){var b=(a.target===this.$control_input[0],this);if(b.isLocked)return void(a.keyCode!==u&&a.preventDefault());switch(a.keyCode){case g:if(b.isCmdDown)return void b.selectAll();break;case i:return void(b.isOpen&&(a.preventDefault(),a.stopPropagation(),b.close()));case o:if(!a.ctrlKey||a.altKey)break;case n:if(!b.isOpen&&b.hasOptions)b.open();else if(b.$activeOption){b.ignoreHover=!0;var c=b.getAdjacentOption(b.$activeOption,1);c.length&&b.setActiveOption(c,!0,!0)}return void a.preventDefault();case l:if(!a.ctrlKey||a.altKey)break;case k:if(b.$activeOption){b.ignoreHover=!0;var d=b.getAdjacentOption(b.$activeOption,-1);d.length&&b.setActiveOption(d,!0,!0)}return void a.preventDefault();case h:return void(b.isOpen&&b.$activeOption&&(b.onOptionSelect({currentTarget:b.$activeOption}),a.preventDefault()));case j:return void b.advanceSelection(-1,a);case m:return void b.advanceSelection(1,a);case u:return b.settings.selectOnTab&&b.isOpen&&b.$activeOption&&(b.onOptionSelect({currentTarget:b.$activeOption}),b.isFull()||a.preventDefault()),void(b.settings.create&&b.createItem()&&a.preventDefault());case p:case q:return void b.deleteSelection(a)}return!b.isFull()&&!b.isInputHidden||(f?a.metaKey:a.ctrlKey)?void 0:void a.preventDefault()},onKeyUp:function(a){var b=this;if(b.isLocked)return a&&a.preventDefault();var c=b.$control_input.val()||"";b.lastValue!==c&&(b.lastValue=c,b.onSearchChange(c),b.refreshOptions(),b.trigger("type",c))},onSearchChange:function(a){var b=this,c=b.settings.load;c&&(b.loadedSearches.hasOwnProperty(a)||(b.loadedSearches[a]=!0,b.load(function(d){c.apply(b,[a,d])})))},onFocus:function(a){var b=this,c=b.isFocused;return b.isDisabled?(b.blur(),a&&a.preventDefault(),!1):void(b.ignoreFocus||(b.isFocused=!0,"focus"===b.settings.preload&&b.onSearchChange(""),c||b.trigger("focus"),b.$activeItems.length||(b.showInput(),b.setActiveItem(null),b.refreshOptions(!!b.settings.openOnFocus)),b.refreshState()))},onBlur:function(a,b){var c=this;if(c.isFocused&&(c.isFocused=!1,!c.ignoreFocus)){if(!c.ignoreBlur&&document.activeElement===c.$dropdown_content[0])return c.ignoreBlur=!0,void c.onFocus(a);var d=function(){c.close(),c.setTextboxValue(""),c.setActiveItem(null),c.setActiveOption(null),c.setCaret(c.items.length),c.refreshState(),(b||document.body).focus(),c.ignoreFocus=!1,c.trigger("blur")};c.ignoreFocus=!0,c.settings.create&&c.settings.createOnBlur?c.createItem(null,!1,d):d()}},onOptionHover:function(a){this.ignoreHover||this.setActiveOption(a.currentTarget,!1)},onOptionSelect:function(b){var c,d,e=this;b.preventDefault&&(b.preventDefault(),b.stopPropagation()),d=a(b.currentTarget),d.hasClass("create")?e.createItem(null,function(){e.settings.closeAfterSelect&&e.close()}):(c=d.attr("data-value"),"undefined"!=typeof c&&(e.lastQuery=null,e.setTextboxValue(""),e.addItem(c),e.settings.closeAfterSelect?e.close():!e.settings.hideSelected&&b.type&&/mouse/.test(b.type)&&e.setActiveOption(e.getOption(c))))},onItemSelect:function(a){var b=this;b.isLocked||"multi"===b.settings.mode&&(a.preventDefault(),b.setActiveItem(a.currentTarget,a))},load:function(a){var b=this,c=b.$wrapper.addClass(b.settings.loadingClass);b.loading++,a.apply(b,[function(a){b.loading=Math.max(b.loading-1,0),a&&a.length&&(b.addOption(a),b.refreshOptions(b.isFocused&&!b.isInputHidden)),b.loading||c.removeClass(b.settings.loadingClass),b.trigger("load",a)}])},setTextboxValue:function(a){var b=this.$control_input,c=b.val()!==a;c&&(b.val(a).triggerHandler("update"),this.lastValue=a)},getValue:function(){return this.tagType===v&&this.$input.attr("multiple")?this.items:this.items.join(this.settings.delimiter)},setValue:function(a,b){var c=b?[]:["change"];F(this,c,function(){this.clear(),this.addItems(a,b)})},setActiveItem:function(b,c){var d,e,f,g,h,i,j,k,l=this;if("single"!==l.settings.mode){if(b=a(b),!b.length)return a(l.$activeItems).removeClass("active"),l.$activeItems=[],void(l.isFocused&&l.showInput());if(d=c&&c.type.toLowerCase(),"mousedown"===d&&l.isShiftDown&&l.$activeItems.length){for(k=l.$control.children(".active:last"),g=Array.prototype.indexOf.apply(l.$control[0].childNodes,[k[0]]),h=Array.prototype.indexOf.apply(l.$control[0].childNodes,[b[0]]),g>h&&(j=g,g=h,h=j),e=g;h>=e;e++)i=l.$control[0].childNodes[e],-1===l.$activeItems.indexOf(i)&&(a(i).addClass("active"),l.$activeItems.push(i));c.preventDefault()}else"mousedown"===d&&l.isCtrlDown||"keydown"===d&&this.isShiftDown?b.hasClass("active")?(f=l.$activeItems.indexOf(b[0]),l.$activeItems.splice(f,1),b.removeClass("active")):l.$activeItems.push(b.addClass("active")[0]):(a(l.$activeItems).removeClass("active"),l.$activeItems=[b.addClass("active")[0]]);l.hideInput(),this.isFocused||l.focus()}},setActiveOption:function(b,c,d){var e,f,g,h,i,j=this;j.$activeOption&&j.$activeOption.removeClass("active"),j.$activeOption=null,b=a(b),b.length&&(j.$activeOption=b.addClass("active"),(c||!y(c))&&(e=j.$dropdown_content.height(),f=j.$activeOption.outerHeight(!0),c=j.$dropdown_content.scrollTop()||0,g=j.$activeOption.offset().top-j.$dropdown_content.offset().top+c,h=g,i=g-e+f,g+f>e+c?j.$dropdown_content.stop().animate({scrollTop:i},d?j.settings.scrollDuration:0):c>g&&j.$dropdown_content.stop().animate({scrollTop:h},d?j.settings.scrollDuration:0)))},selectAll:function(){var a=this;"single"!==a.settings.mode&&(a.$activeItems=Array.prototype.slice.apply(a.$control.children(":not(input)").addClass("active")),a.$activeItems.length&&(a.hideInput(),a.close()),a.focus())},hideInput:function(){var a=this;a.setTextboxValue(""),a.$control_input.css({opacity:0,position:"absolute",left:a.rtl?1e4:-1e4}),a.isInputHidden=!0},showInput:function(){this.$control_input.css({opacity:1,position:"relative",left:0}),this.isInputHidden=!1},focus:function(){var a=this;a.isDisabled||(a.ignoreFocus=!0,a.$control_input[0].focus(),window.setTimeout(function(){a.ignoreFocus=!1,a.onFocus()},0))},blur:function(a){this.$control_input[0].blur(),this.onBlur(null,a)},getScoreFunction:function(a){return this.sifter.getScoreFunction(a,this.getSearchOptions())},getSearchOptions:function(){var a=this.settings,b=a.sortField;return"string"==typeof b&&(b=[{field:b}]),{fields:a.searchField,conjunction:a.searchConjunction,sort:b}},search:function(b){var c,d,e,f=this,g=f.settings,h=this.getSearchOptions();if(g.score&&(e=f.settings.score.apply(this,[b]),"function"!=typeof e))throw new Error('Selectize "score" setting must be a function that returns a function');if(b!==f.lastQuery?(f.lastQuery=b,d=f.sifter.search(b,a.extend(h,{score:e})),f.currentResults=d):d=a.extend(!0,{},f.currentResults),g.hideSelected)for(c=d.items.length-1;c>=0;c--)-1!==f.items.indexOf(z(d.items[c].id))&&d.items.splice(c,1);return d},refreshOptions:function(b){var c,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;"undefined"==typeof b&&(b=!0);var t=this,u=a.trim(t.$control_input.val()),v=t.search(u),w=t.$dropdown_content,x=t.$activeOption&&z(t.$activeOption.attr("data-value"));for(g=v.items.length,"number"==typeof t.settings.maxOptions&&(g=Math.min(g,t.settings.maxOptions)),h={},i=[],c=0;g>c;c++)for(j=t.options[v.items[c].id],k=t.render("option",j),l=j[t.settings.optgroupField]||"",m=a.isArray(l)?l:[l],e=0,f=m&&m.length;f>e;e++)l=m[e],t.optgroups.hasOwnProperty(l)||(l=""),h.hasOwnProperty(l)||(h[l]=[],i.push(l)),h[l].push(k);for(this.settings.lockOptgroupOrder&&i.sort(function(a,b){var c=t.optgroups[a].$order||0,d=t.optgroups[b].$order||0;return c-d}),n=[],c=0,g=i.length;g>c;c++)l=i[c],t.optgroups.hasOwnProperty(l)&&h[l].length?(o=t.render("optgroup_header",t.optgroups[l])||"",o+=h[l].join(""),n.push(t.render("optgroup",a.extend({},t.optgroups[l],{html:o})))):n.push(h[l].join(""));if(w.html(n.join("")),t.settings.highlight&&v.query.length&&v.tokens.length)for(c=0,g=v.tokens.length;g>c;c++)d(w,v.tokens[c].regex);if(!t.settings.hideSelected)for(c=0,g=t.items.length;g>c;c++)t.getOption(t.items[c]).addClass("selected");p=t.canCreate(u),p&&(w.prepend(t.render("option_create",{input:u})),s=a(w[0].childNodes[0])),t.hasOptions=v.items.length>0||p,t.hasOptions?(v.items.length>0?(r=x&&t.getOption(x),r&&r.length?q=r:"single"===t.settings.mode&&t.items.length&&(q=t.getOption(t.items[0])),q&&q.length||(q=s&&!t.settings.addPrecedence?t.getAdjacentOption(s,1):w.find("[data-selectable]:first"))):q=s,t.setActiveOption(q),b&&!t.isOpen&&t.open()):(t.setActiveOption(null),b&&t.isOpen&&t.close())},addOption:function(b){var c,d,e,f=this;if(a.isArray(b))for(c=0,d=b.length;d>c;c++)f.addOption(b[c]);else(e=f.registerOption(b))&&(f.userOptions[e]=!0,f.lastQuery=null,f.trigger("option_add",e,b))},registerOption:function(a){var b=z(a[this.settings.valueField]);return!b||this.options.hasOwnProperty(b)?!1:(a.$order=a.$order||++this.order,this.options[b]=a,b)},registerOptionGroup:function(a){var b=z(a[this.settings.optgroupValueField]);return b?(a.$order=a.$order||++this.order,this.optgroups[b]=a,b):!1},addOptionGroup:function(a,b){b[this.settings.optgroupValueField]=a,(a=this.registerOptionGroup(b))&&this.trigger("optgroup_add",a,b)},removeOptionGroup:function(a){this.optgroups.hasOwnProperty(a)&&(delete this.optgroups[a],this.renderCache={},this.trigger("optgroup_remove",a))},clearOptionGroups:function(){this.optgroups={},this.renderCache={},this.trigger("optgroup_clear")},updateOption:function(b,c){var d,e,f,g,h,i,j,k=this;if(b=z(b),f=z(c[k.settings.valueField]),null!==b&&k.options.hasOwnProperty(b)){if("string"!=typeof f)throw new Error("Value must be set in option data");j=k.options[b].$order,f!==b&&(delete k.options[b],g=k.items.indexOf(b),-1!==g&&k.items.splice(g,1,f)),c.$order=c.$order||j,k.options[f]=c,h=k.renderCache.item,i=k.renderCache.option,h&&(delete h[b],delete h[f]),i&&(delete i[b],delete i[f]),-1!==k.items.indexOf(f)&&(d=k.getItem(b),e=a(k.render("item",c)),d.hasClass("active")&&e.addClass("active"),d.replaceWith(e)),k.lastQuery=null,k.isOpen&&k.refreshOptions(!1)}},removeOption:function(a,b){var c=this;a=z(a);var d=c.renderCache.item,e=c.renderCache.option;d&&delete d[a],e&&delete e[a],delete c.userOptions[a],delete c.options[a],c.lastQuery=null,c.trigger("option_remove",a),c.removeItem(a,b)},clearOptions:function(){var a=this;a.loadedSearches={},a.userOptions={},a.renderCache={},a.options=a.sifter.items={},a.lastQuery=null,a.trigger("option_clear"),a.clear()},getOption:function(a){return this.getElementWithValue(a,this.$dropdown_content.find("[data-selectable]"))},getAdjacentOption:function(b,c){var d=this.$dropdown.find("[data-selectable]"),e=d.index(b)+c;return e>=0&&e<d.length?d.eq(e):a()},getElementWithValue:function(b,c){if(b=z(b),"undefined"!=typeof b&&null!==b)for(var d=0,e=c.length;e>d;d++)if(c[d].getAttribute("data-value")===b)return a(c[d]);return a()},getItem:function(a){return this.getElementWithValue(a,this.$control.children())},addItems:function(b,c){for(var d=a.isArray(b)?b:[b],e=0,f=d.length;f>e;e++)this.isPending=f-1>e,this.addItem(d[e],c)},addItem:function(b,c){var d=c?[]:["change"];F(this,d,function(){var d,e,f,g,h,i=this,j=i.settings.mode;return b=z(b),-1!==i.items.indexOf(b)?void("single"===j&&i.close()):void(i.options.hasOwnProperty(b)&&("single"===j&&i.clear(),"multi"===j&&i.isFull()||(d=a(i.render("item",i.options[b])),h=i.isFull(),i.items.splice(i.caretPos,0,b),i.insertAtCaret(d),(!i.isPending||!h&&i.isFull())&&i.refreshState(),i.isSetup&&(f=i.$dropdown_content.find("[data-selectable]"),i.isPending||(e=i.getOption(b),g=i.getAdjacentOption(e,1).attr("data-value"),i.refreshOptions(i.isFocused&&"single"!==j),g&&i.setActiveOption(i.getOption(g))),!f.length||i.isFull()?i.close():i.positionDropdown(),i.updatePlaceholder(),i.trigger("item_add",b,d),i.updateOriginalInput({silent:c})))))})},removeItem:function(a,b){var c,d,e,f=this;c="object"==typeof a?a:f.getItem(a),a=z(c.attr("data-value")),d=f.items.indexOf(a),-1!==d&&(c.remove(),c.hasClass("active")&&(e=f.$activeItems.indexOf(c[0]),f.$activeItems.splice(e,1)),f.items.splice(d,1),f.lastQuery=null,!f.settings.persist&&f.userOptions.hasOwnProperty(a)&&f.removeOption(a,b),d<f.caretPos&&f.setCaret(f.caretPos-1),f.refreshState(),f.updatePlaceholder(),f.updateOriginalInput({silent:b}),f.positionDropdown(),f.trigger("item_remove",a,c))},createItem:function(b,c){var d=this,e=d.caretPos;b=b||a.trim(d.$control_input.val()||"");var f=arguments[arguments.length-1];if("function"!=typeof f&&(f=function(){}),"boolean"!=typeof c&&(c=!0),!d.canCreate(b))return f(),!1;d.lock();var g="function"==typeof d.settings.create?this.settings.create:function(a){var b={};return b[d.settings.labelField]=a,b[d.settings.valueField]=a,b},h=D(function(a){if(d.unlock(),!a||"object"!=typeof a)return f();var b=z(a[d.settings.valueField]);return"string"!=typeof b?f():(d.setTextboxValue(""),d.addOption(a),d.setCaret(e),d.addItem(b),d.refreshOptions(c&&"single"!==d.settings.mode),void f(a))}),i=g.apply(this,[b,h]);return"undefined"!=typeof i&&h(i),!0},refreshItems:function(){this.lastQuery=null,this.isSetup&&this.addItem(this.items),this.refreshState(),this.updateOriginalInput()},refreshState:function(){var a,b=this;b.isRequired&&(b.items.length&&(b.isInvalid=!1),b.$control_input.prop("required",a)),b.refreshClasses()},refreshClasses:function(){var b=this,c=b.isFull(),d=b.isLocked;b.$wrapper.toggleClass("rtl",b.rtl),b.$control.toggleClass("focus",b.isFocused).toggleClass("disabled",b.isDisabled).toggleClass("required",b.isRequired).toggleClass("invalid",b.isInvalid).toggleClass("locked",d).toggleClass("full",c).toggleClass("not-full",!c).toggleClass("input-active",b.isFocused&&!b.isInputHidden).toggleClass("dropdown-active",b.isOpen).toggleClass("has-options",!a.isEmptyObject(b.options)).toggleClass("has-items",b.items.length>0),b.$control_input.data("grow",!c&&!d)},isFull:function(){return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems},updateOriginalInput:function(a){var b,c,d,e,f=this;if(a=a||{},f.tagType===v){for(d=[],b=0,c=f.items.length;c>b;b++)e=f.options[f.items[b]][f.settings.labelField]||"",d.push('<option value="'+A(f.items[b])+'" selected="selected">'+A(e)+"</option>");d.length||this.$input.attr("multiple")||d.push('<option value="" selected="selected"></option>'),f.$input.html(d.join(""))}else f.$input.val(f.getValue()),f.$input.attr("value",f.$input.val());f.isSetup&&(a.silent||f.trigger("change",f.$input.val()))},updatePlaceholder:function(){if(this.settings.placeholder){var a=this.$control_input;this.items.length?a.removeAttr("placeholder"):a.attr("placeholder",this.settings.placeholder),a.triggerHandler("update",{force:!0})}},open:function(){var a=this;a.isLocked||a.isOpen||"multi"===a.settings.mode&&a.isFull()||(a.focus(),a.isOpen=!0,a.refreshState(),a.$dropdown.css({visibility:"hidden",display:"block"}),a.positionDropdown(),a.$dropdown.css({visibility:"visible"}),a.trigger("dropdown_open",a.$dropdown))},close:function(){var a=this,b=a.isOpen;"single"===a.settings.mode&&a.items.length&&a.hideInput(),a.isOpen=!1,a.$dropdown.hide(),a.setActiveOption(null),a.refreshState(),b&&a.trigger("dropdown_close",a.$dropdown)},positionDropdown:function(){var a=this.$control,b="body"===this.settings.dropdownParent?a.offset():a.position();b.top+=a.outerHeight(!0),this.$dropdown.css({width:a.outerWidth(),top:b.top,left:b.left})},clear:function(a){var b=this;b.items.length&&(b.$control.children(":not(input)").remove(),b.items=[],b.lastQuery=null,b.setCaret(0),b.setActiveItem(null),b.updatePlaceholder(),b.updateOriginalInput({silent:a}),b.refreshState(),b.showInput(),b.trigger("clear"))},insertAtCaret:function(b){var c=Math.min(this.caretPos,this.items.length);0===c?this.$control.prepend(b):a(this.$control[0].childNodes[c]).before(b),this.setCaret(c+1)},deleteSelection:function(b){var c,d,e,f,g,h,i,j,k,l=this;if(e=b&&b.keyCode===p?-1:1,f=H(l.$control_input[0]),l.$activeOption&&!l.settings.hideSelected&&(i=l.getAdjacentOption(l.$activeOption,-1).attr("data-value")),g=[],l.$activeItems.length){for(k=l.$control.children(".active:"+(e>0?"last":"first")),h=l.$control.children(":not(input)").index(k),e>0&&h++,c=0,d=l.$activeItems.length;d>c;c++)g.push(a(l.$activeItems[c]).attr("data-value"));
3
- b&&(b.preventDefault(),b.stopPropagation())}else(l.isFocused||"single"===l.settings.mode)&&l.items.length&&(0>e&&0===f.start&&0===f.length?g.push(l.items[l.caretPos-1]):e>0&&f.start===l.$control_input.val().length&&g.push(l.items[l.caretPos]));if(!g.length||"function"==typeof l.settings.onDelete&&l.settings.onDelete.apply(l,[g])===!1)return!1;for("undefined"!=typeof h&&l.setCaret(h);g.length;)l.removeItem(g.pop());return l.showInput(),l.positionDropdown(),l.refreshOptions(!0),i&&(j=l.getOption(i),j.length&&l.setActiveOption(j)),!0},advanceSelection:function(a,b){var c,d,e,f,g,h,i=this;0!==a&&(i.rtl&&(a*=-1),c=a>0?"last":"first",d=H(i.$control_input[0]),i.isFocused&&!i.isInputHidden?(f=i.$control_input.val().length,g=0>a?0===d.start&&0===d.length:d.start===f,g&&!f&&i.advanceCaret(a,b)):(h=i.$control.children(".active:"+c),h.length&&(e=i.$control.children(":not(input)").index(h),i.setActiveItem(null),i.setCaret(a>0?e+1:e))))},advanceCaret:function(a,b){var c,d,e=this;0!==a&&(c=a>0?"next":"prev",e.isShiftDown?(d=e.$control_input[c](),d.length&&(e.hideInput(),e.setActiveItem(d),b&&b.preventDefault())):e.setCaret(e.caretPos+a))},setCaret:function(b){var c=this;if(b="single"===c.settings.mode?c.items.length:Math.max(0,Math.min(c.items.length,b)),!c.isPending){var d,e,f,g;for(f=c.$control.children(":not(input)"),d=0,e=f.length;e>d;d++)g=a(f[d]).detach(),b>d?c.$control_input.before(g):c.$control.append(g)}c.caretPos=b},lock:function(){this.close(),this.isLocked=!0,this.refreshState()},unlock:function(){this.isLocked=!1,this.refreshState()},disable:function(){var a=this;a.$input.prop("disabled",!0),a.$control_input.prop("disabled",!0).prop("tabindex",-1),a.isDisabled=!0,a.lock()},enable:function(){var a=this;a.$input.prop("disabled",!1),a.$control_input.prop("disabled",!1).prop("tabindex",a.tabIndex),a.isDisabled=!1,a.unlock()},destroy:function(){var b=this,c=b.eventNS,d=b.revertSettings;b.trigger("destroy"),b.off(),b.$wrapper.remove(),b.$dropdown.remove(),b.$input.html("").append(d.$children).removeAttr("tabindex").removeClass("selectized").attr({tabindex:d.tabindex}).show(),b.$control_input.removeData("grow"),b.$input.removeData("selectize"),a(window).off(c),a(document).off(c),a(document.body).off(c),delete b.$input[0].selectize},render:function(a,b){var c,d,e="",f=!1,g=this,h=/^[\t \r\n]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i;return("option"===a||"item"===a)&&(c=z(b[g.settings.valueField]),f=!!c),f&&(y(g.renderCache[a])||(g.renderCache[a]={}),g.renderCache[a].hasOwnProperty(c))?g.renderCache[a][c]:(e=g.settings.render[a].apply(this,[b,A]),("option"===a||"option_create"===a)&&(e=e.replace(h,"<$1 data-selectable")),"optgroup"===a&&(d=b[g.settings.optgroupValueField]||"",e=e.replace(h,'<$1 data-group="'+B(A(d))+'"')),("option"===a||"item"===a)&&(e=e.replace(h,'<$1 data-value="'+B(A(c||""))+'"')),f&&(g.renderCache[a][c]=e),e)},clearCache:function(a){var b=this;"undefined"==typeof a?b.renderCache={}:delete b.renderCache[a]},canCreate:function(a){var b=this;if(!b.settings.create)return!1;var c=b.settings.createFilter;return!(!a.length||"function"==typeof c&&!c.apply(b,[a])||"string"==typeof c&&!new RegExp(c).test(a)||c instanceof RegExp&&!c.test(a))}}),L.count=0,L.defaults={options:[],optgroups:[],plugins:[],delimiter:",",splitOn:null,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,createFilter:null,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,allowEmptyOption:!1,closeAfterSelect:!1,scrollDuration:60,loadThrottle:300,loadingClass:"loading",dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",optgroupLabelField:"label",optgroupValueField:"value",lockOptgroupOrder:!1,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,copyClassesToDropdown:!0,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.optgroupField,i=d.optgroupLabelField,j=d.optgroupValueField,k={},l=function(b,c){var h,i,j,k,l=b.attr(e);if(l)for(c.options=JSON.parse(l),h=0,i=c.options.length;i>h;h++)c.items.push(c.options[h][g]);else{var m=a.trim(b.val()||"");if(!d.allowEmptyOption&&!m.length)return;for(j=m.split(d.delimiter),h=0,i=j.length;i>h;h++)k={},k[f]=j[h],k[g]=j[h],c.options.push(k);c.items=j}},m=function(b,c){var l,m,n,o,p=c.options,q=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},r=function(b,e){b=a(b);var i=z(b.attr("value"));if(i||d.allowEmptyOption)if(k.hasOwnProperty(i)){if(e){var j=k[i][h];j?a.isArray(j)?j.push(e):k[i][h]=[j,e]:k[i][h]=e}}else{var l=q(b)||{};l[f]=l[f]||b.text(),l[g]=l[g]||i,l[h]=l[h]||e,k[i]=l,p.push(l),b.is(":selected")&&c.items.push(i)}},s=function(b){var d,e,f,g,h;for(b=a(b),f=b.attr("label"),f&&(g=q(b)||{},g[i]=f,g[j]=f,c.optgroups.push(g)),h=a("option",b),d=0,e=h.length;e>d;d++)r(h[d],f)};for(c.maxItems=b.attr("multiple")?null:1,o=b.children(),l=0,m=o.length;m>l;l++)n=o[l].tagName.toLowerCase(),"optgroup"===n?s(o[l]):"option"===n&&r(o[l])};return this.each(function(){if(!this.selectize){var e,f=a(this),g=this.tagName.toLowerCase(),h=f.attr("placeholder")||f.attr("data-placeholder");h||d.allowEmptyOption||(h=f.children('option[value=""]').text());var i={placeholder:h,options:[],optgroups:[],items:[]};"select"===g?m(f,i):l(f,i),e=new L(f,a.extend(!0,{},c,i,b))}})},a.fn.selectize.defaults=L.defaults,a.fn.selectize.support={validity:x},L.define("drag_drop",function(){if(!a.fn.sortable)throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".');if("multi"===this.settings.mode){var b=this;b.lock=function(){var a=b.lock;return function(){var c=b.$control.data("sortable");return c&&c.disable(),a.apply(b,arguments)}}(),b.unlock=function(){var a=b.unlock;return function(){var c=b.$control.data("sortable");return c&&c.enable(),a.apply(b,arguments)}}(),b.setup=function(){var c=b.setup;return function(){c.apply(this,arguments);var d=b.$control.sortable({items:"[data-value]",forcePlaceholderSize:!0,disabled:b.isLocked,start:function(a,b){b.placeholder.css("width",b.helper.css("width")),d.css({overflow:"visible"})},stop:function(){d.css({overflow:"hidden"});var c=b.$activeItems?b.$activeItems.slice():null,e=[];d.children("[data-value]").each(function(){e.push(a(this).attr("data-value"))}),b.setValue(e),b.setActiveItem(c)}})}}()}}),L.define("dropdown_header",function(b){var c=this;b=a.extend({title:"Untitled",headerClass:"selectize-dropdown-header",titleRowClass:"selectize-dropdown-header-title",labelClass:"selectize-dropdown-header-label",closeClass:"selectize-dropdown-header-close",html:function(a){return'<div class="'+a.headerClass+'"><div class="'+a.titleRowClass+'"><span class="'+a.labelClass+'">'+a.title+'</span><a href="javascript:void(0)" class="'+a.closeClass+'">&times;</a></div></div>'}},b),c.setup=function(){var d=c.setup;return function(){d.apply(c,arguments),c.$dropdown_header=a(b.html(b)),c.$dropdown.prepend(c.$dropdown_header)}}()}),L.define("optgroup_columns",function(b){var c=this;b=a.extend({equalizeWidth:!0,equalizeHeight:!0},b),this.getAdjacentOption=function(b,c){var d=b.closest("[data-group]").find("[data-selectable]"),e=d.index(b)+c;return e>=0&&e<d.length?d.eq(e):a()},this.onKeyDown=function(){var a=c.onKeyDown;return function(b){var d,e,f,g;return!this.isOpen||b.keyCode!==j&&b.keyCode!==m?a.apply(this,arguments):(c.ignoreHover=!0,g=this.$activeOption.closest("[data-group]"),d=g.find("[data-selectable]").index(this.$activeOption),g=b.keyCode===j?g.prev("[data-group]"):g.next("[data-group]"),f=g.find("[data-selectable]"),e=f.eq(Math.min(f.length-1,d)),void(e.length&&this.setActiveOption(e)))}}();var d=function(){var a,b=d.width,c=document;return"undefined"==typeof b&&(a=c.createElement("div"),a.innerHTML='<div style="width:50px;height:50px;position:absolute;left:-50px;top:-50px;overflow:auto;"><div style="width:1px;height:100px;"></div></div>',a=a.firstChild,c.body.appendChild(a),b=d.width=a.offsetWidth-a.clientWidth,c.body.removeChild(a)),b},e=function(){var e,f,g,h,i,j,k;if(k=a("[data-group]",c.$dropdown_content),f=k.length,f&&c.$dropdown_content.width()){if(b.equalizeHeight){for(g=0,e=0;f>e;e++)g=Math.max(g,k.eq(e).height());k.css({height:g})}b.equalizeWidth&&(j=c.$dropdown_content.innerWidth()-d(),h=Math.round(j/f),k.css({width:h}),f>1&&(i=j-h*(f-1),k.eq(f-1).css({width:i})))}};(b.equalizeHeight||b.equalizeWidth)&&(C.after(this,"positionDropdown",e),C.after(this,"refreshOptions",e))}),L.define("remove_button",function(b){if("single"!==this.settings.mode){b=a.extend({label:"&times;",title:"Remove",className:"remove",append:!0},b);var c=this,d='<a href="javascript:void(0)" class="'+b.className+'" tabindex="-1" title="'+A(b.title)+'">'+b.label+"</a>",e=function(a,b){var c=a.search(/(<\/[^>]+>\s*)$/);return a.substring(0,c)+b+a.substring(c)};this.setup=function(){var f=c.setup;return function(){if(b.append){var g=c.settings.render.item;c.settings.render.item=function(){return e(g.apply(this,arguments),d)}}f.apply(this,arguments),this.$control.on("click","."+b.className,function(b){if(b.preventDefault(),!c.isLocked){var d=a(b.currentTarget).parent();c.setActiveItem(d),c.deleteSelection()&&c.setCaret(c.items.length)}})}}()}}),L.define("restore_on_backspace",function(a){var b=this;a.text=a.text||function(a){return a[this.settings.labelField]},this.onKeyDown=function(){var c=b.onKeyDown;return function(b){var d,e;return b.keyCode===p&&""===this.$control_input.val()&&!this.$activeItems.length&&(d=this.caretPos-1,d>=0&&d<this.items.length)?(e=this.options[this.items[d]],this.deleteSelection(b)&&(this.setTextboxValue(a.text.apply(this,[e])),this.refreshOptions(!0)),void b.preventDefault()):c.apply(this,arguments)}}()}),L});
1
+ /*! selectize.js - v0.12.1 | https://github.com/brianreavis/selectize.js | Apache License (v2) */
2
+ !function(a,b){"function"==typeof define&&define.amd?define("sifter",b):"object"==typeof exports?module.exports=b():a.Sifter=b()}(this,function(){var a=function(a,b){this.items=a,this.settings=b||{diacritics:!0}};a.prototype.tokenize=function(a){if(a=d(String(a||"").toLowerCase()),!a||!a.length)return[];var b,c,f,h,i=[],j=a.split(/ +/);for(b=0,c=j.length;c>b;b++){if(f=e(j[b]),this.settings.diacritics)for(h in g)g.hasOwnProperty(h)&&(f=f.replace(new RegExp(h,"g"),g[h]));i.push({string:j[b],regex:new RegExp(f,"i")})}return i},a.prototype.iterator=function(a,b){var c;c=f(a)?Array.prototype.forEach||function(a){for(var b=0,c=this.length;c>b;b++)a(this[b],b,this)}:function(a){for(var b in this)this.hasOwnProperty(b)&&a(this[b],b,this)},c.apply(a,[b])},a.prototype.getScoreFunction=function(a,b){var c,d,e,f;c=this,a=c.prepareSearch(a,b),e=a.tokens,d=a.options.fields,f=e.length;var g=function(a,b){var c,d;return a?(a=String(a||""),d=a.search(b.regex),-1===d?0:(c=b.string.length/a.length,0===d&&(c+=.5),c)):0},h=function(){var a=d.length;return a?1===a?function(a,b){return g(b[d[0]],a)}:function(b,c){for(var e=0,f=0;a>e;e++)f+=g(c[d[e]],b);return f/a}:function(){return 0}}();return f?1===f?function(a){return h(e[0],a)}:"and"===a.options.conjunction?function(a){for(var b,c=0,d=0;f>c;c++){if(b=h(e[c],a),0>=b)return 0;d+=b}return d/f}:function(a){for(var b=0,c=0;f>b;b++)c+=h(e[b],a);return c/f}:function(){return 0}},a.prototype.getSortFunction=function(a,c){var d,e,f,g,h,i,j,k,l,m,n;if(f=this,a=f.prepareSearch(a,c),n=!a.query&&c.sort_empty||c.sort,l=function(a,b){return"$score"===a?b.score:f.items[b.id][a]},h=[],n)for(d=0,e=n.length;e>d;d++)(a.query||"$score"!==n[d].field)&&h.push(n[d]);if(a.query){for(m=!0,d=0,e=h.length;e>d;d++)if("$score"===h[d].field){m=!1;break}m&&h.unshift({field:"$score",direction:"desc"})}else for(d=0,e=h.length;e>d;d++)if("$score"===h[d].field){h.splice(d,1);break}for(k=[],d=0,e=h.length;e>d;d++)k.push("desc"===h[d].direction?-1:1);return i=h.length,i?1===i?(g=h[0].field,j=k[0],function(a,c){return j*b(l(g,a),l(g,c))}):function(a,c){var d,e,f;for(d=0;i>d;d++)if(f=h[d].field,e=k[d]*b(l(f,a),l(f,c)))return e;return 0}:null},a.prototype.prepareSearch=function(a,b){if("object"==typeof a)return a;b=c({},b);var d=b.fields,e=b.sort,g=b.sort_empty;return d&&!f(d)&&(b.fields=[d]),e&&!f(e)&&(b.sort=[e]),g&&!f(g)&&(b.sort_empty=[g]),{options:b,query:String(a||"").toLowerCase(),tokens:this.tokenize(a),total:0,items:[]}},a.prototype.search=function(a,b){var c,d,e,f,g=this;return d=this.prepareSearch(a,b),b=d.options,a=d.query,f=b.score||g.getScoreFunction(d),a.length?g.iterator(g.items,function(a,e){c=f(a),(b.filter===!1||c>0)&&d.items.push({score:c,id:e})}):g.iterator(g.items,function(a,b){d.items.push({score:1,id:b})}),e=g.getSortFunction(d,b),e&&d.items.sort(e),d.total=d.items.length,"number"==typeof b.limit&&(d.items=d.items.slice(0,b.limit)),d};var b=function(a,b){return"number"==typeof a&&"number"==typeof b?a>b?1:b>a?-1:0:(a=h(String(a||"")),b=h(String(b||"")),a>b?1:b>a?-1:0)},c=function(a){var b,c,d,e;for(b=1,c=arguments.length;c>b;b++)if(e=arguments[b])for(d in e)e.hasOwnProperty(d)&&(a[d]=e[d]);return a},d=function(a){return(a+"").replace(/^\s+|\s+$|/g,"")},e=function(a){return(a+"").replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")},f=Array.isArray||$&&$.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)},g={a:"[aÀÁÂÃÄÅàáâãäåĀāąĄ]",c:"[cÇçćĆčČ]",d:"[dđĐďĎ]",e:"[eÈÉÊËèéêëěĚĒēęĘ]",i:"[iÌÍÎÏìíîïĪī]",l:"[lłŁ]",n:"[nÑñňŇńŃ]",o:"[oÒÓÔÕÕÖØòóôõöøŌō]",r:"[rřŘ]",s:"[sŠšśŚ]",t:"[tťŤ]",u:"[uÙÚÛÜùúûüůŮŪū]",y:"[yŸÿýÝ]",z:"[zŽžżŻźŹ]"},h=function(){var a,b,c,d,e="",f={};for(c in g)if(g.hasOwnProperty(c))for(d=g[c].substring(2,g[c].length-1),e+=d,a=0,b=d.length;b>a;a++)f[d.charAt(a)]=c;var h=new RegExp("["+e+"]","g");return function(a){return a.replace(h,function(a){return f[a]}).toLowerCase()}}();return a}),function(a,b){"function"==typeof define&&define.amd?define("microplugin",b):"object"==typeof exports?module.exports=b():a.MicroPlugin=b()}(this,function(){var a={};a.mixin=function(a){a.plugins={},a.prototype.initializePlugins=function(a){var c,d,e,f=this,g=[];if(f.plugins={names:[],settings:{},requested:{},loaded:{}},b.isArray(a))for(c=0,d=a.length;d>c;c++)"string"==typeof a[c]?g.push(a[c]):(f.plugins.settings[a[c].name]=a[c].options,g.push(a[c].name));else if(a)for(e in a)a.hasOwnProperty(e)&&(f.plugins.settings[e]=a[e],g.push(e));for(;g.length;)f.require(g.shift())},a.prototype.loadPlugin=function(b){var c=this,d=c.plugins,e=a.plugins[b];if(!a.plugins.hasOwnProperty(b))throw new Error('Unable to find "'+b+'" plugin');d.requested[b]=!0,d.loaded[b]=e.fn.apply(c,[c.plugins.settings[b]||{}]),d.names.push(b)},a.prototype.require=function(a){var b=this,c=b.plugins;if(!b.plugins.loaded.hasOwnProperty(a)){if(c.requested[a])throw new Error('Plugin has circular dependency ("'+a+'")');b.loadPlugin(a)}return c.loaded[a]},a.define=function(b,c){a.plugins[b]={name:b,fn:c}}};var b={isArray:Array.isArray||function(a){return"[object Array]"===Object.prototype.toString.call(a)}};return a}),function(a,b){"function"==typeof define&&define.amd?define("selectize",["jquery","sifter","microplugin"],b):"object"==typeof exports?module.exports=b(require("jquery"),require("sifter"),require("microplugin")):a.Selectize=b(a.jQuery,a.Sifter,a.MicroPlugin)}(this,function(a,b,c){"use strict";var d=function(a,b){if("string"!=typeof b||b.length){var c="string"==typeof b?new RegExp(b,"i"):b,d=function(a){var b=0;if(3===a.nodeType){var e=a.data.search(c);if(e>=0&&a.data.length>0){var f=a.data.match(c),g=document.createElement("span");g.className="highlight";var h=a.splitText(e),i=(h.splitText(f[0].length),h.cloneNode(!0));g.appendChild(i),h.parentNode.replaceChild(g,h),b=1}}else if(1===a.nodeType&&a.childNodes&&!/(script|style)/i.test(a.tagName))for(var j=0;j<a.childNodes.length;++j)j+=d(a.childNodes[j]);return b};return a.each(function(){d(this)})}},e=function(){};e.prototype={on:function(a,b){this._events=this._events||{},this._events[a]=this._events[a]||[],this._events[a].push(b)},off:function(a,b){var c=arguments.length;return 0===c?delete this._events:1===c?delete this._events[a]:(this._events=this._events||{},void(a in this._events!=!1&&this._events[a].splice(this._events[a].indexOf(b),1)))},trigger:function(a){if(this._events=this._events||{},a in this._events!=!1)for(var b=0;b<this._events[a].length;b++)this._events[a][b].apply(this,Array.prototype.slice.call(arguments,1))}},e.mixin=function(a){for(var b=["on","off","trigger"],c=0;c<b.length;c++)a.prototype[b[c]]=e.prototype[b[c]]};var f=/Mac/.test(navigator.userAgent),g=65,h=13,i=27,j=37,k=38,l=80,m=39,n=40,o=78,p=8,q=46,r=16,s=f?91:17,t=f?18:17,u=9,v=1,w=2,x=!/android/i.test(window.navigator.userAgent)&&!!document.createElement("form").validity,y=function(a){return"undefined"!=typeof a},z=function(a){return"undefined"==typeof a||null===a?null:"boolean"==typeof a?a?"1":"0":a+""},A=function(a){return(a+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},B=function(a){return(a+"").replace(/\$/g,"$$$$")},C={};C.before=function(a,b,c){var d=a[b];a[b]=function(){return c.apply(a,arguments),d.apply(a,arguments)}},C.after=function(a,b,c){var d=a[b];a[b]=function(){var b=d.apply(a,arguments);return c.apply(a,arguments),b}};var D=function(a){var b=!1;return function(){b||(b=!0,a.apply(this,arguments))}},E=function(a,b){var c;return function(){var d=this,e=arguments;window.clearTimeout(c),c=window.setTimeout(function(){a.apply(d,e)},b)}},F=function(a,b,c){var d,e=a.trigger,f={};a.trigger=function(){var c=arguments[0];return-1===b.indexOf(c)?e.apply(a,arguments):void(f[c]=arguments)},c.apply(a,[]),a.trigger=e;for(d in f)f.hasOwnProperty(d)&&e.apply(a,f[d])},G=function(a,b,c,d){a.on(b,c,function(b){for(var c=b.target;c&&c.parentNode!==a[0];)c=c.parentNode;return b.currentTarget=c,d.apply(this,[b])})},H=function(a){var b={};if("selectionStart"in a)b.start=a.selectionStart,b.length=a.selectionEnd-b.start;else if(document.selection){a.focus();var c=document.selection.createRange(),d=document.selection.createRange().text.length;c.moveStart("character",-a.value.length),b.start=c.text.length-d,b.length=d}return b},I=function(a,b,c){var d,e,f={};if(c)for(d=0,e=c.length;e>d;d++)f[c[d]]=a.css(c[d]);else f=a.css();b.css(f)},J=function(b,c){if(!b)return 0;var d=a("<test>").css({position:"absolute",top:-99999,left:-99999,width:"auto",padding:0,whiteSpace:"pre"}).text(b).appendTo("body");I(c,d,["letterSpacing","fontSize","fontFamily","fontWeight","textTransform"]);var e=d.width();return d.remove(),e},K=function(a){var b=null,c=function(c,d){var e,f,g,h,i,j,k,l;c=c||window.event||{},d=d||{},c.metaKey||c.altKey||(d.force||a.data("grow")!==!1)&&(e=a.val(),c.type&&"keydown"===c.type.toLowerCase()&&(f=c.keyCode,g=f>=97&&122>=f||f>=65&&90>=f||f>=48&&57>=f||32===f,f===q||f===p?(l=H(a[0]),l.length?e=e.substring(0,l.start)+e.substring(l.start+l.length):f===p&&l.start?e=e.substring(0,l.start-1)+e.substring(l.start+1):f===q&&"undefined"!=typeof l.start&&(e=e.substring(0,l.start)+e.substring(l.start+1))):g&&(j=c.shiftKey,k=String.fromCharCode(c.keyCode),k=j?k.toUpperCase():k.toLowerCase(),e+=k)),h=a.attr("placeholder"),!e&&h&&(e=h),i=J(e,a)+4,i!==b&&(b=i,a.width(i),a.triggerHandler("resize")))};a.on("keydown keyup update blur",c),c()},L=function(c,d){var e,f,g,h,i=this;h=c[0],h.selectize=i;var j=window.getComputedStyle&&window.getComputedStyle(h,null);if(g=j?j.getPropertyValue("direction"):h.currentStyle&&h.currentStyle.direction,g=g||c.parents("[dir]:first").attr("dir")||"",a.extend(i,{order:0,settings:d,$input:c,tabIndex:c.attr("tabindex")||"",tagType:"select"===h.tagName.toLowerCase()?v:w,rtl:/rtl/i.test(g),eventNS:".selectize"+ ++L.count,highlightedValue:null,isOpen:!1,isDisabled:!1,isRequired:c.is("[required]"),isInvalid:!1,isLocked:!1,isFocused:!1,isInputHidden:!1,isSetup:!1,isShiftDown:!1,isCmdDown:!1,isCtrlDown:!1,ignoreFocus:!1,ignoreBlur:!1,ignoreHover:!1,hasOptions:!1,currentResults:null,lastValue:"",caretPos:0,loading:0,loadedSearches:{},$activeOption:null,$activeItems:[],optgroups:{},options:{},userOptions:{},items:[],renderCache:{},onSearchChange:null===d.loadThrottle?i.onSearchChange:E(i.onSearchChange,d.loadThrottle)}),i.sifter=new b(this.options,{diacritics:d.diacritics}),i.settings.options){for(e=0,f=i.settings.options.length;f>e;e++)i.registerOption(i.settings.options[e]);delete i.settings.options}if(i.settings.optgroups){for(e=0,f=i.settings.optgroups.length;f>e;e++)i.registerOptionGroup(i.settings.optgroups[e]);delete i.settings.optgroups}i.settings.mode=i.settings.mode||(1===i.settings.maxItems?"single":"multi"),"boolean"!=typeof i.settings.hideSelected&&(i.settings.hideSelected="multi"===i.settings.mode),i.initializePlugins(i.settings.plugins),i.setupCallbacks(),i.setupTemplates(),i.setup()};return e.mixin(L),c.mixin(L),a.extend(L.prototype,{setup:function(){var b,c,d,e,g,h,i,j,k,l=this,m=l.settings,n=l.eventNS,o=a(window),p=a(document),q=l.$input;if(i=l.settings.mode,j=q.attr("class")||"",b=a("<div>").addClass(m.wrapperClass).addClass(j).addClass(i),c=a("<div>").addClass(m.inputClass).addClass("items").appendTo(b),d=a('<input type="text" autocomplete="off" />').appendTo(c).attr("tabindex",q.is(":disabled")?"-1":l.tabIndex),h=a(m.dropdownParent||b),e=a("<div>").addClass(m.dropdownClass).addClass(i).hide().appendTo(h),g=a("<div>").addClass(m.dropdownContentClass).appendTo(e),l.settings.copyClassesToDropdown&&e.addClass(j),b.css({width:q[0].style.width}),l.plugins.names.length&&(k="plugin-"+l.plugins.names.join(" plugin-"),b.addClass(k),e.addClass(k)),(null===m.maxItems||m.maxItems>1)&&l.tagType===v&&q.attr("multiple","multiple"),l.settings.placeholder&&d.attr("placeholder",m.placeholder),!l.settings.splitOn&&l.settings.delimiter){var u=l.settings.delimiter.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&");l.settings.splitOn=new RegExp("\\s*"+u+"+\\s*")}q.attr("autocorrect")&&d.attr("autocorrect",q.attr("autocorrect")),q.attr("autocapitalize")&&d.attr("autocapitalize",q.attr("autocapitalize")),l.$wrapper=b,l.$control=c,l.$control_input=d,l.$dropdown=e,l.$dropdown_content=g,e.on("mouseenter","[data-selectable]",function(){return l.onOptionHover.apply(l,arguments)}),e.on("mousedown click","[data-selectable]",function(){return l.onOptionSelect.apply(l,arguments)}),G(c,"mousedown","*:not(input)",function(){return l.onItemSelect.apply(l,arguments)}),K(d),c.on({mousedown:function(){return l.onMouseDown.apply(l,arguments)},click:function(){return l.onClick.apply(l,arguments)}}),d.on({mousedown:function(a){a.stopPropagation()},keydown:function(){return l.onKeyDown.apply(l,arguments)},keyup:function(){return l.onKeyUp.apply(l,arguments)},keypress:function(){return l.onKeyPress.apply(l,arguments)},resize:function(){l.positionDropdown.apply(l,[])},blur:function(){return l.onBlur.apply(l,arguments)},focus:function(){return l.ignoreBlur=!1,l.onFocus.apply(l,arguments)},paste:function(){return l.onPaste.apply(l,arguments)}}),p.on("keydown"+n,function(a){l.isCmdDown=a[f?"metaKey":"ctrlKey"],l.isCtrlDown=a[f?"altKey":"ctrlKey"],l.isShiftDown=a.shiftKey}),p.on("keyup"+n,function(a){a.keyCode===t&&(l.isCtrlDown=!1),a.keyCode===r&&(l.isShiftDown=!1),a.keyCode===s&&(l.isCmdDown=!1)}),p.on("mousedown"+n,function(a){if(l.isFocused){if(a.target===l.$dropdown[0]||a.target.parentNode===l.$dropdown[0])return!1;l.$control.has(a.target).length||a.target===l.$control[0]||l.blur(a.target)}}),o.on(["scroll"+n,"resize"+n].join(" "),function(){l.isOpen&&l.positionDropdown.apply(l,arguments)}),o.on("mousemove"+n,function(){l.ignoreHover=!1}),this.revertSettings={$children:q.children().detach(),tabindex:q.attr("tabindex")},q.attr("tabindex",-1).hide().after(l.$wrapper),a.isArray(m.items)&&(l.setValue(m.items),delete m.items),x&&q.on("invalid"+n,function(a){a.preventDefault(),l.isInvalid=!0,l.refreshState()}),l.updateOriginalInput(),l.refreshItems(),l.refreshState(),l.updatePlaceholder(),l.isSetup=!0,q.is(":disabled")&&l.disable(),l.on("change",this.onChange),q.data("selectize",l),q.addClass("selectized"),l.trigger("initialize"),m.preload===!0&&l.onSearchChange("")},setupTemplates:function(){var b=this,c=b.settings.labelField,d=b.settings.optgroupLabelField,e={optgroup:function(a){return'<div class="optgroup">'+a.html+"</div>"},optgroup_header:function(a,b){return'<div class="optgroup-header">'+b(a[d])+"</div>"},option:function(a,b){return'<div class="option">'+b(a[c])+"</div>"},item:function(a,b){return'<div class="item">'+b(a[c])+"</div>"},option_create:function(a,b){return'<div class="create">Add <strong>'+b(a.input)+"</strong>&hellip;</div>"}};b.settings.render=a.extend({},e,b.settings.render)},setupCallbacks:function(){var a,b,c={initialize:"onInitialize",change:"onChange",item_add:"onItemAdd",item_remove:"onItemRemove",clear:"onClear",option_add:"onOptionAdd",option_remove:"onOptionRemove",option_clear:"onOptionClear",optgroup_add:"onOptionGroupAdd",optgroup_remove:"onOptionGroupRemove",optgroup_clear:"onOptionGroupClear",dropdown_open:"onDropdownOpen",dropdown_close:"onDropdownClose",type:"onType",load:"onLoad",focus:"onFocus",blur:"onBlur"};for(a in c)c.hasOwnProperty(a)&&(b=this.settings[c[a]],b&&this.on(a,b))},onClick:function(a){var b=this;b.isFocused||(b.focus(),a.preventDefault())},onMouseDown:function(b){{var c=this,d=b.isDefaultPrevented();a(b.target)}if(c.isFocused){if(b.target!==c.$control_input[0])return"single"===c.settings.mode?c.isOpen?c.close():c.open():d||c.setActiveItem(null),!1}else d||window.setTimeout(function(){c.focus()},0)},onChange:function(){this.$input.trigger("change")},onPaste:function(b){var c=this;c.isFull()||c.isInputHidden||c.isLocked?b.preventDefault():c.settings.splitOn&&setTimeout(function(){for(var b=a.trim(c.$control_input.val()||"").split(c.settings.splitOn),d=0,e=b.length;e>d;d++)c.createItem(b[d])},0)},onKeyPress:function(a){if(this.isLocked)return a&&a.preventDefault();var b=String.fromCharCode(a.keyCode||a.which);return this.settings.create&&"multi"===this.settings.mode&&b===this.settings.delimiter?(this.createItem(),a.preventDefault(),!1):void 0},onKeyDown:function(a){var b=(a.target===this.$control_input[0],this);if(b.isLocked)return void(a.keyCode!==u&&a.preventDefault());switch(a.keyCode){case g:if(b.isCmdDown)return void b.selectAll();break;case i:return void(b.isOpen&&(a.preventDefault(),a.stopPropagation(),b.close()));case o:if(!a.ctrlKey||a.altKey)break;case n:if(!b.isOpen&&b.hasOptions)b.open();else if(b.$activeOption){b.ignoreHover=!0;var c=b.getAdjacentOption(b.$activeOption,1);c.length&&b.setActiveOption(c,!0,!0)}return void a.preventDefault();case l:if(!a.ctrlKey||a.altKey)break;case k:if(b.$activeOption){b.ignoreHover=!0;var d=b.getAdjacentOption(b.$activeOption,-1);d.length&&b.setActiveOption(d,!0,!0)}return void a.preventDefault();case h:return void(b.isOpen&&b.$activeOption&&(b.onOptionSelect({currentTarget:b.$activeOption}),a.preventDefault()));case j:return void b.advanceSelection(-1,a);case m:return void b.advanceSelection(1,a);case u:return b.settings.selectOnTab&&b.isOpen&&b.$activeOption&&(b.onOptionSelect({currentTarget:b.$activeOption}),b.isFull()||a.preventDefault()),void(b.settings.create&&b.createItem()&&a.preventDefault());case p:case q:return void b.deleteSelection(a)}return!b.isFull()&&!b.isInputHidden||(f?a.metaKey:a.ctrlKey)?void 0:void a.preventDefault()},onKeyUp:function(a){var b=this;if(b.isLocked)return a&&a.preventDefault();var c=b.$control_input.val()||"";b.lastValue!==c&&(b.lastValue=c,b.onSearchChange(c),b.refreshOptions(),b.trigger("type",c))},onSearchChange:function(a){var b=this,c=b.settings.load;c&&(b.loadedSearches.hasOwnProperty(a)||(b.loadedSearches[a]=!0,b.load(function(d){c.apply(b,[a,d])})))},onFocus:function(a){var b=this,c=b.isFocused;return b.isDisabled?(b.blur(),a&&a.preventDefault(),!1):void(b.ignoreFocus||(b.isFocused=!0,"focus"===b.settings.preload&&b.onSearchChange(""),c||b.trigger("focus"),b.$activeItems.length||(b.showInput(),b.setActiveItem(null),b.refreshOptions(!!b.settings.openOnFocus)),b.refreshState()))},onBlur:function(a,b){var c=this;if(c.isFocused&&(c.isFocused=!1,!c.ignoreFocus)){if(!c.ignoreBlur&&document.activeElement===c.$dropdown_content[0])return c.ignoreBlur=!0,void c.onFocus(a);var d=function(){c.close(),c.setTextboxValue(""),c.setActiveItem(null),c.setActiveOption(null),c.setCaret(c.items.length),c.refreshState(),(b||document.body).focus(),c.ignoreFocus=!1,c.trigger("blur")};c.ignoreFocus=!0,c.settings.create&&c.settings.createOnBlur?c.createItem(null,!1,d):d()}},onOptionHover:function(a){this.ignoreHover||this.setActiveOption(a.currentTarget,!1)},onOptionSelect:function(b){var c,d,e=this;b.preventDefault&&(b.preventDefault(),b.stopPropagation()),d=a(b.currentTarget),d.hasClass("create")?e.createItem(null,function(){e.settings.closeAfterSelect&&e.close()}):(c=d.attr("data-value"),"undefined"!=typeof c&&(e.lastQuery=null,e.setTextboxValue(""),e.addItem(c),e.settings.closeAfterSelect?e.close():!e.settings.hideSelected&&b.type&&/mouse/.test(b.type)&&e.setActiveOption(e.getOption(c))))},onItemSelect:function(a){var b=this;b.isLocked||"multi"===b.settings.mode&&(a.preventDefault(),b.setActiveItem(a.currentTarget,a))},load:function(a){var b=this,c=b.$wrapper.addClass(b.settings.loadingClass);b.loading++,a.apply(b,[function(a){b.loading=Math.max(b.loading-1,0),a&&a.length&&(b.addOption(a),b.refreshOptions(b.isFocused&&!b.isInputHidden)),b.loading||c.removeClass(b.settings.loadingClass),b.trigger("load",a)}])},setTextboxValue:function(a){var b=this.$control_input,c=b.val()!==a;c&&(b.val(a).triggerHandler("update"),this.lastValue=a)},getValue:function(){return this.tagType===v&&this.$input.attr("multiple")?this.items:this.items.join(this.settings.delimiter)},setValue:function(a,b){var c=b?[]:["change"];F(this,c,function(){this.clear(b),this.addItems(a,b)})},setActiveItem:function(b,c){var d,e,f,g,h,i,j,k,l=this;if("single"!==l.settings.mode){if(b=a(b),!b.length)return a(l.$activeItems).removeClass("active"),l.$activeItems=[],void(l.isFocused&&l.showInput());if(d=c&&c.type.toLowerCase(),"mousedown"===d&&l.isShiftDown&&l.$activeItems.length){for(k=l.$control.children(".active:last"),g=Array.prototype.indexOf.apply(l.$control[0].childNodes,[k[0]]),h=Array.prototype.indexOf.apply(l.$control[0].childNodes,[b[0]]),g>h&&(j=g,g=h,h=j),e=g;h>=e;e++)i=l.$control[0].childNodes[e],-1===l.$activeItems.indexOf(i)&&(a(i).addClass("active"),l.$activeItems.push(i));c.preventDefault()}else"mousedown"===d&&l.isCtrlDown||"keydown"===d&&this.isShiftDown?b.hasClass("active")?(f=l.$activeItems.indexOf(b[0]),l.$activeItems.splice(f,1),b.removeClass("active")):l.$activeItems.push(b.addClass("active")[0]):(a(l.$activeItems).removeClass("active"),l.$activeItems=[b.addClass("active")[0]]);l.hideInput(),this.isFocused||l.focus()}},setActiveOption:function(b,c,d){var e,f,g,h,i,j=this;j.$activeOption&&j.$activeOption.removeClass("active"),j.$activeOption=null,b=a(b),b.length&&(j.$activeOption=b.addClass("active"),(c||!y(c))&&(e=j.$dropdown_content.height(),f=j.$activeOption.outerHeight(!0),c=j.$dropdown_content.scrollTop()||0,g=j.$activeOption.offset().top-j.$dropdown_content.offset().top+c,h=g,i=g-e+f,g+f>e+c?j.$dropdown_content.stop().animate({scrollTop:i},d?j.settings.scrollDuration:0):c>g&&j.$dropdown_content.stop().animate({scrollTop:h},d?j.settings.scrollDuration:0)))},selectAll:function(){var a=this;"single"!==a.settings.mode&&(a.$activeItems=Array.prototype.slice.apply(a.$control.children(":not(input)").addClass("active")),a.$activeItems.length&&(a.hideInput(),a.close()),a.focus())},hideInput:function(){var a=this;a.setTextboxValue(""),a.$control_input.css({opacity:0,position:"absolute",left:a.rtl?1e4:-1e4}),a.isInputHidden=!0},showInput:function(){this.$control_input.css({opacity:1,position:"relative",left:0}),this.isInputHidden=!1},focus:function(){var a=this;a.isDisabled||(a.ignoreFocus=!0,a.$control_input[0].focus(),window.setTimeout(function(){a.ignoreFocus=!1,a.onFocus()},0))},blur:function(a){this.$control_input[0].blur(),this.onBlur(null,a)},getScoreFunction:function(a){return this.sifter.getScoreFunction(a,this.getSearchOptions())},getSearchOptions:function(){var a=this.settings,b=a.sortField;return"string"==typeof b&&(b=[{field:b}]),{fields:a.searchField,conjunction:a.searchConjunction,sort:b}},search:function(b){var c,d,e,f=this,g=f.settings,h=this.getSearchOptions();if(g.score&&(e=f.settings.score.apply(this,[b]),"function"!=typeof e))throw new Error('Selectize "score" setting must be a function that returns a function');if(b!==f.lastQuery?(f.lastQuery=b,d=f.sifter.search(b,a.extend(h,{score:e})),f.currentResults=d):d=a.extend(!0,{},f.currentResults),g.hideSelected)for(c=d.items.length-1;c>=0;c--)-1!==f.items.indexOf(z(d.items[c].id))&&d.items.splice(c,1);return d},refreshOptions:function(b){var c,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;"undefined"==typeof b&&(b=!0);var t=this,u=a.trim(t.$control_input.val()),v=t.search(u),w=t.$dropdown_content,x=t.$activeOption&&z(t.$activeOption.attr("data-value"));for(g=v.items.length,"number"==typeof t.settings.maxOptions&&(g=Math.min(g,t.settings.maxOptions)),h={},i=[],c=0;g>c;c++)for(j=t.options[v.items[c].id],k=t.render("option",j),l=j[t.settings.optgroupField]||"",m=a.isArray(l)?l:[l],e=0,f=m&&m.length;f>e;e++)l=m[e],t.optgroups.hasOwnProperty(l)||(l=""),h.hasOwnProperty(l)||(h[l]=[],i.push(l)),h[l].push(k);for(this.settings.lockOptgroupOrder&&i.sort(function(a,b){var c=t.optgroups[a].$order||0,d=t.optgroups[b].$order||0;return c-d}),n=[],c=0,g=i.length;g>c;c++)l=i[c],t.optgroups.hasOwnProperty(l)&&h[l].length?(o=t.render("optgroup_header",t.optgroups[l])||"",o+=h[l].join(""),n.push(t.render("optgroup",a.extend({},t.optgroups[l],{html:o})))):n.push(h[l].join(""));if(w.html(n.join("")),t.settings.highlight&&v.query.length&&v.tokens.length)for(c=0,g=v.tokens.length;g>c;c++)d(w,v.tokens[c].regex);if(!t.settings.hideSelected)for(c=0,g=t.items.length;g>c;c++)t.getOption(t.items[c]).addClass("selected");p=t.canCreate(u),p&&(w.prepend(t.render("option_create",{input:u})),s=a(w[0].childNodes[0])),t.hasOptions=v.items.length>0||p,t.hasOptions?(v.items.length>0?(r=x&&t.getOption(x),r&&r.length?q=r:"single"===t.settings.mode&&t.items.length&&(q=t.getOption(t.items[0])),q&&q.length||(q=s&&!t.settings.addPrecedence?t.getAdjacentOption(s,1):w.find("[data-selectable]:first"))):q=s,t.setActiveOption(q),b&&!t.isOpen&&t.open()):(t.setActiveOption(null),b&&t.isOpen&&t.close())},addOption:function(b){var c,d,e,f=this;if(a.isArray(b))for(c=0,d=b.length;d>c;c++)f.addOption(b[c]);else(e=f.registerOption(b))&&(f.userOptions[e]=!0,f.lastQuery=null,f.trigger("option_add",e,b))},registerOption:function(a){var b=z(a[this.settings.valueField]);return!b||this.options.hasOwnProperty(b)?!1:(a.$order=a.$order||++this.order,this.options[b]=a,b)},registerOptionGroup:function(a){var b=z(a[this.settings.optgroupValueField]);return b?(a.$order=a.$order||++this.order,this.optgroups[b]=a,b):!1},addOptionGroup:function(a,b){b[this.settings.optgroupValueField]=a,(a=this.registerOptionGroup(b))&&this.trigger("optgroup_add",a,b)},removeOptionGroup:function(a){this.optgroups.hasOwnProperty(a)&&(delete this.optgroups[a],this.renderCache={},this.trigger("optgroup_remove",a))},clearOptionGroups:function(){this.optgroups={},this.renderCache={},this.trigger("optgroup_clear")},updateOption:function(b,c){var d,e,f,g,h,i,j,k=this;if(b=z(b),f=z(c[k.settings.valueField]),null!==b&&k.options.hasOwnProperty(b)){if("string"!=typeof f)throw new Error("Value must be set in option data");j=k.options[b].$order,f!==b&&(delete k.options[b],g=k.items.indexOf(b),-1!==g&&k.items.splice(g,1,f)),c.$order=c.$order||j,k.options[f]=c,h=k.renderCache.item,i=k.renderCache.option,h&&(delete h[b],delete h[f]),i&&(delete i[b],delete i[f]),-1!==k.items.indexOf(f)&&(d=k.getItem(b),e=a(k.render("item",c)),d.hasClass("active")&&e.addClass("active"),d.replaceWith(e)),k.lastQuery=null,k.isOpen&&k.refreshOptions(!1)}},removeOption:function(a,b){var c=this;a=z(a);var d=c.renderCache.item,e=c.renderCache.option;d&&delete d[a],e&&delete e[a],delete c.userOptions[a],delete c.options[a],c.lastQuery=null,c.trigger("option_remove",a),c.removeItem(a,b)},clearOptions:function(){var a=this;a.loadedSearches={},a.userOptions={},a.renderCache={},a.options=a.sifter.items={},a.lastQuery=null,a.trigger("option_clear"),a.clear()},getOption:function(a){return this.getElementWithValue(a,this.$dropdown_content.find("[data-selectable]"))},getAdjacentOption:function(b,c){var d=this.$dropdown.find("[data-selectable]"),e=d.index(b)+c;return e>=0&&e<d.length?d.eq(e):a()},getElementWithValue:function(b,c){if(b=z(b),"undefined"!=typeof b&&null!==b)for(var d=0,e=c.length;e>d;d++)if(c[d].getAttribute("data-value")===b)return a(c[d]);return a()},getItem:function(a){return this.getElementWithValue(a,this.$control.children())},addItems:function(b,c){for(var d=a.isArray(b)?b:[b],e=0,f=d.length;f>e;e++)this.isPending=f-1>e,this.addItem(d[e],c)},addItem:function(b,c){var d=c?[]:["change"];F(this,d,function(){var d,e,f,g,h,i=this,j=i.settings.mode;return b=z(b),-1!==i.items.indexOf(b)?void("single"===j&&i.close()):void(i.options.hasOwnProperty(b)&&("single"===j&&i.clear(c),"multi"===j&&i.isFull()||(d=a(i.render("item",i.options[b])),h=i.isFull(),i.items.splice(i.caretPos,0,b),i.insertAtCaret(d),(!i.isPending||!h&&i.isFull())&&i.refreshState(),i.isSetup&&(f=i.$dropdown_content.find("[data-selectable]"),i.isPending||(e=i.getOption(b),g=i.getAdjacentOption(e,1).attr("data-value"),i.refreshOptions(i.isFocused&&"single"!==j),g&&i.setActiveOption(i.getOption(g))),!f.length||i.isFull()?i.close():i.positionDropdown(),i.updatePlaceholder(),i.trigger("item_add",b,d),i.updateOriginalInput({silent:c})))))})},removeItem:function(a,b){var c,d,e,f=this;c="object"==typeof a?a:f.getItem(a),a=z(c.attr("data-value")),d=f.items.indexOf(a),-1!==d&&(c.remove(),c.hasClass("active")&&(e=f.$activeItems.indexOf(c[0]),f.$activeItems.splice(e,1)),f.items.splice(d,1),f.lastQuery=null,!f.settings.persist&&f.userOptions.hasOwnProperty(a)&&f.removeOption(a,b),d<f.caretPos&&f.setCaret(f.caretPos-1),f.refreshState(),f.updatePlaceholder(),f.updateOriginalInput({silent:b}),f.positionDropdown(),f.trigger("item_remove",a,c))},createItem:function(b,c){var d=this,e=d.caretPos;b=b||a.trim(d.$control_input.val()||"");var f=arguments[arguments.length-1];if("function"!=typeof f&&(f=function(){}),"boolean"!=typeof c&&(c=!0),!d.canCreate(b))return f(),!1;d.lock();var g="function"==typeof d.settings.create?this.settings.create:function(a){var b={};return b[d.settings.labelField]=a,b[d.settings.valueField]=a,b},h=D(function(a){if(d.unlock(),!a||"object"!=typeof a)return f();var b=z(a[d.settings.valueField]);return"string"!=typeof b?f():(d.setTextboxValue(""),d.addOption(a),d.setCaret(e),d.addItem(b),d.refreshOptions(c&&"single"!==d.settings.mode),void f(a))}),i=g.apply(this,[b,h]);return"undefined"!=typeof i&&h(i),!0},refreshItems:function(){this.lastQuery=null,this.isSetup&&this.addItem(this.items),this.refreshState(),this.updateOriginalInput()},refreshState:function(){var a,b=this;b.isRequired&&(b.items.length&&(b.isInvalid=!1),b.$control_input.prop("required",a)),b.refreshClasses()},refreshClasses:function(){var b=this,c=b.isFull(),d=b.isLocked;b.$wrapper.toggleClass("rtl",b.rtl),b.$control.toggleClass("focus",b.isFocused).toggleClass("disabled",b.isDisabled).toggleClass("required",b.isRequired).toggleClass("invalid",b.isInvalid).toggleClass("locked",d).toggleClass("full",c).toggleClass("not-full",!c).toggleClass("input-active",b.isFocused&&!b.isInputHidden).toggleClass("dropdown-active",b.isOpen).toggleClass("has-options",!a.isEmptyObject(b.options)).toggleClass("has-items",b.items.length>0),b.$control_input.data("grow",!c&&!d)},isFull:function(){return null!==this.settings.maxItems&&this.items.length>=this.settings.maxItems},updateOriginalInput:function(a){var b,c,d,e,f=this;if(a=a||{},f.tagType===v){for(d=[],b=0,c=f.items.length;c>b;b++)e=f.options[f.items[b]][f.settings.labelField]||"",d.push('<option value="'+A(f.items[b])+'" selected="selected">'+A(e)+"</option>");d.length||this.$input.attr("multiple")||d.push('<option value="" selected="selected"></option>'),f.$input.html(d.join(""))}else f.$input.val(f.getValue()),f.$input.attr("value",f.$input.val());f.isSetup&&(a.silent||f.trigger("change",f.$input.val()))},updatePlaceholder:function(){if(this.settings.placeholder){var a=this.$control_input;this.items.length?a.removeAttr("placeholder"):a.attr("placeholder",this.settings.placeholder),a.triggerHandler("update",{force:!0})}},open:function(){var a=this;a.isLocked||a.isOpen||"multi"===a.settings.mode&&a.isFull()||(a.focus(),a.isOpen=!0,a.refreshState(),a.$dropdown.css({visibility:"hidden",display:"block"}),a.positionDropdown(),a.$dropdown.css({visibility:"visible"}),a.trigger("dropdown_open",a.$dropdown))},close:function(){var a=this,b=a.isOpen;"single"===a.settings.mode&&a.items.length&&a.hideInput(),a.isOpen=!1,a.$dropdown.hide(),a.setActiveOption(null),a.refreshState(),b&&a.trigger("dropdown_close",a.$dropdown)},positionDropdown:function(){var a=this.$control,b="body"===this.settings.dropdownParent?a.offset():a.position();b.top+=a.outerHeight(!0),this.$dropdown.css({width:a.outerWidth(),top:b.top,left:b.left})},clear:function(a){var b=this;b.items.length&&(b.$control.children(":not(input)").remove(),b.items=[],b.lastQuery=null,b.setCaret(0),b.setActiveItem(null),b.updatePlaceholder(),b.updateOriginalInput({silent:a}),b.refreshState(),b.showInput(),b.trigger("clear"))},insertAtCaret:function(b){var c=Math.min(this.caretPos,this.items.length);0===c?this.$control.prepend(b):a(this.$control[0].childNodes[c]).before(b),this.setCaret(c+1)},deleteSelection:function(b){var c,d,e,f,g,h,i,j,k,l=this;if(e=b&&b.keyCode===p?-1:1,f=H(l.$control_input[0]),l.$activeOption&&!l.settings.hideSelected&&(i=l.getAdjacentOption(l.$activeOption,-1).attr("data-value")),g=[],l.$activeItems.length){for(k=l.$control.children(".active:"+(e>0?"last":"first")),h=l.$control.children(":not(input)").index(k),e>0&&h++,c=0,d=l.$activeItems.length;d>c;c++)g.push(a(l.$activeItems[c]).attr("data-value"));
3
+ b&&(b.preventDefault(),b.stopPropagation())}else(l.isFocused||"single"===l.settings.mode)&&l.items.length&&(0>e&&0===f.start&&0===f.length?g.push(l.items[l.caretPos-1]):e>0&&f.start===l.$control_input.val().length&&g.push(l.items[l.caretPos]));if(!g.length||"function"==typeof l.settings.onDelete&&l.settings.onDelete.apply(l,[g])===!1)return!1;for("undefined"!=typeof h&&l.setCaret(h);g.length;)l.removeItem(g.pop());return l.showInput(),l.positionDropdown(),l.refreshOptions(!0),i&&(j=l.getOption(i),j.length&&l.setActiveOption(j)),!0},advanceSelection:function(a,b){var c,d,e,f,g,h,i=this;0!==a&&(i.rtl&&(a*=-1),c=a>0?"last":"first",d=H(i.$control_input[0]),i.isFocused&&!i.isInputHidden?(f=i.$control_input.val().length,g=0>a?0===d.start&&0===d.length:d.start===f,g&&!f&&i.advanceCaret(a,b)):(h=i.$control.children(".active:"+c),h.length&&(e=i.$control.children(":not(input)").index(h),i.setActiveItem(null),i.setCaret(a>0?e+1:e))))},advanceCaret:function(a,b){var c,d,e=this;0!==a&&(c=a>0?"next":"prev",e.isShiftDown?(d=e.$control_input[c](),d.length&&(e.hideInput(),e.setActiveItem(d),b&&b.preventDefault())):e.setCaret(e.caretPos+a))},setCaret:function(b){var c=this;if(b="single"===c.settings.mode?c.items.length:Math.max(0,Math.min(c.items.length,b)),!c.isPending){var d,e,f,g;for(f=c.$control.children(":not(input)"),d=0,e=f.length;e>d;d++)g=a(f[d]).detach(),b>d?c.$control_input.before(g):c.$control.append(g)}c.caretPos=b},lock:function(){this.close(),this.isLocked=!0,this.refreshState()},unlock:function(){this.isLocked=!1,this.refreshState()},disable:function(){var a=this;a.$input.prop("disabled",!0),a.$control_input.prop("disabled",!0).prop("tabindex",-1),a.isDisabled=!0,a.lock()},enable:function(){var a=this;a.$input.prop("disabled",!1),a.$control_input.prop("disabled",!1).prop("tabindex",a.tabIndex),a.isDisabled=!1,a.unlock()},destroy:function(){var b=this,c=b.eventNS,d=b.revertSettings;b.trigger("destroy"),b.off(),b.$wrapper.remove(),b.$dropdown.remove(),b.$input.html("").append(d.$children).removeAttr("tabindex").removeClass("selectized").attr({tabindex:d.tabindex}).show(),b.$control_input.removeData("grow"),b.$input.removeData("selectize"),a(window).off(c),a(document).off(c),a(document.body).off(c),delete b.$input[0].selectize},render:function(a,b){var c,d,e="",f=!1,g=this,h=/^[\t \r\n]*<([a-z][a-z0-9\-_]*(?:\:[a-z][a-z0-9\-_]*)?)/i;return("option"===a||"item"===a)&&(c=z(b[g.settings.valueField]),f=!!c),f&&(y(g.renderCache[a])||(g.renderCache[a]={}),g.renderCache[a].hasOwnProperty(c))?g.renderCache[a][c]:(e=g.settings.render[a].apply(this,[b,A]),("option"===a||"option_create"===a)&&(e=e.replace(h,"<$1 data-selectable")),"optgroup"===a&&(d=b[g.settings.optgroupValueField]||"",e=e.replace(h,'<$1 data-group="'+B(A(d))+'"')),("option"===a||"item"===a)&&(e=e.replace(h,'<$1 data-value="'+B(A(c||""))+'"')),f&&(g.renderCache[a][c]=e),e)},clearCache:function(a){var b=this;"undefined"==typeof a?b.renderCache={}:delete b.renderCache[a]},canCreate:function(a){var b=this;if(!b.settings.create)return!1;var c=b.settings.createFilter;return!(!a.length||"function"==typeof c&&!c.apply(b,[a])||"string"==typeof c&&!new RegExp(c).test(a)||c instanceof RegExp&&!c.test(a))}}),L.count=0,L.defaults={options:[],optgroups:[],plugins:[],delimiter:",",splitOn:null,persist:!0,diacritics:!0,create:!1,createOnBlur:!1,createFilter:null,highlight:!0,openOnFocus:!0,maxOptions:1e3,maxItems:null,hideSelected:null,addPrecedence:!1,selectOnTab:!1,preload:!1,allowEmptyOption:!1,closeAfterSelect:!1,scrollDuration:60,loadThrottle:300,loadingClass:"loading",dataAttr:"data-data",optgroupField:"optgroup",valueField:"value",labelField:"text",optgroupLabelField:"label",optgroupValueField:"value",lockOptgroupOrder:!1,sortField:"$order",searchField:["text"],searchConjunction:"and",mode:null,wrapperClass:"selectize-control",inputClass:"selectize-input",dropdownClass:"selectize-dropdown",dropdownContentClass:"selectize-dropdown-content",dropdownParent:null,copyClassesToDropdown:!0,render:{}},a.fn.selectize=function(b){var c=a.fn.selectize.defaults,d=a.extend({},c,b),e=d.dataAttr,f=d.labelField,g=d.valueField,h=d.optgroupField,i=d.optgroupLabelField,j=d.optgroupValueField,k=function(b,c){var h,i,j,k,l=b.attr(e);if(l)for(c.options=JSON.parse(l),h=0,i=c.options.length;i>h;h++)c.items.push(c.options[h][g]);else{var m=a.trim(b.val()||"");if(!d.allowEmptyOption&&!m.length)return;for(j=m.split(d.delimiter),h=0,i=j.length;i>h;h++)k={},k[f]=j[h],k[g]=j[h],c.options.push(k);c.items=j}},l=function(b,c){var k,l,m,n,o=c.options,p={},q=function(a){var b=e&&a.attr(e);return"string"==typeof b&&b.length?JSON.parse(b):null},r=function(b,e){b=a(b);var i=z(b.attr("value"));if(i||d.allowEmptyOption)if(p.hasOwnProperty(i)){if(e){var j=p[i][h];j?a.isArray(j)?j.push(e):p[i][h]=[j,e]:p[i][h]=e}}else{var k=q(b)||{};k[f]=k[f]||b.text(),k[g]=k[g]||i,k[h]=k[h]||e,p[i]=k,o.push(k),b.is(":selected")&&c.items.push(i)}},s=function(b){var d,e,f,g,h;for(b=a(b),f=b.attr("label"),f&&(g=q(b)||{},g[i]=f,g[j]=f,c.optgroups.push(g)),h=a("option",b),d=0,e=h.length;e>d;d++)r(h[d],f)};for(c.maxItems=b.attr("multiple")?null:1,n=b.children(),k=0,l=n.length;l>k;k++)m=n[k].tagName.toLowerCase(),"optgroup"===m?s(n[k]):"option"===m&&r(n[k])};return this.each(function(){if(!this.selectize){var e,f=a(this),g=this.tagName.toLowerCase(),h=f.attr("placeholder")||f.attr("data-placeholder");h||d.allowEmptyOption||(h=f.children('option[value=""]').text());var i={placeholder:h,options:[],optgroups:[],items:[]};"select"===g?l(f,i):k(f,i),e=new L(f,a.extend(!0,{},c,i,b))}})},a.fn.selectize.defaults=L.defaults,a.fn.selectize.support={validity:x},L.define("drag_drop",function(){if(!a.fn.sortable)throw new Error('The "drag_drop" plugin requires jQuery UI "sortable".');if("multi"===this.settings.mode){var b=this;b.lock=function(){var a=b.lock;return function(){var c=b.$control.data("sortable");return c&&c.disable(),a.apply(b,arguments)}}(),b.unlock=function(){var a=b.unlock;return function(){var c=b.$control.data("sortable");return c&&c.enable(),a.apply(b,arguments)}}(),b.setup=function(){var c=b.setup;return function(){c.apply(this,arguments);var d=b.$control.sortable({items:"[data-value]",forcePlaceholderSize:!0,disabled:b.isLocked,start:function(a,b){b.placeholder.css("width",b.helper.css("width")),d.css({overflow:"visible"})},stop:function(){d.css({overflow:"hidden"});var c=b.$activeItems?b.$activeItems.slice():null,e=[];d.children("[data-value]").each(function(){e.push(a(this).attr("data-value"))}),b.setValue(e),b.setActiveItem(c)}})}}()}}),L.define("dropdown_header",function(b){var c=this;b=a.extend({title:"Untitled",headerClass:"selectize-dropdown-header",titleRowClass:"selectize-dropdown-header-title",labelClass:"selectize-dropdown-header-label",closeClass:"selectize-dropdown-header-close",html:function(a){return'<div class="'+a.headerClass+'"><div class="'+a.titleRowClass+'"><span class="'+a.labelClass+'">'+a.title+'</span><a href="javascript:void(0)" class="'+a.closeClass+'">&times;</a></div></div>'}},b),c.setup=function(){var d=c.setup;return function(){d.apply(c,arguments),c.$dropdown_header=a(b.html(b)),c.$dropdown.prepend(c.$dropdown_header)}}()}),L.define("optgroup_columns",function(b){var c=this;b=a.extend({equalizeWidth:!0,equalizeHeight:!0},b),this.getAdjacentOption=function(b,c){var d=b.closest("[data-group]").find("[data-selectable]"),e=d.index(b)+c;return e>=0&&e<d.length?d.eq(e):a()},this.onKeyDown=function(){var a=c.onKeyDown;return function(b){var d,e,f,g;return!this.isOpen||b.keyCode!==j&&b.keyCode!==m?a.apply(this,arguments):(c.ignoreHover=!0,g=this.$activeOption.closest("[data-group]"),d=g.find("[data-selectable]").index(this.$activeOption),g=b.keyCode===j?g.prev("[data-group]"):g.next("[data-group]"),f=g.find("[data-selectable]"),e=f.eq(Math.min(f.length-1,d)),void(e.length&&this.setActiveOption(e)))}}();var d=function(){var a,b=d.width,c=document;return"undefined"==typeof b&&(a=c.createElement("div"),a.innerHTML='<div style="width:50px;height:50px;position:absolute;left:-50px;top:-50px;overflow:auto;"><div style="width:1px;height:100px;"></div></div>',a=a.firstChild,c.body.appendChild(a),b=d.width=a.offsetWidth-a.clientWidth,c.body.removeChild(a)),b},e=function(){var e,f,g,h,i,j,k;if(k=a("[data-group]",c.$dropdown_content),f=k.length,f&&c.$dropdown_content.width()){if(b.equalizeHeight){for(g=0,e=0;f>e;e++)g=Math.max(g,k.eq(e).height());k.css({height:g})}b.equalizeWidth&&(j=c.$dropdown_content.innerWidth()-d(),h=Math.round(j/f),k.css({width:h}),f>1&&(i=j-h*(f-1),k.eq(f-1).css({width:i})))}};(b.equalizeHeight||b.equalizeWidth)&&(C.after(this,"positionDropdown",e),C.after(this,"refreshOptions",e))}),L.define("remove_button",function(b){if("single"!==this.settings.mode){b=a.extend({label:"&times;",title:"Remove",className:"remove",append:!0},b);var c=this,d='<a href="javascript:void(0)" class="'+b.className+'" tabindex="-1" title="'+A(b.title)+'">'+b.label+"</a>",e=function(a,b){var c=a.search(/(<\/[^>]+>\s*)$/);return a.substring(0,c)+b+a.substring(c)};this.setup=function(){var f=c.setup;return function(){if(b.append){var g=c.settings.render.item;c.settings.render.item=function(){return e(g.apply(this,arguments),d)}}f.apply(this,arguments),this.$control.on("click","."+b.className,function(b){if(b.preventDefault(),!c.isLocked){var d=a(b.currentTarget).parent();c.setActiveItem(d),c.deleteSelection()&&c.setCaret(c.items.length)}})}}()}}),L.define("restore_on_backspace",function(a){var b=this;a.text=a.text||function(a){return a[this.settings.labelField]},this.onKeyDown=function(){var c=b.onKeyDown;return function(b){var d,e;return b.keyCode===p&&""===this.$control_input.val()&&!this.$activeItems.length&&(d=this.caretPos-1,d>=0&&d<this.items.length)?(e=this.options[this.items[d]],this.deleteSelection(b)&&(this.setTextboxValue(a.text.apply(this,[e])),this.refreshOptions(!0)),void b.preventDefault()):c.apply(this,arguments)}}()}),L});
framework/views/backend-settings-form.php CHANGED
@@ -9,8 +9,33 @@
9
  */
10
  ?>
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  <?php if ($side_tabs): ?>
13
- <div class="fw-settings-form-header fw-row" style="opacity:0;">
14
  <div class="fw-col-xs-12 fw-col-sm-6">
15
  <h2><?php echo fw()->theme->manifest->get_name() ?>
16
  <?php if (fw()->theme->manifest->get('author')): ?>
@@ -51,10 +76,9 @@
51
  </div>
52
  <script type="text/javascript">
53
  jQuery(function($){
54
- fwEvents.on("fw:options:init", function(data){
55
- // styles are loaded in footer and are applied after page load
56
- data.$elements.find('.fw-settings-form-header').fadeTo('fast', 1, function(){ $(this).css('opacity', ''); });
57
- }, 300);
58
  });
59
  </script>
60
  <?php endif; ?>
@@ -119,7 +143,7 @@ jQuery(function($){
119
  * so use alternative solution http://stackoverflow.com/a/5721762
120
  */
121
  {
122
- $(this).closest('form').find('input[type="submit"][clicked]').removeAttr('clicked');
123
  $(this).attr('clicked', '');
124
  }
125
 
@@ -134,6 +158,23 @@ jQuery(function($){
134
  </script>
135
  <!-- end: reset warning -->
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  <?php if ($ajax_submit): ?>
138
  <!-- ajax submit -->
139
  <script type="text/javascript">
@@ -247,6 +288,8 @@ jQuery(function($){
247
  setTimeout(function(){
248
  elements.$form.css('transition', 'opacity ease .3s');
249
  elements.$form.css('opacity', '0');
 
 
250
  setTimeout(function() {
251
  var focusTabId = elements.$form.find("input[name='<?php echo esc_js($focus_tab_input_name); ?>']").val();
252
  var scrollTop = jQuery(window).scrollTop();
@@ -279,6 +322,8 @@ jQuery(function($){
279
  elements.$form.css('visibility', '');
280
  }, 300);
281
  }
 
 
282
  }, 300);
283
  }, 300);
284
  }).fail(function(jqXHR, textStatus, errorThrown){
@@ -293,6 +338,7 @@ jQuery(function($){
293
  });
294
  } else {
295
  fw.soleModal.hide('fw-options-ajax-save-loading');
 
296
  }
297
  }
298
  });
9
  */
10
  ?>
11
 
12
+ <script type="text/javascript">
13
+ (function($){
14
+ var fwLoadingId = 'fw-theme-settings';
15
+
16
+ {
17
+ fw.loading.show(fwLoadingId);
18
+
19
+ fwEvents.one('fw:options:init', function(data){
20
+ fw.loading.hide(fwLoadingId);
21
+ });
22
+ }
23
+
24
+ $(function($){
25
+ $(document.body).on({
26
+ 'fw:settings-form:before-html-reset': function(){
27
+ fw.loading.show(fwLoadingId);
28
+ },
29
+ 'fw:settings-form:reset': function(){
30
+ fw.loading.hide(fwLoadingId);
31
+ }
32
+ });
33
+ });
34
+ })(jQuery);
35
+ </script>
36
+
37
  <?php if ($side_tabs): ?>
38
+ <div class="fw-settings-form-header fw-row">
39
  <div class="fw-col-xs-12 fw-col-sm-6">
40
  <h2><?php echo fw()->theme->manifest->get_name() ?>
41
  <?php if (fw()->theme->manifest->get('author')): ?>
76
  </div>
77
  <script type="text/javascript">
78
  jQuery(function($){
79
+ fwEvents.on('fw:options:init', function(data){
80
+ data.$elements.find('.fw-settings-form-header:not(.initialized)').addClass('initialized');
81
+ });
 
82
  });
83
  </script>
84
  <?php endif; ?>
143
  * so use alternative solution http://stackoverflow.com/a/5721762
144
  */
145
  {
146
+ $(this).closest('form').find('[clicked]:submit').removeAttr('clicked');
147
  $(this).attr('clicked', '');
148
  }
149
 
158
  </script>
159
  <!-- end: reset warning -->
160
 
161
+ <script type="text/javascript">
162
+ jQuery(function($){
163
+ var $form = $('form[data-fw-form-id="fw_settings"]:first'),
164
+ timeoutId = 0;
165
+
166
+ $form.on('change.fw_settings_form_delayed_change', function(){
167
+ clearTimeout(timeoutId);
168
+ /**
169
+ * Run on timeout to prevent too often trigger (and cpu load) when a bunch of changes will happen at once
170
+ */
171
+ timeoutId = setTimeout(function () {
172
+ $form.trigger('fw:settings-form:delayed-change');
173
+ }, 333);
174
+ });
175
+ });
176
+ </script>
177
+
178
  <?php if ($ajax_submit): ?>
179
  <!-- ajax submit -->
180
  <script type="text/javascript">
288
  setTimeout(function(){
289
  elements.$form.css('transition', 'opacity ease .3s');
290
  elements.$form.css('opacity', '0');
291
+ elements.$form.trigger('fw:settings-form:before-html-reset');
292
+
293
  setTimeout(function() {
294
  var focusTabId = elements.$form.find("input[name='<?php echo esc_js($focus_tab_input_name); ?>']").val();
295
  var scrollTop = jQuery(window).scrollTop();
322
  elements.$form.css('visibility', '');
323
  }, 300);
324
  }
325
+
326
+ elements.$form.trigger('fw:settings-form:reset');
327
  }, 300);
328
  }, 300);
329
  }).fail(function(jqXHR, textStatus, errorThrown){
338
  });
339
  } else {
340
  fw.soleModal.hide('fw-options-ajax-save-loading');
341
+ elements.$form.trigger('fw:settings-form:saved');
342
  }
343
  }
344
  });
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: unyson, themefusecom
3
  Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio, framework
4
  Requires at least: 4.0.0
5
  Tested up to: 4.2
6
- Stable tag: 2.3.2
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -62,11 +62,7 @@ For extending or theming Unyson, see [developers documetation](http://manual.uny
62
 
63
  = Where can I report bugs or contribute to the project? =
64
 
65
- You can report the issue via Unyson Github Repository [Issues page](https://github.com/ThemeFuse/Unyson/issues).
66
-
67
- = Where can I request new features? =
68
-
69
- The Unyson development team actively participates on [Trello Unyson Development Board](https://trello.com/b/Xm9TxasH/unyson-development), and uses it to communicate with the outside world about its development priorities and tendencies.
70
 
71
  = Will Unyson work with my theme? =
72
 
@@ -86,6 +82,23 @@ Yes; Unyson will work with any theme.
86
 
87
  == Changelog ==
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  = 2.3.2 =
90
  * Added option-type `unique` to make possible [this](http://manual.unyson.io/en/latest/extension/shortcodes/index.html#enqueue-shortcode-dynamic-css-in-page-head)
91
  * Added the `fw_get_google_fonts_v2()` function
3
  Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio, framework
4
  Requires at least: 4.0.0
5
  Tested up to: 4.2
6
+ Stable tag: 2.3.3
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
62
 
63
  = Where can I report bugs or contribute to the project? =
64
 
65
+ You can open issues via Unyson Github Repository [Issues page](https://github.com/ThemeFuse/Unyson/issues).
 
 
 
 
66
 
67
  = Will Unyson work with my theme? =
68
 
82
 
83
  == Changelog ==
84
 
85
+ = 2.3.3 =
86
+ * Fixed [#628](https://github.com/ThemeFuse/Unyson/issues/628), [#649](https://github.com/ThemeFuse/Unyson/issues/649), [#637](https://github.com/ThemeFuse/Unyson/issues/637), [#358](https://github.com/ThemeFuse/Unyson/issues/358)
87
+ * Added option type `typography-v2`
88
+ * Option type `addable-option`, `addable-box` and `addable-popup`: Added the `add-button-text` and `sortable` parameters [#631](https://github.com/ThemeFuse/Unyson/issues/631)
89
+ * Optimized option type `typography` fonts select (now it loads faster)
90
+ * Extension download improvement: Fetch only [the latest release](https://developer.github.com/v3/repos/releases/#get-the-latest-release) instead of [all releases](https://developer.github.com/v3/repos/releases/#list-releases-for-a-repository)
91
+ * Improved the `fw.loading` js helper. Changed the loading image.
92
+ * Option type `range-slider`: fixed bug with default value
93
+ * Option type `checkbox` and `switch`: Fix boolean values when the option is used in options modal inside other options
94
+ * Call `FW_Option_Type::_init()` after the option type has been registered
95
+ * `fw.OptionsModal`: Added html cache [#](https://github.com/ThemeFuse/Unyson/issues/675#issuecomment-112555557)
96
+ * Added `$old_value` parameter in `'fw_post_options_update'` action
97
+ * Added the `fw_get_image_sizes()` function
98
+ * Enabled the `colorpicker` and `textcolor` plugins for the `wp-editor` option type
99
+ * Option type `background-image` and `multi-picker`: minor css fixes
100
+ * Updated `selectize.js` to `0.12.1`
101
+
102
  = 2.3.2 =
103
  * Added option-type `unique` to make possible [this](http://manual.unyson.io/en/latest/extension/shortcodes/index.html#enqueue-shortcode-dynamic-css-in-page-head)
104
  * Added the `fw_get_google_fonts_v2()` function
unyson.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Unyson
4
  * Plugin URI: http://unyson.themefuse.com/
5
  * Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
6
- * Version: 2.3.2
7
  * Author: ThemeFuse
8
  * Author URI: http://themefuse.com
9
  * License: GPL2+
3
  * Plugin Name: Unyson
4
  * Plugin URI: http://unyson.themefuse.com/
5
  * Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
6
+ * Version: 2.3.3
7
  * Author: ThemeFuse
8
  * Author URI: http://themefuse.com
9
  * License: GPL2+