YITH WooCommerce Ajax Search - Version 1.2

Version Description

  • Updated: Plugin Core Framework
Download this release

Release Info

Developer yithemes
Plugin Icon 128x128 YITH WooCommerce Ajax Search
Version 1.2
Comparing to
See all releases

Code changes from version 1.1.3 to 1.2

Files changed (149) hide show
  1. README.txt +4 -5
  2. assets/images/01.jpg +0 -0
  3. assets/images/02.jpg +0 -0
  4. assets/images/03.jpg +0 -0
  5. assets/images/number-five.png +0 -0
  6. assets/images/number-fourth.png +0 -0
  7. assets/images/number-one.png +0 -0
  8. assets/images/number-seven.png +0 -0
  9. assets/images/number-six.png +0 -0
  10. assets/images/number-three.png +0 -0
  11. assets/images/number-two.png +0 -0
  12. assets/images/upgrade.png +0 -0
  13. assets/js/frontend.min.js +2 -31
  14. class.yith-wcas-admin.php +146 -367
  15. class.yith-wcas-frontend.php +1 -1
  16. class.yith-wcas.php +85 -68
  17. functions.yith-wcas.php +1 -1
  18. init.php +78 -15
  19. languages/default.po +967 -60
  20. languages/yit-it_IT.mo +0 -0
  21. languages/yit-it_IT.po +1014 -79
  22. languages/yit.pot +969 -60
  23. plugin-fw/assets/css/chosen/chosen.css +435 -0
  24. plugin-fw/assets/css/codemirror/codemirror.css +260 -0
  25. plugin-fw/assets/css/metaboxes.css +598 -0
  26. plugin-fw/assets/css/overcast/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  27. plugin-fw/assets/css/overcast/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  28. plugin-fw/assets/css/overcast/images/ui-bg_flat_55_c0402a_40x100.png +0 -0
  29. plugin-fw/assets/css/overcast/images/ui-bg_flat_55_eeeeee_40x100.png +0 -0
  30. plugin-fw/assets/css/overcast/images/ui-bg_glass_100_f8f8f8_1x400.png +0 -0
  31. plugin-fw/assets/css/overcast/images/ui-bg_glass_35_dddddd_1x400.png +0 -0
  32. plugin-fw/assets/css/overcast/images/ui-bg_glass_60_eeeeee_1x400.png +0 -0
  33. plugin-fw/assets/css/overcast/images/ui-bg_inset-hard_75_999999_1x100.png +0 -0
  34. plugin-fw/assets/css/overcast/images/ui-bg_inset-soft_50_c9c9c9_1x100.png +0 -0
  35. plugin-fw/assets/css/overcast/images/ui-icons_3383bb_256x240.png +0 -0
  36. plugin-fw/assets/css/overcast/images/ui-icons_454545_256x240.png +0 -0
  37. plugin-fw/assets/css/overcast/images/ui-icons_70b2e1_256x240.png +0 -0
  38. plugin-fw/assets/css/overcast/images/ui-icons_999999_256x240.png +0 -0
  39. plugin-fw/assets/css/overcast/images/ui-icons_fbc856_256x240.png +0 -0
  40. plugin-fw/assets/css/overcast/jquery-ui-1.8.9.custom.css +322 -0
  41. plugin-fw/assets/css/yit-plugin-panel.css +599 -0
  42. plugin-fw/assets/css/yit-upgrader.css +14 -0
  43. plugin-fw/assets/images/chosen/chosen-sprite.png +0 -0
  44. plugin-fw/assets/images/chosen/chosen-sprite@2x.png +0 -0
  45. plugin-fw/assets/images/double-sidebar.png +0 -0
  46. plugin-fw/assets/images/licence-error.png +0 -0
  47. plugin-fw/assets/images/no-sidebar.png +0 -0
  48. plugin-fw/assets/images/off.png +0 -0
  49. plugin-fw/assets/images/on.png +0 -0
  50. plugin-fw/assets/images/select.png +0 -0
  51. plugin-fw/assets/images/sidebar-left.png +0 -0
  52. plugin-fw/assets/images/sidebar-right.png +0 -0
  53. plugin-fw/assets/images/sleep.png +0 -0
  54. plugin-fw/assets/images/slider/grey.gif +0 -0
  55. plugin-fw/assets/images/slider/handle.png +0 -0
  56. plugin-fw/assets/images/slider/orange.gif +0 -0
  57. plugin-fw/assets/images/slider/tooltip.png +0 -0
  58. plugin-fw/assets/images/spinner.png +0 -0
  59. plugin-fw/assets/images/ui-icons_222222_256x240.png +0 -0
  60. plugin-fw/assets/images/ui-icons_2e83ff_256x240.png +0 -0
  61. plugin-fw/assets/images/ui-icons_454545_256x240.png +0 -0
  62. plugin-fw/assets/images/ui-icons_888888_256x240.png +0 -0
  63. plugin-fw/assets/images/x.png +0 -0
  64. plugin-fw/assets/images/yithemes-icon.png +0 -0
  65. plugin-fw/assets/js/chosen/chosen.jquery.js +1211 -0
  66. plugin-fw/assets/js/codemirror/codemirror.js +5799 -0
  67. plugin-fw/assets/js/codemirror/javascript.js +630 -0
  68. plugin-fw/assets/js/metabox.js +350 -0
  69. plugin-fw/assets/js/metabox.min.js +11 -0
  70. plugin-fw/assets/js/multisite-updater.js +216 -0
  71. plugin-fw/assets/js/multisite-updater.min.js +4 -0
  72. plugin-fw/assets/js/panel.spinner.js +139 -0
  73. plugin-fw/assets/js/panel.spinner.min.js +3 -0
  74. plugin-fw/assets/js/yit-cpt-unlimited.js +79 -0
  75. plugin-fw/assets/js/yit-cpt-unlimited.min.js +2 -0
  76. plugin-fw/assets/js/yit-cptu-sortable-posts.js +32 -0
  77. plugin-fw/assets/js/yit-plugin-panel.js +286 -0
  78. plugin-fw/assets/js/yit-plugin-panel.min.js +9 -0
  79. plugin-fw/assets/js/yit-wp-pointer.js +84 -0
  80. plugin-fw/assets/js/yit-wp-pointer.min.js +3 -0
  81. plugin-fw/lib/yit-cpt-unlimited.php +1775 -0
  82. plugin-fw/lib/yit-metabox.php +537 -0
  83. plugin-fw/lib/yit-plugin-common.php +1034 -0
  84. plugin-fw/lib/yit-plugin-gradients.php +536 -0
  85. plugin-fw/lib/yit-plugin-panel-wc.php +344 -0
  86. plugin-fw/lib/yit-plugin-panel.php +710 -0
  87. plugin-fw/lib/yit-plugin-subpanel.php +160 -0
  88. plugin-fw/lib/yit-pointers.php +390 -0
  89. plugin-fw/lib/yit-upgrade.php +539 -0
  90. plugin-fw/lib/yit-video.php +184 -0
  91. plugin-fw/licence/assets/css/yit-licence.css +337 -0
  92. plugin-fw/licence/assets/images/licence-error.png +0 -0
  93. plugin-fw/licence/assets/js/yit-licence.js +139 -0
  94. plugin-fw/licence/assets/js/yit-licence.min.js +4 -0
  95. plugin-fw/licence/lib/yit-licence.php +543 -0
  96. plugin-fw/licence/lib/yit-plugin-licence.php +156 -0
  97. plugin-fw/licence/lib/yit-theme-licence.php +155 -0
  98. plugin-fw/licence/templates/panel/activation/activation-panel.php +152 -0
  99. plugin-fw/templates/metaboxes/tab.php +64 -0
  100. plugin-fw/templates/metaboxes/types/ajax-products.php +64 -0
  101. plugin-fw/templates/metaboxes/types/categories.php +88 -0
  102. plugin-fw/templates/metaboxes/types/checkbox.php +23 -0
  103. plugin-fw/templates/metaboxes/types/chosen.php +32 -0
  104. plugin-fw/templates/metaboxes/types/colorpicker.php +22 -0
  105. plugin-fw/templates/metaboxes/types/contactform.php +553 -0
  106. plugin-fw/templates/metaboxes/types/customtabs.php +152 -0
  107. plugin-fw/templates/metaboxes/types/datepicker.php +21 -0
  108. plugin-fw/templates/metaboxes/types/hidden.php +18 -0
  109. plugin-fw/templates/metaboxes/types/icon-list.php +135 -0
  110. plugin-fw/templates/metaboxes/types/image-gallery.php +43 -0
  111. plugin-fw/templates/metaboxes/types/images.php +85 -0
  112. plugin-fw/templates/metaboxes/types/number.php +37 -0
  113. plugin-fw/templates/metaboxes/types/onoff.php +43 -0
  114. plugin-fw/templates/metaboxes/types/responsivesliders.php +31 -0
  115. plugin-fw/templates/metaboxes/types/select-icon.php +72 -0
  116. plugin-fw/templates/metaboxes/types/select-mailchimp.php +32 -0
  117. plugin-fw/templates/metaboxes/types/select.php +32 -0
  118. plugin-fw/templates/metaboxes/types/sep.php +18 -0
  119. plugin-fw/templates/metaboxes/types/sidebar-layout.php +61 -0
  120. plugin-fw/templates/metaboxes/types/sidebarlist.php +29 -0
  121. plugin-fw/templates/metaboxes/types/sidebars.php +124 -0
  122. plugin-fw/templates/metaboxes/types/simple-text.php +20 -0
  123. plugin-fw/templates/metaboxes/types/slider.php +35 -0
  124. plugin-fw/templates/metaboxes/types/text-array.php +30 -0
  125. plugin-fw/templates/metaboxes/types/text.php +24 -0
  126. plugin-fw/templates/metaboxes/types/textarea-editor.php +42 -0
  127. plugin-fw/templates/metaboxes/types/textarea.php +25 -0
  128. plugin-fw/templates/metaboxes/types/title.php +18 -0
  129. plugin-fw/templates/metaboxes/types/typography.php +255 -0
  130. plugin-fw/templates/metaboxes/types/upload.php +24 -0
  131. plugin-fw/templates/panel/types/chosen.php +36 -0
  132. plugin-fw/templates/panel/types/connected-list.php +27 -0
  133. plugin-fw/templates/panel/types/layout-panel.php +0 -0
  134. plugin-fw/templates/panel/types/on-off.php +34 -0
  135. plugin-fw/templates/panel/types/select-mailchimp.php +36 -0
  136. plugin-fw/templates/panel/types/select.php +41 -0
  137. plugin-fw/templates/panel/types/slider.php +40 -0
  138. plugin-fw/templates/panel/types/text-button.php +36 -0
  139. plugin-fw/templates/panel/types/text.php +35 -0
  140. plugin-fw/templates/panel/types/textarea-codemirror.php +40 -0
  141. plugin-fw/templates/panel/types/textarea.php +35 -0
  142. plugin-fw/templates/panel/types/upload.php +45 -0
  143. plugin-fw/templates/panel/woocommerce/woocommerce-boxinfo.php +36 -0
  144. plugin-fw/templates/panel/woocommerce/woocommerce-form.php +12 -0
  145. plugin-fw/templates/panel/woocommerce/woocommerce-panel.php +12 -0
  146. plugin-fw/templates/panel/woocommerce/woocommerce-upload.php +52 -0
  147. plugin-fw/templates/panel/woocommerce/woocommerce-videobox.php +83 -0
  148. plugin-fw/yit-deactive-plugin.php +35 -0
  149. plugin-fw/yit-functions.php +443 -0
README.txt CHANGED
@@ -1,7 +1,7 @@
1
  === YITH WooCommerce Ajax Search ===
2
 
3
  Contributors: yithemes
4
- Tags: ajax, search, woocommerce, products, themes, yit, e-commerce, shop
5
  Requires at least: 3.5.1
6
  Tested up to: 4.1
7
  Stable tag: 1.2
@@ -36,8 +36,7 @@ Full documentation is available [here](http://yithemes.com/docs-plugins/yith_woo
36
  Once you have installed the plugin, you just need to activate the plugin in order to enable it.
37
 
38
  = Configuration =
39
-
40
- YITH WooCommerce Ajax Search will add a new tab called "Ajax Search" below the Woocommerce -> Settings menu. Here you are able to configure all the plugin settings.
41
 
42
  = Developer =
43
 
@@ -45,7 +44,6 @@ Are you a developer? Want to customize the templates or the style of the plugin?
45
 
46
  = Support =
47
 
48
- Hi there, we have good news here: all our plugins are released for free. Wow!
49
  Already knew it, right?! Great, but maybe you do not know that: if you're looking for how to install the plugins or how to use them within your Wordpress installations, which is the right way to ask support?
50
  That's the way:
51
 
@@ -74,11 +72,12 @@ In WooCommerce->Settings->Ajax Search page, you can choose the minumum size of t
74
  == Changelog ==
75
 
76
  = 1.2 =
 
77
  * Updated: Plugin Core Framework
78
 
79
  = 1.1.3 =
80
 
81
- Fixed: Javascript code in external file
82
 
83
  = 1.1.2 =
84
 
1
  === YITH WooCommerce Ajax Search ===
2
 
3
  Contributors: yithemes
4
+ Tags: ajax, search, woocommerce, products, themes, yit, e-commerce, shop, yith, ajax search, instant search, premium, yithemes
5
  Requires at least: 3.5.1
6
  Tested up to: 4.1
7
  Stable tag: 1.2
36
  Once you have installed the plugin, you just need to activate the plugin in order to enable it.
37
 
38
  = Configuration =
39
+ YITH WooCommerce Ajax Search will add a new submenu called "Cart Messages" under "YIT Plugins" menu. Here you are able to configure all the plugin settings.
 
40
 
41
  = Developer =
42
 
44
 
45
  = Support =
46
 
 
47
  Already knew it, right?! Great, but maybe you do not know that: if you're looking for how to install the plugins or how to use them within your Wordpress installations, which is the right way to ask support?
48
  That's the way:
49
 
72
  == Changelog ==
73
 
74
  = 1.2 =
75
+
76
  * Updated: Plugin Core Framework
77
 
78
  = 1.1.3 =
79
 
80
+ * Fixed: Javascript code in external file
81
 
82
  = 1.1.2 =
83
 
assets/images/01.jpg ADDED
Binary file
assets/images/02.jpg ADDED
Binary file
assets/images/03.jpg ADDED
Binary file
assets/images/number-five.png ADDED
Binary file
assets/images/number-fourth.png ADDED
Binary file
assets/images/number-one.png ADDED
Binary file
assets/images/number-seven.png ADDED
Binary file
assets/images/number-six.png ADDED
Binary file
assets/images/number-three.png ADDED
Binary file
assets/images/number-two.png ADDED
Binary file
assets/images/upgrade.png ADDED
Binary file
assets/js/frontend.min.js CHANGED
@@ -1,31 +1,2 @@
1
- /**
2
- * frontend.js
3
- *
4
- * @author Your Inspiration Themes
5
- * @package YITH WooCommerce Ajax Search
6
- * @version 1.1.1
7
- */
8
- jQuery(document).ready(function($){
9
- "use strict";
10
-
11
- var el = $('#yith-s'),
12
- loader_icon = el.data('loader-icon') == '' ? woocommerce_params.ajax_loader_url : el.data('loader-icon'),
13
- min_chars = el.data('min-chars');
14
-
15
- el.autocomplete({
16
- minChars: min_chars,
17
- appendTo: '.yith-ajaxsearchform-container',
18
- serviceUrl: woocommerce_params.ajax_url + '?action=yith_ajax_search_products',
19
- onSearchStart: function(){
20
- $(this).css('background', 'url(' + loader_icon + ') no-repeat right center');
21
- },
22
- onSearchComplete: function(){
23
- $(this).css('background', 'transparent');
24
- },
25
- onSelect: function (suggestion) {
26
- if( suggestion.id != -1 ) {
27
- window.location.href = suggestion.url;
28
- }
29
- }
30
- });
31
- });
1
+ jQuery(document).ready(function(b){var a=b("#yith-s"),c=""==a.data("loader-icon")?woocommerce_params.ajax_loader_url:a.data("loader-icon"),d=a.data("min-chars");a.autocomplete({minChars:d,appendTo:".yith-ajaxsearchform-container",serviceUrl:woocommerce_params.ajax_url+"?action=yith_ajax_search_products",onSearchStart:function(){b(this).css("background","url("+c+") no-repeat right center")},onSearchComplete:function(){b(this).css("background","transparent")},onSelect:function(a){-1!=a.id&&(window.location.href=
2
+ a.url)}})});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
class.yith-wcas-admin.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Admin class
4
  *
5
- * @author Your Inspiration Themes
6
  * @package YITH WooCommerce Ajax Search
7
  * @version 1.1.1
8
  */
@@ -11,7 +11,7 @@ if ( !defined( 'YITH_WCAS' ) ) { exit; } // Exit if accessed directly
11
 
12
  if( !class_exists( 'YITH_WCAS_Admin' ) ) {
13
  /**
14
- * Admin class.
15
  * The class manage all the admin behaviors.
16
  *
17
  * @since 1.0.0
@@ -19,7 +19,7 @@ if( !class_exists( 'YITH_WCAS_Admin' ) ) {
19
  class YITH_WCAS_Admin {
20
  /**
21
  * Plugin options
22
- *
23
  * @var array
24
  * @access public
25
  * @since 1.0.0
@@ -34,6 +34,26 @@ if( !class_exists( 'YITH_WCAS_Admin' ) ) {
34
  */
35
  public $version;
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  /**
38
  * Various links
39
  *
@@ -41,416 +61,175 @@ if( !class_exists( 'YITH_WCAS_Admin' ) ) {
41
  * @access public
42
  * @since 1.0.0
43
  */
44
- public $banner_url = 'http://cdn.yithemes.com/plugins/yith_magnifier.php?url';
45
- public $banner_img = 'http://cdn.yithemes.com/plugins/yith_magnifier.php';
46
- public $doc_url = 'http://yithemes.com/docs-plugins/yith_ajax_search/';
47
-
48
  /**
49
  * Constructor
50
- *
51
  * @access public
52
  * @since 1.0.0
53
  */
54
  public function __construct( $version ) {
55
 
56
- $this->options = $this->_initOptions();
57
  $this->version = $version;
58
 
59
- //Actions
60
- add_action( 'init', array( $this, 'init' ) );
61
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles_scripts' ) );
62
- add_filter( 'plugin_action_links_' . plugin_basename( dirname(__FILE__) . '/init.php' ), array( $this, 'action_links' ) );
63
-
64
-
65
- add_action( 'woocommerce_settings_tabs_yith_wcas', array( $this, 'print_plugin_options' ) );
66
- add_action( 'woocommerce_update_options_yith_wcas', array( $this, 'update_options' ) );
67
-
68
-
69
- add_action( 'woocommerce_admin_field_banner', array( $this, 'admin_fields_banner' ) );
70
 
 
 
 
71
 
72
- if ( !has_action('woocommerce_admin_field_slider')) add_action( 'woocommerce_admin_field_slider', array( $this, 'admin_fields_slider' ) );
73
- if ( !has_action('woocommerce_admin_field_picker')) add_action( 'woocommerce_admin_field_picker', array( $this, 'admin_fields_picker' ) );
74
- add_action( 'woocommerce_update_option_slider', array( $this, 'admin_update_option' ) );
75
- add_action( 'woocommerce_update_option_picker', array( $this, 'admin_update_option' ) );
76
 
77
-
78
- //Filters
79
- add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_tab_woocommerce' ), 30 );
80
- //add_filter( 'woocommerce_catalog_settings', array( $this, 'add_catalog_image_size' ) );
81
-
82
- //Apply filters
83
- $this->banner_url = apply_filters('yith_wcas_banner_url', $this->banner_url);
84
 
85
  // YITH WCAS Loaded
86
  do_action( 'yith_wcas_loaded' );
87
- }
88
-
89
-
90
- /**
91
- * Init method:
92
- * - default options
93
- *
94
- * @access public
95
- * @since 1.0.0
96
- */
97
- public function init() {
98
- $this->_default_options();
99
- }
100
-
101
-
102
  /**
103
- * Update plugin options.
104
- *
105
- * @return void
106
- * @since 1.0.0
 
 
 
 
 
 
 
107
  */
108
- public function update_options() {
109
- foreach( $this->options as $option ) {
110
- woocommerce_update_options( $option );
111
- }
 
 
112
  }
113
-
114
-
115
- /**
116
- * Add Magnifier's tab to Woocommerce -> Settings page
117
- *
118
- * @access public
119
- * @param array $tabs
120
- *
121
- * @return array
122
- */
123
- public function add_tab_woocommerce($tabs) {
124
- $tabs['yith_wcas'] = __('Ajax Search', 'yit');
125
-
126
- return $tabs;
127
- }
128
-
129
-
130
- /**
131
- * Add Zoom Image size to Woocommerce -> Catalog
132
- *
133
- * @access public
134
- * @param array $settings
135
- *
136
- * @return array
137
-
138
- public function add_catalog_image_size( $settings ) {
139
- $tmp = $settings[ count($settings)-1 ];
140
- unset( $settings[ count($settings)-1 ] );
141
-
142
- $settings[] = array(
143
- 'name' => __( 'Catalog Zoom Images', 'yit' ),
144
- 'desc' => __('The size of images used within the magnifier box', 'yit'),
145
- 'id' => 'woocommerce_magnifier_image',
146
- 'css' => '',
147
- 'type' => 'image_width',
148
- 'default' => array(
149
- 'width' => 600,
150
- 'height' => 600,
151
- 'crop' => true
152
- ),
153
- 'std' => array(
154
- 'width' => 600,
155
- 'height' => 600,
156
- 'crop' => true
157
- ),
158
- 'desc_tip' => true
159
- );
160
- $settings[] = $tmp;
161
- return $settings;
162
- }
163
- */
164
-
165
  /**
166
- * Print all plugin options.
167
- *
168
- * @return void
169
- * @since 1.0.0
 
 
 
170
  */
171
- public function print_plugin_options() {
172
- $links = apply_filters( 'yith_wcas_tab_links', array(
173
- '<a href="#yith_wcas_general">' . __( 'General Settings', 'yit' ) . '</a>',
174
- //'<a href="#yith_wcas_magnifier">' . __( 'Magnifier', 'yit' ) . '</a>',
175
- //'<a href="#yith_wcas_slider">' . __( 'Slider', 'yit' ) . '</a>'
176
- ) );
177
-
178
- $this->_printBanner();
179
- ?>
180
-
181
- <div class="subsubsub_section">
182
- <ul class="subsubsub">
183
- <li>
184
- <?php echo implode( ' | </li><li>', $links ) ?>
185
- </li>
186
- </ul>
187
- <br class="clear" />
188
-
189
- <?php
190
- $option_theme = apply_filters('yith_wcas_options_theme_plugin', $this->options );
191
- foreach( $option_theme as $id => $tab ) : ?>
192
- <!-- tab #<?php echo $id ?> -->
193
- <div class="section" id="yith_wcas_<?php echo $id ?>">
194
- <?php woocommerce_admin_fields( $option_theme[$id] ) ?>
195
- </div>
196
- <?php endforeach ?>
197
- </div>
198
- <?php
199
- }
200
-
201
 
202
- /**
203
- * Initialize the options
204
- *
205
- * @access protected
206
- * @return array
207
- * @since 1.0.0
208
- */
209
- protected function _initOptions() {
210
- $options = array(
211
- 'general' => array(
212
- array(
213
- 'name' => __( 'General Settings', 'yit' ),
214
- 'type' => 'title',
215
- 'desc' => '',
216
- 'id' => 'yith_wcas_general'
217
- ),
218
-
219
- array(
220
- 'name' => __( 'Search input label', 'yit' ),
221
- 'desc' => __( 'Label for Search input field.', 'yit' ),
222
- 'id' => 'yith_wcas_search_input_label',
223
- 'std' => __( 'Search for products', 'yit' ),
224
- 'default' => __( 'Search for products', 'yit' ),
225
- 'desc_tip' => true,
226
- 'type' => 'text',
227
- ),
228
-
229
- array(
230
- 'name' => __( 'Search submit label', 'yit' ),
231
- 'desc' => __( 'Label for Search submit field.', 'yit' ),
232
- 'id' => 'yith_wcas_search_submit_label',
233
- 'std' => __( 'Search', 'yit' ),
234
- 'default' => __( 'Search', 'yit' ),
235
- 'desc_tip' => true,
236
- 'type' => 'text',
237
- ),
238
-
239
- array(
240
- 'name' => __( 'Minimum number of characters', 'yit' ),
241
- 'desc' => __( 'Minimum number of characters required to trigger autosuggest.', 'yit' ),
242
- 'id' => 'yith_wcas_min_chars',
243
- 'std' => '3',
244
- 'default' => '3',
245
- 'css' => 'width:50px;',
246
- 'desc_tip' => true,
247
- 'type' => 'number',
248
- 'custom_attributes' => array(
249
- 'min' => 1,
250
- 'max' => 10,
251
- 'step' => 1
252
- )
253
- ),
254
-
255
- array(
256
- 'name' => __( 'Maximum number of results', 'yit' ),
257
- 'desc' => __( 'Maximum number of results showed within the autosuggest box.', 'yit' ),
258
- 'id' => 'yith_wcas_posts_per_page',
259
- 'std' => '3',
260
- 'default' => '3',
261
- 'css' => 'width:50px;',
262
- 'desc_tip' => true,
263
- 'type' => 'number',
264
- 'custom_attributes' => array(
265
- 'min' => 1,
266
- 'max' => 15,
267
- 'step' => 1
268
- )
269
- ),
270
-
271
- array( 'type' => 'sectionend', 'id' => 'yith_wcas_general_end' )
272
- ),
273
- );
274
-
275
- return apply_filters('yith_wcas_tab_options', $options);
276
- }
277
 
 
 
 
 
278
 
279
- /**
280
- * Default options
281
- *
282
- * Sets up the default options used on the settings page
283
- *
284
- * @access protected
285
- * @return void
286
- * @since 1.0.0
287
- */
288
- protected function _default_options() {
289
- foreach ($this->options as $section) {
290
- foreach ( $section as $value ) {
291
- if ( isset( $value['std'] ) && isset( $value['id'] ) ) {
292
- if ( $value['type'] == 'image_width' ) {
293
- add_option($value['id'].'_width', $value['std']);
294
- add_option($value['id'].'_height', $value['std']);
295
- } else {
296
- add_option($value['id'], $value['std']);
297
- }
298
- }
299
- }
300
- }
301
- }
302
-
303
 
304
- /**
305
- * Create new Woocommerce admin field: slider
306
- *
307
- * @access public
308
- * @param array $value
309
- * @return void
310
- * @since 1.0.0
311
- */
312
- public function admin_fields_slider( $value ) {
313
- $slider_value = ( get_option( $value['id'] ) !== false && get_option( $value['id'] ) !== null ) ?
314
- esc_attr( stripslashes( get_option($value['id'] ) ) ) :
315
- esc_attr( $value['std'] );
316
-
317
- ?><tr valign="top">
318
- <th scope="row" class="titledesc">
319
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo $value['name']; ?></label>
320
- </th>
321
- <td class="forminp">
322
- <div id="<?php echo esc_attr( $value['id'] ); ?>_slider" class="yith_woocommerce_slider" style="width: 300px; float: left;"></div>
323
- <div id="<?php echo esc_attr( $value['id'] ); ?>_value" class="yith_woocommerce_slider_value ui-state-default ui-corner-all"><?php echo $slider_value ?></div>
324
- <input name="<?php echo esc_attr( $value['id'] ); ?>" id="<?php echo esc_attr( $value['id'] ); ?>" type="hidden" value="<?php echo $slider_value ?>" /> <?php echo $value['desc']; ?></td>
325
- </tr>
326
-
327
-
328
-
329
- <script>
330
- jQuery(document).ready(function($){
331
- $('#<?php echo esc_attr( $value['id'] ); ?>_slider').slider({
332
- min: <?php echo $value['min'] ?>,
333
- max: <?php echo $value['max'] ?>,
334
- step: <?php echo $value['step'] ?>,
335
- value: <?php echo $slider_value ?>,
336
- slide: function( event, ui ) {
337
- $( "#<?php echo esc_attr( $value['id'] ); ?>" ).val( ui.value );
338
- $( "#<?php echo esc_attr( $value['id'] ); ?>_value" ).text( ui.value );
339
- }
340
- });
341
- });
342
- </script>
343
-
344
- <?php
345
- }
346
 
 
 
 
 
347
 
348
- /**
349
- * Create new Woocommerce admin field: picker
350
- *
351
- * @access public
352
- * @param array $value
353
- * @return void
354
- * @since 1.0.0
355
- */
356
- public function admin_fields_picker( $value ) {
357
- $picker_value = ( get_option( $value['id'] ) !== false && get_option( $value['id'] ) !== null ) ?
358
- esc_attr( stripslashes( get_option($value['id'] ) ) ) :
359
- esc_attr( $value['std'] );
360
-
361
- ?><tr valign="top">
362
- <th scope="row" class="titledesc">
363
- <label for="<?php echo esc_attr( $value['id'] ); ?>"><?php echo $value['name']; ?></label>
364
- </th>
365
- <td class="forminp">
366
- <div class="color_box"><strong><?php echo $value['name']; ?></strong>
367
- <input name="<?php echo esc_attr( $value['id'] ) ?>" id="<?php echo esc_attr( $value['id'] ) ?>" type="text" value="<?php echo $picker_value ?>" class="colorpick" /> <div id="colorPickerDiv_<?php echo esc_attr( $value['id'] ) ?>" class="colorpickdiv"></div>
368
- </div> <?php echo $value['desc']; ?></td>
369
- </tr>
370
- <?php
371
- }
372
 
373
  /**
374
- * Save the admin field: slider
375
  *
376
- * @access public
377
- * @param mixed $value
 
 
 
378
  * @return void
379
- * @since 1.0.0
380
  */
381
- public function admin_update_option($value) {
382
-
383
- global $woocommerce;
384
-
385
- if ( version_compare( preg_replace( '/-beta-([0-9]+)/', '', $woocommerce->version ), '2.1', '<' ) ) {
386
- $wc_clean = 'woocommerce_clean';
387
  }
388
- else {
389
- $wc_clean = 'wc_clean';
390
- }
391
 
392
- update_option( $value['id'], $wc_clean($_POST[$value['id']]) );
393
  }
394
 
395
- /**
396
- * Enqueue admin styles and scripts
397
- *
398
- * @access public
399
- * @return void
400
- * @since 1.0.0
401
- */
402
- public function enqueue_styles_scripts() {
403
- wp_enqueue_script( 'jquery-ui' );
404
- wp_enqueue_script( 'jquery-ui-core' );
405
- wp_enqueue_script( 'jquery-ui-mouse' );
406
- wp_enqueue_script( 'jquery-ui-slider' );
407
-
408
- wp_enqueue_style( 'yith_wcas_admin', YITH_WCAS_URL . 'assets/css/admin.css' );
409
- }
410
-
411
-
412
  /**
413
- * Print the banner
414
  *
415
- * @access protected
416
- * @return void
417
- * @since 1.0.0
 
 
 
 
 
 
 
 
418
  */
419
- protected function _printBanner() {
420
- ?>
421
- <div class="yith_banner">
422
- <a href="<?php echo $this->banner_url ?>" target="_blank">
423
- <img src="<?php echo $this->banner_img ?>" alt="" />
424
- </a>
425
- </div>
426
- <?php
427
- }
428
 
 
 
 
 
 
429
 
430
- /**
431
- * action_links function.
432
- *
433
- * @access public
434
- * @param mixed $links
435
- * @return void
436
- */
437
- public function action_links( $links ) {
438
 
439
- global $woocommerce;
440
 
441
- if ( version_compare( preg_replace( '/-beta-([0-9]+)/', '', $woocommerce->version ), '2.1', '<' ) ) {
442
- $wc_clean = 'woocommerce_settings';
443
- }
444
- else {
445
- $wc_clean = 'wc-settings';
446
  }
447
 
448
- $plugin_links = array(
449
- '<a href="' . admin_url( 'admin.php?page=' . $wc_clean . '&tab=yith_wcas' ) . '">' . __( 'Settings', 'yit' ) . '</a>',
450
- '<a href="' . $this->doc_url . '">' . __( 'Docs', 'yit' ) . '</a>',
 
 
 
 
 
 
 
 
 
451
  );
452
 
453
- return array_merge( $plugin_links, $links );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
  }
 
455
  }
456
  }
2
  /**
3
  * Admin class
4
  *
5
+ * @author Yithemes
6
  * @package YITH WooCommerce Ajax Search
7
  * @version 1.1.1
8
  */
11
 
12
  if( !class_exists( 'YITH_WCAS_Admin' ) ) {
13
  /**
14
+ * Admin class.
15
  * The class manage all the admin behaviors.
16
  *
17
  * @since 1.0.0
19
  class YITH_WCAS_Admin {
20
  /**
21
  * Plugin options
22
+ *
23
  * @var array
24
  * @access public
25
  * @since 1.0.0
34
  */
35
  public $version;
36
 
37
+ /**
38
+ * @var $_panel Panel Object
39
+ */
40
+ protected $_panel;
41
+
42
+ /**
43
+ * @var $_premium string Premium tab template file name
44
+ */
45
+ protected $_premium = 'premium.php';
46
+
47
+ /**
48
+ * @var string Premium version landing link
49
+ */
50
+ protected $_premium_landing = 'http://yithemes.com/themes/plugins/yith-woocommerce-ajax-search/';
51
+
52
+ /**
53
+ * @var string Ajax Search panel page
54
+ */
55
+ protected $_panel_page = 'yith_wcas_panel';
56
+
57
  /**
58
  * Various links
59
  *
61
  * @access public
62
  * @since 1.0.0
63
  */
64
+ public $doc_url = 'http://yithemes.com/docs-plugins/yith_woocommerce_ajax_search/';
65
+
 
 
66
  /**
67
  * Constructor
68
+ *
69
  * @access public
70
  * @since 1.0.0
71
  */
72
  public function __construct( $version ) {
73
 
 
74
  $this->version = $version;
75
 
76
+ add_action( 'admin_menu', array( $this, 'register_panel' ), 5) ;
 
 
 
 
 
 
 
 
 
 
77
 
78
+ //Add action links
79
+ add_filter( 'plugin_action_links_' . plugin_basename( YITH_WCAS_DIR . '/' . basename( YITH_WCAS_FILE ) ), array( $this, 'action_links') );
80
+ add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 4 );
81
 
82
+ add_action( 'yith_ajax_search_premium', array( $this, 'premium_tab' ) );
 
 
 
83
 
84
+ add_action( 'admin_init', array( $this, 'register_pointer' ) );
 
 
 
 
 
 
85
 
86
  // YITH WCAS Loaded
87
  do_action( 'yith_wcas_loaded' );
88
+ }
89
+
90
+
 
 
 
 
 
 
 
 
 
 
 
 
91
  /**
92
+ * Action Links
93
+ *
94
+ * add the action links to plugin admin page
95
+ *
96
+ * @param $links | links plugin array
97
+ *
98
+ * @return mixed Array
99
+ * @since 1.0
100
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
101
+ * @return mixed
102
+ * @use plugin_action_links_{$plugin_file_name}
103
  */
104
+ public function action_links( $links ) {
105
+
106
+ $links[] = '<a href="' . admin_url( "admin.php?page={$this->_panel_page}" ) . '">' . __( 'Settings', 'yit' ) . '</a>';
107
+ $links[] = '<a href="' . $this->_premium_landing . '" target="_blank">' . __( 'Premium Version', 'yit' ) . '</a>';
108
+
109
+ return $links;
110
  }
111
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  /**
113
+ * Add a panel under YITH Plugins tab
114
+ *
115
+ * @return void
116
+ * @since 1.0
117
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
118
+ * @use /Yit_Plugin_Panel class
119
+ * @see plugin-fw/lib/yit-plugin-panel.php
120
  */
121
+ public function register_panel() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
+ if ( ! empty( $this->_panel ) ) {
124
+ return;
125
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
+ $admin_tabs = array(
128
+ 'settings' => __( 'Settings', 'yit' ),
129
+ 'premium' => __( 'Premium Version', 'yit' ),
130
+ );
131
 
132
+ $args = array(
133
+ 'create_menu_page' => true,
134
+ 'parent_slug' => '',
135
+ 'page_title' => __( 'Ajax Search', 'yit' ),
136
+ 'menu_title' => __( 'Ajax Search', 'yit' ),
137
+ 'capability' => 'manage_options',
138
+ 'parent' => '',
139
+ 'parent_page' => 'yit_plugin_panel',
140
+ 'page' => $this->_panel_page,
141
+ 'admin-tabs' => $admin_tabs,
142
+ 'options-path' => YITH_WCAS_DIR . '/plugin-options'
143
+ );
 
 
 
 
 
 
 
 
 
 
 
 
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
146
+ /* === Fixed: not updated theme === */
147
+ if( ! class_exists( 'YIT_Plugin_Panel_WooCommerce' ) ) {
148
+ require_once( 'plugin-fw/lib/yit-plugin-panel-wc.php' );
149
+ }
150
 
151
+ $this->_panel = new YIT_Plugin_Panel_WooCommerce( $args );
152
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
 
154
  /**
155
+ * Premium Tab Template
156
  *
157
+ * Load the premium tab template on admin page
158
+ *
159
+ * @return void
160
+ * @since 1.0
161
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
162
  * @return void
 
163
  */
164
+ public function premium_tab() {
165
+ $premium_tab_template =YITH_WCAS_TEMPLATE_PATH . '/admin/' . $this->_premium;
166
+ if( file_exists( $premium_tab_template ) ) {
167
+ include_once($premium_tab_template);
 
 
168
  }
 
 
 
169
 
 
170
  }
171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  /**
173
+ * plugin_row_meta
174
  *
175
+ * add the action links to plugin admin page
176
+ *
177
+ * @param $plugin_meta
178
+ * @param $plugin_file
179
+ * @param $plugin_data
180
+ * @param $status
181
+ *
182
+ * @return Array
183
+ * @since 1.0
184
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
185
+ * @use plugin_row_meta
186
  */
187
+ public function plugin_row_meta( $plugin_meta, $plugin_file, $plugin_data, $status ) {
 
 
 
 
 
 
 
 
188
 
189
+ if ( defined( 'YITH_WCAS_FREE_INIT' ) && YITH_WCAS_FREE_INIT == $plugin_file ) {
190
+ $plugin_meta[] = '<a href="' . $this->doc_url . '" target="_blank">' . __( 'Plugin Documentation', 'yit' ) . '</a>';
191
+ }
192
+ return $plugin_meta;
193
+ }
194
 
 
 
 
 
 
 
 
 
195
 
196
+ public function register_pointer(){
197
 
198
+ if( ! class_exists( 'YIT_Pointers' ) ){
199
+ include_once( 'plugin-fw/lib/yit-pointers.php' );
 
 
 
200
  }
201
 
202
+ $args[] = array(
203
+ 'screen_id' => 'plugins',
204
+ 'pointer_id' => 'yith_wcas_panel',
205
+ 'target' => '#toplevel_page_yit_plugin_panel',
206
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p>',
207
+ __( 'YITH WooCommerce Ajax Search', 'yit' ),
208
+ __( 'In the YIT Plugin tab you can find the YITH WooCommerce Ajax Search options.
209
+ With this menu, you can access to all the settings of our plugins that you have activated.
210
+ YITH WooCommerce Ajax Search is available in an outstanding PREMIUM version with many new options, <a href="'.$this->_premium_landing.'">discover it now</a>', 'yit' )
211
+ ),
212
+ 'position' => array( 'edge' => 'left', 'align' => 'center' ),
213
+ 'init' => YITH_WCAS_FREE_INIT
214
  );
215
 
216
+ $args[] = array(
217
+ 'screen_id' => 'update',
218
+ 'pointer_id' => 'yith_wcas_panel',
219
+ 'target' => '#toplevel_page_yit_plugin_panel',
220
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p>',
221
+ __( 'YITH WooCommerce Ajax Search Updated', 'yit' ),
222
+ __( 'From now on, you can find all the options of YITH WooCommerce Ajax Search Updated under YIT Plugin -> Ajax Search instead of WooCommerce -> Settings -> Ajax Search, as in the previous version.
223
+ When one of our plugins updates, a new voice will be added to this menu.
224
+ YITH WooCommerce Ajax Search renovates with new available options, discover the <a href="'.$this->_premium_landing.'">PREMIUM version</a>.
225
+ ', 'yit' )
226
+ ),
227
+ 'position' => array( 'edge' => 'left', 'align' => 'center' ),
228
+ 'init' => YITH_WCAS_FREE_INIT
229
+ );
230
+
231
+ YIT_Pointers()->register( $args );
232
  }
233
+
234
  }
235
  }
class.yith-wcas-frontend.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Frontend class
4
  *
5
- * @author Your Inspiration Themes
6
  * @package YITH WooCommerce Ajax Search
7
  * @version 1.1.1
8
  */
2
  /**
3
  * Frontend class
4
  *
5
+ * @author Yithemes
6
  * @package YITH WooCommerce Ajax Search
7
  * @version 1.1.1
8
  */
class.yith-wcas.php CHANGED
@@ -2,16 +2,18 @@
2
  /**
3
  * Main class
4
  *
5
- * @author Your Inspiration Themes
6
  * @package YITH WooCommerce Ajax Search
7
  * @version 1.1.1
8
  */
9
 
10
- if ( !defined( 'YITH_WCAS' ) ) { exit; } // Exit if accessed directly
 
 
11
 
12
- if( !class_exists( 'YITH_WCAS' ) ) {
13
  /**
14
- * WooCommerce Magnifier
15
  *
16
  * @since 1.0.0
17
  */
@@ -22,8 +24,8 @@ if( !class_exists( 'YITH_WCAS' ) ) {
22
  * @var string
23
  * @since 1.0.0
24
  */
25
- public $version = '1.1.3';
26
-
27
  /**
28
  * Plugin object
29
  *
@@ -32,55 +34,69 @@ if( !class_exists( 'YITH_WCAS' ) ) {
32
  */
33
  public $obj = null;
34
 
35
- /**
36
- * Constructor
37
- *
38
- * @return mixed|YITH_WCAS_Admin|YITH_WCAS_Frontend
39
- * @since 1.0.0
40
- */
41
- public function __construct() {
42
-
43
- // actions
44
- add_action( 'init', array( $this, 'init' ) );
 
 
45
  add_action( 'widgets_init', array( $this, 'registerWidgets' ) );
46
- add_action( 'wp_ajax_yith_ajax_search_products', array( $this, 'ajax_search_products') );
47
- add_action( 'wp_ajax_nopriv_yith_ajax_search_products', array( $this, 'ajax_search_products') );
 
48
 
49
  //register shortcode
50
- add_shortcode( 'yith_woocommerce_ajax_search', array( $this, 'add_woo_ajax_search_shortcode') );
51
-
52
- if( is_admin() ) {
53
- $this->obj = new YITH_WCAS_Admin( $this->version );
54
- } else {
55
- $this->obj = new YITH_WCAS_Frontend( $this->version );
56
- }
57
-
58
- return $this->obj;
59
- }
60
-
61
-
62
- /**
63
- * Init method:
64
- * - default options
65
- *
66
- * @access public
67
- * @since 1.0.0
68
- */
69
- public function init() {}
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  /**
72
  * Load template for [yith_woocommerce_ajax_search] shortcode
73
  *
74
  * @access public
 
75
  * @param $args array
 
76
  * @return void
77
- * @since 1.0.0
78
  */
79
  public function add_woo_ajax_search_shortcode( $args = array() ) {
80
- $args = shortcode_atts( array(), $args );
81
-
82
- $wc_get_template = function_exists('wc_get_template') ? 'wc_get_template' : 'woocommerce_get_template';
83
-
84
  $wc_get_template( 'yith-woocommerce-ajax-search.php', $args, '', YITH_WCAS_DIR . 'templates/' );
85
  }
86
 
@@ -88,7 +104,7 @@ if( !class_exists( 'YITH_WCAS' ) ) {
88
  * Load and register widgets
89
  *
90
  * @access public
91
- * @since 1.0.0
92
  */
93
  public function registerWidgets() {
94
  register_widget( 'YITH_WCAS_Ajax_Search_Widget' );
@@ -96,46 +112,46 @@ if( !class_exists( 'YITH_WCAS' ) ) {
96
 
97
 
98
  /**
99
- * Perform jax search products
100
  */
101
  public function ajax_search_products() {
102
  global $woocommerce;
103
 
104
- $search_keyword = esc_attr($_REQUEST['query']);
105
 
106
  $ordering_args = $woocommerce->query->get_catalog_ordering_args( 'title', 'asc' );
107
- $suggestions = array();
108
 
109
  $args = array(
110
- 's' => apply_filters('yith_wcas_ajax_search_products_search_query', $search_keyword),
111
- 'post_type' => 'product',
112
- 'post_status' => 'publish',
113
- 'ignore_sticky_posts' => 1,
114
- 'orderby' => $ordering_args['orderby'],
115
- 'order' => $ordering_args['order'],
116
- 'posts_per_page' => apply_filters('yith_wcas_ajax_search_products_posts_per_page', get_option('yith_wcas_posts_per_page')),
117
- 'meta_query' => array(
118
  array(
119
- 'key' => '_visibility',
120
- 'value' => array('catalog', 'visible'),
121
- 'compare' => 'IN'
122
  )
123
  )
124
  );
125
 
126
- if( isset( $_REQUEST['product_cat']) ){
127
  $args['tax_query'] = array(
128
  'relation' => 'AND',
129
  array(
130
  'taxonomy' => 'product_cat',
131
- 'field' => 'slug',
132
- 'terms' => $_REQUEST['product_cat']
133
- ));
134
  }
135
 
136
  $products = get_posts( $args );
137
 
138
- if ( ! empty( $products ) ) {
139
  foreach ( $products as $post ) {
140
  $product = wc_get_product( $post );
141
 
@@ -145,11 +161,12 @@ if( !class_exists( 'YITH_WCAS' ) ) {
145
  'url' => $product->get_permalink()
146
  ), $product );
147
  }
148
- } else {
 
149
  $suggestions[] = array(
150
- 'id' => -1,
151
- 'value' => __('No results', 'yit'),
152
- 'url' => '',
153
  );
154
  }
155
  wp_reset_postdata();
@@ -163,5 +180,5 @@ if( !class_exists( 'YITH_WCAS' ) ) {
163
  echo json_encode( $suggestions );
164
  die();
165
  }
166
- }
167
  }
2
  /**
3
  * Main class
4
  *
5
+ * @author Yithemes
6
  * @package YITH WooCommerce Ajax Search
7
  * @version 1.1.1
8
  */
9
 
10
+ if ( !defined( 'YITH_WCAS' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
 
14
+ if ( !class_exists( 'YITH_WCAS' ) ) {
15
  /**
16
+ * YITH WooCommerce Ajax Search
17
  *
18
  * @since 1.0.0
19
  */
24
  * @var string
25
  * @since 1.0.0
26
  */
27
+ public $version = YITH_WCAS_VERSION;
28
+
29
  /**
30
  * Plugin object
31
  *
34
  */
35
  public $obj = null;
36
 
37
+ /**
38
+ * Constructor
39
+ *
40
+ * @return mixed|YITH_WCAS_Admin|YITH_WCAS_Frontend
41
+ * @since 1.0.0
42
+ */
43
+ public function __construct() {
44
+
45
+ // Load Plugin Framework
46
+ add_action( 'after_setup_theme', array( $this, 'plugin_fw_loader' ), 1 );
47
+
48
+ // actions
49
  add_action( 'widgets_init', array( $this, 'registerWidgets' ) );
50
+ add_action( 'wp_ajax_yith_ajax_search_products', array( $this, 'ajax_search_products' ) );
51
+ add_action( 'wp_ajax_nopriv_yith_ajax_search_products', array( $this, 'ajax_search_products' ) );
52
+
53
 
54
  //register shortcode
55
+ add_shortcode( 'yith_woocommerce_ajax_search', array( $this, 'add_woo_ajax_search_shortcode' ) );
56
+
57
+ if ( is_admin() ) {
58
+ $this->obj = new YITH_WCAS_Admin( $this->version );
59
+ }
60
+ else {
61
+ $this->obj = new YITH_WCAS_Frontend( $this->version );
62
+ }
63
+
64
+ return $this->obj;
65
+ }
66
+
67
+
68
+ /**
69
+ * Load Plugin Framework
70
+ *
71
+ * @since 1.0
72
+ * @access public
73
+ * @return void
74
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
75
+ */
76
+ public function plugin_fw_loader() {
77
+
78
+ if ( !defined( 'YIT' ) || !defined( 'YIT_CORE_PLUGIN' ) ) {
79
+
80
+ require_once( 'plugin-fw/yit-plugin.php' );
81
+ }
82
+
83
+ }
84
+
85
+
86
 
87
  /**
88
  * Load template for [yith_woocommerce_ajax_search] shortcode
89
  *
90
  * @access public
91
+ *
92
  * @param $args array
93
+ *
94
  * @return void
95
+ * @since 1.0.0
96
  */
97
  public function add_woo_ajax_search_shortcode( $args = array() ) {
98
+ $args = shortcode_atts( array(), $args );
99
+ $wc_get_template = function_exists( 'wc_get_template' ) ? 'wc_get_template' : 'woocommerce_get_template';
 
 
100
  $wc_get_template( 'yith-woocommerce-ajax-search.php', $args, '', YITH_WCAS_DIR . 'templates/' );
101
  }
102
 
104
  * Load and register widgets
105
  *
106
  * @access public
107
+ * @since 1.0.0
108
  */
109
  public function registerWidgets() {
110
  register_widget( 'YITH_WCAS_Ajax_Search_Widget' );
112
 
113
 
114
  /**
115
+ * Perform ajax search products
116
  */
117
  public function ajax_search_products() {
118
  global $woocommerce;
119
 
120
+ $search_keyword = esc_attr( $_REQUEST['query'] );
121
 
122
  $ordering_args = $woocommerce->query->get_catalog_ordering_args( 'title', 'asc' );
123
+ $suggestions = array();
124
 
125
  $args = array(
126
+ 's' => apply_filters( 'yith_wcas_ajax_search_products_search_query', $search_keyword ),
127
+ 'post_type' => 'product',
128
+ 'post_status' => 'publish',
129
+ 'ignore_sticky_posts' => 1,
130
+ 'orderby' => $ordering_args['orderby'],
131
+ 'order' => $ordering_args['order'],
132
+ 'posts_per_page' => apply_filters( 'yith_wcas_ajax_search_products_posts_per_page', get_option( 'yith_wcas_posts_per_page' ) ),
133
+ 'meta_query' => array(
134
  array(
135
+ 'key' => '_visibility',
136
+ 'value' => array( 'search', 'visible' ),
137
+ 'compare' => 'IN'
138
  )
139
  )
140
  );
141
 
142
+ if ( isset( $_REQUEST['product_cat'] ) ) {
143
  $args['tax_query'] = array(
144
  'relation' => 'AND',
145
  array(
146
  'taxonomy' => 'product_cat',
147
+ 'field' => 'slug',
148
+ 'terms' => $_REQUEST['product_cat']
149
+ ) );
150
  }
151
 
152
  $products = get_posts( $args );
153
 
154
+ if ( !empty( $products ) ) {
155
  foreach ( $products as $post ) {
156
  $product = wc_get_product( $post );
157
 
161
  'url' => $product->get_permalink()
162
  ), $product );
163
  }
164
+ }
165
+ else {
166
  $suggestions[] = array(
167
+ 'id' => - 1,
168
+ 'value' => __( 'No results', 'yit' ),
169
+ 'url' => '',
170
  );
171
  }
172
  wp_reset_postdata();
180
  echo json_encode( $suggestions );
181
  die();
182
  }
183
+ }
184
  }
functions.yith-wcas.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Functions
4
  *
5
- * @author Your Inspiration Themes
6
  * @package YITH WooCommerce Ajax Search
7
  * @version 1.1.1
8
  */
2
  /**
3
  * Functions
4
  *
5
+ * @author Yithemes
6
  * @package YITH WooCommerce Ajax Search
7
  * @version 1.1.1
8
  */
init.php CHANGED
@@ -3,13 +3,13 @@
3
  * Plugin Name: YITH WooCommerce Ajax Search
4
  * Plugin URI: http://yithemes.com/
5
  * Description: YITH WooCommerce Ajax Search allows your users to search products in real time.
6
- * Version: 1.1.3
7
- * Author: Your Inspiration Themes
8
  * Author URI: http://yithemes.com/
9
  * Text Domain: yit
10
  * Domain Path: /languages/
11
- *
12
- * @author Your Inspiration Themes
13
  * @package YITH WooCommerce Ajax Search
14
  * @version 1.1.1
15
  */
@@ -30,22 +30,85 @@
30
  */
31
  if ( !defined( 'ABSPATH' ) ) { exit; } // Exit if accessed directly
32
 
33
- function yith_ajax_search_constructor() {
34
- global $woocommerce;
35
- if ( ! isset( $woocommerce ) ) return;
36
-
37
- /**
38
- * Required functions
39
- */
40
- if( !defined('YITH_FUNCTIONS') ) {
41
- require_once( 'yit-common/yit-functions.php' );
42
  }
43
 
44
- load_plugin_textdomain( 'yit', false, dirname( plugin_basename( __FILE__ ) ). '/languages/' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
 
46
  define( 'YITH_WCAS', true );
 
 
 
 
 
 
 
47
  define( 'YITH_WCAS_URL', plugin_dir_url( __FILE__ ) );
48
- define( 'YITH_WCAS_DIR', plugin_dir_path( __FILE__ ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  // Load required classes and functions
51
  require_once('functions.yith-wcas.php');
3
  * Plugin Name: YITH WooCommerce Ajax Search
4
  * Plugin URI: http://yithemes.com/
5
  * Description: YITH WooCommerce Ajax Search allows your users to search products in real time.
6
+ * Version: 1.2
7
+ * Author: Yithemes
8
  * Author URI: http://yithemes.com/
9
  * Text Domain: yit
10
  * Domain Path: /languages/
11
+ *
12
+ * @author Yithemes
13
  * @package YITH WooCommerce Ajax Search
14
  * @version 1.1.1
15
  */
30
  */
31
  if ( !defined( 'ABSPATH' ) ) { exit; } // Exit if accessed directly
32
 
33
+
34
+ if ( !function_exists( 'WC' ) ) {
35
+ function yith_wcas_install_woocommerce_admin_notice() {
36
+ ?>
37
+ <div class="error">
38
+ <p><?php _e( 'YITH WooCommerce Ajax Search is enabled but not effective. It requires Woocommerce in order to work.', 'yit' ); ?></p>
39
+ </div>
40
+ <?php
 
41
  }
42
 
43
+ add_action( 'admin_notices', 'yith_wcas_install_woocommerce_admin_notice' );
44
+ return;
45
+ }
46
+
47
+ if ( defined( 'YITH_WCAS_PREMIUM' ) ) {
48
+ function yith_wcas_install_free_admin_notice() {
49
+ ?>
50
+ <div class="error">
51
+ <p><?php _e( 'You can\'t activate the free version of YITH WooCommerce Ajax Search while you are using the premium one.', 'yit' ); ?></p>
52
+ </div>
53
+ <?php
54
+ }
55
+
56
+ add_action( 'admin_notices', 'yith_wcas_install_free_admin_notice' );
57
+
58
+ deactivate_plugins( plugin_basename( __FILE__ ) );
59
+ return;
60
+ }
61
+
62
+ if ( !function_exists( 'yith_plugin_registration_hook' ) ) {
63
+ require_once 'plugin-fw/yit-plugin-registration-hook.php';
64
+ }
65
+
66
+ register_activation_hook( __FILE__, 'yith_plugin_registration_hook' );
67
+
68
+
69
+
70
+ if ( defined( 'YITH_WCAS_VERSION' ) ){
71
+ return;
72
+ }else{
73
+ define( 'YITH_WCAS_VERSION', '1.2' );
74
+ }
75
+
76
+ if ( ! defined( 'YITH_WCAS_FREE_INIT' ) ) {
77
+ define( 'YITH_WCAS_FREE_INIT', plugin_basename( __FILE__ ) );
78
+ }
79
 
80
+ if ( ! defined( 'YITH_WCAS' ) ) {
81
  define( 'YITH_WCAS', true );
82
+ }
83
+
84
+ if ( ! defined( 'YITH_WCAS_FILE' ) ) {
85
+ define( 'YITH_WCAS_FILE', __FILE__ );
86
+ }
87
+
88
+ if ( ! defined( 'YITH_WCAS_URL' ) ) {
89
  define( 'YITH_WCAS_URL', plugin_dir_url( __FILE__ ) );
90
+ }
91
+
92
+ if ( ! defined( 'YITH_WCAS_DIR' ) ) {
93
+ define( 'YITH_WCAS_DIR', plugin_dir_path( __FILE__ ) );
94
+ }
95
+
96
+ if ( ! defined( 'YITH_WCAS_TEMPLATE_PATH' ) ) {
97
+ define( 'YITH_WCAS_TEMPLATE_PATH', YITH_WCAS_DIR . 'templates' );
98
+ }
99
+
100
+ if ( ! defined( 'YITH_WCAS_ASSETS_URL' ) ) {
101
+ define( 'YITH_WCAS_ASSETS_URL', YITH_WCAS_URL . 'assets' );
102
+ }
103
+
104
+ if ( ! defined( 'YITH_WCAS_ASSETS_IMAGES_URL' ) ) {
105
+ define( 'YITH_WCAS_ASSETS_IMAGES_URL', YITH_WCAS_ASSETS_URL . '/images/' );
106
+ }
107
+
108
+
109
+ function yith_ajax_search_constructor() {
110
+
111
+ load_plugin_textdomain( 'yit', false, dirname( plugin_basename( __FILE__ ) ). '/languages/' );
112
 
113
  // Load required classes and functions
114
  require_once('functions.yith-wcas.php');
languages/default.po CHANGED
@@ -1,150 +1,1057 @@
1
  msgid ""
2
  msgstr ""
3
- "Project-Id-Version: YITH WooCommerce Ajax Search\n"
4
- "POT-Creation-Date: 2013-07-29 18:57+0100\n"
5
- "PO-Revision-Date: 2013-07-29 18:57+0100\n"
6
  "Last-Translator: \n"
7
- "Language-Team: Your Inspiration Themes <plugins@yithemes.com>\n"
 
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
  "X-Generator: Poedit 1.5.5\n"
12
  "X-Poedit-KeywordsList: __;_e;_x\n"
13
  "X-Poedit-Basepath: ./\n"
 
14
  "X-Poedit-SearchPath-0: ..\n"
15
 
16
- #: ../class.yith-wcas-admin.php:124
 
 
 
 
 
 
 
 
 
 
 
 
17
  msgid "Ajax Search"
18
  msgstr ""
19
 
20
- #: ../class.yith-wcas-admin.php:173 ../class.yith-wcas-admin.php:213
21
- msgid "General Settings"
22
  msgstr ""
23
 
24
- #: ../class.yith-wcas-admin.php:220
25
- msgid "Search input label"
 
 
 
 
 
 
 
 
 
 
26
  msgstr ""
27
 
28
  #: ../class.yith-wcas-admin.php:221
29
- msgid "Label for Search input field."
30
  msgstr ""
31
 
32
- #: ../class.yith-wcas-admin.php:223 ../class.yith-wcas-admin.php:224
33
- msgid "Search for products"
 
 
 
 
 
 
34
  msgstr ""
35
 
36
- #: ../class.yith-wcas-admin.php:230
37
- msgid "Search submit label"
38
  msgstr ""
39
 
40
- #: ../class.yith-wcas-admin.php:231
41
- msgid "Label for Search submit field."
 
 
42
  msgstr ""
43
 
44
- #: ../class.yith-wcas-admin.php:233 ../class.yith-wcas-admin.php:234
45
- msgid "Search"
 
 
46
  msgstr ""
47
 
48
- #: ../class.yith-wcas-admin.php:240
49
- msgid "Minimum number of characters"
 
 
 
 
50
  msgstr ""
51
 
52
- #: ../class.yith-wcas-admin.php:241
53
- msgid "Minimum number of characters required to trigger autosuggest."
 
 
54
  msgstr ""
55
 
56
- #: ../class.yith-wcas-admin.php:256
57
- msgid "Maximum number of results"
 
 
 
 
58
  msgstr ""
59
 
60
- #: ../class.yith-wcas-admin.php:257
61
- msgid "Maximum number of results showed within the autosuggest box."
 
 
62
  msgstr ""
63
 
64
- #: ../class.yith-wcas-admin.php:430
65
- msgid "Settings"
 
 
66
  msgstr ""
67
 
68
- #: ../class.yith-wcas-admin.php:431
69
- msgid "Docs"
 
 
 
 
70
  msgstr ""
71
 
72
- #: ../class.yith-wcas.php:137
73
- msgid "No results"
 
 
74
  msgstr ""
75
 
76
- #: ../templates/yith-woocommerce-ajax-search.php:20
77
- msgid "Search for:"
 
 
78
  msgstr ""
79
 
80
- #: ../widgets/class.yith-wcas-ajax-search.php:29
81
- msgid "An Ajax Search box for products only."
 
 
82
  msgstr ""
83
 
84
- #: ../widgets/class.yith-wcas-ajax-search.php:31
85
- msgid "YITH WooCommerce Ajax Product Search"
 
86
  msgstr ""
87
 
88
- #: ../widgets/class.yith-wcas-ajax-search.php:90
89
- msgid "Title:"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  msgstr ""
91
 
92
- #: ../yit-common/yith-panel.php:396
93
- msgid "Select a date"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  msgstr ""
95
 
96
- #: ../yit-common/yith-panel.php:397
97
- msgid "Hours"
98
  msgstr ""
99
 
100
- #: ../yit-common/yith-panel.php:398 ../yit-common/yith-panel.php:399
101
- msgid "Minutes"
102
  msgstr ""
103
 
104
- #: ../yit-common/yith-panel.php:407
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  msgid "Upload"
106
  msgstr ""
107
 
108
- #: ../yit-common/yith-panel.php:434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  msgid "px"
110
  msgstr ""
111
 
112
- #: ../yit-common/yith-panel.php:435
113
  msgid "em"
114
  msgstr ""
115
 
116
- #: ../yit-common/yith-panel.php:436
117
  msgid "pt"
118
  msgstr ""
119
 
120
- #: ../yit-common/yith-panel.php:437
121
  msgid "rem"
122
  msgstr ""
123
 
124
- #: ../yit-common/yith-panel.php:447
125
- msgid "Select a font family"
 
 
126
  msgstr ""
127
 
128
- #: ../yit-common/yith-panel.php:455
 
 
 
 
129
  msgid "Regular"
130
  msgstr ""
131
 
132
- #: ../yit-common/yith-panel.php:456
133
  msgid "Bold"
134
  msgstr ""
135
 
136
- #: ../yit-common/yith-panel.php:457
137
  msgid "Extra bold"
138
  msgstr ""
139
 
140
- #: ../yit-common/yith-panel.php:458
141
  msgid "Italic"
142
  msgstr ""
143
 
144
- #: ../yit-common/yith-panel.php:459
145
  msgid "Italic bold"
146
  msgstr ""
147
 
148
- #: ../yit-common/yith-panel.php:471
149
- msgid "Click to preview"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  msgstr ""
1
  msgid ""
2
  msgstr ""
3
+ "Project-Id-Version: YITH WooCommerce Ajax Search Free\n"
4
+ "POT-Creation-Date: 2015-01-29 15:45+0100\n"
5
+ "PO-Revision-Date: 2015-01-29 15:45+0100\n"
6
  "Last-Translator: \n"
7
+ "Language-Team: Yithemes <plugins@yithemes.com>\n"
8
+ "Language: en\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
  "X-Generator: Poedit 1.5.5\n"
13
  "X-Poedit-KeywordsList: __;_e;_x\n"
14
  "X-Poedit-Basepath: ./\n"
15
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
  "X-Poedit-SearchPath-0: ..\n"
17
 
18
+ #: ../class.yith-wcas-admin.php:106 ../class.yith-wcas-admin.php:128
19
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1048
20
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1196
21
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1202
22
+ #: ../plugin-fw/lib/yit-plugin-panel.php:62
23
+ msgid "Settings"
24
+ msgstr ""
25
+
26
+ #: ../class.yith-wcas-admin.php:107 ../class.yith-wcas-admin.php:129
27
+ msgid "Premium Version"
28
+ msgstr ""
29
+
30
+ #: ../class.yith-wcas-admin.php:135 ../class.yith-wcas-admin.php:136
31
  msgid "Ajax Search"
32
  msgstr ""
33
 
34
+ #: ../class.yith-wcas-admin.php:190
35
+ msgid "Plugin Documentation"
36
  msgstr ""
37
 
38
+ #: ../class.yith-wcas-admin.php:207 ../plugin-options/settings-options.php:24
39
+ msgid "YITH WooCommerce Ajax Search"
40
+ msgstr ""
41
+
42
+ #: ../class.yith-wcas-admin.php:208
43
+ msgid ""
44
+ "In the YIT Plugin tab you can find the YITH WooCommerce Ajax Search "
45
+ "options.\n"
46
+ "With this menu, you can access to all the settings of our plugins that you "
47
+ "have activated.\n"
48
+ "YITH WooCommerce Ajax Search is available in an outstanding PREMIUM version "
49
+ "with many new options, <a href=\""
50
  msgstr ""
51
 
52
  #: ../class.yith-wcas-admin.php:221
53
+ msgid "YITH WooCommerce Ajax Search Updated"
54
  msgstr ""
55
 
56
+ #: ../class.yith-wcas-admin.php:222
57
+ msgid ""
58
+ "From now on, you can find all the options of YITH WooCommerce Ajax Search "
59
+ "Updated under YIT Plugin -> Ajax Search instead of WooCommerce -> Settings -"
60
+ "> Ajax Search, as in the previous version.\n"
61
+ "When one of our plugins updates, a new voice will be added to this menu.\n"
62
+ "YITH WooCommerce Ajax Search renovates with new available options, discover "
63
+ "the <a href=\""
64
  msgstr ""
65
 
66
+ #: ../class.yith-wcas.php:168
67
+ msgid "No results"
68
  msgstr ""
69
 
70
+ #: ../init.php:38
71
+ msgid ""
72
+ "YITH WooCommerce Ajax Search is enabled but not effective. It requires "
73
+ "Woocommerce in order to work."
74
  msgstr ""
75
 
76
+ #: ../init.php:51
77
+ msgid ""
78
+ "You can't activate the free version of YITH WooCommerce Ajax Search while "
79
+ "you are using the premium one."
80
  msgstr ""
81
 
82
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:460
83
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:574
84
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:719
85
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1632
86
+ #, php-format
87
+ msgid "Add %s"
88
  msgstr ""
89
 
90
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:461
91
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:575
92
+ #, php-format
93
+ msgid "Add New %s"
94
  msgstr ""
95
 
96
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:462
97
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:576
98
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1267
99
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1304
100
+ #, php-format
101
+ msgid "Edit %s"
102
  msgstr ""
103
 
104
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:463
105
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:577
106
+ #, php-format
107
+ msgid "New %s"
108
  msgstr ""
109
 
110
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:464
111
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:578
112
+ #, php-format
113
+ msgid "All %s"
114
  msgstr ""
115
 
116
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:465
117
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:579
118
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1251
119
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1305
120
+ #, php-format
121
+ msgid "View %s"
122
  msgstr ""
123
 
124
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:466
125
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:580
126
+ #, php-format
127
+ msgid "Search %s"
128
  msgstr ""
129
 
130
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:467
131
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:581
132
+ #, php-format
133
+ msgid "No %s found"
134
  msgstr ""
135
 
136
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:468
137
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:582
138
+ #, php-format
139
+ msgid "No %s found in Trash"
140
  msgstr ""
141
 
142
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:625
143
+ #, php-format
144
+ msgid "%s Categories"
145
  msgstr ""
146
 
147
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:626
148
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:635
149
+ msgid "Category"
150
+ msgstr ""
151
+
152
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:627
153
+ msgid "Search Categories"
154
+ msgstr ""
155
+
156
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:628
157
+ msgid "All Categories"
158
+ msgstr ""
159
+
160
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:629
161
+ msgid "Parent Category"
162
+ msgstr ""
163
+
164
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:630
165
+ msgid "Parent Category:"
166
+ msgstr ""
167
+
168
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:631
169
+ msgid "Edit Category"
170
+ msgstr ""
171
+
172
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:632
173
+ msgid "Update Category"
174
+ msgstr ""
175
+
176
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:633
177
+ msgid "Add New Category"
178
+ msgstr ""
179
+
180
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:634
181
+ msgid "New Category Name"
182
+ msgstr ""
183
+
184
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:724
185
+ msgid "Categories"
186
+ msgstr ""
187
+
188
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1042
189
+ #, php-format
190
+ msgid "%s Settings"
191
+ msgstr ""
192
+
193
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1051
194
+ msgid "Type"
195
+ msgstr ""
196
+
197
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1052
198
+ msgid "The layout for this "
199
+ msgstr ""
200
+
201
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1058
202
+ msgid "Rewrite"
203
+ msgstr ""
204
+
205
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1059
206
+ msgid "The word used for the URL of each project (the slug of post if empty)"
207
+ msgstr ""
208
+
209
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1064
210
+ msgid "Label Singular"
211
+ msgstr ""
212
+
213
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1065
214
+ msgid ""
215
+ "Set the label in singular to use for each label (the title of portfolio if "
216
+ "empty)"
217
+ msgstr ""
218
+
219
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1070
220
+ msgid "Label Plural"
221
+ msgstr ""
222
+
223
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1071
224
+ msgid ""
225
+ "Set the label in plural to use for each label (the title of portfolio if "
226
+ "empty)"
227
+ msgstr ""
228
+
229
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1076
230
+ msgid "Taxonomy"
231
+ msgstr ""
232
+
233
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1077
234
+ msgid ""
235
+ "If you want to use a category section for the portfolio, set the name of "
236
+ "taxonomy. Name should be in slug form (must not contain capital letters or "
237
+ "spaces) and not more than 32 characters long (database structure "
238
+ "restriction)."
239
+ msgstr ""
240
+
241
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1082
242
+ msgid "Taxonomy Rewrite"
243
+ msgstr ""
244
+
245
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1083
246
+ msgid "Set the word to use in the URL for each category page."
247
+ msgstr ""
248
+
249
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1088
250
+ msgid "Single layout"
251
+ msgstr ""
252
+
253
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1089
254
+ msgid "The layout for single page of this portfolio"
255
+ msgstr ""
256
+
257
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1130
258
+ msgid "layout settings"
259
+ msgstr ""
260
+
261
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1222
262
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1235
263
+ msgid "Quick links"
264
+ msgstr ""
265
+
266
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1475
267
+ #, php-format
268
+ msgid "Show the frontend of the %s"
269
+ msgstr ""
270
+
271
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1482
272
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:46
273
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:90
274
+ msgid "Name"
275
+ msgstr ""
276
+
277
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1631
278
+ #, php-format
279
+ msgid "Add %s by images"
280
+ msgstr ""
281
+
282
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1633
283
+ msgid "Add with multiupload"
284
+ msgstr ""
285
+
286
+ #: ../plugin-fw/lib/yit-plugin-panel-wc.php:302
287
+ msgid "The changes you made will be lost if you navigate away from this page."
288
+ msgstr ""
289
+
290
+ #: ../plugin-fw/lib/yit-plugin-panel.php:61
291
+ msgid "Plugin Settings"
292
+ msgstr ""
293
+
294
+ #: ../plugin-fw/lib/yit-plugin-panel.php:92
295
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:101
296
+ msgid "YIT Plugins"
297
+ msgstr ""
298
+
299
+ #: ../plugin-fw/lib/yit-plugin-panel.php:269
300
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:142
301
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:5
302
+ msgid "Save Changes"
303
+ msgstr ""
304
+
305
+ #: ../plugin-fw/lib/yit-plugin-panel.php:272
306
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:145
307
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:8
308
+ msgid ""
309
+ "If you continue with this action, you will reset all options are in this "
310
+ "page."
311
+ msgstr ""
312
+
313
+ #: ../plugin-fw/lib/yit-plugin-panel.php:274
314
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:147
315
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:10
316
+ msgid "Reset Defaults"
317
+ msgstr ""
318
+
319
+ #: ../plugin-fw/lib/yit-plugin-panel.php:274
320
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:147
321
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:10
322
+ msgid "Are you sure of it?"
323
+ msgstr ""
324
+
325
+ #: ../plugin-fw/lib/yit-plugin-panel.php:408
326
+ msgid ""
327
+ "The element you have written is already exists. Please, add another name."
328
+ msgstr ""
329
+
330
+ #: ../plugin-fw/lib/yit-plugin-panel.php:409
331
+ msgid "Settings saved"
332
+ msgstr ""
333
+
334
+ #: ../plugin-fw/lib/yit-plugin-panel.php:410
335
+ msgid "Settings reset"
336
+ msgstr ""
337
+
338
+ #: ../plugin-fw/lib/yit-plugin-panel.php:411
339
+ msgid "Element deleted correctly."
340
+ msgstr ""
341
+
342
+ #: ../plugin-fw/lib/yit-plugin-panel.php:412
343
+ #: ../plugin-fw/lib/yit-plugin-panel.php:413
344
+ msgid "Element updated correctly."
345
+ msgstr ""
346
+
347
+ #: ../plugin-fw/lib/yit-plugin-panel.php:414
348
+ msgid "Database imported correctly."
349
+ msgstr ""
350
+
351
+ #: ../plugin-fw/lib/yit-plugin-panel.php:415
352
+ msgid "An error encoured during during import. Please try again."
353
+ msgstr ""
354
+
355
+ #: ../plugin-fw/lib/yit-plugin-panel.php:416
356
+ msgid "The file you have insert doesn't valid."
357
+ msgstr ""
358
+
359
+ #: ../plugin-fw/lib/yit-plugin-panel.php:417
360
+ msgid "I'm sorry, the import featured is disabled."
361
+ msgstr ""
362
+
363
+ #: ../plugin-fw/lib/yit-plugin-panel.php:418
364
+ msgid "Sorting done correctly."
365
+ msgstr ""
366
+
367
+ #: ../plugin-fw/lib/yit-pointers.php:70
368
+ msgid "Plugins Activated"
369
+ msgstr ""
370
+
371
+ #: ../plugin-fw/lib/yit-pointers.php:71
372
+ msgid ""
373
+ "From now on, you can find all the options of your plugins under the YIT "
374
+ "Plugin menu voice.\n"
375
+ " For every installation of our new "
376
+ "plugins, a new voice will be added to access to the customization settings."
377
+ msgstr ""
378
+
379
+ #: ../plugin-fw/lib/yit-pointers.php:73 ../plugin-fw/lib/yit-pointers.php:89
380
+ msgid "Discover all our plugins available on:"
381
+ msgstr ""
382
+
383
+ #: ../plugin-fw/lib/yit-pointers.php:74 ../plugin-fw/lib/yit-pointers.php:90
384
+ msgid "and"
385
+ msgstr ""
386
+
387
+ #: ../plugin-fw/lib/yit-pointers.php:84
388
+ msgid "Plugins Upgraded"
389
+ msgstr ""
390
+
391
+ #: ../plugin-fw/lib/yit-pointers.php:85
392
+ msgid ""
393
+ "From now on, you can find all the options of your plugins under the YIT "
394
+ "Plugin menu voice.\n"
395
+ " When one of our plugins updates, a new "
396
+ "voice will be added to this menu.\n"
397
+ " For example, after the update, the "
398
+ "options from the plugins (YITH WooCommerce Wishlist, YITH WooCommerce Ajax "
399
+ "Search, etc.)\n"
400
+ " will be removed from the previous "
401
+ "location and moved under the YIT Plugin tab."
402
+ msgstr ""
403
+
404
+ #: ../plugin-fw/lib/yit-upgrade.php:120
405
+ msgid "There is a new version of %plugin_name% available."
406
+ msgstr ""
407
+
408
+ #: ../plugin-fw/lib/yit-upgrade.php:121
409
+ msgid "View version %latest% details."
410
+ msgstr ""
411
+
412
+ #: ../plugin-fw/lib/yit-upgrade.php:122
413
+ msgid "Automatic update is unavailable for this plugin,"
414
+ msgstr ""
415
+
416
+ #: ../plugin-fw/lib/yit-upgrade.php:123
417
+ msgid ""
418
+ "please <a href=\"%activate_link%\"> activate </a> your copy of %plugin_name%."
419
+ msgstr ""
420
+
421
+ #: ../plugin-fw/lib/yit-upgrade.php:124
422
+ msgid "Update now."
423
+ msgstr ""
424
+
425
+ #: ../plugin-fw/lib/yit-upgrade.php:220
426
+ msgid "Yithemes Repository"
427
+ msgstr ""
428
+
429
+ #: ../plugin-fw/lib/yit-upgrade.php:254
430
+ msgid "Invalid URL Provided."
431
+ msgstr ""
432
+
433
+ #: ../plugin-fw/lib/yit-upgrade.php:267
434
+ msgid "Could not create Temporary file."
435
+ msgstr ""
436
+
437
+ #: ../plugin-fw/lib/yit-upgrade.php:408
438
+ #, php-format
439
+ msgid ""
440
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
441
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>."
442
+ msgstr ""
443
+
444
+ #: ../plugin-fw/lib/yit-upgrade.php:410
445
+ #, php-format
446
+ msgid ""
447
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
448
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>. <em>You "
449
+ "have to activate the plugin on a single site of the network to benefit from "
450
+ "the automatic updates.</em>"
451
+ msgstr ""
452
+
453
+ #: ../plugin-fw/lib/yit-upgrade.php:412
454
+ #, php-format
455
+ msgid ""
456
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
457
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>. "
458
+ "<em>Automatic update is unavailable for this plugin, please <a href=\"%5$s\" "
459
+ "title=\"Licence activation\">activate</a> your copy of %6s.</em>"
460
+ msgstr ""
461
+
462
+ #: ../plugin-fw/lib/yit-upgrade.php:414
463
+ #, php-format
464
+ msgid ""
465
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
466
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a> or <a "
467
+ "href=\"%5$s\">update now</a>."
468
+ msgstr ""
469
+
470
+ #: ../plugin-fw/lib/yit-upgrade.php:487
471
+ msgid "You can't update plugins for this site."
472
+ msgstr ""
473
+
474
+ #: ../plugin-fw/lib/yit-upgrade.php:491
475
+ msgid "You do not have sufficient permissions to update plugins for this site."
476
+ msgstr ""
477
+
478
+ #: ../plugin-fw/lib/yit-upgrade.php:498
479
+ msgid "Update Plugin"
480
+ msgstr ""
481
+
482
+ #: ../plugin-fw/licence/lib/yit-licence.php:154
483
+ #, php-format
484
+ msgid "%field% field can not be empty"
485
+ msgstr ""
486
+
487
+ #: ../plugin-fw/licence/lib/yit-licence.php:155
488
+ msgid "%field_1% and %field_2% fields can not be empty"
489
+ msgstr ""
490
+
491
+ #: ../plugin-fw/licence/lib/yit-licence.php:156
492
+ msgid "Unable to contact the remote server, please try again later. Thanks!"
493
+ msgstr ""
494
+
495
+ #: ../plugin-fw/licence/lib/yit-licence.php:538
496
+ msgid "Invalid Request"
497
+ msgstr ""
498
+
499
+ #: ../plugin-fw/licence/lib/yit-licence.php:539
500
+ msgid "Invalid licence key"
501
+ msgstr ""
502
+
503
+ #: ../plugin-fw/licence/lib/yit-licence.php:540
504
+ msgid "Software has been deactive"
505
+ msgstr ""
506
+
507
+ #: ../plugin-fw/licence/lib/yit-licence.php:541
508
+ msgid "Exceeded maximum number of activations"
509
+ msgstr ""
510
+
511
+ #: ../plugin-fw/licence/lib/yit-licence.php:542
512
+ msgid "Invalid instance ID"
513
  msgstr ""
514
 
515
+ #: ../plugin-fw/licence/lib/yit-licence.php:543
516
+ msgid "Invalid security key"
517
+ msgstr ""
518
+
519
+ #: ../plugin-fw/licence/lib/yit-licence.php:544
520
+ msgid "Licence key has expired"
521
+ msgstr ""
522
+
523
+ #: ../plugin-fw/licence/lib/yit-licence.php:545
524
+ msgid "Licence key has be banned"
525
+ msgstr ""
526
+
527
+ #: ../plugin-fw/licence/lib/yit-plugin-licence.php:63
528
+ #: ../plugin-fw/licence/lib/yit-plugin-licence.php:64
529
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:63
530
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:64
531
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:106
532
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:107
533
+ msgid "Licence Activation"
534
+ msgstr ""
535
+
536
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:114
537
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:115
538
+ #, php-format
539
+ msgid "%s"
540
+ msgstr ""
541
+
542
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:25
543
+ msgid "Yithemes Licence Activation"
544
+ msgstr ""
545
+
546
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:29
547
+ msgid ""
548
+ "Have you updated your licenses? Have you asked for an extension? Update "
549
+ "information concerning your products."
550
  msgstr ""
551
 
552
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:31
553
+ msgid "Update licence information"
554
  msgstr ""
555
 
556
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:41
557
+ msgid "To Active"
558
  msgstr ""
559
 
560
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:60
561
+ msgid "Activate"
562
+ msgstr ""
563
+
564
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:79
565
+ msgid "Activated"
566
+ msgstr ""
567
+
568
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:83
569
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:114
570
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:138
571
+ msgid "Product Name"
572
+ msgstr ""
573
+
574
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:84
575
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:115
576
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:139
577
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:145
578
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:337
579
+ msgid "Email"
580
+ msgstr ""
581
+
582
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:85
583
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:116
584
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:140
585
+ msgid "Licence Key"
586
+ msgstr ""
587
+
588
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:86
589
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:141
590
+ msgid "Expires"
591
+ msgstr ""
592
+
593
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:87
594
+ msgid "Remaining"
595
+ msgstr ""
596
+
597
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:88
598
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:101
599
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:142
600
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:152
601
+ msgid "Renew"
602
+ msgstr ""
603
+
604
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:99
605
+ #, php-format
606
+ msgid "%1s out of %2s"
607
+ msgstr ""
608
+
609
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:110
610
+ msgid "Banned"
611
+ msgstr ""
612
+
613
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:134
614
+ msgid "Expired"
615
+ msgstr ""
616
+
617
+ #: ../plugin-fw/templates/metaboxes/types/categories.php:36
618
+ msgid "No categories."
619
+ msgstr ""
620
+
621
+ #: ../plugin-fw/templates/metaboxes/types/categories.php:42
622
+ msgid "+ Add New Category"
623
+ msgstr ""
624
+
625
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:5
626
+ msgid "Text Input"
627
+ msgstr ""
628
+
629
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:6
630
+ msgid "Checkbox"
631
+ msgstr ""
632
+
633
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:7
634
+ msgid "Select"
635
+ msgstr ""
636
+
637
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:8
638
+ msgid "Textarea"
639
+ msgstr ""
640
+
641
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:9
642
+ msgid "Radio Input"
643
+ msgstr ""
644
+
645
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:10
646
+ msgid "Password Field"
647
+ msgstr ""
648
+
649
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:11
650
+ msgid "File Upload"
651
+ msgstr ""
652
+
653
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:45
654
+ msgid "Theme Icon"
655
+ msgstr ""
656
+
657
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:46
658
+ msgid "Custom Icon"
659
+ msgstr ""
660
+
661
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:47
662
+ #: ../plugin-fw/templates/metaboxes/types/responsivesliders.php:24
663
+ msgid "None"
664
+ msgstr ""
665
+
666
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:57
667
+ msgid "Add field"
668
+ msgstr ""
669
+
670
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:66
671
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:258
672
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:37
673
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:82
674
+ msgid "Remove"
675
+ msgstr ""
676
+
677
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:67
678
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:259
679
+ msgid "Click to toggle"
680
+ msgstr ""
681
+
682
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:74
683
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:266
684
+ msgid "Title Field"
685
+ msgstr ""
686
+
687
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:78
688
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:270
689
+ msgid "Insert the title of field."
690
+ msgstr ""
691
+
692
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:83
693
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:275
694
+ msgid "Data Name"
695
+ msgstr ""
696
+
697
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:87
698
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:279
699
+ msgid ""
700
+ "REQUIRED: The identification name of this field, that you can insert into "
701
+ "body email configuration. <strong>Note:</strong>Use only lowercase "
702
+ "characters and underscores."
703
+ msgstr ""
704
+
705
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:92
706
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:284
707
+ msgid "Type field"
708
+ msgstr ""
709
+
710
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:100
711
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:292
712
+ msgid "Select the type of this field."
713
+ msgstr ""
714
+
715
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:105
716
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:297
717
+ msgid "Checked"
718
+ msgstr ""
719
+
720
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:109
721
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:301
722
+ msgid "Select this if you want this field already checked."
723
+ msgstr ""
724
+
725
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:114
726
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:306
727
+ msgid "Add options "
728
+ msgstr ""
729
+
730
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:115
731
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:307
732
+ msgid "Add option"
733
+ msgstr ""
734
+
735
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:118
736
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:310
737
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:432
738
+ msgid "Selected"
739
+ msgstr ""
740
+
741
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:121
742
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:313
743
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:432
744
+ msgid "Delete option"
745
+ msgstr ""
746
+
747
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:127
748
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:319
749
+ msgid "Message Error"
750
+ msgstr ""
751
+
752
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:131
753
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:323
754
+ msgid "Insert the error message for validation."
755
+ msgstr ""
756
+
757
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:136
758
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:328
759
+ msgid "Required"
760
+ msgstr ""
761
+
762
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:140
763
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:332
764
+ msgid "Select this if it must be required."
765
+ msgstr ""
766
+
767
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:149
768
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:341
769
+ msgid "Select this if it must be a valid email."
770
+ msgstr ""
771
+
772
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:154
773
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:346
774
+ msgid "Reply To"
775
+ msgstr ""
776
+
777
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:158
778
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:350
779
+ msgid "Select this if it's the email where you can reply."
780
+ msgstr ""
781
+
782
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:163
783
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:355
784
+ msgid "Class"
785
+ msgstr ""
786
+
787
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:167
788
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:359
789
+ msgid ""
790
+ "Insert an additional class(es) (separateb by comma) for more personalization."
791
+ msgstr ""
792
+
793
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:172
794
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:364
795
+ msgid "Icon"
796
+ msgstr ""
797
+
798
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:200
799
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:388
800
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:69
801
+ #: ../plugin-fw/templates/metaboxes/types/select-icon.php:33
802
+ #: ../plugin-fw/templates/metaboxes/types/upload.php:21
803
+ #: ../plugin-fw/templates/panel/types/upload.php:31
804
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-upload.php:35
805
  msgid "Upload"
806
  msgstr ""
807
 
808
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:206
809
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:394
810
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:75
811
+ #: ../plugin-fw/templates/metaboxes/types/select-icon.php:39
812
+ msgid "Image preview"
813
+ msgstr ""
814
+
815
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:214
816
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:402
817
+ msgid "Insert an icon for more personalization."
818
+ msgstr ""
819
+
820
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:219
821
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:406
822
+ msgid "Width"
823
+ msgstr ""
824
+
825
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:244
826
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:418
827
+ msgid "Choose how much long will be the field."
828
+ msgstr ""
829
+
830
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:28
831
+ msgid "Close all"
832
+ msgstr ""
833
+
834
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:28
835
+ msgid "Expand all"
836
+ msgstr ""
837
+
838
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:52
839
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:95
840
+ msgid "Value"
841
+ msgstr ""
842
+
843
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:53
844
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:96
845
+ msgid "The content of the tab. (HTML is supported)"
846
+ msgstr ""
847
+
848
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:65
849
+ msgid "Add custom product tab"
850
+ msgstr ""
851
+
852
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:107
853
+ msgid "Do you want to remove the custom tab?"
854
+ msgstr ""
855
+
856
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:89
857
+ #, php-format
858
+ msgid "(Default: %s <img src=\"%s\"/>)"
859
+ msgstr ""
860
+
861
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:91
862
+ #, php-format
863
+ msgid "(Default: <i %s></i> )"
864
+ msgstr ""
865
+
866
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:35
867
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
868
+ #: ../plugin-fw/templates/metaboxes/types/images.php:33
869
+ #: ../plugin-fw/templates/metaboxes/types/images.php:59
870
+ msgid "Delete image"
871
+ msgstr ""
872
+
873
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
874
+ msgid "Add Images to Gallery"
875
+ msgstr ""
876
+
877
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
878
+ msgid "Add to gallery"
879
+ msgstr ""
880
+
881
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
882
+ msgid "Add images"
883
+ msgstr ""
884
+
885
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
886
+ msgid "Delete"
887
+ msgstr ""
888
+
889
+ #: ../plugin-fw/templates/metaboxes/types/images.php:37
890
+ msgid "Upload new images"
891
+ msgstr ""
892
+
893
+ #: ../plugin-fw/templates/metaboxes/types/images.php:70
894
+ msgid "Are you sure you want to remove this image?"
895
+ msgstr ""
896
+
897
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:25
898
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:36
899
+ msgid "Left sidebar"
900
+ msgstr ""
901
+
902
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:28
903
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:42
904
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:45
905
+ msgid "No sidebar"
906
+ msgstr ""
907
+
908
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:28
909
+ msgid "No sideabr"
910
+ msgstr ""
911
+
912
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:31
913
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:39
914
+ msgid "Right sidebar"
915
+ msgstr ""
916
+
917
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:34
918
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:53
919
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:64
920
+ msgid "Choose a sidebar"
921
+ msgstr ""
922
+
923
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:51
924
+ msgid "Sidebar Left"
925
+ msgstr ""
926
+
927
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:62
928
+ msgid "Sidebar Right"
929
+ msgstr ""
930
+
931
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:42
932
  msgid "px"
933
  msgstr ""
934
 
935
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:43
936
  msgid "em"
937
  msgstr ""
938
 
939
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:44
940
  msgid "pt"
941
  msgstr ""
942
 
943
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:45
944
  msgid "rem"
945
  msgstr ""
946
 
947
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:59
948
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:153
949
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:217
950
+ msgid "Web fonts"
951
  msgstr ""
952
 
953
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:71
954
+ msgid "Google fonts"
955
+ msgstr ""
956
+
957
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:96
958
  msgid "Regular"
959
  msgstr ""
960
 
961
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:97
962
  msgid "Bold"
963
  msgstr ""
964
 
965
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:98
966
  msgid "Extra bold"
967
  msgstr ""
968
 
969
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:99
970
  msgid "Italic"
971
  msgstr ""
972
 
973
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:100
974
  msgid "Italic bold"
975
  msgstr ""
976
 
977
+ #: ../plugin-options/settings-options.php:21
978
+ msgid "Upgrade to the PREMIUM VERSION"
979
+ msgstr ""
980
+
981
+ #: ../plugin-options/settings-options.php:25
982
+ msgid "Discovery the Advanced Features"
983
+ msgstr ""
984
+
985
+ #: ../plugin-options/settings-options.php:26
986
+ msgid ""
987
+ "Upgrade to the PREMIUM VERSION\n"
988
+ "of YITH WOOCOMMERCE AJAX SEARCH to benefit from all features!"
989
+ msgstr ""
990
+
991
+ #: ../plugin-options/settings-options.php:32
992
+ msgid "Get Support and Pro Features"
993
+ msgstr ""
994
+
995
+ #: ../plugin-options/settings-options.php:33
996
+ msgid ""
997
+ "Purchasing the premium version of the plugin, you will take advantage of the "
998
+ "advanced features of the product and you will get one year of free updates "
999
+ "and support through our platform available 24h/24."
1000
+ msgstr ""
1001
+
1002
+ #: ../plugin-options/settings-options.php:43
1003
+ msgid "General settings"
1004
+ msgstr ""
1005
+
1006
+ #: ../plugin-options/settings-options.php:52
1007
+ msgid "Search input label"
1008
+ msgstr ""
1009
+
1010
+ #: ../plugin-options/settings-options.php:54
1011
+ #: ../plugin-options/settings-options.php:62
1012
+ msgid "Label for Search input field."
1013
+ msgstr ""
1014
+
1015
+ #: ../plugin-options/settings-options.php:56
1016
+ msgid "Search for products"
1017
+ msgstr ""
1018
+
1019
+ #: ../plugin-options/settings-options.php:60
1020
+ msgid "Search submit label"
1021
+ msgstr ""
1022
+
1023
+ #: ../plugin-options/settings-options.php:64
1024
+ msgid "Search"
1025
+ msgstr ""
1026
+
1027
+ #: ../plugin-options/settings-options.php:68
1028
+ msgid "Minimum number of characters"
1029
+ msgstr ""
1030
+
1031
+ #: ../plugin-options/settings-options.php:69
1032
+ msgid "Minimum number of characters required to trigger autosuggest."
1033
+ msgstr ""
1034
+
1035
+ #: ../plugin-options/settings-options.php:82
1036
+ msgid "Maximum number of results"
1037
+ msgstr ""
1038
+
1039
+ #: ../plugin-options/settings-options.php:83
1040
+ msgid "Maximum number of results showed within the autosuggest box."
1041
+ msgstr ""
1042
+
1043
+ #: ../templates/yith-woocommerce-ajax-search.php:20
1044
+ msgid "Search for:"
1045
+ msgstr ""
1046
+
1047
+ #: ../widgets/class.yith-wcas-ajax-search.php:29
1048
+ msgid "An Ajax Search box for products only."
1049
+ msgstr ""
1050
+
1051
+ #: ../widgets/class.yith-wcas-ajax-search.php:31
1052
+ msgid "YITH WooCommerce Ajax Product Search"
1053
+ msgstr ""
1054
+
1055
+ #: ../widgets/class.yith-wcas-ajax-search.php:90
1056
+ msgid "Title:"
1057
  msgstr ""
languages/yit-it_IT.mo CHANGED
Binary file
languages/yit-it_IT.po CHANGED
@@ -1,10 +1,11 @@
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: YITH WooCommerce Ajax Search\n"
4
- "POT-Creation-Date: 2013-07-29 18:44+0100\n"
5
- "PO-Revision-Date: 2013-07-29 18:55+0100\n"
6
  "Last-Translator: \n"
7
- "Language-Team: Your Inspiration Themes <plugins@yithemes.com>\n"
 
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -13,138 +14,1072 @@ msgstr ""
13
  "X-Poedit-Basepath: ./\n"
14
  "X-Poedit-SearchPath-0: ..\n"
15
 
16
- #: ../class.yith-wcas-admin.php:124
 
 
 
 
 
 
 
 
 
 
 
 
17
  msgid "Ajax Search"
18
  msgstr "Ajax Search"
19
 
20
- #: ../class.yith-wcas-admin.php:173 ../class.yith-wcas-admin.php:213
21
- msgid "General Settings"
22
- msgstr "Impostazioni Generali"
 
23
 
24
- #: ../class.yith-wcas-admin.php:220
25
- msgid "Search input label"
26
- msgstr "Etichetta campo di ricerca"
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  #: ../class.yith-wcas-admin.php:221
29
- msgid "Label for Search input field."
30
- msgstr "Etichetta per il campo di ricerca"
 
31
 
32
- #: ../class.yith-wcas-admin.php:223 ../class.yith-wcas-admin.php:224
33
- msgid "Search for products"
34
- msgstr "Cerca prodotto"
 
 
 
 
 
 
35
 
36
- #: ../class.yith-wcas-admin.php:230
37
- msgid "Search submit label"
38
- msgstr "Etichetta campo di submit"
39
 
40
- #: ../class.yith-wcas-admin.php:231
41
- msgid "Label for Search submit field."
42
- msgstr "Etichetta per il campo di submit"
 
 
43
 
44
- #: ../class.yith-wcas-admin.php:233 ../class.yith-wcas-admin.php:234
45
- msgid "Search"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  msgstr "Cerca"
47
 
48
- #: ../class.yith-wcas-admin.php:240
49
- msgid "Minimum number of characters"
50
- msgstr "Numero minimo di caratteri"
 
 
51
 
52
- #: ../class.yith-wcas-admin.php:241
53
- msgid "Minimum number of characters required to trigger autosuggest."
54
- msgstr "Numero minimo di caratteri richiesti per avviare la ricerca"
 
 
55
 
56
- #: ../class.yith-wcas-admin.php:256
57
- msgid "Maximum number of results"
58
- msgstr "Numero massimo di risultati"
 
59
 
60
- #: ../class.yith-wcas-admin.php:257
61
- msgid "Maximum number of results showed within the autosuggest box."
62
- msgstr "Numero massimo di risultati mostrati nel box di ricerca"
 
63
 
64
- #: ../class.yith-wcas-admin.php:430
65
- msgid "Settings"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  msgstr "Impostazioni"
67
 
68
- #: ../class.yith-wcas-admin.php:431
69
- msgid "Docs"
70
- msgstr "Documentazione"
71
 
72
- #: ../class.yith-wcas.php:137
73
- msgid "No results"
74
- msgstr "Nessun risultato"
75
 
76
- #: ../templates/yith-woocommerce-ajax-search.php:20
77
- msgid "Search for:"
78
- msgstr "Cerca:"
79
 
80
- #: ../widgets/class.yith-wcas-ajax-search.php:29
81
- msgid "An Ajax Search box for products only."
82
- msgstr "Un filtro di ricerca Ajax per i prodotti di WooCommmerce."
83
 
84
- #: ../widgets/class.yith-wcas-ajax-search.php:31
85
- msgid "YITH WooCommerce Ajax Product Search"
86
- msgstr "YITH WooCommerce Ajax Product Search"
87
 
88
- #: ../widgets/class.yith-wcas-ajax-search.php:90
89
- msgid "Title:"
90
- msgstr "Titolo:"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
 
92
- #: ../yit-common/yith-panel.php:396
93
- msgid "Select a date"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  msgstr "Seleziona una data"
95
 
96
- #: ../yit-common/yith-panel.php:397
97
- msgid "Hours"
98
- msgstr "Ore"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
- #: ../yit-common/yith-panel.php:398 ../yit-common/yith-panel.php:399
101
- msgid "Minutes"
102
- msgstr "Minuti"
 
103
 
104
- #: ../yit-common/yith-panel.php:407
 
 
 
 
 
 
105
  msgid "Upload"
106
  msgstr "Upload"
107
 
108
- #: ../yit-common/yith-panel.php:434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  msgid "px"
110
  msgstr "px"
111
 
112
- #: ../yit-common/yith-panel.php:435
113
  msgid "em"
114
  msgstr "em"
115
 
116
- #: ../yit-common/yith-panel.php:436
117
  msgid "pt"
118
  msgstr "pt"
119
 
120
- #: ../yit-common/yith-panel.php:437
121
  msgid "rem"
122
  msgstr "rem"
123
 
124
- #: ../yit-common/yith-panel.php:447
125
- msgid "Select a font family"
126
- msgstr "Seleziona un font"
 
 
 
 
 
 
127
 
128
- #: ../yit-common/yith-panel.php:455
129
  msgid "Regular"
130
  msgstr "Regular"
131
 
132
- #: ../yit-common/yith-panel.php:456
133
  msgid "Bold"
134
  msgstr "Bold"
135
 
136
- #: ../yit-common/yith-panel.php:457
137
  msgid "Extra bold"
138
  msgstr "Extra bold"
139
 
140
- #: ../yit-common/yith-panel.php:458
141
  msgid "Italic"
142
  msgstr "Italic"
143
 
144
- #: ../yit-common/yith-panel.php:459
145
  msgid "Italic bold"
146
  msgstr "Italic bold"
147
 
148
- #: ../yit-common/yith-panel.php:471
149
- msgid "Click to preview"
150
- msgstr "Clicca per anteprima"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  msgid ""
2
  msgstr ""
3
  "Project-Id-Version: YITH WooCommerce Ajax Search\n"
4
+ "POT-Creation-Date: 2015-01-29 15:45+0100\n"
5
+ "PO-Revision-Date: 2015-01-29 15:45+0100\n"
6
  "Last-Translator: \n"
7
+ "Language-Team: Yithemes <plugins@yithemes.com>\n"
8
+ "Language: it_IT\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
14
  "X-Poedit-Basepath: ./\n"
15
  "X-Poedit-SearchPath-0: ..\n"
16
 
17
+ #: ../class.yith-wcas-admin.php:106 ../class.yith-wcas-admin.php:128
18
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1048
19
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1196
20
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1202
21
+ #: ../plugin-fw/lib/yit-plugin-panel.php:62
22
+ msgid "Settings"
23
+ msgstr "Impostazioni"
24
+
25
+ #: ../class.yith-wcas-admin.php:107 ../class.yith-wcas-admin.php:129
26
+ msgid "Premium Version"
27
+ msgstr ""
28
+
29
+ #: ../class.yith-wcas-admin.php:135 ../class.yith-wcas-admin.php:136
30
  msgid "Ajax Search"
31
  msgstr "Ajax Search"
32
 
33
+ #: ../class.yith-wcas-admin.php:190
34
+ #, fuzzy
35
+ msgid "Plugin Documentation"
36
+ msgstr "Impostazioni"
37
 
38
+ #: ../class.yith-wcas-admin.php:207 ../plugin-options/settings-options.php:24
39
+ #, fuzzy
40
+ msgid "YITH WooCommerce Ajax Search"
41
+ msgstr "YITH WooCommerce Ajax Product Search"
42
+
43
+ #: ../class.yith-wcas-admin.php:208
44
+ msgid ""
45
+ "In the YIT Plugin tab you can find the YITH WooCommerce Ajax Search "
46
+ "options.\n"
47
+ "With this menu, you can access to all the settings of our plugins that you "
48
+ "have activated.\n"
49
+ "YITH WooCommerce Ajax Search is available in an outstanding PREMIUM version "
50
+ "with many new options, <a href=\""
51
+ msgstr ""
52
 
53
  #: ../class.yith-wcas-admin.php:221
54
+ #, fuzzy
55
+ msgid "YITH WooCommerce Ajax Search Updated"
56
+ msgstr "YITH WooCommerce Ajax Product Search"
57
 
58
+ #: ../class.yith-wcas-admin.php:222
59
+ msgid ""
60
+ "From now on, you can find all the options of YITH WooCommerce Ajax Search "
61
+ "Updated under YIT Plugin -> Ajax Search instead of WooCommerce -> Settings -"
62
+ "> Ajax Search, as in the previous version.\n"
63
+ "When one of our plugins updates, a new voice will be added to this menu.\n"
64
+ "YITH WooCommerce Ajax Search renovates with new available options, discover "
65
+ "the <a href=\""
66
+ msgstr ""
67
 
68
+ #: ../class.yith-wcas.php:168
69
+ msgid "No results"
70
+ msgstr "Nessun risultato"
71
 
72
+ #: ../init.php:38
73
+ msgid ""
74
+ "YITH WooCommerce Ajax Search is enabled but not effective. It requires "
75
+ "Woocommerce in order to work."
76
+ msgstr ""
77
 
78
+ #: ../init.php:51
79
+ msgid ""
80
+ "You can't activate the free version of YITH WooCommerce Ajax Search while "
81
+ "you are using the premium one."
82
+ msgstr ""
83
+
84
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:460
85
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:574
86
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:719
87
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1632
88
+ #, php-format
89
+ msgid "Add %s"
90
+ msgstr ""
91
+
92
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:461
93
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:575
94
+ #, php-format
95
+ msgid "Add New %s"
96
+ msgstr ""
97
+
98
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:462
99
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:576
100
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1267
101
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1304
102
+ #, php-format
103
+ msgid "Edit %s"
104
+ msgstr ""
105
+
106
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:463
107
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:577
108
+ #, php-format
109
+ msgid "New %s"
110
+ msgstr ""
111
+
112
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:464
113
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:578
114
+ #, php-format
115
+ msgid "All %s"
116
+ msgstr ""
117
+
118
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:465
119
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:579
120
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1251
121
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1305
122
+ #, php-format
123
+ msgid "View %s"
124
+ msgstr ""
125
+
126
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:466
127
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:580
128
+ #, fuzzy, php-format
129
+ msgid "Search %s"
130
  msgstr "Cerca"
131
 
132
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:467
133
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:581
134
+ #, php-format
135
+ msgid "No %s found"
136
+ msgstr ""
137
 
138
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:468
139
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:582
140
+ #, php-format
141
+ msgid "No %s found in Trash"
142
+ msgstr ""
143
 
144
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:625
145
+ #, php-format
146
+ msgid "%s Categories"
147
+ msgstr ""
148
 
149
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:626
150
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:635
151
+ msgid "Category"
152
+ msgstr ""
153
 
154
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:627
155
+ #, fuzzy
156
+ msgid "Search Categories"
157
+ msgstr "Cerca:"
158
+
159
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:628
160
+ msgid "All Categories"
161
+ msgstr ""
162
+
163
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:629
164
+ msgid "Parent Category"
165
+ msgstr ""
166
+
167
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:630
168
+ msgid "Parent Category:"
169
+ msgstr ""
170
+
171
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:631
172
+ msgid "Edit Category"
173
+ msgstr ""
174
+
175
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:632
176
+ msgid "Update Category"
177
+ msgstr ""
178
+
179
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:633
180
+ msgid "Add New Category"
181
+ msgstr ""
182
+
183
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:634
184
+ msgid "New Category Name"
185
+ msgstr ""
186
+
187
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:724
188
+ msgid "Categories"
189
+ msgstr ""
190
+
191
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1042
192
+ #, fuzzy, php-format
193
+ msgid "%s Settings"
194
  msgstr "Impostazioni"
195
 
196
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1051
197
+ msgid "Type"
198
+ msgstr ""
199
 
200
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1052
201
+ msgid "The layout for this "
202
+ msgstr ""
203
 
204
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1058
205
+ msgid "Rewrite"
206
+ msgstr ""
207
 
208
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1059
209
+ msgid "The word used for the URL of each project (the slug of post if empty)"
210
+ msgstr ""
211
 
212
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1064
213
+ msgid "Label Singular"
214
+ msgstr ""
215
 
216
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1065
217
+ msgid ""
218
+ "Set the label in singular to use for each label (the title of portfolio if "
219
+ "empty)"
220
+ msgstr ""
221
+
222
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1070
223
+ msgid "Label Plural"
224
+ msgstr ""
225
+
226
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1071
227
+ msgid ""
228
+ "Set the label in plural to use for each label (the title of portfolio if "
229
+ "empty)"
230
+ msgstr ""
231
+
232
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1076
233
+ msgid "Taxonomy"
234
+ msgstr ""
235
+
236
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1077
237
+ msgid ""
238
+ "If you want to use a category section for the portfolio, set the name of "
239
+ "taxonomy. Name should be in slug form (must not contain capital letters or "
240
+ "spaces) and not more than 32 characters long (database structure "
241
+ "restriction)."
242
+ msgstr ""
243
+
244
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1082
245
+ msgid "Taxonomy Rewrite"
246
+ msgstr ""
247
+
248
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1083
249
+ msgid "Set the word to use in the URL for each category page."
250
+ msgstr ""
251
+
252
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1088
253
+ msgid "Single layout"
254
+ msgstr ""
255
+
256
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1089
257
+ msgid "The layout for single page of this portfolio"
258
+ msgstr ""
259
+
260
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1130
261
+ #, fuzzy
262
+ msgid "layout settings"
263
+ msgstr "Impostazioni"
264
 
265
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1222
266
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1235
267
+ msgid "Quick links"
268
+ msgstr ""
269
+
270
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1475
271
+ #, php-format
272
+ msgid "Show the frontend of the %s"
273
+ msgstr ""
274
+
275
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1482
276
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:46
277
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:90
278
+ msgid "Name"
279
+ msgstr ""
280
+
281
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1631
282
+ #, php-format
283
+ msgid "Add %s by images"
284
+ msgstr ""
285
+
286
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1633
287
+ msgid "Add with multiupload"
288
+ msgstr ""
289
+
290
+ #: ../plugin-fw/lib/yit-plugin-panel-wc.php:302
291
+ msgid "The changes you made will be lost if you navigate away from this page."
292
+ msgstr ""
293
+
294
+ #: ../plugin-fw/lib/yit-plugin-panel.php:61
295
+ #, fuzzy
296
+ msgid "Plugin Settings"
297
+ msgstr "Impostazioni"
298
+
299
+ #: ../plugin-fw/lib/yit-plugin-panel.php:92
300
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:101
301
+ msgid "YIT Plugins"
302
+ msgstr ""
303
+
304
+ #: ../plugin-fw/lib/yit-plugin-panel.php:269
305
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:142
306
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:5
307
+ msgid "Save Changes"
308
+ msgstr ""
309
+
310
+ #: ../plugin-fw/lib/yit-plugin-panel.php:272
311
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:145
312
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:8
313
+ msgid ""
314
+ "If you continue with this action, you will reset all options are in this "
315
+ "page."
316
+ msgstr ""
317
+
318
+ #: ../plugin-fw/lib/yit-plugin-panel.php:274
319
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:147
320
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:10
321
+ msgid "Reset Defaults"
322
+ msgstr ""
323
+
324
+ #: ../plugin-fw/lib/yit-plugin-panel.php:274
325
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:147
326
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:10
327
+ msgid "Are you sure of it?"
328
+ msgstr ""
329
+
330
+ #: ../plugin-fw/lib/yit-plugin-panel.php:408
331
+ msgid ""
332
+ "The element you have written is already exists. Please, add another name."
333
+ msgstr ""
334
+
335
+ #: ../plugin-fw/lib/yit-plugin-panel.php:409
336
+ #, fuzzy
337
+ msgid "Settings saved"
338
+ msgstr "Impostazioni"
339
+
340
+ #: ../plugin-fw/lib/yit-plugin-panel.php:410
341
+ #, fuzzy
342
+ msgid "Settings reset"
343
+ msgstr "Impostazioni"
344
+
345
+ #: ../plugin-fw/lib/yit-plugin-panel.php:411
346
+ msgid "Element deleted correctly."
347
+ msgstr ""
348
+
349
+ #: ../plugin-fw/lib/yit-plugin-panel.php:412
350
+ #: ../plugin-fw/lib/yit-plugin-panel.php:413
351
+ msgid "Element updated correctly."
352
+ msgstr ""
353
+
354
+ #: ../plugin-fw/lib/yit-plugin-panel.php:414
355
+ msgid "Database imported correctly."
356
+ msgstr ""
357
+
358
+ #: ../plugin-fw/lib/yit-plugin-panel.php:415
359
+ msgid "An error encoured during during import. Please try again."
360
+ msgstr ""
361
+
362
+ #: ../plugin-fw/lib/yit-plugin-panel.php:416
363
+ msgid "The file you have insert doesn't valid."
364
+ msgstr ""
365
+
366
+ #: ../plugin-fw/lib/yit-plugin-panel.php:417
367
+ msgid "I'm sorry, the import featured is disabled."
368
+ msgstr ""
369
+
370
+ #: ../plugin-fw/lib/yit-plugin-panel.php:418
371
+ msgid "Sorting done correctly."
372
+ msgstr ""
373
+
374
+ #: ../plugin-fw/lib/yit-pointers.php:70
375
+ msgid "Plugins Activated"
376
+ msgstr ""
377
+
378
+ #: ../plugin-fw/lib/yit-pointers.php:71
379
+ msgid ""
380
+ "From now on, you can find all the options of your plugins under the YIT "
381
+ "Plugin menu voice.\n"
382
+ " For every installation of our new "
383
+ "plugins, a new voice will be added to access to the customization settings."
384
+ msgstr ""
385
+
386
+ #: ../plugin-fw/lib/yit-pointers.php:73 ../plugin-fw/lib/yit-pointers.php:89
387
+ msgid "Discover all our plugins available on:"
388
+ msgstr ""
389
+
390
+ #: ../plugin-fw/lib/yit-pointers.php:74 ../plugin-fw/lib/yit-pointers.php:90
391
+ msgid "and"
392
+ msgstr ""
393
+
394
+ #: ../plugin-fw/lib/yit-pointers.php:84
395
+ msgid "Plugins Upgraded"
396
+ msgstr ""
397
+
398
+ #: ../plugin-fw/lib/yit-pointers.php:85
399
+ msgid ""
400
+ "From now on, you can find all the options of your plugins under the YIT "
401
+ "Plugin menu voice.\n"
402
+ " When one of our plugins updates, a new "
403
+ "voice will be added to this menu.\n"
404
+ " For example, after the update, the "
405
+ "options from the plugins (YITH WooCommerce Wishlist, YITH WooCommerce Ajax "
406
+ "Search, etc.)\n"
407
+ " will be removed from the previous "
408
+ "location and moved under the YIT Plugin tab."
409
+ msgstr ""
410
+
411
+ #: ../plugin-fw/lib/yit-upgrade.php:120
412
+ msgid "There is a new version of %plugin_name% available."
413
+ msgstr ""
414
+
415
+ #: ../plugin-fw/lib/yit-upgrade.php:121
416
+ msgid "View version %latest% details."
417
+ msgstr ""
418
+
419
+ #: ../plugin-fw/lib/yit-upgrade.php:122
420
+ msgid "Automatic update is unavailable for this plugin,"
421
+ msgstr ""
422
+
423
+ #: ../plugin-fw/lib/yit-upgrade.php:123
424
+ msgid ""
425
+ "please <a href=\"%activate_link%\"> activate </a> your copy of %plugin_name%."
426
+ msgstr ""
427
+
428
+ #: ../plugin-fw/lib/yit-upgrade.php:124
429
+ msgid "Update now."
430
+ msgstr ""
431
+
432
+ #: ../plugin-fw/lib/yit-upgrade.php:220
433
+ msgid "Yithemes Repository"
434
+ msgstr ""
435
+
436
+ #: ../plugin-fw/lib/yit-upgrade.php:254
437
+ msgid "Invalid URL Provided."
438
+ msgstr ""
439
+
440
+ #: ../plugin-fw/lib/yit-upgrade.php:267
441
+ msgid "Could not create Temporary file."
442
+ msgstr ""
443
+
444
+ #: ../plugin-fw/lib/yit-upgrade.php:408
445
+ #, php-format
446
+ msgid ""
447
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
448
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>."
449
+ msgstr ""
450
+
451
+ #: ../plugin-fw/lib/yit-upgrade.php:410
452
+ #, php-format
453
+ msgid ""
454
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
455
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>. <em>You "
456
+ "have to activate the plugin on a single site of the network to benefit from "
457
+ "the automatic updates.</em>"
458
+ msgstr ""
459
+
460
+ #: ../plugin-fw/lib/yit-upgrade.php:412
461
+ #, php-format
462
+ msgid ""
463
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
464
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>. "
465
+ "<em>Automatic update is unavailable for this plugin, please <a href=\"%5$s\" "
466
+ "title=\"Licence activation\">activate</a> your copy of %6s.</em>"
467
+ msgstr ""
468
+
469
+ #: ../plugin-fw/lib/yit-upgrade.php:414
470
+ #, php-format
471
+ msgid ""
472
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
473
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a> or <a "
474
+ "href=\"%5$s\">update now</a>."
475
+ msgstr ""
476
+
477
+ #: ../plugin-fw/lib/yit-upgrade.php:487
478
+ msgid "You can't update plugins for this site."
479
+ msgstr ""
480
+
481
+ #: ../plugin-fw/lib/yit-upgrade.php:491
482
+ msgid "You do not have sufficient permissions to update plugins for this site."
483
+ msgstr ""
484
+
485
+ #: ../plugin-fw/lib/yit-upgrade.php:498
486
+ msgid "Update Plugin"
487
+ msgstr ""
488
+
489
+ #: ../plugin-fw/licence/lib/yit-licence.php:154
490
+ #, php-format
491
+ msgid "%field% field can not be empty"
492
+ msgstr ""
493
+
494
+ #: ../plugin-fw/licence/lib/yit-licence.php:155
495
+ msgid "%field_1% and %field_2% fields can not be empty"
496
+ msgstr ""
497
+
498
+ #: ../plugin-fw/licence/lib/yit-licence.php:156
499
+ msgid "Unable to contact the remote server, please try again later. Thanks!"
500
+ msgstr ""
501
+
502
+ #: ../plugin-fw/licence/lib/yit-licence.php:538
503
+ msgid "Invalid Request"
504
+ msgstr ""
505
+
506
+ #: ../plugin-fw/licence/lib/yit-licence.php:539
507
+ msgid "Invalid licence key"
508
+ msgstr ""
509
+
510
+ #: ../plugin-fw/licence/lib/yit-licence.php:540
511
+ msgid "Software has been deactive"
512
+ msgstr ""
513
+
514
+ #: ../plugin-fw/licence/lib/yit-licence.php:541
515
+ #, fuzzy
516
+ msgid "Exceeded maximum number of activations"
517
+ msgstr "Numero massimo di risultati"
518
+
519
+ #: ../plugin-fw/licence/lib/yit-licence.php:542
520
+ msgid "Invalid instance ID"
521
+ msgstr ""
522
+
523
+ #: ../plugin-fw/licence/lib/yit-licence.php:543
524
+ msgid "Invalid security key"
525
+ msgstr ""
526
+
527
+ #: ../plugin-fw/licence/lib/yit-licence.php:544
528
+ msgid "Licence key has expired"
529
+ msgstr ""
530
+
531
+ #: ../plugin-fw/licence/lib/yit-licence.php:545
532
+ msgid "Licence key has be banned"
533
+ msgstr ""
534
+
535
+ #: ../plugin-fw/licence/lib/yit-plugin-licence.php:63
536
+ #: ../plugin-fw/licence/lib/yit-plugin-licence.php:64
537
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:63
538
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:64
539
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:106
540
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:107
541
+ msgid "Licence Activation"
542
+ msgstr ""
543
+
544
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:114
545
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:115
546
+ #, php-format
547
+ msgid "%s"
548
+ msgstr ""
549
+
550
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:25
551
+ msgid "Yithemes Licence Activation"
552
+ msgstr ""
553
+
554
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:29
555
+ msgid ""
556
+ "Have you updated your licenses? Have you asked for an extension? Update "
557
+ "information concerning your products."
558
+ msgstr ""
559
+
560
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:31
561
+ msgid "Update licence information"
562
+ msgstr ""
563
+
564
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:41
565
+ msgid "To Active"
566
+ msgstr ""
567
+
568
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:60
569
+ msgid "Activate"
570
+ msgstr ""
571
+
572
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:79
573
+ msgid "Activated"
574
+ msgstr ""
575
+
576
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:83
577
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:114
578
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:138
579
+ msgid "Product Name"
580
+ msgstr ""
581
+
582
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:84
583
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:115
584
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:139
585
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:145
586
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:337
587
+ msgid "Email"
588
+ msgstr ""
589
+
590
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:85
591
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:116
592
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:140
593
+ msgid "Licence Key"
594
+ msgstr ""
595
+
596
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:86
597
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:141
598
+ msgid "Expires"
599
+ msgstr ""
600
+
601
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:87
602
+ msgid "Remaining"
603
+ msgstr ""
604
+
605
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:88
606
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:101
607
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:142
608
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:152
609
+ msgid "Renew"
610
+ msgstr ""
611
+
612
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:99
613
+ #, php-format
614
+ msgid "%1s out of %2s"
615
+ msgstr ""
616
+
617
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:110
618
+ msgid "Banned"
619
+ msgstr ""
620
+
621
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:134
622
+ msgid "Expired"
623
+ msgstr ""
624
+
625
+ #: ../plugin-fw/templates/metaboxes/types/categories.php:36
626
+ msgid "No categories."
627
+ msgstr ""
628
+
629
+ #: ../plugin-fw/templates/metaboxes/types/categories.php:42
630
+ msgid "+ Add New Category"
631
+ msgstr ""
632
+
633
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:5
634
+ msgid "Text Input"
635
+ msgstr ""
636
+
637
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:6
638
+ msgid "Checkbox"
639
+ msgstr ""
640
+
641
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:7
642
+ #, fuzzy
643
+ msgid "Select"
644
+ msgstr "Seleziona una data"
645
+
646
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:8
647
+ msgid "Textarea"
648
+ msgstr ""
649
+
650
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:9
651
+ msgid "Radio Input"
652
+ msgstr ""
653
+
654
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:10
655
+ msgid "Password Field"
656
+ msgstr ""
657
+
658
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:11
659
+ #, fuzzy
660
+ msgid "File Upload"
661
+ msgstr "Upload"
662
+
663
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:45
664
+ msgid "Theme Icon"
665
+ msgstr ""
666
+
667
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:46
668
+ msgid "Custom Icon"
669
+ msgstr ""
670
+
671
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:47
672
+ #: ../plugin-fw/templates/metaboxes/types/responsivesliders.php:24
673
+ msgid "None"
674
+ msgstr ""
675
+
676
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:57
677
+ msgid "Add field"
678
+ msgstr ""
679
+
680
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:66
681
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:258
682
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:37
683
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:82
684
+ msgid "Remove"
685
+ msgstr ""
686
+
687
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:67
688
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:259
689
+ #, fuzzy
690
+ msgid "Click to toggle"
691
+ msgstr "Clicca per anteprima"
692
+
693
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:74
694
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:266
695
+ msgid "Title Field"
696
+ msgstr ""
697
+
698
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:78
699
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:270
700
+ msgid "Insert the title of field."
701
+ msgstr ""
702
+
703
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:83
704
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:275
705
+ msgid "Data Name"
706
+ msgstr ""
707
+
708
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:87
709
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:279
710
+ msgid ""
711
+ "REQUIRED: The identification name of this field, that you can insert into "
712
+ "body email configuration. <strong>Note:</strong>Use only lowercase "
713
+ "characters and underscores."
714
+ msgstr ""
715
+
716
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:92
717
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:284
718
+ msgid "Type field"
719
+ msgstr ""
720
+
721
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:100
722
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:292
723
+ msgid "Select the type of this field."
724
+ msgstr ""
725
+
726
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:105
727
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:297
728
+ msgid "Checked"
729
+ msgstr ""
730
+
731
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:109
732
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:301
733
+ msgid "Select this if you want this field already checked."
734
+ msgstr ""
735
+
736
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:114
737
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:306
738
+ msgid "Add options "
739
+ msgstr ""
740
+
741
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:115
742
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:307
743
+ msgid "Add option"
744
+ msgstr ""
745
+
746
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:118
747
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:310
748
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:432
749
+ #, fuzzy
750
+ msgid "Selected"
751
  msgstr "Seleziona una data"
752
 
753
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:121
754
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:313
755
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:432
756
+ msgid "Delete option"
757
+ msgstr ""
758
+
759
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:127
760
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:319
761
+ msgid "Message Error"
762
+ msgstr ""
763
+
764
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:131
765
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:323
766
+ msgid "Insert the error message for validation."
767
+ msgstr ""
768
+
769
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:136
770
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:328
771
+ msgid "Required"
772
+ msgstr ""
773
+
774
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:140
775
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:332
776
+ msgid "Select this if it must be required."
777
+ msgstr ""
778
+
779
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:149
780
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:341
781
+ msgid "Select this if it must be a valid email."
782
+ msgstr ""
783
+
784
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:154
785
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:346
786
+ msgid "Reply To"
787
+ msgstr ""
788
+
789
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:158
790
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:350
791
+ msgid "Select this if it's the email where you can reply."
792
+ msgstr ""
793
+
794
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:163
795
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:355
796
+ msgid "Class"
797
+ msgstr ""
798
+
799
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:167
800
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:359
801
+ msgid ""
802
+ "Insert an additional class(es) (separateb by comma) for more personalization."
803
+ msgstr ""
804
 
805
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:172
806
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:364
807
+ msgid "Icon"
808
+ msgstr ""
809
 
810
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:200
811
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:388
812
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:69
813
+ #: ../plugin-fw/templates/metaboxes/types/select-icon.php:33
814
+ #: ../plugin-fw/templates/metaboxes/types/upload.php:21
815
+ #: ../plugin-fw/templates/panel/types/upload.php:31
816
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-upload.php:35
817
  msgid "Upload"
818
  msgstr "Upload"
819
 
820
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:206
821
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:394
822
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:75
823
+ #: ../plugin-fw/templates/metaboxes/types/select-icon.php:39
824
+ msgid "Image preview"
825
+ msgstr ""
826
+
827
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:214
828
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:402
829
+ msgid "Insert an icon for more personalization."
830
+ msgstr ""
831
+
832
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:219
833
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:406
834
+ msgid "Width"
835
+ msgstr ""
836
+
837
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:244
838
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:418
839
+ msgid "Choose how much long will be the field."
840
+ msgstr ""
841
+
842
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:28
843
+ msgid "Close all"
844
+ msgstr ""
845
+
846
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:28
847
+ msgid "Expand all"
848
+ msgstr ""
849
+
850
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:52
851
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:95
852
+ msgid "Value"
853
+ msgstr ""
854
+
855
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:53
856
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:96
857
+ msgid "The content of the tab. (HTML is supported)"
858
+ msgstr ""
859
+
860
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:65
861
+ msgid "Add custom product tab"
862
+ msgstr ""
863
+
864
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:107
865
+ msgid "Do you want to remove the custom tab?"
866
+ msgstr ""
867
+
868
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:89
869
+ #, php-format
870
+ msgid "(Default: %s <img src=\"%s\"/>)"
871
+ msgstr ""
872
+
873
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:91
874
+ #, php-format
875
+ msgid "(Default: <i %s></i> )"
876
+ msgstr ""
877
+
878
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:35
879
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
880
+ #: ../plugin-fw/templates/metaboxes/types/images.php:33
881
+ #: ../plugin-fw/templates/metaboxes/types/images.php:59
882
+ msgid "Delete image"
883
+ msgstr ""
884
+
885
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
886
+ msgid "Add Images to Gallery"
887
+ msgstr ""
888
+
889
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
890
+ msgid "Add to gallery"
891
+ msgstr ""
892
+
893
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
894
+ msgid "Add images"
895
+ msgstr ""
896
+
897
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
898
+ msgid "Delete"
899
+ msgstr ""
900
+
901
+ #: ../plugin-fw/templates/metaboxes/types/images.php:37
902
+ msgid "Upload new images"
903
+ msgstr ""
904
+
905
+ #: ../plugin-fw/templates/metaboxes/types/images.php:70
906
+ msgid "Are you sure you want to remove this image?"
907
+ msgstr ""
908
+
909
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:25
910
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:36
911
+ msgid "Left sidebar"
912
+ msgstr ""
913
+
914
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:28
915
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:42
916
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:45
917
+ msgid "No sidebar"
918
+ msgstr ""
919
+
920
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:28
921
+ msgid "No sideabr"
922
+ msgstr ""
923
+
924
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:31
925
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:39
926
+ msgid "Right sidebar"
927
+ msgstr ""
928
+
929
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:34
930
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:53
931
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:64
932
+ msgid "Choose a sidebar"
933
+ msgstr ""
934
+
935
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:51
936
+ msgid "Sidebar Left"
937
+ msgstr ""
938
+
939
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:62
940
+ msgid "Sidebar Right"
941
+ msgstr ""
942
+
943
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:42
944
  msgid "px"
945
  msgstr "px"
946
 
947
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:43
948
  msgid "em"
949
  msgstr "em"
950
 
951
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:44
952
  msgid "pt"
953
  msgstr "pt"
954
 
955
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:45
956
  msgid "rem"
957
  msgstr "rem"
958
 
959
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:59
960
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:153
961
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:217
962
+ msgid "Web fonts"
963
+ msgstr ""
964
+
965
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:71
966
+ msgid "Google fonts"
967
+ msgstr ""
968
 
969
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:96
970
  msgid "Regular"
971
  msgstr "Regular"
972
 
973
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:97
974
  msgid "Bold"
975
  msgstr "Bold"
976
 
977
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:98
978
  msgid "Extra bold"
979
  msgstr "Extra bold"
980
 
981
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:99
982
  msgid "Italic"
983
  msgstr "Italic"
984
 
985
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:100
986
  msgid "Italic bold"
987
  msgstr "Italic bold"
988
 
989
+ #: ../plugin-options/settings-options.php:21
990
+ msgid "Upgrade to the PREMIUM VERSION"
991
+ msgstr ""
992
+
993
+ #: ../plugin-options/settings-options.php:25
994
+ msgid "Discovery the Advanced Features"
995
+ msgstr ""
996
+
997
+ #: ../plugin-options/settings-options.php:26
998
+ msgid ""
999
+ "Upgrade to the PREMIUM VERSION\n"
1000
+ "of YITH WOOCOMMERCE AJAX SEARCH to benefit from all features!"
1001
+ msgstr ""
1002
+
1003
+ #: ../plugin-options/settings-options.php:32
1004
+ msgid "Get Support and Pro Features"
1005
+ msgstr ""
1006
+
1007
+ #: ../plugin-options/settings-options.php:33
1008
+ msgid ""
1009
+ "Purchasing the premium version of the plugin, you will take advantage of the "
1010
+ "advanced features of the product and you will get one year of free updates "
1011
+ "and support through our platform available 24h/24."
1012
+ msgstr ""
1013
+
1014
+ #: ../plugin-options/settings-options.php:43
1015
+ #, fuzzy
1016
+ msgid "General settings"
1017
+ msgstr "Impostazioni Generali"
1018
+
1019
+ #: ../plugin-options/settings-options.php:52
1020
+ msgid "Search input label"
1021
+ msgstr "Etichetta campo di ricerca"
1022
+
1023
+ #: ../plugin-options/settings-options.php:54
1024
+ #: ../plugin-options/settings-options.php:62
1025
+ msgid "Label for Search input field."
1026
+ msgstr "Etichetta per il campo di ricerca"
1027
+
1028
+ #: ../plugin-options/settings-options.php:56
1029
+ msgid "Search for products"
1030
+ msgstr "Cerca prodotto"
1031
+
1032
+ #: ../plugin-options/settings-options.php:60
1033
+ msgid "Search submit label"
1034
+ msgstr "Etichetta campo di submit"
1035
+
1036
+ #: ../plugin-options/settings-options.php:64
1037
+ msgid "Search"
1038
+ msgstr "Cerca"
1039
+
1040
+ #: ../plugin-options/settings-options.php:68
1041
+ msgid "Minimum number of characters"
1042
+ msgstr "Numero minimo di caratteri"
1043
+
1044
+ #: ../plugin-options/settings-options.php:69
1045
+ msgid "Minimum number of characters required to trigger autosuggest."
1046
+ msgstr "Numero minimo di caratteri richiesti per avviare la ricerca"
1047
+
1048
+ #: ../plugin-options/settings-options.php:82
1049
+ msgid "Maximum number of results"
1050
+ msgstr "Numero massimo di risultati"
1051
+
1052
+ #: ../plugin-options/settings-options.php:83
1053
+ msgid "Maximum number of results showed within the autosuggest box."
1054
+ msgstr "Numero massimo di risultati mostrati nel box di ricerca"
1055
+
1056
+ #: ../templates/yith-woocommerce-ajax-search.php:20
1057
+ msgid "Search for:"
1058
+ msgstr "Cerca:"
1059
+
1060
+ #: ../widgets/class.yith-wcas-ajax-search.php:29
1061
+ msgid "An Ajax Search box for products only."
1062
+ msgstr "Un filtro di ricerca Ajax per i prodotti di WooCommmerce."
1063
+
1064
+ #: ../widgets/class.yith-wcas-ajax-search.php:31
1065
+ msgid "YITH WooCommerce Ajax Product Search"
1066
+ msgstr "YITH WooCommerce Ajax Product Search"
1067
+
1068
+ #: ../widgets/class.yith-wcas-ajax-search.php:90
1069
+ msgid "Title:"
1070
+ msgstr "Titolo:"
1071
+
1072
+ #~ msgid "Label for Search submit field."
1073
+ #~ msgstr "Etichetta per il campo di submit"
1074
+
1075
+ #~ msgid "Docs"
1076
+ #~ msgstr "Documentazione"
1077
+
1078
+ #~ msgid "Hours"
1079
+ #~ msgstr "Ore"
1080
+
1081
+ #~ msgid "Minutes"
1082
+ #~ msgstr "Minuti"
1083
+
1084
+ #~ msgid "Select a font family"
1085
+ #~ msgstr "Seleziona un font"
languages/yit.pot CHANGED
@@ -1,148 +1,1057 @@
1
  msgid ""
2
  msgstr ""
3
- "Project-Id-Version: YITH WooCommerce Ajax Search\n"
4
- "POT-Creation-Date: 2013-07-29 18:57+0100\n"
5
- "PO-Revision-Date: 2013-07-29 18:58+0100\n"
6
  "Last-Translator: \n"
7
- "Language-Team: Your Inspiration Themes <plugins@yithemes.com>\n"
 
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
  "X-Generator: Poedit 1.5.5\n"
12
  "X-Poedit-KeywordsList: __;_e;_x\n"
 
 
 
13
 
14
- #: ../class.yith-wcas-admin.php:124
 
 
 
 
 
 
 
 
 
 
 
 
15
  msgid "Ajax Search"
16
  msgstr ""
17
 
18
- #: ../class.yith-wcas-admin.php:173 ../class.yith-wcas-admin.php:213
19
- msgid "General Settings"
20
  msgstr ""
21
 
22
- #: ../class.yith-wcas-admin.php:220
23
- msgid "Search input label"
 
 
 
 
 
 
 
 
 
 
24
  msgstr ""
25
 
26
  #: ../class.yith-wcas-admin.php:221
27
- msgid "Label for Search input field."
28
  msgstr ""
29
 
30
- #: ../class.yith-wcas-admin.php:223 ../class.yith-wcas-admin.php:224
31
- msgid "Search for products"
 
 
 
 
 
 
32
  msgstr ""
33
 
34
- #: ../class.yith-wcas-admin.php:230
35
- msgid "Search submit label"
36
  msgstr ""
37
 
38
- #: ../class.yith-wcas-admin.php:231
39
- msgid "Label for Search submit field."
 
 
40
  msgstr ""
41
 
42
- #: ../class.yith-wcas-admin.php:233 ../class.yith-wcas-admin.php:234
43
- msgid "Search"
 
 
44
  msgstr ""
45
 
46
- #: ../class.yith-wcas-admin.php:240
47
- msgid "Minimum number of characters"
 
 
 
 
48
  msgstr ""
49
 
50
- #: ../class.yith-wcas-admin.php:241
51
- msgid "Minimum number of characters required to trigger autosuggest."
 
 
52
  msgstr ""
53
 
54
- #: ../class.yith-wcas-admin.php:256
55
- msgid "Maximum number of results"
 
 
 
 
56
  msgstr ""
57
 
58
- #: ../class.yith-wcas-admin.php:257
59
- msgid "Maximum number of results showed within the autosuggest box."
 
 
60
  msgstr ""
61
 
62
- #: ../class.yith-wcas-admin.php:430
63
- msgid "Settings"
 
 
64
  msgstr ""
65
 
66
- #: ../class.yith-wcas-admin.php:431
67
- msgid "Docs"
 
 
 
 
68
  msgstr ""
69
 
70
- #: ../class.yith-wcas.php:137
71
- msgid "No results"
 
 
72
  msgstr ""
73
 
74
- #: ../templates/yith-woocommerce-ajax-search.php:20
75
- msgid "Search for:"
 
 
76
  msgstr ""
77
 
78
- #: ../widgets/class.yith-wcas-ajax-search.php:29
79
- msgid "An Ajax Search box for products only."
 
 
80
  msgstr ""
81
 
82
- #: ../widgets/class.yith-wcas-ajax-search.php:31
83
- msgid "YITH WooCommerce Ajax Product Search"
 
84
  msgstr ""
85
 
86
- #: ../widgets/class.yith-wcas-ajax-search.php:90
87
- msgid "Title:"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  msgstr ""
89
 
90
- #: ../yit-common/yith-panel.php:396
91
- msgid "Select a date"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  msgstr ""
93
 
94
- #: ../yit-common/yith-panel.php:397
95
- msgid "Hours"
96
  msgstr ""
97
 
98
- #: ../yit-common/yith-panel.php:398 ../yit-common/yith-panel.php:399
99
- msgid "Minutes"
100
  msgstr ""
101
 
102
- #: ../yit-common/yith-panel.php:407
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  msgid "Upload"
104
  msgstr ""
105
 
106
- #: ../yit-common/yith-panel.php:434
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  msgid "px"
108
  msgstr ""
109
 
110
- #: ../yit-common/yith-panel.php:435
111
  msgid "em"
112
  msgstr ""
113
 
114
- #: ../yit-common/yith-panel.php:436
115
  msgid "pt"
116
  msgstr ""
117
 
118
- #: ../yit-common/yith-panel.php:437
119
  msgid "rem"
120
  msgstr ""
121
 
122
- #: ../yit-common/yith-panel.php:447
123
- msgid "Select a font family"
 
 
124
  msgstr ""
125
 
126
- #: ../yit-common/yith-panel.php:455
 
 
 
 
127
  msgid "Regular"
128
  msgstr ""
129
 
130
- #: ../yit-common/yith-panel.php:456
131
  msgid "Bold"
132
  msgstr ""
133
 
134
- #: ../yit-common/yith-panel.php:457
135
  msgid "Extra bold"
136
  msgstr ""
137
 
138
- #: ../yit-common/yith-panel.php:458
139
  msgid "Italic"
140
  msgstr ""
141
 
142
- #: ../yit-common/yith-panel.php:459
143
  msgid "Italic bold"
144
  msgstr ""
145
 
146
- #: ../yit-common/yith-panel.php:471
147
- msgid "Click to preview"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  msgstr ""
1
  msgid ""
2
  msgstr ""
3
+ "Project-Id-Version: YITH WooCommerce Ajax Search Free\n"
4
+ "POT-Creation-Date: 2015-01-29 15:45+0100\n"
5
+ "PO-Revision-Date: 2015-01-29 15:45+0100\n"
6
  "Last-Translator: \n"
7
+ "Language-Team: Yithemes <plugins@yithemes.com>\n"
8
+ "Language: en\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=UTF-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
  "X-Generator: Poedit 1.5.5\n"
13
  "X-Poedit-KeywordsList: __;_e;_x\n"
14
+ "X-Poedit-Basepath: ./\n"
15
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
16
+ "X-Poedit-SearchPath-0: ..\n"
17
 
18
+ #: ../class.yith-wcas-admin.php:106 ../class.yith-wcas-admin.php:128
19
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1048
20
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1196
21
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1202
22
+ #: ../plugin-fw/lib/yit-plugin-panel.php:62
23
+ msgid "Settings"
24
+ msgstr ""
25
+
26
+ #: ../class.yith-wcas-admin.php:107 ../class.yith-wcas-admin.php:129
27
+ msgid "Premium Version"
28
+ msgstr ""
29
+
30
+ #: ../class.yith-wcas-admin.php:135 ../class.yith-wcas-admin.php:136
31
  msgid "Ajax Search"
32
  msgstr ""
33
 
34
+ #: ../class.yith-wcas-admin.php:190
35
+ msgid "Plugin Documentation"
36
  msgstr ""
37
 
38
+ #: ../class.yith-wcas-admin.php:207 ../plugin-options/settings-options.php:24
39
+ msgid "YITH WooCommerce Ajax Search"
40
+ msgstr ""
41
+
42
+ #: ../class.yith-wcas-admin.php:208
43
+ msgid ""
44
+ "In the YIT Plugin tab you can find the YITH WooCommerce Ajax Search "
45
+ "options.\n"
46
+ "With this menu, you can access to all the settings of our plugins that you "
47
+ "have activated.\n"
48
+ "YITH WooCommerce Ajax Search is available in an outstanding PREMIUM version "
49
+ "with many new options, <a href=\""
50
  msgstr ""
51
 
52
  #: ../class.yith-wcas-admin.php:221
53
+ msgid "YITH WooCommerce Ajax Search Updated"
54
  msgstr ""
55
 
56
+ #: ../class.yith-wcas-admin.php:222
57
+ msgid ""
58
+ "From now on, you can find all the options of YITH WooCommerce Ajax Search "
59
+ "Updated under YIT Plugin -> Ajax Search instead of WooCommerce -> Settings -"
60
+ "> Ajax Search, as in the previous version.\n"
61
+ "When one of our plugins updates, a new voice will be added to this menu.\n"
62
+ "YITH WooCommerce Ajax Search renovates with new available options, discover "
63
+ "the <a href=\""
64
  msgstr ""
65
 
66
+ #: ../class.yith-wcas.php:168
67
+ msgid "No results"
68
  msgstr ""
69
 
70
+ #: ../init.php:38
71
+ msgid ""
72
+ "YITH WooCommerce Ajax Search is enabled but not effective. It requires "
73
+ "Woocommerce in order to work."
74
  msgstr ""
75
 
76
+ #: ../init.php:51
77
+ msgid ""
78
+ "You can't activate the free version of YITH WooCommerce Ajax Search while "
79
+ "you are using the premium one."
80
  msgstr ""
81
 
82
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:460
83
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:574
84
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:719
85
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1632
86
+ #, php-format
87
+ msgid "Add %s"
88
  msgstr ""
89
 
90
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:461
91
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:575
92
+ #, php-format
93
+ msgid "Add New %s"
94
  msgstr ""
95
 
96
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:462
97
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:576
98
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1267
99
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1304
100
+ #, php-format
101
+ msgid "Edit %s"
102
  msgstr ""
103
 
104
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:463
105
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:577
106
+ #, php-format
107
+ msgid "New %s"
108
  msgstr ""
109
 
110
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:464
111
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:578
112
+ #, php-format
113
+ msgid "All %s"
114
  msgstr ""
115
 
116
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:465
117
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:579
118
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1251
119
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1305
120
+ #, php-format
121
+ msgid "View %s"
122
  msgstr ""
123
 
124
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:466
125
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:580
126
+ #, php-format
127
+ msgid "Search %s"
128
  msgstr ""
129
 
130
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:467
131
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:581
132
+ #, php-format
133
+ msgid "No %s found"
134
  msgstr ""
135
 
136
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:468
137
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:582
138
+ #, php-format
139
+ msgid "No %s found in Trash"
140
  msgstr ""
141
 
142
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:625
143
+ #, php-format
144
+ msgid "%s Categories"
145
  msgstr ""
146
 
147
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:626
148
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:635
149
+ msgid "Category"
150
+ msgstr ""
151
+
152
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:627
153
+ msgid "Search Categories"
154
+ msgstr ""
155
+
156
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:628
157
+ msgid "All Categories"
158
+ msgstr ""
159
+
160
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:629
161
+ msgid "Parent Category"
162
+ msgstr ""
163
+
164
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:630
165
+ msgid "Parent Category:"
166
+ msgstr ""
167
+
168
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:631
169
+ msgid "Edit Category"
170
+ msgstr ""
171
+
172
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:632
173
+ msgid "Update Category"
174
+ msgstr ""
175
+
176
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:633
177
+ msgid "Add New Category"
178
+ msgstr ""
179
+
180
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:634
181
+ msgid "New Category Name"
182
+ msgstr ""
183
+
184
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:724
185
+ msgid "Categories"
186
+ msgstr ""
187
+
188
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1042
189
+ #, php-format
190
+ msgid "%s Settings"
191
+ msgstr ""
192
+
193
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1051
194
+ msgid "Type"
195
+ msgstr ""
196
+
197
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1052
198
+ msgid "The layout for this "
199
+ msgstr ""
200
+
201
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1058
202
+ msgid "Rewrite"
203
+ msgstr ""
204
+
205
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1059
206
+ msgid "The word used for the URL of each project (the slug of post if empty)"
207
+ msgstr ""
208
+
209
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1064
210
+ msgid "Label Singular"
211
+ msgstr ""
212
+
213
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1065
214
+ msgid ""
215
+ "Set the label in singular to use for each label (the title of portfolio if "
216
+ "empty)"
217
+ msgstr ""
218
+
219
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1070
220
+ msgid "Label Plural"
221
+ msgstr ""
222
+
223
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1071
224
+ msgid ""
225
+ "Set the label in plural to use for each label (the title of portfolio if "
226
+ "empty)"
227
+ msgstr ""
228
+
229
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1076
230
+ msgid "Taxonomy"
231
+ msgstr ""
232
+
233
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1077
234
+ msgid ""
235
+ "If you want to use a category section for the portfolio, set the name of "
236
+ "taxonomy. Name should be in slug form (must not contain capital letters or "
237
+ "spaces) and not more than 32 characters long (database structure "
238
+ "restriction)."
239
+ msgstr ""
240
+
241
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1082
242
+ msgid "Taxonomy Rewrite"
243
+ msgstr ""
244
+
245
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1083
246
+ msgid "Set the word to use in the URL for each category page."
247
+ msgstr ""
248
+
249
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1088
250
+ msgid "Single layout"
251
+ msgstr ""
252
+
253
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1089
254
+ msgid "The layout for single page of this portfolio"
255
+ msgstr ""
256
+
257
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1130
258
+ msgid "layout settings"
259
+ msgstr ""
260
+
261
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1222
262
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1235
263
+ msgid "Quick links"
264
+ msgstr ""
265
+
266
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1475
267
+ #, php-format
268
+ msgid "Show the frontend of the %s"
269
+ msgstr ""
270
+
271
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1482
272
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:46
273
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:90
274
+ msgid "Name"
275
+ msgstr ""
276
+
277
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1631
278
+ #, php-format
279
+ msgid "Add %s by images"
280
+ msgstr ""
281
+
282
+ #: ../plugin-fw/lib/yit-cpt-unlimited.php:1633
283
+ msgid "Add with multiupload"
284
+ msgstr ""
285
+
286
+ #: ../plugin-fw/lib/yit-plugin-panel-wc.php:302
287
+ msgid "The changes you made will be lost if you navigate away from this page."
288
+ msgstr ""
289
+
290
+ #: ../plugin-fw/lib/yit-plugin-panel.php:61
291
+ msgid "Plugin Settings"
292
+ msgstr ""
293
+
294
+ #: ../plugin-fw/lib/yit-plugin-panel.php:92
295
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:101
296
+ msgid "YIT Plugins"
297
+ msgstr ""
298
+
299
+ #: ../plugin-fw/lib/yit-plugin-panel.php:269
300
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:142
301
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:5
302
+ msgid "Save Changes"
303
+ msgstr ""
304
+
305
+ #: ../plugin-fw/lib/yit-plugin-panel.php:272
306
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:145
307
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:8
308
+ msgid ""
309
+ "If you continue with this action, you will reset all options are in this "
310
+ "page."
311
+ msgstr ""
312
+
313
+ #: ../plugin-fw/lib/yit-plugin-panel.php:274
314
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:147
315
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:10
316
+ msgid "Reset Defaults"
317
+ msgstr ""
318
+
319
+ #: ../plugin-fw/lib/yit-plugin-panel.php:274
320
+ #: ../plugin-fw/lib/yit-plugin-subpanel.php:147
321
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-form.php:10
322
+ msgid "Are you sure of it?"
323
+ msgstr ""
324
+
325
+ #: ../plugin-fw/lib/yit-plugin-panel.php:408
326
+ msgid ""
327
+ "The element you have written is already exists. Please, add another name."
328
+ msgstr ""
329
+
330
+ #: ../plugin-fw/lib/yit-plugin-panel.php:409
331
+ msgid "Settings saved"
332
+ msgstr ""
333
+
334
+ #: ../plugin-fw/lib/yit-plugin-panel.php:410
335
+ msgid "Settings reset"
336
+ msgstr ""
337
+
338
+ #: ../plugin-fw/lib/yit-plugin-panel.php:411
339
+ msgid "Element deleted correctly."
340
+ msgstr ""
341
+
342
+ #: ../plugin-fw/lib/yit-plugin-panel.php:412
343
+ #: ../plugin-fw/lib/yit-plugin-panel.php:413
344
+ msgid "Element updated correctly."
345
+ msgstr ""
346
+
347
+ #: ../plugin-fw/lib/yit-plugin-panel.php:414
348
+ msgid "Database imported correctly."
349
+ msgstr ""
350
+
351
+ #: ../plugin-fw/lib/yit-plugin-panel.php:415
352
+ msgid "An error encoured during during import. Please try again."
353
+ msgstr ""
354
+
355
+ #: ../plugin-fw/lib/yit-plugin-panel.php:416
356
+ msgid "The file you have insert doesn't valid."
357
+ msgstr ""
358
+
359
+ #: ../plugin-fw/lib/yit-plugin-panel.php:417
360
+ msgid "I'm sorry, the import featured is disabled."
361
+ msgstr ""
362
+
363
+ #: ../plugin-fw/lib/yit-plugin-panel.php:418
364
+ msgid "Sorting done correctly."
365
+ msgstr ""
366
+
367
+ #: ../plugin-fw/lib/yit-pointers.php:70
368
+ msgid "Plugins Activated"
369
+ msgstr ""
370
+
371
+ #: ../plugin-fw/lib/yit-pointers.php:71
372
+ msgid ""
373
+ "From now on, you can find all the options of your plugins under the YIT "
374
+ "Plugin menu voice.\n"
375
+ " For every installation of our new "
376
+ "plugins, a new voice will be added to access to the customization settings."
377
+ msgstr ""
378
+
379
+ #: ../plugin-fw/lib/yit-pointers.php:73 ../plugin-fw/lib/yit-pointers.php:89
380
+ msgid "Discover all our plugins available on:"
381
+ msgstr ""
382
+
383
+ #: ../plugin-fw/lib/yit-pointers.php:74 ../plugin-fw/lib/yit-pointers.php:90
384
+ msgid "and"
385
+ msgstr ""
386
+
387
+ #: ../plugin-fw/lib/yit-pointers.php:84
388
+ msgid "Plugins Upgraded"
389
+ msgstr ""
390
+
391
+ #: ../plugin-fw/lib/yit-pointers.php:85
392
+ msgid ""
393
+ "From now on, you can find all the options of your plugins under the YIT "
394
+ "Plugin menu voice.\n"
395
+ " When one of our plugins updates, a new "
396
+ "voice will be added to this menu.\n"
397
+ " For example, after the update, the "
398
+ "options from the plugins (YITH WooCommerce Wishlist, YITH WooCommerce Ajax "
399
+ "Search, etc.)\n"
400
+ " will be removed from the previous "
401
+ "location and moved under the YIT Plugin tab."
402
+ msgstr ""
403
+
404
+ #: ../plugin-fw/lib/yit-upgrade.php:120
405
+ msgid "There is a new version of %plugin_name% available."
406
+ msgstr ""
407
+
408
+ #: ../plugin-fw/lib/yit-upgrade.php:121
409
+ msgid "View version %latest% details."
410
+ msgstr ""
411
+
412
+ #: ../plugin-fw/lib/yit-upgrade.php:122
413
+ msgid "Automatic update is unavailable for this plugin,"
414
+ msgstr ""
415
+
416
+ #: ../plugin-fw/lib/yit-upgrade.php:123
417
+ msgid ""
418
+ "please <a href=\"%activate_link%\"> activate </a> your copy of %plugin_name%."
419
+ msgstr ""
420
+
421
+ #: ../plugin-fw/lib/yit-upgrade.php:124
422
+ msgid "Update now."
423
+ msgstr ""
424
+
425
+ #: ../plugin-fw/lib/yit-upgrade.php:220
426
+ msgid "Yithemes Repository"
427
+ msgstr ""
428
+
429
+ #: ../plugin-fw/lib/yit-upgrade.php:254
430
+ msgid "Invalid URL Provided."
431
+ msgstr ""
432
+
433
+ #: ../plugin-fw/lib/yit-upgrade.php:267
434
+ msgid "Could not create Temporary file."
435
+ msgstr ""
436
+
437
+ #: ../plugin-fw/lib/yit-upgrade.php:408
438
+ #, php-format
439
+ msgid ""
440
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
441
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>."
442
+ msgstr ""
443
+
444
+ #: ../plugin-fw/lib/yit-upgrade.php:410
445
+ #, php-format
446
+ msgid ""
447
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
448
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>. <em>You "
449
+ "have to activate the plugin on a single site of the network to benefit from "
450
+ "the automatic updates.</em>"
451
+ msgstr ""
452
+
453
+ #: ../plugin-fw/lib/yit-upgrade.php:412
454
+ #, php-format
455
+ msgid ""
456
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
457
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a>. "
458
+ "<em>Automatic update is unavailable for this plugin, please <a href=\"%5$s\" "
459
+ "title=\"Licence activation\">activate</a> your copy of %6s.</em>"
460
+ msgstr ""
461
+
462
+ #: ../plugin-fw/lib/yit-upgrade.php:414
463
+ #, php-format
464
+ msgid ""
465
+ "There is a new version of %1$s available. <a href=\"%2$s\" class=\"thickbox "
466
+ "yit-changelog-button\" title=\"%3$s\">View version %4$s details</a> or <a "
467
+ "href=\"%5$s\">update now</a>."
468
+ msgstr ""
469
+
470
+ #: ../plugin-fw/lib/yit-upgrade.php:487
471
+ msgid "You can't update plugins for this site."
472
+ msgstr ""
473
+
474
+ #: ../plugin-fw/lib/yit-upgrade.php:491
475
+ msgid "You do not have sufficient permissions to update plugins for this site."
476
+ msgstr ""
477
+
478
+ #: ../plugin-fw/lib/yit-upgrade.php:498
479
+ msgid "Update Plugin"
480
+ msgstr ""
481
+
482
+ #: ../plugin-fw/licence/lib/yit-licence.php:154
483
+ #, php-format
484
+ msgid "%field% field can not be empty"
485
+ msgstr ""
486
+
487
+ #: ../plugin-fw/licence/lib/yit-licence.php:155
488
+ msgid "%field_1% and %field_2% fields can not be empty"
489
+ msgstr ""
490
+
491
+ #: ../plugin-fw/licence/lib/yit-licence.php:156
492
+ msgid "Unable to contact the remote server, please try again later. Thanks!"
493
+ msgstr ""
494
+
495
+ #: ../plugin-fw/licence/lib/yit-licence.php:538
496
+ msgid "Invalid Request"
497
+ msgstr ""
498
+
499
+ #: ../plugin-fw/licence/lib/yit-licence.php:539
500
+ msgid "Invalid licence key"
501
+ msgstr ""
502
+
503
+ #: ../plugin-fw/licence/lib/yit-licence.php:540
504
+ msgid "Software has been deactive"
505
+ msgstr ""
506
+
507
+ #: ../plugin-fw/licence/lib/yit-licence.php:541
508
+ msgid "Exceeded maximum number of activations"
509
+ msgstr ""
510
+
511
+ #: ../plugin-fw/licence/lib/yit-licence.php:542
512
+ msgid "Invalid instance ID"
513
  msgstr ""
514
 
515
+ #: ../plugin-fw/licence/lib/yit-licence.php:543
516
+ msgid "Invalid security key"
517
+ msgstr ""
518
+
519
+ #: ../plugin-fw/licence/lib/yit-licence.php:544
520
+ msgid "Licence key has expired"
521
+ msgstr ""
522
+
523
+ #: ../plugin-fw/licence/lib/yit-licence.php:545
524
+ msgid "Licence key has be banned"
525
+ msgstr ""
526
+
527
+ #: ../plugin-fw/licence/lib/yit-plugin-licence.php:63
528
+ #: ../plugin-fw/licence/lib/yit-plugin-licence.php:64
529
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:63
530
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:64
531
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:106
532
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:107
533
+ msgid "Licence Activation"
534
+ msgstr ""
535
+
536
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:114
537
+ #: ../plugin-fw/licence/lib/yit-theme-licence.php:115
538
+ #, php-format
539
+ msgid "%s"
540
+ msgstr ""
541
+
542
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:25
543
+ msgid "Yithemes Licence Activation"
544
+ msgstr ""
545
+
546
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:29
547
+ msgid ""
548
+ "Have you updated your licenses? Have you asked for an extension? Update "
549
+ "information concerning your products."
550
  msgstr ""
551
 
552
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:31
553
+ msgid "Update licence information"
554
  msgstr ""
555
 
556
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:41
557
+ msgid "To Active"
558
  msgstr ""
559
 
560
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:60
561
+ msgid "Activate"
562
+ msgstr ""
563
+
564
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:79
565
+ msgid "Activated"
566
+ msgstr ""
567
+
568
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:83
569
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:114
570
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:138
571
+ msgid "Product Name"
572
+ msgstr ""
573
+
574
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:84
575
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:115
576
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:139
577
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:145
578
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:337
579
+ msgid "Email"
580
+ msgstr ""
581
+
582
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:85
583
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:116
584
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:140
585
+ msgid "Licence Key"
586
+ msgstr ""
587
+
588
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:86
589
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:141
590
+ msgid "Expires"
591
+ msgstr ""
592
+
593
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:87
594
+ msgid "Remaining"
595
+ msgstr ""
596
+
597
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:88
598
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:101
599
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:142
600
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:152
601
+ msgid "Renew"
602
+ msgstr ""
603
+
604
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:99
605
+ #, php-format
606
+ msgid "%1s out of %2s"
607
+ msgstr ""
608
+
609
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:110
610
+ msgid "Banned"
611
+ msgstr ""
612
+
613
+ #: ../plugin-fw/licence/templates/panel/activation/activation-panel.php:134
614
+ msgid "Expired"
615
+ msgstr ""
616
+
617
+ #: ../plugin-fw/templates/metaboxes/types/categories.php:36
618
+ msgid "No categories."
619
+ msgstr ""
620
+
621
+ #: ../plugin-fw/templates/metaboxes/types/categories.php:42
622
+ msgid "+ Add New Category"
623
+ msgstr ""
624
+
625
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:5
626
+ msgid "Text Input"
627
+ msgstr ""
628
+
629
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:6
630
+ msgid "Checkbox"
631
+ msgstr ""
632
+
633
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:7
634
+ msgid "Select"
635
+ msgstr ""
636
+
637
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:8
638
+ msgid "Textarea"
639
+ msgstr ""
640
+
641
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:9
642
+ msgid "Radio Input"
643
+ msgstr ""
644
+
645
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:10
646
+ msgid "Password Field"
647
+ msgstr ""
648
+
649
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:11
650
+ msgid "File Upload"
651
+ msgstr ""
652
+
653
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:45
654
+ msgid "Theme Icon"
655
+ msgstr ""
656
+
657
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:46
658
+ msgid "Custom Icon"
659
+ msgstr ""
660
+
661
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:47
662
+ #: ../plugin-fw/templates/metaboxes/types/responsivesliders.php:24
663
+ msgid "None"
664
+ msgstr ""
665
+
666
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:57
667
+ msgid "Add field"
668
+ msgstr ""
669
+
670
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:66
671
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:258
672
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:37
673
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:82
674
+ msgid "Remove"
675
+ msgstr ""
676
+
677
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:67
678
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:259
679
+ msgid "Click to toggle"
680
+ msgstr ""
681
+
682
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:74
683
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:266
684
+ msgid "Title Field"
685
+ msgstr ""
686
+
687
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:78
688
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:270
689
+ msgid "Insert the title of field."
690
+ msgstr ""
691
+
692
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:83
693
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:275
694
+ msgid "Data Name"
695
+ msgstr ""
696
+
697
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:87
698
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:279
699
+ msgid ""
700
+ "REQUIRED: The identification name of this field, that you can insert into "
701
+ "body email configuration. <strong>Note:</strong>Use only lowercase "
702
+ "characters and underscores."
703
+ msgstr ""
704
+
705
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:92
706
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:284
707
+ msgid "Type field"
708
+ msgstr ""
709
+
710
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:100
711
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:292
712
+ msgid "Select the type of this field."
713
+ msgstr ""
714
+
715
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:105
716
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:297
717
+ msgid "Checked"
718
+ msgstr ""
719
+
720
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:109
721
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:301
722
+ msgid "Select this if you want this field already checked."
723
+ msgstr ""
724
+
725
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:114
726
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:306
727
+ msgid "Add options "
728
+ msgstr ""
729
+
730
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:115
731
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:307
732
+ msgid "Add option"
733
+ msgstr ""
734
+
735
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:118
736
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:310
737
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:432
738
+ msgid "Selected"
739
+ msgstr ""
740
+
741
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:121
742
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:313
743
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:432
744
+ msgid "Delete option"
745
+ msgstr ""
746
+
747
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:127
748
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:319
749
+ msgid "Message Error"
750
+ msgstr ""
751
+
752
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:131
753
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:323
754
+ msgid "Insert the error message for validation."
755
+ msgstr ""
756
+
757
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:136
758
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:328
759
+ msgid "Required"
760
+ msgstr ""
761
+
762
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:140
763
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:332
764
+ msgid "Select this if it must be required."
765
+ msgstr ""
766
+
767
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:149
768
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:341
769
+ msgid "Select this if it must be a valid email."
770
+ msgstr ""
771
+
772
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:154
773
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:346
774
+ msgid "Reply To"
775
+ msgstr ""
776
+
777
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:158
778
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:350
779
+ msgid "Select this if it's the email where you can reply."
780
+ msgstr ""
781
+
782
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:163
783
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:355
784
+ msgid "Class"
785
+ msgstr ""
786
+
787
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:167
788
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:359
789
+ msgid ""
790
+ "Insert an additional class(es) (separateb by comma) for more personalization."
791
+ msgstr ""
792
+
793
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:172
794
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:364
795
+ msgid "Icon"
796
+ msgstr ""
797
+
798
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:200
799
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:388
800
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:69
801
+ #: ../plugin-fw/templates/metaboxes/types/select-icon.php:33
802
+ #: ../plugin-fw/templates/metaboxes/types/upload.php:21
803
+ #: ../plugin-fw/templates/panel/types/upload.php:31
804
+ #: ../plugin-fw/templates/panel/woocommerce/woocommerce-upload.php:35
805
  msgid "Upload"
806
  msgstr ""
807
 
808
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:206
809
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:394
810
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:75
811
+ #: ../plugin-fw/templates/metaboxes/types/select-icon.php:39
812
+ msgid "Image preview"
813
+ msgstr ""
814
+
815
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:214
816
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:402
817
+ msgid "Insert an icon for more personalization."
818
+ msgstr ""
819
+
820
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:219
821
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:406
822
+ msgid "Width"
823
+ msgstr ""
824
+
825
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:244
826
+ #: ../plugin-fw/templates/metaboxes/types/contactform.php:418
827
+ msgid "Choose how much long will be the field."
828
+ msgstr ""
829
+
830
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:28
831
+ msgid "Close all"
832
+ msgstr ""
833
+
834
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:28
835
+ msgid "Expand all"
836
+ msgstr ""
837
+
838
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:52
839
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:95
840
+ msgid "Value"
841
+ msgstr ""
842
+
843
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:53
844
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:96
845
+ msgid "The content of the tab. (HTML is supported)"
846
+ msgstr ""
847
+
848
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:65
849
+ msgid "Add custom product tab"
850
+ msgstr ""
851
+
852
+ #: ../plugin-fw/templates/metaboxes/types/customtabs.php:107
853
+ msgid "Do you want to remove the custom tab?"
854
+ msgstr ""
855
+
856
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:89
857
+ #, php-format
858
+ msgid "(Default: %s <img src=\"%s\"/>)"
859
+ msgstr ""
860
+
861
+ #: ../plugin-fw/templates/metaboxes/types/icon-list.php:91
862
+ #, php-format
863
+ msgid "(Default: <i %s></i> )"
864
+ msgstr ""
865
+
866
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:35
867
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
868
+ #: ../plugin-fw/templates/metaboxes/types/images.php:33
869
+ #: ../plugin-fw/templates/metaboxes/types/images.php:59
870
+ msgid "Delete image"
871
+ msgstr ""
872
+
873
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
874
+ msgid "Add Images to Gallery"
875
+ msgstr ""
876
+
877
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
878
+ msgid "Add to gallery"
879
+ msgstr ""
880
+
881
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
882
+ msgid "Add images"
883
+ msgstr ""
884
+
885
+ #: ../plugin-fw/templates/metaboxes/types/image-gallery.php:40
886
+ msgid "Delete"
887
+ msgstr ""
888
+
889
+ #: ../plugin-fw/templates/metaboxes/types/images.php:37
890
+ msgid "Upload new images"
891
+ msgstr ""
892
+
893
+ #: ../plugin-fw/templates/metaboxes/types/images.php:70
894
+ msgid "Are you sure you want to remove this image?"
895
+ msgstr ""
896
+
897
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:25
898
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:36
899
+ msgid "Left sidebar"
900
+ msgstr ""
901
+
902
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:28
903
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:42
904
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:45
905
+ msgid "No sidebar"
906
+ msgstr ""
907
+
908
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:28
909
+ msgid "No sideabr"
910
+ msgstr ""
911
+
912
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:31
913
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:39
914
+ msgid "Right sidebar"
915
+ msgstr ""
916
+
917
+ #: ../plugin-fw/templates/metaboxes/types/sidebar-layout.php:34
918
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:53
919
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:64
920
+ msgid "Choose a sidebar"
921
+ msgstr ""
922
+
923
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:51
924
+ msgid "Sidebar Left"
925
+ msgstr ""
926
+
927
+ #: ../plugin-fw/templates/metaboxes/types/sidebars.php:62
928
+ msgid "Sidebar Right"
929
+ msgstr ""
930
+
931
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:42
932
  msgid "px"
933
  msgstr ""
934
 
935
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:43
936
  msgid "em"
937
  msgstr ""
938
 
939
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:44
940
  msgid "pt"
941
  msgstr ""
942
 
943
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:45
944
  msgid "rem"
945
  msgstr ""
946
 
947
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:59
948
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:153
949
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:217
950
+ msgid "Web fonts"
951
  msgstr ""
952
 
953
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:71
954
+ msgid "Google fonts"
955
+ msgstr ""
956
+
957
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:96
958
  msgid "Regular"
959
  msgstr ""
960
 
961
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:97
962
  msgid "Bold"
963
  msgstr ""
964
 
965
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:98
966
  msgid "Extra bold"
967
  msgstr ""
968
 
969
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:99
970
  msgid "Italic"
971
  msgstr ""
972
 
973
+ #: ../plugin-fw/templates/metaboxes/types/typography.php:100
974
  msgid "Italic bold"
975
  msgstr ""
976
 
977
+ #: ../plugin-options/settings-options.php:21
978
+ msgid "Upgrade to the PREMIUM VERSION"
979
+ msgstr ""
980
+
981
+ #: ../plugin-options/settings-options.php:25
982
+ msgid "Discovery the Advanced Features"
983
+ msgstr ""
984
+
985
+ #: ../plugin-options/settings-options.php:26
986
+ msgid ""
987
+ "Upgrade to the PREMIUM VERSION\n"
988
+ "of YITH WOOCOMMERCE AJAX SEARCH to benefit from all features!"
989
+ msgstr ""
990
+
991
+ #: ../plugin-options/settings-options.php:32
992
+ msgid "Get Support and Pro Features"
993
+ msgstr ""
994
+
995
+ #: ../plugin-options/settings-options.php:33
996
+ msgid ""
997
+ "Purchasing the premium version of the plugin, you will take advantage of the "
998
+ "advanced features of the product and you will get one year of free updates "
999
+ "and support through our platform available 24h/24."
1000
+ msgstr ""
1001
+
1002
+ #: ../plugin-options/settings-options.php:43
1003
+ msgid "General settings"
1004
+ msgstr ""
1005
+
1006
+ #: ../plugin-options/settings-options.php:52
1007
+ msgid "Search input label"
1008
+ msgstr ""
1009
+
1010
+ #: ../plugin-options/settings-options.php:54
1011
+ #: ../plugin-options/settings-options.php:62
1012
+ msgid "Label for Search input field."
1013
+ msgstr ""
1014
+
1015
+ #: ../plugin-options/settings-options.php:56
1016
+ msgid "Search for products"
1017
+ msgstr ""
1018
+
1019
+ #: ../plugin-options/settings-options.php:60
1020
+ msgid "Search submit label"
1021
+ msgstr ""
1022
+
1023
+ #: ../plugin-options/settings-options.php:64
1024
+ msgid "Search"
1025
+ msgstr ""
1026
+
1027
+ #: ../plugin-options/settings-options.php:68
1028
+ msgid "Minimum number of characters"
1029
+ msgstr ""
1030
+
1031
+ #: ../plugin-options/settings-options.php:69
1032
+ msgid "Minimum number of characters required to trigger autosuggest."
1033
+ msgstr ""
1034
+
1035
+ #: ../plugin-options/settings-options.php:82
1036
+ msgid "Maximum number of results"
1037
+ msgstr ""
1038
+
1039
+ #: ../plugin-options/settings-options.php:83
1040
+ msgid "Maximum number of results showed within the autosuggest box."
1041
+ msgstr ""
1042
+
1043
+ #: ../templates/yith-woocommerce-ajax-search.php:20
1044
+ msgid "Search for:"
1045
+ msgstr ""
1046
+
1047
+ #: ../widgets/class.yith-wcas-ajax-search.php:29
1048
+ msgid "An Ajax Search box for products only."
1049
+ msgstr ""
1050
+
1051
+ #: ../widgets/class.yith-wcas-ajax-search.php:31
1052
+ msgid "YITH WooCommerce Ajax Product Search"
1053
+ msgstr ""
1054
+
1055
+ #: ../widgets/class.yith-wcas-ajax-search.php:90
1056
+ msgid "Title:"
1057
  msgstr ""
plugin-fw/assets/css/chosen/chosen.css ADDED
@@ -0,0 +1,435 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ Chosen, a Select Box Enhancer for jQuery and Prototype
3
+ by Patrick Filler for Harvest, http://getharvest.com
4
+
5
+ Version 1.1.0
6
+ Full source at https://github.com/harvesthq/chosen
7
+ Copyright (c) 2011 Harvest http://getharvest.com
8
+
9
+ MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10
+ This file is generated by `grunt build`, do not edit it by hand.
11
+ */
12
+
13
+ /* @group Base */
14
+ .chosen-container {
15
+ position: relative;
16
+ display: inline-block;
17
+ vertical-align: middle;
18
+ font-size: 13px;
19
+ zoom: 1;
20
+ *display: inline;
21
+ -webkit-user-select: none;
22
+ -moz-user-select: none;
23
+ user-select: none;
24
+ }
25
+ .chosen-container .chosen-drop {
26
+ position: absolute;
27
+ top: 100%;
28
+ left: -9999px;
29
+ z-index: 1010;
30
+ -webkit-box-sizing: border-box;
31
+ -moz-box-sizing: border-box;
32
+ box-sizing: border-box;
33
+ width: 100%;
34
+ border: 1px solid #aaa;
35
+ border-top: 0;
36
+ background: #fff;
37
+ box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
38
+ }
39
+ .chosen-container.chosen-with-drop .chosen-drop {
40
+ left: 0;
41
+ }
42
+ .chosen-container a {
43
+ cursor: pointer;
44
+ }
45
+
46
+ /* @end */
47
+ /* @group Single Chosen */
48
+ .chosen-container-single .chosen-single {
49
+ position: relative;
50
+ display: block;
51
+ overflow: hidden;
52
+ padding: 0 0 0 8px;
53
+ height: 23px;
54
+ border: 1px solid #aaa;
55
+ border-radius: 5px;
56
+ background-color: #fff;
57
+ background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
58
+ background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
59
+ background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
60
+ background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
61
+ background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
62
+ background-clip: padding-box;
63
+ box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
64
+ color: #444;
65
+ text-decoration: none;
66
+ white-space: nowrap;
67
+ line-height: 24px;
68
+ }
69
+ .chosen-container-single .chosen-default {
70
+ color: #999;
71
+ }
72
+ .chosen-container-single .chosen-single span {
73
+ display: block;
74
+ overflow: hidden;
75
+ margin-right: 26px;
76
+ text-overflow: ellipsis;
77
+ white-space: nowrap;
78
+ }
79
+ .chosen-container-single .chosen-single-with-deselect span {
80
+ margin-right: 38px;
81
+ }
82
+ .chosen-container-single .chosen-single abbr {
83
+ position: absolute;
84
+ top: 6px;
85
+ right: 26px;
86
+ display: block;
87
+ width: 12px;
88
+ height: 12px;
89
+ background: url('../../images/chosen/chosen-sprite.png') -42px 1px no-repeat;
90
+ font-size: 1px;
91
+ }
92
+ .chosen-container-single .chosen-single abbr:hover {
93
+ background-position: -42px -10px;
94
+ }
95
+ .chosen-container-single.chosen-disabled .chosen-single abbr:hover {
96
+ background-position: -42px -10px;
97
+ }
98
+ .chosen-container-single .chosen-single div {
99
+ position: absolute;
100
+ top: 0;
101
+ right: 0;
102
+ display: block;
103
+ width: 18px;
104
+ height: 100%;
105
+ }
106
+ .chosen-container-single .chosen-single div b {
107
+ display: block;
108
+ width: 100%;
109
+ height: 100%;
110
+ background: url('../../images/chosen/chosen-sprite.png') no-repeat 0px 2px;
111
+ }
112
+ .chosen-container-single .chosen-search {
113
+ position: relative;
114
+ z-index: 1010;
115
+ margin: 0;
116
+ padding: 3px 4px;
117
+ white-space: nowrap;
118
+ }
119
+ .chosen-container-single .chosen-search input[type="text"] {
120
+ -webkit-box-sizing: border-box;
121
+ -moz-box-sizing: border-box;
122
+ box-sizing: border-box;
123
+ margin: 1px 0;
124
+ padding: 4px 20px 4px 5px;
125
+ width: 100%;
126
+ height: auto;
127
+ outline: 0;
128
+ border: 1px solid #aaa;
129
+ background: white url('../../images/chosen/chosen-sprite.png') no-repeat 100% -20px;
130
+ background: url('../../images/chosen/chosen-sprite.png') no-repeat 100% -20px;
131
+ font-size: 1em;
132
+ font-family: sans-serif;
133
+ line-height: normal;
134
+ border-radius: 0;
135
+ }
136
+ .chosen-container-single .chosen-drop {
137
+ margin-top: -1px;
138
+ border-radius: 0 0 4px 4px;
139
+ background-clip: padding-box;
140
+ }
141
+ .chosen-container-single.chosen-container-single-nosearch .chosen-search {
142
+ position: absolute;
143
+ left: -9999px;
144
+ }
145
+
146
+ /* @end */
147
+ /* @group Results */
148
+ .chosen-container .chosen-results {
149
+ position: relative;
150
+ overflow-x: hidden;
151
+ overflow-y: auto;
152
+ margin: 0 4px 4px 0;
153
+ padding: 0 0 0 4px;
154
+ max-height: 240px;
155
+ -webkit-overflow-scrolling: touch;
156
+ }
157
+ .chosen-container .chosen-results li {
158
+ display: none;
159
+ margin: 0;
160
+ padding: 5px 6px;
161
+ list-style: none;
162
+ line-height: 15px;
163
+ -webkit-touch-callout: none;
164
+ }
165
+ .chosen-container .chosen-results li.active-result {
166
+ display: list-item;
167
+ cursor: pointer;
168
+ }
169
+ .chosen-container .chosen-results li.disabled-result {
170
+ display: list-item;
171
+ color: #ccc;
172
+ cursor: default;
173
+ }
174
+ .chosen-container .chosen-results li.highlighted {
175
+ background-color: #3875d7;
176
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
177
+ background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
178
+ background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
179
+ background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
180
+ background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
181
+ color: #fff;
182
+ }
183
+ .chosen-container .chosen-results li.no-results {
184
+ display: list-item;
185
+ background: #f4f4f4;
186
+ }
187
+ .chosen-container .chosen-results li.group-result {
188
+ display: list-item;
189
+ font-weight: bold;
190
+ cursor: default;
191
+ }
192
+ .chosen-container .chosen-results li.group-option {
193
+ padding-left: 15px;
194
+ }
195
+ .chosen-container .chosen-results li em {
196
+ font-style: normal;
197
+ text-decoration: underline;
198
+ }
199
+
200
+ /* @end */
201
+ /* @group Multi Chosen */
202
+ .chosen-container-multi .chosen-choices {
203
+ position: relative;
204
+ overflow: hidden;
205
+ -webkit-box-sizing: border-box;
206
+ -moz-box-sizing: border-box;
207
+ box-sizing: border-box;
208
+ margin: 0;
209
+ padding: 0;
210
+ width: 100%;
211
+ height: auto !important;
212
+ height: 1%;
213
+ border: 1px solid #aaa;
214
+ background-color: #fff;
215
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
216
+ background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
217
+ background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
218
+ background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
219
+ background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
220
+ cursor: text;
221
+ }
222
+ .chosen-container-multi .chosen-choices li {
223
+ float: left;
224
+ list-style: none;
225
+ }
226
+ .chosen-container-multi .chosen-choices li.search-field {
227
+ margin: 0;
228
+ padding: 0;
229
+ white-space: nowrap;
230
+ }
231
+ .chosen-container-multi .chosen-choices li.search-field input[type="text"] {
232
+ margin: 1px 0;
233
+ padding: 5px;
234
+ height: 15px;
235
+ outline: 0;
236
+ border: 0 !important;
237
+ background: transparent !important;
238
+ box-shadow: none;
239
+ color: #666;
240
+ font-size: 100%;
241
+ font-family: sans-serif;
242
+ line-height: normal;
243
+ border-radius: 0;
244
+ }
245
+ .chosen-container-multi .chosen-choices li.search-field .default {
246
+ color: #999;
247
+ }
248
+ .chosen-container-multi .chosen-choices li.search-choice {
249
+ position: relative;
250
+ margin: 3px 0 3px 5px;
251
+ padding: 3px 20px 3px 5px;
252
+ border: 1px solid #aaa;
253
+ border-radius: 3px;
254
+ background-color: #e4e4e4;
255
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
256
+ background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
257
+ background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
258
+ background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
259
+ background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
260
+ background-clip: padding-box;
261
+ box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
262
+ color: #333;
263
+ line-height: 13px;
264
+ cursor: default;
265
+ }
266
+ .chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
267
+ position: absolute;
268
+ top: 4px;
269
+ right: 3px;
270
+ display: block;
271
+ width: 12px;
272
+ height: 12px;
273
+ background: url('../../images/chosen/chosen-sprite.png') -42px 1px no-repeat;
274
+ font-size: 1px;
275
+ }
276
+ .chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
277
+ background-position: -42px -10px;
278
+ }
279
+ .chosen-container-multi .chosen-choices li.search-choice-disabled {
280
+ padding-right: 5px;
281
+ border: 1px solid #ccc;
282
+ background-color: #e4e4e4;
283
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
284
+ background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
285
+ background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
286
+ background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
287
+ background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
288
+ color: #666;
289
+ }
290
+ .chosen-container-multi .chosen-choices li.search-choice-focus {
291
+ background: #d4d4d4;
292
+ }
293
+ .chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
294
+ background-position: -42px -10px;
295
+ }
296
+ .chosen-container-multi .chosen-results {
297
+ margin: 0;
298
+ padding: 0;
299
+ }
300
+ .chosen-container-multi .chosen-drop .result-selected {
301
+ display: list-item;
302
+ color: #ccc;
303
+ cursor: default;
304
+ }
305
+
306
+ /* @end */
307
+ /* @group Active */
308
+ .chosen-container-active .chosen-single {
309
+ border: 1px solid #5897fb;
310
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
311
+ }
312
+ .chosen-container-active.chosen-with-drop .chosen-single {
313
+ border: 1px solid #aaa;
314
+ -moz-border-radius-bottomright: 0;
315
+ border-bottom-right-radius: 0;
316
+ -moz-border-radius-bottomleft: 0;
317
+ border-bottom-left-radius: 0;
318
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
319
+ background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
320
+ background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
321
+ background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
322
+ background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
323
+ box-shadow: 0 1px 0 #fff inset;
324
+ }
325
+ .chosen-container-active.chosen-with-drop .chosen-single div {
326
+ border-left: none;
327
+ background: transparent;
328
+ }
329
+ .chosen-container-active.chosen-with-drop .chosen-single div b {
330
+ background-position: -18px 2px;
331
+ }
332
+ .chosen-container-active .chosen-choices {
333
+ border: 1px solid #5897fb;
334
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
335
+ }
336
+ .chosen-container-active .chosen-choices li.search-field input[type="text"] {
337
+ color: #111 !important;
338
+ }
339
+
340
+ /* @end */
341
+ /* @group Disabled Support */
342
+ .chosen-disabled {
343
+ opacity: 0.5 !important;
344
+ cursor: default;
345
+ }
346
+ .chosen-disabled .chosen-single {
347
+ cursor: default;
348
+ }
349
+ .chosen-disabled .chosen-choices .search-choice .search-choice-close {
350
+ cursor: default;
351
+ }
352
+
353
+ /* @end */
354
+ /* @group Right to Left */
355
+ .chosen-rtl {
356
+ text-align: right;
357
+ }
358
+ .chosen-rtl .chosen-single {
359
+ overflow: visible;
360
+ padding: 0 8px 0 0;
361
+ }
362
+ .chosen-rtl .chosen-single span {
363
+ margin-right: 0;
364
+ margin-left: 26px;
365
+ direction: rtl;
366
+ }
367
+ .chosen-rtl .chosen-single-with-deselect span {
368
+ margin-left: 38px;
369
+ }
370
+ .chosen-rtl .chosen-single div {
371
+ right: auto;
372
+ left: 3px;
373
+ }
374
+ .chosen-rtl .chosen-single abbr {
375
+ right: auto;
376
+ left: 26px;
377
+ }
378
+ .chosen-rtl .chosen-choices li {
379
+ float: right;
380
+ }
381
+ .chosen-rtl .chosen-choices li.search-field input[type="text"] {
382
+ direction: rtl;
383
+ }
384
+ .chosen-rtl .chosen-choices li.search-choice {
385
+ margin: 3px 5px 3px 0;
386
+ padding: 3px 5px 3px 19px;
387
+ }
388
+ .chosen-rtl .chosen-choices li.search-choice .search-choice-close {
389
+ right: auto;
390
+ left: 4px;
391
+ }
392
+ .chosen-rtl.chosen-container-single-nosearch .chosen-search,
393
+ .chosen-rtl .chosen-drop {
394
+ left: 9999px;
395
+ }
396
+ .chosen-rtl.chosen-container-single .chosen-results {
397
+ margin: 0 0 4px 4px;
398
+ padding: 0 4px 0 0;
399
+ }
400
+ .chosen-rtl .chosen-results li.group-option {
401
+ padding-right: 15px;
402
+ padding-left: 0;
403
+ }
404
+ .chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
405
+ border-right: none;
406
+ }
407
+ .chosen-rtl .chosen-search input[type="text"] {
408
+ padding: 4px 5px 4px 20px;
409
+ background: white url('../../images/chosen/chosen-sprite.png') no-repeat -30px -20px;
410
+ background: url('../../images/chosen/chosen-sprite.png') no-repeat -30px -20px;
411
+ direction: rtl;
412
+ }
413
+ .chosen-rtl.chosen-container-single .chosen-single div b {
414
+ background-position: 6px 2px;
415
+ }
416
+ .chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
417
+ background-position: -12px 2px;
418
+ }
419
+
420
+ /* @end */
421
+ /* @group Retina compatibility */
422
+ @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
423
+ .chosen-rtl .chosen-search input[type="text"],
424
+ .chosen-container-single .chosen-single abbr,
425
+ .chosen-container-single .chosen-single div b,
426
+ .chosen-container-single .chosen-search input[type="text"],
427
+ .chosen-container-multi .chosen-choices .search-choice .search-choice-close,
428
+ .chosen-container .chosen-results-scroll-down span,
429
+ .chosen-container .chosen-results-scroll-up span {
430
+ background-image: url('../../images/chosen/chosen-sprite@2x.png') !important;
431
+ background-size: 52px 37px !important;
432
+ background-repeat: no-repeat !important;
433
+ }
434
+ }
435
+ /* @end */
plugin-fw/assets/css/codemirror/codemirror.css ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* BASICS */
2
+
3
+ .CodeMirror {
4
+ /* Set height, width, borders, and global font properties here */
5
+ font-family: monospace;
6
+ height: 400px;
7
+ clear: both;
8
+ padding: 0;
9
+ }
10
+ .CodeMirror-scroll {
11
+ /* Set scrolling behaviour here */
12
+ overflow: auto;
13
+ }
14
+
15
+ /* PADDING */
16
+
17
+ .CodeMirror-lines {
18
+ padding: 4px 0; /* Vertical padding around content */
19
+ }
20
+ .CodeMirror pre {
21
+ padding: 0 4px; /* Horizontal padding of content */
22
+ }
23
+
24
+ .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
25
+ background-color: white; /* The little square between H and V scrollbars */
26
+ }
27
+
28
+ /* GUTTER */
29
+
30
+ .CodeMirror-gutters {
31
+ border-right: 1px solid #ddd;
32
+ background-color: #f7f7f7;
33
+ white-space: nowrap;
34
+ }
35
+ .CodeMirror-linenumbers {}
36
+ .CodeMirror-linenumber {
37
+ padding: 0 3px 0 5px;
38
+ min-width: 20px;
39
+ text-align: right;
40
+ color: #999;
41
+ }
42
+
43
+ /* CURSOR */
44
+
45
+ .CodeMirror div.CodeMirror-cursor {
46
+ border-left: 1px solid black;
47
+ z-index: 3;
48
+ }
49
+ /* Shown when moving in bi-directional text */
50
+ .CodeMirror div.CodeMirror-secondarycursor {
51
+ border-left: 1px solid silver;
52
+ }
53
+ .CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor {
54
+ width: auto;
55
+ border: 0;
56
+ background: #7e7;
57
+ z-index: 1;
58
+ }
59
+ /* Can style cursor different in overwrite (non-insert) mode */
60
+ .CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {}
61
+
62
+ .cm-tab { display: inline-block; }
63
+
64
+ /* DEFAULT THEME */
65
+
66
+ .cm-s-default .cm-keyword {color: #708;}
67
+ .cm-s-default .cm-atom {color: #219;}
68
+ .cm-s-default .cm-number {color: #164;}
69
+ .cm-s-default .cm-def {color: #00f;}
70
+ .cm-s-default .cm-variable {color: black;}
71
+ .cm-s-default .cm-variable-2 {color: #05a;}
72
+ .cm-s-default .cm-variable-3 {color: #085;}
73
+ .cm-s-default .cm-property {color: black;}
74
+ .cm-s-default .cm-operator {color: black;}
75
+ .cm-s-default .cm-comment {color: #a50;}
76
+ .cm-s-default .cm-string {color: #a11;}
77
+ .cm-s-default .cm-string-2 {color: #f50;}
78
+ .cm-s-default .cm-meta {color: #555;}
79
+ .cm-s-default .cm-error {color: #f00;}
80
+ .cm-s-default .cm-qualifier {color: #555;}
81
+ .cm-s-default .cm-builtin {color: #30a;}
82
+ .cm-s-default .cm-bracket {color: #997;}
83
+ .cm-s-default .cm-tag {color: #170;}
84
+ .cm-s-default .cm-attribute {color: #00c;}
85
+ .cm-s-default .cm-header {color: blue;}
86
+ .cm-s-default .cm-quote {color: #090;}
87
+ .cm-s-default .cm-hr {color: #999;}
88
+ .cm-s-default .cm-link {color: #00c;}
89
+
90
+ .cm-negative {color: #d44;}
91
+ .cm-positive {color: #292;}
92
+ .cm-header, .cm-strong {font-weight: bold;}
93
+ .cm-em {font-style: italic;}
94
+ .cm-link {text-decoration: underline;}
95
+
96
+ .cm-invalidchar {color: #f00;}
97
+
98
+ div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
99
+ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
100
+
101
+ /* STOP */
102
+
103
+ /* The rest of this file contains styles related to the mechanics of
104
+ the editor. You probably shouldn't touch them. */
105
+
106
+ .CodeMirror {
107
+ line-height: 1;
108
+ position: relative;
109
+ overflow: hidden;
110
+ background: #fafafa;
111
+ color: black;
112
+ }
113
+
114
+ .CodeMirror-scroll {
115
+ /* 30px is the magic margin used to hide the element's real scrollbars */
116
+ /* See overflow: hidden in .CodeMirror */
117
+ margin-bottom: -30px; margin-right: -30px;
118
+ padding-bottom: 30px; padding-right: 30px;
119
+ height: 100%;
120
+ outline: none; /* Prevent dragging from highlighting the element */
121
+ position: relative;
122
+ }
123
+ .CodeMirror-sizer {
124
+ position: relative;
125
+ }
126
+
127
+ /* The fake, visible scrollbars. Used to force redraw during scrolling
128
+ before actuall scrolling happens, thus preventing shaking and
129
+ flickering artifacts. */
130
+ .CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
131
+ position: absolute;
132
+ z-index: 6;
133
+ display: none;
134
+ }
135
+ .CodeMirror-vscrollbar {
136
+ right: 0; top: 0;
137
+ overflow-x: hidden;
138
+ overflow-y: scroll;
139
+ }
140
+ .CodeMirror-hscrollbar {
141
+ bottom: 0; left: 0;
142
+ overflow-y: hidden;
143
+ overflow-x: scroll;
144
+ }
145
+ .CodeMirror-scrollbar-filler {
146
+ right: 0; bottom: 0;
147
+ }
148
+ .CodeMirror-gutter-filler {
149
+ left: 0; bottom: 0;
150
+ }
151
+
152
+ .CodeMirror-gutters {
153
+ position: absolute; left: 0; top: 0;
154
+ padding-bottom: 30px;
155
+ z-index: 3;
156
+ }
157
+ .CodeMirror-gutter {
158
+ white-space: normal;
159
+ height: 100%;
160
+ padding-bottom: 30px;
161
+ margin-bottom: -32px;
162
+ display: inline-block;
163
+ /* Hack to make IE7 behave */
164
+ *zoom:1;
165
+ *display:inline;
166
+ }
167
+ .CodeMirror-gutter-elt {
168
+ position: absolute;
169
+ cursor: default;
170
+ z-index: 4;
171
+ }
172
+
173
+ .CodeMirror-lines {
174
+ cursor: text;
175
+ }
176
+ .CodeMirror pre {
177
+ /* Reset some styles that the rest of the page might have set */
178
+ -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
179
+ border-width: 0;
180
+ background: transparent;
181
+ font-family: inherit;
182
+ font-size: inherit;
183
+ margin: 0;
184
+ white-space: pre;
185
+ word-wrap: normal;
186
+ line-height: inherit;
187
+ color: inherit;
188
+ z-index: 2;
189
+ position: relative;
190
+ overflow: visible;
191
+ }
192
+ .CodeMirror-wrap pre {
193
+ word-wrap: break-word;
194
+ white-space: pre-wrap;
195
+ word-break: normal;
196
+ }
197
+ .CodeMirror-code pre {
198
+ border-right: 30px solid transparent;
199
+ width: -webkit-fit-content;
200
+ width: -moz-fit-content;
201
+ width: fit-content;
202
+ }
203
+ .CodeMirror-wrap .CodeMirror-code pre {
204
+ border-right: none;
205
+ width: auto;
206
+ }
207
+ .CodeMirror-linebackground {
208
+ position: absolute;
209
+ left: 0; right: 0; top: 0; bottom: 0;
210
+ z-index: 0;
211
+ }
212
+
213
+ .CodeMirror-linewidget {
214
+ position: relative;
215
+ z-index: 2;
216
+ overflow: auto;
217
+ }
218
+
219
+ .CodeMirror-widget {
220
+ }
221
+
222
+ .CodeMirror-wrap .CodeMirror-scroll {
223
+ overflow-x: hidden;
224
+ }
225
+
226
+ .CodeMirror-measure {
227
+ position: absolute;
228
+ width: 100%; height: 0px;
229
+ overflow: hidden;
230
+ visibility: hidden;
231
+ }
232
+ .CodeMirror-measure pre { position: static; }
233
+
234
+ .CodeMirror div.CodeMirror-cursor {
235
+ position: absolute;
236
+ visibility: hidden;
237
+ border-right: none;
238
+ width: 0;
239
+ }
240
+ .CodeMirror-focused div.CodeMirror-cursor {
241
+ visibility: visible;
242
+ }
243
+
244
+ .CodeMirror-selected { background: #d9d9d9; }
245
+ .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
246
+
247
+ .cm-searching {
248
+ background: #ffa;
249
+ background: rgba(255, 255, 0, .4);
250
+ }
251
+
252
+ /* IE7 hack to prevent it from returning funny offsetTops on the spans */
253
+ .CodeMirror span { *vertical-align: text-bottom; }
254
+
255
+ @media print {
256
+ /* Hide the cursor when printing */
257
+ .CodeMirror div.CodeMirror-cursor {
258
+ visibility: hidden;
259
+ }
260
+ }
plugin-fw/assets/css/metaboxes.css ADDED
@@ -0,0 +1,598 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* self-clear floats */
2
+ .clearfix:after { content:"."; display:block; height:0; clear:both; visibility:hidden; overflow:hidden; }
3
+ /* ie.css */
4
+ * html .clearfix { /* IE6 */
5
+ height:1%;
6
+ }
7
+ *:first-child+html .clearfix { /* IE7 */
8
+ min-height:1%;
9
+ }
10
+
11
+ .clearboth { clear: both }
12
+
13
+ /* === TAB STYLE */
14
+ .metaboxes-tab { margin:-6px -12px -8px; }
15
+ .metaboxes-tab div.tabs-panel { height:auto; overflow:visible; margin-top:0px; padding:0 10px; background:none; border:0; border-top:1px solid #D4D4D4; }
16
+ .metaboxes-tab ul.metaboxes-tabs { background:#F5F5F5; margin:0; padding:10px 0 0 5px; }
17
+ .metaboxes-tab ul.metaboxes-tabs li { padding:8px 15px; border:1px solid #D4D4D4; float:left; background:#EDEDED; border-bottom-color:#EDEDED; margin:0 0 -1px 5px; box-shadow:1px 1px 1px 0 #FFFFFF inset; }
18
+ .metaboxes-tab ul.metaboxes-tabs li a { color:#555; text-decoration:none; }
19
+ .metaboxes-tab ul.metaboxes-tabs li.tabs { background:#F6F6F6; border-bottom:1px solid #F6F6F6; }
20
+ .metaboxes-tab p.field-row { margin:20px 0; }
21
+ .metaboxes-tab div.sep { height:1px; background:#DFDFDF; clear:both; margin-left:-10px; margin-right:-10px; }
22
+ .metaboxes-tab label { font-weight:bold; width:160px; float:left; line-height:23px; margin-left:-184px; }
23
+ .metaboxes-tab label small { font-weight:normal; line-height:15px; font-style:italic; color:#999; display:block; }
24
+ .metaboxes-tab input[type="text"], .metaboxes-tab select, .metaboxes-tab textarea { width:30%; }
25
+ .metaboxes-tab input[type="checkbox"] { vertical-align: middle }
26
+ .metaboxes-tab select {padding:0;}
27
+ .metaboxes-tab input.button-secondary, .metaboxes-tab input.checkbox { width:auto; }
28
+ .metaboxes-tab .description { color:#AFAFAF; font-size:90%; font-style:italic; line-height:23px; padding-left:5px; }
29
+ .metaboxes-tab p.field-row.textarea .description { vertical-align:top; }
30
+ .metaboxes-tab p.field-row.checkbox {background:none;}
31
+
32
+ .metaboxes-tab .the-metabox { margin:20px 0; margin-left:184px;}
33
+ .metaboxes-tab .the-metabox.no-label { margin:20px 0; margin-left:0;}
34
+ .metaboxes-tab hr { height: 0px; border-top: 1px solid #dadada; width: auto; margin-left: -10px; margin-right: -10px; }
35
+ .metaboxes-tab .the-metabox p { margin:0;}
36
+ .metaboxes-tab .the-metabox:last-child { border-bottom: 0px; }
37
+ .metaboxes-tab .the-metabox.checkbox { background:none; }
38
+ .metaboxes-tab .the-metabox.slider .ui-slider { margin-right:15px; }
39
+
40
+ .metaboxes-tab span.desc { font-size: 11px; color: #AFAFAF; }
41
+ .metaboxes-tab span.desc.inline { display: inline-block; vertical-align: top; line-height: 23px; }
42
+ .metaboxes-tab .onoff span.desc, .metaboxes-tab .onoff label { padding:6px 0; }
43
+ .metaboxes-tab .select span.desc, .metaboxes-tab .select label { padding:2px 0; }
44
+ .metaboxes-tab .slider span.desc, .metaboxes-tab .slider label { padding:15px 0; }
45
+ .metaboxes-tab .slider span.desc { display:block; padding:20px 0; }
46
+
47
+ .metaboxes-tab ul.metaboxes-tabs li {
48
+ -webkit-border-top-left-radius: 3px;
49
+ -webkit-border-top-right-radius: 3px;
50
+ -moz-border-radius-topleft: 3px;
51
+ -moz-border-radius-topright: 3px;
52
+ border-top-left-radius: 3px;
53
+ border-top-right-radius: 3px;
54
+ }
55
+
56
+ /* image gallery */
57
+ .metaboxes-tab .image-gallery ul li{
58
+ display: inline-block;
59
+ width: 80px;
60
+ margin-left: 10px;
61
+ position: relative;
62
+ }
63
+ .metaboxes-tab .image-gallery ul li img{
64
+ width: 80px;
65
+ border: 1px solid #ccc;
66
+ }
67
+ .metaboxes-tab .image-gallery ul li ul{
68
+ position: absolute;
69
+ top: -6px;
70
+ right: -1px;
71
+ width: 20px;
72
+ height: 20px;
73
+ }
74
+ .metaboxes-tab .image-gallery ul a.delete{
75
+ background: url(../images/x.png) no-repeat;
76
+ width: 20px;
77
+ height: 20px;
78
+ display: block;
79
+ text-indent: -99999px;
80
+ }
81
+ /* sidebar layout */
82
+ .yit-sidebar-layout input[type="radio"] {
83
+ display: none;
84
+ width: 0px;
85
+ }
86
+ .yit-sidebar-layout input[type="radio"]:first-child {
87
+ margin-right: -2px;
88
+ }
89
+
90
+ .yit-sidebar-layout input[type="radio"] + img {
91
+ border: 2px solid #fff;
92
+ padding: 1px;
93
+ }
94
+
95
+ .yit-sidebar-layout input[type="radio"] + img:hover {
96
+ cursor: pointer;
97
+ }
98
+
99
+ .yit-sidebar-layout input[checked] + img {
100
+ border: 2px solid #f2ad35;
101
+ padding: 1px;
102
+ }
103
+
104
+ .yit-sidebar-layout select {
105
+ vertical-align: 12px;
106
+ width: inherit !important;
107
+ }
108
+
109
+ /* wp editor */
110
+ .the-metabox.textarea-editor .mceIframeContainer {
111
+ background:#fff;
112
+ }
113
+ .the-metabox.textarea-editor label {
114
+ margin-top:24px;
115
+ }
116
+
117
+ /* categories */
118
+ .categories-panel { width:30%; float:left; margin-right:4px; }
119
+ .categories-panel .box { height:200px; border:1px solid #DFDFDF; background:#fff; padding:6px 10px; overflow: auto; }
120
+ .categories-panel ul { list-style:none; margin:0; }
121
+ .categories-panel ul li { line-height: 19px; margin: 0; padding: 0; word-wrap: break-word; }
122
+ .categories-panel ul li label { font-weight:normal !important; margin-left:0 !important; }
123
+ .categories-panel input.newcategory { width:100%; margin-bottom:3px; }
124
+
125
+ /* contact form */
126
+ .contactform_item {
127
+ border-style: solid;
128
+ border-width: 1px;
129
+ line-height: 1;
130
+ margin-bottom: 20px;
131
+ padding: 0;
132
+ background-color: #F5F5F5;
133
+ background-image: -moz-linear-gradient(center top , #F9F9F9, #F5F5F5);
134
+ border-color: #DFDFDF;
135
+ border-radius: 3px 3px 3px 3px;
136
+ box-shadow: 0 1px 0 #FFFFFF inset;
137
+ min-width: 255px;
138
+ position: relative;
139
+ }
140
+ .contactform_item .handlediv { position:relative; top: -4px; }
141
+ .contactform_item h3 { min-height: 21px }
142
+ .contactform_item .inside { padding: 10px !important; }
143
+ .contactform_item .deps { display: none; }
144
+ .contactform_item .addoptions p.option { margin: 5px 0 5px 200px }
145
+ .contactform_item .addoptions p label { width: 80px !important; }
146
+ .contactform_item .add-field-option { margin-bottom: 10px !important; }
147
+ .remove_item { float: right; }
148
+ .metabox-sortable-placeholder { border: 1px dotted #dedede; margin: 10px 0 }
149
+
150
+ /* features tab */
151
+ .featurestab_item{
152
+ border-style: solid;
153
+ border-width: 1px;
154
+ line-height: 1;
155
+ margin-bottom: 20px;
156
+ padding: 0;
157
+ background-color: #F5F5F5;
158
+ background-image: -moz-linear-gradient(center top , #F9F9F9, #F5F5F5);
159
+ border-color: #DFDFDF;
160
+ border-radius: 3px 3px 3px 3px;
161
+ box-shadow: 0 1px 0 #FFFFFF inset;
162
+ min-width: 255px;
163
+ position: relative;
164
+ }
165
+ .featurestab_item .handlediv { position:relative; top: -4px; }
166
+ .featurestab_item h3 { min-height: 21px }
167
+ .featurestab_item .inside { padding: 10px !important; }
168
+ .featurestab_item .deps { display: none; }
169
+ .featurestab_item .addoptions p.option { margin: 5px 0 5px 200px }
170
+ .featurestab_item .addoptions p label { width: 80px !important; }
171
+ .featurestab_item .add-field-option { margin-bottom: 10px !important; }
172
+
173
+ /* slider */
174
+ .the-metabox.slider { padding-top:20px; }
175
+
176
+ /* on off */
177
+ .the-metabox .rm_onoff span.onoff { float:left; margin-right:5px; margin-left:-4px; /* image fix */ }
178
+
179
+ /* select */
180
+ .the-metabox .select_wrapper { width:341px; background-color:#fff; }
181
+ .the-metabox .select_wrapper select { width:100%; }
182
+ .the-metabox .icon_type{ width:30%; float: left; margin-right: 40px }
183
+ .the-metabox .icon_type select, .the-metabox div.option .select_wrapper select{ width: 100% }
184
+
185
+ #post-type-settings .category-list label { width: 187px; }
186
+ .remove_cat { float: right; text-align:center; display: block; width: 20px; height: 20px; border-radius: 20px; font-weight: bold; font-size: 10px; background: #efefef; text-decoration: none; }
187
+
188
+ .the-metabox .select_wrapper {
189
+ background: url("../images/select.png") no-repeat scroll right center #FAFAFA;
190
+ border-color: #CCCCCC #EEEEEE #EEEEEE #CCCCCC;
191
+ border-radius: 4px 4px 4px 4px;
192
+ border-style: solid;
193
+ border-width: 1px;
194
+ color: #555555;
195
+ display: block;
196
+ float: left;
197
+ font-family: sans-serif;
198
+ font-size: 12px;
199
+ min-height: 26px;
200
+ margin-bottom: 9px !important;
201
+ margin-left: 0;
202
+ margin-right: 5px;
203
+ margin-top: 0;
204
+ width: 400px;
205
+ position: relative;
206
+ }
207
+
208
+ /*chosen*/
209
+
210
+ .chosen .select_wrapper {
211
+ background: none;
212
+ border: none;
213
+ }
214
+ .chosen .select_wrapper .chosen-container{
215
+ width: 338px!important;
216
+ }
217
+ .chosen .select_wrapper .chosen-container .search-field input{
218
+ height: 27px!important;
219
+ color: #333;
220
+ }
221
+ .chosen .select_wrapper .chosen-container .chosen-choices{
222
+ border: 1px solid #ddd;
223
+ box-shadow: none;
224
+ }
225
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice{
226
+ height: 15px!important;
227
+ min-width: 105px;
228
+ }
229
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice span{
230
+ line-height: 15px;
231
+ height: 15px;
232
+ padding-top: 2px;
233
+ }
234
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice a.search-choice-close{
235
+ top: 5px;
236
+ }
237
+ .chosen .select_wrapper .chosen-container .chosen-drop .chosen-search input{
238
+ width: 100%!important;
239
+ }
240
+
241
+ /* typography */
242
+ .the-metabox.typography .select_wrapper.font-family { width:200px; }
243
+ .the-metabox.typography .spinner_container { float:left; margin-right:10px; }
244
+ .the-metabox.typography .spinner_container input.number {
245
+ width:50px !important;
246
+ -webkit-border-top-right-radius: 0px;
247
+ -webkit-border-bottom-right-radius: 0px;
248
+ -moz-border-radius-topright: 0px;
249
+ -moz-border-radius-bottomright: 0px;
250
+ border-top-right-radius: 0px;
251
+ border-bottom-right-radius: 0px;
252
+ }
253
+
254
+ /* number */
255
+ .the-metabox.number input.number { width:50px !important; }
256
+ /* number */
257
+ .rm_number .number {
258
+ width: 70px;
259
+ text-align: right;
260
+ -webkit-border-top-right-radius: 0px;
261
+ -webkit-border-bottom-right-radius: 0px;
262
+ -moz-border-radius-topright: 0px;
263
+ -moz-border-radius-bottomright: 0px;
264
+ border-top-right-radius: 0px;
265
+ border-bottom-right-radius: 0px;
266
+ }
267
+
268
+ .spinner-wrapper { position: relative; height: 23px; overflow: hidden; }
269
+ .spinner-wrapper input.number { float: left; }
270
+ .spinner-wrapper .spinner-button { cursor:pointer; float: left; position: absolute; left: 69px; width: 15px; height: 12px; border: 1px solid #DFDFDF; background: #fff; margin: 0; padding: 0; line-height: 9999px; overflow: hidden; background: url('../images/spinner.png') no-repeat center -11px }
271
+ .spinner-wrapper .spinner-button.button-plus { top: 0; -webkit-border-top-right-radius: 3px !important; -moz-border-radius-topright: 3px !important; border-top-right-radius: 3px !important; }
272
+ .spinner-wrapper .spinner-button.button-minus { bottom: 0; background-position: center -30px; -webkit-border-bottom-right-radius: 3px !important; -moz-border-radius-bottomright: 3px !important; border-bottom-right-radius: 3px !important; }
273
+
274
+
275
+ .spinner-wrapper .spinner-button.button-plus:active { background-position: center 0px; }
276
+ .spinner-wrapper .spinner-button.button-minus:active { background-position: center -20px; }
277
+
278
+
279
+ .rm_typography .spinner_container { float: left; margin-right: 10px; }
280
+ .rm_typography .spinner-wrapper { height: 28px; }
281
+ .rm_typography .spinner-wrapper input.number { height: 28px; }
282
+ .rm_typography .spinner-wrapper .spinner-button.button-plus { height: 15px; background-position: center -10px; }
283
+ .rm_typography .spinner-wrapper .spinner-button.button-minus { height: 14px; }
284
+
285
+ .the-metabox .spinner-wrapper .spinner-button { left: 49px; }
286
+ .the-metabox.typography .spinner-wrapper .spinner-button { left: 35px; }
287
+
288
+ /* colorpicker */
289
+ .the-metabox.colorpicker { display:block; width: auto; height: auto; overflow: visible; background-image: none; position: static; font-family: inherit;}
290
+ .the-metabox.colorpicker input { background-color: transparent; border: 1px solid #DFDFDF; position: static; font-size: inherit; font-family: inherit; color: inherit; text-align: center; margin: 0 5px 0px; padding: 0; outline: none; width: auto; }
291
+
292
+ /* images */
293
+ .the-metabox.images, .the-metabox.images label { margin-left:0; display:block; }
294
+ .the-metabox.images .slides-wrapper { clear:both; }
295
+ .the-metabox.images .slides-wrapper li { position:relative; }
296
+ .the-metabox.images a.delete { display:block; margin-left:4px; text-decoration:none; font-weight:bold; color:red; position:absolute; top:0; right:0; width:10px; height:18px; z-index:10; cursor:pointer !important; }
297
+
298
+ /* wp editor */
299
+ .wp_themeSkin iframe { background: #fff !important; }
300
+
301
+ /* custom tabs */
302
+ .customtab_item {
303
+ border-style: solid;
304
+ border-width: 1px;
305
+ line-height: 1;
306
+ margin-bottom: 20px;
307
+ padding: 0;
308
+ background-color: #F5F5F5;
309
+ background-image: -moz-linear-gradient(center top , #F9F9F9, #F5F5F5);
310
+ border-color: #DFDFDF;
311
+ border-radius: 3px 3px 3px 3px;
312
+ box-shadow: 0 1px 0 #FFFFFF inset;
313
+ min-width: 255px;
314
+ position: relative;
315
+ }
316
+ .customtab_item .handlediv { position:relative; top: -4px; }
317
+ .customtab_item h3 { min-height: 21px }
318
+ .customtab_item .inside { padding: 10px !important; }
319
+ .customtab_item .deps { display: none; }
320
+ .customtab_item .addoptions p.option { margin: 5px 0 5px 200px }
321
+ .customtab_item .addoptions p label { width: 80px !important; }
322
+ .customtab_item .add-field-option { margin-bottom: 10px !important; }
323
+ .customtab_item .remove_item { float: right; }
324
+ .metabox-sortable-placeholder { border: 1px dotted #dedede; margin: 10px 0 }
325
+
326
+ .the-metabox.customtabs {
327
+ margin-left: 0;
328
+ }
329
+
330
+ #customtab_item_sample {
331
+ display: none;
332
+ }
333
+
334
+ .the-metabox.customtabs .field-row {
335
+ margin-bottom: 10px;
336
+ }
337
+
338
+ #yit_custom_tabs label {
339
+ font-weight: normal;
340
+ width: auto;
341
+ float: none;
342
+ line-height: auto;
343
+ margin-left: 0;
344
+ }
345
+
346
+
347
+ .wp-admin p label input[type=radio]{
348
+ width: 16px;
349
+ margin-right: 10px;
350
+ margin-top: 3px;
351
+ }
352
+ .wp-admin .form-field._preset_onsale_icon_field label input[type=radio]{
353
+ margin-top: 0;
354
+ }
355
+
356
+ .the-metabox .spinner {
357
+ margin-top: 5px;
358
+ float: none;
359
+ }
360
+
361
+ /* slider */
362
+ /*numbers*/
363
+ .ui-slider .maxCaption, .ui-slider .minCaption {
364
+ margin-bottom: 5px;
365
+ }
366
+ .ui-slider .feedback {
367
+ background: url(../images/slider/tooltip.png) no-repeat center top;
368
+ position: absolute;
369
+ top: -25px;
370
+ width: 35px;
371
+ height: 43px;
372
+ text-align: center;
373
+ width: 100%;
374
+ display: block;
375
+ }
376
+ .ui-slider .feedback strong {
377
+ display: inline-block;
378
+ padding-top: 4px;
379
+ top: -30px;
380
+ }
381
+ /*handle*/
382
+ .ui-slider-horizontal .ui-slider-handle{
383
+ background: transparent url(../images/slider/handle.png) no-repeat left top !important;
384
+ border: 0px !important;
385
+ top: -.35em !important;
386
+ width: 18px !important;
387
+ height: 19px !important;
388
+ }
389
+
390
+ /*bg on the left:grey*/
391
+ .ui-slider.ui-widget-content {
392
+ background: url(../images/slider/grey.gif) repeat-x left center !important;
393
+ border-color: #c1c1c0 !important;
394
+ height: 10px !important;
395
+ }
396
+
397
+ .iris-slider-offset.ui-slider.ui-widget-content {
398
+ background: transparent!important;
399
+ height: auto!important;
400
+ }
401
+
402
+ /*bg on the right:orange*/
403
+ .ui-slider.ui-widget-content .ui-widget-header {
404
+ background: url(../images/slider/orange.gif) repeat-x left center !important;
405
+ left: 2px !important;
406
+ -webkit-border-radius: 15px;
407
+ -moz-border-radius: 15px;
408
+ -khtml-border-radius: 15px;
409
+ border-radius: 15px;
410
+ }
411
+
412
+
413
+ /*sidebars*/
414
+
415
+ #choose-sidebars.choose{
416
+ margin-left: 0px;
417
+ }
418
+
419
+
420
+ #_active_page_options-container label, #_active_page_options-container p{
421
+ display: inline-block;
422
+ margin: 0px;
423
+ }
424
+ #_active_page_options-container label{
425
+ margin-right: 10px;
426
+ margin-top: 3px;
427
+ }
428
+ #_active_page_options-container {
429
+ float: right;
430
+ margin-right: 20px;
431
+ margin-top: 5px;
432
+ }
433
+
434
+ /* sortable table posts */
435
+
436
+ #the-list.ui-sortable tr:hover {
437
+ cursor: move;
438
+ }
439
+
440
+
441
+ /*datepicker*/
442
+ /*! jQuery UI - v1.11.2 - 2015-01-21
443
+ * http://jqueryui.com
444
+ * Includes: core.css, datepicker.css, theme.css
445
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=0px&bgColorHeader=%23dddddd&bgTextureHeader=flat&bgImgOpacityHeader=60&borderColorHeader=%23aaaaaa&fcHeader=%23222222&iconColorHeader=%23222222&bgColorContent=%23ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=%23aaaaaa&fcContent=%23222222&iconColorContent=%23222222&bgColorDefault=%23e9e9e9&bgTextureDefault=flat&bgImgOpacityDefault=75&borderColorDefault=%23d3d3d3&fcDefault=%23555555&iconColorDefault=%23888888&bgColorHover=%23dadada&bgTextureHover=flat&bgImgOpacityHover=75&borderColorHover=%23999999&fcHover=%23212121&iconColorHover=%23454545&bgColorActive=%23ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=%23aaaaaa&fcActive=%23212121&iconColorActive=%23454545&bgColorHighlight=%23fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=%2389b17e&fcHighlight=%23363636&iconColorHighlight=%232e83ff&bgColorError=%23fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=%23cd0a0a&fcError=%23cd0a0a&iconColorError=%23cd0a0a&bgColorOverlay=%23aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=%23aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
446
+ * Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
447
+
448
+ /* Layout helpers
449
+ ----------------------------------*/
450
+ .ui-helper-hidden {
451
+ display: none;
452
+ }
453
+ .ui-helper-hidden-accessible {
454
+ border: 0;
455
+ clip: rect(0 0 0 0);
456
+ height: 1px;
457
+ margin: -1px;
458
+ overflow: hidden;
459
+ padding: 0;
460
+ position: absolute;
461
+ width: 1px;
462
+ }
463
+ .ui-helper-reset {
464
+ margin: 0;
465
+ padding: 0;
466
+ border: 0;
467
+ outline: 0;
468
+ line-height: 1.3;
469
+ text-decoration: none;
470
+ font-size: 100%;
471
+ list-style: none;
472
+ }
473
+ .ui-helper-clearfix:before,
474
+ .ui-helper-clearfix:after {
475
+ content: "";
476
+ display: table;
477
+ border-collapse: collapse;
478
+ }
479
+ .ui-helper-clearfix:after {
480
+ clear: both;
481
+ }
482
+ .ui-helper-clearfix {
483
+ min-height: 0; /* support: IE7 */
484
+ }
485
+ .ui-helper-zfix {
486
+ width: 100%;
487
+ height: 100%;
488
+ top: 0;
489
+ left: 0;
490
+ position: absolute;
491
+ opacity: 0;
492
+ filter:Alpha(Opacity=0); /* support: IE8 */
493
+ }
494
+
495
+ .ui-front {
496
+ z-index: 100;
497
+ }
498
+
499
+
500
+ /* Interaction Cues
501
+ ----------------------------------*/
502
+ .ui-state-disabled {
503
+ cursor: default !important;
504
+ }
505
+
506
+
507
+ /* Icons
508
+ ----------------------------------*/
509
+
510
+ /* states and images */
511
+ .ui-icon {
512
+ display: block;
513
+ text-indent: -99999px;
514
+ overflow: hidden;
515
+ background-repeat: no-repeat;
516
+ }
517
+
518
+
519
+ /* DATE PICKER
520
+ ----------------------------------*/
521
+
522
+ .ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}
523
+ .ui-datepicker{width:17em;padding:.2em .2em 0;display:none;z-index:100!important;}
524
+ .ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}
525
+ .ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}
526
+ .ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}
527
+ .ui-datepicker .ui-datepicker-prev{left:2px}
528
+ .ui-datepicker .ui-datepicker-next{right:2px}
529
+ .ui-datepicker .ui-datepicker-prev-hover{left:1px}
530
+ .ui-datepicker .ui-datepicker-next-hover{right:1px}
531
+ .ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}
532
+ .ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}
533
+ .ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}
534
+ .ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}
535
+ .ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}
536
+ .ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:700;border:0}
537
+ .ui-datepicker td{border:0;padding:1px}
538
+ .ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}
539
+ .ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}
540
+ .ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em;width:auto;overflow:visible}
541
+ .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}
542
+ .ui-datepicker.ui-datepicker-multi{width:auto}
543
+ .ui-datepicker-multi .ui-datepicker-group{float:left}
544
+ .ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}
545
+ .ui-datepicker-multi-2 .ui-datepicker-group{width:50%}
546
+ .ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}
547
+ .ui-datepicker-multi-4 .ui-datepicker-group{width:25%}
548
+ .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}
549
+ .ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}
550
+ .ui-datepicker-row-break{clear:both;width:100%;font-size:0}
551
+ .ui-datepicker-rtl{direction:rtl}
552
+ .ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}
553
+ .ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}
554
+ .ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}
555
+ .ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}
556
+ .ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}
557
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}
558
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}
559
+ .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}
560
+ .ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}
561
+ .ui-widget .ui-widget{font-size:1em}
562
+ .ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}
563
+ .ui-widget-content{border:1px solid #aaa;background:#fff 50% 50% repeat-x;color:#222}
564
+ .ui-widget-content a{color:#222}
565
+ .ui-widget-header{border:1px solid #aaa;background:#ddd 50% 50% repeat-x;color:#222;font-weight:700}
566
+ .ui-widget-header a{color:#222}
567
+ .ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:0 solid #d3d3d3;background:#e9e9e9 50% 50% repeat-x;font-weight:400;color:#555}
568
+ .ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}
569
+ .ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:0 solid #999;background:#dadada 50% 50% repeat-x;font-weight:400;color:#212121}
570
+ .ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#212121;text-decoration:none}
571
+ .ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:0 solid #aaa;background:#fff 50% 50% repeat-x;font-weight:400;color:#212121}
572
+ .ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}
573
+ .ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:0 solid #89b17e;background:#fbf9ee 50% 50% repeat-x;color:#363636}
574
+ .ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}
575
+ .ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:0 solid #cd0a0a;background:#fef1ec 50% 50% repeat-x;color:#cd0a0a}
576
+ .ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}
577
+ .ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}
578
+ .ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:700}
579
+ .ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:400}
580
+ .ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}
581
+ .ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}
582
+ .ui-icon{width:16px;height:16px}
583
+ .ui-icon,.ui-widget-content .ui-icon{background-image:url(../images/ui-icons_222222_256x240.png)}
584
+ .ui-widget-header .ui-icon{background-image:url(../images/ui-icons_222222_256x240.png)}
585
+ .ui-state-default .ui-icon{background-image:url(../images/ui-icons_888888_256x240.png)}
586
+ .ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(../images/ui-icons_454545_256x240.png)}
587
+ .ui-state-active .ui-icon{background-image:url(../images/ui-icons_454545_256x240.png)}
588
+ .ui-state-highlight .ui-icon{background-image:url(../images/ui-icons_2e83ff_256x240.png)}
589
+ .ui-icon-circle-triangle-e{background-position:-48px -192px}
590
+ .ui-icon-circle-triangle-s{background-position:-64px -192px}
591
+ .ui-icon-circle-triangle-w{background-position:-80px -192px}
592
+ .ui-icon-circle-triangle-n{background-position:-96px -192px}
593
+ .ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:0}
594
+ .ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:0}
595
+ .ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:0}
596
+ .ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:0}
597
+ .ui-widget-overlay{background:#aaa 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}
598
+ .ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}
plugin-fw/assets/css/overcast/images/ui-bg_flat_0_aaaaaa_40x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_flat_0_eeeeee_40x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_flat_55_c0402a_40x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_flat_55_eeeeee_40x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_glass_100_f8f8f8_1x400.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_glass_35_dddddd_1x400.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_glass_60_eeeeee_1x400.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_inset-hard_75_999999_1x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-bg_inset-soft_50_c9c9c9_1x100.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_3383bb_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_454545_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_70b2e1_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_999999_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/images/ui-icons_fbc856_256x240.png ADDED
Binary file
plugin-fw/assets/css/overcast/jquery-ui-1.8.9.custom.css ADDED
@@ -0,0 +1,322 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * jQuery UI CSS Framework 1.8.8
3
+ *
4
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT or GPL Version 2 licenses.
6
+ * http://jquery.org/license
7
+ *
8
+ * http://docs.jquery.com/UI/Theming/API
9
+ */
10
+
11
+ /* Layout helpers
12
+ ----------------------------------*/
13
+ .ui-helper-hidden { display: none; }
14
+ .ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); }
15
+ .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
16
+ .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
17
+ .ui-helper-clearfix { display: inline-block; }
18
+ /* required comment for clearfix to work in Opera \*/
19
+ * html .ui-helper-clearfix { height:1%; }
20
+ .ui-helper-clearfix { display:block; }
21
+ /* end clearfix */
22
+ .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
23
+
24
+
25
+ /* Interaction Cues
26
+ ----------------------------------*/
27
+ .ui-state-disabled { cursor: default !important; }
28
+
29
+
30
+ /* Icons
31
+ ----------------------------------*/
32
+
33
+ /* states and images */
34
+ .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
35
+
36
+
37
+ /* Misc visuals
38
+ ----------------------------------*/
39
+
40
+ /* Overlays */
41
+ .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
42
+
43
+
44
+ /*
45
+ * jQuery UI CSS Framework 1.8.8
46
+ *
47
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
48
+ * Dual licensed under the MIT or GPL Version 2 licenses.
49
+ * http://jquery.org/license
50
+ *
51
+ * http://docs.jquery.com/UI/Theming/API
52
+ *
53
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Helvetica,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=6px&bgColorHeader=dddddd&bgTextureHeader=02_glass.png&bgImgOpacityHeader=35&borderColorHeader=bbbbbb&fcHeader=444444&iconColorHeader=999999&bgColorContent=c9c9c9&bgTextureContent=05_inset_soft.png&bgImgOpacityContent=50&borderColorContent=aaaaaa&fcContent=333333&iconColorContent=999999&bgColorDefault=eeeeee&bgTextureDefault=02_glass.png&bgImgOpacityDefault=60&borderColorDefault=cccccc&fcDefault=3383bb&iconColorDefault=70b2e1&bgColorHover=f8f8f8&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=bbbbbb&fcHover=599fcf&iconColorHover=3383bb&bgColorActive=999999&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=75&borderColorActive=999999&fcActive=ffffff&iconColorActive=454545&bgColorHighlight=eeeeee&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=ffffff&fcHighlight=444444&iconColorHighlight=3383bb&bgColorError=c0402a&bgTextureError=01_flat.png&bgImgOpacityError=55&borderColorError=c0402a&fcError=ffffff&iconColorError=fbc856&bgColorOverlay=eeeeee&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=80&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=60&thicknessShadow=4px&offsetTopShadow=-4px&offsetLeftShadow=-4px&cornerRadiusShadow=0pxdow=0px
54
+ */
55
+
56
+
57
+ /* Component containers
58
+ ----------------------------------*/
59
+ .ui-widget { font-family: Trebuchet MS, Helvetica, Arial, sans-serif; font-size: 1.1em; }
60
+ .ui-widget .ui-widget { font-size: 1em; }
61
+ .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Helvetica, Arial, sans-serif; font-size: 1em; }
62
+ .ui-widget-content { border: 1px solid #aaaaaa; background: #f1f1f1; color: #333333; }
63
+ .ui-widget-content a { color: #333333; }
64
+ .ui-widget-header { border: 1px solid #bbbbbb; background: #ccc; color: #444444; font-weight: bold; }
65
+ .ui-widget-header a { color: #444444; }
66
+
67
+ /* Interaction states
68
+ ----------------------------------*/
69
+ .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #eeeeee url(images/ui-bg_glass_60_eeeeee_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #3383bb; }
70
+ .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #3383bb; text-decoration: none; }
71
+ .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #bbbbbb; background: #f8f8f8 url(images/ui-bg_glass_100_f8f8f8_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #599fcf; }
72
+ .ui-state-hover a, .ui-state-hover a:hover { color: #599fcf; text-decoration: none; }
73
+ .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #999999; background: #999999 url(images/ui-bg_inset-hard_75_999999_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #ffffff; }
74
+ .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff; text-decoration: none; }
75
+ .ui-widget :active { outline: none; }
76
+
77
+ /* Interaction Cues
78
+ ----------------------------------*/
79
+ .ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #ffffff; background: #eeeeee url(images/ui-bg_flat_55_eeeeee_40x100.png) 50% 50% repeat-x; color: #444444; }
80
+ .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #444444; }
81
+ .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #c0402a; background: #c0402a url(images/ui-bg_flat_55_c0402a_40x100.png) 50% 50% repeat-x; color: #ffffff; }
82
+ .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }
83
+ .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }
84
+ .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }
85
+ .ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
86
+ .ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
87
+ .ui-sortable-placeholder { border: 1px dotted black; visibility: visible !important; }
88
+ .ui-sortable-placeholder * { visibility: hidden; }
89
+
90
+ /* Icons
91
+ ----------------------------------*/
92
+
93
+ /* states and images */
94
+ /*.ui-widget-content .ui-icon {background-image: url(images/ui-icons_999999_256x240.png); }
95
+ .ui-widget-header .ui-icon {background-image: url(images/ui-icons_999999_256x240.png); } */
96
+ .ui-state-default .ui-icon { background-image: url(images/ui-icons_70b2e1_256x240.png); }
97
+ /*.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_3383bb_256x240.png); }
98
+ .ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); }
99
+ .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_3383bb_256x240.png); }
100
+ .ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_fbc856_256x240.png); } */
101
+
102
+ /* positioning */
103
+ /*.ui-icon-carat-1-n { background-position: 0 0; }
104
+ .ui-icon-carat-1-ne { background-position: -16px 0; }
105
+ .ui-icon-carat-1-e { background-position: -32px 0; }
106
+ .ui-icon-carat-1-se { background-position: -48px 0; }
107
+ .ui-icon-carat-1-s { background-position: -64px 0; }
108
+ .ui-icon-carat-1-sw { background-position: -80px 0; }
109
+ .ui-icon-carat-1-w { background-position: -96px 0; }
110
+ .ui-icon-carat-1-nw { background-position: -112px 0; }
111
+ .ui-icon-carat-2-n-s { background-position: -128px 0; }
112
+ .ui-icon-carat-2-e-w { background-position: -144px 0; }
113
+ .ui-icon-triangle-1-n { background-position: 0 -16px; }
114
+ .ui-icon-triangle-1-ne { background-position: -16px -16px; }
115
+ .ui-icon-triangle-1-e { background-position: -32px -16px; }
116
+ .ui-icon-triangle-1-se { background-position: -48px -16px; }
117
+ .ui-icon-triangle-1-s { background-position: -64px -16px; }
118
+ .ui-icon-triangle-1-sw { background-position: -80px -16px; }
119
+ .ui-icon-triangle-1-w { background-position: -96px -16px; }
120
+ .ui-icon-triangle-1-nw { background-position: -112px -16px; }
121
+ .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
122
+ .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
123
+ .ui-icon-arrow-1-n { background-position: 0 -32px; }
124
+ .ui-icon-arrow-1-ne { background-position: -16px -32px; }
125
+ .ui-icon-arrow-1-e { background-position: -32px -32px; }
126
+ .ui-icon-arrow-1-se { background-position: -48px -32px; }
127
+ .ui-icon-arrow-1-s { background-position: -64px -32px; }
128
+ .ui-icon-arrow-1-sw { background-position: -80px -32px; }
129
+ .ui-icon-arrow-1-w { background-position: -96px -32px; }
130
+ .ui-icon-arrow-1-nw { background-position: -112px -32px; }
131
+ .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
132
+ .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
133
+ .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
134
+ .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
135
+ .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
136
+ .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
137
+ .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
138
+ .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
139
+ .ui-icon-arrowthick-1-n { background-position: 0 -48px; }
140
+ .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
141
+ .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
142
+ .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
143
+ .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
144
+ .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
145
+ .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
146
+ .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
147
+ .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
148
+ .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
149
+ .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
150
+ .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
151
+ .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
152
+ .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
153
+ .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
154
+ .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
155
+ .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
156
+ .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
157
+ .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
158
+ .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
159
+ .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
160
+ .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
161
+ .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
162
+ .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
163
+ .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
164
+ .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
165
+ .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
166
+ .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
167
+ .ui-icon-arrow-4 { background-position: 0 -80px; }
168
+ .ui-icon-arrow-4-diag { background-position: -16px -80px; }
169
+ .ui-icon-extlink { background-position: -32px -80px; }
170
+ .ui-icon-newwin { background-position: -48px -80px; }
171
+ .ui-icon-refresh { background-position: -64px -80px; }
172
+ .ui-icon-shuffle { background-position: -80px -80px; }
173
+ .ui-icon-transfer-e-w { background-position: -96px -80px; }
174
+ .ui-icon-transferthick-e-w { background-position: -112px -80px; }
175
+ .ui-icon-folder-collapsed { background-position: 0 -96px; }
176
+ .ui-icon-folder-open { background-position: -16px -96px; }
177
+ .ui-icon-document { background-position: -32px -96px; }
178
+ .ui-icon-document-b { background-position: -48px -96px; }
179
+ .ui-icon-note { background-position: -64px -96px; }
180
+ .ui-icon-mail-closed { background-position: -80px -96px; }
181
+ .ui-icon-mail-open { background-position: -96px -96px; }
182
+ .ui-icon-suitcase { background-position: -112px -96px; }
183
+ .ui-icon-comment { background-position: -128px -96px; }
184
+ .ui-icon-person { background-position: -144px -96px; }
185
+ .ui-icon-print { background-position: -160px -96px; }
186
+ .ui-icon-trash { background-position: -176px -96px; }
187
+ .ui-icon-locked { background-position: -192px -96px; }
188
+ .ui-icon-unlocked { background-position: -208px -96px; }
189
+ .ui-icon-bookmark { background-position: -224px -96px; }
190
+ .ui-icon-tag { background-position: -240px -96px; }
191
+ .ui-icon-home { background-position: 0 -112px; }
192
+ .ui-icon-flag { background-position: -16px -112px; }
193
+ .ui-icon-calendar { background-position: -32px -112px; }
194
+ .ui-icon-cart { background-position: -48px -112px; }
195
+ .ui-icon-pencil { background-position: -64px -112px; }
196
+ .ui-icon-clock { background-position: -80px -112px; }
197
+ .ui-icon-disk { background-position: -96px -112px; }
198
+ .ui-icon-calculator { background-position: -112px -112px; }
199
+ .ui-icon-zoomin { background-position: -128px -112px; }
200
+ .ui-icon-zoomout { background-position: -144px -112px; }
201
+ .ui-icon-search { background-position: -160px -112px; }
202
+ .ui-icon-wrench { background-position: -176px -112px; }
203
+ .ui-icon-gear { background-position: -192px -112px; }
204
+ .ui-icon-heart { background-position: -208px -112px; }
205
+ .ui-icon-star { background-position: -224px -112px; }
206
+ .ui-icon-link { background-position: -240px -112px; }
207
+ .ui-icon-cancel { background-position: 0 -128px; } */
208
+ .ui-icon-plus { background-position: -16px -128px; }
209
+ .ui-icon-minus { background-position: -48px -128px; }
210
+ .ui-icon-minusthick { background-position: -64px -128px; }
211
+ /*.ui-icon-plusthick { background-position: -32px -128px; }
212
+ .ui-icon-close { background-position: -80px -128px; }
213
+ .ui-icon-closethick { background-position: -96px -128px; }
214
+ .ui-icon-key { background-position: -112px -128px; }
215
+ .ui-icon-lightbulb { background-position: -128px -128px; }
216
+ .ui-icon-scissors { background-position: -144px -128px; }
217
+ .ui-icon-clipboard { background-position: -160px -128px; }
218
+ .ui-icon-copy { background-position: -176px -128px; }
219
+ .ui-icon-contact { background-position: -192px -128px; }
220
+ .ui-icon-image { background-position: -208px -128px; }
221
+ .ui-icon-video { background-position: -224px -128px; }
222
+ .ui-icon-script { background-position: -240px -128px; }
223
+ .ui-icon-alert { background-position: 0 -144px; }
224
+ .ui-icon-info { background-position: -16px -144px; }
225
+ .ui-icon-notice { background-position: -32px -144px; }
226
+ .ui-icon-help { background-position: -48px -144px; }
227
+ .ui-icon-check { background-position: -64px -144px; }
228
+ .ui-icon-bullet { background-position: -80px -144px; }
229
+ .ui-icon-radio-off { background-position: -96px -144px; }
230
+ .ui-icon-radio-on { background-position: -112px -144px; }
231
+ .ui-icon-pin-w { background-position: -128px -144px; }
232
+ .ui-icon-pin-s { background-position: -144px -144px; }
233
+ .ui-icon-play { background-position: 0 -160px; }
234
+ .ui-icon-pause { background-position: -16px -160px; }
235
+ .ui-icon-seek-next { background-position: -32px -160px; }
236
+ .ui-icon-seek-prev { background-position: -48px -160px; }
237
+ .ui-icon-seek-end { background-position: -64px -160px; }
238
+ .ui-icon-seek-start { background-position: -80px -160px; } */
239
+ /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
240
+ /*.ui-icon-seek-first { background-position: -80px -160px; }
241
+ .ui-icon-stop { background-position: -96px -160px; }
242
+ .ui-icon-eject { background-position: -112px -160px; }
243
+ .ui-icon-volume-off { background-position: -128px -160px; }
244
+ .ui-icon-volume-on { background-position: -144px -160px; }
245
+ .ui-icon-power { background-position: 0 -176px; }
246
+ .ui-icon-signal-diag { background-position: -16px -176px; }
247
+ .ui-icon-signal { background-position: -32px -176px; }
248
+ .ui-icon-battery-0 { background-position: -48px -176px; }
249
+ .ui-icon-battery-1 { background-position: -64px -176px; }
250
+ .ui-icon-battery-2 { background-position: -80px -176px; }
251
+ .ui-icon-battery-3 { background-position: -96px -176px; }
252
+ .ui-icon-circle-plus { background-position: 0 -192px; }
253
+ .ui-icon-circle-minus { background-position: -16px -192px; }
254
+ .ui-icon-circle-close { background-position: -32px -192px; }
255
+ .ui-icon-circle-triangle-e { background-position: -48px -192px; }
256
+ .ui-icon-circle-triangle-s { background-position: -64px -192px; }
257
+ .ui-icon-circle-triangle-w { background-position: -80px -192px; }
258
+ .ui-icon-circle-triangle-n { background-position: -96px -192px; }
259
+ .ui-icon-circle-arrow-e { background-position: -112px -192px; }
260
+ .ui-icon-circle-arrow-s { background-position: -128px -192px; }
261
+ .ui-icon-circle-arrow-w { background-position: -144px -192px; }
262
+ .ui-icon-circle-arrow-n { background-position: -160px -192px; }
263
+ .ui-icon-circle-zoomin { background-position: -176px -192px; }
264
+ .ui-icon-circle-zoomout { background-position: -192px -192px; }
265
+ .ui-icon-circle-check { background-position: -208px -192px; }
266
+ .ui-icon-circlesmall-plus { background-position: 0 -208px; }
267
+ .ui-icon-circlesmall-minus { background-position: -16px -208px; }
268
+ .ui-icon-circlesmall-close { background-position: -32px -208px; }
269
+ .ui-icon-squaresmall-plus { background-position: -48px -208px; }
270
+ .ui-icon-squaresmall-minus { background-position: -64px -208px; }
271
+ .ui-icon-squaresmall-close { background-position: -80px -208px; }
272
+ .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
273
+ .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
274
+ .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
275
+ .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
276
+ .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
277
+ .ui-icon-grip-diagonal-se { background-position: -80px -224px; } */
278
+
279
+
280
+ /* Misc visuals
281
+ ----------------------------------*/
282
+
283
+ /* Corner radius */
284
+ .ui-corner-tl { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; }
285
+ .ui-corner-tr { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }
286
+ .ui-corner-bl { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
287
+ .ui-corner-br { -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
288
+ .ui-corner-top { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; }
289
+ .ui-corner-bottom { -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
290
+ .ui-corner-right { -moz-border-radius-topright: 6px; -webkit-border-top-right-radius: 6px; border-top-right-radius: 6px; -moz-border-radius-bottomright: 6px; -webkit-border-bottom-right-radius: 6px; border-bottom-right-radius: 6px; }
291
+ .ui-corner-left { -moz-border-radius-topleft: 6px; -webkit-border-top-left-radius: 6px; border-top-left-radius: 6px; -moz-border-radius-bottomleft: 6px; -webkit-border-bottom-left-radius: 6px; border-bottom-left-radius: 6px; }
292
+ .ui-corner-all { -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
293
+
294
+ /* Overlays */
295
+ .ui-widget-overlay { background: #eeeeee url(images/ui-bg_flat_0_eeeeee_40x100.png) 50% 50% repeat-x; opacity: .80;filter:Alpha(Opacity=80); }
296
+ .ui-widget-shadow { margin: -4px 0 0 -4px; padding: 4px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .60;filter:Alpha(Opacity=60); -moz-border-radius: 0pxdow=0px; -webkit-border-radius: 0pxdow=0px; border-radius: 0pxdow=0px; }/*
297
+ * jQuery UI Slider 1.8.8
298
+ *
299
+ * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
300
+ * Dual licensed under the MIT or GPL Version 2 licenses.
301
+ * http://jquery.org/license
302
+ *
303
+ * http://docs.jquery.com/UI/Slider#theming
304
+ */
305
+ .ui-slider { position: relative; text-align: left; width:340px; float:left }
306
+ .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }
307
+ .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }
308
+ .ui-slider .minCaption { float: left }
309
+ .ui-slider .maxCaption { float: right }
310
+ .ui-slider .feedback { text-align:center; width:100%; display:block }
311
+
312
+ .ui-slider-horizontal { height: .8em; }
313
+ .ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }
314
+ .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }
315
+ .ui-slider-horizontal .ui-slider-range-min { left: 0; }
316
+ .ui-slider-horizontal .ui-slider-range-max { right: 0; }
317
+
318
+ .ui-slider-vertical { width: .8em; height: 100px; }
319
+ .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }
320
+ .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }
321
+ .ui-slider-vertical .ui-slider-range-min { bottom: 0; }
322
+ .ui-slider-vertical .ui-slider-range-max { top: 0; }
plugin-fw/assets/css/yit-plugin-panel.css ADDED
@@ -0,0 +1,599 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * This file belongs to the YIT Plugin Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+ /* onoff */
11
+ .rm_onoff input {
12
+ display: none;
13
+ }
14
+
15
+ .rm_onoff input + span {
16
+ cursor: pointer;
17
+ text-indent: -9999px;
18
+ display: block;
19
+ width: 85px;
20
+ height: 37px;
21
+ background: transparent url(../images/off.png);
22
+ }
23
+
24
+ .rm_onoff input:checked + span {
25
+ background: transparent url(../images/on.png);
26
+ }
27
+
28
+ .rm_onoff input.onoffchecked + span {
29
+ background: transparent url(../images/on.png);
30
+ }
31
+
32
+ /* slider */
33
+ /*numbers*/
34
+ .ui-slider .maxCaption, .ui-slider .minCaption {
35
+ margin-bottom: 5px;
36
+ }
37
+ .ui-slider .feedback {
38
+ background: url(../images/slider/tooltip.png) no-repeat center top;
39
+ position: absolute;
40
+ top: -25px;
41
+ width: 35px;
42
+ height: 43px;
43
+ text-align: center;
44
+ width: 100%;
45
+ display: block;
46
+ }
47
+ .ui-slider .feedback strong {
48
+ display: inline-block;
49
+ padding-top: 4px;
50
+ top: -30px;
51
+ }
52
+ /*handle*/
53
+ .yit-options .ui-slider-horizontal .ui-slider-handle {
54
+ background: transparent url(../images/slider/handle.png) no-repeat left top !important;
55
+ border: 0px !important;
56
+ top: -.35em !important;
57
+ width: 18px !important;
58
+ height: 19px !important;
59
+ }
60
+
61
+ /*bg on the left:grey*/
62
+ .yit-options .ui-slider.ui-widget-content {
63
+ background: url(../images/slider/grey.gif) repeat-x left center !important;
64
+ border-color: #c1c1c0 !important;
65
+ height: 10px !important;
66
+ }
67
+
68
+ .iris-slider-offset.ui-slider.ui-widget-content {
69
+ background: transparent!important;
70
+ height: auto!important;
71
+ }
72
+
73
+ /*bg on the right:orange*/
74
+ .ui-slider.ui-widget-content .ui-widget-header {
75
+ background: url(../images/slider/orange.gif) repeat-x left center !important;
76
+ left: 2px !important;
77
+ -webkit-border-radius: 15px;
78
+ -moz-border-radius: 15px;
79
+ -khtml-border-radius: 15px;
80
+ border-radius: 15px;
81
+ }
82
+
83
+ .plugin-option tr{
84
+ border-bottom: 1px solid #ccc;
85
+ }
86
+ .plugin-option .yit_options{
87
+ border-bottom: 0px;
88
+ }
89
+ .plugin-option .yit_options .option {
90
+ width: 600px;
91
+ float: left;
92
+ }
93
+
94
+ .plugin-option .form-table td{
95
+ padding: 25px 10px;
96
+ }
97
+
98
+ .yit-options .select_wrapper {
99
+ background: url("../images/select.png") no-repeat scroll right center #FAFAFA;
100
+ border-color: #CCCCCC #EEEEEE #EEEEEE #CCCCCC;
101
+ border-radius: 4px 4px 4px 4px;
102
+ border-style: solid;
103
+ border-width: 1px;
104
+ color: #555555;
105
+ display: block;
106
+ float: left;
107
+ font-family: sans-serif;
108
+ font-size: 12px;
109
+ height: 26px;
110
+ margin-bottom: 9px !important;
111
+ margin-left: 0;
112
+ margin-right: 5px;
113
+ margin-top: 0;
114
+ width: 400px;
115
+ }
116
+ .chosen .select_wrapper {
117
+ background: none;
118
+ border: none;
119
+ }
120
+ .chosen .select_wrapper .chosen-container{
121
+ width: 338px!important;
122
+ }
123
+ .chosen .select_wrapper .chosen-container .search-field input{
124
+ height: 27px!important;
125
+ color: #333;
126
+ }
127
+ .chosen .select_wrapper .chosen-container .chosen-choices{
128
+ border: 1px solid #ddd;
129
+ box-shadow: none;
130
+ }
131
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice{
132
+ height: 15px!important;
133
+ min-width: 105px;
134
+ }
135
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice span{
136
+ line-height: 15px;
137
+ height: 15px;
138
+ padding-top: 2px;
139
+ }
140
+ .chosen .select_wrapper .chosen-container .chosen-choices li.search-choice a.search-choice-close{
141
+ top: 5px;
142
+ }
143
+ .chosen .select_wrapper .chosen-container .chosen-drop .chosen-search input{
144
+ width: 100%!important;
145
+ }
146
+ .select_wrapper span {
147
+ height: 26px;
148
+ line-height: 26px;
149
+ padding-left: 6px;
150
+ position: absolute;
151
+ z-index: 2;
152
+ }
153
+ .ie8 .yit_options select {
154
+ height: 26px;
155
+ }
156
+ .yit_options select, .the-metabox .select_wrapper select {
157
+ cursor: pointer;
158
+ height: 28px;
159
+ margin: 0;
160
+ opacity: 0;
161
+ padding: 0;
162
+ position: relative;
163
+ width: inherit;
164
+ z-index: 4;
165
+ background-color: #FAFAFA;
166
+ }
167
+
168
+
169
+ /* Style to woocommerce panel*/
170
+ #plugin-fw-wc{
171
+ padding-top: 20px;
172
+ }
173
+ #plugin-fw-wc table.form-table{
174
+ background-color: #fff;
175
+ margin-bottom: 20px;
176
+ }
177
+ #plugin-fw-wc table.form-table th {
178
+ padding: 20px;
179
+ }
180
+ #plugin-fw-wc h3{
181
+ padding:0px 10px 10px ;
182
+ border-bottom: 1px solid #eee;
183
+ }
184
+ #plugin-fw-wc .yith_videobox .column{
185
+ width: 45%;
186
+ float: left;
187
+ padding-right: 2.5%;
188
+ border-right: 1px solid #ebebeb;
189
+ padding-bottom: 2em;
190
+ }
191
+ #plugin-fw-wc .yith_videobox .column.two{
192
+ margin-right: 0;
193
+ padding-right: 0;
194
+ padding-left: 2.5%;
195
+ border: 0;
196
+ max-width: 49%;
197
+ }
198
+ #plugin-fw-wc .yith_videobox h2{
199
+ font-size: 16px;
200
+ margin-bottom: 20px;
201
+ }
202
+ #plugin-fw-wc .postbox .inside{
203
+ display: inline-block;
204
+ }
205
+ #plugin-fw-wc .yith-video-link {
206
+ width: 100%;
207
+ max-width: 200px;
208
+ float: left;
209
+ margin: 0 1.5em 1.5em 0;
210
+ }
211
+ #plugin-fw-wc .yith-video-link {
212
+ width: 100%;
213
+ max-width: 200px;
214
+ float: left;
215
+ margin: 0 1.5em 1.5em 0;
216
+ }
217
+ #plugin-fw-wc .yith-image-frame img {
218
+ max-width: 100%;
219
+ height: auto;
220
+ }
221
+
222
+ #plugin-fw-wc .yith-video-link img {
223
+ max-width: 100%;
224
+ height: auto;
225
+ }
226
+ #plugin-fw-wc .yith-video-iframe {
227
+ display: none;
228
+
229
+ }
230
+
231
+ /* === Plugins Upgrader === */
232
+
233
+ .yit-plugin-changelog-wrapper {
234
+ display: none;
235
+ }
236
+
237
+ .yit-plugin-changelog-title {
238
+ text-transform: uppercase;
239
+ }
240
+
241
+ .yit-plugin-changelog {
242
+ background: #fcfcfc;
243
+ height: 97%;
244
+ z-index: 999;
245
+ overflow: auto;
246
+ }
247
+
248
+ /* === Plugins Licence Activation === */
249
+
250
+ .yit-container.plugin-licence-activation {
251
+ font-family: 'Raleway', sans-serif;
252
+ }
253
+
254
+ .yit-container.plugin-licence-activation .to-active-wrapper {
255
+ margin-bottom: 60px;
256
+ }
257
+
258
+ .yit-container.plugin-licence-activation .to-active-wrapper form.to-active-form {
259
+ position: relative;
260
+ border-color: #e1e1e1;
261
+ border-style: solid;
262
+ border-width: 0;
263
+ }
264
+
265
+ .yit-container.plugin-licence-activation .to-active-wrapper form.to-active-form:first-child {
266
+ border-top-width: 1px;
267
+ }
268
+
269
+ .yit-container.plugin-licence-activation .to-active-wrapper form.to-active-form:last-child {
270
+ border-bottom-width: 1px;
271
+ }
272
+
273
+ .yit-container.plugin-licence-activation .to-active-wrapper table.to-active-table {
274
+ border-width: 0;
275
+ border-spacing: 0;
276
+ width: 100%;
277
+ }
278
+
279
+ .yit-container.plugin-licence-activation .message {
280
+ display: none;
281
+ line-height: normal;
282
+ background: #ffffff url(../images/licence-error.png) 15px center no-repeat;
283
+ padding-left: 65px;
284
+ padding-right: 15px;
285
+ width: 150px;
286
+ }
287
+
288
+ .yit-container.plugin-licence-activation .message-wrapper {
289
+ height: 75px;
290
+ display: none;
291
+ position: absolute;
292
+ top: 0;
293
+ right: -250px;
294
+ border: 1px solid #ff3838;
295
+ }
296
+
297
+ .yit-container.plugin-licence-activation .message-wrapper.visible {
298
+ display: table;
299
+ }
300
+
301
+ .yit-container.plugin-licence-activation .message {
302
+ display: table-cell;
303
+ vertical-align: middle;
304
+ }
305
+
306
+ .yit-container.plugin-licence-activation .arrow-left:after,
307
+ .yit-container.plugin-licence-activation .arrow-left:before {
308
+ content: "";
309
+ display: block;
310
+ width: 0;
311
+ height: 0;
312
+ position: absolute;
313
+ }
314
+
315
+ .yit-container.plugin-licence-activation .arrow-left:before {
316
+ border-top: 9px solid transparent;
317
+ border-bottom: 9px solid transparent;
318
+ border-right: 9px solid #ff3838;
319
+ top: 26px;
320
+ left: -9px;
321
+ }
322
+
323
+ .yit-container.plugin-licence-activation .arrow-left:after {
324
+ border-top: 8px solid transparent;
325
+ border-bottom: 8px solid transparent;
326
+ border-right: 8px solid #fff;
327
+ left: -8px;
328
+ top: 27px;
329
+ }
330
+
331
+ .yit-container.plugin-licence-activation h2,
332
+ .yit-container.plugin-licence-activation h3 {
333
+ text-transform: uppercase;
334
+ font-weight: 800;
335
+ margin-bottom: 30px;
336
+ }
337
+
338
+ .yit-container.plugin-licence-activation h2 {
339
+ color: #808a97;
340
+ font-size: 25px;
341
+ }
342
+ .yit-container.plugin-licence-activation h3 {
343
+ color: #313131;
344
+ font-size: 15px;
345
+ height: 20px;
346
+ }
347
+
348
+ .yit-container.plugin-licence-activation h3.to-active {
349
+ height: 20px;
350
+ position: relative;
351
+ vertical-align: top;
352
+ }
353
+
354
+ .yit-container.plugin-licence-activation .spinner.show{
355
+ display: inline-block;
356
+ vertical-align: middle;
357
+ float: none;
358
+ }
359
+
360
+ .yit-container.plugin-licence-activation h3.to-active > .spinner.show {
361
+ display: inline-block;
362
+ float: none;
363
+ top: -3px;
364
+ position: relative;
365
+ }
366
+
367
+ .yit-container.plugin-licence-activation .licence-check-section{
368
+ margin-bottom: 60px;
369
+ }
370
+
371
+ .yit-container.plugin-licence-activation span.licence-label {
372
+ font-weight: 500;
373
+ color: #606060;
374
+ margin-bottom: 30px;
375
+ }
376
+
377
+ .yit-container.plugin-licence-activation .button-licence {
378
+ border: 0;
379
+ font-size: 13px;
380
+ text-transform: uppercase;
381
+ background-color: #808a97;
382
+ color: #fff;
383
+ font-weight: 700;
384
+ border-radius: 3px;
385
+ cursor: pointer;
386
+ text-decoration: none;
387
+ padding: 5px 7px;
388
+ -webkit-transition: background-color 0.3s ease;
389
+ -moz-transition: background-color 0.3s ease;
390
+ -ms-transition: background-color 0.3s ease;
391
+ -o-transition: background-color 0.3s ease;
392
+ transition: background-color 0.3s ease;
393
+ }
394
+
395
+ .yit-container.plugin-licence-activation .button-licence:hover {
396
+ background-color: #4d5c6f;
397
+ }
398
+
399
+ .yit-container.plugin-licence-activation .button-licence.clicked {
400
+ cursor: not-allowed;
401
+ background-color: #e2e2e2 !important;
402
+ }
403
+
404
+ .yit-container.plugin-licence-activation .button-licence.licence-check {
405
+ font-weight: 400;
406
+ padding: 12px 19px;
407
+ }
408
+
409
+ .yit-container.plugin-licence-activation .button-licence.licence-renew {
410
+ text-decoration: none;
411
+ padding: 7px 12px;
412
+ font-size: 9px;
413
+ }
414
+
415
+ .yit-container.plugin-licence-activation .button-licence.licence-renew:focus {
416
+ box-shadow: none;
417
+ }
418
+
419
+ .yit-container.plugin-licence-activation table:not(.to-active-table) {
420
+ width: 100%;
421
+ border: 1px solid #dcdcdc;
422
+ border-spacing: 0;
423
+ border-radius: 5px;
424
+ border-collapse: separate;
425
+ overflow: hidden;
426
+ }
427
+
428
+ .yit-container.plugin-licence-activation table:not(.to-active-table) th {
429
+ border-bottom: 1px solid #dcdcdc;
430
+ }
431
+
432
+ .yit-container.plugin-licence-activation table:not(.to-active-table) td,
433
+ .yit-container.plugin-licence-activation table:not(.to-active-table) th {
434
+ border-right: 1px solid #dcdcdc;
435
+ }
436
+ .yit-container.plugin-licence-activation table td:last-child,
437
+ .yit-container.plugin-licence-activation table th:last-child {
438
+ border-right: 0;
439
+ }
440
+
441
+ .yit-container.plugin-licence-activation table thead tr {
442
+ background-color: #f6f4f4;
443
+ }
444
+
445
+ .yit-container.plugin-licence-activation table tbody tr {
446
+ background-color: #ffffff;
447
+ }
448
+
449
+ .yit-container.plugin-licence-activation table thead tr th {
450
+ font-size: 13px;
451
+ color: #313131;
452
+ text-transform: uppercase;
453
+ font-weight: bold;
454
+ }
455
+
456
+ .yit-container.plugin-licence-activation table thead tr,
457
+ .yit-container.plugin-licence-activation table tbody tr {
458
+ line-height: 60px;
459
+ }
460
+
461
+ .yit-container.plugin-licence-activation table tbody tr td{
462
+ text-align: center;
463
+ line-height: 20px;
464
+ padding: 10px 5px;
465
+ }
466
+
467
+ .yit-container.plugin-licence-activation .button-licence.licence-activation {
468
+ padding: 12px 18px;
469
+ }
470
+
471
+ .yit-container.plugin-licence-activation .to-active-table tr {
472
+ line-height: 75px;
473
+ }
474
+
475
+ .yit-container.plugin-licence-activation .to-active-table tr.plugin-row {
476
+ background-color: transparent;
477
+ -webkit-transition: all 0.3s ease;
478
+ -moz-transition: all 0.3s ease;
479
+ -ms-transition: all 0.3s ease;
480
+ -o-transition: all 0.3s ease;
481
+ transition: all 0.3s ease;
482
+ }
483
+
484
+ .yit-container.plugin-licence-activation .to-active-table tr.plugin-row.error {
485
+ background-color: #ffdcdc;
486
+ }
487
+
488
+ .yit-container.plugin-licence-activation .to-active-table td {
489
+ padding-right: 12px;
490
+ width: 33%;
491
+ }
492
+
493
+
494
+ .yit-container.plugin-licence-activation .to-active-table td.plugin-name {
495
+ color: #808a97;
496
+ font-size: 12px;
497
+ text-transform: uppercase;
498
+ font-weight: bold;
499
+ line-height: 20px;
500
+ width: 20%;
501
+ padding-left: 20px;
502
+ }
503
+
504
+ .yit-container.plugin-licence-activation .to-active-table td.activate-button {
505
+ width: 15%;
506
+ position: relative;
507
+ }
508
+
509
+ .yit-container.plugin-licence-activation input[type=text],
510
+ .yit-container.plugin-licence-activation input[type=email]{
511
+ -webkit-transition: all 0.3s ease;
512
+ -moz-transition: all 0.3s ease;
513
+ -ms-transition: all 0.3s ease;
514
+ -o-transition: all 0.3s ease;
515
+ transition: all 0.3s ease;
516
+
517
+ border: 1px solid #dcdcdc;
518
+ padding: 0 15px;
519
+ border-radius: 3px;
520
+ height: 41px;
521
+ width: 100%;
522
+ }
523
+
524
+ .yit-container.plugin-licence-activation input[type=text].require,
525
+ .yit-container.plugin-licence-activation input[type=email].require {
526
+ border: 1px solid #ff3838;
527
+ }
528
+
529
+ .yit-container.plugin-licence-activation input[type=text]:focus,
530
+ .yit-container.plugin-licence-activation input[type=email]:focus{
531
+ webkit-box-shadow: 0 0 1px rgba(30,140,190,.8);
532
+ box-shadow: 0 0 1px rgba(30,140,190,.8);
533
+ }
534
+
535
+ .yit-container.plugin-licence-activation input[type=text]{
536
+ text-transform: uppercase;
537
+ text-align: center;
538
+ }
539
+
540
+ .yit-container.plugin-licence-activation input[type=email] {
541
+ text-align: left;
542
+ }
543
+
544
+ .yit-container.plugin-licence-activation input[type=submit]:focus{
545
+ outline: 0;
546
+ }
547
+
548
+ /* === Woocommerce panel === */
549
+ #plugin-fw-wc .yit_options{
550
+ padding: 0;
551
+ border: 0;
552
+ }
553
+ #plugin-fw-wc .yit_options input.upload_button, .yit_options input.button{
554
+ background: none;
555
+ border: 1px solid #ccc;
556
+ }
557
+
558
+ /* === WP Pointers === */
559
+
560
+ #adminmenu li.menu-top.yit-pointer-selected-row,
561
+ #adminmenu li.menu-top.yit-pointer-selected-row:hover,
562
+ #adminmenu li.yit-pointer-selected-row a.menu-top {
563
+ background-color: #acc327;
564
+ color: #000;
565
+ }
566
+
567
+ #adminmenu a.menu-top.toplevel_page_yit_plugin_panel.yit-pointer{
568
+ color: #000;
569
+ }
570
+
571
+ #adminmenu a.menu-top.toplevel_page_yit_plugin_panel.yit-pointer:hover,
572
+ #adminmenu .wp-submenu a.yit-pointer-selected-row {
573
+ color: #fff;
574
+ }
575
+
576
+ #adminmenu .wp-submenu a.yit-pointer-selected-row:hover {
577
+ color: #45bbe6;
578
+ }
579
+
580
+ /* === Responsive === */
581
+
582
+ @media (max-width: 767px) {}
583
+
584
+ @media (max-width: 480px) {}
585
+
586
+ @media (min-width: 768px) and (max-width: 992px) {}
587
+
588
+ @media (min-width: 980px) and (max-width: 1199px) {}
589
+
590
+ @media (min-width: 1200px) {
591
+ .yit-container.plugin-licence-activation{
592
+ width: 900px;
593
+ }
594
+ }
595
+
596
+ @media only screen and (-webkit-min-device-pixel-ratio: 1.5),
597
+ only screen and (-o-min-device-pixel-ratio: 3/2),
598
+ only screen and (min--moz-device-pixel-ratio: 1.5),
599
+ only screen and (min-device-pixel-ratio: 1.5) {}
plugin-fw/assets/css/yit-upgrader.css ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* === Plugins Upgrader === */
2
+
3
+ .yit-plugin-changelog-wrapper {
4
+ display: none;
5
+ }
6
+
7
+ .yit-plugin-changelog-title {
8
+ text-transform: uppercase;
9
+ }
10
+
11
+ .yit-plugin-changelog {
12
+ background: #fcfcfc;
13
+ height: 97%;
14
+ }
plugin-fw/assets/images/chosen/chosen-sprite.png ADDED
Binary file
plugin-fw/assets/images/chosen/chosen-sprite@2x.png ADDED
Binary file
plugin-fw/assets/images/double-sidebar.png ADDED
Binary file
plugin-fw/assets/images/licence-error.png ADDED
Binary file
plugin-fw/assets/images/no-sidebar.png ADDED
Binary file
plugin-fw/assets/images/off.png ADDED
Binary file
plugin-fw/assets/images/on.png ADDED
Binary file
plugin-fw/assets/images/select.png ADDED
Binary file
plugin-fw/assets/images/sidebar-left.png ADDED
Binary file
plugin-fw/assets/images/sidebar-right.png ADDED
Binary file
plugin-fw/assets/images/sleep.png ADDED
Binary file
plugin-fw/assets/images/slider/grey.gif ADDED
Binary file
plugin-fw/assets/images/slider/handle.png ADDED
Binary file
plugin-fw/assets/images/slider/orange.gif ADDED
Binary file
plugin-fw/assets/images/slider/tooltip.png ADDED
Binary file
plugin-fw/assets/images/spinner.png ADDED
Binary file
plugin-fw/assets/images/ui-icons_222222_256x240.png ADDED
Binary file
plugin-fw/assets/images/ui-icons_2e83ff_256x240.png ADDED
Binary file
plugin-fw/assets/images/ui-icons_454545_256x240.png ADDED
Binary file
plugin-fw/assets/images/ui-icons_888888_256x240.png ADDED
Binary file
plugin-fw/assets/images/x.png ADDED
Binary file
plugin-fw/assets/images/yithemes-icon.png ADDED
Binary file
plugin-fw/assets/js/chosen/chosen.jquery.js ADDED
@@ -0,0 +1,1211 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ Chosen, a Select Box Enhancer for jQuery and Prototype
3
+ by Patrick Filler for Harvest, http://getharvest.com
4
+
5
+ Version 1.1.0
6
+ Full source at https://github.com/harvesthq/chosen
7
+ Copyright (c) 2011 Harvest http://getharvest.com
8
+
9
+ MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
10
+ This file is generated by `grunt build`, do not edit it by hand.
11
+ */
12
+
13
+ (function() {
14
+ var $, AbstractChosen, Chosen, SelectParser, _ref,
15
+ __hasProp = {}.hasOwnProperty,
16
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
17
+
18
+ SelectParser = (function() {
19
+ function SelectParser() {
20
+ this.options_index = 0;
21
+ this.parsed = [];
22
+ }
23
+
24
+ SelectParser.prototype.add_node = function(child) {
25
+ if (child.nodeName.toUpperCase() === "OPTGROUP") {
26
+ return this.add_group(child);
27
+ } else {
28
+ return this.add_option(child);
29
+ }
30
+ };
31
+
32
+ SelectParser.prototype.add_group = function(group) {
33
+ var group_position, option, _i, _len, _ref, _results;
34
+ group_position = this.parsed.length;
35
+ this.parsed.push({
36
+ array_index: group_position,
37
+ group: true,
38
+ label: this.escapeExpression(group.label),
39
+ children: 0,
40
+ disabled: group.disabled
41
+ });
42
+ _ref = group.childNodes;
43
+ _results = [];
44
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
45
+ option = _ref[_i];
46
+ _results.push(this.add_option(option, group_position, group.disabled));
47
+ }
48
+ return _results;
49
+ };
50
+
51
+ SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
52
+ if (option.nodeName.toUpperCase() === "OPTION") {
53
+ if (option.text !== "") {
54
+ if (group_position != null) {
55
+ this.parsed[group_position].children += 1;
56
+ }
57
+ this.parsed.push({
58
+ array_index: this.parsed.length,
59
+ options_index: this.options_index,
60
+ value: option.value,
61
+ text: option.text,
62
+ html: option.innerHTML,
63
+ selected: option.selected,
64
+ disabled: group_disabled === true ? group_disabled : option.disabled,
65
+ group_array_index: group_position,
66
+ classes: option.className,
67
+ style: option.style.cssText
68
+ });
69
+ } else {
70
+ this.parsed.push({
71
+ array_index: this.parsed.length,
72
+ options_index: this.options_index,
73
+ empty: true
74
+ });
75
+ }
76
+ return this.options_index += 1;
77
+ }
78
+ };
79
+
80
+ SelectParser.prototype.escapeExpression = function(text) {
81
+ var map, unsafe_chars;
82
+ if ((text == null) || text === false) {
83
+ return "";
84
+ }
85
+ if (!/[\&\<\>\"\'\`]/.test(text)) {
86
+ return text;
87
+ }
88
+ map = {
89
+ "<": "&lt;",
90
+ ">": "&gt;",
91
+ '"': "&quot;",
92
+ "'": "&#x27;",
93
+ "`": "&#x60;"
94
+ };
95
+ unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
96
+ return text.replace(unsafe_chars, function(chr) {
97
+ return map[chr] || "&amp;";
98
+ });
99
+ };
100
+
101
+ return SelectParser;
102
+
103
+ })();
104
+
105
+ SelectParser.select_to_array = function(select) {
106
+ var child, parser, _i, _len, _ref;
107
+ parser = new SelectParser();
108
+ _ref = select.childNodes;
109
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
110
+ child = _ref[_i];
111
+ parser.add_node(child);
112
+ }
113
+ return parser.parsed;
114
+ };
115
+
116
+ AbstractChosen = (function() {
117
+ function AbstractChosen(form_field, options) {
118
+ this.form_field = form_field;
119
+ this.options = options != null ? options : {};
120
+ if (!AbstractChosen.browser_is_supported()) {
121
+ return;
122
+ }
123
+ this.is_multiple = this.form_field.multiple;
124
+ this.set_default_text();
125
+ this.set_default_values();
126
+ this.setup();
127
+ this.set_up_html();
128
+ this.register_observers();
129
+ }
130
+
131
+ AbstractChosen.prototype.set_default_values = function() {
132
+ var _this = this;
133
+ this.click_test_action = function(evt) {
134
+ return _this.test_active_click(evt);
135
+ };
136
+ this.activate_action = function(evt) {
137
+ return _this.activate_field(evt);
138
+ };
139
+ this.active_field = false;
140
+ this.mouse_on_container = false;
141
+ this.results_showing = false;
142
+ this.result_highlighted = null;
143
+ this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
144
+ this.disable_search_threshold = this.options.disable_search_threshold || 0;
145
+ this.disable_search = this.options.disable_search || false;
146
+ this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
147
+ this.group_search = this.options.group_search != null ? this.options.group_search : true;
148
+ this.search_contains = this.options.search_contains || false;
149
+ this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
150
+ this.max_selected_options = this.options.max_selected_options || Infinity;
151
+ this.inherit_select_classes = this.options.inherit_select_classes || false;
152
+ this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
153
+ return this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
154
+ };
155
+
156
+ AbstractChosen.prototype.set_default_text = function() {
157
+ if (this.form_field.getAttribute("data-placeholder")) {
158
+ this.default_text = this.form_field.getAttribute("data-placeholder");
159
+ } else if (this.is_multiple) {
160
+ this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
161
+ } else {
162
+ this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
163
+ }
164
+ return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
165
+ };
166
+
167
+ AbstractChosen.prototype.mouse_enter = function() {
168
+ return this.mouse_on_container = true;
169
+ };
170
+
171
+ AbstractChosen.prototype.mouse_leave = function() {
172
+ return this.mouse_on_container = false;
173
+ };
174
+
175
+ AbstractChosen.prototype.input_focus = function(evt) {
176
+ var _this = this;
177
+ if (this.is_multiple) {
178
+ if (!this.active_field) {
179
+ return setTimeout((function() {
180
+ return _this.container_mousedown();
181
+ }), 50);
182
+ }
183
+ } else {
184
+ if (!this.active_field) {
185
+ return this.activate_field();
186
+ }
187
+ }
188
+ };
189
+
190
+ AbstractChosen.prototype.input_blur = function(evt) {
191
+ var _this = this;
192
+ if (!this.mouse_on_container) {
193
+ this.active_field = false;
194
+ return setTimeout((function() {
195
+ return _this.blur_test();
196
+ }), 100);
197
+ }
198
+ };
199
+
200
+ AbstractChosen.prototype.results_option_build = function(options) {
201
+ var content, data, _i, _len, _ref;
202
+ content = '';
203
+ _ref = this.results_data;
204
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
205
+ data = _ref[_i];
206
+ if (data.group) {
207
+ content += this.result_add_group(data);
208
+ } else {
209
+ content += this.result_add_option(data);
210
+ }
211
+ if (options != null ? options.first : void 0) {
212
+ if (data.selected && this.is_multiple) {
213
+ this.choice_build(data);
214
+ } else if (data.selected && !this.is_multiple) {
215
+ this.single_set_selected_text(data.text);
216
+ }
217
+ }
218
+ }
219
+ return content;
220
+ };
221
+
222
+ AbstractChosen.prototype.result_add_option = function(option) {
223
+ var classes, option_el;
224
+ if (!option.search_match) {
225
+ return '';
226
+ }
227
+ if (!this.include_option_in_results(option)) {
228
+ return '';
229
+ }
230
+ classes = [];
231
+ if (!option.disabled && !(option.selected && this.is_multiple)) {
232
+ classes.push("active-result");
233
+ }
234
+ if (option.disabled && !(option.selected && this.is_multiple)) {
235
+ classes.push("disabled-result");
236
+ }
237
+ if (option.selected) {
238
+ classes.push("result-selected");
239
+ }
240
+ if (option.group_array_index != null) {
241
+ classes.push("group-option");
242
+ }
243
+ if (option.classes !== "") {
244
+ classes.push(option.classes);
245
+ }
246
+ option_el = document.createElement("li");
247
+ option_el.className = classes.join(" ");
248
+ option_el.style.cssText = option.style;
249
+ option_el.setAttribute("data-option-array-index", option.array_index);
250
+ option_el.innerHTML = option.search_text;
251
+ return this.outerHTML(option_el);
252
+ };
253
+
254
+ AbstractChosen.prototype.result_add_group = function(group) {
255
+ var group_el;
256
+ if (!(group.search_match || group.group_match)) {
257
+ return '';
258
+ }
259
+ if (!(group.active_options > 0)) {
260
+ return '';
261
+ }
262
+ group_el = document.createElement("li");
263
+ group_el.className = "group-result";
264
+ group_el.innerHTML = group.search_text;
265
+ return this.outerHTML(group_el);
266
+ };
267
+
268
+ AbstractChosen.prototype.results_update_field = function() {
269
+ this.set_default_text();
270
+ if (!this.is_multiple) {
271
+ this.results_reset_cleanup();
272
+ }
273
+ this.result_clear_highlight();
274
+ this.results_build();
275
+ if (this.results_showing) {
276
+ return this.winnow_results();
277
+ }
278
+ };
279
+
280
+ AbstractChosen.prototype.reset_single_select_options = function() {
281
+ var result, _i, _len, _ref, _results;
282
+ _ref = this.results_data;
283
+ _results = [];
284
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
285
+ result = _ref[_i];
286
+ if (result.selected) {
287
+ _results.push(result.selected = false);
288
+ } else {
289
+ _results.push(void 0);
290
+ }
291
+ }
292
+ return _results;
293
+ };
294
+
295
+ AbstractChosen.prototype.results_toggle = function() {
296
+ if (this.results_showing) {
297
+ return this.results_hide();
298
+ } else {
299
+ return this.results_show();
300
+ }
301
+ };
302
+
303
+ AbstractChosen.prototype.results_search = function(evt) {
304
+ if (this.results_showing) {
305
+ return this.winnow_results();
306
+ } else {
307
+ return this.results_show();
308
+ }
309
+ };
310
+
311
+ AbstractChosen.prototype.winnow_results = function() {
312
+ var escapedSearchText, option, regex, regexAnchor, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
313
+ this.no_results_clear();
314
+ results = 0;
315
+ searchText = this.get_search_text();
316
+ escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
317
+ regexAnchor = this.search_contains ? "" : "^";
318
+ regex = new RegExp(regexAnchor + escapedSearchText, 'i');
319
+ zregex = new RegExp(escapedSearchText, 'i');
320
+ _ref = this.results_data;
321
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
322
+ option = _ref[_i];
323
+ option.search_match = false;
324
+ results_group = null;
325
+ if (this.include_option_in_results(option)) {
326
+ if (option.group) {
327
+ option.group_match = false;
328
+ option.active_options = 0;
329
+ }
330
+ if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
331
+ results_group = this.results_data[option.group_array_index];
332
+ if (results_group.active_options === 0 && results_group.search_match) {
333
+ results += 1;
334
+ }
335
+ results_group.active_options += 1;
336
+ }
337
+ if (!(option.group && !this.group_search)) {
338
+ option.search_text = option.group ? option.label : option.html;
339
+ option.search_match = this.search_string_match(option.search_text, regex);
340
+ if (option.search_match && !option.group) {
341
+ results += 1;
342
+ }
343
+ if (option.search_match) {
344
+ if (searchText.length) {
345
+ startpos = option.search_text.search(zregex);
346
+ text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
347
+ option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
348
+ }
349
+ if (results_group != null) {
350
+ results_group.group_match = true;
351
+ }
352
+ } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
353
+ option.search_match = true;
354
+ }
355
+ }
356
+ }
357
+ }
358
+ this.result_clear_highlight();
359
+ if (results < 1 && searchText.length) {
360
+ this.update_results_content("");
361
+ return this.no_results(searchText);
362
+ } else {
363
+ this.update_results_content(this.results_option_build());
364
+ return this.winnow_results_set_highlight();
365
+ }
366
+ };
367
+
368
+ AbstractChosen.prototype.search_string_match = function(search_string, regex) {
369
+ var part, parts, _i, _len;
370
+ if (regex.test(search_string)) {
371
+ return true;
372
+ } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
373
+ parts = search_string.replace(/\[|\]/g, "").split(" ");
374
+ if (parts.length) {
375
+ for (_i = 0, _len = parts.length; _i < _len; _i++) {
376
+ part = parts[_i];
377
+ if (regex.test(part)) {
378
+ return true;
379
+ }
380
+ }
381
+ }
382
+ }
383
+ };
384
+
385
+ AbstractChosen.prototype.choices_count = function() {
386
+ var option, _i, _len, _ref;
387
+ if (this.selected_option_count != null) {
388
+ return this.selected_option_count;
389
+ }
390
+ this.selected_option_count = 0;
391
+ _ref = this.form_field.options;
392
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
393
+ option = _ref[_i];
394
+ if (option.selected) {
395
+ this.selected_option_count += 1;
396
+ }
397
+ }
398
+ return this.selected_option_count;
399
+ };
400
+
401
+ AbstractChosen.prototype.choices_click = function(evt) {
402
+ evt.preventDefault();
403
+ if (!(this.results_showing || this.is_disabled)) {
404
+ return this.results_show();
405
+ }
406
+ };
407
+
408
+ AbstractChosen.prototype.keyup_checker = function(evt) {
409
+ var stroke, _ref;
410
+ stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
411
+ this.search_field_scale();
412
+ switch (stroke) {
413
+ case 8:
414
+ if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
415
+ return this.keydown_backstroke();
416
+ } else if (!this.pending_backstroke) {
417
+ this.result_clear_highlight();
418
+ return this.results_search();
419
+ }
420
+ break;
421
+ case 13:
422
+ evt.preventDefault();
423
+ if (this.results_showing) {
424
+ return this.result_select(evt);
425
+ }
426
+ break;
427
+ case 27:
428
+ if (this.results_showing) {
429
+ this.results_hide();
430
+ }
431
+ return true;
432
+ case 9:
433
+ case 38:
434
+ case 40:
435
+ case 16:
436
+ case 91:
437
+ case 17:
438
+ break;
439
+ default:
440
+ return this.results_search();
441
+ }
442
+ };
443
+
444
+ AbstractChosen.prototype.clipboard_event_checker = function(evt) {
445
+ var _this = this;
446
+ return setTimeout((function() {
447
+ return _this.results_search();
448
+ }), 50);
449
+ };
450
+
451
+ AbstractChosen.prototype.container_width = function() {
452
+ if (this.options.width != null) {
453
+ return this.options.width;
454
+ } else {
455
+ return "" + this.form_field.offsetWidth + "px";
456
+ }
457
+ };
458
+
459
+ AbstractChosen.prototype.include_option_in_results = function(option) {
460
+ if (this.is_multiple && (!this.display_selected_options && option.selected)) {
461
+ return false;
462
+ }
463
+ if (!this.display_disabled_options && option.disabled) {
464
+ return false;
465
+ }
466
+ if (option.empty) {
467
+ return false;
468
+ }
469
+ return true;
470
+ };
471
+
472
+ AbstractChosen.prototype.search_results_touchstart = function(evt) {
473
+ this.touch_started = true;
474
+ return this.search_results_mouseover(evt);
475
+ };
476
+
477
+ AbstractChosen.prototype.search_results_touchmove = function(evt) {
478
+ this.touch_started = false;
479
+ return this.search_results_mouseout(evt);
480
+ };
481
+
482
+ AbstractChosen.prototype.search_results_touchend = function(evt) {
483
+ if (this.touch_started) {
484
+ return this.search_results_mouseup(evt);
485
+ }
486
+ };
487
+
488
+ AbstractChosen.prototype.outerHTML = function(element) {
489
+ var tmp;
490
+ if (element.outerHTML) {
491
+ return element.outerHTML;
492
+ }
493
+ tmp = document.createElement("div");
494
+ tmp.appendChild(element);
495
+ return tmp.innerHTML;
496
+ };
497
+
498
+ AbstractChosen.browser_is_supported = function() {
499
+ if (window.navigator.appName === "Microsoft Internet Explorer") {
500
+ return document.documentMode >= 8;
501
+ }
502
+ if (/iP(od|hone)/i.test(window.navigator.userAgent)) {
503
+ return false;
504
+ }
505
+ if (/Android/i.test(window.navigator.userAgent)) {
506
+ if (/Mobile/i.test(window.navigator.userAgent)) {
507
+ return false;
508
+ }
509
+ }
510
+ return true;
511
+ };
512
+
513
+ AbstractChosen.default_multiple_text = "Select Some Options";
514
+
515
+ AbstractChosen.default_single_text = "Select an Option";
516
+
517
+ AbstractChosen.default_no_result_text = "No results match";
518
+
519
+ return AbstractChosen;
520
+
521
+ })();
522
+
523
+ $ = jQuery;
524
+
525
+ $.fn.extend({
526
+ chosen: function(options) {
527
+ if (!AbstractChosen.browser_is_supported()) {
528
+ return this;
529
+ }
530
+ return this.each(function(input_field) {
531
+ var $this, chosen;
532
+ $this = $(this);
533
+ chosen = $this.data('chosen');
534
+ if (options === 'destroy' && chosen) {
535
+ chosen.destroy();
536
+ } else if (!chosen) {
537
+ $this.data('chosen', new Chosen(this, options));
538
+ }
539
+ });
540
+ }
541
+ });
542
+
543
+ Chosen = (function(_super) {
544
+ __extends(Chosen, _super);
545
+
546
+ function Chosen() {
547
+ _ref = Chosen.__super__.constructor.apply(this, arguments);
548
+ return _ref;
549
+ }
550
+
551
+ Chosen.prototype.setup = function() {
552
+ this.form_field_jq = $(this.form_field);
553
+ this.current_selectedIndex = this.form_field.selectedIndex;
554
+ return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl");
555
+ };
556
+
557
+ Chosen.prototype.set_up_html = function() {
558
+ var container_classes, container_props;
559
+ container_classes = ["chosen-container"];
560
+ container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
561
+ if (this.inherit_select_classes && this.form_field.className) {
562
+ container_classes.push(this.form_field.className);
563
+ }
564
+ if (this.is_rtl) {
565
+ container_classes.push("chosen-rtl");
566
+ }
567
+ container_props = {
568
+ 'class': container_classes.join(' '),
569
+ 'style': "width: " + (this.container_width()) + ";",
570
+ 'title': this.form_field.title
571
+ };
572
+ if (this.form_field.id.length) {
573
+ container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
574
+ }
575
+ this.container = $("<div />", container_props);
576
+ if (this.is_multiple) {
577
+ this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>');
578
+ } else {
579
+ this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>');
580
+ }
581
+ this.form_field_jq.hide().after(this.container);
582
+ this.dropdown = this.container.find('div.chosen-drop').first();
583
+ this.search_field = this.container.find('input').first();
584
+ this.search_results = this.container.find('ul.chosen-results').first();
585
+ this.search_field_scale();
586
+ this.search_no_results = this.container.find('li.no-results').first();
587
+ if (this.is_multiple) {
588
+ this.search_choices = this.container.find('ul.chosen-choices').first();
589
+ this.search_container = this.container.find('li.search-field').first();
590
+ } else {
591
+ this.search_container = this.container.find('div.chosen-search').first();
592
+ this.selected_item = this.container.find('.chosen-single').first();
593
+ }
594
+ this.results_build();
595
+ this.set_tab_index();
596
+ this.set_label_behavior();
597
+ return this.form_field_jq.trigger("chosen:ready", {
598
+ chosen: this
599
+ });
600
+ };
601
+
602
+ Chosen.prototype.register_observers = function() {
603
+ var _this = this;
604
+ this.container.bind('mousedown.chosen', function(evt) {
605
+ _this.container_mousedown(evt);
606
+ });
607
+ this.container.bind('mouseup.chosen', function(evt) {
608
+ _this.container_mouseup(evt);
609
+ });
610
+ this.container.bind('mouseenter.chosen', function(evt) {
611
+ _this.mouse_enter(evt);
612
+ });
613
+ this.container.bind('mouseleave.chosen', function(evt) {
614
+ _this.mouse_leave(evt);
615
+ });
616
+ this.search_results.bind('mouseup.chosen', function(evt) {
617
+ _this.search_results_mouseup(evt);
618
+ });
619
+ this.search_results.bind('mouseover.chosen', function(evt) {
620
+ _this.search_results_mouseover(evt);
621
+ });
622
+ this.search_results.bind('mouseout.chosen', function(evt) {
623
+ _this.search_results_mouseout(evt);
624
+ });
625
+ this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
626
+ _this.search_results_mousewheel(evt);
627
+ });
628
+ this.search_results.bind('touchstart.chosen', function(evt) {
629
+ _this.search_results_touchstart(evt);
630
+ });
631
+ this.search_results.bind('touchmove.chosen', function(evt) {
632
+ _this.search_results_touchmove(evt);
633
+ });
634
+ this.search_results.bind('touchend.chosen', function(evt) {
635
+ _this.search_results_touchend(evt);
636
+ });
637
+ this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
638
+ _this.results_update_field(evt);
639
+ });
640
+ this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
641
+ _this.activate_field(evt);
642
+ });
643
+ this.form_field_jq.bind("chosen:open.chosen", function(evt) {
644
+ _this.container_mousedown(evt);
645
+ });
646
+ this.form_field_jq.bind("chosen:close.chosen", function(evt) {
647
+ _this.input_blur(evt);
648
+ });
649
+ this.search_field.bind('blur.chosen', function(evt) {
650
+ _this.input_blur(evt);
651
+ });
652
+ this.search_field.bind('keyup.chosen', function(evt) {
653
+ _this.keyup_checker(evt);
654
+ });
655
+ this.search_field.bind('keydown.chosen', function(evt) {
656
+ _this.keydown_checker(evt);
657
+ });
658
+ this.search_field.bind('focus.chosen', function(evt) {
659
+ _this.input_focus(evt);
660
+ });
661
+ this.search_field.bind('cut.chosen', function(evt) {
662
+ _this.clipboard_event_checker(evt);
663
+ });
664
+ this.search_field.bind('paste.chosen', function(evt) {
665
+ _this.clipboard_event_checker(evt);
666
+ });
667
+ if (this.is_multiple) {
668
+ return this.search_choices.bind('click.chosen', function(evt) {
669
+ _this.choices_click(evt);
670
+ });
671
+ } else {
672
+ return this.container.bind('click.chosen', function(evt) {
673
+ evt.preventDefault();
674
+ });
675
+ }
676
+ };
677
+
678
+ Chosen.prototype.destroy = function() {
679
+ $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
680
+ if (this.search_field[0].tabIndex) {
681
+ this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
682
+ }
683
+ this.container.remove();
684
+ this.form_field_jq.removeData('chosen');
685
+ return this.form_field_jq.show();
686
+ };
687
+
688
+ Chosen.prototype.search_field_disabled = function() {
689
+ this.is_disabled = this.form_field_jq[0].disabled;
690
+ if (this.is_disabled) {
691
+ this.container.addClass('chosen-disabled');
692
+ this.search_field[0].disabled = true;
693
+ if (!this.is_multiple) {
694
+ this.selected_item.unbind("focus.chosen", this.activate_action);
695
+ }
696
+ return this.close_field();
697
+ } else {
698
+ this.container.removeClass('chosen-disabled');
699
+ this.search_field[0].disabled = false;
700
+ if (!this.is_multiple) {
701
+ return this.selected_item.bind("focus.chosen", this.activate_action);
702
+ }
703
+ }
704
+ };
705
+
706
+ Chosen.prototype.container_mousedown = function(evt) {
707
+ if (!this.is_disabled) {
708
+ if (evt && evt.type === "mousedown" && !this.results_showing) {
709
+ evt.preventDefault();
710
+ }
711
+ if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
712
+ if (!this.active_field) {
713
+ if (this.is_multiple) {
714
+ this.search_field.val("");
715
+ }
716
+ $(this.container[0].ownerDocument).bind('click.chosen', this.click_test_action);
717
+ this.results_show();
718
+ } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
719
+ evt.preventDefault();
720
+ this.results_toggle();
721
+ }
722
+ return this.activate_field();
723
+ }
724
+ }
725
+ };
726
+
727
+ Chosen.prototype.container_mouseup = function(evt) {
728
+ if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
729
+ return this.results_reset(evt);
730
+ }
731
+ };
732
+
733
+ Chosen.prototype.search_results_mousewheel = function(evt) {
734
+ var delta;
735
+ if (evt.originalEvent) {
736
+ delta = -evt.originalEvent.wheelDelta || evt.originalEvent.detail;
737
+ }
738
+ if (delta != null) {
739
+ evt.preventDefault();
740
+ if (evt.type === 'DOMMouseScroll') {
741
+ delta = delta * 40;
742
+ }
743
+ return this.search_results.scrollTop(delta + this.search_results.scrollTop());
744
+ }
745
+ };
746
+
747
+ Chosen.prototype.blur_test = function(evt) {
748
+ if (!this.active_field && this.container.hasClass("chosen-container-active")) {
749
+ return this.close_field();
750
+ }
751
+ };
752
+
753
+ Chosen.prototype.close_field = function() {
754
+ $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
755
+ this.active_field = false;
756
+ this.results_hide();
757
+ this.container.removeClass("chosen-container-active");
758
+ this.clear_backstroke();
759
+ this.show_search_field_default();
760
+ return this.search_field_scale();
761
+ };
762
+
763
+ Chosen.prototype.activate_field = function() {
764
+ this.container.addClass("chosen-container-active");
765
+ this.active_field = true;
766
+ this.search_field.val(this.search_field.val());
767
+ return this.search_field.focus();
768
+ };
769
+
770
+ Chosen.prototype.test_active_click = function(evt) {
771
+ var active_container;
772
+ active_container = $(evt.target).closest('.chosen-container');
773
+ if (active_container.length && this.container[0] === active_container[0]) {
774
+ return this.active_field = true;
775
+ } else {
776
+ return this.close_field();
777
+ }
778
+ };
779
+
780
+ Chosen.prototype.results_build = function() {
781
+ this.parsing = true;
782
+ this.selected_option_count = null;
783
+ this.results_data = SelectParser.select_to_array(this.form_field);
784
+ if (this.is_multiple) {
785
+ this.search_choices.find("li.search-choice").remove();
786
+ } else if (!this.is_multiple) {
787
+ this.single_set_selected_text();
788
+ if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
789
+ this.search_field[0].readOnly = true;
790
+ this.container.addClass("chosen-container-single-nosearch");
791
+ } else {
792
+ this.search_field[0].readOnly = false;
793
+ this.container.removeClass("chosen-container-single-nosearch");
794
+ }
795
+ }
796
+ this.update_results_content(this.results_option_build({
797
+ first: true
798
+ }));
799
+ this.search_field_disabled();
800
+ this.show_search_field_default();
801
+ this.search_field_scale();
802
+ return this.parsing = false;
803
+ };
804
+
805
+ Chosen.prototype.result_do_highlight = function(el) {
806
+ var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
807
+ if (el.length) {
808
+ this.result_clear_highlight();
809
+ this.result_highlight = el;
810
+ this.result_highlight.addClass("highlighted");
811
+ maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
812
+ visible_top = this.search_results.scrollTop();
813
+ visible_bottom = maxHeight + visible_top;
814
+ high_top = this.result_highlight.position().top + this.search_results.scrollTop();
815
+ high_bottom = high_top + this.result_highlight.outerHeight();
816
+ if (high_bottom >= visible_bottom) {
817
+ return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
818
+ } else if (high_top < visible_top) {
819
+ return this.search_results.scrollTop(high_top);
820
+ }
821
+ }
822
+ };
823
+
824
+ Chosen.prototype.result_clear_highlight = function() {
825
+ if (this.result_highlight) {
826
+ this.result_highlight.removeClass("highlighted");
827
+ }
828
+ return this.result_highlight = null;
829
+ };
830
+
831
+ Chosen.prototype.results_show = function() {
832
+ if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
833
+ this.form_field_jq.trigger("chosen:maxselected", {
834
+ chosen: this
835
+ });
836
+ return false;
837
+ }
838
+ this.container.addClass("chosen-with-drop");
839
+ this.results_showing = true;
840
+ this.search_field.focus();
841
+ this.search_field.val(this.search_field.val());
842
+ this.winnow_results();
843
+ return this.form_field_jq.trigger("chosen:showing_dropdown", {
844
+ chosen: this
845
+ });
846
+ };
847
+
848
+ Chosen.prototype.update_results_content = function(content) {
849
+ return this.search_results.html(content);
850
+ };
851
+
852
+ Chosen.prototype.results_hide = function() {
853
+ if (this.results_showing) {
854
+ this.result_clear_highlight();
855
+ this.container.removeClass("chosen-with-drop");
856
+ this.form_field_jq.trigger("chosen:hiding_dropdown", {
857
+ chosen: this
858
+ });
859
+ }
860
+ return this.results_showing = false;
861
+ };
862
+
863
+ Chosen.prototype.set_tab_index = function(el) {
864
+ var ti;
865
+ if (this.form_field.tabIndex) {
866
+ ti = this.form_field.tabIndex;
867
+ this.form_field.tabIndex = -1;
868
+ return this.search_field[0].tabIndex = ti;
869
+ }
870
+ };
871
+
872
+ Chosen.prototype.set_label_behavior = function() {
873
+ var _this = this;
874
+ this.form_field_label = this.form_field_jq.parents("label");
875
+ if (!this.form_field_label.length && this.form_field.id.length) {
876
+ this.form_field_label = $("label[for='" + this.form_field.id + "']");
877
+ }
878
+ if (this.form_field_label.length > 0) {
879
+ return this.form_field_label.bind('click.chosen', function(evt) {
880
+ if (_this.is_multiple) {
881
+ return _this.container_mousedown(evt);
882
+ } else {
883
+ return _this.activate_field();
884
+ }
885
+ });
886
+ }
887
+ };
888
+
889
+ Chosen.prototype.show_search_field_default = function() {
890
+ if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
891
+ this.search_field.val(this.default_text);
892
+ return this.search_field.addClass("default");
893
+ } else {
894
+ this.search_field.val("");
895
+ return this.search_field.removeClass("default");
896
+ }
897
+ };
898
+
899
+ Chosen.prototype.search_results_mouseup = function(evt) {
900
+ var target;
901
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
902
+ if (target.length) {
903
+ this.result_highlight = target;
904
+ this.result_select(evt);
905
+ return this.search_field.focus();
906
+ }
907
+ };
908
+
909
+ Chosen.prototype.search_results_mouseover = function(evt) {
910
+ var target;
911
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
912
+ if (target) {
913
+ return this.result_do_highlight(target);
914
+ }
915
+ };
916
+
917
+ Chosen.prototype.search_results_mouseout = function(evt) {
918
+ if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
919
+ return this.result_clear_highlight();
920
+ }
921
+ };
922
+
923
+ Chosen.prototype.choice_build = function(item) {
924
+ var choice, close_link,
925
+ _this = this;
926
+ choice = $('<li />', {
927
+ "class": "search-choice"
928
+ }).html("<span>" + item.html + "</span>");
929
+ if (item.disabled) {
930
+ choice.addClass('search-choice-disabled');
931
+ } else {
932
+ close_link = $('<a />', {
933
+ "class": 'search-choice-close',
934
+ 'data-option-array-index': item.array_index
935
+ });
936
+ close_link.bind('click.chosen', function(evt) {
937
+ return _this.choice_destroy_link_click(evt);
938
+ });
939
+ choice.append(close_link);
940
+ }
941
+ return this.search_container.before(choice);
942
+ };
943
+
944
+ Chosen.prototype.choice_destroy_link_click = function(evt) {
945
+ evt.preventDefault();
946
+ evt.stopPropagation();
947
+ if (!this.is_disabled) {
948
+ return this.choice_destroy($(evt.target));
949
+ }
950
+ };
951
+
952
+ Chosen.prototype.choice_destroy = function(link) {
953
+ if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
954
+ this.show_search_field_default();
955
+ if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
956
+ this.results_hide();
957
+ }
958
+ link.parents('li').first().remove();
959
+ return this.search_field_scale();
960
+ }
961
+ };
962
+
963
+ Chosen.prototype.results_reset = function() {
964
+ this.reset_single_select_options();
965
+ this.form_field.options[0].selected = true;
966
+ this.single_set_selected_text();
967
+ this.show_search_field_default();
968
+ this.results_reset_cleanup();
969
+ this.form_field_jq.trigger("change");
970
+ if (this.active_field) {
971
+ return this.results_hide();
972
+ }
973
+ };
974
+
975
+ Chosen.prototype.results_reset_cleanup = function() {
976
+ this.current_selectedIndex = this.form_field.selectedIndex;
977
+ return this.selected_item.find("abbr").remove();
978
+ };
979
+
980
+ Chosen.prototype.result_select = function(evt) {
981
+ var high, item;
982
+ if (this.result_highlight) {
983
+ high = this.result_highlight;
984
+ this.result_clear_highlight();
985
+ if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
986
+ this.form_field_jq.trigger("chosen:maxselected", {
987
+ chosen: this
988
+ });
989
+ return false;
990
+ }
991
+ if (this.is_multiple) {
992
+ high.removeClass("active-result");
993
+ } else {
994
+ this.reset_single_select_options();
995
+ }
996
+ item = this.results_data[high[0].getAttribute("data-option-array-index")];
997
+ item.selected = true;
998
+ this.form_field.options[item.options_index].selected = true;
999
+ this.selected_option_count = null;
1000
+ if (this.is_multiple) {
1001
+ this.choice_build(item);
1002
+ } else {
1003
+ this.single_set_selected_text(item.text);
1004
+ }
1005
+ if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
1006
+ this.results_hide();
1007
+ }
1008
+ this.search_field.val("");
1009
+ if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
1010
+ this.form_field_jq.trigger("change", {
1011
+ 'selected': this.form_field.options[item.options_index].value
1012
+ });
1013
+ }
1014
+ this.current_selectedIndex = this.form_field.selectedIndex;
1015
+ return this.search_field_scale();
1016
+ }
1017
+ };
1018
+
1019
+ Chosen.prototype.single_set_selected_text = function(text) {
1020
+ if (text == null) {
1021
+ text = this.default_text;
1022
+ }
1023
+ if (text === this.default_text) {
1024
+ this.selected_item.addClass("chosen-default");
1025
+ } else {
1026
+ this.single_deselect_control_build();
1027
+ this.selected_item.removeClass("chosen-default");
1028
+ }
1029
+ return this.selected_item.find("span").text(text);
1030
+ };
1031
+
1032
+ Chosen.prototype.result_deselect = function(pos) {
1033
+ var result_data;
1034
+ result_data = this.results_data[pos];
1035
+ if (!this.form_field.options[result_data.options_index].disabled) {
1036
+ result_data.selected = false;
1037
+ this.form_field.options[result_data.options_index].selected = false;
1038
+ this.selected_option_count = null;
1039
+ this.result_clear_highlight();
1040
+ if (this.results_showing) {
1041
+ this.winnow_results();
1042
+ }
1043
+ this.form_field_jq.trigger("change", {
1044
+ deselected: this.form_field.options[result_data.options_index].value
1045
+ });
1046
+ this.search_field_scale();
1047
+ return true;
1048
+ } else {
1049
+ return false;
1050
+ }
1051
+ };
1052
+
1053
+ Chosen.prototype.single_deselect_control_build = function() {
1054
+ if (!this.allow_single_deselect) {
1055
+ return;
1056
+ }
1057
+ if (!this.selected_item.find("abbr").length) {
1058
+ this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
1059
+ }
1060
+ return this.selected_item.addClass("chosen-single-with-deselect");
1061
+ };
1062
+
1063
+ Chosen.prototype.get_search_text = function() {
1064
+ if (this.search_field.val() === this.default_text) {
1065
+ return "";
1066
+ } else {
1067
+ return $('<div/>').text($.trim(this.search_field.val())).html();
1068
+ }
1069
+ };
1070
+
1071
+ Chosen.prototype.winnow_results_set_highlight = function() {
1072
+ var do_high, selected_results;
1073
+ selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
1074
+ do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
1075
+ if (do_high != null) {
1076
+ return this.result_do_highlight(do_high);
1077
+ }
1078
+ };
1079
+
1080
+ Chosen.prototype.no_results = function(terms) {
1081
+ var no_results_html;
1082
+ no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
1083
+ no_results_html.find("span").first().html(terms);
1084
+ this.search_results.append(no_results_html);
1085
+ return this.form_field_jq.trigger("chosen:no_results", {
1086
+ chosen: this
1087
+ });
1088
+ };
1089
+
1090
+ Chosen.prototype.no_results_clear = function() {
1091
+ return this.search_results.find(".no-results").remove();
1092
+ };
1093
+
1094
+ Chosen.prototype.keydown_arrow = function() {
1095
+ var next_sib;
1096
+ if (this.results_showing && this.result_highlight) {
1097
+ next_sib = this.result_highlight.nextAll("li.active-result").first();
1098
+ if (next_sib) {
1099
+ return this.result_do_highlight(next_sib);
1100
+ }
1101
+ } else {
1102
+ return this.results_show();
1103
+ }
1104
+ };
1105
+
1106
+ Chosen.prototype.keyup_arrow = function() {
1107
+ var prev_sibs;
1108
+ if (!this.results_showing && !this.is_multiple) {
1109
+ return this.results_show();
1110
+ } else if (this.result_highlight) {
1111
+ prev_sibs = this.result_highlight.prevAll("li.active-result");
1112
+ if (prev_sibs.length) {
1113
+ return this.result_do_highlight(prev_sibs.first());
1114
+ } else {
1115
+ if (this.choices_count() > 0) {
1116
+ this.results_hide();
1117
+ }
1118
+ return this.result_clear_highlight();
1119
+ }
1120
+ }
1121
+ };
1122
+
1123
+ Chosen.prototype.keydown_backstroke = function() {
1124
+ var next_available_destroy;
1125
+ if (this.pending_backstroke) {
1126
+ this.choice_destroy(this.pending_backstroke.find("a").first());
1127
+ return this.clear_backstroke();
1128
+ } else {
1129
+ next_available_destroy = this.search_container.siblings("li.search-choice").last();
1130
+ if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
1131
+ this.pending_backstroke = next_available_destroy;
1132
+ if (this.single_backstroke_delete) {
1133
+ return this.keydown_backstroke();
1134
+ } else {
1135
+ return this.pending_backstroke.addClass("search-choice-focus");
1136
+ }
1137
+ }
1138
+ }
1139
+ };
1140
+
1141
+ Chosen.prototype.clear_backstroke = function() {
1142
+ if (this.pending_backstroke) {
1143
+ this.pending_backstroke.removeClass("search-choice-focus");
1144
+ }
1145
+ return this.pending_backstroke = null;
1146
+ };
1147
+
1148
+ Chosen.prototype.keydown_checker = function(evt) {
1149
+ var stroke, _ref1;
1150
+ stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
1151
+ this.search_field_scale();
1152
+ if (stroke !== 8 && this.pending_backstroke) {
1153
+ this.clear_backstroke();
1154
+ }
1155
+ switch (stroke) {
1156
+ case 8:
1157
+ this.backstroke_length = this.search_field.val().length;
1158
+ break;
1159
+ case 9:
1160
+ if (this.results_showing && !this.is_multiple) {
1161
+ this.result_select(evt);
1162
+ }
1163
+ this.mouse_on_container = false;
1164
+ break;
1165
+ case 13:
1166
+ evt.preventDefault();
1167
+ break;
1168
+ case 38:
1169
+ evt.preventDefault();
1170
+ this.keyup_arrow();
1171
+ break;
1172
+ case 40:
1173
+ evt.preventDefault();
1174
+ this.keydown_arrow();
1175
+ break;
1176
+ }
1177
+ };
1178
+
1179
+ Chosen.prototype.search_field_scale = function() {
1180
+ var div, f_width, h, style, style_block, styles, w, _i, _len;
1181
+ if (this.is_multiple) {
1182
+ h = 0;
1183
+ w = 0;
1184
+ style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
1185
+ styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
1186
+ for (_i = 0, _len = styles.length; _i < _len; _i++) {
1187
+ style = styles[_i];
1188
+ style_block += style + ":" + this.search_field.css(style) + ";";
1189
+ }
1190
+ div = $('<div />', {
1191
+ 'style': style_block
1192
+ });
1193
+ div.text(this.search_field.val());
1194
+ $('body').append(div);
1195
+ w = div.width() + 25;
1196
+ div.remove();
1197
+ f_width = this.container.outerWidth();
1198
+ if (w > f_width - 10) {
1199
+ w = f_width - 10;
1200
+ }
1201
+ return this.search_field.css({
1202
+ 'width': w + 'px'
1203
+ });
1204
+ }
1205
+ };
1206
+
1207
+ return Chosen;
1208
+
1209
+ })(AbstractChosen);
1210
+
1211
+ }).call(this);
plugin-fw/assets/js/codemirror/codemirror.js ADDED
@@ -0,0 +1,5799 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // CodeMirror version 3.15
2
+ //
3
+ // CodeMirror is the only global var we claim
4
+ window.CodeMirror = (function() {
5
+ "use strict";
6
+
7
+ // BROWSER SNIFFING
8
+
9
+ // Crude, but necessary to handle a number of hard-to-feature-detect
10
+ // bugs and behavior differences.
11
+ var gecko = /gecko\/\d/i.test(navigator.userAgent);
12
+ var ie = /MSIE \d/.test(navigator.userAgent);
13
+ var ie_lt8 = ie && (document.documentMode == null || document.documentMode < 8);
14
+ var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);
15
+ var webkit = /WebKit\//.test(navigator.userAgent);
16
+ var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
17
+ var chrome = /Chrome\//.test(navigator.userAgent);
18
+ var opera = /Opera\//.test(navigator.userAgent);
19
+ var safari = /Apple Computer/.test(navigator.vendor);
20
+ var khtml = /KHTML\//.test(navigator.userAgent);
21
+ var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent);
22
+ var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
23
+ var phantom = /PhantomJS/.test(navigator.userAgent);
24
+
25
+ var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
26
+ // This is woefully incomplete. Suggestions for alternative methods welcome.
27
+ var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
28
+ var mac = ios || /Mac/.test(navigator.platform);
29
+ var windows = /windows/i.test(navigator.platform);
30
+
31
+ var opera_version = opera && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
32
+ if (opera_version) opera_version = Number(opera_version[1]);
33
+ if (opera_version && opera_version >= 15) { opera = false; webkit = true; }
34
+ // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
35
+ var flipCtrlCmd = mac && (qtwebkit || opera && (opera_version == null || opera_version < 12.11));
36
+ var captureMiddleClick = gecko || (ie && !ie_lt9);
37
+
38
+ // Optimize some code when these features are not used
39
+ var sawReadOnlySpans = false, sawCollapsedSpans = false;
40
+
41
+ // CONSTRUCTOR
42
+
43
+ function CodeMirror(place, options) {
44
+ if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
45
+
46
+ this.options = options = options || {};
47
+ // Determine effective options based on given values and defaults.
48
+ for (var opt in defaults) if (!options.hasOwnProperty(opt) && defaults.hasOwnProperty(opt))
49
+ options[opt] = defaults[opt];
50
+ setGuttersForLineNumbers(options);
51
+
52
+ var docStart = typeof options.value == "string" ? 0 : options.value.first;
53
+ var display = this.display = makeDisplay(place, docStart);
54
+ display.wrapper.CodeMirror = this;
55
+ updateGutters(this);
56
+ if (options.autofocus && !mobile) focusInput(this);
57
+
58
+ this.state = {keyMaps: [],
59
+ overlays: [],
60
+ modeGen: 0,
61
+ overwrite: false, focused: false,
62
+ suppressEdits: false, pasteIncoming: false,
63
+ draggingText: false,
64
+ highlight: new Delayed()};
65
+
66
+ themeChanged(this);
67
+ if (options.lineWrapping)
68
+ this.display.wrapper.className += " CodeMirror-wrap";
69
+
70
+ var doc = options.value;
71
+ if (typeof doc == "string") doc = new Doc(options.value, options.mode);
72
+ operation(this, attachDoc)(this, doc);
73
+
74
+ // Override magic textarea content restore that IE sometimes does
75
+ // on our hidden textarea on reload
76
+ if (ie) setTimeout(bind(resetInput, this, true), 20);
77
+
78
+ registerEventHandlers(this);
79
+ // IE throws unspecified error in certain cases, when
80
+ // trying to access activeElement before onload
81
+ var hasFocus; try { hasFocus = (document.activeElement == display.input); } catch(e) { }
82
+ if (hasFocus || (options.autofocus && !mobile)) setTimeout(bind(onFocus, this), 20);
83
+ else onBlur(this);
84
+
85
+ operation(this, function() {
86
+ for (var opt in optionHandlers)
87
+ if (optionHandlers.propertyIsEnumerable(opt))
88
+ optionHandlers[opt](this, options[opt], Init);
89
+ for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
90
+ })();
91
+ }
92
+
93
+ // DISPLAY CONSTRUCTOR
94
+
95
+ function makeDisplay(place, docStart) {
96
+ var d = {};
97
+
98
+ var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none; font-size: 4px;");
99
+ if (webkit) input.style.width = "1000px";
100
+ else input.setAttribute("wrap", "off");
101
+ // if border: 0; -- iOS fails to open keyboard (issue #1287)
102
+ if (ios) input.style.border = "1px solid black";
103
+ input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false");
104
+
105
+ // Wraps and hides input textarea
106
+ d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
107
+ // The actual fake scrollbars.
108
+ d.scrollbarH = elt("div", [elt("div", null, null, "height: 1px")], "CodeMirror-hscrollbar");
109
+ d.scrollbarV = elt("div", [elt("div", null, null, "width: 1px")], "CodeMirror-vscrollbar");
110
+ d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
111
+ d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
112
+ // DIVs containing the selection and the actual code
113
+ d.lineDiv = elt("div", null, "CodeMirror-code");
114
+ d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
115
+ // Blinky cursor, and element used to ensure cursor fits at the end of a line
116
+ d.cursor = elt("div", "\u00a0", "CodeMirror-cursor");
117
+ // Secondary cursor, shown when on a 'jump' in bi-directional text
118
+ d.otherCursor = elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor");
119
+ // Used to measure text size
120
+ d.measure = elt("div", null, "CodeMirror-measure");
121
+ // Wraps everything that needs to exist inside the vertically-padded coordinate system
122
+ d.lineSpace = elt("div", [d.measure, d.selectionDiv, d.lineDiv, d.cursor, d.otherCursor],
123
+ null, "position: relative; outline: none");
124
+ // Moved around its parent to cover visible view
125
+ d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
126
+ // Set to the height of the text, causes scrolling
127
+ d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
128
+ // D is needed because behavior of elts with overflow: auto and padding is inconsistent across browsers
129
+ d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;");
130
+ // Will contain the gutters, if any
131
+ d.gutters = elt("div", null, "CodeMirror-gutters");
132
+ d.lineGutter = null;
133
+ // Provides scrolling
134
+ d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
135
+ d.scroller.setAttribute("tabIndex", "-1");
136
+ // The element in which the editor lives.
137
+ d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV,
138
+ d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
139
+ // Work around IE7 z-index bug
140
+ if (ie_lt8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
141
+ if (place.appendChild) place.appendChild(d.wrapper); else place(d.wrapper);
142
+
143
+ // Needed to hide big blue blinking cursor on Mobile Safari
144
+ if (ios) input.style.width = "0px";
145
+ if (!webkit) d.scroller.draggable = true;
146
+ // Needed to handle Tab key in KHTML
147
+ if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; }
148
+ // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
149
+ else if (ie_lt8) d.scrollbarH.style.minWidth = d.scrollbarV.style.minWidth = "18px";
150
+
151
+ // Current visible range (may be bigger than the view window).
152
+ d.viewOffset = d.lastSizeC = 0;
153
+ d.showingFrom = d.showingTo = docStart;
154
+
155
+ // Used to only resize the line number gutter when necessary (when
156
+ // the amount of lines crosses a boundary that makes its width change)
157
+ d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
158
+ // See readInput and resetInput
159
+ d.prevInput = "";
160
+ // Set to true when a non-horizontal-scrolling widget is added. As
161
+ // an optimization, widget aligning is skipped when d is false.
162
+ d.alignWidgets = false;
163
+ // Flag that indicates whether we currently expect input to appear
164
+ // (after some event like 'keypress' or 'input') and are polling
165
+ // intensively.
166
+ d.pollingFast = false;
167
+ // Self-resetting timeout for the poller
168
+ d.poll = new Delayed();
169
+
170
+ d.cachedCharWidth = d.cachedTextHeight = null;
171
+ d.measureLineCache = [];
172
+ d.measureLineCachePos = 0;
173
+
174
+ // Tracks when resetInput has punted to just putting a short
175
+ // string instead of the (large) selection.
176
+ d.inaccurateSelection = false;
177
+
178
+ // Tracks the maximum line length so that the horizontal scrollbar
179
+ // can be kept static when scrolling.
180
+ d.maxLine = null;
181
+ d.maxLineLength = 0;
182
+ d.maxLineChanged = false;
183
+
184
+ // Used for measuring wheel scrolling granularity
185
+ d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
186
+
187
+ return d;
188
+ }
189
+
190
+ // STATE UPDATES
191
+
192
+ // Used to get the editor into a consistent state again when options change.
193
+
194
+ function loadMode(cm) {
195
+ cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
196
+ cm.doc.iter(function(line) {
197
+ if (line.stateAfter) line.stateAfter = null;
198
+ if (line.styles) line.styles = null;
199
+ });
200
+ cm.doc.frontier = cm.doc.first;
201
+ startWorker(cm, 100);
202
+ cm.state.modeGen++;
203
+ if (cm.curOp) regChange(cm);
204
+ }
205
+
206
+ function wrappingChanged(cm) {
207
+ if (cm.options.lineWrapping) {
208
+ cm.display.wrapper.className += " CodeMirror-wrap";
209
+ cm.display.sizer.style.minWidth = "";
210
+ } else {
211
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", "");
212
+ computeMaxLength(cm);
213
+ }
214
+ estimateLineHeights(cm);
215
+ regChange(cm);
216
+ clearCaches(cm);
217
+ setTimeout(function(){updateScrollbars(cm);}, 100);
218
+ }
219
+
220
+ function estimateHeight(cm) {
221
+ var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
222
+ var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
223
+ return function(line) {
224
+ if (lineIsHidden(cm.doc, line))
225
+ return 0;
226
+ else if (wrapping)
227
+ return (Math.ceil(line.text.length / perLine) || 1) * th;
228
+ else
229
+ return th;
230
+ };
231
+ }
232
+
233
+ function estimateLineHeights(cm) {
234
+ var doc = cm.doc, est = estimateHeight(cm);
235
+ doc.iter(function(line) {
236
+ var estHeight = est(line);
237
+ if (estHeight != line.height) updateLineHeight(line, estHeight);
238
+ });
239
+ }
240
+
241
+ function keyMapChanged(cm) {
242
+ var map = keyMap[cm.options.keyMap], style = map.style;
243
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") +
244
+ (style ? " cm-keymap-" + style : "");
245
+ cm.state.disableInput = map.disableInput;
246
+ }
247
+
248
+ function themeChanged(cm) {
249
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
250
+ cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
251
+ clearCaches(cm);
252
+ }
253
+
254
+ function guttersChanged(cm) {
255
+ updateGutters(cm);
256
+ regChange(cm);
257
+ setTimeout(function(){alignHorizontally(cm);}, 20);
258
+ }
259
+
260
+ function updateGutters(cm) {
261
+ var gutters = cm.display.gutters, specs = cm.options.gutters;
262
+ removeChildren(gutters);
263
+ for (var i = 0; i < specs.length; ++i) {
264
+ var gutterClass = specs[i];
265
+ var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
266
+ if (gutterClass == "CodeMirror-linenumbers") {
267
+ cm.display.lineGutter = gElt;
268
+ gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
269
+ }
270
+ }
271
+ gutters.style.display = i ? "" : "none";
272
+ }
273
+
274
+ function lineLength(doc, line) {
275
+ if (line.height == 0) return 0;
276
+ var len = line.text.length, merged, cur = line;
277
+ while (merged = collapsedSpanAtStart(cur)) {
278
+ var found = merged.find();
279
+ cur = getLine(doc, found.from.line);
280
+ len += found.from.ch - found.to.ch;
281
+ }
282
+ cur = line;
283
+ while (merged = collapsedSpanAtEnd(cur)) {
284
+ var found = merged.find();
285
+ len -= cur.text.length - found.from.ch;
286
+ cur = getLine(doc, found.to.line);
287
+ len += cur.text.length - found.to.ch;
288
+ }
289
+ return len;
290
+ }
291
+
292
+ function computeMaxLength(cm) {
293
+ var d = cm.display, doc = cm.doc;
294
+ d.maxLine = getLine(doc, doc.first);
295
+ d.maxLineLength = lineLength(doc, d.maxLine);
296
+ d.maxLineChanged = true;
297
+ doc.iter(function(line) {
298
+ var len = lineLength(doc, line);
299
+ if (len > d.maxLineLength) {
300
+ d.maxLineLength = len;
301
+ d.maxLine = line;
302
+ }
303
+ });
304
+ }
305
+
306
+ // Make sure the gutters options contains the element
307
+ // "CodeMirror-linenumbers" when the lineNumbers option is true.
308
+ function setGuttersForLineNumbers(options) {
309
+ var found = false;
310
+ for (var i = 0; i < options.gutters.length; ++i) {
311
+ if (options.gutters[i] == "CodeMirror-linenumbers") {
312
+ if (options.lineNumbers) found = true;
313
+ else options.gutters.splice(i--, 1);
314
+ }
315
+ }
316
+ if (!found && options.lineNumbers)
317
+ options.gutters.push("CodeMirror-linenumbers");
318
+ }
319
+
320
+ // SCROLLBARS
321
+
322
+ // Re-synchronize the fake scrollbars with the actual size of the
323
+ // content. Optionally force a scrollTop.
324
+ function updateScrollbars(cm) {
325
+ var d = cm.display, docHeight = cm.doc.height;
326
+ var totalHeight = docHeight + paddingVert(d);
327
+ d.sizer.style.minHeight = d.heightForcer.style.top = totalHeight + "px";
328
+ d.gutters.style.height = Math.max(totalHeight, d.scroller.clientHeight - scrollerCutOff) + "px";
329
+ var scrollHeight = Math.max(totalHeight, d.scroller.scrollHeight);
330
+ var needsH = d.scroller.scrollWidth > (d.scroller.clientWidth + 1);
331
+ var needsV = scrollHeight > (d.scroller.clientHeight + 1);
332
+ if (needsV) {
333
+ d.scrollbarV.style.display = "block";
334
+ d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0";
335
+ d.scrollbarV.firstChild.style.height =
336
+ (scrollHeight - d.scroller.clientHeight + d.scrollbarV.clientHeight) + "px";
337
+ } else d.scrollbarV.style.display = "";
338
+ if (needsH) {
339
+ d.scrollbarH.style.display = "block";
340
+ d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0";
341
+ d.scrollbarH.firstChild.style.width =
342
+ (d.scroller.scrollWidth - d.scroller.clientWidth + d.scrollbarH.clientWidth) + "px";
343
+ } else d.scrollbarH.style.display = "";
344
+ if (needsH && needsV) {
345
+ d.scrollbarFiller.style.display = "block";
346
+ d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px";
347
+ } else d.scrollbarFiller.style.display = "";
348
+ if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
349
+ d.gutterFiller.style.display = "block";
350
+ d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px";
351
+ d.gutterFiller.style.width = d.gutters.offsetWidth + "px";
352
+ } else d.gutterFiller.style.display = "";
353
+
354
+ if (mac_geLion && scrollbarWidth(d.measure) === 0)
355
+ d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px";
356
+ }
357
+
358
+ function visibleLines(display, doc, viewPort) {
359
+ var top = display.scroller.scrollTop, height = display.wrapper.clientHeight;
360
+ if (typeof viewPort == "number") top = viewPort;
361
+ else if (viewPort) {top = viewPort.top; height = viewPort.bottom - viewPort.top;}
362
+ top = Math.floor(top - paddingTop(display));
363
+ var bottom = Math.ceil(top + height);
364
+ return {from: lineAtHeight(doc, top), to: lineAtHeight(doc, bottom)};
365
+ }
366
+
367
+ // LINE NUMBERS
368
+
369
+ function alignHorizontally(cm) {
370
+ var display = cm.display;
371
+ if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
372
+ var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
373
+ var gutterW = display.gutters.offsetWidth, l = comp + "px";
374
+ for (var n = display.lineDiv.firstChild; n; n = n.nextSibling) if (n.alignable) {
375
+ for (var i = 0, a = n.alignable; i < a.length; ++i) a[i].style.left = l;
376
+ }
377
+ if (cm.options.fixedGutter)
378
+ display.gutters.style.left = (comp + gutterW) + "px";
379
+ }
380
+
381
+ function maybeUpdateLineNumberWidth(cm) {
382
+ if (!cm.options.lineNumbers) return false;
383
+ var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
384
+ if (last.length != display.lineNumChars) {
385
+ var test = display.measure.appendChild(elt("div", [elt("div", last)],
386
+ "CodeMirror-linenumber CodeMirror-gutter-elt"));
387
+ var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
388
+ display.lineGutter.style.width = "";
389
+ display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);
390
+ display.lineNumWidth = display.lineNumInnerWidth + padding;
391
+ display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
392
+ display.lineGutter.style.width = display.lineNumWidth + "px";
393
+ return true;
394
+ }
395
+ return false;
396
+ }
397
+
398
+ function lineNumberFor(options, i) {
399
+ return String(options.lineNumberFormatter(i + options.firstLineNumber));
400
+ }
401
+ function compensateForHScroll(display) {
402
+ return getRect(display.scroller).left - getRect(display.sizer).left;
403
+ }
404
+
405
+ // DISPLAY DRAWING
406
+
407
+ function updateDisplay(cm, changes, viewPort, forced) {
408
+ var oldFrom = cm.display.showingFrom, oldTo = cm.display.showingTo, updated;
409
+ var visible = visibleLines(cm.display, cm.doc, viewPort);
410
+ for (;;) {
411
+ if (!updateDisplayInner(cm, changes, visible, forced)) break;
412
+ forced = false;
413
+ updated = true;
414
+ updateSelection(cm);
415
+ updateScrollbars(cm);
416
+
417
+ // Clip forced viewport to actual scrollable area
418
+ if (viewPort)
419
+ viewPort = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight,
420
+ typeof viewPort == "number" ? viewPort : viewPort.top);
421
+ visible = visibleLines(cm.display, cm.doc, viewPort);
422
+ if (visible.from >= cm.display.showingFrom && visible.to <= cm.display.showingTo)
423
+ break;
424
+ changes = [];
425
+ }
426
+
427
+ if (updated) {
428
+ signalLater(cm, "update", cm);
429
+ if (cm.display.showingFrom != oldFrom || cm.display.showingTo != oldTo)
430
+ signalLater(cm, "viewportChange", cm, cm.display.showingFrom, cm.display.showingTo);
431
+ }
432
+ return updated;
433
+ }
434
+
435
+ // Uses a set of changes plus the current scroll position to
436
+ // determine which DOM updates have to be made, and makes the
437
+ // updates.
438
+ function updateDisplayInner(cm, changes, visible, forced) {
439
+ var display = cm.display, doc = cm.doc;
440
+ if (!display.wrapper.clientWidth) {
441
+ display.showingFrom = display.showingTo = doc.first;
442
+ display.viewOffset = 0;
443
+ return;
444
+ }
445
+
446
+ // Bail out if the visible area is already rendered and nothing changed.
447
+ if (!forced && changes.length == 0 &&
448
+ visible.from > display.showingFrom && visible.to < display.showingTo)
449
+ return;
450
+
451
+ if (maybeUpdateLineNumberWidth(cm))
452
+ changes = [{from: doc.first, to: doc.first + doc.size}];
453
+ var gutterW = display.sizer.style.marginLeft = display.gutters.offsetWidth + "px";
454
+ display.scrollbarH.style.left = cm.options.fixedGutter ? gutterW : "0";
455
+
456
+ // Used to determine which lines need their line numbers updated
457
+ var positionsChangedFrom = Infinity;
458
+ if (cm.options.lineNumbers)
459
+ for (var i = 0; i < changes.length; ++i)
460
+ if (changes[i].diff) { positionsChangedFrom = changes[i].from; break; }
461
+
462
+ var end = doc.first + doc.size;
463
+ var from = Math.max(visible.from - cm.options.viewportMargin, doc.first);
464
+ var to = Math.min(end, visible.to + cm.options.viewportMargin);
465
+ if (display.showingFrom < from && from - display.showingFrom < 20) from = Math.max(doc.first, display.showingFrom);
466
+ if (display.showingTo > to && display.showingTo - to < 20) to = Math.min(end, display.showingTo);
467
+ if (sawCollapsedSpans) {
468
+ from = lineNo(visualLine(doc, getLine(doc, from)));
469
+ while (to < end && lineIsHidden(doc, getLine(doc, to))) ++to;
470
+ }
471
+
472
+ // Create a range of theoretically intact lines, and punch holes
473
+ // in that using the change info.
474
+ var intact = [{from: Math.max(display.showingFrom, doc.first),
475
+ to: Math.min(display.showingTo, end)}];
476
+ if (intact[0].from >= intact[0].to) intact = [];
477
+ else intact = computeIntact(intact, changes);
478
+ // When merged lines are present, we might have to reduce the
479
+ // intact ranges because changes in continued fragments of the
480
+ // intact lines do require the lines to be redrawn.
481
+ if (sawCollapsedSpans)
482
+ for (var i = 0; i < intact.length; ++i) {
483
+ var range = intact[i], merged;
484
+ while (merged = collapsedSpanAtEnd(getLine(doc, range.to - 1))) {
485
+ var newTo = merged.find().from.line;
486
+ if (newTo > range.from) range.to = newTo;
487
+ else { intact.splice(i--, 1); break; }
488
+ }
489
+ }
490
+
491
+ // Clip off the parts that won't be visible
492
+ var intactLines = 0;
493
+ for (var i = 0; i < intact.length; ++i) {
494
+ var range = intact[i];
495
+ if (range.from < from) range.from = from;
496
+ if (range.to > to) range.to = to;
497
+ if (range.from >= range.to) intact.splice(i--, 1);
498
+ else intactLines += range.to - range.from;
499
+ }
500
+ if (!forced && intactLines == to - from && from == display.showingFrom && to == display.showingTo) {
501
+ updateViewOffset(cm);
502
+ return;
503
+ }
504
+ intact.sort(function(a, b) {return a.from - b.from;});
505
+
506
+ // Avoid crashing on IE's "unspecified error" when in iframes
507
+ try {
508
+ var focused = document.activeElement;
509
+ } catch(e) {}
510
+ if (intactLines < (to - from) * .7) display.lineDiv.style.display = "none";
511
+ patchDisplay(cm, from, to, intact, positionsChangedFrom);
512
+ display.lineDiv.style.display = "";
513
+ if (focused && document.activeElement != focused && focused.offsetHeight) focused.focus();
514
+
515
+ var different = from != display.showingFrom || to != display.showingTo ||
516
+ display.lastSizeC != display.wrapper.clientHeight;
517
+ // This is just a bogus formula that detects when the editor is
518
+ // resized or the font size changes.
519
+ if (different) {
520
+ display.lastSizeC = display.wrapper.clientHeight;
521
+ startWorker(cm, 400);
522
+ }
523
+ display.showingFrom = from; display.showingTo = to;
524
+
525
+ updateHeightsInViewport(cm);
526
+ updateViewOffset(cm);
527
+
528
+ return true;
529
+ }
530
+
531
+ function updateHeightsInViewport(cm) {
532
+ var display = cm.display;
533
+ var prevBottom = display.lineDiv.offsetTop;
534
+ for (var node = display.lineDiv.firstChild, height; node; node = node.nextSibling) if (node.lineObj) {
535
+ if (ie_lt8) {
536
+ var bot = node.offsetTop + node.offsetHeight;
537
+ height = bot - prevBottom;
538
+ prevBottom = bot;
539
+ } else {
540
+ var box = getRect(node);
541
+ height = box.bottom - box.top;
542
+ }
543
+ var diff = node.lineObj.height - height;
544
+ if (height < 2) height = textHeight(display);
545
+ if (diff > .001 || diff < -.001) {
546
+ updateLineHeight(node.lineObj, height);
547
+ var widgets = node.lineObj.widgets;
548
+ if (widgets) for (var i = 0; i < widgets.length; ++i)
549
+ widgets[i].height = widgets[i].node.offsetHeight;
550
+ }
551
+ }
552
+ }
553
+
554
+ function updateViewOffset(cm) {
555
+ var off = cm.display.viewOffset = heightAtLine(cm, getLine(cm.doc, cm.display.showingFrom));
556
+ // Position the mover div to align with the current virtual scroll position
557
+ cm.display.mover.style.top = off + "px";
558
+ }
559
+
560
+ function computeIntact(intact, changes) {
561
+ for (var i = 0, l = changes.length || 0; i < l; ++i) {
562
+ var change = changes[i], intact2 = [], diff = change.diff || 0;
563
+ for (var j = 0, l2 = intact.length; j < l2; ++j) {
564
+ var range = intact[j];
565
+ if (change.to <= range.from && change.diff) {
566
+ intact2.push({from: range.from + diff, to: range.to + diff});
567
+ } else if (change.to <= range.from || change.from >= range.to) {
568
+ intact2.push(range);
569
+ } else {
570
+ if (change.from > range.from)
571
+ intact2.push({from: range.from, to: change.from});
572
+ if (change.to < range.to)
573
+ intact2.push({from: change.to + diff, to: range.to + diff});
574
+ }
575
+ }
576
+ intact = intact2;
577
+ }
578
+ return intact;
579
+ }
580
+
581
+ function getDimensions(cm) {
582
+ var d = cm.display, left = {}, width = {};
583
+ for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
584
+ left[cm.options.gutters[i]] = n.offsetLeft;
585
+ width[cm.options.gutters[i]] = n.offsetWidth;
586
+ }
587
+ return {fixedPos: compensateForHScroll(d),
588
+ gutterTotalWidth: d.gutters.offsetWidth,
589
+ gutterLeft: left,
590
+ gutterWidth: width,
591
+ wrapperWidth: d.wrapper.clientWidth};
592
+ }
593
+
594
+ function patchDisplay(cm, from, to, intact, updateNumbersFrom) {
595
+ var dims = getDimensions(cm);
596
+ var display = cm.display, lineNumbers = cm.options.lineNumbers;
597
+ if (!intact.length && (!webkit || !cm.display.currentWheelTarget))
598
+ removeChildren(display.lineDiv);
599
+ var container = display.lineDiv, cur = container.firstChild;
600
+
601
+ function rm(node) {
602
+ var next = node.nextSibling;
603
+ if (webkit && mac && cm.display.currentWheelTarget == node) {
604
+ node.style.display = "none";
605
+ node.lineObj = null;
606
+ } else {
607
+ node.parentNode.removeChild(node);
608
+ }
609
+ return next;
610
+ }
611
+
612
+ var nextIntact = intact.shift(), lineN = from;
613
+ cm.doc.iter(from, to, function(line) {
614
+ if (nextIntact && nextIntact.to == lineN) nextIntact = intact.shift();
615
+ if (lineIsHidden(cm.doc, line)) {
616
+ if (line.height != 0) updateLineHeight(line, 0);
617
+ if (line.widgets && cur.previousSibling) for (var i = 0; i < line.widgets.length; ++i) {
618
+ var w = line.widgets[i];
619
+ if (w.showIfHidden) {
620
+ var prev = cur.previousSibling;
621
+ if (/pre/i.test(prev.nodeName)) {
622
+ var wrap = elt("div", null, null, "position: relative");
623
+ prev.parentNode.replaceChild(wrap, prev);
624
+ wrap.appendChild(prev);
625
+ prev = wrap;
626
+ }
627
+ var wnode = prev.appendChild(elt("div", [w.node], "CodeMirror-linewidget"));
628
+ if (!w.handleMouseEvents) wnode.ignoreEvents = true;
629
+ positionLineWidget(w, wnode, prev, dims);
630
+ }
631
+ }
632
+ } else if (nextIntact && nextIntact.from <= lineN && nextIntact.to > lineN) {
633
+ // This line is intact. Skip to the actual node. Update its
634
+ // line number if needed.
635
+ while (cur.lineObj != line) cur = rm(cur);
636
+ if (lineNumbers && updateNumbersFrom <= lineN && cur.lineNumber)
637
+ setTextContent(cur.lineNumber, lineNumberFor(cm.options, lineN));
638
+ cur = cur.nextSibling;
639
+ } else {
640
+ // For lines with widgets, make an attempt to find and reuse
641
+ // the existing element, so that widgets aren't needlessly
642
+ // removed and re-inserted into the dom
643
+ if (line.widgets) for (var j = 0, search = cur, reuse; search && j < 20; ++j, search = search.nextSibling)
644
+ if (search.lineObj == line && /div/i.test(search.nodeName)) { reuse = search; break; }
645
+ // This line needs to be generated.
646
+ var lineNode = buildLineElement(cm, line, lineN, dims, reuse);
647
+ if (lineNode != reuse) {
648
+ container.insertBefore(lineNode, cur);
649
+ } else {
650
+ while (cur != reuse) cur = rm(cur);
651
+ cur = cur.nextSibling;
652
+ }
653
+
654
+ lineNode.lineObj = line;
655
+ }
656
+ ++lineN;
657
+ });
658
+ while (cur) cur = rm(cur);
659
+ }
660
+
661
+ function buildLineElement(cm, line, lineNo, dims, reuse) {
662
+ var lineElement = lineContent(cm, line);
663
+ var markers = line.gutterMarkers, display = cm.display, wrap;
664
+
665
+ if (!cm.options.lineNumbers && !markers && !line.bgClass && !line.wrapClass && !line.widgets)
666
+ return lineElement;
667
+
668
+ // Lines with gutter elements, widgets or a background class need
669
+ // to be wrapped again, and have the extra elements added to the
670
+ // wrapper div
671
+
672
+ if (reuse) {
673
+ reuse.alignable = null;
674
+ var isOk = true, widgetsSeen = 0, insertBefore = null;
675
+ for (var n = reuse.firstChild, next; n; n = next) {
676
+ next = n.nextSibling;
677
+ if (!/\bCodeMirror-linewidget\b/.test(n.className)) {
678
+ reuse.removeChild(n);
679
+ } else {
680
+ for (var i = 0; i < line.widgets.length; ++i) {
681
+ var widget = line.widgets[i];
682
+ if (widget.node == n.firstChild) {
683
+ if (!widget.above && !insertBefore) insertBefore = n;
684
+ positionLineWidget(widget, n, reuse, dims);
685
+ ++widgetsSeen;
686
+ break;
687
+ }
688
+ }
689
+ if (i == line.widgets.length) { isOk = false; break; }
690
+ }
691
+ }
692
+ reuse.insertBefore(lineElement, insertBefore);
693
+ if (isOk && widgetsSeen == line.widgets.length) {
694
+ wrap = reuse;
695
+ reuse.className = line.wrapClass || "";
696
+ }
697
+ }
698
+ if (!wrap) {
699
+ wrap = elt("div", null, line.wrapClass, "position: relative");
700
+ wrap.appendChild(lineElement);
701
+ }
702
+ // Kludge to make sure the styled element lies behind the selection (by z-index)
703
+ if (line.bgClass)
704
+ wrap.insertBefore(elt("div", null, line.bgClass + " CodeMirror-linebackground"), wrap.firstChild);
705
+ if (cm.options.lineNumbers || markers) {
706
+ var gutterWrap = wrap.insertBefore(elt("div", null, null, "position: absolute; left: " +
707
+ (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"),
708
+ wrap.firstChild);
709
+ if (cm.options.fixedGutter) (wrap.alignable || (wrap.alignable = [])).push(gutterWrap);
710
+ if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
711
+ wrap.lineNumber = gutterWrap.appendChild(
712
+ elt("div", lineNumberFor(cm.options, lineNo),
713
+ "CodeMirror-linenumber CodeMirror-gutter-elt",
714
+ "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
715
+ + display.lineNumInnerWidth + "px"));
716
+ if (markers)
717
+ for (var k = 0; k < cm.options.gutters.length; ++k) {
718
+ var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
719
+ if (found)
720
+ gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
721
+ dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
722
+ }
723
+ }
724
+ if (ie_lt8) wrap.style.zIndex = 2;
725
+ if (line.widgets && wrap != reuse) for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
726
+ var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
727
+ if (!widget.handleMouseEvents) node.ignoreEvents = true;
728
+ positionLineWidget(widget, node, wrap, dims);
729
+ if (widget.above)
730
+ wrap.insertBefore(node, cm.options.lineNumbers && line.height != 0 ? gutterWrap : lineElement);
731
+ else
732
+ wrap.appendChild(node);
733
+ signalLater(widget, "redraw");
734
+ }
735
+ return wrap;
736
+ }
737
+
738
+ function positionLineWidget(widget, node, wrap, dims) {
739
+ if (widget.noHScroll) {
740
+ (wrap.alignable || (wrap.alignable = [])).push(node);
741
+ var width = dims.wrapperWidth;
742
+ node.style.left = dims.fixedPos + "px";
743
+ if (!widget.coverGutter) {
744
+ width -= dims.gutterTotalWidth;
745
+ node.style.paddingLeft = dims.gutterTotalWidth + "px";
746
+ }
747
+ node.style.width = width + "px";
748
+ }
749
+ if (widget.coverGutter) {
750
+ node.style.zIndex = 5;
751
+ node.style.position = "relative";
752
+ if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
753
+ }
754
+ }
755
+
756
+ // SELECTION / CURSOR
757
+
758
+ function updateSelection(cm) {
759
+ var display = cm.display;
760
+ var collapsed = posEq(cm.doc.sel.from, cm.doc.sel.to);
761
+ if (collapsed || cm.options.showCursorWhenSelecting)
762
+ updateSelectionCursor(cm);
763
+ else
764
+ display.cursor.style.display = display.otherCursor.style.display = "none";
765
+ if (!collapsed)
766
+ updateSelectionRange(cm);
767
+ else
768
+ display.selectionDiv.style.display = "none";
769
+
770
+ // Move the hidden textarea near the cursor to prevent scrolling artifacts
771
+ if (cm.options.moveInputWithCursor) {
772
+ var headPos = cursorCoords(cm, cm.doc.sel.head, "div");
773
+ var wrapOff = getRect(display.wrapper), lineOff = getRect(display.lineDiv);
774
+ display.inputDiv.style.top = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
775
+ headPos.top + lineOff.top - wrapOff.top)) + "px";
776
+ display.inputDiv.style.left = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
777
+ headPos.left + lineOff.left - wrapOff.left)) + "px";
778
+ }
779
+ }
780
+
781
+ // No selection, plain cursor
782
+ function updateSelectionCursor(cm) {
783
+ var display = cm.display, pos = cursorCoords(cm, cm.doc.sel.head, "div");
784
+ display.cursor.style.left = pos.left + "px";
785
+ display.cursor.style.top = pos.top + "px";
786
+ display.cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
787
+ display.cursor.style.display = "";
788
+
789
+ if (pos.other) {
790
+ display.otherCursor.style.display = "";
791
+ display.otherCursor.style.left = pos.other.left + "px";
792
+ display.otherCursor.style.top = pos.other.top + "px";
793
+ display.otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
794
+ } else { display.otherCursor.style.display = "none"; }
795
+ }
796
+
797
+ // Highlight selection
798
+ function updateSelectionRange(cm) {
799
+ var display = cm.display, doc = cm.doc, sel = cm.doc.sel;
800
+ var fragment = document.createDocumentFragment();
801
+ var clientWidth = display.lineSpace.offsetWidth, pl = paddingLeft(cm.display);
802
+
803
+ function add(left, top, width, bottom) {
804
+ if (top < 0) top = 0;
805
+ fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
806
+ "px; top: " + top + "px; width: " + (width == null ? clientWidth - left : width) +
807
+ "px; height: " + (bottom - top) + "px"));
808
+ }
809
+
810
+ function drawForLine(line, fromArg, toArg) {
811
+ var lineObj = getLine(doc, line);
812
+ var lineLen = lineObj.text.length;
813
+ var start, end;
814
+ function coords(ch, bias) {
815
+ return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
816
+ }
817
+
818
+ iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
819
+ var leftPos = coords(from, "left"), rightPos, left, right;
820
+ if (from == to) {
821
+ rightPos = leftPos;
822
+ left = right = leftPos.left;
823
+ } else {
824
+ rightPos = coords(to - 1, "right");
825
+ if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
826
+ left = leftPos.left;
827
+ right = rightPos.right;
828
+ }
829
+ if (fromArg == null && from == 0) left = pl;
830
+ if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
831
+ add(left, leftPos.top, null, leftPos.bottom);
832
+ left = pl;
833
+ if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
834
+ }
835
+ if (toArg == null && to == lineLen) right = clientWidth;
836
+ if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
837
+ start = leftPos;
838
+ if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
839
+ end = rightPos;
840
+ if (left < pl + 1) left = pl;
841
+ add(left, rightPos.top, right - left, rightPos.bottom);
842
+ });
843
+ return {start: start, end: end};
844
+ }
845
+
846
+ if (sel.from.line == sel.to.line) {
847
+ drawForLine(sel.from.line, sel.from.ch, sel.to.ch);
848
+ } else {
849
+ var fromLine = getLine(doc, sel.from.line), toLine = getLine(doc, sel.to.line);
850
+ var singleVLine = visualLine(doc, fromLine) == visualLine(doc, toLine);
851
+ var leftEnd = drawForLine(sel.from.line, sel.from.ch, singleVLine ? fromLine.text.length : null).end;
852
+ var rightStart = drawForLine(sel.to.line, singleVLine ? 0 : null, sel.to.ch).start;
853
+ if (singleVLine) {
854
+ if (leftEnd.top < rightStart.top - 2) {
855
+ add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
856
+ add(pl, rightStart.top, rightStart.left, rightStart.bottom);
857
+ } else {
858
+ add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
859
+ }
860
+ }
861
+ if (leftEnd.bottom < rightStart.top)
862
+ add(pl, leftEnd.bottom, null, rightStart.top);
863
+ }
864
+
865
+ removeChildrenAndAdd(display.selectionDiv, fragment);
866
+ display.selectionDiv.style.display = "";
867
+ }
868
+
869
+ // Cursor-blinking
870
+ function restartBlink(cm) {
871
+ if (!cm.state.focused) return;
872
+ var display = cm.display;
873
+ clearInterval(display.blinker);
874
+ var on = true;
875
+ display.cursor.style.visibility = display.otherCursor.style.visibility = "";
876
+ display.blinker = setInterval(function() {
877
+ display.cursor.style.visibility = display.otherCursor.style.visibility = (on = !on) ? "" : "hidden";
878
+ }, cm.options.cursorBlinkRate);
879
+ }
880
+
881
+ // HIGHLIGHT WORKER
882
+
883
+ function startWorker(cm, time) {
884
+ if (cm.doc.mode.startState && cm.doc.frontier < cm.display.showingTo)
885
+ cm.state.highlight.set(time, bind(highlightWorker, cm));
886
+ }
887
+
888
+ function highlightWorker(cm) {
889
+ var doc = cm.doc;
890
+ if (doc.frontier < doc.first) doc.frontier = doc.first;
891
+ if (doc.frontier >= cm.display.showingTo) return;
892
+ var end = +new Date + cm.options.workTime;
893
+ var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
894
+ var changed = [], prevChange;
895
+ doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.showingTo + 500), function(line) {
896
+ if (doc.frontier >= cm.display.showingFrom) { // Visible
897
+ var oldStyles = line.styles;
898
+ line.styles = highlightLine(cm, line, state);
899
+ var ischange = !oldStyles || oldStyles.length != line.styles.length;
900
+ for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
901
+ if (ischange) {
902
+ if (prevChange && prevChange.end == doc.frontier) prevChange.end++;
903
+ else changed.push(prevChange = {start: doc.frontier, end: doc.frontier + 1});
904
+ }
905
+ line.stateAfter = copyState(doc.mode, state);
906
+ } else {
907
+ processLine(cm, line, state);
908
+ line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
909
+ }
910
+ ++doc.frontier;
911
+ if (+new Date > end) {
912
+ startWorker(cm, cm.options.workDelay);
913
+ return true;
914
+ }
915
+ });
916
+ if (changed.length)
917
+ operation(cm, function() {
918
+ for (var i = 0; i < changed.length; ++i)
919
+ regChange(this, changed[i].start, changed[i].end);
920
+ })();
921
+ }
922
+
923
+ // Finds the line to start with when starting a parse. Tries to
924
+ // find a line with a stateAfter, so that it can start with a
925
+ // valid state. If that fails, it returns the line with the
926
+ // smallest indentation, which tends to need the least context to
927
+ // parse correctly.
928
+ function findStartLine(cm, n, precise) {
929
+ var minindent, minline, doc = cm.doc;
930
+ for (var search = n, lim = n - 100; search > lim; --search) {
931
+ if (search <= doc.first) return doc.first;
932
+ var line = getLine(doc, search - 1);
933
+ if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
934
+ var indented = countColumn(line.text, null, cm.options.tabSize);
935
+ if (minline == null || minindent > indented) {
936
+ minline = search - 1;
937
+ minindent = indented;
938
+ }
939
+ }
940
+ return minline;
941
+ }
942
+
943
+ function getStateBefore(cm, n, precise) {
944
+ var doc = cm.doc, display = cm.display;
945
+ if (!doc.mode.startState) return true;
946
+ var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
947
+ if (!state) state = startState(doc.mode);
948
+ else state = copyState(doc.mode, state);
949
+ doc.iter(pos, n, function(line) {
950
+ processLine(cm, line, state);
951
+ var save = pos == n - 1 || pos % 5 == 0 || pos >= display.showingFrom && pos < display.showingTo;
952
+ line.stateAfter = save ? copyState(doc.mode, state) : null;
953
+ ++pos;
954
+ });
955
+ return state;
956
+ }
957
+
958
+ // POSITION MEASUREMENT
959
+
960
+ function paddingTop(display) {return display.lineSpace.offsetTop;}
961
+ function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
962
+ function paddingLeft(display) {
963
+ var e = removeChildrenAndAdd(display.measure, elt("pre", null, null, "text-align: left")).appendChild(elt("span", "x"));
964
+ return e.offsetLeft;
965
+ }
966
+
967
+ function measureChar(cm, line, ch, data, bias) {
968
+ var dir = -1;
969
+ data = data || measureLine(cm, line);
970
+
971
+ for (var pos = ch;; pos += dir) {
972
+ var r = data[pos];
973
+ if (r) break;
974
+ if (dir < 0 && pos == 0) dir = 1;
975
+ }
976
+ bias = pos > ch ? "left" : pos < ch ? "right" : bias;
977
+ if (bias == "left" && r.leftSide) r = r.leftSide;
978
+ else if (bias == "right" && r.rightSide) r = r.rightSide;
979
+ return {left: pos < ch ? r.right : r.left,
980
+ right: pos > ch ? r.left : r.right,
981
+ top: r.top,
982
+ bottom: r.bottom};
983
+ }
984
+
985
+ function findCachedMeasurement(cm, line) {
986
+ var cache = cm.display.measureLineCache;
987
+ for (var i = 0; i < cache.length; ++i) {
988
+ var memo = cache[i];
989
+ if (memo.text == line.text && memo.markedSpans == line.markedSpans &&
990
+ cm.display.scroller.clientWidth == memo.width &&
991
+ memo.classes == line.textClass + "|" + line.bgClass + "|" + line.wrapClass)
992
+ return memo;
993
+ }
994
+ }
995
+
996
+ function clearCachedMeasurement(cm, line) {
997
+ var exists = findCachedMeasurement(cm, line);
998
+ if (exists) exists.text = exists.measure = exists.markedSpans = null;
999
+ }
1000
+
1001
+ function measureLine(cm, line) {
1002
+ // First look in the cache
1003
+ var cached = findCachedMeasurement(cm, line);
1004
+ if (cached) return cached.measure;
1005
+
1006
+ // Failing that, recompute and store result in cache
1007
+ var measure = measureLineInner(cm, line);
1008
+ var cache = cm.display.measureLineCache;
1009
+ var memo = {text: line.text, width: cm.display.scroller.clientWidth,
1010
+ markedSpans: line.markedSpans, measure: measure,
1011
+ classes: line.textClass + "|" + line.bgClass + "|" + line.wrapClass};
1012
+ if (cache.length == 16) cache[++cm.display.measureLineCachePos % 16] = memo;
1013
+ else cache.push(memo);
1014
+ return measure;
1015
+ }
1016
+
1017
+ function measureLineInner(cm, line) {
1018
+ var display = cm.display, measure = emptyArray(line.text.length);
1019
+ var pre = lineContent(cm, line, measure, true);
1020
+
1021
+ // IE does not cache element positions of inline elements between
1022
+ // calls to getBoundingClientRect. This makes the loop below,
1023
+ // which gathers the positions of all the characters on the line,
1024
+ // do an amount of layout work quadratic to the number of
1025
+ // characters. When line wrapping is off, we try to improve things
1026
+ // by first subdividing the line into a bunch of inline blocks, so
1027
+ // that IE can reuse most of the layout information from caches
1028
+ // for those blocks. This does interfere with line wrapping, so it
1029
+ // doesn't work when wrapping is on, but in that case the
1030
+ // situation is slightly better, since IE does cache line-wrapping
1031
+ // information and only recomputes per-line.
1032
+ if (ie && !ie_lt8 && !cm.options.lineWrapping && pre.childNodes.length > 100) {
1033
+ var fragment = document.createDocumentFragment();
1034
+ var chunk = 10, n = pre.childNodes.length;
1035
+ for (var i = 0, chunks = Math.ceil(n / chunk); i < chunks; ++i) {
1036
+ var wrap = elt("div", null, null, "display: inline-block");
1037
+ for (var j = 0; j < chunk && n; ++j) {
1038
+ wrap.appendChild(pre.firstChild);
1039
+ --n;
1040
+ }
1041
+ fragment.appendChild(wrap);
1042
+ }
1043
+ pre.appendChild(fragment);
1044
+ }
1045
+
1046
+ removeChildrenAndAdd(display.measure, pre);
1047
+
1048
+ var outer = getRect(display.lineDiv);
1049
+ var vranges = [], data = emptyArray(line.text.length), maxBot = pre.offsetHeight;
1050
+ // Work around an IE7/8 bug where it will sometimes have randomly
1051
+ // replaced our pre with a clone at this point.
1052
+ if (ie_lt9 && display.measure.first != pre)
1053
+ removeChildrenAndAdd(display.measure, pre);
1054
+
1055
+ function measureRect(rect) {
1056
+ var top = rect.top - outer.top, bot = rect.bottom - outer.top;
1057
+ if (bot > maxBot) bot = maxBot;
1058
+ if (top < 0) top = 0;
1059
+ for (var i = vranges.length - 2; i >= 0; i -= 2) {
1060
+ var rtop = vranges[i], rbot = vranges[i+1];
1061
+ if (rtop > bot || rbot < top) continue;
1062
+ if (rtop <= top && rbot >= bot ||
1063
+ top <= rtop && bot >= rbot ||
1064
+ Math.min(bot, rbot) - Math.max(top, rtop) >= (bot - top) >> 1) {
1065
+ vranges[i] = Math.min(top, rtop);
1066
+ vranges[i+1] = Math.max(bot, rbot);
1067
+ break;
1068
+ }
1069
+ }
1070
+ if (i < 0) { i = vranges.length; vranges.push(top, bot); }
1071
+ return {left: rect.left - outer.left,
1072
+ right: rect.right - outer.left,
1073
+ top: i, bottom: null};
1074
+ }
1075
+ function finishRect(rect) {
1076
+ rect.bottom = vranges[rect.top+1];
1077
+ rect.top = vranges[rect.top];
1078
+ }
1079
+
1080
+ for (var i = 0, cur; i < measure.length; ++i) if (cur = measure[i]) {
1081
+ var node = cur, rect = null;
1082
+ // A widget might wrap, needs special care
1083
+ if (/\bCodeMirror-widget\b/.test(cur.className) && cur.getClientRects) {
1084
+ if (cur.firstChild.nodeType == 1) node = cur.firstChild;
1085
+ var rects = node.getClientRects();
1086
+ if (rects.length > 1) {
1087
+ rect = data[i] = measureRect(rects[0]);
1088
+ rect.rightSide = measureRect(rects[rects.length - 1]);
1089
+ }
1090
+ }
1091
+ if (!rect) rect = data[i] = measureRect(getRect(node));
1092
+ if (cur.measureRight) rect.right = getRect(cur.measureRight).left;
1093
+ if (cur.leftSide) rect.leftSide = measureRect(getRect(cur.leftSide));
1094
+ }
1095
+ for (var i = 0, cur; i < data.length; ++i) if (cur = data[i]) {
1096
+ finishRect(cur);
1097
+ if (cur.leftSide) finishRect(cur.leftSide);
1098
+ if (cur.rightSide) finishRect(cur.rightSide);
1099
+ }
1100
+ return data;
1101
+ }
1102
+
1103
+ function measureLineWidth(cm, line) {
1104
+ var hasBadSpan = false;
1105
+ if (line.markedSpans) for (var i = 0; i < line.markedSpans; ++i) {
1106
+ var sp = line.markedSpans[i];
1107
+ if (sp.collapsed && (sp.to == null || sp.to == line.text.length)) hasBadSpan = true;
1108
+ }
1109
+ var cached = !hasBadSpan && findCachedMeasurement(cm, line);
1110
+ if (cached) return measureChar(cm, line, line.text.length, cached.measure, "right").right;
1111
+
1112
+ var pre = lineContent(cm, line, null, true);
1113
+ var end = pre.appendChild(zeroWidthElement(cm.display.measure));
1114
+ removeChildrenAndAdd(cm.display.measure, pre);
1115
+ return getRect(end).right - getRect(cm.display.lineDiv).left;
1116
+ }
1117
+
1118
+ function clearCaches(cm) {
1119
+ cm.display.measureLineCache.length = cm.display.measureLineCachePos = 0;
1120
+ cm.display.cachedCharWidth = cm.display.cachedTextHeight = null;
1121
+ if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
1122
+ cm.display.lineNumChars = null;
1123
+ }
1124
+
1125
+ function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
1126
+ function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
1127
+
1128
+ // Context is one of "line", "div" (display.lineDiv), "local"/null (editor), or "page"
1129
+ function intoCoordSystem(cm, lineObj, rect, context) {
1130
+ if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
1131
+ var size = widgetHeight(lineObj.widgets[i]);
1132
+ rect.top += size; rect.bottom += size;
1133
+ }
1134
+ if (context == "line") return rect;
1135
+ if (!context) context = "local";
1136
+ var yOff = heightAtLine(cm, lineObj);
1137
+ if (context == "local") yOff += paddingTop(cm.display);
1138
+ else yOff -= cm.display.viewOffset;
1139
+ if (context == "page" || context == "window") {
1140
+ var lOff = getRect(cm.display.lineSpace);
1141
+ yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
1142
+ var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
1143
+ rect.left += xOff; rect.right += xOff;
1144
+ }
1145
+ rect.top += yOff; rect.bottom += yOff;
1146
+ return rect;
1147
+ }
1148
+
1149
+ // Context may be "window", "page", "div", or "local"/null
1150
+ // Result is in "div" coords
1151
+ function fromCoordSystem(cm, coords, context) {
1152
+ if (context == "div") return coords;
1153
+ var left = coords.left, top = coords.top;
1154
+ // First move into "page" coordinate system
1155
+ if (context == "page") {
1156
+ left -= pageScrollX();
1157
+ top -= pageScrollY();
1158
+ } else if (context == "local" || !context) {
1159
+ var localBox = getRect(cm.display.sizer);
1160
+ left += localBox.left;
1161
+ top += localBox.top;
1162
+ }
1163
+
1164
+ var lineSpaceBox = getRect(cm.display.lineSpace);
1165
+ return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
1166
+ }
1167
+
1168
+ function charCoords(cm, pos, context, lineObj, bias) {
1169
+ if (!lineObj) lineObj = getLine(cm.doc, pos.line);
1170
+ return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, null, bias), context);
1171
+ }
1172
+
1173
+ function cursorCoords(cm, pos, context, lineObj, measurement) {
1174
+ lineObj = lineObj || getLine(cm.doc, pos.line);
1175
+ if (!measurement) measurement = measureLine(cm, lineObj);
1176
+ function get(ch, right) {
1177
+ var m = measureChar(cm, lineObj, ch, measurement, right ? "right" : "left");
1178
+ if (right) m.left = m.right; else m.right = m.left;
1179
+ return intoCoordSystem(cm, lineObj, m, context);
1180
+ }
1181
+ function getBidi(ch, partPos) {
1182
+ var part = order[partPos], right = part.level % 2;
1183
+ if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
1184
+ part = order[--partPos];
1185
+ ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
1186
+ right = true;
1187
+ } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
1188
+ part = order[++partPos];
1189
+ ch = bidiLeft(part) - part.level % 2;
1190
+ right = false;
1191
+ }
1192
+ if (right && ch == part.to && ch > part.from) return get(ch - 1);
1193
+ return get(ch, right);
1194
+ }
1195
+ var order = getOrder(lineObj), ch = pos.ch;
1196
+ if (!order) return get(ch);
1197
+ var partPos = getBidiPartAt(order, ch);
1198
+ var val = getBidi(ch, partPos);
1199
+ if (bidiOther != null) val.other = getBidi(ch, bidiOther);
1200
+ return val;
1201
+ }
1202
+
1203
+ function PosWithInfo(line, ch, outside, xRel) {
1204
+ var pos = new Pos(line, ch);
1205
+ pos.xRel = xRel;
1206
+ if (outside) pos.outside = true;
1207
+ return pos;
1208
+ }
1209
+
1210
+ // Coords must be lineSpace-local
1211
+ function coordsChar(cm, x, y) {
1212
+ var doc = cm.doc;
1213
+ y += cm.display.viewOffset;
1214
+ if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
1215
+ var lineNo = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
1216
+ if (lineNo > last)
1217
+ return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
1218
+ if (x < 0) x = 0;
1219
+
1220
+ for (;;) {
1221
+ var lineObj = getLine(doc, lineNo);
1222
+ var found = coordsCharInner(cm, lineObj, lineNo, x, y);
1223
+ var merged = collapsedSpanAtEnd(lineObj);
1224
+ var mergedPos = merged && merged.find();
1225
+ if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
1226
+ lineNo = mergedPos.to.line;
1227
+ else
1228
+ return found;
1229
+ }
1230
+ }
1231
+
1232
+ function coordsCharInner(cm, lineObj, lineNo, x, y) {
1233
+ var innerOff = y - heightAtLine(cm, lineObj);
1234
+ var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
1235
+ var measurement = measureLine(cm, lineObj);
1236
+
1237
+ function getX(ch) {
1238
+ var sp = cursorCoords(cm, Pos(lineNo, ch), "line",
1239
+ lineObj, measurement);
1240
+ wrongLine = true;
1241
+ if (innerOff > sp.bottom) return sp.left - adjust;
1242
+ else if (innerOff < sp.top) return sp.left + adjust;
1243
+ else wrongLine = false;
1244
+ return sp.left;
1245
+ }
1246
+
1247
+ var bidi = getOrder(lineObj), dist = lineObj.text.length;
1248
+ var from = lineLeft(lineObj), to = lineRight(lineObj);
1249
+ var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
1250
+
1251
+ if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
1252
+ // Do a binary search between these bounds.
1253
+ for (;;) {
1254
+ if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
1255
+ var ch = x < fromX || x - fromX <= toX - x ? from : to;
1256
+ var xDiff = x - (ch == from ? fromX : toX);
1257
+ while (isExtendingChar.test(lineObj.text.charAt(ch))) ++ch;
1258
+ var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
1259
+ xDiff < 0 ? -1 : xDiff ? 1 : 0);
1260
+ return pos;
1261
+ }
1262
+ var step = Math.ceil(dist / 2), middle = from + step;
1263
+ if (bidi) {
1264
+ middle = from;
1265
+ for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
1266
+ }
1267
+ var middleX = getX(middle);
1268
+ if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
1269
+ else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
1270
+ }
1271
+ }
1272
+
1273
+ var measureText;
1274
+ function textHeight(display) {
1275
+ if (display.cachedTextHeight != null) return display.cachedTextHeight;
1276
+ if (measureText == null) {
1277
+ measureText = elt("pre");
1278
+ // Measure a bunch of lines, for browsers that compute
1279
+ // fractional heights.
1280
+ for (var i = 0; i < 49; ++i) {
1281
+ measureText.appendChild(document.createTextNode("x"));
1282
+ measureText.appendChild(elt("br"));
1283
+ }
1284
+ measureText.appendChild(document.createTextNode("x"));
1285
+ }
1286
+ removeChildrenAndAdd(display.measure, measureText);
1287
+ var height = measureText.offsetHeight / 50;
1288
+ if (height > 3) display.cachedTextHeight = height;
1289
+ removeChildren(display.measure);
1290
+ return height || 1;
1291
+ }
1292
+
1293
+ function charWidth(display) {
1294
+ if (display.cachedCharWidth != null) return display.cachedCharWidth;
1295
+ var anchor = elt("span", "x");
1296
+ var pre = elt("pre", [anchor]);
1297
+ removeChildrenAndAdd(display.measure, pre);
1298
+ var width = anchor.offsetWidth;
1299
+ if (width > 2) display.cachedCharWidth = width;
1300
+ return width || 10;
1301
+ }
1302
+
1303
+ // OPERATIONS
1304
+
1305
+ // Operations are used to wrap changes in such a way that each
1306
+ // change won't have to update the cursor and display (which would
1307
+ // be awkward, slow, and error-prone), but instead updates are
1308
+ // batched and then all combined and executed at once.
1309
+
1310
+ var nextOpId = 0;
1311
+ function startOperation(cm) {
1312
+ cm.curOp = {
1313
+ // An array of ranges of lines that have to be updated. See
1314
+ // updateDisplay.
1315
+ changes: [],
1316
+ forceUpdate: false,
1317
+ updateInput: null,
1318
+ userSelChange: null,
1319
+ textChanged: null,
1320
+ selectionChanged: false,
1321
+ cursorActivity: false,
1322
+ updateMaxLine: false,
1323
+ updateScrollPos: false,
1324
+ id: ++nextOpId
1325
+ };
1326
+ if (!delayedCallbackDepth++) delayedCallbacks = [];
1327
+ }
1328
+
1329
+ function endOperation(cm) {
1330
+ var op = cm.curOp, doc = cm.doc, display = cm.display;
1331
+ cm.curOp = null;
1332
+
1333
+ if (op.updateMaxLine) computeMaxLength(cm);
1334
+ if (display.maxLineChanged && !cm.options.lineWrapping && display.maxLine) {
1335
+ var width = measureLineWidth(cm, display.maxLine);
1336
+ display.sizer.style.minWidth = Math.max(0, width + 3 + scrollerCutOff) + "px";
1337
+ display.maxLineChanged = false;
1338
+ var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + display.sizer.offsetWidth - display.scroller.clientWidth);
1339
+ if (maxScrollLeft < doc.scrollLeft && !op.updateScrollPos)
1340
+ setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true);
1341
+ }
1342
+ var newScrollPos, updated;
1343
+ if (op.updateScrollPos) {
1344
+ newScrollPos = op.updateScrollPos;
1345
+ } else if (op.selectionChanged && display.scroller.clientHeight) { // don't rescroll if not visible
1346
+ var coords = cursorCoords(cm, doc.sel.head);
1347
+ newScrollPos = calculateScrollPos(cm, coords.left, coords.top, coords.left, coords.bottom);
1348
+ }
1349
+ if (op.changes.length || op.forceUpdate || newScrollPos && newScrollPos.scrollTop != null) {
1350
+ updated = updateDisplay(cm, op.changes, newScrollPos && newScrollPos.scrollTop, op.forceUpdate);
1351
+ if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop;
1352
+ }
1353
+ if (!updated && op.selectionChanged) updateSelection(cm);
1354
+ if (op.updateScrollPos) {
1355
+ display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = newScrollPos.scrollTop;
1356
+ display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = newScrollPos.scrollLeft;
1357
+ alignHorizontally(cm);
1358
+ if (op.scrollToPos)
1359
+ scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos), op.scrollToPosMargin);
1360
+ } else if (newScrollPos) {
1361
+ scrollCursorIntoView(cm);
1362
+ }
1363
+ if (op.selectionChanged) restartBlink(cm);
1364
+
1365
+ if (cm.state.focused && op.updateInput)
1366
+ resetInput(cm, op.userSelChange);
1367
+
1368
+ var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
1369
+ if (hidden) for (var i = 0; i < hidden.length; ++i)
1370
+ if (!hidden[i].lines.length) signal(hidden[i], "hide");
1371
+ if (unhidden) for (var i = 0; i < unhidden.length; ++i)
1372
+ if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
1373
+
1374
+ var delayed;
1375
+ if (!--delayedCallbackDepth) {
1376
+ delayed = delayedCallbacks;
1377
+ delayedCallbacks = null;
1378
+ }
1379
+ if (op.textChanged)
1380
+ signal(cm, "change", cm, op.textChanged);
1381
+ if (op.cursorActivity) signal(cm, "cursorActivity", cm);
1382
+ if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i]();
1383
+ }
1384
+
1385
+ // Wraps a function in an operation. Returns the wrapped function.
1386
+ function operation(cm1, f) {
1387
+ return function() {
1388
+ var cm = cm1 || this, withOp = !cm.curOp;
1389
+ if (withOp) startOperation(cm);
1390
+ try { var result = f.apply(cm, arguments); }
1391
+ finally { if (withOp) endOperation(cm); }
1392
+ return result;
1393
+ };
1394
+ }
1395
+ function docOperation(f) {
1396
+ return function() {
1397
+ var withOp = this.cm && !this.cm.curOp, result;
1398
+ if (withOp) startOperation(this.cm);
1399
+ try { result = f.apply(this, arguments); }
1400
+ finally { if (withOp) endOperation(this.cm); }
1401
+ return result;
1402
+ };
1403
+ }
1404
+ function runInOp(cm, f) {
1405
+ var withOp = !cm.curOp, result;
1406
+ if (withOp) startOperation(cm);
1407
+ try { result = f(); }
1408
+ finally { if (withOp) endOperation(cm); }
1409
+ return result;
1410
+ }
1411
+
1412
+ function regChange(cm, from, to, lendiff) {
1413
+ if (from == null) from = cm.doc.first;
1414
+ if (to == null) to = cm.doc.first + cm.doc.size;
1415
+ cm.curOp.changes.push({from: from, to: to, diff: lendiff});
1416
+ }
1417
+
1418
+ // INPUT HANDLING
1419
+
1420
+ function slowPoll(cm) {
1421
+ if (cm.display.pollingFast) return;
1422
+ cm.display.poll.set(cm.options.pollInterval, function() {
1423
+ readInput(cm);
1424
+ if (cm.state.focused) slowPoll(cm);
1425
+ });
1426
+ }
1427
+
1428
+ function fastPoll(cm) {
1429
+ var missed = false;
1430
+ cm.display.pollingFast = true;
1431
+ function p() {
1432
+ var changed = readInput(cm);
1433
+ if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}
1434
+ else {cm.display.pollingFast = false; slowPoll(cm);}
1435
+ }
1436
+ cm.display.poll.set(20, p);
1437
+ }
1438
+
1439
+ // prevInput is a hack to work with IME. If we reset the textarea
1440
+ // on every change, that breaks IME. So we look for changes
1441
+ // compared to the previous content instead. (Modern browsers have
1442
+ // events that indicate IME taking place, but these are not widely
1443
+ // supported or compatible enough yet to rely on.)
1444
+ function readInput(cm) {
1445
+ var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc, sel = doc.sel;
1446
+ if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.state.disableInput) return false;
1447
+ var text = input.value;
1448
+ if (text == prevInput && posEq(sel.from, sel.to)) return false;
1449
+ if (ie && !ie_lt9 && cm.display.inputHasSelection === text) {
1450
+ resetInput(cm, true);
1451
+ return false;
1452
+ }
1453
+
1454
+ var withOp = !cm.curOp;
1455
+ if (withOp) startOperation(cm);
1456
+ sel.shift = false;
1457
+ var same = 0, l = Math.min(prevInput.length, text.length);
1458
+ while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
1459
+ var from = sel.from, to = sel.to;
1460
+ if (same < prevInput.length)
1461
+ from = Pos(from.line, from.ch - (prevInput.length - same));
1462
+ else if (cm.state.overwrite && posEq(from, to) && !cm.state.pasteIncoming)
1463
+ to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + (text.length - same)));
1464
+
1465
+ var updateInput = cm.curOp.updateInput;
1466
+ var changeEvent = {from: from, to: to, text: splitLines(text.slice(same)),
1467
+ origin: cm.state.pasteIncoming ? "paste" : "+input"};
1468
+ makeChange(cm.doc, changeEvent, "end");
1469
+ cm.curOp.updateInput = updateInput;
1470
+ signalLater(cm, "inputRead", cm, changeEvent);
1471
+
1472
+ if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = "";
1473
+ else cm.display.prevInput = text;
1474
+ if (withOp) endOperation(cm);
1475
+ cm.state.pasteIncoming = false;
1476
+ return true;
1477
+ }
1478
+
1479
+ function resetInput(cm, user) {
1480
+ var minimal, selected, doc = cm.doc;
1481
+ if (!posEq(doc.sel.from, doc.sel.to)) {
1482
+ cm.display.prevInput = "";
1483
+ minimal = hasCopyEvent &&
1484
+ (doc.sel.to.line - doc.sel.from.line > 100 || (selected = cm.getSelection()).length > 1000);
1485
+ var content = minimal ? "-" : selected || cm.getSelection();
1486
+ cm.display.input.value = content;
1487
+ if (cm.state.focused) selectInput(cm.display.input);
1488
+ if (ie && !ie_lt9) cm.display.inputHasSelection = content;
1489
+ } else if (user) {
1490
+ cm.display.prevInput = cm.display.input.value = "";
1491
+ if (ie && !ie_lt9) cm.display.inputHasSelection = null;
1492
+ }
1493
+ cm.display.inaccurateSelection = minimal;
1494
+ }
1495
+
1496
+ function focusInput(cm) {
1497
+ if (cm.options.readOnly != "nocursor" && (!mobile || document.activeElement != cm.display.input))
1498
+ cm.display.input.focus();
1499
+ }
1500
+
1501
+ function isReadOnly(cm) {
1502
+ return cm.options.readOnly || cm.doc.cantEdit;
1503
+ }
1504
+
1505
+ // EVENT HANDLERS
1506
+
1507
+ function registerEventHandlers(cm) {
1508
+ var d = cm.display;
1509
+ on(d.scroller, "mousedown", operation(cm, onMouseDown));
1510
+ if (ie)
1511
+ on(d.scroller, "dblclick", operation(cm, function(e) {
1512
+ if (signalDOMEvent(cm, e)) return;
1513
+ var pos = posFromMouse(cm, e);
1514
+ if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
1515
+ e_preventDefault(e);
1516
+ var word = findWordAt(getLine(cm.doc, pos.line).text, pos);
1517
+ extendSelection(cm.doc, word.from, word.to);
1518
+ }));
1519
+ else
1520
+ on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
1521
+ on(d.lineSpace, "selectstart", function(e) {
1522
+ if (!eventInWidget(d, e)) e_preventDefault(e);
1523
+ });
1524
+ // Gecko browsers fire contextmenu *after* opening the menu, at
1525
+ // which point we can't mess with it anymore. Context menu is
1526
+ // handled in onMouseDown for Gecko.
1527
+ if (!captureMiddleClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
1528
+
1529
+ on(d.scroller, "scroll", function() {
1530
+ if (d.scroller.clientHeight) {
1531
+ setScrollTop(cm, d.scroller.scrollTop);
1532
+ setScrollLeft(cm, d.scroller.scrollLeft, true);
1533
+ signal(cm, "scroll", cm);
1534
+ }
1535
+ });
1536
+ on(d.scrollbarV, "scroll", function() {
1537
+ if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop);
1538
+ });
1539
+ on(d.scrollbarH, "scroll", function() {
1540
+ if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft);
1541
+ });
1542
+
1543
+ on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
1544
+ on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
1545
+
1546
+ function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); }
1547
+ on(d.scrollbarH, "mousedown", reFocus);
1548
+ on(d.scrollbarV, "mousedown", reFocus);
1549
+ // Prevent wrapper from ever scrolling
1550
+ on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
1551
+
1552
+ var resizeTimer;
1553
+ function onResize() {
1554
+ if (resizeTimer == null) resizeTimer = setTimeout(function() {
1555
+ resizeTimer = null;
1556
+ // Might be a text scaling operation, clear size caches.
1557
+ d.cachedCharWidth = d.cachedTextHeight = knownScrollbarWidth = null;
1558
+ clearCaches(cm);
1559
+ runInOp(cm, bind(regChange, cm));
1560
+ }, 100);
1561
+ }
1562
+ on(window, "resize", onResize);
1563
+ // Above handler holds on to the editor and its data structures.
1564
+ // Here we poll to unregister it when the editor is no longer in
1565
+ // the document, so that it can be garbage-collected.
1566
+ function unregister() {
1567
+ for (var p = d.wrapper.parentNode; p && p != document.body; p = p.parentNode) {}
1568
+ if (p) setTimeout(unregister, 5000);
1569
+ else off(window, "resize", onResize);
1570
+ }
1571
+ setTimeout(unregister, 5000);
1572
+
1573
+ on(d.input, "keyup", operation(cm, function(e) {
1574
+ if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
1575
+ if (e.keyCode == 16) cm.doc.sel.shift = false;
1576
+ }));
1577
+ on(d.input, "input", bind(fastPoll, cm));
1578
+ on(d.input, "keydown", operation(cm, onKeyDown));
1579
+ on(d.input, "keypress", operation(cm, onKeyPress));
1580
+ on(d.input, "focus", bind(onFocus, cm));
1581
+ on(d.input, "blur", bind(onBlur, cm));
1582
+
1583
+ function drag_(e) {
1584
+ if (signalDOMEvent(cm, e) || cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))) return;
1585
+ e_stop(e);
1586
+ }
1587
+ if (cm.options.dragDrop) {
1588
+ on(d.scroller, "dragstart", function(e){onDragStart(cm, e);});
1589
+ on(d.scroller, "dragenter", drag_);
1590
+ on(d.scroller, "dragover", drag_);
1591
+ on(d.scroller, "drop", operation(cm, onDrop));
1592
+ }
1593
+ on(d.scroller, "paste", function(e){
1594
+ if (eventInWidget(d, e)) return;
1595
+ focusInput(cm);
1596
+ fastPoll(cm);
1597
+ });
1598
+ on(d.input, "paste", function() {
1599
+ cm.state.pasteIncoming = true;
1600
+ fastPoll(cm);
1601
+ });
1602
+
1603
+ function prepareCopy() {
1604
+ if (d.inaccurateSelection) {
1605
+ d.prevInput = "";
1606
+ d.inaccurateSelection = false;
1607
+ d.input.value = cm.getSelection();
1608
+ selectInput(d.input);
1609
+ }
1610
+ }
1611
+ on(d.input, "cut", prepareCopy);
1612
+ on(d.input, "copy", prepareCopy);
1613
+
1614
+ // Needed to handle Tab key in KHTML
1615
+ if (khtml) on(d.sizer, "mouseup", function() {
1616
+ if (document.activeElement == d.input) d.input.blur();
1617
+ focusInput(cm);
1618
+ });
1619
+ }
1620
+
1621
+ function eventInWidget(display, e) {
1622
+ for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
1623
+ if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true;
1624
+ }
1625
+ }
1626
+
1627
+ function posFromMouse(cm, e, liberal) {
1628
+ var display = cm.display;
1629
+ if (!liberal) {
1630
+ var target = e_target(e);
1631
+ if (target == display.scrollbarH || target == display.scrollbarH.firstChild ||
1632
+ target == display.scrollbarV || target == display.scrollbarV.firstChild ||
1633
+ target == display.scrollbarFiller || target == display.gutterFiller) return null;
1634
+ }
1635
+ var x, y, space = getRect(display.lineSpace);
1636
+ // Fails unpredictably on IE[67] when mouse is dragged around quickly.
1637
+ try { x = e.clientX; y = e.clientY; } catch (e) { return null; }
1638
+ return coordsChar(cm, x - space.left, y - space.top);
1639
+ }
1640
+
1641
+ var lastClick, lastDoubleClick;
1642
+ function onMouseDown(e) {
1643
+ if (signalDOMEvent(this, e)) return;
1644
+ var cm = this, display = cm.display, doc = cm.doc, sel = doc.sel;
1645
+ sel.shift = e.shiftKey;
1646
+
1647
+ if (eventInWidget(display, e)) {
1648
+ if (!webkit) {
1649
+ display.scroller.draggable = false;
1650
+ setTimeout(function(){display.scroller.draggable = true;}, 100);
1651
+ }
1652
+ return;
1653
+ }
1654
+ if (clickInGutter(cm, e)) return;
1655
+ var start = posFromMouse(cm, e);
1656
+
1657
+ switch (e_button(e)) {
1658
+ case 3:
1659
+ if (captureMiddleClick) onContextMenu.call(cm, cm, e);
1660
+ return;
1661
+ case 2:
1662
+ if (start) extendSelection(cm.doc, start);
1663
+ setTimeout(bind(focusInput, cm), 20);
1664
+ e_preventDefault(e);
1665
+ return;
1666
+ }
1667
+ // For button 1, if it was clicked inside the editor
1668
+ // (posFromMouse returning non-null), we have to adjust the
1669
+ // selection.
1670
+ if (!start) {if (e_target(e) == display.scroller) e_preventDefault(e); return;}
1671
+
1672
+ if (!cm.state.focused) onFocus(cm);
1673
+
1674
+ var now = +new Date, type = "single";
1675
+ if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {
1676
+ type = "triple";
1677
+ e_preventDefault(e);
1678
+ setTimeout(bind(focusInput, cm), 20);
1679
+ selectLine(cm, start.line);
1680
+ } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {
1681
+ type = "double";
1682
+ lastDoubleClick = {time: now, pos: start};
1683
+ e_preventDefault(e);
1684
+ var word = findWordAt(getLine(doc, start.line).text, start);
1685
+ extendSelection(cm.doc, word.from, word.to);
1686
+ } else { lastClick = {time: now, pos: start}; }
1687
+
1688
+ var last = start;
1689
+ if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && !posEq(sel.from, sel.to) &&
1690
+ !posLess(start, sel.from) && !posLess(sel.to, start) && type == "single") {
1691
+ var dragEnd = operation(cm, function(e2) {
1692
+ if (webkit) display.scroller.draggable = false;
1693
+ cm.state.draggingText = false;
1694
+ off(document, "mouseup", dragEnd);
1695
+ off(display.scroller, "drop", dragEnd);
1696
+ if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
1697
+ e_preventDefault(e2);
1698
+ extendSelection(cm.doc, start);
1699
+ focusInput(cm);
1700
+ }
1701
+ });
1702
+ // Let the drag handler handle this.
1703
+ if (webkit) display.scroller.draggable = true;
1704
+ cm.state.draggingText = dragEnd;
1705
+ // IE's approach to draggable
1706
+ if (display.scroller.dragDrop) display.scroller.dragDrop();
1707
+ on(document, "mouseup", dragEnd);
1708
+ on(display.scroller, "drop", dragEnd);
1709
+ return;
1710
+ }
1711
+ e_preventDefault(e);
1712
+ if (type == "single") extendSelection(cm.doc, clipPos(doc, start));
1713
+
1714
+ var startstart = sel.from, startend = sel.to, lastPos = start;
1715
+
1716
+ function doSelect(cur) {
1717
+ if (posEq(lastPos, cur)) return;
1718
+ lastPos = cur;
1719
+
1720
+ if (type == "single") {
1721
+ extendSelection(cm.doc, clipPos(doc, start), cur);
1722
+ return;
1723
+ }
1724
+
1725
+ startstart = clipPos(doc, startstart);
1726
+ startend = clipPos(doc, startend);
1727
+ if (type == "double") {
1728
+ var word = findWordAt(getLine(doc, cur.line).text, cur);
1729
+ if (posLess(cur, startstart)) extendSelection(cm.doc, word.from, startend);
1730
+ else extendSelection(cm.doc, startstart, word.to);
1731
+ } else if (type == "triple") {
1732
+ if (posLess(cur, startstart)) extendSelection(cm.doc, startend, clipPos(doc, Pos(cur.line, 0)));
1733
+ else extendSelection(cm.doc, startstart, clipPos(doc, Pos(cur.line + 1, 0)));
1734
+ }
1735
+ }
1736
+
1737
+ var editorSize = getRect(display.wrapper);
1738
+ // Used to ensure timeout re-tries don't fire when another extend
1739
+ // happened in the meantime (clearTimeout isn't reliable -- at
1740
+ // least on Chrome, the timeouts still happen even when cleared,
1741
+ // if the clear happens after their scheduled firing time).
1742
+ var counter = 0;
1743
+
1744
+ function extend(e) {
1745
+ var curCount = ++counter;
1746
+ var cur = posFromMouse(cm, e, true);
1747
+ if (!cur) return;
1748
+ if (!posEq(cur, last)) {
1749
+ if (!cm.state.focused) onFocus(cm);
1750
+ last = cur;
1751
+ doSelect(cur);
1752
+ var visible = visibleLines(display, doc);
1753
+ if (cur.line >= visible.to || cur.line < visible.from)
1754
+ setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
1755
+ } else {
1756
+ var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
1757
+ if (outside) setTimeout(operation(cm, function() {
1758
+ if (counter != curCount) return;
1759
+ display.scroller.scrollTop += outside;
1760
+ extend(e);
1761
+ }), 50);
1762
+ }
1763
+ }
1764
+
1765
+ function done(e) {
1766
+ counter = Infinity;
1767
+ e_preventDefault(e);
1768
+ focusInput(cm);
1769
+ off(document, "mousemove", move);
1770
+ off(document, "mouseup", up);
1771
+ }
1772
+
1773
+ var move = operation(cm, function(e) {
1774
+ if (!ie && !e_button(e)) done(e);
1775
+ else extend(e);
1776
+ });
1777
+ var up = operation(cm, done);
1778
+ on(document, "mousemove", move);
1779
+ on(document, "mouseup", up);
1780
+ }
1781
+
1782
+ function clickInGutter(cm, e) {
1783
+ var display = cm.display;
1784
+ try { var mX = e.clientX, mY = e.clientY; }
1785
+ catch(e) { return false; }
1786
+
1787
+ if (mX >= Math.floor(getRect(display.gutters).right)) return false;
1788
+ e_preventDefault(e);
1789
+ if (!hasHandler(cm, "gutterClick")) return true;
1790
+
1791
+ var lineBox = getRect(display.lineDiv);
1792
+ if (mY > lineBox.bottom) return true;
1793
+ mY -= lineBox.top - display.viewOffset;
1794
+
1795
+ for (var i = 0; i < cm.options.gutters.length; ++i) {
1796
+ var g = display.gutters.childNodes[i];
1797
+ if (g && getRect(g).right >= mX) {
1798
+ var line = lineAtHeight(cm.doc, mY);
1799
+ var gutter = cm.options.gutters[i];
1800
+ signalLater(cm, "gutterClick", cm, line, gutter, e);
1801
+ break;
1802
+ }
1803
+ }
1804
+ return true;
1805
+ }
1806
+
1807
+ // Kludge to work around strange IE behavior where it'll sometimes
1808
+ // re-fire a series of drag-related events right after the drop (#1551)
1809
+ var lastDrop = 0;
1810
+
1811
+ function onDrop(e) {
1812
+ var cm = this;
1813
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e) || (cm.options.onDragEvent && cm.options.onDragEvent(cm, addStop(e))))
1814
+ return;
1815
+ e_preventDefault(e);
1816
+ if (ie) lastDrop = +new Date;
1817
+ var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
1818
+ if (!pos || isReadOnly(cm)) return;
1819
+ if (files && files.length && window.FileReader && window.File) {
1820
+ var n = files.length, text = Array(n), read = 0;
1821
+ var loadFile = function(file, i) {
1822
+ var reader = new FileReader;
1823
+ reader.onload = function() {
1824
+ text[i] = reader.result;
1825
+ if (++read == n) {
1826
+ pos = clipPos(cm.doc, pos);
1827
+ makeChange(cm.doc, {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}, "around");
1828
+ }
1829
+ };
1830
+ reader.readAsText(file);
1831
+ };
1832
+ for (var i = 0; i < n; ++i) loadFile(files[i], i);
1833
+ } else {
1834
+ // Don't do a replace if the drop happened inside of the selected text.
1835
+ if (cm.state.draggingText && !(posLess(pos, cm.doc.sel.from) || posLess(cm.doc.sel.to, pos))) {
1836
+ cm.state.draggingText(e);
1837
+ // Ensure the editor is re-focused
1838
+ setTimeout(bind(focusInput, cm), 20);
1839
+ return;
1840
+ }
1841
+ try {
1842
+ var text = e.dataTransfer.getData("Text");
1843
+ if (text) {
1844
+ var curFrom = cm.doc.sel.from, curTo = cm.doc.sel.to;
1845
+ setSelection(cm.doc, pos, pos);
1846
+ if (cm.state.draggingText) replaceRange(cm.doc, "", curFrom, curTo, "paste");
1847
+ cm.replaceSelection(text, null, "paste");
1848
+ focusInput(cm);
1849
+ onFocus(cm);
1850
+ }
1851
+ }
1852
+ catch(e){}
1853
+ }
1854
+ }
1855
+
1856
+ function onDragStart(cm, e) {
1857
+ if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
1858
+ if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
1859
+
1860
+ var txt = cm.getSelection();
1861
+ e.dataTransfer.setData("Text", txt);
1862
+
1863
+ // Use dummy image instead of default browsers image.
1864
+ // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
1865
+ if (e.dataTransfer.setDragImage && !safari) {
1866
+ var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
1867
+ if (opera) {
1868
+ img.width = img.height = 1;
1869
+ cm.display.wrapper.appendChild(img);
1870
+ // Force a relayout, or Opera won't use our image for some obscure reason
1871
+ img._top = img.offsetTop;
1872
+ }
1873
+ e.dataTransfer.setDragImage(img, 0, 0);
1874
+ if (opera) img.parentNode.removeChild(img);
1875
+ }
1876
+ }
1877
+
1878
+ function setScrollTop(cm, val) {
1879
+ if (Math.abs(cm.doc.scrollTop - val) < 2) return;
1880
+ cm.doc.scrollTop = val;
1881
+ if (!gecko) updateDisplay(cm, [], val);
1882
+ if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
1883
+ if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val;
1884
+ if (gecko) updateDisplay(cm, []);
1885
+ startWorker(cm, 100);
1886
+ }
1887
+ function setScrollLeft(cm, val, isScroller) {
1888
+ if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
1889
+ val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
1890
+ cm.doc.scrollLeft = val;
1891
+ alignHorizontally(cm);
1892
+ if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
1893
+ if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val;
1894
+ }
1895
+
1896
+ // Since the delta values reported on mouse wheel events are
1897
+ // unstandardized between browsers and even browser versions, and
1898
+ // generally horribly unpredictable, this code starts by measuring
1899
+ // the scroll effect that the first few mouse wheel events have,
1900
+ // and, from that, detects the way it can convert deltas to pixel
1901
+ // offsets afterwards.
1902
+ //
1903
+ // The reason we want to know the amount a wheel event will scroll
1904
+ // is that it gives us a chance to update the display before the
1905
+ // actual scrolling happens, reducing flickering.
1906
+
1907
+ var wheelSamples = 0, wheelPixelsPerUnit = null;
1908
+ // Fill in a browser-detected starting value on browsers where we
1909
+ // know one. These don't have to be accurate -- the result of them
1910
+ // being wrong would just be a slight flicker on the first wheel
1911
+ // scroll (if it is large enough).
1912
+ if (ie) wheelPixelsPerUnit = -.53;
1913
+ else if (gecko) wheelPixelsPerUnit = 15;
1914
+ else if (chrome) wheelPixelsPerUnit = -.7;
1915
+ else if (safari) wheelPixelsPerUnit = -1/3;
1916
+
1917
+ function onScrollWheel(cm, e) {
1918
+ var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
1919
+ if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
1920
+ if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
1921
+ else if (dy == null) dy = e.wheelDelta;
1922
+
1923
+ var display = cm.display, scroll = display.scroller;
1924
+ // Quit if there's nothing to scroll here
1925
+ if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
1926
+ dy && scroll.scrollHeight > scroll.clientHeight)) return;
1927
+
1928
+ // Webkit browsers on OS X abort momentum scrolls when the target
1929
+ // of the scroll event is removed from the scrollable element.
1930
+ // This hack (see related code in patchDisplay) makes sure the
1931
+ // element is kept around.
1932
+ if (dy && mac && webkit) {
1933
+ for (var cur = e.target; cur != scroll; cur = cur.parentNode) {
1934
+ if (cur.lineObj) {
1935
+ cm.display.currentWheelTarget = cur;
1936
+ break;
1937
+ }
1938
+ }
1939
+ }
1940
+
1941
+ // On some browsers, horizontal scrolling will cause redraws to
1942
+ // happen before the gutter has been realigned, causing it to
1943
+ // wriggle around in a most unseemly way. When we have an
1944
+ // estimated pixels/delta value, we just handle horizontal
1945
+ // scrolling entirely here. It'll be slightly off from native, but
1946
+ // better than glitching out.
1947
+ if (dx && !gecko && !opera && wheelPixelsPerUnit != null) {
1948
+ if (dy)
1949
+ setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
1950
+ setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
1951
+ e_preventDefault(e);
1952
+ display.wheelStartX = null; // Abort measurement, if in progress
1953
+ return;
1954
+ }
1955
+
1956
+ if (dy && wheelPixelsPerUnit != null) {
1957
+ var pixels = dy * wheelPixelsPerUnit;
1958
+ var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
1959
+ if (pixels < 0) top = Math.max(0, top + pixels - 50);
1960
+ else bot = Math.min(cm.doc.height, bot + pixels + 50);
1961
+ updateDisplay(cm, [], {top: top, bottom: bot});
1962
+ }
1963
+
1964
+ if (wheelSamples < 20) {
1965
+ if (display.wheelStartX == null) {
1966
+ display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
1967
+ display.wheelDX = dx; display.wheelDY = dy;
1968
+ setTimeout(function() {
1969
+ if (display.wheelStartX == null) return;
1970
+ var movedX = scroll.scrollLeft - display.wheelStartX;
1971
+ var movedY = scroll.scrollTop - display.wheelStartY;
1972
+ var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
1973
+ (movedX && display.wheelDX && movedX / display.wheelDX);
1974
+ display.wheelStartX = display.wheelStartY = null;
1975
+ if (!sample) return;
1976
+ wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
1977
+ ++wheelSamples;
1978
+ }, 200);
1979
+ } else {
1980
+ display.wheelDX += dx; display.wheelDY += dy;
1981
+ }
1982
+ }
1983
+ }
1984
+
1985
+ function doHandleBinding(cm, bound, dropShift) {
1986
+ if (typeof bound == "string") {
1987
+ bound = commands[bound];
1988
+ if (!bound) return false;
1989
+ }
1990
+ // Ensure previous input has been read, so that the handler sees a
1991
+ // consistent view of the document
1992
+ if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;
1993
+ var doc = cm.doc, prevShift = doc.sel.shift, done = false;
1994
+ try {
1995
+ if (isReadOnly(cm)) cm.state.suppressEdits = true;
1996
+ if (dropShift) doc.sel.shift = false;
1997
+ done = bound(cm) != Pass;
1998
+ } finally {
1999
+ doc.sel.shift = prevShift;
2000
+ cm.state.suppressEdits = false;
2001
+ }
2002
+ return done;
2003
+ }
2004
+
2005
+ function allKeyMaps(cm) {
2006
+ var maps = cm.state.keyMaps.slice(0);
2007
+ if (cm.options.extraKeys) maps.push(cm.options.extraKeys);
2008
+ maps.push(cm.options.keyMap);
2009
+ return maps;
2010
+ }
2011
+
2012
+ var maybeTransition;
2013
+ function handleKeyBinding(cm, e) {
2014
+ // Handle auto keymap transitions
2015
+ var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto;
2016
+ clearTimeout(maybeTransition);
2017
+ if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() {
2018
+ if (getKeyMap(cm.options.keyMap) == startMap) {
2019
+ cm.options.keyMap = (next.call ? next.call(null, cm) : next);
2020
+ keyMapChanged(cm);
2021
+ }
2022
+ }, 50);
2023
+
2024
+ var name = keyName(e, true), handled = false;
2025
+ if (!name) return false;
2026
+ var keymaps = allKeyMaps(cm);
2027
+
2028
+ if (e.shiftKey) {
2029
+ // First try to resolve full name (including 'Shift-'). Failing
2030
+ // that, see if there is a cursor-motion command (starting with
2031
+ // 'go') bound to the keyname without 'Shift-'.
2032
+ handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);})
2033
+ || lookupKey(name, keymaps, function(b) {
2034
+ if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
2035
+ return doHandleBinding(cm, b);
2036
+ });
2037
+ } else {
2038
+ handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); });
2039
+ }
2040
+
2041
+ if (handled) {
2042
+ e_preventDefault(e);
2043
+ restartBlink(cm);
2044
+ if (ie_lt9) { e.oldKeyCode = e.keyCode; e.keyCode = 0; }
2045
+ signalLater(cm, "keyHandled", cm, name, e);
2046
+ }
2047
+ return handled;
2048
+ }
2049
+
2050
+ function handleCharBinding(cm, e, ch) {
2051
+ var handled = lookupKey("'" + ch + "'", allKeyMaps(cm),
2052
+ function(b) { return doHandleBinding(cm, b, true); });
2053
+ if (handled) {
2054
+ e_preventDefault(e);
2055
+ restartBlink(cm);
2056
+ signalLater(cm, "keyHandled", cm, "'" + ch + "'", e);
2057
+ }
2058
+ return handled;
2059
+ }
2060
+
2061
+ var lastStoppedKey = null;
2062
+ function onKeyDown(e) {
2063
+ var cm = this;
2064
+ if (!cm.state.focused) onFocus(cm);
2065
+ if (ie && e.keyCode == 27) { e.returnValue = false; }
2066
+ if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
2067
+ var code = e.keyCode;
2068
+ // IE does strange things with escape.
2069
+ cm.doc.sel.shift = code == 16 || e.shiftKey;
2070
+ // First give onKeyEvent option a chance to handle this.
2071
+ var handled = handleKeyBinding(cm, e);
2072
+ if (opera) {
2073
+ lastStoppedKey = handled ? code : null;
2074
+ // Opera has no cut event... we try to at least catch the key combo
2075
+ if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
2076
+ cm.replaceSelection("");
2077
+ }
2078
+ }
2079
+
2080
+ function onKeyPress(e) {
2081
+ var cm = this;
2082
+ if (signalDOMEvent(cm, e) || cm.options.onKeyEvent && cm.options.onKeyEvent(cm, addStop(e))) return;
2083
+ var keyCode = e.keyCode, charCode = e.charCode;
2084
+ if (opera && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
2085
+ if (((opera && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;
2086
+ var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
2087
+ if (this.options.electricChars && this.doc.mode.electricChars &&
2088
+ this.options.smartIndent && !isReadOnly(this) &&
2089
+ this.doc.mode.electricChars.indexOf(ch) > -1)
2090
+ setTimeout(operation(cm, function() {indentLine(cm, cm.doc.sel.to.line, "smart");}), 75);
2091
+ if (handleCharBinding(cm, e, ch)) return;
2092
+ if (ie && !ie_lt9) cm.display.inputHasSelection = null;
2093
+ fastPoll(cm);
2094
+ }
2095
+
2096
+ function onFocus(cm) {
2097
+ if (cm.options.readOnly == "nocursor") return;
2098
+ if (!cm.state.focused) {
2099
+ signal(cm, "focus", cm);
2100
+ cm.state.focused = true;
2101
+ if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1)
2102
+ cm.display.wrapper.className += " CodeMirror-focused";
2103
+ resetInput(cm, true);
2104
+ }
2105
+ slowPoll(cm);
2106
+ restartBlink(cm);
2107
+ }
2108
+ function onBlur(cm) {
2109
+ if (cm.state.focused) {
2110
+ signal(cm, "blur", cm);
2111
+ cm.state.focused = false;
2112
+ cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-focused", "");
2113
+ }
2114
+ clearInterval(cm.display.blinker);
2115
+ setTimeout(function() {if (!cm.state.focused) cm.doc.sel.shift = false;}, 150);
2116
+ }
2117
+
2118
+ var detectingSelectAll;
2119
+ function onContextMenu(cm, e) {
2120
+ if (signalDOMEvent(cm, e, "contextmenu")) return;
2121
+ var display = cm.display, sel = cm.doc.sel;
2122
+ if (eventInWidget(display, e)) return;
2123
+
2124
+ var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
2125
+ if (!pos || opera) return; // Opera is difficult.
2126
+ if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))
2127
+ operation(cm, setSelection)(cm.doc, pos, pos);
2128
+
2129
+ var oldCSS = display.input.style.cssText;
2130
+ display.inputDiv.style.position = "absolute";
2131
+ display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
2132
+ "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: white; outline: none;" +
2133
+ "border-width: 0; outline: none; overflow: hidden; opacity: .05; -ms-opacity: .05; filter: alpha(opacity=5);";
2134
+ focusInput(cm);
2135
+ resetInput(cm, true);
2136
+ // Adds "Select all" to context menu in FF
2137
+ if (posEq(sel.from, sel.to)) display.input.value = display.prevInput = " ";
2138
+
2139
+ function prepareSelectAllHack() {
2140
+ if (display.input.selectionStart != null) {
2141
+ var extval = display.input.value = " " + (posEq(sel.from, sel.to) ? "" : display.input.value);
2142
+ display.prevInput = " ";
2143
+ display.input.selectionStart = 1; display.input.selectionEnd = extval.length;
2144
+ }
2145
+ }
2146
+ function rehide() {
2147
+ display.inputDiv.style.position = "relative";
2148
+ display.input.style.cssText = oldCSS;
2149
+ if (ie_lt9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos;
2150
+ slowPoll(cm);
2151
+
2152
+ // Try to detect the user choosing select-all
2153
+ if (display.input.selectionStart != null) {
2154
+ if (!ie || ie_lt9) prepareSelectAllHack();
2155
+ clearTimeout(detectingSelectAll);
2156
+ var i = 0, poll = function(){
2157
+ if (display.prevInput == " " && display.input.selectionStart == 0)
2158
+ operation(cm, commands.selectAll)(cm);
2159
+ else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500);
2160
+ else resetInput(cm);
2161
+ };
2162
+ detectingSelectAll = setTimeout(poll, 200);
2163
+ }
2164
+ }
2165
+
2166
+ if (ie && !ie_lt9) prepareSelectAllHack();
2167
+ if (captureMiddleClick) {
2168
+ e_stop(e);
2169
+ var mouseup = function() {
2170
+ off(window, "mouseup", mouseup);
2171
+ setTimeout(rehide, 20);
2172
+ };
2173
+ on(window, "mouseup", mouseup);
2174
+ } else {
2175
+ setTimeout(rehide, 50);
2176
+ }
2177
+ }
2178
+
2179
+ // UPDATING
2180
+
2181
+ var changeEnd = CodeMirror.changeEnd = function(change) {
2182
+ if (!change.text) return change.to;
2183
+ return Pos(change.from.line + change.text.length - 1,
2184
+ lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
2185
+ };
2186
+
2187
+ // Make sure a position will be valid after the given change.
2188
+ function clipPostChange(doc, change, pos) {
2189
+ if (!posLess(change.from, pos)) return clipPos(doc, pos);
2190
+ var diff = (change.text.length - 1) - (change.to.line - change.from.line);
2191
+ if (pos.line > change.to.line + diff) {
2192
+ var preLine = pos.line - diff, lastLine = doc.first + doc.size - 1;
2193
+ if (preLine > lastLine) return Pos(lastLine, getLine(doc, lastLine).text.length);
2194
+ return clipToLen(pos, getLine(doc, preLine).text.length);
2195
+ }
2196
+ if (pos.line == change.to.line + diff)
2197
+ return clipToLen(pos, lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0) +
2198
+ getLine(doc, change.to.line).text.length - change.to.ch);
2199
+ var inside = pos.line - change.from.line;
2200
+ return clipToLen(pos, change.text[inside].length + (inside ? 0 : change.from.ch));
2201
+ }
2202
+
2203
+ // Hint can be null|"end"|"start"|"around"|{anchor,head}
2204
+ function computeSelAfterChange(doc, change, hint) {
2205
+ if (hint && typeof hint == "object") // Assumed to be {anchor, head} object
2206
+ return {anchor: clipPostChange(doc, change, hint.anchor),
2207
+ head: clipPostChange(doc, change, hint.head)};
2208
+
2209
+ if (hint == "start") return {anchor: change.from, head: change.from};
2210
+
2211
+ var end = changeEnd(change);
2212
+ if (hint == "around") return {anchor: change.from, head: end};
2213
+ if (hint == "end") return {anchor: end, head: end};
2214
+
2215
+ // hint is null, leave the selection alone as much as possible
2216
+ var adjustPos = function(pos) {
2217
+ if (posLess(pos, change.from)) return pos;
2218
+ if (!posLess(change.to, pos)) return end;
2219
+
2220
+ var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
2221
+ if (pos.line == change.to.line) ch += end.ch - change.to.ch;
2222
+ return Pos(line, ch);
2223
+ };
2224
+ return {anchor: adjustPos(doc.sel.anchor), head: adjustPos(doc.sel.head)};
2225
+ }
2226
+
2227
+ function filterChange(doc, change, update) {
2228
+ var obj = {
2229
+ canceled: false,
2230
+ from: change.from,
2231
+ to: change.to,
2232
+ text: change.text,
2233
+ origin: change.origin,
2234
+ cancel: function() { this.canceled = true; }
2235
+ };
2236
+ if (update) obj.update = function(from, to, text, origin) {
2237
+ if (from) this.from = clipPos(doc, from);
2238
+ if (to) this.to = clipPos(doc, to);
2239
+ if (text) this.text = text;
2240
+ if (origin !== undefined) this.origin = origin;
2241
+ };
2242
+ signal(doc, "beforeChange", doc, obj);
2243
+ if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);
2244
+
2245
+ if (obj.canceled) return null;
2246
+ return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
2247
+ }
2248
+
2249
+ // Replace the range from from to to by the strings in replacement.
2250
+ // change is a {from, to, text [, origin]} object
2251
+ function makeChange(doc, change, selUpdate, ignoreReadOnly) {
2252
+ if (doc.cm) {
2253
+ if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, selUpdate, ignoreReadOnly);
2254
+ if (doc.cm.state.suppressEdits) return;
2255
+ }
2256
+
2257
+ if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
2258
+ change = filterChange(doc, change, true);
2259
+ if (!change) return;
2260
+ }
2261
+
2262
+ // Possibly split or suppress the update based on the presence
2263
+ // of read-only spans in its range.
2264
+ var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
2265
+ if (split) {
2266
+ for (var i = split.length - 1; i >= 1; --i)
2267
+ makeChangeNoReadonly(doc, {from: split[i].from, to: split[i].to, text: [""]});
2268
+ if (split.length)
2269
+ makeChangeNoReadonly(doc, {from: split[0].from, to: split[0].to, text: change.text}, selUpdate);
2270
+ } else {
2271
+ makeChangeNoReadonly(doc, change, selUpdate);
2272
+ }
2273
+ }
2274
+
2275
+ function makeChangeNoReadonly(doc, change, selUpdate) {
2276
+ var selAfter = computeSelAfterChange(doc, change, selUpdate);
2277
+ addToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
2278
+
2279
+ makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
2280
+ var rebased = [];
2281
+
2282
+ linkedDocs(doc, function(doc, sharedHist) {
2283
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
2284
+ rebaseHist(doc.history, change);
2285
+ rebased.push(doc.history);
2286
+ }
2287
+ makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
2288
+ });
2289
+ }
2290
+
2291
+ function makeChangeFromHistory(doc, type) {
2292
+ if (doc.cm && doc.cm.state.suppressEdits) return;
2293
+
2294
+ var hist = doc.history;
2295
+ var event = (type == "undo" ? hist.done : hist.undone).pop();
2296
+ if (!event) return;
2297
+
2298
+ var anti = {changes: [], anchorBefore: event.anchorAfter, headBefore: event.headAfter,
2299
+ anchorAfter: event.anchorBefore, headAfter: event.headBefore,
2300
+ generation: hist.generation};
2301
+ (type == "undo" ? hist.undone : hist.done).push(anti);
2302
+ hist.generation = event.generation || ++hist.maxGeneration;
2303
+
2304
+ var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
2305
+
2306
+ for (var i = event.changes.length - 1; i >= 0; --i) {
2307
+ var change = event.changes[i];
2308
+ change.origin = type;
2309
+ if (filter && !filterChange(doc, change, false)) {
2310
+ (type == "undo" ? hist.done : hist.undone).length = 0;
2311
+ return;
2312
+ }
2313
+
2314
+ anti.changes.push(historyChangeFromChange(doc, change));
2315
+
2316
+ var after = i ? computeSelAfterChange(doc, change, null)
2317
+ : {anchor: event.anchorBefore, head: event.headBefore};
2318
+ makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
2319
+ var rebased = [];
2320
+
2321
+ linkedDocs(doc, function(doc, sharedHist) {
2322
+ if (!sharedHist && indexOf(rebased, doc.history) == -1) {
2323
+ rebaseHist(doc.history, change);
2324
+ rebased.push(doc.history);
2325
+ }
2326
+ makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
2327
+ });
2328
+ }
2329
+ }
2330
+
2331
+ function shiftDoc(doc, distance) {
2332
+ function shiftPos(pos) {return Pos(pos.line + distance, pos.ch);}
2333
+ doc.first += distance;
2334
+ if (doc.cm) regChange(doc.cm, doc.first, doc.first, distance);
2335
+ doc.sel.head = shiftPos(doc.sel.head); doc.sel.anchor = shiftPos(doc.sel.anchor);
2336
+ doc.sel.from = shiftPos(doc.sel.from); doc.sel.to = shiftPos(doc.sel.to);
2337
+ }
2338
+
2339
+ function makeChangeSingleDoc(doc, change, selAfter, spans) {
2340
+ if (doc.cm && !doc.cm.curOp)
2341
+ return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
2342
+
2343
+ if (change.to.line < doc.first) {
2344
+ shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
2345
+ return;
2346
+ }
2347
+ if (change.from.line > doc.lastLine()) return;
2348
+
2349
+ // Clip the change to the size of this doc
2350
+ if (change.from.line < doc.first) {
2351
+ var shift = change.text.length - 1 - (doc.first - change.from.line);
2352
+ shiftDoc(doc, shift);
2353
+ change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
2354
+ text: [lst(change.text)], origin: change.origin};
2355
+ }
2356
+ var last = doc.lastLine();
2357
+ if (change.to.line > last) {
2358
+ change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
2359
+ text: [change.text[0]], origin: change.origin};
2360
+ }
2361
+
2362
+ change.removed = getBetween(doc, change.from, change.to);
2363
+
2364
+ if (!selAfter) selAfter = computeSelAfterChange(doc, change, null);
2365
+ if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans, selAfter);
2366
+ else updateDoc(doc, change, spans, selAfter);
2367
+ }
2368
+
2369
+ function makeChangeSingleDocInEditor(cm, change, spans, selAfter) {
2370
+ var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
2371
+
2372
+ var recomputeMaxLength = false, checkWidthStart = from.line;
2373
+ if (!cm.options.lineWrapping) {
2374
+ checkWidthStart = lineNo(visualLine(doc, getLine(doc, from.line)));
2375
+ doc.iter(checkWidthStart, to.line + 1, function(line) {
2376
+ if (line == display.maxLine) {
2377
+ recomputeMaxLength = true;
2378
+ return true;
2379
+ }
2380
+ });
2381
+ }
2382
+
2383
+ if (!posLess(doc.sel.head, change.from) && !posLess(change.to, doc.sel.head))
2384
+ cm.curOp.cursorActivity = true;
2385
+
2386
+ updateDoc(doc, change, spans, selAfter, estimateHeight(cm));
2387
+
2388
+ if (!cm.options.lineWrapping) {
2389
+ doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
2390
+ var len = lineLength(doc, line);
2391
+ if (len > display.maxLineLength) {
2392
+ display.maxLine = line;
2393
+ display.maxLineLength = len;
2394
+ display.maxLineChanged = true;
2395
+ recomputeMaxLength = false;
2396
+ }
2397
+ });
2398
+ if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
2399
+ }
2400
+
2401
+ // Adjust frontier, schedule worker
2402
+ doc.frontier = Math.min(doc.frontier, from.line);
2403
+ startWorker(cm, 400);
2404
+
2405
+ var lendiff = change.text.length - (to.line - from.line) - 1;
2406
+ // Remember that these lines changed, for updating the display
2407
+ regChange(cm, from.line, to.line + 1, lendiff);
2408
+
2409
+ if (hasHandler(cm, "change")) {
2410
+ var changeObj = {from: from, to: to,
2411
+ text: change.text,
2412
+ removed: change.removed,
2413
+ origin: change.origin};
2414
+ if (cm.curOp.textChanged) {
2415
+ for (var cur = cm.curOp.textChanged; cur.next; cur = cur.next) {}
2416
+ cur.next = changeObj;
2417
+ } else cm.curOp.textChanged = changeObj;
2418
+ }
2419
+ }
2420
+
2421
+ function replaceRange(doc, code, from, to, origin) {
2422
+ if (!to) to = from;
2423
+ if (posLess(to, from)) { var tmp = to; to = from; from = tmp; }
2424
+ if (typeof code == "string") code = splitLines(code);
2425
+ makeChange(doc, {from: from, to: to, text: code, origin: origin}, null);
2426
+ }
2427
+
2428
+ // POSITION OBJECT
2429
+
2430
+ function Pos(line, ch) {
2431
+ if (!(this instanceof Pos)) return new Pos(line, ch);
2432
+ this.line = line; this.ch = ch;
2433
+ }
2434
+ CodeMirror.Pos = Pos;
2435
+
2436
+ function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}
2437
+ function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}
2438
+ function copyPos(x) {return Pos(x.line, x.ch);}
2439
+
2440
+ // SELECTION
2441
+
2442
+ function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
2443
+ function clipPos(doc, pos) {
2444
+ if (pos.line < doc.first) return Pos(doc.first, 0);
2445
+ var last = doc.first + doc.size - 1;
2446
+ if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
2447
+ return clipToLen(pos, getLine(doc, pos.line).text.length);
2448
+ }
2449
+ function clipToLen(pos, linelen) {
2450
+ var ch = pos.ch;
2451
+ if (ch == null || ch > linelen) return Pos(pos.line, linelen);
2452
+ else if (ch < 0) return Pos(pos.line, 0);
2453
+ else return pos;
2454
+ }
2455
+ function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
2456
+
2457
+ // If shift is held, this will move the selection anchor. Otherwise,
2458
+ // it'll set the whole selection.
2459
+ function extendSelection(doc, pos, other, bias) {
2460
+ if (doc.sel.shift || doc.sel.extend) {
2461
+ var anchor = doc.sel.anchor;
2462
+ if (other) {
2463
+ var posBefore = posLess(pos, anchor);
2464
+ if (posBefore != posLess(other, anchor)) {
2465
+ anchor = pos;
2466
+ pos = other;
2467
+ } else if (posBefore != posLess(pos, other)) {
2468
+ pos = other;
2469
+ }
2470
+ }
2471
+ setSelection(doc, anchor, pos, bias);
2472
+ } else {
2473
+ setSelection(doc, pos, other || pos, bias);
2474
+ }
2475
+ if (doc.cm) doc.cm.curOp.userSelChange = true;
2476
+ }
2477
+
2478
+ function filterSelectionChange(doc, anchor, head) {
2479
+ var obj = {anchor: anchor, head: head};
2480
+ signal(doc, "beforeSelectionChange", doc, obj);
2481
+ if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
2482
+ obj.anchor = clipPos(doc, obj.anchor); obj.head = clipPos(doc, obj.head);
2483
+ return obj;
2484
+ }
2485
+
2486
+ // Update the selection. Last two args are only used by
2487
+ // updateDoc, since they have to be expressed in the line
2488
+ // numbers before the update.
2489
+ function setSelection(doc, anchor, head, bias, checkAtomic) {
2490
+ if (!checkAtomic && hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) {
2491
+ var filtered = filterSelectionChange(doc, anchor, head);
2492
+ head = filtered.head;
2493
+ anchor = filtered.anchor;
2494
+ }
2495
+
2496
+ var sel = doc.sel;
2497
+ sel.goalColumn = null;
2498
+ // Skip over atomic spans.
2499
+ if (checkAtomic || !posEq(anchor, sel.anchor))
2500
+ anchor = skipAtomic(doc, anchor, bias, checkAtomic != "push");
2501
+ if (checkAtomic || !posEq(head, sel.head))
2502
+ head = skipAtomic(doc, head, bias, checkAtomic != "push");
2503
+
2504
+ if (posEq(sel.anchor, anchor) && posEq(sel.head, head)) return;
2505
+
2506
+ sel.anchor = anchor; sel.head = head;
2507
+ var inv = posLess(head, anchor);
2508
+ sel.from = inv ? head : anchor;
2509
+ sel.to = inv ? anchor : head;
2510
+
2511
+ if (doc.cm)
2512
+ doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged =
2513
+ doc.cm.curOp.cursorActivity = true;
2514
+
2515
+ signalLater(doc, "cursorActivity", doc);
2516
+ }
2517
+
2518
+ function reCheckSelection(cm) {
2519
+ setSelection(cm.doc, cm.doc.sel.from, cm.doc.sel.to, null, "push");
2520
+ }
2521
+
2522
+ function skipAtomic(doc, pos, bias, mayClear) {
2523
+ var flipped = false, curPos = pos;
2524
+ var dir = bias || 1;
2525
+ doc.cantEdit = false;
2526
+ search: for (;;) {
2527
+ var line = getLine(doc, curPos.line);
2528
+ if (line.markedSpans) {
2529
+ for (var i = 0; i < line.markedSpans.length; ++i) {
2530
+ var sp = line.markedSpans[i], m = sp.marker;
2531
+ if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
2532
+ (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
2533
+ if (mayClear) {
2534
+ signal(m, "beforeCursorEnter");
2535
+ if (m.explicitlyCleared) {
2536
+ if (!line.markedSpans) break;
2537
+ else {--i; continue;}
2538
+ }
2539
+ }
2540
+ if (!m.atomic) continue;
2541
+ var newPos = m.find()[dir < 0 ? "from" : "to"];
2542
+ if (posEq(newPos, curPos)) {
2543
+ newPos.ch += dir;
2544
+ if (newPos.ch < 0) {
2545
+ if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
2546
+ else newPos = null;
2547
+ } else if (newPos.ch > line.text.length) {
2548
+ if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
2549
+ else newPos = null;
2550
+ }
2551
+ if (!newPos) {
2552
+ if (flipped) {
2553
+ // Driven in a corner -- no valid cursor position found at all
2554
+ // -- try again *with* clearing, if we didn't already
2555
+ if (!mayClear) return skipAtomic(doc, pos, bias, true);
2556
+ // Otherwise, turn off editing until further notice, and return the start of the doc
2557
+ doc.cantEdit = true;
2558
+ return Pos(doc.first, 0);
2559
+ }
2560
+ flipped = true; newPos = pos; dir = -dir;
2561
+ }
2562
+ }
2563
+ curPos = newPos;
2564
+ continue search;
2565
+ }
2566
+ }
2567
+ }
2568
+ return curPos;
2569
+ }
2570
+ }
2571
+
2572
+ // SCROLLING
2573
+
2574
+ function scrollCursorIntoView(cm) {
2575
+ var coords = scrollPosIntoView(cm, cm.doc.sel.head, cm.options.cursorScrollMargin);
2576
+ if (!cm.state.focused) return;
2577
+ var display = cm.display, box = getRect(display.sizer), doScroll = null;
2578
+ if (coords.top + box.top < 0) doScroll = true;
2579
+ else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
2580
+ if (doScroll != null && !phantom) {
2581
+ var hidden = display.cursor.style.display == "none";
2582
+ if (hidden) {
2583
+ display.cursor.style.display = "";
2584
+ display.cursor.style.left = coords.left + "px";
2585
+ display.cursor.style.top = (coords.top - display.viewOffset) + "px";
2586
+ }
2587
+ display.cursor.scrollIntoView(doScroll);
2588
+ if (hidden) display.cursor.style.display = "none";
2589
+ }
2590
+ }
2591
+
2592
+ function scrollPosIntoView(cm, pos, margin) {
2593
+ if (margin == null) margin = 0;
2594
+ for (;;) {
2595
+ var changed = false, coords = cursorCoords(cm, pos);
2596
+ var scrollPos = calculateScrollPos(cm, coords.left, coords.top - margin, coords.left, coords.bottom + margin);
2597
+ var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
2598
+ if (scrollPos.scrollTop != null) {
2599
+ setScrollTop(cm, scrollPos.scrollTop);
2600
+ if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
2601
+ }
2602
+ if (scrollPos.scrollLeft != null) {
2603
+ setScrollLeft(cm, scrollPos.scrollLeft);
2604
+ if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
2605
+ }
2606
+ if (!changed) return coords;
2607
+ }
2608
+ }
2609
+
2610
+ function scrollIntoView(cm, x1, y1, x2, y2) {
2611
+ var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
2612
+ if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
2613
+ if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
2614
+ }
2615
+
2616
+ function calculateScrollPos(cm, x1, y1, x2, y2) {
2617
+ var display = cm.display, snapMargin = textHeight(cm.display);
2618
+ if (y1 < 0) y1 = 0;
2619
+ var screen = display.scroller.clientHeight - scrollerCutOff, screentop = display.scroller.scrollTop, result = {};
2620
+ var docBottom = cm.doc.height + paddingVert(display);
2621
+ var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
2622
+ if (y1 < screentop) {
2623
+ result.scrollTop = atTop ? 0 : y1;
2624
+ } else if (y2 > screentop + screen) {
2625
+ var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
2626
+ if (newTop != screentop) result.scrollTop = newTop;
2627
+ }
2628
+
2629
+ var screenw = display.scroller.clientWidth - scrollerCutOff, screenleft = display.scroller.scrollLeft;
2630
+ x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth;
2631
+ var gutterw = display.gutters.offsetWidth;
2632
+ var atLeft = x1 < gutterw + 10;
2633
+ if (x1 < screenleft + gutterw || atLeft) {
2634
+ if (atLeft) x1 = 0;
2635
+ result.scrollLeft = Math.max(0, x1 - 10 - gutterw);
2636
+ } else if (x2 > screenw + screenleft - 3) {
2637
+ result.scrollLeft = x2 + 10 - screenw;
2638
+ }
2639
+ return result;
2640
+ }
2641
+
2642
+ function updateScrollPos(cm, left, top) {
2643
+ cm.curOp.updateScrollPos = {scrollLeft: left == null ? cm.doc.scrollLeft : left,
2644
+ scrollTop: top == null ? cm.doc.scrollTop : top};
2645
+ }
2646
+
2647
+ function addToScrollPos(cm, left, top) {
2648
+ var pos = cm.curOp.updateScrollPos || (cm.curOp.updateScrollPos = {scrollLeft: cm.doc.scrollLeft, scrollTop: cm.doc.scrollTop});
2649
+ var scroll = cm.display.scroller;
2650
+ pos.scrollTop = Math.max(0, Math.min(scroll.scrollHeight - scroll.clientHeight, pos.scrollTop + top));
2651
+ pos.scrollLeft = Math.max(0, Math.min(scroll.scrollWidth - scroll.clientWidth, pos.scrollLeft + left));
2652
+ }
2653
+
2654
+ // API UTILITIES
2655
+
2656
+ function indentLine(cm, n, how, aggressive) {
2657
+ var doc = cm.doc;
2658
+ if (how == null) how = "add";
2659
+ if (how == "smart") {
2660
+ if (!cm.doc.mode.indent) how = "prev";
2661
+ else var state = getStateBefore(cm, n);
2662
+ }
2663
+
2664
+ var tabSize = cm.options.tabSize;
2665
+ var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
2666
+ var curSpaceString = line.text.match(/^\s*/)[0], indentation;
2667
+ if (how == "smart") {
2668
+ indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
2669
+ if (indentation == Pass) {
2670
+ if (!aggressive) return;
2671
+ how = "prev";
2672
+ }
2673
+ }
2674
+ if (how == "prev") {
2675
+ if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
2676
+ else indentation = 0;
2677
+ } else if (how == "add") {
2678
+ indentation = curSpace + cm.options.indentUnit;
2679
+ } else if (how == "subtract") {
2680
+ indentation = curSpace - cm.options.indentUnit;
2681
+ } else if (typeof how == "number") {
2682
+ indentation = curSpace + how;
2683
+ }
2684
+ indentation = Math.max(0, indentation);
2685
+
2686
+ var indentString = "", pos = 0;
2687
+ if (cm.options.indentWithTabs)
2688
+ for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
2689
+ if (pos < indentation) indentString += spaceStr(indentation - pos);
2690
+
2691
+ if (indentString != curSpaceString)
2692
+ replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
2693
+ line.stateAfter = null;
2694
+ }
2695
+
2696
+ function changeLine(cm, handle, op) {
2697
+ var no = handle, line = handle, doc = cm.doc;
2698
+ if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
2699
+ else no = lineNo(handle);
2700
+ if (no == null) return null;
2701
+ if (op(line, no)) regChange(cm, no, no + 1);
2702
+ else return null;
2703
+ return line;
2704
+ }
2705
+
2706
+ function findPosH(doc, pos, dir, unit, visually) {
2707
+ var line = pos.line, ch = pos.ch, origDir = dir;
2708
+ var lineObj = getLine(doc, line);
2709
+ var possible = true;
2710
+ function findNextLine() {
2711
+ var l = line + dir;
2712
+ if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
2713
+ line = l;
2714
+ return lineObj = getLine(doc, l);
2715
+ }
2716
+ function moveOnce(boundToLine) {
2717
+ var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
2718
+ if (next == null) {
2719
+ if (!boundToLine && findNextLine()) {
2720
+ if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
2721
+ else ch = dir < 0 ? lineObj.text.length : 0;
2722
+ } else return (possible = false);
2723
+ } else ch = next;
2724
+ return true;
2725
+ }
2726
+
2727
+ if (unit == "char") moveOnce();
2728
+ else if (unit == "column") moveOnce(true);
2729
+ else if (unit == "word" || unit == "group") {
2730
+ var sawType = null, group = unit == "group";
2731
+ for (var first = true;; first = false) {
2732
+ if (dir < 0 && !moveOnce(!first)) break;
2733
+ var cur = lineObj.text.charAt(ch) || "\n";
2734
+ var type = isWordChar(cur) ? "w"
2735
+ : !group ? null
2736
+ : /\s/.test(cur) ? null
2737
+ : "p";
2738
+ if (sawType && sawType != type) {
2739
+ if (dir < 0) {dir = 1; moveOnce();}
2740
+ break;
2741
+ }
2742
+ if (type) sawType = type;
2743
+ if (dir > 0 && !moveOnce(!first)) break;
2744
+ }
2745
+ }
2746
+ var result = skipAtomic(doc, Pos(line, ch), origDir, true);
2747
+ if (!possible) result.hitSide = true;
2748
+ return result;
2749
+ }
2750
+
2751
+ function findPosV(cm, pos, dir, unit) {
2752
+ var doc = cm.doc, x = pos.left, y;
2753
+ if (unit == "page") {
2754
+ var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
2755
+ y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
2756
+ } else if (unit == "line") {
2757
+ y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
2758
+ }
2759
+ for (;;) {
2760
+ var target = coordsChar(cm, x, y);
2761
+ if (!target.outside) break;
2762
+ if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
2763
+ y += dir * 5;
2764
+ }
2765
+ return target;
2766
+ }
2767
+
2768
+ function findWordAt(line, pos) {
2769
+ var start = pos.ch, end = pos.ch;
2770
+ if (line) {
2771
+ if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
2772
+ var startChar = line.charAt(start);
2773
+ var check = isWordChar(startChar) ? isWordChar
2774
+ : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
2775
+ : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
2776
+ while (start > 0 && check(line.charAt(start - 1))) --start;
2777
+ while (end < line.length && check(line.charAt(end))) ++end;
2778
+ }
2779
+ return {from: Pos(pos.line, start), to: Pos(pos.line, end)};
2780
+ }
2781
+
2782
+ function selectLine(cm, line) {
2783
+ extendSelection(cm.doc, Pos(line, 0), clipPos(cm.doc, Pos(line + 1, 0)));
2784
+ }
2785
+
2786
+ // PROTOTYPE
2787
+
2788
+ // The publicly visible API. Note that operation(null, f) means
2789
+ // 'wrap f in an operation, performed on its `this` parameter'
2790
+
2791
+ CodeMirror.prototype = {
2792
+ constructor: CodeMirror,
2793
+ focus: function(){window.focus(); focusInput(this); onFocus(this); fastPoll(this);},
2794
+
2795
+ setOption: function(option, value) {
2796
+ var options = this.options, old = options[option];
2797
+ if (options[option] == value && option != "mode") return;
2798
+ options[option] = value;
2799
+ if (optionHandlers.hasOwnProperty(option))
2800
+ operation(this, optionHandlers[option])(this, value, old);
2801
+ },
2802
+
2803
+ getOption: function(option) {return this.options[option];},
2804
+ getDoc: function() {return this.doc;},
2805
+
2806
+ addKeyMap: function(map, bottom) {
2807
+ this.state.keyMaps[bottom ? "push" : "unshift"](map);
2808
+ },
2809
+ removeKeyMap: function(map) {
2810
+ var maps = this.state.keyMaps;
2811
+ for (var i = 0; i < maps.length; ++i)
2812
+ if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) {
2813
+ maps.splice(i, 1);
2814
+ return true;
2815
+ }
2816
+ },
2817
+
2818
+ addOverlay: operation(null, function(spec, options) {
2819
+ var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
2820
+ if (mode.startState) throw new Error("Overlays may not be stateful.");
2821
+ this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
2822
+ this.state.modeGen++;
2823
+ regChange(this);
2824
+ }),
2825
+ removeOverlay: operation(null, function(spec) {
2826
+ var overlays = this.state.overlays;
2827
+ for (var i = 0; i < overlays.length; ++i) {
2828
+ var cur = overlays[i].modeSpec;
2829
+ if (cur == spec || typeof spec == "string" && cur.name == spec) {
2830
+ overlays.splice(i, 1);
2831
+ this.state.modeGen++;
2832
+ regChange(this);
2833
+ return;
2834
+ }
2835
+ }
2836
+ }),
2837
+
2838
+ indentLine: operation(null, function(n, dir, aggressive) {
2839
+ if (typeof dir != "string" && typeof dir != "number") {
2840
+ if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
2841
+ else dir = dir ? "add" : "subtract";
2842
+ }
2843
+ if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
2844
+ }),
2845
+ indentSelection: operation(null, function(how) {
2846
+ var sel = this.doc.sel;
2847
+ if (posEq(sel.from, sel.to)) return indentLine(this, sel.from.line, how);
2848
+ var e = sel.to.line - (sel.to.ch ? 0 : 1);
2849
+ for (var i = sel.from.line; i <= e; ++i) indentLine(this, i, how);
2850
+ }),
2851
+
2852
+ // Fetch the parser token for a given character. Useful for hacks
2853
+ // that want to inspect the mode state (say, for completion).
2854
+ getTokenAt: function(pos, precise) {
2855
+ var doc = this.doc;
2856
+ pos = clipPos(doc, pos);
2857
+ var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode;
2858
+ var line = getLine(doc, pos.line);
2859
+ var stream = new StringStream(line.text, this.options.tabSize);
2860
+ while (stream.pos < pos.ch && !stream.eol()) {
2861
+ stream.start = stream.pos;
2862
+ var style = mode.token(stream, state);
2863
+ }
2864
+ return {start: stream.start,
2865
+ end: stream.pos,
2866
+ string: stream.current(),
2867
+ className: style || null, // Deprecated, use 'type' instead
2868
+ type: style || null,
2869
+ state: state};
2870
+ },
2871
+
2872
+ getTokenTypeAt: function(pos) {
2873
+ pos = clipPos(this.doc, pos);
2874
+ var styles = getLineStyles(this, getLine(this.doc, pos.line));
2875
+ var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
2876
+ if (ch == 0) return styles[2];
2877
+ for (;;) {
2878
+ var mid = (before + after) >> 1;
2879
+ if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
2880
+ else if (styles[mid * 2 + 1] < ch) before = mid + 1;
2881
+ else return styles[mid * 2 + 2];
2882
+ }
2883
+ },
2884
+
2885
+ getModeAt: function(pos) {
2886
+ var mode = this.doc.mode;
2887
+ if (!mode.innerMode) return mode;
2888
+ return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
2889
+ },
2890
+
2891
+ getHelper: function(pos, type) {
2892
+ if (!helpers.hasOwnProperty(type)) return;
2893
+ var help = helpers[type], mode = this.getModeAt(pos);
2894
+ return mode[type] && help[mode[type]] ||
2895
+ mode.helperType && help[mode.helperType] ||
2896
+ help[mode.name];
2897
+ },
2898
+
2899
+ getStateAfter: function(line, precise) {
2900
+ var doc = this.doc;
2901
+ line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
2902
+ return getStateBefore(this, line + 1, precise);
2903
+ },
2904
+
2905
+ cursorCoords: function(start, mode) {
2906
+ var pos, sel = this.doc.sel;
2907
+ if (start == null) pos = sel.head;
2908
+ else if (typeof start == "object") pos = clipPos(this.doc, start);
2909
+ else pos = start ? sel.from : sel.to;
2910
+ return cursorCoords(this, pos, mode || "page");
2911
+ },
2912
+
2913
+ charCoords: function(pos, mode) {
2914
+ return charCoords(this, clipPos(this.doc, pos), mode || "page");
2915
+ },
2916
+
2917
+ coordsChar: function(coords, mode) {
2918
+ coords = fromCoordSystem(this, coords, mode || "page");
2919
+ return coordsChar(this, coords.left, coords.top);
2920
+ },
2921
+
2922
+ lineAtHeight: function(height, mode) {
2923
+ height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
2924
+ return lineAtHeight(this.doc, height + this.display.viewOffset);
2925
+ },
2926
+ heightAtLine: function(line, mode) {
2927
+ var end = false, last = this.doc.first + this.doc.size - 1;
2928
+ if (line < this.doc.first) line = this.doc.first;
2929
+ else if (line > last) { line = last; end = true; }
2930
+ var lineObj = getLine(this.doc, line);
2931
+ return intoCoordSystem(this, getLine(this.doc, line), {top: 0, left: 0}, mode || "page").top +
2932
+ (end ? lineObj.height : 0);
2933
+ },
2934
+
2935
+ defaultTextHeight: function() { return textHeight(this.display); },
2936
+ defaultCharWidth: function() { return charWidth(this.display); },
2937
+
2938
+ setGutterMarker: operation(null, function(line, gutterID, value) {
2939
+ return changeLine(this, line, function(line) {
2940
+ var markers = line.gutterMarkers || (line.gutterMarkers = {});
2941
+ markers[gutterID] = value;
2942
+ if (!value && isEmpty(markers)) line.gutterMarkers = null;
2943
+ return true;
2944
+ });
2945
+ }),
2946
+
2947
+ clearGutter: operation(null, function(gutterID) {
2948
+ var cm = this, doc = cm.doc, i = doc.first;
2949
+ doc.iter(function(line) {
2950
+ if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
2951
+ line.gutterMarkers[gutterID] = null;
2952
+ regChange(cm, i, i + 1);
2953
+ if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
2954
+ }
2955
+ ++i;
2956
+ });
2957
+ }),
2958
+
2959
+ addLineClass: operation(null, function(handle, where, cls) {
2960
+ return changeLine(this, handle, function(line) {
2961
+ var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
2962
+ if (!line[prop]) line[prop] = cls;
2963
+ else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false;
2964
+ else line[prop] += " " + cls;
2965
+ return true;
2966
+ });
2967
+ }),
2968
+
2969
+ removeLineClass: operation(null, function(handle, where, cls) {
2970
+ return changeLine(this, handle, function(line) {
2971
+ var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass";
2972
+ var cur = line[prop];
2973
+ if (!cur) return false;
2974
+ else if (cls == null) line[prop] = null;
2975
+ else {
2976
+ var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)"));
2977
+ if (!found) return false;
2978
+ var end = found.index + found[0].length;
2979
+ line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
2980
+ }
2981
+ return true;
2982
+ });
2983
+ }),
2984
+
2985
+ addLineWidget: operation(null, function(handle, node, options) {
2986
+ return addLineWidget(this, handle, node, options);
2987
+ }),
2988
+
2989
+ removeLineWidget: function(widget) { widget.clear(); },
2990
+
2991
+ lineInfo: function(line) {
2992
+ if (typeof line == "number") {
2993
+ if (!isLine(this.doc, line)) return null;
2994
+ var n = line;
2995
+ line = getLine(this.doc, line);
2996
+ if (!line) return null;
2997
+ } else {
2998
+ var n = lineNo(line);
2999
+ if (n == null) return null;
3000
+ }
3001
+ return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
3002
+ textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
3003
+ widgets: line.widgets};
3004
+ },
3005
+
3006
+ getViewport: function() { return {from: this.display.showingFrom, to: this.display.showingTo};},
3007
+
3008
+ addWidget: function(pos, node, scroll, vert, horiz) {
3009
+ var display = this.display;
3010
+ pos = cursorCoords(this, clipPos(this.doc, pos));
3011
+ var top = pos.bottom, left = pos.left;
3012
+ node.style.position = "absolute";
3013
+ display.sizer.appendChild(node);
3014
+ if (vert == "over") {
3015
+ top = pos.top;
3016
+ } else if (vert == "above" || vert == "near") {
3017
+ var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
3018
+ hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
3019
+ // Default to positioning above (if specified and possible); otherwise default to positioning below
3020
+ if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
3021
+ top = pos.top - node.offsetHeight;
3022
+ else if (pos.bottom + node.offsetHeight <= vspace)
3023
+ top = pos.bottom;
3024
+ if (left + node.offsetWidth > hspace)
3025
+ left = hspace - node.offsetWidth;
3026
+ }
3027
+ node.style.top = top + "px";
3028
+ node.style.left = node.style.right = "";
3029
+ if (horiz == "right") {
3030
+ left = display.sizer.clientWidth - node.offsetWidth;
3031
+ node.style.right = "0px";
3032
+ } else {
3033
+ if (horiz == "left") left = 0;
3034
+ else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
3035
+ node.style.left = left + "px";
3036
+ }
3037
+ if (scroll)
3038
+ scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
3039
+ },
3040
+
3041
+ triggerOnKeyDown: operation(null, onKeyDown),
3042
+
3043
+ execCommand: function(cmd) {return commands[cmd](this);},
3044
+
3045
+ findPosH: function(from, amount, unit, visually) {
3046
+ var dir = 1;
3047
+ if (amount < 0) { dir = -1; amount = -amount; }
3048
+ for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
3049
+ cur = findPosH(this.doc, cur, dir, unit, visually);
3050
+ if (cur.hitSide) break;
3051
+ }
3052
+ return cur;
3053
+ },
3054
+
3055
+ moveH: operation(null, function(dir, unit) {
3056
+ var sel = this.doc.sel, pos;
3057
+ if (sel.shift || sel.extend || posEq(sel.from, sel.to))
3058
+ pos = findPosH(this.doc, sel.head, dir, unit, this.options.rtlMoveVisually);
3059
+ else
3060
+ pos = dir < 0 ? sel.from : sel.to;
3061
+ extendSelection(this.doc, pos, pos, dir);
3062
+ }),
3063
+
3064
+ deleteH: operation(null, function(dir, unit) {
3065
+ var sel = this.doc.sel;
3066
+ if (!posEq(sel.from, sel.to)) replaceRange(this.doc, "", sel.from, sel.to, "+delete");
3067
+ else replaceRange(this.doc, "", sel.from, findPosH(this.doc, sel.head, dir, unit, false), "+delete");
3068
+ this.curOp.userSelChange = true;
3069
+ }),
3070
+
3071
+ findPosV: function(from, amount, unit, goalColumn) {
3072
+ var dir = 1, x = goalColumn;
3073
+ if (amount < 0) { dir = -1; amount = -amount; }
3074
+ for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
3075
+ var coords = cursorCoords(this, cur, "div");
3076
+ if (x == null) x = coords.left;
3077
+ else coords.left = x;
3078
+ cur = findPosV(this, coords, dir, unit);
3079
+ if (cur.hitSide) break;
3080
+ }
3081
+ return cur;
3082
+ },
3083
+
3084
+ moveV: operation(null, function(dir, unit) {
3085
+ var sel = this.doc.sel;
3086
+ var pos = cursorCoords(this, sel.head, "div");
3087
+ if (sel.goalColumn != null) pos.left = sel.goalColumn;
3088
+ var target = findPosV(this, pos, dir, unit);
3089
+
3090
+ if (unit == "page") addToScrollPos(this, 0, charCoords(this, target, "div").top - pos.top);
3091
+ extendSelection(this.doc, target, target, dir);
3092
+ sel.goalColumn = pos.left;
3093
+ }),
3094
+
3095
+ toggleOverwrite: function(value) {
3096
+ if (value != null && value == this.state.overwrite) return;
3097
+ if (this.state.overwrite = !this.state.overwrite)
3098
+ this.display.cursor.className += " CodeMirror-overwrite";
3099
+ else
3100
+ this.display.cursor.className = this.display.cursor.className.replace(" CodeMirror-overwrite", "");
3101
+ },
3102
+ hasFocus: function() { return this.state.focused; },
3103
+
3104
+ scrollTo: operation(null, function(x, y) {
3105
+ updateScrollPos(this, x, y);
3106
+ }),
3107
+ getScrollInfo: function() {
3108
+ var scroller = this.display.scroller, co = scrollerCutOff;
3109
+ return {left: scroller.scrollLeft, top: scroller.scrollTop,
3110
+ height: scroller.scrollHeight - co, width: scroller.scrollWidth - co,
3111
+ clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co};
3112
+ },
3113
+
3114
+ scrollIntoView: operation(null, function(pos, margin) {
3115
+ if (typeof pos == "number") pos = Pos(pos, 0);
3116
+ if (!margin) margin = 0;
3117
+ var coords = pos;
3118
+
3119
+ if (!pos || pos.line != null) {
3120
+ this.curOp.scrollToPos = pos ? clipPos(this.doc, pos) : this.doc.sel.head;
3121
+ this.curOp.scrollToPosMargin = margin;
3122
+ coords = cursorCoords(this, this.curOp.scrollToPos);
3123
+ }
3124
+ var sPos = calculateScrollPos(this, coords.left, coords.top - margin, coords.right, coords.bottom + margin);
3125
+ updateScrollPos(this, sPos.scrollLeft, sPos.scrollTop);
3126
+ }),
3127
+
3128
+ setSize: operation(null, function(width, height) {
3129
+ function interpret(val) {
3130
+ return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
3131
+ }
3132
+ if (width != null) this.display.wrapper.style.width = interpret(width);
3133
+ if (height != null) this.display.wrapper.style.height = interpret(height);
3134
+ if (this.options.lineWrapping)
3135
+ this.display.measureLineCache.length = this.display.measureLineCachePos = 0;
3136
+ this.curOp.forceUpdate = true;
3137
+ }),
3138
+
3139
+ operation: function(f){return runInOp(this, f);},
3140
+
3141
+ refresh: operation(null, function() {
3142
+ clearCaches(this);
3143
+ updateScrollPos(this, this.doc.scrollLeft, this.doc.scrollTop);
3144
+ regChange(this);
3145
+ }),
3146
+
3147
+ swapDoc: operation(null, function(doc) {
3148
+ var old = this.doc;
3149
+ old.cm = null;
3150
+ attachDoc(this, doc);
3151
+ clearCaches(this);
3152
+ resetInput(this, true);
3153
+ updateScrollPos(this, doc.scrollLeft, doc.scrollTop);
3154
+ return old;
3155
+ }),
3156
+
3157
+ getInputField: function(){return this.display.input;},
3158
+ getWrapperElement: function(){return this.display.wrapper;},
3159
+ getScrollerElement: function(){return this.display.scroller;},
3160
+ getGutterElement: function(){return this.display.gutters;}
3161
+ };
3162
+ eventMixin(CodeMirror);
3163
+
3164
+ // OPTION DEFAULTS
3165
+
3166
+ var optionHandlers = CodeMirror.optionHandlers = {};
3167
+
3168
+ // The default configuration options.
3169
+ var defaults = CodeMirror.defaults = {};
3170
+
3171
+ function option(name, deflt, handle, notOnInit) {
3172
+ CodeMirror.defaults[name] = deflt;
3173
+ if (handle) optionHandlers[name] =
3174
+ notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
3175
+ }
3176
+
3177
+ var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
3178
+
3179
+ // These two are, on init, called from the constructor because they
3180
+ // have to be initialized before the editor can start at all.
3181
+ option("value", "", function(cm, val) {
3182
+ cm.setValue(val);
3183
+ }, true);
3184
+ option("mode", null, function(cm, val) {
3185
+ cm.doc.modeOption = val;
3186
+ loadMode(cm);
3187
+ }, true);
3188
+
3189
+ option("indentUnit", 2, loadMode, true);
3190
+ option("indentWithTabs", false);
3191
+ option("smartIndent", true);
3192
+ option("tabSize", 4, function(cm) {
3193
+ loadMode(cm);
3194
+ clearCaches(cm);
3195
+ regChange(cm);
3196
+ }, true);
3197
+ option("electricChars", true);
3198
+ option("rtlMoveVisually", !windows);
3199
+
3200
+ option("theme", "default", function(cm) {
3201
+ themeChanged(cm);
3202
+ guttersChanged(cm);
3203
+ }, true);
3204
+ option("keyMap", "default", keyMapChanged);
3205
+ option("extraKeys", null);
3206
+
3207
+ option("onKeyEvent", null);
3208
+ option("onDragEvent", null);
3209
+
3210
+ option("lineWrapping", false, wrappingChanged, true);
3211
+ option("gutters", [], function(cm) {
3212
+ setGuttersForLineNumbers(cm.options);
3213
+ guttersChanged(cm);
3214
+ }, true);
3215
+ option("fixedGutter", true, function(cm, val) {
3216
+ cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
3217
+ cm.refresh();
3218
+ }, true);
3219
+ option("coverGutterNextToScrollbar", false, updateScrollbars, true);
3220
+ option("lineNumbers", false, function(cm) {
3221
+ setGuttersForLineNumbers(cm.options);
3222
+ guttersChanged(cm);
3223
+ }, true);
3224
+ option("firstLineNumber", 1, guttersChanged, true);
3225
+ option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
3226
+ option("showCursorWhenSelecting", false, updateSelection, true);
3227
+
3228
+ option("readOnly", false, function(cm, val) {
3229
+ if (val == "nocursor") {onBlur(cm); cm.display.input.blur();}
3230
+ else if (!val) resetInput(cm, true);
3231
+ });
3232
+ option("dragDrop", true);
3233
+
3234
+ option("cursorBlinkRate", 530);
3235
+ option("cursorScrollMargin", 0);
3236
+ option("cursorHeight", 1);
3237
+ option("workTime", 100);
3238
+ option("workDelay", 100);
3239
+ option("flattenSpans", true);
3240
+ option("pollInterval", 100);
3241
+ option("undoDepth", 40, function(cm, val){cm.doc.history.undoDepth = val;});
3242
+ option("historyEventDelay", 500);
3243
+ option("viewportMargin", 10, function(cm){cm.refresh();}, true);
3244
+ option("maxHighlightLength", 10000, function(cm){loadMode(cm); cm.refresh();}, true);
3245
+ option("moveInputWithCursor", true, function(cm, val) {
3246
+ if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;
3247
+ });
3248
+
3249
+ option("tabindex", null, function(cm, val) {
3250
+ cm.display.input.tabIndex = val || "";
3251
+ });
3252
+ option("autofocus", null);
3253
+
3254
+ // MODE DEFINITION AND QUERYING
3255
+
3256
+ // Known modes, by name and by MIME
3257
+ var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
3258
+
3259
+ CodeMirror.defineMode = function(name, mode) {
3260
+ if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
3261
+ if (arguments.length > 2) {
3262
+ mode.dependencies = [];
3263
+ for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
3264
+ }
3265
+ modes[name] = mode;
3266
+ };
3267
+
3268
+ CodeMirror.defineMIME = function(mime, spec) {
3269
+ mimeModes[mime] = spec;
3270
+ };
3271
+
3272
+ CodeMirror.resolveMode = function(spec) {
3273
+ if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
3274
+ spec = mimeModes[spec];
3275
+ } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
3276
+ var found = mimeModes[spec.name];
3277
+ spec = createObj(found, spec);
3278
+ spec.name = found.name;
3279
+ } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
3280
+ return CodeMirror.resolveMode("application/xml");
3281
+ }
3282
+ if (typeof spec == "string") return {name: spec};
3283
+ else return spec || {name: "null"};
3284
+ };
3285
+
3286
+ CodeMirror.getMode = function(options, spec) {
3287
+ var spec = CodeMirror.resolveMode(spec);
3288
+ var mfactory = modes[spec.name];
3289
+ if (!mfactory) return CodeMirror.getMode(options, "text/plain");
3290
+ var modeObj = mfactory(options, spec);
3291
+ if (modeExtensions.hasOwnProperty(spec.name)) {
3292
+ var exts = modeExtensions[spec.name];
3293
+ for (var prop in exts) {
3294
+ if (!exts.hasOwnProperty(prop)) continue;
3295
+ if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
3296
+ modeObj[prop] = exts[prop];
3297
+ }
3298
+ }
3299
+ modeObj.name = spec.name;
3300
+
3301
+ return modeObj;
3302
+ };
3303
+
3304
+ CodeMirror.defineMode("null", function() {
3305
+ return {token: function(stream) {stream.skipToEnd();}};
3306
+ });
3307
+ CodeMirror.defineMIME("text/plain", "null");
3308
+
3309
+ var modeExtensions = CodeMirror.modeExtensions = {};
3310
+ CodeMirror.extendMode = function(mode, properties) {
3311
+ var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
3312
+ copyObj(properties, exts);
3313
+ };
3314
+
3315
+ // EXTENSIONS
3316
+
3317
+ CodeMirror.defineExtension = function(name, func) {
3318
+ CodeMirror.prototype[name] = func;
3319
+ };
3320
+ CodeMirror.defineDocExtension = function(name, func) {
3321
+ Doc.prototype[name] = func;
3322
+ };
3323
+ CodeMirror.defineOption = option;
3324
+
3325
+ var initHooks = [];
3326
+ CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
3327
+
3328
+ var helpers = CodeMirror.helpers = {};
3329
+ CodeMirror.registerHelper = function(type, name, value) {
3330
+ if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {};
3331
+ helpers[type][name] = value;
3332
+ };
3333
+
3334
+ // UTILITIES
3335
+
3336
+ CodeMirror.isWordChar = isWordChar;
3337
+
3338
+ // MODE STATE HANDLING
3339
+
3340
+ // Utility functions for working with state. Exported because modes
3341
+ // sometimes need to do this.
3342
+ function copyState(mode, state) {
3343
+ if (state === true) return state;
3344
+ if (mode.copyState) return mode.copyState(state);
3345
+ var nstate = {};
3346
+ for (var n in state) {
3347
+ var val = state[n];
3348
+ if (val instanceof Array) val = val.concat([]);
3349
+ nstate[n] = val;
3350
+ }
3351
+ return nstate;
3352
+ }
3353
+ CodeMirror.copyState = copyState;
3354
+
3355
+ function startState(mode, a1, a2) {
3356
+ return mode.startState ? mode.startState(a1, a2) : true;
3357
+ }
3358
+ CodeMirror.startState = startState;
3359
+
3360
+ CodeMirror.innerMode = function(mode, state) {
3361
+ while (mode.innerMode) {
3362
+ var info = mode.innerMode(state);
3363
+ if (!info || info.mode == mode) break;
3364
+ state = info.state;
3365
+ mode = info.mode;
3366
+ }
3367
+ return info || {mode: mode, state: state};
3368
+ };
3369
+
3370
+ // STANDARD COMMANDS
3371
+
3372
+ var commands = CodeMirror.commands = {
3373
+ selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()));},
3374
+ killLine: function(cm) {
3375
+ var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);
3376
+ if (!sel && cm.getLine(from.line).length == from.ch)
3377
+ cm.replaceRange("", from, Pos(from.line + 1, 0), "+delete");
3378
+ else cm.replaceRange("", from, sel ? to : Pos(from.line), "+delete");
3379
+ },
3380
+ deleteLine: function(cm) {
3381
+ var l = cm.getCursor().line;
3382
+ cm.replaceRange("", Pos(l, 0), Pos(l), "+delete");
3383
+ },
3384
+ delLineLeft: function(cm) {
3385
+ var cur = cm.getCursor();
3386
+ cm.replaceRange("", Pos(cur.line, 0), cur, "+delete");
3387
+ },
3388
+ undo: function(cm) {cm.undo();},
3389
+ redo: function(cm) {cm.redo();},
3390
+ goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
3391
+ goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
3392
+ goLineStart: function(cm) {
3393
+ cm.extendSelection(lineStart(cm, cm.getCursor().line));
3394
+ },
3395
+ goLineStartSmart: function(cm) {
3396
+ var cur = cm.getCursor(), start = lineStart(cm, cur.line);
3397
+ var line = cm.getLineHandle(start.line);
3398
+ var order = getOrder(line);
3399
+ if (!order || order[0].level == 0) {
3400
+ var firstNonWS = Math.max(0, line.text.search(/\S/));
3401
+ var inWS = cur.line == start.line && cur.ch <= firstNonWS && cur.ch;
3402
+ cm.extendSelection(Pos(start.line, inWS ? 0 : firstNonWS));
3403
+ } else cm.extendSelection(start);
3404
+ },
3405
+ goLineEnd: function(cm) {
3406
+ cm.extendSelection(lineEnd(cm, cm.getCursor().line));
3407
+ },
3408
+ goLineRight: function(cm) {
3409
+ var top = cm.charCoords(cm.getCursor(), "div").top + 5;
3410
+ cm.extendSelection(cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"));
3411
+ },
3412
+ goLineLeft: function(cm) {
3413
+ var top = cm.charCoords(cm.getCursor(), "div").top + 5;
3414
+ cm.extendSelection(cm.coordsChar({left: 0, top: top}, "div"));
3415
+ },
3416
+ goLineUp: function(cm) {cm.moveV(-1, "line");},
3417
+ goLineDown: function(cm) {cm.moveV(1, "line");},
3418
+ goPageUp: function(cm) {cm.moveV(-1, "page");},
3419
+ goPageDown: function(cm) {cm.moveV(1, "page");},
3420
+ goCharLeft: function(cm) {cm.moveH(-1, "char");},
3421
+ goCharRight: function(cm) {cm.moveH(1, "char");},
3422
+ goColumnLeft: function(cm) {cm.moveH(-1, "column");},
3423
+ goColumnRight: function(cm) {cm.moveH(1, "column");},
3424
+ goWordLeft: function(cm) {cm.moveH(-1, "word");},
3425
+ goGroupRight: function(cm) {cm.moveH(1, "group");},
3426
+ goGroupLeft: function(cm) {cm.moveH(-1, "group");},
3427
+ goWordRight: function(cm) {cm.moveH(1, "word");},
3428
+ delCharBefore: function(cm) {cm.deleteH(-1, "char");},
3429
+ delCharAfter: function(cm) {cm.deleteH(1, "char");},
3430
+ delWordBefore: function(cm) {cm.deleteH(-1, "word");},
3431
+ delWordAfter: function(cm) {cm.deleteH(1, "word");},
3432
+ delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
3433
+ delGroupAfter: function(cm) {cm.deleteH(1, "group");},
3434
+ indentAuto: function(cm) {cm.indentSelection("smart");},
3435
+ indentMore: function(cm) {cm.indentSelection("add");},
3436
+ indentLess: function(cm) {cm.indentSelection("subtract");},
3437
+ insertTab: function(cm) {cm.replaceSelection("\t", "end", "+input");},
3438
+ defaultTab: function(cm) {
3439
+ if (cm.somethingSelected()) cm.indentSelection("add");
3440
+ else cm.replaceSelection("\t", "end", "+input");
3441
+ },
3442
+ transposeChars: function(cm) {
3443
+ var cur = cm.getCursor(), line = cm.getLine(cur.line);
3444
+ if (cur.ch > 0 && cur.ch < line.length - 1)
3445
+ cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),
3446
+ Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1));
3447
+ },
3448
+ newlineAndIndent: function(cm) {
3449
+ operation(cm, function() {
3450
+ cm.replaceSelection("\n", "end", "+input");
3451
+ cm.indentLine(cm.getCursor().line, null, true);
3452
+ })();
3453
+ },
3454
+ toggleOverwrite: function(cm) {cm.toggleOverwrite();}
3455
+ };
3456
+
3457
+ // STANDARD KEYMAPS
3458
+
3459
+ var keyMap = CodeMirror.keyMap = {};
3460
+ keyMap.basic = {
3461
+ "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
3462
+ "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
3463
+ "Delete": "delCharAfter", "Backspace": "delCharBefore", "Tab": "defaultTab", "Shift-Tab": "indentAuto",
3464
+ "Enter": "newlineAndIndent", "Insert": "toggleOverwrite"
3465
+ };
3466
+ // Note that the save and find-related commands aren't defined by
3467
+ // default. Unknown commands are simply ignored.
3468
+ keyMap.pcDefault = {
3469
+ "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
3470
+ "Ctrl-Home": "goDocStart", "Alt-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd",
3471
+ "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
3472
+ "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
3473
+ "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
3474
+ "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
3475
+ fallthrough: "basic"
3476
+ };
3477
+ keyMap.macDefault = {
3478
+ "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
3479
+ "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
3480
+ "Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore",
3481
+ "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
3482
+ "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
3483
+ "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft",
3484
+ fallthrough: ["basic", "emacsy"]
3485
+ };
3486
+ keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
3487
+ keyMap.emacsy = {
3488
+ "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
3489
+ "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
3490
+ "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
3491
+ "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
3492
+ };
3493
+
3494
+ // KEYMAP DISPATCH
3495
+
3496
+ function getKeyMap(val) {
3497
+ if (typeof val == "string") return keyMap[val];
3498
+ else return val;
3499
+ }
3500
+
3501
+ function lookupKey(name, maps, handle) {
3502
+ function lookup(map) {
3503
+ map = getKeyMap(map);
3504
+ var found = map[name];
3505
+ if (found === false) return "stop";
3506
+ if (found != null && handle(found)) return true;
3507
+ if (map.nofallthrough) return "stop";
3508
+
3509
+ var fallthrough = map.fallthrough;
3510
+ if (fallthrough == null) return false;
3511
+ if (Object.prototype.toString.call(fallthrough) != "[object Array]")
3512
+ return lookup(fallthrough);
3513
+ for (var i = 0, e = fallthrough.length; i < e; ++i) {
3514
+ var done = lookup(fallthrough[i]);
3515
+ if (done) return done;
3516
+ }
3517
+ return false;
3518
+ }
3519
+
3520
+ for (var i = 0; i < maps.length; ++i) {
3521
+ var done = lookup(maps[i]);
3522
+ if (done) return done != "stop";
3523
+ }
3524
+ }
3525
+ function isModifierKey(event) {
3526
+ var name = keyNames[event.keyCode];
3527
+ return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
3528
+ }
3529
+ function keyName(event, noShift) {
3530
+ if (opera && event.keyCode == 34 && event["char"]) return false;
3531
+ var name = keyNames[event.keyCode];
3532
+ if (name == null || event.altGraphKey) return false;
3533
+ if (event.altKey) name = "Alt-" + name;
3534
+ if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name;
3535
+ if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name;
3536
+ if (!noShift && event.shiftKey) name = "Shift-" + name;
3537
+ return name;
3538
+ }
3539
+ CodeMirror.lookupKey = lookupKey;
3540
+ CodeMirror.isModifierKey = isModifierKey;
3541
+ CodeMirror.keyName = keyName;
3542
+
3543
+ // FROMTEXTAREA
3544
+
3545
+ CodeMirror.fromTextArea = function(textarea, options) {
3546
+ if (!options) options = {};
3547
+ options.value = textarea.value;
3548
+ if (!options.tabindex && textarea.tabindex)
3549
+ options.tabindex = textarea.tabindex;
3550
+ if (!options.placeholder && textarea.placeholder)
3551
+ options.placeholder = textarea.placeholder;
3552
+ // Set autofocus to true if this textarea is focused, or if it has
3553
+ // autofocus and no other element is focused.
3554
+ if (options.autofocus == null) {
3555
+ var hasFocus = document.body;
3556
+ // doc.activeElement occasionally throws on IE
3557
+ try { hasFocus = document.activeElement; } catch(e) {}
3558
+ options.autofocus = hasFocus == textarea ||
3559
+ textarea.getAttribute("autofocus") != null && hasFocus == document.body;
3560
+ }
3561
+
3562
+ function save() {textarea.value = cm.getValue();}
3563
+ if (textarea.form) {
3564
+ on(textarea.form, "submit", save);
3565
+ // Deplorable hack to make the submit method do the right thing.
3566
+ if (!options.leaveSubmitMethodAlone) {
3567
+ var form = textarea.form, realSubmit = form.submit;
3568
+ try {
3569
+ var wrappedSubmit = form.submit = function() {
3570
+ save();
3571
+ form.submit = realSubmit;
3572
+ form.submit();
3573
+ form.submit = wrappedSubmit;
3574
+ };
3575
+ } catch(e) {}
3576
+ }
3577
+ }
3578
+
3579
+ textarea.style.display = "none";
3580
+ var cm = CodeMirror(function(node) {
3581
+ textarea.parentNode.insertBefore(node, textarea.nextSibling);
3582
+ }, options);
3583
+ cm.save = save;
3584
+ cm.getTextArea = function() { return textarea; };
3585
+ cm.toTextArea = function() {
3586
+ save();
3587
+ textarea.parentNode.removeChild(cm.getWrapperElement());
3588
+ textarea.style.display = "";
3589
+ if (textarea.form) {
3590
+ off(textarea.form, "submit", save);
3591
+ if (typeof textarea.form.submit == "function")
3592
+ textarea.form.submit = realSubmit;
3593
+ }
3594
+ };
3595
+ return cm;
3596
+ };
3597
+
3598
+ // STRING STREAM
3599
+
3600
+ // Fed to the mode parsers, provides helper functions to make
3601
+ // parsers more succinct.
3602
+
3603
+ // The character stream used by a mode's parser.
3604
+ function StringStream(string, tabSize) {
3605
+ this.pos = this.start = 0;
3606
+ this.string = string;
3607
+ this.tabSize = tabSize || 8;
3608
+ this.lastColumnPos = this.lastColumnValue = 0;
3609
+ }
3610
+
3611
+ StringStream.prototype = {
3612
+ eol: function() {return this.pos >= this.string.length;},
3613
+ sol: function() {return this.pos == 0;},
3614
+ peek: function() {return this.string.charAt(this.pos) || undefined;},
3615
+ next: function() {
3616
+ if (this.pos < this.string.length)
3617
+ return this.string.charAt(this.pos++);
3618
+ },
3619
+ eat: function(match) {
3620
+ var ch = this.string.charAt(this.pos);
3621
+ if (typeof match == "string") var ok = ch == match;
3622
+ else var ok = ch && (match.test ? match.test(ch) : match(ch));
3623
+ if (ok) {++this.pos; return ch;}
3624
+ },
3625
+ eatWhile: function(match) {
3626
+ var start = this.pos;
3627
+ while (this.eat(match)){}
3628
+ return this.pos > start;
3629
+ },
3630
+ eatSpace: function() {
3631
+ var start = this.pos;
3632
+ while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
3633
+ return this.pos > start;
3634
+ },
3635
+ skipToEnd: function() {this.pos = this.string.length;},
3636
+ skipTo: function(ch) {
3637
+ var found = this.string.indexOf(ch, this.pos);
3638
+ if (found > -1) {this.pos = found; return true;}
3639
+ },
3640
+ backUp: function(n) {this.pos -= n;},
3641
+ column: function() {
3642
+ if (this.lastColumnPos < this.start) {
3643
+ this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
3644
+ this.lastColumnPos = this.start;
3645
+ }
3646
+ return this.lastColumnValue;
3647
+ },
3648
+ indentation: function() {return countColumn(this.string, null, this.tabSize);},
3649
+ match: function(pattern, consume, caseInsensitive) {
3650
+ if (typeof pattern == "string") {
3651
+ var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
3652
+ var substr = this.string.substr(this.pos, pattern.length);
3653
+ if (cased(substr) == cased(pattern)) {
3654
+ if (consume !== false) this.pos += pattern.length;
3655
+ return true;
3656
+ }
3657
+ } else {
3658
+ var match = this.string.slice(this.pos).match(pattern);
3659
+ if (match && match.index > 0) return null;
3660
+ if (match && consume !== false) this.pos += match[0].length;
3661
+ return match;
3662
+ }
3663
+ },
3664
+ current: function(){return this.string.slice(this.start, this.pos);}
3665
+ };
3666
+ CodeMirror.StringStream = StringStream;
3667
+
3668
+ // TEXTMARKERS
3669
+
3670
+ function TextMarker(doc, type) {
3671
+ this.lines = [];
3672
+ this.type = type;
3673
+ this.doc = doc;
3674
+ }
3675
+ CodeMirror.TextMarker = TextMarker;
3676
+ eventMixin(TextMarker);
3677
+
3678
+ TextMarker.prototype.clear = function() {
3679
+ if (this.explicitlyCleared) return;
3680
+ var cm = this.doc.cm, withOp = cm && !cm.curOp;
3681
+ if (withOp) startOperation(cm);
3682
+ if (hasHandler(this, "clear")) {
3683
+ var found = this.find();
3684
+ if (found) signalLater(this, "clear", found.from, found.to);
3685
+ }
3686
+ var min = null, max = null;
3687
+ for (var i = 0; i < this.lines.length; ++i) {
3688
+ var line = this.lines[i];
3689
+ var span = getMarkedSpanFor(line.markedSpans, this);
3690
+ if (span.to != null) max = lineNo(line);
3691
+ line.markedSpans = removeMarkedSpan(line.markedSpans, span);
3692
+ if (span.from != null)
3693
+ min = lineNo(line);
3694
+ else if (this.collapsed && !lineIsHidden(this.doc, line) && cm)
3695
+ updateLineHeight(line, textHeight(cm.display));
3696
+ }
3697
+ if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
3698
+ var visual = visualLine(cm.doc, this.lines[i]), len = lineLength(cm.doc, visual);
3699
+ if (len > cm.display.maxLineLength) {
3700
+ cm.display.maxLine = visual;
3701
+ cm.display.maxLineLength = len;
3702
+ cm.display.maxLineChanged = true;
3703
+ }
3704
+ }
3705
+
3706
+ if (min != null && cm) regChange(cm, min, max + 1);
3707
+ this.lines.length = 0;
3708
+ this.explicitlyCleared = true;
3709
+ if (this.atomic && this.doc.cantEdit) {
3710
+ this.doc.cantEdit = false;
3711
+ if (cm) reCheckSelection(cm);
3712
+ }
3713
+ if (withOp) endOperation(cm);
3714
+ };
3715
+
3716
+ TextMarker.prototype.find = function() {
3717
+ var from, to;
3718
+ for (var i = 0; i < this.lines.length; ++i) {
3719
+ var line = this.lines[i];
3720
+ var span = getMarkedSpanFor(line.markedSpans, this);
3721
+ if (span.from != null || span.to != null) {
3722
+ var found = lineNo(line);
3723
+ if (span.from != null) from = Pos(found, span.from);
3724
+ if (span.to != null) to = Pos(found, span.to);
3725
+ }
3726
+ }
3727
+ if (this.type == "bookmark") return from;
3728
+ return from && {from: from, to: to};
3729
+ };
3730
+
3731
+ TextMarker.prototype.changed = function() {
3732
+ var pos = this.find(), cm = this.doc.cm;
3733
+ if (!pos || !cm) return;
3734
+ var line = getLine(this.doc, pos.from.line);
3735
+ clearCachedMeasurement(cm, line);
3736
+ if (pos.from.line >= cm.display.showingFrom && pos.from.line < cm.display.showingTo) {
3737
+ for (var node = cm.display.lineDiv.firstChild; node; node = node.nextSibling) if (node.lineObj == line) {
3738
+ if (node.offsetHeight != line.height) updateLineHeight(line, node.offsetHeight);
3739
+ break;
3740
+ }
3741
+ runInOp(cm, function() {
3742
+ cm.curOp.selectionChanged = cm.curOp.forceUpdate = cm.curOp.updateMaxLine = true;
3743
+ });
3744
+ }
3745
+ };
3746
+
3747
+ TextMarker.prototype.attachLine = function(line) {
3748
+ if (!this.lines.length && this.doc.cm) {
3749
+ var op = this.doc.cm.curOp;
3750
+ if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
3751
+ (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
3752
+ }
3753
+ this.lines.push(line);
3754
+ };
3755
+ TextMarker.prototype.detachLine = function(line) {
3756
+ this.lines.splice(indexOf(this.lines, line), 1);
3757
+ if (!this.lines.length && this.doc.cm) {
3758
+ var op = this.doc.cm.curOp;
3759
+ (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
3760
+ }
3761
+ };
3762
+
3763
+ function markText(doc, from, to, options, type) {
3764
+ if (options && options.shared) return markTextShared(doc, from, to, options, type);
3765
+ if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
3766
+
3767
+ var marker = new TextMarker(doc, type);
3768
+ if (type == "range" && !posLess(from, to)) return marker;
3769
+ if (options) copyObj(options, marker);
3770
+ if (marker.replacedWith) {
3771
+ marker.collapsed = true;
3772
+ marker.replacedWith = elt("span", [marker.replacedWith], "CodeMirror-widget");
3773
+ if (!options.handleMouseEvents) marker.replacedWith.ignoreEvents = true;
3774
+ }
3775
+ if (marker.collapsed) sawCollapsedSpans = true;
3776
+
3777
+ if (marker.addToHistory)
3778
+ addToHistory(doc, {from: from, to: to, origin: "markText"},
3779
+ {head: doc.sel.head, anchor: doc.sel.anchor}, NaN);
3780
+
3781
+ var curLine = from.line, size = 0, collapsedAtStart, collapsedAtEnd, cm = doc.cm, updateMaxLine;
3782
+ doc.iter(curLine, to.line + 1, function(line) {
3783
+ if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(doc, line) == cm.display.maxLine)
3784
+ updateMaxLine = true;
3785
+ var span = {from: null, to: null, marker: marker};
3786
+ size += line.text.length;
3787
+ if (curLine == from.line) {span.from = from.ch; size -= from.ch;}
3788
+ if (curLine == to.line) {span.to = to.ch; size -= line.text.length - to.ch;}
3789
+ if (marker.collapsed) {
3790
+ if (curLine == to.line) collapsedAtEnd = collapsedSpanAt(line, to.ch);
3791
+ if (curLine == from.line) collapsedAtStart = collapsedSpanAt(line, from.ch);
3792
+ else updateLineHeight(line, 0);
3793
+ }
3794
+ addMarkedSpan(line, span);
3795
+ ++curLine;
3796
+ });
3797
+ if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
3798
+ if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
3799
+ });
3800
+
3801
+ if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
3802
+
3803
+ if (marker.readOnly) {
3804
+ sawReadOnlySpans = true;
3805
+ if (doc.history.done.length || doc.history.undone.length)
3806
+ doc.clearHistory();
3807
+ }
3808
+ if (marker.collapsed) {
3809
+ if (collapsedAtStart != collapsedAtEnd)
3810
+ throw new Error("Inserting collapsed marker overlapping an existing one");
3811
+ marker.size = size;
3812
+ marker.atomic = true;
3813
+ }
3814
+ if (cm) {
3815
+ if (updateMaxLine) cm.curOp.updateMaxLine = true;
3816
+ if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.collapsed)
3817
+ regChange(cm, from.line, to.line + 1);
3818
+ if (marker.atomic) reCheckSelection(cm);
3819
+ }
3820
+ return marker;
3821
+ }
3822
+
3823
+ // SHARED TEXTMARKERS
3824
+
3825
+ function SharedTextMarker(markers, primary) {
3826
+ this.markers = markers;
3827
+ this.primary = primary;
3828
+ for (var i = 0, me = this; i < markers.length; ++i) {
3829
+ markers[i].parent = this;
3830
+ on(markers[i], "clear", function(){me.clear();});
3831
+ }
3832
+ }
3833
+ CodeMirror.SharedTextMarker = SharedTextMarker;
3834
+ eventMixin(SharedTextMarker);
3835
+
3836
+ SharedTextMarker.prototype.clear = function() {
3837
+ if (this.explicitlyCleared) return;
3838
+ this.explicitlyCleared = true;
3839
+ for (var i = 0; i < this.markers.length; ++i)
3840
+ this.markers[i].clear();
3841
+ signalLater(this, "clear");
3842
+ };
3843
+ SharedTextMarker.prototype.find = function() {
3844
+ return this.primary.find();
3845
+ };
3846
+
3847
+ function markTextShared(doc, from, to, options, type) {
3848
+ options = copyObj(options);
3849
+ options.shared = false;
3850
+ var markers = [markText(doc, from, to, options, type)], primary = markers[0];
3851
+ var widget = options.replacedWith;
3852
+ linkedDocs(doc, function(doc) {
3853
+ if (widget) options.replacedWith = widget.cloneNode(true);
3854
+ markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
3855
+ for (var i = 0; i < doc.linked.length; ++i)
3856
+ if (doc.linked[i].isParent) return;
3857
+ primary = lst(markers);
3858
+ });
3859
+ return new SharedTextMarker(markers, primary);
3860
+ }
3861
+
3862
+ // TEXTMARKER SPANS
3863
+
3864
+ function getMarkedSpanFor(spans, marker) {
3865
+ if (spans) for (var i = 0; i < spans.length; ++i) {
3866
+ var span = spans[i];
3867
+ if (span.marker == marker) return span;
3868
+ }
3869
+ }
3870
+ function removeMarkedSpan(spans, span) {
3871
+ for (var r, i = 0; i < spans.length; ++i)
3872
+ if (spans[i] != span) (r || (r = [])).push(spans[i]);
3873
+ return r;
3874
+ }
3875
+ function addMarkedSpan(line, span) {
3876
+ line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
3877
+ span.marker.attachLine(line);
3878
+ }
3879
+
3880
+ function markedSpansBefore(old, startCh, isInsert) {
3881
+ if (old) for (var i = 0, nw; i < old.length; ++i) {
3882
+ var span = old[i], marker = span.marker;
3883
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
3884
+ if (startsBefore || marker.type == "bookmark" && span.from == startCh && (!isInsert || !span.marker.insertLeft)) {
3885
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
3886
+ (nw || (nw = [])).push({from: span.from,
3887
+ to: endsAfter ? null : span.to,
3888
+ marker: marker});
3889
+ }
3890
+ }
3891
+ return nw;
3892
+ }
3893
+
3894
+ function markedSpansAfter(old, endCh, isInsert) {
3895
+ if (old) for (var i = 0, nw; i < old.length; ++i) {
3896
+ var span = old[i], marker = span.marker;
3897
+ var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
3898
+ if (endsAfter || marker.type == "bookmark" && span.from == endCh && (!isInsert || span.marker.insertLeft)) {
3899
+ var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
3900
+ (nw || (nw = [])).push({from: startsBefore ? null : span.from - endCh,
3901
+ to: span.to == null ? null : span.to - endCh,
3902
+ marker: marker});
3903
+ }
3904
+ }
3905
+ return nw;
3906
+ }
3907
+
3908
+ function stretchSpansOverChange(doc, change) {
3909
+ var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
3910
+ var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
3911
+ if (!oldFirst && !oldLast) return null;
3912
+
3913
+ var startCh = change.from.ch, endCh = change.to.ch, isInsert = posEq(change.from, change.to);
3914
+ // Get the spans that 'stick out' on both sides
3915
+ var first = markedSpansBefore(oldFirst, startCh, isInsert);
3916
+ var last = markedSpansAfter(oldLast, endCh, isInsert);
3917
+
3918
+ // Next, merge those two ends
3919
+ var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
3920
+ if (first) {
3921
+ // Fix up .to properties of first
3922
+ for (var i = 0; i < first.length; ++i) {
3923
+ var span = first[i];
3924
+ if (span.to == null) {
3925
+ var found = getMarkedSpanFor(last, span.marker);
3926
+ if (!found) span.to = startCh;
3927
+ else if (sameLine) span.to = found.to == null ? null : found.to + offset;
3928
+ }
3929
+ }
3930
+ }
3931
+ if (last) {
3932
+ // Fix up .from in last (or move them into first in case of sameLine)
3933
+ for (var i = 0; i < last.length; ++i) {
3934
+ var span = last[i];
3935
+ if (span.to != null) span.to += offset;
3936
+ if (span.from == null) {
3937
+ var found = getMarkedSpanFor(first, span.marker);
3938
+ if (!found) {
3939
+ span.from = offset;
3940
+ if (sameLine) (first || (first = [])).push(span);
3941
+ }
3942
+ } else {
3943
+ span.from += offset;
3944
+ if (sameLine) (first || (first = [])).push(span);
3945
+ }
3946
+ }
3947
+ }
3948
+ if (sameLine && first) {
3949
+ // Make sure we didn't create any zero-length spans
3950
+ for (var i = 0; i < first.length; ++i)
3951
+ if (first[i].from != null && first[i].from == first[i].to && first[i].marker.type != "bookmark")
3952
+ first.splice(i--, 1);
3953
+ if (!first.length) first = null;
3954
+ }
3955
+
3956
+ var newMarkers = [first];
3957
+ if (!sameLine) {
3958
+ // Fill gap with whole-line-spans
3959
+ var gap = change.text.length - 2, gapMarkers;
3960
+ if (gap > 0 && first)
3961
+ for (var i = 0; i < first.length; ++i)
3962
+ if (first[i].to == null)
3963
+ (gapMarkers || (gapMarkers = [])).push({from: null, to: null, marker: first[i].marker});
3964
+ for (var i = 0; i < gap; ++i)
3965
+ newMarkers.push(gapMarkers);
3966
+ newMarkers.push(last);
3967
+ }
3968
+ return newMarkers;
3969
+ }
3970
+
3971
+ function mergeOldSpans(doc, change) {
3972
+ var old = getOldSpans(doc, change);
3973
+ var stretched = stretchSpansOverChange(doc, change);
3974
+ if (!old) return stretched;
3975
+ if (!stretched) return old;
3976
+
3977
+ for (var i = 0; i < old.length; ++i) {
3978
+ var oldCur = old[i], stretchCur = stretched[i];
3979
+ if (oldCur && stretchCur) {
3980
+ spans: for (var j = 0; j < stretchCur.length; ++j) {
3981
+ var span = stretchCur[j];
3982
+ for (var k = 0; k < oldCur.length; ++k)
3983
+ if (oldCur[k].marker == span.marker) continue spans;
3984
+ oldCur.push(span);
3985
+ }
3986
+ } else if (stretchCur) {
3987
+ old[i] = stretchCur;
3988
+ }
3989
+ }
3990
+ return old;
3991
+ }
3992
+
3993
+ function removeReadOnlyRanges(doc, from, to) {
3994
+ var markers = null;
3995
+ doc.iter(from.line, to.line + 1, function(line) {
3996
+ if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
3997
+ var mark = line.markedSpans[i].marker;
3998
+ if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
3999
+ (markers || (markers = [])).push(mark);
4000
+ }
4001
+ });
4002
+ if (!markers) return null;
4003
+ var parts = [{from: from, to: to}];
4004
+ for (var i = 0; i < markers.length; ++i) {
4005
+ var mk = markers[i], m = mk.find();
4006
+ for (var j = 0; j < parts.length; ++j) {
4007
+ var p = parts[j];
4008
+ if (posLess(p.to, m.from) || posLess(m.to, p.from)) continue;
4009
+ var newParts = [j, 1];
4010
+ if (posLess(p.from, m.from) || !mk.inclusiveLeft && posEq(p.from, m.from))
4011
+ newParts.push({from: p.from, to: m.from});
4012
+ if (posLess(m.to, p.to) || !mk.inclusiveRight && posEq(p.to, m.to))
4013
+ newParts.push({from: m.to, to: p.to});
4014
+ parts.splice.apply(parts, newParts);
4015
+ j += newParts.length - 1;
4016
+ }
4017
+ }
4018
+ return parts;
4019
+ }
4020
+
4021
+ function collapsedSpanAt(line, ch) {
4022
+ var sps = sawCollapsedSpans && line.markedSpans, found;
4023
+ if (sps) for (var sp, i = 0; i < sps.length; ++i) {
4024
+ sp = sps[i];
4025
+ if (!sp.marker.collapsed) continue;
4026
+ if ((sp.from == null || sp.from < ch) &&
4027
+ (sp.to == null || sp.to > ch) &&
4028
+ (!found || found.width < sp.marker.width))
4029
+ found = sp.marker;
4030
+ }
4031
+ return found;
4032
+ }
4033
+ function collapsedSpanAtStart(line) { return collapsedSpanAt(line, -1); }
4034
+ function collapsedSpanAtEnd(line) { return collapsedSpanAt(line, line.text.length + 1); }
4035
+
4036
+ function visualLine(doc, line) {
4037
+ var merged;
4038
+ while (merged = collapsedSpanAtStart(line))
4039
+ line = getLine(doc, merged.find().from.line);
4040
+ return line;
4041
+ }
4042
+
4043
+ function lineIsHidden(doc, line) {
4044
+ var sps = sawCollapsedSpans && line.markedSpans;
4045
+ if (sps) for (var sp, i = 0; i < sps.length; ++i) {
4046
+ sp = sps[i];
4047
+ if (!sp.marker.collapsed) continue;
4048
+ if (sp.from == null) return true;
4049
+ if (sp.marker.replacedWith) continue;
4050
+ if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
4051
+ return true;
4052
+ }
4053
+ }
4054
+ function lineIsHiddenInner(doc, line, span) {
4055
+ if (span.to == null) {
4056
+ var end = span.marker.find().to, endLine = getLine(doc, end.line);
4057
+ return lineIsHiddenInner(doc, endLine, getMarkedSpanFor(endLine.markedSpans, span.marker));
4058
+ }
4059
+ if (span.marker.inclusiveRight && span.to == line.text.length)
4060
+ return true;
4061
+ for (var sp, i = 0; i < line.markedSpans.length; ++i) {
4062
+ sp = line.markedSpans[i];
4063
+ if (sp.marker.collapsed && !sp.marker.replacedWith && sp.from == span.to &&
4064
+ (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
4065
+ lineIsHiddenInner(doc, line, sp)) return true;
4066
+ }
4067
+ }
4068
+
4069
+ function detachMarkedSpans(line) {
4070
+ var spans = line.markedSpans;
4071
+ if (!spans) return;
4072
+ for (var i = 0; i < spans.length; ++i)
4073
+ spans[i].marker.detachLine(line);
4074
+ line.markedSpans = null;
4075
+ }
4076
+
4077
+ function attachMarkedSpans(line, spans) {
4078
+ if (!spans) return;
4079
+ for (var i = 0; i < spans.length; ++i)
4080
+ spans[i].marker.attachLine(line);
4081
+ line.markedSpans = spans;
4082
+ }
4083
+
4084
+ // LINE WIDGETS
4085
+
4086
+ var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {
4087
+ if (options) for (var opt in options) if (options.hasOwnProperty(opt))
4088
+ this[opt] = options[opt];
4089
+ this.cm = cm;
4090
+ this.node = node;
4091
+ };
4092
+ eventMixin(LineWidget);
4093
+ function widgetOperation(f) {
4094
+ return function() {
4095
+ var withOp = !this.cm.curOp;
4096
+ if (withOp) startOperation(this.cm);
4097
+ try {var result = f.apply(this, arguments);}
4098
+ finally {if (withOp) endOperation(this.cm);}
4099
+ return result;
4100
+ };
4101
+ }
4102
+ LineWidget.prototype.clear = widgetOperation(function() {
4103
+ var ws = this.line.widgets, no = lineNo(this.line);
4104
+ if (no == null || !ws) return;
4105
+ for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
4106
+ if (!ws.length) this.line.widgets = null;
4107
+ var aboveVisible = heightAtLine(this.cm, this.line) < this.cm.doc.scrollTop;
4108
+ updateLineHeight(this.line, Math.max(0, this.line.height - widgetHeight(this)));
4109
+ if (aboveVisible) addToScrollPos(this.cm, 0, -this.height);
4110
+ regChange(this.cm, no, no + 1);
4111
+ });
4112
+ LineWidget.prototype.changed = widgetOperation(function() {
4113
+ var oldH = this.height;
4114
+ this.height = null;
4115
+ var diff = widgetHeight(this) - oldH;
4116
+ if (!diff) return;
4117
+ updateLineHeight(this.line, this.line.height + diff);
4118
+ var no = lineNo(this.line);
4119
+ regChange(this.cm, no, no + 1);
4120
+ });
4121
+
4122
+ function widgetHeight(widget) {
4123
+ if (widget.height != null) return widget.height;
4124
+ if (!widget.node.parentNode || widget.node.parentNode.nodeType != 1)
4125
+ removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative"));
4126
+ return widget.height = widget.node.offsetHeight;
4127
+ }
4128
+
4129
+ function addLineWidget(cm, handle, node, options) {
4130
+ var widget = new LineWidget(cm, node, options);
4131
+ if (widget.noHScroll) cm.display.alignWidgets = true;
4132
+ changeLine(cm, handle, function(line) {
4133
+ var widgets = line.widgets || (line.widgets = []);
4134
+ if (widget.insertAt == null) widgets.push(widget);
4135
+ else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
4136
+ widget.line = line;
4137
+ if (!lineIsHidden(cm.doc, line) || widget.showIfHidden) {
4138
+ var aboveVisible = heightAtLine(cm, line) < cm.doc.scrollTop;
4139
+ updateLineHeight(line, line.height + widgetHeight(widget));
4140
+ if (aboveVisible) addToScrollPos(cm, 0, widget.height);
4141
+ }
4142
+ return true;
4143
+ });
4144
+ return widget;
4145
+ }
4146
+
4147
+ // LINE DATA STRUCTURE
4148
+
4149
+ // Line objects. These hold state related to a line, including
4150
+ // highlighting info (the styles array).
4151
+ var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
4152
+ this.text = text;
4153
+ attachMarkedSpans(this, markedSpans);
4154
+ this.height = estimateHeight ? estimateHeight(this) : 1;
4155
+ };
4156
+ eventMixin(Line);
4157
+
4158
+ function updateLine(line, text, markedSpans, estimateHeight) {
4159
+ line.text = text;
4160
+ if (line.stateAfter) line.stateAfter = null;
4161
+ if (line.styles) line.styles = null;
4162
+ if (line.order != null) line.order = null;
4163
+ detachMarkedSpans(line);
4164
+ attachMarkedSpans(line, markedSpans);
4165
+ var estHeight = estimateHeight ? estimateHeight(line) : 1;
4166
+ if (estHeight != line.height) updateLineHeight(line, estHeight);
4167
+ }
4168
+
4169
+ function cleanUpLine(line) {
4170
+ line.parent = null;
4171
+ detachMarkedSpans(line);
4172
+ }
4173
+
4174
+ // Run the given mode's parser over a line, update the styles
4175
+ // array, which contains alternating fragments of text and CSS
4176
+ // classes.
4177
+ function runMode(cm, text, mode, state, f) {
4178
+ var flattenSpans = mode.flattenSpans;
4179
+ if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
4180
+ var curStart = 0, curStyle = null;
4181
+ var stream = new StringStream(text, cm.options.tabSize), style;
4182
+ if (text == "" && mode.blankLine) mode.blankLine(state);
4183
+ while (!stream.eol()) {
4184
+ if (stream.pos > cm.options.maxHighlightLength) {
4185
+ flattenSpans = false;
4186
+ // Webkit seems to refuse to render text nodes longer than 57444 characters
4187
+ stream.pos = Math.min(text.length, stream.start + 50000);
4188
+ style = null;
4189
+ } else {
4190
+ style = mode.token(stream, state);
4191
+ }
4192
+ if (!flattenSpans || curStyle != style) {
4193
+ if (curStart < stream.start) f(stream.start, curStyle);
4194
+ curStart = stream.start; curStyle = style;
4195
+ }
4196
+ stream.start = stream.pos;
4197
+ }
4198
+ if (curStart < stream.pos) f(stream.pos, curStyle);
4199
+ }
4200
+
4201
+ function highlightLine(cm, line, state) {
4202
+ // A styles array always starts with a number identifying the
4203
+ // mode/overlays that it is based on (for easy invalidation).
4204
+ var st = [cm.state.modeGen];
4205
+ // Compute the base array of styles
4206
+ runMode(cm, line.text, cm.doc.mode, state, function(end, style) {st.push(end, style);});
4207
+
4208
+ // Run overlays, adjust style array.
4209
+ for (var o = 0; o < cm.state.overlays.length; ++o) {
4210
+ var overlay = cm.state.overlays[o], i = 1, at = 0;
4211
+ runMode(cm, line.text, overlay.mode, true, function(end, style) {
4212
+ var start = i;
4213
+ // Ensure there's a token end at the current position, and that i points at it
4214
+ while (at < end) {
4215
+ var i_end = st[i];
4216
+ if (i_end > end)
4217
+ st.splice(i, 1, end, st[i+1], i_end);
4218
+ i += 2;
4219
+ at = Math.min(end, i_end);
4220
+ }
4221
+ if (!style) return;
4222
+ if (overlay.opaque) {
4223
+ st.splice(start, i - start, end, style);
4224
+ i = start + 2;
4225
+ } else {
4226
+ for (; start < i; start += 2) {
4227
+ var cur = st[start+1];
4228
+ st[start+1] = cur ? cur + " " + style : style;
4229
+ }
4230
+ }
4231
+ });
4232
+ }
4233
+
4234
+ return st;
4235
+ }
4236
+
4237
+ function getLineStyles(cm, line) {
4238
+ if (!line.styles || line.styles[0] != cm.state.modeGen)
4239
+ line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
4240
+ return line.styles;
4241
+ }
4242
+
4243
+ // Lightweight form of highlight -- proceed over this line and
4244
+ // update state, but don't save a style array.
4245
+ function processLine(cm, line, state) {
4246
+ var mode = cm.doc.mode;
4247
+ var stream = new StringStream(line.text, cm.options.tabSize);
4248
+ if (line.text == "" && mode.blankLine) mode.blankLine(state);
4249
+ while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
4250
+ mode.token(stream, state);
4251
+ stream.start = stream.pos;
4252
+ }
4253
+ }
4254
+
4255
+ var styleToClassCache = {};
4256
+ function styleToClass(style) {
4257
+ if (!style) return null;
4258
+ return styleToClassCache[style] ||
4259
+ (styleToClassCache[style] = "cm-" + style.replace(/ +/g, " cm-"));
4260
+ }
4261
+
4262
+ function lineContent(cm, realLine, measure, copyWidgets) {
4263
+ var merged, line = realLine, empty = true;
4264
+ while (merged = collapsedSpanAtStart(line))
4265
+ line = getLine(cm.doc, merged.find().from.line);
4266
+
4267
+ var builder = {pre: elt("pre"), col: 0, pos: 0,
4268
+ measure: null, measuredSomething: false, cm: cm,
4269
+ copyWidgets: copyWidgets};
4270
+ if (line.textClass) builder.pre.className = line.textClass;
4271
+
4272
+ do {
4273
+ if (line.text) empty = false;
4274
+ builder.measure = line == realLine && measure;
4275
+ builder.pos = 0;
4276
+ builder.addToken = builder.measure ? buildTokenMeasure : buildToken;
4277
+ if ((ie || webkit) && cm.getOption("lineWrapping"))
4278
+ builder.addToken = buildTokenSplitSpaces(builder.addToken);
4279
+ var next = insertLineContent(line, builder, getLineStyles(cm, line));
4280
+ if (measure && line == realLine && !builder.measuredSomething) {
4281
+ measure[0] = builder.pre.appendChild(zeroWidthElement(cm.display.measure));
4282
+ builder.measuredSomething = true;
4283
+ }
4284
+ if (next) line = getLine(cm.doc, next.to.line);
4285
+ } while (next);
4286
+
4287
+ if (measure && !builder.measuredSomething && !measure[0])
4288
+ measure[0] = builder.pre.appendChild(empty ? elt("span", "\u00a0") : zeroWidthElement(cm.display.measure));
4289
+ if (!builder.pre.firstChild && !lineIsHidden(cm.doc, realLine))
4290
+ builder.pre.appendChild(document.createTextNode("\u00a0"));
4291
+
4292
+ var order;
4293
+ // Work around problem with the reported dimensions of single-char
4294
+ // direction spans on IE (issue #1129). See also the comment in
4295
+ // cursorCoords.
4296
+ if (measure && ie && (order = getOrder(line))) {
4297
+ var l = order.length - 1;
4298
+ if (order[l].from == order[l].to) --l;
4299
+ var last = order[l], prev = order[l - 1];
4300
+ if (last.from + 1 == last.to && prev && last.level < prev.level) {
4301
+ var span = measure[builder.pos - 1];
4302
+ if (span) span.parentNode.insertBefore(span.measureRight = zeroWidthElement(cm.display.measure),
4303
+ span.nextSibling);
4304
+ }
4305
+ }
4306
+
4307
+ signal(cm, "renderLine", cm, realLine, builder.pre);
4308
+ return builder.pre;
4309
+ }
4310
+
4311
+ var tokenSpecialChars = /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\uFEFF]/g;
4312
+ function buildToken(builder, text, style, startStyle, endStyle, title) {
4313
+ if (!text) return;
4314
+ if (!tokenSpecialChars.test(text)) {
4315
+ builder.col += text.length;
4316
+ var content = document.createTextNode(text);
4317
+ } else {
4318
+ var content = document.createDocumentFragment(), pos = 0;
4319
+ while (true) {
4320
+ tokenSpecialChars.lastIndex = pos;
4321
+ var m = tokenSpecialChars.exec(text);
4322
+ var skipped = m ? m.index - pos : text.length - pos;
4323
+ if (skipped) {
4324
+ content.appendChild(document.createTextNode(text.slice(pos, pos + skipped)));
4325
+ builder.col += skipped;
4326
+ }
4327
+ if (!m) break;
4328
+ pos += skipped + 1;
4329
+ if (m[0] == "\t") {
4330
+ var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
4331
+ content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
4332
+ builder.col += tabWidth;
4333
+ } else {
4334
+ var token = elt("span", "\u2022", "cm-invalidchar");
4335
+ token.title = "\\u" + m[0].charCodeAt(0).toString(16);
4336
+ content.appendChild(token);
4337
+ builder.col += 1;
4338
+ }
4339
+ }
4340
+ }
4341
+ if (style || startStyle || endStyle || builder.measure) {
4342
+ var fullStyle = style || "";
4343
+ if (startStyle) fullStyle += startStyle;
4344
+ if (endStyle) fullStyle += endStyle;
4345
+ var token = elt("span", [content], fullStyle);
4346
+ if (title) token.title = title;
4347
+ return builder.pre.appendChild(token);
4348
+ }
4349
+ builder.pre.appendChild(content);
4350
+ }
4351
+
4352
+ function buildTokenMeasure(builder, text, style, startStyle, endStyle) {
4353
+ var wrapping = builder.cm.options.lineWrapping;
4354
+ for (var i = 0; i < text.length; ++i) {
4355
+ var ch = text.charAt(i), start = i == 0;
4356
+ if (ch >= "\ud800" && ch < "\udbff" && i < text.length - 1) {
4357
+ ch = text.slice(i, i + 2);
4358
+ ++i;
4359
+ } else if (i && wrapping && spanAffectsWrapping(text, i)) {
4360
+ builder.pre.appendChild(elt("wbr"));
4361
+ }
4362
+ var old = builder.measure[builder.pos];
4363
+ var span = builder.measure[builder.pos] =
4364
+ buildToken(builder, ch, style,
4365
+ start && startStyle, i == text.length - 1 && endStyle);
4366
+ if (old) span.leftSide = old.leftSide || old;
4367
+ // In IE single-space nodes wrap differently than spaces
4368
+ // embedded in larger text nodes, except when set to
4369
+ // white-space: normal (issue #1268).
4370
+ if (ie && wrapping && ch == " " && i && !/\s/.test(text.charAt(i - 1)) &&
4371
+ i < text.length - 1 && !/\s/.test(text.charAt(i + 1)))
4372
+ span.style.whiteSpace = "normal";
4373
+ builder.pos += ch.length;
4374
+ }
4375
+ if (text.length) builder.measuredSomething = true;
4376
+ }
4377
+
4378
+ function buildTokenSplitSpaces(inner) {
4379
+ function split(old) {
4380
+ var out = " ";
4381
+ for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
4382
+ out += " ";
4383
+ return out;
4384
+ }
4385
+ return function(builder, text, style, startStyle, endStyle, title) {
4386
+ return inner(builder, text.replace(/ {3,}/, split), style, startStyle, endStyle, title);
4387
+ };
4388
+ }
4389
+
4390
+ function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
4391
+ var widget = !ignoreWidget && marker.replacedWith;
4392
+ if (widget) {
4393
+ if (builder.copyWidgets) widget = widget.cloneNode(true);
4394
+ builder.pre.appendChild(widget);
4395
+ if (builder.measure) {
4396
+ if (size) {
4397
+ builder.measure[builder.pos] = widget;
4398
+ } else {
4399
+ var elt = builder.measure[builder.pos] = zeroWidthElement(builder.cm.display.measure);
4400
+ if (marker.type != "bookmark" || marker.insertLeft)
4401
+ builder.pre.insertBefore(elt, widget);
4402
+ else
4403
+ builder.pre.appendChild(elt);
4404
+ }
4405
+ builder.measuredSomething = true;
4406
+ }
4407
+ }
4408
+ builder.pos += size;
4409
+ }
4410
+
4411
+ // Outputs a number of spans to make up a line, taking highlighting
4412
+ // and marked text into account.
4413
+ function insertLineContent(line, builder, styles) {
4414
+ var spans = line.markedSpans, allText = line.text, at = 0;
4415
+ if (!spans) {
4416
+ for (var i = 1; i < styles.length; i+=2)
4417
+ builder.addToken(builder, allText.slice(at, at = styles[i]), styleToClass(styles[i+1]));
4418
+ return;
4419
+ }
4420
+
4421
+ var len = allText.length, pos = 0, i = 1, text = "", style;
4422
+ var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
4423
+ for (;;) {
4424
+ if (nextChange == pos) { // Update current marker set
4425
+ spanStyle = spanEndStyle = spanStartStyle = title = "";
4426
+ collapsed = null; nextChange = Infinity;
4427
+ var foundBookmark = null;
4428
+ for (var j = 0; j < spans.length; ++j) {
4429
+ var sp = spans[j], m = sp.marker;
4430
+ if (sp.from <= pos && (sp.to == null || sp.to > pos)) {
4431
+ if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; }
4432
+ if (m.className) spanStyle += " " + m.className;
4433
+ if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
4434
+ if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
4435
+ if (m.title && !title) title = m.title;
4436
+ if (m.collapsed && (!collapsed || collapsed.marker.size < m.size))
4437
+ collapsed = sp;
4438
+ } else if (sp.from > pos && nextChange > sp.from) {
4439
+ nextChange = sp.from;
4440
+ }
4441
+ if (m.type == "bookmark" && sp.from == pos && m.replacedWith) foundBookmark = m;
4442
+ }
4443
+ if (collapsed && (collapsed.from || 0) == pos) {
4444
+ buildCollapsedSpan(builder, (collapsed.to == null ? len : collapsed.to) - pos,
4445
+ collapsed.marker, collapsed.from == null);
4446
+ if (collapsed.to == null) return collapsed.marker.find();
4447
+ }
4448
+ if (foundBookmark && !collapsed) buildCollapsedSpan(builder, 0, foundBookmark);
4449
+ }
4450
+ if (pos >= len) break;
4451
+
4452
+ var upto = Math.min(len, nextChange);
4453
+ while (true) {
4454
+ if (text) {
4455
+ var end = pos + text.length;
4456
+ if (!collapsed) {
4457
+ var tokenText = end > upto ? text.slice(0, upto - pos) : text;
4458
+ builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
4459
+ spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title);
4460
+ }
4461
+ if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
4462
+ pos = end;
4463
+ spanStartStyle = "";
4464
+ }
4465
+ text = allText.slice(at, at = styles[i++]);
4466
+ style = styleToClass(styles[i++]);
4467
+ }
4468
+ }
4469
+ }
4470
+
4471
+ // DOCUMENT DATA STRUCTURE
4472
+
4473
+ function updateDoc(doc, change, markedSpans, selAfter, estimateHeight) {
4474
+ function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
4475
+ function update(line, text, spans) {
4476
+ updateLine(line, text, spans, estimateHeight);
4477
+ signalLater(line, "change", line, change);
4478
+ }
4479
+
4480
+ var from = change.from, to = change.to, text = change.text;
4481
+ var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
4482
+ var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
4483
+
4484
+ // First adjust the line structure
4485
+ if (from.ch == 0 && to.ch == 0 && lastText == "") {
4486
+ // This is a whole-line replace. Treated specially to make
4487
+ // sure line objects move the way they are supposed to.
4488
+ for (var i = 0, e = text.length - 1, added = []; i < e; ++i)
4489
+ added.push(new Line(text[i], spansFor(i), estimateHeight));
4490
+ update(lastLine, lastLine.text, lastSpans);
4491
+ if (nlines) doc.remove(from.line, nlines);
4492
+ if (added.length) doc.insert(from.line, added);
4493
+ } else if (firstLine == lastLine) {
4494
+ if (text.length == 1) {
4495
+ update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
4496
+ } else {
4497
+ for (var added = [], i = 1, e = text.length - 1; i < e; ++i)
4498
+ added.push(new Line(text[i], spansFor(i), estimateHeight));
4499
+ added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
4500
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
4501
+ doc.insert(from.line + 1, added);
4502
+ }
4503
+ } else if (text.length == 1) {
4504
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
4505
+ doc.remove(from.line + 1, nlines);
4506
+ } else {
4507
+ update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
4508
+ update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
4509
+ for (var i = 1, e = text.length - 1, added = []; i < e; ++i)
4510
+ added.push(new Line(text[i], spansFor(i), estimateHeight));
4511
+ if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
4512
+ doc.insert(from.line + 1, added);
4513
+ }
4514
+
4515
+ signalLater(doc, "change", doc, change);
4516
+ setSelection(doc, selAfter.anchor, selAfter.head, null, true);
4517
+ }
4518
+
4519
+ function LeafChunk(lines) {
4520
+ this.lines = lines;
4521
+ this.parent = null;
4522
+ for (var i = 0, e = lines.length, height = 0; i < e; ++i) {
4523
+ lines[i].parent = this;
4524
+ height += lines[i].height;
4525
+ }
4526
+ this.height = height;
4527
+ }
4528
+
4529
+ LeafChunk.prototype = {
4530
+ chunkSize: function() { return this.lines.length; },
4531
+ removeInner: function(at, n) {
4532
+ for (var i = at, e = at + n; i < e; ++i) {
4533
+ var line = this.lines[i];
4534
+ this.height -= line.height;
4535
+ cleanUpLine(line);
4536
+ signalLater(line, "delete");
4537
+ }
4538
+ this.lines.splice(at, n);
4539
+ },
4540
+ collapse: function(lines) {
4541
+ lines.splice.apply(lines, [lines.length, 0].concat(this.lines));
4542
+ },
4543
+ insertInner: function(at, lines, height) {
4544
+ this.height += height;
4545
+ this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
4546
+ for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;
4547
+ },
4548
+ iterN: function(at, n, op) {
4549
+ for (var e = at + n; at < e; ++at)
4550
+ if (op(this.lines[at])) return true;
4551
+ }
4552
+ };
4553
+
4554
+ function BranchChunk(children) {
4555
+ this.children = children;
4556
+ var size = 0, height = 0;
4557
+ for (var i = 0, e = children.length; i < e; ++i) {
4558
+ var ch = children[i];
4559
+ size += ch.chunkSize(); height += ch.height;
4560
+ ch.parent = this;
4561
+ }
4562
+ this.size = size;
4563
+ this.height = height;
4564
+ this.parent = null;
4565
+ }
4566
+
4567
+ BranchChunk.prototype = {
4568
+ chunkSize: function() { return this.size; },
4569
+ removeInner: function(at, n) {
4570
+ this.size -= n;
4571
+ for (var i = 0; i < this.children.length; ++i) {
4572
+ var child = this.children[i], sz = child.chunkSize();
4573
+ if (at < sz) {
4574
+ var rm = Math.min(n, sz - at), oldHeight = child.height;
4575
+ child.removeInner(at, rm);
4576
+ this.height -= oldHeight - child.height;
4577
+ if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
4578
+ if ((n -= rm) == 0) break;
4579
+ at = 0;
4580
+ } else at -= sz;
4581
+ }
4582
+ if (this.size - n < 25) {
4583
+ var lines = [];
4584
+ this.collapse(lines);
4585
+ this.children = [new LeafChunk(lines)];
4586
+ this.children[0].parent = this;
4587
+ }
4588
+ },
4589
+ collapse: function(lines) {
4590
+ for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);
4591
+ },
4592
+ insertInner: function(at, lines, height) {
4593
+ this.size += lines.length;
4594
+ this.height += height;
4595
+ for (var i = 0, e = this.children.length; i < e; ++i) {
4596
+ var child = this.children[i], sz = child.chunkSize();
4597
+ if (at <= sz) {
4598
+ child.insertInner(at, lines, height);
4599
+ if (child.lines && child.lines.length > 50) {
4600
+ while (child.lines.length > 50) {
4601
+ var spilled = child.lines.splice(child.lines.length - 25, 25);
4602
+ var newleaf = new LeafChunk(spilled);
4603
+ child.height -= newleaf.height;
4604
+ this.children.splice(i + 1, 0, newleaf);
4605
+ newleaf.parent = this;
4606
+ }
4607
+ this.maybeSpill();
4608
+ }
4609
+ break;
4610
+ }
4611
+ at -= sz;
4612
+ }
4613
+ },
4614
+ maybeSpill: function() {
4615
+ if (this.children.length <= 10) return;
4616
+ var me = this;
4617
+ do {
4618
+ var spilled = me.children.splice(me.children.length - 5, 5);
4619
+ var sibling = new BranchChunk(spilled);
4620
+ if (!me.parent) { // Become the parent node
4621
+ var copy = new BranchChunk(me.children);
4622
+ copy.parent = me;
4623
+ me.children = [copy, sibling];
4624
+ me = copy;
4625
+ } else {
4626
+ me.size -= sibling.size;
4627
+ me.height -= sibling.height;
4628
+ var myIndex = indexOf(me.parent.children, me);
4629
+ me.parent.children.splice(myIndex + 1, 0, sibling);
4630
+ }
4631
+ sibling.parent = me.parent;
4632
+ } while (me.children.length > 10);
4633
+ me.parent.maybeSpill();
4634
+ },
4635
+ iterN: function(at, n, op) {
4636
+ for (var i = 0, e = this.children.length; i < e; ++i) {
4637
+ var child = this.children[i], sz = child.chunkSize();
4638
+ if (at < sz) {
4639
+ var used = Math.min(n, sz - at);
4640
+ if (child.iterN(at, used, op)) return true;
4641
+ if ((n -= used) == 0) break;
4642
+ at = 0;
4643
+ } else at -= sz;
4644
+ }
4645
+ }
4646
+ };
4647
+
4648
+ var nextDocId = 0;
4649
+ var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
4650
+ if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
4651
+ if (firstLine == null) firstLine = 0;
4652
+
4653
+ BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
4654
+ this.first = firstLine;
4655
+ this.scrollTop = this.scrollLeft = 0;
4656
+ this.cantEdit = false;
4657
+ this.history = makeHistory();
4658
+ this.cleanGeneration = 1;
4659
+ this.frontier = firstLine;
4660
+ var start = Pos(firstLine, 0);
4661
+ this.sel = {from: start, to: start, head: start, anchor: start, shift: false, extend: false, goalColumn: null};
4662
+ this.id = ++nextDocId;
4663
+ this.modeOption = mode;
4664
+
4665
+ if (typeof text == "string") text = splitLines(text);
4666
+ updateDoc(this, {from: start, to: start, text: text}, null, {head: start, anchor: start});
4667
+ };
4668
+
4669
+ Doc.prototype = createObj(BranchChunk.prototype, {
4670
+ constructor: Doc,
4671
+ iter: function(from, to, op) {
4672
+ if (op) this.iterN(from - this.first, to - from, op);
4673
+ else this.iterN(this.first, this.first + this.size, from);
4674
+ },
4675
+
4676
+ insert: function(at, lines) {
4677
+ var height = 0;
4678
+ for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;
4679
+ this.insertInner(at - this.first, lines, height);
4680
+ },
4681
+ remove: function(at, n) { this.removeInner(at - this.first, n); },
4682
+
4683
+ getValue: function(lineSep) {
4684
+ var lines = getLines(this, this.first, this.first + this.size);
4685
+ if (lineSep === false) return lines;
4686
+ return lines.join(lineSep || "\n");
4687
+ },
4688
+ setValue: function(code) {
4689
+ var top = Pos(this.first, 0), last = this.first + this.size - 1;
4690
+ makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
4691
+ text: splitLines(code), origin: "setValue"},
4692
+ {head: top, anchor: top}, true);
4693
+ },
4694
+ replaceRange: function(code, from, to, origin) {
4695
+ from = clipPos(this, from);
4696
+ to = to ? clipPos(this, to) : from;
4697
+ replaceRange(this, code, from, to, origin);
4698
+ },
4699
+ getRange: function(from, to, lineSep) {
4700
+ var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
4701
+ if (lineSep === false) return lines;
4702
+ return lines.join(lineSep || "\n");
4703
+ },
4704
+
4705
+ getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
4706
+ setLine: function(line, text) {
4707
+ if (isLine(this, line))
4708
+ replaceRange(this, text, Pos(line, 0), clipPos(this, Pos(line)));
4709
+ },
4710
+ removeLine: function(line) {
4711
+ if (line) replaceRange(this, "", clipPos(this, Pos(line - 1)), clipPos(this, Pos(line)));
4712
+ else replaceRange(this, "", Pos(0, 0), clipPos(this, Pos(1, 0)));
4713
+ },
4714
+
4715
+ getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
4716
+ getLineNumber: function(line) {return lineNo(line);},
4717
+
4718
+ getLineHandleVisualStart: function(line) {
4719
+ if (typeof line == "number") line = getLine(this, line);
4720
+ return visualLine(this, line);
4721
+ },
4722
+
4723
+ lineCount: function() {return this.size;},
4724
+ firstLine: function() {return this.first;},
4725
+ lastLine: function() {return this.first + this.size - 1;},
4726
+
4727
+ clipPos: function(pos) {return clipPos(this, pos);},
4728
+
4729
+ getCursor: function(start) {
4730
+ var sel = this.sel, pos;
4731
+ if (start == null || start == "head") pos = sel.head;
4732
+ else if (start == "anchor") pos = sel.anchor;
4733
+ else if (start == "end" || start === false) pos = sel.to;
4734
+ else pos = sel.from;
4735
+ return copyPos(pos);
4736
+ },
4737
+ somethingSelected: function() {return !posEq(this.sel.head, this.sel.anchor);},
4738
+
4739
+ setCursor: docOperation(function(line, ch, extend) {
4740
+ var pos = clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line);
4741
+ if (extend) extendSelection(this, pos);
4742
+ else setSelection(this, pos, pos);
4743
+ }),
4744
+ setSelection: docOperation(function(anchor, head) {
4745
+ setSelection(this, clipPos(this, anchor), clipPos(this, head || anchor));
4746
+ }),
4747
+ extendSelection: docOperation(function(from, to) {
4748
+ extendSelection(this, clipPos(this, from), to && clipPos(this, to));
4749
+ }),
4750
+
4751
+ getSelection: function(lineSep) {return this.getRange(this.sel.from, this.sel.to, lineSep);},
4752
+ replaceSelection: function(code, collapse, origin) {
4753
+ makeChange(this, {from: this.sel.from, to: this.sel.to, text: splitLines(code), origin: origin}, collapse || "around");
4754
+ },
4755
+ undo: docOperation(function() {makeChangeFromHistory(this, "undo");}),
4756
+ redo: docOperation(function() {makeChangeFromHistory(this, "redo");}),
4757
+
4758
+ setExtending: function(val) {this.sel.extend = val;},
4759
+
4760
+ historySize: function() {
4761
+ var hist = this.history;
4762
+ return {undo: hist.done.length, redo: hist.undone.length};
4763
+ },
4764
+ clearHistory: function() {this.history = makeHistory(this.history.maxGeneration);},
4765
+
4766
+ markClean: function() {
4767
+ this.cleanGeneration = this.changeGeneration();
4768
+ },
4769
+ changeGeneration: function() {
4770
+ this.history.lastOp = this.history.lastOrigin = null;
4771
+ return this.history.generation;
4772
+ },
4773
+ isClean: function (gen) {
4774
+ return this.history.generation == (gen || this.cleanGeneration);
4775
+ },
4776
+
4777
+ getHistory: function() {
4778
+ return {done: copyHistoryArray(this.history.done),
4779
+ undone: copyHistoryArray(this.history.undone)};
4780
+ },
4781
+ setHistory: function(histData) {
4782
+ var hist = this.history = makeHistory(this.history.maxGeneration);
4783
+ hist.done = histData.done.slice(0);
4784
+ hist.undone = histData.undone.slice(0);
4785
+ },
4786
+
4787
+ markText: function(from, to, options) {
4788
+ return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
4789
+ },
4790
+ setBookmark: function(pos, options) {
4791
+ var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
4792
+ insertLeft: options && options.insertLeft};
4793
+ pos = clipPos(this, pos);
4794
+ return markText(this, pos, pos, realOpts, "bookmark");
4795
+ },
4796
+ findMarksAt: function(pos) {
4797
+ pos = clipPos(this, pos);
4798
+ var markers = [], spans = getLine(this, pos.line).markedSpans;
4799
+ if (spans) for (var i = 0; i < spans.length; ++i) {
4800
+ var span = spans[i];
4801
+ if ((span.from == null || span.from <= pos.ch) &&
4802
+ (span.to == null || span.to >= pos.ch))
4803
+ markers.push(span.marker.parent || span.marker);
4804
+ }
4805
+ return markers;
4806
+ },
4807
+ getAllMarks: function() {
4808
+ var markers = [];
4809
+ this.iter(function(line) {
4810
+ var sps = line.markedSpans;
4811
+ if (sps) for (var i = 0; i < sps.length; ++i)
4812
+ if (sps[i].from != null) markers.push(sps[i].marker);
4813
+ });
4814
+ return markers;
4815
+ },
4816
+
4817
+ posFromIndex: function(off) {
4818
+ var ch, lineNo = this.first;
4819
+ this.iter(function(line) {
4820
+ var sz = line.text.length + 1;
4821
+ if (sz > off) { ch = off; return true; }
4822
+ off -= sz;
4823
+ ++lineNo;
4824
+ });
4825
+ return clipPos(this, Pos(lineNo, ch));
4826
+ },
4827
+ indexFromPos: function (coords) {
4828
+ coords = clipPos(this, coords);
4829
+ var index = coords.ch;
4830
+ if (coords.line < this.first || coords.ch < 0) return 0;
4831
+ this.iter(this.first, coords.line, function (line) {
4832
+ index += line.text.length + 1;
4833
+ });
4834
+ return index;
4835
+ },
4836
+
4837
+ copy: function(copyHistory) {
4838
+ var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
4839
+ doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
4840
+ doc.sel = {from: this.sel.from, to: this.sel.to, head: this.sel.head, anchor: this.sel.anchor,
4841
+ shift: this.sel.shift, extend: false, goalColumn: this.sel.goalColumn};
4842
+ if (copyHistory) {
4843
+ doc.history.undoDepth = this.history.undoDepth;
4844
+ doc.setHistory(this.getHistory());
4845
+ }
4846
+ return doc;
4847
+ },
4848
+
4849
+ linkedDoc: function(options) {
4850
+ if (!options) options = {};
4851
+ var from = this.first, to = this.first + this.size;
4852
+ if (options.from != null && options.from > from) from = options.from;
4853
+ if (options.to != null && options.to < to) to = options.to;
4854
+ var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
4855
+ if (options.sharedHist) copy.history = this.history;
4856
+ (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
4857
+ copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
4858
+ return copy;
4859
+ },
4860
+ unlinkDoc: function(other) {
4861
+ if (other instanceof CodeMirror) other = other.doc;
4862
+ if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
4863
+ var link = this.linked[i];
4864
+ if (link.doc != other) continue;
4865
+ this.linked.splice(i, 1);
4866
+ other.unlinkDoc(this);
4867
+ break;
4868
+ }
4869
+ // If the histories were shared, split them again
4870
+ if (other.history == this.history) {
4871
+ var splitIds = [other.id];
4872
+ linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
4873
+ other.history = makeHistory();
4874
+ other.history.done = copyHistoryArray(this.history.done, splitIds);
4875
+ other.history.undone = copyHistoryArray(this.history.undone, splitIds);
4876
+ }
4877
+ },
4878
+ iterLinkedDocs: function(f) {linkedDocs(this, f);},
4879
+
4880
+ getMode: function() {return this.mode;},
4881
+ getEditor: function() {return this.cm;}
4882
+ });
4883
+
4884
+ Doc.prototype.eachLine = Doc.prototype.iter;
4885
+
4886
+ // The Doc methods that should be available on CodeMirror instances
4887
+ var dontDelegate = "iter insert remove copy getEditor".split(" ");
4888
+ for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
4889
+ CodeMirror.prototype[prop] = (function(method) {
4890
+ return function() {return method.apply(this.doc, arguments);};
4891
+ })(Doc.prototype[prop]);
4892
+
4893
+ eventMixin(Doc);
4894
+
4895
+ function linkedDocs(doc, f, sharedHistOnly) {
4896
+ function propagate(doc, skip, sharedHist) {
4897
+ if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
4898
+ var rel = doc.linked[i];
4899
+ if (rel.doc == skip) continue;
4900
+ var shared = sharedHist && rel.sharedHist;
4901
+ if (sharedHistOnly && !shared) continue;
4902
+ f(rel.doc, shared);
4903
+ propagate(rel.doc, doc, shared);
4904
+ }
4905
+ }
4906
+ propagate(doc, null, true);
4907
+ }
4908
+
4909
+ function attachDoc(cm, doc) {
4910
+ if (doc.cm) throw new Error("This document is already in use.");
4911
+ cm.doc = doc;
4912
+ doc.cm = cm;
4913
+ estimateLineHeights(cm);
4914
+ loadMode(cm);
4915
+ if (!cm.options.lineWrapping) computeMaxLength(cm);
4916
+ cm.options.mode = doc.modeOption;
4917
+ regChange(cm);
4918
+ }
4919
+
4920
+ // LINE UTILITIES
4921
+
4922
+ function getLine(chunk, n) {
4923
+ n -= chunk.first;
4924
+ while (!chunk.lines) {
4925
+ for (var i = 0;; ++i) {
4926
+ var child = chunk.children[i], sz = child.chunkSize();
4927
+ if (n < sz) { chunk = child; break; }
4928
+ n -= sz;
4929
+ }
4930
+ }
4931
+ return chunk.lines[n];
4932
+ }
4933
+
4934
+ function getBetween(doc, start, end) {
4935
+ var out = [], n = start.line;
4936
+ doc.iter(start.line, end.line + 1, function(line) {
4937
+ var text = line.text;
4938
+ if (n == end.line) text = text.slice(0, end.ch);
4939
+ if (n == start.line) text = text.slice(start.ch);
4940
+ out.push(text);
4941
+ ++n;
4942
+ });
4943
+ return out;
4944
+ }
4945
+ function getLines(doc, from, to) {
4946
+ var out = [];
4947
+ doc.iter(from, to, function(line) { out.push(line.text); });
4948
+ return out;
4949
+ }
4950
+
4951
+ function updateLineHeight(line, height) {
4952
+ var diff = height - line.height;
4953
+ for (var n = line; n; n = n.parent) n.height += diff;
4954
+ }
4955
+
4956
+ function lineNo(line) {
4957
+ if (line.parent == null) return null;
4958
+ var cur = line.parent, no = indexOf(cur.lines, line);
4959
+ for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
4960
+ for (var i = 0;; ++i) {
4961
+ if (chunk.children[i] == cur) break;
4962
+ no += chunk.children[i].chunkSize();
4963
+ }
4964
+ }
4965
+ return no + cur.first;
4966
+ }
4967
+
4968
+ function lineAtHeight(chunk, h) {
4969
+ var n = chunk.first;
4970
+ outer: do {
4971
+ for (var i = 0, e = chunk.children.length; i < e; ++i) {
4972
+ var child = chunk.children[i], ch = child.height;
4973
+ if (h < ch) { chunk = child; continue outer; }
4974
+ h -= ch;
4975
+ n += child.chunkSize();
4976
+ }
4977
+ return n;
4978
+ } while (!chunk.lines);
4979
+ for (var i = 0, e = chunk.lines.length; i < e; ++i) {
4980
+ var line = chunk.lines[i], lh = line.height;
4981
+ if (h < lh) break;
4982
+ h -= lh;
4983
+ }
4984
+ return n + i;
4985
+ }
4986
+
4987
+ function heightAtLine(cm, lineObj) {
4988
+ lineObj = visualLine(cm.doc, lineObj);
4989
+
4990
+ var h = 0, chunk = lineObj.parent;
4991
+ for (var i = 0; i < chunk.lines.length; ++i) {
4992
+ var line = chunk.lines[i];
4993
+ if (line == lineObj) break;
4994
+ else h += line.height;
4995
+ }
4996
+ for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
4997
+ for (var i = 0; i < p.children.length; ++i) {
4998
+ var cur = p.children[i];
4999
+ if (cur == chunk) break;
5000
+ else h += cur.height;
5001
+ }
5002
+ }
5003
+ return h;
5004
+ }
5005
+
5006
+ function getOrder(line) {
5007
+ var order = line.order;
5008
+ if (order == null) order = line.order = bidiOrdering(line.text);
5009
+ return order;
5010
+ }
5011
+
5012
+ // HISTORY
5013
+
5014
+ function makeHistory(startGen) {
5015
+ return {
5016
+ // Arrays of history events. Doing something adds an event to
5017
+ // done and clears undo. Undoing moves events from done to
5018
+ // undone, redoing moves them in the other direction.
5019
+ done: [], undone: [], undoDepth: Infinity,
5020
+ // Used to track when changes can be merged into a single undo
5021
+ // event
5022
+ lastTime: 0, lastOp: null, lastOrigin: null,
5023
+ // Used by the isClean() method
5024
+ generation: startGen || 1, maxGeneration: startGen || 1
5025
+ };
5026
+ }
5027
+
5028
+ function attachLocalSpans(doc, change, from, to) {
5029
+ var existing = change["spans_" + doc.id], n = 0;
5030
+ doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
5031
+ if (line.markedSpans)
5032
+ (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
5033
+ ++n;
5034
+ });
5035
+ }
5036
+
5037
+ function historyChangeFromChange(doc, change) {
5038
+ var from = { line: change.from.line, ch: change.from.ch };
5039
+ var histChange = {from: from, to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
5040
+ attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
5041
+ linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
5042
+ return histChange;
5043
+ }
5044
+
5045
+ function addToHistory(doc, change, selAfter, opId) {
5046
+ var hist = doc.history;
5047
+ hist.undone.length = 0;
5048
+ var time = +new Date, cur = lst(hist.done);
5049
+
5050
+ if (cur &&
5051
+ (hist.lastOp == opId ||
5052
+ hist.lastOrigin == change.origin && change.origin &&
5053
+ ((change.origin.charAt(0) == "+" && doc.cm && hist.lastTime > time - doc.cm.options.historyEventDelay) ||
5054
+ change.origin.charAt(0) == "*"))) {
5055
+ // Merge this change into the last event
5056
+ var last = lst(cur.changes);
5057
+ if (posEq(change.from, change.to) && posEq(change.from, last.to)) {
5058
+ // Optimized case for simple insertion -- don't want to add
5059
+ // new changesets for every character typed
5060
+ last.to = changeEnd(change);
5061
+ } else {
5062
+ // Add new sub-event
5063
+ cur.changes.push(historyChangeFromChange(doc, change));
5064
+ }
5065
+ cur.anchorAfter = selAfter.anchor; cur.headAfter = selAfter.head;
5066
+ } else {
5067
+ // Can not be merged, start a new event.
5068
+ cur = {changes: [historyChangeFromChange(doc, change)],
5069
+ generation: hist.generation,
5070
+ anchorBefore: doc.sel.anchor, headBefore: doc.sel.head,
5071
+ anchorAfter: selAfter.anchor, headAfter: selAfter.head};
5072
+ hist.done.push(cur);
5073
+ hist.generation = ++hist.maxGeneration;
5074
+ while (hist.done.length > hist.undoDepth)
5075
+ hist.done.shift();
5076
+ }
5077
+ hist.lastTime = time;
5078
+ hist.lastOp = opId;
5079
+ hist.lastOrigin = change.origin;
5080
+ }
5081
+
5082
+ function removeClearedSpans(spans) {
5083
+ if (!spans) return null;
5084
+ for (var i = 0, out; i < spans.length; ++i) {
5085
+ if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
5086
+ else if (out) out.push(spans[i]);
5087
+ }
5088
+ return !out ? spans : out.length ? out : null;
5089
+ }
5090
+
5091
+ function getOldSpans(doc, change) {
5092
+ var found = change["spans_" + doc.id];
5093
+ if (!found) return null;
5094
+ for (var i = 0, nw = []; i < change.text.length; ++i)
5095
+ nw.push(removeClearedSpans(found[i]));
5096
+ return nw;
5097
+ }
5098
+
5099
+ // Used both to provide a JSON-safe object in .getHistory, and, when
5100
+ // detaching a document, to split the history in two
5101
+ function copyHistoryArray(events, newGroup) {
5102
+ for (var i = 0, copy = []; i < events.length; ++i) {
5103
+ var event = events[i], changes = event.changes, newChanges = [];
5104
+ copy.push({changes: newChanges, anchorBefore: event.anchorBefore, headBefore: event.headBefore,
5105
+ anchorAfter: event.anchorAfter, headAfter: event.headAfter});
5106
+ for (var j = 0; j < changes.length; ++j) {
5107
+ var change = changes[j], m;
5108
+ newChanges.push({from: change.from, to: change.to, text: change.text});
5109
+ if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
5110
+ if (indexOf(newGroup, Number(m[1])) > -1) {
5111
+ lst(newChanges)[prop] = change[prop];
5112
+ delete change[prop];
5113
+ }
5114
+ }
5115
+ }
5116
+ }
5117
+ return copy;
5118
+ }
5119
+
5120
+ // Rebasing/resetting history to deal with externally-sourced changes
5121
+
5122
+ function rebaseHistSel(pos, from, to, diff) {
5123
+ if (to < pos.line) {
5124
+ pos.line += diff;
5125
+ } else if (from < pos.line) {
5126
+ pos.line = from;
5127
+ pos.ch = 0;
5128
+ }
5129
+ }
5130
+
5131
+ // Tries to rebase an array of history events given a change in the
5132
+ // document. If the change touches the same lines as the event, the
5133
+ // event, and everything 'behind' it, is discarded. If the change is
5134
+ // before the event, the event's positions are updated. Uses a
5135
+ // copy-on-write scheme for the positions, to avoid having to
5136
+ // reallocate them all on every rebase, but also avoid problems with
5137
+ // shared position objects being unsafely updated.
5138
+ function rebaseHistArray(array, from, to, diff) {
5139
+ for (var i = 0; i < array.length; ++i) {
5140
+ var sub = array[i], ok = true;
5141
+ for (var j = 0; j < sub.changes.length; ++j) {
5142
+ var cur = sub.changes[j];
5143
+ if (!sub.copied) { cur.from = copyPos(cur.from); cur.to = copyPos(cur.to); }
5144
+ if (to < cur.from.line) {
5145
+ cur.from.line += diff;
5146
+ cur.to.line += diff;
5147
+ } else if (from <= cur.to.line) {
5148
+ ok = false;
5149
+ break;
5150
+ }
5151
+ }
5152
+ if (!sub.copied) {
5153
+ sub.anchorBefore = copyPos(sub.anchorBefore); sub.headBefore = copyPos(sub.headBefore);
5154
+ sub.anchorAfter = copyPos(sub.anchorAfter); sub.readAfter = copyPos(sub.headAfter);
5155
+ sub.copied = true;
5156
+ }
5157
+ if (!ok) {
5158
+ array.splice(0, i + 1);
5159
+ i = 0;
5160
+ } else {
5161
+ rebaseHistSel(sub.anchorBefore); rebaseHistSel(sub.headBefore);
5162
+ rebaseHistSel(sub.anchorAfter); rebaseHistSel(sub.headAfter);
5163
+ }
5164
+ }
5165
+ }
5166
+
5167
+ function rebaseHist(hist, change) {
5168
+ var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
5169
+ rebaseHistArray(hist.done, from, to, diff);
5170
+ rebaseHistArray(hist.undone, from, to, diff);
5171
+ }
5172
+
5173
+ // EVENT OPERATORS
5174
+
5175
+ function stopMethod() {e_stop(this);}
5176
+ // Ensure an event has a stop method.
5177
+ function addStop(event) {
5178
+ if (!event.stop) event.stop = stopMethod;
5179
+ return event;
5180
+ }
5181
+
5182
+ function e_preventDefault(e) {
5183
+ if (e.preventDefault) e.preventDefault();
5184
+ else e.returnValue = false;
5185
+ }
5186
+ function e_stopPropagation(e) {
5187
+ if (e.stopPropagation) e.stopPropagation();
5188
+ else e.cancelBubble = true;
5189
+ }
5190
+ function e_defaultPrevented(e) {
5191
+ return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
5192
+ }
5193
+ function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
5194
+ CodeMirror.e_stop = e_stop;
5195
+ CodeMirror.e_preventDefault = e_preventDefault;
5196
+ CodeMirror.e_stopPropagation = e_stopPropagation;
5197
+
5198
+ function e_target(e) {return e.target || e.srcElement;}
5199
+ function e_button(e) {
5200
+ var b = e.which;
5201
+ if (b == null) {
5202
+ if (e.button & 1) b = 1;
5203
+ else if (e.button & 2) b = 3;
5204
+ else if (e.button & 4) b = 2;
5205
+ }
5206
+ if (mac && e.ctrlKey && b == 1) b = 3;
5207
+ return b;
5208
+ }
5209
+
5210
+ // EVENT HANDLING
5211
+
5212
+ function on(emitter, type, f) {
5213
+ if (emitter.addEventListener)
5214
+ emitter.addEventListener(type, f, false);
5215
+ else if (emitter.attachEvent)
5216
+ emitter.attachEvent("on" + type, f);
5217
+ else {
5218
+ var map = emitter._handlers || (emitter._handlers = {});
5219
+ var arr = map[type] || (map[type] = []);
5220
+ arr.push(f);
5221
+ }
5222
+ }
5223
+
5224
+ function off(emitter, type, f) {
5225
+ if (emitter.removeEventListener)
5226
+ emitter.removeEventListener(type, f, false);
5227
+ else if (emitter.detachEvent)
5228
+ emitter.detachEvent("on" + type, f);
5229
+ else {
5230
+ var arr = emitter._handlers && emitter._handlers[type];
5231
+ if (!arr) return;
5232
+ for (var i = 0; i < arr.length; ++i)
5233
+ if (arr[i] == f) { arr.splice(i, 1); break; }
5234
+ }
5235
+ }
5236
+
5237
+ function signal(emitter, type /*, values...*/) {
5238
+ var arr = emitter._handlers && emitter._handlers[type];
5239
+ if (!arr) return;
5240
+ var args = Array.prototype.slice.call(arguments, 2);
5241
+ for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
5242
+ }
5243
+
5244
+ var delayedCallbacks, delayedCallbackDepth = 0;
5245
+ function signalLater(emitter, type /*, values...*/) {
5246
+ var arr = emitter._handlers && emitter._handlers[type];
5247
+ if (!arr) return;
5248
+ var args = Array.prototype.slice.call(arguments, 2);
5249
+ if (!delayedCallbacks) {
5250
+ ++delayedCallbackDepth;
5251
+ delayedCallbacks = [];
5252
+ setTimeout(fireDelayed, 0);
5253
+ }
5254
+ function bnd(f) {return function(){f.apply(null, args);};};
5255
+ for (var i = 0; i < arr.length; ++i)
5256
+ delayedCallbacks.push(bnd(arr[i]));
5257
+ }
5258
+
5259
+ function signalDOMEvent(cm, e, override) {
5260
+ signal(cm, override || e.type, cm, e);
5261
+ return e_defaultPrevented(e) || e.codemirrorIgnore;
5262
+ }
5263
+
5264
+ function fireDelayed() {
5265
+ --delayedCallbackDepth;
5266
+ var delayed = delayedCallbacks;
5267
+ delayedCallbacks = null;
5268
+ for (var i = 0; i < delayed.length; ++i) delayed[i]();
5269
+ }
5270
+
5271
+ function hasHandler(emitter, type) {
5272
+ var arr = emitter._handlers && emitter._handlers[type];
5273
+ return arr && arr.length > 0;
5274
+ }
5275
+
5276
+ CodeMirror.on = on; CodeMirror.off = off; CodeMirror.signal = signal;
5277
+
5278
+ function eventMixin(ctor) {
5279
+ ctor.prototype.on = function(type, f) {on(this, type, f);};
5280
+ ctor.prototype.off = function(type, f) {off(this, type, f);};
5281
+ }
5282
+
5283
+ // MISC UTILITIES
5284
+
5285
+ // Number of pixels added to scroller and sizer to hide scrollbar
5286
+ var scrollerCutOff = 30;
5287
+
5288
+ // Returned or thrown by various protocols to signal 'I'm not
5289
+ // handling this'.
5290
+ var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
5291
+
5292
+ function Delayed() {this.id = null;}
5293
+ Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};
5294
+
5295
+ // Counts the column offset in a string, taking tabs into account.
5296
+ // Used mostly to find indentation.
5297
+ function countColumn(string, end, tabSize, startIndex, startValue) {
5298
+ if (end == null) {
5299
+ end = string.search(/[^\s\u00a0]/);
5300
+ if (end == -1) end = string.length;
5301
+ }
5302
+ for (var i = startIndex || 0, n = startValue || 0; i < end; ++i) {
5303
+ if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
5304
+ else ++n;
5305
+ }
5306
+ return n;
5307
+ }
5308
+ CodeMirror.countColumn = countColumn;
5309
+
5310
+ var spaceStrs = [""];
5311
+ function spaceStr(n) {
5312
+ while (spaceStrs.length <= n)
5313
+ spaceStrs.push(lst(spaceStrs) + " ");
5314
+ return spaceStrs[n];
5315
+ }
5316
+
5317
+ function lst(arr) { return arr[arr.length-1]; }
5318
+
5319
+ function selectInput(node) {
5320
+ if (ios) { // Mobile Safari apparently has a bug where select() is broken.
5321
+ node.selectionStart = 0;
5322
+ node.selectionEnd = node.value.length;
5323
+ } else {
5324
+ // Suppress mysterious IE10 errors
5325
+ try { node.select(); }
5326
+ catch(_e) {}
5327
+ }
5328
+ }
5329
+
5330
+ function indexOf(collection, elt) {
5331
+ if (collection.indexOf) return collection.indexOf(elt);
5332
+ for (var i = 0, e = collection.length; i < e; ++i)
5333
+ if (collection[i] == elt) return i;
5334
+ return -1;
5335
+ }
5336
+
5337
+ function createObj(base, props) {
5338
+ function Obj() {}
5339
+ Obj.prototype = base;
5340
+ var inst = new Obj();
5341
+ if (props) copyObj(props, inst);
5342
+ return inst;
5343
+ }
5344
+
5345
+ function copyObj(obj, target) {
5346
+ if (!target) target = {};
5347
+ for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop];
5348
+ return target;
5349
+ }
5350
+
5351
+ function emptyArray(size) {
5352
+ for (var a = [], i = 0; i < size; ++i) a.push(undefined);
5353
+ return a;
5354
+ }
5355
+
5356
+ function bind(f) {
5357
+ var args = Array.prototype.slice.call(arguments, 1);
5358
+ return function(){return f.apply(null, args);};
5359
+ }
5360
+
5361
+ var nonASCIISingleCaseWordChar = /[\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
5362
+ function isWordChar(ch) {
5363
+ return /\w/.test(ch) || ch > "\x80" &&
5364
+ (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
5365
+ }
5366
+
5367
+ function isEmpty(obj) {
5368
+ for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
5369
+ return true;
5370
+ }
5371
+
5372
+ var isExtendingChar = /[\u0300-\u036F\u0483-\u0487\u0488-\u0489\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\uA66F\uA670-\uA672\uA674-\uA67D\uA69F\udc00-\udfff]/;
5373
+
5374
+ // DOM UTILITIES
5375
+
5376
+ function elt(tag, content, className, style) {
5377
+ var e = document.createElement(tag);
5378
+ if (className) e.className = className;
5379
+ if (style) e.style.cssText = style;
5380
+ if (typeof content == "string") setTextContent(e, content);
5381
+ else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
5382
+ return e;
5383
+ }
5384
+
5385
+ function removeChildren(e) {
5386
+ for (var count = e.childNodes.length; count > 0; --count)
5387
+ e.removeChild(e.firstChild);
5388
+ return e;
5389
+ }
5390
+
5391
+ function removeChildrenAndAdd(parent, e) {
5392
+ return removeChildren(parent).appendChild(e);
5393
+ }
5394
+
5395
+ function setTextContent(e, str) {
5396
+ if (ie_lt9) {
5397
+ e.innerHTML = "";
5398
+ e.appendChild(document.createTextNode(str));
5399
+ } else e.textContent = str;
5400
+ }
5401
+
5402
+ function getRect(node) {
5403
+ return node.getBoundingClientRect();
5404
+ }
5405
+ CodeMirror.replaceGetRect = function(f) { getRect = f; };
5406
+
5407
+ // FEATURE DETECTION
5408
+
5409
+ // Detect drag-and-drop
5410
+ var dragAndDrop = function() {
5411
+ // There is *some* kind of drag-and-drop support in IE6-8, but I
5412
+ // couldn't get it to work yet.
5413
+ if (ie_lt9) return false;
5414
+ var div = elt('div');
5415
+ return "draggable" in div || "dragDrop" in div;
5416
+ }();
5417
+
5418
+ // For a reason I have yet to figure out, some browsers disallow
5419
+ // word wrapping between certain characters *only* if a new inline
5420
+ // element is started between them. This makes it hard to reliably
5421
+ // measure the position of things, since that requires inserting an
5422
+ // extra span. This terribly fragile set of tests matches the
5423
+ // character combinations that suffer from this phenomenon on the
5424
+ // various browsers.
5425
+ function spanAffectsWrapping() { return false; }
5426
+ if (gecko) // Only for "$'"
5427
+ spanAffectsWrapping = function(str, i) {
5428
+ return str.charCodeAt(i - 1) == 36 && str.charCodeAt(i) == 39;
5429
+ };
5430
+ else if (safari && !/Version\/([6-9]|\d\d)\b/.test(navigator.userAgent))
5431
+ spanAffectsWrapping = function(str, i) {
5432
+ return /\-[^ \-?]|\?[^ !\'\"\),.\-\/:;\?\]\}]/.test(str.slice(i - 1, i + 1));
5433
+ };
5434
+ else if (webkit && !/Chrome\/(?:29|[3-9]\d|\d\d\d)\./.test(navigator.userAgent))
5435
+ spanAffectsWrapping = function(str, i) {
5436
+ if (i > 1 && str.charCodeAt(i - 1) == 45) {
5437
+ if (/\w/.test(str.charAt(i - 2)) && /[^\-?\.]/.test(str.charAt(i))) return true;
5438
+ if (i > 2 && /[\d\.,]/.test(str.charAt(i - 2)) && /[\d\.,]/.test(str.charAt(i))) return false;
5439
+ }
5440
+ return /[~!#%&*)=+}\]|\"\.>,:;][({[<]|-[^\-?\.\u2010-\u201f\u2026]|\?[\w~`@#$%\^&*(_=+{[|><]|…[\w~`@#$%\^&*(_=+{[><]/.test(str.slice(i - 1, i + 1));
5441
+ };
5442
+
5443
+ var knownScrollbarWidth;
5444
+ function scrollbarWidth(measure) {
5445
+ if (knownScrollbarWidth != null) return knownScrollbarWidth;
5446
+ var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll");
5447
+ removeChildrenAndAdd(measure, test);
5448
+ if (test.offsetWidth)
5449
+ knownScrollbarWidth = test.offsetHeight - test.clientHeight;
5450
+ return knownScrollbarWidth || 0;
5451
+ }
5452
+
5453
+ var zwspSupported;
5454
+ function zeroWidthElement(measure) {
5455
+ if (zwspSupported == null) {
5456
+ var test = elt("span", "\u200b");
5457
+ removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
5458
+ if (measure.firstChild.offsetHeight != 0)
5459
+ zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_lt8;
5460
+ }
5461
+ if (zwspSupported) return elt("span", "\u200b");
5462
+ else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
5463
+ }
5464
+
5465
+ // See if "".split is the broken IE version, if so, provide an
5466
+ // alternative way to split lines.
5467
+ var splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
5468
+ var pos = 0, result = [], l = string.length;
5469
+ while (pos <= l) {
5470
+ var nl = string.indexOf("\n", pos);
5471
+ if (nl == -1) nl = string.length;
5472
+ var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
5473
+ var rt = line.indexOf("\r");
5474
+ if (rt != -1) {
5475
+ result.push(line.slice(0, rt));
5476
+ pos += rt + 1;
5477
+ } else {
5478
+ result.push(line);
5479
+ pos = nl + 1;
5480
+ }
5481
+ }
5482
+ return result;
5483
+ } : function(string){return string.split(/\r\n?|\n/);};
5484
+ CodeMirror.splitLines = splitLines;
5485
+
5486
+ var hasSelection = window.getSelection ? function(te) {
5487
+ try { return te.selectionStart != te.selectionEnd; }
5488
+ catch(e) { return false; }
5489
+ } : function(te) {
5490
+ try {var range = te.ownerDocument.selection.createRange();}
5491
+ catch(e) {}
5492
+ if (!range || range.parentElement() != te) return false;
5493
+ return range.compareEndPoints("StartToEnd", range) != 0;
5494
+ };
5495
+
5496
+ var hasCopyEvent = (function() {
5497
+ var e = elt("div");
5498
+ if ("oncopy" in e) return true;
5499
+ e.setAttribute("oncopy", "return;");
5500
+ return typeof e.oncopy == 'function';
5501
+ })();
5502
+
5503
+ // KEY NAMING
5504
+
5505
+ var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
5506
+ 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
5507
+ 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
5508
+ 46: "Delete", 59: ";", 91: "Mod", 92: "Mod", 93: "Mod", 109: "-", 107: "=", 127: "Delete",
5509
+ 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
5510
+ 221: "]", 222: "'", 63276: "PageUp", 63277: "PageDown", 63275: "End", 63273: "Home",
5511
+ 63234: "Left", 63232: "Up", 63235: "Right", 63233: "Down", 63302: "Insert", 63272: "Delete"};
5512
+ CodeMirror.keyNames = keyNames;
5513
+ (function() {
5514
+ // Number keys
5515
+ for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);
5516
+ // Alphabetic keys
5517
+ for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
5518
+ // Function keys
5519
+ for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
5520
+ })();
5521
+
5522
+ // BIDI HELPERS
5523
+
5524
+ function iterateBidiSections(order, from, to, f) {
5525
+ if (!order) return f(from, to, "ltr");
5526
+ var found = false;
5527
+ for (var i = 0; i < order.length; ++i) {
5528
+ var part = order[i];
5529
+ if (part.from < to && part.to > from || from == to && part.to == from) {
5530
+ f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
5531
+ found = true;
5532
+ }
5533
+ }
5534
+ if (!found) f(from, to, "ltr");
5535
+ }
5536
+
5537
+ function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
5538
+ function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
5539
+
5540
+ function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
5541
+ function lineRight(line) {
5542
+ var order = getOrder(line);
5543
+ if (!order) return line.text.length;
5544
+ return bidiRight(lst(order));
5545
+ }
5546
+
5547
+ function lineStart(cm, lineN) {
5548
+ var line = getLine(cm.doc, lineN);
5549
+ var visual = visualLine(cm.doc, line);
5550
+ if (visual != line) lineN = lineNo(visual);
5551
+ var order = getOrder(visual);
5552
+ var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
5553
+ return Pos(lineN, ch);
5554
+ }
5555
+ function lineEnd(cm, lineN) {
5556
+ var merged, line;
5557
+ while (merged = collapsedSpanAtEnd(line = getLine(cm.doc, lineN)))
5558
+ lineN = merged.find().to.line;
5559
+ var order = getOrder(line);
5560
+ var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
5561
+ return Pos(lineN, ch);
5562
+ }
5563
+
5564
+ function compareBidiLevel(order, a, b) {
5565
+ var linedir = order[0].level;
5566
+ if (a == linedir) return true;
5567
+ if (b == linedir) return false;
5568
+ return a < b;
5569
+ }
5570
+ var bidiOther;
5571
+ function getBidiPartAt(order, pos) {
5572
+ for (var i = 0, found; i < order.length; ++i) {
5573
+ var cur = order[i];
5574
+ if (cur.from < pos && cur.to > pos) { bidiOther = null; return i; }
5575
+ if (cur.from == pos || cur.to == pos) {
5576
+ if (found == null) {
5577
+ found = i;
5578
+ } else if (compareBidiLevel(order, cur.level, order[found].level)) {
5579
+ bidiOther = found;
5580
+ return i;
5581
+ } else {
5582
+ bidiOther = i;
5583
+ return found;
5584
+ }
5585
+ }
5586
+ }
5587
+ bidiOther = null;
5588
+ return found;
5589
+ }
5590
+
5591
+ function moveInLine(line, pos, dir, byUnit) {
5592
+ if (!byUnit) return pos + dir;
5593
+ do pos += dir;
5594
+ while (pos > 0 && isExtendingChar.test(line.text.charAt(pos)));
5595
+ return pos;
5596
+ }
5597
+
5598
+ // This is somewhat involved. It is needed in order to move
5599
+ // 'visually' through bi-directional text -- i.e., pressing left
5600
+ // should make the cursor go left, even when in RTL text. The
5601
+ // tricky part is the 'jumps', where RTL and LTR text touch each
5602
+ // other. This often requires the cursor offset to move more than
5603
+ // one unit, in order to visually move one unit.
5604
+ function moveVisually(line, start, dir, byUnit) {
5605
+ var bidi = getOrder(line);
5606
+ if (!bidi) return moveLogically(line, start, dir, byUnit);
5607
+ var pos = getBidiPartAt(bidi, start), part = bidi[pos];
5608
+ var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);
5609
+
5610
+ for (;;) {
5611
+ if (target > part.from && target < part.to) return target;
5612
+ if (target == part.from || target == part.to) {
5613
+ if (getBidiPartAt(bidi, target) == pos) return target;
5614
+ part = bidi[pos += dir];
5615
+ return (dir > 0) == part.level % 2 ? part.to : part.from;
5616
+ } else {
5617
+ part = bidi[pos += dir];
5618
+ if (!part) return null;
5619
+ if ((dir > 0) == part.level % 2)
5620
+ target = moveInLine(line, part.to, -1, byUnit);
5621
+ else
5622
+ target = moveInLine(line, part.from, 1, byUnit);
5623
+ }
5624
+ }
5625
+ }
5626
+
5627
+ function moveLogically(line, start, dir, byUnit) {
5628
+ var target = start + dir;
5629
+ if (byUnit) while (target > 0 && isExtendingChar.test(line.text.charAt(target))) target += dir;
5630
+ return target < 0 || target > line.text.length ? null : target;
5631
+ }
5632
+
5633
+ // Bidirectional ordering algorithm
5634
+ // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
5635
+ // that this (partially) implements.
5636
+
5637
+ // One-char codes used for character types:
5638
+ // L (L): Left-to-Right
5639
+ // R (R): Right-to-Left
5640
+ // r (AL): Right-to-Left Arabic
5641
+ // 1 (EN): European Number
5642
+ // + (ES): European Number Separator
5643
+ // % (ET): European Number Terminator
5644
+ // n (AN): Arabic Number
5645
+ // , (CS): Common Number Separator
5646
+ // m (NSM): Non-Spacing Mark
5647
+ // b (BN): Boundary Neutral
5648
+ // s (B): Paragraph Separator
5649
+ // t (S): Segment Separator
5650
+ // w (WS): Whitespace
5651
+ // N (ON): Other Neutrals
5652
+
5653
+ // Returns null if characters are ordered as they appear
5654
+ // (left-to-right), or an array of sections ({from, to, level}
5655
+ // objects) in the order in which they occur visually.
5656
+ var bidiOrdering = (function() {
5657
+ // Character types for codepoints 0 to 0xff
5658
+ var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLL";
5659
+ // Character types for codepoints 0x600 to 0x6ff
5660
+ var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmmrrrrrrrrrrrrrrrrrr";
5661
+ function charType(code) {
5662
+ if (code <= 0xff) return lowTypes.charAt(code);
5663
+ else if (0x590 <= code && code <= 0x5f4) return "R";
5664
+ else if (0x600 <= code && code <= 0x6ff) return arabicTypes.charAt(code - 0x600);
5665
+ else if (0x700 <= code && code <= 0x8ac) return "r";
5666
+ else return "L";
5667
+ }
5668
+
5669
+ var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
5670
+ var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
5671
+ // Browsers seem to always treat the boundaries of block elements as being L.
5672
+ var outerType = "L";
5673
+
5674
+ return function(str) {
5675
+ if (!bidiRE.test(str)) return false;
5676
+ var len = str.length, types = [];
5677
+ for (var i = 0, type; i < len; ++i)
5678
+ types.push(type = charType(str.charCodeAt(i)));
5679
+
5680
+ // W1. Examine each non-spacing mark (NSM) in the level run, and
5681
+ // change the type of the NSM to the type of the previous
5682
+ // character. If the NSM is at the start of the level run, it will
5683
+ // get the type of sor.
5684
+ for (var i = 0, prev = outerType; i < len; ++i) {
5685
+ var type = types[i];
5686
+ if (type == "m") types[i] = prev;
5687
+ else prev = type;
5688
+ }
5689
+
5690
+ // W2. Search backwards from each instance of a European number
5691
+ // until the first strong type (R, L, AL, or sor) is found. If an
5692
+ // AL is found, change the type of the European number to Arabic
5693
+ // number.
5694
+ // W3. Change all ALs to R.
5695
+ for (var i = 0, cur = outerType; i < len; ++i) {
5696
+ var type = types[i];
5697
+ if (type == "1" && cur == "r") types[i] = "n";
5698
+ else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
5699
+ }
5700
+
5701
+ // W4. A single European separator between two European numbers
5702
+ // changes to a European number. A single common separator between
5703
+ // two numbers of the same type changes to that type.
5704
+ for (var i = 1, prev = types[0]; i < len - 1; ++i) {
5705
+ var type = types[i];
5706
+ if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
5707
+ else if (type == "," && prev == types[i+1] &&
5708
+ (prev == "1" || prev == "n")) types[i] = prev;
5709
+ prev = type;
5710
+ }
5711
+
5712
+ // W5. A sequence of European terminators adjacent to European
5713
+ // numbers changes to all European numbers.
5714
+ // W6. Otherwise, separators and terminators change to Other
5715
+ // Neutral.
5716
+ for (var i = 0; i < len; ++i) {
5717
+ var type = types[i];
5718
+ if (type == ",") types[i] = "N";
5719
+ else if (type == "%") {
5720
+ for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
5721
+ var replace = (i && types[i-1] == "!") || (end < len - 1 && types[end] == "1") ? "1" : "N";
5722
+ for (var j = i; j < end; ++j) types[j] = replace;
5723
+ i = end - 1;
5724
+ }
5725
+ }
5726
+
5727
+ // W7. Search backwards from each instance of a European number
5728
+ // until the first strong type (R, L, or sor) is found. If an L is
5729
+ // found, then change the type of the European number to L.
5730
+ for (var i = 0, cur = outerType; i < len; ++i) {
5731
+ var type = types[i];
5732
+ if (cur == "L" && type == "1") types[i] = "L";
5733
+ else if (isStrong.test(type)) cur = type;
5734
+ }
5735
+
5736
+ // N1. A sequence of neutrals takes the direction of the
5737
+ // surrounding strong text if the text on both sides has the same
5738
+ // direction. European and Arabic numbers act as if they were R in
5739
+ // terms of their influence on neutrals. Start-of-level-run (sor)
5740
+ // and end-of-level-run (eor) are used at level run boundaries.
5741
+ // N2. Any remaining neutrals take the embedding direction.
5742
+ for (var i = 0; i < len; ++i) {
5743
+ if (isNeutral.test(types[i])) {
5744
+ for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
5745
+ var before = (i ? types[i-1] : outerType) == "L";
5746
+ var after = (end < len - 1 ? types[end] : outerType) == "L";
5747
+ var replace = before || after ? "L" : "R";
5748
+ for (var j = i; j < end; ++j) types[j] = replace;
5749
+ i = end - 1;
5750
+ }
5751
+ }
5752
+
5753
+ // Here we depart from the documented algorithm, in order to avoid
5754
+ // building up an actual levels array. Since there are only three
5755
+ // levels (0, 1, 2) in an implementation that doesn't take
5756
+ // explicit embedding into account, we can build up the order on
5757
+ // the fly, without following the level-based algorithm.
5758
+ var order = [], m;
5759
+ for (var i = 0; i < len;) {
5760
+ if (countsAsLeft.test(types[i])) {
5761
+ var start = i;
5762
+ for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
5763
+ order.push({from: start, to: i, level: 0});
5764
+ } else {
5765
+ var pos = i, at = order.length;
5766
+ for (++i; i < len && types[i] != "L"; ++i) {}
5767
+ for (var j = pos; j < i;) {
5768
+ if (countsAsNum.test(types[j])) {
5769
+ if (pos < j) order.splice(at, 0, {from: pos, to: j, level: 1});
5770
+ var nstart = j;
5771
+ for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
5772
+ order.splice(at, 0, {from: nstart, to: j, level: 2});
5773
+ pos = j;
5774
+ } else ++j;
5775
+ }
5776
+ if (pos < i) order.splice(at, 0, {from: pos, to: i, level: 1});
5777
+ }
5778
+ }
5779
+ if (order[0].level == 1 && (m = str.match(/^\s+/))) {
5780
+ order[0].from = m[0].length;
5781
+ order.unshift({from: 0, to: m[0].length, level: 0});
5782
+ }
5783
+ if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
5784
+ lst(order).to -= m[0].length;
5785
+ order.push({from: len - m[0].length, to: len, level: 0});
5786
+ }
5787
+ if (order[0].level != lst(order).level)
5788
+ order.push({from: len, to: len, level: order[0].level});
5789
+
5790
+ return order;
5791
+ };
5792
+ })();
5793
+
5794
+ // THE END
5795
+
5796
+ CodeMirror.version = "3.15.0";
5797
+
5798
+ return CodeMirror;
5799
+ })();
plugin-fw/assets/js/codemirror/javascript.js ADDED
@@ -0,0 +1,630 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // TODO actually recognize syntax of TypeScript constructs
2
+
3
+ CodeMirror.defineMode("javascript", function(config, parserConfig) {
4
+ var indentUnit = config.indentUnit;
5
+ var statementIndent = parserConfig.statementIndent;
6
+ var jsonMode = parserConfig.json;
7
+ var isTS = parserConfig.typescript;
8
+
9
+ // Tokenizer
10
+
11
+ var keywords = function(){
12
+ function kw(type) {return {type: type, style: "keyword"};}
13
+ var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
14
+ var operator = kw("operator"), atom = {type: "atom", style: "atom"};
15
+
16
+ var jsKeywords = {
17
+ "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
18
+ "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
19
+ "var": kw("var"), "const": kw("var"), "let": kw("var"),
20
+ "function": kw("function"), "catch": kw("catch"),
21
+ "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
22
+ "in": operator, "typeof": operator, "instanceof": operator,
23
+ "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
24
+ "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
25
+ "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
26
+ };
27
+
28
+ // Extend the 'normal' keywords with the TypeScript language extensions
29
+ if (isTS) {
30
+ var type = {type: "variable", style: "variable-3"};
31
+ var tsKeywords = {
32
+ // object-like things
33
+ "interface": kw("interface"),
34
+ "extends": kw("extends"),
35
+ "constructor": kw("constructor"),
36
+
37
+ // scope modifiers
38
+ "public": kw("public"),
39
+ "private": kw("private"),
40
+ "protected": kw("protected"),
41
+ "static": kw("static"),
42
+
43
+ // types
44
+ "string": type, "number": type, "bool": type, "any": type
45
+ };
46
+
47
+ for (var attr in tsKeywords) {
48
+ jsKeywords[attr] = tsKeywords[attr];
49
+ }
50
+ }
51
+
52
+ return jsKeywords;
53
+ }();
54
+
55
+ var isOperatorChar = /[+\-*&%=<>!?|~^]/;
56
+
57
+ function readRegexp(stream) {
58
+ var escaped = false, next, inSet = false;
59
+ while ((next = stream.next()) != null) {
60
+ if (!escaped) {
61
+ if (next == "/" && !inSet) return;
62
+ if (next == "[") inSet = true;
63
+ else if (inSet && next == "]") inSet = false;
64
+ }
65
+ escaped = !escaped && next == "\\";
66
+ }
67
+ }
68
+
69
+ // Used as scratch variables to communicate multiple values without
70
+ // consing up tons of objects.
71
+ var type, content;
72
+ function ret(tp, style, cont) {
73
+ type = tp; content = cont;
74
+ return style;
75
+ }
76
+ function tokenBase(stream, state) {
77
+ var ch = stream.next();
78
+ if (ch == '"' || ch == "'") {
79
+ state.tokenize = tokenString(ch);
80
+ return state.tokenize(stream, state);
81
+ } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
82
+ return ret("number", "number");
83
+ } else if (ch == "." && stream.match("..")) {
84
+ return ret("spread", "meta");
85
+ } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
86
+ return ret(ch);
87
+ } else if (ch == "=" && stream.eat(">")) {
88
+ return ret("=>", "operator");
89
+ } else if (ch == "0" && stream.eat(/x/i)) {
90
+ stream.eatWhile(/[\da-f]/i);
91
+ return ret("number", "number");
92
+ } else if (/\d/.test(ch)) {
93
+ stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
94
+ return ret("number", "number");
95
+ } else if (ch == "/") {
96
+ if (stream.eat("*")) {
97
+ state.tokenize = tokenComment;
98
+ return tokenComment(stream, state);
99
+ } else if (stream.eat("/")) {
100
+ stream.skipToEnd();
101
+ return ret("comment", "comment");
102
+ } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
103
+ state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
104
+ readRegexp(stream);
105
+ stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla
106
+ return ret("regexp", "string-2");
107
+ } else {
108
+ stream.eatWhile(isOperatorChar);
109
+ return ret("operator", "operator", stream.current());
110
+ }
111
+ } else if (ch == "`") {
112
+ state.tokenize = tokenQuasi;
113
+ return tokenQuasi(stream, state);
114
+ } else if (ch == "#") {
115
+ stream.skipToEnd();
116
+ return ret("error", "error");
117
+ } else if (isOperatorChar.test(ch)) {
118
+ stream.eatWhile(isOperatorChar);
119
+ return ret("operator", "operator", stream.current());
120
+ } else {
121
+ stream.eatWhile(/[\w\$_]/);
122
+ var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
123
+ return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
124
+ ret("variable", "variable", word);
125
+ }
126
+ }
127
+
128
+ function tokenString(quote) {
129
+ return function(stream, state) {
130
+ var escaped = false, next;
131
+ while ((next = stream.next()) != null) {
132
+ if (next == quote && !escaped) break;
133
+ escaped = !escaped && next == "\\";
134
+ }
135
+ if (!escaped) state.tokenize = tokenBase;
136
+ return ret("string", "string");
137
+ };
138
+ }
139
+
140
+ function tokenComment(stream, state) {
141
+ var maybeEnd = false, ch;
142
+ while (ch = stream.next()) {
143
+ if (ch == "/" && maybeEnd) {
144
+ state.tokenize = tokenBase;
145
+ break;
146
+ }
147
+ maybeEnd = (ch == "*");
148
+ }
149
+ return ret("comment", "comment");
150
+ }
151
+
152
+ function tokenQuasi(stream, state) {
153
+ var escaped = false, next;
154
+ while ((next = stream.next()) != null) {
155
+ if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
156
+ state.tokenize = tokenBase;
157
+ break;
158
+ }
159
+ escaped = !escaped && next == "\\";
160
+ }
161
+ return ret("quasi", "string-2", stream.current());
162
+ }
163
+
164
+ var brackets = "([{}])";
165
+ // This is a crude lookahead trick to try and notice that we're
166
+ // parsing the argument patterns for a fat-arrow function before we
167
+ // actually hit the arrow token. It only works if the arrow is on
168
+ // the same line as the arguments and there's no strange noise
169
+ // (comments) in between. Fallback is to only notice when we hit the
170
+ // arrow, and not declare the arguments as locals for the arrow
171
+ // body.
172
+ function findFatArrow(stream, state) {
173
+ if (state.fatArrowAt) state.fatArrowAt = null;
174
+ var arrow = stream.string.indexOf("=>", stream.start);
175
+ if (arrow < 0) return;
176
+
177
+ var depth = 0, sawSomething = false;
178
+ for (var pos = arrow - 1; pos >= 0; --pos) {
179
+ var ch = stream.string.charAt(pos);
180
+ var bracket = brackets.indexOf(ch);
181
+ if (bracket >= 0 && bracket < 3) {
182
+ if (!depth) { ++pos; break; }
183
+ if (--depth == 0) break;
184
+ } else if (bracket >= 3 && bracket < 6) {
185
+ ++depth;
186
+ } else if (/[$\w]/.test(ch)) {
187
+ sawSomething = true;
188
+ } else if (sawSomething && !depth) {
189
+ ++pos;
190
+ break;
191
+ }
192
+ }
193
+ if (sawSomething && !depth) state.fatArrowAt = pos;
194
+ }
195
+
196
+ // Parser
197
+
198
+ var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true};
199
+
200
+ function JSLexical(indented, column, type, align, prev, info) {
201
+ this.indented = indented;
202
+ this.column = column;
203
+ this.type = type;
204
+ this.prev = prev;
205
+ this.info = info;
206
+ if (align != null) this.align = align;
207
+ }
208
+
209
+ function inScope(state, varname) {
210
+ for (var v = state.localVars; v; v = v.next)
211
+ if (v.name == varname) return true;
212
+ for (var cx = state.context; cx; cx = cx.prev) {
213
+ for (var v = cx.vars; v; v = v.next)
214
+ if (v.name == varname) return true;
215
+ }
216
+ }
217
+
218
+ function parseJS(state, style, type, content, stream) {
219
+ var cc = state.cc;
220
+ // Communicate our context to the combinators.
221
+ // (Less wasteful than consing up a hundred closures on every call.)
222
+ cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
223
+
224
+ if (!state.lexical.hasOwnProperty("align"))
225
+ state.lexical.align = true;
226
+
227
+ while(true) {
228
+ var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
229
+ if (combinator(type, content)) {
230
+ while(cc.length && cc[cc.length - 1].lex)
231
+ cc.pop()();
232
+ if (cx.marked) return cx.marked;
233
+ if (type == "variable" && inScope(state, content)) return "variable-2";
234
+ return style;
235
+ }
236
+ }
237
+ }
238
+
239
+ // Combinator utils
240
+
241
+ var cx = {state: null, column: null, marked: null, cc: null};
242
+ function pass() {
243
+ for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
244
+ }
245
+ function cont() {
246
+ pass.apply(null, arguments);
247
+ return true;
248
+ }
249
+ function register(varname) {
250
+ function inList(list) {
251
+ for (var v = list; v; v = v.next)
252
+ if (v.name == varname) return true;
253
+ return false;
254
+ }
255
+ var state = cx.state;
256
+ if (state.context) {
257
+ cx.marked = "def";
258
+ if (inList(state.localVars)) return;
259
+ state.localVars = {name: varname, next: state.localVars};
260
+ } else {
261
+ if (inList(state.globalVars)) return;
262
+ if (parserConfig.globalVars)
263
+ state.globalVars = {name: varname, next: state.globalVars};
264
+ }
265
+ }
266
+
267
+ // Combinators
268
+
269
+ var defaultVars = {name: "this", next: {name: "arguments"}};
270
+ function pushcontext() {
271
+ cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
272
+ cx.state.localVars = defaultVars;
273
+ }
274
+ function popcontext() {
275
+ cx.state.localVars = cx.state.context.vars;
276
+ cx.state.context = cx.state.context.prev;
277
+ }
278
+ function pushlex(type, info) {
279
+ var result = function() {
280
+ var state = cx.state, indent = state.indented;
281
+ if (state.lexical.type == "stat") indent = state.lexical.indented;
282
+ state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
283
+ };
284
+ result.lex = true;
285
+ return result;
286
+ }
287
+ function poplex() {
288
+ var state = cx.state;
289
+ if (state.lexical.prev) {
290
+ if (state.lexical.type == ")")
291
+ state.indented = state.lexical.indented;
292
+ state.lexical = state.lexical.prev;
293
+ }
294
+ }
295
+ poplex.lex = true;
296
+
297
+ function expect(wanted) {
298
+ return function(type) {
299
+ if (type == wanted) return cont();
300
+ else if (wanted == ";") return pass();
301
+ else return cont(arguments.callee);
302
+ };
303
+ }
304
+
305
+ function statement(type, value) {
306
+ if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
307
+ if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
308
+ if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
309
+ if (type == "{") return cont(pushlex("}"), block, poplex);
310
+ if (type == ";") return cont();
311
+ if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse);
312
+ if (type == "function") return cont(functiondef);
313
+ if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
314
+ if (type == "variable") return cont(pushlex("stat"), maybelabel);
315
+ if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
316
+ block, poplex, poplex);
317
+ if (type == "case") return cont(expression, expect(":"));
318
+ if (type == "default") return cont(expect(":"));
319
+ if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
320
+ statement, poplex, popcontext);
321
+ if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
322
+ if (type == "class") return cont(pushlex("form"), className, objlit, poplex);
323
+ if (type == "export") return cont(pushlex("form"), afterExport, poplex);
324
+ if (type == "import") return cont(pushlex("form"), afterImport, poplex);
325
+ return pass(pushlex("stat"), expression, expect(";"), poplex);
326
+ }
327
+ function expression(type) {
328
+ return expressionInner(type, false);
329
+ }
330
+ function expressionNoComma(type) {
331
+ return expressionInner(type, true);
332
+ }
333
+ function expressionInner(type, noComma) {
334
+ if (cx.state.fatArrowAt == cx.stream.start) {
335
+ var body = noComma ? arrowBodyNoComma : arrowBody;
336
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
337
+ else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
338
+ }
339
+
340
+ var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
341
+ if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
342
+ if (type == "function") return cont(functiondef);
343
+ if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
344
+ if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
345
+ if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
346
+ if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
347
+ if (type == "{") return contCommasep(objprop, "}", null, maybeop);
348
+ return cont();
349
+ }
350
+ function maybeexpression(type) {
351
+ if (type.match(/[;\}\)\],]/)) return pass();
352
+ return pass(expression);
353
+ }
354
+ function maybeexpressionNoComma(type) {
355
+ if (type.match(/[;\}\)\],]/)) return pass();
356
+ return pass(expressionNoComma);
357
+ }
358
+
359
+ function maybeoperatorComma(type, value) {
360
+ if (type == ",") return cont(expression);
361
+ return maybeoperatorNoComma(type, value, false);
362
+ }
363
+ function maybeoperatorNoComma(type, value, noComma) {
364
+ var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
365
+ var expr = noComma == false ? expression : expressionNoComma;
366
+ if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
367
+ if (type == "operator") {
368
+ if (/\+\+|--/.test(value)) return cont(me);
369
+ if (value == "?") return cont(expression, expect(":"), expr);
370
+ return cont(expr);
371
+ }
372
+ if (type == "quasi") { cx.cc.push(me); return quasi(value); }
373
+ if (type == ";") return;
374
+ if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
375
+ if (type == ".") return cont(property, me);
376
+ if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
377
+ }
378
+ function quasi(value) {
379
+ if (value.slice(value.length - 2) != "${") return cont();
380
+ return cont(expression, continueQuasi);
381
+ }
382
+ function continueQuasi(type) {
383
+ if (type == "}") {
384
+ cx.marked = "string-2";
385
+ cx.state.tokenize = tokenQuasi;
386
+ return cont();
387
+ }
388
+ }
389
+ function arrowBody(type) {
390
+ findFatArrow(cx.stream, cx.state);
391
+ if (type == "{") return pass(statement);
392
+ return pass(expression);
393
+ }
394
+ function arrowBodyNoComma(type) {
395
+ findFatArrow(cx.stream, cx.state);
396
+ if (type == "{") return pass(statement);
397
+ return pass(expressionNoComma);
398
+ }
399
+ function maybelabel(type) {
400
+ if (type == ":") return cont(poplex, statement);
401
+ return pass(maybeoperatorComma, expect(";"), poplex);
402
+ }
403
+ function property(type) {
404
+ if (type == "variable") {cx.marked = "property"; return cont();}
405
+ }
406
+ function objprop(type, value) {
407
+ if (type == "variable") {
408
+ cx.marked = "property";
409
+ if (value == "get" || value == "set") return cont(getterSetter);
410
+ } else if (type == "number" || type == "string") {
411
+ cx.marked = type + " property";
412
+ } else if (type == "[") {
413
+ return cont(expression, expect("]"), afterprop);
414
+ }
415
+ if (atomicTypes.hasOwnProperty(type)) return cont(afterprop);
416
+ }
417
+ function getterSetter(type) {
418
+ if (type != "variable") return pass(afterprop);
419
+ cx.marked = "property";
420
+ return cont(functiondef);
421
+ }
422
+ function afterprop(type) {
423
+ if (type == ":") return cont(expressionNoComma);
424
+ if (type == "(") return pass(functiondef);
425
+ }
426
+ function commasep(what, end) {
427
+ function proceed(type) {
428
+ if (type == ",") {
429
+ var lex = cx.state.lexical;
430
+ if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
431
+ return cont(what, proceed);
432
+ }
433
+ if (type == end) return cont();
434
+ return cont(expect(end));
435
+ }
436
+ return function(type) {
437
+ if (type == end) return cont();
438
+ return pass(what, proceed);
439
+ };
440
+ }
441
+ function contCommasep(what, end, info) {
442
+ for (var i = 3; i < arguments.length; i++)
443
+ cx.cc.push(arguments[i]);
444
+ return cont(pushlex(end, info), commasep(what, end), poplex);
445
+ }
446
+ function block(type) {
447
+ if (type == "}") return cont();
448
+ return pass(statement, block);
449
+ }
450
+ function maybetype(type) {
451
+ if (isTS && type == ":") return cont(typedef);
452
+ }
453
+ function typedef(type) {
454
+ if (type == "variable"){cx.marked = "variable-3"; return cont();}
455
+ }
456
+ function vardef() {
457
+ return pass(pattern, maybetype, maybeAssign, vardefCont);
458
+ }
459
+ function pattern(type, value) {
460
+ if (type == "variable") { register(value); return cont(); }
461
+ if (type == "[") return contCommasep(pattern, "]");
462
+ if (type == "{") return contCommasep(proppattern, "}");
463
+ }
464
+ function proppattern(type, value) {
465
+ if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
466
+ register(value);
467
+ return cont(maybeAssign);
468
+ }
469
+ if (type == "variable") cx.marked = "property";
470
+ return cont(expect(":"), pattern, maybeAssign);
471
+ }
472
+ function maybeAssign(_type, value) {
473
+ if (value == "=") return cont(expressionNoComma);
474
+ }
475
+ function vardefCont(type) {
476
+ if (type == ",") return cont(vardef);
477
+ }
478
+ function maybeelse(type, value) {
479
+ if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex);
480
+ }
481
+ function forspec(type) {
482
+ if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
483
+ }
484
+ function forspec1(type) {
485
+ if (type == "var") return cont(vardef, expect(";"), forspec2);
486
+ if (type == ";") return cont(forspec2);
487
+ if (type == "variable") return cont(formaybeinof);
488
+ return pass(expression, expect(";"), forspec2);
489
+ }
490
+ function formaybeinof(_type, value) {
491
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
492
+ return cont(maybeoperatorComma, forspec2);
493
+ }
494
+ function forspec2(type, value) {
495
+ if (type == ";") return cont(forspec3);
496
+ if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
497
+ return pass(expression, expect(";"), forspec3);
498
+ }
499
+ function forspec3(type) {
500
+ if (type != ")") cont(expression);
501
+ }
502
+ function functiondef(type, value) {
503
+ if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
504
+ if (type == "variable") {register(value); return cont(functiondef);}
505
+ if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
506
+ }
507
+ function funarg(type) {
508
+ if (type == "spread") return cont(funarg);
509
+ return pass(pattern, maybetype);
510
+ }
511
+ function className(type, value) {
512
+ if (type == "variable") {register(value); return cont(classNameAfter);}
513
+ }
514
+ function classNameAfter(_type, value) {
515
+ if (value == "extends") return cont(expression);
516
+ }
517
+ function objlit(type) {
518
+ if (type == "{") return contCommasep(objprop, "}");
519
+ }
520
+ function afterModule(type, value) {
521
+ if (type == "string") return cont(statement);
522
+ if (type == "variable") { register(value); return cont(maybeFrom); }
523
+ }
524
+ function afterExport(_type, value) {
525
+ if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
526
+ if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
527
+ return pass(statement);
528
+ }
529
+ function afterImport(type) {
530
+ if (type == "string") return cont();
531
+ return pass(importSpec, maybeFrom);
532
+ }
533
+ function importSpec(type, value) {
534
+ if (type == "{") return contCommasep(importSpec, "}");
535
+ if (type == "variable") register(value);
536
+ return cont();
537
+ }
538
+ function maybeFrom(_type, value) {
539
+ if (value == "from") { cx.marked = "keyword"; return cont(expression); }
540
+ }
541
+ function arrayLiteral(type) {
542
+ if (type == "]") return cont();
543
+ return pass(expressionNoComma, maybeArrayComprehension);
544
+ }
545
+ function maybeArrayComprehension(type) {
546
+ if (type == "for") return pass(comprehension, expect("]"));
547
+ if (type == ",") return cont(commasep(expressionNoComma, "]"));
548
+ return pass(commasep(expressionNoComma, "]"));
549
+ }
550
+ function comprehension(type) {
551
+ if (type == "for") return cont(forspec, comprehension);
552
+ if (type == "if") return cont(expression, comprehension);
553
+ }
554
+
555
+ // Interface
556
+
557
+ return {
558
+ startState: function(basecolumn) {
559
+ var state = {
560
+ tokenize: tokenBase,
561
+ lastType: "sof",
562
+ cc: [],
563
+ lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
564
+ localVars: parserConfig.localVars,
565
+ context: parserConfig.localVars && {vars: parserConfig.localVars},
566
+ indented: 0
567
+ };
568
+ if (parserConfig.globalVars) state.globalVars = parserConfig.globalVars;
569
+ return state;
570
+ },
571
+
572
+ token: function(stream, state) {
573
+ if (stream.sol()) {
574
+ if (!state.lexical.hasOwnProperty("align"))
575
+ state.lexical.align = false;
576
+ state.indented = stream.indentation();
577
+ findFatArrow(stream, state);
578
+ }
579
+ if (state.tokenize != tokenComment && stream.eatSpace()) return null;
580
+ var style = state.tokenize(stream, state);
581
+ if (type == "comment") return style;
582
+ state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
583
+ return parseJS(state, style, type, content, stream);
584
+ },
585
+
586
+ indent: function(state, textAfter) {
587
+ if (state.tokenize == tokenComment) return CodeMirror.Pass;
588
+ if (state.tokenize != tokenBase) return 0;
589
+ var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
590
+ // Kludge to prevent 'maybelse' from blocking lexical scope pops
591
+ for (var i = state.cc.length - 1; i >= 0; --i) {
592
+ var c = state.cc[i];
593
+ if (c == poplex) lexical = lexical.prev;
594
+ else if (c != maybeelse) break;
595
+ }
596
+ if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
597
+ if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
598
+ lexical = lexical.prev;
599
+ var type = lexical.type, closing = firstChar == type;
600
+
601
+ if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
602
+ else if (type == "form" && firstChar == "{") return lexical.indented;
603
+ else if (type == "form") return lexical.indented + indentUnit;
604
+ else if (type == "stat")
605
+ return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0);
606
+ else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
607
+ return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
608
+ else if (lexical.align) return lexical.column + (closing ? 0 : 1);
609
+ else return lexical.indented + (closing ? 0 : indentUnit);
610
+ },
611
+
612
+ electricChars: ":{}",
613
+ blockCommentStart: jsonMode ? null : "/*",
614
+ blockCommentEnd: jsonMode ? null : "*/",
615
+ lineComment: jsonMode ? null : "//",
616
+ fold: "brace",
617
+
618
+ helperType: jsonMode ? "json" : "javascript",
619
+ jsonMode: jsonMode
620
+ };
621
+ });
622
+
623
+ CodeMirror.defineMIME("text/javascript", "javascript");
624
+ CodeMirror.defineMIME("text/ecmascript", "javascript");
625
+ CodeMirror.defineMIME("application/javascript", "javascript");
626
+ CodeMirror.defineMIME("application/ecmascript", "javascript");
627
+ CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
628
+ CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
629
+ CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
630
+ CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
plugin-fw/assets/js/metabox.js ADDED
@@ -0,0 +1,350 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+ (function ($) {
10
+
11
+ $('.metaboxes-tab').each(function () {
12
+ $('.tabs-panel', this).hide();
13
+
14
+ var active_tab = wpCookies.get('active_metabox_tab');
15
+ if (active_tab == null) {
16
+ active_tab = $('ul.metaboxes-tabs li:first-child a', this).attr('href');
17
+ } else {
18
+ active_tab = '#' + active_tab;
19
+ }
20
+
21
+ $(active_tab).show();
22
+
23
+ $('.metaboxes-tabs a', this).click(function (e) {
24
+ if ($(this).parent().hasClass('tabs')) {
25
+ e.preventDefault();
26
+ return;
27
+ }
28
+
29
+ var t = $(this).attr('href');
30
+ $(this).parent().addClass('tabs').siblings('li').removeClass('tabs');
31
+ $('.tabs-panel').slideUp('fast');
32
+ $(t).delay(350).slideDown('fast');
33
+
34
+ return false;
35
+ });
36
+ });
37
+
38
+ //upload
39
+ var _custom_media = true,
40
+ _orig_send_attachment = wp.media.editor.send.attachment;
41
+
42
+ $(document).on('click', '.metaboxes-tab .upload_button', function(e) {
43
+ var send_attachment_bkp = wp.media.editor.send.attachment;
44
+ var button = $(this);
45
+ var id = button.attr('id').replace('-button', '');
46
+ _custom_media = true;
47
+ wp.media.editor.send.attachment = function(props, attachment){
48
+ if ( _custom_media ) {
49
+ if( $("#"+id).is('input[type=text]') ) {
50
+ $("#"+id).val(attachment.url);
51
+ } else {
52
+ $("#"+id + '_custom').val(attachment.url);
53
+ }
54
+ } else {
55
+ return _orig_send_attachment.apply( this, [props, attachment] );
56
+ };
57
+ }
58
+
59
+ wp.media.editor.open(button);
60
+ return false;
61
+ });
62
+
63
+ $('.metaboxes-tab .add_media').on('click', function(){
64
+ _custom_media = false;
65
+ });
66
+
67
+ //colorpicker
68
+ $('.metaboxes-tab .panel-colorpicker').wpColorPicker({
69
+ onInit: function(){ console.log('test');},
70
+ change: function(event, ui){
71
+ },
72
+ clear: function(){
73
+ var input = $(this);
74
+ input.val(input.data('default-color'));
75
+ input.change();
76
+ }
77
+ });
78
+
79
+
80
+ $('.metaboxes-tab .panel-colorpicker').each( function() {
81
+ var select_label = $(this).data('variations-label');
82
+ $(this).parent().parent().find('a.wp-color-result').attr('title', select_label);
83
+ });
84
+
85
+ //datepicker
86
+ $('.metaboxes-tab .panel-datepicker').each( function() {
87
+ $(this).datepicker();
88
+ });
89
+
90
+
91
+ // select
92
+ var select_value = function() {
93
+ var value = '';
94
+
95
+ if( $(this).attr('multiple')){
96
+ $(this).children("option:selected").each(function(i,v){
97
+ if( i != 0)
98
+ value += ', ';
99
+
100
+ value += $(v).text();
101
+ });
102
+
103
+ if( value == '' ){
104
+ $(this).children().children("option:selected").each(function(i,v){
105
+ if( i != 0)
106
+ value += ', ';
107
+
108
+ value += $(v).text();
109
+ });
110
+ }
111
+ }
112
+ else{
113
+ value = $(this).children("option:selected").text();
114
+
115
+ if( value == '' )
116
+ value = $(this).children().children("option:selected").text();
117
+ }
118
+
119
+
120
+ if ( $(this).parent().find('span').length <= 0 ) {
121
+ $(this).before('<span></span>');
122
+ }
123
+
124
+ $(this).parent().children('span').replaceWith('<span>'+value +'</span>');
125
+ };
126
+ $('.metaboxes-tab .select_wrapper select').not('.chosen').each(select_value).change(select_value);
127
+
128
+ //Open select multiple
129
+ $('.metaboxes-tab .select_wrapper').click( function(e){
130
+ e.stopPropagation();
131
+ $(this).find('select[multiple]').not('.chosen').toggle();
132
+ });
133
+ //Stops click propagation on select, to prevent select hide
134
+ $('.metaboxes-tab .select_wrapper select[multiple]').not('.chosen').click( function(e){
135
+ e.stopPropagation();
136
+ });
137
+ //Hides select on window click
138
+ $(window).click(function(){
139
+ $('.metaboxes-tab .select_wrapper select[multiple]').not('.chosen').hide();
140
+ })
141
+
142
+ //on-off
143
+ $('.metaboxes-tab .onoff_container span').on('click', function(){
144
+
145
+ var input = $( this ).prev( 'input' );
146
+ var checked = input.prop( 'checked' );
147
+
148
+ if( checked ) {
149
+ input.prop( 'checked', false ).attr( 'value', 'no' ).removeClass('onoffchecked');
150
+ } else {
151
+ input.prop( 'checked', true ).attr( 'value', 'yes' ).addClass('onoffchecked');
152
+ }
153
+
154
+ input.change();
155
+ });
156
+
157
+ //chosen
158
+ $('.metaboxes-tab .chosen .select_wrapper select').chosen();
159
+
160
+
161
+ $('.metaboxes-tab .slider_container .ui-slider-horizontal').each(function(){
162
+ var val = $(this).data('val');
163
+ var minValue = $(this).data('min');
164
+ var maxValue = $(this).data('max');
165
+ var step = $(this).data('step');
166
+ var labels = $(this).data('labels');
167
+
168
+ $(this).slider({
169
+ value: val,
170
+ min: minValue,
171
+ max: maxValue,
172
+ range: 'min',
173
+ step: step,
174
+
175
+ slide: function( event, ui ) {
176
+ $(this).find('input').val( ui.value );
177
+ $(this).siblings('.feedback').find('strong' ).text( ui.value + labels );
178
+ }
179
+ });
180
+ });
181
+
182
+
183
+ var act_page_option = $('#_active_page_options-container').parent().html();
184
+ $('#_active_page_options-container').parent().remove();
185
+ $(act_page_option).insertAfter('#yit-post-setting .handlediv');
186
+ $(act_page_option).insertAfter('#yit-page-setting .handlediv');
187
+
188
+
189
+ $('#_active_page_options-container').on('click', function(){
190
+ if( $('#_active_page_options').is(":checked") ){
191
+ $('#yit-page-setting .inside .metaboxes-tab, #yit-post-setting .inside .metaboxes-tab').css( { 'opacity' : 1 , 'pointer-events' : 'auto' } );
192
+ }else{
193
+ $('#yit-page-setting .inside .metaboxes-tab, #yit-post-setting .inside .metaboxes-tab').css( { 'opacity' : 0.5 , 'pointer-events' : 'none' } );
194
+ }
195
+ }).click();
196
+
197
+
198
+ //dependencies handler
199
+ $('.metaboxes-tab [data-field]').each(function(){
200
+ var t = $(this);
201
+
202
+ var field = '#' + t.data('field'),
203
+ dep = '#' + t.data('dep'),
204
+ value = t.data('value');
205
+
206
+
207
+ dependencies_handler( field, dep, value.toString() );
208
+
209
+ $(dep).on('change', function(){
210
+ dependencies_handler( field, dep, value.toString() );
211
+ }).change();
212
+ });
213
+
214
+ //Handle dependencies.
215
+ function dependencies_handler ( id, deps, values ) {
216
+ var result = true;
217
+
218
+
219
+ //Single dependency
220
+ if( typeof( deps ) == 'string' ) {
221
+ if( deps.substr( 0, 6 ) == ':radio' )
222
+ {deps = deps + ':checked'; }
223
+
224
+ var val = $( deps ).val();
225
+
226
+ if( $(deps).attr('type') == 'checkbox'){
227
+ var thisCheck = $(deps);
228
+ if ( thisCheck.is ( ':checked' ) ) {
229
+ val = 'yes';
230
+ }
231
+ else {
232
+ val = 'no';
233
+ }
234
+ }
235
+
236
+ var values = values.split( ',' );
237
+
238
+ for( var i = 0; i < values.length; i++ ) {
239
+ if( val != values[i] )
240
+ { result = false; }
241
+ else
242
+ { result = true; break; }
243
+ }
244
+ }
245
+
246
+ if( !result ) {
247
+ $( id + '-container' ).parent().hide();
248
+ } else {
249
+ $( id + '-container' ).parent().show();
250
+ }
251
+ };
252
+
253
+ // Image gallery
254
+ $(document).on('click', '.image-gallery-button', function (e) {
255
+ var $t = $(this),
256
+ $container = $t.closest('.image-gallery'),
257
+ $image_gallery_ids = $container.find('.image_gallery_ids'),
258
+ attachment_ids = $image_gallery_ids.val(),
259
+ $gallery_images_wrapper = $container.find('ul.slides-wrapper');
260
+
261
+
262
+ // Create the media frame.
263
+ var image_gallery_frame = wp.media.frames.image_gallery = wp.media({
264
+ // Set the title of the modal.
265
+ title : $t.data('choose'),
266
+ button: {
267
+ text: $t.data('update')
268
+ },
269
+ states: [
270
+ new wp.media.controller.Library({
271
+ title : $t.data('choose'),
272
+ filterable: 'all',
273
+ multiple : true
274
+ })
275
+ ]
276
+ });
277
+
278
+ // When an image is selected, run a callback.
279
+ image_gallery_frame.on('select', function () {
280
+ var selection = image_gallery_frame.state().get('selection');
281
+ selection.map(function (attachment) {
282
+ attachment = attachment.toJSON();
283
+
284
+ if (attachment.id) {
285
+ attachment_ids = attachment_ids ? attachment_ids + "," + attachment.id : attachment.id;
286
+ $gallery_images_wrapper.append('<li class="image" data-attachment_id="' + attachment.id + '"><img src="' + attachment.sizes.thumbnail.url + '"/><ul class="actions"><li><a href="#" class="delete" title="' + $t.data('delete') + '">x</a></li></ul></li>');
287
+ }
288
+ });
289
+
290
+ $image_gallery_ids.val(attachment_ids);
291
+ });
292
+
293
+ image_gallery_frame.open();
294
+
295
+ });
296
+
297
+ // Image ordering
298
+ $('.image-gallery ul.slides-wrapper').each(function(){
299
+ var $t = $(this);
300
+ $t.sortable({
301
+ items : 'li.image',
302
+ cursor : 'move',
303
+ scrollSensitivity : 40,
304
+ forcePlaceholderSize: true,
305
+ forceHelperSize : false,
306
+ helper : 'clone',
307
+ opacity : 0.65,
308
+ start : function (event, ui) {
309
+ ui.item.css('background-color', '#f6f6f6');
310
+ },
311
+ stop : function (event, ui) {
312
+ ui.item.removeAttr('style');
313
+ },
314
+ update : function (event, ui) {
315
+ var attachment_ids = '';
316
+
317
+ $t.find('li.image').css('cursor', 'default').each(function () {
318
+ var attachment_id = $(this).attr('data-attachment_id');
319
+ attachment_ids = attachment_ids + attachment_id + ',';
320
+ });
321
+
322
+ $t.closest('.image-gallery').find('.image_gallery_ids').val(attachment_ids);
323
+ }
324
+ });
325
+ });
326
+
327
+ // Remove images
328
+ $('.image-gallery ul.slides-wrapper').on( 'click', 'a.delete', function() {
329
+
330
+ var $wrapper = $(this).closest('.image-gallery'),
331
+ $gallery = $(this).closest('.image-gallery ul.slides-wrapper'),
332
+ $image_gallery_ids = $wrapper.find('.image_gallery_ids'),
333
+ attachment_ids = '';
334
+
335
+ $(this).closest('li.image').remove();
336
+
337
+ $gallery.find('li.image').css('cursor','default').each(function() {
338
+ var attachment_id = $(this).attr( 'data-attachment_id' );
339
+ attachment_ids = attachment_ids + attachment_id + ',';
340
+ });
341
+
342
+ $image_gallery_ids.val( attachment_ids );
343
+
344
+ return false;
345
+ });
346
+
347
+
348
+
349
+
350
+ })(jQuery);
plugin-fw/assets/js/metabox.min.js ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ (function(a){function k(b,c,d){var e=!0;if("string"==typeof c){":radio"==c.substr(0,6)&&(c+=":checked");var g=a(c).val();"checkbox"==a(c).attr("type")&&(g=a(c).is(":checked")?"yes":"no");d=d.split(",");for(c=0;c<d.length;c++)if(g!=d[c])e=!1;else{e=!0;break}}e?a(b+"-container").parent().show():a(b+"-container").parent().hide()}a(".metaboxes-tab").each(function(){a(".tabs-panel",this).hide();var b=wpCookies.get("active_metabox_tab"),b=null==b?a("ul.metaboxes-tabs li:first-child a",this).attr("href"):
2
+ "#"+b;a(b).show();a(".metaboxes-tabs a",this).click(function(b){if(a(this).parent().hasClass("tabs"))b.preventDefault();else return b=a(this).attr("href"),a(this).parent().addClass("tabs").siblings("li").removeClass("tabs"),a(".tabs-panel").slideUp("fast"),a(b).delay(350).slideDown("fast"),!1})});var h=!0,l=wp.media.editor.send.attachment;a(document).on("click",".metaboxes-tab .upload_button",function(b){b=a(this);var c=b.attr("id").replace("-button","");h=!0;wp.media.editor.send.attachment=function(b,
3
+ e){if(h)a("#"+c).is("input[type=text]")?a("#"+c).val(e.url):a("#"+c+"_custom").val(e.url);else return l.apply(this,[b,e])};wp.media.editor.open(b);return!1});a(".metaboxes-tab .add_media").on("click",function(){h=!1});a(".metaboxes-tab .panel-colorpicker").wpColorPicker({onInit:function(){console.log("test")},change:function(a,c){},clear:function(){var b=a(this);b.val(b.data("default-color"));b.change()}});a(".metaboxes-tab .panel-colorpicker").each(function(){var b=a(this).data("variations-label");
4
+ a(this).parent().parent().find("a.wp-color-result").attr("title",b)});a(".metaboxes-tab .panel-datepicker").each(function(){a(this).datepicker()});var f=function(){var b="";a(this).attr("multiple")?(a(this).children("option:selected").each(function(c,d){0!=c&&(b+=", ");b+=a(d).text()}),""==b&&a(this).children().children("option:selected").each(function(c,d){0!=c&&(b+=", ");b+=a(d).text()})):(b=a(this).children("option:selected").text(),""==b&&(b=a(this).children().children("option:selected").text()));
5
+ 0>=a(this).parent().find("span").length&&a(this).before("<span></span>");a(this).parent().children("span").replaceWith("<span>"+b+"</span>")};a(".metaboxes-tab .select_wrapper select").not(".chosen").each(f).change(f);a(".metaboxes-tab .select_wrapper").click(function(b){b.stopPropagation();a(this).find("select[multiple]").not(".chosen").toggle()});a(".metaboxes-tab .select_wrapper select[multiple]").not(".chosen").click(function(a){a.stopPropagation()});a(window).click(function(){a(".metaboxes-tab .select_wrapper select[multiple]").not(".chosen").hide()});
6
+ a(".metaboxes-tab .onoff_container span").on("click",function(){var b=a(this).prev("input");b.prop("checked")?b.prop("checked",!1).attr("value","no").removeClass("onoffchecked"):b.prop("checked",!0).attr("value","yes").addClass("onoffchecked");b.change()});a(".metaboxes-tab .chosen .select_wrapper select").chosen();a(".metaboxes-tab .slider_container .ui-slider-horizontal").each(function(){var b=a(this).data("val"),c=a(this).data("min"),d=a(this).data("max"),e=a(this).data("step"),g=a(this).data("labels");
7
+ a(this).slider({value:b,min:c,max:d,range:"min",step:e,slide:function(b,c){a(this).find("input").val(c.value);a(this).siblings(".feedback").find("strong").text(c.value+g)}})});f=a("#_active_page_options-container").parent().html();a("#_active_page_options-container").parent().remove();a(f).insertAfter("#yit-post-setting .handlediv");a(f).insertAfter("#yit-page-setting .handlediv");a("#_active_page_options-container").on("click",function(){a("#_active_page_options").is(":checked")?a("#yit-page-setting .inside .metaboxes-tab, #yit-post-setting .inside .metaboxes-tab").css({opacity:1,
8
+ "pointer-events":"auto"}):a("#yit-page-setting .inside .metaboxes-tab, #yit-post-setting .inside .metaboxes-tab").css({opacity:.5,"pointer-events":"none"})}).click();a(".metaboxes-tab [data-field]").each(function(){var b=a(this),c="#"+b.data("field"),d="#"+b.data("dep"),e=b.data("value");k(c,d,e.toString());a(d).on("change",function(){k(c,d,e.toString())}).change()});a(document).on("click",".image-gallery-button",function(b){var c=a(this);b=c.closest(".image-gallery");var d=b.find(".image_gallery_ids"),
9
+ e=d.val(),g=b.find("ul.slides-wrapper"),f=wp.media.frames.image_gallery=wp.media({title:c.data("choose"),button:{text:c.data("update")},states:[new wp.media.controller.Library({title:c.data("choose"),filterable:"all",multiple:!0})]});f.on("select",function(){f.state().get("selection").map(function(a){a=a.toJSON();a.id&&(e=e?e+","+a.id:a.id,g.append('<li class="image" data-attachment_id="'+a.id+'"><img src="'+a.sizes.thumbnail.url+'"/><ul class="actions"><li><a href="#" class="delete" title="'+c.data("delete")+
10
+ '">x</a></li></ul></li>'))});d.val(e)});f.open()});a(".image-gallery ul.slides-wrapper").each(function(){var b=a(this);b.sortable({items:"li.image",cursor:"move",scrollSensitivity:40,forcePlaceholderSize:!0,forceHelperSize:!1,helper:"clone",opacity:.65,start:function(a,b){b.item.css("background-color","#f6f6f6")},stop:function(a,b){b.item.removeAttr("style")},update:function(c,d){var e="";b.find("li.image").css("cursor","default").each(function(){var b=a(this).attr("data-attachment_id");e=e+b+","});
11
+ b.closest(".image-gallery").find(".image_gallery_ids").val(e)}})});a(".image-gallery ul.slides-wrapper").on("click","a.delete",function(){var b=a(this).closest(".image-gallery"),c=a(this).closest(".image-gallery ul.slides-wrapper"),b=b.find(".image_gallery_ids"),d="";a(this).closest("li.image").remove();c.find("li.image").css("cursor","default").each(function(){var b=a(this).attr("data-attachment_id");d=d+b+","});b.val(d);return!1})})(jQuery);
plugin-fw/assets/js/multisite-updater.js ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+ (function ($) {
10
+
11
+ var plugins_menu_item = $( '#menu-plugins' ),
12
+ update = plugins_menu_item.find('.update-plugins'),
13
+ count = update.find(".update-count").text(),
14
+ registered = plugins.registered,
15
+ activated = plugins.activated;
16
+
17
+ if( count == 0 || count == ''){
18
+ var update_row = '<span class="update-plugins"><span class="plugin-count"></span></span>';
19
+ count = 0;
20
+ plugins_menu_item.find( '.wp-menu-name').append( update_row );
21
+ }
22
+
23
+ /**
24
+ * Add the plugin update rows for old plugins
25
+ */
26
+ update_plugins_row( registered, activated, count, plugins );
27
+
28
+ /**
29
+ *
30
+ * Add the update plugin rows for old plugin
31
+ *
32
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
33
+ *
34
+ * @param registered Registred plugins
35
+ * @param activated Activated plugins
36
+ * @param count Number of old plugins
37
+ * @param localize Localize strings array
38
+ *
39
+ * @return void
40
+ */
41
+ function update_plugins_row( registered, activated, count, localize ){
42
+ for( var init in registered ){
43
+ var plugin = registered[init];
44
+ for( var headers in plugin ){
45
+
46
+ if( headers == 'slug' || version_compare( plugin[headers].Version, plugin[headers].Latest, '>=' ) ) {
47
+ continue;
48
+ }
49
+
50
+ count = parseInt(count) + 1;
51
+ $(".plugin-count").empty().html(count);
52
+
53
+ var regex = new RegExp(' ', 'g'),
54
+ info = plugin[headers],
55
+ name = '' + info.Name,
56
+ id = name.replace(regex, '-').trim(),
57
+ row = '#' + id.toLowerCase();
58
+
59
+ $(row).addClass("update");
60
+
61
+ var html = '<tr class="plugin-update-tr">' +
62
+ '<td colspan="3" class="plugin-update colspanchange">' +
63
+ '<div class="update-message">' + localize.strings.new_version.replace( '%plugin_name%', name ) +
64
+ '<a class="thickbox" href="' + localize.details_url[init] + '">' + localize.strings.latest.replace( '%latest%', plugin[headers].Latest ) + '</a>';
65
+
66
+ if( typeof activated[init] == "undefined" ) {
67
+
68
+ html = html +
69
+ ' <em>' + localize.strings.unavailable + '</em>' +
70
+ localize.strings.activate.replace( '%activate_link%', localize.licence_activation_url ).replace( '%plugin_name%', name );
71
+ } else {
72
+ html = html +
73
+ '. <a href="' + localize.update_url[init] + '">' + localize.strings.update_now + '</a>';
74
+ }
75
+
76
+ if( typeof localize.changelogs[init] != 'undefined' ){
77
+ html = html + localize.changelogs[init];
78
+ }
79
+
80
+ html = html +
81
+ '</div>' +
82
+ '</td>' +
83
+ '</tr>';
84
+
85
+ $(html).insertAfter(row);
86
+ }
87
+ }
88
+ }
89
+
90
+ /**
91
+ *
92
+ * @param v1 Version 1
93
+ * @param v2 Version 2
94
+ * @param operator Compare type
95
+ * @returns bool
96
+ *
97
+ * @see php.js library http://phpjs.org/
98
+ */
99
+ function version_compare(v1, v2, operator) {
100
+ // discuss at: http://phpjs.org/functions/version_compare/
101
+ // original by: Philippe Jausions (http://pear.php.net/user/jausions)
102
+ // original by: Aidan Lister (http://aidanlister.com/)
103
+ // reimplemented by: Kankrelune (http://www.webfaktory.info/)
104
+ // improved by: Brett Zamir (http://brett-zamir.me)
105
+ // improved by: Scott Baker
106
+ // improved by: Theriault
107
+ // example 1: version_compare('8.2.5rc', '8.2.5a');
108
+ // returns 1: 1
109
+ // example 2: version_compare('8.2.50', '8.2.52', '<');
110
+ // returns 2: true
111
+ // example 3: version_compare('5.3.0-dev', '5.3.0');
112
+ // returns 3: -1
113
+ // example 4: version_compare('4.1.0.52','4.01.0.51');
114
+ // returns 4: 1
115
+
116
+ this.php_js = this.php_js || {};
117
+ this.php_js.ENV = this.php_js.ENV || {};
118
+ // END REDUNDANT
119
+ // Important: compare must be initialized at 0.
120
+ var i = 0,
121
+ x = 0,
122
+ compare = 0,
123
+ // vm maps textual PHP versions to negatives so they're less than 0.
124
+ // PHP currently defines these as CASE-SENSITIVE. It is important to
125
+ // leave these as negatives so that they can come before numerical versions
126
+ // and as if no letters were there to begin with.
127
+ // (1alpha is < 1 and < 1.1 but > 1dev1)
128
+ // If a non-numerical value can't be mapped to this table, it receives
129
+ // -7 as its value.
130
+ vm = {
131
+ 'dev' : -6,
132
+ 'alpha': -5,
133
+ 'a' : -5,
134
+ 'beta' : -4,
135
+ 'b' : -4,
136
+ 'RC' : -3,
137
+ 'rc' : -3,
138
+ '#' : -2,
139
+ 'p' : 1,
140
+ 'pl' : 1
141
+ },
142
+ // This function will be called to prepare each version argument.
143
+ // It replaces every _, -, and + with a dot.
144
+ // It surrounds any nonsequence of numbers/dots with dots.
145
+ // It replaces sequences of dots with a single dot.
146
+ // version_compare('4..0', '4.0') == 0
147
+ // Important: A string of 0 length needs to be converted into a value
148
+ // even less than an unexisting value in vm (-7), hence [-8].
149
+ // It's also important to not strip spaces because of this.
150
+ // version_compare('', ' ') == 1
151
+ prepVersion = function (v) {
152
+ v = ('' + v)
153
+ .replace(/[_\-+]/g, '.');
154
+ v = v.replace(/([^.\d]+)/g, '.$1.')
155
+ .replace(/\.{2,}/g, '.');
156
+ return (!v.length ? [-8] : v.split('.'));
157
+ };
158
+ // This converts a version component to a number.
159
+ // Empty component becomes 0.
160
+ // Non-numerical component becomes a negative number.
161
+ // Numerical component becomes itself as an integer.
162
+ numVersion = function (v) {
163
+ return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10));
164
+ };
165
+ v1 = prepVersion(v1);
166
+ v2 = prepVersion(v2);
167
+ x = Math.max(v1.length, v2.length);
168
+ for (i = 0; i < x; i++) {
169
+ if (v1[i] == v2[i]) {
170
+ continue;
171
+ }
172
+ v1[i] = numVersion(v1[i]);
173
+ v2[i] = numVersion(v2[i]);
174
+ if (v1[i] < v2[i]) {
175
+ compare = -1;
176
+ break;
177
+ } else if (v1[i] > v2[i]) {
178
+ compare = 1;
179
+ break;
180
+ }
181
+ }
182
+ if (!operator) {
183
+ return compare;
184
+ }
185
+
186
+ // Important: operator is CASE-SENSITIVE.
187
+ // "No operator" seems to be treated as "<."
188
+ // Any other values seem to make the function return null.
189
+ switch (operator) {
190
+ case '>':
191
+ case 'gt':
192
+ return (compare > 0);
193
+ case '>=':
194
+ case 'ge':
195
+ return (compare >= 0);
196
+ case '<=':
197
+ case 'le':
198
+ return (compare <= 0);
199
+ case '==':
200
+ case '=':
201
+ case 'eq':
202
+ return (compare === 0);
203
+ case '<>':
204
+ case '!=':
205
+ case 'ne':
206
+ return (compare !== 0);
207
+ case '':
208
+ case '<':
209
+ case 'lt':
210
+ return (compare < 0);
211
+ default:
212
+ return null;
213
+ }
214
+ }
215
+
216
+ })(jQuery);
plugin-fw/assets/js/multisite-updater.min.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ (function(m){function n(c,d,k){this.php_js=this.php_js||{};this.php_js.ENV=this.php_js.ENV||{};var a=0,e=0,b=0,f={dev:-6,alpha:-5,a:-5,beta:-4,b:-4,RC:-3,rc:-3,"#":-2,p:1,pl:1},a=function(a){a=(""+a).replace(/[_\-+]/g,".");a=a.replace(/([^.\d]+)/g,".$1.").replace(/\.{2,}/g,".");return a.length?a.split("."):[-8]};numVersion=function(a){return a?isNaN(a)?f[a]||-7:parseInt(a,10):0};c=a(c);d=a(d);e=Math.max(c.length,d.length);for(a=0;a<e;a++)if(c[a]!=d[a])if(c[a]=numVersion(c[a]),d[a]=numVersion(d[a]),
2
+ c[a]<d[a]){b=-1;break}else if(c[a]>d[a]){b=1;break}if(!k)return b;switch(k){case ">":case "gt":return 0<b;case ">=":case "ge":return 0<=b;case "<=":case "le":return 0>=b;case "==":case "=":case "eq":return 0===b;case "<>":case "!=":case "ne":return 0!==b;case "":case "<":case "lt":return 0>b;default:return null}}var l=m("#menu-plugins"),g=l.find(".update-plugins").find(".update-count").text(),p=plugins.registered,q=plugins.activated;if(0==g||""==g)g=0,l.find(".wp-menu-name").append('<span class="update-plugins"><span class="plugin-count"></span></span>');
3
+ (function(c,d,k,a){for(var e in c){var b=c[e],f;for(f in b)if("slug"!=f&&!n(b[f].Version,b[f].Latest,">=")){k=parseInt(k)+1;m(".plugin-count").empty().html(k);var g=""+b[f].Name,l="#"+g.replace(RegExp(" ","g"),"-").trim().toLowerCase();m(l).addClass("update");var h='<tr class="plugin-update-tr"><td colspan="3" class="plugin-update colspanchange"><div class="update-message">'+a.strings.new_version.replace("%plugin_name%",g)+'<a class="thickbox" href="'+a.details_url[e]+'">'+a.strings.latest.replace("%latest%",
4
+ b[f].Latest)+"</a>",h="undefined"==typeof d[e]?h+" <em>"+a.strings.unavailable+"</em>"+a.strings.activate.replace("%activate_link%",a.licence_activation_url).replace("%plugin_name%",g):h+'. <a href="'+a.update_url[e]+'">'+a.strings.update_now+"</a>";"undefined"!=typeof a.changelogs[e]&&(h+=a.changelogs[e]);h+="</div></td></tr>";m(h).insertAfter(l)}}})(p,q,g,plugins)})(jQuery);
plugin-fw/assets/js/panel.spinner.js ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Spinner for jQuery (version 0.1)
3
+ Copyright (c) 2012 Simone D'Amico
4
+ http://simonedamico.com/
5
+
6
+ Licensed under the MIT license:
7
+ http://www.opensource.org/licenses/mit-license.php
8
+
9
+ Any and all use of this script must be accompanied by this copyright/license notice in its present form.
10
+
11
+ */
12
+ (function($){
13
+ $.fn.spinner = function(params) {
14
+
15
+ //private methods
16
+ var _createButton = function( buttonClass, buttonLabel ) {
17
+ return $('<button/>', {
18
+ 'class' : buttonClass + ' spinner-button',
19
+ text : buttonLabel
20
+ });
21
+ };
22
+
23
+ var _createBody = function(input) {
24
+ //create wrapper
25
+ var wrapper = input.wrap('<div class="spinner-wrapper"></div>').parent();
26
+
27
+ //create spinner buttons
28
+ var plus = _createButton('button-plus', '+').appendTo(wrapper).show(),
29
+ minus = _createButton('button-minus', '-').appendTo(wrapper).show();
30
+
31
+ return wrapper;
32
+ };
33
+
34
+ var _buttonClick = function( e ) {
35
+ var input = e.data.input,
36
+ params = e.data.params,
37
+ button = $(this),
38
+ value = parseFloat(input.val());
39
+
40
+ if( button.hasClass('button-plus') ) {
41
+ if( params.max != null ) {
42
+ if( ( value + params.interval ) <= params.max ) {
43
+ input.val( value + params.interval );
44
+ } else {
45
+ input.val( params.max );
46
+ }
47
+ } else {
48
+ input.val( value + params.interval );
49
+ }
50
+ } else if( button.hasClass('button-minus') ) {
51
+ if( params.min != null ) {
52
+ if( ( value - params.interval ) >= params.min ) {
53
+ input.val( value - params.interval );
54
+ } else {
55
+ input.val( params.min );
56
+ }
57
+ } else {
58
+ input.val( value - params.interval );
59
+ }
60
+ }
61
+
62
+ input.change(); e.preventDefault();
63
+ };
64
+
65
+ var _validateContent = function( e ) {
66
+ var value = parseFloat( $(this).val() );
67
+
68
+ if( params.max != null && value >= params.max ) {
69
+ $(this).val(params.max);
70
+ } else if( value <= params.min || isNaN( value ) ) {
71
+ $(this).val(params.min ? params.min : 0);
72
+ } else {
73
+ $(this).val(value);
74
+ }
75
+ };
76
+
77
+
78
+ //public methods
79
+ var methods = {
80
+ init : function( params ) {
81
+
82
+ var params = $.extend({
83
+ min: null,
84
+ max: null,
85
+ interval: 1,
86
+ defaultValue: 0,
87
+ mouseWheel: true,
88
+ largeInterval: 10
89
+ }, params);
90
+
91
+ var self = this,
92
+ t = $(this),
93
+ data = t.data('spinner');
94
+
95
+ return this.each(function(){
96
+ //check if the plugin hasn't already been initialized
97
+ //and it's an input[type=text] element
98
+ if( !data && t.is(':text') ) {
99
+ //initialize the value
100
+ if( params.defaultValue ) {
101
+ t.val( params.defaultValue );
102
+ }
103
+
104
+ //create the spinner body
105
+ var wrapper = _createBody(t);
106
+
107
+ //event handlers
108
+ //var mouseWheelEventName = $.browser.mozilla ? 'DOMMouseScroll' : 'mousewheel';
109
+
110
+ wrapper.find('.spinner-button')
111
+ .bind('click.spinner', { params: params, input: t }, _buttonClick);
112
+
113
+ t.bind('blur.spinner', _validateContent)
114
+ //.bind('keyup.spinner', _validateKey)
115
+ //.bind(mouseWheelEventName, _inputMousewheel);
116
+
117
+ //register field data
118
+ t.data('spinner', {
119
+ target: self
120
+ });
121
+ }
122
+ });
123
+ },
124
+
125
+ destroy : function( params) {
126
+ console.log('destroy', params);
127
+ }
128
+ };
129
+
130
+ //execute the plugin
131
+ if ( methods[params] ) {
132
+ return methods[params].apply( this, Array.prototype.slice.call( arguments, 1 ));
133
+ } else if ( typeof params === 'object' || ! params ) {
134
+ return methods.init.apply( this, arguments );
135
+ } else {
136
+ $.error( 'Method ' + params + ' does not exist' );
137
+ }
138
+ };
139
+ })(jQuery);
plugin-fw/assets/js/panel.spinner.min.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ (function(d){d.fn.spinner=function(c){var h=function(b,e){return d("<button/>",{"class":b+" spinner-button",text:e})},k=function(b){var e=b.data.input,a=b.data.params,c=d(this),f=parseFloat(e.val());c.hasClass("button-plus")?null!=a.max?f+a.interval<=a.max?e.val(f+a.interval):e.val(a.max):e.val(f+a.interval):c.hasClass("button-minus")&&(null!=a.min?f-a.interval>=a.min?e.val(f-a.interval):e.val(a.min):e.val(f-a.interval));e.change();b.preventDefault()},l=function(b){b=parseFloat(d(this).val());null!=
2
+ c.max&&b>=c.max?d(this).val(c.max):b<=c.min||isNaN(b)?d(this).val(c.min?c.min:0):d(this).val(b)},g={init:function(b){b=d.extend({min:null,max:null,interval:1,defaultValue:0,mouseWheel:!0,largeInterval:10},b);var c=this,a=d(this),g=a.data("spinner");return this.each(function(){if(!g&&a.is(":text")){b.defaultValue&&a.val(b.defaultValue);var d=a.wrap('<div class="spinner-wrapper"></div>').parent();h("button-plus","+").appendTo(d).show();h("button-minus","-").appendTo(d).show();d.find(".spinner-button").bind("click.spinner",
3
+ {params:b,input:a},k);a.bind("blur.spinner",l);a.data("spinner",{target:c})}})},destroy:function(b){console.log("destroy",b)}};if(g[c])return g[c].apply(this,Array.prototype.slice.call(arguments,1));if("object"!==typeof c&&c)d.error("Method "+c+" does not exist");else return g.init.apply(this,arguments)}})(jQuery);
plugin-fw/assets/js/yit-cpt-unlimited.js ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+ (function($) {
11
+ "use strict";
12
+ // Author code here
13
+
14
+ // open media box
15
+ $('.wrap h2').on( 'click', 'a.multi-uploader', function(event){
16
+ event.preventDefault();
17
+
18
+ var file_frame,
19
+ button = $(this),
20
+ selected = false;
21
+
22
+ // spinner
23
+ button.next('span.spinner').css( 'display', 'inline-block' );
24
+
25
+ // If the media frame already exists, reopen it.
26
+ if ( file_frame ) {
27
+ file_frame.open();
28
+ return;
29
+ }
30
+
31
+ // Create the media frame.
32
+ file_frame = wp.media.frames.file_frame = wp.media({
33
+ title: button.data( 'uploader_title' ),
34
+ button: {
35
+ text: button.data( 'uploader_button_text' )
36
+ },
37
+ library: {
38
+ type: 'image'
39
+ },
40
+ multiple: true // Set to true to allow multiple files to be selected
41
+ });
42
+
43
+ // When an image is selected, run a callback.
44
+ file_frame.on( 'select', function() {
45
+ var selection = file_frame.state().get('selection'),
46
+ images = [];
47
+
48
+ selection.map( function( attachment ) {
49
+ attachment = attachment.toJSON();
50
+
51
+ // Do something with attachment.id and/or attachment.url here
52
+ images.push( { id: attachment.id, url: attachment.url, title: attachment.title } );
53
+ });
54
+
55
+ // make AJAX request
56
+ $.post( ajaxurl, {
57
+ images: images,
58
+ post_type: typenow,
59
+ action: 'yit_cptu_multiuploader'
60
+ }, function( data ){
61
+ location.reload();
62
+ });
63
+
64
+ button.next('span.spinner').css( 'display', 'inline-block' );
65
+
66
+ // flag
67
+ selected = true;
68
+ });
69
+
70
+ // when close
71
+ file_frame.on( 'close', function() {
72
+ if ( ! selected ) button.next('span.spinner').hide();
73
+ });
74
+
75
+ // Finally, open the modal
76
+ file_frame.open();
77
+ });
78
+
79
+ })(jQuery);
plugin-fw/assets/js/yit-cpt-unlimited.min.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ (function(c){c(".wrap h2").on("click","a.multi-uploader",function(f){f.preventDefault();var a,b=c(this),d=!1;b.next("span.spinner").css("display","inline-block");a||(a=wp.media.frames.file_frame=wp.media({title:b.data("uploader_title"),button:{text:b.data("uploader_button_text")},library:{type:"image"},multiple:!0}),a.on("select",function(){var e=[];a.state().get("selection").map(function(a){a=a.toJSON();e.push({id:a.id,url:a.url,title:a.title})});c.post(ajaxurl,{images:e,post_type:typenow,action:"yit_cptu_multiuploader"},
2
+ function(a){location.reload()});b.next("span.spinner").css("display","inline-block");d=!0}),a.on("close",function(){d||b.next("span.spinner").hide()}));a.open()})})(jQuery);
plugin-fw/assets/js/yit-cptu-sortable-posts.js ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+ (function($) {
11
+ "use strict";
12
+ // Author code here
13
+
14
+ $("#the-list").sortable({
15
+ items : 'tr',
16
+ axis : 'y',
17
+ helper : function(e, ui) {
18
+ ui.children().children().each(function() {
19
+ $(this).width( $(this).width() );
20
+ });
21
+ return ui;
22
+ },
23
+ update : function(e, ui) {
24
+ $.post( ajaxurl, {
25
+ action: 'cpt_sort_posts',
26
+ order: $("#the-list").sortable("serialize"),
27
+ post_type: typenow
28
+ });
29
+ }
30
+ });
31
+
32
+ })(jQuery);
plugin-fw/assets/js/yit-plugin-panel.js ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Plugin Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+
11
+ (function ($) {
12
+
13
+ // select
14
+ var select_value = function () {
15
+
16
+ var value = '';
17
+
18
+ if ($(this).attr('multiple')) {
19
+ $(this).children("option:selected").each(function (i, v) {
20
+ if (i != 0)
21
+ value += ', ';
22
+
23
+ value += $(v).text();
24
+ });
25
+
26
+ if (value == '') {
27
+ $(this).children().children("option:selected").each(function (i, v) {
28
+ if (i != 0)
29
+ value += ', ';
30
+
31
+ value += $(v).text();
32
+ });
33
+ }
34
+ }
35
+ else {
36
+ value = $(this).children("option:selected").text();
37
+
38
+ if (value == '')
39
+ value = $(this).children().children("option:selected").text();
40
+ }
41
+
42
+
43
+ if ($(this).parent().find('span').length <= 0) {
44
+ $(this).before('<span></span>');
45
+ }
46
+
47
+ $(this).parent().children('span').replaceWith('<span>' + value + '</span>');
48
+ };
49
+ $('.plugin-option .select_wrapper select').not('.chosen').each(select_value).change(select_value);
50
+
51
+ //Open select multiple
52
+ $('.plugin-option .select_wrapper').click(function (e) {
53
+ e.stopPropagation();
54
+ $(this).find('select[multiple]').not('.chosen').toggle();
55
+ });
56
+ //Stops click propagation on select, to prevent select hide
57
+ $('.plugin-option .select_wrapper select[multiple]').not('.chosen').click(function (e) {
58
+ e.stopPropagation();
59
+ });
60
+ //Hides select on window click
61
+ $(window).click(function () {
62
+ $('.plugin-option .select_wrapper select[multiple]').not('.chosen').hide();
63
+ })
64
+ //chosen
65
+ $('.plugin-option .chosen .select_wrapper select').chosen();
66
+
67
+ // on-off
68
+ $('.plugin-option .on_off_container span').on('click', function () {
69
+ var input = $(this).prev('input');
70
+ var checked = input.prop('checked');
71
+
72
+ if (checked) {
73
+ input.prop('checked', false).attr('value', 'no').removeClass('onoffchecked');
74
+ } else {
75
+ input.prop('checked', true).attr('value', 'yes').addClass('onoffchecked');
76
+ }
77
+
78
+ input.change();
79
+ });
80
+
81
+
82
+ //slider
83
+ $('.plugin-option .slider_container .ui-slider-horizontal').each(function () {
84
+ var val = $(this).data('val');
85
+ var minValue = $(this).data('min');
86
+ var maxValue = $(this).data('max');
87
+ var step = $(this).data('step');
88
+ var labels = $(this).data('labels');
89
+
90
+ $(this).slider({
91
+ value: val,
92
+ min : minValue,
93
+ max : maxValue,
94
+ range: 'min',
95
+ step : step,
96
+
97
+ slide: function (event, ui) {
98
+ $(this).find('input').val(ui.value);
99
+ $(this).siblings('.feedback').find('strong').text(ui.value + labels);
100
+ }
101
+ });
102
+ });
103
+
104
+
105
+ if (typeof wp !== 'undefined' && typeof wp.media !== 'undefined') {
106
+
107
+ //upload
108
+ var _custom_media = true,
109
+ _orig_send_attachment = wp.media.editor.send.attachment;
110
+
111
+ // preview
112
+ $('.plugin-option .upload_img_url').change(function () {
113
+ var url = $(this).val();
114
+ var re = new RegExp("(http|ftp|https)://[a-zA-Z0-9@?^=%&amp;:/~+#-_.]*.(gif|jpg|jpeg|png|ico)");
115
+
116
+ var preview = $(this).parent().siblings('.upload_img_preview');
117
+ if (re.test(url)) {
118
+ preview.html('<img src="' + url + '" style="max-width:600px; max-height:300px;" />');
119
+ } else {
120
+ preview.html('');
121
+ }
122
+ }).change();
123
+
124
+ $(document).on('click', '.plugin-option .upload_button', function (e) {
125
+ var send_attachment_bkp = wp.media.editor.send.attachment;
126
+ var button = $(this);
127
+ var id = button.attr('id').replace('-button', '');
128
+ _custom_media = true;
129
+ wp.media.editor.send.attachment = function (props, attachment) {
130
+ if (_custom_media) {
131
+ if ($("#" + id).is('input[type=text]')) {
132
+ $("#" + id).val(attachment.url);
133
+ } else {
134
+ $("#" + id + '_custom').val(attachment.url);
135
+ }
136
+
137
+ } else {
138
+ return _orig_send_attachment.apply(this, [props, attachment]);
139
+ }
140
+ ;
141
+ }
142
+
143
+ wp.media.editor.open(button);
144
+ return false;
145
+ });
146
+
147
+ }
148
+
149
+ $('.plugin-option .add_media').on('click', function () {
150
+ _custom_media = false;
151
+ });
152
+
153
+ //dependencies handler
154
+ $('[data-field]').each(function () {
155
+ var t = $(this);
156
+
157
+ var field = '#' + t.data('field'),
158
+ dep = '#' + t.data('dep'),
159
+ value = t.data('value');
160
+
161
+ $(dep).on('change',function () {
162
+ dependencies_handler(field, dep, value.toString());
163
+ }).change();
164
+ });
165
+
166
+ //Handle dependencies.
167
+ function dependencies_handler(id, deps, values) {
168
+ var result = true;
169
+
170
+ //Single dependency
171
+ if (typeof( deps ) == 'string') {
172
+ if (deps.substr(0, 6) == ':radio') {
173
+ deps = deps + ':checked';
174
+ }
175
+
176
+ var values = values.split(',');
177
+
178
+ for (var i = 0; i < values.length; i++) {
179
+
180
+ if ($(deps).val() != values[i]) {
181
+ result = false;
182
+ }
183
+ else {
184
+ result = true;
185
+ break;
186
+ }
187
+ }
188
+ }
189
+
190
+ if (!result) {
191
+ $(id + '-container').closest('tr').hide();
192
+ } else {
193
+ $(id + '-container').closest('tr').show();
194
+ }
195
+ };
196
+
197
+ //connected list
198
+ $('.rm_connectedlist').each(function () {
199
+ var ul = $(this).find('ul');
200
+ var input = $(this).find(':hidden');
201
+ var sortable = ul.sortable({
202
+ connectWith: ul,
203
+ update : function (event, ui) {
204
+ var value = {};
205
+
206
+ ul.each(function () {
207
+ var options = {};
208
+
209
+ $(this).children().each(function () {
210
+ options[ $(this).data('option') ] = $(this).text();
211
+ });
212
+
213
+ value[ $(this).data('list') ] = options;
214
+ });
215
+
216
+ input.val((JSON.stringify(value)).replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0'));
217
+ }
218
+ }).disableSelection();
219
+ });
220
+
221
+ $(document).ready(function () {
222
+
223
+ $('.yith-video-link').click(function (event) {
224
+ event.preventDefault();
225
+ var target = $(this).data('video-id');
226
+
227
+ $('.' + target).dialog({
228
+ dialogClass : 'wp-dialog yit-dialog yit-video-dialog',
229
+ modal : true,
230
+ closeOnEscape: true,
231
+ width : 'auto',
232
+ resizable : false,
233
+ draggable : false,
234
+ create : function (event, ui) {
235
+ $(this).css("maxWidth", "853px");
236
+ },
237
+ open : function (event, ui) {
238
+
239
+ $('.ui-widget-overlay').bind('click', function () {
240
+ $(this).siblings('.ui-dialog').find('.ui-dialog-content').dialog('close');
241
+ });
242
+
243
+ }
244
+
245
+ });
246
+
247
+ $('.ui-dialog :button').blur();
248
+
249
+ });
250
+ });
251
+
252
+ //codemirror
253
+ $(document).ready(function () {
254
+ $('.codemirror').each(function (i, v) {
255
+ var editor = CodeMirror.fromTextArea(v, {
256
+ lineNumbers : 1,
257
+ mode : 'javascript',
258
+ showCursorWhenSelecting: true
259
+ })
260
+
261
+ $(v).data('codemirrorInstance', editor);
262
+ })
263
+ })
264
+
265
+ //google analytics generation
266
+ $(document).ready(function () {
267
+ $('.google-analytic-generate').click(function () {
268
+ var editor = $('#' + $(this).data('textarea')).data('codemirrorInstance');
269
+ var gatc = $('#' + $(this).data('input')).val();
270
+ var basename = $(this).data('basename');
271
+
272
+ var text = "(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n";
273
+ text += "(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement( o ),\n";
274
+ text += "m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n";
275
+ text += "})(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n";
276
+ text += "ga('create', '" + gatc + "', '" + basename + "');\n";
277
+ text += "ga('send', 'pageview');\n";
278
+ editor.replaceRange(
279
+ text,
280
+ editor.getCursor('start'),
281
+ editor.getCursor('end')
282
+ )
283
+ })
284
+ })
285
+
286
+ })(jQuery);
plugin-fw/assets/js/yit-plugin-panel.min.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ (function(a){var k=function(){var b="";a(this).attr("multiple")?(a(this).children("option:selected").each(function(c,e){0!=c&&(b+=", ");b+=a(e).text()}),""==b&&a(this).children().children("option:selected").each(function(c,e){0!=c&&(b+=", ");b+=a(e).text()})):(b=a(this).children("option:selected").text(),""==b&&(b=a(this).children().children("option:selected").text()));0>=a(this).parent().find("span").length&&a(this).before("<span></span>");a(this).parent().children("span").replaceWith("<span>"+b+
2
+ "</span>")};a(".plugin-option .select_wrapper select").not(".chosen").each(k).change(k);a(".plugin-option .select_wrapper").click(function(b){b.stopPropagation();a(this).find("select[multiple]").not(".chosen").toggle()});a(".plugin-option .select_wrapper select[multiple]").not(".chosen").click(function(a){a.stopPropagation()});a(window).click(function(){a(".plugin-option .select_wrapper select[multiple]").not(".chosen").hide()});a(".plugin-option .chosen .select_wrapper select").chosen();a(".plugin-option .on_off_container span").on("click",
3
+ function(){var b=a(this).prev("input");b.prop("checked")?b.prop("checked",!1).attr("value","no").removeClass("onoffchecked"):b.prop("checked",!0).attr("value","yes").addClass("onoffchecked");b.change()});a(".plugin-option .slider_container .ui-slider-horizontal").each(function(){var b=a(this).data("val"),c=a(this).data("min"),e=a(this).data("max"),d=a(this).data("step"),l=a(this).data("labels");a(this).slider({value:b,min:c,max:e,range:"min",step:d,slide:function(b,c){a(this).find("input").val(c.value);
4
+ a(this).siblings(".feedback").find("strong").text(c.value+l)}})});if("undefined"!==typeof wp&&"undefined"!==typeof wp.media){var f=!0,m=wp.media.editor.send.attachment;a(".plugin-option .upload_img_url").change(function(){var b=a(this).val(),c=a(this).parent().siblings(".upload_img_preview");/(http|ftp|https):\/\/[a-zA-Z0-9@?^=%&amp;:/~+#-_.]*.(gif|jpg|jpeg|png|ico)/.test(b)?c.html('<img src="'+b+'" style="max-width:600px; max-height:300px;" />'):c.html("")}).change();a(document).on("click",".plugin-option .upload_button",
5
+ function(b){b=a(this);var c=b.attr("id").replace("-button","");f=!0;wp.media.editor.send.attachment=function(b,d){if(f)a("#"+c).is("input[type=text]")?a("#"+c).val(d.url):a("#"+c+"_custom").val(d.url);else return m.apply(this,[b,d])};wp.media.editor.open(b);return!1})}a(".plugin-option .add_media").on("click",function(){f=!1});a("[data-field]").each(function(){var b=a(this),c="#"+b.data("field"),e="#"+b.data("dep"),d=b.data("value");a(e).on("change",function(){var b=e,g=d.toString(),f=!0;if("string"==
6
+ typeof b){":radio"==b.substr(0,6)&&(b+=":checked");for(var g=g.split(","),h=0;h<g.length;h++)if(a(b).val()!=g[h])f=!1;else{f=!0;break}}f?a(c+"-container").closest("tr").show():a(c+"-container").closest("tr").hide()}).change()});a(".rm_connectedlist").each(function(){var b=a(this).find("ul"),c=a(this).find(":hidden");b.sortable({connectWith:b,update:function(e,d){var f={};b.each(function(){var b={};a(this).children().each(function(){b[a(this).data("option")]=a(this).text()});f[a(this).data("list")]=
7
+ b});c.val(JSON.stringify(f).replace(/[\\"']/g,"\\$&").replace(/\u0000/g,"\\0"))}}).disableSelection()});a(document).ready(function(){a(".yith-video-link").click(function(b){b.preventDefault();b=a(this).data("video-id");a("."+b).dialog({dialogClass:"wp-dialog yit-dialog yit-video-dialog",modal:!0,closeOnEscape:!0,width:"auto",resizable:!1,draggable:!1,create:function(b,e){a(this).css("maxWidth","853px")},open:function(b,e){a(".ui-widget-overlay").bind("click",function(){a(this).siblings(".ui-dialog").find(".ui-dialog-content").dialog("close")})}});
8
+ a(".ui-dialog :button").blur()})});a(document).ready(function(){a(".codemirror").each(function(b,c){var e=CodeMirror.fromTextArea(c,{lineNumbers:1,mode:"javascript",showCursorWhenSelecting:!0});a(c).data("codemirrorInstance",e)})});a(document).ready(function(){a(".google-analytic-generate").click(function(){var b=a("#"+a(this).data("textarea")).data("codemirrorInstance"),c=a("#"+a(this).data("input")).val(),e=a(this).data("basename"),d;d="(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement( o ),\nm=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n";
9
+ d+="})(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n\n";d+="ga('create', '"+c+"', '"+e+"');\n";d+="ga('send', 'pageview');\n";b.replaceRange(d,b.getCursor("start"),b.getCursor("end"))})})})(jQuery);
plugin-fw/assets/js/yit-wp-pointer.js ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready( function($) {
2
+
3
+ var pointers = custom_pointer.pointers[0],
4
+ options = pointers.options,
5
+ target = $(pointers.target),
6
+ pointer_id = pointers.pointer_id;
7
+
8
+ $(target).find('.wp-submenu li a').each(function () {
9
+
10
+ var t = $(this),
11
+ href = t.attr('href');
12
+
13
+ href = href.replace('admin.php?page=', '');
14
+
15
+ if( href == pointer_id ){
16
+
17
+ var selected_plugin_row = t.add( target ),
18
+ top_level_menu = target.find( pointers.target.replace( '#', '.' ) );
19
+
20
+ target.toggleClass('wp-no-current-submenu wp-menu-open wp-has-current-submenu');
21
+
22
+ t.pointer({
23
+ pointerClass: 'yit-wp-pointer',
24
+ content : options.content,
25
+ position: options.position,
26
+ open : function () { console.log( 'here' );
27
+ selected_plugin_row.toggleClass( 'yit-pointer-selected-row' );
28
+ top_level_menu.addClass( 'yit-pointer' );
29
+ },
30
+
31
+
32
+ close : function () {
33
+ target.toggleClass('wp-no-current-submenu wp-menu-open wp-has-current-submenu');
34
+ selected_plugin_row.toggleClass( 'yit-pointer-selected-row' );
35
+ top_level_menu.removeClass( 'yit-pointer' );
36
+
37
+ $.ajax({
38
+ type : 'POST',
39
+ url : ajaxurl,
40
+ data : {
41
+ "action" : "dismiss-wp-pointer",
42
+ "pointer": pointer_id
43
+ },
44
+ success: function (response) {
45
+ }
46
+ });
47
+
48
+ }
49
+ }).pointer('open');
50
+ } else if( 'yith_default_pointer' == pointer_id ) {
51
+
52
+ var selected_plugin_row = t.add( target ),
53
+ top_level_menu = target.find( pointers.target.replace( '#', '.' )),
54
+ yit_plugins = $( pointers.target );
55
+
56
+ yit_plugins.addClass('wp-has-current-submenu');
57
+
58
+ top_level_menu.pointer({
59
+ pointerClass: 'yit-wp-pointer',
60
+ content : options.content,
61
+ position: options.position,
62
+
63
+ open : function () {
64
+ yit_plugins.addClass( 'yit-pointer-selected-row' );
65
+ },
66
+
67
+ close : function () {
68
+ yit_plugins.removeClass( 'yit-pointer-selected-row wp-has-current-submenu' );
69
+
70
+ $.ajax({
71
+ type : 'POST',
72
+ url : ajaxurl,
73
+ data : {
74
+ "action" : "dismiss-wp-pointer",
75
+ "pointer": pointer_id
76
+ },
77
+ success: function (response) {
78
+ }
79
+ });
80
+ }
81
+ }).pointer('open');
82
+ }
83
+ });
84
+ });
plugin-fw/assets/js/yit-wp-pointer.min.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ jQuery(document).ready(function(b){var c=custom_pointer.pointers[0],d=c.options,a=b(c.target),e=c.pointer_id;b(a).find(".wp-submenu li a").each(function(){var f=b(this),h=f.attr("href"),h=h.replace("admin.php?page=","");if(h==e){var k=f.add(a),g=a.find(c.target.replace("#","."));a.toggleClass("wp-no-current-submenu wp-menu-open wp-has-current-submenu");f.pointer({pointerClass:"yit-wp-pointer",content:d.content,position:d.position,open:function(){console.log("here");k.toggleClass("yit-pointer-selected-row");
2
+ g.addClass("yit-pointer")},close:function(){a.toggleClass("wp-no-current-submenu wp-menu-open wp-has-current-submenu");k.toggleClass("yit-pointer-selected-row");g.removeClass("yit-pointer");b.ajax({type:"POST",url:ajaxurl,data:{action:"dismiss-wp-pointer",pointer:e},success:function(a){}})}}).pointer("open")}else if("yith_default_pointer"==e){var k=f.add(a),g=a.find(c.target.replace("#",".")),l=b(c.target);l.addClass("wp-has-current-submenu");g.pointer({pointerClass:"yit-wp-pointer",content:d.content,
3
+ position:d.position,open:function(){l.addClass("yit-pointer-selected-row")},close:function(){l.removeClass("yit-pointer-selected-row wp-has-current-submenu");b.ajax({type:"POST",url:ajaxurl,data:{action:"dismiss-wp-pointer",pointer:e},success:function(a){}})}}).pointer("open")}})});
plugin-fw/lib/yit-cpt-unlimited.php ADDED
@@ -0,0 +1,1775 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if (!defined('ABSPATH')) {exit('Direct access forbidden.');
11
+ }
12
+
13
+ /**
14
+ * Manage the custom post types as Portfolio, Contact Forms and similar (called CPTU)
15
+ *
16
+ * @class YIT_CPT_Unlimited
17
+ * @package Yithemes
18
+ * @since 2.0.0
19
+ * @author Your Inspiration Themes
20
+ *
21
+ */
22
+
23
+ class YIT_CPT_Unlimited {
24
+
25
+ /**
26
+ * @var string The name of main post type of CPTU
27
+ * @since 1.0
28
+ */
29
+ protected $_name = '';
30
+
31
+ /**
32
+ * @var string The prefix of each post type created by the post of main CPTU
33
+ * @since 1.0
34
+ */
35
+ protected $_prefix_cpt = '';
36
+
37
+ /**
38
+ * @var string The labels defined for the main CPTU
39
+ * @since 1.0
40
+ */
41
+ protected $_labels = '';
42
+
43
+ /**
44
+ * @var string The configuration arguments of post type
45
+ * @since 1.0
46
+ */
47
+ protected $_args = '';
48
+
49
+ /**
50
+ * @var array All post types created by the post of main CPTU
51
+ * @since 1.0
52
+ */
53
+ public $post_types = array();
54
+
55
+ /**
56
+ * @var array $layouts Array with all portfolio layouts available for this site
57
+ * @since 1.0
58
+ */
59
+ public $layouts = array();
60
+
61
+ /**
62
+ * @var string $template_path The pathname of template folder
63
+ * @since 1.0
64
+ */
65
+ protected $template_path = '';
66
+
67
+ /**
68
+ * @var string $template_url The URL of template folder
69
+ * @since 1.0
70
+ */
71
+ protected $template_url = '';
72
+
73
+ /**
74
+ * @var int $_index Unique sequential ID to differentiate same shortcodes in the same page
75
+ */
76
+ public $index = 0;
77
+
78
+ /**
79
+ * @var string $_layout Temporary attribute to load automatically the settings for each layout
80
+ * @since 1.0
81
+ */
82
+ private $_layout = '';
83
+
84
+
85
+ /**
86
+ * Constructor
87
+ *
88
+ * Accept an array of arguments to define the characteristics of CPTU to register.
89
+ *
90
+ * @since 1.0
91
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
92
+ */
93
+ public function __construct( $args = array() ) {
94
+
95
+ $defaults = array(
96
+ 'name' => '',
97
+ 'post_type_prefix' => '',
98
+ 'labels' => array(
99
+ 'main_name' => '',
100
+ 'singular' => '',
101
+ 'plural' => '',
102
+ 'menu' => ''
103
+ ),
104
+ 'manage_layouts' => false,
105
+ 'add_multiuploader' => false,
106
+ 'sortable' => false,
107
+ 'has_single' => false,
108
+ 'has_taxonomy' => false,
109
+ 'label_item_sing' => '',
110
+ 'label_item_plur' => '',
111
+ 'shortcode_name' => '',
112
+ 'shortcode_icon' => '', // URL or icon name from http://melchoyce.github.io/dashicons/
113
+ 'layout_option' => '_type' // the option ID of layout metabox
114
+ );
115
+ $this->_args = wp_parse_args( $args, $defaults );
116
+
117
+ // fix labels
118
+ if ( empty( $this->_args['labels']['main_name'] ) ) {
119
+ $this->_args['labels']['main_name'] = $this->_args['labels']['singular'];
120
+ }
121
+ if ( empty( $this->_args['labels']['menu'] ) ) {
122
+ $this->_args['labels']['menu'] = $this->_args['labels']['singular'];
123
+ }
124
+
125
+ /* populate */
126
+ $this->_name = $this->_args['name'];
127
+ $this->_prefix_cpt = $this->_args['post_type_prefix'];
128
+ $this->_labels = $this->_args['labels'];
129
+
130
+ add_action( 'init', array( $this, 'register_post_type' ) );
131
+ add_action( 'init', array( $this, 'register_cptu_post_types' ) );
132
+
133
+ add_action( 'save_post', array( $this, 'rewrite_flush') );
134
+
135
+ // admin interface
136
+ add_action( 'admin_head', array( $this, 'add_cptu_menu_item' ) );
137
+ add_action( 'admin_init', array( $this, 'add_quick_links_metaboxes' ) );
138
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_assets' ) );
139
+
140
+ // metaboxes
141
+ add_action( 'after_setup_theme', array( $this, 'add_metabox_cptu' ), 2 );
142
+ add_action( 'after_setup_theme', array( $this, 'add_metabox_item_fields' ), 2 );
143
+
144
+ // multiuploader
145
+ if ( $this->_args['add_multiuploader'] ) {
146
+ add_action( 'admin_footer', array( $this, 'add_button_multiuploader' ) );
147
+ add_action( 'wp_ajax_yit_cptu_multiuploader', array( $this, 'post_multiuploader' ) );
148
+ }
149
+
150
+ // layouts
151
+ if ( $this->_args['manage_layouts'] ) {
152
+ // get all layouts available
153
+ $this->get_layouts();
154
+ }
155
+
156
+ // single layout
157
+ if ( $this->_args['has_single'] ) {
158
+ add_action( 'yit_loop', array( $this, 'single_template' ) );
159
+ add_action( 'wp', array( $this, 'single_template_config' ) );
160
+
161
+ if ( defined('DOING_AJAX') && DOING_AJAX ) {
162
+ add_action( 'init', array( $this, 'single_template_config' ) );
163
+ }
164
+ }
165
+
166
+ // archive template
167
+ add_action( 'wp', array( $this, 'archive_template' ) );
168
+
169
+ // enqueue the assets of each layout
170
+ add_action( 'wp_enqueue_scripts', array( $this, 'frontend_assets' ) );
171
+
172
+ // add the shortcode, used to show the frontend
173
+ if ( ! empty( $this->_args['shortcode_name'] ) ) {
174
+ add_shortcode( $this->_args['shortcode_name'], array( &$this, 'add_shortcode' ) );
175
+ add_filter( 'yit_shortcode_' . $this->_args['shortcode_name'] . '_icon', array( $this, 'shortcode_icon') );
176
+ add_filter( 'yit-shortcode-plugin-init', array( $this, 'add_shortcode_to_box' ) );
177
+ }
178
+
179
+ // add sortable feature
180
+ if ( $this->_args['sortable'] ) {
181
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_sortable_assets' ) );
182
+ add_action( 'wp_ajax_cpt_sort_posts', array( $this, 'sort_posts' ) );
183
+ add_action( 'admin_init', array( $this, 'init_menu_order' ) );
184
+ add_filter( 'pre_get_posts', array( $this, 'filter_active' ) );
185
+ add_filter( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
186
+ add_filter( 'get_next_post_where', array( $this, 'sorted_next_post_where' ) );
187
+ add_filter( 'get_previous_post_where', array( $this, 'sorted_prev_post_where' ) );
188
+ add_filter( 'get_next_post_sort', array( $this, 'sorted_next_post_sort' ) );
189
+ add_filter( 'get_previous_post_sort', array( $this, 'sorted_prev_post_sort' ) );
190
+ }
191
+
192
+ // add default columns to post type table list
193
+ add_filter( 'manage_edit-' . $this->_name . '_columns', array( $this, 'cptu_define_columns' ) );
194
+ add_action( 'manage_' . $this->_name . '_posts_custom_column' , array( $this, 'cptu_change_columns' ), 10, 2 );
195
+
196
+ // add required post type for wordpress importer
197
+ add_filter( 'wp_import_post_data_raw', array( $this, 'add_importer_required_post_type' ) );
198
+ add_filter( 'wp_import_terms', array( $this, 'add_importer_required_taxonomy' ) );
199
+ add_action( 'wp_import_set_post_terms', array( $this, 'recount_terms_post' ), 10, 3 );
200
+
201
+ }
202
+
203
+ /**
204
+ * Enqueue the assets for the sortable feature
205
+ *
206
+ * @return void
207
+ * @since 1.0
208
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
209
+ */
210
+ public function admin_sortable_assets() {
211
+ global $post;
212
+
213
+ if ( ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
214
+ return;
215
+ }
216
+
217
+ wp_enqueue_script( 'yit-cptu-sortable-posts', YIT_CORE_PLUGIN_URL . '/assets/js/yit-cptu-sortable-posts.js', array( 'jquery', 'jquery-ui-sortable' ), '1.0', true );
218
+ }
219
+
220
+ public function init_menu_order( $post_types = array() ) {
221
+ global $wpdb;
222
+
223
+ if ( empty( $post_types ) ) {
224
+ $post_types = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT post_type FROM $wpdb->posts WHERE post_type LIKE %s", str_replace( '_', '\_', $this->_prefix_cpt ) . '%' ) );
225
+ } elseif ( ! is_array( $post_types ) ) {
226
+ $post_types = array( $post_types );
227
+ }
228
+
229
+ foreach ( $post_types as $post_type ) {
230
+ $count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = '{$post_type}' AND post_status IN ('publish', 'pending', 'draft', 'private', 'future') AND menu_order = 0" );
231
+
232
+ if ( empty( $count ) ) {
233
+ continue;
234
+ }
235
+
236
+ $sql = "SELECT ID
237
+ FROM $wpdb->posts
238
+ WHERE post_type = '" . $post_type . "'
239
+ AND post_status IN ('publish', 'pending', 'draft', 'private', 'future')
240
+ ORDER BY post_date DESC
241
+ ";
242
+
243
+ $results = $wpdb->get_results( $sql );
244
+
245
+ foreach ( $results as $key => $result ) {
246
+ $wpdb->update( $wpdb->posts, array( 'menu_order' => $key + 1 ), array( 'ID' => $result->ID ) );
247
+ }
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Save the order of posts from sortable feature
253
+ *
254
+ * @return void
255
+ * @since 1.0
256
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
257
+ */
258
+ public function sort_posts() {
259
+ global $wpdb;
260
+
261
+ parse_str( $_REQUEST['order'], $data );
262
+
263
+ if ( is_array( $data ) ) {
264
+ //$this->init_menu_order( $_REQUEST['post_type'] );
265
+
266
+ $id_arr = array( );
267
+ foreach ( $data as $key => $values ) {
268
+ foreach ( $values as $position => $id ) {
269
+ $id_arr[] = $id;
270
+ }
271
+ }
272
+
273
+
274
+ $menu_order_arr = array( );
275
+ foreach ( $id_arr as $key => $id ) {
276
+ $results = $wpdb->get_results( "SELECT menu_order FROM $wpdb->posts WHERE ID = " . $id );
277
+ foreach ( $results as $result ) {
278
+ $menu_order_arr[] = $result->menu_order;
279
+ }
280
+ }
281
+
282
+ sort( $menu_order_arr );
283
+
284
+ foreach ( $data as $key => $values ) {
285
+ foreach ( $values as $position => $id ) {
286
+ $wpdb->update( $wpdb->posts, array( 'menu_order' => $menu_order_arr[$position] ), array( 'ID' => $id ) );
287
+ }
288
+ }
289
+ }
290
+
291
+ die();
292
+ }
293
+
294
+ public function filter_active( $wp_query ) {
295
+ if ( isset( $wp_query->query['suppress_filters'] ) )
296
+ $wp_query->query['suppress_filters'] = false;
297
+ if ( isset( $wp_query->query_vars['suppress_filters'] ) )
298
+ $wp_query->query_vars['suppress_filters'] = false;
299
+ return $wp_query;
300
+ }
301
+
302
+ public function pre_get_posts( $wp_query ) {
303
+ if ( is_admin() && !defined( 'DOING_AJAX' ) ) {
304
+ if ( isset( $wp_query->query['post_type'] ) ) {
305
+ $post_types = (array) $wp_query->query['post_type'];
306
+ foreach ( $post_types as $post_type ) {
307
+ if ( $this->_is_valid( $post_type ) ) {
308
+ $wp_query->set( 'orderby', 'menu_order' );
309
+ $wp_query->set( 'order', 'ASC' );
310
+ }
311
+ }
312
+ }
313
+
314
+ } else {
315
+
316
+ $active = false;
317
+
318
+ if ( isset( $wp_query->query['suppress_filters'] ) || isset( $wp_query->query['post_type'] ) ) {
319
+ $post_types = (array) $wp_query->query['post_type'];
320
+ foreach ( $post_types as $post_type ) {
321
+ if ( $this->_is_valid( $post_type ) ) {
322
+ $active = true;
323
+ }
324
+ }
325
+ }
326
+
327
+ if ( $active ) {
328
+ if ( !isset( $wp_query->query['orderby'] ) || $wp_query->query['orderby'] == 'post_date' )
329
+ $wp_query->set( 'orderby', 'menu_order' );
330
+ if ( !isset( $wp_query->query['order'] ) || $wp_query->query['order'] == 'DESC' )
331
+ $wp_query->set( 'order', 'ASC' );
332
+ }
333
+ }
334
+ }
335
+
336
+ /**
337
+ * Filters where clause for get next post
338
+ *
339
+ * @param $where
340
+ *
341
+ * @return string
342
+ * @since 1.0
343
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
344
+ */
345
+ public function sorted_next_post_where( $where ){
346
+ global $post;
347
+ if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
348
+ $post = get_post( intval( $_REQUEST['post_id'] ) );
349
+ }
350
+ else{
351
+ $post = get_post();
352
+ }
353
+
354
+ if( ! $post || ! $this->_is_valid( $post->post_type ) ){
355
+ return $where;
356
+ }
357
+
358
+ $result = str_replace( "'" . $post->post_date . "'", $post->menu_order, $where );
359
+ $result = str_replace( 'p.post_date', 'p.menu_order', $result );
360
+
361
+ return $result;
362
+ }
363
+
364
+ /**
365
+ * Filters where clause for get prev post
366
+ *
367
+ * @param $where
368
+ *
369
+ * @return string
370
+ * @since 1.0
371
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
372
+ */
373
+ public function sorted_prev_post_where( $where ){
374
+ global $post;
375
+
376
+ if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
377
+ $post = get_post( intval( $_REQUEST['post_id'] ) );
378
+ }
379
+ else{
380
+ $post = get_post();
381
+ }
382
+
383
+ if( ! $post || ! $this->_is_valid( $post->post_type ) ){
384
+ return $where;
385
+ }
386
+
387
+ $result = str_replace( "'" . $post->post_date . "'", $post->menu_order, $where );
388
+ $result = str_replace( 'p.post_date', 'p.menu_order', $result );
389
+
390
+ return $result;
391
+ }
392
+
393
+ /**
394
+ * Filters sort clause for get next post
395
+ *
396
+ * @param $sort
397
+ *
398
+ * @return string
399
+ * @since 1.0
400
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
401
+ */
402
+ public function sorted_next_post_sort( $sort ){
403
+ global $post;
404
+
405
+ if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
406
+ $post = get_post( intval( $_REQUEST['post_id'] ) );
407
+ }
408
+ else{
409
+ $post = get_post();
410
+ }
411
+
412
+ if( ! $post || ! $this->_is_valid( $post->post_type ) ){
413
+ return $sort;
414
+ }
415
+
416
+ $result = str_replace( 'p.post_date', 'p.menu_order', $sort );
417
+ return $result;
418
+ }
419
+
420
+ /**
421
+ * Filters sort clause for get prev post
422
+ *
423
+ * @param $sort
424
+ *
425
+ * @return string
426
+ * @since 1.0
427
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
428
+ */
429
+ public function sorted_prev_post_sort( $sort ){
430
+ global $post;
431
+
432
+ if( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ){
433
+ $post = get_post( intval( $_REQUEST['post_id'] ) );
434
+ }
435
+ else{
436
+ $post = get_post();
437
+ }
438
+
439
+ if( ! $post || ! $this->_is_valid( $post->post_type ) ){
440
+ return $sort;
441
+ }
442
+
443
+ $result = str_replace( 'p.post_date', 'p.menu_order', $sort );
444
+ return $result;
445
+ }
446
+
447
+ /**
448
+ * Register post type
449
+ *
450
+ * Register the post type for the creation of portfolios
451
+ *
452
+ * @return void
453
+ * @since 1.0
454
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
455
+ */
456
+ public function register_post_type() {
457
+ $labels = array(
458
+ 'name' => ucfirst( $this->_labels['main_name'] ),
459
+ 'singular_name' => ucfirst( $this->_labels['singular'] ),
460
+ 'add_new' => sprintf( __( 'Add %s', 'yit' ), ucfirst( $this->_labels['singular'] ) ),
461
+ 'add_new_item' => sprintf( __( 'Add New %s', 'yit' ), ucfirst( $this->_labels['singular'] ) ),
462
+ 'edit_item' => sprintf( __( 'Edit %s', 'yit' ), ucfirst( $this->_labels['singular'] ) ),
463
+ 'new_item' => sprintf( __( 'New %s', 'yit' ), ucfirst( $this->_labels['singular'] ) ),
464
+ 'all_items' => sprintf( __( 'All %s', 'yit' ), ucfirst( $this->_labels['plural'] ) ),
465
+ 'view_item' => sprintf( __( 'View %s', 'yit' ), ucfirst( $this->_labels['singular'] ) ),
466
+ 'search_items' => sprintf( __( 'Search %s', 'yit' ), ucfirst( $this->_labels['plural'] ) ),
467
+ 'not_found' => sprintf( __( 'No %s found', 'yit' ), ucfirst( $this->_labels['plural'] ) ),
468
+ 'not_found_in_trash' => sprintf( __( 'No %s found in Trash', 'yit' ), ucfirst( $this->_labels['plural'] ) ),
469
+ 'parent_item_colon' => '',
470
+ 'menu_name' => ucfirst( $this->_labels['menu'] )
471
+ );
472
+
473
+ $args = array(
474
+ 'labels' => apply_filters( 'yit_' . $this->_name . '_labels', $labels ),
475
+ 'public' => false,
476
+ 'publicly_queryable' => false,
477
+ 'show_ui' => true,
478
+ 'show_in_menu' => true,
479
+ 'query_var' => false,
480
+ 'capability_type' => 'post',
481
+ 'hierarchical' => false,
482
+ 'menu_position' => null,
483
+ 'supports' => array( 'title' )
484
+ );
485
+
486
+ if ( ! empty( $this->_args['menu_icon'] ) ) {
487
+ $args['menu_icon'] = $this->_args['menu_icon'];
488
+ }
489
+
490
+ register_post_type( $this->_name, apply_filters( 'yit_' . $this->_name . '_args', $args ) );
491
+ }
492
+
493
+ /**
494
+ * Retrieve the values configured inside the custom post type
495
+ *
496
+ * @param $post /WP_Query The post where get the arguments configured in the cpt
497
+ *
498
+ * @return array
499
+ * @since 1.0
500
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
501
+ */
502
+ protected function _cpt_args( $post ) {
503
+ if ( ! isset( $post->ID ) ) {
504
+ return;
505
+ }
506
+
507
+ $args = apply_filters( 'yit_cptu_register_post_type_args', array(
508
+ 'layout' => get_post_meta( $post->ID, $this->_args['layout_option'], true ),
509
+ 'rewrite' => get_post_meta( $post->ID, '_rewrite', true ),
510
+ 'label_singular' => ! empty( $this->_args['label_item_sing'] ) ? $this->_args['label_item_sing'] : get_post_meta( $post->ID, '_label_singular', true ),
511
+ 'label_plural' => ! empty( $this->_args['label_item_plur'] ) ? $this->_args['label_item_plur'] : get_post_meta( $post->ID, '_label_plural', true ),
512
+ 'taxonomy' => get_post_meta( $post->ID, '_taxonomy', true ),
513
+ 'taxonomy_rewrite' => get_post_meta( $post->ID, '_taxonomy_rewrite', true ),
514
+ ), $this->_name, $post );
515
+
516
+ $title = $post->post_title;
517
+
518
+ if ( empty( $args['label_singular'] ) ) {
519
+ $args['label_singular'] = $title;
520
+ }
521
+
522
+ if ( empty( $args['label_plural'] ) ) {
523
+ $args['label_plural'] = $title;
524
+ }
525
+
526
+ return $args;
527
+ }
528
+
529
+ /**
530
+ * Retrieve the post types created for this CPTU
531
+ *
532
+ * @return array The link changed
533
+ * @since 1.0
534
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
535
+ */
536
+ public function get_post_types() {
537
+ if ( ! empty( $this->post_types ) ) {
538
+ return $this->post_types;
539
+ }
540
+
541
+ $args = array(
542
+ 'post_type' => $this->_name,
543
+ 'posts_per_page' => -1,
544
+ 'post_status' => 'publish'
545
+ );
546
+ $this->post_types = get_posts( $args );
547
+
548
+ return $this->post_types;
549
+ }
550
+
551
+ /**
552
+ * Register portfolio post types
553
+ *
554
+ * Register the post types for each portfolio created by admin
555
+ *
556
+ * @return void
557
+ * @since 1.0
558
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
559
+ */
560
+ public function register_cptu_post_types() {
561
+ $post_types = $this->get_post_types();
562
+ $pts = array();
563
+
564
+ foreach ( $post_types as $pt ) {
565
+
566
+ extract( $this->_cpt_args( $pt ) );
567
+
568
+ $name = $pt->post_name;
569
+ $title = $pt->post_title;
570
+
571
+ $labels = array(
572
+ 'name' => $title,
573
+ 'singular_name' => $label_singular,
574
+ 'add_new' => sprintf( __( 'Add %s', 'yit' ), $label_singular ),
575
+ 'add_new_item' => sprintf( __( 'Add New %s', 'yit' ), $label_singular ),
576
+ 'edit_item' => sprintf( __( 'Edit %s', 'yit' ), $label_singular ),
577
+ 'new_item' => sprintf( __( 'New %s', 'yit' ), $label_singular ),
578
+ 'all_items' => sprintf( __( 'All %s', 'yit' ), $label_plural ),
579
+ 'view_item' => sprintf( __( 'View %s', 'yit' ), $label_singular ),
580
+ 'search_items' => sprintf( __( 'Search %s', 'yit' ), $label_plural ),
581
+ 'not_found' => sprintf( __( 'No %s found', 'yit' ), $label_plural ),
582
+ 'not_found_in_trash' => sprintf( __( 'No %s found in Trash', 'yit' ), $label_plural ),
583
+ 'parent_item_colon' => '',
584
+ 'menu_name' => $title
585
+ );
586
+
587
+ $args = array(
588
+ 'labels' => apply_filters( 'yit_' . $this->_prefix_cpt . $name . '_labels', $labels ),
589
+ 'public' => true,
590
+ 'publicly_queryable' => true,
591
+ 'show_ui' => true,
592
+ 'show_in_menu' => false,
593
+ 'query_var' => true,
594
+ 'capability_type' => 'post',
595
+ 'hierarchical' => false,
596
+ 'menu_position' => null,
597
+ 'supports' => array( 'title', 'editor', 'thumbnail' )
598
+ );
599
+
600
+ if ( ! $this->_args['has_single'] ) {
601
+ $args['public'] = false;
602
+ $args['publicly_queryable'] = false;
603
+ $args['query_var'] = false;
604
+ }
605
+
606
+ if ( $this->_args['manage_layouts'] && isset($this->layouts[ $layout ]) && ! $this->layouts[ $layout ]['support']['description'] ) {
607
+ unset( $args['supports'][1] ); // remove 'editor'
608
+ }
609
+
610
+ if ( ! empty( $rewrite ) ) {
611
+ $args['rewrite'] = array( 'slug' => $rewrite );
612
+ }
613
+
614
+ // register post type
615
+ $post_type = yit_avoid_duplicate( str_replace( '-', '_', substr( $this->_prefix_cpt . $name, 0, 16) ), $post_types );
616
+ register_post_type( $post_type, apply_filters( 'yit_' . $this->_prefix_cpt . $name . '_args', $args, $pt ) ); // save the post type in post meta
617
+
618
+ update_post_meta( $pt->ID, '_post_type', $post_type );
619
+ $pts[] = $post_type;
620
+
621
+ // register taxonomy
622
+ if ( $this->_args['has_taxonomy'] && ! empty( $taxonomy ) ) {
623
+
624
+ $labels = array(
625
+ 'name' => sprintf( _x( '%s Categories', 'taxonomy general name', 'yit' ), $label_singular ),
626
+ 'singular_name' => _x( 'Category', 'taxonomy singular name', 'yit' ),
627
+ 'search_items' => __( 'Search Categories', 'yit' ),
628
+ 'all_items' => __( 'All Categories', 'yit' ),
629
+ 'parent_item' => __( 'Parent Category', 'yit' ),
630
+ 'parent_item_colon' => __( 'Parent Category:', 'yit' ),
631
+ 'edit_item' => __( 'Edit Category', 'yit' ),
632
+ 'update_item' => __( 'Update Category', 'yit' ),
633
+ 'add_new_item' => __( 'Add New Category', 'yit' ),
634
+ 'new_item_name' => __( 'New Category Name', 'yit' ),
635
+ 'menu_name' => __( 'Category', 'yit' ),
636
+ );
637
+
638
+ $args = array(
639
+ 'hierarchical' => true,
640
+ 'labels' => $labels,
641
+ 'show_ui' => true,
642
+ 'show_admin_column' => true,
643
+ 'query_var' => true,
644
+ );
645
+
646
+ if ( ! empty( $taxonomy_rewrite ) ) {
647
+ $args['rewrite'] = array( 'slug' => $taxonomy_rewrite );
648
+ }
649
+
650
+ register_taxonomy( substr( $taxonomy, 0, 32 ), $post_type, $args );
651
+
652
+ }
653
+
654
+ }
655
+
656
+ wp_cache_set( 'yit_cptu_post_types', $post_types );
657
+ }
658
+
659
+ /**
660
+ * Flush Rewrite Rules
661
+ *
662
+ * rewrite rules when a cpt unlimited is saved
663
+ *
664
+ * @return void
665
+ * @since 1.0
666
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
667
+ */
668
+
669
+ public function rewrite_flush( $post ){
670
+
671
+ if ( isset( $post ) && $this->_is_valid( get_post_type( intval( $post ) ) ) ) {
672
+ flush_rewrite_rules();
673
+ }
674
+
675
+ }
676
+
677
+ /**
678
+ * Add the item for each portfolio under "Portfolios"
679
+ *
680
+ * @return void
681
+ * @since 1.0
682
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
683
+ */
684
+ public function add_cptu_menu_item() {
685
+ global $submenu, $post, $parent_file, $pagenow;
686
+
687
+ // get current post type
688
+ if ( isset( $post->post_type ) ) {
689
+ $post_type = $post->post_type;
690
+ } else if ( isset( $_REQUEST['post_type'] ) ) {
691
+ $post_type = $_REQUEST['post_type'];
692
+ } else {
693
+ return;
694
+ }
695
+
696
+ $item = 'edit.php?post_type=' . $this->_name;
697
+
698
+ // add new items
699
+ if ( strpos( $post_type, $this->_prefix_cpt ) !== false ) {
700
+ global $wpdb;
701
+ $portfolio = $wpdb->get_row( $wpdb->prepare( "SELECT p.* FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $post_type, $this->_name ) );
702
+
703
+ if ( ! isset( $portfolio->ID ) ) {
704
+ return;
705
+ }
706
+
707
+ $label_singular = ! empty( $this->_args['label_item_sing'] ) ? $this->_args['label_item_sing'] : get_post_meta( $portfolio->ID, '_label_singular', true );
708
+ $label_plural = ! empty( $this->_args['label_item_plur'] ) ? $this->_args['label_item_plur'] : get_post_meta( $portfolio->ID, '_label_plural', true );
709
+
710
+ if ( empty( $label_plural ) ) {
711
+ $label_plural = $portfolio->post_title;
712
+ }
713
+
714
+ if ( empty( $label_singular ) ) {
715
+ $label_singular = $portfolio->post_title;
716
+ }
717
+
718
+ $submenu[ $item ][15] = array( ucfirst( $label_plural ), 'edit_posts', 'edit.php?post_type=' . $post_type );
719
+ $submenu[ $item ][20] = array( sprintf( __('Add %s', 'yit'), ucfirst( $label_singular ) ), 'edit_posts', 'post-new.php?post_type=' . $post_type );
720
+
721
+ global $wp_taxonomies;
722
+ $taxonomy = get_post_meta( $portfolio->ID, '_taxonomy', true );
723
+ if ( isset( $wp_taxonomies[ $taxonomy ] ) ) {
724
+ $submenu[ $item ][25] = array( __('Categories', 'yit'), 'edit_posts', 'edit-tags.php?taxonomy=' . $taxonomy . '&post_type=' . $post_type );
725
+ }
726
+ }
727
+
728
+ // set the parent item inside the single of each post type
729
+ if ( $pagenow == 'post.php' && isset( $_GET['post'] ) && $this->_is_valid( get_post_type( intval( $_GET['post'] ) ) ) ) {
730
+ $parent_file = 'edit.php?post_type=' . $this->_name;
731
+ }
732
+ }
733
+
734
+ /**
735
+ * Locate folder of CPTU templates, if there isn't a layouts management
736
+ *
737
+ * @return string
738
+ * @since 1.0
739
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
740
+ */
741
+ public function template_path() {
742
+ if ( ! empty( $this->template_path ) ) {
743
+ return $this->template_path;
744
+ }
745
+
746
+ // paths
747
+ $stylesheet_path_1 = get_stylesheet_directory() . '/theme/templates/' . $this->_name . '/';
748
+ $stylesheet_path_2 = get_template_directory() . '/theme/templates/' . $this->_name . '/';
749
+ $template_path_1 = get_stylesheet_directory() . '/' . $this->_name . '/';
750
+ $template_path_2 = get_template_directory() . '/' . $this->_name . '/';
751
+ $plugin_path = $this->_args['plugin_path'] . '/templates/';
752
+
753
+ foreach ( array( 'stylesheet_path_1', 'stylesheet_path_2', 'template_path_1', 'template_path_2', 'plugin_path' ) as $var ) {
754
+ $path = ${$var};
755
+
756
+ if ( file_exists( $path ) ) {
757
+ $this->template_path = $path;
758
+ }
759
+ }
760
+
761
+ return $this->template_path;
762
+ }
763
+
764
+ /**
765
+ * Locate folder of CPTU templates, if there isn't a layouts management
766
+ *
767
+ * @return string
768
+ * @since 1.0
769
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
770
+ */
771
+ public function template_url() {
772
+ if ( ! empty( $this->template_url ) ) {
773
+ return $this->template_path;
774
+ }
775
+
776
+ $this->template_url = str_replace( array(
777
+ get_stylesheet_directory(),
778
+ get_template_directory(),
779
+ $this->_args['plugin_path']
780
+ ), array(
781
+ get_stylesheet_directory_uri(),
782
+ get_template_directory_uri(),
783
+ $this->_args['plugin_url']
784
+ ), $this->template_path() );
785
+
786
+ return $this->template_url;
787
+ }
788
+
789
+ /**
790
+ * Retrieve all layouts to manage by custom post type added in the site in this order:
791
+ * 1. Child theme (if exists)
792
+ * 2. Theme
793
+ * 3. Plugin
794
+ *
795
+ * It also load the config.php file of each layout
796
+ *
797
+ * @return void
798
+ * @since 1.0
799
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
800
+ */
801
+ public function get_layouts() {
802
+
803
+ // paths
804
+ $stylesheet_path_1 = get_stylesheet_directory() . '/theme/templates/' . $this->_name . '/';
805
+ $stylesheet_path_2 = get_template_directory() . '/theme/templates/' . $this->_name . '/';
806
+ $template_path_1 = get_stylesheet_directory() . '/' . $this->_name . '/';
807
+ $template_path_2 = get_template_directory() . '/' . $this->_name . '/';
808
+ $plugin_path = $this->_args['plugin_path'] . '/templates/';
809
+
810
+ foreach ( array( 'stylesheet_path_1', 'stylesheet_path_2', 'template_path_1', 'template_path_2', 'plugin_path' ) as $var ) {
811
+ $path = ${$var};
812
+
813
+ if ( file_exists( $path ) ) {
814
+ foreach ( scandir( $path ) as $scan ) {
815
+ if ( ! isset( $this->layouts[$scan] ) && is_dir( $path . $scan ) && ! in_array( $scan, array( '.', '..', '.svn' ) ) && $scan[0] != '_' ) {
816
+ $this->layouts[$scan] = array(
817
+ 'name' => ucfirst( str_replace( '-', ' ', $scan ) ),
818
+ 'path' => $path . $scan,
819
+ 'url' => str_replace( array(
820
+ get_stylesheet_directory(),
821
+ get_template_directory(),
822
+ $this->_args['plugin_path']
823
+ ), array(
824
+ get_stylesheet_directory_uri(),
825
+ get_template_directory_uri(),
826
+ $this->_args['plugin_url']
827
+ ), $path . $scan ),
828
+ 'css' => array(),
829
+ 'js' => array(),
830
+ 'support' => array(
831
+ 'description' => true
832
+ ),
833
+ 'columns' => array()
834
+ );
835
+
836
+ // set the vars for config.php
837
+ $layout = $scan;
838
+ $this->_layout = $layout; // temporary attribute to load automatically the configuration inside the config.php, for this layout
839
+
840
+ // TODO Fare in modo di caricare il file config.php soltanto quando realmente serve
841
+ if ( ! in_array( $scan, array( 'single' ) ) && file_exists( $path . $scan . '/config.php' ) ) {
842
+ include_once( $path . $scan . '/config.php' );
843
+ }
844
+ }
845
+ }
846
+ }
847
+
848
+ }
849
+ }
850
+
851
+ /**
852
+ * Say if you want to set description for the current layout or not. This method must be used only inside the
853
+ * config.php file of layout
854
+ *
855
+ * @param $v string 'yes' or 'no'
856
+ *
857
+ * @return void
858
+ * @since 1.0
859
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
860
+ */
861
+ public function add_description_field( $v ) {
862
+ $this->layouts[ $this->_layout ]['support']['description'] = $v == 'yes' ? true : false;
863
+ }
864
+
865
+ /**
866
+ * Add the extra fields for the specific layout type of portfolio
867
+ *
868
+ * @param array $fields The fields to add
869
+ *
870
+ * @return void
871
+ * @since 1.0
872
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
873
+ */
874
+ public function add_layout_fields( $fields = array() ) {
875
+ // change the ID
876
+ foreach ( $fields as $id => $val ) {
877
+ unset( $fields[ $id ] );
878
+ $id = $this->_layout . '_' . $id;
879
+ $fields[ $id ] = $val;
880
+ }
881
+
882
+ $this->layouts[ $this->_layout ]['fields'] = $fields;
883
+ }
884
+
885
+ /**
886
+ * Add fields to add to the metabox of each item of each post type created
887
+ *
888
+ * @param array $fields The fields to add
889
+ *
890
+ * @return void
891
+ * @since 1.0
892
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
893
+ */
894
+ public function add_item_fields( $fields = array() ) {
895
+ // change the ID
896
+ foreach ( $fields as $id => $val ) {
897
+ unset( $fields[ $id ] );
898
+ //$id = $this->_layout . '_' . $id;
899
+ $fields[ $id ] = $val;
900
+ }
901
+ $this->layouts[ $this->_layout ]['item_fields'] = $fields;
902
+ }
903
+
904
+ /**
905
+ * Add columns to the table list
906
+ *
907
+ * @param array $columns The columns to add in the table list
908
+ *
909
+ * @return void
910
+ * @since 1.0
911
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
912
+ */
913
+ public function add_table_columns( $columns ) {
914
+ $this->layouts[ $this->_layout ]['columns'] = $columns;
915
+ }
916
+
917
+ /**
918
+ * Enqueue the css files of layout
919
+ *
920
+ * @param string $handle Name of the stylesheet.
921
+ * @param string|bool $src Path to the stylesheet from the root directory of WordPress. Example: '/css/mystyle.css'.
922
+ * @param array $deps An array of registered style handles this stylesheet depends on. Default empty array.
923
+ * @param string|bool $ver String specifying the stylesheet version number, if it has one. This parameter is used
924
+ * to ensure that the correct version is sent to the client regardless of caching, and so
925
+ * should be included if a version number is available and makes sense for the stylesheet.
926
+ * @param string $media Optional. The media for which this stylesheet has been defined.
927
+ * Default 'all'. Accepts 'all', 'aural', 'braille', 'handheld', 'projection', 'print',
928
+ * 'screen', 'tty', or 'tv'.
929
+ *
930
+ * @return void
931
+ * @since 1.0
932
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
933
+ */
934
+ public function enqueue_style( $handle, $src = false, $deps = array(), $ver = false, $media = 'all' ) {
935
+ $this->layouts[ $this->_layout ]['css'][] = compact( 'handle', 'src', 'deps', 'ver', 'media' );
936
+ }
937
+
938
+ /**
939
+ * Enqueue the js files of layout
940
+ *
941
+ * @param string $handle Name of the script.
942
+ * @param string|bool $src Path to the script from the root directory of WordPress. Example: '/js/myscript.js'.
943
+ * @param array $deps An array of registered handles this script depends on. Default empty array.
944
+ * @param string|bool $ver Optional. String specifying the script version number, if it has one. This parameter
945
+ * is used to ensure that the correct version is sent to the client regardless of caching,
946
+ * and so should be included if a version number is available and makes sense for the script.
947
+ * @param bool $in_footer Optional. Whether to enqueue the script before </head> or before </body>.
948
+ * Default 'false'. Accepts 'false' or 'true'.
949
+ *
950
+ * @return void
951
+ * @since 1.0
952
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
953
+ */
954
+ public function enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false ) {
955
+ $this->layouts[ $this->_layout ]['js'][] = compact( 'handle', 'src', 'deps', 'ver', 'in_footer' );
956
+ }
957
+
958
+ /**
959
+ * Enqueue the assets for the frontend
960
+ *
961
+ * @return void
962
+ * @since 1.0
963
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
964
+ */
965
+ public function frontend_assets() {
966
+ global $post;
967
+
968
+ // not single
969
+ if ( ! is_single() || ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
970
+ $posts = get_posts(array(
971
+ 'post_type' => $this->_name,
972
+ 'posts_per_page' => -1,
973
+ 'post_status' => 'publish',
974
+ 'fields' => 'ids'
975
+ ));
976
+
977
+ $enqueued = array();
978
+
979
+ foreach ( $posts as $post_id ) {
980
+ $layout = get_post_meta( $post_id, $this->_args['layout_option'], true );
981
+
982
+ if ( in_array( $layout, array( $enqueued ) ) || ! isset( $this->layouts[ $layout ]['css'] ) ) {
983
+ continue;
984
+ }
985
+
986
+ foreach ( $this->layouts[ $layout ]['css'] as $asset ) {
987
+ if ( empty( $asset ) ) {
988
+ continue;
989
+ }
990
+ yit_enqueue_style( $asset['handle'], empty( $asset['src'] ) ? false : $this->locate_url( $layout ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['media'] );
991
+ }
992
+
993
+ $enqueued[] = $layout;
994
+ }
995
+ }
996
+
997
+ // load assets of single template
998
+ else {
999
+ $layout = 'single';
1000
+
1001
+ if ( ! isset( $this->layouts[ $layout ]['css'] ) ) {
1002
+ return;
1003
+ }
1004
+
1005
+ foreach ( $this->layouts[ $layout ]['css'] as $asset ) {
1006
+ if ( empty( $asset ) ) {
1007
+ continue;
1008
+ }
1009
+ yit_enqueue_style( $asset['handle'], $this->locate_url( $layout ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['media'] );
1010
+ }
1011
+ }
1012
+
1013
+ }
1014
+
1015
+ /**
1016
+ * Register Metaboxes options
1017
+ *
1018
+ * Add the metabox for the portfolio settings
1019
+ *
1020
+ * @return void
1021
+ * @since 1.0
1022
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1023
+ */
1024
+ public function add_metabox_cptu() {
1025
+
1026
+ // Reorganize layouts
1027
+ if ( $this->_args['manage_layouts'] ) {
1028
+ $layouts = array();
1029
+ foreach ( $this->layouts as $layout_id => $layout ) {
1030
+ if ( 'single' == $layout_id ) {
1031
+ continue;
1032
+ }
1033
+ $layouts[ $layout_id ] = $layout['name'];
1034
+ }
1035
+
1036
+ $layouts = apply_filters( 'yit_cptu_' . $this->_name . '_layout_values', $layouts );
1037
+ }
1038
+
1039
+ $single_layouts = apply_filters( 'yit_cptu_' . $this->_name . '_single_layout_values', array() );
1040
+
1041
+ $metabox_args = array(
1042
+ 'label' => sprintf( __( '%s Settings', 'yit' ), $this->_labels['singular'] ),
1043
+ 'pages' => $this->_name, //or array( 'post-type1', 'post-type2')
1044
+ 'context' => 'normal', //('normal', 'advanced', or 'side')
1045
+ 'priority' => 'default',
1046
+ 'tabs' => array(
1047
+ 'settings' => array(
1048
+ 'label' => __( 'Settings', 'yit' ),
1049
+ 'fields' => apply_filters( 'yit_cptu_fields', array(
1050
+ 'type' => array(
1051
+ 'label' => __( 'Type', 'yit' ),
1052
+ 'desc' => __( 'The layout for this '.strtolower( $this->_labels['singular'] ) , 'yit' ),
1053
+ 'type' => 'select',
1054
+ 'options' => isset( $layouts ) ? $layouts : array(),
1055
+ 'std' => '' ),
1056
+
1057
+ 'rewrite' => array(
1058
+ 'label' => __( 'Rewrite', 'yit' ),
1059
+ 'desc' => __( 'The word used for the URL of each project (the slug of post if empty)', 'yit' ),
1060
+ 'type' => 'text',
1061
+ 'std' => '' ),
1062
+
1063
+ 'label_singular' => array(
1064
+ 'label' => __( 'Label Singular', 'yit' ),
1065
+ 'desc' => __( 'Set the label in singular to use for each label (the title of portfolio if empty)', 'yit' ),
1066
+ 'type' => 'text',
1067
+ 'std' => '' ),
1068
+
1069
+ 'label_plural' => array(
1070
+ 'label' => __( 'Label Plural', 'yit' ),
1071
+ 'desc' => __( 'Set the label in plural to use for each label (the title of portfolio if empty)', 'yit' ),
1072
+ 'type' => 'text',
1073
+ 'std' => '' ),
1074
+
1075
+ 'taxonomy' => array(
1076
+ 'label' => __( 'Taxonomy', 'yit' ),
1077
+ 'desc' => __( 'If you want to use a category section for the portfolio, set the name of taxonomy. Name should be in slug form (must not contain capital letters or spaces) and not more than 32 characters long (database structure restriction).', 'yit' ),
1078
+ 'type' => 'text',
1079
+ 'std' => '' ),
1080
+
1081
+ 'taxonomy_rewrite' => array(
1082
+ 'label' => __( 'Taxonomy Rewrite', 'yit' ),
1083
+ 'desc' => __( 'Set the word to use in the URL for each category page.', 'yit' ),
1084
+ 'type' => 'text',
1085
+ 'std' => '' ),
1086
+
1087
+ 'single_layout' => array(
1088
+ 'label' => __( 'Single layout', 'yit' ),
1089
+ 'desc' => __( 'The layout for single page of this portfolio', 'yit' ),
1090
+ 'type' => 'select',
1091
+ 'options' => $single_layouts,
1092
+ 'std' => '' ),
1093
+ ) )
1094
+ )
1095
+ )
1096
+
1097
+ );
1098
+
1099
+ if ( ! $this->_args['has_single'] ) {
1100
+ unset( $metabox_args['tabs']['settings']['fields']['rewrite'] );
1101
+ }
1102
+
1103
+ if ( ! $this->_args['has_taxonomy'] ) {
1104
+ unset( $metabox_args['tabs']['settings']['fields']['taxonomy'] );
1105
+ unset( $metabox_args['tabs']['settings']['fields']['taxonomy_rewrite'] );
1106
+ }
1107
+
1108
+ if ( ! empty( $this->_args['label_item_sing'] ) ) {
1109
+ unset( $metabox_args['tabs']['settings']['fields']['label_singular'] );
1110
+ }
1111
+
1112
+ if ( ! empty( $this->_args['label_item_plur'] ) ) {
1113
+ unset( $metabox_args['tabs']['settings']['fields']['label_plural'] );
1114
+ }
1115
+
1116
+ if ( $this->_args['manage_layouts'] ) {
1117
+
1118
+ if ( count( $layouts ) < 1 ) {
1119
+ unset( $metabox_args['tabs']['settings']['fields']['type'] );
1120
+ }
1121
+
1122
+ // Layouts options
1123
+ foreach ( $this->layouts as $layout => $args ) {
1124
+ if ( ! isset( $args['fields'] ) ) {
1125
+ continue;
1126
+ }
1127
+
1128
+ // Section title
1129
+ $metabox_args['tabs']['settings']['fields'][ $layout . '_title' ] = array(
1130
+ 'desc' => $args['name'] . ' ' . __( 'layout settings', 'yit' ),
1131
+ 'type' => 'title',
1132
+ 'deps' => array(
1133
+ 'ids' => '_type',
1134
+ 'values' => $layout
1135
+ )
1136
+ );
1137
+
1138
+ // Options
1139
+ foreach( $args['fields'] as $field_id => $field ) {
1140
+ $metabox_args['tabs']['settings']['fields'][ $field_id ] = $field;
1141
+ $metabox_args['tabs']['settings']['fields'][ $field_id ]['deps'] = array(
1142
+ 'ids' => '_type',
1143
+ 'values' => $layout
1144
+ );
1145
+ }
1146
+ }
1147
+ }else {
1148
+ unset( $metabox_args['tabs']['settings']['fields']['type'] );
1149
+ }
1150
+
1151
+ if( count( $single_layouts ) < 1 ){
1152
+ unset( $metabox_args['tabs']['settings']['fields']['single_layout'] );
1153
+ }
1154
+
1155
+ // undo if tab empty
1156
+ if ( empty( $metabox_args['tabs']['settings']['fields'] ) ) {
1157
+ return;
1158
+ }
1159
+
1160
+ $metabox = YIT_Metabox( $this->_name . '_cptu_settings' );
1161
+ $metabox->init( $metabox_args );
1162
+ }
1163
+
1164
+ /**
1165
+ * Register Metaboxes options
1166
+ *
1167
+ * Add the metabox for the portfolio settings
1168
+ *
1169
+ * @return void
1170
+ * @since 1.0
1171
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1172
+ */
1173
+ public function add_metabox_item_fields() {
1174
+ global $pagenow, $post_type;
1175
+
1176
+ // get the actual post type, to add the metabox only if necessary
1177
+ if ( $pagenow == 'post.php' && isset( $_REQUEST['post'] ) ) {
1178
+ $post_type = get_post_type( intval( $_REQUEST['post'] ) );
1179
+ }
1180
+ elseif( $pagenow == 'post.php' && isset( $_REQUEST['post_ID'] ) ){
1181
+ $post_type = get_post_type( intval( $_REQUEST['post_ID'] ) );
1182
+ }
1183
+ elseif ( $pagenow == 'post-new.php' && isset( $_REQUEST['post_type'] ) ) {
1184
+ $post_type = $_REQUEST['post_type'];
1185
+ } else {
1186
+ return;
1187
+ }
1188
+
1189
+ $layout = get_post_meta( $this->_get_id_by_name( $post_type ), $this->_args['layout_option'], true );
1190
+
1191
+ if ( empty( $this->layouts[ $layout ]['item_fields'] ) ) {
1192
+ return;
1193
+ }
1194
+
1195
+ $metabox_args = array(
1196
+ 'label' => __( 'Settings', 'yit' ),
1197
+ 'pages' => $post_type, //or array( 'post-type1', 'post-type2')
1198
+ 'context' => 'normal', //('normal', 'advanced', or 'side')
1199
+ 'priority' => 'default',
1200
+ 'tabs' => array(
1201
+ 'settings' => array(
1202
+ 'label' => __( 'Settings', 'yit' ),
1203
+ 'fields' => $this->layouts[ $layout ]['item_fields']
1204
+ )
1205
+ )
1206
+ );
1207
+
1208
+ $metabox = YIT_Metabox( $post_type . '_item_fields' );
1209
+ $metabox->init( $metabox_args );
1210
+
1211
+ }
1212
+
1213
+ /**
1214
+ * Add quick links inside the editing page of CPTU and Custom Post Types
1215
+ *
1216
+ * @return void
1217
+ * @since 1.0
1218
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1219
+ */
1220
+ public function add_quick_links_metaboxes() {
1221
+ // CPTU
1222
+ add_meta_box( $this->_name . '_quick_links', __( 'Quick links', 'yit' ), array( $this, 'quick_links_cptu_inner' ), $this->_name, 'side', 'high' );
1223
+
1224
+ // CPTs
1225
+ $args = array(
1226
+ 'post_type' => $this->_name,
1227
+ 'posts_per_page' => -1,
1228
+ 'post_status' => 'publish'
1229
+ );
1230
+ $post_types = get_posts( $args );
1231
+
1232
+ foreach ( $post_types as $post ) {
1233
+ $post_type = get_post_meta( $post->ID, '_post_type', true );
1234
+ extract( $this->_cpt_args( $post ) );
1235
+ add_meta_box( $post->post_type . '_quick_links', __( 'Quick links', 'yit' ), array( $this, 'quick_links_cpt_inner' ), $post_type, 'side', 'high' );
1236
+ }
1237
+ }
1238
+
1239
+ /**
1240
+ * Link to: "View Items", inside the CPTU
1241
+ *
1242
+ * @param $post
1243
+ *
1244
+ * @return void
1245
+ * @since 1.0
1246
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1247
+ */
1248
+ public function quick_links_cptu_inner( $post ) {
1249
+ extract( $this->_cpt_args( $post ) );
1250
+ ?>
1251
+ <a href="<?php echo admin_url( 'edit.php?post_type=' . get_post_meta( $post->ID, '_post_type', true ) ) ?>"><?php printf( __( 'View %s', 'yit' ), $label_plural ) ?></a>
1252
+ <?php
1253
+ }
1254
+
1255
+ /**
1256
+ * Link to: "Edit %s", inside the CPTU
1257
+ *
1258
+ * @param $post
1259
+ *
1260
+ * @return void
1261
+ * @since 1.0
1262
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1263
+ */
1264
+ public function quick_links_cpt_inner( $post ) {
1265
+ $post = get_post( $this->_get_id_by_name( $post->post_type ) );
1266
+ ?>
1267
+ <a href="<?php echo admin_url( "post.php?post={$post->ID}&action=edit" ) ?>"><?php printf( __( 'Edit %s', 'yit' ), $post->post_title ) ?></a>
1268
+ <?php
1269
+ }
1270
+
1271
+ /**
1272
+ * Define the columns to use in the list table of main sliders post type
1273
+ *
1274
+ * @param $columns array The columns used in the list table
1275
+ *
1276
+ * @return array
1277
+ * @since 1.0
1278
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1279
+ */
1280
+ public function cptu_define_columns( $columns ) {
1281
+ unset( $columns['date'] );
1282
+
1283
+ $columns['actions'] = '';
1284
+
1285
+ return $columns;
1286
+ }
1287
+
1288
+ /**
1289
+ * Change the content of each column of the table list
1290
+ *
1291
+ * @param $column string The current column
1292
+ * @param $post_id int The current post ID
1293
+ *
1294
+ * @return void
1295
+ * @since 1.0
1296
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1297
+ */
1298
+ public function cptu_change_columns( $column, $post_id ) {
1299
+ $post = get_post( $post_id );
1300
+ extract( $this->_cpt_args( $post ) );
1301
+
1302
+ switch ( $column ) {
1303
+ case 'actions' :
1304
+ echo '<a href="' . admin_url( "post.php?post={$post_id}&action=edit" ) . '" class="button-secondary">' . sprintf( __( 'Edit %s', 'yit' ), ucfirst( $this->_labels['singular'] ) ) . '</a> ';
1305
+ echo '<a href="' . admin_url( 'edit.php?post_type=' . get_post_meta( $post_id, '_post_type', true ) ) . '" class="button-secondary">' . sprintf( __( 'View %s', 'yit' ), $label_plural ) . '</a> ';
1306
+ break;
1307
+ }
1308
+ }
1309
+
1310
+ /**
1311
+ * Retrieve the path of layout specified in parameter
1312
+ *
1313
+ * @param $layout
1314
+ * @param $file string The file to find
1315
+ *
1316
+ * @return bool|string
1317
+ * @since 1.0
1318
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1319
+ */
1320
+ public function locate_file( $layout, $file = '' ) {
1321
+ if ( ! $this->_args['manage_layouts'] ) {
1322
+ return $this->template_path(). '/' . ( ! empty( $file ) ? $file . '.php' : '' );
1323
+ }
1324
+
1325
+ if ( ! isset( $this->layouts[ $layout ] ) ) {
1326
+ $layout = 'default';
1327
+ }
1328
+
1329
+ return $this->layouts[ $layout ]['path'] . '/' . ( ! empty( $file ) ? $file . '.php' : '' );
1330
+ }
1331
+
1332
+ /**
1333
+ * Retrieve the URL of layout specified in parameter
1334
+ *
1335
+ * @param $layout
1336
+ * @param $file string The file to find
1337
+ *
1338
+ * @return bool|string
1339
+ * @since 1.0
1340
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1341
+ */
1342
+ public function locate_url( $layout, $file = '' ) {
1343
+ if ( ! $this->_args['manage_layouts'] ) {
1344
+ return $this->template_url();
1345
+
1346
+ }
1347
+
1348
+ if ( ! isset( $this->layouts[ $layout ] ) ) {
1349
+ $layout = 'default';
1350
+ }
1351
+
1352
+ return $this->layouts[ $layout ]['url'] . '/' . ( ! empty( $file ) ? $file . '.php' : '' );
1353
+ }
1354
+
1355
+ /**
1356
+ * Retrieve the post ID relative to the post of post type
1357
+ *
1358
+ * @param $name string
1359
+ *
1360
+ * @return mixed
1361
+ * @since 1.0
1362
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1363
+ */
1364
+ protected function _get_id_by_name( $name ) {
1365
+ global $wpdb;
1366
+ return $wpdb->get_var( $wpdb->prepare( "SELECT pm.post_id FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $name, $this->_name ) );
1367
+ }
1368
+
1369
+ /**
1370
+ * Retrieve the post_type of portfolio by portfolio name
1371
+ *
1372
+ * @param $name string
1373
+ *
1374
+ * @return mixed
1375
+ * @since 1.0
1376
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1377
+ */
1378
+ protected function _get_post_type_by_name( $name ) {
1379
+ global $wpdb;
1380
+ return $wpdb->get_var( $wpdb->prepare( "SELECT pm.meta_value FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND p.post_name = %s AND p.post_type = %s", '_post_type', $name, $this->_name ) );
1381
+ }
1382
+
1383
+ /**
1384
+ * The shortcode used to show the frontend
1385
+ *
1386
+ * @param array $atts
1387
+ * @param null $content
1388
+ *
1389
+ * @return string|null
1390
+ * @since 1.0
1391
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1392
+ */
1393
+ public function add_shortcode( $atts, $content = null ) {
1394
+ $atts = wp_parse_args( $atts, array(
1395
+ 'name' => null,
1396
+ 'cat' => array(),
1397
+ 'posts_per_page' => false,
1398
+ 'style' => null,
1399
+ ) );
1400
+
1401
+ // don't show the slider if 'name' is empty or is 'none'
1402
+ if ( empty( $atts['name'] ) || 'none' == $atts['name'] ) return null;
1403
+
1404
+ // compatibility fix: remove prefix if exists in portfolio object
1405
+ if( function_exists( 'YIT_Portfolio' ) && method_exists( YIT_Portfolio(), 'is' ) && YIT_Portfolio()->is( $atts['name'] ) ){
1406
+ $atts['name'] = str_replace( YIT_Portfolio()->post_type_prefix, '', $atts['name'] );
1407
+ }
1408
+
1409
+ // pass vars to template
1410
+ $atts['post_type'] = $this->_get_post_type_by_name( $atts['name'] );
1411
+ $atts['layout'] = $this->_args['manage_layouts'] ? get_post_meta( $this->_get_id_by_name( $atts['post_type'] ), $this->_args['layout_option'], true ) : '';
1412
+ extract( apply_filters( 'yit_cptu_frontend_vars', $atts, $this->_name ) );
1413
+
1414
+ // add the javascript assets
1415
+ if ( $this->_args['manage_layouts'] && isset( $this->layouts[ $layout ]['js'] ) && ! empty( $this->layouts[ $layout ]['js'] ) ) {
1416
+ foreach ( $this->layouts[ $layout ]['js'] as $asset ) {
1417
+ if ( empty( $asset ) ) continue;
1418
+
1419
+ if ( empty( $asset['src'] ) ) {
1420
+ wp_enqueue_script( $asset['handle'] );
1421
+ continue;
1422
+ }
1423
+
1424
+ yit_enqueue_script( $asset['handle'], $this->locate_url( $layout ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['in_footer'] );
1425
+ }
1426
+ }
1427
+
1428
+ // Unique sequential index to differentiate more cpt in the same page
1429
+ ++$this->index;
1430
+
1431
+ ob_start();
1432
+
1433
+ include( $this->locate_file( $layout, 'markup' ) );
1434
+
1435
+ return ob_get_clean();
1436
+
1437
+ }
1438
+
1439
+ /**
1440
+ * Shortcode icon
1441
+ *
1442
+ * Return the shortcode icone to display on shortcode panel
1443
+ *
1444
+ * @param $icon_url string Icone url found by yit_shortcode plugin
1445
+ *
1446
+ * @return string
1447
+ * @since 1.0.0
1448
+ * @author Antonino Scarfi' <antonio.scarfi@yithemes.it>
1449
+ */
1450
+ public function shortcode_icon( $icon_url ) {
1451
+ return ! empty( $this->_args['shortcode_icon'] ) ? $this->_args['shortcode_icon'] : $icon_url;
1452
+ }
1453
+
1454
+ /**
1455
+ * Return an array with cptu options to shortcode panel
1456
+ *
1457
+ * All definition settings to add cptu shortcode to Yit Shortcode Panel
1458
+ *
1459
+ * @param array $shortcodes
1460
+ *
1461
+ * @return array
1462
+ * @since 1.0
1463
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1464
+ */
1465
+ public function add_shortcode_to_box( $shortcodes ) {
1466
+ $post_types = array();
1467
+
1468
+ foreach ( $this->get_post_types() as $post ) {
1469
+ $post_types[ $post->post_name ] = $post->post_title;
1470
+ }
1471
+
1472
+ $args = array(
1473
+ $this->_args['shortcode_name'] => array(
1474
+ 'title' => $this->_labels['singular'],
1475
+ 'description' => sprintf( __( 'Show the frontend of the %s', 'yit' ), $this->_labels['main_name'] ),
1476
+ 'tab' => 'cpt',
1477
+ 'create' => false,
1478
+ 'has_content' => false,
1479
+ 'in_visual_composer' => true,
1480
+ 'attributes' => array(
1481
+ 'name' => array(
1482
+ 'title' => __( 'Name', 'yit' ),
1483
+ 'type' => 'select',
1484
+ 'options' => $post_types,
1485
+ 'std' => ''
1486
+ ),
1487
+ )
1488
+ )
1489
+ );
1490
+
1491
+ return array_merge( $shortcodes, $args );
1492
+ }
1493
+
1494
+ /**
1495
+ * Check the post type passed in parameter, if is generated by this CPTU
1496
+ *
1497
+ * @param $post_type string The post type to check
1498
+ *
1499
+ * @return bool
1500
+ * @since 1.0
1501
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1502
+ */
1503
+ protected function _is_valid( $post_type ) {
1504
+ return (bool)( strpos( $post_type, $this->_args['post_type_prefix'] ) !== false );
1505
+ }
1506
+
1507
+ /**
1508
+ * Add as a valid post type all cptu when importing dummy data
1509
+ *
1510
+ * @param $post array The post object
1511
+ *
1512
+ * @return array
1513
+ * @since 1.0
1514
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
1515
+ */
1516
+ public function add_importer_required_post_type( $post ){
1517
+ global $wp_post_types, $wp_taxonomies;
1518
+
1519
+ if( strpos( $post['post_type'], $this->_prefix_cpt ) === FALSE ){
1520
+ return $post;
1521
+ }
1522
+
1523
+ if( ! isset( $wp_post_types[ $post['post_type'] ] ) ){
1524
+ $wp_post_types[ $post['post_type'] ] = array(
1525
+ 'name' => ''
1526
+ );
1527
+ }
1528
+
1529
+ if( ! empty( $post['terms'] ) ){
1530
+ foreach( $post['terms'] as $term ){
1531
+ if( ! isset( $wp_taxonomies[ $term['domain'] ] ) ){
1532
+ $wp_taxonomies[ $term['domain'] ] = array(
1533
+ 'name' => ''
1534
+ );
1535
+ }
1536
+ }
1537
+ }
1538
+
1539
+
1540
+ return $post;
1541
+ }
1542
+
1543
+ /**
1544
+ * Add taxonomy when importing dummy data
1545
+ *
1546
+ * @param $terms array Array of terms
1547
+ *
1548
+ * @return array
1549
+ * @since 1.0
1550
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
1551
+ */
1552
+ public function add_importer_required_taxonomy( $terms ){
1553
+ global $wp_taxonomies;
1554
+
1555
+ if( ! empty( $terms ) ){
1556
+ foreach ( $terms as $term ) {
1557
+ if( isset( $term['domain'] ) && ! isset( $wp_taxonomies[ $term['domain'] ] ) ){
1558
+ $wp_taxonomies[ $term['domain'] ] = array(
1559
+ 'name' => ''
1560
+ );
1561
+ }
1562
+ }
1563
+ }
1564
+
1565
+ return $terms;
1566
+ }
1567
+
1568
+ /**
1569
+ * Force terms recount for imported taxonomy
1570
+ *
1571
+ * @param $tt_ids array Terms ids
1572
+ * @param $ids array Post ids
1573
+ * @param $tax string Taxonomy name
1574
+ *
1575
+ * @return void
1576
+ * @since 1.0
1577
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
1578
+ */
1579
+ public function recount_terms_post( $tt_ids, $ids, $tax ){
1580
+ wp_update_term_count( $tt_ids, $tax );
1581
+ }
1582
+
1583
+ // ### ASSETS ###
1584
+
1585
+ /**
1586
+ * Enqueue the assets for the admin
1587
+ *
1588
+ * @return void
1589
+ * @since 1.0
1590
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1591
+ */
1592
+ public function admin_assets() {
1593
+ wp_enqueue_media();
1594
+ wp_enqueue_script( 'yit-cptu', YIT_CORE_PLUGIN_URL . '/assets/js/yit-cpt-unlimited.js', array('jquery'), '', true );
1595
+ }
1596
+
1597
+ /**
1598
+ * Add the button to the top of the list table page of CPTU
1599
+ *
1600
+ * @return void
1601
+ * @since 1.0
1602
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1603
+ */
1604
+ public function add_button_multiuploader() {
1605
+ global $pagenow, $post_type, $wpdb;
1606
+
1607
+ if( $pagenow != 'edit.php' ){
1608
+ return;
1609
+ }
1610
+
1611
+ $cptu = $wpdb->get_var( $wpdb->prepare( "SELECT p.post_type FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s", '_post_type', $post_type ) );
1612
+
1613
+ $post = get_post( $this->_get_id_by_name( $post_type ) );
1614
+ if ( empty( $post ) ) {
1615
+ return;
1616
+ }
1617
+ extract( $this->_cpt_args( $post ) );
1618
+
1619
+ if ( $cptu != $this->_name || ! $this->_is_valid( $post_type ) ) {
1620
+ return;
1621
+ }
1622
+ ?>
1623
+ <script>
1624
+ (function($) {
1625
+ "use strict";
1626
+ // Author code here
1627
+
1628
+ var button = $('<a />', {
1629
+ href: '#',
1630
+ class: 'multi-uploader add-new-h2',
1631
+ 'data-uploader_title': '<?php printf( __( 'Add %s by images', 'yit' ), $label_plural ) ?>',
1632
+ 'data-uploader_button_text': '<?php printf( __( 'Add %s', 'yit' ), $label_plural ) ?>'
1633
+ }).text('<?php _e( 'Add with multiupload', 'yit' ) ?>');
1634
+
1635
+ var spinner = $('<span />', {
1636
+ class: 'spinner',
1637
+ style: 'float: none;'
1638
+ });
1639
+
1640
+ button.appendTo('.wrap h2').after(spinner);
1641
+
1642
+ })(jQuery);
1643
+ </script>
1644
+ <?php
1645
+ }
1646
+
1647
+ /**
1648
+ * Add more posts by multiupload
1649
+ *
1650
+ * @return void
1651
+ * @since 1.0
1652
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1653
+ */
1654
+ public function post_multiuploader() {
1655
+ if ( ! isset( $_REQUEST['images'] ) || ! isset( $_REQUEST['post_type'] ) && $this->_is_valid( $_REQUEST['post_type'] ) ) {
1656
+ return;
1657
+ }
1658
+
1659
+ foreach ( $_REQUEST['images'] as $the ) {
1660
+
1661
+ // Create post object
1662
+ $arg = array(
1663
+ 'post_title' => $the['title'],
1664
+ 'post_type' => $_REQUEST['post_type']
1665
+ );
1666
+ $post_id = wp_insert_post( $arg );
1667
+
1668
+ set_post_thumbnail( $post_id, $the['id'] );
1669
+
1670
+ }
1671
+
1672
+ die();
1673
+ }
1674
+
1675
+
1676
+ // ###### SINGLE TEMPLATE ######
1677
+
1678
+ /**
1679
+ * Load the single template file
1680
+ *
1681
+ * @return void
1682
+ * @since 1.0
1683
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1684
+ */
1685
+ public function single_template() {
1686
+ global $post, $wpdb;
1687
+
1688
+ // if ( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ) {
1689
+ // $post = get_post( $_REQUEST['post_id'] );
1690
+ // }
1691
+
1692
+ if ( ( ( ! defined('DOING_AJAX') || ! DOING_AJAX ) && ! is_single() ) || ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
1693
+ return;
1694
+ }
1695
+
1696
+ // add the javascript assets
1697
+ if ( $this->_args['manage_layouts'] ) {
1698
+ foreach ( $this->layouts[ 'single' ]['js'] as $asset ) {
1699
+ yit_enqueue_script( $asset['handle'], $this->locate_url( 'single' ) . $asset['src'], $asset['deps'], $asset['ver'], $asset['in_footer'] );
1700
+ }
1701
+ }
1702
+
1703
+ $post_name = $wpdb->get_var( $wpdb->prepare( "SELECT p.post_name FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $post->post_type, $this->_name ) );
1704
+ extract( apply_filters( 'yit_cptu_frontend_vars', array( 'name' => $post_name ), $this->_name ) );
1705
+
1706
+ include( $this->locate_file( 'single', 'markup' ) );
1707
+ }
1708
+
1709
+ /**
1710
+ * Load a file for the configuration of single template page of portfolio
1711
+ *
1712
+ * @return void
1713
+ * @since 1.0
1714
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1715
+ */
1716
+ public function single_template_config() {
1717
+ global $post, $wpdb;
1718
+
1719
+ if ( defined('DOING_AJAX') && DOING_AJAX && isset( $_REQUEST['post_id'] ) ) {
1720
+ $post = get_post( $_REQUEST['post_id'] );
1721
+ }
1722
+
1723
+ if ( ( ( ! defined('DOING_AJAX') || ! DOING_AJAX ) && ! is_single() ) || ! isset( $post->post_type ) || ! $this->_is_valid( $post->post_type ) ) {
1724
+ return;
1725
+ }
1726
+
1727
+ $this->_layout = 'single';
1728
+ $path = $this->locate_file( 'single', 'config' );
1729
+
1730
+ if ( file_exists( $path ) ) {
1731
+ $post_name = $wpdb->get_var( $wpdb->prepare( "SELECT p.post_name FROM $wpdb->postmeta AS pm INNER JOIN $wpdb->posts AS p ON p.ID = pm.post_id WHERE pm.meta_key = %s AND pm.meta_value = %s AND p.post_type = %s", '_post_type', $post->post_type, $this->_name ) );
1732
+ extract( apply_filters( 'yit_cptu_frontend_vars', array( 'name' => $post_name ), $this->_name ) );
1733
+
1734
+ include( $path );
1735
+ }
1736
+ }
1737
+
1738
+
1739
+ // ########################## ARCHIVE TEMPLATE ###############################
1740
+
1741
+
1742
+ /**
1743
+ * Load the template for archive page
1744
+ *
1745
+ * @return void
1746
+ * @since 1.0
1747
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1748
+ */
1749
+ public function archive_template() {
1750
+ global $wp_query;
1751
+
1752
+
1753
+ // check if we are in archive template
1754
+ if ( !( ! is_admin() && is_archive() && isset( $wp_query->post->post_type ) && $this->_is_valid( $wp_query->post->post_type ) ) ) {
1755
+ return;
1756
+ }
1757
+
1758
+ // remove the action from loop of theme
1759
+ remove_action( 'yit_content_loop', 'yit_content_loop', 10 );
1760
+ add_action( 'yit_content_loop', array( $this, 'archive_template_loop' ), 10 );
1761
+
1762
+ }
1763
+
1764
+ /**
1765
+ * Load loop for the archive template
1766
+ *
1767
+ * @return void
1768
+ * @since 1.0
1769
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
1770
+ */
1771
+ public function archive_template_loop() {
1772
+ echo $this->add_shortcode( array( 'name' => $GLOBALS['wp_query']->post->post_type ) );
1773
+ }
1774
+
1775
+ }
plugin-fw/lib/yit-metabox.php ADDED
@@ -0,0 +1,537 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ } // Exit if accessed directly
15
+
16
+ if ( ! class_exists( 'YIT_Metabox' ) ) {
17
+ /**
18
+ * YIT Metabox
19
+ *
20
+ * the metabox can be created using this code
21
+ * <code>
22
+ * $args1 = array(
23
+ * 'label' => __( 'Metabox Label', 'yit' ),
24
+ * 'pages' => 'page', //or array( 'post-type1', 'post-type2')
25
+ * 'context' => 'normal', //('normal', 'advanced', or 'side')
26
+ * 'priority' => 'default',
27
+ * 'tabs' => array(
28
+ * 'settings' => array( //tab
29
+ * 'label' => __( 'Settings', 'yit' ),
30
+ * 'fields' => array(
31
+ * 'meta_checkbox' => array(
32
+ * 'label' => __( 'Show title', 'yit' ),
33
+ * 'desc' => __( 'Show or not the title of the page.', 'yit' ),
34
+ * 'type' => 'checkbox',
35
+ * 'private' => false,
36
+ * 'std' => '1'),
37
+ * ),
38
+ * ),
39
+ * );
40
+ *
41
+ * $metabox1 = YIT_Metabox( 'yit-metabox-id' );
42
+ * $metabox1->init( $args );
43
+ * </code>
44
+ *
45
+ * @class YIT_Metaboxes
46
+ * @package Yithemes
47
+ * @since 1.0.0
48
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
49
+ *
50
+ */
51
+
52
+ class YIT_Metabox {
53
+
54
+ /**
55
+ * @var string the id of metabox
56
+ *
57
+ * @since 1.0
58
+ */
59
+
60
+ public $id;
61
+
62
+ /**
63
+ * @var array An array where are saved all metabox settings options
64
+ *
65
+ * @since 1.0
66
+ */
67
+ private $options = array();
68
+
69
+ /**
70
+ * @var array An array where are saved all tabs of metabox
71
+ *
72
+ * @since 1.0
73
+ */
74
+ private $tabs = array();
75
+
76
+ /**
77
+ * @var object The single instance of the class
78
+ * @since 1.0
79
+ */
80
+ protected static $_instance = array();
81
+
82
+ /**
83
+ * Main Instance
84
+ *
85
+ * @static
86
+ *
87
+ * @param $id
88
+ *
89
+ * @return object Main instance
90
+ *
91
+ * @since 1.0
92
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
93
+ */
94
+ public static function instance( $id ) {
95
+ if ( ! isset( self::$_instance[$id] ) ) {
96
+ self::$_instance[$id] = new self( $id );
97
+ }
98
+ return self::$_instance[$id];
99
+ }
100
+
101
+ /**
102
+ * Constructor
103
+ *
104
+ * @param string $id
105
+ *
106
+ * @return \YIT_Metabox
107
+ * @since 1.0
108
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
109
+ */
110
+ function __construct( $id = '' ) {
111
+ $this->id = $id;
112
+
113
+ }
114
+
115
+
116
+ /**
117
+ * Init
118
+ *
119
+ * set options and tabs, add actions to register metabox, scripts and save data
120
+ *
121
+ * @param array $options
122
+ *
123
+ * @return void
124
+ * @since 1.0
125
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
126
+ */
127
+ public function init( $options = array() ) {
128
+
129
+ $this->set_options( $options );
130
+ $this->set_tabs();
131
+
132
+
133
+ add_action( 'add_meta_boxes', array( $this, 'register_metabox' ) );
134
+ add_action( 'save_post', array( $this, 'save_postdata' ) );
135
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ), 15 );
136
+
137
+ }
138
+
139
+ /**
140
+ * Enqueue script and styles in admin side
141
+ *
142
+ * Add style and scripts to administrator
143
+ *
144
+ * @return void
145
+ * @since 1.0
146
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
147
+ */
148
+ public function enqueue() {
149
+
150
+ wp_enqueue_media();
151
+ wp_enqueue_style( 'wp-color-picker' );
152
+ wp_enqueue_style( 'yit-plugin-metaboxes', YIT_CORE_PLUGIN_URL . '/assets/css/metaboxes.css' );
153
+ wp_enqueue_style( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/css/chosen/chosen.css' );
154
+ wp_enqueue_script( 'jquery-ui-datepicker' );
155
+ wp_enqueue_script( 'yit-spinner', YIT_CORE_PLUGIN_URL . '/assets/js/panel.spinner.js', array( 'jquery' ), '0.0.1', true );
156
+ wp_enqueue_script( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/js/chosen/chosen.jquery.js', array( 'jquery' ), '1.1.0', true );
157
+ wp_enqueue_script( 'yit-metabox', YIT_CORE_PLUGIN_URL . '/assets/js/metabox.js', array( 'jquery', 'wp-color-picker' ), '1.0.0', true );
158
+ wp_enqueue_style( 'jquery-ui-overcast', YIT_CORE_PLUGIN_URL . '/assets/css/overcast/jquery-ui-1.8.9.custom.css', false, '1.8.9', 'all' );
159
+
160
+ if( function_exists( 'WC' ) ){
161
+ wp_enqueue_script( 'woocommerce_admin' );
162
+ wp_enqueue_script('ajax-chosen');
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Set Options
168
+ *
169
+ * Set the variable options
170
+ *
171
+ * @param array $options
172
+ *
173
+ * @return void
174
+ * @since 1.0
175
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
176
+ */
177
+ public function set_options( $options = array() ) {
178
+ $this->options = $options;
179
+
180
+ }
181
+
182
+ /**
183
+ * Set Tabs
184
+ *
185
+ * Set the variable tabs
186
+ *
187
+ * @internal param array $tabs
188
+ *
189
+ * @return void
190
+ * @since 1.0
191
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
192
+ */
193
+ public function set_tabs() {
194
+ if ( ! isset( $this->options['tabs'] ) ) {
195
+ return;
196
+ }
197
+ $this->tabs = $this->options['tabs'] ;
198
+ if( isset($this->tabs['settings']['fields']) ){
199
+ $this->tabs['settings']['fields'] = array_filter( $this->tabs['settings']['fields'] );
200
+ }
201
+ }
202
+
203
+
204
+ /**
205
+ * Add Tab
206
+ *
207
+ * Add a tab inside the metabox
208
+ *
209
+ * @internal param array $tabs
210
+ *
211
+ * @param array $tab the new tab to add to the metabox
212
+ * @param string $where tell where insert the tab if after or before a $refer
213
+ * @param null $refer an existent tab inside metabox
214
+ *
215
+ * @return void
216
+ * @since 1.0
217
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
218
+ */
219
+ public function add_tab( $tab, $where = 'after', $refer = null ) {
220
+ if ( ! is_null( $refer ) ) {
221
+ $ref_pos = array_search( $refer, array_keys( $this->tabs ) );
222
+ if ( $ref_pos !== false ) {
223
+ if ( $where == 'after' ) {
224
+ $this->tabs = array_slice( $this->tabs, 0, $ref_pos + 1, true ) +
225
+ $tab +
226
+ array_slice( $this->tabs, $ref_pos + 1, count( $this->tabs ) - 1, true );
227
+ }
228
+ else {
229
+ $this->tabs = array_slice( $this->tabs, 0, $ref_pos, true ) +
230
+ $tab +
231
+ array_slice( $this->tabs, $ref_pos, count( $this->tabs ), true );
232
+ }
233
+ }
234
+ }
235
+ else {
236
+ $this->tabs = array_merge( $tab, $this->tabs );
237
+ }
238
+
239
+ }
240
+
241
+ /**
242
+ * Remove Tab
243
+ *
244
+ * Remove a tab from the tabs of metabox
245
+ *
246
+ * @internal param array $tabs
247
+ *
248
+ * @param $id_tab
249
+ *
250
+ * @return void
251
+ * @since 1.0
252
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
253
+ */
254
+ public function remove_tab( $id_tab ) {
255
+ if ( isset( $this->tabs[$id_tab] ) ) {
256
+ unset ( $this->tabs[$id_tab] );
257
+ }
258
+ }
259
+
260
+
261
+ /**
262
+ * Add Field
263
+ *
264
+ * Add a field inside a tab of metabox
265
+ *
266
+ * @internal param array $tabs
267
+ *
268
+ * @param string $tab_id the id of the tabs where add the field
269
+ * @param array $args the field to add
270
+ * @param string $where tell where insert the field if after or before a $refer
271
+ * @param null $refer an existent field inside tab
272
+ *
273
+ * @return void
274
+ * @since 1.0
275
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
276
+ */
277
+ public function add_field( $tab_id, $args, $where = 'after', $refer = null ) {
278
+ if ( isset( $this->tabs[$tab_id] ) ) {
279
+
280
+ $cf = $this->tabs[$tab_id]['fields'];
281
+ if ( ! is_null( $refer ) ) {
282
+ $ref_pos = array_search( $refer, array_keys( $cf ) );
283
+ if ( $ref_pos !== false ) {
284
+ if ( $where == 'after' ) {
285
+ $this->tabs[$tab_id]['fields'] = array_slice( $cf, 0, $ref_pos + 1, true ) +
286
+ $args +
287
+ array_slice( $cf, $ref_pos, count( $cf ) - 1, true );
288
+
289
+ } elseif ( $where == 'before' ) {
290
+ $this->tabs[$tab_id]['fields'] = array_slice( $cf, 0, $ref_pos, true ) +
291
+ $args +
292
+ array_slice( $cf, $ref_pos, count( $cf ), true );
293
+
294
+ }
295
+ }
296
+ }
297
+ else {
298
+ if ( $where == 'first' ) {
299
+ $this->tabs[$tab_id]['fields'] = $args + $cf;
300
+
301
+ } else {
302
+ $this->tabs[$tab_id]['fields'] = array_merge( $this->tabs[$tab_id]['fields'], $args );
303
+ }
304
+ }
305
+
306
+ }
307
+
308
+
309
+ }
310
+
311
+ /**
312
+ * Remove Field
313
+ *
314
+ * Remove a field from the metabox, search inside the tabs and remove it if exists
315
+ *
316
+ * @param $id_field
317
+ *
318
+ * @return void
319
+ * @since 1.0
320
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
321
+ */
322
+ public function remove_field( $id_field ) {
323
+ foreach ( $this->tabs as $tab_name => $tab ) {
324
+ if ( isset( $tab['fields'][$id_field] ) ) {
325
+ unset ( $this->tabs[$tab_name]['fields'][$id_field] );
326
+ }
327
+ }
328
+ }
329
+
330
+ /**
331
+ * Reorder tabs
332
+ *
333
+ * Order the tabs and fields and set id and name to each field
334
+ *
335
+ * @internal param $id_field
336
+ *
337
+ * @return void
338
+ * @since 1.0
339
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
340
+ */
341
+ public function reorder_tabs() {
342
+ foreach ( $this->tabs as $tab_name => $tab ) {
343
+ foreach ( $tab['fields'] as $id_field => $field ) {
344
+ $this->tabs[$tab_name]['fields'][$id_field]['private'] = ( isset( $field['private'] ) ) ? $field['private'] : true;
345
+ $this->tabs[$tab_name]['fields'][$id_field]['id'] = $this->get_option_metabox_id( $id_field, $this->tabs[$tab_name]['fields'][$id_field]['private'] );
346
+ $this->tabs[$tab_name]['fields'][$id_field]['name'] = $this->get_option_metabox_name( $this->tabs[$tab_name]['fields'][$id_field]['id'] );
347
+ }
348
+ }
349
+
350
+ }
351
+
352
+
353
+ /**
354
+ * Get Option Metabox ID
355
+ *
356
+ * return the id of the field
357
+ *
358
+ * @param string $id_field
359
+ * @param bool $private if private add an _befor the id
360
+ *
361
+ * @return string
362
+ * @since 1.0
363
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
364
+ */
365
+ public function get_option_metabox_id( $id_field, $private = true ) {
366
+ if ( $private ) {
367
+ return '_' . $id_field;
368
+ }
369
+ else {
370
+ return $id_field;
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Get Option Metabox Name
376
+ *
377
+ * return the name of the field, this name will be used as attribute name of the input field
378
+ *
379
+ * @param string $id_field
380
+ * @param bool $private if private add an _befor the id
381
+ *
382
+ * @return string
383
+ * @since 1.0
384
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
385
+ */
386
+ public function get_option_metabox_name( $id_field, $private = true ) {
387
+ $db_name = apply_filters( 'yit_metaboxes_option_main_name', 'yit_metaboxes' );
388
+ $return = $db_name . '[';
389
+
390
+ if ( ! strpos( $id_field, '[' ) ) {
391
+ return $return . $id_field . ']';
392
+ }
393
+ $return .= substr( $id_field, 0, strpos( $id_field, '[' ) );
394
+ $return .= ']';
395
+ $return .= substr( $id_field, strpos( $id_field, '[' ) );
396
+
397
+ return $return;
398
+ }
399
+
400
+ /**
401
+ * Register the metabox
402
+ *
403
+ * call the wp function add_metabox to add the metabox
404
+ *
405
+ *
406
+ * @return void
407
+ * @since 1.0
408
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
409
+ */
410
+ public function register_metabox() {
411
+ add_meta_box( $this->id, $this->options['label'], array( $this, 'show' ), $this->options['pages'], $this->options['context'], $this->options['priority'] );
412
+ }
413
+
414
+ /**
415
+ * Show metabox
416
+ *
417
+ * show the html of metabox
418
+ *
419
+ *
420
+ * @return void
421
+ * @since 1.0
422
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
423
+ */
424
+ public function show() {
425
+ $this->reorder_tabs();
426
+
427
+ yit_plugin_get_template( YIT_CORE_PLUGIN_PATH, 'metaboxes/tab.php', array( 'tabs' => $this->tabs ) );
428
+ }
429
+
430
+ /**
431
+ * Save Post Data
432
+ *
433
+ * Save the post data in the database when save the post
434
+ *
435
+ * @param $post_id
436
+ *
437
+ * @return int
438
+ * @since 1.0
439
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
440
+ */
441
+ public function save_postdata( $post_id ) {
442
+
443
+
444
+
445
+ if ( ! isset( $_POST['yit_metaboxes_nonce'] ) || ! wp_verify_nonce( $_POST['yit_metaboxes_nonce'], 'metaboxes-fields-nonce' ) ) {
446
+ return $post_id;
447
+ }
448
+
449
+
450
+ if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
451
+ return $post_id;
452
+ }
453
+
454
+ if ( isset( $_POST['post_type'] ) ) {
455
+ $post_type = $_POST['post_type'];
456
+ }
457
+ else {
458
+ return $post_id;
459
+ }
460
+
461
+ if ( 'page' == $post_type ) {
462
+ if ( ! current_user_can( 'edit_page', $post_id ) ) {
463
+ return $post_id;
464
+ }
465
+ }
466
+ else {
467
+ if ( ! current_user_can( 'edit_post', $post_id ) ) {
468
+ return $post_id;
469
+ }
470
+ }
471
+
472
+ $this->reorder_tabs();
473
+
474
+
475
+ foreach ( $this->tabs as $tab ) {
476
+
477
+ foreach ( $tab['fields'] as $field ) {
478
+
479
+ if ( in_array( $field['type'], array( 'title' ) ) ) {
480
+ continue;
481
+ }
482
+
483
+ if ( isset( $_POST['yit_metaboxes'][$field['id']] ) ) {
484
+
485
+ add_post_meta( $post_id, $field['id'], $_POST['yit_metaboxes'][$field['id']], true ) || update_post_meta( $post_id, $field['id'], $_POST['yit_metaboxes'][$field['id']] );
486
+ }
487
+ elseif ( in_array( $field['type'], array( 'onoff', 'checkbox' ) ) ) {
488
+ add_post_meta( $post_id, $field['id'], '0', true ) || update_post_meta( $post_id, $field['id'], '0' );
489
+ }
490
+ else {
491
+ delete_post_meta( $post_id, $field['id'] );
492
+ }
493
+ }
494
+ }
495
+
496
+ }
497
+
498
+ /**
499
+ * Remove Fields
500
+ *
501
+ * Remove a fields list from the metabox, search inside the tabs and remove it if exists
502
+ *
503
+ * @param $id_fields
504
+ *
505
+ * @return void
506
+ * @since 2.0.0
507
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
508
+ */
509
+ public function remove_fields( $id_fields ) {
510
+ foreach ( $id_fields as $k => $field ) {
511
+ $this->remove_field( $field );
512
+ }
513
+ }
514
+ }
515
+ }
516
+
517
+ if ( ! function_exists( 'YIT_Metabox' ) ) {
518
+
519
+ /**
520
+ * Main instance of plugin
521
+ *
522
+ * @param $id
523
+ *
524
+ * @return \YIT_Metabox
525
+ * @since 1.0
526
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
527
+ */
528
+
529
+
530
+ function YIT_Metabox( $id ) {
531
+ return YIT_Metabox::instance( $id );
532
+ }
533
+ }
534
+
535
+
536
+
537
+
plugin-fw/lib/yit-plugin-common.php ADDED
@@ -0,0 +1,1034 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! class_exists( 'YIT_Plugin_Common' ) ) :
12
+
13
+ /**
14
+ * Core configuration class
15
+ *
16
+ * @since 1.0.0
17
+ */
18
+ class YIT_Plugin_Common {
19
+
20
+ /**
21
+ * Config array
22
+ *
23
+ * @var array
24
+ */
25
+ protected static $_config = array(
26
+ 'slider' => array( 'nivo', 'elegant' ),
27
+
28
+
29
+ 'awesome_icons' => array(
30
+ 'f042' => 'adjust',
31
+ 'f170' => 'adn',
32
+ 'f037' => 'align-center',
33
+ 'f039' => 'align-justify',
34
+ 'f036' => 'align-left',
35
+ 'f038' => 'align-right',
36
+ 'f0f9' => 'ambulance',
37
+ 'f13d' => 'anchor',
38
+ 'f17b' => 'android',
39
+ 'f103' => 'angle-double-down',
40
+ 'f100' => 'angle-double-left',
41
+ 'f101' => 'angle-double-right',
42
+ 'f102' => 'angle-double-up',
43
+ 'f107' => 'angle-down',
44
+ 'f104' => 'angle-left',
45
+ 'f105' => 'angle-right',
46
+ 'f106' => 'angle-up',
47
+ 'f179' => 'apple',
48
+ 'f187' => 'archive',
49
+ 'f0ab' => 'arrow-circle-down',
50
+ 'f0a8' => 'arrow-circle-left',
51
+ 'f01a' => 'arrow-circle-o-down',
52
+ 'f190' => 'arrow-circle-o-left',
53
+ 'f18e' => 'arrow-circle-o-right',
54
+ 'f01b' => 'arrow-circle-o-up',
55
+ 'f0a9' => 'arrow-circle-right',
56
+ 'f0aa' => 'arrow-circle-up',
57
+ 'f063' => 'arrow-down',
58
+ 'f060' => 'arrow-left',
59
+ 'f061' => 'arrow-right',
60
+ 'f062' => 'arrow-up',
61
+ 'f047' => 'arrows',
62
+ 'f0b2' => 'arrows-alt',
63
+ 'f07e' => 'arrows-h',
64
+ 'f07d' => 'arrows-v',
65
+ 'f069' => 'asterisk',
66
+ 'f04a' => 'backward',
67
+ 'f05e' => 'ban',
68
+ 'f080' => 'bar-chart-o',
69
+ 'f02a' => 'barcode',
70
+ 'f0c9' => 'bars',
71
+ 'f0fc' => 'beer',
72
+ 'f0f3' => 'bell',
73
+ 'f0a2' => 'bell-o',
74
+ 'f171' => 'bitbucket',
75
+ 'f172' => 'bitbucket-square',
76
+ 'f032' => 'bold',
77
+ 'f0e7' => 'bolt',
78
+ 'f02d' => 'book',
79
+ 'f02e' => 'bookmark',
80
+ 'f097' => 'bookmark-o',
81
+ 'f0b1' => 'briefcase',
82
+ 'f15a' => 'btc',
83
+ 'f188' => 'bug',
84
+ 'f0f7' => 'building-o',
85
+ 'f0a1' => 'bullhorn',
86
+ 'f140' => 'bullseye',
87
+ 'f073' => 'calendar',
88
+ 'f133' => 'calendar-o',
89
+ 'f030' => 'camera',
90
+ 'f083' => 'camera-retro',
91
+ 'f0d7' => 'caret-down',
92
+ 'f0d9' => 'caret-left',
93
+ 'f0da' => 'caret-right',
94
+ 'f150' => 'caret-square-o-down',
95
+ 'f191' => 'caret-square-o-left',
96
+ 'f152' => 'caret-square-o-right',
97
+ 'f151' => 'caret-square-o-up',
98
+ 'f0d8' => 'caret-up',
99
+ 'f0a3' => 'certificate',
100
+ 'f127' => 'chain-broken',
101
+ 'f00c' => 'check',
102
+ 'f058' => 'check-circle',
103
+ 'f05d' => 'check-circle-o',
104
+ 'f14a' => 'check-square',
105
+ 'f046' => 'check-square-o',
106
+ 'f13a' => 'chevron-circle-down',
107
+ 'f137' => 'chevron-circle-left',
108
+ 'f138' => 'chevron-circle-right',
109
+ 'f139' => 'chevron-circle-up',
110
+ 'f078' => 'chevron-down',
111
+ 'f053' => 'chevron-left',
112
+ 'f054' => 'chevron-right',
113
+ 'f077' => 'chevron-up',
114
+ 'f10c' => 'circle-o',
115
+ 'f0ea' => 'clipboard',
116
+ 'f017' => 'clock-o',
117
+ 'f0c2' => 'cloud',
118
+ 'f0ed' => 'cloud-download',
119
+ 'f0ee' => 'cloud-upload',
120
+ 'f121' => 'code',
121
+ 'f126' => 'code-fork',
122
+ 'f0f4' => 'coffee',
123
+ 'f013' => 'cog',
124
+ 'f085' => 'cogs',
125
+ 'f0db' => 'columns',
126
+ 'f075' => 'comment',
127
+ 'f0e5' => 'comment-o',
128
+ 'f086' => 'comments',
129
+ 'f0e6' => 'comments-o',
130
+ 'f14e' => 'compass',
131
+ 'f066' => 'compress',
132
+ 'f09d' => 'credit-card',
133
+ 'f125' => 'crop',
134
+ 'f05b' => 'crosshairs',
135
+ 'f13c' => 'css3',
136
+ 'f0f5' => 'cutlery',
137
+ 'f108' => 'desktop',
138
+ 'f192' => 'dot-circle-o',
139
+ 'f019' => 'download',
140
+ 'f17d' => 'dribbble',
141
+ 'f16b' => 'dropbox',
142
+ 'f052' => 'eject',
143
+ 'f141' => 'ellipsis-h',
144
+ 'f142' => 'ellipsis-v',
145
+ 'f0e0' => 'envelope',
146
+ 'f003' => 'envelope-o',
147
+ 'f12d' => 'eraser',
148
+ 'f153' => 'eur',
149
+ 'f0ec' => 'exchange',
150
+ 'f12a' => 'exclamation',
151
+ 'f06a' => 'exclamation-circle',
152
+ 'f071' => 'exclamation-triangle',
153
+ 'f065' => 'expand',
154
+ 'f08e' => 'external-link',
155
+ 'f14c' => 'external-link-square',
156
+ 'f06e' => 'eye',
157
+ 'f070' => 'eye-slash',
158
+ 'f09a' => 'facebook',
159
+ 'f082' => 'facebook-square',
160
+ 'f049' => 'fast-backward',
161
+ 'f050' => 'fast-forward',
162
+ 'f182' => 'female',
163
+ 'f0fb' => 'fighter-jet',
164
+ 'f15b' => 'file',
165
+ 'f016' => 'file-o',
166
+ 'f15c' => 'file-text',
167
+ 'f0f6' => 'file-text-o',
168
+ 'f0c5' => 'files-o',
169
+ 'f008' => 'film',
170
+ 'f0b0' => 'filter',
171
+ 'f06d' => 'fire',
172
+ 'f134' => 'fire-extinguisher',
173
+ 'f024' => 'flag',
174
+ 'f11e' => 'flag-checkered',
175
+ 'f11d' => 'flag-o',
176
+ 'f0c3' => 'flask',
177
+ 'f16e' => 'flickr',
178
+ 'f0c7' => 'floppy-o',
179
+ 'f07b' => 'folder',
180
+ 'f114' => 'folder-o',
181
+ 'f07c' => 'folder-open',
182
+ 'f115' => 'folder-open-o',
183
+ 'f031' => 'font',
184
+ 'f04e' => 'forward',
185
+ 'f180' => 'foursquare',
186
+ 'f119' => 'frown-o',
187
+ 'f11b' => 'gamepad',
188
+ 'f0e3' => 'gavel',
189
+ 'f154' => 'gbp',
190
+ 'f06b' => 'gift',
191
+ 'f09b' => 'github',
192
+ 'f113' => 'github-alt',
193
+ 'f092' => 'github-square',
194
+ 'f184' => 'gittip',
195
+ 'f000' => 'glass',
196
+ 'f0ac' => 'globe',
197
+ 'f0d5' => 'google-plus',
198
+ 'f0d4' => 'google-plus-square',
199
+ 'f0fd' => 'h-square',
200
+ 'f0a7' => 'hand-o-down',
201
+ 'f0a5' => 'hand-o-left',
202
+ 'f0a4' => 'hand-o-right',
203
+ 'f0a6' => 'hand-o-up',
204
+ 'f0a0' => 'hdd-o',
205
+ 'f025' => 'headphones',
206
+ 'f004' => 'heart',
207
+ 'f08a' => 'heart-o',
208
+ 'f015' => 'home',
209
+ 'f0f8' => 'hospital-o',
210
+ 'f13b' => 'html5',
211
+ 'f01c' => 'inbox',
212
+ 'f03c' => 'indent',
213
+ 'f129' => 'info',
214
+ 'f05a' => 'info-circle',
215
+ 'f156' => 'inr',
216
+ 'f16d' => 'instagram',
217
+ 'f033' => 'italic',
218
+ 'f157' => 'jpy',
219
+ 'f084' => 'key',
220
+ 'f11c' => 'keyboard-o',
221
+ 'f159' => 'krw',
222
+ 'f109' => 'laptop',
223
+ 'f06c' => 'leaf',
224
+ 'f094' => 'lemon-o',
225
+ 'f149' => 'level-down',
226
+ 'f148' => 'level-up',
227
+ 'f0eb' => 'lightbulb-o',
228
+ 'f0c1' => 'link',
229
+ 'f0e1' => 'linkedin',
230
+ 'f08c' => 'linkedin-square',
231
+ 'f17c' => 'linux',
232
+ 'f03a' => 'list',
233
+ 'f022' => 'list-alt',
234
+ 'f0cb' => 'list-ol',
235
+ 'f0ca' => 'list-ul',
236
+ 'f124' => 'location-arrow',
237
+ 'f023' => 'lock',
238
+ 'f175' => 'long-arrow-down',
239
+ 'f177' => 'long-arrow-left',
240
+ 'f178' => 'long-arrow-right',
241
+ 'f176' => 'long-arrow-up',
242
+ 'f0d0' => 'magic',
243
+ 'f076' => 'magnet',
244
+ 'f122' => 'mail-reply-all',
245
+ 'f183' => 'male',
246
+ 'f041' => 'map-marker',
247
+ 'f136' => 'maxcdn',
248
+ 'f0fa' => 'medkit',
249
+ 'f11a' => 'meh-o',
250
+ 'f130' => 'microphone',
251
+ 'f131' => 'microphone-slash',
252
+ 'f068' => 'minus',
253
+ 'f056' => 'minus-circle',
254
+ 'f146' => 'minus-square',
255
+ 'f147' => 'minus-square-o',
256
+ 'f10b' => 'mobile',
257
+ 'f0d6' => 'money',
258
+ 'f186' => 'moon-o',
259
+ 'f001' => 'music',
260
+ 'f03b' => 'outdent',
261
+ 'f18c' => 'pagelines',
262
+ 'f0c6' => 'paperclip',
263
+ 'f04c' => 'pause',
264
+ 'f040' => 'pencil',
265
+ 'f14b' => 'pencil-square',
266
+ 'f044' => 'pencil-square-o',
267
+ 'f095' => 'phone',
268
+ 'f098' => 'phone-square',
269
+ 'f03e' => 'picture-o',
270
+ 'f0d2' => 'pinterest',
271
+ 'f0d3' => 'pinterest-square',
272
+ 'f072' => 'plane',
273
+ 'f04b' => 'play',
274
+ 'f144' => 'play-circle',
275
+ 'f01d' => 'play-circle-o',
276
+ 'f067' => 'plus',
277
+ 'f055' => 'plus-circle',
278
+ 'f0fe' => 'plus-square',
279
+ 'f196' => 'plus-square-o',
280
+ 'f011' => 'power-off',
281
+ 'f02f' => 'print',
282
+ 'f12e' => 'puzzle-piece',
283
+ 'f029' => 'qrcode',
284
+ 'f128' => 'question',
285
+ 'f059' => 'question-circle',
286
+ 'f10d' => 'quote-left',
287
+ 'f10e' => 'quote-right',
288
+ 'f074' => 'random',
289
+ 'f021' => 'refresh',
290
+ 'f18b' => 'renren',
291
+ 'f01e' => 'repeat',
292
+ 'f112' => 'reply',
293
+ 'f122' => 'reply-all',
294
+ 'f079' => 'retweet',
295
+ 'f018' => 'road',
296
+ 'f135' => 'rocket',
297
+ 'f09e' => 'rss',
298
+ 'f143' => 'rss-square',
299
+ 'f158' => 'rub',
300
+ 'f0c4' => 'scissors',
301
+ 'f002' => 'search',
302
+ 'f010' => 'search-minus',
303
+ 'f00e' => 'search-plus',
304
+ 'f064' => 'share',
305
+ 'f14d' => 'share-square',
306
+ 'f045' => 'share-square-o',
307
+ 'f132' => 'shield',
308
+ 'f07a' => 'shopping-cart',
309
+ 'f090' => 'sign-in',
310
+ 'f08b' => 'sign-out',
311
+ 'f012' => 'signal',
312
+ 'f0e8' => 'sitemap',
313
+ 'f17e' => 'skype',
314
+ 'f118' => 'smile-o',
315
+ 'f0dc' => 'sort',
316
+ 'f15d' => 'sort-alpha-asc',
317
+ 'f15e' => 'sort-alpha-desc',
318
+ 'f160' => 'sort-amount-asc',
319
+ 'f161' => 'sort-amount-desc',
320
+ 'f0dd' => 'sort-asc',
321
+ 'f0de' => 'sort-desc',
322
+ 'f162' => 'sort-numeric-asc',
323
+ 'f163' => 'sort-numeric-desc',
324
+ 'f110' => 'spinner',
325
+ 'f0c8' => 'square',
326
+ 'f096' => 'square-o',
327
+ 'f18d' => 'stack-exchange',
328
+ 'f16c' => 'stack-overflow',
329
+ 'f005' => 'star',
330
+ 'f089' => 'star-half',
331
+ 'f123' => 'star-half-o',
332
+ 'f006' => 'star-o',
333
+ 'f048' => 'step-backward',
334
+ 'f051' => 'step-forward',
335
+ 'f0f1' => 'stethoscope',
336
+ 'f04d' => 'stop',
337
+ 'f0cc' => 'strikethrough',
338
+ 'f12c' => 'subscript',
339
+ 'f0f2' => 'suitcase',
340
+ 'f185' => 'sun-o',
341
+ 'f12b' => 'superscript',
342
+ 'f0ce' => 'table',
343
+ 'f10a' => 'tablet',
344
+ 'f0e4' => 'tachometer',
345
+ 'f02b' => 'tag',
346
+ 'f02c' => 'tags',
347
+ 'f0ae' => 'tasks',
348
+ 'f120' => 'terminal',
349
+ 'f034' => 'text-height',
350
+ 'f035' => 'text-width',
351
+ 'f00a' => 'th',
352
+ 'f009' => 'th-large',
353
+ 'f00b' => 'th-list',
354
+ 'f08d' => 'thumb-tack',
355
+ 'f165' => 'thumbs-down',
356
+ 'f088' => 'thumbs-o-down',
357
+ 'f087' => 'thumbs-o-up',
358
+ 'f164' => 'thumbs-up',
359
+ 'f145' => 'ticket',
360
+ 'f00d' => 'times',
361
+ 'f057' => 'times-circle',
362
+ 'f05c' => 'times-circle-o',
363
+ 'f043' => 'tint',
364
+ 'f014' => 'trash-o',
365
+ 'f181' => 'trello',
366
+ 'f091' => 'trophy',
367
+ 'f0d1' => 'truck',
368
+ 'f195' => 'try',
369
+ 'f173' => 'tumblr',
370
+ 'f174' => 'tumblr-square',
371
+ 'f099' => 'twitter',
372
+ 'f081' => 'twitter-square',
373
+ 'f0e9' => 'umbrella',
374
+ 'f0cd' => 'underline',
375
+ 'f0e2' => 'undo',
376
+ 'f09c' => 'unlock',
377
+ 'f13e' => 'unlock-alt',
378
+ 'f093' => 'upload',
379
+ 'f155' => 'usd',
380
+ 'f007' => 'user',
381
+ 'f0f0' => 'user-md',
382
+ 'f0c0' => 'users',
383
+ 'f03d' => 'video-camera',
384
+ 'f194' => 'vimeo-square',
385
+ 'f189' => 'vk',
386
+ 'f027' => 'volume-down',
387
+ 'f026' => 'volume-off',
388
+ 'f028' => 'volume-up',
389
+ 'f18a' => 'weibo',
390
+ 'f193' => 'wheelchair',
391
+ 'f17a' => 'windows',
392
+ 'f0ad' => 'wrench',
393
+ 'f168' => 'xing',
394
+ 'f169' => 'xing-square',
395
+ 'f167' => 'youtube',
396
+ 'f16a' => 'youtube-play',
397
+ 'f166' => 'youtube-square'
398
+ ),
399
+ 'awesome_icons2' => array(
400
+ '\f042' => 'adjust',
401
+ '\f170' => 'adn',
402
+ '\f037' => 'align-center',
403
+ '\f039' => 'align-justify',
404
+ '\f036' => 'align-left',
405
+ '\f038' => 'align-right',
406
+ '\f0f9' => 'ambulance',
407
+ '\f13d' => 'anchor',
408
+ '\f17b' => 'android',
409
+ '\f103' => 'angle-double-down',
410
+ '\f100' => 'angle-double-left',
411
+ '\f101' => 'angle-double-right',
412
+ '\f102' => 'angle-double-up',
413
+ '\f107' => 'angle-down',
414
+ '\f104' => 'angle-left',
415
+ '\f105' => 'angle-right',
416
+ '\f106' => 'angle-up',
417
+ '\f179' => 'apple',
418
+ '\f187' => 'archive',
419
+ '\f0ab' => 'arrow-circle-down',
420
+ '\f0a8' => 'arrow-circle-left',
421
+ '\f01a' => 'arrow-circle-o-down',
422
+ '\f190' => 'arrow-circle-o-left',
423
+ '\f18e' => 'arrow-circle-o-right',
424
+ '\f01b' => 'arrow-circle-o-up',
425
+ '\f0a9' => 'arrow-circle-right',
426
+ '\f0aa' => 'arrow-circle-up',
427
+ '\f063' => 'arrow-down',
428
+ '\f060' => 'arrow-left',
429
+ '\f061' => 'arrow-right',
430
+ '\f062' => 'arrow-up',
431
+ '\f047' => 'arrows',
432
+ '\f0b2' => 'arrows-alt',
433
+ '\f07e' => 'arrows-h',
434
+ '\f07d' => 'arrows-v',
435
+ '\f069' => 'asterisk',
436
+ '\f04a' => 'backward',
437
+ '\f05e' => 'ban',
438
+ '\f080' => 'bar-chart-o',
439
+ '\f02a' => 'barcode',
440
+ '\f0c9' => 'bars',
441
+ '\f0fc' => 'beer',
442
+ '\f0f3' => 'bell',
443
+ '\f0a2' => 'bell-o',
444
+ '\f171' => 'bitbucket',
445
+ '\f172' => 'bitbucket-square',
446
+ '\f032' => 'bold',
447
+ '\f0e7' => 'bolt',
448
+ '\f02d' => 'book',
449
+ '\f02e' => 'bookmark',
450
+ '\f097' => 'bookmark-o',
451
+ '\f0b1' => 'briefcase',
452
+ '\f15a' => 'btc',
453
+ '\f188' => 'bug',
454
+ '\f0f7' => 'building-o',
455
+ '\f0a1' => 'bullhorn',
456
+ '\f140' => 'bullseye',
457
+ '\f073' => 'calendar',
458
+ '\f133' => 'calendar-o',
459
+ '\f030' => 'camera',
460
+ '\f083' => 'camera-retro',
461
+ '\f0d7' => 'caret-down',
462
+ '\f0d9' => 'caret-left',
463
+ '\f0da' => 'caret-right',
464
+ '\f150' => 'caret-square-o-down',
465
+ '\f191' => 'caret-square-o-left',
466
+ '\f152' => 'caret-square-o-right',
467
+ '\f151' => 'caret-square-o-up',
468
+ '\f0d8' => 'caret-up',
469
+ '\f0a3' => 'certificate',
470
+ '\f127' => 'chain-broken',
471
+ '\f00c' => 'check',
472
+ '\f058' => 'check-circle',
473
+ '\f05d' => 'check-circle-o',
474
+ '\f14a' => 'check-square',
475
+ '\f046' => 'check-square-o',
476
+ '\f13a' => 'chevron-circle-down',
477
+ '\f137' => 'chevron-circle-left',
478
+ '\f138' => 'chevron-circle-right',
479
+ '\f139' => 'chevron-circle-up',
480
+ '\f078' => 'chevron-down',
481
+ '\f053' => 'chevron-left',
482
+ '\f054' => 'chevron-right',
483
+ '\f077' => 'chevron-up',
484
+ '\f10c' => 'circle-o',
485
+ '\f0ea' => 'clipboard',
486
+ '\f017' => 'clock-o',
487
+ '\f0c2' => 'cloud',
488
+ '\f0ed' => 'cloud-download',
489
+ '\f0ee' => 'cloud-upload',
490
+ '\f121' => 'code',
491
+ '\f126' => 'code-fork',
492
+ '\f0f4' => 'coffee',
493
+ '\f013' => 'cog',
494
+ '\f085' => 'cogs',
495
+ '\f0db' => 'columns',
496
+ '\f075' => 'comment',
497
+ '\f0e5' => 'comment-o',
498
+ '\f086' => 'comments',
499
+ '\f0e6' => 'comments-o',
500
+ '\f14e' => 'compass',
501
+ '\f066' => 'compress',
502
+ '\f09d' => 'credit-card',
503
+ '\f125' => 'crop',
504
+ '\f05b' => 'crosshairs',
505
+ '\f13c' => 'css3',
506
+ '\f0f5' => 'cutlery',
507
+ '\f108' => 'desktop',
508
+ '\f192' => 'dot-circle-o',
509
+ '\f019' => 'download',
510
+ '\f17d' => 'dribbble',
511
+ '\f16b' => 'dropbox',
512
+ '\f052' => 'eject',
513
+ '\f141' => 'ellipsis-h',
514
+ '\f142' => 'ellipsis-v',
515
+ '\f0e0' => 'envelope',
516
+ '\f003' => 'envelope-o',
517
+ '\f12d' => 'eraser',
518
+ '\f153' => 'eur',
519
+ '\f0ec' => 'exchange',
520
+ '\f12a' => 'exclamation',
521
+ '\f06a' => 'exclamation-circle',
522
+ '\f071' => 'exclamation-triangle',
523
+ '\f065' => 'expand',
524
+ '\f08e' => 'external-link',
525
+ '\f14c' => 'external-link-square',
526
+ '\f06e' => 'eye',
527
+ '\f070' => 'eye-slash',
528
+ '\f09a' => 'facebook',
529
+ '\f082' => 'facebook-square',
530
+ '\f049' => 'fast-backward',
531
+ '\f050' => 'fast-forward',
532
+ '\f182' => 'female',
533
+ '\f0fb' => 'fighter-jet',
534
+ '\f15b' => 'file',
535
+ '\f016' => 'file-o',
536
+ '\f15c' => 'file-text',
537
+ '\f0f6' => 'file-text-o',
538
+ '\f0c5' => 'files-o',
539
+ '\f008' => 'film',
540
+ '\f0b0' => 'filter',
541
+ '\f06d' => 'fire',
542
+ '\f134' => 'fire-extinguisher',
543
+ '\f024' => 'flag',
544
+ '\f11e' => 'flag-checkered',
545
+ '\f11d' => 'flag-o',
546
+ '\f0c3' => 'flask',
547
+ '\f16e' => 'flickr',
548
+ '\f0c7' => 'floppy-o',
549
+ '\f07b' => 'folder',
550
+ '\f114' => 'folder-o',
551
+ '\f07c' => 'folder-open',
552
+ '\f115' => 'folder-open-o',
553
+ '\f031' => 'font',
554
+ '\f04e' => 'forward',
555
+ '\f180' => 'foursquare',
556
+ '\f119' => 'frown-o',
557
+ '\f11b' => 'gamepad',
558
+ '\f0e3' => 'gavel',
559
+ '\f154' => 'gbp',
560
+ '\f06b' => 'gift',
561
+ '\f09b' => 'github',
562
+ '\f113' => 'github-alt',
563
+ '\f092' => 'github-square',
564
+ '\f184' => 'gittip',
565
+ '\f000' => 'glass',
566
+ '\f0ac' => 'globe',
567
+ '\f0d5' => 'google-plus',
568
+ '\f0d4' => 'google-plus-square',
569
+ '\f0fd' => 'h-square',
570
+ '\f0a7' => 'hand-o-down',
571
+ '\f0a5' => 'hand-o-left',
572
+ '\f0a4' => 'hand-o-right',
573
+ '\f0a6' => 'hand-o-up',
574
+ '\f0a0' => 'hdd-o',
575
+ '\f025' => 'headphones',
576
+ '\f004' => 'heart',
577
+ '\f08a' => 'heart-o',
578
+ '\f015' => 'home',
579
+ '\f0f8' => 'hospital-o',
580
+ '\f13b' => 'html5',
581
+ '\f01c' => 'inbox',
582
+ '\f03c' => 'indent',
583
+ '\f129' => 'info',
584
+ '\f05a' => 'info-circle',
585
+ '\f156' => 'inr',
586
+ '\f16d' => 'instagram',
587
+ '\f033' => 'italic',
588
+ '\f157' => 'jpy',
589
+ '\f084' => 'key',
590
+ '\f11c' => 'keyboard-o',
591
+ '\f159' => 'krw',
592
+ '\f109' => 'laptop',
593
+ '\f06c' => 'leaf',
594
+ '\f094' => 'lemon-o',
595
+ '\f149' => 'level-down',
596
+ '\f148' => 'level-up',
597
+ '\f0eb' => 'lightbulb-o',
598
+ '\f0c1' => 'link',
599
+ '\f0e1' => 'linkedin',
600
+ '\f08c' => 'linkedin-square',
601
+ '\f17c' => 'linux',
602
+ '\f03a' => 'list',
603
+ '\f022' => 'list-alt',
604
+ '\f0cb' => 'list-ol',
605
+ '\f0ca' => 'list-ul',
606
+ '\f124' => 'location-arrow',
607
+ '\f023' => 'lock',
608
+ '\f175' => 'long-arrow-down',
609
+ '\f177' => 'long-arrow-left',
610
+ '\f178' => 'long-arrow-right',
611
+ '\f176' => 'long-arrow-up',
612
+ '\f0d0' => 'magic',
613
+ '\f076' => 'magnet',
614
+ '\f122' => 'mail-reply-all',
615
+ '\f183' => 'male',
616
+ '\f041' => 'map-marker',
617
+ '\f136' => 'maxcdn',
618
+ '\f0fa' => 'medkit',
619
+ '\f11a' => 'meh-o',
620
+ '\f130' => 'microphone',
621
+ '\f131' => 'microphone-slash',
622
+ '\f068' => 'minus',
623
+ '\f056' => 'minus-circle',
624
+ '\f146' => 'minus-square',
625
+ '\f147' => 'minus-square-o',
626
+ '\f10b' => 'mobile',
627
+ '\f0d6' => 'money',
628
+ '\f186' => 'moon-o',
629
+ '\f001' => 'music',
630
+ '\f03b' => 'outdent',
631
+ '\f18c' => 'pagelines',
632
+ '\f0c6' => 'paperclip',
633
+ '\f04c' => 'pause',
634
+ '\f040' => 'pencil',
635
+ '\f14b' => 'pencil-square',
636
+ '\f044' => 'pencil-square-o',
637
+ '\f095' => 'phone',
638
+ '\f098' => 'phone-square',
639
+ '\f03e' => 'picture-o',
640
+ '\f0d2' => 'pinterest',
641
+ '\f0d3' => 'pinterest-square',
642
+ '\f072' => 'plane',
643
+ '\f04b' => 'play',
644
+ '\f144' => 'play-circle',
645
+ '\f01d' => 'play-circle-o',
646
+ '\f067' => 'plus',
647
+ '\f055' => 'plus-circle',
648
+ '\f0fe' => 'plus-square',
649
+ '\f196' => 'plus-square-o',
650
+ '\f011' => 'power-off',
651
+ '\f02f' => 'print',
652
+ '\f12e' => 'puzzle-piece',
653
+ '\f029' => 'qrcode',
654
+ '\f128' => 'question',
655
+ '\f059' => 'question-circle',
656
+ '\f10d' => 'quote-left',
657
+ '\f10e' => 'quote-right',
658
+ '\f074' => 'random',
659
+ '\f021' => 'refresh',
660
+ '\f18b' => 'renren',
661
+ '\f01e' => 'repeat',
662
+ '\f112' => 'reply',
663
+ '\f122' => 'reply-all',
664
+ '\f079' => 'retweet',
665
+ '\f018' => 'road',
666
+ '\f135' => 'rocket',
667
+ '\f09e' => 'rss',
668
+ '\f143' => 'rss-square',
669
+ '\f158' => 'rub',
670
+ '\f0c4' => 'scissors',
671
+ '\f002' => 'search',
672
+ '\f010' => 'search-minus',
673
+ '\f00e' => 'search-plus',
674
+ '\f064' => 'share',
675
+ '\f14d' => 'share-square',
676
+ '\f045' => 'share-square-o',
677
+ '\f132' => 'shield',
678
+ '\f07a' => 'shopping-cart',
679
+ '\f090' => 'sign-in',
680
+ '\f08b' => 'sign-out',
681
+ '\f012' => 'signal',
682
+ '\f0e8' => 'sitemap',
683
+ '\f17e' => 'skype',
684
+ '\f118' => 'smile-o',
685
+ '\f0dc' => 'sort',
686
+ '\f15d' => 'sort-alpha-asc',
687
+ '\f15e' => 'sort-alpha-desc',
688
+ '\f160' => 'sort-amount-asc',
689
+ '\f161' => 'sort-amount-desc',
690
+ '\f0dd' => 'sort-asc',
691
+ '\f0de' => 'sort-desc',
692
+ '\f162' => 'sort-numeric-asc',
693
+ '\f163' => 'sort-numeric-desc',
694
+ '\f110' => 'spinner',
695
+ '\f0c8' => 'square',
696
+ '\f096' => 'square-o',
697
+ '\f18d' => 'stack-exchange',
698
+ '\f16c' => 'stack-overflow',
699
+ '\f005' => 'star',
700
+ '\f089' => 'star-half',
701
+ '\f123' => 'star-half-o',
702
+ '\f006' => 'star-o',
703
+ '\f048' => 'step-backward',
704
+ '\f051' => 'step-forward',
705
+ '\f0f1' => 'stethoscope',
706
+ '\f04d' => 'stop',
707
+ '\f0cc' => 'strikethrough',
708
+ '\f12c' => 'subscript',
709
+ '\f0f2' => 'suitcase',
710
+ '\f185' => 'sun-o',
711
+ '\f12b' => 'superscript',
712
+ '\f0ce' => 'table',
713
+ '\f10a' => 'tablet',
714
+ '\f0e4' => 'tachometer',
715
+ '\f02b' => 'tag',
716
+ '\f02c' => 'tags',
717
+ '\f0ae' => 'tasks',
718
+ '\f120' => 'terminal',
719
+ '\f034' => 'text-height',
720
+ '\f035' => 'text-width',
721
+ '\f00a' => 'th',
722
+ '\f009' => 'th-large',
723
+ '\f00b' => 'th-list',
724
+ '\f08d' => 'thumb-tack',
725
+ '\f165' => 'thumbs-down',
726
+ '\f088' => 'thumbs-o-down',
727
+ '\f087' => 'thumbs-o-up',
728
+ '\f164' => 'thumbs-up',
729
+ '\f145' => 'ticket',
730
+ '\f00d' => 'times',
731
+ '\f057' => 'times-circle',
732
+ '\f05c' => 'times-circle-o',
733
+ '\f043' => 'tint',
734
+ '\f014' => 'trash-o',
735
+ '\f181' => 'trello',
736
+ '\f091' => 'trophy',
737
+ '\f0d1' => 'truck',
738
+ '\f195' => 'try',
739
+ '\f173' => 'tumblr',
740
+ '\f174' => 'tumblr-square',
741
+ '\f099' => 'twitter',
742
+ '\f081' => 'twitter-square',
743
+ '\f0e9' => 'umbrella',
744
+ '\f0cd' => 'underline',
745
+ '\f0e2' => 'undo',
746
+ '\f09c' => 'unlock',
747
+ '\f13e' => 'unlock-alt',
748
+ '\f093' => 'upload',
749
+ '\f155' => 'usd',
750
+ '\f007' => 'user',
751
+ '\f0f0' => 'user-md',
752
+ '\f0c0' => 'users',
753
+ '\f03d' => 'video-camera',
754
+ '\f194' => 'vimeo-square',
755
+ '\f189' => 'vk',
756
+ '\f027' => 'volume-down',
757
+ '\f026' => 'volume-off',
758
+ '\f028' => 'volume-up',
759
+ '\f18a' => 'weibo',
760
+ '\f193' => 'wheelchair',
761
+ '\f17a' => 'windows',
762
+ '\f0ad' => 'wrench',
763
+ '\f168' => 'xing',
764
+ '\f169' => 'xing-square',
765
+ '\f167' => 'youtube',
766
+ '\f16a' => 'youtube-play',
767
+ '\f166' => 'youtube-square'
768
+ ),
769
+
770
+ 'awesome_icons_socials' =>array(
771
+ 'f170' => 'adn',
772
+ 'f17b' => 'android',
773
+ 'f179' => 'apple',
774
+ 'f171' => 'bitbucket',
775
+ 'f171' => 'bitbucket-square',
776
+ 'f02e' => 'bookmark',
777
+ 'f097' => 'bookmark-o',
778
+ 'f15a' => 'btc',
779
+ 'f13c' => 'css3',
780
+ 'f17d' => 'dribble',
781
+ 'f16b' => 'dropbox',
782
+ 'f09a' => 'facebook',
783
+ 'f082' => 'facebook-square',
784
+ 'f16e' => 'flickr',
785
+ 'f180' => 'foursquare',
786
+ 'f09b'=> 'github' ,
787
+ 'f113'=> 'github-alt',
788
+ 'f092' => 'github-square',
789
+ 'f184' => 'gittip',
790
+ 'f0d5' => 'google-plus',
791
+ 'f0d4' => 'google-plus-square',
792
+ 'f13b' => 'html5',
793
+ 'f16d' => 'instagram',
794
+ 'f0e1' => 'linkedin',
795
+ 'f08c' => 'linkedin-square',
796
+ 'f17c' => 'Linux',
797
+ 'f136' => 'maxcdn',
798
+ 'f18c' => 'pagelines',
799
+ 'f0d2' => 'pinterest',
800
+ 'f0d3' => 'pinterest-square',
801
+ 'f18b' => 'renren',
802
+ 'f09e' => 'rss',
803
+ 'f17e' => 'skype',
804
+ 'f18d' => 'stack-exchange',
805
+ 'f16c' => 'stack-overflow',
806
+ 'f181' => 'trello',
807
+ 'f173' => 'tumblr',
808
+ 'f174' => 'Tumblr Square',
809
+ 'f099' => 'twitter',
810
+ 'f081' => 'twitter-square',
811
+ 'f194' => 'vimeo-square',
812
+ 'f189' => 'vk',
813
+ 'f18a' => 'weibo',
814
+ 'f17a' => 'windows',
815
+ 'f168' => 'xing',
816
+ 'f169' => 'xing-square',
817
+ 'f167' => 'youtube'
818
+ ),
819
+ 'header_backgrounds' => array(),
820
+ 'body_backgrounds' => array(),
821
+
822
+ // tags used in theme options (e.g. %tag%) to have some common informations
823
+ 'tag' => array( //'themeurl' => get_template_directory_uri()
824
+ ),
825
+
826
+ 'cycle_fx' => array(
827
+ 'blindX' => 'blindX', 'blindY' => 'blindY', 'blindZ' => 'blindZ', 'cover' => 'cover', 'curtainX' => 'curtainX',
828
+ 'curtainY' => 'curtainY', 'fade' => 'fade', 'fadeZoom' => 'fadeZoom', 'growX' => 'growX', 'growY' => 'growY',
829
+ 'scrollUp' => 'scrollUp', 'scrollDown' => 'scrollDown', 'scrollLeft' => 'scrollLeft', 'scrollRight' => 'scrollRight', 'scrollHorz' => 'scrollHorz',
830
+ 'shuffle' => 'shuffle', 'slideX' => 'slideX', 'slideY' => 'slideY', 'toss' => 'toss', 'turnUp' => 'turnUp',
831
+ 'turnLeft' => 'turnLeft', 'turnRight' => 'turnRight', 'uncover' => 'uncover', 'wipe' => 'wipe', 'zoom' => 'zoom',
832
+ 'none' => 'none', 'turnDown' => 'turnDown', 'scrollVert' => 'scrollVert'
833
+ ),
834
+
835
+ 'animate' => array(
836
+ '' => "none",
837
+ "bounce" => "bounce",
838
+ "flash" =>"flash",
839
+ "pulse" =>"pulse",
840
+ //"rubberBand"=>"rubberBand",
841
+ "shake" =>"shake",
842
+ "swing"=>"swing",
843
+ "tada" =>"tada",
844
+ "wobble"=>"wobble",
845
+ "bounceIn"=>"bounceIn",
846
+ "bounceInDown"=>"bounceInDown",
847
+ "bounceInLeft"=>"bounceInLeft",
848
+ "bounceInRight"=>"bounceInRight",
849
+ "bounceInUp"=>"bounceInUp",
850
+ "fadeIn"=>"fadeIn",
851
+ "fadeInDown"=>"fadeInDown",
852
+ "fadeInDownBig"=>"fadeInDownBig",
853
+ "fadeInLeft"=>"fadeInLeft",
854
+ "fadeInLeftBig"=>"fadeInLeftBig",
855
+ "fadeInRight"=>"fadeInRight",
856
+ "fadeInRightBig"=>"fadeInRightBig",
857
+ "fadeInUp"=>"fadeInUp",
858
+ "fadeInUpBig"=>"fadeInUpBig",
859
+ "flip"=>"flip",
860
+ "flipInX"=>"flipInX",
861
+ "flipInY"=>"flipInY",
862
+ "lightSpeedIn"=>"lightSpeedIn",
863
+ "rotateIn"=>"rotateIn",
864
+ "rotateInDownLeft"=>"rotateInDownLeft",
865
+ "rotateInDownRight"=>"rotateInDownRight",
866
+ "rotateInUpLeft"=>"rotateInUpLeft",
867
+ "rotateInUpRight"=>"rotateInUpRight",
868
+ //"slideInDown"=>"slideInDown",
869
+ //"slideInLeft"=>"slideInLeft",
870
+ //"slideInRight"=>"slideInRight",
871
+ "rollIn"=>"rollIn",
872
+ ),
873
+
874
+ 'easings' => array(
875
+ FALSE => 'none',
876
+ 'easeInQuad' => 'easeInQuad',
877
+ 'easeOutQuad' => 'easeOutQuad',
878
+ 'easeInOutQuad' => 'easeInOutQuad',
879
+ 'easeInCubic' => 'easeInCubic',
880
+ 'easeOutCubic' => 'easeOutCubic',
881
+ 'easeInOutCubic' => 'easeInOutCubic',
882
+ 'easeInQuart' => 'easeInQuart',
883
+ 'easeOutQuart' => 'easeOutQuart',
884
+ 'easeInOutQuart' => 'easeInOutQuart',
885
+ 'easeInQuint' => 'easeInQuint',
886
+ 'easeOutQuint' => 'easeOutQuint',
887
+ 'easeInOutQuint' => 'easeInOutQuint',
888
+ 'easeInSine' => 'easeInSine',
889
+ 'easeOutSine' => 'easeOutSine',
890
+ 'easeInOutSine' => 'easeInOutSine',
891
+ 'easeInExpo' => 'easeInExpo',
892
+ 'easeOutExpo' => 'easeOutExpo',
893
+ 'easeInOutExpo' => 'easeInOutExpo',
894
+ 'easeInCirc' => 'easeInCirc',
895
+ 'easeOutCirc' => 'easeOutCirc',
896
+ 'easeInOutCirc' => 'easeInOutCirc',
897
+ 'easeInElastic' => 'easeInElastic',
898
+ 'easeOutElastic' => 'easeOutElastic',
899
+ 'easeInOutElastic' => 'easeInOutElastic',
900
+ 'easeInBack' => 'easeInBack',
901
+ 'easeOutBack' => 'easeOutBack',
902
+ 'easeInOutBack' => 'easeInOutBack',
903
+ 'easeInBounce' => 'easeInBounce',
904
+ 'easeOutBounce' => 'easeOutBounce',
905
+ 'easeInOutBounce' => 'easeInOutBounce'
906
+ )
907
+ );
908
+
909
+ /**
910
+ * Get configuration array
911
+ *
912
+ * @return array
913
+ */
914
+ public static function load() {
915
+ self::_loadThemeInfo();
916
+ //ksort( self::$_config['awesome_icons'] );
917
+
918
+ return self::$_config;
919
+ }
920
+
921
+ /**
922
+ * Return theme data
923
+ *
924
+ * First the method checks if the wp_get_theme() function exists (WP 3.4.0 at least).
925
+ * If not, the method calls the deprecated function get_template_directory()
926
+ *
927
+ * @return array
928
+ */
929
+ protected static function _loadThemeInfo() {
930
+ $theme = wp_get_theme();
931
+
932
+ self::$_config['theme'] = array(
933
+ 'name' => $theme->Name,
934
+ 'description' => $theme->Description,
935
+ 'author' => $theme->Author,
936
+ 'authoruri' => $theme->{'Author URI'},
937
+ 'version' => $theme->Version,
938
+ 'template' => $theme->Template,
939
+ 'status' => $theme->Status,
940
+ 'tags' => $theme->Tags
941
+ );
942
+ }
943
+
944
+
945
+ public function init() {
946
+ self::$_config['header_backgrounds'] = apply_filters( 'yit_header_backgrounds', self::$_config['header_backgrounds'] );
947
+ self::$_config['body_backgrounds'] = apply_filters( 'yit_body_backgrounds', self::$_config['body_backgrounds'] );
948
+ }
949
+
950
+ /**
951
+ * Return the font awesome array icon
952
+ *
953
+ * @return string Array
954
+ * @access public
955
+ * @since 1.0.0
956
+ */
957
+ public static function get_awesome_icons() {
958
+ return self::$_config['awesome_icons'];
959
+ }
960
+
961
+ /**
962
+ * Return the font awesome array socials icon
963
+ *
964
+ * @return string Array
965
+ * @access public
966
+ * @since 1.0.0
967
+ */
968
+ public static function get_awesome_icons_socials() {
969
+ return self::$_config['awesome_icons_socials'];
970
+ }
971
+
972
+
973
+ /**
974
+ * Return the list of icons
975
+ *
976
+ * @return string Array
977
+ * @access public
978
+ * @since 1.0.0
979
+ */
980
+ public static function get_icon_list() {
981
+
982
+ $standard_icon_list = array(
983
+ 'FontAwesome' => self::$_config['awesome_icons2']
984
+ );
985
+
986
+ return apply_filters( 'yit_icon_list', $standard_icon_list );
987
+ }
988
+
989
+ /**
990
+ * Return the data of icon
991
+ *
992
+ * @return string Array
993
+ * @access public
994
+ * @since 1.0.0
995
+ */
996
+ public static function get_icon( $icon ) {
997
+
998
+ $icon_list = self::get_icon_list();
999
+ $icon_data = '';
1000
+ if ( $icon != '' ) {
1001
+ $ic = explode( ':', $icon );
1002
+ $icon_code = array_search( $ic[1], $icon_list[$ic[0]] );
1003
+
1004
+ if( $icon_code ){
1005
+ $icon_code = ( strpos( $icon_code, '\\' ) === 0 ) ? '&#x' . substr( $icon_code, 1 ) . ';' : $icon_code;
1006
+ }
1007
+
1008
+ $icon_data = 'data-font="' . $ic[0] . '" data-key="' . $ic[1] . '" data-icon="' . $icon_code . '"';
1009
+ }
1010
+
1011
+ return $icon_data;
1012
+ }
1013
+
1014
+
1015
+ /*
1016
+ * Return the code of the relative awesome class name
1017
+ *
1018
+ * @return string
1019
+ * @access public
1020
+ * @since 1.0.0
1021
+ */
1022
+ public static function get_awesome_icons_code_by_value($class){
1023
+ $awesome_icons=self::$_config['awesome_icons'];
1024
+ foreach($awesome_icons as $key => $value){
1025
+ if($class==$value) {
1026
+ return $key;
1027
+ }
1028
+ }
1029
+
1030
+ return "";
1031
+ }
1032
+ }
1033
+
1034
+ endif;
plugin-fw/lib/yit-plugin-gradients.php ADDED
@@ -0,0 +1,536 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Your Inspiration Themes
4
+ *
5
+ * In this files there is a collection of a functions useful for the core
6
+ * of the framework.
7
+ *
8
+ * @package WordPress
9
+ * @subpackage Your Inspiration Themes
10
+ * @author Your Inspiration Themes Team <info@yithemes.com>
11
+ *
12
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
13
+ * that is bundled with this package in the file LICENSE.txt.
14
+ * It is also available through the world-wide-web at this URL:
15
+ * http://www.gnu.org/licenses/gpl-3.0.txt
16
+ */
17
+
18
+ /**
19
+ * Handles colors
20
+ *
21
+ * @since 1.0
22
+ */
23
+ /**
24
+ * Generates CSS 3 gradients for all browsers.
25
+ *
26
+ * @since 1.0
27
+ */
28
+
29
+ if ( ! class_exists( 'YIT_Gradients' ) ) {
30
+
31
+ class YIT_Gradients {
32
+
33
+ /**
34
+ * An array of colors to use for a gradient.
35
+ *
36
+ * @var array
37
+ * @since 1.0
38
+ */
39
+ public $colors_gradient = array();
40
+
41
+ /**
42
+ * Set properties
43
+ *
44
+ * @param string $key
45
+ * @param $value
46
+ *
47
+ * @internal param array $colors_gradient
48
+ * @return void
49
+ * @since 1.0
50
+ */
51
+ public function set( $key, $value ) {
52
+ if ( property_exists( $this, $key ) ) {
53
+ $this->{$key} = $value;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Get properties
59
+ *
60
+ * @param string $key
61
+ *
62
+ * @return mixed
63
+ * @since 1.0
64
+ */
65
+ public function get( $key ) {
66
+ if ( property_exists( $this, $key ) ) {
67
+ return $this->{$key};
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Add a color to use in a gradient.
73
+ *
74
+ * @param string $color
75
+ * @param int $position
76
+ *
77
+ * @return void
78
+ * @since 1.0
79
+ */
80
+ public function add_color_gradient( $color, $position ) {
81
+ $the_color['color'] = $color;
82
+ $the_color['position'] = $position;
83
+
84
+ array_push( $this->colors_gradient, $the_color );
85
+ }
86
+
87
+ /**
88
+ * Generate the CSS code for a gradient.
89
+ *
90
+ * @param string $role
91
+ * @param string $direction
92
+ *
93
+ * @return string|bool
94
+ * @since 1.0
95
+ */
96
+ public function gradient( $role, $direction ) {
97
+ if ( ! empty( $this->colors_gradient ) ) {
98
+
99
+ $css = array(
100
+ 'old' => $this->_make_old_gradient( $this->colors_gradient[0]['color'] ), //old browser
101
+ 'ff3' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'moz' ), //firefox 3.6+
102
+ 'chr_saf4' => $this->_make_chr_saf4_gradient( $this->colors_gradient, $direction ), //chrome and safari4+
103
+ 'chr10_saf5' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'webkit' ), //chrome10+ and safari5+
104
+ 'opera' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'o' ), //opera11.10+
105
+ 'ie10' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'ms' ), //internet explorer 10+
106
+ 'w3c' => $this->_make_modern_gradient( $this->colors_gradient, $direction, 'w3c' ), //w3c
107
+ 'ie6_9' => $this->_make_ie6_gradient( $this->colors_gradient, $direction ) //ie6-9
108
+ );
109
+
110
+ $css = $role . '{' . implode( ';', $css ) . '}';
111
+
112
+ $this->colors_gradient = array();
113
+
114
+ return $css;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Reverse a gradient. This method should be used only before calling ::make_gradient(). Otherwise it will not works.
120
+ *
121
+ * @return void
122
+ * @since 1.0
123
+ */
124
+ public function reverse_gradient() {
125
+ $colors_gradient = array_reverse( $this->get( 'colors_gradient' ) );
126
+
127
+ for ( $i = 0; $i < count( $colors_gradient ); $i ++ ) {
128
+ $colors_gradient[$i]['position'] = 100 - $colors_gradient[$i]['position'];
129
+ }
130
+
131
+ $this->set( 'colors_gradient', $colors_gradient );
132
+ }
133
+
134
+ /**
135
+ * Generate the CSS code for a gradient.
136
+ *
137
+ * @param string $role
138
+ * @param string $direction
139
+ *
140
+ * @return string|bool
141
+ * @since 1.0
142
+ */
143
+ public function get_gradient( $role, $direction ) {
144
+ return $this->gradient( $role, $direction );
145
+ }
146
+
147
+ /**
148
+ * Generate the CSS code for a gradient.
149
+ *
150
+ * @param string $role
151
+ * @param string $direction
152
+ *
153
+ * @return void
154
+ * @since 1.0
155
+ */
156
+ public function the_gradient( $role, $direction ) {
157
+ echo $this->get_gradient( $role, $direction );
158
+ }
159
+
160
+ /**
161
+ * Generate the CSS code for a gradient.
162
+ *
163
+ * @param string $role
164
+ * @param string $from
165
+ * @param string $to
166
+ * @param string $direction
167
+ *
168
+ * @return string|bool
169
+ * @since 1.0
170
+ */
171
+ public function gradient_from_to( $role, $from, $to, $direction ) {
172
+
173
+ $colors = array(
174
+ array(
175
+ 'color' => $from,
176
+ 'position' => 0
177
+ ),
178
+ array(
179
+ 'color' => $to,
180
+ 'position' => 100
181
+ ),
182
+ );
183
+
184
+ $this->set( 'colors_gradient', $colors );
185
+ return $this->get_gradient( $role, $direction );
186
+ }
187
+
188
+ /**
189
+ * Generate the CSS code for a gradient.
190
+ *
191
+ * @param string $role
192
+ * @param string $color
193
+ * @param string $direction
194
+ * @param int|string $factor
195
+ *
196
+ * @return string|bool
197
+ * @since 1.0
198
+ */
199
+ public function gradient_darker( $role, $color, $direction, $factor = 30 ) {
200
+
201
+ $colors = array(
202
+ array(
203
+ 'color' => $color,
204
+ 'position' => 0
205
+ ),
206
+ array(
207
+ 'color' => $this->hex_darker( $color, $factor ),
208
+ 'position' => 100
209
+ ),
210
+ );
211
+
212
+ $this->set( 'colors_gradient', $colors );
213
+ return $this->get_gradient( $role, $direction );
214
+ }
215
+
216
+ /**
217
+ * Generate the CSS code for a gradient.
218
+ *
219
+ * @param string $role
220
+ * @param string $color
221
+ * @param string $direction
222
+ * @param int|string $factor
223
+ *
224
+ * @return string|bool
225
+ * @since 1.0
226
+ */
227
+ public function gradient_lighter( $role, $color, $direction, $factor = 30 ) {
228
+
229
+ $colors = array(
230
+ array(
231
+ 'color' => $color,
232
+ 'position' => 0
233
+ ),
234
+ array(
235
+ 'color' => $this->hex_lighter( $color, $factor ),
236
+ 'position' => 100
237
+ ),
238
+ );
239
+
240
+ $this->set( 'colors_gradient', $colors );
241
+ return $this->get_gradient( $role, $direction );
242
+ }
243
+
244
+ /**
245
+ * Generate the CSS code for a gradient that not supports gradients (add only a background color).
246
+ *
247
+ * @param $color
248
+ *
249
+ * @internal param string $role
250
+ * @return string|bool
251
+ * @access private
252
+ * @since 1.0
253
+ */
254
+ private function _make_old_gradient( $color ) {
255
+ return 'background:' . $color;
256
+ }
257
+
258
+ /**
259
+ * Generate the CSS code for a gradient in IE6-9.
260
+ *
261
+ * @param $colors
262
+ * @param $direction
263
+ *
264
+ * @internal param string $role
265
+ * @return string|bool
266
+ * @access private
267
+ * @since 1.0
268
+ */
269
+ private function _make_ie6_gradient( $colors, $direction ) {
270
+ $css = 'filter:progid:DXImageTransform.Microsoft.gradient(';
271
+ $css .= 'startColorstr=\'' . $colors[0]['color'] . '\',';
272
+ $css .= 'endColorstr=\'' . $colors[count( $colors ) - 1]['color'] . '\',';
273
+
274
+ if ( $direction == 'horizontal' ) {
275
+ $css .= 'GradientType=1';
276
+ }
277
+ else {
278
+ $css .= 'GradientType=0';
279
+ } //vertical
280
+
281
+ $css .= ')';
282
+
283
+ return $css;
284
+ }
285
+
286
+ /**
287
+ * Make the CSS 3 for a gradient in modern browsers( FF3.6+, Chrome, Safari5+, Opera11.10+, IE10+ )
288
+ *
289
+ * @param array $colors
290
+ * @param string $direction
291
+ * @param $browser
292
+ *
293
+ * @return string
294
+ * @access private
295
+ * @since 1.0
296
+ */
297
+ private function _make_modern_gradient( $colors, $direction, $browser ) {
298
+ $css = 'background:';
299
+
300
+ //Add the browser suffix
301
+ if ( $browser != 'w3c' ) {
302
+ $browser = '-' . $browser . '-';
303
+ }
304
+ else {
305
+ $browser = '';
306
+ }
307
+
308
+ switch ( $direction ) {
309
+ case 'vertical' :
310
+ $css .= $browser . 'linear-gradient(top,';
311
+ break;
312
+ case 'horizontal' :
313
+ $css .= $browser . 'linear-gradient(left,';
314
+ break;
315
+ case 'diagonal-bottom':
316
+ $css .= $browser . 'linear-gradient(-45deg,';
317
+ break;
318
+ case 'diagonal-top' :
319
+ $css .= $browser . 'linear-gradient(45deg,';
320
+ break;
321
+ case 'radial' :
322
+ $css .= $browser . 'radial-gradient(center, ellipse cover,';
323
+ break;
324
+ }
325
+
326
+ foreach ( $colors as $stop ) {
327
+ $css .= $stop['color'] . ' ' . $stop['position'] . '%, ';
328
+ }
329
+
330
+ $css = rtrim( $css );
331
+ $css = rtrim( $css, ',' );
332
+ $css .= ')';
333
+
334
+ return $css;
335
+ }
336
+
337
+ /**
338
+ * Make the CSS 3 for a gradient in Chrome and Safari 4+
339
+ *
340
+ * @param array $colors
341
+ * @param string $direction
342
+ *
343
+ * @return string
344
+ * @access private
345
+ * @since 1.0
346
+ */
347
+ private function _make_chr_saf4_gradient( $colors, $direction ) {
348
+ $css = 'background:';
349
+
350
+ switch ( $direction ) {
351
+ case 'vertical' :
352
+ $css .= '-webkit-gradient(linear,left top,left bottom,';
353
+ break;
354
+ case 'horizontal' :
355
+ $css .= '-webkit-gradient(linear,left top,right top,';
356
+ break;
357
+ case 'diagonal-bottom':
358
+ $css .= '-webkit-gradient(linear,left top,right bottom,';
359
+ break;
360
+ case 'diagonal-top' :
361
+ $css .= '-webkit-gradient(linear,left bottom,right top,';
362
+ break;
363
+ case 'radial' :
364
+ $css .= '-webkit-gradient(radial,center center, 0px, center center, 100%,';
365
+ break;
366
+ }
367
+
368
+ foreach ( $colors as $stop ) {
369
+ $css .= 'color-stop(' . $stop['position'] . '%, ' . $stop['color'] . '), ';
370
+ }
371
+
372
+ $css = rtrim( $css );
373
+ $css = rtrim( $css, ',' );
374
+ $css .= ')';
375
+
376
+ return $css;
377
+ }
378
+
379
+
380
+ /**
381
+ * Return an instance of the model called
382
+ *
383
+ * @param string $class The name of class that I want the instance
384
+ *
385
+ * @since 2.0.0
386
+ * @author Simone D'Amico <simone.damico@yithemes.com>
387
+ * @return mixed
388
+ */
389
+ public function getModel( $class ) {
390
+ return YIT_Registry::get_instance()->$class;
391
+ }
392
+
393
+
394
+ /**
395
+ * Return a color darker then $color.
396
+ *
397
+ * @param string $color
398
+ * @param int $factor
399
+ *
400
+ * @return string
401
+ * @since 1.0
402
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
403
+ */
404
+ public function hex_darker( $color, $factor = 30 ) {
405
+ $color = str_replace( '#', '', $color );
406
+
407
+ $base['R'] = hexdec( substr( $color, 0, 2 ) );
408
+ $base['G'] = hexdec( substr( $color, 2, 2 ) );
409
+ $base['B'] = hexdec( substr( $color, 4, 2 ) );
410
+
411
+ $color = '#';
412
+
413
+ foreach ( $base as $k => $v ) {
414
+ $amount = $v / 100;
415
+ $amount = round( $amount * $factor );
416
+ $new_decimal = $v - $amount;
417
+
418
+ $new_hex_component = dechex( $new_decimal );
419
+
420
+ if ( strlen( $new_hex_component ) < 2 ) {
421
+ $new_hex_component = "0" . $new_hex_component;
422
+ }
423
+
424
+ $color .= $new_hex_component;
425
+ }
426
+
427
+ return $color;
428
+ }
429
+
430
+ /**
431
+ * Return a color lighter then $color.
432
+ *
433
+ * @param string $color
434
+ * @param int $factor
435
+ *
436
+ * @return string
437
+ * @since 1.0
438
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
439
+ */
440
+ public function hex_lighter( $color, $factor = 30 ) {
441
+ $color = str_replace( '#', '', $color );
442
+
443
+ $base['R'] = hexdec( $color{0} . $color{1} );
444
+ $base['G'] = hexdec( $color{2} . $color{3} );
445
+ $base['B'] = hexdec( $color{4} . $color{5} );
446
+
447
+ $color = '#';
448
+
449
+ foreach ( $base as $k => $v ) {
450
+ $amount = 255 - $v;
451
+ $amount = $amount / 100;
452
+ $amount = round( $amount * $factor );
453
+ $new_decimal = $v + $amount;
454
+
455
+ $new_hex_component = dechex( $new_decimal );
456
+
457
+ if ( strlen( $new_hex_component ) < 2 ) {
458
+ $new_hex_component = "0" . $new_hex_component;
459
+ }
460
+
461
+ $color .= $new_hex_component;
462
+ }
463
+
464
+ return $color;
465
+ }
466
+
467
+ /**
468
+ * Detect if we must use a color darker or lighter then the background.
469
+ *
470
+ * @param string $color
471
+ * @param string $dark
472
+ * @param string $light
473
+ *
474
+ * @return string
475
+ * @since 1.0
476
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
477
+ */
478
+ public function light_or_dark( $color, $dark = '#000000', $light = '#FFFFFF' ) {
479
+ $hex = str_replace( '#', '', $color );
480
+
481
+ $c_r = hexdec( substr( $hex, 0, 2 ) );
482
+ $c_g = hexdec( substr( $hex, 2, 2 ) );
483
+ $c_b = hexdec( substr( $hex, 4, 2 ) );
484
+ $brightness = ( ( $c_r * 299 ) + ( $c_g * 587 ) + ( $c_b * 114 ) ) / 1000;
485
+
486
+ return ( $brightness > 155 ) ? $dark : $light;
487
+ }
488
+
489
+ /**
490
+ * Detect if we must use a color darker or lighter then the background.
491
+ *
492
+ * @param $hex
493
+ *
494
+ * @internal param string $color
495
+ * @return string
496
+ * @since 1.0
497
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
498
+ */
499
+ public function hex2rgb( $hex ) {
500
+ $hex = str_replace( "#", "", $hex );
501
+
502
+ if ( strlen( $hex ) == 3 ) {
503
+ $r = hexdec( substr( $hex, 0, 1 ) . substr( $hex, 0, 1 ) );
504
+ $g = hexdec( substr( $hex, 1, 1 ) . substr( $hex, 1, 1 ) );
505
+ $b = hexdec( substr( $hex, 2, 1 ) . substr( $hex, 2, 1 ) );
506
+ }
507
+ else {
508
+ $r = hexdec( substr( $hex, 0, 2 ) );
509
+ $g = hexdec( substr( $hex, 2, 2 ) );
510
+ $b = hexdec( substr( $hex, 4, 2 ) );
511
+ }
512
+ $rgb = array( $r, $g, $b );
513
+ //return implode(",", $rgb); // returns the rgb values separated by commas
514
+ return $rgb; // returns an array with the rgb values
515
+ }
516
+
517
+ /**
518
+ * Magic method for this class
519
+ *
520
+ * @param $name string The name of magic property
521
+ *
522
+ * @since 2.0.0
523
+ * @author Simone D'Amico <simone.damico@yithemes.com>
524
+ * @return mixed
525
+ */
526
+ public function __get( $name ) {
527
+ if ( $name == 'request' ) {
528
+ if ( ! $this->_request instanceof YIT_Request ) {
529
+ $this->_request = YIT_Registry::get_instance()->request;
530
+ }
531
+
532
+ return $this->_request;
533
+ }
534
+ }
535
+ }
536
+ }
plugin-fw/lib/yit-plugin-panel-wc.php ADDED
@@ -0,0 +1,344 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Plugin_Panel_WooCommerce' ) ) {
16
+ /**
17
+ * YIT Plugin Panel for WooCommerce
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Plugin_Panel
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
25
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
26
+ */
27
+
28
+ class YIT_Plugin_Panel_WooCommerce extends YIT_Plugin_Panel {
29
+
30
+ /**
31
+ * @var string version of class
32
+ */
33
+ public $version = '1.0.0';
34
+
35
+ /**
36
+ * @var array a setting list of parameters
37
+ */
38
+ public $settings = array();
39
+
40
+ /**
41
+ * @var array
42
+ */
43
+ protected $_tabs_path_files;
44
+
45
+ /**
46
+ * Constructor
47
+ *
48
+ * @since 1.0
49
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
50
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
51
+ */
52
+ public function __construct( $args = array() ) {
53
+
54
+ if ( ! empty( $args ) ) {
55
+ $this->settings = $args;
56
+ $this->_tabs_path_files = $this->get_tabs_path_files();
57
+
58
+ if( isset( $this->settings['create_menu_page'] ) && $this->settings[ 'create_menu_page'] ){
59
+ $this->add_menu_page();
60
+ }
61
+ add_action( 'admin_init', array( $this, 'set_default_options') );
62
+ add_action( 'admin_menu', array( $this, 'add_setting_page' ) );
63
+ add_action( 'admin_bar_menu', array( $this, 'add_admin_bar_menu' ), 100 );
64
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
65
+ add_action( 'admin_init', array( $this, 'woocommerce_update_options' ) );
66
+ add_action( 'woocommerce_admin_field_boxinfo', array( $this, 'yit_boxinfo' ), 10, 1 );
67
+ add_action( 'woocommerce_admin_field_videobox', array( $this, 'yit_videobox' ), 10, 1 );
68
+
69
+ add_action( 'woocommerce_admin_field_upload', array( $this, 'yit_upload' ), 10, 1 );
70
+ add_action( 'woocommerce_update_option_upload', array( $this, 'yit_upload_update' ), 10, 1 );
71
+
72
+ }
73
+ }
74
+
75
+
76
+ /**
77
+ * Show a tabbed panel to setting page
78
+ *
79
+ * a callback function called by add_setting_page => add_submenu_page
80
+ *
81
+ * @return void
82
+ * @since 1.0
83
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
84
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
85
+ */
86
+ public function yit_panel() {
87
+ $additional_info = array(
88
+ 'current_tab' => $this->get_current_tab(),
89
+ 'available_tabs' => $this->settings['admin-tabs'],
90
+ 'default_tab' => $this->get_available_tabs( true ), //get default tabs
91
+ 'page' => $this->settings['page']
92
+ );
93
+
94
+ $additional_info = apply_filters( 'yith_admin_tab_params', $additional_info );
95
+ $additional_info['additional_info'] = $additional_info;
96
+
97
+ extract( $additional_info );
98
+ require_once( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/woocommerce/woocommerce-panel.php' );
99
+ }
100
+
101
+ /**
102
+ * Show a box panel with specific content in two columns as a new woocommerce type
103
+ *
104
+ *
105
+ * @return void
106
+ * @since 1.0
107
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
108
+ */
109
+ public function yit_boxinfo( $args = array() ) {
110
+ if ( !empty( $args ) ) {
111
+ extract( $args );
112
+ require_once( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/woocommerce/woocommerce-boxinfo.php' );
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Show a box panel with specific content in two columns as a new woocommerce type
118
+ *
119
+ *
120
+ * @return void
121
+ * @since 1.0
122
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
123
+ */
124
+ public function yit_videobox( $args = array() ) {
125
+ if ( !empty( $args ) ) {
126
+ extract( $args );
127
+ require_once( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/woocommerce/woocommerce-videobox.php' );
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Show a input fields to upload images
133
+ *
134
+ *
135
+ * @return void
136
+ * @since 1.0
137
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
138
+ */
139
+
140
+ public function yit_upload_update( $option_value ) {
141
+ return $option_value;
142
+ }
143
+
144
+ /**
145
+ * Show a input fields to upload images
146
+ *
147
+ *
148
+ * @return void
149
+ * @since 1.0
150
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
151
+ */
152
+
153
+ public function yit_upload( $args = array() ) {
154
+
155
+ if ( !empty( $args ) ) {
156
+ $args['value'] = ( get_option($args['id'])) ? get_option($args['id']) : $args['default'];
157
+ extract( $args );
158
+
159
+ include( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/woocommerce/woocommerce-upload.php' );
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Returns current active tab slug
165
+ *
166
+ * @return string
167
+ * @since 2.0.0
168
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
169
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
170
+ */
171
+ public function get_current_tab() {
172
+ global $pagenow;
173
+ $tabs = $this->get_available_tabs();
174
+
175
+ if ( $pagenow == 'admin.php' && isset( $_REQUEST['tab'] ) && in_array( $_REQUEST['tab'], $tabs ) ) {
176
+ return $_REQUEST['tab'];
177
+ }
178
+ else {
179
+ return $tabs[0];
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Return available tabs
185
+ *
186
+ * read all options and show sections and fields
187
+ *
188
+ * @param bool false for all tabs slug, true for current tab
189
+ *
190
+ * @return mixed Array tabs | String current tab
191
+ * @since 1.0
192
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
193
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
194
+ */
195
+ public function get_available_tabs( $default = false ) {
196
+ $tabs = array_keys( $this->settings['admin-tabs'] );
197
+ return $default ? $tabs[0] : $tabs;
198
+ }
199
+
200
+
201
+ /**
202
+ * Add sections and fields to setting panel
203
+ *
204
+ * read all options and show sections and fields
205
+ *
206
+ * @return void
207
+ * @since 1.0
208
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
209
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
210
+ */
211
+ public function add_fields() {
212
+ $yit_options = $this->get_main_array_options();
213
+ $current_tab = $this->get_current_tab();
214
+
215
+ if ( ! $current_tab ) {
216
+ return;
217
+ }
218
+
219
+ woocommerce_admin_fields( $yit_options[$current_tab] );
220
+ }
221
+
222
+ /**
223
+ * Print the panel content
224
+ *
225
+ * check if the tab is a wc options tab or custom tab and print the content
226
+ *
227
+ * @return void
228
+ * @since 1.0
229
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
230
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
231
+ */
232
+ public function print_panel_content() {
233
+ $yit_options = $this->get_main_array_options();
234
+ $current_tab = $this->get_current_tab();
235
+ $custom_tab_action = $this->is_custom_tab( $yit_options, $current_tab );
236
+
237
+ if ( $custom_tab_action ) {
238
+ $this->print_custom_tab( $custom_tab_action );
239
+ return;
240
+ }
241
+ else {
242
+ require_once( YIT_CORE_PLUGIN_TEMPLATE_PATH . '/panel/woocommerce/woocommerce-form.php' );
243
+ }
244
+ }
245
+
246
+ /**
247
+ * Update options
248
+ *
249
+ * @return void
250
+ * @since 1.0
251
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
252
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
253
+ * @see woocommerce_update_options function
254
+ * @internal fire two action (before and after update): yit_panel_wc_before_update and yit_panel_wc_after_update
255
+ */
256
+ public function woocommerce_update_options() {
257
+
258
+ if ( isset( $_POST['yit_panel_wc_options_nonce'] ) && wp_verify_nonce( $_POST['yit_panel_wc_options_nonce'], 'yit_panel_wc_options_'.$this->settings['page'] ) ) {
259
+
260
+ do_action( 'yit_panel_wc_before_update' );
261
+
262
+ $yit_options = $this->get_main_array_options();
263
+ $current_tab = $this->get_current_tab();
264
+
265
+ woocommerce_update_options( $yit_options[ $current_tab ] );
266
+
267
+ do_action( 'yit_panel_wc_after_update' );
268
+
269
+ } elseif( isset( $_REQUEST['yit-action'] ) && $_REQUEST['yit-action'] == 'wc-options-reset' ){
270
+
271
+ $yit_options = $this->get_main_array_options();
272
+ $current_tab = $this->get_current_tab();
273
+
274
+ foreach( $yit_options[ $current_tab ] as $id => $option ){
275
+ if( isset( $option['default'] ) ){
276
+ update_option( $option['id'], $option['default'] );
277
+ }
278
+ }
279
+ }
280
+ }
281
+
282
+ /**
283
+ * Add Admin WC Style and Scripts
284
+ *
285
+ * @return void
286
+ * @since 1.0
287
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
288
+ * @author Antonio La Rocca <antonio.larocca@yithemes.com>
289
+ */
290
+ public function admin_enqueue_scripts() {
291
+ global $woocommerce;
292
+
293
+ wp_enqueue_style( 'raleway-font', '//fonts.googleapis.com/css?family=Raleway:400,500,600,700,800,100,200,300,900' );
294
+
295
+ wp_enqueue_media();
296
+ wp_enqueue_style( 'woocommerce_admin_styles', $woocommerce->plugin_url() . '/assets/css/admin.css', array(), $woocommerce->version );
297
+ wp_enqueue_style( 'yit-plugin-style', YIT_CORE_PLUGIN_URL . '/assets/css/yit-plugin-panel.css', $woocommerce->version );
298
+ wp_enqueue_style ( 'wp-jquery-ui-dialog' );
299
+
300
+
301
+ wp_enqueue_style( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/css/chosen/chosen.css' );
302
+ wp_enqueue_script( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/js/chosen/chosen.jquery.js', array( 'jquery' ), '1.1.0', true );
303
+ wp_enqueue_script( 'woocommerce_settings', $woocommerce->plugin_url() . '/assets/js/admin/settings.min.js', array( 'jquery', 'jquery-ui-datepicker','jquery-ui-dialog', 'jquery-ui-sortable', 'iris', 'chosen' ), $woocommerce->version, true );
304
+ wp_enqueue_script( 'yit-plugin-panel', YIT_CORE_PLUGIN_URL . '/assets/js/yit-plugin-panel.min.js', array( 'jquery', 'jquery-chosen' ), $this->version, true );
305
+ wp_localize_script( 'woocommerce_settings', 'woocommerce_settings_params', array(
306
+ 'i18n_nav_warning' => __( 'The changes you made will be lost if you navigate away from this page.', 'yit' )
307
+ ) );
308
+ }
309
+
310
+ /**
311
+ * Default options
312
+ *
313
+ * Sets up the default options used on the settings page
314
+ *
315
+ * @access public
316
+ * @return void
317
+ * @since 1.0.0
318
+ */
319
+ public function set_default_options() {
320
+
321
+ $default_options = $this->get_main_array_options();
322
+
323
+ foreach ($default_options as $section) {
324
+ foreach ( $section as $value ) {
325
+ if ( ( isset( $value['std'] ) || isset( $value['default'] ) ) && isset( $value['id'] ) ) {
326
+ $default_value = ( isset( $value['default'] ) ) ? $value['default'] : $value['std'];
327
+
328
+ if ( $value['type'] == 'image_width' ) {
329
+ add_option($value['id'].'_width', $default_value);
330
+ add_option($value['id'].'_height', $default_value);
331
+ } else {
332
+ add_option($value['id'], $default_value);
333
+ }
334
+
335
+ }
336
+
337
+ }
338
+ }
339
+
340
+ }
341
+
342
+
343
+ }
344
+ }
plugin-fw/lib/yit-plugin-panel.php ADDED
@@ -0,0 +1,710 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Plugin_Panel' ) ) {
16
+ /**
17
+ * YIT Plugin Panel
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Plugin_Panel
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Your Inspiration Themes
25
+ */
26
+
27
+ class YIT_Plugin_Panel {
28
+
29
+ /**
30
+ * @var string version of class
31
+ */
32
+ public $version = '1.0.0';
33
+
34
+ /**
35
+ * @var array a setting list of parameters
36
+ */
37
+ public $settings = array();
38
+
39
+ /**
40
+ * @var array
41
+ */
42
+ protected $_tabs_path_files;
43
+
44
+ /**
45
+ * @var array
46
+ */
47
+ private $_main_array_options = array();
48
+
49
+ /**
50
+ * Constructor
51
+ *
52
+ * @since 1.0
53
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
54
+ */
55
+ public function __construct( $args = array() ) {
56
+
57
+ if ( ! empty( $args ) ) {
58
+
59
+ $default_args = array(
60
+ 'parent_slug' => 'edit.php?',
61
+ 'page_title' => __( 'Plugin Settings', 'yit' ),
62
+ 'menu_title' => __( 'Settings', 'yit' ),
63
+ 'capability' => 'manage_options'
64
+ );
65
+
66
+ $this->settings = wp_parse_args( $args, $default_args );
67
+ $this->_tabs_path_files = $this->get_tabs_path_files();
68
+
69
+ if ( isset( $this->settings['create_menu_page'] ) && $this->settings['create_menu_page'] ) {
70
+ $this->add_menu_page();
71
+ }
72
+
73
+ add_action( 'admin_init', array( &$this, 'register_settings' ) );
74
+ add_action( 'admin_menu', array( &$this, 'add_setting_page' ) );
75
+ add_action( 'admin_bar_menu', array( &$this, 'add_admin_bar_menu' ), 100 );
76
+ add_action( 'admin_init', array( &$this, 'add_fields' ) );
77
+
78
+
79
+ }
80
+
81
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
82
+ }
83
+
84
+ /**
85
+ * Add Menu page link
86
+ *
87
+ * @return void
88
+ * @since 1.0
89
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
90
+ */
91
+ public function add_menu_page() {
92
+ add_menu_page( 'yit_plugin_panel', __( 'YIT Plugins', 'yit' ), 'manage_options', 'yit_plugin_panel', NULL, YIT_CORE_PLUGIN_URL . '/assets/images/yithemes-icon.png', 62 );
93
+ }
94
+
95
+ /**
96
+ * Remove duplicate submenu
97
+ *
98
+ * Submenu page hack: Remove the duplicate YIT Plugin link on subpages
99
+ *
100
+ * @return void
101
+ * @since 1.0
102
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
103
+ */
104
+ public function remove_duplicate_submenu_page() {
105
+ /* === Duplicate Items Hack === */
106
+ remove_submenu_page( 'yit_plugin_panel', 'yit_plugin_panel' );
107
+ }
108
+
109
+ /**
110
+ * Enqueue script and styles in admin side
111
+ *
112
+ * Add style and scripts to administrator
113
+ *
114
+ * @return void
115
+ * @since 1.0
116
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
117
+ */
118
+ public function admin_enqueue_scripts() {
119
+ //scripts
120
+ wp_enqueue_media();
121
+ wp_enqueue_script( 'jquery-ui' );
122
+ wp_enqueue_script( 'jquery-ui-core' );
123
+ wp_enqueue_script( 'jquery-ui-slider' );
124
+ wp_enqueue_style( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/css/chosen/chosen.css' );
125
+ wp_enqueue_script( 'jquery-chosen', YIT_CORE_PLUGIN_URL . '/assets/js/chosen/chosen.jquery.js', array( 'jquery' ), '1.1.0', true );
126
+ wp_enqueue_script( 'yit-plugin-panel', YIT_CORE_PLUGIN_URL . '/assets/js/yit-plugin-panel.min.js', array( 'jquery', 'jquery-chosen' ), $this->version, true );
127
+ wp_register_script( 'codemirror', YIT_CORE_PLUGIN_URL . '/assets/js/codemirror/codemirror.js', array( 'jquery' ), $this->version, true );
128
+ wp_register_script( 'codemirror-javascript', YIT_CORE_PLUGIN_URL . '/assets/js/codemirror/javascript.js', array( 'jquery', 'codemirror' ), $this->version, true );
129
+
130
+
131
+ wp_register_style( 'codemirror', YIT_CORE_PLUGIN_URL . '/assets/css/codemirror/codemirror.css' );
132
+
133
+ //styles
134
+ wp_enqueue_style( 'jquery-ui-overcast', YIT_CORE_PLUGIN_URL . '/assets/css/overcast/jquery-ui-1.8.9.custom.css', false, '1.8.9', 'all' );
135
+ wp_enqueue_style( 'yit-plugin-style', YIT_CORE_PLUGIN_URL . '/assets/css/yit-plugin-panel.css', $this->version );
136
+ wp_enqueue_style( 'raleway-font', '//fonts.googleapis.com/css?family=Raleway:400,500,600,700,800,100,200,300,900' );
137
+ }
138
+
139
+ /**
140
+ * Register Settings
141
+ *
142
+ * Generate wp-admin settings pages by registering your settings and using a few callbacks to control the output
143
+ *
144
+ * @return void
145
+ * @since 1.0
146
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
147
+ */
148
+ public function register_settings() {
149
+ register_setting( 'yit_' . $this->settings['parent'] . '_options', 'yit_' . $this->settings['parent'] . '_options', array( &$this, 'options_validate' ) );
150
+ }
151
+
152
+ /**
153
+ * Options Validate
154
+ *
155
+ * a callback function called by Register Settings function
156
+ *
157
+ * @param $input
158
+ *
159
+ * @return array validate input fields
160
+ * @since 1.0
161
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
162
+ */
163
+ public function options_validate( $input ) {
164
+
165
+ $current_tab = ! empty( $input['current_tab'] ) ? $input['current_tab'] : 'general';
166
+
167
+ $yit_options = $this->get_main_array_options();
168
+
169
+ // default
170
+ $valid_input = $this->get_options();
171
+
172
+ $submit = ( ! empty( $input['submit-general'] ) ? true : false );
173
+ $reset = ( ! empty( $input['reset-general'] ) ? true : false );
174
+
175
+ foreach ( $yit_options[$current_tab] as $section => $data ) {
176
+ foreach ( $data as $option ) {
177
+ if ( isset( $option['sanitize_call'] ) && isset( $option['id'] ) ) { //yiw_debug($option, false);
178
+ if ( is_array( $option['sanitize_call'] ) ) :
179
+ foreach ( $option['sanitize_call'] as $callback ) {
180
+ if ( is_array( $input[$option['id']] ) ) {
181
+ $valid_input[$option['id']] = array_map( $callback, $input[$option['id']] );
182
+ }
183
+ else {
184
+ $valid_input[$option['id']] = call_user_func( $callback, $input[$option['id']] );
185
+ }
186
+ }
187
+ else :
188
+ if ( is_array( $input[$option['id']] ) ) {
189
+ $valid_input[$option['id']] = array_map( $option['sanitize_call'], $input[$option['id']] );
190
+ }
191
+ else {
192
+ $valid_input[$option['id']] = call_user_func( $option['sanitize_call'], $input[$option['id']] );
193
+ }
194
+ endif;
195
+ }
196
+ else {
197
+ if ( isset( $option['id'] ) ) {
198
+ if ( isset( $input[$option['id']] ) ) {
199
+ $valid_input[$option['id']] = $input[$option['id']];
200
+ }
201
+ else {
202
+ $valid_input[$option['id']] = 'no';
203
+ }
204
+
205
+ }
206
+ }
207
+
208
+ }
209
+ }
210
+
211
+ return $valid_input;
212
+ }
213
+
214
+ /**
215
+ * Add Setting SubPage
216
+ *
217
+ * add Setting SubPage to wordpress administrator
218
+ *
219
+ * @return array validate input fields
220
+ * @since 1.0
221
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
222
+ */
223
+ public function add_setting_page() {
224
+ add_submenu_page( $this->settings['parent_slug'] . $this->settings['parent_page'], $this->settings['page_title'], $this->settings['menu_title'], $this->settings['capability'], $this->settings['page'], array( &$this, 'yit_panel' ) );
225
+ /* === Duplicate Items Hack === */
226
+ $this->remove_duplicate_submenu_page();
227
+ do_action( 'yit_after_add_settings_page' );
228
+ }
229
+
230
+ /**
231
+ * Show a tabbed panel to setting page
232
+ *
233
+ * a callback function called by add_setting_page => add_submenu_page
234
+ *
235
+ * @return void
236
+ * @since 1.0
237
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
238
+ */
239
+ public function yit_panel() {
240
+
241
+ $tabs = '';
242
+ $current_tab = $this->get_current_tab();
243
+ $yit_options = $this->get_main_array_options();
244
+
245
+ // tabs
246
+ foreach ( $this->settings['admin-tabs'] as $tab => $tab_value ) {
247
+ $active_class = ( $current_tab == $tab ) ? ' nav-tab-active' : '';
248
+ $tabs .= '<a class="nav-tab' . $active_class . '" href="?' . $this->settings['parent_page'] . '&page=' . $this->settings['page'] . '&tab=' . $tab . '">' . $tab_value . '</a>';
249
+ }
250
+ ?>
251
+ <div id="icon-themes" class="icon32"><br /></div>
252
+ <h2 class="nav-tab-wrapper">
253
+ <?php echo $tabs ?>
254
+ </h2>
255
+ <?php
256
+ $custom_tab_action = $this->is_custom_tab( $yit_options, $current_tab );
257
+ if ( $custom_tab_action ) {
258
+ $this->print_custom_tab( $custom_tab_action );
259
+ return;
260
+ }
261
+ ?>
262
+ <div id="wrap" class="plugin-option">
263
+ <?php $this->message(); ?>
264
+ <h2><?php echo $this->get_tab_title() ?></h2>
265
+ <?php if ( $this->is_show_form() ) : ?>
266
+ <form method="post" action="options.php">
267
+ <?php do_settings_sections( 'yit' ); ?>
268
+ <p>&nbsp;</p>
269
+ <?php settings_fields( 'yit_' . $this->settings['parent'] . '_options' ); ?>
270
+ <input type="hidden" name="<?php echo $this->get_name_field( 'current_tab' ) ?>" value="<?php echo esc_attr( $current_tab ) ?>" />
271
+ <input type="submit" class="button-primary" value="<?php _e( 'Save Changes', 'yit' ) ?>" style="float:left;margin-right:10px;" />
272
+ </form>
273
+ <form method="post">
274
+ <?php $warning = __( 'If you continue with this action, you will reset all options are in this page.', 'yit' ) ?>
275
+ <input type="hidden" name="yit-action" value="reset" />
276
+ <input type="submit" name="yit-reset" class="button-secondary" value="<?php _e( 'Reset Defaults', 'yit' ) ?>" onclick="return confirm('<?php echo $warning . '\n' . __( 'Are you sure of it?', 'yit' ) ?>');" />
277
+ </form>
278
+ <p>&nbsp;</p>
279
+ <?php endif ?>
280
+ </div>
281
+ <?php
282
+ }
283
+
284
+ public function is_custom_tab( $options, $current_tab ) {
285
+ foreach ( $options[$current_tab] as $section => $option ) {
286
+ if ( isset( $option['type'] ) && isset( $option['action'] ) && 'custom_tab' == $option['type'] && ! empty( $option['action'] ) ) {
287
+ return $option['action'];
288
+ }
289
+ else {
290
+ return false;
291
+ }
292
+ }
293
+ }
294
+
295
+ /**
296
+ * Fire the action to print the custom tab
297
+ *
298
+ *
299
+ * @param $action Action to fire
300
+ *
301
+ * @return void
302
+ * @since 1.0
303
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
304
+ */
305
+ public function print_custom_tab( $action ) {
306
+ do_action( $action );
307
+ }
308
+
309
+ /**
310
+ * Add sections and fields to setting panel
311
+ *
312
+ * read all options and show sections and fields
313
+ *
314
+ * @return void
315
+ * @since 1.0
316
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
317
+ */
318
+ public function add_fields() {
319
+ $yit_options = $this->get_main_array_options();
320
+ $current_tab = $this->get_current_tab();
321
+
322
+ if ( ! $current_tab ) {
323
+ return;
324
+ }
325
+ foreach ( $yit_options[$current_tab] as $section => $data ) {
326
+ add_settings_section( "yit_settings_{$current_tab}_{$section}", $this->get_section_title( $section ), $this->get_section_description( $section ), 'yit' );
327
+ foreach ( $data as $option ) {
328
+ if ( isset( $option['id'] ) && isset( $option['type'] ) && isset( $option['name'] ) ) {
329
+ add_settings_field( "yit_setting_" . $option['id'], $option['name'], array( $this, 'render_field' ), 'yit', "yit_settings_{$current_tab}_{$section}", array( 'option' => $option, 'label_for' => $this->get_id_field( $option['id'] ) ) );
330
+ }
331
+ }
332
+ }
333
+ }
334
+
335
+
336
+ /**
337
+ * Add the tabs to admin bar menu
338
+ *
339
+ * set all tabs of settings page on wp admin bar
340
+ *
341
+ * @return void|array return void when capability is false
342
+ * @since 1.0
343
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
344
+ */
345
+ public function add_admin_bar_menu() {
346
+
347
+ global $wp_admin_bar;
348
+
349
+ if ( ! current_user_can( 'manage_options' ) ) {
350
+ return;
351
+ }
352
+
353
+ if ( ! empty( $this->settings['admin_tabs'] ) ) {
354
+ foreach ( $this->settings['admin-tabs'] as $item => $title ) {
355
+
356
+ $wp_admin_bar->add_menu( array(
357
+ 'parent' => $this->settings['parent'],
358
+ 'title' => $title,
359
+ 'id' => $this->settings['parent'] . '-' . $item,
360
+ 'href' => admin_url( 'themes.php' ) . '?page=' . $this->settings['parent_page'] . '&tab=' . $item
361
+ ) );
362
+ }
363
+ }
364
+ }
365
+
366
+
367
+ /**
368
+ * Get current tab
369
+ *
370
+ * get the id of tab showed, return general is the current tab is not defined
371
+ *
372
+ * @return string
373
+ * @since 1.0
374
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
375
+ */
376
+ function get_current_tab() {
377
+ $admin_tabs = array_keys( $this->settings['admin-tabs'] );
378
+
379
+ if ( ! isset( $_GET['page'] ) || $_GET['page'] != $this->settings['page'] ) {
380
+ return false;
381
+ }
382
+ if ( isset( $_REQUEST['yit_tab_options'] ) ) {
383
+ return $_REQUEST['yit_tab_options'];
384
+ }
385
+ elseif ( isset( $_GET['tab'] ) && isset( $this->_tabs_path_files[$_GET['tab']] ) ) {
386
+ return $_GET['tab'];
387
+ }
388
+ elseif ( isset( $admin_tabs[0] ) ) {
389
+ return $admin_tabs[0];
390
+ }
391
+ else {
392
+ return 'general';
393
+ }
394
+ }
395
+
396
+
397
+ /**
398
+ * Message
399
+ *
400
+ * define an array of message and show the content od message if
401
+ * is find in the query string
402
+ *
403
+ * @return void
404
+ * @since 1.0
405
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
406
+ */
407
+ public function message() {
408
+
409
+ $message = array(
410
+ 'element_exists' => $this->get_message( '<strong>' . __( 'The element you have written is already exists. Please, add another name.', 'yit' ) . '</strong>', 'error', false ),
411
+ 'saved' => $this->get_message( '<strong>' . __( 'Settings saved', 'yit' ) . '.</strong>', 'updated', false ),
412
+ 'reset' => $this->get_message( '<strong>' . __( 'Settings reset', 'yit' ) . '.</strong>', 'updated', false ),
413
+ 'delete' => $this->get_message( '<strong>' . __( 'Element deleted correctly.', 'yit' ) . '</strong>', 'updated', false ),
414
+ 'updated' => $this->get_message( '<strong>' . __( 'Element updated correctly.', 'yit' ) . '</strong>', 'updated', false ),
415
+ 'settings-updated' => $this->get_message( '<strong>' . __( 'Element updated correctly.', 'yit' ) . '</strong>', 'updated', false ),
416
+ 'imported' => $this->get_message( '<strong>' . __( 'Database imported correctly.', 'yit' ) . '</strong>', 'updated', false ),
417
+ 'no-imported' => $this->get_message( '<strong>' . __( 'An error encoured during during import. Please try again.', 'yit' ) . '</strong>', 'error', false ),
418
+ 'file-not-valid' => $this->get_message( '<strong>' . __( "The file you have insert doesn't valid.", 'yit' ) . '</strong>', 'error', false ),
419
+ 'cant-import' => $this->get_message( '<strong>' . __( "I'm sorry, the import featured is disabled.", 'yit' ) . '</strong>', 'error', false ),
420
+ 'ord' => $this->get_message( '<strong>' . __( "Sorting done correctly.", 'yit' ) . '</strong>', 'updated', false )
421
+ );
422
+
423
+ foreach ( $message as $key => $value ) {
424
+ if ( isset( $_GET[$key] ) ) {
425
+ echo $message[$key];
426
+ }
427
+ }
428
+
429
+ }
430
+
431
+ /**
432
+ * Get Message
433
+ *
434
+ * return html code of message
435
+ *
436
+ * @param $message
437
+ * @param string $type can be 'error' or 'updated'
438
+ * @param bool $echo
439
+ *
440
+ * @return void|string
441
+ * @since 1.0
442
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
443
+ */
444
+ public function get_message( $message, $type = 'error', $echo = true ) {
445
+ $message = '<div id="message" class="' . $type . ' fade"><p>' . $message . '</p></div>';
446
+ if ( $echo ) {
447
+ echo $message;
448
+ }
449
+ return $message;
450
+ }
451
+
452
+
453
+ /**
454
+ * Get Tab Path Files
455
+ *
456
+ * return an array with filenames of tabs
457
+ *
458
+ * @return array
459
+ * @since 1.0
460
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
461
+ */
462
+ function get_tabs_path_files() {
463
+
464
+ $option_files_path = $this->settings['options-path'] . '/';
465
+
466
+ $tabs = array();
467
+
468
+ foreach ( ( array ) glob( $option_files_path . '*.php' ) as $filename ) {
469
+ preg_match( '/(.*)-options\.(.*)/', basename( $filename ), $filename_parts );
470
+ $tab = $filename_parts[1];
471
+
472
+ $tabs[$tab] = $filename;
473
+ }
474
+
475
+ return $tabs;
476
+ }
477
+
478
+ /**
479
+ * Get main array options
480
+ *
481
+ * return an array with all options defined on options-files
482
+ *
483
+ * @return array
484
+ * @since 1.0
485
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
486
+ */
487
+ function get_main_array_options() {
488
+ if ( ! empty( $this->_main_array_options ) ) {
489
+ return $this->_main_array_options;
490
+ }
491
+
492
+ foreach ( $this->settings['admin-tabs'] as $item => $v ) {
493
+ $path = $this->settings['options-path'] . '/' . $item . '-options.php';
494
+ if ( file_exists( $path ) ) {
495
+ $this->_main_array_options = array_merge( $this->_main_array_options, include $path );
496
+ }
497
+ }
498
+
499
+ return $this->_main_array_options;
500
+ }
501
+
502
+
503
+ /**
504
+ * Set an array with all default options
505
+ *
506
+ * put default options in an array
507
+ *
508
+ * @return array
509
+ * @since 1.0
510
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
511
+ */
512
+ public function get_default_options() {
513
+ $yit_options = $this->get_main_array_options();
514
+ $default_options = array();
515
+
516
+ foreach ( $yit_options as $tab => $sections ) {
517
+ foreach ( $sections as $section ) {
518
+ foreach ( $section as $id => $value ) {
519
+ if ( isset( $value['std'] ) && isset( $value['id'] ) ) {
520
+ $default_options[$value['id']] = $value['std'];
521
+ }
522
+ }
523
+ }
524
+ }
525
+
526
+ unset( $yit_options );
527
+ return $default_options;
528
+ }
529
+
530
+
531
+ /**
532
+ * Get the title of the tab
533
+ *
534
+ * return the title of tab
535
+ *
536
+ * @return string
537
+ * @since 1.0
538
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
539
+ */
540
+ function get_tab_title() {
541
+ $yit_options = $this->get_main_array_options();
542
+ $current_tab = $this->get_current_tab();
543
+
544
+ foreach ( $yit_options[$current_tab] as $sections => $data ) {
545
+ foreach ( $data as $option ) {
546
+ if ( isset( $option['type'] ) && $option['type'] == 'title' ) {
547
+ return $option['name'];
548
+ }
549
+ }
550
+ }
551
+ }
552
+
553
+ /**
554
+ * Get the title of the section
555
+ *
556
+ * return the title of section
557
+ *
558
+ * @param $section
559
+ *
560
+ * @return string
561
+ * @since 1.0
562
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
563
+ */
564
+ function get_section_title( $section ) {
565
+ $yit_options = $this->get_main_array_options();
566
+ $current_tab = $this->get_current_tab();
567
+
568
+ foreach ( $yit_options[$current_tab][$section] as $option ) {
569
+ if ( isset( $option['type'] ) && $option['type'] == 'section' ) {
570
+ return $option['name'];
571
+ }
572
+ }
573
+ }
574
+
575
+ /**
576
+ * Get the description of the section
577
+ *
578
+ * return the description of section if is set
579
+ *
580
+ * @param $section
581
+ *
582
+ * @return string
583
+ * @since 1.0
584
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
585
+ */
586
+ function get_section_description( $section ) {
587
+ $yit_options = $this->get_main_array_options();
588
+ $current_tab = $this->get_current_tab();
589
+
590
+ foreach ( $yit_options[$current_tab][$section] as $option ) {
591
+ if ( isset( $option['type'] ) && $option['type'] == 'section' && isset( $option['desc'] ) ) {
592
+ return '<p>' . $option['desc'] . '</p>';
593
+ }
594
+ }
595
+ }
596
+
597
+
598
+ /**
599
+ * Show form when necessary
600
+ *
601
+ * return true if 'showform' is not defined
602
+ *
603
+ * @return bool
604
+ * @since 1.0
605
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
606
+ */
607
+ function is_show_form() {
608
+ $yit_options = $this->get_main_array_options();
609
+ $current_tab = $this->get_current_tab();
610
+
611
+ foreach ( $yit_options[$current_tab] as $sections => $data ) {
612
+ foreach ( $data as $option ) {
613
+ if ( ! isset( $option['type'] ) || $option['type'] != 'title' ) {
614
+ continue;
615
+ }
616
+ if ( isset( $option['showform'] ) ) {
617
+ return $option['showform'];
618
+ }
619
+ else {
620
+ return true;
621
+ }
622
+ }
623
+ }
624
+ }
625
+
626
+ /**
627
+ * Get name field
628
+ *
629
+ * return a string with the name of the input field
630
+ *
631
+ * @param string $name
632
+ *
633
+ * @return string
634
+ * @since 1.0
635
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
636
+ */
637
+ function get_name_field( $name = '' ) {
638
+ return 'yit_' . $this->settings['parent'] . '_options[' . $name . ']';
639
+ }
640
+
641
+ /**
642
+ * Get id field
643
+ *
644
+ * return a string with the id of the input field
645
+ *
646
+ * @param string $id
647
+ *
648
+ * @return string
649
+ * @since 1.0
650
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
651
+ */
652
+ function get_id_field( $id ) {
653
+ return 'yit_' . $this->settings['parent'] . '_options_' . $id;
654
+ }
655
+
656
+
657
+ /**
658
+ * Render the field showed in the setting page
659
+ *
660
+ * include the file of the option type, if file do not exists
661
+ * return a text area
662
+ *
663
+ * @param array $param
664
+ *
665
+ * @return void
666
+ * @since 1.0
667
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
668
+ */
669
+ function render_field( $param ) {
670
+
671
+ if ( ! empty( $param ) && isset( $param ['option'] ) ) {
672
+ $option = $param ['option'];
673
+ $db_options = $this->get_options();
674
+
675
+ $db_value = ( isset( $db_options[$option['id']] ) ) ? $db_options[$option['id']] : '';
676
+ if ( isset( $option['deps'] ) ) {
677
+ $deps = $option['deps'];
678
+ }
679
+ $type = YIT_CORE_PLUGIN_PATH . '/templates/panel/types/' . $option['type'] . '.php';
680
+ if ( file_exists( $type ) ) {
681
+ include $type;
682
+ }
683
+ else {
684
+ do_action( "yit_panel_{$option['type']}" );
685
+ }
686
+ }
687
+ }
688
+
689
+ /**
690
+ * Get options from db
691
+ *
692
+ * return the options from db, if the options aren't defined in the db,
693
+ * get the default options ad add the options in the db
694
+ *
695
+ * @return array
696
+ * @since 1.0
697
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
698
+ */
699
+ public function get_options() {
700
+ $options = get_option( 'yit_' . $this->settings['parent'] . '_options' );
701
+ if ( $options === false || ( isset( $_REQUEST['yit-action'] ) && $_REQUEST['yit-action'] == 'reset' ) ) {
702
+ $options = $this->get_default_options();
703
+ }
704
+ return $options;
705
+ }
706
+
707
+
708
+ }
709
+
710
+ }
plugin-fw/lib/yit-plugin-subpanel.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Plugin_SubPanel' ) ) {
16
+ /**
17
+ * YIT Plugin Panel
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Plugin_Panel
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Your Inspiration Themes
25
+ */
26
+
27
+ class YIT_Plugin_SubPanel extends YIT_Plugin_Panel {
28
+
29
+ /**
30
+ * @var string version of class
31
+ */
32
+ public $version = '1.0.0';
33
+
34
+ /**
35
+ * @var array a setting list of parameters
36
+ */
37
+ public $settings = array();
38
+
39
+
40
+ /**
41
+ * @var array
42
+ */
43
+ private $_main_array_options = array();
44
+
45
+ /**
46
+ * Constructor
47
+ *
48
+ * @since 1.0
49
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
50
+ */
51
+
52
+ public function __construct( $args = array() ) {
53
+ if ( ! empty( $args ) ) {
54
+ $this->settings = $args;
55
+ $this->settings['parent'] = $this->settings['page'];
56
+ $this->_tabs_path_files = $this->get_tabs_path_files();
57
+
58
+ add_action( 'admin_init', array( $this, 'register_settings' ) );
59
+ add_action( 'admin_menu', array( &$this, 'add_setting_page' ) );
60
+ add_action( 'admin_bar_menu', array( &$this, 'add_admin_bar_menu' ), 100 );
61
+ add_action( 'admin_init', array( &$this, 'add_fields' ) );
62
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
63
+ }
64
+ }
65
+
66
+
67
+ /**
68
+ * Register Settings
69
+ *
70
+ * Generate wp-admin settings pages by registering your settings and using a few callbacks to control the output
71
+ *
72
+ * @return void
73
+ * @since 1.0
74
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
75
+ */
76
+ public function register_settings() {
77
+ register_setting( 'yit_' . $this->settings['page'] . '_options', 'yit_' . $this->settings['page'] . '_options', array( &$this, 'options_validate' ) );
78
+ }
79
+
80
+
81
+
82
+ /**
83
+ * Add Setting SubPage
84
+ *
85
+ * add Setting SubPage to wordpress administrator
86
+ *
87
+ * @return array validate input fields
88
+ * @since 1.0
89
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
90
+ */
91
+ public function add_setting_page() {
92
+
93
+ $logo = YIT_CORE_PLUGIN_URL . '/assets/images/yithemes-icon.png';
94
+
95
+ $admin_logo = function_exists( 'yit_get_option' ) ? yit_get_option( 'admin-logo-menu' ) : '';
96
+
97
+ if ( isset( $admin_logo ) && ! empty( $admin_logo ) && $admin_logo != '' && $admin_logo) {
98
+ $logo = $admin_logo;
99
+ }
100
+
101
+ add_menu_page( 'yit_plugin_panel', __( 'YIT Plugins', 'yit' ), 'nosuchcapability', 'yit_plugin_panel', NULL, $logo, 62 );
102
+ add_submenu_page( 'yit_plugin_panel', $this->settings['label'], $this->settings['label'], 'manage_options', $this->settings['page'], array( $this, 'yit_panel' ) );
103
+ remove_submenu_page( 'yit_plugin_panel', 'yit_plugin_panel' );
104
+
105
+ }
106
+
107
+ /**
108
+ * Show a tabbed panel to setting page
109
+ *
110
+ * a callback function called by add_setting_page => add_submenu_page
111
+ *
112
+ * @return void
113
+ * @since 1.0
114
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
115
+ */
116
+ public function yit_panel() {
117
+
118
+ $tabs = '';
119
+ $current_tab = $this->get_current_tab();
120
+
121
+ // tabs
122
+ foreach ( $this->settings['admin-tabs'] as $tab => $tab_value ) {
123
+ $active_class = ( $current_tab == $tab ) ? ' nav-tab-active' : '';
124
+ $tabs .= '<a class="nav-tab' . $active_class . '" href="?page=' . $this->settings['page'] . '&tab=' . $tab . '">' . $tab_value . '</a>';
125
+ }
126
+ ?>
127
+ <div id="icon-themes" class="icon32"><br /></div>
128
+ <h2 class="nav-tab-wrapper">
129
+ <?php echo $tabs ?>
130
+ </h2>
131
+
132
+ <div id="wrap" class="plugin-option">
133
+ <?php $this->message(); ?>
134
+ <h2><?php echo $this->get_tab_title() ?></h2>
135
+
136
+ <?php if ( $this->is_show_form() ) : ?>
137
+ <form method="post" action="options.php">
138
+ <?php do_settings_sections( 'yit' ); ?>
139
+ <p>&nbsp;</p>
140
+ <?php settings_fields( 'yit_' . $this->settings['page'] . '_options' ); ?>
141
+ <input type="hidden" name="<?php echo $this->get_name_field( 'current_tab' ) ?>" value="<?php echo esc_attr( $current_tab ) ?>" />
142
+ <input type="submit" class="button-primary" value="<?php _e( 'Save Changes', 'yit' ) ?>" style="float:left;margin-right:10px;" />
143
+ </form>
144
+ <form method="post">
145
+ <?php $warning = __( 'If you continue with this action, you will reset all options are in this page.', 'yit' ) ?>
146
+ <input type="hidden" name="yit-action" value="reset" />
147
+ <input type="submit" name="yit-reset" class="button-secondary" value="<?php _e( 'Reset Defaults', 'yit' ) ?>" onclick="return confirm('<?php echo $warning . '\n' . __( 'Are you sure of it?', 'yit' ) ?>');" />
148
+ </form>
149
+ <p>&nbsp;</p>
150
+ <?php endif ?>
151
+ </div>
152
+ <?php
153
+ }
154
+
155
+
156
+
157
+ }
158
+
159
+ }
160
+
plugin-fw/lib/yit-pointers.php ADDED
@@ -0,0 +1,390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+ /**
15
+ *
16
+ *
17
+ * @class yit-pointers
18
+ * @package Yithemes
19
+ * @since Version 2.0.0
20
+ * @author Your Inspiration Themes
21
+ *
22
+ */
23
+ if ( ! class_exists( 'YIT_Pointers' ) ) {
24
+ /**
25
+ * YIT Pointers
26
+ *
27
+ * Initializes the new feature pointers.
28
+ *
29
+ * @class YIT_Pointers
30
+ * @package Yithemes
31
+ * @since 1.0
32
+ * @author Your Inspiration Themes
33
+ * @see WP_Internal_Pointers
34
+ */
35
+ class YIT_Pointers {
36
+
37
+ /**
38
+ * @var YIT_Upgrade The main instance
39
+ */
40
+ protected static $_instance;
41
+
42
+ /**
43
+ * @var screen id where to show pointer
44
+ */
45
+ public $screen_ids = array();
46
+
47
+ public $pointers = array();
48
+
49
+ public $special_screen = array();
50
+
51
+ protected $_plugins_registered = array();
52
+
53
+ protected $_default_pointer = array();
54
+
55
+ protected $_default_position = array( 'edge' => 'left', 'align' => 'center' );
56
+
57
+ /**
58
+ * Construct
59
+ *
60
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
61
+ * @since 1.0
62
+ */
63
+ public function __construct() {
64
+
65
+ $this->_default_pointer['plugins'] = array(
66
+ 'screen_id' => 'plugins',
67
+ 'options' => array(
68
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p> <p> %s <a href="http://yithemes.com/product-category/plugins/" target="_blank">Yithemes.com</a> %s
69
+ <a href="https://profiles.wordpress.org/yithemes/" target="_blank">Wordpress.org</a></p>',
70
+ __( 'Plugins Activated', 'yit' ),
71
+ __( 'From now on, you can find all the options of your plugins under the YIT Plugin menu voice.
72
+ For every installation of our new plugins, a new voice will be added to access to the customization settings.', 'yit' ),
73
+ __( 'Discover all our plugins available on:', 'yit' ),
74
+ __( 'and', 'yit' )
75
+ ),
76
+ ),
77
+ );
78
+
79
+ $this->_default_pointer['update'] = array(
80
+ 'screen_id' => 'update',
81
+ 'options' => array(
82
+ 'content' => sprintf( '<h3> %s </h3> <p> %s </p> <p> %s <a href="http://yithemes.com/product-category/plugins/" target="_blank">Yithemes.com</a> %s
83
+ <a href="https://profiles.wordpress.org/yithemes/" target="_blank">Wordpress.org</a></p>',
84
+ __( 'Plugins Upgraded', 'yit' ),
85
+ __( 'From now on, you can find all the options of your plugins under the YIT Plugin menu voice.
86
+ When one of our plugins updates, a new voice will be added to this menu.
87
+ For example, after the update, the options from the plugins (YITH WooCommerce Wishlist, YITH WooCommerce Ajax Search, etc.)
88
+ will be removed from the previous location and moved under the YIT Plugin tab.', 'yit' ),
89
+ __( 'Discover all our plugins available on:', 'yit' ),
90
+ __( 'and', 'yit' )
91
+ ),
92
+ ),
93
+ );
94
+
95
+ $this->_default_pointer = $this->parse_args( $this->_default_pointer );
96
+
97
+ /**
98
+ * Screens that require a particular action
99
+ */
100
+ $this->special_screen = apply_filters( 'yit-pointer-special-screen', array( 'plugins', 'update' ) );
101
+
102
+ add_action( 'admin_enqueue_scripts', array( $this, 'pointer_load' ) );
103
+ add_action( 'admin_init', array( $this, 'add_pointers' ), 100 );
104
+ }
105
+
106
+ public function parse_args( $args ) {
107
+ $default = array(
108
+ 'pointer_id' => 'yith_default_pointer',
109
+ 'target' => '#toplevel_page_yit_plugin_panel',
110
+ 'init' => null
111
+ );
112
+
113
+ foreach ( $args as $id => $pointer ) {
114
+ $args[ $id ] = wp_parse_args( $pointer, $default );
115
+ $args[ $id ]['options']['position'] = $this->_default_position;
116
+ }
117
+
118
+ return $args;
119
+ }
120
+
121
+ public function add_pointers(){
122
+ if( ! empty( $this->screen_ids ) ){
123
+ foreach( $this->screen_ids as $screen_id ){
124
+ add_filter( "yit_pointers-{$screen_id}", array( $this, 'pointers' ) );
125
+ }
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Main plugin Instance
131
+ *
132
+ * @static
133
+ * @return object Main instance
134
+ *
135
+ * @since 1.0
136
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
137
+ */
138
+ public static function instance() {
139
+ if ( is_null( self::$_instance ) ) {
140
+ self::$_instance = new self();
141
+ }
142
+
143
+ return self::$_instance;
144
+ }
145
+
146
+ public function register( $args ) {
147
+
148
+ foreach ( $args as $id => $pointer ) {
149
+
150
+ extract( $pointer );
151
+
152
+ if ( ! isset( $screen_id ) && ! empty( $screen_id ) && ! isset( $init ) && ! empty( $init ) ) {
153
+ return;
154
+ }
155
+
156
+ if ( ! in_array( $screen_id, $this->screen_ids ) ) {
157
+ $this->screen_ids[] = $screen_id;
158
+ }
159
+
160
+ $this->pointers[$screen_id][$pointer_id] = array(
161
+ 'target' => $target,
162
+ 'options' => array(
163
+ 'content' => $content,
164
+ 'position' => $position,
165
+ ),
166
+ 'init' => isset( $init ) ? $init : false
167
+ );
168
+ }
169
+ }
170
+
171
+ public function get_plugins_init( $screen_id ) {
172
+
173
+ $registered = array();
174
+
175
+ foreach( $this->pointers[ $screen_id ] as $pointer_id => $pointer ){
176
+ $registered[ $pointer['init'] ] = $pointer_id;
177
+ }
178
+
179
+ return $registered;
180
+ }
181
+
182
+ public function pointer_load( $hook_suffix ) {
183
+
184
+ /**
185
+ * Get pointers for this screen
186
+ */
187
+ $screen = get_current_screen();
188
+ $pointers = apply_filters( "yit_pointers-{$screen->id}", array() );
189
+
190
+ if ( ! $pointers || ! is_array( $pointers ) ) {
191
+ return;
192
+ }
193
+
194
+ /**
195
+ * Get dismissed pointers
196
+ */
197
+ $dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
198
+ $valid_pointers = array();
199
+ //$point_id = null;
200
+
201
+ /**
202
+ * show pointers only on plugin activate action
203
+ */
204
+ if( in_array( $screen->id, $this->special_screen ) ){
205
+
206
+ $show = false;
207
+ $registered = $this->get_plugins_init( $screen->id );
208
+ $recently_activate = get_option( 'yit_recently_activated', array() );
209
+
210
+ /**
211
+ * For "plugins" screen
212
+ */
213
+ $is_single_activate = ( isset( $_GET['activate'] ) && 'true' == $_GET['activate'] ) ? true : false;
214
+ $is_multi_activate = ( isset( $_GET['activate-multi'] ) && 'true' == $_GET['activate-multi'] ) ? true : false;
215
+
216
+ /**
217
+ * For "update" screen
218
+ *
219
+ * Single plugin update use GET method
220
+ *
221
+ * Multi update plugins with bulk action send two post args called "action" and "action2"
222
+ * action refer to first bulk action button (at the top of plugins table)
223
+ * action2 refer to last bulk action button (at the bottom of plugins table)
224
+ *
225
+ */
226
+ $is_single_upgrade = ( isset( $_GET['action'] ) && 'upgrade-plugin' == $_GET['action'] ) ? true : false;
227
+ $is_multi_upgrade = ( isset( $_POST['action'] ) && 'update-selected' == $_POST['action'] ) || ( isset( $_POST['action2'] ) && 'update-selected' == $_POST['action2'] ) ? true: false;
228
+
229
+ if( $is_single_activate || $is_single_upgrade ){
230
+
231
+ $point_id = '';
232
+
233
+ /**
234
+ * Single activation plugin
235
+ * Single update plugin
236
+ */
237
+ foreach( $registered as $init => $p_id ){
238
+ if ( in_array( $init, $recently_activate ) ) {
239
+ $point_id = $p_id;
240
+ $pointer = $pointers[ $point_id ];
241
+
242
+ /**
243
+ * Sanity check
244
+ */
245
+ if ( ! ( in_array( $point_id, $dismissed ) || empty( $pointer ) || empty( $point_id ) || empty( $pointer['target'] ) || empty( $pointer['options'] ) ) ) {
246
+ /**
247
+ * Add the pointer to $valid_pointers array
248
+ */
249
+ $pointer['pointer_id'] = $point_id;
250
+ $valid_pointers['pointers'][] = $pointer;
251
+ $show = true;
252
+ }
253
+ break;
254
+ }
255
+ }
256
+ } else if( $is_multi_activate || $is_multi_upgrade ){
257
+
258
+ /**
259
+ * Bulk Action: multi plugins activation
260
+ * Bulk Action: multi plugins update
261
+ */
262
+ $point_id = array();
263
+ $screen_id = $screen->id;
264
+
265
+ if( $is_multi_upgrade && isset( $_POST['checked'] ) && ( count( $_POST['checked'] ) > 0 ) ){
266
+ $recently_activate = $_POST['checked'];
267
+ $screen_id = 'update';
268
+ $pointers = apply_filters( "yit_pointers-{$screen_id}", array() );
269
+ }
270
+
271
+ foreach ( $registered as $init => $p_id ) {
272
+ if ( in_array( $init, $recently_activate ) ) {
273
+ $point_id[] = $p_id;
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Bulk Action: Activate Plugins
279
+ *
280
+ * count( $point_id ) is the number of YITH plugins that have registered specific pointers
281
+ * case 0 -> No pointers -> Exit
282
+ * case 1 -> Only one pointers to show -> Use the specific plugin pointer
283
+ * defautl -> Two or more plugins need to show a pointer -> use a generic pointers
284
+ *
285
+ */
286
+ switch ( count( $point_id ) ) {
287
+ case 0:
288
+ $show = false;
289
+ break;
290
+
291
+ case 1:
292
+ $point_id = array_pop( $point_id );
293
+ $pointer = $pointers[$point_id];
294
+ /**
295
+ * Sanity check
296
+ */
297
+ if ( ! ( in_array( $point_id, $dismissed ) || empty( $pointer ) || empty( $point_id ) || empty( $pointer['target'] ) || empty( $pointer['options'] ) ) ) {
298
+ /**
299
+ * Add the pointer to $valid_pointers array
300
+ */
301
+ $pointer['pointer_id'] = $point_id;
302
+ $valid_pointers['pointers'][] = $pointer;
303
+ $show = true;
304
+ }
305
+ break;
306
+
307
+ default:
308
+ $valid_pointers['pointers'][] = $this->_default_pointer[ $screen_id ];
309
+ $show = true;
310
+ break;
311
+ }
312
+ }
313
+
314
+ update_option( 'yit_recently_activated', array() );
315
+
316
+ if( ! $show ){
317
+ return;
318
+ }
319
+
320
+ } else {
321
+ /**
322
+ * Check pointers and remove dismissed ones.
323
+ */
324
+ foreach ( $pointers as $pointer_id => $pointer ) {
325
+
326
+ /**
327
+ * Sanity check
328
+ */
329
+ if ( in_array( $pointer_id, $dismissed ) || empty( $pointer ) || empty( $pointer_id ) || empty( $pointer['target'] ) || empty( $pointer['options'] ) ) {
330
+ continue;
331
+ }
332
+
333
+ $pointer['pointer_id'] = $pointer_id;
334
+
335
+ /**
336
+ * Add the pointer to $valid_pointers array
337
+ */
338
+ $valid_pointers['pointers'][] = $pointer;
339
+ }
340
+ }
341
+
342
+ /**
343
+ * No valid pointers? Stop here.
344
+ */
345
+ if ( empty( $valid_pointers ) ) {
346
+ return;
347
+ }
348
+
349
+ $script_file = function_exists( 'yit_load_js_file' ) ? yit_load_js_file( 'yit-wp-pointer.js' ) : 'yit-wp-pointer.min.js';
350
+
351
+ /**
352
+ * Enqueue wp-pointer script and style
353
+ */
354
+ wp_enqueue_style( 'wp-pointer' );
355
+ wp_enqueue_script( 'wp-pointer' );
356
+
357
+ wp_enqueue_script( 'yit-wp-pointer', YIT_CORE_PLUGIN_URL . '/assets/js/' . $script_file, array( 'wp-pointer' ), false, true );
358
+ wp_localize_script( 'yit-wp-pointer', 'custom_pointer', $valid_pointers );
359
+ }
360
+
361
+ public function pointers( $pointers ){
362
+ $screen_id = str_replace( 'yit_pointers-', '', current_filter() );
363
+ $pointers_to_add = $this->get_pointers( $screen_id );
364
+
365
+ return ! empty( $pointers_to_add ) ? array_merge( $pointers, $pointers_to_add ) : $pointers;
366
+ }
367
+
368
+ public function get_pointers( $screen_id ){
369
+ return isset( $this->pointers[ $screen_id ] ) ? $this->pointers[ $screen_id ] : array();
370
+ }
371
+ }
372
+ }
373
+
374
+ if ( ! function_exists( 'YIT_Pointers' ) ) {
375
+ /**
376
+ * Main instance of plugin
377
+ *
378
+ * @return object YIT_Pointers
379
+ * @since 1.0
380
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
381
+ */
382
+ function YIT_Pointers() {
383
+ return YIT_Pointers::instance();
384
+ }
385
+ }
386
+
387
+ /**
388
+ * Instance a YIT_Pointers object
389
+ */
390
+ YIT_Pointers();
plugin-fw/lib/yit-upgrade.php ADDED
@@ -0,0 +1,539 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+ if ( ! class_exists( 'YIT_Upgrade' ) ) {
15
+ /**
16
+ * YIT Upgrade
17
+ *
18
+ * Notify and Update plugin
19
+ *
20
+ * @class YIT_Upgrade
21
+ * @package Yithemes
22
+ * @since 1.0
23
+ * @author Your Inspiration Themes
24
+ * @see WP_Updater Class
25
+ */
26
+
27
+ class YIT_Upgrade {
28
+
29
+ /**
30
+ * @var string XML notifier update
31
+ */
32
+ protected $_xml = 'http://update.yithemes.com/plugins/%plugin_slug%.xml';
33
+
34
+ /**
35
+ * @var string api server url
36
+ */
37
+ protected $_package_url = 'http://www.yithemes.com';
38
+
39
+ /**
40
+ * @var array The registered plugins
41
+ */
42
+ protected $_plugins = array();
43
+
44
+ /**
45
+ * @var YIT_Upgrade The main instance
46
+ */
47
+ protected static $_instance;
48
+
49
+ /**
50
+ * Construct
51
+ *
52
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
53
+ * @since 1.0
54
+ */
55
+ public function __construct() {
56
+ add_filter( 'upgrader_pre_download', array( $this, 'upgrader_pre_download') , 10, 3 );
57
+ add_filter( 'http_request_host_is_external', '__return_true' );
58
+ add_action( 'update-custom_upgrade-plugin-multisite', array( $this, 'upgrade_plugin_multisite' ) );
59
+
60
+ if( is_network_admin() ){
61
+ add_action( 'admin_enqueue_scripts', array( $this, 'network_admin_enqueue_scripts' ) );
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Main plugin Instance
67
+ *
68
+ * @param $plugin_slug | string The plugin slug
69
+ * @param $plugin_init | string The plugin init file
70
+ *
71
+ * @return void
72
+ *
73
+ * @since 1.0
74
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
75
+ */
76
+ public function register( $plugin_slug, $plugin_init ) {
77
+
78
+ if( ! function_exists( 'get_plugins' ) ){
79
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
80
+ }
81
+
82
+ $plugins = get_plugins();
83
+ $plugin_info = $plugins[ $plugin_init ];
84
+
85
+ $this->_plugins[ $plugin_init ] = array(
86
+ 'info' => $plugin_info,
87
+ 'slug' => $plugin_slug,
88
+ );
89
+
90
+ /* === HOOKS === */
91
+ if( ! is_multisite() || is_plugin_active_for_network( $plugin_init ) ){
92
+ add_action( 'admin_init', array( $this, 'remove_wp_plugin_update_row' ), 15 );
93
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
94
+ } else if( is_multisite() && current_user_can( 'update_plugins' ) ) {
95
+ $xml = str_replace( '%plugin_slug%', $plugin_slug, $this->_xml );
96
+ $remote_xml = wp_remote_get( $xml );
97
+
98
+ if( ! is_wp_error( $remote_xml ) && isset( $remote_xml['response']['code'] ) && '200' == $remote_xml['response']['code'] ) {
99
+ $plugin_remote_info = new SimpleXmlElement( $remote_xml['body'] );
100
+ $this->_plugins[ $plugin_init ]['info']['Latest'] = (string) $plugin_remote_info->latest;
101
+ $this->_plugins[ $plugin_init ]['info']['changelog'] = (string) $plugin_remote_info->changelog;
102
+ add_action( 'admin_enqueue_scripts', array( $this, 'multisite_updater_script' ) );
103
+ }
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Add the multisite updater scripts
109
+ *
110
+ * @return void
111
+ *
112
+ * @since 1.0
113
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
114
+ */
115
+ public function multisite_updater_script(){
116
+
117
+ $update_url = array();
118
+ $changelogs = array();
119
+ $strings = array(
120
+ 'new_version' => __( 'There is a new version of %plugin_name% available.', 'yit' ),
121
+ 'latest' => __( 'View version %latest% details.', 'yit' ),
122
+ 'unavailable' => __( 'Automatic update is unavailable for this plugin,', 'yit' ),
123
+ 'activate' => __( 'please <a href="%activate_link%"> activate </a> your copy of %plugin_name%.', 'yit' ),
124
+ 'update_now' => __( 'Update now.', 'yit' )
125
+
126
+ );
127
+
128
+ foreach( $this->_plugins as $init => $info ){
129
+ YIT_Plugin_Licence()->check( $init );
130
+
131
+ $update_url[ $init ] = wp_nonce_url( self_admin_url('update.php?action=upgrade-plugin-multisite&plugin=') . $init, 'upgrade-plugin-multisite_' . $init );
132
+ $changelog_id = str_replace( array( '/', '.php', '.' ), array( '-', '', '-' ), $init );
133
+ $details_url[ $init ] = '#TB_inline' . add_query_arg( array( 'width' => 722, 'height' => 914, 'inlineId' => $changelog_id ) , '' );
134
+ $changelogs[ $init ] = $this->in_theme_update_message( $this->_plugins[ $init ], $this->_plugins[ $init ]['info']['changelog'], $changelog_id, false );
135
+ }
136
+
137
+ $localize_script_args = array(
138
+ 'registered' => $this->_plugins,
139
+ 'activated' => YIT_Plugin_Licence()->get_activated_products(),
140
+ 'licence_activation_url' => YIT_Plugin_Licence()->get_licence_activation_page_url(),
141
+ 'update_url' => $update_url,
142
+ 'details_url' => $details_url,
143
+ 'strings' => $strings,
144
+ 'changelogs' => $changelogs
145
+ );
146
+
147
+ yit_enqueue_script( 'yit-multisite-updater', YIT_CORE_PLUGIN_URL . '/assets/js/multisite-updater.min.js', array( 'jquery' ), false, true );
148
+
149
+ wp_localize_script( 'yit-multisite-updater', 'plugins', $localize_script_args );
150
+ }
151
+
152
+ public function network_admin_enqueue_scripts(){
153
+ yit_enqueue_style( 'yit-upgrader', YIT_CORE_PLUGIN_URL . '/assets/css/yit-upgrader.css' );
154
+ }
155
+
156
+ /**
157
+ * Call the protected method _upgrader_pre_download to retrive the zip package file
158
+ *
159
+ * @param bool $reply Whether to bail without returning the package. Default false.
160
+ * @param string $package The package file name.
161
+ * @param \WP_Upgrader $upgrader WP_Upgrader instance.
162
+ *
163
+ * @return string | The download file
164
+ *
165
+ * @since 1.0
166
+ * @see wp-admin/includes/class-wp-upgrader.php
167
+ * @access public
168
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
169
+ */
170
+ public function upgrader_pre_download( $reply, $package, $upgrader ){
171
+ return $this->_upgrader_pre_download( $reply, $package, $upgrader );
172
+ }
173
+
174
+ /**
175
+ * Retrive the zip package file
176
+ *
177
+ * @param bool $reply Whether to bail without returning the package. Default false.
178
+ * @param string $package The package file name.
179
+ * @param \WP_Upgrader $upgrader WP_Upgrader instance.
180
+ *
181
+ * @return string | The download file
182
+ *
183
+ * @since 1.0
184
+ * @see wp-admin/includes/class-wp-upgrader.php
185
+ * @access protected
186
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
187
+ */
188
+ protected function _upgrader_pre_download( $reply, $package, $upgrader ) {
189
+
190
+ /**
191
+ * It isn't YITH Premium plugins, please wordpress update it for me!
192
+ */
193
+ if( ! isset( $upgrader->skin->plugin ) ) {
194
+ return $reply;
195
+ }
196
+
197
+ $plugin_info = YIT_Plugin_Licence()->get_product( $upgrader->skin->plugin );
198
+
199
+ /**
200
+ * False ? It isn't YITH Premium plugins, please wordpress update it for me!
201
+ */
202
+ if( false === $plugin_info ) {
203
+ return $reply;
204
+ }
205
+
206
+ $licence = YIT_Plugin_Licence()->get_licence();
207
+ $product_id = $plugin_info['product_id'];
208
+ $args = array(
209
+ 'email' => $licence[ $product_id ]['email'],
210
+ 'licence_key' => $licence[$product_id]['licence_key'],
211
+ 'product_id' => $plugin_info['product_id'],
212
+ 'secret_key' => $plugin_info['secret_key'],
213
+ 'instance' => YIT_Plugin_Licence()->get_home_url(),
214
+ 'wc-api' => 'download-api',
215
+ 'request' => 'download'
216
+ );
217
+
218
+ if ( ! preg_match( '!^(http|https|ftp)://!i', $package ) && file_exists( $package ) ) {
219
+ //Local file or remote?
220
+ return $package;
221
+ }
222
+
223
+ if ( empty( $package ) ) {
224
+ return new WP_Error( 'no_package', $upgrader->strings['no_package'] );
225
+ }
226
+
227
+ $upgrader->skin->feedback( 'downloading_package', __( 'Yithemes Repository', 'yit' ) );
228
+
229
+ $download_file = $this->_download_url( $package, $args );
230
+
231
+ /**
232
+ * Regenerate update_plugins transient
233
+ */
234
+ $this->force_regenerate_update_transient();
235
+
236
+ if ( is_wp_error( $download_file ) ) {
237
+ return new WP_Error( 'download_failed', $upgrader->strings['download_failed'], $download_file->get_error_message() );
238
+ }
239
+
240
+ return $download_file;
241
+ }
242
+
243
+ /**
244
+ * Retrive the temp filename
245
+ *
246
+ * @param string $url The package url
247
+ * @param string $body The post data fields
248
+ * @param int $timeout Execution timeout (default: 300)
249
+ *
250
+ * @return string | The temp filename
251
+ *
252
+ * @since 1.0
253
+ * @see wp-admin/includes/class-wp-upgrader.php
254
+ * @access protected
255
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
256
+ */
257
+ protected function _download_url( $url, $body, $timeout = 300 ) {
258
+
259
+ //WARNING: The file is not automatically deleted, The script must unlink() the file.
260
+ if ( ! $url ) {
261
+ return new WP_Error( 'http_no_url', __( 'Invalid URL Provided.' ) );
262
+ }
263
+
264
+ $tmpfname = wp_tempnam( $url );
265
+
266
+ $args = array(
267
+ 'timeout' => $timeout,
268
+ 'stream' => true,
269
+ 'filename' => $tmpfname,
270
+ 'body' => $body
271
+ );
272
+
273
+ if ( ! $tmpfname ) {
274
+ return new WP_Error( 'http_no_file', __( 'Could not create Temporary file.' ) );
275
+ }
276
+
277
+ $response = wp_safe_remote_post( $url, $args );
278
+
279
+ if ( is_wp_error( $response ) ) {
280
+ unlink( $tmpfname );
281
+ return $response;
282
+ }
283
+
284
+ if ( 200 != wp_remote_retrieve_response_code( $response ) ) {
285
+ unlink( $tmpfname );
286
+ return new WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ) );
287
+ }
288
+
289
+ $content_md5 = wp_remote_retrieve_header( $response, 'content-md5' );
290
+
291
+ if ( $content_md5 ) {
292
+ $md5_check = verify_file_md5( $tmpfname, $content_md5 );
293
+ if ( is_wp_error( $md5_check ) ) {
294
+ unlink( $tmpfname );
295
+ return $md5_check;
296
+ }
297
+ }
298
+
299
+ return $tmpfname;
300
+ }
301
+
302
+ /**
303
+ * Main plugin Instance
304
+ *
305
+ * @static
306
+ * @return object Main instance
307
+ *
308
+ * @since 1.0
309
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
310
+ */
311
+ public static function instance() {
312
+ if ( is_null( self::$_instance ) ) {
313
+ self::$_instance = new self();
314
+ }
315
+
316
+ return self::$_instance;
317
+ }
318
+
319
+ /**
320
+ * Delete the update plugins transient
321
+ *
322
+ * @return void
323
+ *
324
+ * @since 1.0
325
+ * @see update_plugins transient and pre_set_site_transient_update_plugins hooks
326
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
327
+ */
328
+ public function force_regenerate_update_transient(){
329
+ delete_site_transient( 'update_plugins' );
330
+ }
331
+
332
+ /**
333
+ * Check for plugins update
334
+ *
335
+ * If a new plugin version is available set it in the pre_set_site_transient_update_plugins hooks
336
+ *
337
+ * @param mixed $transient | update_plugins transient value
338
+ * @param bool $save | Default: false. Set true to regenerate the update_transient plugins
339
+ *
340
+ * @return mixed $transient | The new update_plugins transient value
341
+ *
342
+ * @since 1.0
343
+ * @see update_plugins transient and pre_set_site_transient_update_plugins hooks
344
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
345
+ */
346
+ public function check_update( $transient, $save = false ) {
347
+
348
+ foreach ($this->_plugins as $init => $plugin) {
349
+ $xml = str_replace('%plugin_slug%', $this->_plugins[$init]['slug'], $this->_xml);
350
+ $remote_xml = wp_remote_get($xml);
351
+
352
+ if (!is_wp_error($remote_xml) && isset($remote_xml['response']['code']) && '200' == $remote_xml['response']['code']) {
353
+
354
+
355
+ $plugin_remote_info = new SimpleXmlElement($remote_xml['body']);
356
+
357
+ if (version_compare($plugin_remote_info->latest, $plugin['info']['Version'], '>') && !isset($transient->response[$init])) {
358
+
359
+ $package = YIT_Plugin_Licence()->check($init) ? $this->_package_url : null;
360
+
361
+ $obj = new stdClass();
362
+ $obj->slug = (string)$init;
363
+ $obj->new_version = (string)$plugin_remote_info->latest;
364
+ $obj->changelog = (string)$plugin_remote_info->changelog;
365
+ $obj->package = $package;
366
+ $transient->response[$init] = $obj;
367
+ }
368
+
369
+ }
370
+ }
371
+
372
+ if( $save ) {
373
+ set_site_transient( 'update_plugins', $transient );
374
+ }
375
+
376
+ return $transient;
377
+ }
378
+
379
+ /**
380
+ * Add the plugin update row in plugin page
381
+ *
382
+ * @return void
383
+ * @fire "in_theme_update_message-{$init}" action
384
+ *
385
+ * @since 1.0
386
+ * @see after_plugin_row_{$init} action
387
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
388
+ */
389
+ public function plugin_update_row() {
390
+
391
+ $current = get_site_transient( 'update_plugins' );
392
+ $init = str_replace( 'after_plugin_row_', '', current_filter() );
393
+
394
+ if ( ! isset( $current->response[ $init ] ) ) {
395
+ return false;
396
+ }
397
+
398
+ /**
399
+ * stdClass Object
400
+ */
401
+ $r = $current->response[ $init ];
402
+
403
+ $changelog_id = str_replace( array( '/', '.php', '.' ), array( '-', '', '-' ), $init );
404
+ $details_url = '#TB_inline' . add_query_arg( array( 'width' => 722, 'height' => 914, 'inlineId' => $changelog_id ) , '' );
405
+
406
+ /**
407
+ * @see wp_plugin_update_rows() in wp-single\wp-admin\includes\update.php
408
+ */
409
+ $wp_list_table = _get_list_table( 'WP_MS_Themes_List_Table' );
410
+
411
+ if( is_network_admin() || ! is_multisite() || true ) {
412
+ echo '<tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange"><div class="update-message">';
413
+
414
+ if( ! current_user_can( 'update_plugins' ) ){
415
+ printf( __('There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button" title="%3$s">View version %4$s details</a>.', 'yit'), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version );
416
+ }elseif( is_plugin_active_for_network( $init ) ){
417
+ printf( __( 'There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button" title="%3$s">View version %4$s details</a>. <em>You have to activate the plugin on a single site of the network to benefit from the automatic updates.</em>', 'yit' ), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version );
418
+ }elseif ( empty( $r->package ) ) {
419
+ printf( __( 'There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button" title="%3$s">View version %4$s details</a>. <em>Automatic update is unavailable for this plugin, please <a href="%5$s" title="Licence activation">activate</a> your copy of %6s.</em>', 'yit' ), $this->_plugins[ $init ]['info']['Name'], esc_url( $details_url ), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version, YIT_Plugin_Licence()->get_licence_activation_page_url(), $this->_plugins[ $init ]['info']['Name'] );
420
+ } else {
421
+ printf( __('There is a new version of %1$s available. <a href="%2$s" class="thickbox yit-changelog-button" title="%3$s">View version %4$s details</a> or <a href="%5$s">update now</a>.', 'yit'), $this->_plugins[ $init ]['info']['Name'], esc_url($details_url), esc_attr( $this->_plugins[ $init ]['info']['Name'] ), $r->new_version, wp_nonce_url( self_admin_url('update.php?action=upgrade-plugin&plugin=') . $init, 'upgrade-plugin_' . $init ) );
422
+ }
423
+
424
+ /**
425
+ * Fires at the end of the update message container in each
426
+ * row of the themes list table.
427
+ *
428
+ * The dynamic portion of the hook name, `$theme_key`, refers to
429
+ * the theme slug as found in the WordPress.org themes repository.
430
+ *
431
+ * @since Wordpress 3.1.0
432
+ * }
433
+ */
434
+ do_action( "in_theme_update_message-{$init}", $this->_plugins[ $init ], $r->changelog, $changelog_id );
435
+
436
+ echo '</div></td></tr>';
437
+ }
438
+ }
439
+
440
+ /**
441
+ * Remove the standard plugin_update_row
442
+ *
443
+ * Remove the standard plugin_update_row and Add a custom plugin update row in plugin page.
444
+ *
445
+ * @return void
446
+ * @fire "in_theme_update_message-{$init}" action
447
+ *
448
+ * @since 1.0
449
+ * @see after_plugin_row_{$init} action
450
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
451
+ */
452
+ public function remove_wp_plugin_update_row() {
453
+ foreach( $this->_plugins as $init => $plugin ){
454
+ remove_action( "after_plugin_row_{$init}", 'wp_plugin_update_row', 10, 2 );
455
+ add_action( "after_plugin_row_{$init}", array( $this, 'plugin_update_row' ) );
456
+ add_action( "in_theme_update_message-{$init}", array( $this, 'in_theme_update_message' ), 10, 3 );
457
+ }
458
+ }
459
+
460
+ public function in_theme_update_message( $plugin, $changelog, $changelog_id, $echo = true ){
461
+
462
+ $res = "<div id='{$changelog_id}' class='yit-plugin-changelog-wrapper'>
463
+ <div class='yit-plugin-changelog'>
464
+ <h2 class='yit-plugin-changelog-title'>{$plugin['info']['Name']} - Changelog</h2>
465
+ <p>{$changelog}</p>
466
+ </div>
467
+ </div>";
468
+
469
+ if( $echo ){
470
+ echo $res;
471
+ }
472
+ else{
473
+ return $res;
474
+ }
475
+ }
476
+
477
+ /**
478
+ * Auto-Update Plugin in multisite
479
+ *
480
+ * Manage the non standard upgrade-plugin-multisite action
481
+ *
482
+ * @return void
483
+ *
484
+ * @since 1.0
485
+ * @see upgrade-plugin action
486
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
487
+ */
488
+ public function upgrade_plugin_multisite(){
489
+
490
+ $plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
491
+ $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : '';
492
+
493
+ if( 'upgrade-plugin-multisite' != $action ){
494
+ wp_die( __( 'You can\'t update plugins for this site.', 'yit' ) );
495
+ }
496
+
497
+ if ( ! current_user_can( 'update_plugins' ) ) {
498
+ wp_die( __( 'You do not have sufficient permissions to update plugins for this site.', 'yit' ) );
499
+ }
500
+
501
+ $this->check_update( get_site_transient( 'update_plugins') , true );
502
+
503
+ check_admin_referer( 'upgrade-plugin-multisite_' . $plugin );
504
+
505
+ $title = __( 'Update Plugin' );
506
+ $parent_file = 'plugins.php';
507
+ $submenu_file = 'plugins.php';
508
+
509
+ wp_enqueue_script( 'updates' );
510
+ require_once( ABSPATH . 'wp-admin/admin-header.php' );
511
+
512
+ $nonce = 'upgrade-plugin-multisite_' . $plugin;
513
+ $url = 'update.php?action=upgrade-plugin-multisite&plugin=' . urlencode( $plugin );
514
+
515
+ $upgrader = new Plugin_Upgrader( new Plugin_Upgrader_Skin( compact( 'title', 'nonce', 'url', 'plugin' ) ) );
516
+ $upgrader->upgrade( $plugin );
517
+
518
+ include( ABSPATH . 'wp-admin/admin-footer.php' );
519
+ }
520
+ }
521
+ }
522
+
523
+ if ( ! function_exists( 'YIT_Upgrade' ) ) {
524
+ /**
525
+ * Main instance of plugin
526
+ *
527
+ * @return object
528
+ * @since 1.0
529
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
530
+ */
531
+ function YIT_Upgrade() {
532
+ return YIT_Upgrade::instance();
533
+ }
534
+ }
535
+
536
+ /**
537
+ * Instance a YIT_Upgrade object
538
+ */
539
+ YIT_Upgrade();
plugin-fw/lib/yit-video.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ } // Exit if accessed directly
15
+
16
+ if ( ! class_exists( 'YIT_Video' ) ) {
17
+ /**
18
+ * YIT Video
19
+ *
20
+ * Class to manage the video from youtube and vimeo or other services
21
+ *
22
+ * @class YIT_Video
23
+ * @package Yithemes
24
+ * @since 1.0.0
25
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
26
+ *
27
+ */
28
+
29
+ class YIT_Video {
30
+
31
+ /**
32
+ * Generate the HTML for a youtube video
33
+ *
34
+ * @static
35
+ *
36
+ * @param array $args Array of arguments to configure the video to generate
37
+ *
38
+ * @return string
39
+ * @since 1.0
40
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
41
+ */
42
+ public static function youtube( $args = array() ) {
43
+ $defaults = array(
44
+ 'id' => '',
45
+ 'url' => '',
46
+ 'width' => 425,
47
+ 'height' => 356,
48
+ 'echo' => false
49
+ );
50
+ $args = wp_parse_args( $args, $defaults );
51
+ extract( $args );
52
+
53
+ // get video ID if you have only URL
54
+ if ( empty( $id ) && ! empty( $url ) ) {
55
+ $id = self::video_id_by_url( $url );
56
+ } elseif ( empty( $id ) && empty( $url ) ) {
57
+ return;
58
+ }
59
+
60
+ if( ! $echo ) ob_start();
61
+
62
+ $id = preg_replace( '/[&|&amp;]feature=([\w\-]*)/', '', $id ); ?>
63
+
64
+ <div class="post_video youtube">
65
+ <iframe wmode="transparent" width="<?php echo $width; ?>" height="<?php echo $height; ?>" src="http://www.youtube.com/embed/<?php echo $id; ?>?wmode=transparent" frameborder="0" allowfullscreen></iframe>
66
+ </div>
67
+
68
+ <?php
69
+ if( ! $echo ) return ob_get_clean();
70
+ }
71
+
72
+ /**
73
+ * Generate the HTML for a vimeo video
74
+ *
75
+ * @static
76
+ *
77
+ * @param array $args Array of arguments to configure the video to generate
78
+ *
79
+ * @return string
80
+ * @since 1.0
81
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
82
+ */
83
+ public static function vimeo( $args = array() ) {
84
+ $defaults = array(
85
+ 'id' => '',
86
+ 'url' => '',
87
+ 'width' => 425,
88
+ 'height' => 356,
89
+ 'echo' => false
90
+ );
91
+ $args = wp_parse_args( $args, $defaults );
92
+ extract( $args );
93
+
94
+ // get video ID if you have only URL
95
+ if ( empty( $id ) && ! empty( $url ) ) {
96
+ $id = self::video_id_by_url( $url );
97
+ }
98
+
99
+ if( ! $echo ) ob_start();
100
+
101
+ $id = preg_replace( '/[&|&amp;]feature=([\w\-]*)/', '', $id ) ?>
102
+
103
+ <div class="post_video vimeo">
104
+ <iframe wmode="transparent" src="http://player.vimeo.com/video/<?php echo $id; ?>?title=0&amp;byline=0&amp;portrait=0" width="<?php echo $width; ?>" height="<?php echo $height; ?>" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
105
+ </div>
106
+
107
+ <?php
108
+ if( ! $echo ) return ob_get_clean();
109
+ }
110
+
111
+ /**
112
+ * Retrieve video ID from URL
113
+ *
114
+ * @static
115
+ *
116
+ * @param array $url The URL of video
117
+ *
118
+ * @return bool|string
119
+ * @since 1.0
120
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
121
+ */
122
+ public static function video_id_by_url( $url ) {
123
+ $parsed = parse_url( esc_url( $url ) );
124
+
125
+ switch ( $parsed['host'] ) {
126
+
127
+ case 'www.youtube.com' :
128
+ case 'youtu.be' :
129
+ $id = self::youtube_id_by_url( $url );
130
+ return "youtube:$id";
131
+
132
+ case 'vimeo.com' :
133
+ preg_match( '/http:\/\/(\w+.)?vimeo\.com\/(.*)/', $url, $matches );
134
+ $id = $matches[2];
135
+ return "vimeo:$id";
136
+
137
+ default :
138
+ return false;
139
+
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Retrieve video ID from URL
145
+ *
146
+ * @static
147
+ *
148
+ * @param array $url The URL of video
149
+ *
150
+ * @return bool|string
151
+ * @since 1.0
152
+ * @author Antonino Scarfi' <antonino.scarfi@yithemes.com>
153
+ */
154
+ protected static function youtube_id_by_url( $url ) {
155
+ if ( preg_match( '/http:\/\/youtu.be/', $url, $matches) ) {
156
+ $url = parse_url($url, PHP_URL_PATH);
157
+ $url = str_replace( '/', '', $url);
158
+ return $url;
159
+
160
+ } elseif ( preg_match( '/watch/', $url, $matches) ) {
161
+ $arr = parse_url($url);
162
+ $url = str_replace( 'v=', '', $arr['query'] );
163
+ return $url;
164
+
165
+ } elseif ( preg_match( '/http:\/\/www.youtube.com\/v/', $url, $matches) ) {
166
+ $arr = parse_url($url);
167
+ $url = str_replace( '/v/', '', $arr['path'] );
168
+ return $url;
169
+
170
+ } elseif ( preg_match( '/http:\/\/www.youtube.com\/embed/', $url, $matches) ) {
171
+ $arr = parse_url($url);
172
+ $url = str_replace( '/embed/', '', $arr['path'] );
173
+ return $url;
174
+
175
+ } elseif ( preg_match("#(?<=v=)[a-zA-Z0-9-]+(?=&)|(?<=[0-9]/)[^&\n]+|(?<=v=)[^&\n]+#", $url, $matches) ) {
176
+ return $matches[0];
177
+
178
+ } else {
179
+ return false;
180
+ }
181
+ }
182
+
183
+ }
184
+ }
plugin-fw/licence/assets/css/yit-licence.css ADDED
@@ -0,0 +1,337 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* === Plugins Upgrader === */
2
+
3
+ .yit-plugin-changelog-wrapper {
4
+ display: none;
5
+ }
6
+
7
+ .yit-plugin-changelog-title {
8
+ text-transform: uppercase;
9
+ }
10
+
11
+ .yit-plugin-changelog {
12
+ background: #fcfcfc;
13
+ height: 97%;
14
+ z-index: 999;
15
+ overflow: auto;
16
+ }
17
+
18
+ /* === Plugins Licence Activation === */
19
+
20
+ .yit-container.product-licence-activation {
21
+ font-family: 'Raleway', sans-serif;
22
+ }
23
+
24
+ .yit-container.product-licence-activation .to-active-wrapper {
25
+ margin-bottom: 60px;
26
+ }
27
+
28
+ .yit-container.product-licence-activation .to-active-wrapper form.to-active-form {
29
+ position: relative;
30
+ border-color: #e1e1e1;
31
+ border-style: solid;
32
+ border-width: 0;
33
+ }
34
+
35
+ .yit-container.product-licence-activation .to-active-wrapper form.to-active-form:first-child {
36
+ border-top-width: 1px;
37
+ }
38
+
39
+ .yit-container.product-licence-activation .to-active-wrapper form.to-active-form:last-child {
40
+ border-bottom-width: 1px;
41
+ }
42
+
43
+ .yit-container.product-licence-activation .to-active-wrapper table.to-active-table {
44
+ border-width: 0;
45
+ border-spacing: 0;
46
+ width: 100%;
47
+ }
48
+
49
+ .yit-container.product-licence-activation .message {
50
+ display: none;
51
+ line-height: normal;
52
+ background: #ffffff url(../images/licence-error.png) 15px center no-repeat;
53
+ padding-left: 65px;
54
+ padding-right: 15px;
55
+ width: 150px;
56
+ }
57
+
58
+ .yit-container.product-licence-activation .message-wrapper {
59
+ height: 75px;
60
+ display: none;
61
+ position: absolute;
62
+ top: 0;
63
+ right: -250px;
64
+ border: 1px solid #ff3838;
65
+ }
66
+
67
+ .yit-container.product-licence-activation .message-wrapper.visible {
68
+ display: table;
69
+ }
70
+
71
+ .yit-container.product-licence-activation .message {
72
+ display: table-cell;
73
+ vertical-align: middle;
74
+ }
75
+
76
+ .yit-container.product-licence-activation .arrow-left:after,
77
+ .yit-container.product-licence-activation .arrow-left:before {
78
+ content: "";
79
+ display: block;
80
+ width: 0;
81
+ height: 0;
82
+ position: absolute;
83
+ }
84
+
85
+ .yit-container.product-licence-activation .arrow-left:before {
86
+ border-top: 9px solid transparent;
87
+ border-bottom: 9px solid transparent;
88
+ border-right: 9px solid #ff3838;
89
+ top: 26px;
90
+ left: -9px;
91
+ }
92
+
93
+ .yit-container.product-licence-activation .arrow-left:after {
94
+ border-top: 8px solid transparent;
95
+ border-bottom: 8px solid transparent;
96
+ border-right: 8px solid #fff;
97
+ left: -8px;
98
+ top: 27px;
99
+ }
100
+
101
+ .yit-container.product-licence-activation h2,
102
+ .yit-container.product-licence-activation h3 {
103
+ text-transform: uppercase;
104
+ font-weight: 800;
105
+ margin-bottom: 30px;
106
+ }
107
+
108
+ .yit-container.product-licence-activation h2 {
109
+ color: #808a97;
110
+ font-size: 25px;
111
+ }
112
+ .yit-container.product-licence-activation h3 {
113
+ color: #313131;
114
+ font-size: 15px;
115
+ height: 20px;
116
+ }
117
+
118
+ .yit-container.product-licence-activation h3.to-active {
119
+ height: 20px;
120
+ position: relative;
121
+ vertical-align: top;
122
+ }
123
+
124
+ .yit-container.product-licence-activation .spinner.show{
125
+ display: inline-block;
126
+ vertical-align: middle;
127
+ float: none;
128
+ }
129
+
130
+ .yit-container.product-licence-activation h3.to-active > .spinner.show {
131
+ display: inline-block;
132
+ float: none;
133
+ top: -3px;
134
+ position: relative;
135
+ }
136
+
137
+ .yit-container.product-licence-activation .licence-check-section{
138
+ margin-bottom: 60px;
139
+ }
140
+
141
+ .yit-container.product-licence-activation span.licence-label {
142
+ font-weight: 500;
143
+ color: #606060;
144
+ margin-bottom: 30px;
145
+ }
146
+
147
+ .yit-container.product-licence-activation .button-licence {
148
+ border: 0;
149
+ font-size: 13px;
150
+ text-transform: uppercase;
151
+ background-color: #808a97;
152
+ color: #fff;
153
+ font-weight: 700;
154
+ border-radius: 3px;
155
+ cursor: pointer;
156
+ text-decoration: none;
157
+ padding: 5px 7px;
158
+ -webkit-transition: background-color 0.3s ease;
159
+ -moz-transition: background-color 0.3s ease;
160
+ -ms-transition: background-color 0.3s ease;
161
+ -o-transition: background-color 0.3s ease;
162
+ transition: background-color 0.3s ease;
163
+ }
164
+
165
+ .yit-container.product-licence-activation .button-licence:hover {
166
+ background-color: #4d5c6f;
167
+ }
168
+
169
+ .yit-container.product-licence-activation .button-licence.clicked {
170
+ cursor: not-allowed;
171
+ background-color: #e2e2e2 !important;
172
+ }
173
+
174
+ .yit-container.product-licence-activation .button-licence.licence-check {
175
+ font-weight: 400;
176
+ padding: 12px 19px;
177
+ }
178
+
179
+ .yit-container.product-licence-activation .button-licence.licence-renew {
180
+ text-decoration: none;
181
+ padding: 7px 12px;
182
+ font-size: 9px;
183
+ }
184
+
185
+ .yit-container.product-licence-activation .button-licence.licence-renew:focus {
186
+ box-shadow: none;
187
+ }
188
+
189
+ .yit-container.product-licence-activation table:not(.to-active-table) {
190
+ width: 100%;
191
+ border: 1px solid #dcdcdc;
192
+ border-spacing: 0;
193
+ border-radius: 5px;
194
+ border-collapse: separate;
195
+ overflow: hidden;
196
+ }
197
+
198
+ .yit-container.product-licence-activation table:not(.to-active-table) th {
199
+ border-bottom: 1px solid #dcdcdc;
200
+ }
201
+
202
+ .yit-container.product-licence-activation table:not(.to-active-table) td,
203
+ .yit-container.product-licence-activation table:not(.to-active-table) th {
204
+ border-right: 1px solid #dcdcdc;
205
+ }
206
+ .yit-container.product-licence-activation table td:last-child,
207
+ .yit-container.product-licence-activation table th:last-child {
208
+ border-right: 0;
209
+ }
210
+
211
+ .yit-container.product-licence-activation table thead tr {
212
+ background-color: #f6f4f4;
213
+ }
214
+
215
+ .yit-container.product-licence-activation table tbody tr {
216
+ background-color: #ffffff;
217
+ }
218
+
219
+ .yit-container.product-licence-activation table thead tr th {
220
+ font-size: 13px;
221
+ color: #313131;
222
+ text-transform: uppercase;
223
+ font-weight: bold;
224
+ }
225
+
226
+ .yit-container.product-licence-activation table thead tr,
227
+ .yit-container.product-licence-activation table tbody tr {
228
+ line-height: 60px;
229
+ }
230
+
231
+ .yit-container.product-licence-activation table tbody tr td{
232
+ text-align: center;
233
+ line-height: 20px;
234
+ padding: 10px 5px;
235
+ }
236
+
237
+ .yit-container.product-licence-activation .button-licence.licence-activation {
238
+ padding: 12px 18px;
239
+ }
240
+
241
+ .yit-container.product-licence-activation .to-active-table tr {
242
+ line-height: 75px;
243
+ }
244
+
245
+ .yit-container.product-licence-activation .to-active-table tr.product-row {
246
+ background-color: transparent;
247
+ -webkit-transition: all 0.3s ease;
248
+ -moz-transition: all 0.3s ease;
249
+ -ms-transition: all 0.3s ease;
250
+ -o-transition: all 0.3s ease;
251
+ transition: all 0.3s ease;
252
+ }
253
+
254
+ .yit-container.product-licence-activation .to-active-table tr.product-row.error {
255
+ background-color: #ffdcdc;
256
+ }
257
+
258
+ .yit-container.product-licence-activation .to-active-table td {
259
+ padding-right: 12px;
260
+ width: 33%;
261
+ }
262
+
263
+
264
+ .yit-container.product-licence-activation .to-active-table td.product-name {
265
+ color: #808a97;
266
+ font-size: 12px;
267
+ text-transform: uppercase;
268
+ font-weight: bold;
269
+ line-height: 20px;
270
+ width: 20%;
271
+ padding-left: 20px;
272
+ }
273
+
274
+ .yit-container.product-licence-activation .to-active-table td.activate-button {
275
+ width: 15%;
276
+ position: relative;
277
+ }
278
+
279
+ .yit-container.product-licence-activation input[type=text],
280
+ .yit-container.product-licence-activation input[type=email]{
281
+ -webkit-transition: all 0.3s ease;
282
+ -moz-transition: all 0.3s ease;
283
+ -ms-transition: all 0.3s ease;
284
+ -o-transition: all 0.3s ease;
285
+ transition: all 0.3s ease;
286
+
287
+ border: 1px solid #dcdcdc;
288
+ padding: 0 15px;
289
+ border-radius: 3px;
290
+ height: 41px;
291
+ width: 100%;
292
+ }
293
+
294
+ .yit-container.product-licence-activation input[type=text].require,
295
+ .yit-container.product-licence-activation input[type=email].require {
296
+ border: 1px solid #ff3838;
297
+ }
298
+
299
+ .yit-container.product-licence-activation input[type=text]:focus,
300
+ .yit-container.product-licence-activation input[type=email]:focus{
301
+ webkit-box-shadow: 0 0 1px rgba(30,140,190,.8);
302
+ box-shadow: 0 0 1px rgba(30,140,190,.8);
303
+ }
304
+
305
+ .yit-container.product-licence-activation input[type=text]{
306
+ text-transform: uppercase;
307
+ text-align: center;
308
+ }
309
+
310
+ .yit-container.product-licence-activation input[type=email] {
311
+ text-align: left;
312
+ }
313
+
314
+ .yit-container.product-licence-activation input[type=submit]:focus{
315
+ outline: 0;
316
+ }
317
+
318
+ /* === Responsive === */
319
+
320
+ @media (max-width: 767px) {}
321
+
322
+ @media (max-width: 480px) {}
323
+
324
+ @media (min-width: 768px) and (max-width: 992px) {}
325
+
326
+ @media (min-width: 980px) and (max-width: 1199px) {}
327
+
328
+ @media (min-width: 1200px) {
329
+ .yit-container.product-licence-activation{
330
+ width: 900px;
331
+ }
332
+ }
333
+
334
+ @media only screen and (-webkit-min-device-pixel-ratio: 1.5),
335
+ only screen and (-o-min-device-pixel-ratio: 3/2),
336
+ only screen and (min--moz-device-pixel-ratio: 1.5),
337
+ only screen and (min-device-pixel-ratio: 1.5) {}
plugin-fw/licence/assets/images/licence-error.png ADDED
Binary file
plugin-fw/licence/assets/js/yit-licence.js ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file belongs to the YIT Plugin Framework.
3
+ *
4
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
5
+ * that is bundled with this package in the file LICENSE.txt.
6
+ * It is also available through the world-wide-web at this URL:
7
+ * http://www.gnu.org/licenses/gpl-3.0.txt
8
+ */
9
+
10
+
11
+ (function ($) {
12
+
13
+ /* === Licence API === */
14
+
15
+ var licence_activation = function (button) {
16
+ button.on('click', function (e, button) {
17
+ e.preventDefault();
18
+
19
+ var t = $(this),
20
+ form_id = t.data('formid'),
21
+ form = $('#' + form_id),
22
+ data = form.serialize(),
23
+ message = $(form).find('.message'),
24
+ message_wrapper = $(form).find('.message-wrapper'),
25
+ email = form.find('.user-email'),
26
+ licence_key = form.find('.licence-key'),
27
+ email_val = form.find('.user-email').val(),
28
+ licence_key_val = form.find('.licence-key').val(),
29
+ error = false,
30
+ error_fields = new Array(),
31
+ product_row = form.find('.product-row'),
32
+ spinner = $('h3.to-active').find('.spinner');
33
+
34
+ /* Init Input Fields */
35
+ message.empty();
36
+ message_wrapper.removeClass('visible')
37
+ email.removeClass('require');
38
+ licence_key.removeClass('require');
39
+ product_row.removeClass('error');
40
+ spinner.addClass('show');
41
+ t.prop("disabled", true).addClass('clicked');
42
+
43
+ if ('' == email_val) {
44
+ error = true;
45
+ error_fields[ error_fields.length ] = 'Email';
46
+ email.addClass('require');
47
+ }
48
+
49
+ if ('' == licence_key_val) {
50
+ error = true;
51
+ error_fields[ error_fields.length ] = 'Licence Key';
52
+ licence_key.addClass('require');
53
+ }
54
+
55
+ if (false == error) {
56
+ jQuery.ajax({
57
+ type : 'POST',
58
+ url : ajaxurl,
59
+ data : data,
60
+ success: function (response) {
61
+
62
+ spinner.removeClass('show');
63
+ t.prop("disabled", false).removeClass('clicked');
64
+
65
+ if (true == response.activated) {
66
+ $('.product-licence-activation').empty().replaceWith(response.template);
67
+ licence_api();
68
+ } else if (false != response) {
69
+ message.text(response.error);
70
+ message_wrapper.addClass('visible');
71
+ product_row.addClass('error');
72
+ } else {
73
+ message.text(licence_message.server);
74
+ message_wrapper.addClass('visible');
75
+ product_row.addClass('error');
76
+ }
77
+ }
78
+ });
79
+ } else {
80
+ if (error_fields.length == 1) {
81
+ message.text(licence_message.error.replace('%field%', error_fields[0]));
82
+ message_wrapper.addClass('visible');
83
+ product_row.addClass('error');
84
+ } else {
85
+ var message_text = licence_message.errors;
86
+ for (var i = 0; i < error_fields.length; i++) {
87
+ message_text = message_text.replace('%field_' + ( i + 1) + '%', error_fields[i]);
88
+ message_wrapper.addClass('visible');
89
+ }
90
+ message.text(message_text);
91
+ message_wrapper.addClass('visible');
92
+ product_row.addClass('error');
93
+ }
94
+
95
+ spinner.removeClass('show');
96
+ t.prop("disabled", false).removeClass('clicked');
97
+ }
98
+ });
99
+ }
100
+
101
+ var licence_update = function (button) {
102
+ button.on('click', function (e) {
103
+ e.preventDefault();
104
+
105
+ var t = $(this),
106
+ form = $('#licence-check-update'),
107
+ data = form.serialize();
108
+
109
+ t.prop("disabled", true).addClass('clicked');
110
+ form.find('div.spinner').addClass('show');
111
+
112
+ jQuery.ajax({
113
+ type : 'POST',
114
+ url : ajaxurl,
115
+ data : data,
116
+ success: function (response) {
117
+ $('.product-licence-activation').empty().replaceWith(response.template);
118
+ licence_api();
119
+ }
120
+ });
121
+ });
122
+ }
123
+
124
+ var licence_api = function () {
125
+ var button = $('.licence-activation'),
126
+ check = $('.licence-check');
127
+
128
+ licence_activation(button);
129
+ licence_update(check);
130
+ }
131
+
132
+ licence_api();
133
+
134
+ $('body').on('click', '.yit-changelog-button', function (e) {
135
+ $('#TB_window').remove();
136
+
137
+ });
138
+
139
+ })(jQuery);
plugin-fw/licence/assets/js/yit-licence.min.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ (function(b){var g=function(d){d.on("click",function(u,d){u.preventDefault();var e=b(this),a=e.data("formid"),c=b("#"+a),f=c.serialize(),h=b(c).find(".message"),l=b(c).find(".message-wrapper"),r=c.find(".user-email"),t=c.find(".licence-key"),g=c.find(".user-email").val(),q=c.find(".licence-key").val(),m=!1,a=[],n=c.find(".product-row"),p=b("h3.to-active").find(".spinner");h.empty();l.removeClass("visible");r.removeClass("require");t.removeClass("require");n.removeClass("error");p.addClass("show");
2
+ e.prop("disabled",!0).addClass("clicked");""==g&&(m=!0,a[a.length]="Email",r.addClass("require"));""==q&&(m=!0,a[a.length]="Licence Key",t.addClass("require"));if(0==m)jQuery.ajax({type:"POST",url:ajaxurl,data:f,success:function(a){p.removeClass("show");e.prop("disabled",!1).removeClass("clicked");1==a.activated?(b(".product-licence-activation").empty().replaceWith(a.template),k()):(0!=a?h.text(a.error):h.text(licence_message.server),l.addClass("visible"),n.addClass("error"))}});else{if(1==a.length)h.text(licence_message.error.replace("%field%",
3
+ a[0]));else{c=licence_message.errors;for(f=0;f<a.length;f++)c=c.replace("%field_"+(f+1)+"%",a[f]),l.addClass("visible");h.text(c)}l.addClass("visible");n.addClass("error");p.removeClass("show");e.prop("disabled",!1).removeClass("clicked")}})},q=function(d){d.on("click",function(d){d.preventDefault();d=b(this);var g=b("#licence-check-update"),e=g.serialize();d.prop("disabled",!0).addClass("clicked");g.find("div.spinner").addClass("show");jQuery.ajax({type:"POST",url:ajaxurl,data:e,success:function(a){b(".product-licence-activation").empty().replaceWith(a.template);
4
+ k()}})})},k=function(){var d=b(".licence-activation"),k=b(".licence-check");g(d);q(k)};k();b("body").on("click",".yit-changelog-button",function(d){b("#TB_window").remove()})})(jQuery);
plugin-fw/licence/lib/yit-licence.php ADDED
@@ -0,0 +1,543 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Licence' ) ) {
16
+ /**
17
+ * YIT Licence Panel
18
+ *
19
+ * Setting Page to Manage Products
20
+ *
21
+ * @class YIT_Licence
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
25
+ */
26
+
27
+ abstract class YIT_Licence {
28
+
29
+ /**
30
+ * @var mixed array The registered products info
31
+ * @since 1.0
32
+ */
33
+ protected $_products = array();
34
+
35
+ /**
36
+ * @var array The settings require to add the submenu page "Activation"
37
+ * @since 1.0
38
+ */
39
+ protected $_settings = array();
40
+
41
+ /**
42
+ * @var string Option name
43
+ * @since 1.0
44
+ */
45
+ protected $_licence_option = 'yit_products_licence_activation';
46
+
47
+ /**
48
+ * @var string The yithemes api uri
49
+ * @since 1.0
50
+ */
51
+ protected $_api_uri = 'http://www.yithemes.com';
52
+
53
+ /**
54
+ * @var string The yithemes api uri query args
55
+ * @since 1.0
56
+ */
57
+ protected $_api_uri_query_args = '?wc-api=software-api&request=%request%';
58
+
59
+ /**
60
+ * Constructor
61
+ *
62
+ * @since 1.0
63
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
64
+ */
65
+ abstract public function __construct();
66
+
67
+ /**
68
+ * Premium products registration
69
+ *
70
+ * @param $init string | The products identifier
71
+ * @param $secret_key string | The secret key
72
+ * @param $product_id string | The product id
73
+ *
74
+ * @return void
75
+ *
76
+ * @since 1.0
77
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
78
+ */
79
+ abstract public function register( $init, $secret_key, $product_id );
80
+
81
+ /**
82
+ * Get protected array products
83
+ *
84
+ * @return mixed array
85
+ *
86
+ * @since 1.0
87
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
88
+ */
89
+ public function get_products() {
90
+ return $this->_products;
91
+ }
92
+
93
+ /**
94
+ * Get The home url without protocol
95
+ *
96
+ * @return string | The home url
97
+ *
98
+ * @since 1.0
99
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
100
+ */
101
+ public function get_home_url() {
102
+ return is_ssl() ? str_replace( 'https://', '', home_url() ) : str_replace( 'http://', '', home_url() );
103
+ }
104
+
105
+ /**
106
+ * Check if the request is ajax
107
+ *
108
+ * @return bool true if the request is ajax, false otherwise
109
+ *
110
+ * @since 1.0
111
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
112
+ */
113
+ public function is_ajax() {
114
+ return defined( 'DOING_AJAX' ) && DOING_AJAX ? true : false;
115
+ }
116
+
117
+ /**
118
+ * Admin Enqueue Scripts
119
+ *
120
+ * @return void
121
+ *
122
+ * @since 1.0
123
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
124
+ */
125
+ public function admin_enqueue_scripts(){
126
+
127
+ /**
128
+ * Support to YIT Framework < 2.0
129
+ */
130
+ $filename = function_exists( 'yit_load_js_file' ) ? yit_load_js_file( 'yit-licence.js' ) : 'yit-licence.js';
131
+ $script_path = defined( 'YIT_CORE_PLUGIN_URL' ) ? YIT_CORE_PLUGIN_URL : get_template_directory_uri() . '/core/plugin-fw';
132
+ $style_path = defined( 'YIT_CORE_PLUGIN_URL' ) ? YIT_CORE_PLUGIN_URL : get_template_directory_uri() . '/core/plugin-fw';
133
+
134
+ wp_enqueue_script( 'yit-licence', $script_path . '/licence/assets/js/' . $filename, array( 'jquery' ), '1.0.0', true );
135
+ wp_enqueue_style( 'yit-theme-licence', $style_path . '/licence/assets/css/yit-licence.css' );
136
+ }
137
+
138
+ /**
139
+ * Localize Scripts
140
+ *
141
+ * @return void
142
+ *
143
+ * @since 1.0
144
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
145
+ */
146
+ public function localize_script() {
147
+ wp_localize_script( 'yit-licence', 'licence_message', array(
148
+ 'error' => __( '%field% field can not be empty', 'yit' ),
149
+ 'errors' => __( '%field_1% and %field_2% fields can not be empty', 'yit' ),
150
+ 'server' => __( 'Unable to contact the remote server, please try again later. Thanks!', 'yit' )
151
+ )
152
+ );
153
+ }
154
+
155
+ /**
156
+ * Activate Plugins
157
+ *
158
+ * Send a request to API server to activate plugins
159
+ *
160
+ * @return void
161
+ * @use wp_send_json
162
+ *
163
+ * @since 1.0
164
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
165
+ */
166
+ public function activate() {
167
+
168
+ $product_init = $_REQUEST['product_init'];
169
+ $product = $this->get_product( $product_init );
170
+
171
+ $args = array(
172
+ 'email' => sanitize_email( $_REQUEST['email'] ),
173
+ 'licence_key' => sanitize_text_field( $_REQUEST['licence_key'] ),
174
+ 'product_id' => sanitize_text_field( $product['product_id'] ),
175
+ 'secret_key' => sanitize_text_field( $product['secret_key'] ),
176
+ 'instance' => $this->get_home_url()
177
+ );
178
+
179
+ $api_uri = add_query_arg( $args, $this->get_api_uri( 'activation' ) );
180
+ $response = wp_remote_get( $api_uri );
181
+
182
+ if ( is_wp_error( $response ) ) {
183
+ $body = false;
184
+ }
185
+ else {
186
+ $body = json_decode( $response['body'] );
187
+ $body = is_object( $body ) ? get_object_vars( $body ) : false;
188
+ }
189
+
190
+ if ( $body && is_array( $body ) && isset( $body['activated'] ) && $body['activated'] ) {
191
+
192
+ $option[$product['product_id']] = array(
193
+ 'email' => $args['email'],
194
+ 'licence_key' => $args['licence_key'],
195
+ 'licence_expires' => $body['licence_expires'],
196
+ 'message' => $body['message'],
197
+ 'activated' => true,
198
+ 'activation_limit' => $body['activation_limit'],
199
+ 'activation_remaining' => $body['activation_remaining'],
200
+ );
201
+
202
+ /* === Check for other plugins activation === */
203
+ $options = $this->get_licence();
204
+ $options[$product['product_id']] = $option[$product['product_id']];
205
+
206
+ update_option( $this->_licence_option, $options );
207
+
208
+ /* === Licence Activation Template === */
209
+ $body['template'] = $this->show_activation_panel();
210
+ }
211
+
212
+ wp_send_json( $body );
213
+ }
214
+
215
+ /**
216
+ * Check Plugins Licence
217
+ *
218
+ * Send a request to API server to check if plugins is activated
219
+ *
220
+ * @param string|The plugin init slug $plugin_init
221
+ *
222
+ * @return bool | true if activated, false otherwise
223
+ *
224
+ * @since 1.0
225
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
226
+ */
227
+ public function check( $product_init ) {
228
+
229
+ $status = false;
230
+ $body = false;
231
+ $product = $this->get_product( $product_init );
232
+ $licence = $this->get_licence();
233
+ $product_id = $product['product_id'];
234
+
235
+ if( ! isset( $licence[ $product_id ] ) ) {
236
+ return false;
237
+ }
238
+
239
+ $args = array(
240
+ 'email' => $licence[$product_id]['email'],
241
+ 'licence_key' => $licence[$product_id]['licence_key'],
242
+ 'product_id' => $product_id,
243
+ 'secret_key' => $product['secret_key'],
244
+ 'instance' => $this->get_home_url()
245
+ );
246
+
247
+ $api_uri = add_query_arg( $args, $this->get_api_uri( 'check' ) );
248
+ $response = wp_remote_get( $api_uri );
249
+
250
+ if ( ! is_wp_error( $response ) ) {
251
+ $body = json_decode( $response['body'] );
252
+ $body = is_object( $body ) ? get_object_vars( $body ) : false;
253
+ }
254
+
255
+ if ( $body && is_array( $body ) && isset( $body['success'] ) ) {
256
+ if ( $body['success'] ) {
257
+
258
+ /**
259
+ * Code 200 -> Licence key is valid
260
+ */
261
+ $licence[ $product_id ]['status_code'] = '200';
262
+ $licence[ $product_id ]['activated'] = $body['activated'];
263
+ $licence[ $product_id ]['licence_expires'] = $body['licence_expires'];
264
+ $licence[ $product_id ]['activation_remaining'] = $body['activation_remaining'];
265
+ $licence[ $product_id ]['activation_limit'] = $body['activation_limit'];
266
+ $status = (bool) $body['activated'];
267
+ }
268
+ elseif ( isset( $body['code'] ) ) {
269
+
270
+ switch ( $body['code'] ) {
271
+
272
+ /**
273
+ * Error Code List:
274
+ *
275
+ * 100 -> Invalid Request
276
+ * 101 -> Invalid licence key
277
+ * 102 -> Software has been deactive
278
+ * 103 -> Exceeded maximum number of activations
279
+ * 104 -> Invalid instance ID
280
+ * 105 -> Invalid security key
281
+ * 106 -> Licence key has expired
282
+ * 107 -> Licence key has be banned
283
+ *
284
+ * Only code 101, 106 and 107 have effect on DB
285
+ *
286
+ */
287
+
288
+ case '101':
289
+ case '102':
290
+ unset( $licence[ $product_id ] );
291
+ break;
292
+
293
+ case '106':
294
+ $licence[ $product_id ]['activated'] = false;
295
+ $licence[ $product_id ]['message'] = $body['additional_info'];
296
+ $licence[ $product_id ]['status_code'] = $body['code'];
297
+ $licence[ $product_id ]['licence_expires'] = $body['licence_expires'];
298
+ break;
299
+
300
+ case '107':
301
+ $licence[ $product_id ]['activated'] = false;
302
+ $licence[ $product_id ]['message'] = $body['additional_info'];
303
+ $licence[ $product_id ]['status_code'] = $body['code'];
304
+ break;
305
+ }
306
+ }
307
+
308
+ /* === Update Plugin Licence Information === */
309
+ update_option( $this->_licence_option, $licence );
310
+ }
311
+ return $status;
312
+ }
313
+
314
+ /**
315
+ * Update Plugins Information
316
+ *
317
+ * Send a request to API server to check activate plugins and update the informations
318
+ *
319
+ * @return void
320
+ * @use YIT_Theme_Licence->check()
321
+ *
322
+ * @since 1.0
323
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
324
+ */
325
+ public function update_licence_information() {
326
+ foreach ( $this->_products as $init => $info ) {
327
+ $this->check( $init );
328
+ }
329
+
330
+ /* === Regenerate Update Plugins Transient === */
331
+ //YIT_Upgrade()->force_regenerate_update_transient();
332
+
333
+ do_action( 'yit_licence_after_check' );
334
+
335
+ $response['template'] = $this->show_activation_panel();
336
+ wp_send_json( $response );
337
+ }
338
+
339
+ /**
340
+ * Include activation page template
341
+ *
342
+ * @return mixed void | string the contents of the output buffer and end output buffering.
343
+ *
344
+ * @since 1.0
345
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
346
+ */
347
+ public function show_activation_panel() {
348
+
349
+ $path = defined( 'YIT_CORE_PLUGIN_PATH' ) ? YIT_CORE_PLUGIN_PATH : get_template_directory() . '/core/plugin-fw/';
350
+
351
+ if ( $this->is_ajax() ) {
352
+ ob_start();
353
+ require_once( $path . '/licence/templates/panel/activation/activation-panel.php' );
354
+ return ob_get_clean();
355
+ }
356
+ else {
357
+ require_once( $path . '/licence/templates/panel/activation/activation-panel.php' );
358
+ }
359
+ }
360
+
361
+ /**
362
+ * Get activated products
363
+ *
364
+ * @return array
365
+ *
366
+ * @since 1.0
367
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
368
+ */
369
+ public function get_activated_products() {
370
+ $activated_products = array();
371
+ $licence = $this->get_licence();
372
+
373
+ if ( is_array( $licence ) ) {
374
+ foreach ( $this->_products as $init => $info ) {
375
+ if ( in_array( $info['product_id'], array_keys( $licence ) ) && isset( $licence[$info['product_id']]['activated'] ) && $licence[$info['product_id']]['activated'] ) {
376
+ $product[$init] = $this->_products[$init];
377
+ $product[$init]['licence'] = $licence[$info['product_id']];
378
+ $activated_products[$init] = $product[$init];
379
+ }
380
+ }
381
+ }
382
+
383
+ return $activated_products;
384
+ }
385
+
386
+ /**
387
+ * Get to active products
388
+ *
389
+ * @return array
390
+ *
391
+ * @since 1.0
392
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
393
+ */
394
+ public function get_to_active_products() {
395
+ return array_diff_key( $this->get_products(), $this->get_activated_products() );
396
+ }
397
+
398
+ /**
399
+ * Get no active products
400
+ *
401
+ * @return array
402
+ *
403
+ * @since 1.0
404
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
405
+ */
406
+ public function get_no_active_licence_key() {
407
+ $unactive_products = $this->get_to_active_products();
408
+ $licence = $this->get_licence();
409
+ $licence_key = array();
410
+
411
+ /**
412
+ * Remove banned licence key
413
+ */
414
+ foreach ( $unactive_products as $init => $info ) {
415
+ $product_id = $unactive_products[$init]['product_id'];
416
+ if ( isset( $licence[$product_id]['activated'] ) && ! $licence[$product_id]['activated'] && isset( $licence[$product_id]['status_code'] ) ) {
417
+ $status_code = $licence[$product_id]['status_code'];
418
+
419
+ switch ( $status_code ) {
420
+ case '106':
421
+ $licence_key[$status_code][$init] = $unactive_products[$init];
422
+ $licence_key[$status_code][$init]['licence'] = $licence[$product_id];
423
+ break;
424
+
425
+ case '107':
426
+ $licence_key[$status_code][$init] = $unactive_products[$init];
427
+ $licence_key[$status_code][$init]['licence'] = $licence[$product_id];
428
+ break;
429
+ }
430
+ }
431
+ }
432
+ return $licence_key;
433
+ }
434
+
435
+ /**
436
+ * Get a specific product information
437
+ *
438
+ * @param $product_init | product init file
439
+ *
440
+ * @return mixed array
441
+ *
442
+ * @since 1.0
443
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
444
+ */
445
+ public function get_product( $init ) {
446
+ return isset( $this->_products[$init] ) ? $this->_products[$init] : false;
447
+ }
448
+
449
+ /**
450
+ * Get product product id information
451
+ *
452
+ * @param $product_init | product init file
453
+ *
454
+ * @return mixed array
455
+ *
456
+ * @since 1.0
457
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
458
+ */
459
+ public function get_product_id( $init ) {
460
+ return isset( $this->_products[$init]['product_id'] ) ? $this->_products[$init]['product_id'] : false;
461
+ }
462
+
463
+ /**
464
+ * Get Renewing uri
465
+ *
466
+ * @param $licence_key The licence key to renew
467
+ *
468
+ * @return mixed The renewing uri if licence_key exists, false otherwise
469
+ *
470
+ * @since 1.0
471
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
472
+ */
473
+ public function get_renewing_uri( $licence_key ) {
474
+ return ! empty( $licence_key ) ? str_replace( 'www.', '', $this->_api_uri ) . '?renewing_key=' . $licence_key : false;
475
+ }
476
+
477
+ /**
478
+ * Get protected yithemes api uri
479
+ *
480
+ * @param $request
481
+ *
482
+ * @return mixed array
483
+ *
484
+ * @since 1.0
485
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
486
+ */
487
+ public function get_api_uri( $request ) {
488
+ return str_replace( '%request%', $request, $this->_api_uri . $this->_api_uri_query_args );
489
+ }
490
+
491
+ /**
492
+ * Get the activation page url
493
+ *
494
+ * @return String | Activation page url
495
+ *
496
+ * @since 1.0
497
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
498
+ */
499
+ public function get_licence_activation_page_url() {
500
+ return add_query_arg( array( 'page' => $this->_settings['page'] ), admin_url( 'admin.php' ) );
501
+ }
502
+
503
+
504
+ /**
505
+ * Get the licence information
506
+ *
507
+ * @return array | licence array
508
+ *
509
+ * @since 1.0
510
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
511
+ */
512
+ public function get_licence() {
513
+ return get_option( $this->_licence_option );
514
+ }
515
+
516
+ /**
517
+ * Get the licence information
518
+ *
519
+ * @param $code string The error code
520
+ *
521
+ * @return string | Error code message
522
+ *
523
+ * @since 1.0
524
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
525
+ */
526
+ public function get_error_code_message( $code ) {
527
+
528
+ $error_strings = array(
529
+ '100' => __( 'Invalid Request', 'yit' ),
530
+ '101' => __( 'Invalid licence key', 'yit' ),
531
+ '102' => __( 'Software has been deactive', 'yit' ),
532
+ '103' => __( 'Exceeded maximum number of activations', 'yit' ),
533
+ '104' => __( 'Invalid instance ID', 'yit' ),
534
+ '105' => __( 'Invalid security key', 'yit' ),
535
+ '106' => __( 'Licence key has expired', 'yit' ),
536
+ '107' => __( 'Licence key has be banned', 'yit' )
537
+ );
538
+
539
+ return isset( $error_strings[$code] ) ? $error_strings[$code] : false;
540
+ }
541
+
542
+ }
543
+ }
plugin-fw/licence/lib/yit-plugin-licence.php ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Plugin_Licence' ) ) {
16
+ /**
17
+ * YIT Plugin Licence Panel
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Plugin_Licence
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
25
+ */
26
+
27
+ class YIT_Plugin_Licence extends YIT_Licence {
28
+
29
+ /**
30
+ * @var array The settings require to add the submenu page "Activation"
31
+ * @since 1.0
32
+ */
33
+ protected $_settings = array();
34
+
35
+ /**
36
+ * @var object The single instance of the class
37
+ * @since 1.0
38
+ */
39
+ protected static $_instance = null;
40
+
41
+ /**
42
+ * @var string Option name
43
+ * @since 1.0
44
+ */
45
+ protected $_licence_option = 'yit_plugin_licence_activation';
46
+
47
+ /**
48
+ * @var string product type
49
+ * @since 1.0
50
+ */
51
+ protected $_product_type = 'plugin';
52
+
53
+ /**
54
+ * Constructor
55
+ *
56
+ * @since 1.0
57
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
58
+ */
59
+ public function __construct() {
60
+
61
+ $this->_settings = array(
62
+ 'parent_page' => 'yit_plugin_panel',
63
+ 'page_title' => __( 'Licence Activation', 'yit' ),
64
+ 'menu_title' => __( 'Licence Activation', 'yit' ),
65
+ 'capability' => 'manage_options',
66
+ 'page' => 'yith_plugins_activation',
67
+ );
68
+
69
+ add_action( 'admin_menu', array( $this, 'add_submenu_page' ), 99 );
70
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
71
+ add_action( 'admin_enqueue_scripts', array( $this, 'localize_script' ), 15 );
72
+ add_action( "wp_ajax_activate-{$this->_product_type}", array( $this, 'activate' ) );
73
+ add_action( "wp_ajax_nopriv_activate-{$this->_product_type}", array( $this, 'activate' ) );
74
+ add_action( "wp_ajax_update_licence_information-{$this->_product_type}", array( $this, 'update_licence_information' ) );
75
+ add_action( "wp_ajax_nopriv_update_licence_information-{$this->_product_type}", array( $this, 'update_licence_information' ) );
76
+ add_action( 'yit_licence_after_check', array( $this, 'licence_after_check' ) );
77
+ }
78
+
79
+
80
+ public function licence_after_check() {
81
+ /* === Regenerate Update Plugins Transient === */
82
+ YIT_Upgrade()->force_regenerate_update_transient();
83
+ }
84
+
85
+ /**
86
+ * Main plugin Instance
87
+ *
88
+ * @static
89
+ * @return object Main instance
90
+ *
91
+ * @since 1.0
92
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
93
+ */
94
+ public static function instance() {
95
+ if ( is_null( self::$_instance ) ) {
96
+ self::$_instance = new self();
97
+ }
98
+
99
+ return self::$_instance;
100
+ }
101
+
102
+ /**
103
+ * Add "Activation" submenu page under YIT Plugins
104
+ *
105
+ * @return void
106
+ * @since 1.0
107
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
108
+ */
109
+ public function add_submenu_page() {
110
+ add_submenu_page(
111
+ $this->_settings['parent_page'],
112
+ $this->_settings['page_title'],
113
+ $this->_settings['menu_title'],
114
+ $this->_settings['capability'],
115
+ $this->_settings['page'],
116
+ array( $this, 'show_activation_panel' )
117
+ );
118
+ }
119
+
120
+ /**
121
+ * Premium plugin registration
122
+ *
123
+ * @param $plugin_init | string | The plugin init file
124
+ * @param $secret_key | string | The product secret key
125
+ * @param $product_id | string | The plugin slug (product_id)
126
+ *
127
+ * @return void
128
+ *
129
+ * @since 1.0
130
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
131
+ */
132
+ public function register( $plugin_init, $secret_key, $product_id ) {
133
+ if ( ! function_exists( 'get_plugins' ) ) {
134
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
135
+ }
136
+
137
+ $plugins = get_plugins();
138
+ $plugins[$plugin_init]['secret_key'] = $secret_key;
139
+ $plugins[$plugin_init]['product_id'] = $product_id;
140
+ $this->_products[$plugin_init] = $plugins[$plugin_init];
141
+ }
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Main instance of plugin
147
+ *
148
+ * @return object
149
+ * @since 1.0
150
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
151
+ */
152
+ if( ! function_exists( 'YIT_Plugin_Licence' ) ){
153
+ function YIT_Plugin_Licence() {
154
+ return YIT_Plugin_Licence::instance();
155
+ }
156
+ }
plugin-fw/licence/lib/yit-theme-licence.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! class_exists( 'YIT_Theme_Licence' ) ) {
16
+ /**
17
+ * YIT Plugin Licence Panel
18
+ *
19
+ * Setting Page to Manage Plugins
20
+ *
21
+ * @class YIT_Theme_Licence
22
+ * @package Yithemes
23
+ * @since 1.0
24
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
25
+ */
26
+
27
+ class YIT_Theme_Licence extends YIT_Licence {
28
+
29
+ /**
30
+ * @var array The settings require to add the submenu page "Activation"
31
+ * @since 1.0
32
+ */
33
+ protected $_settings = array();
34
+
35
+ /**
36
+ * @var object The single instance of the class
37
+ * @since 1.0
38
+ */
39
+ protected static $_instance = null;
40
+
41
+ /**
42
+ * @var string Option name
43
+ * @since 1.0
44
+ */
45
+ protected $_licence_option = 'yit_theme_licence_activation';
46
+
47
+ /**
48
+ * @var string product type
49
+ * @since 1.0
50
+ */
51
+ protected $_product_type = 'theme';
52
+
53
+ /**
54
+ * Constructor
55
+ *
56
+ * @since 1.0
57
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
58
+ */
59
+ public function __construct() {
60
+
61
+ $this->_settings = array(
62
+ 'parent_page' => 'yit_product_panel',
63
+ 'page_title' => __( 'Licence Activation', 'yit' ),
64
+ 'menu_title' => __( 'Licence Activation', 'yit' ),
65
+ 'capability' => 'manage_options',
66
+ 'page' => 'yith_plugins_activation',
67
+ );
68
+
69
+ add_action( 'admin_menu', array( $this, 'add_submenu_page' ), 99 );
70
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
71
+ add_action( 'admin_enqueue_scripts', array( $this, 'localize_script' ), 15 );
72
+ add_action( "wp_ajax_activate-{$this->_product_type}", array( $this, 'activate' ) );
73
+ add_action( "wp_ajax_nopriv_activate-{$this->_product_type}", array( $this, 'activate' ) );
74
+ add_action( "wp_ajax_update_licence_information-{$this->_product_type}", array( $this, 'update_licence_information' ) );
75
+ add_action( "wp_ajax_nopriv_update_licence_information-{$this->_product_type}", array( $this, 'update_licence_information' ) );
76
+ }
77
+
78
+ /**
79
+ * Main plugin Instance
80
+ *
81
+ * @static
82
+ * @return object Main instance
83
+ *
84
+ * @since 1.0
85
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
86
+ */
87
+ public static function instance() {
88
+ if ( is_null( self::$_instance ) ) {
89
+ self::$_instance = new self();
90
+ }
91
+
92
+ return self::$_instance;
93
+ }
94
+
95
+ /**
96
+ * Add "Activation" submenu page under YIT Plugins
97
+ *
98
+ * @return void
99
+ * @since 1.0
100
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
101
+ */
102
+ public function add_submenu_page() {
103
+
104
+ $admin_tree = array(
105
+ 'parent_slug' => apply_filters( 'yit_licence_parent_slug', 'yit_panel'),
106
+ 'page_title' => __( 'Licence Activation', 'yit' ),
107
+ 'menu_title' => __( 'Licence Activation', 'yit' ),
108
+ 'capability' => 'manage_options',
109
+ 'menu_slug' => 'yit_panel_licence',
110
+ 'function' => 'show_activation_panel'
111
+ );
112
+
113
+ add_submenu_page( $admin_tree['parent_slug'],
114
+ sprintf( __( '%s', 'yit' ), $admin_tree['page_title'] ),
115
+ sprintf( __( '%s', 'yit' ), $admin_tree['menu_title'] ),
116
+ $admin_tree['capability'],
117
+ $admin_tree['menu_slug'],
118
+ array( $this, $admin_tree['function'] )
119
+ );
120
+ }
121
+
122
+ /**
123
+ * Premium product registration
124
+ *
125
+ * @param $product_init | string | The product init file
126
+ * @param $secret_key | string | The product secret key
127
+ * @param $product_id | string | The product slug (product_id)
128
+ *
129
+ * @return void
130
+ *
131
+ * @since 1.0
132
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
133
+ */
134
+ public function register( $product_init, $secret_key, $product_id ) {
135
+ $theme = wp_get_theme();
136
+ $products[$product_init]['Name'] = $theme->Name;
137
+ $products[$product_init]['secret_key'] = $secret_key;
138
+ $products[$product_init]['product_id'] = $product_id;
139
+ $this->_products[$product_init] = $products[$product_init];
140
+ }
141
+ }
142
+ }
143
+
144
+ /**
145
+ * Main instance
146
+ *
147
+ * @return object
148
+ * @since 1.0
149
+ * @author Andrea Grillo <andrea.grillo@yithemes.com>
150
+ */
151
+ if( ! function_exists( 'YIT_Theme_Licence' ) ){
152
+ function YIT_Theme_Licence() {
153
+ return YIT_Theme_Licence::instance();
154
+ }
155
+ }
plugin-fw/licence/templates/panel/activation/activation-panel.php ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ $to_active_products = $this->get_to_active_products();
12
+ $activated_products = $this->get_activated_products();
13
+ $no_active_products = $this->get_no_active_licence_key();
14
+ $expired_products = isset( $no_active_products[ '106' ] ) ? $no_active_products[ '106' ] : array();
15
+ $banned_products = isset( $no_active_products[ '107' ] ) ? $no_active_products[ '107' ] : array();
16
+ ?>
17
+
18
+ <div class="yit-container product-licence-activation">
19
+ <h2><?php _e( 'Yithemes Licence Activation', 'yit' ) ?></h2>
20
+
21
+ <div class="licence-check-section">
22
+ <form method="post" id="licence-check-update" action="<?php echo admin_url( 'admin-ajax.php' ) ?>">
23
+ <span class="licence-label" style="display: block;"><?php _e( 'Have you updated your licenses? Have you asked for an extension? Update information concerning your products.', 'yit' ); ?></span>
24
+ <input type="hidden" name="action" value="update_licence_information-<?php echo $this->_product_type ?>" />
25
+ <input type="submit" name="submit" value="<?php _e( 'Update licence information', 'yit' ) ?>" class="button-licence licence-check" />
26
+ <div class="spinner"></div>
27
+ </form>
28
+ </div>
29
+
30
+ <!-- To Active Products -->
31
+
32
+
33
+ <?php if( ! empty( $to_active_products ) ) : ?>
34
+ <h3 class="to-active">
35
+ <?php _e( 'To Active', 'yit' ) ?>
36
+ <span class="spinner"></span>
37
+ </h3>
38
+ <div class="to-active-wrapper">
39
+ <?php foreach( $to_active_products as $init => $info ) : ?>
40
+ <form class="to-active-form" method="post" id="<?php echo $info['product_id'] ?>" action="<?php echo admin_url( 'admin-ajax.php' ) ?>">
41
+ <table class="to-active-table">
42
+ <tbody>
43
+ <tr class="product-row">
44
+ <td class="product-name">
45
+ <?php echo $info['Name'] ?>
46
+ </td>
47
+ <td>
48
+ <input type="email" name="email" placeholder="Your email on Yithemes.com" value="" class="user-email" />
49
+ </td>
50
+ <td>
51
+ <input type="text" name="licence_key" placeholder="Licence Key" value="" class="licence-key" />
52
+ </td>
53
+ <td class="activate-button">
54
+ <input type="submit" name="submit" value="<?php _e( 'Activate', 'yit' )?>" class="button-licence licence-activation" data-formid="<?php echo $info['product_id'] ?>"/>
55
+ </td>
56
+ </tr>
57
+ <input type="hidden" name="action" value="activate-<?php echo $this->_product_type ?>" />
58
+ <input type="hidden" name="product_init" value="<?php echo $init ?>" />
59
+ </tbody>
60
+ </table>
61
+ <div class="spinner"></div>
62
+ <div class="message-wrapper">
63
+ <span class="message arrow-left"></span>
64
+ </div>
65
+ </form>
66
+ <?php endforeach; ?>
67
+ </div>
68
+ <?php endif; ?>
69
+
70
+ <!-- Activated Products -->
71
+
72
+ <?php if( ! empty( $activated_products ) ) : ?>
73
+ <h3><?php _e( 'Activated', 'yit' ) ?></h3>
74
+ <table class="expired-table">
75
+ <thead>
76
+ <tr>
77
+ <th><?php _e( 'Product Name', 'yit' ) ?></th>
78
+ <th><?php _e( 'Email', 'yit' ) ?></th>
79
+ <th><?php _e( 'Licence Key', 'yit' ) ?></th>
80
+ <th><?php _e( 'Expires', 'yit' ) ?></th>
81
+ <th><?php _e( 'Remaining', 'yit' ) ?></th>
82
+ <th><?php _e( 'Renew', 'yit' ) ?></th>
83
+ </tr>
84
+ </thead>
85
+ <tbody>
86
+ <?php foreach( $activated_products as $init => $info ) : ?>
87
+ <tr>
88
+ <td class="product-name"><?php echo $info['Name'] ?></td>
89
+ <td class="product-licence-email"><?php echo $info['licence']['email'] ?></td>
90
+ <td class="product-licence-key"><?php echo $info['licence']['licence_key'] ?></td>
91
+ <td class="product-licence-expires"><?php echo date("F j, Y", $info['licence']['licence_expires'] ); ?></td>
92
+ <td class="product-licence-remaining">
93
+ <?php printf( __( '%1s out of %2s', 'yit' ), $info['licence']['activation_remaining'], $info['licence']['activation_limit'] ); ?>
94
+ </td>
95
+ <td><a class="button-licence licence-renew" href="<?php echo $this->get_renewing_uri( $info['licence']['licence_key'] ) ?>" target="_blank"><?php _e( 'Renew', 'yit' ) ?></a></td>
96
+ </tr>
97
+ <?php endforeach; ?>
98
+ </tbody>
99
+ <?php endif;?>
100
+
101
+ <!-- Banned Products -->
102
+
103
+ <?php if( ! empty( $banned_products ) ) : ?>
104
+ <h3><?php _e( 'Banned', 'yit' ) ?></h3>
105
+ <table class="expired-table">
106
+ <thead>
107
+ <tr>
108
+ <th><?php _e( 'Product Name', 'yit' ) ?></th>
109
+ <th><?php _e( 'Email', 'yit' ) ?></th>
110
+ <th><?php _e( 'Licence Key', 'yit' ) ?></th>
111
+ </tr>
112
+ </thead>
113
+ <tbody>
114
+ <?php foreach( $banned_products as $init => $info ) : ?>
115
+ <tr>
116
+ <td class="product-name"><?php echo $info['Name'] ?></td>
117
+ <td class="product-licence-email"><?php echo $info['licence']['email'] ?></td>
118
+ <td class="product-licence-key"><?php echo $info['licence']['licence_key'] ?></td>
119
+ </tr>
120
+ <?php endforeach; ?>
121
+ </tbody>
122
+ </table>
123
+ <?php endif;?>
124
+
125
+ <!-- Expired Products -->
126
+
127
+ <?php if( ! empty( $expired_products ) ) : ?>
128
+ <h3><?php _e( 'Expired', 'yit' ) ?></h3>
129
+ <table class="expired-table">
130
+ <thead>
131
+ <tr>
132
+ <th><?php _e( 'Product Name', 'yit' ) ?></th>
133
+ <th><?php _e( 'Email', 'yit' ) ?></th>
134
+ <th><?php _e( 'Licence Key', 'yit' ) ?></th>
135
+ <th><?php _e( 'Expires', 'yit' ) ?></th>
136
+ <th><?php _e( 'Renew', 'yit' ) ?></th>
137
+ </tr>
138
+ </thead>
139
+ <tbody>
140
+ <?php foreach( $expired_products as $init => $info ) : ?>
141
+ <tr>
142
+ <td class="product-name"><?php echo $info['Name'] ?></td>
143
+ <td class="product-licence-email"><?php echo $info['licence']['email'] ?></td>
144
+ <td class="product-licence-key"><?php echo $info['licence']['licence_key'] ?></td>
145
+ <td class="product-licence-expires"><?php echo date("F j, Y", $info['licence']['licence_expires'] ); ?></td>
146
+ <td><a class="button-licence licence-renew" href="<?php echo $this->get_renewing_uri( $info['licence']['licence_key'] ) ?>" target="_blank"><?php _e( 'Renew', 'yit' ) ?></a></td>
147
+ </tr>
148
+ <?php endforeach; ?>
149
+ </tbody>
150
+ </table>
151
+ <?php endif;?>
152
+ </div>
plugin-fw/templates/metaboxes/tab.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ global $post;
16
+
17
+ do_action( 'yit_before_metaboxes_tab' ) ?>
18
+ <div class="metaboxes-tab">
19
+ <?php do_action( 'yit_before_metaboxes_labels' ) ?>
20
+ <ul class="metaboxes-tabs clearfix"<?php if ( count( $tabs ) <= 1 ) : ?> style="display:none;"<?php endif; ?>>
21
+ <?php
22
+ $i = 0;
23
+ foreach ( $tabs as $tab ) :
24
+ if ( ! isset( $tab['fields'] ) || empty( $tab['fields'] ) ) {
25
+ continue;
26
+ }
27
+ ?>
28
+ <li<?php if ( ! $i ) : ?> class="tabs"<?php endif ?>>
29
+ <a href="#<?php echo urldecode( sanitize_title( $tab['label'] ) ) ?>"><?php echo $tab['label'] ?></a></li><?php
30
+ $i ++;
31
+ endforeach;
32
+ ?>
33
+ </ul>
34
+ <?php do_action( 'yit_after_metaboxes_labels' ) ?>
35
+ <?php if( isset( $tab['label'] ) ) : ?>
36
+ <?php do_action( 'yit_before_metabox_option_' . urldecode( sanitize_title( $tab['label'] ) ) ); ?>
37
+ <?php endif ?>
38
+
39
+ <?php
40
+ // Use nonce for verification
41
+ wp_nonce_field( 'metaboxes-fields-nonce', 'yit_metaboxes_nonce' );
42
+ ?>
43
+ <?php foreach ( $tabs as $tab ) :
44
+
45
+ ?>
46
+ <div class="tabs-panel" id="<?php echo urldecode( sanitize_title( $tab['label'] ) ) ?>">
47
+ <?php
48
+ if ( ! isset( $tab['fields'] ) ) {
49
+ continue;
50
+ }
51
+
52
+ $tab['fields'] = apply_filters( 'yit_metabox_' . sanitize_title( $tab['label'] ) . '_tab_fields', $tab['fields'] );
53
+
54
+ foreach ( $tab['fields'] as $id_tab=>$field ) :
55
+ $value = yit_get_post_meta( $post->ID, $field['id'] );
56
+ $field['value'] = $value != '' ? $value : ( isset( $field['std'] ) ? $field['std'] : '' );
57
+ ?>
58
+ <div class="the-metabox <?php echo $field['type'] ?> clearfix<?php if ( empty( $field['label'] ) ) : ?> no-label<?php endif; ?>">
59
+ <?php yit_plugin_get_template( YIT_CORE_PLUGIN_PATH, '/metaboxes/types/' . $field['type'] . '.php', array( 'args' => $field ) ) ?>
60
+ </div>
61
+ <?php endforeach ?>
62
+ </div>
63
+ <?php endforeach ?>
64
+ </div>
plugin-fw/templates/metaboxes/types/ajax-products.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+ $is_multiple = isset( $multiple ) && $multiple;
17
+ $multiple = ( $is_multiple ) ? ' multiple' : '';
18
+ ?>
19
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
20
+
21
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
22
+
23
+ <select id="<?php echo $id ?>" name="<?php echo $name ?><?php if( $is_multiple ) echo "[]" ?>" class="ajax_chosen_select_products" multiple="multiple" data-placeholder="<?php _e('Search for a product','yit') ?>">
24
+ <?php
25
+ if ( $value ) {
26
+ foreach ( $value as $product_id ) {
27
+ $product = wc_get_product( $product_id );
28
+ if ( $product ) {
29
+ echo '<option value="' . esc_attr( $product_id ) . '" selected="selected">' . esc_html( $product->get_formatted_name() ) . '</option>';
30
+ }
31
+ }
32
+ }
33
+ ?>
34
+ </select>
35
+
36
+ <span class="desc inline"><?php echo $desc ?></span>
37
+ </div>
38
+ <script>
39
+
40
+ (function ($) {
41
+
42
+ // Ajax Chosen Product Selectors
43
+
44
+ $("select.ajax_chosen_select_products").ajaxChosen({
45
+ method: 'GET',
46
+ url: '<?php echo admin_url('admin-ajax.php') ?>',
47
+ dataType: 'json',
48
+ afterTypeDelay: 100,
49
+ data: {
50
+ action: 'woocommerce_json_search_products',
51
+ security: '<?php echo wp_create_nonce("search-products") ?>'
52
+ }
53
+ }, function (data) {
54
+ var terms = {};
55
+
56
+ $.each(data, function (i, val) {
57
+ terms[i] = val;
58
+ });
59
+
60
+ return terms;
61
+ });
62
+
63
+ })(jQuery);
64
+ </script>
plugin-fw/templates/metaboxes/types/categories.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ global $post;
16
+
17
+ extract( $args );
18
+
19
+ if ( empty( $value ) || ! is_array( $value ) )
20
+ $value = array();
21
+
22
+ $categories = yit_get_model('cpt_unlimited')->get_setting( 'categories', $post->ID );
23
+ ?>
24
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
25
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
26
+ <div class="categories-panel">
27
+ <div class="box">
28
+ <ul id="<?php echo $id ?>-category-list" class="category-list">
29
+ <?php if ( ! empty( $categories ) ) : ?>
30
+ <?php foreach ( $categories as $cat_slug => $cat_name ) : ?>
31
+ <li>
32
+ <label class="selectit"><input type="checkbox" name="<?php echo $name ?>[]" value="<?php echo esc_attr( $cat_slug ) ?>"<?php checked( in_array( $cat_slug, $value ) ) ?> /> <?php echo $cat_name ?> <a class="remove_cat" href="#">X</a></label>
33
+ </li>
34
+ <?php endforeach; ?>
35
+ <?php else : ?>
36
+ <li class="remove-after-add"><i><?php _e( 'No categories.', 'yit' ); ?></i></li>
37
+ <?php endif; ?>
38
+ </ul>
39
+ </div>
40
+ <div class="wp-hidden-children">
41
+ <h4>
42
+ <a tabindex="3" class="hide-if-no-js" href="#category-add" id="<?php echo $id ?>-category-add"><?php _e( '+ Add New Category', 'yit' ); ?></a>
43
+ </h4>
44
+ <p class="category-add-field" id="<?php echo $id ?>-category-field">
45
+ <input type="text" class="newcategory" name="newcategory" style="width:100%;" id="<?php echo $id ?>-new-category" />
46
+ <input type="button" value="<?php esc_attr_e( 'Add' ); ?>" class="add:categorychecklist:category-add button category-add-submit" id="<?php echo $id ?>-category-add-submit" />
47
+ </p>
48
+ </div>
49
+ </div>
50
+ <span class="desc inline"><?php echo $desc ?></span>
51
+ </div>
52
+ <script type="text/javascript">
53
+ jQuery(document).ready(function($){
54
+ $('#<?php echo $id ?>-category-field').hide();
55
+ $(document).on('click', '#<?php echo $id ?>-category-add', function(){
56
+ $('#<?php echo $id ?>-category-field').toggle();
57
+ return false;
58
+ });
59
+
60
+ $(document).on('click', '#<?php echo $id ?>-category-add-submit', function(){
61
+ var t = $(this);
62
+ var new_category = $('#<?php echo $id ?>-new-category').val();
63
+
64
+ var data = {
65
+ action: 'add_category_post_type',
66
+ post_id: <?php echo $post->ID; ?>,
67
+ new_category: new_category
68
+ };
69
+
70
+ $.post(ajaxurl, data, function(response) {
71
+ t.prev().val('');
72
+ var new_cat = response;
73
+
74
+ $('.remove-after-add').hide();
75
+ $('.category-list').each(function(){
76
+ var this_post_id = $(this).attr('id');
77
+ var name = '<?php echo $name ?>';
78
+ this_post_id = this_post_id.match( /([0-9]+)/gi );
79
+ name = name.replace( /[0-9]+/g, this_post_id[0] );
80
+ $(this).prepend('<li><label class="selectit"><input type="checkbox" name="'+name+'[]" value="'+new_cat.slug+'" /> '+new_cat.name+' <a class="remove_cat" href="#">X</a></label></li>');
81
+ $('#<?php echo $id ?>-category-list li:first-child .selectit input').attr('checked', true);
82
+ });
83
+ }, 'json');
84
+
85
+ });
86
+
87
+ });
88
+ </script>
plugin-fw/templates/metaboxes/types/checkbox.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+
15
+ extract( $args );
16
+ ?>
17
+ <div id="<?php echo $id ?>-container" <?php if ( isset($deps) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
18
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
19
+ <p>
20
+ <input type="checkbox" id="<?php echo $id ?>" name="<?php echo $name ?>" value="1" <?php if( isset( $std ) ) : ?>data-std="<?php echo $std ?>" <?php endif; checked( $value, 1 ) ?> />
21
+ <span class="desc inline"><?php echo $desc ?></span>
22
+ </p>
23
+ </div>
plugin-fw/templates/metaboxes/types/chosen.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+ $is_multiple = isset( $multiple ) && $multiple;
17
+ $multiple = ( $is_multiple ) ? ' multiple' : '';
18
+ ?>
19
+ <div id="<?php echo $id ?>-container" class="chosen" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
20
+
21
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
22
+
23
+ <div class="select_wrapper">
24
+ <select<?php echo $multiple ?> id="<?php echo $id ?>" class="chosen" name="<?php echo $name ?><?php if( $is_multiple ) echo "[]" ?>" <?php if ( isset( $std ) ) : ?>data-std="<?php echo ( $is_multiple )? implode(' ,', $std) : $std ?>"<?php endif ?>>
25
+ <?php foreach ( $options as $key => $item ) : ?>
26
+ <option value="<?php echo esc_attr( $key ) ?>" <?php if( $is_multiple ): selected( true, in_array( $key, $value ) ); else: selected( $key, $value ); endif; ?> ><?php echo $item ?></option>
27
+ <?php endforeach; ?>
28
+ </select>
29
+ </div>
30
+
31
+ <span class="desc inline"><?php echo $desc ?></span>
32
+ </div>
plugin-fw/templates/metaboxes/types/colorpicker.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+ ?>
17
+ <div id="<?php echo $id ?>-container" <?php if ( isset($deps) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
18
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
19
+
20
+ <input type="text" name="<?php echo $name ?>" id="<?php echo $id ?>" value="<?php echo esc_attr( $value ) ?>" <?php if( isset( $std ) ) : ?>data-default-color="<?php echo $std ?>"<?php endif ?> class="panel-colorpicker"/>
21
+ <span class="desc inline"><?php echo $desc ?></span>
22
+ </div>
plugin-fw/templates/metaboxes/types/contactform.php ADDED
@@ -0,0 +1,553 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ extract( $args );
3
+
4
+ $types = array(
5
+ 'text' => __( 'Text Input', 'yit' ),
6
+ 'checkbox' => __( 'Checkbox', 'yit' ),
7
+ 'select' => __( 'Select', 'yit' ),
8
+ 'textarea' => __( 'Textarea', 'yit' ),
9
+ 'radio' => __( 'Radio Input', 'yit' ),
10
+ 'password' => __( 'Password Field', 'yit' ),
11
+ 'file' => __( 'File Upload', 'yit' ),
12
+ );
13
+
14
+ $defaults = array(
15
+ 'order' => 0,
16
+ 'title' => '',
17
+ 'data_name' => '',
18
+ 'type' => 'text',
19
+ 'already_checked' => '',
20
+ 'options' => array(),
21
+ 'option_selected' => '',
22
+ 'error' => '',
23
+ 'required' => '',
24
+ 'is_email' => '',
25
+ 'reply_to' => '',
26
+ 'class' => '',
27
+ 'select-icon' => 'none',
28
+ 'icon' => '',
29
+ 'custom-icon' => ''
30
+ );
31
+
32
+ if ( ! is_array( $value ) ) {
33
+ $value = array();
34
+ }
35
+ foreach ( $value as $i => $v ) {
36
+ $value[$i] = wp_parse_args( $value[$i], $defaults );
37
+ }
38
+
39
+ $index = 1;
40
+
41
+
42
+ /* Select Font Awesome */
43
+
44
+ $options["select"]=array(
45
+ 'icon' => __( 'Theme Icon', 'yit' ),
46
+ 'custom' => __( 'Custom Icon', 'yit' ),
47
+ 'none' => __( 'None', 'yit' )
48
+ );
49
+
50
+ $options["icon"] = YIT_Plugin_Common::get_awesome_icons();
51
+
52
+ /* End select Font Awesome */
53
+ ?>
54
+
55
+
56
+ <p class="field-row">
57
+ <a href="" class="button-secondary add-items"><?php _e( 'Add field', 'yit' ) ?></a>
58
+ <img src="<?php echo esc_url( admin_url( 'images/wpspin_light.gif' ) ); ?>" class="ajax-loading" id="add-items-ajax-loading" alt="" />
59
+ </p>
60
+
61
+
62
+ <div class="contactform_items panel" id="panel_form">
63
+ <?php while ( $index <= count( $value ) ): ?>
64
+ <div class="contactform_item closed">
65
+ <h3>
66
+ <button type="button" class="remove_item button" rel=""><?php _e( 'Remove', 'yit' ) ?></button>
67
+ <div class="handlediv" title="<?php _e( 'Click to toggle', 'yit' ) ?>"></div>
68
+ <strong><?php echo $value[$index]['title'] ?> <?php yit_string( '(', $types[$value[$index]['type']], ')' ) ?></strong>
69
+ <input type="hidden" class="contactform_menu_order" name="<?php echo $name ?>[<?php echo $index ?>][order]" value="<?php echo esc_attr( $index ) ?>" />
70
+ </h3>
71
+ <div class="inside">
72
+
73
+ <div class="the-metabox text clearfix">
74
+ <label for="<?php echo $id ?>_title_<?php echo $index ?>"><?php _e( 'Title Field', 'yit' ) ?></label>
75
+
76
+ <p>
77
+ <input type="text" value="<?php echo esc_attr( $value[$index]['title'] ) ?>" id="<?php echo $id ?>_title_<?php echo $index ?>" name="<?php echo $name ?>[<?php echo $index ?>][title]" />
78
+ <span class="desc inline"><?php _e( 'Insert the title of field.', 'yit' ) ?></span>
79
+ </p>
80
+ </div>
81
+
82
+ <div class="the-metabox text clearfix">
83
+ <label for="<?php echo $id ?>_data_name_<?php echo $index ?>"><?php _e( 'Data Name', 'yit' ) ?></label>
84
+
85
+ <p>
86
+ <input type="text" value="<?php echo esc_attr( $value[$index]['data_name'] ) ?>" id="<?php echo $id ?>_data_name_<?php echo $index ?>" name="<?php echo $name ?>[<?php echo $index ?>][data_name]" />
87
+ <span class="desc inline"><?php _e( 'REQUIRED: The identification name of this field, that you can insert into body email configuration. <strong>Note:</strong>Use only lowercase characters and underscores.', 'yit' ) ?></span>
88
+ </p>
89
+ </div>
90
+
91
+ <div class="the-metabox select clearfix text-field-type">
92
+ <label for="<?php echo $id ?>_type_<?php echo $index ?>"><?php _e( 'Type field', 'yit' ) ?></label>
93
+
94
+ <p>
95
+ <select id="<?php echo $id ?>_type_<?php echo $index ?>" name="<?php echo $name . '[' . $index . ']' ?>[type]">
96
+ <?php foreach ( $types as $type => $name_type ) : ?>
97
+ <option value="<?php echo esc_attr( $type ) ?>"<?php selected( $type, $value[$index]['type'] ) ?>><?php echo $name_type ?></option>
98
+ <?php endforeach; ?>
99
+ </select>
100
+ <span class="desc inline"><?php _e( 'Select the type of this field.', 'yit' ) ?></span>
101
+ </p>
102
+ </div>
103
+
104
+ <div class="the-metabox checkbox clearfix deps_checkbox deps">
105
+ <label for="<?php echo $id ?>_already_checked_<?php echo $index ?>"><?php _e( 'Checked', 'yit' ) ?></label>
106
+
107
+ <p>
108
+ <input type="checkbox" id="<?php echo $id ?>_already_checked_<?php echo $index ?>" name="<?php echo $name ?>[<?php echo $index ?>][already_checked]" value="1"<?php checked( $value[$index]['already_checked'] ) ?> />
109
+ <span class="desc inline"><?php _e( 'Select this if you want this field already checked.', 'yit' ) ?></span>
110
+ </p>
111
+ </div>
112
+
113
+ <div id="<?php echo $id ?>_addoptions" class="the-metabox addoptions clearfix deps_radio deps_select deps">
114
+ <label for=""><?php _e( 'Add options ', 'yit' ) ?></label>
115
+ <a href="#" class="add-field-option button-secondary" data-index="<?php echo $index ?>"><?php _e( 'Add option', 'yit' ) ?></a><br /><br />
116
+ <?php foreach ( $value[$index]['options'] as $key => $option ) : ?>
117
+ <p class="option">
118
+ <label><input type="radio" name="<?php echo $name ?>[<?php echo $index ?>][option_selected]" value="<?php echo esc_attr( $key ) ?>"<?php checked( $value[$index]['option_selected'], $key ) ?> /> <?php _e( 'Selected', 'yit' ) ?>
119
+ </label>
120
+ <input type="text" name="<?php echo $name ?>[<?php echo $index ?>][options][]" value="<?php echo $option ?>" style="width:200px" />
121
+ <a href="#" class="del-field-option button-secondary"><?php _e( 'Delete option', 'yit' ) ?></a>
122
+ </p>
123
+ <?php endforeach; ?>
124
+ </div>
125
+
126
+ <div class="the-metabox text clearfix">
127
+ <label for="<?php echo $id ?>_error_<?php echo $index ?>"><?php _e( 'Message Error', 'yit' ) ?></label>
128
+
129
+ <p>
130
+ <input type="text" value="<?php echo esc_attr( $value[$index]['error'] ) ?>" id="<?php echo $id ?>_error_<?php echo $index ?>" name="<?php echo $name ?>[<?php echo $index ?>][error]" />
131
+ <span class="desc inline"><?php _e( 'Insert the error message for validation.', 'yit' ) ?></span>
132
+ </p>
133
+ </div>
134
+
135
+ <div class="the-metabox checkbox clearfix">
136
+ <label for="<?php echo $id ?>_required_<?php echo $index ?>"><?php _e( 'Required', 'yit' ) ?></label>
137
+
138
+ <p>
139
+ <input type="checkbox" id="<?php echo $id ?>_required_<?php echo $index ?>" name="<?php echo $name ?>[<?php echo $index ?>][required]" value="1"<?php checked( $value[$index]['required'] ) ?> />
140
+ <span class="desc inline"><?php _e( 'Select this if it must be required.', 'yit' ) ?></span>
141
+ </p>
142
+ </div>
143
+
144
+ <div class="the-metabox checkbox clearfix">
145
+ <label for="<?php echo $id ?>_is_email_<?php echo $index ?>"><?php _e( 'Email', 'yit' ) ?></label>
146
+
147
+ <p>
148
+ <input type="checkbox" id="<?php echo $id ?>_is_email_<?php echo $index ?>" name="<?php echo $name ?>[<?php echo $index ?>][is_email]" value="1"<?php checked( $value[$index]['is_email'] ) ?> />
149
+ <span class="desc inline"><?php _e( 'Select this if it must be a valid email.', 'yit' ) ?></span>
150
+ </p>
151
+ </div>
152
+
153
+ <div class="the-metabox checkbox clearfix">
154
+ <label for="<?php echo $id ?>_reply_to_<?php echo $index ?>"><?php _e( 'Reply To', 'yit' ) ?></label>
155
+
156
+ <p>
157
+ <input type="checkbox" id="<?php echo $id ?>_reply_to_<?php echo $index ?>" name="<?php echo $name ?>[<?php echo $index ?>][reply_to]" value="1"<?php checked( $value[$index]['reply_to'] ) ?> />
158
+ <span class="desc inline"><?php _e( 'Select this if it\'s the email where you can reply.', 'yit' ) ?></span>
159
+ </p>
160
+ </div>
161
+
162
+ <div class="the-metabox text clearfix">
163
+ <label for="<?php echo $id ?>_class_<?php echo $index ?>"><?php _e( 'Class', 'yit' ) ?></label>
164
+
165
+ <p>
166
+ <input type="text" value="<?php echo esc_attr( $value[$index]['class'] ) ?>" id="<?php echo $id ?>_class_<?php echo $index ?>" name="<?php echo $name ?>[<?php echo $index ?>][class]" />
167
+ <span class="desc inline"><?php _e( 'Insert an additional class(es) (separateb by comma) for more personalization.', 'yit' ) ?></span>
168
+ </p>
169
+ </div>
170
+
171
+ <div class="the-metabox text clearfix">
172
+ <label for="<?php echo $id ?>_icon_<?php echo $index ?>"><?php _e( 'Icon', 'yit' ) ?></label>
173
+
174
+ <p>
175
+
176
+ <div class="option">
177
+
178
+ <div class="icon_type">
179
+ <select name="<?php echo $name ?>[<?php echo $index ?>][select-icon]" id="<?php echo $id ?>_icon_<?php echo $index ?>">
180
+ <?php foreach ( $options['select'] as $val => $option ) { ?>
181
+ <option value="<?php echo esc_attr( $val ) ?>"<?php selected( $value[$index]['select-icon'], $val ) ?>><?php echo $option; ?></option>
182
+ <?php } ?>
183
+ </select>
184
+ </div>
185
+
186
+
187
+
188
+ <div class="awesome_icon" style="font-family: 'FontAwesome'">
189
+ <select style="font-family: 'FontAwesome'" name="<?php echo $name ?>[<?php echo $index ?>][icon]" id="<?php echo $id ?>_icon_<?php echo $index ?>[icon]">
190
+ <?php foreach ( $options['icon'] as $option => $val ) { ?>
191
+ <option value="<?php echo esc_attr( $val ) ?>"<?php selected( $value[$index]['icon'], $val ); ?>>
192
+ <?php echo '&#x' . $option . '; ' . $val; ?>
193
+ </option>
194
+ <?php } ?>
195
+ </select>
196
+ </div>
197
+
198
+ <div class="input_wrapper custom_icon">
199
+ <input type="text" name="<?php echo $name ?>[<?php echo $index ?>][custom]" id="<?php echo $id ?>_icon_<?php echo $index ?>[custom-icon]" value="<?php echo esc_attr( $value[$index]['custom'] ); ?>" class="upload_img_url upload_custom_icon" />
200
+ <input type="button" name="<?php echo $name ?>[<?php echo $index ?>][custom]-button" value="<?php _e( 'Upload', 'yit' ) ?>" id="<?php echo $id ?>_icon_<?php echo $index ?>[custom-icon]-button" class="upload_button button" />
201
+
202
+ <div class="upload_img_preview" style="margin-top:10px;">
203
+ <?php
204
+ $file = $current_options['custom'];
205
+ if ( preg_match( '/(jpg|jpeg|png|gif|ico)$/', $file ) ) {
206
+ echo __('Image preview', 'yit') . ': ' . "<img src=\"" . YIT_CORE_ASSETS_URL . "/images/sleep.png\" data-src=\"$file\" />";
207
+ }
208
+ ?>
209
+ </div>
210
+
211
+ </div>
212
+ </div>
213
+
214
+ <span class="desc inline"><?php _e( 'Insert an icon for more personalization.', 'yit' ) ?></span>
215
+ </p>
216
+ </div>
217
+
218
+ <div class="the-metabox text clearfix">
219
+ <label for="<?php echo $id ?>_width_<?php echo $index ?>"><?php _e( 'Width', 'yit' ) ?></label>
220
+
221
+ <p>
222
+ <select id="<?php echo $id ?>_width_<?php echo $index ?>" name="<?php echo $name . '[' . $index . ']' ?>[width]">
223
+ <?php
224
+ for ( $i = 1; $i < 13; $i ++ ) {
225
+ ?>
226
+ <option value="col-sm-<?php echo $i ?>"
227
+ <?php
228
+ if ( isset( $value[$index]['width'] ) ) {
229
+ selected( 'col-sm-' . $i, $value[$index]['width'] );
230
+ }
231
+ else {
232
+ if ( $value['type'] == 'textarea' ) {
233
+ selected( 'col-sm-' . $i, 'col-sm-9' );
234
+ }
235
+ else {
236
+ selected( 'col-sm-' . $i, 'col-sm-3' );
237
+ }
238
+ }
239
+ ?>><?php echo $i ?></option>
240
+ <?php
241
+ }
242
+ ?>
243
+ </select>
244
+ <span class="desc inline"><?php _e( 'Choose how much long will be the field.', 'yit' ) ?></span>
245
+ </p>
246
+ </div>
247
+ </div>
248
+ </div>
249
+ <?php
250
+ $index ++;
251
+ endwhile;
252
+ ?>
253
+
254
+ </div>
255
+
256
+ <div class="contactform_item closed" id="stamp_form" style="display:none;">
257
+ <h3>
258
+ <button type="button" class="remove_item button" rel=""><?php _e( 'Remove', 'yit' ) ?></button>
259
+ <div class="handlediv" title="<?php _e( 'Click to toggle', 'yit' ) ?>"></div>
260
+ <strong></strong>
261
+ <input disabled type="hidden" class="contactform_menu_order" name="<?php echo $name ?>[][order]" value=""/>
262
+ </h3>
263
+ <div class="inside">
264
+
265
+ <div class="the-metabox text clearfix">
266
+ <label for="<?php echo $id ?>_title"><?php _e( 'Title Field', 'yit' ) ?></label>
267
+
268
+ <p>
269
+ <input disabled type="text" value="" id="<?php echo $id ?>_title" name="<?php echo $name ?>[][title]" />
270
+ <span class="desc inline"><?php _e( 'Insert the title of field.', 'yit' ) ?></span>
271
+ </p>
272
+ </div>
273
+
274
+ <div class="the-metabox text clearfix">
275
+ <label for="<?php echo $id ?>_data_name"><?php _e( 'Data Name', 'yit' ) ?></label>
276
+
277
+ <p>
278
+ <input disabled type="text" value="" id="<?php echo $id ?>_data_name" name="<?php echo $name ?>[][data_name]" />
279
+ <span class="desc inline"><?php _e( 'REQUIRED: The identification name of this field, that you can insert into body email configuration. <strong>Note:</strong>Use only lowercase characters and underscores.', 'yit' ) ?></span>
280
+ </p>
281
+ </div>
282
+
283
+ <div class="the-metabox select clearfix text-field-type">
284
+ <label for="<?php echo $id ?>_type"><?php _e( 'Type field', 'yit' ) ?></label>
285
+
286
+ <p>
287
+ <select disabled id="<?php echo $id ?>_type" name="<?php echo $name ?>[][type]">
288
+ <?php foreach ( $types as $type => $name_type ) : ?>
289
+ <option value="<?php echo esc_attr( $type ) ?>"><?php echo $name_type ?></option>
290
+ <?php endforeach; ?>
291
+ </select>
292
+ <span class="desc inline"><?php _e( 'Select the type of this field.', 'yit' ) ?></span>
293
+ </p>
294
+ </div>
295
+
296
+ <div class="the-metabox checkbox clearfix deps_checkbox deps">
297
+ <label for="<?php echo $id ?>_already_checked"><?php _e( 'Checked', 'yit' ) ?></label>
298
+
299
+ <p>
300
+ <input disabled type="checkbox" id="<?php echo $id ?>_already_checked" name="<?php echo $name ?>[][already_checked]" value="1" />
301
+ <span class="desc inline"><?php _e( 'Select this if you want this field already checked.', 'yit' ) ?></span>
302
+ </p>
303
+ </div>
304
+
305
+ <div id="<?php echo $id ?>_addoptions" class="the-metabox addoptions clearfix deps_radio deps_select deps">
306
+ <label for=""><?php _e( 'Add options ', 'yit' ) ?></label>
307
+ <a href="#" class="add-field-option button-secondary"><?php _e( 'Add option', 'yit' ) ?></a><br /><br />
308
+
309
+ <p class="option">
310
+ <label><input disabled type="radio" name="<?php echo $name ?>[][option_selected]" value="" /> <?php _e( 'Selected', 'yit' ) ?>
311
+ </label>
312
+ <input disabled type="text" name="<?php echo $name ?>[][options][]" value="" style="width:200px" />
313
+ <a href="#" class="del-field-option button-secondary"><?php _e( 'Delete option', 'yit' ) ?></a>
314
+ </p>
315
+
316
+ </div>
317
+
318
+ <div class="the-metabox text clearfix">
319
+ <label for="<?php echo $id ?>_error"><?php _e( 'Message Error', 'yit' ) ?></label>
320
+
321
+ <p>
322
+ <input disabled type="text" value="" id="<?php echo $id ?>_error" name="<?php echo $name ?>[][error]" />
323
+ <span class="desc inline"><?php _e( 'Insert the error message for validation.', 'yit' ) ?></span>
324
+ </p>
325
+ </div>
326
+
327
+ <div class="the-metabox checkbox clearfix">
328
+ <label for="<?php echo $id ?>_required"><?php _e( 'Required', 'yit' ) ?></label>
329
+
330
+ <p>
331
+ <input disabled type="checkbox" id="<?php echo $id ?>_required" name="<?php echo $name ?>[][required]" value="1" />
332
+ <span class="desc inline"><?php _e( 'Select this if it must be required.', 'yit' ) ?></span>
333
+ </p>
334
+ </div>
335
+
336
+ <div class="the-metabox checkbox clearfix">
337
+ <label for="<?php echo $id ?>_is_email"><?php _e( 'Email', 'yit' ) ?></label>
338
+
339
+ <p>
340
+ <input disabled type="checkbox" id="<?php echo $id ?>_is_email" name="<?php echo $name ?>[][is_email]" value="1" />
341
+ <span class="desc inline"><?php _e( 'Select this if it must be a valid email.', 'yit' ) ?></span>
342
+ </p>
343
+ </div>
344
+
345
+ <div class="the-metabox checkbox clearfix">
346
+ <label for="<?php echo $id ?>_reply_to"><?php _e( 'Reply To', 'yit' ) ?></label>
347
+
348
+ <p>
349
+ <input disabled type="checkbox" id="<?php echo $id ?>_reply_to" name="<?php echo $name ?>[][reply_to]" value="1" />
350
+ <span class="desc inline"><?php _e( 'Select this if it\'s the email where you can reply.', 'yit' ) ?></span>
351
+ </p>
352
+ </div>
353
+
354
+ <div class="the-metabox text clearfix">
355
+ <label for="<?php echo $id ?>_class"><?php _e( 'Class', 'yit' ) ?></label>
356
+
357
+ <p>
358
+ <input disabled type="text" value="" id="<?php echo $id ?>_class" name="<?php echo $name ?>[][class]" />
359
+ <span class="desc inline"><?php _e( 'Insert an additional class(es) (separateb by comma) for more personalization.', 'yit' ) ?></span>
360
+ </p>
361
+ </div>
362
+
363
+ <div class="the-metabox text clearfix">
364
+ <label for="<?php echo $id ?>_icon"><?php _e( 'Icon', 'yit' ) ?></label>
365
+
366
+ <div class="option">
367
+
368
+ <div class="icon_type">
369
+ <select disabled name="<?php echo $name ?>[][select-icon]" id="<?php echo $id ?>_icon">
370
+ <?php foreach ( $options['select'] as $val => $option ) { ?>
371
+ <option value="<?php echo esc_attr( $val ) ?>"><?php echo $option; ?></option>
372
+ <?php } ?>
373
+ </select>
374
+ </div>
375
+
376
+ <div class="awesome_icon" style="font-family: 'FontAwesome'">
377
+ <select disabled style="font-family: 'FontAwesome'" name="<?php echo $name ?>[][icon]" id="<?php echo $id ?>_icon[icon]">
378
+ <?php foreach ( $options['icon'] as $option => $val ) { ?>
379
+ <option value="<?php echo esc_attr( $val ) ?>">
380
+ <?php echo '&#x' . $option . '; ' . $val; ?>
381
+ </option>
382
+ <?php } ?>
383
+ </select>
384
+ </div>
385
+
386
+ <div class="input_wrapper custom_icon">
387
+ <input disabled type="text" name="<?php echo $name ?>[][custom]" id="<?php echo $id ?>_icon[custom-icon]" value="" class="upload_img_url upload_custom_icon" />
388
+ <input disabled type="button" name="<?php echo $name ?>[][custom]-button" value="<?php _e( 'Upload', 'yit' ) ?>" id="<?php echo $id ?>_icon[custom-icon]-button" class="upload_button button" />
389
+
390
+ <div class="upload_img_preview" style="margin-top:10px;">
391
+ <?php
392
+ $file = '';
393
+ if ( preg_match( '/(jpg|jpeg|png|gif|ico)$/', $file ) ) {
394
+ echo __('Image preview', 'yit') . ': ' . "<img src=\"" . YIT_CORE_ASSETS_URL . "/images/sleep.png\" data-src=\"$file\" />";
395
+ }
396
+ ?>
397
+ </div>
398
+
399
+ </div>
400
+ </div>
401
+
402
+ <span class="desc inline"><?php _e( 'Insert an icon for more personalization.', 'yit' ) ?></span>
403
+ </div>
404
+
405
+ <div class="the-metabox text clearfix">
406
+ <label for="<?php echo $id ?>_width"><?php _e( 'Width', 'yit' ) ?></label>
407
+
408
+ <p>
409
+ <select disabled id="<?php echo $id ?>_width" name="<?php echo $name?>[][width]">
410
+ <?php
411
+ for ( $i = 1; $i < 13; $i ++ ) {
412
+ ?>
413
+ <option value="col-sm-<?php echo $i ?>"> <?php echo $i ?> </option>
414
+ <?php
415
+ }
416
+ ?>
417
+ </select>
418
+ <span class="desc inline"><?php _e( 'Choose how much long will be the field.', 'yit' ) ?></span>
419
+ </p>
420
+ </div>
421
+ </div>
422
+ </div>
423
+
424
+ <script>
425
+
426
+ var index = <?php echo $index ?>;
427
+
428
+ jQuery(document).ready(function ($) {
429
+
430
+ $(document).on('click', '#<?php echo $id ?>_addoptions .add-field-option', function(){
431
+ var select_index = $(this).data('index');
432
+ var option = "<p class='option'><label><input type='radio' name='<?php echo $name ?>[option_selected]' value='' /> <?php _e( 'Selected', 'yit' ) ?></label><input type='text' name='<?php echo $name ?>[" + select_index + "][options][]' style='width:200px' /> <a href='#' class='del-field-option button-secondary'><?php _e( 'Delete option', 'yit' ) ?></a></p>";
433
+
434
+ $(option).appendTo( $(this).parents('#<?php echo $id ?>_addoptions') );
435
+ return false;
436
+ });
437
+
438
+ //toggle items
439
+ $(document).on('click', '.contactform_item h3, .contactform_item .handlediv', function () {
440
+ var p = $(this).parent('.contactform_item'), id = p.attr('id');
441
+ p.toggleClass('closed');
442
+
443
+ if (!p.hasClass('closed')) {
444
+ p.find('.inside').show();
445
+ } else {
446
+ p.find('.inside').hide();
447
+ }
448
+
449
+ });
450
+
451
+ //add item
452
+ $(".add-items").click(function () {
453
+
454
+
455
+ var a = $("#stamp_form").clone();
456
+ a.appendTo("#panel_form").attr("id", "").show();
457
+
458
+ a.find("input, select").each(function(){
459
+ $(this).prop('disabled', false);
460
+ var str = $(this).attr("name");
461
+
462
+ var nam = str.replace("[]","["+ index +"]");
463
+ $(this).attr("name", nam );
464
+ });
465
+
466
+ index++;
467
+
468
+ $('body').trigger('yit_contact_form_added_item');
469
+
470
+ return false;
471
+ });
472
+
473
+ //remove item
474
+ $(document).on('click', '.remove_item', function () {
475
+ if ($('.remove_item').length > 1) {
476
+ var str = $(this).parents('.contactform_item').find("input:first-child").attr("name").match( /(.*)\[(.*)\](.*)\[(.*)\]/ );
477
+
478
+ var i = parseInt(str[2]);
479
+
480
+ $('.contactform_item:gt('+ --i +')').find("input, select").each(function(){
481
+ var str = $(this).attr("name").match( /(.*)\[(.*)\](.*)\[(.*)\]/ );
482
+ var indice = parseInt(str[2]);
483
+ var nam = $(this).attr('name').replace("[" + indice + "]", "[" + --indice + "]");
484
+ $(this).attr("name", nam );
485
+ });
486
+
487
+ $(this).parents('.contactform_item').remove();
488
+
489
+ index--;
490
+
491
+ $('body').trigger('yit_contact_form_removed_item');
492
+ }
493
+
494
+ return false;
495
+ });
496
+
497
+ //sortable
498
+ $('.contactform_items').sortable({
499
+ items:'.contactform_item',
500
+ cursor:'move',
501
+ axis:'y',
502
+ handle: 'h3',
503
+ scrollSensitivity:60,
504
+ forcePlaceholderSize: true,
505
+ helper: 'clone',
506
+ opacity: 0.65,
507
+ placeholder: 'metabox-sortable-placeholder',
508
+ start:function(event,ui){
509
+ ui.item.css('background-color','#f6f6f6');
510
+ },
511
+ stop:function(event,ui){
512
+ ui.item.removeAttr('style');
513
+
514
+
515
+ variation_row_indexes();
516
+ }
517
+ });
518
+
519
+
520
+ function variation_row_indexes() {
521
+ $('.contactform_items .contactform_item').each(function(index){
522
+ index++;
523
+ $(this).find("input,select").each(function(){
524
+ var str = $(this).attr('name').match( /(.*)\[(.*)\](.*)\[(.*)\]/ );
525
+ var nam = $(this).attr('name').replace("[" +parseInt(str[2])+ "]", "[" +index+ "]");
526
+ $(this).attr('name', nam);
527
+ });
528
+ });
529
+ }
530
+
531
+ //
532
+ var field_type_handler = function(){
533
+ var this_item = $(this);
534
+ $(this_item).on('change', '.text-field-type select', function(){
535
+ var val = $(this).val();
536
+ $('.deps', this_item).hide().filter(function(i){ return $(this).hasClass( 'deps_' + val ); }).show();
537
+ });
538
+ $('.text-field-type select').change();
539
+ };
540
+ $('.contactform_item').each(field_type_handler);
541
+
542
+
543
+ //
544
+ $(document).on('click', '.del-field-option', function(){
545
+ if( $('.option').length > 1 ) {
546
+ $(this).parents('.option').remove();
547
+ }
548
+
549
+ return false;
550
+ });
551
+
552
+ });
553
+ </script>
plugin-fw/templates/metaboxes/types/customtabs.php ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract($args);
16
+
17
+ $args['labels'] = array(
18
+ 'plural_name' => 'Tabs',
19
+ 'singular_name' => 'Tab',
20
+ 'item_name_sing' => 'Tab',
21
+ 'item_name_plur' => 'Tabs',
22
+ );
23
+
24
+ ?>
25
+ <div id="<?php echo $id ?>-container" <?php if ( isset($deps) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
26
+ <div id="yit_custom_tabs" class="panel wc-metaboxes-wrapper" style="display: block;">
27
+ <p class="toolbar">
28
+ <a href="#" class="close_all"><?php _e('Close all', 'yit') ?></a><a href="#" class="expand_all"><?php _e('Expand all', 'yit') ?></a>
29
+ </p>
30
+
31
+ <div class="yit_custom_tabs wc-metaboxes ui-sortable" style="">
32
+
33
+ <?php if( !empty($value) ): ?>
34
+ <?php foreach( $value as $i=>$tab ): ?>
35
+ <div class="yit_custom_tab wc-metabox closed" rel="0">
36
+ <h3>
37
+ <button type="button" class="remove_row button"><?php _e('Remove', 'yit') ?></button>
38
+ <div class="handlediv" title="Click to toggle"></div>
39
+ <strong class="attribute_name"><?php echo $tab['name'] ?></strong>
40
+ </h3>
41
+
42
+ <table cellpadding="0" cellspacing="0" class="woocommerce_attribute_data wc-metabox-content" style="display: table;">
43
+ <tbody>
44
+ <tr>
45
+ <td class="attribute_name">
46
+ <label><?php _e('Name', 'yit') ?>:</label>
47
+ <input type="text" class="attribute_name" name="<?php echo $name ?>[<?php echo $i ?>][name]" value="<?php echo esc_attr( $tab['name'] ) ?>">
48
+ <input type="hidden" name="<?php echo $name ?>[<?php echo $i ?>][position]" class="attribute_position" value="<?php echo $i ?>">
49
+ </td>
50
+
51
+ <td rowspan="3">
52
+ <label><?php _e('Value', 'yit') ?>:</label>
53
+ <textarea name="<?php echo $name ?>[<?php echo $i ?>][value]" cols="5" rows="5" placeholder="<?php _e('The content of the tab. (HTML is supported)','yit') ?>"><?php echo $tab['value'] ?></textarea>
54
+ </td>
55
+ </tr>
56
+ </tbody>
57
+ </table>
58
+
59
+ </div>
60
+ <?php endforeach ?>
61
+ <?php endif ?>
62
+ </div>
63
+
64
+ <p class="toolbar">
65
+ <button type="button" class="button button-primary add_custom_tab"><?php _e( 'Add custom product tab', 'yit' ) ?></button>
66
+ </p>
67
+
68
+ <div class="clear"></div>
69
+ </div>
70
+ </div>
71
+
72
+ <script>
73
+ jQuery(document).ready(function($){
74
+ // Add rows
75
+ $('button.add_custom_tab').on('click', function(){
76
+
77
+ var size = $('.yit_custom_tabs .yit_custom_tab').size() + 1;
78
+
79
+ // Add custom attribute row
80
+ $('.yit_custom_tabs').append('<div class="yit_custom_tab wc-metabox">\
81
+ <h3>\
82
+ <button type="button" class="remove_row button"><?php _e('Remove', 'yit') ?></button>\
83
+ <div class="handlediv" title="Click to toggle"></div>\
84
+ <strong class="attribute_name"></strong>\
85
+ </h3>\
86
+ <table cellpadding="0" cellspacing="0" class="woocommerce_attribute_data">\
87
+ <tbody>\
88
+ <tr>\
89
+ <td class="attribute_name">\
90
+ <label><?php _e('Name', 'yit') ?>:</label>\
91
+ <input type="text" class="attribute_name" name="<?php echo $name ?>[' + size + '][name]" />\
92
+ <input type="hidden" name="<?php echo $name ?>[' + size + '][position]" class="attribute_position" value="' + size + '" />\
93
+ </td>\
94
+ <td rowspan="3">\
95
+ <label><?php _e('Value', 'yit') ?>:</label>\
96
+ <textarea name="<?php echo $name ?>[' + size + '][value]" cols="5" rows="5" placeholder="<?php echo addslashes( __('The content of the tab. (HTML is supported)','yit') ) ?>"></textarea>\
97
+ </td>\
98
+ </tr>\
99
+ </tbody>\
100
+ </table>\
101
+ </div>');
102
+
103
+ });
104
+
105
+
106
+ $('.yit_custom_tabs').on('click', 'button.remove_row', function() {
107
+ var answer = confirm("<?php _e('Do you want to remove the custom tab?', 'yit') ?>");
108
+ if (answer){
109
+ var $parent = $(this).parent().parent();
110
+
111
+ $parent.remove();
112
+ attribute_row_indexes();
113
+ }
114
+ return false;
115
+ });
116
+
117
+ // Attribute ordering
118
+ $('.yit_custom_tabs').sortable({
119
+ items:'.yit_custom_tab',
120
+ cursor:'move',
121
+ axis:'y',
122
+ handle: 'h3',
123
+ scrollSensitivity:40,
124
+ forcePlaceholderSize: true,
125
+ helper: 'clone',
126
+ opacity: 0.65,
127
+ placeholder: 'wc-metabox-sortable-placeholder',
128
+ start:function(event,ui){
129
+ ui.item.css('background-color','#f6f6f6');
130
+ },
131
+ stop:function(event,ui){
132
+ ui.item.removeAttr('style');
133
+ attribute_row_indexes();
134
+ }
135
+ });
136
+
137
+ function attribute_row_indexes() {
138
+ $('.yit_custom_tabs .yit_custom_tab').each(function(index, el){
139
+ var newVal = '[' + $(el).index('.yit_custom_tabs .yit_custom_tab') + ']';
140
+ var oldVal = '[' + $('.attribute_position', el).val() + ']';
141
+
142
+ $(':input:not(button)', el).each(function(){
143
+ var name = $(this).attr('name');
144
+ $(this).attr('name', name.replace(oldVal, newVal));
145
+ });
146
+
147
+ $('.attribute_position', el).val( $(el).index('.yit_custom_tabs .yit_custom_tab') );
148
+ });
149
+ };
150
+
151
+ });
152
+ </script>
plugin-fw/templates/metaboxes/types/datepicker.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+ ?>
17
+ <div id="<?php echo $id ?>-container" <?php if ( isset($deps) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
18
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
19
+ <input type="text" name="<?php echo $name ?>" id="<?php echo $id ?>" value="<?php echo esc_attr( $value ) ?>" class="panel-datepicker"/>
20
+ <span class="desc inline"><?php echo $desc ?></span>
21
+ </div>
plugin-fw/templates/metaboxes/types/hidden.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+
16
+ extract( $args );
17
+ ?>
18
+ <input type="hidden" id="<?php echo $id ?>" name="<?php echo $name ?>" value="<?php echo esc_attr( $val ) ?>" <?php if( isset( $std ) ) : ?>data-std="<?php echo $std ?>"<?php endif ?> />
plugin-fw/templates/metaboxes/types/icon-list.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ /**
12
+ * Awesome Icon Admin View
13
+ *
14
+ * @package Yithemes
15
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.com>
16
+ * @since 1.0.0
17
+ */
18
+
19
+ extract( $args );
20
+
21
+
22
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
23
+
24
+ $current_options = wp_parse_args( $args['value'], $args['std'] );
25
+ $current_icon = YIT_Icon()->get_icon_data( $current_options['icon'] );
26
+ $current_icon = YIT_Icon()->get_icon_data( $std['icon'] );
27
+
28
+ $options['icon'] = YIT_Plugin_Common::get_icon_list();
29
+
30
+ ?>
31
+
32
+
33
+
34
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>class="select_icon rm_option rm_input rm_text">
35
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
36
+
37
+ <div class="option">
38
+ <div class="select_wrapper icon_list_type clearfix">
39
+ <select name="<?php echo $name ?>[select]" id="<?php echo $id ?>[select]" <?php if ( isset( $std['select'] ) ) : ?>data-std="<?php echo $std['select']; ?>"<?php endif; ?>>
40
+ <?php foreach ( $options['select'] as $val => $option ) : ?>
41
+ <option value="<?php echo $val ?>" <?php selected( $current_options['select'], $val ); ?> ><?php echo $option ?></option>
42
+ <?php endforeach; ?>
43
+ </select>
44
+ </div>
45
+
46
+
47
+ <div class="icon-manager-wrapper">
48
+ <div class="icon-manager-text">
49
+ <div class="icon-preview" <?php echo $current_icon ?>></div>
50
+ <input type="text" id="<?php echo $id ?>[icon]" class="icon-text" name="<?php echo $name ?>[icon]" value="<?php echo $current_options['icon']; ?>" />
51
+ </div>
52
+
53
+
54
+ <div class="icon-manager">
55
+ <ul class="icon-list-wrapper">
56
+ <?php foreach ( $options['icon'] as $font => $icons ):
57
+ foreach ( $icons as $key => $icon ): ?>
58
+ <li data-font="<?php echo $font ?>" data-icon="<?php echo ( strpos( $key , '\\') === 0 ) ? '&#x'.substr( $key , 1 ) : $key ?>" data-key="<?php echo $key ?>" data-name="<?php echo $icon ?>"></li>
59
+ <?php
60
+ endforeach;
61
+ endforeach; ?>
62
+ </ul>
63
+ </div>
64
+ </div>
65
+
66
+
67
+ <div class="input_wrapper custom_icon_wrapper upload" style="clear:both;">
68
+ <input type="text" name="<?php echo $name ?>[custom]" id="<?php echo $id ?>[custom]" value="<?php echo $current_options['custom'] ?>" class="upload_img_url upload_custom_icon" />
69
+ <input type="button" value="<?php _e( 'Upload', 'yit' ) ?>" id="<?php echo $id; ?>-custom-button" class="upload_button button" />
70
+
71
+ <div class="upload_img_preview" style="margin-top:10px;">
72
+ <?php
73
+ $file = $current_options['custom'];
74
+ if ( preg_match( '/(jpg|jpeg|png|gif|ico)$/', $file ) ) {
75
+ echo __('Image preview', 'yit') . ': ' . "<img src=\"" . YIT_CORE_ASSETS_URL . "/images/sleep.png\" data-src=\"$file\" />";
76
+ }
77
+ ?>
78
+ </div>
79
+ </div>
80
+
81
+ </div>
82
+
83
+ <div class="clear"></div>
84
+
85
+
86
+ <div class="description">
87
+ <?php echo $desc ?>
88
+ <?php if( $std['select'] == 'custom' ) : ?>
89
+ <?php printf( __( '(Default: %s <img src="%s"/>)', 'yit' ), $options['select']['custom'], $std['custom'] ) ?>
90
+ <?php else: ?>
91
+ <?php printf( __( '(Default: <i %s></i> )', 'yit' ), $current_icon ) ?>
92
+ <?php endif; ?>
93
+ </div>
94
+
95
+ <div class="clear"></div>
96
+
97
+ </div>
98
+
99
+ <script>
100
+
101
+ jQuery(document).ready( function($){
102
+
103
+ $('.select_wrapper.icon_list_type').on('change', function(){
104
+
105
+ var t = $(this);
106
+ var parents = $('#' + t.parents('div.select_icon').attr('id'));
107
+ var option = $('option:selected', this).val();
108
+ var to_show = option == 'none' ? '' : option == 'icon' ? '.icon-manager-wrapper' : '.custom_icon_wrapper';
109
+
110
+ parents.find('.option > div:not(.icon_list_type)').removeClass('show').addClass('hidden');
111
+ parents.find( to_show ).removeClass( 'hidden' ).addClass( 'show' );
112
+ });
113
+
114
+ $('.select_wrapper.icon_list_type').trigger('change');
115
+
116
+ var $icon_list = $('.select_icon').find('ul.icon-list-wrapper'),
117
+ $preview = $('.icon-preview'),
118
+ $element_list = $icon_list.find('li'),
119
+ $icon_text = $('.icon-text');
120
+
121
+ $element_list.on("click", function () {
122
+ var $t = $(this);
123
+ $element_list.removeClass('active');
124
+ $t.addClass('active');
125
+ $preview.attr('data-font', $t.data('font'));
126
+ $preview.attr('data-icon', $t.data('icon'));
127
+ $preview.attr('data-name', $t.data('name'));
128
+ $preview.attr('data-key', $t.data('key'));
129
+
130
+ $icon_text.val($t.data('font') + ':' + $t.data('name'));
131
+
132
+ });
133
+ });
134
+
135
+ </script>
plugin-fw/templates/metaboxes/types/image-gallery.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( !defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+ $array_id = array();
17
+ if ( !empty( $value ) ) {
18
+ $array_id = array_filter( explode( ',', $value ) );
19
+ }
20
+
21
+ ?>
22
+ <div id="<?php echo $id ?>-container" class="image-gallery" <?php if (isset( $deps )): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
23
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
24
+
25
+ <p>
26
+ <span class="desc inline"><?php echo $desc ?></span>
27
+ <ul id="<?php echo $id ?>-extra-images" class="slides-wrapper extra-images ui-sortable clearfix">
28
+ <?php if ( !empty( $array_id ) ) : ?>
29
+ <?php foreach ( $array_id as $image_id ) : ?>
30
+ <li class="image" data-attachment_id = <?php echo esc_attr($image_id) ?>>
31
+ <a href="#">
32
+ <?php yit_image( "id=$image_id&size=admin-post-type-thumbnails" ); ?>
33
+ </a>
34
+ <ul class="actions">
35
+ <li><a href="#" class="delete" title="<?php _e( 'Delete image', 'yit' ); ?>">x</a></li>
36
+ </ul>
37
+ </li>
38
+ <?php endforeach; endif; ?>
39
+ </ul>
40
+ <input type="button" data-choose="<?php _e( 'Add Images to Gallery', 'yit' ); ?>" data-update="<?php _e( 'Add to gallery', 'yit' ); ?>" value="<?php _e( 'Add images', 'yit' ) ?>" data-delete="<?php _e( 'Delete image', 'yit' ); ?>" data-text="<?php _e( 'Delete', 'yit' ); ?>" id="<?php echo $id ?>-button" class="image-gallery-button button" />
41
+ <input type="hidden" class="image_gallery_ids" id="image_gallery_ids" name="<?php echo $name ?>" value="<?php echo esc_attr( $value ); ?>" />
42
+ </p>
43
+ </div>
plugin-fw/templates/metaboxes/types/images.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+ global $post;
15
+
16
+ extract( $args );
17
+
18
+ if ( empty( $value ) || ! is_array( $value ) )
19
+ $value = array();
20
+
21
+ //$categories = yit_get_model('cpt_unlimited')->get_setting( 'categories', $post->ID );
22
+ ?>
23
+ <div id="<?php echo $id ?>-container" <?php if ( isset($deps) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
24
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
25
+ <span class="desc inline"><?php echo $desc ?></span>
26
+ <ul id="<?php echo $id ?>-extra-images" class="slides-wrapper extra-images ui-sortable clearfix" style="">
27
+ <?php if ( ! empty( $value ) ) : foreach ( $value as $image_id ) : ?>
28
+ <li>
29
+ <a href="#">
30
+ <?php yit_image( "id=$image_id&size=admin-post-type-thumbnails" );//echo wp_get_attachment_image( $image_id, 'admin-post-type-thumbnails' ); ?>
31
+ <input type="hidden" name="<?php echo $name ?>[]" value="<?php echo esc_attr( $image_id ) ?>" />
32
+ </a>
33
+ <a href="#" title="<?php _e( 'Delete image', 'yit' ) ?>" class="delete">X</a>
34
+ </li>
35
+ <?php endforeach; endif; ?>
36
+ </ul>
37
+ <a href="#" class="button-secondary upload-extra-images" id="<?php echo $id ?>-upload-extra-images"><?php _e( 'Upload new images', 'yit' ) ?></a>
38
+ </div>
39
+ <script type="text/javascript">
40
+ jQuery(document).ready(function($){
41
+ $('#<?php echo $id ?>-upload-extra-images').on( 'click', function(){
42
+ tb_show('', 'media-upload.php?post_id=0&TB_iframe=1&width=700');
43
+
44
+ window.send_to_editor = function(html) {
45
+
46
+ var imgurl = $('a', '<div>' + html + '</div>').attr('href');
47
+ var image_id = $('img', html).attr('class').replace(/(.*?)wp-image-/, '');
48
+
49
+ var data = {
50
+ action: 'generate_preview_image_post_type',
51
+ item_id: image_id
52
+ };
53
+
54
+ $.post(ajaxurl, data, function(response) {
55
+ var thumburl = imgurl.split('.').reverse();
56
+ var baseurl = imgurl.replace( '.' + thumburl[0], '' );
57
+ thumburl = baseurl + '-140x100.' + thumburl[0];
58
+
59
+ $('#<?php echo $id ?>-extra-images.slides-wrapper').append('<li><a href="#"><img src="'+thumburl+'" width="140" height="100" /> <input type="hidden" name="<?php echo $name ?>[]" value="'+image_id+'" /></a><a href="#" title="<?php echo addslashes( __( 'Delete image', 'yit' ) ) ?>" class="delete">X</a></li>');
60
+ });
61
+
62
+ tb_remove();
63
+
64
+ }
65
+
66
+ return false;
67
+ });
68
+
69
+ $('#<?php echo $id ?>-extra-images a.delete').on( 'click', function(){
70
+ if ( confirm( "<?php _e( 'Are you sure you want to remove this image?', 'yit' ) ?>" ) ) {
71
+ $(this).parent().remove();
72
+ }
73
+
74
+ return false;
75
+ });
76
+
77
+ // SORTABLE
78
+ $('#<?php echo $id ?>-extra-images').sortable({
79
+ axis: 'x',
80
+ stop: function(e, ui) {}
81
+ });
82
+
83
+ $('.extra-images a:not(.delete)').click(function(){ return false; });
84
+ });
85
+ </script>
plugin-fw/templates/metaboxes/types/number.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+
17
+ ?>
18
+ <div id="<?php echo $id ?>-container" <?php if ( isset($deps) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
19
+ <div class="rm_number">
20
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
21
+ <span class="field">
22
+ <input class="number" type="text" id="<?php echo $id ?>" name="<?php echo $name ?>" <?php echo $min.' '.$max ?> value="<?php echo esc_attr( $value ) ?>" <?php if( isset( $std ) ) : ?>data-std="<?php echo $std ?>"<?php endif ?>" />
23
+ <?php yit_string( '<span class="description">', $desc, '</span>' ); ?>
24
+ </span>
25
+ </div>
26
+ </div>
27
+ <script type="text/javascript" charset="utf-8">
28
+ jQuery(document).ready( function( $ ) {
29
+ $('#<?php echo $id ?>').spinner({
30
+ <?php if( isset( $min )): ?>min: <?php echo $min ?>, <?php endif ?>
31
+ <?php if( isset( $max )): ?>max: <?php echo $max ?>, <?php endif ?>
32
+ showOn: 'always',
33
+ upIconClass: "ui-icon-plus",
34
+ downIconClass: "ui-icon-minus"
35
+ });
36
+ });
37
+ </script>
plugin-fw/templates/metaboxes/types/onoff.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+
17
+ ?>
18
+ <div id="<?php echo $id ?>-container" <?php if ( isset($deps) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?> class="rm_onoff onoff_container">
19
+
20
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
21
+ <p>
22
+ <input type="checkbox" id="<?php echo $id ?>" name="<?php echo $name ?>" value="<?php echo esc_attr( $value ) ?>" <?php checked( $value, 'yes' ) ?> class="on_off" <?php if( isset( $std ) ) : ?>data-std="<?php echo $std ?>"<?php endif ?> />
23
+ <span class="onoff">&nbsp;</span>
24
+ <span class="desc inline"><?php echo $desc ?></span>
25
+ </p>
26
+ </div>
27
+
28
+ <script type="text/javascript">
29
+ jQuery( document ).ready( function( $ ) {
30
+ $( '#<?php echo $id ?>-option span' ).click( function() {
31
+ var input = $( this ).prev( 'input' );
32
+ var checked = input.attr( 'checked' );
33
+
34
+ if( checked ) {
35
+ input.attr( 'checked', false ).attr( 'value', 0 ).removeClass('onoffchecked');
36
+ } else {
37
+ input.attr( 'checked', true ).attr( 'value', 1 ).addClass('onoffchecked');
38
+ }
39
+
40
+ input.change();
41
+ } );
42
+ } );
43
+ </script>
plugin-fw/templates/metaboxes/types/responsivesliders.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+ extract( $args );
15
+
16
+ $options = yit_get_responsive_sliders();
17
+ ?>
18
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
19
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
20
+
21
+ <div class="select_wrapper">
22
+ <select id="<?php echo $id ?>" name="<?php echo $name ?>" <?php if ( isset( $std ) ) : ?>data-std="<?php echo $std ?>"<?php endif ?>>
23
+ <option></option>
24
+ <option value="none"><?php _e( 'None', 'yit' ) ?></option>
25
+ <?php foreach ( $options as $key => $item ) : ?>
26
+ <option value="<?php echo esc_attr( $key ) ?>"<?php selected( $key, $value ) ?>><?php echo $item ?></option>
27
+ <?php endforeach; ?>
28
+ </select>
29
+ </div>
30
+ <span class="desc inline"><?php echo $desc ?></span>
31
+ </div>
plugin-fw/templates/metaboxes/types/select-icon.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ extract( $args );
5
+
6
+ $current_options = wp_parse_args( $args['value'], $args['std'] );
7
+
8
+ ?>
9
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?> class="select_icon">
10
+
11
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
12
+
13
+ <div class="option">
14
+
15
+ <div class="select_wrapper icon_type">
16
+ <select id="<?php echo $id ?>[select]" name="<?php echo $name ?>[select]" <?php if ( isset( $std['select'] ) ) : ?>data-std="<?php echo $std['select']; ?>"<?php endif; ?>>
17
+ <?php foreach ( $options['select'] as $val => $option ) : ?>
18
+ <option value="<?php echo $val ?>" <?php selected( $current_options['select'], $val ); ?> ><?php echo $option ?></option>
19
+ <?php endforeach; ?>
20
+ </select>
21
+ </div>
22
+
23
+ <div class="select_wrapper awesome_icon" style="font-family: 'FontAwesome'">
24
+ <select style="font-family: 'FontAwesome'" id="<?php echo $id ?>[icon]" name="<?php echo $name ?>[icon]">
25
+ <?php foreach ( $options['icon'] as $val => $option ) : $esc_icon = ! empty( $val ) ? '&#x' . $val . '; ' : ''; ?>
26
+ <option value="<?php echo $option ?>" <?php selected( $current_options['icon'], $option ); ?> ><?php echo $esc_icon . $option; ?></option>
27
+ <?php endforeach; ?>
28
+ </select>
29
+ </div>
30
+
31
+ <div class="input_wrapper custom_icon">
32
+ <input type="text" name="<?php echo $name ?>[custom]" id="<?php echo $id ?>[custom]" value="<?php echo $current_options['custom'] ?>" class="upload_img_url upload_custom_icon" />
33
+ <input type="button" value="<?php _e( 'Upload', 'yit' ) ?>" id="<?php echo $id; ?>-custom-button" class="upload_button button" />
34
+
35
+ <div class="upload_img_preview" style="margin-top:10px;">
36
+ <?php
37
+ $file = $current_options['custom'];
38
+ if ( preg_match( '/(jpg|jpeg|png|gif|ico)$/', $file ) ) {
39
+ echo __( 'Image preview', 'yit' ) . ': ' . "<img src=\"" . YIT_CORE_ASSETS_URL . "/images/sleep.png\" data-src=\"$file\" />";
40
+ }
41
+ ?>
42
+ </div>
43
+
44
+ </div>
45
+ </div>
46
+
47
+ <div class="clear"></div>
48
+
49
+ <div class="description">
50
+ <?php echo $desc ?>
51
+ </div>
52
+
53
+ </div>
54
+
55
+ <script>
56
+
57
+ jQuery(document).ready( function($){
58
+
59
+ $('.select_wrapper.icon_type').on('change', function(){
60
+ var t = $(this);
61
+ var parents = $('#' + t.parents('div.select_icon').attr('id'));
62
+ var option = $('option:selected', this).val();
63
+ var to_show = option == 'none' ? '' : option == 'icon' ? '.awesome_icon' : '.custom_icon';
64
+
65
+ parents.find('.option > div:not(.icon_type)').addClass('hidden').removeClass( 'show' );
66
+ parents.find( to_show ).removeClass( 'hidden' ).addClass( 'show' );
67
+ });
68
+
69
+ $('.select_wrapper.icon_type').trigger('change');
70
+ });
71
+
72
+ </script>
plugin-fw/templates/metaboxes/types/select-mailchimp.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+ $multiple = ( isset( $multiple ) && $multiple ) ? ' multiple' : '';
17
+ ?>
18
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
19
+
20
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
21
+
22
+ <div class="select_wrapper">
23
+ <select<?php echo $multiple ?> id="<?php echo $id ?>" name="<?php echo $name ?>" <?php if ( isset( $std ) ) : ?>data-std="<?php echo $std ?>"<?php endif ?>>
24
+ <?php foreach ( $options as $key => $item ) : ?>
25
+ <option value="<?php echo $key ?>"<?php selected( $key, $value ) ?>><?php echo $item ?></option>
26
+ <?php endforeach; ?>
27
+ </select>
28
+ </div>
29
+ <input type="button" class="button-secondary <?php echo $class?>" value="<?php echo $button_name?>"/>
30
+ <span class="spinner"></span>
31
+ <span class="desc inline"><?php echo $desc ?></span>
32
+ </div>
plugin-fw/templates/metaboxes/types/select.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+ $is_multiple = isset( $multiple ) && $multiple;
17
+ $multiple = ( $is_multiple ) ? ' multiple' : '';
18
+ ?>
19
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
20
+
21
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
22
+
23
+ <div class="select_wrapper">
24
+ <select<?php echo $multiple ?> id="<?php echo $id ?>" name="<?php echo $name ?><?php if( $is_multiple ) echo "[]" ?>" <?php if ( isset( $std ) ) : ?>data-std="<?php echo ( $is_multiple )? implode(' ,', $std) : $std ?>"<?php endif ?>>
25
+ <?php foreach ( $options as $key => $item ) : ?>
26
+ <option value="<?php echo esc_attr( $key ) ?>" <?php if( $is_multiple ): selected( true, in_array( $key, $value ) ); else: selected( $key, $value ); endif; ?> ><?php echo $item ?></option>
27
+ <?php endforeach; ?>
28
+ </select>
29
+ </div>
30
+
31
+ <span class="desc inline"><?php echo $desc ?></span>
32
+ </div>
plugin-fw/templates/metaboxes/types/sep.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+
16
+ // doesn't do nothing, allow to stamp the container of this option with sep class:
17
+ // <div class="the-metabox sep"></div>
18
+ ?>
plugin-fw/templates/metaboxes/types/sidebar-layout.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+
17
+ $layout = ! isset( $value['layout'] ) ? 'sidebar-right' : $value['layout'];
18
+ $sidebar = ! isset( $value['sidebar'] ) ? '' : $value['sidebar'];
19
+ ?>
20
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
21
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
22
+
23
+ <p class="yit-sidebar-layout">
24
+ <input type="radio" name="<?php echo $name ?>[layout]" id="<?php echo $id . '-left' ?>" value="sidebar-left" <?php checked( $layout, 'sidebar-left' ) ?> />
25
+ <img src="<?php echo YIT_CORE_ASSETS_URL ?>/images/sideleft.png" title="<?php _e( 'Left sidebar', 'yit' ) ?>" alt="<?php _e( 'Left sidebar', 'yit' ) ?>" />
26
+
27
+ <input type="radio" name="<?php echo $name ?>[layout]" id="<?php echo $id . '-no' ?>" value="sidebar-no" <?php checked( $layout, 'sidebar-no' ) ?> />
28
+ <img src="<?php echo YIT_CORE_ASSETS_URL ?>/images/noside.png" title="<?php _e( 'No sidebar', 'yit' ) ?>" alt="<?php _e( 'No sideabr', 'yit' ) ?>" />
29
+
30
+ <input type="radio" name="<?php echo $name ?>[layout]" id="<?php echo $id . '-right' ?>" value="sidebar-right" <?php checked( $layout, 'sidebar-right' ) ?> />
31
+ <img src="<?php echo YIT_CORE_ASSETS_URL ?>/images/sideright.png" title="<?php _e( 'Right sidebar', 'yit' ) ?>" alt="<?php _e( 'Right sidebar', 'yit' ) ?>" />
32
+
33
+ <select name="<?php echo $name ?>[sidebar]" id="<?php echo $id ?>-sidebar">
34
+ <option value="-1"><?php _e( 'Choose a sidebar', 'yit' ) ?></option>
35
+ <?php foreach ( yit_registered_sidebars() as $val => $option ) { ?>
36
+ <option value="<?php echo esc_attr( $val ) ?>" <?php selected( $sidebar, $val ) ?>><?php echo $option; ?></option>
37
+ <?php } ?>
38
+ </select>
39
+ <script type="text/javascript">
40
+ jQuery(document).ready(function ($) {
41
+ $('.yit-sidebar-layout img').click(function () {
42
+ $(this).parent().children(':radio').attr('checked', false);
43
+ $(this).prev(':radio').attr('checked', true);
44
+ });
45
+
46
+ if ($('#<?php echo $id . '-no' ?>').attr('checked')) {
47
+ $('#<?php echo $id ?>-sidebar').hide();
48
+ }
49
+
50
+ $('.yit-sidebar-layout :radio').next('img').click(function () {
51
+
52
+ if ($(this).prev(':radio').val() == 'sidebar-no') {
53
+ $('#<?php echo $id ?>-sidebar').fadeOut();
54
+ } else {
55
+ $('#<?php echo $id ?>-sidebar').fadeIn();
56
+ }
57
+ });
58
+ });
59
+ </script>
60
+ </p>
61
+ </div>
plugin-fw/templates/metaboxes/types/sidebarlist.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+
17
+ $options = yit_registered_sidebars();
18
+ ?>
19
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
20
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
21
+ <div class="select_wrapper">
22
+ <select id="<?php echo $id ?>" name="<?php echo $name ?>">
23
+ <?php foreach ( $options as $key => $item ) : ?>
24
+ <option value="<?php echo esc_attr( $key ) ?>"<?php selected( $key, $value ) ?>><?php echo $item ?></option>
25
+ <?php endforeach; ?>
26
+ </select>
27
+ </div>
28
+ <span class="desc inline"><?php echo $desc ?></span>
29
+ </div>
plugin-fw/templates/metaboxes/types/sidebars.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ /**
12
+ * Select Plugin Admin View
13
+ *
14
+ * @package Yithemes
15
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
16
+ * @since 1.0.0
17
+ */
18
+
19
+ extract( $args );
20
+ //
21
+ //$layout = ! isset( $value['layout'] ) ? 'sidebar-right' : $value['layout'];
22
+ //$sidebar1 = ! isset( $value['sidebar1'] ) ? '-1' : $value['sidebar1'];
23
+ //$sidebar2 = ! isset( $value['sidebar2'] ) ? '-1' : $value['sidebar2'];
24
+
25
+
26
+ $layout = ! isset( $value['layout'] ) ? 'sidebar-no' : $value['layout'];
27
+ $sidebar_left = ! isset( $value['sidebar-left'] ) ? '-1' : $value['sidebar-left'];
28
+ $sidebar_right = ! isset( $value['sidebar-right'] ) ? '-1' : $value['sidebar-right'];
29
+
30
+ ?>
31
+ <div class="yit-sidebar-layout">
32
+ <div class="option">
33
+ <label for="_slider_name"><?php echo $label ?></label>
34
+
35
+ <input type="radio" name="<?php echo $name ?>[layout]" id="<?php echo $id . '-left' ?>" value="sidebar-left" <?php checked( $layout, 'sidebar-left' ) ?> />
36
+ <img src="<?php echo YIT_CORE_PLUGIN_URL ?>/assets/images/sidebar-left.png" title="<?php _e( 'Left sidebar', 'yit' ) ?>" alt="<?php _e( 'Left sidebar', 'yit' ) ?>" class="<?php echo $id . '-left' ?>" />
37
+
38
+ <input type="radio" name="<?php echo $name ?>[layout]" id="<?php echo $id . '-right' ?>" value="sidebar-right" <?php checked( $layout, 'sidebar-right' ) ?> />
39
+ <img src="<?php echo YIT_CORE_PLUGIN_URL ?>/assets/images/sidebar-right.png" title="<?php _e( 'Right sidebar', 'yit' ) ?>" alt="<?php _e( 'Right sidebar', 'yit' ) ?>" class="<?php echo $id . '-right' ?>" />
40
+
41
+ <input type="radio" name="<?php echo $name ?>[layout]" id="<?php echo $id . '-double' ?>" value="sidebar-double" <?php checked( $layout, 'sidebar-double' ) ?> />
42
+ <img src="<?php echo YIT_CORE_PLUGIN_URL ?>/assets/images/double-sidebar.png" title="<?php _e( 'No sidebar', 'yit' ) ?>" alt="<?php _e( 'No sidebar', 'yit' ) ?>" class="<?php echo $id . '-double' ?>" />
43
+
44
+ <input type="radio" name="<?php echo $name ?>[layout]" id="<?php echo $id . '-no' ?>" value="sidebar-no" <?php checked( $layout, 'sidebar-no' ) ?> />
45
+ <img src="<?php echo YIT_CORE_PLUGIN_URL ?>/assets/images/no-sidebar.png" title="<?php _e( 'No sidebar', 'yit' ) ?>" alt="<?php _e( 'No sidebar', 'yit' ) ?>" class="<?php echo $id . '-no' ?>" />
46
+ </div>
47
+ <div class="clearfix"></div>
48
+ <div class="option" id="choose-sidebars">
49
+ <div class="side">
50
+ <div class="select-mask" <?php if ( $layout != 'sidebar-double' && $layout != 'sidebar-left' ) { echo 'style="display:none"'; } ?> id="<?php echo $id ?>-sidebar-left-container">
51
+ <label for ="<?php echo $id ?>-sidebar-left"><?php _e('Sidebar Left','yit') ?></label>
52
+ <select name="<?php echo $name ?>[sidebar-left]" id="<?php echo $id ?>-sidebar-left">
53
+ <option value="-1"><?php _e( 'Choose a sidebar', 'yit' ) ?></option>
54
+ <?php foreach ( yit_registered_sidebars() as $val => $option ) { ?>
55
+ <option value="<?php echo esc_attr( $val ) ?>" <?php selected( $sidebar_left, $val ) ?>><?php echo $option; ?></option>
56
+ <?php } ?>
57
+ </select>
58
+ </div>
59
+ </div>
60
+ <div class="side" style="clear: both">
61
+ <div class="select-mask" <?php if ( $layout != 'sidebar-double' && $layout != 'sidebar-right' ) { echo 'style="display:none"'; } ?> id="<?php echo $id ?>-sidebar-right-container">
62
+ <label for ="<?php echo $id ?>-sidebar-right"><?php _e('Sidebar Right','yit') ?></label>
63
+ <select name="<?php echo $name ?>[sidebar-right]" id="<?php echo $id ?>-sidebar-right">
64
+ <option value="-1"><?php _e( 'Choose a sidebar', 'yit' ) ?></option>
65
+ <?php foreach ( yit_registered_sidebars() as $val => $option ) { ?>
66
+ <option value="<?php echo esc_attr( $val ) ?>" <?php selected( $sidebar_right, $val ) ?>><?php echo $option; ?></option>
67
+ <?php } ?>
68
+ </select>
69
+ </div>
70
+ </div>
71
+ </div>
72
+
73
+ </div>
74
+
75
+ <script type="text/javascript">
76
+ (function ($){
77
+
78
+ $(document).on('click', '.yit-sidebar-layout img' , function(e) {
79
+
80
+ $( this ).parent().children( ':radio' ).attr( 'checked', false );
81
+ $( this ).prev( ':radio' ).attr( 'checked', true );
82
+ });
83
+
84
+ $(document).on('click', 'img._sidebars-no' , function(e) {
85
+ $( '#_sidebars-sidebar-left-container, #_sidebars-sidebar-right-container' ).hide();
86
+ });
87
+
88
+ $(document).on('click', 'img._sidebars-left' , function(e) {
89
+ $('#_sidebars-sidebar-right-container' ).hide();
90
+ $('#_sidebars-sidebar-left-container' ).show();
91
+ });
92
+
93
+ $(document).on('click', 'img._sidebars-right' , function(e) {
94
+ $('#_sidebars-sidebar-right-container' ).show();
95
+ $('#_sidebars-sidebar-left-container' ).hide();
96
+ });
97
+
98
+ $(document).on('click', 'img._sidebars-double' , function(e) {
99
+ $( '#_sidebars-sidebar-right-container, #_sidebars-sidebar-left-container' ).show();
100
+ });
101
+
102
+ //
103
+ // $(document).on('click', '.yit-sidebar-layout img' , function() {
104
+ //
105
+ // $( this ).parent().children( ':radio' ).attr( 'checked', false );
106
+ // $( this ).prev( ':radio' ).attr( 'checked', true );
107
+ // });
108
+ //
109
+ // $('img._sidebar-no').click( function() {
110
+ // $( '#_sidebar-sidebar1-container, #_sidebar-sidebar2-container' ).hide();
111
+ // });
112
+ //
113
+ // $( 'img._sidebar-left, img._sidebar-right').click( function() {
114
+ // $('#_sidebar-sidebar2-container' ).hide();
115
+ // $('#_sidebar-sidebar1-container' ).show();
116
+ // });
117
+ //
118
+ // $('img._sidebar-double').click( function() {
119
+ // $( '#_sidebar-sidebar1-container, #_sidebar-sidebar2-container' ).show();
120
+ // });
121
+
122
+
123
+ })(jQuery);
124
+ </script>
plugin-fw/templates/metaboxes/types/simple-text.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+
16
+ extract( $args );
17
+
18
+ $id = empty( $id ) ? '' : " id=\"$id\"";
19
+ ?>
20
+ <p<?php echo $id ?>><?php echo $desc ?></p>
plugin-fw/templates/metaboxes/types/slider.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+
16
+ extract( $args );
17
+
18
+ if ( ! isset( $labels ) ) {
19
+ $labels = '';
20
+ }
21
+
22
+ ?>
23
+ <div id="<?php echo $id ?>-container" class="slider_container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
24
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
25
+ <div class="ui-slider">
26
+ <span class="minCaption"><?php echo $min ?></span>
27
+ <span class="maxCaption"><?php echo $max ?></span>
28
+ <span id="<?php echo $id ?>-feedback" class="feedback"><strong><?php echo $value ?></strong></span>
29
+
30
+ <div id="<?php echo $id ?>-div" data-step="<?php echo isset( $step ) ? $step : 1 ?>" data-labels="<?php echo '' ?>" data-min="<?php echo $min ?>" data-max="<?php echo $max ?>" data-val="<?php echo $value; ?>" class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all">
31
+ <input id="<?php echo $id ?>" type="hidden" name="<?php echo $name ?>" value="<?php echo esc_attr( $value ); ?>" />
32
+ </div>
33
+ </div>
34
+ <span class="description"><?php echo $desc ?></span>
35
+ </div>
plugin-fw/templates/metaboxes/types/text-array.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+
17
+ $size = isset( $size ) ? " style=\"width:{$size}px;\"" : '';
18
+ ?>
19
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
20
+ <label for="<?php echo $id ?>"><?php echo $label ?>
21
+ <small><?php echo $desc ?></small>
22
+ </label>
23
+
24
+ <p>
25
+ <?php foreach ( $fields as $field_name => $field_label ) : ?>
26
+ <?php echo $field_label ?>:
27
+ <input type="text" name="<?php echo $name ?>[<?php echo $field_name ?>]" id="<?php echo $id ?>_<?php echo $field_name ?>" value="<?php echo isset( $value[$field_name] ) ? esc_attr( $value[$field_name] ) : '' ?>"<?php echo $size ?> /> &nbsp; &nbsp;
28
+ <?php endforeach ?>
29
+ </p>
30
+ </div>
plugin-fw/templates/metaboxes/types/text.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+ extract( $args );
15
+
16
+ ?>
17
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?> data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
18
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
19
+
20
+ <p>
21
+ <input type="text" name="<?php echo $name ?>" id="<?php echo $id ?>" value="<?php echo esc_attr( $value ) ?>" <?php if ( isset( $std ) ) : ?>data-std="<?php echo $std ?>"<?php endif ?> />
22
+ <span class="desc inline"><?php echo $desc ?></span>
23
+ </p>
24
+ </div>
plugin-fw/templates/metaboxes/types/textarea-editor.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+
16
+ // wp_editor is includes since 3.3 of wordpress
17
+ if ( ! function_exists( 'wp_editor' ) ) {
18
+ include 'textarea.php';
19
+ return;
20
+ }
21
+
22
+ extract( $args );
23
+
24
+ $editor_args = array(
25
+ 'wpautop' => true, // use wpautop?
26
+ 'media_buttons' => true, // show insert/upload button(s)
27
+ 'textarea_name' => $name, // set the textarea name to something different, square brackets [] can be used here
28
+ 'textarea_rows' => 20, // rows="..."
29
+ 'tabindex' => '',
30
+ 'editor_css' => '', // intended for extra styles for both visual and HTML editors buttons, needs to include the <style> tags, can use "scoped".
31
+ 'editor_class' => '', // add extra class(es) to the editor textarea
32
+ 'teeny' => false, // output the minimal editor config used in Press This
33
+ 'dfw' => false, // replace the default fullscreen with DFW (needs specific DOM elements and css)
34
+ 'tinymce' => true, // load TinyMCE, can be used to pass settings directly to TinyMCE using an array()
35
+ 'quicktags' => true // load Quicktags, can be used to pass settings directly to Quicktags using an array()
36
+ );
37
+ ?>
38
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?> >
39
+ <?php if ( ! empty( $title ) ) : ?><label for="<?php echo $id ?>"><?php echo $title ?></label><?php endif; ?>
40
+ <div class="editor"><?php wp_editor( $value, $id, $editor_args ); ?></div>
41
+ <p><span class="desc"><?php echo $desc ?></span></p>
42
+ </div>
plugin-fw/templates/metaboxes/types/textarea.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+
16
+ extract( $args );
17
+ ?>
18
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
19
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
20
+
21
+ <p>
22
+ <textarea id="<?php echo $id ?>" name="<?php echo $name ?>" rows="5" cols="50" <?php if ( isset( $std ) ) : ?>data-std="<?php echo $std ?>"<?php endif ?>><?php echo $value ?></textarea>
23
+ <span class="desc inline"><?php echo $desc ?></span>
24
+ </p>
25
+ </div>
plugin-fw/templates/metaboxes/types/title.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ } // Exit if accessed directly
13
+
14
+ extract( $args );
15
+ ?>
16
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
17
+ <h3 style="margin: 0 -10px;"><?php echo $desc ?></h3>
18
+ </div>
plugin-fw/templates/metaboxes/types/typography.php ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+
17
+ $defaults = array(
18
+ 'size' => 12,
19
+ 'unit' => 'px',
20
+ 'family' => '',
21
+ 'style' => 'regular',
22
+ 'color' => '#000000'
23
+ );
24
+ $value = wp_parse_args( $value, $defaults );
25
+ ?>
26
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $deps ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?> >
27
+ <div id="<?php echo $id ?>" class="rm_typography rm_option">
28
+ <div class="option">
29
+ <label for="<?php echo $id ?>"><?php echo $label ?>
30
+ <small><?php echo $desc ?></small>
31
+ </label>
32
+
33
+ <?php if ( strpos( $style['properties'], 'font-size' ) !== false ) : ?>
34
+ <!-- Size -->
35
+ <div class="spinner_container">
36
+ <input class="number" type="text" name="<?php echo $name ?>[size]" id="<?php echo $id ?>-size" value="<?php echo esc_attr( $value['size'] ) ?>" />
37
+ </div>
38
+
39
+ <!-- Unit -->
40
+ <div class="select_wrapper font-unit">
41
+ <select name="<?php echo $name ?>[unit]" id="<?php echo $id ?>-unit">
42
+ <option value="px" <?php selected( $value['unit'], 'px' ) ?>><?php _e( 'px', 'yit' ) ?></option>
43
+ <option value="em" <?php selected( $value['unit'], 'em' ) ?>><?php _e( 'em', 'yit' ) ?></option>
44
+ <option value="pt" <?php selected( $value['unit'], 'pt' ) ?>><?php _e( 'pt', 'yit' ) ?></option>
45
+ <option value="rem" <?php selected( $value['unit'], 'rem' ) ?>><?php _e( 'rem', 'yit' ) ?></option>
46
+ </select>
47
+ </div>
48
+ <?php endif; ?>
49
+
50
+ <?php if ( strpos( $style['properties'], 'font-family' ) !== false ) : ?>
51
+ <!-- Family -->
52
+ <div class="select_wrapper font-family">
53
+ <select name="<?php echo $name ?>[family]" id="<?php echo $id ?>-family">
54
+ <?php
55
+ $web_fonts = yit_get_web_fonts();
56
+ $google_fonts = yit_get_google_fonts();
57
+
58
+ if ( ! empty( $web_fonts ) ) {
59
+ echo '<optgroup label="' . __( 'Web fonts', 'yit' ) . '">';
60
+
61
+ foreach ( $web_fonts as $font_name => $rule ) {
62
+ ?>
63
+ <option value='<?php echo esc_attr( $rule ) ?>' <?php selected( stripslashes( $value['family'] ), $rule ) ?>><?php echo $font_name ?></option>
64
+ <?php
65
+ }
66
+
67
+ echo '</optgroup>';
68
+ }
69
+
70
+ if ( ! empty( $google_fonts ) ) {
71
+ echo '<optgroup label="' . __( 'Google fonts', 'yit' ) . '">';
72
+
73
+ foreach ( $google_fonts->items as $font ) {
74
+ // $font_human = trim( stripslashes( end( array_slice( explode( ',', $font ), 0, 1 ) ) ), "'" );
75
+ // $std_human = trim( stripslashes( end( array_slice( explode( ',', $value['family'] ), 0, 1 ) ) ), "'" );
76
+
77
+ //if( isset($font->family) ):
78
+ //Only me and god know what happen on this line...
79
+ ?>
80
+ <option value="<?php echo stripslashes( $font ) ?>" <?php selected( $value['family'], $font ) ?>><?php echo $font ?></option>
81
+ <?php
82
+ //endif;
83
+ }
84
+
85
+ echo '</optgroup>';
86
+ }
87
+ ?>
88
+ </select>
89
+ </div>
90
+ <?php endif; ?>
91
+
92
+ <?php if ( strpos( $style['properties'], 'font-style' ) !== false ) : ?>
93
+ <!-- Style -->
94
+ <div class="select_wrapper font-style">
95
+ <select name="<?php echo $name ?>[style]" id="<?php echo $id ?>-style">
96
+ <option value="regular" <?php selected( $value['style'], 'regular' ) ?>><?php _e( 'Regular', 'yit' ) ?></option>
97
+ <option value="bold" <?php selected( $value['style'], 'bold' ) ?>><?php _e( 'Bold', 'yit' ) ?></option>
98
+ <option value="extra-bold" <?php selected( $std['style'], 'extra-bold' ) ?>><?php _e( 'Extra bold', 'yit' ) ?></option>
99
+ <option value="italic" <?php selected( $value['style'], 'italic' ) ?>><?php _e( 'Italic', 'yit' ) ?></option>
100
+ <option value="bold-italic" <?php selected( $value['style'], 'bold-italic' ) ?>><?php _e( 'Italic bold', 'yit' ) ?></option>
101
+ </select>
102
+ </div>
103
+ <?php endif; ?>
104
+
105
+ <?php if ( strpos( $style['properties'], 'color' ) !== false ) : ?>
106
+ <!-- Color -->
107
+ <div id="<?php echo $id ?>_container" class="colorpicker_container">
108
+ <div style="background-color: <?php echo $value['color'] ?>"></div>
109
+ </div>
110
+ <input type="text" name="<?php echo $name ?>[color]" id="<?php echo $id ?>-color" style="width:150px" value="<?php echo esc_attr( $value['color'] ) ?>" />
111
+ <?php endif; ?>
112
+ </div>
113
+ <div class="clear"></div>
114
+ <div class="font-preview">
115
+ <p>The quick brown fox jumps over the lazy dog</p>
116
+ </div>
117
+ </div>
118
+ </div>
119
+ <script type="text/javascript" charset="utf-8">
120
+ jQuery(document).ready(function ($) {
121
+ var container = $('#<?php echo $id ?>');
122
+ var preview = container.children('.font-preview').children('p');
123
+
124
+ //Set current value, before trigger change event
125
+
126
+ //Color
127
+ preview.css('color', '<?php echo $value['color'] ?>');
128
+ //Font size
129
+ var size = $('#<?php echo $id ?>-size').val();
130
+ var unit = $('#<?php echo $id ?>-unit').val();
131
+
132
+ preview.css('font-size', size + unit);
133
+ preview.css('line-height', ( unit == 'em' || unit == 'rem' ? Number(size) + 0.4 : Number(size) + 4 ) + unit);
134
+ //Font style
135
+ var style = $('#<?php echo $id ?>-style').val();
136
+
137
+ if (style == 'italic') {
138
+ preview.css({ 'font-weight': 'normal', 'font-style': 'italic' });
139
+ } else if (style == 'bold') {
140
+ preview.css({ 'font-weight': 'bold', 'font-style': 'normal' });
141
+ } else if (style == 'extra-bold') {
142
+ preview.css({ 'font-weight': '800', 'font-style': 'normal' });
143
+ } else if (style == 'bold-italic') {
144
+ preview.css({ 'font-weight': 'bold', 'font-style': 'italic' });
145
+ } else {
146
+ preview.css({ 'font-weight': 'normal', 'font-style': 'normal' });
147
+ }
148
+
149
+ //Font Family
150
+ var group = $('#<?php echo $id ?>-family').find('option:selected').parent().attr('label');
151
+
152
+ if ($('#<?php echo $id ?>-family').length > 0) {
153
+ if (group == '<?php _e( 'Web fonts', 'yit' ) ?>') {
154
+ //Web font
155
+ preview.css('font-family', $('#<?php echo $id ?>-family').val());
156
+ } else {
157
+ //Google font
158
+ WebFontConfig = {
159
+ google: { families: [ $('#<?php echo $id ?>-family :selected').text() ] }
160
+ };
161
+ (function () {
162
+ var wf = document.createElement('script');
163
+ wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
164
+ '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
165
+ wf.type = 'text/javascript';
166
+ wf.async = 'true';
167
+
168
+ var s = document.getElementsByTagName('script')[0];
169
+ s.parentNode.insertBefore(wf, s);
170
+ })();
171
+
172
+ var preview_font = $('#<?php echo $id ?>-family').val()
173
+ preview.css('font-family', preview_font.replace(/:(.*)?/g, ''));
174
+ }
175
+ }
176
+
177
+ $('#<?php echo $id ?>-size').spinner({
178
+ <?php if( isset( $min )): ?>min: <?php echo $min ?>, <?php endif ?>
179
+ <?php if( isset( $max )): ?>max: <?php echo $max ?>, <?php endif ?>
180
+ showOn : 'always',
181
+ upIconClass : "ui-icon-plus",
182
+ downIconClass : "ui-icon-minus",
183
+ });
184
+
185
+ $('#<?php echo $id ?>_container').ColorPicker({
186
+ color : '<?php echo $value['color'] ?>',
187
+ onShow : function (colpkr) {
188
+ $(colpkr).fadeIn(500);
189
+ return false;
190
+ },
191
+ onHide : function (colpkr) {
192
+ $(colpkr).fadeOut(500);
193
+ return false;
194
+ },
195
+ onChange: function (hsb, hex, rgb) {
196
+ $('#<?php echo $id ?>_container div').css('backgroundColor', '#' + hex);
197
+ $('#<?php echo $id ?>_container').next('input').attr('value', '#' + hex);
198
+
199
+ //Preview color change
200
+ preview.css('color', '#' + hex);
201
+ }
202
+ });
203
+
204
+ //Font Size Change
205
+ $('#<?php echo $id ?>-size, #<?php echo $id ?>-unit').change(function () {
206
+ var size = $('#<?php echo $id ?>-size').val();
207
+ var unit = $('#<?php echo $id ?>-unit').val();
208
+
209
+ preview.css('font-size', size + unit);
210
+ preview.css('line-height', ( unit == 'em' || unit == 'rem' ? Number(size) + 0.4 : Number(size) + 4 ) + unit);
211
+ });
212
+
213
+ //Font Family Change
214
+ $('#<?php echo $id ?>-family').change(function () {
215
+ var group = $(this).find('option:selected').parent().attr('label');
216
+
217
+ if (group == '<?php _e( 'Web fonts', 'yit' ) ?>') {
218
+ //Web font
219
+ preview.css('font-family', $(this).val());
220
+ } else {
221
+ //Google font
222
+ WebFontConfig = {
223
+ google: { families: [ $(':selected', this).text() ] }
224
+ };
225
+ (function () {
226
+ var wf = document.createElement('script');
227
+ wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
228
+ '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
229
+ wf.type = 'text/javascript';
230
+ wf.async = 'true';
231
+ var s = document.getElementsByTagName('script')[0];
232
+ s.parentNode.insertBefore(wf, s);
233
+ })();
234
+
235
+ var preview_font = $(this).val();
236
+ preview.css('font-family', preview_font.replace(/:(.*)?/g, ''));
237
+ }
238
+ });
239
+
240
+ //Font Style Change
241
+ $('#<?php echo $id ?>-style').change(function () {
242
+ var style = $(this).val();
243
+
244
+ if (style == 'italic') {
245
+ preview.css({ 'font-weight': 'normal', 'font-style': 'italic' });
246
+ } else if (style == 'bold') {
247
+ preview.css({ 'font-weight': 'bold', 'font-style': 'normal' });
248
+ } else if (style == 'bold-italic') {
249
+ preview.css({ 'font-weight': 'bold', 'font-style': 'italic' });
250
+ } else {
251
+ preview.css({ 'font-weight': 'normal', 'font-style': 'normal' });
252
+ }
253
+ });
254
+ });
255
+ </script>
plugin-fw/templates/metaboxes/types/upload.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ extract( $args );
16
+ ?>
17
+ <div id="<?php echo $id ?>-container" <?php if ( isset($deps) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $deps['ids'] ?>" data-value="<?php echo $deps['values'] ?>" <?php endif ?>>
18
+ <label for="<?php echo $id ?>"><?php echo $label ?></label>
19
+ <p>
20
+ <input type="text" id="<?php echo $id ?>" name="<?php echo $name ?>" value="<?php echo esc_attr( $value ) ?>" <?php if( isset( $std ) ) : ?>data-std="<?php echo $std ?>"<?php endif ?> class="upload_img_url"/>
21
+ <input type="button" class="button-secondary upload_button" id="<?php echo $id ?>-button" value="<?php _e( 'Upload', 'yit' ) ?>" />
22
+ <span class="desc inline"><?php echo $desc ?></span>
23
+ </p>
24
+ </div>
plugin-fw/templates/panel/types/chosen.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ $id = $this->get_id_field( $option['id'] );
16
+ $name = $this->get_name_field( $option['id'] );
17
+
18
+ $is_multiple = isset( $option['multiple'] ) && $option['multiple'];
19
+ $multiple = ( $is_multiple ) ? ' multiple' : '';
20
+
21
+ $db_value = ( $is_multiple && ! is_array( $db_value ) ) ? array() : $db_value;
22
+ ?>
23
+ <div id="<?php echo $id ?>-container" class="chosen yit_options rm_option rm_input rm_text" <?php if ( isset( $option['deps'] ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $this->get_id_field( $option['deps']['ids'] ) ?>" data-value="<?php echo $option['deps']['values'] ?>" <?php endif ?>>
24
+ <div class="option">
25
+ <div class="select_wrapper">
26
+ <select name="<?php echo $name ?><?php if( $is_multiple ) echo "[]" ?>" class="chosen" id="<?php echo $id ?>" <?php echo $multiple ?> >
27
+ <?php foreach ( $option['options'] as $key => $value ) : ?>
28
+ <option value="<?php echo esc_attr( $key ) ?>"<?php ($is_multiple) ? selected( true, in_array( $key, $db_value) ) : selected( $key, $db_value ) ?>><?php echo $value ?></option>
29
+ <?php endforeach; ?>
30
+ </select>
31
+ </div>
32
+ </div>
33
+ <span class="description"><?php echo $option['desc'] ?></span>
34
+
35
+ <div class="clear"></div>
36
+ </div>
plugin-fw/templates/panel/types/connected-list.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $id = $this->get_id_field( $option['id'] );
3
+ $name = $this->get_name_field( $option['id'] );
4
+ ?>
5
+
6
+ <div id="<?php echo $id ?>-container" class="yit_options rm_option rm_input rm_text rm_connectedlist" <?php if( isset( $option['deps'] ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $this->get_id_field( $option['deps']['ids'] ) ?>" data-value="<?php echo $option['deps']['values'] ?>" <?php endif ?>>
7
+ <div class="option">
8
+ <?php $yit_option = json_decode( stripslashes( $db_value ), true ); ?>
9
+ <?php $lists = is_array($yit_option) ? $yit_option : $option['lists']; ?>
10
+
11
+ <?php foreach( $lists as $list => $options ): ?>
12
+ <div class="list_container">
13
+ <h4><?php echo $option['heads'][ $list ] ?></h4>
14
+ <ul id="list_<?php echo $list ?>" class="connectedSortable" data-list="<?php echo $list ?>">
15
+ <?php foreach( $options as $value => $label ): ?>
16
+ <li data-option="<?php echo $value ?>" class="ui-state-default"><?php echo $label ?></li>
17
+ <?php endforeach ?>
18
+ </ul>
19
+ </div>
20
+ <?php endforeach ?>
21
+ <input type="hidden" name="<?php echo $name ?>" id="<?php echo $id ?>" value='<?php echo esc_attr( $db_value ) ?>' />
22
+ </div>
23
+ <div class="description">
24
+ <?php echo $option['desc'] ?>
25
+ </div>
26
+ <div class="clear"></div>
27
+ </div>
plugin-fw/templates/panel/types/layout-panel.php ADDED
File without changes
plugin-fw/templates/panel/types/on-off.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ /**
12
+ * ON-OFF Plugin Admin View
13
+ *
14
+ * @package Yithemes
15
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
16
+ * @since 1.0.0
17
+ */
18
+
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit;
21
+ } // Exit if accessed directly
22
+
23
+ $id = $this->get_id_field( $option['id'] );
24
+ $name = $this->get_name_field( $option['id'] );
25
+
26
+ ?>
27
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $option['deps'] ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $this->get_id_field( $option['deps']['ids'] ) ?>" data-value="<?php echo $option['deps']['values'] ?>" <?php endif ?> class="on_off_container yit_options rm_option rm_input rm_onoff">
28
+ <div class="option">
29
+ <input type="checkbox" name="<?php echo $name ?>" id="<?php echo $id ?>" value="<?php echo esc_attr( $db_value ) ?>" <?php checked( $db_value, 'yes' ); ?> class="on_off<?php if ( $db_value == 'yes' ): ?> onoffchecked<?php endif ?>" />
30
+ <span>&nbsp;</span>
31
+ </div>
32
+ <span class="description"><?php echo $option['desc'] ?></span>
33
+ </div>
34
+
plugin-fw/templates/panel/types/select-mailchimp.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ /**
12
+ * Select Mailchimp Plugin Admin View
13
+ *
14
+ * @package Yithemes
15
+ * @author Antonio La Rocca <antonio.larocca@yithemes.it>
16
+ * @since 1.0.0
17
+ */
18
+
19
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
20
+ ?>
21
+
22
+ <div id="<?php echo $this->get_id_field( $option['id'] ) ?>-container" class="yit_options rm_option rm_input rm_text" <?php if ( isset( $option['deps'] ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $this->get_id_field( $option['deps']['ids'] ) ?>" data-value="<?php echo $option['deps']['values'] ?>" <?php endif ?>>
23
+ <div class="option">
24
+ <div class="select_wrapper">
25
+ <select name="<?php echo $this->get_name_field( $option['id'] ) ?>" id="<?php echo $this->get_id_field( $option['id'] ) ?>">
26
+ <?php foreach( $option['options'] as $key => $value ) : ?>
27
+ <option value="<?php echo esc_attr( $key ) ?>"<?php selected( $key, $db_value ) ?>><?php echo $value ?></option>
28
+ <?php endforeach; ?>
29
+ </select>
30
+ </div>
31
+ <input type="button" class="button-secondary <?php echo $option['class']?>" value="<?php echo esc_attr( $option['button_name'] ) ?>"/>
32
+ <span class="spinner"></span>
33
+ </div>
34
+ <span class="description"><?php echo $option['desc'] ?></span>
35
+ <div class="clear"></div>
36
+ </div>
plugin-fw/templates/panel/types/select.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ /**
12
+ * Select Plugin Admin View
13
+ *
14
+ * @package Yithemes
15
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
16
+ * @since 1.0.0
17
+ */
18
+
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit;
21
+ } // Exit if accessed directly
22
+ $id = $this->get_id_field( $option['id'] );
23
+ $name = $this->get_name_field( $option['id'] );
24
+
25
+ $is_multiple = isset( $option['multiple'] ) && $option['multiple'];
26
+ $multiple = ( $is_multiple ) ? ' multiple' : '';
27
+ ?>
28
+ <div id="<?php echo $id ?>-container" class="yit_options rm_option rm_input rm_text" <?php if ( isset( $option['deps'] ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $this->get_id_field( $option['deps']['ids'] ) ?>" data-value="<?php echo $option['deps']['values'] ?>" <?php endif ?>>
29
+ <div class="option">
30
+ <div class="select_wrapper">
31
+ <select name="<?php echo $name ?><?php if( $is_multiple ) echo "[]" ?>" id="<?php echo $id ?>" <?php echo $multiple ?> >
32
+ <?php foreach ( $option['options'] as $key => $value ) : ?>
33
+ <option value="<?php echo esc_attr( $key ) ?>"<?php ($is_multiple) ? selected( true, in_array( $key, $db_value) ) : selected( $key, $db_value ) ?>><?php echo $value ?></option>
34
+ <?php endforeach; ?>
35
+ </select>
36
+ </div>
37
+ </div>
38
+ <span class="description"><?php echo $option['desc'] ?></span>
39
+
40
+ <div class="clear"></div>
41
+ </div>
plugin-fw/templates/panel/types/slider.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ /**
12
+ * Slider Plugin Admin View
13
+ *
14
+ * @package Yithemes
15
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
16
+ * @since 1.0.0
17
+ */
18
+
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit;
21
+ } // Exit if accessed directly
22
+
23
+ $id = $this->get_id_field( $option['id'] );
24
+ $name = $this->get_name_field( $option['id'] );
25
+ ?>
26
+ <div id="<?php echo $id ?>-container" class="slider_container yit_options rm_option rm_input slider_control slider" <?php if ( isset( $option['deps'] ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $this->get_id_field( $option['deps']['ids'] ) ?>" data-value="<?php echo $option['deps']['values'] ?>" <?php endif ?>>
27
+ <div class="option">
28
+ <div class="ui-slider">
29
+ <span class="minCaption"><?php echo $option['min'] ?></span>
30
+ <span class="maxCaption"><?php echo $option['max'] ?></span>
31
+ <span id="<?php echo $id ?>-feedback" class="feedback"><strong><?php echo $db_value ?></strong></span>
32
+
33
+ <div id="<?php echo $id ?>-div" data-step="<?php echo isset( $option['step'] ) ? $option['step'] : 1 ?>" data-labels="<?php echo '' ?>" data-min="<?php echo $option['min'] ?>" data-max="<?php echo $option['max'] ?>" data-val="<?php echo $db_value; ?>" class="ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all">
34
+ <input id="<?php echo $id ?>" type="hidden" name="<?php echo $name ?>" value="<?php echo esc_attr( $db_value ); ?>" />
35
+ </div>
36
+ </div>
37
+ </div>
38
+
39
+ <span class="description"><?php echo $option['desc'] ?></span>
40
+ </div>
plugin-fw/templates/panel/types/text-button.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ /**
12
+ * Text Plugin Admin View
13
+ *
14
+ * @package Yithemes
15
+ * @author Antonio La Rocca <antonio.larocca@yithemes.it>
16
+ * @since 1.0.0
17
+ */
18
+
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit;
21
+ } // Exit if accessed directly
22
+
23
+ $id = $this->get_id_field( $option['id'] );
24
+ $name = $this->get_name_field( $option['id'] );
25
+
26
+ ?>
27
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $option['deps'] ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $this->get_id_field( $option['deps']['ids'] ) ?>" data-value="<?php echo $option['deps']['values'] ?>" <?php endif ?> class="yit_options rm_option rm_input rm_text">
28
+ <div class="option">
29
+ <input type="text" name="<?php echo $name ?>" id="<?php echo $id ?>" value="<?php echo esc_attr( $db_value ) ?>" />
30
+ <input type="button" class="<?php echo $option['button-class']?> button button-secondary" value="<?php echo esc_attr( $option['button-name'] ) ?>" <?php if ( isset( $option['data'] ) && ! empty( $option['data'] ) ): foreach( $option['data'] as $id => $data ): ?> data-<?php echo $id?>="<?php echo $data?>" <?php endforeach; endif;?> />
31
+ </div>
32
+ <span class="description"><?php echo $option['desc'] ?></span>
33
+
34
+ <div class="clear"></div>
35
+ </div>
36
+
plugin-fw/templates/panel/types/text.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ /**
12
+ * Text Plugin Admin View
13
+ *
14
+ * @package Yithemes
15
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
16
+ * @since 1.0.0
17
+ */
18
+
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit;
21
+ } // Exit if accessed directly
22
+
23
+ $id = $this->get_id_field( $option['id'] );
24
+ $name = $this->get_name_field( $option['id'] );
25
+
26
+ ?>
27
+ <div id="<?php echo $id ?>-container" <?php if ( isset( $option['deps'] ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $this->get_id_field( $option['deps']['ids'] ) ?>" data-value="<?php echo $option['deps']['values'] ?>" <?php endif ?> class="yit_options rm_option rm_input rm_text">
28
+ <div class="option">
29
+ <input type="text" name="<?php echo $name ?>" id="<?php echo $id ?>" value="<?php echo esc_attr( $db_value ) ?>" />
30
+ </div>
31
+ <span class="description"><?php echo $option['desc'] ?></span>
32
+
33
+ <div class="clear"></div>
34
+ </div>
35
+
plugin-fw/templates/panel/types/textarea-codemirror.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ /**
12
+ * Textarea Plugin Admin View
13
+ *
14
+ * @package Yithemes
15
+ * @author Antonio La Rocca <antonio.larocca@yithemes.it>
16
+ * @since 1.0.0
17
+ */
18
+
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit;
21
+ } // Exit if accessed directly
22
+
23
+ $id = $this->get_id_field( $option['id'] );
24
+ $name = $this->get_name_field( $option['id'] );
25
+
26
+ ?>
27
+ <div id="<?php echo $id ?>-container" class="yit_options rm_option rm_input rm_text" <?php if ( isset( $option['deps'] ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $this->get_id_field( $option['deps']['ids'] ) ?>" data-value="<?php echo $option['deps']['values'] ?>" <?php endif ?>>
28
+ <div class="option">
29
+ <textarea name="<?php echo $name ?>" class="codemirror" id="<?php echo $id ?>" rows="8" cols="50"><?php echo $db_value ?></textarea>
30
+ </div>
31
+ <span class="description"><?php echo $option['desc'] ?></span>
32
+
33
+ <div class="clear"></div>
34
+ </div>
35
+
36
+ <?php
37
+ wp_enqueue_script('codemirror');
38
+ wp_enqueue_script('codemirror-javascript');
39
+ wp_enqueue_style('codemirror');
40
+ ?>
plugin-fw/templates/panel/types/textarea.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ /**
12
+ * Textarea Plugin Admin View
13
+ *
14
+ * @package Yithemes
15
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
16
+ * @since 1.0.0
17
+ */
18
+
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit;
21
+ } // Exit if accessed directly
22
+
23
+ $id = $this->get_id_field( $option['id'] );
24
+ $name = $this->get_name_field( $option['id'] );
25
+
26
+ ?>
27
+ <div id="<?php echo $id ?>-container" class="yit_options rm_option rm_input rm_text" <?php if ( isset( $option['deps'] ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $this->get_id_field( $option['deps']['ids'] ) ?>" data-value="<?php echo $option['deps']['values'] ?>" <?php endif ?>>
28
+ <div class="option">
29
+ <textarea name="<?php echo $name ?>" id="<?php echo $id ?>" rows="8" cols="50"><?php echo $db_value ?></textarea>
30
+ </div>
31
+ <span class="description"><?php echo $option['desc'] ?></span>
32
+
33
+ <div class="clear"></div>
34
+ </div>
35
+
plugin-fw/templates/panel/types/upload.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ /**
12
+ * Upload Plugin Admin View
13
+ *
14
+ * @package Yithemes
15
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
16
+ * @since 1.0.0
17
+ */
18
+
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit;
21
+ } // Exit if accessed directly
22
+
23
+ $id = $this->get_id_field( $option['id'] );
24
+ $name = $this->get_name_field( $option['id'] );
25
+
26
+ ?>
27
+ <div id="<?php echo $id ?>-container" >
28
+ <div id="<?php echo $id ?>-container" class="yit_options rm_option rm_input rm_text rm_upload" <?php if ( isset( $option['deps'] ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $this->get_id_field( $option['deps']['ids'] ) ?>" data-value="<?php echo $option['deps']['values'] ?>" <?php endif ?>>
29
+ <div class="option">
30
+ <input type="text" name="<?php echo $name ?>" id="<?php echo $id ?>" value="<?php echo $db_value == '1' ? '' : esc_attr( $db_value ) ?>" class="upload_img_url" />
31
+ <input type="button" value="<?php _e( 'Upload', 'yit' ) ?>" id="<?php echo $id ?>-button" class="upload_button button" />
32
+ </div>
33
+ <div class="clear"></div>
34
+ <span class="description"><?php echo $option['desc'] ?></span>
35
+ </div>
36
+ <div class="upload_img_preview" style="margin-top:10px;">
37
+ <?php
38
+ $file = $db_value;
39
+ if ( preg_match( '/(jpg|jpeg|png|gif|ico)$/', $file ) ) {
40
+ echo "<img src=\"" . $this->settings['plugin-url'] . "/plugin-fw/assets/images/sleep.png\" data-src=\"$file\" />";
41
+ }
42
+ ?>
43
+ </div>
44
+ </div>
45
+
plugin-fw/templates/panel/woocommerce/woocommerce-boxinfo.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ /**
16
+ * 'section_general_settings_boxinfo' => array(
17
+ * 'name' => __( 'General information', 'yit' ),
18
+ * 'type' => 'boxinfo',
19
+ * 'default' => array(
20
+ * 'plugin_name' => __( 'Plugin Name', 'yit' ),
21
+ * 'buy_url' => 'http://www.yithemes.com',
22
+ * 'demo_url' => 'http://plugins.yithemes.com/demo-url/'
23
+ * ),
24
+ * 'id' => 'yith_wcas_general_boxinfo'
25
+ * ),
26
+ */
27
+ ?>
28
+ <div id="<?php echo $id ?>" class="meta-box-sortables">
29
+ <div id="<?php echo $id ?>-content-panel" class="postbox " style="display: block;">
30
+ <h3><?php echo $name ?></h3>
31
+ <div class="inside">
32
+ <p>Lorem ipsum ... </p>
33
+ <p class="submit"><a href="<?php echo $default['buy_url'] ?>" class="button-primary">Buy Plugin</a></p>
34
+ </div>
35
+ </div>
36
+ </div>
plugin-fw/templates/panel/woocommerce/woocommerce-form.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div id="<?php echo $this->settings['page']?>_<?php echo $this->get_current_tab()?>">
2
+ <form id="plugin-fw-wc" method="post">
3
+ <?php $this->add_fields() ?>
4
+ <?php wp_nonce_field( 'yit_panel_wc_options_'.$this->settings['page'], 'yit_panel_wc_options_nonce' ); ?>
5
+ <input style="float: left; margin-right: 10px;" class="button-primary" type="submit" value="<?php _e( 'Save Changes', 'yit' )?>"/>
6
+ </form>
7
+ <form id="plugin-fw-wc-reset" method="post">
8
+ <?php $warning = __( 'If you continue with this action, you will reset all options are in this page.', 'yit' ) ?>
9
+ <input type="hidden" name="yit-action" value="wc-options-reset" />
10
+ <input type="submit" name="yit-reset" class="button-secondary" value="<?php _e( 'Reset Defaults', 'yit' ) ?>" onclick="return confirm('<?php echo $warning . '\n' . __( 'Are you sure of it?', 'yit' ) ?>');" />
11
+ </form>
12
+ </div>
plugin-fw/templates/panel/woocommerce/woocommerce-panel.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php add_thickbox();?>
2
+ <div class="wrap">
3
+ <div id="icon-users" class="icon32"><br/></div>
4
+ <?php if( ! empty( $available_tabs ) ): ?>
5
+ <h2 class="nav-tab-wrapper woo-nav-tab-wrapper">
6
+ <?php foreach( $available_tabs as $id => $label ): ?>
7
+ <a href="?page=<?php echo $page ?>&tab=<?php echo $id ?>" class="nav-tab <?php echo ( $current_tab == $id ) ? 'nav-tab-active' : '' ?>"><?php echo $label ?></a>
8
+ <?php endforeach; ?>
9
+ </h2>
10
+ <?php $this->print_panel_content() ?>
11
+ <?php endif; ?>
12
+ </div>
plugin-fw/templates/panel/woocommerce/woocommerce-upload.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ /**
12
+ * Upload Plugin Admin View
13
+ *
14
+ * @package Yithemes
15
+ * @author Emanuela Castorina <emanuela.castorina@yithemes.it>
16
+ * @since 1.0.0
17
+ */
18
+
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit;
21
+ } // Exit if accessed directly
22
+
23
+
24
+ ?>
25
+
26
+ <tr valign="top">
27
+ <th scope="row" class="image_upload">
28
+ <label for="<?php echo $id ?>"><?php echo $name ?></label>
29
+ </th>
30
+ <td class="forminp forminp-color plugin-option">
31
+
32
+ <div id="<?php echo $id ?>-container" class="yit_options rm_option rm_input rm_text rm_upload" <?php if ( isset( $option['deps'] ) ): ?>data-field="<?php echo $id ?>" data-dep="<?php echo $this->get_id_field( $option['deps']['ids'] ) ?>" data-value="<?php echo $option['deps']['values'] ?>" <?php endif ?>>
33
+ <div class="option">
34
+ <input type="text" name="<?php echo $id ?>" id="<?php echo $id ?>" value="<?php echo $value == '1' ? '' : esc_attr( $value ) ?>" class="upload_img_url" />
35
+ <input type="button" value="<?php _e( 'Upload', 'yit' ) ?>" id="<?php echo $id ?>-button" class="upload_button button" />
36
+ </div>
37
+ <div class="clear"></div>
38
+ <span class="description"><?php echo $desc ?></span>
39
+ <div class="upload_img_preview" style="margin-top:10px;">
40
+ <?php
41
+ $file = $value;
42
+ if ( preg_match( '/(jpg|jpeg|png|gif|ico)$/', $file ) ) {
43
+ echo "<img src=\"" . YIT_CORE_PLUGIN_URL. "/assets/images/sleep.png\" data-src=\"$file\" />";
44
+ }
45
+ ?>
46
+ </div>
47
+ </div>
48
+
49
+
50
+ </td>
51
+ </tr>
52
+
plugin-fw/templates/panel/woocommerce/woocommerce-videobox.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ /**
16
+ * Example to call this template
17
+ *
18
+ * 'section_general_settings_videobox' => array(
19
+ * 'name' => __( 'Title of box', 'yit' ),
20
+ * 'type' => 'videobox',
21
+ * 'default' => array(
22
+ * 'plugin_name' => __( 'Plugin Name', 'yit' ),
23
+ * 'title_first_column' => __( 'Title first column', 'yit' ),
24
+ * 'description_first_column' => __('Lorem ipsum ... ', 'yit'),
25
+ * 'video' => array(
26
+ * 'video_id' => 'vimeo_code',
27
+ * 'video_image_url' => '#',
28
+ * 'video_description' => __( 'Lorem ipsum dolor sit amet....', 'yit' ),
29
+ * ),
30
+ * 'title_second_column' => __( 'Title first column', 'yit' ),
31
+ * 'description_second_column' => __('Lorem ipsum dolor sit amet.... ', 'yit'),
32
+ * 'button' => array(
33
+ * 'href' => 'http://www.yithemes.com',
34
+ * 'title' => 'Get Support and Pro Features'
35
+ * )
36
+ * ),
37
+ * 'id' => 'yith_wcas_general_videobox'
38
+ * ),
39
+ */
40
+ ?>
41
+ <div id="normal-sortables" class="meta-box-sortables">
42
+ <div id="<?php echo $id ?>" class="postbox ">
43
+ <h3><span><?php echo $name ?></span></h3>
44
+ <div class="inside">
45
+ <div class="yith_videobox">
46
+ <div class="column"><h2><?php echo $default['title_first_column'] ?></h2>
47
+ <?php if ( isset( $default['video'] ) && !empty( $default['video'] ) ): ?>
48
+ <a class="yith-video-link" href="#" data-video-id="yith-video-iframe">
49
+ <img src="<?php echo $default['video']['video_image_url'] ?>">
50
+ </a>
51
+
52
+ <p class="yit-video-description">
53
+ <?php echo $default['video']['video_description'] ?>
54
+ </p>
55
+
56
+ <p class="yith-video-iframe">
57
+ <iframe src="//player.vimeo.com/video/<?php echo $default['video']['video_id'] ?>?title=0&amp;byline=0&amp;portrait=0" width="853" height="480" frameborder="0"></iframe>
58
+ </p>
59
+ <?php endif ?>
60
+ <?php if ( isset( $default['image'] ) && !empty( $default['image'] ) ): ?>
61
+ <a href="<?php echo $default['image']['image_link'] ?>" target="_blank" class="yith-image-frame">
62
+ <img src="<?php echo $default['image']['image_url'] ?>">
63
+ </a>
64
+ <?php endif ?>
65
+ <?php if ( isset( $default['description_first_column'] ) && $default['description_first_column'] != '' ): ?>
66
+ <p><?php echo $default['description_first_column'] ?></p>
67
+ <?php endif ?>
68
+ </div>
69
+ <div class="column two">
70
+ <h2><?php echo $default['title_second_column'] ?>?</h2>
71
+
72
+ <p><?php echo $default['description_second_column'] ?></p>
73
+
74
+ <?php if ( isset( $default['button'] ) && !empty( $default['button'] ) ): ?>
75
+ <p>
76
+ <a class="button-primary" href="<?php echo $default['button']['href'] ?>" target="_blank"><?php echo $default['button']['title'] ?></a>
77
+ </p>
78
+ <?php endif ?>
79
+ </div>
80
+ </div>
81
+ </div>
82
+ </div>
83
+ </div>
plugin-fw/yit-deactive-plugin.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file belongs to the YIT Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! function_exists( 'yit_deactive_free_version' ) ) {
12
+ function yit_deactive_free_version( $to_deactive, $to_active ) {
13
+
14
+ if ( ! function_exists( 'is_plugin_active' ) ) {
15
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
16
+ }
17
+
18
+ if ( defined( $to_deactive ) && is_plugin_active( constant( $to_deactive ) ) ) {
19
+ deactivate_plugins( constant( $to_deactive ) );
20
+
21
+ if( ! function_exists( 'wp_create_nonce' ) ){
22
+ header( 'Location: plugins.php');
23
+ exit();
24
+ }
25
+
26
+
27
+ global $status, $page, $s;
28
+ $redirect = 'plugins.php?action=activate&plugin=' . $to_active . '&plugin_status=' . $status . '&paged=' . $page . '&s=' . $s;
29
+ $redirect = add_query_arg( '_wpnonce', wp_create_nonce( 'activate-plugin_' . $to_active ), $redirect );
30
+
31
+ header( 'Location: ' . $redirect );
32
+ exit();
33
+ }
34
+ }
35
+ }
plugin-fw/yit-functions.php ADDED
@@ -0,0 +1,815 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file belongs to the YIT Plugin Framework.
4
+ *
5
+ * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
6
+ * that is bundled with this package in the file LICENSE.txt.
7
+ * It is also available through the world-wide-web at this URL:
8
+ * http://www.gnu.org/licenses/gpl-3.0.txt
9
+ */
10
+
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ } // Exit if accessed directly
14
+
15
+ if ( ! function_exists( 'yit_plugin_locate_template' ) ) {
16
+ /**
17
+ * Locate the templates and return the path of the file found
18
+ *
19
+ * @param string $plugin_basename
20
+ * @param string $path
21
+ * @param array $var
22
+ *
23
+ * @return string
24
+ * @since 2.0.0
25
+ */
26
+ function yit_plugin_locate_template( $plugin_basename, $path, $var = NULL ) {
27
+
28
+ $template_path = '/theme/templates/' . $path;
29
+
30
+ $located = locate_template( array(
31
+ $template_path
32
+ ) );
33
+
34
+ if ( ! $located ) {
35
+ $located = $plugin_basename . '/templates/' . $path;
36
+ }
37
+
38
+ return $located;
39
+ }
40
+
41
+ }
42
+
43
+ if ( ! function_exists( 'yit_plugin_get_template' ) ) {
44
+ /**
45
+ * Retrieve a template file.
46
+ *
47
+ * @param string $plugin_basename
48
+ * @param string $path
49
+ * @param mixed $var
50
+ * @param bool $return
51
+ *
52
+ * @return string
53
+ * @since 2.0.0
54
+ */
55
+ function yit_plugin_get_template( $plugin_basename, $path, $var = null, $return = false ) {
56
+
57
+ $located = yit_plugin_locate_template( $plugin_basename, $path, $var );
58
+
59
+ if ( $var && is_array( $var ) ) {
60
+ extract( $var );
61
+ }
62
+
63
+ if ( $return ) {
64
+ ob_start();
65
+ }
66
+
67
+ // include file located
68
+ include( $located );
69
+
70
+ if ( $return ) {
71
+ return ob_get_clean();
72
+ }
73
+ }
74
+ }
75
+
76
+ if ( ! function_exists( 'yit_plugin_content' ) ) {
77
+ /**
78
+ * Return post content with read more link (if needed)
79
+ *
80
+ * @param string $what
81
+ * @param int|string $limit
82
+ * @param string $more_text
83
+ * @param string $split
84
+ * @param string $in_paragraph
85
+ *
86
+ * @return string
87
+ * @since 2.0.0
88
+ */
89
+ function yit_plugin_content( $what = 'content', $limit = 25, $more_text = '', $split = '[...]', $in_paragraph = 'true' ) {
90
+ if ( $what == 'content' ) {
91
+ $content = get_the_content( $more_text );
92
+ }
93
+ else {
94
+ if ( $what == 'excerpt' ) {
95
+ $content = get_the_excerpt();
96
+ }
97
+ else {
98
+ $content = $what;
99
+ }
100
+ }
101
+
102
+ if ( $limit == 0 ) {
103
+ if ( $what == 'excerpt' ) {
104
+ $content = apply_filters( 'the_excerpt', $content );
105
+ }
106
+ else {
107
+ $content = preg_replace( '/<img[^>]+./', '', $content ); //remove images
108
+ $content = apply_filters( 'the_content', $content );
109
+ $content = str_replace( ']]>', ']]&gt;', $content );
110
+ }
111
+
112
+ return $content;
113
+ }
114
+
115
+ // remove the tag more from the content
116
+ if ( preg_match( "/<(a)[^>]*class\s*=\s*(['\"])more-link\\2[^>]*>(.*?)<\/\\1>/", $content, $matches ) ) {
117
+
118
+ if ( strpos( $matches[0], '[button' ) ) {
119
+ $more_link = str_replace( 'href="#"', 'href="' . get_permalink() . '"', do_shortcode( $matches[3] ) );
120
+ }
121
+ else {
122
+ $more_link = $matches[0];
123
+ }
124
+
125
+ $content = str_replace( $more_link, '', $content );
126
+ $split = '';
127
+ }
128
+
129
+ if ( empty( $content ) ) {
130
+ return;
131
+ }
132
+ $content = explode( ' ', $content );
133
+
134
+ if ( ! empty( $more_text ) && ! isset( $more_link ) ) {
135
+ //array_pop( $content );
136
+ $more_link = strpos( $more_text, '<a class="btn"' ) ? $more_text : '<a class="read-more' . apply_filters( 'yit_simple_read_more_classes', ' ' ) . '" href="' . get_permalink() . '">' . $more_text . '</a>';
137
+ $split = '';
138
+ }
139
+ elseif ( ! isset( $more_link ) ) {
140
+ $more_link = '';
141
+ }
142
+
143
+ // split
144
+ if ( count( $content ) >= $limit ) {
145
+ $split_content = '';
146
+ for ( $i = 0; $i < $limit; $i ++ ) {
147
+ $split_content .= $content[$i] . ' ';
148
+ }
149
+
150
+ $content = $split_content . $split;
151
+ }
152
+ else {
153
+ $content = implode( " ", $content );
154
+ }
155
+
156
+ // TAGS UNCLOSED
157
+ $tags = array();
158
+ // get all tags opened
159
+ preg_match_all( "/(<([\w]+)[^>]*>)/", $content, $tags_opened, PREG_SET_ORDER );
160
+ foreach ( $tags_opened as $tag ) {
161
+ $tags[] = $tag[2];
162
+ }
163
+
164
+ // get all tags closed and remove it from the tags opened.. the rest will be closed at the end of the content
165
+ preg_match_all( "/(<\/([\w]+)[^>]*>)/", $content, $tags_closed, PREG_SET_ORDER );
166
+ foreach ( $tags_closed as $tag ) {
167
+ unset( $tags[array_search( $tag[2], $tags )] );
168
+ }
169
+
170
+ // close the tags
171
+ if ( ! empty( $tags ) ) {
172
+ foreach ( $tags as $tag ) {
173
+ $content .= "</$tag>";
174
+ }
175
+ }
176
+
177
+ //$content = preg_replace( '/\[.+\]/', '', $content );
178
+ if ( $in_paragraph == true ): $content .= $more_link; endif;
179
+ $content = preg_replace( '/<img[^>]+./', '', $content ); //remove images
180
+ $content = apply_filters( 'the_content', $content );
181
+ $content = str_replace( ']]>', ']]&gt;', $content ); // echo str_replace( array( '<', '>' ), array( '&lt;', '&gt;' ), $content );
182
+ if ( $in_paragraph == false ): $content .= $more_link; endif;
183
+
184
+ return $content;
185
+ }
186
+ }
187
+
188
+ if ( ! function_exists( 'yit_plugin_string' ) ) {
189
+ /**
190
+ * Simple echo a string, with a before and after string, only if the main string is not empty.
191
+ *
192
+ * @param string $before What there is before the main string
193
+ * @param string $string The main string. If it is empty or null, the functions return null.
194
+ * @param string $after What there is after the main string
195
+ * @param bool $echo If echo or only return it
196
+ *
197
+ * @return string The complete string, if the main string is not empty or null
198
+ * @since 2.0.0
199
+ */
200
+ function yit_plugin_string( $before = '', $string = '', $after = '', $echo = true ) {
201
+ $html = '';
202
+
203
+ if ( $string != '' AND ! is_null( $string ) ) {
204
+ $html = $before . $string . $after;
205
+ }
206
+
207
+ if ( $echo ) {
208
+ echo $html;
209
+ }
210
+
211
+ return $html;
212
+ }
213
+ }
214
+
215
+ if ( ! function_exists( 'yit_plugin_decode_title' ) ) {
216
+ /**
217
+ * Change some special characters to put easily html into a string
218
+ *
219
+ * E.G.
220
+ * string: This is [my title] with | a new line
221
+ * return: This is <span class="title-highlight">my title</span> with <br /> a new line
222
+ *
223
+ * @param string $title The string to convert
224
+ *
225
+ * @return string The html
226
+ *
227
+ * @since 1.0
228
+ */
229
+ function yit_plugin_decode_title( $title ) {
230
+ $replaces = apply_filters( 'yit_title_special_characters', array() );
231
+
232
+ return preg_replace( array_keys( $replaces ), array_values( $replaces ), $title );
233
+ }
234
+ }
235
+
236
+ if ( ! function_exists( 'yit_plugin_get_attachment_id' ) ) {
237
+
238
+ /**
239
+ * Return the ID of an attachment.
240
+ *
241
+ * @param string $url
242
+ *
243
+ * @return int
244
+ *
245
+ * @since 2.0.0
246
+ */
247
+
248
+ function yit_plugin_get_attachment_id( $url ) {
249
+
250
+ $upload_dir = wp_upload_dir();
251
+ $dir = trailingslashit( $upload_dir['baseurl'] );
252
+
253
+ if ( false === strpos( $url, $dir ) ) {
254
+ return false;
255
+ }
256
+
257
+ $file = basename( $url );
258
+
259
+ $query = array(
260
+ 'post_type' => 'attachment',
261
+ 'fields' => 'ids',
262
+ 'meta_query' => array(
263
+ array(
264
+ 'value' => $file,
265
+ 'compare' => 'LIKE',
266
+ )
267
+ )
268
+ );
269
+
270
+ $query['meta_query'][0]['key'] = '_wp_attached_file';
271
+ $ids = get_posts( $query );
272
+
273
+ foreach ( $ids as $id ) {
274
+ $attachment_image = wp_get_attachment_image_src( $id, 'full' );
275
+ if ( $url == str_replace( 'https://', 'http://', array_shift( $attachment_image ) ) ) {
276
+ return $id;
277
+ }
278
+ }
279
+ $query['meta_query'][0]['key'] = '_wp_attachment_metadata';
280
+ $ids = get_posts( $query );
281
+
282
+ foreach ( $ids as $id ) {
283
+
284
+ $meta = wp_get_attachment_metadata( $id );
285
+ if ( ! isset( $meta['sizes'] ) ) {
286
+ continue;
287
+ }
288
+
289
+ foreach ( (array) $meta['sizes'] as $size => $values ) {
290
+ if ( $values['file'] == $file && $url == str_replace( 'https://', 'http://', array_shift( wp_get_attachment_image_src( $id, $size ) ) ) ) {
291
+
292
+ return $id;
293
+ }
294
+ }
295
+ }
296
+
297
+ return false;
298
+ }
299
+ }
300
+
301
+ if ( ! function_exists( 'yit_enqueue_script' ) ) {
302
+ /**
303
+ * Enqueues script.
304
+ *
305
+ * Registers the script if src provided (does NOT overwrite) and enqueues.
306
+ *
307
+ * @since 2.0.0
308
+ * @author Simone D'Amico <simone.damico@yithemes.com>
309
+ * @see yit_register_script() For parameter information.
310
+ */
311
+ function yit_enqueue_script( $handle, $src, $deps = array(), $ver = false, $in_footer = true ) {
312
+
313
+ if ( function_exists( 'YIT_Asset' ) && ! is_admin() ) {
314
+ $enqueue = true;
315
+ YIT_Asset()->set( 'script', $handle, compact( 'src', 'deps', 'ver', 'in_footer', 'enqueue' ) );
316
+ }
317
+ else {
318
+ wp_enqueue_script( $handle, $src, $deps, $ver, $in_footer );
319
+ }
320
+ }
321
+ }
322
+
323
+ if ( ! function_exists( 'yit_enqueue_style' ) ) {
324
+ /**
325
+ * Enqueues style.
326
+ *
327
+ * Registers the style if src provided (does NOT overwrite) and enqueues.
328
+ *
329
+ * @since 2.0.0
330
+ * @author Simone D'Amico <simone.damico@yithemes.com>
331
+ * @see yit_register_style() For parameter information.
332
+ */
333
+ function yit_enqueue_style( $handle, $src, $deps = array(), $ver = false, $media = 'all' ) {
334
+
335
+ if ( function_exists( 'YIT_Asset' ) ) {
336
+ $enqueue = true;
337
+ $who = YIT_Asset()->get_stylesheet_handle( get_stylesheet_uri(), 'style' );
338
+ $where = 'before';
339
+
340
+ YIT_Asset()->set( 'style', $handle, compact( 'src', 'deps', 'ver', 'media', 'enqueue' ), $where, $who );
341
+ }
342
+ else {
343
+ wp_enqueue_style( $handle, $src, $deps, $ver, $media );
344
+ }
345
+ }
346
+ }
347
+
348
+ if ( ! function_exists( 'yit_get_post_meta' ) ) {
349
+ /**
350
+ * Retrieve the value of a metabox.
351
+ *
352
+ * This function retrieve the value of a metabox attached to a post. It return either a single value or an array.
353
+ *
354
+ * @param int $id Post ID.
355
+ * @param string $meta The meta key to retrieve.
356
+ *
357
+ * @return mixed Single value or array
358
+ * @since 2.0.0
359
+ */
360
+ function yit_get_post_meta( $id, $meta ) {
361
+ if ( ! strpos( $meta, '[' ) ) {
362
+ return get_post_meta( $id, $meta, true );
363
+ }
364
+
365
+ $sub_meta = explode( '[', $meta );
366
+
367
+ $meta = get_post_meta( $id, $meta, true );
368
+ for ( $i = 0; $i < count( $sub_meta ); $i ++ ) {
369
+ $meta = $meta[rtrim( $sub_meta[$i], ']' )];
370
+ }
371
+
372
+ return $meta;
373
+ }
374
+ }
375
+
376
+ if ( ! function_exists( 'yit_string' ) ) {
377
+ /**
378
+ * Simple echo a string, with a before and after string, only if the main string is not empty.
379
+ *
380
+ * @param string $before What there is before the main string
381
+ * @param string $string The main string. If it is empty or null, the functions return null.
382
+ * @param string $after What there is after the main string
383
+ * @param bool $echo If echo or only return it
384
+ *
385
+ * @return string The complete string, if the main string is not empty or null
386
+ * @since 2.0.0
387
+ */
388
+ function yit_string( $before = '', $string = '', $after = '', $echo = true ) {
389
+ $html = '';
390
+
391
+ if ( $string != '' AND ! is_null( $string ) ) {
392
+ $html = $before . $string . $after;
393
+ }
394
+
395
+ if ( $echo ) {
396
+ echo $html;
397
+ }
398
+
399
+ return $html;
400
+ }
401
+ }
402
+
403
+
404
+ if ( ! function_exists( 'yit_pagination' ) ) {
405
+ /**
406
+ * Print pagination
407
+ *
408
+ * @param string $pages
409
+ * @param int $range
410
+ *
411
+ * @return string
412
+ * @since 2.0.0
413
+ */
414
+ function yit_pagination( $pages = '', $range = 10 ) {
415
+ $showitems = ( $range * 2 ) + 1;
416
+
417
+ $paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : false;
418
+ if ( $paged === false ) {
419
+ $paged = ( get_query_var( 'page' ) ) ? get_query_var( 'page' ) : false;
420
+ }
421
+ if ( $paged === false ) {
422
+ $paged = 1;
423
+ }
424
+
425
+
426
+ $html = '';
427
+
428
+ if ( $pages == '' ) {
429
+ global $wp_query;
430
+
431
+ if ( isset( $wp_query->max_num_pages ) ) {
432
+ $pages = $wp_query->max_num_pages;
433
+ }
434
+
435
+ if ( ! $pages ) {
436
+ $pages = 1;
437
+ }
438
+ }
439
+
440
+ if ( 1 != $pages ) {
441
+ $html .= "<div class='general-pagination clearfix'>";
442
+ if ( $paged > 2 ) {
443
+ $html .= sprintf( '<a class="%s" href="%s">&laquo;