Child Theme Configurator - Version 1.6.4

Version Description

  • New Feature: Copy selector button for Raw CSS textarea on Query/Selector tab.
  • Fix: Menus rendering incorrectly for RTL locales
  • Fix: Border-top etc. not being written correctly to stylesheet
  • Fix: Refactored ajax semaphore logic and flow
Download this release

Release Info

Developer lilaeamedia
Plugin Icon 128x128 Child Theme Configurator
Version 1.6.4
Comparing to
See all releases

Code changes from version 1.6.3 to 1.6.4

child-theme-configurator.php CHANGED
@@ -6,7 +6,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
6
  Plugin Name: Child Theme Configurator
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Create a Child Theme and customize the stylesheet as you wish. Search, preview and modify any selector, rule or value using this fast CSS editor.
9
- Version: 1.6.3
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
@@ -16,17 +16,19 @@ if ( !defined( 'ABSPATH' ) ) exit;
16
  */
17
 
18
  defined( 'LF' ) or define( 'LF', "\n" );
19
- defined( 'CHLD_THM_CFG_OPTIONS' ) or define( 'CHLD_THM_CFG_OPTIONS', 'chld_thm_cfg_options' );
20
- defined( 'CHLD_THM_CFG_VERSION' ) or define( 'CHLD_THM_CFG_VERSION', '1.6.3' );
21
- defined( 'CHLD_THM_CFG_MIN_WP_VERSION' ) or define( 'CHLD_THM_CFG_MIN_WP_VERSION', '3.7' );
22
- defined( 'CHLD_THM_CFG_MAX_SELECTORS' ) or define( 'CHLD_THM_CFG_MAX_SELECTORS', '50000' );
23
- defined( 'CHLD_THM_CFG_MAX_RECURSE_LOOPS' ) or define( 'CHLD_THM_CFG_MAX_RECURSE_LOOPS', '1000' );
24
- defined( 'CHLD_THM_CFG_MENU' ) or define( 'CHLD_THM_CFG_MENU', 'chld_thm_cfg_menu' );
 
 
25
 
26
  class ChildThemeConfigurator {
27
  static function init() {
28
  // initialize languages
29
- load_plugin_textdomain( 'chld_thm_cfg', FALSE, basename( dirname( __FILE__ ) ) . '/lang' );
30
  // verify WP version support
31
  global $wp_version;
32
  if ( version_compare( $wp_version, CHLD_THM_CFG_MIN_WP_VERSION ) < 0 ):
@@ -34,8 +36,10 @@ if ( !defined( 'ABSPATH' ) ) exit;
34
  return;
35
  endif;
36
  // setup admin hooks
37
- add_action( 'network_admin_menu', 'ChildThemeConfigurator::network_admin' );
38
- add_action( 'admin_menu', 'ChildThemeConfigurator::admin' );
 
 
39
  // setup ajax actions
40
  add_action( 'wp_ajax_ctc_update', 'ChildThemeConfigurator::save' );
41
  add_action( 'wp_ajax_ctc_query', 'ChildThemeConfigurator::query' );
@@ -93,16 +97,17 @@ if ( !defined( 'ABSPATH' ) ) exit;
93
  }
94
  static function version_notice() {
95
  deactivate_plugins( plugin_basename( __FILE__ ) );
96
- unset( $_GET['activate'] );
97
  echo '<div class="update-nag"><p>' . sprintf( __( 'Child Theme Configurator requires WordPress version %s or later.', 'chld_thm_cfg' ), CHLD_THM_CFG_MIN_WP_VERSION ) . '</p></div>' . LF;
98
  }
99
  }
100
 
101
- if ( is_admin() ) ChildThemeConfigurator::init();
 
102
 
103
- register_uninstall_hook( __FILE__, 'chld_thm_cfg_delete_plugin' );
104
 
105
- function chld_thm_cfg_delete_plugin() {
106
  delete_option( CHLD_THM_CFG_OPTIONS );
107
  delete_option( CHLD_THM_CFG_OPTIONS . '_configvars' );
108
  delete_option( CHLD_THM_CFG_OPTIONS . '_dict_qs' );
6
  Plugin Name: Child Theme Configurator
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Create a Child Theme and customize the stylesheet as you wish. Search, preview and modify any selector, rule or value using this fast CSS editor.
9
+ Version: 1.6.4
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
16
  */
17
 
18
  defined( 'LF' ) or define( 'LF', "\n" );
19
+ define( 'CHLD_THM_CFG_OPTIONS', 'chld_thm_cfg_options' );
20
+ define( 'CHLD_THM_CFG_VERSION', '1.6.4' );
21
+ define( 'CHLD_THM_CFG_MIN_WP_VERSION', '3.7' );
22
+ define( 'CHLD_THM_CFG_MAX_SELECTORS', '50000' );
23
+ define( 'CHLD_THM_CFG_MAX_RECURSE_LOOPS', '1000' );
24
+ define( 'CHLD_THM_CFG_MENU', 'chld_thm_cfg_menu' );
25
+ define( 'CHLD_THM_CFG_DIR', dirname( __FILE__ ) );
26
+ define( 'CHLD_THM_CFG_URL', plugin_dir_url( __FILE__ ) );
27
 
28
  class ChildThemeConfigurator {
29
  static function init() {
30
  // initialize languages
31
+ load_plugin_textdomain( 'chld_thm_cfg', FALSE, basename( CHLD_THM_CFG_DIR ) . '/lang' );
32
  // verify WP version support
33
  global $wp_version;
34
  if ( version_compare( $wp_version, CHLD_THM_CFG_MIN_WP_VERSION ) < 0 ):
36
  return;
37
  endif;
38
  // setup admin hooks
39
+ if ( is_multisite() )
40
+ add_action( 'network_admin_menu', 'ChildThemeConfigurator::network_admin' );
41
+ else
42
+ add_action( 'admin_menu', 'ChildThemeConfigurator::admin' );
43
  // setup ajax actions
44
  add_action( 'wp_ajax_ctc_update', 'ChildThemeConfigurator::save' );
45
  add_action( 'wp_ajax_ctc_query', 'ChildThemeConfigurator::query' );
97
  }
98
  static function version_notice() {
99
  deactivate_plugins( plugin_basename( __FILE__ ) );
100
+ unset( $_GET[ 'activate' ] );
101
  echo '<div class="update-nag"><p>' . sprintf( __( 'Child Theme Configurator requires WordPress version %s or later.', 'chld_thm_cfg' ), CHLD_THM_CFG_MIN_WP_VERSION ) . '</p></div>' . LF;
102
  }
103
  }
104
 
105
+ if ( is_admin() )
106
+ add_action( 'plugins_loaded', 'ChildThemeConfigurator::init' );
107
 
108
+ register_uninstall_hook( __FILE__, 'chld_thm_cfg_uninstall' );
109
 
110
+ function chld_thm_cfg_uninstall() {
111
  delete_option( CHLD_THM_CFG_OPTIONS );
112
  delete_option( CHLD_THM_CFG_OPTIONS . '_configvars' );
113
  delete_option( CHLD_THM_CFG_OPTIONS . '_dict_qs' );
css/chld-thm-cfg.css CHANGED
@@ -6,16 +6,38 @@ a.nav-tab, a.nav-tab:focus, a.nav-tab:active {
6
  box-shadow: none;
7
  }
8
 
9
- .nav-tab-active {
10
- /*background-color:#f9f9f9;*/
11
- }
12
-
13
  .ctc-option-panel-container {
14
  position: relative;
15
- min-height: 600px;
16
- max-height: 800px;
17
  overflow: auto;
18
- border-bottom: 1px solid #f9f9f9;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  }
20
 
21
  #view_child_options_panel, #view_parnt_options_panel {
@@ -28,10 +50,52 @@ a.nav-tab, a.nav-tab:focus, a.nav-tab:active {
28
  .ctc-option-panel {
29
  visibility: hidden;
30
  position: absolute;
31
- width: 96%;
 
32
  top: 0;
33
  left: 0;
34
  padding: 10px 2%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  }
36
 
37
  .ctc-option-panel-active {
@@ -71,17 +135,16 @@ a.nav-tab, a.nav-tab:focus, a.nav-tab:active {
71
  .ctc-input-cell {
72
  display: block;
73
  float: left;
74
- width: 25%;
75
- max-width: 250px;
76
- margin-right: 2.13%;
77
  word-wrap: break-word;
78
  }
79
 
80
  .ctc-input-cell-wide {
81
  display: block;
82
  float: left;
83
- width: 70%;
84
- margin-right: 2.13%;
85
  }
86
 
87
  .ctc-input-cell-wide textarea {
@@ -97,14 +160,14 @@ a.nav-tab, a.nav-tab:focus, a.nav-tab:active {
97
  }
98
 
99
  .ctc-button-cell, .ctc-input-cell.ctc-button-cell {
100
- width: 85px;
101
  }
102
 
103
  .ctc-textarea-button-cell {
104
- margin: 4px 0 15px;
105
- width: 85px;
106
  text-align: right;
107
- float:right;
108
  }
109
 
110
  .ctc-selector-link {
@@ -140,7 +203,11 @@ a.nav-tab, a.nav-tab:focus, a.nav-tab:active {
140
  .ctc-selector-inner-container {
141
  position: relative;
142
  max-height: 500px;
143
- overflow: auto;
 
 
 
 
144
  }
145
 
146
  .ctc-status-icon.success {
@@ -211,7 +278,7 @@ a.nav-tab, a.nav-tab:focus, a.nav-tab:active {
211
  .ctc-child-input-cell {
212
  display: block;
213
  float: left;
214
- margin-right: 2.13%;
215
  }
216
 
217
  .ctc-child-input-cell-container {
@@ -231,6 +298,10 @@ a.nav-tab, a.nav-tab:focus, a.nav-tab:active {
231
  /*width:60px;*/
232
  }
233
 
 
 
 
 
234
  .ctc-select {
235
  max-width: 100%;
236
  }
@@ -282,6 +353,9 @@ a.nav-tab, a.nav-tab:focus, a.nav-tab:active {
282
  padding: 3px 1em 3px 0.4em;
283
  cursor: pointer;
284
  min-height: 0px;
 
 
 
285
  }
286
 
287
  /*** Added in 1.6.0 for new options ***/
@@ -289,6 +363,7 @@ a.nav-tab, a.nav-tab:focus, a.nav-tab:active {
289
  /*margin:0;
290
  padding:0;*/
291
  position: relative;
 
292
  }
293
 
294
  .ctc-section-toggle:after {
@@ -432,3 +507,35 @@ h3.theme-name {
432
  text-overflow: ellipsis;
433
  white-space: nowrap;
434
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  box-shadow: none;
7
  }
8
 
 
 
 
 
9
  .ctc-option-panel-container {
10
  position: relative;
11
+ min-height: 1100px;
12
+ width:100%;
13
  overflow: auto;
14
+ }
15
+ #all_styles_panel {
16
+ -moz-columns:3;
17
+ -moz-column-gap:3em;
18
+ -webkit-columns:3;
19
+ -webkit-column-gap:3em;
20
+ columns:3;
21
+ column-gap:3em;
22
+ }
23
+ #ctc_recent_selectors ul li, #all_styles_panel ul li {
24
+ margin: 0;
25
+ }
26
+
27
+ #ctc_recent_selectors ul li a, #all_styles_panel ul li a {
28
+ text-decoration: none;
29
+ font-size: .8em;
30
+ line-height: 1.2;
31
+ word-wrap: break-word;
32
+ display: block;
33
+ padding: .5em;
34
+ }
35
+
36
+ #ctc_recent_selectors ul li a:hover, #ctc_recent_selectors ul li a:focus, #all_styles_panel ul li a:hover, #all_styles_panel ul li a:focus {
37
+ background-color: #fff;
38
+ -webkit-box-shadow: none;
39
+ -moz-box-shadow: none;
40
+ box-shadow: none;
41
  }
42
 
43
  #view_child_options_panel, #view_parnt_options_panel {
50
  .ctc-option-panel {
51
  visibility: hidden;
52
  position: absolute;
53
+ /* overflow:auto; */
54
+ width: 95%;
55
  top: 0;
56
  left: 0;
57
  padding: 10px 2%;
58
+ transition: width 1s ease;
59
+ -moz-transition: width 1s ease;
60
+ -webkit-transition: width 1s ease;
61
+ -o-transition: width 1s ease;
62
+ }
63
+ .ctc-recent-container {
64
+ top:0;
65
+ right:0;
66
+ position:absolute;
67
+ max-width: 200px;
68
+ width: 17%;
69
+ display: none;
70
+ overflow: auto;
71
+ visibility:visible;
72
+ left:inherit;
73
+ background-color: #E4E4E4;
74
+ }
75
+ #ctc_recent_selectors {
76
+ padding: 0 8px;
77
+ }
78
+ a.ctc-recent-tab {
79
+ float:right;
80
+ border:1px solid #ccc;
81
+ background-color: #E4E4E4;
82
+ color: #555;
83
+ display: inline-block;
84
+ text-decoration: none;
85
+ /*margin:0;*/
86
+ margin: -1px 0 0 0;
87
+ box-shadow: none;
88
+ -moz-box-shadow:none;
89
+ -webkit-box-shadow: none;
90
+ outline:none;
91
+ }
92
+ h2 .ctc-recent-tab {
93
+ padding: 6px 10px;
94
+ font-weight: 700;
95
+ font-size: 15px;
96
+ line-height: 24px;
97
+ }
98
+ .ctc-recent-tab h3 {
99
  }
100
 
101
  .ctc-option-panel-active {
135
  .ctc-input-cell {
136
  display: block;
137
  float: left;
138
+ width: 30%;
139
+ margin-right: 2%;
 
140
  word-wrap: break-word;
141
  }
142
 
143
  .ctc-input-cell-wide {
144
  display: block;
145
  float: left;
146
+ width: 60%;
147
+ margin-right: 2%;
148
  }
149
 
150
  .ctc-input-cell-wide textarea {
160
  }
161
 
162
  .ctc-button-cell, .ctc-input-cell.ctc-button-cell {
163
+ /*width: 85px;*/
164
  }
165
 
166
  .ctc-textarea-button-cell {
167
+ margin: 4px 10px 15px;
168
+ /*width: 85px;*/
169
  text-align: right;
170
+ float: right;
171
  }
172
 
173
  .ctc-selector-link {
203
  .ctc-selector-inner-container {
204
  position: relative;
205
  max-height: 500px;
206
+ /*overflow: auto;*/
207
+ }
208
+
209
+ .ctc-status-icon {
210
+ /*max-width: 4%;*/
211
  }
212
 
213
  .ctc-status-icon.success {
278
  .ctc-child-input-cell {
279
  display: block;
280
  float: left;
281
+ margin-right: 2%;
282
  }
283
 
284
  .ctc-child-input-cell-container {
298
  /*width:60px;*/
299
  }
300
 
301
+ .ctc-disabled {
302
+ opacity: 0.5;
303
+ }
304
+
305
  .ctc-select {
306
  max-width: 100%;
307
  }
353
  padding: 3px 1em 3px 0.4em;
354
  cursor: pointer;
355
  min-height: 0px;
356
+ overflow: hidden;
357
+ text-overflow: ellipsis;
358
+ max-width: 450px;
359
  }
360
 
361
  /*** Added in 1.6.0 for new options ***/
363
  /*margin:0;
364
  padding:0;*/
365
  position: relative;
366
+ cursor: pointer;
367
  }
368
 
369
  .ctc-section-toggle:after {
507
  text-overflow: ellipsis;
508
  white-space: nowrap;
509
  }
510
+ /* get pro tab styles */
511
+ #get_pro_panel h1 {
512
+ font-size:1.75em;
513
+ color: rgb(198, 66, 0);
514
+ }
515
+ #get_pro_panel h3 {
516
+ font-size:1.4em;
517
+ margin-bottom:0;
518
+ }
519
+
520
+ #get_pro_panel p {
521
+ font-size:1.15em;
522
+ margin: .5em 0;
523
+ }
524
+ #get_pro_panel ul {
525
+ list-style: square;
526
+ }
527
+ #get_pro_panel li {
528
+ margin-left:2em;
529
+ }
530
+ #get_pro_panel h3 a {
531
+ display: inline-block;
532
+ padding:5px 10px;
533
+ background-color: rgb(198, 66, 0);
534
+ color: #fff;
535
+ text-decoration: none;
536
+ }
537
+
538
+ #get_pro_panel h3 a:hover {
539
+ background-color: #FF902E;
540
+ color: #fff;
541
+ }
css/pro-banner.jpg ADDED
Binary file
includes/class-ctc-css.php CHANGED
@@ -6,7 +6,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
6
  Class: ChildThemeConfiguratorCSS
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Handles all CSS output, parsing, normalization
9
- Version: 1.6.3
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
@@ -36,9 +36,10 @@ class ChildThemeConfiguratorCSS {
36
  var $styles; // temporary update cache
37
  var $child; // child theme slug
38
  var $parnt; // parent theme slug
39
- var $parntss; // parent additional stylesheets
 
 
40
  var $enqueue; // load parent css method (enqueue, import, none)
41
- var $configtype; // theme or plugin extension
42
  var $child_name; // child theme name
43
  var $child_author; // stylesheet author
44
  var $child_version; // stylesheet version
@@ -51,7 +52,7 @@ class ChildThemeConfiguratorCSS {
51
  'transform'
52
  );
53
  var $configvars = array(
54
- 'parntss',
55
  // the enqueue flag prevents the transition from 1.5.4
56
  // from breaking the stylesheet by forcing the user to regenerate
57
  // the config data before updating the stylesheet. Otherwise,
@@ -62,14 +63,15 @@ class ChildThemeConfiguratorCSS {
62
  'child_version',
63
  'child_author',
64
  'child_name',
65
- 'configtype',
66
  'parnt',
67
  'child',
 
68
  'valkey',
69
  'rulekey',
70
  'qskey',
71
  'selkey',
72
- 'querykey',
 
73
  );
74
  var $dicts = array(
75
  'dict_qs',
@@ -79,7 +81,7 @@ class ChildThemeConfiguratorCSS {
79
  'dict_val',
80
  'dict_seq',
81
  'sel_ndx',
82
- 'val_ndx'
83
  );
84
  function __construct() {
85
  // scalars
@@ -90,10 +92,11 @@ class ChildThemeConfiguratorCSS {
90
  $this->valkey = 0;
91
  $this->child = '';
92
  $this->parnt = '';
93
- $this->configtype = 'theme';
94
  $this->child_name = '';
95
  $this->child_author = 'Child Theme Configurator';
96
  $this->child_version = '1.0';
 
97
  // multi-dim arrays
98
  $this->dict_qs = array();
99
  $this->dict_sel = array();
@@ -103,7 +106,8 @@ class ChildThemeConfiguratorCSS {
103
  $this->dict_seq = array();
104
  $this->sel_ndx = array();
105
  $this->val_ndx = array();
106
- $this->parntss = array();
 
107
  $this->imports = array( 'child' => array(), 'parnt' => array() );
108
  }
109
  // helper function to globalize ctc object
@@ -112,14 +116,15 @@ class ChildThemeConfiguratorCSS {
112
  return $chld_thm_cfg;
113
  }
114
  // loads current ctc config data into local memory
115
- function read_config() {
116
-
117
- if ( $configarray = get_option( CHLD_THM_CFG_OPTIONS . '_configvars' ) ):
 
118
  foreach ( $this->configvars as $configkey )
119
- if ( isset( $configarray[$configkey] ) )
120
- $this->{$configkey} = $configarray[$configkey];
121
  foreach ( $this->dicts as $configkey ):
122
- if ( $configarray = get_option( CHLD_THM_CFG_OPTIONS . '_' . $configkey ) )
123
  $this->{$configkey} = $configarray;
124
  endforeach;
125
  else:
@@ -127,17 +132,19 @@ class ChildThemeConfiguratorCSS {
127
  endif;
128
  }
129
  // writes ctc config data to options api
130
- function save_config() {
131
-
 
 
 
132
  $configarray = array();
133
  foreach ( $this->configvars as $configkey )
134
- $configarray[$configkey] = $this->{$configkey};
135
- update_option( CHLD_THM_CFG_OPTIONS . '_configvars', $configarray );
136
  foreach ( $this->dicts as $configkey )
137
- update_option( CHLD_THM_CFG_OPTIONS . '_' . $configkey, $this->{$configkey} );
138
- // remove pre 1.5.4 options
139
- delete_option( CHLD_THM_CFG_OPTIONS );
140
  }
 
141
  /*
142
  * get_prop
143
  * Getter interface (data sliced different ways depending on objname )
@@ -145,29 +152,33 @@ class ChildThemeConfiguratorCSS {
145
  function get_prop( $objname, $params = NULL ) {
146
  switch ( $objname ):
147
  case 'imports':
148
- return $this->obj_to_utf8( is_array( $this->imports['child'] ) ? ( current( $this->imports['child'] ) == 1 ? array_keys( $this->imports['child'] ) : array_keys( array_flip( $this->imports['child'] ) ) ) : array() );
 
 
 
 
149
  case 'sel_ndx':
150
- return $this->obj_to_utf8( $this->denorm_sel_ndx( empty( $params['key'] ) ? NULL : $params['key'] ) );
151
  case 'rule_val':
152
- return empty( $params['key'] ) ? array() : $this->denorm_rule_val( $params['key'] );
153
  case 'val_qry':
154
- if ( isset( $params['rule'] ) && isset( $this->dict_rule[$params['rule']] ) ):
155
- return empty( $params['key'] ) ?
156
- array() : $this->denorm_val_query( $params['key'], $params['rule'] );
157
  endif;
158
  case 'sel_val':
159
- return empty( $params['key'] ) ?
160
- array() : $this->denorm_sel_val( $params['key'] );
161
  case 'rule':
162
  return $this->obj_to_utf8( array_flip( $this->dict_rule ) );
163
  case 'child':
164
  return $this->child;
165
  case 'parnt':
166
  return $this->parnt;
167
- case 'parntss':
168
- return isset( $this->parntss ) ? $this->parntss : array();
169
- case 'configtype':
170
  return $this->configtype;
 
 
171
  case 'child_name':
172
  return $this->child_name;
173
  case 'author':
@@ -176,22 +187,27 @@ class ChildThemeConfiguratorCSS {
176
  return $this->child_version;
177
  case 'preview':
178
  $this->styles = '';
179
- if ( empty( $params['key'] ) || 'child' == $params['key'] ):
180
  $this->read_stylesheet( 'child' );
181
  else:
182
- if ( isset( $this->parntss ) ):
183
- foreach ( $this->parntss as $template ):
184
  $this->styles .= '/*** BEGIN ' . $template . ' ***/' . LF;
185
  $this->read_stylesheet( 'parnt', $template );
186
  $this->styles .= '/*** END ' . $template . ' ***/' . LF;
187
  endforeach;
188
  endif;
189
- $this->styles .= '/*** BEGIN style.css ***/' . LF;
190
- $this->read_stylesheet( 'parnt' );
191
- $this->styles .= '/*** END style.css ***/' . LF;
 
 
192
  endif;
193
  $this->normalize_css();
194
  return $this->styles;
 
 
 
195
  endswitch;
196
  return FALSE;
197
  }
@@ -201,13 +217,13 @@ class ChildThemeConfiguratorCSS {
201
  * Setter interface (scalar values only)
202
  */
203
  function set_prop( $prop, $value ) {
204
- if ( is_scalar( $this->{$prop} ) )
205
- $this->{$prop} = $value;
206
  else return FALSE;
207
  }
208
  // formats css string for accurate parsing
209
  function normalize_css() {
210
- if ( preg_match( "/(\}[\w\#\.]|; *\})/", $this->styles ) ): // prettify compressed CSS
211
  $this->styles = preg_replace( "/\*\/\s*/s", "*/\n", $this->styles ); // end comment
212
  $this->styles = preg_replace( "/\{\s*/s", " {\n ", $this->styles ); // open brace
213
  $this->styles = preg_replace( "/;\s*/s", ";\n ", $this->styles ); // semicolon
@@ -246,15 +262,16 @@ class ChildThemeConfiguratorCSS {
246
 
247
  // normalize selector styling
248
  $sel = implode( ', ', preg_split( '#\s*,\s*#s', trim( $sel ) ) );
 
249
  // add selector and query to index
250
- if ( !isset( $this->dict_query[$query] ) ) $this->dict_query[$query] = ++$this->querykey;
251
- if ( !isset( $this->dict_sel[$sel] ) ) $this->dict_sel[$sel] = ++$this->selkey;
252
- if ( !isset( $this->sel_ndx[$this->dict_query[$query]][$this->dict_sel[$sel]] ) ):
253
  // increment key number
254
- $this->sel_ndx[$this->dict_query[$query]][$this->dict_sel[$sel]] = ++$this->qskey;
255
 
256
- $this->dict_qs[$this->qskey]['s'] = $this->dict_sel[$sel];
257
- $this->dict_qs[$this->qskey]['q'] = $this->dict_query[$query];
258
  // tell the UI to update a single cached query/selector lookup by passing 'qsid' as the key
259
  // (normally the entire array is replaced):
260
  if ( $this->ctc()->cache_updates )
@@ -269,12 +286,12 @@ class ChildThemeConfiguratorCSS {
269
  );
270
  endif;
271
  // update sequence for this selector if this is a later instance to keep cascade priority
272
- if ( !isset( $this->dict_seq[$this->qskey] ) )
273
- $this->dict_seq[$this->qskey] = $this->qskey;
274
  // set data and value
275
  if ( $rule ):
276
- if ( !isset( $this->dict_rule[$rule] ) ):
277
- $this->dict_rule[$rule] = ++$this->rulekey;
278
  // tell the UI to update a single cached rule:
279
  if ( $this->ctc()->cache_updates ):
280
  $this->ctc()->updates[] = array(
@@ -284,14 +301,15 @@ class ChildThemeConfiguratorCSS {
284
  );
285
  endif;
286
  endif;
287
- $qsid = $this->sel_ndx[$this->dict_query[$query]][$this->dict_sel[$sel]];
288
- $ruleid = $this->dict_rule[$rule];
289
- if ( !isset( $this->dict_val[$value] ) ):
290
- $this->dict_val[$value] = ++$this->valkey;
291
  endif;
292
- $this->val_ndx[$qsid][$ruleid][$template] = $this->dict_val[$value];
293
- // set the important flag for this value
294
- $this->val_ndx[$qsid][$ruleid]['i_' . $template] = $important;
 
295
  // tell the UI to add a single cached query/selector data array:
296
  if ( $this->ctc()->cache_updates ):
297
  $updatearr = array(
@@ -302,7 +320,7 @@ class ChildThemeConfiguratorCSS {
302
  $this->ctc()->updates[] = $updatearr;
303
  endif;
304
  if ( isset( $seq ) ): // this is a renamed selector
305
- $this->dict_seq[$qsid] = $seq;
306
  if ( $this->ctc()->cache_updates ):
307
  $this->ctc()->updates[] = array(
308
  'obj' => 'rewrite',
@@ -313,26 +331,25 @@ class ChildThemeConfiguratorCSS {
313
  endif;
314
  endif;
315
  }
316
- // loads raw css file into local memory
317
- function read_stylesheet( $template = 'child', $file = 'style.css' ) {
318
-
319
- // these conditions support revert/restore option in 1.6.0+
320
- if ( 'all' == $file ) return;
321
- elseif ( '' == $file ) $file = 'style.css';
322
- // end revert/restore conditions
323
-
324
- $source = $this->get_prop( $template );
325
- $configtype = $this->get_prop( 'configtype' );
326
- if ( empty( $source ) || !is_scalar( $source ) ) return FALSE;
327
- $themedir = get_theme_root() . '/' . $source;
328
- $stylesheet = apply_filters( 'chld_thm_cfg_' . $template, $themedir . '/' . $file , $this );
329
-
330
- // read stylesheet
331
- if ( $stylesheet_verified = $this->is_file_ok( $stylesheet, 'read' ) ):
332
- $import_url = preg_replace( '%^' . preg_quote( $themedir ) . '/%', '', $stylesheet_verified );
333
- $this->styles .= @file_get_contents( $stylesheet_verified ) . "\n";
334
- endif;
335
  }
 
336
  /* recurse_directory
337
  * searches filesystem for valid files based on parameters and returns array of filepaths.
338
  * Because it requires logic specific to CTC, core WP recurse function is not used.
@@ -346,7 +363,7 @@ class ChildThemeConfiguratorCSS {
346
 
347
  $ext = '(' . implode( '|', array_keys( $this->ctc()->imgmimes ) ) . ')';
348
  endif;
349
- while( count( $dirs ) && $loops < CHLD_THM_CFG_MAX_RECURSE_LOOPS ):
350
  $loops++;
351
  $dir = array_shift( $dirs );
352
  if ( $handle = opendir( $dir ) ):
@@ -390,55 +407,74 @@ class ChildThemeConfiguratorCSS {
390
  */
391
  function parse_post_data() {
392
  $this->cache_updates = TRUE;
393
- if ( isset( $_POST['ctc_new_selectors'] ) ):
394
- $this->styles = $this->parse_css_input( LF . $_POST['ctc_new_selectors'] );
395
  $this->parse_css( 'child',
396
- ( isset( $_POST['ctc_sel_ovrd_query'] )?trim( $_POST['ctc_sel_ovrd_query'] ):NULL ), FALSE );
397
- elseif ( isset( $_POST['ctc_child_imports'] ) ):
398
- $this->imports['child'] = array();
399
- $this->styles = $this->parse_css_input( $_POST['ctc_child_imports'] );
400
  $this->parse_css( 'child' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
  else:
402
- $newselector = isset( $_POST['ctc_rewrite_selector'] ) ? $this->sanitize( $this->parse_css_input( $_POST['ctc_rewrite_selector'] ) ) : NULL;
 
403
  // set the custom sequence value
404
  foreach ( preg_grep( '#^ctc_ovrd_child_seq_#', array_keys( $_POST ) ) as $post_key ):
405
  if ( preg_match( '#^ctc_ovrd_child_seq_(\d+)$#', $post_key, $matches ) ):
406
- $qsid = $matches[1];
407
- $this->dict_seq[$qsid] = intval( $_POST[$post_key] );
408
  endif;
409
  endforeach;
410
  $parts = array();
411
  foreach ( preg_grep( '#^ctc_(ovrd|\d+)_child#', array_keys( $_POST ) ) as $post_key ):
412
  if ( preg_match( '#^ctc_(ovrd|\d+)_child_([\w\-]+?)_(\d+?)(_(.+))?$#', $post_key, $matches ) ):
413
- $valid = $matches[1];
414
- $rule = $matches[2];
415
- if ( NULL == $rule || !isset( $this->dict_rule[$rule] ) ) continue;
416
- $ruleid = $this->dict_rule[$rule];
417
- $qsid = $matches[3];
418
- $value = $this->normalize_color( $this->sanitize( $this->parse_css_input( $_POST[$post_key] ) ) );
419
  $important = $this->is_important( $value );
420
- if ( !empty( $_POST['ctc_' . $valid . '_child_' . $rule . '_i_' . $qsid] ) ) $important = 1;
421
 
422
  $selarr = $this->denorm_query_sel( $qsid );
423
- if ( !empty( $matches[5] ) ):
424
- $parts[$qsid][$rule][$matches[5]] = $value;
425
- $parts[$qsid][$rule]['important'] = $important;
426
- $parts[$qsid][$rule]['query'] = $selarr['query'];
427
- $parts[$qsid][$rule]['selector'] = $selarr['selector'];
428
  else:
429
- if ( $newselector && $newselector != $selarr['selector'] ):
430
  // If this is a renamed selector, add new selector to array
431
  // and clear original child selector values.
432
  // Passing the sequence in the last argument serves two purposes:
433
  // 1. sets sequence for new renamed selector.
434
  // 2. tells the update_arrays function to flag this as a
435
  // renamed selector to pass back in result array.
436
- $this->update_arrays( 'child', $selarr['query'], $newselector,
437
- $rule, trim( $value ), $important, $this->dict_seq[$qsid] );
438
- $this->update_arrays( 'child', $selarr['query'], $selarr['selector'], $rule, '' );
439
  else:
440
  // Otherwise, just update with the new values:
441
- $this->update_arrays( 'child', $selarr['query'], $selarr['selector'],
442
  $rule, trim( $value ), $important );
443
  endif;
444
  endif;
@@ -447,40 +483,41 @@ class ChildThemeConfiguratorCSS {
447
  foreach ( $parts as $qsid => $rule_arr ):
448
  foreach ( $rule_arr as $rule => $rule_part ):
449
  if ( 'background' == $rule ):
450
- $value = $rule_part['background_url'];
451
  elseif ( 'background-image' == $rule ):
452
- if ( empty( $rule_part['background_url'] ) ):
453
- if ( empty( $rule_part['background_color2'] ) ):
454
  $value = '';
455
  else:
456
  $value = implode( ':', array(
457
- $rule_part['background_origin'],
458
- $rule_part['background_color1'], '0%',
459
- $rule_part['background_color2'], '100%'
460
  ) );
461
  endif;
462
  else:
463
- $value = $rule_part['background_url'];
464
  endif;
465
  elseif ( preg_match( '#^border(\-(top|right|bottom|left))?$#', $rule ) ):
466
  $value = implode( ' ', array(
467
- $rule_part['border_width'],
468
- $rule_part['border_style'],
469
- $rule_part['border_color']
470
  ) );
471
  else:
472
  $value = '';
473
  endif;
474
- if ( $newselector && $newselector != $rule_part['selector'] ):
475
- $this->update_arrays( 'child', $rule_part['query'], $newselector,
476
- $rule, trim( $value ), $rule_part['important'], $this->dict_seq[$qsid] );
477
- $this->update_arrays( 'child', $rule_part['query'], $rule_part['selector'], $rule, '' );
478
  else:
479
- $this->update_arrays( 'child', $rule_part['query'], $rule_part['selector'],
480
- $rule, trim( $value ), $rule_part['important'] );
481
  endif;
482
  endforeach;
483
  endforeach;
 
484
  endif;
485
  }
486
 
@@ -509,7 +546,7 @@ class ChildThemeConfiguratorCSS {
509
  * reads stylesheet to get WordPress meta data and passes rest to parse_css
510
  */
511
  function parse_css_file( $template, $file = 'style.css' ) {
512
-
513
  $this->ctc()->cache_updates = FALSE;
514
  $this->styles = ''; // reset styles
515
  $this->read_stylesheet( $template, $file );
@@ -517,10 +554,36 @@ class ChildThemeConfiguratorCSS {
517
  $regex = '#Theme Name:\s*(.+?)\n#i';
518
  preg_match( $regex, $this->styles, $matches );
519
  $child_name = $this->get_prop( 'child_name' );
520
- if ( !empty( $matches[1] ) && 'child' == $template && empty( $child_name ) ) $this->set_prop( 'child_name', $matches[1] );
521
  $this->parse_css( $template );
522
  }
523
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
524
  /*
525
  * parse_css
526
  * Accepts raw CSS as text and parses into individual properties.
@@ -539,12 +602,12 @@ class ChildThemeConfiguratorCSS {
539
 
540
  $regex = '#(\@import.+?);#';
541
  preg_match_all( $regex, $this->styles, $matches );
542
- foreach ( preg_grep( '#' . $this->get_prop( 'parnt' ) . '\/style\.css#', $matches[1], PREG_GREP_INVERT ) as $import )
543
- $this->imports[$template][$import] = 1;
544
  if ( $this->ctc()->cache_updates ):
545
  $this->ctc()->updates[] = array(
546
  'obj' => 'imports',
547
- 'data' => array_keys( $this->imports[$template] ),
548
  );
549
  endif;
550
  endif;
@@ -554,26 +617,29 @@ class ChildThemeConfiguratorCSS {
554
  '#(\@media[^\{]+?)\{(.*?\})?\s*?\}#s', // get all other media queries
555
  ) as $regex ): // (((?!\@media).) backreference too memory intensive - rolled back in v 1.4.8.1
556
  preg_match_all( $regex, $this->styles, $matches );
557
- foreach ( $matches[1] as $segment ):
558
- $ruleset[trim( $segment )] = array_shift( $matches[2] ) . ( isset( $ruleset[trim( $segment )] )?$ruleset[trim( $segment )]:'' );
559
  endforeach;
560
  // stripping rulesets leaves base styles
561
  $this->styles = preg_replace( $regex, '', $this->styles );
562
  endforeach;
563
- $ruleset[$basequery] = $this->styles;
564
  foreach ( $ruleset as $query => $segment ):
565
  // make sure there is semicolon before closing brace
566
  $segment = preg_replace( '#(\})#', ";$1", $segment );
567
  // parses selectors and corresponding rules
568
  $regex = '#\s([\[\.\#\:\w][\w\-\s\(\)\[\]\'\^\*\.\#\+:,"=>]+?)\s*\{(.*?)\}#s'; //
569
  preg_match_all( $regex, $segment, $matches );
570
- foreach( $matches[1] as $sel ):
571
- $stuff = array_shift( $matches[2] );
572
  $this->update_arrays( $template, $query, $sel );
573
  // handle base64 data
574
  $stuff = preg_replace( '#data:([^;]+?);([^\)]+?)\)#s', "data:$1%%semi%%$2)", $stuff );
575
  foreach ( explode( ';', $stuff ) as $ruleval ):
576
- if ( $this->qskey > CHLD_THM_CFG_MAX_SELECTORS ) break;
 
 
 
577
  if ( FALSE === strpos( $ruleval, ':' ) ) continue;
578
  list( $rule, $value ) = explode( ':', $ruleval, 2 );
579
  $rule = trim( $rule );
@@ -642,32 +708,38 @@ class ChildThemeConfiguratorCSS {
642
  $rulearr = array_flip( $this->dict_rule );
643
  $valarr = array_flip( $this->dict_val );
644
  $selarr = array_flip( $this->dict_sel );
 
645
  foreach ( $this->sort_queries() as $query => $sort_order ):
646
  $has_selector = 0;
647
  $sel_output = '';
648
- $selectors = $this->sel_ndx[$this->dict_query[$query]];
649
  uasort( $selectors, array( $this, 'cmp_seq' ) );
650
  if ( 'base' != $query ) $sel_output .= $query . ' {' . LF;
651
  foreach ( $selectors as $selid => $qsid ):
652
  $has_value = 0;
653
- $sel = $selarr[$selid];
654
- if ( !empty( $this->val_ndx[$qsid] ) ):
655
  $shorthand = array();
656
- foreach ( $this->val_ndx[$qsid] as $ruleid => $valid ):
657
- if ( isset( $valid['child'] )
658
- && isset( $valarr[$valid['child']] )
659
- && '' !== $valarr[$valid['child']]
660
- && ( !isset( $valid['parnt'] ) || $valid['parnt'] != $valid['child'] ) ):
661
  if ( ! $has_value ):
662
- $sel_output .= isset( $this->dict_seq[$qsid] )?'/*' . $this->dict_seq[$qsid] . '*/' . LF:'';
663
  // show load order
664
  $sel_output .= $sel . ' {' . LF;
665
  $has_value = 1;
666
  $has_selector = 1;
667
  endif;
668
- $important_parnt = empty( $valid['i_parnt'] ) ? 0 : 1;
669
- $important = isset( $valid['i_child'] ) ? $valid['i_child'] : $important_parnt;
670
- $sel_output .= $this->add_vendor_rules( $rulearr[$ruleid], $valarr[$valid['child']], $shorthand, $important );
 
 
 
 
 
671
  endif;
672
  endforeach;
673
  $sel_output .= $this->encode_shorthand( $shorthand ); // . ( $important ? ' !important' : '' );
@@ -680,24 +752,32 @@ class ChildThemeConfiguratorCSS {
680
  if ( $has_selector ) $output .= $sel_output;
681
  endforeach;
682
  $stylesheet = apply_filters( 'chld_thm_cfg_target', $this->get_child_target(), $this );
 
 
683
  if ( $stylesheet_verified = $this->is_file_ok( $stylesheet, 'write' ) ):
684
  global $wp_filesystem; // this was initialized earlier;
685
- // backup current stylesheet
686
- if ( $backup && is_file( $stylesheet_verified ) ):
687
- $timestamp = date( 'YmdHis', current_time( 'timestamp' ) );
688
- $bakfile = preg_replace( "/\.css$/", '', $stylesheet_verified ) . '-' . $timestamp . '.css';
689
- // don't write new stylesheet if backup fails
690
- if ( !$wp_filesystem->copy( $this->ctc()->fspath( $stylesheet_verified ), $this->ctc()->fspath( $bakfile ) ) ) return FALSE;
691
- endif;
692
- // write new stylesheet:
693
- // try direct write first, then wp_filesystem write
694
- // stylesheet must already exist and be writable by web server
695
- if ( FALSE !== @file_put_contents( $stylesheet_verified, $output ) ): //is_writable( $stylesheet_verified ) &&
696
- return TRUE;
697
- elseif ( FALSE !== $wp_filesystem->put_contents( $this->ctc()->fspath( $stylesheet_verified ), $output ) ):
698
- return TRUE;
699
- endif;
 
 
 
 
 
700
  endif;
 
701
  return FALSE;
702
  }
703
 
@@ -712,7 +792,7 @@ class ChildThemeConfiguratorCSS {
712
  if ( 'filter' == $rule && ( FALSE !== strpos( $value, 'progid:DXImageTransform.Microsoft.Gradient' ) ) ) return;
713
  $importantstr = $important ? ' !important' : '';
714
  if ( preg_match( "/^(margin|padding)\-(top|right|bottom|left)$/", $rule, $matches ) ):
715
- $shorthand[$matches[1]][$matches[2]] = $value . $importantstr;
716
  return '';
717
  elseif ( preg_match( '/^(' . implode( '|', $this->vendorrule ) . ')$/', $rule ) ):
718
  foreach( array( 'moz', 'webkit', 'o' ) as $prefix ):
@@ -725,31 +805,35 @@ class ChildThemeConfiguratorCSS {
725
  if ( $gradient = $this->decode_gradient( $value ) ):
726
  // standard gradient
727
  foreach( array( 'moz', 'webkit', 'o', 'ms' ) as $prefix ):
728
- $rules .= ' background-image: -' . $prefix . '-' . 'linear-gradient(' . $gradient['origin'] . ', '
729
- . $gradient['color1'] . ', ' . $gradient['color2'] . ')' . $importantstr . ';' . LF;
730
  endforeach;
731
  // W3C standard gradient
732
  // rotate origin 90 degrees
733
- if ( preg_match( '/(\d+)deg/', $gradient['origin'], $matches ) ):
734
- $org = ( 90 - $matches[1] ) . 'deg';
735
  else:
736
- foreach ( preg_split( "/\s+/", $gradient['origin'] ) as $dir ):
737
  $dir = strtolower( $dir );
738
- $dirs[] = ( 'top' == $dir ? 'bottom' : ( 'bottom' == $dir ? 'top' : ( 'left' == $dir ? 'right' : ( 'right' == $dir ? 'left' : $dir ) ) ) );
 
 
 
739
  endforeach;
740
  $org = 'to ' . implode( ' ', $dirs );
741
  endif;
742
  $rules .= ' background-image: linear-gradient(' . $org . ', '
743
- . $gradient['color1'] . ', ' . $gradient['color2'] . ')' . $importantstr . ';' . LF;
744
 
745
  // legacy webkit gradient - we'll add if there is demand
746
  // '-webkit-gradient(linear,' .$origin . ', ' . $color1 . ', '. $color2 . ')';
747
 
748
  // MS filter gradient
749
- $type = ( in_array( $gradient['origin'], array( 'left', 'right', '0deg', '180deg' ) ) ? 1 : 0 );
750
- $color1 = preg_replace( "/^#/", '#00', $gradient['color1'] );
751
  $rules .= ' filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=' . $type . ', StartColorStr="'
752
- . strtoupper( $color1 ) . '", EndColorStr="' . strtoupper( $gradient['color2'] ) . '")' . $importantstr . ';' . LF;
 
753
  else:
754
  // url or other value
755
  $rules .= ' ' . $rule . ': ' . $value . $importantstr . ';' . LF;
@@ -775,23 +859,23 @@ class ChildThemeConfiguratorCSS {
775
  endif;
776
  else:
777
  $regex = '#(url *\([^\)]+\))#';
778
- if ( preg_match( $regex, $value, $matches ) ) $url = $matches[1];
779
  $parts = preg_split( $regex, $value );
780
 
781
  if ( count( $parts ) == 1 ):
782
  // this is a named color or single hex color or none
783
- $part = str_replace( ' ', '', $parts[0] );
784
  $rules[] = 'none' == $part ? 'background' : 'background-color';
785
  $values[] = $part;
786
  else:
787
  $rules[] = 'background-image';
788
  $values[] = $url;
789
- if ( !empty( $parts[0] ) && '' !== $parts[0] ):
790
  $rules[] = 'background-color';
791
- $values[] = trim( $parts[0] );
792
  endif;
793
  $position = array();
794
- foreach( preg_split( '/ +/', trim( $parts[1] ) ) as $part ):
795
  if ( '' === $part ) continue; // empty( $part ) ||
796
  if ( FALSE === strpos( $part, 'repeat' ) ):
797
  $position[] = $part;
@@ -816,25 +900,25 @@ class ChildThemeConfiguratorCSS {
816
  function normalize_font( $value, &$rules, &$values ) {
817
  $regex = '#^((\d+|bold|normal) )?((italic|normal) )?(([\d\.]+(px|r?em|%))[\/ ])?(([\d\.]+(px|r?em|%)?) )?(.+)$#is';
818
  preg_match( $regex, $value, $parts );
819
- if ( !empty( $parts[2] ) ):
820
  $rules[] = 'font-weight';
821
- $values[] = $parts[2];
822
  endif;
823
- if ( !empty( $parts[4] ) ):
824
  $rules[] = 'font-style';
825
- $values[] = $parts[4];
826
  endif;
827
- if ( !empty( $parts[6] ) ):
828
  $rules[] = 'font-size';
829
- $values[] = $parts[6];
830
  endif;
831
- if ( !empty( $parts[9] ) ):
832
  $rules[] = 'line-height';
833
- $values[] = $parts[9];
834
  endif;
835
- if ( !empty( $parts[11] ) ):
836
  $rules[] = 'font-family';
837
- $values[] = $parts[11];
838
  endif;
839
  }
840
 
@@ -846,17 +930,17 @@ class ChildThemeConfiguratorCSS {
846
  */
847
  function normalize_margin_padding( $rule, $value, &$rules, &$values ) {
848
  $parts = preg_split( "/ +/", trim( $value ) );
849
- if ( !isset( $parts[1] ) ) $parts[1] = $parts[0];
850
- if ( !isset( $parts[2] ) ) $parts[2] = $parts[0];
851
- if ( !isset( $parts[3] ) ) $parts[3] = $parts[1];
852
- $rules[0] = $rule . '-top';
853
- $values[0] = $parts[0];
854
- $rules[1] = $rule . '-right';
855
- $values[1] = $parts[1];
856
- $rules[2] = $rule . '-bottom';
857
- $values[2] = $parts[2];
858
- $rules[3] = $rule . '-left';
859
- $values[3] = $parts[3];
860
  }
861
 
862
  /*
@@ -871,31 +955,31 @@ class ChildThemeConfiguratorCSS {
871
  $rule = array();
872
  $importantct = 0;
873
  // which sides do we have and are they important?
874
- foreach( $shorthand[$key] as $side => $val ):
875
  $ict = 0;
876
- $rule[$side] = trim( preg_replace( '/'.$importantstr.'/', '', $val, 1, $ict ) );
877
- $important[$side] = $ict;
878
  $importantct += $ict;
879
  endforeach;
880
  // shorthand must have 4 explicit values and all must have same priority
881
  if ( 4 == count( $rule ) && ( 0 == $importantct || 4 == $importantct ) ):
882
  // let's try to condense the values into as few as possible, starting with the top value
883
  $parts = array();
884
- $parts[0] = $rule['top'];
885
  // if left is not the same as right, we must use all 4 values
886
- if ( $rule['left'] !== $rule['right'] ):
887
- $parts[3] = $rule['left'];
888
- $parts[2] = $rule['bottom'];
889
- $parts[1] = $rule['right'];
890
  endif;
891
  // if top is not the same as bottom, we must use at least 3 values
892
- if ( $rule['bottom'] !== $rule['top'] ):
893
- $parts[2] = $rule['bottom'];
894
- $parts[1] = $rule['right'];
895
  endif;
896
  // if top is not the same as right, we must use at least 2 values
897
- if ( $rule['right'] !== $rule['top'] ):
898
- $parts[1] = $rule['right'];
899
  endif;
900
  // the order of the sides is critical: top right bottom left
901
  ksort( $parts );
@@ -905,7 +989,7 @@ class ChildThemeConfiguratorCSS {
905
  else:
906
  // otherwise return separate rule for each side
907
  foreach ( $rule as $side => $value ):
908
- $rules .= ' ' . $key . '-' . $side . ': ' . $value . ( $important[$side] ? $importantstr : '' ) . ';' . LF;
909
  endforeach;
910
  endif;
911
  endforeach;
@@ -923,34 +1007,34 @@ class ChildThemeConfiguratorCSS {
923
  $regex = '#gradient[^\)]*?\((((top|bottom|left|right)?( (top|bottom|left|right))?|\d+deg),)?([^\)]*[\'"]?(\#\w{3,8}|rgba?\([\d, ]+?\)|hsla?\([\d%, ]+?\))( \d+%)?)([^\)]*[\'"]?(\#\w{3,8}|rgba?\([\d, ]+?\)|hsla?\([\d%, ]+?\))( \d+%)?)([^\)]*gradienttype=[\'"]?(\d)[\'"]?)?[^\)]*\)#i';
924
  $param = $parts = array();
925
  preg_match( $regex, $value, $parts );
926
- if ( empty( $parts[13] ) ):
927
- if ( empty( $parts[2] ) ):
928
- $param[0] = 'top';
929
  else:
930
- $param[0] = trim( $parts[2] );
931
  endif;
932
- if ( empty( $parts[8] ) ):
933
- $param[2] = '0%';
934
  else:
935
- $param[2] = trim( $parts[8] );
936
  endif;
937
- if ( empty( $parts[11] ) ):
938
- $param[4] = '100%';
939
  else:
940
- $param[4] = trim( $parts[11] );
941
  endif;
942
- elseif( '0' == $parts[13] ):
943
- $param[0] = 'top';
944
- $param[2] = '0%';
945
- $param[4] = '100%';
946
- elseif ( '1' == $parts[13] ):
947
- $param[0] = 'left';
948
- $param[2] = '0%';
949
- $param[4] = '100%';
950
  endif;
951
- if ( isset( $parts[7] ) && isset( $parts[10] ) ):
952
- $param[1] = $parts[7];
953
- $param[3] = $parts[10];
954
  ksort( $param );
955
  return implode( ':', $param );
956
  else: return $value;
@@ -963,15 +1047,15 @@ class ChildThemeConfiguratorCSS {
963
  */
964
  function decode_border( $value ) {
965
  if ( preg_match( '#^(0|none)#i', $value ) ):
966
- $parts[0] = $value;
967
- $parts[1] = $parts[2] = '';
968
  else:
969
  $parts = preg_split( '#\s+#', $value, 3 );
970
  endif;
971
  return array(
972
- 'width' => empty( $parts[0] ) ? '' : $parts[0],
973
- 'style' => empty( $parts[1] ) ? '' : $parts[1],
974
- 'color' => empty( $parts[2] ) ? '' : $parts[2],
975
  );
976
  }
977
 
@@ -983,11 +1067,11 @@ class ChildThemeConfiguratorCSS {
983
  $parts = explode( ':', $value, 5 );
984
  if ( !preg_match( '#(url|none)#i', $value ) && 5 == count( $parts ) ):
985
  return array(
986
- 'origin' => empty( $parts[0] ) ? '' : $parts[0],
987
- 'color1' => empty( $parts[1] ) ? '' : $parts[1],
988
- 'stop1' => empty( $parts[2] ) ? '' : $parts[2],
989
- 'color2' => empty( $parts[3] ) ? '' : $parts[3],
990
- 'stop2' => empty( $parts[4] ) ? '' : $parts[4],
991
  );
992
  endif;
993
  return FALSE;
@@ -1001,10 +1085,10 @@ class ChildThemeConfiguratorCSS {
1001
  $rule_sel_arr = array();
1002
  $val_arr = array_flip( $this->dict_val );
1003
  foreach ( $this->val_ndx as $selid => $rules ):
1004
- if ( !isset( $rules[$ruleid] ) ) continue;
1005
- foreach ( $rules[$ruleid] as $theme => $val ):
1006
- if ( !isset( $val_arr[$val] ) || '' === $val_arr[$val] ) continue;
1007
- $rule_sel_arr[$val] = $val_arr[$val];
1008
  endforeach;
1009
  endforeach;
1010
  return $rule_sel_arr;
@@ -1019,12 +1103,12 @@ class ChildThemeConfiguratorCSS {
1019
  $value_query_arr = array();
1020
  foreach ( $this->val_ndx as $qsid => $rules ):
1021
  foreach ( $rules as $ruleid => $values ):
1022
- if ( $ruleid != $this->dict_rule[$rule] ) continue;
1023
  foreach ( $values as $name => $val ):
1024
  if ( 'i' == $name || $val != $valid ) continue;
1025
  $selarr = $this->denorm_query_sel( $qsid );
1026
  $valarr = $this->denorm_sel_val( $qsid );
1027
- $value_query_arr[$rule][$selarr['query']][$qsid] = $valarr;
1028
  endforeach;
1029
  endforeach;
1030
  endforeach;
@@ -1036,14 +1120,15 @@ class ChildThemeConfiguratorCSS {
1036
  * Return id, query and selector values of a specific qsid (query-selector ID)
1037
  */
1038
  function denorm_query_sel( $qsid ) {
1039
- $queryarr = array_flip( $this->dict_query );
1040
- $selarr = array_flip( $this->dict_sel );
1041
- $this->dict_seq[$qsid] = isset( $this->dict_seq[$qsid] ) ? $this->dict_seq[$qsid] : $qsid;
 
1042
  return array(
1043
  'id' => $qsid,
1044
- 'query' => $queryarr[$this->dict_qs[$qsid]['q']],
1045
- 'selector' => $selarr[$this->dict_qs[$qsid]['s']],
1046
- 'seq' => $this->dict_seq[$qsid],
1047
  );
1048
  }
1049
 
@@ -1056,15 +1141,15 @@ class ChildThemeConfiguratorCSS {
1056
  $selarr = $this->denorm_query_sel( $qsid );
1057
  $valarr = array_flip( $this->dict_val );
1058
  $rulearr = array_flip( $this->dict_rule );
1059
- if ( isset( $this->val_ndx[$qsid] ) && is_array( $this->val_ndx[$qsid] ) ):
1060
- foreach ( $this->val_ndx[$qsid] as $ruleid => $values ):
1061
  foreach ( $values as $name => $val ):
1062
  if ( 'i_parnt' == $name || 'i_child' == $name ):
1063
- $selarr['value'][$rulearr[$ruleid]][$name] = ( empty( $val ) ? 0 : 1 );
1064
- elseif ( !isset( $valarr[$val] ) || '' === $valarr[$val] ):
1065
  continue;
1066
  else:
1067
- $selarr['value'][$rulearr[$ruleid]][$name] = $valarr[$val];
1068
  endif;
1069
  endforeach;
1070
  // add load order
@@ -1083,10 +1168,10 @@ class ChildThemeConfiguratorCSS {
1083
  $selarr = array_flip( $this->dict_sel );
1084
  foreach( $this->sel_ndx as $queryid => $sel ):
1085
  foreach( $sel as $selid => $qsid ):
1086
- $sel_ndx_norm[$queryarr[$queryid]][$selarr[$selid]] = $qsid;
1087
  endforeach;
1088
  endforeach;
1089
- return empty( $query ) ? $sel_ndx_norm : $sel_ndx_norm[$query];
1090
  }
1091
 
1092
  /*
@@ -1112,15 +1197,15 @@ class ChildThemeConfiguratorCSS {
1112
  $queries = array();
1113
  $queryarr = array_flip( $this->dict_query );
1114
  foreach ( array_keys( $this->sel_ndx ) as $queryid ):
1115
- $query = $queryarr[$queryid];
1116
  if ( 'base' == $query ):
1117
- $queries['base'] = -999999;
1118
  continue;
1119
  endif;
1120
  if ( preg_match( "/((min|max)(\-device)?\-width)\s*:\s*(\d+)/", $query, $matches ) ):
1121
- $queries[$query] = 'min-width' == $matches[1] ? $matches[4] : -$matches[4];
1122
  else:
1123
- $queries[$query] = $queryid - 10000;
1124
  endif;
1125
  endforeach;
1126
  asort( $queries );
@@ -1129,8 +1214,8 @@ class ChildThemeConfiguratorCSS {
1129
 
1130
  // sort selectors based on dict_seq if exists, otherwise qsid
1131
  function cmp_seq( $a, $b ) {
1132
- $cmpa = isset( $this->dict_seq[$a] ) ? $this->dict_seq[$a] : $a;
1133
- $cmpb = isset( $this->dict_seq[$b] ) ? $this->dict_seq[$b] : $b;
1134
  if ( $cmpa == $cmpb ) return 0;
1135
  return ( $cmpa < $cmpb ) ? -1 : 1;
1136
  }
@@ -1142,40 +1227,46 @@ class ChildThemeConfiguratorCSS {
1142
  * and stringifies NULLs
1143
  */
1144
  function obj_to_utf8( $data ) {
1145
-
1146
- if ( is_object( $data ) ) {
1147
  $data = get_object_vars( $data );
1148
- }
1149
- if ( is_array( $data ) ) {
1150
  return array_map( array( &$this, __FUNCTION__ ), $data );
1151
- }
1152
- else {
1153
  return is_null( $data ) ? '' : utf8_encode( $data );
1154
- }
1155
  }
1156
  // convert ascii character into decimal value
1157
  function to_ascii( $matches ) {
1158
- return ord( $matches[0] );
1159
  }
1160
  // convert decimal value into ascii character
1161
  function from_ascii( $matches ) {
1162
- return chr( $matches[0] );
1163
  }
1164
 
1165
  /* is_file_ok
1166
  * verify file exists and is in valid location
1167
  */
1168
  function is_file_ok( $stylesheet, $permission = 'read' ) {
 
 
 
 
1169
  // remove any ../ manipulations
1170
  $stylesheet = preg_replace( "%\.\./%", '/', $stylesheet );
1171
- if ( 'read' == $permission && !is_file( $stylesheet ) ) return FALSE;
1172
- if ( 'search' == $permission && !is_dir( $stylesheet ) ) return FALSE;
 
 
 
 
 
1173
  // sanity check for php files
1174
  //if ( !preg_match( '%' . preg_quote( $ext ) . '$%', $stylesheet ) ) return FALSE;
1175
  // check if in themes dir;
1176
  if ( preg_match( '%^' . preg_quote( get_theme_root() ) . '%', $stylesheet ) ) return $stylesheet;
1177
  // check if in plugins dir
1178
  if ( preg_match( '%^' . preg_quote( WP_PLUGIN_DIR ) . '%', $stylesheet ) ) return $stylesheet;
 
1179
  return FALSE;
1180
  }
1181
  /* normalize_color
@@ -1188,7 +1279,7 @@ class ChildThemeConfiguratorCSS {
1188
  }
1189
  // callback for normalize_color regex
1190
  function tolower( $matches ) {
1191
- return '#' . strtolower( $matches[1] );
1192
  }
1193
  }
1194
  ?>
6
  Class: ChildThemeConfiguratorCSS
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Handles all CSS output, parsing, normalization
9
+ Version: 1.6.4
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
36
  var $styles; // temporary update cache
37
  var $child; // child theme slug
38
  var $parnt; // parent theme slug
39
+ var $configtype; // legacy plugin slug
40
+ var $addl_css; // parent additional stylesheets
41
+ var $recent; // history of edited styles
42
  var $enqueue; // load parent css method (enqueue, import, none)
 
43
  var $child_name; // child theme name
44
  var $child_author; // stylesheet author
45
  var $child_version; // stylesheet version
52
  'transform'
53
  );
54
  var $configvars = array(
55
+ 'addl_css',
56
  // the enqueue flag prevents the transition from 1.5.4
57
  // from breaking the stylesheet by forcing the user to regenerate
58
  // the config data before updating the stylesheet. Otherwise,
63
  'child_version',
64
  'child_author',
65
  'child_name',
 
66
  'parnt',
67
  'child',
68
+ 'configtype', // legacy support
69
  'valkey',
70
  'rulekey',
71
  'qskey',
72
  'selkey',
73
+ 'querykey',
74
+ 'recent',
75
  );
76
  var $dicts = array(
77
  'dict_qs',
81
  'dict_val',
82
  'dict_seq',
83
  'sel_ndx',
84
+ 'val_ndx',
85
  );
86
  function __construct() {
87
  // scalars
92
  $this->valkey = 0;
93
  $this->child = '';
94
  $this->parnt = '';
95
+ $this->configtype = 'theme'; // legacy support
96
  $this->child_name = '';
97
  $this->child_author = 'Child Theme Configurator';
98
  $this->child_version = '1.0';
99
+
100
  // multi-dim arrays
101
  $this->dict_qs = array();
102
  $this->dict_sel = array();
106
  $this->dict_seq = array();
107
  $this->sel_ndx = array();
108
  $this->val_ndx = array();
109
+ $this->addl_css = array();
110
+ $this->recent = array();
111
  $this->imports = array( 'child' => array(), 'parnt' => array() );
112
  }
113
  // helper function to globalize ctc object
116
  return $chld_thm_cfg;
117
  }
118
  // loads current ctc config data into local memory
119
+ function load_config() {
120
+ $option = CHLD_THM_CFG_OPTIONS . apply_filters( 'chld_thm_cfg_option', '' );
121
+ //echo 'loading option: ' . $option . LF;
122
+ if ( $configarray = get_option( $option . '_configvars' ) ):
123
  foreach ( $this->configvars as $configkey )
124
+ if ( isset( $configarray[ $configkey ] ) )
125
+ $this->{$configkey} = $configarray[ $configkey ];
126
  foreach ( $this->dicts as $configkey ):
127
+ if ( $configarray = get_option( $option . '_' . $configkey ) )
128
  $this->{$configkey} = $configarray;
129
  endforeach;
130
  else:
132
  endif;
133
  }
134
  // writes ctc config data to options api
135
+ function save_config( $override = NULL ) {
136
+ if ( isset( $override ) ) $option = $override;
137
+ else $option = apply_filters( 'chld_thm_cfg_option', '' );
138
+ $option = CHLD_THM_CFG_OPTIONS . $option;
139
+ //echo 'saving option: ' . $option . LF;
140
  $configarray = array();
141
  foreach ( $this->configvars as $configkey )
142
+ $configarray[ $configkey ] = $this->{$configkey};
143
+ update_option( $option . '_configvars', $configarray );
144
  foreach ( $this->dicts as $configkey )
145
+ update_option( $option . '_' . $configkey, $this->{$configkey} );
 
 
146
  }
147
+
148
  /*
149
  * get_prop
150
  * Getter interface (data sliced different ways depending on objname )
152
  function get_prop( $objname, $params = NULL ) {
153
  switch ( $objname ):
154
  case 'imports':
155
+ return $this->obj_to_utf8( is_array( $this->imports[ 'child' ] ) ?
156
+ ( current( $this->imports[ 'child' ] ) == 1 ?
157
+ array_keys( $this->imports[ 'child' ] ) :
158
+ array_keys( array_flip( $this->imports[ 'child' ] ) ) ) :
159
+ array() );
160
  case 'sel_ndx':
161
+ return $this->obj_to_utf8( $this->denorm_sel_ndx( empty( $params[ 'key' ] ) ? NULL : $params[ 'key' ] ) );
162
  case 'rule_val':
163
+ return empty( $params[ 'key' ] ) ? array() : $this->denorm_rule_val( $params[ 'key' ] );
164
  case 'val_qry':
165
+ if ( isset( $params[ 'rule' ] ) && isset( $this->dict_rule[ $params[ 'rule' ] ] ) ):
166
+ return empty( $params[ 'key' ] ) ?
167
+ array() : $this->denorm_val_query( $params[ 'key' ], $params[ 'rule' ] );
168
  endif;
169
  case 'sel_val':
170
+ return empty( $params[ 'key' ] ) ?
171
+ array() : $this->denorm_sel_val( $params[ 'key' ] );
172
  case 'rule':
173
  return $this->obj_to_utf8( array_flip( $this->dict_rule ) );
174
  case 'child':
175
  return $this->child;
176
  case 'parnt':
177
  return $this->parnt;
178
+ case 'configtype': // legacy plugin extension support
 
 
179
  return $this->configtype;
180
+ case 'addl_css':
181
+ return isset( $this->addl_css ) ? $this->addl_css : array();
182
  case 'child_name':
183
  return $this->child_name;
184
  case 'author':
187
  return $this->child_version;
188
  case 'preview':
189
  $this->styles = '';
190
+ if ( empty( $params[ 'key' ] ) || 'child' == $params[ 'key' ] ):
191
  $this->read_stylesheet( 'child' );
192
  else:
193
+ if ( isset( $this->addl_css ) ):
194
+ foreach ( $this->addl_css as $template ):
195
  $this->styles .= '/*** BEGIN ' . $template . ' ***/' . LF;
196
  $this->read_stylesheet( 'parnt', $template );
197
  $this->styles .= '/*** END ' . $template . ' ***/' . LF;
198
  endforeach;
199
  endif;
200
+ if ( $this->ctc()->is_theme() || $this->ctc()->is_legacy() ):
201
+ $this->styles .= '/*** BEGIN style.css ***/' . LF;
202
+ $this->read_stylesheet( 'parnt' );
203
+ $this->styles .= '/*** END style.css ***/' . LF;
204
+ endif;
205
  endif;
206
  $this->normalize_css();
207
  return $this->styles;
208
+ break;
209
+ default:
210
+ return $this->obj_to_utf8( apply_filters( 'chld_thm_get_prop', NULL, $objname, $params ) );
211
  endswitch;
212
  return FALSE;
213
  }
217
  * Setter interface (scalar values only)
218
  */
219
  function set_prop( $prop, $value ) {
220
+ if ( is_null( $this->{ $prop } ) || is_scalar( $this->{ $prop } ) )
221
+ $this->{ $prop } = $value;
222
  else return FALSE;
223
  }
224
  // formats css string for accurate parsing
225
  function normalize_css() {
226
+ if ( preg_match( "/(\}[\w\#\.]|; *\})/", $this->styles ) ): // prettify compressed CSS
227
  $this->styles = preg_replace( "/\*\/\s*/s", "*/\n", $this->styles ); // end comment
228
  $this->styles = preg_replace( "/\{\s*/s", " {\n ", $this->styles ); // open brace
229
  $this->styles = preg_replace( "/;\s*/s", ";\n ", $this->styles ); // semicolon
262
 
263
  // normalize selector styling
264
  $sel = implode( ', ', preg_split( '#\s*,\s*#s', trim( $sel ) ) );
265
+ //echo "$template $query $sel $rule $value $important" . LF;
266
  // add selector and query to index
267
+ if ( !isset( $this->dict_query[ $query ] ) ) $this->dict_query[ $query ] = ++$this->querykey;
268
+ if ( !isset( $this->dict_sel[ $sel ] ) ) $this->dict_sel[ $sel ] = ++$this->selkey;
269
+ if ( !isset( $this->sel_ndx[ $this->dict_query[ $query ] ][ $this->dict_sel[ $sel ] ] ) ):
270
  // increment key number
271
+ $this->sel_ndx[ $this->dict_query[ $query ] ][ $this->dict_sel[ $sel ] ] = ++$this->qskey;
272
 
273
+ $this->dict_qs[ $this->qskey ][ 's' ] = $this->dict_sel[ $sel ];
274
+ $this->dict_qs[ $this->qskey ][ 'q' ] = $this->dict_query[ $query ];
275
  // tell the UI to update a single cached query/selector lookup by passing 'qsid' as the key
276
  // (normally the entire array is replaced):
277
  if ( $this->ctc()->cache_updates )
286
  );
287
  endif;
288
  // update sequence for this selector if this is a later instance to keep cascade priority
289
+ if ( !isset( $this->dict_seq[ $this->qskey ] ) )
290
+ $this->dict_seq[ $this->qskey ] = $this->qskey;
291
  // set data and value
292
  if ( $rule ):
293
+ if ( !isset( $this->dict_rule[ $rule ] ) ):
294
+ $this->dict_rule[ $rule ] = ++$this->rulekey;
295
  // tell the UI to update a single cached rule:
296
  if ( $this->ctc()->cache_updates ):
297
  $this->ctc()->updates[] = array(
301
  );
302
  endif;
303
  endif;
304
+ $qsid = $this->sel_ndx[ $this->dict_query[ $query ] ][ $this->dict_sel[ $sel ] ];
305
+ $ruleid = $this->dict_rule[ $rule ];
306
+ if ( !isset( $this->dict_val[ $value ] ) ):
307
+ $this->dict_val[ $value ] = ++$this->valkey;
308
  endif;
309
+
310
+ $this->val_ndx[ $qsid ][ $ruleid ][ $template ] = $this->dict_val[ $value ];
311
+ // set the important flag for this value
312
+ $this->val_ndx[ $qsid ][ $ruleid ][ 'i_' . $template ] = $important;
313
  // tell the UI to add a single cached query/selector data array:
314
  if ( $this->ctc()->cache_updates ):
315
  $updatearr = array(
320
  $this->ctc()->updates[] = $updatearr;
321
  endif;
322
  if ( isset( $seq ) ): // this is a renamed selector
323
+ $this->dict_seq[ $qsid ] = $seq;
324
  if ( $this->ctc()->cache_updates ):
325
  $this->ctc()->updates[] = array(
326
  'obj' => 'rewrite',
331
  endif;
332
  endif;
333
  }
334
+
335
+ function prune_if_empty( $qsid ) {
336
+ if (! isset( $this->dict_val[ '' ] ) ) return FALSE;
337
+ $empty = $this->dict_val[ '' ];
338
+ foreach ( $this->val_ndx[ $qsid ] as $ruleid => $arr ):
339
+ // if any values exist return
340
+ if ( ( isset( $arr[ 'child' ] ) && $empty != $arr[ 'child' ] )
341
+ || ( isset( $arr[ 'parnt' ] ) && $empty != $arr[ 'parnt' ] ) ):
342
+
343
+ do_action( 'chld_thm_cfg_update_qsid', $qsid );
344
+ return FALSE;
345
+ endif;
346
+ endforeach;
347
+ // no values, prune from data ( keep dictionary entries )
348
+ unset( $this->sel_ndx[ $this->dict_qs[ $qsid ][ 'q' ] ][ $this->dict_qs[ $qsid ][ 's' ] ] );
349
+ unset( $this->val_ndx[ $qsid ] );
350
+ unset( $this->dict_qs[ $qsid ] );
 
 
351
  }
352
+
353
  /* recurse_directory
354
  * searches filesystem for valid files based on parameters and returns array of filepaths.
355
  * Because it requires logic specific to CTC, core WP recurse function is not used.
363
 
364
  $ext = '(' . implode( '|', array_keys( $this->ctc()->imgmimes ) ) . ')';
365
  endif;
366
+ while( count( $dirs ) && $loops < CHLD_THM_CFG_MAX_RECURSE_LOOPS ): // failsafe valve
367
  $loops++;
368
  $dir = array_shift( $dirs );
369
  if ( $handle = opendir( $dir ) ):
407
  */
408
  function parse_post_data() {
409
  $this->cache_updates = TRUE;
410
+ if ( isset( $_POST[ 'ctc_new_selectors' ] ) ):
411
+ $this->styles = $this->parse_css_input( LF . $_POST[ 'ctc_new_selectors' ] );
412
  $this->parse_css( 'child',
413
+ ( isset( $_POST[ 'ctc_sel_ovrd_query' ] )?trim( $_POST[ 'ctc_sel_ovrd_query' ] ):NULL ), FALSE );
414
+ elseif ( isset( $_POST[ 'ctc_child_imports' ] ) ):
415
+ $this->imports[ 'child' ] = array();
416
+ $this->styles = $this->parse_css_input( $_POST[ 'ctc_child_imports' ] );
417
  $this->parse_css( 'child' );
418
+ elseif ( isset( $_POST[ 'ctc_configtype' ] ) ):
419
+ ob_start();
420
+ do_action( 'chld_thm_cfg_get_stylesheets' );
421
+ $this->ctc()->updates[] = array(
422
+ 'obj' => 'stylesheets',
423
+ 'key' => '',
424
+ 'data' => ob_get_contents(),
425
+ );
426
+ ob_end_clean();
427
+ ob_start();
428
+ do_action( 'chld_thm_cfg_get_backups' );
429
+ $this->ctc()->updates[] = array(
430
+ 'obj' => 'backups',
431
+ 'key' => '',
432
+ 'data' => ob_get_contents(),
433
+ );
434
+ ob_end_clean();
435
+ return;
436
  else:
437
+ $newselector = isset( $_POST[ 'ctc_rewrite_selector' ] ) ?
438
+ $this->sanitize( $this->parse_css_input( $_POST[ 'ctc_rewrite_selector' ] ) ) : NULL;
439
  // set the custom sequence value
440
  foreach ( preg_grep( '#^ctc_ovrd_child_seq_#', array_keys( $_POST ) ) as $post_key ):
441
  if ( preg_match( '#^ctc_ovrd_child_seq_(\d+)$#', $post_key, $matches ) ):
442
+ $qsid = $matches[ 1 ];
443
+ $this->dict_seq[ $qsid ] = intval( $_POST[ $post_key ] );
444
  endif;
445
  endforeach;
446
  $parts = array();
447
  foreach ( preg_grep( '#^ctc_(ovrd|\d+)_child#', array_keys( $_POST ) ) as $post_key ):
448
  if ( preg_match( '#^ctc_(ovrd|\d+)_child_([\w\-]+?)_(\d+?)(_(.+))?$#', $post_key, $matches ) ):
449
+ $valid = $matches[ 1 ];
450
+ $rule = $matches[ 2 ];
451
+ if ( NULL == $rule || !isset( $this->dict_rule[ $rule ] ) ) continue;
452
+ $ruleid = $this->dict_rule[ $rule ];
453
+ $qsid = $matches[ 3 ];
454
+ $value = $this->normalize_color( $this->sanitize( $this->parse_css_input( $_POST[ $post_key ] ) ) );
455
  $important = $this->is_important( $value );
456
+ if ( !empty( $_POST[ 'ctc_' . $valid . '_child_' . $rule . '_i_' . $qsid ] ) ) $important = 1;
457
 
458
  $selarr = $this->denorm_query_sel( $qsid );
459
+ if ( !empty( $matches[ 5 ] ) ):
460
+ $parts[ $qsid ][ $rule ][ $matches[ 5 ] ] = $value;
461
+ $parts[ $qsid ][ $rule ][ 'important' ] = $important;
462
+ $parts[ $qsid ][ $rule ][ 'query' ] = $selarr[ 'query' ];
463
+ $parts[ $qsid ][ $rule ][ 'selector' ] = $selarr[ 'selector' ];
464
  else:
465
+ if ( $newselector && $newselector != $selarr[ 'selector' ] ):
466
  // If this is a renamed selector, add new selector to array
467
  // and clear original child selector values.
468
  // Passing the sequence in the last argument serves two purposes:
469
  // 1. sets sequence for new renamed selector.
470
  // 2. tells the update_arrays function to flag this as a
471
  // renamed selector to pass back in result array.
472
+ $this->update_arrays( 'child', $selarr[ 'query' ], $newselector,
473
+ $rule, trim( $value ), $important, $this->dict_seq[ $qsid ] );
474
+ $this->update_arrays( 'child', $selarr[ 'query' ], $selarr[ 'selector' ], $rule, '' );
475
  else:
476
  // Otherwise, just update with the new values:
477
+ $this->update_arrays( 'child', $selarr[ 'query' ], $selarr[ 'selector' ],
478
  $rule, trim( $value ), $important );
479
  endif;
480
  endif;
483
  foreach ( $parts as $qsid => $rule_arr ):
484
  foreach ( $rule_arr as $rule => $rule_part ):
485
  if ( 'background' == $rule ):
486
+ $value = $rule_part[ 'background_url' ];
487
  elseif ( 'background-image' == $rule ):
488
+ if ( empty( $rule_part[ 'background_url' ] ) ):
489
+ if ( empty( $rule_part[ 'background_color2' ] ) ):
490
  $value = '';
491
  else:
492
  $value = implode( ':', array(
493
+ $rule_part[ 'background_origin' ],
494
+ $rule_part[ 'background_color1' ], '0%',
495
+ $rule_part[ 'background_color2' ], '100%'
496
  ) );
497
  endif;
498
  else:
499
+ $value = $rule_part[ 'background_url' ];
500
  endif;
501
  elseif ( preg_match( '#^border(\-(top|right|bottom|left))?$#', $rule ) ):
502
  $value = implode( ' ', array(
503
+ $rule_part[ 'border_width' ],
504
+ $rule_part[ 'border_style' ],
505
+ $rule_part[ 'border_color' ]
506
  ) );
507
  else:
508
  $value = '';
509
  endif;
510
+ if ( $newselector && $newselector != $rule_part[ 'selector' ] ):
511
+ $this->update_arrays( 'child', $rule_part[ 'query' ], $newselector,
512
+ $rule, trim( $value ), $rule_part[ 'important' ], $this->dict_seq[ $qsid ] );
513
+ $this->update_arrays( 'child', $rule_part[ 'query' ], $rule_part[ 'selector' ], $rule, '' );
514
  else:
515
+ $this->update_arrays( 'child', $rule_part[ 'query' ], $rule_part[ 'selector' ],
516
+ $rule, trim( $value ), $rule_part[ 'important' ] );
517
  endif;
518
  endforeach;
519
  endforeach;
520
+ $this->prune_if_empty( $qsid );
521
  endif;
522
  }
523
 
546
  * reads stylesheet to get WordPress meta data and passes rest to parse_css
547
  */
548
  function parse_css_file( $template, $file = 'style.css' ) {
549
+ // turn off caching when parsing files to reduce memory usage
550
  $this->ctc()->cache_updates = FALSE;
551
  $this->styles = ''; // reset styles
552
  $this->read_stylesheet( $template, $file );
554
  $regex = '#Theme Name:\s*(.+?)\n#i';
555
  preg_match( $regex, $this->styles, $matches );
556
  $child_name = $this->get_prop( 'child_name' );
557
+ if ( !empty( $matches[ 1 ] ) && 'child' == $template && empty( $child_name ) ) $this->set_prop( 'child_name', $matches[ 1 ] );
558
  $this->parse_css( $template );
559
  }
560
 
561
+ // loads raw css file into local memory
562
+ function read_stylesheet( $template = 'child', $file = 'style.css' ) {
563
+
564
+ // these conditions support revert/restore option in 1.6.0+
565
+ if ( 'all' == $file ) return;
566
+ elseif ( '' == $file ) $file = 'style.css';
567
+ // end revert/restore conditions
568
+
569
+ $source = $this->get_prop( $template );
570
+ if ( empty( $source ) || !is_scalar( $source ) ) return FALSE;
571
+ $themedir = trailingslashit( get_theme_root() ) . $source;
572
+ $stylesheet = apply_filters( 'chld_thm_cfg_' . $template, trailingslashit( $themedir )
573
+ . $file , ( $this->ctc()->is_legacy() ? $this : $file ) ); // support for plugins extension < 2.0
574
+
575
+ //echo 'reading stylesheet: ' . $stylesheet . LF;
576
+
577
+ // read stylesheet
578
+
579
+ if ( $stylesheet_verified = $this->is_file_ok( $stylesheet, 'read' ) ):
580
+ $this->styles .= @file_get_contents( $stylesheet_verified ) . "\n";
581
+ //echo 'count after get contents: ' . strlen( $this->styles ) . LF;
582
+ else:
583
+ //echo 'not ok!' . LF;
584
+ endif;
585
+ }
586
+
587
  /*
588
  * parse_css
589
  * Accepts raw CSS as text and parses into individual properties.
602
 
603
  $regex = '#(\@import.+?);#';
604
  preg_match_all( $regex, $this->styles, $matches );
605
+ foreach ( preg_grep( '#' . $this->get_prop( 'parnt' ) . '\/style\.css#', $matches[ 1 ], PREG_GREP_INVERT ) as $import )
606
+ $this->imports[ $template ][ $import ] = 1;
607
  if ( $this->ctc()->cache_updates ):
608
  $this->ctc()->updates[] = array(
609
  'obj' => 'imports',
610
+ 'data' => array_keys( $this->imports[ $template ] ),
611
  );
612
  endif;
613
  endif;
617
  '#(\@media[^\{]+?)\{(.*?\})?\s*?\}#s', // get all other media queries
618
  ) as $regex ): // (((?!\@media).) backreference too memory intensive - rolled back in v 1.4.8.1
619
  preg_match_all( $regex, $this->styles, $matches );
620
+ foreach ( $matches[ 1 ] as $segment ):
621
+ $ruleset[ trim( $segment ) ] = array_shift( $matches[ 2 ] ) . ( isset( $ruleset[ trim( $segment ) ] )?$ruleset[ trim( $segment ) ]:'' );
622
  endforeach;
623
  // stripping rulesets leaves base styles
624
  $this->styles = preg_replace( $regex, '', $this->styles );
625
  endforeach;
626
+ $ruleset[ $basequery ] = $this->styles;
627
  foreach ( $ruleset as $query => $segment ):
628
  // make sure there is semicolon before closing brace
629
  $segment = preg_replace( '#(\})#', ";$1", $segment );
630
  // parses selectors and corresponding rules
631
  $regex = '#\s([\[\.\#\:\w][\w\-\s\(\)\[\]\'\^\*\.\#\+:,"=>]+?)\s*\{(.*?)\}#s'; //
632
  preg_match_all( $regex, $segment, $matches );
633
+ foreach( $matches[ 1 ] as $sel ):
634
+ $stuff = array_shift( $matches[ 2 ] );
635
  $this->update_arrays( $template, $query, $sel );
636
  // handle base64 data
637
  $stuff = preg_replace( '#data:([^;]+?);([^\)]+?)\)#s', "data:$1%%semi%%$2)", $stuff );
638
  foreach ( explode( ';', $stuff ) as $ruleval ):
639
+ /**
640
+ * FIXME: set limit of number of parsed selectors?
641
+ * if ( $this->qskey > CHLD_THM_CFG_MAX_SELECTORS ) break;
642
+ */
643
  if ( FALSE === strpos( $ruleval, ':' ) ) continue;
644
  list( $rule, $value ) = explode( ':', $ruleval, 2 );
645
  $rule = trim( $rule );
708
  $rulearr = array_flip( $this->dict_rule );
709
  $valarr = array_flip( $this->dict_val );
710
  $selarr = array_flip( $this->dict_sel );
711
+
712
  foreach ( $this->sort_queries() as $query => $sort_order ):
713
  $has_selector = 0;
714
  $sel_output = '';
715
+ $selectors = $this->sel_ndx[ $this->dict_query[ $query ] ];
716
  uasort( $selectors, array( $this, 'cmp_seq' ) );
717
  if ( 'base' != $query ) $sel_output .= $query . ' {' . LF;
718
  foreach ( $selectors as $selid => $qsid ):
719
  $has_value = 0;
720
+ $sel = $selarr[ $selid ];
721
+ if ( !empty( $this->val_ndx[ $qsid ] ) ):
722
  $shorthand = array();
723
+ foreach ( $this->val_ndx[ $qsid ] as $ruleid => $valid ):
724
+ if ( isset( $valid[ 'child' ] )
725
+ && isset( $valarr[ $valid[ 'child' ] ] )
726
+ && '' !== $valarr[ $valid[ 'child' ] ]
727
+ && ( !isset( $valid[ 'parnt' ] ) || $valid[ 'parnt' ] != $valid[ 'child' ] ) ):
728
  if ( ! $has_value ):
729
+ $sel_output .= isset( $this->dict_seq[ $qsid ] )?'/*' . $this->dict_seq[ $qsid ] . '*/' . LF:'';
730
  // show load order
731
  $sel_output .= $sel . ' {' . LF;
732
  $has_value = 1;
733
  $has_selector = 1;
734
  endif;
735
+ $important_parnt = empty( $valid[ 'i_parnt' ] ) ? 0 : 1;
736
+ $important = isset( $valid[ 'i_child' ] ) ? $valid[ 'i_child' ] : $important_parnt;
737
+ $sel_output .= $this->add_vendor_rules(
738
+ $rulearr[ $ruleid ],
739
+ $valarr[ $valid[ 'child' ] ],
740
+ $shorthand,
741
+ $important
742
+ );
743
  endif;
744
  endforeach;
745
  $sel_output .= $this->encode_shorthand( $shorthand ); // . ( $important ? ' !important' : '' );
752
  if ( $has_selector ) $output .= $sel_output;
753
  endforeach;
754
  $stylesheet = apply_filters( 'chld_thm_cfg_target', $this->get_child_target(), $this );
755
+ //echo 'writing stylesheet: ' . $stylesheet . LF;
756
+ //echo //print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), true) . LF;
757
  if ( $stylesheet_verified = $this->is_file_ok( $stylesheet, 'write' ) ):
758
  global $wp_filesystem; // this was initialized earlier;
759
+ // backup current stylesheet
760
+ if ( $backup && is_file( $stylesheet_verified ) ):
761
+ $timestamp = date( 'YmdHis', current_time( 'timestamp' ) );
762
+ $bakfile = preg_replace( "/\.css$/", '', $stylesheet_verified ) . '-' . $timestamp . '.css';
763
+ // don't write new stylesheet if backup fails
764
+ if ( !$wp_filesystem->copy(
765
+ $this->ctc()->fspath( $stylesheet_verified ),
766
+ $this->ctc()->fspath( $bakfile ) ) ) return FALSE;
767
+ endif;
768
+ // write new stylesheet:
769
+ // try direct write first, then wp_filesystem write
770
+ // stylesheet must already exist and be writable by web server
771
+ if ( FALSE !== @file_put_contents( $stylesheet_verified, $output ) ): //is_writable( $stylesheet_verified ) &&
772
+ //echo 'stylesheet write successful: ' . $stylesheet_verified . LF;
773
+ return TRUE;
774
+ elseif ( FALSE !== $wp_filesystem->put_contents( $this->ctc()->fspath( $stylesheet_verified ), $output ) ):
775
+ //echo 'filesystem stylesheet write successful: ' . $stylesheet_verified . LF;
776
+ return TRUE;
777
+ endif;
778
+ //echo 'stylesheet write failed: ' . $stylesheet_verified . LF;
779
  endif;
780
+ //echo 'file not ok! ' . $stylesheet . LF;
781
  return FALSE;
782
  }
783
 
792
  if ( 'filter' == $rule && ( FALSE !== strpos( $value, 'progid:DXImageTransform.Microsoft.Gradient' ) ) ) return;
793
  $importantstr = $important ? ' !important' : '';
794
  if ( preg_match( "/^(margin|padding)\-(top|right|bottom|left)$/", $rule, $matches ) ):
795
+ $shorthand[ $matches[ 1 ] ][ $matches[ 2 ] ] = $value . $importantstr;
796
  return '';
797
  elseif ( preg_match( '/^(' . implode( '|', $this->vendorrule ) . ')$/', $rule ) ):
798
  foreach( array( 'moz', 'webkit', 'o' ) as $prefix ):
805
  if ( $gradient = $this->decode_gradient( $value ) ):
806
  // standard gradient
807
  foreach( array( 'moz', 'webkit', 'o', 'ms' ) as $prefix ):
808
+ $rules .= ' background-image: -' . $prefix . '-' . 'linear-gradient(' . $gradient[ 'origin' ] . ', '
809
+ . $gradient[ 'color1' ] . ', ' . $gradient[ 'color2' ] . ')' . $importantstr . ';' . LF;
810
  endforeach;
811
  // W3C standard gradient
812
  // rotate origin 90 degrees
813
+ if ( preg_match( '/(\d+)deg/', $gradient[ 'origin' ], $matches ) ):
814
+ $org = ( 90 - $matches[ 1 ] ) . 'deg';
815
  else:
816
+ foreach ( preg_split( "/\s+/", $gradient[ 'origin' ] ) as $dir ):
817
  $dir = strtolower( $dir );
818
+ $dirs[] = ( 'top' == $dir ? 'bottom' :
819
+ ( 'bottom' == $dir ? 'top' :
820
+ ( 'left' == $dir ? 'right' :
821
+ ( 'right' == $dir ? 'left' : $dir ) ) ) );
822
  endforeach;
823
  $org = 'to ' . implode( ' ', $dirs );
824
  endif;
825
  $rules .= ' background-image: linear-gradient(' . $org . ', '
826
+ . $gradient[ 'color1' ] . ', ' . $gradient[ 'color2' ] . ')' . $importantstr . ';' . LF;
827
 
828
  // legacy webkit gradient - we'll add if there is demand
829
  // '-webkit-gradient(linear,' .$origin . ', ' . $color1 . ', '. $color2 . ')';
830
 
831
  // MS filter gradient
832
+ $type = ( in_array( $gradient[ 'origin' ], array( 'left', 'right', '0deg', '180deg' ) ) ? 1 : 0 );
833
+ $color1 = preg_replace( "/^#/", '#00', $gradient[ 'color1' ] );
834
  $rules .= ' filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=' . $type . ', StartColorStr="'
835
+ . strtoupper( $color1 ) . '", EndColorStr="' . strtoupper( $gradient[ 'color2' ] ) . '")'
836
+ . $importantstr . ';' . LF;
837
  else:
838
  // url or other value
839
  $rules .= ' ' . $rule . ': ' . $value . $importantstr . ';' . LF;
859
  endif;
860
  else:
861
  $regex = '#(url *\([^\)]+\))#';
862
+ if ( preg_match( $regex, $value, $matches ) ) $url = $matches[ 1 ];
863
  $parts = preg_split( $regex, $value );
864
 
865
  if ( count( $parts ) == 1 ):
866
  // this is a named color or single hex color or none
867
+ $part = str_replace( ' ', '', $parts[ 0 ] );
868
  $rules[] = 'none' == $part ? 'background' : 'background-color';
869
  $values[] = $part;
870
  else:
871
  $rules[] = 'background-image';
872
  $values[] = $url;
873
+ if ( !empty( $parts[ 0 ] ) && '' !== $parts[ 0 ] ):
874
  $rules[] = 'background-color';
875
+ $values[] = trim( $parts[ 0 ] );
876
  endif;
877
  $position = array();
878
+ foreach( preg_split( '/ +/', trim( $parts[ 1 ] ) ) as $part ):
879
  if ( '' === $part ) continue; // empty( $part ) ||
880
  if ( FALSE === strpos( $part, 'repeat' ) ):
881
  $position[] = $part;
900
  function normalize_font( $value, &$rules, &$values ) {
901
  $regex = '#^((\d+|bold|normal) )?((italic|normal) )?(([\d\.]+(px|r?em|%))[\/ ])?(([\d\.]+(px|r?em|%)?) )?(.+)$#is';
902
  preg_match( $regex, $value, $parts );
903
+ if ( !empty( $parts[ 2 ] ) ):
904
  $rules[] = 'font-weight';
905
+ $values[] = $parts[ 2 ];
906
  endif;
907
+ if ( !empty( $parts[ 4 ] ) ):
908
  $rules[] = 'font-style';
909
+ $values[] = $parts[ 4 ];
910
  endif;
911
+ if ( !empty( $parts[ 6 ] ) ):
912
  $rules[] = 'font-size';
913
+ $values[] = $parts[ 6 ];
914
  endif;
915
+ if ( !empty( $parts[ 9 ] ) ):
916
  $rules[] = 'line-height';
917
+ $values[] = $parts[ 9 ];
918
  endif;
919
+ if ( !empty( $parts[ 11 ] ) ):
920
  $rules[] = 'font-family';
921
+ $values[] = $parts[ 11 ];
922
  endif;
923
  }
924
 
930
  */
931
  function normalize_margin_padding( $rule, $value, &$rules, &$values ) {
932
  $parts = preg_split( "/ +/", trim( $value ) );
933
+ if ( !isset( $parts[ 1 ] ) ) $parts[ 1 ] = $parts[ 0 ];
934
+ if ( !isset( $parts[ 2 ] ) ) $parts[ 2 ] = $parts[ 0 ];
935
+ if ( !isset( $parts[ 3 ] ) ) $parts[ 3 ] = $parts[ 1 ];
936
+ $rules[ 0 ] = $rule . '-top';
937
+ $values[ 0 ] = $parts[ 0 ];
938
+ $rules[ 1 ] = $rule . '-right';
939
+ $values[ 1 ] = $parts[ 1 ];
940
+ $rules[ 2 ] = $rule . '-bottom';
941
+ $values[ 2 ] = $parts[ 2 ];
942
+ $rules[ 3 ] = $rule . '-left';
943
+ $values[ 3 ] = $parts[ 3 ];
944
  }
945
 
946
  /*
955
  $rule = array();
956
  $importantct = 0;
957
  // which sides do we have and are they important?
958
+ foreach( $shorthand[ $key ] as $side => $val ):
959
  $ict = 0;
960
+ $rule[ $side ] = trim( preg_replace( '/'.$importantstr.'/', '', $val, 1, $ict ) );
961
+ $important[ $side ] = $ict;
962
  $importantct += $ict;
963
  endforeach;
964
  // shorthand must have 4 explicit values and all must have same priority
965
  if ( 4 == count( $rule ) && ( 0 == $importantct || 4 == $importantct ) ):
966
  // let's try to condense the values into as few as possible, starting with the top value
967
  $parts = array();
968
+ $parts[ 0 ] = $rule[ 'top' ];
969
  // if left is not the same as right, we must use all 4 values
970
+ if ( $rule[ 'left' ] !== $rule[ 'right' ] ):
971
+ $parts[ 3 ] = $rule[ 'left' ];
972
+ $parts[ 2 ] = $rule[ 'bottom' ];
973
+ $parts[ 1 ] = $rule[ 'right' ];
974
  endif;
975
  // if top is not the same as bottom, we must use at least 3 values
976
+ if ( $rule[ 'bottom' ] !== $rule[ 'top' ] ):
977
+ $parts[ 2 ] = $rule[ 'bottom' ];
978
+ $parts[ 1 ] = $rule[ 'right' ];
979
  endif;
980
  // if top is not the same as right, we must use at least 2 values
981
+ if ( $rule[ 'right' ] !== $rule[ 'top' ] ):
982
+ $parts[ 1 ] = $rule[ 'right' ];
983
  endif;
984
  // the order of the sides is critical: top right bottom left
985
  ksort( $parts );
989
  else:
990
  // otherwise return separate rule for each side
991
  foreach ( $rule as $side => $value ):
992
+ $rules .= ' ' . $key . '-' . $side . ': ' . $value . ( $important[ $side ] ? $importantstr : '' ) . ';' . LF;
993
  endforeach;
994
  endif;
995
  endforeach;
1007
  $regex = '#gradient[^\)]*?\((((top|bottom|left|right)?( (top|bottom|left|right))?|\d+deg),)?([^\)]*[\'"]?(\#\w{3,8}|rgba?\([\d, ]+?\)|hsla?\([\d%, ]+?\))( \d+%)?)([^\)]*[\'"]?(\#\w{3,8}|rgba?\([\d, ]+?\)|hsla?\([\d%, ]+?\))( \d+%)?)([^\)]*gradienttype=[\'"]?(\d)[\'"]?)?[^\)]*\)#i';
1008
  $param = $parts = array();
1009
  preg_match( $regex, $value, $parts );
1010
+ if ( empty( $parts[ 13 ] ) ):
1011
+ if ( empty( $parts[ 2 ] ) ):
1012
+ $param[ 0 ] = 'top';
1013
  else:
1014
+ $param[ 0 ] = trim( $parts[ 2 ] );
1015
  endif;
1016
+ if ( empty( $parts[ 8 ] ) ):
1017
+ $param[ 2 ] = '0%';
1018
  else:
1019
+ $param[ 2 ] = trim( $parts[ 8 ] );
1020
  endif;
1021
+ if ( empty( $parts[ 11 ] ) ):
1022
+ $param[ 4 ] = '100%';
1023
  else:
1024
+ $param[ 4 ] = trim( $parts[ 11 ] );
1025
  endif;
1026
+ elseif( '0' == $parts[ 13 ] ):
1027
+ $param[ 0 ] = 'top';
1028
+ $param[ 2 ] = '0%';
1029
+ $param[ 4 ] = '100%';
1030
+ elseif ( '1' == $parts[ 13 ] ):
1031
+ $param[ 0 ] = 'left';
1032
+ $param[ 2 ] = '0%';
1033
+ $param[ 4 ] = '100%';
1034
  endif;
1035
+ if ( isset( $parts[ 7 ] ) && isset( $parts[ 10 ] ) ):
1036
+ $param[ 1 ] = $parts[ 7 ];
1037
+ $param[ 3 ] = $parts[ 10 ];
1038
  ksort( $param );
1039
  return implode( ':', $param );
1040
  else: return $value;
1047
  */
1048
  function decode_border( $value ) {
1049
  if ( preg_match( '#^(0|none)#i', $value ) ):
1050
+ $parts[ 0 ] = $value;
1051
+ $parts[ 1 ] = $parts[ 2 ] = '';
1052
  else:
1053
  $parts = preg_split( '#\s+#', $value, 3 );
1054
  endif;
1055
  return array(
1056
+ 'width' => empty( $parts[ 0 ] ) ? '' : $parts[ 0 ],
1057
+ 'style' => empty( $parts[ 1 ] ) ? '' : $parts[ 1 ],
1058
+ 'color' => empty( $parts[ 2 ] ) ? '' : $parts[ 2 ],
1059
  );
1060
  }
1061
 
1067
  $parts = explode( ':', $value, 5 );
1068
  if ( !preg_match( '#(url|none)#i', $value ) && 5 == count( $parts ) ):
1069
  return array(
1070
+ 'origin' => empty( $parts[ 0 ] ) ? '' : $parts[ 0 ],
1071
+ 'color1' => empty( $parts[ 1 ] ) ? '' : $parts[ 1 ],
1072
+ 'stop1' => empty( $parts[ 2 ] ) ? '' : $parts[ 2 ],
1073
+ 'color2' => empty( $parts[ 3 ] ) ? '' : $parts[ 3 ],
1074
+ 'stop2' => empty( $parts[ 4 ] ) ? '' : $parts[ 4 ],
1075
  );
1076
  endif;
1077
  return FALSE;
1085
  $rule_sel_arr = array();
1086
  $val_arr = array_flip( $this->dict_val );
1087
  foreach ( $this->val_ndx as $selid => $rules ):
1088
+ if ( !isset( $rules[ $ruleid ] ) ) continue;
1089
+ foreach ( $rules[ $ruleid ] as $theme => $val ):
1090
+ if ( !isset( $val_arr[ $val ] ) || '' === $val_arr[ $val ] ) continue;
1091
+ $rule_sel_arr[ $val ] = $val_arr[ $val ];
1092
  endforeach;
1093
  endforeach;
1094
  return $rule_sel_arr;
1103
  $value_query_arr = array();
1104
  foreach ( $this->val_ndx as $qsid => $rules ):
1105
  foreach ( $rules as $ruleid => $values ):
1106
+ if ( $ruleid != $this->dict_rule[ $rule ] ) continue;
1107
  foreach ( $values as $name => $val ):
1108
  if ( 'i' == $name || $val != $valid ) continue;
1109
  $selarr = $this->denorm_query_sel( $qsid );
1110
  $valarr = $this->denorm_sel_val( $qsid );
1111
+ $value_query_arr[ $rule ][ $selarr[ 'query' ] ][ $qsid ] = $valarr;
1112
  endforeach;
1113
  endforeach;
1114
  endforeach;
1120
  * Return id, query and selector values of a specific qsid (query-selector ID)
1121
  */
1122
  function denorm_query_sel( $qsid ) {
1123
+ if ( !isset( $this->dict_qs[ $qsid ] ) ) return array();
1124
+ $queryarr = array_flip( $this->dict_query );
1125
+ $selarr = array_flip( $this->dict_sel );
1126
+ $this->dict_seq[ $qsid ] = isset( $this->dict_seq[ $qsid ] ) ? $this->dict_seq[ $qsid ] : $qsid;
1127
  return array(
1128
  'id' => $qsid,
1129
+ 'query' => $queryarr[ $this->dict_qs[ $qsid ][ 'q' ] ],
1130
+ 'selector' => $selarr[ $this->dict_qs[ $qsid ][ 's' ] ],
1131
+ 'seq' => $this->dict_seq[ $qsid ],
1132
  );
1133
  }
1134
 
1141
  $selarr = $this->denorm_query_sel( $qsid );
1142
  $valarr = array_flip( $this->dict_val );
1143
  $rulearr = array_flip( $this->dict_rule );
1144
+ if ( isset( $this->val_ndx[ $qsid ] ) && is_array( $this->val_ndx[ $qsid ] ) ):
1145
+ foreach ( $this->val_ndx[ $qsid ] as $ruleid => $values ):
1146
  foreach ( $values as $name => $val ):
1147
  if ( 'i_parnt' == $name || 'i_child' == $name ):
1148
+ $selarr[ 'value' ][ $rulearr[ $ruleid ] ][ $name ] = ( empty( $val ) ? 0 : 1 );
1149
+ elseif ( !isset( $valarr[ $val ] ) || '' === $valarr[ $val ] ):
1150
  continue;
1151
  else:
1152
+ $selarr[ 'value' ][ $rulearr[ $ruleid ] ][ $name ] = $valarr[ $val ];
1153
  endif;
1154
  endforeach;
1155
  // add load order
1168
  $selarr = array_flip( $this->dict_sel );
1169
  foreach( $this->sel_ndx as $queryid => $sel ):
1170
  foreach( $sel as $selid => $qsid ):
1171
+ $sel_ndx_norm[ $queryarr[ $queryid ] ][ $selarr[ $selid ] ] = $qsid;
1172
  endforeach;
1173
  endforeach;
1174
+ return empty( $query ) ? $sel_ndx_norm : $sel_ndx_norm[ $query ];
1175
  }
1176
 
1177
  /*
1197
  $queries = array();
1198
  $queryarr = array_flip( $this->dict_query );
1199
  foreach ( array_keys( $this->sel_ndx ) as $queryid ):
1200
+ $query = $queryarr[ $queryid ];
1201
  if ( 'base' == $query ):
1202
+ $queries[ 'base' ] = -999999;
1203
  continue;
1204
  endif;
1205
  if ( preg_match( "/((min|max)(\-device)?\-width)\s*:\s*(\d+)/", $query, $matches ) ):
1206
+ $queries[ $query ] = 'min-width' == $matches[ 1 ] ? $matches[ 4 ] : -$matches[ 4 ];
1207
  else:
1208
+ $queries[ $query ] = $queryid - 10000;
1209
  endif;
1210
  endforeach;
1211
  asort( $queries );
1214
 
1215
  // sort selectors based on dict_seq if exists, otherwise qsid
1216
  function cmp_seq( $a, $b ) {
1217
+ $cmpa = isset( $this->dict_seq[ $a ] ) ? $this->dict_seq[ $a ] : $a;
1218
+ $cmpb = isset( $this->dict_seq[ $b ] ) ? $this->dict_seq[ $b ] : $b;
1219
  if ( $cmpa == $cmpb ) return 0;
1220
  return ( $cmpa < $cmpb ) ? -1 : 1;
1221
  }
1227
  * and stringifies NULLs
1228
  */
1229
  function obj_to_utf8( $data ) {
1230
+ if ( is_object( $data ) )
 
1231
  $data = get_object_vars( $data );
1232
+ if ( is_array( $data ) )
 
1233
  return array_map( array( &$this, __FUNCTION__ ), $data );
1234
+ else
 
1235
  return is_null( $data ) ? '' : utf8_encode( $data );
 
1236
  }
1237
  // convert ascii character into decimal value
1238
  function to_ascii( $matches ) {
1239
+ return ord( $matches[ 0 ] );
1240
  }
1241
  // convert decimal value into ascii character
1242
  function from_ascii( $matches ) {
1243
+ return chr( $matches[ 0 ] );
1244
  }
1245
 
1246
  /* is_file_ok
1247
  * verify file exists and is in valid location
1248
  */
1249
  function is_file_ok( $stylesheet, $permission = 'read' ) {
1250
+ //echo 'verifying stylesheet (' . $permission . ') : ' . $stylesheet . LF;
1251
+ //echo 'current styles string: ' . strlen( $this->styles ) . LF;
1252
+ //echo 'current qs key: ' . $this->qskey . LF;
1253
+ //$this->ctc()->backtrace_summary();
1254
  // remove any ../ manipulations
1255
  $stylesheet = preg_replace( "%\.\./%", '/', $stylesheet );
1256
+ if ( 'read' == $permission && !is_file( $stylesheet ) ):
1257
+ //echo ' no file!' . LF;
1258
+ return FALSE;
1259
+ elseif ( 'search' == $permission && !is_dir( $stylesheet ) ):
1260
+ //echo ' no dir!' . LF;
1261
+ return FALSE;
1262
+ endif;
1263
  // sanity check for php files
1264
  //if ( !preg_match( '%' . preg_quote( $ext ) . '$%', $stylesheet ) ) return FALSE;
1265
  // check if in themes dir;
1266
  if ( preg_match( '%^' . preg_quote( get_theme_root() ) . '%', $stylesheet ) ) return $stylesheet;
1267
  // check if in plugins dir
1268
  if ( preg_match( '%^' . preg_quote( WP_PLUGIN_DIR ) . '%', $stylesheet ) ) return $stylesheet;
1269
+ //echo 'not in wp namespace! ' . LF;
1270
  return FALSE;
1271
  }
1272
  /* normalize_color
1279
  }
1280
  // callback for normalize_color regex
1281
  function tolower( $matches ) {
1282
+ return '#' . strtolower( $matches[ 1 ] );
1283
  }
1284
  }
1285
  ?>
includes/class-ctc-ui.php CHANGED
@@ -5,7 +5,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
5
  Class: Child_Theme_Configurator_UI
6
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
7
  Description: Handles the plugin User Interface
8
- Version: 1.6.3
9
  Author: Lilaea Media
10
  Author URI: http://www.lilaeamedia.com/
11
  Text Domain: chld_thm_cfg
@@ -15,6 +15,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
15
  */
16
  class ChildThemeConfiguratorUI {
17
  // helper function to globalize ctc object
 
18
  function ctc() {
19
  global $chld_thm_cfg;
20
  return $chld_thm_cfg;
@@ -23,23 +24,20 @@ class ChildThemeConfiguratorUI {
23
  function render() {
24
  $css = $this->ctc()->css;
25
  $themes = $this->ctc()->themes;
26
- $parent = isset( $_GET['ctc_parent'] ) ? sanitize_text_field( $_GET['ctc_parent'] ) : $css->get_prop( 'parnt' );
27
  $child = $css->get_prop( 'child' );
28
- $configtype = $css->get_prop( 'configtype' );
29
- if ( empty( $configtype ) ) $configtype = 'theme';
30
- $hidechild = ( count( $themes['child'] ) ? '' : 'style="display:none"' );
31
- $enqueueset = 'theme' != $configtype || isset( $css->enqueue );
32
- $mustimport = $this->parent_stylesheet_check( $parent );
33
  $imports = $css->get_prop( 'imports' );
34
  $id = 0;
35
  $this->ctc()->fs_method = get_filesystem_method();
36
  add_thickbox();
37
  add_action( 'chld_thm_cfg_related_links', array( $this, 'lilaea_plug' ) );
38
- include ( $this->ctc()->pluginPath .'/includes/forms/main.php' );
39
  }
40
 
41
- function parent_stylesheet_check( $parent ) {
42
- $file = trailingslashit( get_theme_root() ) . trailingslashit( $parent ) . 'header.php';
43
  $regex = '/<link[^>]+?stylesheet_ur[li]/is';
44
  if ( file_exists( $file ) ):
45
  $contents = file_get_contents( $file );
@@ -48,18 +46,17 @@ class ChildThemeConfiguratorUI {
48
  return FALSE;
49
  }
50
 
51
-
52
- function render_theme_menu( $template = 'child', $selected = NULL ) {
53
  ?>
54
- <select class="ctc-select" id="ctc_theme_<?php echo $template; ?>" name="ctc_theme_<?php echo $template; ?>" style="visibility:hidden"><?php
55
- foreach ( $this->ctc()->themes[$template] as $slug => $theme )
56
  echo '<option value="' . $slug . '"' . ( $slug == $selected ? ' selected' : '' ) . '>'
57
- . esc_attr( $theme['Name'] ) . '</option>' . LF; ?>
58
  </select>
59
  <div style="display:none">
60
  <?php
61
- foreach ( $this->ctc()->themes[$template] as $slug => $theme )
62
- include ( $this->ctc()->pluginPath . 'includes/forms/themepreview.php' ); ?>
63
  </div>
64
  <?php
65
  }
@@ -77,18 +74,18 @@ class ChildThemeConfiguratorUI {
77
  $excludes = implode( "|", ( array ) apply_filters( 'chld_thm_cfg_template_excludes', $this->ctc()->excludes ) );
78
  if ( 'parnt' == $template && ( preg_match( '%^(' . $excludes . ' )\w*\/%',$templatefile )
79
  || 'functions' == basename( $templatefile ) ) ) continue;
80
- include ( $this->ctc()->pluginPath . 'includes/forms/file.php' );
81
  endforeach;
82
- if ( 'child' == $template && ( $backups = $this->ctc()->get_files( $theme, 'backup' ) ) ):
83
  foreach ( $backups as $backup => $label ):
84
  $templatefile = preg_replace( '%\.css$%', '', $backup );
85
- include ( $this->ctc()->pluginPath . 'includes/forms/backup.php' );
86
  endforeach;
87
  endif;
88
  $inputs = ob_get_contents();
89
  ob_end_clean();
90
  if ( $counter ):
91
- include ( $this->ctc()->pluginPath . 'includes/forms/fileform.php' );
92
  endif;
93
  endif;
94
  }
@@ -104,11 +101,11 @@ class ChildThemeConfiguratorUI {
104
  ob_start();
105
  foreach ( $files as $file ):
106
  $templatefile = preg_replace( '/^images\//', '', $file );
107
- include( $this->ctc()->pluginPath . 'includes/forms/image.php' );
108
  endforeach;
109
  $inputs = ob_get_contents();
110
  ob_end_clean();
111
- if ( $counter ) include( $this->ctc()->pluginPath . 'includes/forms/images.php' );
112
  endif;
113
  }
114
 
@@ -133,15 +130,15 @@ class ChildThemeConfiguratorUI {
133
  echo '<li>' . $err . '</li>' . LF;
134
  endforeach;
135
  echo '</ul></div>' . LF;
136
- elseif ( isset( $_GET['updated'] ) ):
137
  echo '<div class="updated">' . LF;
138
- if ( 8 == $_GET['updated'] ):
139
  echo '<p>' . __( 'Child Theme files modified successfully.', 'chld_thm_cfg' ) . '</p>' . LF;
140
  else:
141
  $child_theme = wp_get_theme( $this->ctc()->css->get_prop( 'child' ) );
142
  echo '<p>' . apply_filters( 'chld_thm_cfg_update_msg', sprintf( __( 'Child Theme <strong>%s</strong> has been generated successfully.
143
  ', 'chld_thm_cfg' ), $child_theme->Name ), $this->ctc() ) . LF;
144
- if ( ! $this->ctc()->css->get_prop( 'configtype' ) || $this->ctc()->css->get_prop( 'configtype' ) == 'theme' ):
145
  echo '<strong>' . __( 'IMPORTANT:', 'chld_thm_cfg' ) . LF;
146
  if ( is_multisite() && !$child_theme->is_allowed() ):
147
  echo 'You must <a href="' . network_admin_url( '/themes.php' ) . '" title="' . __( 'Go to Themes', 'chld_thm_cfg' ) . '" class="ctc-live-preview">' . __( 'Network enable', 'chld_thm_cfg' ) . '</a> ' . __( 'your child theme.', 'chld_thm_cfg' );
@@ -168,7 +165,7 @@ class ChildThemeConfiguratorUI {
168
  $regex_tab = '/' . preg_quote( '<!-- BEGIN tab -->' ) . '\s*<h\d id="(.*?)">(.*?)<\/h\d>(.*?)' . preg_quote( '<!-- END tab -->' ) . '/s';
169
  ob_start();
170
  // stub for multiple languages future release
171
- include( $this->ctc()->pluginPath . 'includes/help/help_en_US.php' );
172
  $help_raw = ob_get_contents();
173
  ob_end_clean();
174
  // parse raw html for tokens
@@ -176,11 +173,11 @@ class ChildThemeConfiguratorUI {
176
  preg_match_all( $regex_tab, $help_raw, $tabs );
177
 
178
  // Add help tabs
179
- if ( isset( $tabs[1] ) ):
180
- while( count( $tabs[1] ) ):
181
- $id = array_shift( $tabs[1] );
182
- $title = array_shift( $tabs[2] );
183
- $content = array_shift( $tabs[3] );
184
  $screen->add_help_tab( array(
185
  'id' => $id,
186
  'title' => $title,
@@ -188,13 +185,15 @@ class ChildThemeConfiguratorUI {
188
  ) );
189
  endwhile;
190
  endif;
191
- if ( isset( $sidebar[1] ) )
192
- $screen->set_help_sidebar( $sidebar[1] );
193
 
194
  }
195
  }
 
196
  function lilaea_plug() {
197
- include ( $this->ctc()->pluginPath . 'includes/forms/related.php' );
198
  }
 
199
  }
200
  ?>
5
  Class: Child_Theme_Configurator_UI
6
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
7
  Description: Handles the plugin User Interface
8
+ Version: 1.6.4
9
  Author: Lilaea Media
10
  Author URI: http://www.lilaeamedia.com/
11
  Text Domain: chld_thm_cfg
15
  */
16
  class ChildThemeConfiguratorUI {
17
  // helper function to globalize ctc object
18
+
19
  function ctc() {
20
  global $chld_thm_cfg;
21
  return $chld_thm_cfg;
24
  function render() {
25
  $css = $this->ctc()->css;
26
  $themes = $this->ctc()->themes;
 
27
  $child = $css->get_prop( 'child' );
28
+ $hidechild = ( count( $themes[ 'child' ] ) ? '' : 'style="display:none"' );
29
+ $enqueueset = isset( $css->enqueue );
30
+ $mustimport = $this->parent_stylesheet_check();
 
 
31
  $imports = $css->get_prop( 'imports' );
32
  $id = 0;
33
  $this->ctc()->fs_method = get_filesystem_method();
34
  add_thickbox();
35
  add_action( 'chld_thm_cfg_related_links', array( $this, 'lilaea_plug' ) );
36
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/main.php' );
37
  }
38
 
39
+ function parent_stylesheet_check() {
40
+ $file = trailingslashit( get_theme_root() ) . trailingslashit( $this->ctc()->get_current_parent() ) . 'header.php';
41
  $regex = '/<link[^>]+?stylesheet_ur[li]/is';
42
  if ( file_exists( $file ) ):
43
  $contents = file_get_contents( $file );
46
  return FALSE;
47
  }
48
 
49
+ function render_theme_menu( $template = 'child', $selected = NULL ) {
 
50
  ?>
51
+ <select class="ctc-select" id="ctc_theme_<?php echo $template; ?>" name="ctc_theme_<?php echo $template; ?>" style="visibility:hidden" <?php echo $this->ctc()->is_theme() ? '' : ' disabled '; ?> ><?php
52
+ foreach ( $this->ctc()->themes[ $template ] as $slug => $theme )
53
  echo '<option value="' . $slug . '"' . ( $slug == $selected ? ' selected' : '' ) . '>'
54
+ . esc_attr( $theme[ 'Name' ] ) . '</option>' . LF; ?>
55
  </select>
56
  <div style="display:none">
57
  <?php
58
+ foreach ( $this->ctc()->themes[ $template ] as $slug => $theme )
59
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/themepreview.php' ); ?>
60
  </div>
61
  <?php
62
  }
74
  $excludes = implode( "|", ( array ) apply_filters( 'chld_thm_cfg_template_excludes', $this->ctc()->excludes ) );
75
  if ( 'parnt' == $template && ( preg_match( '%^(' . $excludes . ' )\w*\/%',$templatefile )
76
  || 'functions' == basename( $templatefile ) ) ) continue;
77
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/file.php' );
78
  endforeach;
79
+ if ( 'child' == $template && ( $backups = $this->ctc()->get_files( $theme, 'backup,pluginbackup' ) ) ):
80
  foreach ( $backups as $backup => $label ):
81
  $templatefile = preg_replace( '%\.css$%', '', $backup );
82
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/backup.php' );
83
  endforeach;
84
  endif;
85
  $inputs = ob_get_contents();
86
  ob_end_clean();
87
  if ( $counter ):
88
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/fileform.php' );
89
  endif;
90
  endif;
91
  }
101
  ob_start();
102
  foreach ( $files as $file ):
103
  $templatefile = preg_replace( '/^images\//', '', $file );
104
+ include( CHLD_THM_CFG_DIR . '/includes/forms/image.php' );
105
  endforeach;
106
  $inputs = ob_get_contents();
107
  ob_end_clean();
108
+ if ( $counter ) include( CHLD_THM_CFG_DIR . '/includes/forms/images.php' );
109
  endif;
110
  }
111
 
130
  echo '<li>' . $err . '</li>' . LF;
131
  endforeach;
132
  echo '</ul></div>' . LF;
133
+ elseif ( isset( $_GET[ 'updated' ] ) ):
134
  echo '<div class="updated">' . LF;
135
+ if ( 8 == $_GET[ 'updated' ] ):
136
  echo '<p>' . __( 'Child Theme files modified successfully.', 'chld_thm_cfg' ) . '</p>' . LF;
137
  else:
138
  $child_theme = wp_get_theme( $this->ctc()->css->get_prop( 'child' ) );
139
  echo '<p>' . apply_filters( 'chld_thm_cfg_update_msg', sprintf( __( 'Child Theme <strong>%s</strong> has been generated successfully.
140
  ', 'chld_thm_cfg' ), $child_theme->Name ), $this->ctc() ) . LF;
141
+ if ( $this->ctc()->is_theme() ):
142
  echo '<strong>' . __( 'IMPORTANT:', 'chld_thm_cfg' ) . LF;
143
  if ( is_multisite() && !$child_theme->is_allowed() ):
144
  echo 'You must <a href="' . network_admin_url( '/themes.php' ) . '" title="' . __( 'Go to Themes', 'chld_thm_cfg' ) . '" class="ctc-live-preview">' . __( 'Network enable', 'chld_thm_cfg' ) . '</a> ' . __( 'your child theme.', 'chld_thm_cfg' );
165
  $regex_tab = '/' . preg_quote( '<!-- BEGIN tab -->' ) . '\s*<h\d id="(.*?)">(.*?)<\/h\d>(.*?)' . preg_quote( '<!-- END tab -->' ) . '/s';
166
  ob_start();
167
  // stub for multiple languages future release
168
+ include( CHLD_THM_CFG_DIR . '/includes/help/help_en_US.php' );
169
  $help_raw = ob_get_contents();
170
  ob_end_clean();
171
  // parse raw html for tokens
173
  preg_match_all( $regex_tab, $help_raw, $tabs );
174
 
175
  // Add help tabs
176
+ if ( isset( $tabs[ 1 ] ) ):
177
+ while( count( $tabs[ 1 ] ) ):
178
+ $id = array_shift( $tabs[ 1 ] );
179
+ $title = array_shift( $tabs[ 2 ] );
180
+ $content = array_shift( $tabs[ 3 ] );
181
  $screen->add_help_tab( array(
182
  'id' => $id,
183
  'title' => $title,
185
  ) );
186
  endwhile;
187
  endif;
188
+ if ( isset( $sidebar[ 1 ] ) )
189
+ $screen->set_help_sidebar( $sidebar[ 1 ] );
190
 
191
  }
192
  }
193
+
194
  function lilaea_plug() {
195
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/related.php' );
196
  }
197
+
198
  }
199
  ?>
includes/class-ctc.php CHANGED
@@ -6,7 +6,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
6
  Class: Child_Theme_Configurator
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Main Controller Class
9
- Version: 1.6.3
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
@@ -16,39 +16,47 @@ if ( !defined( 'ABSPATH' ) ) exit;
16
  */
17
  class ChildThemeConfiguratorAdmin {
18
 
19
- var $css;
20
- var $pluginPath;
21
- var $pluginURL;
22
- var $menuName;
23
- var $ns;
24
- var $ui;
25
- var $themes;
26
- var $errors;
27
- var $hook;
28
  var $is_ajax;
29
- var $updated;
30
- var $uploadsubdir;
31
- var $files;
32
  var $fs;
 
33
  var $fs_prompt;
34
  var $fs_method;
35
- var $postarrays = array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  'ctc_img',
37
  'ctc_file_parnt',
38
  'ctc_file_child',
 
39
  );
40
- var $configfields = array(
41
  'theme_parnt',
42
  'child_type',
43
  'theme_child',
44
  'child_name',
45
- 'configtype',
46
  'child_template',
47
  'child_author',
48
  'child_version',
49
- 'revert'
 
50
  );
51
- var $actionfields = array(
52
  'load_styles',
53
  'parnt_templates_submit',
54
  'child_templates_submit',
@@ -58,14 +66,15 @@ class ChildThemeConfiguratorAdmin {
58
  'export_child_zip',
59
  'reset_permission',
60
  'templates_writable_submit',
61
- 'set_writable'
 
62
  );
63
- var $imgmimes = array(
64
  'jpg|jpeg|jpe' => 'image/jpeg',
65
  'gif' => 'image/gif',
66
  'png' => 'image/png',
67
  );
68
- var $excludes = array(
69
  'inc',
70
  'core',
71
  'lang',
@@ -73,79 +82,82 @@ class ChildThemeConfiguratorAdmin {
73
  'js',
74
  'lib',
75
  'theme',
76
- 'options'
77
  );
78
- var $updates = array();
79
- var $cache_updates = TRUE;
80
- var $swatch_text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
81
 
82
- function __construct( $file ) {
83
- $this->pluginPath = trailingslashit( dirname( $file ) );
84
- $this->pluginURL = plugin_dir_url( $file );
85
- $this->menuName = CHLD_THM_CFG_MENU; // backward compatability for plugins extension
 
 
86
  }
87
  function render() {
88
  $this->ui->render();
89
  }
90
  function enqueue_scripts() {
91
- wp_enqueue_style( 'chld-thm-cfg-admin', $this->pluginURL . 'css/chld-thm-cfg.css', array(), '1.6.3' );
92
 
93
  // we need to use local jQuery UI Widget/Menu/Selectmenu 1.11.2 because selectmenu is not included in < 1.11.2
94
  // this will be updated in a later release to use WP Core scripts when it is widely adopted
95
  if ( !wp_script_is( 'jquery-ui-selectmenu', 'registered' ) ): // selectmenu.min.js
96
- wp_enqueue_script( 'jquery-ui-selectmenu', $this->pluginURL . 'js/selectmenu.min.js', array( 'jquery','jquery-ui-core','jquery-ui-position' ), FALSE, TRUE );
 
97
  endif;
98
- wp_enqueue_script( 'ctc-thm-cfg-ctcgrad', $this->pluginURL . 'js/ctcgrad.min.js', array( 'jquery' ), FALSE, TRUE );
99
- wp_enqueue_script( 'chld-thm-cfg-admin', $this->pluginURL . 'js/chld-thm-cfg.min.js',
100
  array(
101
  'jquery-ui-autocomplete',
102
  'jquery-ui-selectmenu',
103
  'wp-color-picker',
104
  ), FALSE, TRUE );
105
  $localize_array = apply_filters( 'chld_thm_cfg_localize_script', array(
106
- 'ssl' => is_ssl(),
107
- 'homeurl' => get_home_url(),
108
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
109
- 'theme_uri' => get_theme_root_uri(),
110
- 'page' => CHLD_THM_CFG_MENU,
111
- 'themes' => $this->themes,
112
- 'source' => apply_filters( 'chld_thm_cfg_source_uri', get_theme_root_uri() . '/'
113
- . $this->css->get_prop( 'parnt' ) . '/style.css', $this->css ),
114
- 'target' => apply_filters( 'chld_thm_cfg_target_uri', get_theme_root_uri() . '/'
115
- . $this->css->get_prop( 'child' ) . '/style.css', $this->css ),
116
- 'parnt' => $this->css->get_prop( 'parnt' ),
117
- 'child' => $this->css->get_prop( 'child' ),
118
- 'addl_css' => $this->css->get_prop( 'parntss' ),
119
- 'imports' => $this->css->get_prop( 'imports' ),
120
- 'rule' => $this->css->get_prop( 'rule' ),
121
- 'sel_ndx' => $this->css->get_prop( 'sel_ndx' ),
122
- 'val_qry' => array(),
123
- 'rule_val' => array(),
124
- 'sel_val' => array(),
125
- 'field_labels' => array(
126
- '_background_url' => __( 'URL/None', 'chld_thm_cfg' ),
127
- '_background_origin' => __( 'Origin', 'chld_thm_cfg' ),
128
- '_background_color1' => __( 'Color 1', 'chld_thm_cfg' ),
129
- '_background_color2' => __( 'Color 2', 'chld_thm_cfg' ),
130
- '_border_width' => __( 'Width/None', 'chld_thm_cfg' ),
131
- '_border_style' => __( 'Style', 'chld_thm_cfg' ),
132
- '_border_color' => __( 'Color', 'chld_thm_cfg' ),
133
- ),
134
- 'load_txt' => __( 'Are you sure? This will replace your current settings.', 'chld_thm_cfg' ),
135
- 'swatch_txt' => $this->swatch_text,
136
- 'swatch_label' => __( 'Sample', 'chld_thm_cfg' ),
137
- 'important_label' => __( '<span style="font-size:10px">!</span>', 'chld_thm_cfg' ),
138
- 'selector_txt' => __( 'Selectors', 'chld_thm_cfg' ),
139
- 'close_txt' => __( 'Close', 'chld_thm_cfg' ),
140
- 'edit_txt' => __( 'Edit', 'chld_thm_cfg' ),
141
- 'cancel_txt' => __( 'Cancel', 'chld_thm_cfg' ),
142
- 'rename_txt' => __( 'Rename', 'chld_thm_cfg' ),
143
- 'css_fail_txt' => __( 'The stylesheet cannot be displayed.', 'chld_thm_cfg' ),
144
- 'child_only_txt' => __( '(Child Only)', 'chld_thm_cfg' ),
145
- 'inval_theme_txt' => __( 'Please enter a valid Child Theme', 'chld_thm_cfg' ),
146
- 'inval_name_txt' => __( 'Please enter a valid Child Theme name', 'chld_thm_cfg' ),
147
- 'theme_exists_txt' => __( '<strong>%s</strong> exists. Please enter a different Child Theme', 'chld_thm_cfg' ),
148
- ) );
 
 
 
149
  wp_localize_script(
150
  'chld-thm-cfg-admin',
151
  'ctcAjax',
@@ -153,36 +165,28 @@ class ChildThemeConfiguratorAdmin {
153
  );
154
  }
155
 
156
- function load_imports() {
157
- // allows fonts and other externals to be previewed
158
- // loads early not to conflict with admin stylesheets
159
- $regex = "/\@import *(url)? *\( *['\"]?((https?:\/\/)?(.+?))['\"]? *\).*$/";
160
- if ( $imports = $this->css->get_prop( 'imports' ) ):
161
- $count = 1;
162
- foreach ( $imports as $import ):
163
- preg_match( $regex, $import, $matches );
164
- if ( empty( $matches[3] ) && !empty( $matches[4] ) ): // relative filepath
165
- $url = get_stylesheet_directory_uri();
166
- preg_replace( "#\.\./#", '', $matches[4], -1, $count );
167
- for( $i = 0; $i < $count; $i++ ):
168
- $url = dirname( $url );
169
- endfor;
170
- $import = preg_replace( $regex, '@import url(' . trailingslashit( $url ) . $matches[4] . ')', $import );
171
- endif;
172
- wp_enqueue_style( 'chld-thm-cfg-admin' . ++$count, preg_replace( $regex, "$2", $import ) );
173
- endforeach;
174
- endif;
175
- }
176
-
177
  function ctc_page_init () {
 
178
  $this->get_themes();
 
179
  $this->load_config();
 
 
 
180
  do_action( 'chld_thm_cfg_forms', $this ); // hook for custom forms
181
- $this->write_config();
182
- include_once( $this->pluginPath . 'includes/class-ctc-ui.php' );
 
 
183
  $this->ui = new ChildThemeConfiguratorUI();
 
184
  $this->ui->render_help_content();
185
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ),999 );
 
 
186
  $this->load_imports();
187
  }
188
 
@@ -195,7 +199,7 @@ class ChildThemeConfiguratorAdmin {
195
  // get the theme slug
196
  $slug = $theme->get_stylesheet();
197
  // add theme to themes array
198
- $this->themes[$group][$slug] = array(
199
  'Name' => $theme->get( 'Name' ),
200
  'Author' => $theme->get( 'Author' ),
201
  'Version' => $theme->get( 'Version' ),
@@ -205,75 +209,39 @@ class ChildThemeConfiguratorAdmin {
205
  endforeach;
206
  }
207
 
208
- function validate_post( $action = 'ctc_update', $noncefield = '_wpnonce' ) {
209
  // security: request must be post, user must have permission, referrer must be local and nonce must match
210
- return ( 'POST' == $_SERVER['REQUEST_METHOD']
211
- && current_user_can( 'install_themes' ) // ( 'edit_theme_options' )
212
- && ( $this->is_ajax ? check_ajax_referer( $action, $noncefield, FALSE ) : check_admin_referer( $action, $noncefield, FALSE ) ) );
213
- }
214
-
215
- function ajax_save_postdata() {
216
- $this->is_ajax = TRUE;
217
- if ( $this->validate_post() ):
218
- $this->verify_creds();
219
- $this->load_config();
220
- $this->css->parse_post_data();
221
- $this->css->write_css();
222
- $result = $this->css->obj_to_utf8( $this->updates );
223
- $this->css->save_config();
224
- // send all updates back to browser to update cache
225
- die( json_encode( $result ) );
226
- else:
227
- die( 0 );
228
- endif;
229
- }
230
-
231
- function ajax_query_css() {
232
- $this->is_ajax = TRUE;
233
- if ( $this->validate_post() ):
234
- $this->load_config();
235
- $regex = "/^ctc_query_/";
236
- foreach( preg_grep( $regex, array_keys( $_POST ) ) as $key ):
237
- $name = preg_replace( $regex, '', $key );
238
- $param[$name] = sanitize_text_field( $_POST[$key] );
239
- endforeach;
240
- if ( !empty( $param['obj'] ) ):
241
- $result = array(
242
- array(
243
- 'key' => isset( $param['key'] ) ? $param['key'] : '',
244
- 'obj' => $param['obj'],
245
- 'data' => $this->css->get_prop( $param['obj'], $param ),
246
- ),
247
- );
248
- die( json_encode( $result ) );
249
- endif;
250
- endif;
251
- die( 0 );
252
  }
253
 
254
  function load_config() {
255
- include_once( $this->pluginPath . 'includes/class-ctc-css.php' );
256
  $this->css = new ChildThemeConfiguratorCSS();
257
  // if not new format or themes do not exist reinitialize
258
- if ( FALSE === $this->css->read_config()
259
  || ! $this->check_theme_exists( $this->css->get_prop( 'child' ) )
260
  || ! $this->check_theme_exists( $this->css->get_prop( 'parnt' ) ) ):
261
  $this->css = new ChildThemeConfiguratorCSS();
262
- $parent = get_template();
263
- $this->css->set_prop( 'parnt', $parent );
264
  endif;
265
- if ( 'GET' == strtoupper( $_SERVER['REQUEST_METHOD'] ) ):
266
  if ( $this->css->get_prop( 'child' ) ):
267
  // get filesystem credentials if available
268
  $this->verify_creds();
269
- $stylesheet = $this->css->get_child_target( 'style.css' );
270
  // check file permissions
271
  if ( !is_writable( $stylesheet ) && !$this->fs ):
272
- add_action( 'admin_notices', array( $this, 'writable_notice' ) );
273
  endif;
274
- // check for first run, enqueue flag will be null for anyone coming from < 1.6.0
275
- if ( !isset( $this->css->enqueue ) )
276
  add_action( 'admin_notices', array( $this, 'enqueue_notice' ) );
 
 
 
 
277
  endif;
278
  // check if file ownership is messed up from old version or other plugin
279
 
@@ -283,18 +251,85 @@ class ChildThemeConfiguratorAdmin {
283
  endif;
284
  }
285
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
  /***
287
  * Handles processing for all form submissions.
288
- * Older versions ( < 1.6.0 ) had grown too spaghetti-like so we moved conditions
289
  * to switch statement with the main setup logic in a separate function.
290
  */
291
- function write_config() {
292
  // make sure this is a post
293
- if ( 'POST' == strtoupper( $_SERVER['REQUEST_METHOD'] ) ):
294
  // see if a valid action was passed
295
- foreach ( $this->actionfields as $action ):
296
- if ( in_array( 'ctc_' . $action, array_keys( $_POST ) ) ):
297
- $actionfield = $action;
298
  break;
299
  endif;
300
  endforeach;
@@ -302,7 +337,7 @@ class ChildThemeConfiguratorAdmin {
302
 
303
  // make sure post passes security checkpoint
304
  $this->errors = array();
305
- if ( $this->validate_post() ):
306
  // zip export does not require filesystem access so check that first
307
  if ( 'export_child_zip' == $actionfield ):
308
  $this->export_zip();
@@ -311,9 +346,9 @@ class ChildThemeConfiguratorAdmin {
311
  // all other actions require filesystem access
312
  else:
313
  // handle uploaded file before checking filesystem
314
- if ( 'theme_image_submit' == $actionfield && isset( $_FILES['ctc_theme_image'] ) ):
315
  $this->handle_file_upload( 'ctc_theme_image', $this->imgmimes );
316
- elseif ( 'theme_screenshot_submit' == $actionfield && isset( $_FILES['ctc_theme_screenshot'] ) ):
317
  $this->handle_file_upload( 'ctc_theme_screenshot', $this->imgmimes );
318
  endif;
319
  // now we need to check filesystem access
@@ -330,8 +365,8 @@ class ChildThemeConfiguratorAdmin {
330
 
331
  case 'parnt_templates_submit':
332
  // copy parent templates to child
333
- if ( isset( $_POST['ctc_file_parnt'] ) ):
334
- foreach ( $_POST['ctc_file_parnt'] as $file ):
335
  $this->copy_parent_file( sanitize_text_field( $file ) );
336
  endforeach;
337
  $msg = '8&tab=file_options';
@@ -340,13 +375,15 @@ class ChildThemeConfiguratorAdmin {
340
 
341
  case 'child_templates_submit':
342
  // delete child theme files
343
- if ( isset( $_POST['ctc_file_child'] ) ):
344
- if ( in_array( 'functions', $_POST['ctc_file_child'] ) ):
345
- $this->errors[] = __( 'The Functions file is required and cannot be deleted.', 'chld_thm_cfg' );
 
 
346
  else:
347
- foreach ( $_POST['ctc_file_child'] as $file ):
348
  $this->delete_child_file( sanitize_text_field( $file ),
349
- ( 0 === strpos( $file, 'style' ) ? 'css' : 'php' ) );
350
  endforeach;
351
  $msg = '8&tab=file_options';
352
  endif;
@@ -355,8 +392,8 @@ class ChildThemeConfiguratorAdmin {
355
 
356
  case 'image_submit':
357
  // delete child theme images
358
- if ( isset( $_POST['ctc_img'] ) ):
359
- foreach ( $_POST['ctc_img'] as $file ):
360
  $this->delete_child_file( 'images/' . sanitize_text_field( $file ), 'img' );
361
  endforeach;
362
  $msg = '8&tab=file_options';
@@ -365,9 +402,10 @@ class ChildThemeConfiguratorAdmin {
365
 
366
  case 'templates_writable_submit':
367
  // make specific files writable ( systems not running suExec )
368
- if ( isset( $_POST['ctc_file_child'] ) ):
369
- foreach ( $_POST['ctc_file_child'] as $file ):
370
- $this->set_writable( sanitize_text_field( $file ), ( 0 === strpos( $file, 'style' ) ? 'css' : 'php' ) );
 
371
  endforeach;
372
  $msg = '8&tab=file_options';
373
  endif;
@@ -387,7 +425,7 @@ class ChildThemeConfiguratorAdmin {
387
 
388
  case 'theme_image_submit':
389
  // move uploaded child theme images (now we have filesystem access)
390
- if ( isset( $_POST['movefile'] ) ):
391
  $this->move_file_upload( 'images' );
392
  $msg = '8&tab=file_options';
393
  endif;
@@ -395,7 +433,7 @@ class ChildThemeConfiguratorAdmin {
395
 
396
  case 'theme_screenshot_submit':
397
  // move uploaded child theme screenshot (now we have filesystem access)
398
- if ( isset( $_POST['movefile'] ) ):
399
  // remove old screenshot
400
  foreach( array_keys( $this->imgmimes ) as $extreg ):
401
  foreach ( explode( '|', $extreg ) as $ext ):
@@ -406,7 +444,6 @@ class ChildThemeConfiguratorAdmin {
406
  $msg = '8&tab=file_options';
407
  endif;
408
  break;
409
-
410
  default:
411
  // assume we are on the files tab so just redirect there
412
  $msg = '8&tab=file_options';
@@ -427,109 +464,121 @@ class ChildThemeConfiguratorAdmin {
427
  return FALSE;
428
  }
429
 
430
- function check_theme_exists( $theme ) {
431
- return in_array( $theme, array_keys( wp_get_themes() ) );
432
- }
433
-
434
  /***
435
  * Handle the creation or update of a child theme
436
  */
437
  function setup_child_theme() {
438
-
439
  // sanitize and extract config fields into local vars
440
  foreach ( $this->configfields as $configfield ):
 
441
  $varparts = explode( '_', $configfield );
442
  $varname = end( $varparts );
443
- ${$varname} = empty( $_POST['ctc_' . $configfield] ) ? '' : sanitize_text_field( $_POST['ctc_' . $configfield] );
 
 
444
  endforeach;
445
 
446
- // check that all requirements are met
 
 
 
 
 
 
 
 
447
  if ( $parnt ):
448
  if ( ! $this->check_theme_exists( $parnt ) ):
449
- $this->errors[] = sprintf( __( '%s does not exist. Please select a valid Parent Theme', 'chld_thm_cfg' ), $parnt );
 
 
450
  endif;
451
  else:
452
- $this->errors[] = __( 'Please select a valid Parent Theme', 'chld_thm_cfg' );
453
  endif;
454
- // if this is a shiny brand new child theme certain rules apply
455
- if ( 'new' == $type ):
456
- if ( empty( $template ) && empty( $name ) ):
457
- $this->errors[] = __( 'Please enter a valid Child Theme template name', 'chld_thm_cfg' );
458
- else:
459
- $configtype = 'theme'; // no custom stylesheets until style.css exists!
460
- $child = strtolower( preg_replace( "%[^\w\-]%", '', empty( $template ) ? $name : $template ) );
461
- if ( $this->check_theme_exists( $child ) ):
462
- $this->errors[] = sprintf( __( '<strong>%s</strong> exists. Please enter a different Child Theme template name', 'chld_thm_cfg' ), $child );
463
- else:
464
- add_action( 'chld_thm_cfg_addl_files', array( &$this, 'add_base_files' ), 10, 2 );
465
- add_action( 'chld_thm_cfg_addl_files', array( &$this, 'copy_screenshot' ), 10, 2 );
466
- add_action( 'chld_thm_cfg_addl_files', array( &$this, 'enqueue_parent_css' ), 15, 2 );
467
- endif;
468
- endif;
469
- // check if we have additional files from a plugin extension. if so, we have to override
470
- // function to support wp_filesystem requirements
471
- elseif ( empty( $configtype ) || 'theme' == $configtype ):
472
- // no configtype means this is either from this plugin or a plugin after 1.5.0
473
- add_action( 'chld_thm_cfg_addl_files', array( &$this, 'add_base_files' ), 10, 2 );
474
- add_action( 'chld_thm_cfg_addl_files', array( &$this, 'copy_screenshot' ), 10, 2 );
475
- add_action( 'chld_thm_cfg_addl_files', array( &$this, 'enqueue_parent_css' ), 15, 2 );
476
- elseif( has_action( 'chld_thm_cfg_addl_files' ) ):
477
- // action exists so we have to hijack it to use new filesystem checks
478
- remove_all_actions( 'chld_thm_cfg_addl_files' );
479
- // back compat for plugins extension
480
- add_action( 'chld_thm_cfg_addl_files', array( &$this, 'write_addl_files' ), 10, 2 );
481
  endif;
482
-
483
  if ( empty( $name ) ):
484
  $name = ucfirst( $child );
485
  endif;
486
-
487
- if ( empty( $child ) ):
488
- $this->errors[] = __( 'Please enter a valid Child Theme directory', 'chld_thm_cfg' );
489
- endif;
490
-
491
  if ( FALSE === $this->verify_child_dir( $child ) ):
492
  $this->errors[] = __( 'Your theme directories are not writable.', 'chld_thm_cfg' );
493
  add_action( 'admin_notices', array( $this, 'writable_notice' ) );
494
  endif;
495
 
 
 
 
 
 
 
 
 
 
 
 
 
 
496
  // if no errors so far, we are good to create child theme
497
  if ( empty( $this->errors ) ):
498
  $this->css = new ChildThemeConfiguratorCSS();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
499
  $this->css->set_prop( 'parnt', $parnt );
500
  $this->css->set_prop( 'child', $child );
501
  $this->css->set_prop( 'child_name', $name );
502
  $this->css->set_prop( 'child_author', $author );
503
  $this->css->set_prop( 'child_version', strlen( $version ) ? $version : '1.0' );
504
- $this->css->set_prop( 'configtype', $configtype );
 
 
 
 
505
 
506
  // hook for add'l plugin files and subdirectories
507
  do_action( 'chld_thm_cfg_addl_files', $this );
508
 
509
- // always parse parent stylesheet
510
- $this->css->parse_css_file( 'parnt' );
 
511
 
512
  // parse child stylesheet, backup or skip ( to reset )
513
  $this->css->parse_css_file( 'child', $revert );
514
 
515
  // parse additional stylesheets
516
- if ( isset( $_POST['ctc_additional_css'] ) && is_array( $_POST['ctc_additional_css'] ) ):
517
- $this->css->parentss = array();
518
- foreach ( $_POST['ctc_additional_css'] as $file ):
519
  $this->css->parse_css_file( 'parnt', $file );
520
- $this->css->parntss[] = $file;
521
  endforeach;
522
  endif;
523
 
524
  // try to write new stylsheet. If it fails send alert.
525
- if ( FALSE === $this->css->write_css( isset( $_POST['ctc_backup'] ) ) ):
 
526
  $this->errors[] = __( 'Your stylesheet is not writable.', 'chld_thm_cfg' );
527
  add_action( 'admin_notices', array( $this, 'writable_notice' ) );
528
  return FALSE;
529
  endif;
530
 
531
  // copy parent theme mods option set
532
- if ( isset( $_POST['ctc_parent_mods'] ) ):
533
  // we can copy settings from parent to child even if neither is currently active
534
  // so we need cases for active parent, active child or neither
535
 
@@ -542,19 +591,19 @@ class ChildThemeConfiguratorAdmin {
542
  $child_widgets = retrieve_widgets();
543
  else:
544
  // otherwise get widgets from parent theme mods
545
- $child_widgets = $child_mods['sidebars_widgets']['data'];
546
  endif;
547
  if ( $active_theme == $child ):
548
  // if child theme is active, remove widgets from temp array
549
- unset( $child_mods['sidebars_widgets'] );
550
  // copy temp array to child mods
551
  update_option( 'theme_mods_' . $child, $child_mods );
552
  // copy widgets to active sidebars_widgets array
553
  wp_set_sidebars_widgets( $child_widgets );
554
  else:
555
  // otherwise copy widgets to temp array with time stamp
556
- $child_mods['sidebars_widgets']['data'] = $child_widgets;
557
- $child_mods['sidebars_widgets']['time'] = time();
558
  // copy temp array to child theme mods
559
  update_option( 'theme_mods_' . $child, $child_mods );
560
  endif;
@@ -567,10 +616,32 @@ class ChildThemeConfiguratorAdmin {
567
  do_action( 'chld_thm_cfg_addl_options', $this ); // hook for add'l plugin options
568
 
569
  // return message id 1, which says new child theme created successfull;
570
- return 1; //isset( $_POST['ctc_scan_subdirs'] ) ? '9&tab=import_options' : 1;
571
  endif;
572
  return FALSE;
573
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
574
  /*
575
  * TODO: this is a stub for future use
576
  */
@@ -580,11 +651,11 @@ class ChildThemeConfiguratorAdmin {
580
 
581
  function update_redirect( $msg = 1 ) {
582
  if ( empty( $this->is_ajax ) ):
583
-
584
  wp_safe_redirect(
585
  ( is_multisite() ?
586
- network_admin_url( 'themes.php?page=' . CHLD_THM_CFG_MENU . '&updated=' . $msg ) :
587
- admin_url( 'tools.php?page=' . CHLD_THM_CFG_MENU . '&updated=' . $msg ) )
588
  );
589
  die();
590
  endif;
@@ -622,19 +693,18 @@ if ( !defined( 'ABSPATH' ) ) exit;
622
  }
623
 
624
  function enqueue_parent_code(){
625
- return explode( "\n", apply_filters( 'chld_thm_cfg_enqueue_parent', "
 
626
  if ( !function_exists( 'chld_thm_cfg_parent_css' ) ):
627
  function chld_thm_cfg_parent_css() {
628
- wp_enqueue_style( 'chld_thm_cfg_parent', get_template_directory_uri() . '/style.css' );
629
  }
630
  endif;
631
  add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
632
- " ) );
633
  }
634
 
635
  function enqueue_parent_css( $obj ) {
636
- if ( isset( $_POST['ctc_parent_enqueue'] ) )
637
- $this->css->enqueue = sanitize_text_field( $_POST['ctc_parent_enqueue'] );
638
  $marker = 'ENQUEUE PARENT ACTION';
639
  $insertion = 'enqueue' == $this->css->enqueue ? $this->enqueue_parent_code() : array();
640
  if ( $filename = $this->css->is_file_ok( $this->css->get_child_target( 'functions.php' ), 'write' ) ):
@@ -648,6 +718,8 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
648
  */
649
  function insert_with_markers( $filename, $marker, $insertion ) {
650
  if ( !$this->fs ) return FALSE; // return if no filesystem access
 
 
651
  global $wp_filesystem;
652
  if( !$wp_filesystem->exists( $this->fspath( $filename ) ) ):
653
  $markerdata = FALSE;
@@ -689,12 +761,23 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
689
  }
690
 
691
  function write_child_file( $file, $contents ) {
692
- if ( !$this->fs ) return FALSE; // return if no filesystem access
 
 
 
693
  global $wp_filesystem;
694
  $file = $this->fspath( $this->css->is_file_ok( $this->css->get_child_target( $file ), 'write' ) );
 
695
  if ( $file && !$wp_filesystem->exists( $file ) ):
696
- if ( FALSE === $wp_filesystem->put_contents( $file, $contents ) ) return FALSE;
 
 
 
 
 
 
697
  endif;
 
698
  }
699
 
700
  function copy_screenshot( $obj ) {
@@ -726,8 +809,8 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
726
  $child_dir = dirname( $this->theme_basename( '', $child_file ) );
727
  if ( $parent_file // sanity check
728
  && $child_file // sanity check
729
- && $this->verify_child_dir( $child_dir ) //create child subdir if necessary
730
- && $wp_filesystem->copy( $parent_file, $this->fspath( $child_file ), FS_CHMOD_FILE ) ) return TRUE;
731
  $this->errors[] = __( 'Could not copy file.', 'chld_thm_cfg' );
732
  }
733
 
@@ -743,25 +826,33 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
743
  }
744
 
745
  function get_files( $theme, $type = 'template' ) {
746
- if ( !isset( $this->files[$theme] ) ):
747
- $this->files[$theme] = array();
748
  $imgext = '(' . implode( '|', array_keys( $this->imgmimes ) ) . ')';
749
  foreach ( $this->css->recurse_directory(
750
  trailingslashit( get_theme_root() ) . $theme, '', TRUE ) as $file ):
751
  $file = $this->theme_basename( $theme, $file );
752
  if ( preg_match( "/^style\-(\d+)\.css$/", $file, $matches ) ):
753
- $date = date_i18n( 'D, j M Y g:i A', strtotime( $matches[1] ) );
754
- $this->files[$theme]['backup'][$file] = $date;
 
 
 
755
  elseif ( preg_match( "/\.php$/", $file ) ):
756
- $this->files[$theme]['template'][] = $file;
757
  elseif ( preg_match( "/\.css$/", $file ) && 'style.css' != $file ):
758
- $this->files[$theme]['stylesheet'][] = $file;
759
  elseif ( preg_match( "/^images\/.+?\." . $imgext . "$/", $file ) ):
760
- $this->files[$theme]['img'][] = $file;
761
  endif;
762
  endforeach;
763
  endif;
764
- return isset( $this->files[$theme][$type] ) ? $this->files[$theme][$type] : array();
 
 
 
 
 
765
  }
766
 
767
  function theme_basename( $theme, $file ) {
@@ -773,32 +864,33 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
773
  function uploads_basename( $file ) {
774
  $file = $this->normalize_path( $file );
775
  $uplarr = wp_upload_dir();
776
- $upldir = trailingslashit( $uplarr['basedir'] );
777
  return preg_replace( '%^' . preg_quote( $upldir ) . '%', '', $file );
778
  }
779
 
780
  function uploads_fullpath( $file ) {
781
  $file = $this->normalize_path( $file );
782
  $uplarr = wp_upload_dir();
783
- $upldir = trailingslashit( $uplarr['basedir'] );
784
  return $upldir . $file;
785
  }
786
 
787
  function serialize_postarrays() {
788
  foreach ( $this->postarrays as $field )
789
- if ( isset( $_POST[$field] ) && is_array( $_POST[$field] ) )
790
- $_POST[$field] = implode( "%%", $_POST[$field] );
791
  }
792
 
793
  function unserialize_postarrays() {
794
  foreach ( $this->postarrays as $field )
795
- if ( isset( $_POST[$field] ) && !is_array( $_POST[$field] ) )
796
- $_POST[$field] = explode( "%%", $_POST[$field] );
797
  }
798
 
799
  function set_writable( $file = NULL ) {
800
 
801
- $file = isset( $file ) ? $this->css->get_child_target( $file . '.php' ) : apply_filters( 'chld_thm_cfg_target', $this->css->get_child_target(), $this->css );
 
802
  if ( $this->fs ): // filesystem access
803
  global $wp_filesystem;
804
  if ( $file && $wp_filesystem->chmod( $this->fspath( $file ), 0666 ) ) return;
@@ -817,7 +909,7 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
817
  $themedir = trailingslashit( get_theme_root() );
818
  $fsthemedir = $this->fspath( $themedir );
819
  // is child theme owned by user?
820
- if ( fileowner( $dir ) == fileowner( ABSPATH ) ):
821
  $copy = FALSE;
822
  $wp_filesystem->chmod( $dir );
823
  // recursive chmod ( as user )
@@ -862,7 +954,9 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
862
  $oldfiles = $this->css->recurse_directory( trailingslashit( $themedir ) . $child . '-old', NULL, TRUE );
863
  array_unshift( $oldfiles, trailingslashit( $themedir ) . $child . '-old' );
864
  foreach ( array_reverse( $oldfiles ) as $file ):
865
- if ( $wp_filesystem->delete( $this->fspath( $file ) ) || ( is_dir( $file ) && @rmdir( $file ) ) || ( is_file( $file ) && @unlink( $file ) ) ):
 
 
866
  $deletedfiles++;
867
  endif;
868
  endforeach;
@@ -878,26 +972,28 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
878
  add_action( 'admin_notices', array( $this, 'writable_notice' ) );
879
  endif;
880
  }
881
-
 
 
882
  function handle_file_upload( $field, $childdir = NULL, $mimes = NULL ){
883
- $uploadedfile = $_FILES[$field];
884
  $upload_overrides = array(
885
  'test_form' => FALSE,
886
  'mimes' => ( is_array( $mimes ) ? $mimes : NULL )
887
  );
888
  if ( ! function_exists( 'wp_handle_upload' ) ) require_once( ABSPATH . 'wp-admin/includes/file.php' );
889
  $movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
890
- if ( isset( $movefile['error'] ) ):
891
- $this->errors[] = $movefile['error'];
892
  return FALSE;
893
  endif;
894
- $_POST['movefile'] = $this->uploads_basename( $movefile['file'] );
895
  }
896
 
897
  function move_file_upload( $subdir = 'images' ) {
898
  if ( !$this->fs ) return FALSE; // return if no filesystem access
899
  global $wp_filesystem;
900
- $source_file = sanitize_text_field( $_POST['movefile'] );
901
  $target_file = ( '' == $subdir ?
902
  preg_replace( "%^.+(\.\w+)$%", "screenshot$1", basename( $source_file ) ) :
903
  trailingslashit( $subdir ) . basename( $source_file ) );
@@ -949,9 +1045,10 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
949
  //fs prompt does not support arrays as post data - serialize arrays
950
  $this->serialize_postarrays();
951
  // generate callback url
952
- $url = is_multisite() ? network_admin_url( 'themes.php?page=' . CHLD_THM_CFG_MENU ) :
953
- admin_url( 'tools.php?page=' . CHLD_THM_CFG_MENU );
954
- $nonce_url = wp_nonce_url( $url, 'ctc_update', '_wpnonce' );
 
955
  // buffer output so we can process prior to http header
956
  ob_start();
957
  if ( $creds = request_filesystem_credentials( $nonce_url, '', FALSE, FALSE, $args ) ):
@@ -994,25 +1091,29 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
994
  function writable_notice() {
995
  ?> <div class="update-nag">
996
  <p><?php _e( 'Child Theme Configurator is unable to write to the stylesheet. This can be resolved using one of the following options:<ol>', 'chld_thm_cfg' );
997
- if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && preg_match( '%unix%i',$_SERVER['SERVER_SOFTWARE'] ) ):
 
998
  _e( '<li>Temporarily make the stylesheet writable by clicking the button below. You should change this back when you are finished editing for security by clicking "Make read-only" under the "Files" tab.</li>', 'chld_thm_cfg' );
999
- ?><form action="?page=<?php echo CHLD_THM_CFG_MENU; ?>" method="post"><?php wp_nonce_field( 'ctc_update' ); ?>
 
1000
  <input name="ctc_set_writable" class="button" type="submit" value="<?php _e( 'Temporarily make stylesheet writable', 'chld_thm_cfg' ); ?>"/></form><?php endif;
1001
  _e( '<li><a target="_blank" href="http://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants" title="Editin wp-config.php">Add your FTP/SSH credentials to the WordPress config file</a>.</li>', 'chld_thm_cfg' );
1002
- if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && preg_match( '%iis%i',$_SERVER['SERVER_SOFTWARE'] ) )
1003
  _e( '<li><a target="_blank" href="http://technet.microsoft.com/en-us/library/cc771170" title="Setting Application Pool Identity">Assign WordPress to an application pool that has write permissions</a> (Windows IIS systems).</li>', 'chld_thm_cfg' );
1004
  _e( '<li><a target="_blank" href="http://codex.wordpress.org/Changing_File_Permissions" title="Changing File Permissions">Set the stylesheet write permissions on the server manually</a> (not recommended).</li>', 'chld_thm_cfg' );
1005
- if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && preg_match( '%unix%i',$_SERVER['SERVER_SOFTWARE'] ) )
1006
  _e( '<li>Run PHP under Apache with suEXEC (contact your web host).</li>', 'chld_thm_cfg' ) ?>
1007
  </ol></p>
1008
  </div>
1009
  <?php
1010
  }
1011
  function owner_notice() {
 
1012
  ?>
1013
  <div class="update-nag">
1014
  <p><?php _e( 'This Child Theme is not owned by your website account. It may have been created by a prior version of this plugin or by another program. Moving forward, it must be owned by your website account to make changes. Child Theme Configurator will attempt to correct this when you click the button below.', 'chld_thm_cfg' ) ?></p>
1015
- <form action="?page=<?php echo CHLD_THM_CFG_MENU; ?>" method="post"><?php wp_nonce_field( 'ctc_update' ); ?>
 
1016
  <input name="ctc_reset_permission" class="button" type="submit" value="<?php _e( 'Correct Child Theme Permissions', 'chld_thm_cfg' ); ?>"/></form> </div>
1017
  <?php
1018
  }
@@ -1020,44 +1121,110 @@ add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
1020
  function enqueue_notice() {
1021
  ?>
1022
  <div class="update-nag">
1023
- <p><?php _e( 'Child Theme Configurator has changed the way it handles the parent stylesheet. Please set your preferences below and click "Generate Child Theme Files" to update your configuration.', 'chld_thm_cfg' ) ?></p>
1024
  </div>
1025
  <?php
1026
  }
1027
 
1028
- // back compatibility function for plugins extension
1029
- function write_addl_files( $chld_thm_cfg ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1030
  global $chld_thm_cfg_plugins;
1031
- if ( !is_object( $chld_thm_cfg_plugins ) || !$chld_thm_cfg->fs ) return FALSE;
1032
- $configtype = $chld_thm_cfg->css->get_prop( 'configtype' );
 
1033
  if ( 'theme' == $configtype || !( $def = $chld_thm_cfg_plugins->defs->get_def( $configtype ) ) ) return FALSE;
1034
- $child = trailingslashit( $chld_thm_cfg->css->get_prop( 'child' ) );
1035
- if ( isset( $def['addl'] ) && is_array( $def['addl'] ) && count( $def['addl'] ) ):
1036
- foreach ( $def['addl'] as $path => $type ):
1037
 
1038
  // sanitize the crap out of the target data -- it will be used to create paths
1039
  $path = $this->normalize_path( preg_replace( "%[^\w\\//\-]%", '', sanitize_text_field( $child . $path ) ) );
1040
- if ( ( 'dir' == $type && FALSE === $chld_thm_cfg->verify_child_dir( $path ) )
1041
- || ( 'dir' != $type && FALSE === $chld_thm_cfg->write_child_file( $path, '' ) ) ):
1042
- $chld_thm_cfg->errors[] =
1043
- __( 'Your theme directories are not writable.', 'chld_thm_cfg_plugins' );
1044
  endif;
1045
  endforeach;
1046
  endif;
1047
  // write main def file
1048
- if ( isset( $def['target'] ) ):
1049
- $path = $this->normalize_path( preg_replace( "%[^\w\\//\-\.]%", '', sanitize_text_field( $def['target'] ) ) ); //$child .
1050
- if ( FALSE === $chld_thm_cfg->write_child_file( $path, '' ) ):
1051
- $chld_thm_cfg->errors[] =
1052
- __( 'Your stylesheet is not writable.', 'chld_thm_cfg_plugins' );
1053
  return FALSE;
1054
  endif;
1055
  endif;
1056
  }
1057
- // backwards compatability < 3.9
1058
  function normalize_path( $path ) {
1059
  $path = str_replace( '\\', '/', $path );
1060
  $path = preg_replace( '|/+|','/', $path );
1061
  return $path;
1062
  }
1063
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  Class: Child_Theme_Configurator
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Main Controller Class
9
+ Version: 1.6.4
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
16
  */
17
  class ChildThemeConfiguratorAdmin {
18
 
19
+ // state
 
 
 
 
 
 
 
 
20
  var $is_ajax;
21
+ var $is_get;
22
+ var $is_post;
23
+ var $skip_form;
24
  var $fs;
25
+
26
  var $fs_prompt;
27
  var $fs_method;
28
+ var $uploadsubdir;
29
+ var $menuName; // backward compatibility with plugin extension
30
+ var $cache_updates = TRUE;
31
+ var $debug = '';
32
+ var $swatch_text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
33
+ // state arrays
34
+ var $themes = array();
35
+ var $errors = array();
36
+ var $files = array();
37
+ var $updates = array();
38
+ // objects
39
+ var $css;
40
+ var $ui;
41
+ // config arrays
42
+ var $postarrays = array(
43
  'ctc_img',
44
  'ctc_file_parnt',
45
  'ctc_file_child',
46
+ 'ctc_additional_css',
47
  );
48
+ var $configfields = array(
49
  'theme_parnt',
50
  'child_type',
51
  'theme_child',
52
  'child_name',
 
53
  'child_template',
54
  'child_author',
55
  'child_version',
56
+ 'configtype', // backward compatability
57
+ 'revert',
58
  );
59
+ var $actionfields = array(
60
  'load_styles',
61
  'parnt_templates_submit',
62
  'child_templates_submit',
66
  'export_child_zip',
67
  'reset_permission',
68
  'templates_writable_submit',
69
+ 'set_writable',
70
+ 'upgrade',
71
  );
72
+ var $imgmimes = array(
73
  'jpg|jpeg|jpe' => 'image/jpeg',
74
  'gif' => 'image/gif',
75
  'png' => 'image/png',
76
  );
77
+ var $excludes = array(
78
  'inc',
79
  'core',
80
  'lang',
82
  'js',
83
  'lib',
84
  'theme',
85
+ 'options',
86
  );
 
 
 
87
 
88
+ function __construct() {
89
+ $this->menuName = CHLD_THM_CFG_MENU; // backward compatability for plugins extension
90
+ add_action( 'chld_thm_cfg_tabs', array( &$this, 'render_addl_tabs' ), 10, 4 );
91
+ add_action( 'chld_thm_cfg_panels', array( &$this, 'render_addl_panels' ), 10, 4 );
92
+ $this->is_post = ( 'POST' == $_SERVER[ 'REQUEST_METHOD' ] );
93
+ $this->is_get = ( 'GET' == $_SERVER[ 'REQUEST_METHOD' ] );
94
  }
95
  function render() {
96
  $this->ui->render();
97
  }
98
  function enqueue_scripts() {
99
+ wp_enqueue_style( 'chld-thm-cfg-admin', CHLD_THM_CFG_URL . 'css/chld-thm-cfg.css', array(), '1.6.4' );
100
 
101
  // we need to use local jQuery UI Widget/Menu/Selectmenu 1.11.2 because selectmenu is not included in < 1.11.2
102
  // this will be updated in a later release to use WP Core scripts when it is widely adopted
103
  if ( !wp_script_is( 'jquery-ui-selectmenu', 'registered' ) ): // selectmenu.min.js
104
+ wp_enqueue_script( 'jquery-ui-selectmenu', CHLD_THM_CFG_URL . 'js/selectmenu.min.js',
105
+ array( 'jquery','jquery-ui-core','jquery-ui-position' ), FALSE, TRUE );
106
  endif;
107
+ wp_enqueue_script( 'ctc-thm-cfg-ctcgrad', CHLD_THM_CFG_URL . 'js/ctcgrad.min.js', array( 'jquery' ), FALSE, TRUE );
108
+ wp_enqueue_script( 'chld-thm-cfg-admin', CHLD_THM_CFG_URL . 'js/chld-thm-cfg.min.js',
109
  array(
110
  'jquery-ui-autocomplete',
111
  'jquery-ui-selectmenu',
112
  'wp-color-picker',
113
  ), FALSE, TRUE );
114
  $localize_array = apply_filters( 'chld_thm_cfg_localize_script', array(
115
+ 'ssl' => is_ssl(),
116
+ 'homeurl' => get_home_url(),
117
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
118
+ 'theme_uri' => get_theme_root_uri(),
119
+ 'page' => CHLD_THM_CFG_MENU,
120
+ 'themes' => $this->themes,
121
+ 'source' => apply_filters( 'chld_thm_cfg_source_uri', get_theme_root_uri() . '/'
122
+ . $this->css->get_prop( 'parnt' ) . '/style.css', $this->css ),
123
+ 'target' => apply_filters( 'chld_thm_cfg_target_uri', get_theme_root_uri() . '/'
124
+ . $this->css->get_prop( 'child' ) . '/style.css', $this->css ),
125
+ 'parnt' => $this->css->get_prop( 'parnt' ),
126
+ 'child' => $this->css->get_prop( 'child' ),
127
+ 'addl_css' => $this->css->get_prop( 'addl_css' ),
128
+ 'imports' => $this->css->get_prop( 'imports' ),
129
+ // caches will be loaded dynamically
130
+ 'rule' => array(),
131
+ 'sel_ndx' => array(),
132
+ 'val_qry' => array(),
133
+ 'rule_val' => array(),
134
+ 'sel_val' => array(),
135
+ 'recent' => array(),
136
+ 'field_labels' => array(
137
+ '_background_url' => __( 'URL/None', 'chld_thm_cfg' ),
138
+ '_background_origin' => __( 'Origin', 'chld_thm_cfg' ),
139
+ '_background_color1' => __( 'Color 1', 'chld_thm_cfg' ),
140
+ '_background_color2' => __( 'Color 2', 'chld_thm_cfg' ),
141
+ '_border_width' => __( 'Width/None', 'chld_thm_cfg' ),
142
+ '_border_style' => __( 'Style', 'chld_thm_cfg' ),
143
+ '_border_color' => __( 'Color', 'chld_thm_cfg' ),
144
+ ),
145
+ 'swatch_txt' => $this->swatch_text,
146
+ 'load_txt' => __( 'Are you sure? This will replace your current settings.', 'chld_thm_cfg' ),
147
+ 'swatch_label' => __( 'Sample', 'chld_thm_cfg' ),
148
+ 'important_label' => __( '<span style="font-size:10px">!</span>', 'chld_thm_cfg' ),
149
+ 'selector_txt' => __( 'Selectors', 'chld_thm_cfg' ),
150
+ 'close_txt' => __( 'Close', 'chld_thm_cfg' ),
151
+ 'edit_txt' => __( 'Edit', 'chld_thm_cfg' ),
152
+ 'cancel_txt' => __( 'Cancel', 'chld_thm_cfg' ),
153
+ 'rename_txt' => __( 'Rename', 'chld_thm_cfg' ),
154
+ 'css_fail_txt' => __( 'The stylesheet cannot be displayed.', 'chld_thm_cfg' ),
155
+ 'child_only_txt' => __( '(Child Only)', 'chld_thm_cfg' ),
156
+ 'inval_theme_txt' => __( 'Please enter a valid Child Theme.', 'chld_thm_cfg' ),
157
+ 'inval_name_txt' => __( 'Please enter a valid Child Theme name.', 'chld_thm_cfg' ),
158
+ 'theme_exists_txt' => __( '<strong>%s</strong> exists. Please enter a different Child Theme', 'chld_thm_cfg' ),
159
+ 'recent_txt' => __( 'No recent edits.', 'chld_thm_cfg' ),
160
+ ) );
161
  wp_localize_script(
162
  'chld-thm-cfg-admin',
163
  'ctcAjax',
165
  );
166
  }
167
 
168
+ /**
169
+ * initialize configurator
170
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  function ctc_page_init () {
172
+ // get all available themes
173
  $this->get_themes();
174
+ // load config data and validate
175
  $this->load_config();
176
+ // perform any checks prior to processing config data
177
+ do_action( 'chld_thm_cfg_preprocess' );
178
+ // process any additional forms
179
  do_action( 'chld_thm_cfg_forms', $this ); // hook for custom forms
180
+ // process main post data
181
+ $this->process_post();
182
+ // initialize UI
183
+ include_once( CHLD_THM_CFG_DIR . '/includes/class-ctc-ui.php' );
184
  $this->ui = new ChildThemeConfiguratorUI();
185
+ // initialize help
186
  $this->ui->render_help_content();
187
+ // load styles and scripts
188
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ), 999 );
189
+ // load web fonts for this theme
190
  $this->load_imports();
191
  }
192
 
199
  // get the theme slug
200
  $slug = $theme->get_stylesheet();
201
  // add theme to themes array
202
+ $this->themes[ $group ][ $slug ] = array(
203
  'Name' => $theme->get( 'Name' ),
204
  'Author' => $theme->get( 'Author' ),
205
  'Version' => $theme->get( 'Version' ),
209
  endforeach;
210
  }
211
 
212
+ function validate_post( $action = 'ctc_update', $noncefield = '_wpnonce', $cap = 'install_themes' ) {
213
  // security: request must be post, user must have permission, referrer must be local and nonce must match
214
+ return ( $this->is_post
215
+ && current_user_can( $cap ) // ( 'edit_themes' )
216
+ && ( $this->is_ajax ? check_ajax_referer( $action, $noncefield, FALSE ) :
217
+ check_admin_referer( $action, $noncefield, FALSE ) ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  }
219
 
220
  function load_config() {
221
+ include_once( CHLD_THM_CFG_DIR . '/includes/class-ctc-css.php' );
222
  $this->css = new ChildThemeConfiguratorCSS();
223
  // if not new format or themes do not exist reinitialize
224
+ if ( FALSE === $this->css->load_config()
225
  || ! $this->check_theme_exists( $this->css->get_prop( 'child' ) )
226
  || ! $this->check_theme_exists( $this->css->get_prop( 'parnt' ) ) ):
227
  $this->css = new ChildThemeConfiguratorCSS();
 
 
228
  endif;
229
+ if ( $this->is_get ):
230
  if ( $this->css->get_prop( 'child' ) ):
231
  // get filesystem credentials if available
232
  $this->verify_creds();
233
+ $stylesheet = apply_filters( 'chld_thm_cfg_target', $this->css->get_child_target( 'style.css' ), $this->css );
234
  // check file permissions
235
  if ( !is_writable( $stylesheet ) && !$this->fs ):
236
+ add_action( 'admin_notices', array( $this, 'writable_notice' ) );
237
  endif;
238
+ // enqueue flag will be null for anyone coming from < 1.6.0
239
+ if ( !isset( $this->css->enqueue ) ):
240
  add_action( 'admin_notices', array( $this, 'enqueue_notice' ) );
241
+ endif;
242
+ // check for first run
243
+ elseif ( !isset( $this->css->enqueue ) ):
244
+ add_action( 'admin_notices', array( $this, 'config_notice' ) );
245
  endif;
246
  // check if file ownership is messed up from old version or other plugin
247
 
251
  endif;
252
  }
253
 
254
+ /**
255
+ * ajax callback for saving form data
256
+ */
257
+ function ajax_save_postdata( $action = 'ctc_update' ) {
258
+ $this->is_ajax = TRUE;
259
+ // security check
260
+ if ( $this->validate_post( $action ) ):
261
+ if ( 'ctc_plugin' == $action ) do_action( 'chld_thm_cfg_pluginmode' );
262
+ $this->verify_creds(); // initialize filesystem access
263
+ // add these actions before checking configtype
264
+ // set configtype since this request came via ajax
265
+ if ( 'ctc_plugin' == $_POST[ 'action' ] ) do_action( 'chld_thm_cfg_pluginmode' );
266
+ // this action swaps out the above two actions if in plugins mode
267
+
268
+ $this->load_config(); // get configuration data from options API
269
+ $this->css->parse_post_data(); // parse any passed values
270
+
271
+ // if child theme config has been set up, save new data
272
+ // return recent edits and selected stylesheets as cache updates
273
+ if ( $this->css->get_prop( 'child' ) ):
274
+ $this->css->write_css();
275
+ // add any additional updates to pass back to browser
276
+ do_action( 'chld_thm_cfg_cache_updates' );
277
+ $this->updates[] = array(
278
+ 'obj' => 'addl_css',
279
+ 'key' => '',
280
+ 'data' => $this->css->get_prop( 'addl_css' ),
281
+ );
282
+ endif;
283
+ $result = $this->css->obj_to_utf8( $this->updates );
284
+
285
+ // update config data in options API
286
+ $this->css->save_config();
287
+ // send all updates back to browser to update cache
288
+ die( json_encode( $result ) );
289
+ else:
290
+ die( 0 );
291
+ endif;
292
+ }
293
+
294
+ /**
295
+ * ajax callback to query config data
296
+ */
297
+ function ajax_query_css( $action = 'ctc_update' ) {
298
+ $this->is_ajax = TRUE;
299
+ if ( $this->validate_post( $action ) ):
300
+ if ( 'ctc_plugin' == $action ) do_action( 'chld_thm_cfg_pluginmode' );
301
+ $this->load_config();
302
+ $regex = "/^ctc_query_/";
303
+ foreach( preg_grep( $regex, array_keys( $_POST ) ) as $key ):
304
+ $name = preg_replace( $regex, '', $key );
305
+ $param[ $name ] = sanitize_text_field( $_POST[ $key ] );
306
+ endforeach;
307
+ if ( !empty( $param[ 'obj' ] ) ):
308
+ // add any additional updates to pass back to browser
309
+ do_action( 'chld_thm_cfg_cache_updates' );
310
+ $this->updates[] = array(
311
+ 'key' => isset( $param[ 'key' ] ) ? $param[ 'key' ] : '',
312
+ 'obj' => $param[ 'obj' ],
313
+ 'data' => $this->css->get_prop( $param[ 'obj' ], $param ),
314
+ );
315
+ die( json_encode( $this->updates ) );
316
+ endif;
317
+ endif;
318
+ die( 0 );
319
+ }
320
+
321
  /***
322
  * Handles processing for all form submissions.
323
+ * Older versions ( < 1.6.0 ) smelled like spaghetti so we moved conditions
324
  * to switch statement with the main setup logic in a separate function.
325
  */
326
+ function process_post() {
327
  // make sure this is a post
328
+ if ( $this->is_post ):
329
  // see if a valid action was passed
330
+ foreach ( $this->actionfields as $field ):
331
+ if ( in_array( 'ctc_' . $field, array_keys( $_POST ) ) ):
332
+ $actionfield = $field;
333
  break;
334
  endif;
335
  endforeach;
337
 
338
  // make sure post passes security checkpoint
339
  $this->errors = array();
340
+ if ( $this->validate_post( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ) ):
341
  // zip export does not require filesystem access so check that first
342
  if ( 'export_child_zip' == $actionfield ):
343
  $this->export_zip();
346
  // all other actions require filesystem access
347
  else:
348
  // handle uploaded file before checking filesystem
349
+ if ( 'theme_image_submit' == $actionfield && isset( $_FILES[ 'ctc_theme_image' ] ) ):
350
  $this->handle_file_upload( 'ctc_theme_image', $this->imgmimes );
351
+ elseif ( 'theme_screenshot_submit' == $actionfield && isset( $_FILES[ 'ctc_theme_screenshot' ] ) ):
352
  $this->handle_file_upload( 'ctc_theme_screenshot', $this->imgmimes );
353
  endif;
354
  // now we need to check filesystem access
365
 
366
  case 'parnt_templates_submit':
367
  // copy parent templates to child
368
+ if ( isset( $_POST[ 'ctc_file_parnt' ] ) ):
369
+ foreach ( $_POST[ 'ctc_file_parnt' ] as $file ):
370
  $this->copy_parent_file( sanitize_text_field( $file ) );
371
  endforeach;
372
  $msg = '8&tab=file_options';
375
 
376
  case 'child_templates_submit':
377
  // delete child theme files
378
+ if ( isset( $_POST[ 'ctc_file_child' ] ) ):
379
+ if ( in_array( 'functions', $_POST[ 'ctc_file_child' ] ) ):
380
+ $this->errors[] =
381
+ __( 'The Functions file is required and cannot be deleted.',
382
+ 'chld_thm_cfg' );
383
  else:
384
+ foreach ( $_POST[ 'ctc_file_child' ] as $file ):
385
  $this->delete_child_file( sanitize_text_field( $file ),
386
+ ( preg_match( "/^style|ctc\-plugins/", $file ) ? 'css' : 'php' ) );
387
  endforeach;
388
  $msg = '8&tab=file_options';
389
  endif;
392
 
393
  case 'image_submit':
394
  // delete child theme images
395
+ if ( isset( $_POST[ 'ctc_img' ] ) ):
396
+ foreach ( $_POST[ 'ctc_img' ] as $file ):
397
  $this->delete_child_file( 'images/' . sanitize_text_field( $file ), 'img' );
398
  endforeach;
399
  $msg = '8&tab=file_options';
402
 
403
  case 'templates_writable_submit':
404
  // make specific files writable ( systems not running suExec )
405
+ if ( isset( $_POST[ 'ctc_file_child' ] ) ):
406
+ foreach ( $_POST[ 'ctc_file_child' ] as $file ):
407
+ $this->set_writable( sanitize_text_field( $file ),
408
+ ( 0 === strpos( $file, 'style' ) ? 'css' : 'php' ) );
409
  endforeach;
410
  $msg = '8&tab=file_options';
411
  endif;
425
 
426
  case 'theme_image_submit':
427
  // move uploaded child theme images (now we have filesystem access)
428
+ if ( isset( $_POST[ 'movefile' ] ) ):
429
  $this->move_file_upload( 'images' );
430
  $msg = '8&tab=file_options';
431
  endif;
433
 
434
  case 'theme_screenshot_submit':
435
  // move uploaded child theme screenshot (now we have filesystem access)
436
+ if ( isset( $_POST[ 'movefile' ] ) ):
437
  // remove old screenshot
438
  foreach( array_keys( $this->imgmimes ) as $extreg ):
439
  foreach ( explode( '|', $extreg ) as $ext ):
444
  $msg = '8&tab=file_options';
445
  endif;
446
  break;
 
447
  default:
448
  // assume we are on the files tab so just redirect there
449
  $msg = '8&tab=file_options';
464
  return FALSE;
465
  }
466
 
 
 
 
 
467
  /***
468
  * Handle the creation or update of a child theme
469
  */
470
  function setup_child_theme() {
 
471
  // sanitize and extract config fields into local vars
472
  foreach ( $this->configfields as $configfield ):
473
+
474
  $varparts = explode( '_', $configfield );
475
  $varname = end( $varparts );
476
+ ${$varname} = empty( $_POST[ 'ctc_' . $configfield ] ) ? '' :
477
+ sanitize_text_field( $_POST[ 'ctc_' . $configfield ] );
478
+
479
  endforeach;
480
 
481
+ // legacy plugin extension needs parent/child values but this version disables the inputs
482
+ // so get we them from current css object
483
+ if ( !$this->is_theme( $configtype ) && $this->is_legacy() ):
484
+ $parnt = $this->css->get_prop( 'parnt' );
485
+ $child = $this->css->get_prop( 'child' );
486
+ $name = $this->css->get_prop( 'child_name' );
487
+ endif;
488
+
489
+ // validate parent and child theme inputs
490
  if ( $parnt ):
491
  if ( ! $this->check_theme_exists( $parnt ) ):
492
+ $this->errors[] = sprintf(
493
+ __( '%s does not exist. Please select a valid Parent Theme.',
494
+ 'chld_thm_cfg' ), $parnt );
495
  endif;
496
  else:
497
+ $this->errors[] = __( 'Please select a valid Parent Theme.', 'chld_thm_cfg' );
498
  endif;
499
+ if ( 'existing' == $type && empty( $child ) ):
500
+ $this->errors[] = __( 'Please enter a valid Child Theme directory.', 'chld_thm_cfg' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
501
  endif;
 
502
  if ( empty( $name ) ):
503
  $name = ucfirst( $child );
504
  endif;
 
 
 
 
 
505
  if ( FALSE === $this->verify_child_dir( $child ) ):
506
  $this->errors[] = __( 'Your theme directories are not writable.', 'chld_thm_cfg' );
507
  add_action( 'admin_notices', array( $this, 'writable_notice' ) );
508
  endif;
509
 
510
+ // if this is a shiny brand new child theme certain rules apply
511
+ if ( 'new' == $type ):
512
+ if ( empty( $template ) && empty( $name ) ):
513
+ $this->errors[] = __( 'Please enter a valid Child Theme template name.', 'chld_thm_cfg' );
514
+ else:
515
+ $child = strtolower( preg_replace( "%[^\w\-]%", '', empty( $template ) ? $name : $template ) );
516
+ if ( $this->check_theme_exists( $child ) ):
517
+ $this->errors[] = sprintf(
518
+ __( '<strong>%s</strong> exists. Please enter a different Child Theme template name.',
519
+ 'chld_thm_cfg' ), $child );
520
+ endif;
521
+ endif;
522
+ endif;
523
  // if no errors so far, we are good to create child theme
524
  if ( empty( $this->errors ) ):
525
  $this->css = new ChildThemeConfiguratorCSS();
526
+ // check if we have additional files from legacy plugin extension. if so, we have to override
527
+ // function to support wp_filesystem requirements
528
+ if ( $this->is_theme( $configtype ) ):
529
+ // is theme means this is not a plugin stylesheet config
530
+ add_action( 'chld_thm_cfg_addl_files', array( &$this, 'add_base_files' ), 10, 2 );
531
+ add_action( 'chld_thm_cfg_addl_files', array( &$this, 'copy_screenshot' ), 10, 2 );
532
+ add_action( 'chld_thm_cfg_addl_files', array( &$this, 'enqueue_parent_css' ), 15, 2 );
533
+ elseif( $this->is_legacy()
534
+ && has_action( 'chld_thm_cfg_addl_files' ) ):
535
+ // backwards compatability for plugins extension < 2.0.0 (before pro)
536
+ // action exists so we have to hijack it to use new filesystem checks
537
+ remove_all_actions( 'chld_thm_cfg_addl_files' );
538
+ add_action( 'chld_thm_cfg_addl_files', array( &$this, 'write_addl_files' ), 10, 2 );
539
+ $this->css->set_prop( 'configtype', $configtype );
540
+ endif;
541
+ //echo 'parnt: ' . $parnt . ' child: ' . $child . LF;
542
  $this->css->set_prop( 'parnt', $parnt );
543
  $this->css->set_prop( 'child', $child );
544
  $this->css->set_prop( 'child_name', $name );
545
  $this->css->set_prop( 'child_author', $author );
546
  $this->css->set_prop( 'child_version', strlen( $version ) ? $version : '1.0' );
547
+
548
+ if ( isset( $_POST[ 'ctc_parent_enqueue' ] ) )
549
+ $this->css->set_prop( 'enqueue', sanitize_text_field( $_POST[ 'ctc_parent_enqueue' ] ) );
550
+ elseif ( !$this->is_theme( $configtype ) )
551
+ $this->css->set_prop( 'enqueue', 'enqueue' );
552
 
553
  // hook for add'l plugin files and subdirectories
554
  do_action( 'chld_thm_cfg_addl_files', $this );
555
 
556
+ // parse parent stylesheet if theme or legacy plugin extension
557
+ if ( $this->is_theme( $configtype ) || $this->is_legacy() )
558
+ $this->css->parse_css_file( 'parnt' );
559
 
560
  // parse child stylesheet, backup or skip ( to reset )
561
  $this->css->parse_css_file( 'child', $revert );
562
 
563
  // parse additional stylesheets
564
+ if ( isset( $_POST[ 'ctc_additional_css' ] ) && is_array( $_POST[ 'ctc_additional_css' ] ) ):
565
+ $this->css->addl_css = array();
566
+ foreach ( $_POST[ 'ctc_additional_css' ] as $file ):
567
  $this->css->parse_css_file( 'parnt', $file );
568
+ $this->css->addl_css[] = $file;
569
  endforeach;
570
  endif;
571
 
572
  // try to write new stylsheet. If it fails send alert.
573
+ if ( FALSE === $this->css->write_css( isset( $_POST[ 'ctc_backup' ] ) ) ):
574
+ $this->debug .= 'failed to write' . LF;
575
  $this->errors[] = __( 'Your stylesheet is not writable.', 'chld_thm_cfg' );
576
  add_action( 'admin_notices', array( $this, 'writable_notice' ) );
577
  return FALSE;
578
  endif;
579
 
580
  // copy parent theme mods option set
581
+ if ( isset( $_POST[ 'ctc_parent_mods' ] ) ):
582
  // we can copy settings from parent to child even if neither is currently active
583
  // so we need cases for active parent, active child or neither
584
 
591
  $child_widgets = retrieve_widgets();
592
  else:
593
  // otherwise get widgets from parent theme mods
594
+ $child_widgets = $child_mods[ 'sidebars_widgets' ][ 'data' ];
595
  endif;
596
  if ( $active_theme == $child ):
597
  // if child theme is active, remove widgets from temp array
598
+ unset( $child_mods[ 'sidebars_widgets' ] );
599
  // copy temp array to child mods
600
  update_option( 'theme_mods_' . $child, $child_mods );
601
  // copy widgets to active sidebars_widgets array
602
  wp_set_sidebars_widgets( $child_widgets );
603
  else:
604
  // otherwise copy widgets to temp array with time stamp
605
+ $child_mods[ 'sidebars_widgets' ][ 'data' ] = $child_widgets;
606
+ $child_mods[ 'sidebars_widgets' ][ 'time' ] = time();
607
  // copy temp array to child theme mods
608
  update_option( 'theme_mods_' . $child, $child_mods );
609
  endif;
616
  do_action( 'chld_thm_cfg_addl_options', $this ); // hook for add'l plugin options
617
 
618
  // return message id 1, which says new child theme created successfull;
619
+ return 1; //isset( $_POST[ 'ctc_scan_subdirs' ] ) ? '9&tab=import_options' : 1;
620
  endif;
621
  return FALSE;
622
  }
623
+
624
+ function load_imports() {
625
+ // allows fonts and other externals to be previewed
626
+ // loads early not to conflict with admin stylesheets
627
+ $regex = "/\@import *(url)? *\( *['\"]?((https?:\/\/)?(.+?))['\"]? *\).*$/";
628
+ if ( $imports = $this->css->get_prop( 'imports' ) ):
629
+ $count = 1;
630
+ foreach ( $imports as $import ):
631
+ preg_match( $regex, $import, $matches );
632
+ if ( empty( $matches[ 3 ] ) && !empty( $matches[ 4 ] ) ): // relative filepath
633
+ $url = get_stylesheet_directory_uri();
634
+ preg_replace( "#\.\./#", '', $matches[ 4 ], -1, $count );
635
+ for( $i = 0; $i < $count; $i++ ):
636
+ $url = dirname( $url );
637
+ endfor;
638
+ $import = preg_replace( $regex, '@import url(' . trailingslashit( $url ) . $matches[ 4 ] . ')', $import );
639
+ endif;
640
+ wp_enqueue_style( 'chld-thm-cfg-admin' . ++$count, preg_replace( $regex, "$2", $import ) );
641
+ endforeach;
642
+ endif;
643
+ }
644
+
645
  /*
646
  * TODO: this is a stub for future use
647
  */
651
 
652
  function update_redirect( $msg = 1 ) {
653
  if ( empty( $this->is_ajax ) ):
654
+ $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU );
655
  wp_safe_redirect(
656
  ( is_multisite() ?
657
+ network_admin_url( 'themes.php?page=' . $ctcpage . '&updated=' . $msg ) :
658
+ admin_url( 'tools.php?page=' . $ctcpage . '&updated=' . $msg ) )
659
  );
660
  die();
661
  endif;
693
  }
694
 
695
  function enqueue_parent_code(){
696
+ return explode( "\n", "// AUTO GENERATED - Do not modify or remove comment markers above or below:
697
+
698
  if ( !function_exists( 'chld_thm_cfg_parent_css' ) ):
699
  function chld_thm_cfg_parent_css() {
700
+ wp_enqueue_style( 'chld_thm_cfg_parent', trailingslashit( get_template_directory_uri() ) . 'style.css' );
701
  }
702
  endif;
703
  add_action( 'wp_enqueue_scripts', 'chld_thm_cfg_parent_css' );
704
+ " );
705
  }
706
 
707
  function enqueue_parent_css( $obj ) {
 
 
708
  $marker = 'ENQUEUE PARENT ACTION';
709
  $insertion = 'enqueue' == $this->css->enqueue ? $this->enqueue_parent_code() : array();
710
  if ( $filename = $this->css->is_file_ok( $this->css->get_child_target( 'functions.php' ), 'write' ) ):
718
  */
719
  function insert_with_markers( $filename, $marker, $insertion ) {
720
  if ( !$this->fs ) return FALSE; // return if no filesystem access
721
+ // make sure file exists with php header
722
+ $this->add_base_files( $this );
723
  global $wp_filesystem;
724
  if( !$wp_filesystem->exists( $this->fspath( $filename ) ) ):
725
  $markerdata = FALSE;
761
  }
762
 
763
  function write_child_file( $file, $contents ) {
764
+ if ( !$this->fs ):
765
+ $this->debug( 'no filesystem access' );
766
+ return FALSE; // return if no filesystem access
767
+ endif;
768
  global $wp_filesystem;
769
  $file = $this->fspath( $this->css->is_file_ok( $this->css->get_child_target( $file ), 'write' ) );
770
+ //echo 'writing to filesystem: ' . $file . LF;
771
  if ( $file && !$wp_filesystem->exists( $file ) ):
772
+ if ( FALSE === $wp_filesystem->put_contents( $file, $contents ) ):
773
+ //echo 'filesystem write failed!' . LF;
774
+ return FALSE;
775
+ endif;
776
+ else:
777
+ //echo 'file exists!' . LF;
778
+ return FALSE;
779
  endif;
780
+ //echo 'filesystem write successful' . LF;
781
  }
782
 
783
  function copy_screenshot( $obj ) {
809
  $child_dir = dirname( $this->theme_basename( '', $child_file ) );
810
  if ( $parent_file // sanity check
811
  && $child_file // sanity check
812
+ && $this->verify_child_dir( $child_dir ) //create child subdir if necessary
813
+ && $wp_filesystem->copy( $parent_file, $this->fspath( $child_file ), FS_CHMOD_FILE ) ) return TRUE;
814
  $this->errors[] = __( 'Could not copy file.', 'chld_thm_cfg' );
815
  }
816
 
826
  }
827
 
828
  function get_files( $theme, $type = 'template' ) {
829
+ if ( !isset( $this->files[ $theme ] ) ):
830
+ $this->files[ $theme ] = array();
831
  $imgext = '(' . implode( '|', array_keys( $this->imgmimes ) ) . ')';
832
  foreach ( $this->css->recurse_directory(
833
  trailingslashit( get_theme_root() ) . $theme, '', TRUE ) as $file ):
834
  $file = $this->theme_basename( $theme, $file );
835
  if ( preg_match( "/^style\-(\d+)\.css$/", $file, $matches ) ):
836
+ $date = date_i18n( 'D, j M Y g:i A', strtotime( $matches[ 1 ] ) );
837
+ $this->files[ $theme ][ 'backup' ][ $file ] = $date;
838
+ elseif ( preg_match( "/^ctc\-plugins\-(\d+)\.css$/", $file, $matches ) ):
839
+ $date = date_i18n( 'D, j M Y g:i A', strtotime( $matches[ 1 ] ) );
840
+ $this->files[ $theme ][ 'pluginbackup' ][ $file ] = $date;
841
  elseif ( preg_match( "/\.php$/", $file ) ):
842
+ $this->files[ $theme ][ 'template' ][] = $file;
843
  elseif ( preg_match( "/\.css$/", $file ) && 'style.css' != $file ):
844
+ $this->files[ $theme ][ 'stylesheet' ][] = $file;
845
  elseif ( preg_match( "/^images\/.+?\." . $imgext . "$/", $file ) ):
846
+ $this->files[ $theme ][ 'img' ][] = $file;
847
  endif;
848
  endforeach;
849
  endif;
850
+ $types = explode(",", $type);
851
+ $files = array();
852
+ foreach ( $types as $type )
853
+ if ( isset( $this->files[ $theme ][ $type ] ) )
854
+ $files = array_merge( $this->files[ $theme ][ $type ], $files );
855
+ return $files;
856
  }
857
 
858
  function theme_basename( $theme, $file ) {
864
  function uploads_basename( $file ) {
865
  $file = $this->normalize_path( $file );
866
  $uplarr = wp_upload_dir();
867
+ $upldir = trailingslashit( $uplarr[ 'basedir' ] );
868
  return preg_replace( '%^' . preg_quote( $upldir ) . '%', '', $file );
869
  }
870
 
871
  function uploads_fullpath( $file ) {
872
  $file = $this->normalize_path( $file );
873
  $uplarr = wp_upload_dir();
874
+ $upldir = trailingslashit( $uplarr[ 'basedir' ] );
875
  return $upldir . $file;
876
  }
877
 
878
  function serialize_postarrays() {
879
  foreach ( $this->postarrays as $field )
880
+ if ( isset( $_POST[ $field ] ) && is_array( $_POST[ $field ] ) )
881
+ $_POST[ $field ] = implode( "%%", $_POST[ $field ] );
882
  }
883
 
884
  function unserialize_postarrays() {
885
  foreach ( $this->postarrays as $field )
886
+ if ( isset( $_POST[ $field ] ) && !is_array( $_POST[ $field ] ) )
887
+ $_POST[ $field ] = explode( "%%", $_POST[ $field ] );
888
  }
889
 
890
  function set_writable( $file = NULL ) {
891
 
892
+ $file = isset( $file ) ? $this->css->get_child_target( $file . '.php' ) :
893
+ apply_filters( 'chld_thm_cfg_target', $this->css->get_child_target(), $this->css );
894
  if ( $this->fs ): // filesystem access
895
  global $wp_filesystem;
896
  if ( $file && $wp_filesystem->chmod( $this->fspath( $file ), 0666 ) ) return;
909
  $themedir = trailingslashit( get_theme_root() );
910
  $fsthemedir = $this->fspath( $themedir );
911
  // is child theme owned by user?
912
+ if ( fileowner( $dir ) == fileowner( $themedir ) ):
913
  $copy = FALSE;
914
  $wp_filesystem->chmod( $dir );
915
  // recursive chmod ( as user )
954
  $oldfiles = $this->css->recurse_directory( trailingslashit( $themedir ) . $child . '-old', NULL, TRUE );
955
  array_unshift( $oldfiles, trailingslashit( $themedir ) . $child . '-old' );
956
  foreach ( array_reverse( $oldfiles ) as $file ):
957
+ if ( $wp_filesystem->delete( $this->fspath( $file ) )
958
+ || ( is_dir( $file ) && @rmdir( $file ) )
959
+ || ( is_file( $file ) && @unlink( $file ) ) ):
960
  $deletedfiles++;
961
  endif;
962
  endforeach;
972
  add_action( 'admin_notices', array( $this, 'writable_notice' ) );
973
  endif;
974
  }
975
+ function set_skip_form() {
976
+ $this->skip_form = TRUE;
977
+ }
978
  function handle_file_upload( $field, $childdir = NULL, $mimes = NULL ){
979
+ $uploadedfile = $_FILES[ $field ];
980
  $upload_overrides = array(
981
  'test_form' => FALSE,
982
  'mimes' => ( is_array( $mimes ) ? $mimes : NULL )
983
  );
984
  if ( ! function_exists( 'wp_handle_upload' ) ) require_once( ABSPATH . 'wp-admin/includes/file.php' );
985
  $movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
986
+ if ( isset( $movefile[ 'error' ] ) ):
987
+ $this->errors[] = $movefile[ 'error' ];
988
  return FALSE;
989
  endif;
990
+ $_POST[ 'movefile' ] = $this->uploads_basename( $movefile[ 'file' ] );
991
  }
992
 
993
  function move_file_upload( $subdir = 'images' ) {
994
  if ( !$this->fs ) return FALSE; // return if no filesystem access
995
  global $wp_filesystem;
996
+ $source_file = sanitize_text_field( $_POST[ 'movefile' ] );
997
  $target_file = ( '' == $subdir ?
998
  preg_replace( "%^.+(\.\w+)$%", "screenshot$1", basename( $source_file ) ) :
999
  trailingslashit( $subdir ) . basename( $source_file ) );
1045
  //fs prompt does not support arrays as post data - serialize arrays
1046
  $this->serialize_postarrays();
1047
  // generate callback url
1048
+ $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU );
1049
+ $url = is_multisite() ? network_admin_url( 'themes.php?page=' . $ctcpage ) :
1050
+ admin_url( 'tools.php?page=' . $ctcpage );
1051
+ $nonce_url = wp_nonce_url( $url, apply_filters( 'chld_thm_cfg_action', 'ctc_update' ), '_wpnonce' );
1052
  // buffer output so we can process prior to http header
1053
  ob_start();
1054
  if ( $creds = request_filesystem_credentials( $nonce_url, '', FALSE, FALSE, $args ) ):
1091
  function writable_notice() {
1092
  ?> <div class="update-nag">
1093
  <p><?php _e( 'Child Theme Configurator is unable to write to the stylesheet. This can be resolved using one of the following options:<ol>', 'chld_thm_cfg' );
1094
+ $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU );
1095
+ if ( isset( $_SERVER[ 'SERVER_SOFTWARE' ] ) && preg_match( '%unix%i',$_SERVER[ 'SERVER_SOFTWARE' ] ) ):
1096
  _e( '<li>Temporarily make the stylesheet writable by clicking the button below. You should change this back when you are finished editing for security by clicking "Make read-only" under the "Files" tab.</li>', 'chld_thm_cfg' );
1097
+ ?><form action="?page=<?php echo $ctcpage; ?>" method="post">
1098
+ <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
1099
  <input name="ctc_set_writable" class="button" type="submit" value="<?php _e( 'Temporarily make stylesheet writable', 'chld_thm_cfg' ); ?>"/></form><?php endif;
1100
  _e( '<li><a target="_blank" href="http://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants" title="Editin wp-config.php">Add your FTP/SSH credentials to the WordPress config file</a>.</li>', 'chld_thm_cfg' );
1101
+ if ( isset( $_SERVER[ 'SERVER_SOFTWARE' ] ) && preg_match( '%iis%i',$_SERVER[ 'SERVER_SOFTWARE' ] ) )
1102
  _e( '<li><a target="_blank" href="http://technet.microsoft.com/en-us/library/cc771170" title="Setting Application Pool Identity">Assign WordPress to an application pool that has write permissions</a> (Windows IIS systems).</li>', 'chld_thm_cfg' );
1103
  _e( '<li><a target="_blank" href="http://codex.wordpress.org/Changing_File_Permissions" title="Changing File Permissions">Set the stylesheet write permissions on the server manually</a> (not recommended).</li>', 'chld_thm_cfg' );
1104
+ if ( isset( $_SERVER[ 'SERVER_SOFTWARE' ] ) && preg_match( '%unix%i',$_SERVER[ 'SERVER_SOFTWARE' ] ) )
1105
  _e( '<li>Run PHP under Apache with suEXEC (contact your web host).</li>', 'chld_thm_cfg' ) ?>
1106
  </ol></p>
1107
  </div>
1108
  <?php
1109
  }
1110
  function owner_notice() {
1111
+ $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU );
1112
  ?>
1113
  <div class="update-nag">
1114
  <p><?php _e( 'This Child Theme is not owned by your website account. It may have been created by a prior version of this plugin or by another program. Moving forward, it must be owned by your website account to make changes. Child Theme Configurator will attempt to correct this when you click the button below.', 'chld_thm_cfg' ) ?></p>
1115
+ <form action="?page=<?php echo $ctcpage; ?>" method="post">
1116
+ <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
1117
  <input name="ctc_reset_permission" class="button" type="submit" value="<?php _e( 'Correct Child Theme Permissions', 'chld_thm_cfg' ); ?>"/></form> </div>
1118
  <?php
1119
  }
1121
  function enqueue_notice() {
1122
  ?>
1123
  <div class="update-nag">
1124
+ <p><?php _e( 'Child Theme Configurator needs to update its interal data. Please set your preferences below and click "Generate Child Theme Files" to update your configuration.', 'chld_thm_cfg' ) ?></p>
1125
  </div>
1126
  <?php
1127
  }
1128
 
1129
+ function config_notice() {
1130
+ ?>
1131
+ <div class="update-nag">
1132
+ <p><?php _e( 'Child Theme Configurator did not detect any configuration data, either because this is the first time it has been used, or because a previously configured Child Theme has been removed. Please set your preferences below and click "Generate Child Theme Files".', 'chld_thm_cfg' ) ?></p>
1133
+ </div>
1134
+ <?php
1135
+ }
1136
+
1137
+ function render_addl_tabs( $ctc, $active_tab = NULL, $hidechild = '' ) {
1138
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/addl_tabs.php' );
1139
+ }
1140
+
1141
+ function render_addl_panels( $ctc, $active_tab = NULL, $hidechild = '' ) {
1142
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/addl_panels.php' );
1143
+ }
1144
+
1145
+ // back compatibility function for legacy plugins extension
1146
+ function write_addl_files( $obj ) {
1147
  global $chld_thm_cfg_plugins;
1148
+ if ( !is_object( $chld_thm_cfg_plugins ) || !$this->fs ) return FALSE;
1149
+ $configtype = $this->css->get_prop( 'configtype' );
1150
+ //echo $configtype . LF;
1151
  if ( 'theme' == $configtype || !( $def = $chld_thm_cfg_plugins->defs->get_def( $configtype ) ) ) return FALSE;
1152
+ $child = trailingslashit( $this->css->get_prop( 'child' ) );
1153
+ if ( isset( $def[ 'addl' ] ) && is_array( $def[ 'addl' ] ) && count( $def[ 'addl' ] ) ):
1154
+ foreach ( $def[ 'addl' ] as $path => $type ):
1155
 
1156
  // sanitize the crap out of the target data -- it will be used to create paths
1157
  $path = $this->normalize_path( preg_replace( "%[^\w\\//\-]%", '', sanitize_text_field( $child . $path ) ) );
1158
+ if ( ( 'dir' == $type && FALSE === $this->verify_child_dir( $path ) )
1159
+ || ( 'dir' != $type && FALSE === $this->write_child_file( $path, '' ) ) ):
1160
+ //$this->errors[] = __( 'Your theme directories are not writable.', 'chld_thm_cfg_plugins' );
 
1161
  endif;
1162
  endforeach;
1163
  endif;
1164
  // write main def file
1165
+ if ( isset( $def[ 'target' ] ) ):
1166
+ $path = $this->normalize_path( preg_replace( "%[^\w\\//\-\.]%", '', sanitize_text_field( $def[ 'target' ] ) ) ); //$child .
1167
+ if ( FALSE === $this->write_child_file( $path, '' ) ):
1168
+ //echo "invalid path: " . $path . ' ' . ' was: ' . $def[ 'target' ] . LF;
1169
+ //$this->errors[] = __( 'Your stylesheet is not writable.', 'chld_thm_cfg_plugins' );
1170
  return FALSE;
1171
  endif;
1172
  endif;
1173
  }
1174
+ // backwards compatability < WP 3.9
1175
  function normalize_path( $path ) {
1176
  $path = str_replace( '\\', '/', $path );
1177
  $path = preg_replace( '|/+|','/', $path );
1178
  return $path;
1179
  }
1180
+
1181
+ function check_theme_exists( $theme ) {
1182
+ return in_array( $theme, array_keys( wp_get_themes() ) );
1183
+ }
1184
+
1185
+ // helper functions to support legacy plugin extension
1186
+ function is_legacy() {
1187
+ return defined('CHLD_THM_CFG_PLUGINS_VERSION')
1188
+ && version_compare( CHLD_THM_CFG_PLUGINS_VERSION, '2.0.0', '<' );
1189
+ }
1190
+
1191
+ /* not using plugin mode */
1192
+ function is_theme( $configtype = '' ) {
1193
+ // if filter returns a value, we are using plugin mode
1194
+ // otherwise if configtype has a value and it is not a theme then we are in legacy plugin mode
1195
+ $pluginmode = apply_filters( 'chld_thm_cfg_action', NULL );
1196
+ if ( $pluginmode || ( !empty( $configtype ) && 'theme' != $configtype ) ):
1197
+ return FALSE;
1198
+ endif;
1199
+ if ( $this->is_legacy()
1200
+ && is_object( $this->css )
1201
+ && ( $configtype = $this->css->get_prop( 'configtype' ) )
1202
+ && !empty( $configtype ) && 'theme' != $configtype ):
1203
+ return FALSE;
1204
+ endif;
1205
+ return TRUE;
1206
+ }
1207
+
1208
+ /* returns parent theme either from existing config or passed as post var */
1209
+ function get_current_parent() {
1210
+ if ( isset( $_GET[ 'ctc_parent' ] ) && ( $parent = sanitize_text_field( $_GET[ 'ctc_parent' ] ) ) )
1211
+ return $parent;
1212
+ elseif ( $parent = $this->css->get_prop( 'parnt' ) )
1213
+ return $parent;
1214
+ else return get_template();
1215
+ }
1216
+
1217
+ /* debug backtrace with extraneous steps (missing class, function or line) removed */
1218
+ function backtrace_summary() {
1219
+ $bt = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
1220
+ $thisstep = array_shift( $bt );
1221
+ foreach ( $bt as $ndx => $step )
1222
+ if ( isset( $step[ 'class' ] ) && isset( $step[ 'function' ] ) && isset( $step[ 'line' ] ) )
1223
+ echo $ndx . ': ' . $step[ 'class' ] . ' ' . $step[ 'function' ] . ' ' . $step[ 'line' ] . LF;
1224
+ }
1225
+
1226
+ function debug( $msg = NULL ) {
1227
+ $this->debug .= isset( $msg ) ? $msg . LF : '';
1228
+ }
1229
+
1230
+ }
includes/forms/addl_css.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !defined( 'ABSPATH' ) ) exit;
3
+ // Additional stylesheets
4
+ $stylesheets = $this->get_files( $this->get_current_parent(), 'stylesheet' );
5
+ if ( count( $stylesheets ) ):?>
6
+ <div class="ctc-input-cell ctc-section-toggle" id="ctc_additional_css_files"> <strong>
7
+ <?php _e( 'Parse additional stylesheets:', 'chld_thm_cfg' ); ?>
8
+ </strong> </div>
9
+ <div class="ctc-input-cell-wide ctc-section-toggle-content" id="ctc_additional_css_files_content">
10
+ <p style="margin-top:0">
11
+ <?php _e( 'Stylesheets that are currently being loaded by the parent theme are automatically selected below (except for Bootstrap stylesheets which add a large amount data to the configuration). To further reduce overhead, select only the additional stylesheets you wish to customize.', 'chld_thm_cfg' ); ?>
12
+ </p>
13
+ <ul>
14
+ <?php foreach ( $stylesheets as $stylesheet ): ?>
15
+ <li>
16
+ <label>
17
+ <input class="ctc_checkbox" name="ctc_additional_css[]" type="checkbox"
18
+ value="<?php echo $stylesheet; ?>" />
19
+ <?php echo esc_attr( $stylesheet ); ?></label>
20
+ </li>
21
+ <?php endforeach; ?>
22
+ </ul>
23
+ </div>
24
+ <?php endif; ?>
includes/forms/addl_panels.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if ( !defined( 'ABSPATH' ) ) exit;
4
+ if ( !defined( 'CHLD_THM_CFG_PLUGINS_VERSION' ) ):
5
+ $page = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU );
6
+ $linktext = __( 'Reload', 'chld_thm_cfg_plugins' );
7
+ $link = '<a href="' . ( is_multisite() ?
8
+ network_admin_url( 'themes.php' ) :
9
+ admin_url( 'tools.php' ) ) . '?page=' . $page . '&tab=addl_tab" title="' . $linktext . '">' . $linktext . '</a>';
10
+ ?><div id="get_pro_panel" class="ctc-option-panel<?php echo 'get_pro' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?> >
11
+ <a href="http://www.lilaeamedia.com/child-theme-configurator-pro/" title="<?php _e( 'Learn more about CTC Pro', 'chld_thm_cfg' ); ?>"><img src="<?php echo CHLD_THM_CFG_URL . 'css/pro-banner.jpg'; ?>" width="610" height="197" /></a>
12
+ <h1><?php _e( 'Customizing WordPress Themes just got even easier.', 'chld_thm_cfg' ); ?></h1>
13
+ <p><?php _e( 'Thousands of users have already seen the benefits of using Child Theme Configurator. If you spend any amount of time customizing WordPress, CTC Pro will help maximize your productivity.', 'chld_thm_cfg' ); ?></p>
14
+ <h1><?php _e( 'Designed by Developers Who Use It Every Day.', 'chld_thm_cfg' ); ?></h1>
15
+ <p><?php _e( 'We\'ve packed in more features to make design work quicker and easier with <strong>Child Theme Configurator Pro.', 'chld_thm_cfg' ); ?></strong></p>
16
+ <ul>
17
+ <li><h3><?php _e( 'Custom Plugin Stylesheets', 'chld_thm_cfg' ); ?></h3>
18
+ <p><?php _e( 'Use the top-rated CTC interface to take control of your site\'s plugin styles. All new design makes it much easier to get the results you want.', 'chld_thm_cfg' ); ?></p></li>
19
+ <li><h3><?php _e( 'Links to all styles in a single view', 'chld_thm_cfg' ); ?></h3><p><?php _e( 'Use the "All Styles" panel to find the selector you wish to edit from a single combined list.', 'chld_thm_cfg' ); ?></p></li>
20
+ <li><h3><?php _e( 'Most recent edits', 'chld_thm_cfg' ); ?></h3><p><?php _e( 'Return to recently edited selectors from a toggleable sidebar.', 'chld_thm_cfg' ); ?></li>
21
+ <li><h3><?php _e( 'Free Upgrades', 'chld_thm_cfg' ); ?></h3>
22
+ <p><?php _e( 'Your Update Key gives you access to new Pro features as soon as they are released.', 'chld_thm_cfg' ); ?></li>
23
+ <li><h3><?php _e( 'Top-rated Online Support', 'chld_thm_cfg' ); ?></h3></li>
24
+ <li><h3><?php _e( 'Online Documentation', 'chld_thm_cfg' ); ?></h3></li>
25
+ <li><h3><?php _e( 'Tutorial Videos', 'chld_thm_cfg' ); ?></h3></li>
26
+ </ul>
27
+ <p><?php _e( 'For a limited time we are offering Child Theme Configurator Pro for a special introductory price.', 'chld_thm_cfg' ); ?></p>
28
+ <h3><a href="http://www.lilaeamedia.com/cart/?add-to-cart=1710" title="<?php _e( 'Buy CTC Pro', 'chld_thm_cfg' ); ?>"><?php _e( 'Buy Now - Only $12.95 USD', 'chld_thm_cfg' ); ?></a></h3></div><?php
29
+ endif;
includes/forms/addl_tabs.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if accessed directly
3
+ if ( !defined( 'ABSPATH' ) ) exit;
4
+ if ( !defined( 'CHLD_THM_CFG_PLUGINS_VERSION' ) ):
5
+ ?>
6
+ <a id="get_pro" href="?page=<?php echo CHLD_THM_CFG_MENU; ?>&amp;tab=get_pro"
7
+ class="nav-tab<?php echo 'get_pro' == $active_tab ? ' nav-tab-active' : ''; ?>" <?php echo $hidechild; ?>>
8
+ <?php _e( 'Get CTC Pro', 'chld_thm_cfg_plugins' ); ?>
9
+ </a>
10
+ <?php
11
+ endif;
includes/forms/at-import.php CHANGED
@@ -1,12 +1,13 @@
1
  <?php
2
  if ( !defined( 'ABSPATH' ) ) exit;
3
  // @imports Panel
 
4
  ?>
5
 
6
  <div id="import_options_panel"
7
  class="ctc-option-panel<?php echo 'import_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>>
8
- <form id="ctc_import_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>">
9
- <?php wp_nonce_field( 'ctc_update' ); ?>
10
  <div class="ctc-input-row clearfix" id="ctc_child_imports_row">
11
  <div class="ctc-input-cell">
12
  <div class="ctc-textarea-button-cell" id="ctc_save_imports_cell">
1
  <?php
2
  if ( !defined( 'ABSPATH' ) ) exit;
3
  // @imports Panel
4
+ $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU );
5
  ?>
6
 
7
  <div id="import_options_panel"
8
  class="ctc-option-panel<?php echo 'import_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>>
9
+ <form id="ctc_import_form" method="post" action=""><!-- ?page=<?php echo $ctcpage; ?>" -->
10
+ <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
11
  <div class="ctc-input-row clearfix" id="ctc_child_imports_row">
12
  <div class="ctc-input-cell">
13
  <div class="ctc-textarea-button-cell" id="ctc_save_imports_cell">
includes/forms/backups.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !defined( 'ABSPATH' ) ) exit;
3
+ // Additional stylesheets
4
+ ?><br/>
5
+ <?php
6
+ foreach ( $this->get_files( $this->css->get_prop( 'child' ), 'backup' ) as $backup => $label ): ?>
7
+ <label>
8
+ <input class="ctc_checkbox" id="ctc_revert_<?php echo $backup; ?>" name="ctc_revert" type="radio"
9
+ value="<?php echo $backup; ?>" />
10
+ <?php echo __( 'Restore backup from', 'chld_thm_cfg' ) . ' ' . $label; ?></label>
11
+ <br/>
12
+ <?php endforeach;
includes/forms/fileform.php CHANGED
@@ -17,7 +17,7 @@ endif;
17
  ?>
18
  <div class="ctc-input-row clearfix" id="input_row_<?php echo $template; ?>_templates">
19
  <form id="ctc_<?php echo $template; ?>_templates_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>&amp;tab=file_options">
20
- <?php wp_nonce_field( 'ctc_update' ); ?>
21
  <div class="ctc-input-cell"> <strong>
22
  <?php echo 'parnt' == $template ? __( 'Parent Templates', 'chld_thm_cfg' ) : __( 'Child Theme Files', 'chld_thm_cfg' ); ?>
23
  </strong>
17
  ?>
18
  <div class="ctc-input-row clearfix" id="input_row_<?php echo $template; ?>_templates">
19
  <form id="ctc_<?php echo $template; ?>_templates_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>&amp;tab=file_options">
20
+ <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
21
  <div class="ctc-input-cell"> <strong>
22
  <?php echo 'parnt' == $template ? __( 'Parent Templates', 'chld_thm_cfg' ) : __( 'Child Theme Files', 'chld_thm_cfg' ); ?>
23
  </strong>
includes/forms/files.php CHANGED
@@ -10,7 +10,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
10
  <?php $this->render_image_form(); ?>
11
  <div class="ctc-input-row clearfix" id="input_row_theme_image">
12
  <form id="ctc_theme_image_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>" enctype="multipart/form-data">
13
- <?php wp_nonce_field( 'ctc_update' ); ?>
14
  <div class="ctc-input-cell"> <strong>
15
  <?php _e( 'Upload New Child Theme Image', 'chld_thm_cfg' ); ?>
16
  </strong>
@@ -36,7 +36,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
36
  <?php endif; ?>
37
  <div class="ctc-input-row clearfix" id="input_row_screenshot">
38
  <form id="ctc_screenshot_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>" enctype="multipart/form-data">
39
- <?php wp_nonce_field( 'ctc_update' ); ?>
40
  <div class="ctc-input-cell"> <strong>
41
  <?php _e( 'Upload New Screenshot', 'chld_thm_cfg' ); ?>
42
  </strong>
@@ -54,7 +54,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
54
  </div>
55
  <div class="ctc-input-row clearfix" id="input_row_screenshot">
56
  <form id="ctc_export_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>">
57
- <?php wp_nonce_field( 'ctc_update' ); ?>
58
  <div class="ctc-input-cell"> <strong>
59
  <?php _e( 'Export Child Theme as Zip Archive', 'chld_thm_cfg' ); ?>
60
  </strong> </div>
@@ -68,7 +68,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
68
  <?php if ( 'direct' != $this->ctc()->fs_method ): ?>
69
  <div class="ctc-input-row clearfix" id="input_row_permissions">
70
  <form id="ctc_permission_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>">
71
- <?php wp_nonce_field( 'ctc_update' ); ?>
72
  <div class="ctc-input-cell"> <strong>
73
  <?php _e( 'Secure Child Theme', 'chld_thm_cfg' ); ?>
74
  </strong>
@@ -83,5 +83,5 @@ if ( !defined( 'ABSPATH' ) ) exit;
83
  </div>
84
  </form>
85
  </div>
86
- <?php endif; ?>
87
  </div>
10
  <?php $this->render_image_form(); ?>
11
  <div class="ctc-input-row clearfix" id="input_row_theme_image">
12
  <form id="ctc_theme_image_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>" enctype="multipart/form-data">
13
+ <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
14
  <div class="ctc-input-cell"> <strong>
15
  <?php _e( 'Upload New Child Theme Image', 'chld_thm_cfg' ); ?>
16
  </strong>
36
  <?php endif; ?>
37
  <div class="ctc-input-row clearfix" id="input_row_screenshot">
38
  <form id="ctc_screenshot_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>" enctype="multipart/form-data">
39
+ <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
40
  <div class="ctc-input-cell"> <strong>
41
  <?php _e( 'Upload New Screenshot', 'chld_thm_cfg' ); ?>
42
  </strong>
54
  </div>
55
  <div class="ctc-input-row clearfix" id="input_row_screenshot">
56
  <form id="ctc_export_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>">
57
+ <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
58
  <div class="ctc-input-cell"> <strong>
59
  <?php _e( 'Export Child Theme as Zip Archive', 'chld_thm_cfg' ); ?>
60
  </strong> </div>
68
  <?php if ( 'direct' != $this->ctc()->fs_method ): ?>
69
  <div class="ctc-input-row clearfix" id="input_row_permissions">
70
  <form id="ctc_permission_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>">
71
+ <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
72
  <div class="ctc-input-cell"> <strong>
73
  <?php _e( 'Secure Child Theme', 'chld_thm_cfg' ); ?>
74
  </strong>
83
  </div>
84
  </form>
85
  </div>
86
+ <?php endif; do_action( 'chld_thm_cfg_files_tab' ); ?>
87
  </div>
includes/forms/images.php CHANGED
@@ -4,7 +4,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
4
  ?>
5
  <div class="ctc-input-row clearfix" id="input_row_images">
6
  <form id="ctc_image_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>">
7
- <?php wp_nonce_field( 'ctc_update' ); ?>
8
  <div class="ctc-input-cell"> <strong>
9
  <?php _e( 'Child Theme Images', 'chld_thm_cfg' ); ?>
10
  </strong>
4
  ?>
5
  <div class="ctc-input-row clearfix" id="input_row_images">
6
  <form id="ctc_image_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>">
7
+ <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
8
  <div class="ctc-input-cell"> <strong>
9
  <?php _e( 'Child Theme Images', 'chld_thm_cfg' ); ?>
10
  </strong>
includes/forms/main.php CHANGED
@@ -18,40 +18,43 @@ background:#f9f9f9 url(<?php echo includes_url( 'images/xit-2x.gif' );
18
  ?>) left top no-repeat;
19
  }
20
  </style>
21
- <div class="wrap">
22
  <?php do_action( 'chld_thm_cfg_related_links' ); ?>
23
- <h2><?php echo __( 'Child Theme Configurator', 'chld_thm_cfg' ) . ' ' . __( 'version', 'chld_thm_cfg' ) . ' ' . CHLD_THM_CFG_VERSION; ?></h2>
24
  <?php
25
- if ( 'POST' == $_SERVER['REQUEST_METHOD'] && !$this->ctc()->fs ):
26
- echo $this->ctc()->fs_prompt;
27
  else: ?>
28
  <div id="ctc_error_notice">
29
  <?php $this->settings_errors(); ?>
30
  </div>
31
- <?php
32
- include ( $this->ctc()->pluginPath . 'includes/forms/tabs.php' );
33
- ?>
34
- <i id="ctc_status_preview"></i>
35
- </h2>
36
- <div class="ctc-option-panel-container">
37
  <?php
38
- include ( $this->ctc()->pluginPath . 'includes/forms/parent-child.php' );
 
 
 
 
 
 
 
 
39
  if ( $enqueueset ):
40
- include ( $this->ctc()->pluginPath . 'includes/forms/rule-value.php' );
41
- include ( $this->ctc()->pluginPath . 'includes/forms/query-selector.php' );
42
- include ( $this->ctc()->pluginPath . 'includes/forms/at-import.php' ); ?>
43
- <div id="view_child_options_panel"
44
  class="ctc-option-panel<?php echo 'view_child_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>> </div>
45
- <div id="view_parnt_options_panel"
46
  class="ctc-option-panel<?php echo 'view_parnt_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>> </div>
47
- <?php
48
  if ( '' == $hidechild ):
49
- include ( $this->ctc()->pluginPath . 'includes/forms/files.php' );
50
  endif;
51
  do_action( 'chld_thm_cfg_panels', $this->ctc(), $active_tab, $hidechild );
52
  endif; ?>
53
- </div>
54
- <?php
 
55
  endif;
56
  ?>
57
  </div>
18
  ?>) left top no-repeat;
19
  }
20
  </style>
21
+ <div class="wrap" id="ctc_main">
22
  <?php do_action( 'chld_thm_cfg_related_links' ); ?>
23
+ <h2><?php echo apply_filters( 'chld_thm_cfg_header', __( 'Child Theme Configurator', 'chld_thm_cfg' ) . ' ' . __( 'version', 'chld_thm_cfg' ) . ' ' . CHLD_THM_CFG_VERSION ); ?></h2>
24
  <?php
25
+ if ( $this->ctc()->is_post && !$this->ctc()->fs ):
26
+ echo $this->ctc()->fs_prompt;
27
  else: ?>
28
  <div id="ctc_error_notice">
29
  <?php $this->settings_errors(); ?>
30
  </div>
 
 
 
 
 
 
31
  <?php
32
+ // if flag has been set because an action is required, do not render interface
33
+ if ( !$this->ctc()->skip_form ):
34
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/tabs.php' );
35
+ ?><div style="position:relative">
36
+ <div class="ctc-option-panel-container">
37
+ <?php
38
+ $parent_child_panel = apply_filters( 'chld_thm_cfg_pc_panel',
39
+ CHLD_THM_CFG_DIR . '/includes/forms/parent-child.php' );
40
+ include ( $parent_child_panel );
41
  if ( $enqueueset ):
42
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/rule-value.php' );
43
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/query-selector.php' );
44
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/at-import.php' ); ?>
45
+ <div id="view_child_options_panel"
46
  class="ctc-option-panel<?php echo 'view_child_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>> </div>
47
+ <div id="view_parnt_options_panel"
48
  class="ctc-option-panel<?php echo 'view_parnt_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>> </div>
49
+ <?php
50
  if ( '' == $hidechild ):
51
+ include ( CHLD_THM_CFG_DIR . '/includes/forms/files.php' );
52
  endif;
53
  do_action( 'chld_thm_cfg_panels', $this->ctc(), $active_tab, $hidechild );
54
  endif; ?>
55
+ </div>
56
+ <?php do_action( 'chld_thm_cfg_sidebar' ); ?></div><?php
57
+ endif;
58
  endif;
59
  ?>
60
  </div>
includes/forms/parent-child.php CHANGED
@@ -4,64 +4,60 @@ if ( !defined( 'ABSPATH' ) ) exit;
4
  ?>
5
 
6
  <div id="parent_child_options_panel" class="ctc-option-panel<?php echo 'parent_child_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>">
7
- <form id="ctc_load_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>">
8
- <?php
9
  wp_nonce_field( 'ctc_update' );
10
- if ( has_action( 'chld_thm_cfg_controls' ) ):
11
- if ( '' == $hidechild ) do_action( 'chld_thm_cfg_controls', $this->ctc() );
12
- $themeonly = 'style="display:none"';
13
- else:
14
- $themeonly = '';
15
- endif;
16
  ?>
17
- <div class="ctc-theme-only" <?php echo 'theme' != $configtype ? $themeonly : ''; ?>>
18
- <div class="ctc-input-row clearfix" id="input_row_parnt">
19
- <div class="ctc-input-cell"> <strong>
20
- <?php _e( 'Parent Theme', 'chld_thm_cfg' ); ?>
21
- </strong> </div>
22
- <div class="ctc-input-cell">
23
- <?php $this->render_theme_menu( 'parnt', $parent ); ?>
24
- </div>
25
- </div>
26
- <div class="ctc-input-row clearfix" id="input_row_child">
27
- <div class="ctc-input-cell"> <strong>
28
- <?php _e( 'Child Theme', 'chld_thm_cfg' ); ?>
29
- </strong> </div>
30
- <div class="ctc-input-cell">
31
- <input class="ctc-radio" id="ctc_child_type_new" name="ctc_child_type" type="radio" value="new"
32
  <?php echo ( !empty( $hidechild ) ? 'checked' : '' ); ?>
33
- <?php echo $hidechild;?> />
34
- <label for="ctc_child_type_new">
35
- <?php _e( 'Create New Child Theme', 'chld_thm_cfg' ); ?>
36
- </label>
37
- </div>
38
- <div class="ctc-input-cell">
39
- <input class="ctc-radio" id="ctc_child_type_existing" name="ctc_child_type" type="radio" value="existing"
40
  <?php echo ( empty( $hidechild ) ? 'checked' : '' ); ?>
41
- <?php echo $hidechild; ?>/>
42
- &nbsp;
43
- <label for="ctc_child_type_existing" <?php echo $hidechild;?>>
44
- <?php _e( 'Use Existing Child Theme', 'chld_thm_cfg' ); ?>
45
- </label>
46
- </div>
47
- <div class="ctc-input-cell" style="clear:both"> <strong>&nbsp;</strong> </div>
48
- <div class="ctc-input-cell" >
49
- <input class="ctc_text" id="ctc_child_template" name="ctc_child_template" type="text" placeholder="<?php _e( 'Theme Slug', 'chld_thm_cfg' ); ?>" autocomplete="off"/>
50
- </div>
51
- <?php if ( '' == $hidechild ): ?>
52
- <div class="ctc-input-cell">
53
- <?php $this->render_theme_menu( 'child', $child ); ?>
54
- </div>
55
- <?php endif; ?>
56
- </div>
57
- <div class="ctc-input-row clearfix" id="input_row_child_name">
58
- <div class="ctc-input-cell"> <strong>
59
- <?php _e( 'Child Theme Name', 'chld_thm_cfg' ); ?>
60
- </strong> </div>
61
- <div class="ctc-input-cell">
62
- <input class="ctc_text" id="ctc_child_name" name="ctc_child_name" type="text"
63
- value="<?php echo esc_attr( $css->get_prop( 'child_name' ) ); ?>" placeholder="<?php _e( 'Theme Name', 'chld_thm_cfg' ); ?>" autocomplete="off" />
64
- </div>
65
  </div>
66
  </div>
67
  <div class="ctc-input-row clearfix">
@@ -82,123 +78,118 @@ if ( !defined( 'ABSPATH' ) ) exit;
82
  value="<?php echo esc_attr( $css->get_prop( 'version' ) ); ?>" placeholder="<?php _e( 'Version', 'chld_thm_cfg' ); ?>" autocomplete="off" />
83
  </div>
84
  </div>
85
- <div class="ctc-theme-only" <?php echo 'theme' != $configtype ? $themeonly : ''; ?>>
86
- <div class="ctc-input-row clearfix">
87
- <div class="ctc-input-cell"> <strong>
88
- <?php _e( 'Copy Parent Theme Menus, Widgets and other Options', 'chld_thm_cfg' ); ?>
89
- </strong> </div>
90
- <div class="ctc-input-cell">
91
- <input class="ctc_checkbox" id="ctc_parent_mods" name="ctc_parent_mods" type="checkbox"
92
- value="1" />
93
- </div>
94
- <div class="ctc-input-cell"> <strong>
95
- <?php _e( 'NOTE:', 'chld_thm_cfg' ); ?>
96
- </strong>
97
- <?php _e( 'This will overwrite child theme options you may have already set.', 'chld_thm_cfg' ); ?>
98
- </div>
99
- </div>
100
- <?php if ( '' == $hidechild ): ?>
101
- <div class="ctc-input-row clearfix">
102
- <div class="ctc-input-cell"> <strong>
103
- <?php _e( 'Backup current stylesheet', 'chld_thm_cfg' ); ?>
104
- </strong> </div>
105
- <div class="ctc-input-cell">
106
- <input class="ctc_checkbox" id="ctc_backup" name="ctc_backup" type="checkbox"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  value="1" />
108
- </div>
109
- <div class="ctc-input-cell"> <strong>
110
- <?php _e( 'NOTE:', 'chld_thm_cfg' ); ?>
111
- </strong>
112
- <?php _e( 'This creates a copy of the current stylesheet before applying changes. You can remove old backup files using the Files tab.', 'chld_thm_cfg' ); ?>
113
- </div>
114
- </div>
115
- <?php
116
- endif;
117
- $parent_handling = ( isset( $css->enqueue ) ? $css->enqueue : ( $mustimport ? 'import' : 'enqueue' ) );
118
- ?>
119
- <div class="ctc-input-row clearfix">
120
- <div class="ctc-input-cell"> <strong>
121
- <?php _e( 'Parent stylesheet handling:', 'chld_thm_cfg' ); ?>
122
- </strong> </div>
123
- <div class="ctc-input-cell">
124
- <label>
125
- <input class="ctc_radio" id="ctc_parent_enqueue_enqueue" name="ctc_parent_enqueue" type="radio"
126
- value="enqueue" <?php checked( 'enqueue', $parent_handling ); ?>/>
127
- <?php _e( '&lt;link&gt; (default)', 'chld_thm_cfg' ); ?>
128
- </label>
129
- <br/>
130
- <label>
131
- <input class="ctc_radio" id="ctc_parent_enqueue_import" name="ctc_parent_enqueue" type="radio"
132
- value="import" <?php checked( 'import', $parent_handling ); ?>/>
133
- <?php _e( '@import', 'chld_thm_cfg' ); ?>
134
- </label>
135
- <br/>
136
- <label>
137
- <input class="ctc_radio" id="ctc_parent_enqueue_none" name="ctc_parent_enqueue" type="radio"
138
- value="none" <?php checked( 'none', $parent_handling ); ?>/>
139
- <?php _e( 'none (handled by theme)', 'chld_thm_cfg' ); ?>
140
- </label>
141
- </div>
142
- <div class="ctc-input-cell"> <strong>
143
- <?php _e( 'NOTE:', 'chld_thm_cfg' ); ?>
144
- <?php if ( $mustimport ) _e( 'This theme does not currently enqueue the stylesheet and must use the @import option to render correctly.', 'chld_thm_cfg' ); ?>
145
- </strong>
146
- <?php _e( "Select @import for older themes that do not enqueue the stylesheet. Select 'none' if core styles are automatically loaded for child themes. Select '&lt;link&gt;' if unsure.", 'chld_thm_cfg' ); ?>
147
- </div>
148
  </div>
149
- <?php if ( '' == $hidechild ): ?>
150
- <div class="ctc-input-row clearfix">
151
- <div class="ctc-input-cell ctc-section-toggle" id="ctc_revert_css"> <strong>
152
- <?php _e( 'Reset/Restore from backup:', 'chld_thm_cfg' ); ?>
153
- </strong> </div>
154
- <div class="ctc-input-cell-wide ctc-section-toggle-content" id="ctc_revert_css_content">
155
- <label>
156
- <input class="ctc_checkbox" id="ctc_revert_none" name="ctc_revert" type="radio"
 
 
 
 
 
157
  value="" checked="" />
158
- <?php _e( 'Leave unchanged', 'chld_thm_cfg' );?>
159
- </label>
160
- <br/>
161
- <label>
162
- <input class="ctc_checkbox" id="ctc_revert_all" name="ctc_revert" type="radio"
163
  value="all" />
164
- <?php _e( 'Reset all', 'chld_thm_cfg' );?>
165
- </label>
166
- <br/>
167
- <?php
168
- foreach ( $this->ctc()->get_files( $child, 'backup' ) as $backup => $label ): ?>
169
  <label>
170
  <input class="ctc_checkbox" id="ctc_revert_<?php echo $backup; ?>" name="ctc_revert" type="radio"
171
  value="<?php echo $backup; ?>" />
172
  <?php echo __( 'Restore backup from', 'chld_thm_cfg' ) . ' ' . $label; ?></label>
173
  <br/>
174
- <?php
175
- endforeach;
176
- ?>
177
- </div>
178
- </div>
179
- <?php endif;
180
- $stylesheets = $this->ctc()->get_files( $parent, 'stylesheet' );
181
- if ( count( $stylesheets ) ):?>
182
- <div class="ctc-input-row clearfix">
183
- <div class="ctc-input-cell ctc-section-toggle" id="ctc_additional_css_files"> <strong>
184
- <?php _e( 'Parse additional stylesheets:', 'chld_thm_cfg' ); ?>
185
- </strong> </div>
186
- <div class="ctc-input-cell-wide ctc-section-toggle-content" id="ctc_additional_css_files_content">
187
- <p style="margin-top:0">
188
- <?php _e( 'Stylesheets that are currently being loaded by the parent theme are automatically selected below (except for Bootstrap stylesheets which add a large amount data to the configuration). To further reduce overhead, select only the additional stylesheets you wish to customize.', 'chld_thm_cfg' ); ?>
189
- </p>
190
- <?php
191
- foreach ( $stylesheets as $stylesheet ): ?>
192
- <div class="ctc-input-cell">
193
- <label>
194
- <input class="ctc_checkbox" name="ctc_additional_css[]" type="checkbox"
195
- value="<?php echo $stylesheet; ?>" />
196
- <?php echo $stylesheet; ?></label>
197
- </div>
198
  <?php endforeach; ?>
199
- </div>
200
  </div>
201
- <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  </div>
203
  <div class="ctc-input-row clearfix">
204
  <div class="ctc-input-cell"> <strong>&nbsp;</strong> </div>
4
  ?>
5
 
6
  <div id="parent_child_options_panel" class="ctc-option-panel<?php echo 'parent_child_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>">
7
+ <form id="ctc_load_form" method="post" action=""><!-- ?page=<?php echo CHLD_THM_CFG_MENU; ?>"-->
8
+ <?php
9
  wp_nonce_field( 'ctc_update' );
10
+ //if ( '' == $hidechild )
11
+ do_action( 'chld_thm_cfg_controls', $this->ctc() );
12
+ $disabled = $this->ctc()->is_legacy() && !$this->ctc()->is_theme() ? ' disabled ' : '';
13
+ $disabledclass = $this->ctc()->is_legacy() && !$this->ctc()->is_theme() ? ' ctc-disabled ' : '';
 
 
14
  ?>
15
+ <div class="ctc-input-row clearfix ctc-themeonly-container<?php echo $disabledclass; ?>" id="input_row_parnt">
16
+ <div class="ctc-input-cell"> <strong>
17
+ <?php _e( 'Parent Theme', 'chld_thm_cfg' ); ?>
18
+ </strong> </div>
19
+ <div class="ctc-input-cell">
20
+ <?php $this->render_theme_menu( 'parnt', $this->ctc()->get_current_parent() ); ?>
21
+ </div>
22
+ </div>
23
+ <div class="ctc-input-row clearfix ctc-themeonly-container<?php echo $disabledclass; ?>" id="input_row_child">
24
+ <div class="ctc-input-cell"> <strong>
25
+ <?php _e( 'Child Theme', 'chld_thm_cfg' ); ?>
26
+ </strong> </div>
27
+ <div class="ctc-input-cell">
28
+ <input class="ctc-radio ctc-themeonly" id="ctc_child_type_new" name="ctc_child_type" type="radio" value="new"
 
29
  <?php echo ( !empty( $hidechild ) ? 'checked' : '' ); ?>
30
+ <?php echo $hidechild . ' ' . $disabled;?> />
31
+ <label for="ctc_child_type_new">
32
+ <?php _e( 'Create New Child Theme', 'chld_thm_cfg' ); ?>
33
+ </label>
34
+ </div>
35
+ <div class="ctc-input-cell">
36
+ <input class="ctc-radio ctc-themeonly" id="ctc_child_type_existing" name="ctc_child_type" type="radio" value="existing"
37
  <?php echo ( empty( $hidechild ) ? 'checked' : '' ); ?>
38
+ <?php echo $hidechild . ' ' . $disabled; ?> />
39
+ &nbsp;
40
+ <label for="ctc_child_type_existing" <?php echo $hidechild;?>>
41
+ <?php _e( 'Use Existing Child Theme', 'chld_thm_cfg' ); ?>
42
+ </label>
43
+ </div>
44
+ <div class="ctc-input-cell" style="clear:both"> <strong>&nbsp;</strong> </div>
45
+ <div class="ctc-input-cell" >
46
+ <input class="ctc_text ctc-themeonly" id="ctc_child_template" name="ctc_child_template" type="text" placeholder="<?php _e( 'Theme Slug', 'chld_thm_cfg' ); ?>" autocomplete="off" <?php echo $disabled; ?> />
47
+ </div>
48
+ <?php if ( '' == $hidechild ): ?>
49
+ <div class="ctc-input-cell">
50
+ <?php $this->render_theme_menu( 'child', $child ); ?>
51
+ </div>
52
+ <?php endif; ?>
53
+ </div>
54
+ <div class="ctc-input-row clearfix ctc-themeonly-container<?php echo $disabledclass; ?>" id="input_row_child_name">
55
+ <div class="ctc-input-cell"> <strong>
56
+ <?php _e( 'Child Theme Name', 'chld_thm_cfg' ); ?>
57
+ </strong> </div>
58
+ <div class="ctc-input-cell">
59
+ <input class="ctc_text ctc-themeonly" id="ctc_child_name" name="ctc_child_name" type="text"
60
+ value="<?php echo esc_attr( $css->get_prop( 'child_name' ) ); ?>" placeholder="<?php _e( 'Theme Name', 'chld_thm_cfg' ); ?>" autocomplete="off" <?php echo $disabled; ?> />
 
61
  </div>
62
  </div>
63
  <div class="ctc-input-row clearfix">
78
  value="<?php echo esc_attr( $css->get_prop( 'version' ) ); ?>" placeholder="<?php _e( 'Version', 'chld_thm_cfg' ); ?>" autocomplete="off" />
79
  </div>
80
  </div>
81
+ <div class="ctc-input-row clearfix ctc-themeonly-container<?php echo $disabledclass; ?>">
82
+ <div class="ctc-input-cell"> <strong>
83
+ <?php _e( 'Copy Parent Theme Menus, Widgets and other Options', 'chld_thm_cfg' ); ?>
84
+ </strong> </div>
85
+ <div class="ctc-input-cell">
86
+ <input class="ctc_checkbox ctc-themeonly" id="ctc_parent_mods" name="ctc_parent_mods" type="checkbox"
87
+ value="1" <?php echo $disabled; ?> />
88
+ </div>
89
+ <div class="ctc-input-cell"> <strong>
90
+ <?php _e( 'NOTE:', 'chld_thm_cfg' ); ?>
91
+ </strong>
92
+ <?php _e( 'This will overwrite child theme options you may have already set.', 'chld_thm_cfg' ); ?>
93
+ </div>
94
+ </div>
95
+ <?php $parent_handling = ( isset( $css->enqueue ) ? $css->enqueue : ( $mustimport ? 'import' : 'enqueue' ) ); ?>
96
+ <div class="ctc-input-row clearfix ctc-themeonly-container<?php echo $disabledclass; ?>">
97
+ <div class="ctc-input-cell"> <strong>
98
+ <?php _e( 'Parent stylesheet handling:', 'chld_thm_cfg' ); ?>
99
+ </strong> </div>
100
+ <div class="ctc-input-cell">
101
+ <label>
102
+ <input class="ctc_radio ctc-themeonly" id="ctc_parent_enqueue_enqueue" name="ctc_parent_enqueue" type="radio"
103
+ value="enqueue" <?php checked( 'enqueue', $parent_handling ); ?> <?php echo $disabled; ?> />
104
+ <?php _e( '&lt;link&gt; (default)', 'chld_thm_cfg' ); ?>
105
+ </label>
106
+ <br/>
107
+ <label>
108
+ <input class="ctc_radio ctc-themeonly" id="ctc_parent_enqueue_import" name="ctc_parent_enqueue" type="radio"
109
+ value="import" <?php checked( 'import', $parent_handling ); ?> <?php echo $disabled; ?> />
110
+ <?php _e( '@import', 'chld_thm_cfg' ); ?>
111
+ </label>
112
+ <br/>
113
+ <label>
114
+ <input class="ctc_radio ctc-themeonly" id="ctc_parent_enqueue_none" name="ctc_parent_enqueue" type="radio"
115
+ value="none" <?php checked( 'none', $parent_handling ); ?> <?php echo $disabled; ?> />
116
+ <?php _e( 'none (handled by theme)', 'chld_thm_cfg' ); ?>
117
+ </label>
118
+ </div>
119
+ <div class="ctc-input-cell"> <strong>
120
+ <?php _e( 'NOTE:', 'chld_thm_cfg' ); ?>
121
+ <?php if ( $mustimport ) _e( 'This theme does not currently enqueue the stylesheet and must use the @import option to render correctly.', 'chld_thm_cfg' ); ?>
122
+ </strong>
123
+ <?php _e( "Select @import for older themes that do not enqueue the stylesheet. Select 'none' if core styles are automatically loaded for child themes. Select '&lt;link&gt;' if unsure.", 'chld_thm_cfg' ); ?>
124
+ </div>
125
+ </div>
126
+ <?php if ( '' == $hidechild ): ?>
127
+ <div class="ctc-input-row clearfix">
128
+ <div class="ctc-input-cell"> <strong>
129
+ <?php _e( 'Backup current stylesheet', 'chld_thm_cfg' ); ?>
130
+ </strong> </div>
131
+ <div class="ctc-input-cell">
132
+ <input class="ctc_checkbox" id="ctc_backup" name="ctc_backup" type="checkbox"
133
  value="1" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  </div>
135
+ <div class="ctc-input-cell"> <strong>
136
+ <?php _e( 'NOTE:', 'chld_thm_cfg' ); ?>
137
+ </strong>
138
+ <?php _e( 'This creates a copy of the current stylesheet before applying changes. You can remove old backup files using the Files tab.', 'chld_thm_cfg' ); ?>
139
+ </div>
140
+ </div>
141
+ <div class="ctc-input-row clearfix">
142
+ <div class="ctc-input-cell ctc-section-toggle" id="ctc_revert_css"> <strong>
143
+ <?php _e( 'Reset/Restore from backup:', 'chld_thm_cfg' ); ?>
144
+ </strong> </div>
145
+ <div class="ctc-input-cell-wide ctc-section-toggle-content" id="ctc_revert_css_content">
146
+ <label>
147
+ <input class="ctc_checkbox" id="ctc_revert_none" name="ctc_revert" type="radio"
148
  value="" checked="" />
149
+ <?php _e( 'Leave unchanged', 'chld_thm_cfg' );?>
150
+ </label>
151
+ <br/>
152
+ <label>
153
+ <input class="ctc_checkbox" id="ctc_revert_all" name="ctc_revert" type="radio"
154
  value="all" />
155
+ <?php _e( 'Reset all', 'chld_thm_cfg' );?>
156
+ </label>
157
+ <div id="ctc_backup_files"><?php
158
+ foreach ( $this->ctc()->get_files( $css->get_prop( 'child' ), 'backup' ) as $backup => $label ): ?>
 
159
  <label>
160
  <input class="ctc_checkbox" id="ctc_revert_<?php echo $backup; ?>" name="ctc_revert" type="radio"
161
  value="<?php echo $backup; ?>" />
162
  <?php echo __( 'Restore backup from', 'chld_thm_cfg' ) . ' ' . $label; ?></label>
163
  <br/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  <?php endforeach; ?>
165
+ </div>
166
  </div>
167
+ </div>
168
+ <?php endif; ?>
169
+ <div class="ctc-input-row clearfix" id="ctc_stylesheet_files">
170
+ <?php
171
+ // Additional stylesheets
172
+ $stylesheets = $this->ctc()->get_files( $this->ctc()->get_current_parent(), 'stylesheet' );
173
+ if ( count( $stylesheets ) ):?>
174
+ <div class="ctc-input-cell ctc-section-toggle" id="ctc_additional_css_files"> <strong>
175
+ <?php _e( 'Parse additional stylesheets:', 'chld_thm_cfg' ); ?>
176
+ </strong> </div>
177
+ <div class="ctc-input-cell-wide ctc-section-toggle-content" id="ctc_additional_css_files_content">
178
+ <p style="margin-top:0">
179
+ <?php _e( 'Stylesheets that are currently being loaded by the parent theme are automatically selected below (except for Bootstrap stylesheets which add a large amount data to the configuration). To further reduce overhead, select only the additional stylesheets you wish to customize.', 'chld_thm_cfg' ); ?>
180
+ </p>
181
+ <ul>
182
+ <?php foreach ( $stylesheets as $stylesheet ): ?>
183
+ <li>
184
+ <label>
185
+ <input class="ctc_checkbox" name="ctc_additional_css[]" type="checkbox"
186
+ value="<?php echo $stylesheet; ?>" />
187
+ <?php echo esc_attr( $stylesheet ); ?></label>
188
+ </li>
189
+ <?php endforeach; ?>
190
+ </ul>
191
+ </div><?php
192
+ endif; ?>
193
  </div>
194
  <div class="ctc-input-row clearfix">
195
  <div class="ctc-input-cell"> <strong>&nbsp;</strong> </div>
includes/forms/query-selector.php CHANGED
@@ -1,11 +1,13 @@
1
  <?php
2
  if ( !defined( 'ABSPATH' ) ) exit;
3
  // Query/Selector Panel
 
4
  ?>
5
 
6
  <div id="query_selector_options_panel"
7
  class="ctc-option-panel<?php echo 'query_selector_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>>
8
- <form id="ctc_query_selector_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>">
 
9
  <div class="ctc-input-row clearfix" id="input_row_query">
10
  <div class="ctc-input-cell"> <strong>
11
  <?php _e( 'Query', 'chld_thm_cfg' ); ?>
@@ -40,7 +42,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
40
  <div id="ctc_status_sel_val"></div>
41
  <div class="ctc-input-cell ctc-button-cell" id="ctc_save_query_selector_cell">
42
  <input type="button" class="button button-primary ctc-save-input" id="ctc_save_query_selector"
43
- name="ctc_save_query_selector" value="<?php _e( 'Save', 'chld_thm_cfg' ); ?>" disabled />
44
  <input type="hidden" id="ctc_sel_ovrd_qsid"
45
  name="ctc_sel_ovrd_qsid" value="" />
46
  </div>
@@ -73,11 +75,13 @@ if ( !defined( 'ABSPATH' ) ) exit;
73
  </strong> </div>
74
  <div class="ctc-input-cell" id="ctc_child_load_order_container">&nbsp;</div>
75
  </div>
76
- </div>
77
  <div class="ctc-selector-row clearfix" id="ctc_new_selector_row">
78
  <div class="ctc-input-cell">
79
  <div class="ctc-textarea-button-cell" id="ctc_save_query_selector_cell">
80
- <input type="button" class="button ctc-save-input" id="ctc_save_new_selectors"
 
 
81
  name="ctc_save_new_selectors" value="<?php _e( 'Save', 'chld_thm_cfg' ); ?>" disabled />
82
  </div>
83
  <strong>
1
  <?php
2
  if ( !defined( 'ABSPATH' ) ) exit;
3
  // Query/Selector Panel
4
+ $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU );
5
  ?>
6
 
7
  <div id="query_selector_options_panel"
8
  class="ctc-option-panel<?php echo 'query_selector_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>>
9
+ <form id="ctc_query_selector_form" method="post" action="?page=<?php echo $ctcpage; ?>">
10
+ <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
11
  <div class="ctc-input-row clearfix" id="input_row_query">
12
  <div class="ctc-input-cell"> <strong>
13
  <?php _e( 'Query', 'chld_thm_cfg' ); ?>
42
  <div id="ctc_status_sel_val"></div>
43
  <div class="ctc-input-cell ctc-button-cell" id="ctc_save_query_selector_cell">
44
  <input type="button" class="button button-primary ctc-save-input" id="ctc_save_query_selector"
45
+ name="ctc_save_query_selector" value="<?php _e( 'Save Child Values', 'chld_thm_cfg' ); ?>" disabled />
46
  <input type="hidden" id="ctc_sel_ovrd_qsid"
47
  name="ctc_sel_ovrd_qsid" value="" />
48
  </div>
75
  </strong> </div>
76
  <div class="ctc-input-cell" id="ctc_child_load_order_container">&nbsp;</div>
77
  </div>
78
+ </div></form><form id="ctc_raw_css_form" method="post" action="?page=<?php echo $ctcpage; ?>">
79
  <div class="ctc-selector-row clearfix" id="ctc_new_selector_row">
80
  <div class="ctc-input-cell">
81
  <div class="ctc-textarea-button-cell" id="ctc_save_query_selector_cell">
82
+ <input type="button" class="button" id="ctc_copy_selector"
83
+ name="ctc_copy_selector" value="<?php _e( 'Copy Selector', 'chld_thm_cfg' ); ?>" /> &nbsp;
84
+ <input type="button" class="button button-primary ctc-save-input" id="ctc_save_new_selectors"
85
  name="ctc_save_new_selectors" value="<?php _e( 'Save', 'chld_thm_cfg' ); ?>" disabled />
86
  </div>
87
  <strong>
includes/forms/related.php CHANGED
@@ -1 +1 @@
1
- <span style="float:right;margin-left:2em;margin-top:-6px;text-shadow:1px 2px 0 #fff"><strong><?php _e( 'New user?','chld_thm_cfg' ); ?> <span style="color:#F1823B"><?php _e( 'Click help', 'chld_thm_cfg' ); ?></span></strong> <i class="dashicons dashicons-arrow-right-alt" style="color:#F1823B"></i></span><a href="http://www.lilaeamedia.com/plugins/child-theme-plugin-styles/" target="_blank" title="<?php _e( 'Get CTC for Plugins and other tools', 'chld_thm_cfg' ); ?>" style="float:right"><img src="<?php echo $this->ctc()->pluginURL; ?>/css/lilaea-logo.png" height="36" width="145" alt="<?php _e( 'Lilaea Media - Responsive Tools for a Mobile World', 'chld_thm_cfg' ); ?>" /></a>
1
+ <span style="float:right;margin-left:2em;margin-top:-6px;text-shadow:1px 2px 0 #fff"><strong><?php _e( 'New user?','chld_thm_cfg' ); ?> <span style="color:#F1823B"><?php _e( 'Click help', 'chld_thm_cfg' ); ?></span></strong> <i class="dashicons dashicons-arrow-right-alt" style="color:#F1823B"></i></span><a href="http://www.lilaeamedia.com/child-theme-configurator-pro/" target="_blank" title="<?php _e( 'Get CTC Pro and other tools', 'chld_thm_cfg' ); ?>" style="float:right"><img src="<?php echo CHLD_THM_CFG_URL; ?>css/lilaea-logo.png" height="36" width="145" alt="<?php _e( 'Lilaea Media - Responsive Tools for a Mobile World', 'chld_thm_cfg' ); ?>" /></a>
includes/forms/rule-value.php CHANGED
@@ -1,12 +1,13 @@
1
  <?php
2
  if ( !defined( 'ABSPATH' ) ) exit;
3
  // Rule/Value Panel
 
4
  ?>
5
 
6
  <div id="rule_value_options_panel"
7
  class="ctc-option-panel<?php echo 'rule_value_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>>
8
- <form id="ctc_rule_value_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>">
9
- <?php wp_nonce_field( 'ctc_update' ); ?>
10
  <div class="ctc-input-row clearfix" id="ctc_input_row_rule_menu">
11
  <div class="ctc-input-cell"> <strong>
12
  <?php _e( 'Rule', 'chld_thm_cfg' ); ?>
1
  <?php
2
  if ( !defined( 'ABSPATH' ) ) exit;
3
  // Rule/Value Panel
4
+ $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU );
5
  ?>
6
 
7
  <div id="rule_value_options_panel"
8
  class="ctc-option-panel<?php echo 'rule_value_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>>
9
+ <form id="ctc_rule_value_form" method="post" action="?page=<?php echo $ctcpage; ?>">
10
+ <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
11
  <div class="ctc-input-row clearfix" id="ctc_input_row_rule_menu">
12
  <div class="ctc-input-cell"> <strong>
13
  <?php _e( 'Rule', 'chld_thm_cfg' ); ?>
includes/forms/tabs.php CHANGED
@@ -5,7 +5,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
5
  $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'parent_child_options';
6
  ?>
7
 
8
- <h2 class="nav-tab-wrapper">
9
  <a id="parent_child_options" href=""
10
  class="nav-tab<?php echo 'parent_child_options' == $active_tab ? ' nav-tab-active' : ''; ?>">
11
  <?php _e( 'Parent/Child', 'chld_thm_cfg' ); ?>
@@ -36,5 +36,7 @@ $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'parent_child_options';
36
  </a>
37
  <?php
38
  endif;
39
- endif;
40
- do_action( 'chld_thm_cfg_tabs', $this->ctc(), $active_tab, $hidechild ); ?>
 
 
5
  $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'parent_child_options';
6
  ?>
7
 
8
+ <h2 class="nav-tab-wrapper clearfix">
9
  <a id="parent_child_options" href=""
10
  class="nav-tab<?php echo 'parent_child_options' == $active_tab ? ' nav-tab-active' : ''; ?>">
11
  <?php _e( 'Parent/Child', 'chld_thm_cfg' ); ?>
36
  </a>
37
  <?php
38
  endif;
39
+ do_action( 'chld_thm_cfg_tabs', $this->ctc(), $active_tab, $hidechild );
40
+ endif; ?>
41
+ <i id="ctc_status_preview"></i>
42
+ </h2>
includes/forms/themepreview.php CHANGED
@@ -6,13 +6,13 @@ if ( !defined( 'ABSPATH' ) ) exit;
6
  ?>
7
 
8
  <div id="ctc_theme_option_<?php echo $slug; ?>" class="clearfix ctc-theme-option">
9
- <div class="ctc-theme-option-left"><img src="<?php echo $theme['screenshot']; ?>" class="ctc-theme-option-image"/></div>
10
  <div class="ctc-theme-option-right">
11
- <h3 class="theme-name"><?php echo $theme['Name']; ?></h3>
12
- <?php _e( 'Version: ', 'chld_thm_cfg' ); echo esc_attr( $theme['Version'] );?>
13
  <br/>
14
- <?php _e( 'By: ', 'chld_thm_cfg' ); echo esc_attr( $theme['Author'] );?>
15
- <br/><?php if ( !is_multisite() || $theme['allowed'] ): ?>
16
  <a href="<?php echo admin_url( '/customize.php?theme=' . $slug );?>" title="<?php _e( 'Preview', 'chld_thm_cfg' );
17
  if ( is_multisite() ) _e(' in default Site', 'chld_thm_cfg'); ?>" class="ctc-live-preview" target="_blank">
18
  <?php _e( 'Live Preview', 'chld_thm_cfg' ); ?>
6
  ?>
7
 
8
  <div id="ctc_theme_option_<?php echo $slug; ?>" class="clearfix ctc-theme-option">
9
+ <div class="ctc-theme-option-left"><img src="<?php echo $theme[ 'screenshot' ]; ?>" class="ctc-theme-option-image"/></div>
10
  <div class="ctc-theme-option-right">
11
+ <h3 class="theme-name"><?php echo $theme[ 'Name' ]; ?></h3>
12
+ <?php _e( 'Version: ', 'chld_thm_cfg' ); echo esc_attr( $theme[ 'Version' ] );?>
13
  <br/>
14
+ <?php _e( 'By: ', 'chld_thm_cfg' ); echo esc_attr( $theme[ 'Author' ] );?>
15
+ <br/><?php if ( !is_multisite() || $theme[ 'allowed' ] ): ?>
16
  <a href="<?php echo admin_url( '/customize.php?theme=' . $slug );?>" title="<?php _e( 'Preview', 'chld_thm_cfg' );
17
  if ( is_multisite() ) _e(' in default Site', 'chld_thm_cfg'); ?>" class="ctc-live-preview" target="_blank">
18
  <?php _e( 'Live Preview', 'chld_thm_cfg' ); ?>
includes/help/help_en_US.php CHANGED
@@ -93,7 +93,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
93
  <li>Click "Live Preview" below the new Child Theme to see it in action.</li>
94
  <li>When you are ready to take the Child Theme live, click "Activate."</li>
95
  </ol>
96
- <p><strong>MULTISITE USERS:</strong> You must Network Enable your child theme before you can use Live Preview. Go to "Themes" in the Network Admin.</p>
97
  <!-- END tab -->
98
  <!-- BEGIN tab -->
99
  <h3 id="ctc_permissions">File Permissions</h3>
@@ -207,12 +207,12 @@ The plugin only loads the bulk of the code in the admin when you are using the t
207
  <!-- BEGIN sidebar -->
208
  <h4>Our plugins will not nag you for donations...</h4>
209
  <span style="font-size:smaller">...but we LOVE referrals.</span><br/><a href="http://wordpress.org/support/view/plugin-reviews/child-theme-configurator?rate=5#postform">Give Us 5 Stars</a>
210
- <h4>Not just for themes ... but plugins, too!</h4>
211
- <p style="font-size:smaller">Easily modify styles for any WordPress Plugin installed on your website. The Child Theme Configurator Plugin Extension scans your plugins and allows you to create custom stylesheets in your Child Theme. <a href="http://www.lilaeamedia.com/plugins/child-theme-plugin-styles" title="Child Theme Configurator Extension">Learn more</a></p>
 
212
  <ul>
213
  <li><a href="http://www.lilaeamedia.com/about/contact/">Contact us</a></li>
214
  <li><a href="http://www.lilaeamedia.com/plugins/child-theme-configurator">Plugin Website</a></li>
215
- <li><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8QE5YJ8WE96AJ">Donate</a></li>
216
  <li><a href="http://codex.wordpress.org/Child_Themes">WordPress Codex</a></li>
217
  <li><a href="http://wordpress.stackexchange.com/">WordPress Answers</a></li>
218
  </ul>
93
  <li>Click "Live Preview" below the new Child Theme to see it in action.</li>
94
  <li>When you are ready to take the Child Theme live, click "Activate."</li>
95
  </ol>
96
+ <p><strong>MULTISITE USERS:</strong> You must Network Enable your child theme before you can use Live Preview. Go to 'Themes' in the Network Admin.</p>
97
  <!-- END tab -->
98
  <!-- BEGIN tab -->
99
  <h3 id="ctc_permissions">File Permissions</h3>
207
  <!-- BEGIN sidebar -->
208
  <h4>Our plugins will not nag you for donations...</h4>
209
  <span style="font-size:smaller">...but we LOVE referrals.</span><br/><a href="http://wordpress.org/support/view/plugin-reviews/child-theme-configurator?rate=5#postform">Give Us 5 Stars</a>
210
+ <h4>Introducing CTC Pro</h4>
211
+ <a href="http://www.lilaeamedia.com/child-theme-configurator-pro/" title="<?php _e( 'Learn more about CTC Pro', 'chld_thm_cfg' ); ?>"><img src="<?php echo CHLD_THM_CFG_URL . 'css/pro-banner.jpg'; ?>" width="150" height="48" /></a>
212
+ <p style="font-size:smaller">Designed by WordPress developers who use it every day, CTC Pro adds plugin stylesheets and other features to make design work quicker and easier. This is a free upgrade for users that purchased the Plugins Extension. <a href="http://www.lilaeamedia.com/plugins/child-theme-configurator-pro" title="Child Theme Configurator Pro">Learn more</a></p>
213
  <ul>
214
  <li><a href="http://www.lilaeamedia.com/about/contact/">Contact us</a></li>
215
  <li><a href="http://www.lilaeamedia.com/plugins/child-theme-configurator">Plugin Website</a></li>
 
216
  <li><a href="http://codex.wordpress.org/Child_Themes">WordPress Codex</a></li>
217
  <li><a href="http://wordpress.stackexchange.com/">WordPress Answers</a></li>
218
  </ul>
js/chld-thm-cfg.js CHANGED
@@ -2,43 +2,118 @@
2
  * Script: chld-thm-cfg.js
3
  * Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
4
  * Description: Handles jQuery, AJAX and other UI
5
- * Version: 1.6.3
6
  * Author: Lilaea Media
7
  * Author URI: http://www.lilaeamedia.com/
8
  * License: GPLv2
9
  * Copyright (C) 2014-2015 Lilaea Media
10
  */
11
- jQuery(document).ready(function($){
12
 
13
  // initialize functions
14
- function esc_quot(str){
15
- return ctc_is_empty(str) ? str : str.toString().replace(quot_regex, '&quot;');
16
  }
17
- function ctc_setup_iris(obj) {
18
- //console.log('setting up iris ' + ('undefined' != typeof $(obj).attr('id') ? $(obj).attr('id') : ''));
19
- $(obj).iris({
20
- change: function(e,ui) {
21
- //console.log('change event '
22
- //+ ('undefined' != typeof $(this).attr('id') ? $(this).attr('id') : '')
23
- //+ ' ' + ui.color.toString());
24
- $(obj).data('color', ui.color.toString());
25
- ctc_coalesce_inputs(obj);
26
- }
27
- });
28
- }
29
- function from_ascii(str) {
30
- var ascii = parseInt(str),
31
- chr = String.fromCharCode(ascii)
32
  return chr;
33
  }
34
- function to_ascii(str) {
35
- var ascii = str.charCodeAt(0);
 
36
  return ascii;
37
  }
38
- function ctc_coalesce_inputs(obj) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  var regex = /^(ctc_(ovrd|\d+)_(parent|child)_([0-9a-z\-]+)_(\d+))(_\w+)?$/,
40
- $container = $(obj).parents('.ctc-selector-row, .ctc-parent-row').first(),
41
- $swatch = $container.find('.ctc-swatch').first(),
42
  cssrules = { 'parent': {}, 'child': {} },
43
  gradient = {
44
  'parent': {
@@ -55,37 +130,37 @@ jQuery(document).ready(function($){
55
  has_gradient = { 'child': false, 'parent': false },
56
  postdata = {};
57
  // set up objects for all neighboring inputs
58
- $container.find('.ctc-parent-value, .ctc-child-value').each(function(){
59
- var inputid = $(this).attr('id'),
60
- inputparts = inputid.toString().match(regex),
61
  inputseq = inputparts[2],
62
  inputtheme = inputparts[3],
63
- inputrule = ('undefined' == typeof inputparts[4] ? '' : inputparts[4]),
64
  qsid = inputparts[5],
65
- rulepart = ('undefined' == typeof inputparts[6] ? '' : inputparts[6]),
66
- value = ('parent' == inputtheme ? $(this).text().replace(/!$/,'') : $(this).val()),
67
  important = 'ctc_' + inputseq + '_child_' + inputrule + '_i_' + qsid,
68
  parts, subparts;
69
- if (false === ctc_is_empty($(this).data('color'))) {
70
- value = $(this).data('color');
71
- $(this).data('color', null);
72
  }
73
- //console.log('id: ' + inputid + ' value: ' + value);
74
- if ('child' == inputtheme) {
75
  postdata[inputid] = value;
76
- postdata[important] = ($('#' + important).is(':checked')) ? 1 : 0;
77
  }
78
- /*if ('' === value) {
79
- $('#'+important).prop('checked', false);
80
  return;
81
  }*/
82
- if ('' != value) {
83
  // handle specific inputs
84
- if (false === ctc_is_empty(rulepart)) {
85
- //console.log('rulepart: ' + rulepart + ' value: ' + value);
86
- switch(rulepart) {
87
  case '_border_width':
88
- cssrules[inputtheme][inputrule + '-width'] = value;
89
  break;
90
  case '_border_style':
91
  cssrules[inputtheme][inputrule + '-style'] = value;
@@ -94,7 +169,7 @@ jQuery(document).ready(function($){
94
  cssrules[inputtheme][inputrule + '-color'] = value;
95
  break;
96
  case '_background_url':
97
- cssrules[inputtheme]['background-image'] = ctc_image_url(inputtheme, value);
98
  break;
99
  case '_background_color':
100
  cssrules[inputtheme]['background-color'] = obj.value;
@@ -114,18 +189,18 @@ jQuery(document).ready(function($){
114
  }
115
  } else {
116
  // handle borders
117
- if (parts = inputrule.toString().match(/^border(\-(top|right|bottom|left))?$/) && !value.match(/none/)) {
118
- subparts = value.toString().split(/ +/);
119
  cssrules[inputtheme][inputrule + '-width'] = 'undefined' == typeof subparts[0] ? '' : subparts[0];
120
  cssrules[inputtheme][inputrule + '-style'] = 'undefined' == typeof subparts[1] ? '' : subparts[1];
121
  cssrules[inputtheme][inputrule + '-color'] = 'undefined' == typeof subparts[2] ? '' : subparts[2];
122
  // handle background images
123
- } else if ( 'background-image' == inputrule && !value.match(/none/) ) {
124
- if (value.toString().match(/url\(/) ) {
125
- cssrules[inputtheme]['background-image'] = ctc_image_url(inputtheme, value);
126
  } else {
127
- subparts = value.toString().split(/ +/);
128
- if (subparts.length > 2) {
129
  gradient[inputtheme].origin = 'undefined' == typeof subparts[0] ? 'top' : subparts[0];
130
  gradient[inputtheme].start = 'undefined' == typeof subparts[1] ? 'transparent' : subparts[1];
131
  gradient[inputtheme].end = 'undefined' == typeof subparts[2] ? 'transparent' : subparts[2];
@@ -134,288 +209,393 @@ jQuery(document).ready(function($){
134
  cssrules[inputtheme]['background-image'] = value;
135
  }
136
  }
137
- } else if ('seq' != inputrule) {
138
  cssrules[inputtheme][inputrule] = value;
139
  }
140
  }
141
  }
142
- });
143
  // update swatch
144
- if ('undefined' != typeof $swatch && false === ctc_is_empty($swatch.attr('id'))) {
145
- $swatch.removeAttr('style');
146
- if (has_gradient.parent) { $swatch.ctcgrad(gradient.parent.origin, [gradient.parent.start, gradient.parent.end]); }
147
- $swatch.css(cssrules.parent);
148
- if (!($swatch.attr('id').toString().match(/parent/))){
149
- if (has_gradient.child) { $swatch.ctcgrad(gradient.child.origin, [gradient.child.start, gradient.child.end]); }
150
- $swatch.css(cssrules.child);
151
  }
152
- $swatch.css({'z-index':-1});
153
  }
154
  return postdata;
155
  }
156
- function ctc_update_cache(response) {
157
- var currQuery, currSelId, currRuleId;
158
- $(response).each(function(){
159
- switch (this.obj) {
160
- case 'imports':
161
- ctcAjax.imports = this.data;
162
- break;
163
-
164
- case 'rule_val':
165
- ctcAjax.rule_val[this.key] = this.data;
166
- currRuleId = this.key;
167
- break;
168
-
169
- case 'val_qry':
170
- ctcAjax.val_qry[this.key] = this.data;
171
- break;
172
-
173
- case 'rule':
174
- ctcAjax.rule = this.data;
175
- break;
176
-
177
- case 'sel_ndx':
178
- if (ctc_is_empty(this.key)) {
179
- ctcAjax.sel_ndx = this.data;
180
- } else if ('qsid' == this.key) {
181
- if (ctc_is_empty(ctcAjax.sel_ndx[this.data.query])) {
182
- ctcAjax.sel_ndx[this.data.query] = {}
183
- }
184
- ctcAjax.sel_ndx[this.data.query][this.data.selector] = this.data.qsid;
185
- } else {
186
- ctcAjax.sel_ndx[this.key] = this.data;
187
- currQuery = this.key;
188
- }
189
- break;
190
-
191
- case 'sel_val':
192
- ctcAjax.sel_val[this.key] = this.data;
193
- currSelId = this.key;
194
- break;
195
- case 'rewrite':
196
- rewrite_id = this.key;
197
- rewrite_sel = this.data;
198
- break;
199
  }
200
- });
 
 
 
 
201
  }
202
- function ctc_image_url(theme, value) {
203
- var parts = value.toString().match(/url\(['" ]*(.+?)['" ]*\)/),
204
- path = ctc_is_empty(parts) ? null : parts[1],
205
- url = ctcAjax.theme_uri + '/' + ('parent' == theme ? ctcAjax.parnt : ctcAjax.child) + '/',
 
206
  image_url;
207
- if (!path) {
208
  return false;
209
- } else if (path.toString().match(/^(data:|https?:|\/)/)) {
210
  image_url = value;
211
  } else {
212
  image_url = 'url(' + url + path + ')';
213
  }
214
  return image_url;
215
  }
216
- function ctc_is_empty(obj) {
217
- // first bail when definitely empty or undefined (true) NOTE: zero is not empty
218
- if ('undefined' == typeof obj || false === obj || null === obj || '' === obj) { return true; }
219
- // then, if this is bool, string or number it must not be empty (false)
220
- if (true === obj || "string" === typeof obj || "number" === typeof obj) { return false; }
221
- // thanks to Abena Kuttin for Win safe version
222
  // check for object type to be safe
223
- if ("object" === typeof obj) {
224
  // Use a standard for in loop
225
- for (var x in obj) {
226
  // A for in will iterate over members on the prototype
227
  // chain as well, but Object.getOwnPropertyNames returns
228
  // only those directly on the object, so use hasOwnProperty.
229
- if (obj.hasOwnProperty(x)) {
230
- // any value means not empty (false)
231
  return false;
232
  }
233
  }
234
- // no properties, so return empty (true)
235
  return true;
236
  }
237
  // this must be an unsupported datatype, so return not empty
238
  return false;
239
 
240
  }
241
- function ctc_load_queries() {
242
- var arr = [];
243
- if (1 === loading.sel_ndx) return arr;
244
- if (0 === loading.sel_ndx) { // {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  // retrieve from server
246
- loading.sel_ndx = 1;
247
- ctc_query_css('sel_ndx', null, ctc_setup_query_menu);
248
- return arr;
 
 
249
  }
250
- if (false === ctc_is_empty(ctcAjax.sel_ndx)) {
251
- $.each(ctcAjax.sel_ndx, function(key, value) {
 
 
252
  var obj = { label: key, value: key };
253
- arr.push(obj);
254
- });
255
  }
256
- return arr;
 
257
  }
258
- function ctc_load_selectors(query) {
259
- var arr = [];
260
- if (1 === loading.sel_ndx) {
261
- return arr;
262
- }
263
- if (0 === loading.sel_ndx) {
 
264
  // retrieve from server
265
- loading.sel_ndx = 1;
266
- ctc_query_css('sel_ndx', query, ctc_setup_selector_menu);
267
- return arr;
268
  }
269
- if (false === ctc_is_empty(ctcAjax.sel_ndx[query])) {
270
- $.each(ctcAjax.sel_ndx[query], function(key, value) {
 
 
271
  var obj = { label: key, value: value };
272
- arr.push(obj);
273
- });
 
 
 
 
 
 
 
274
  }
275
- return arr;
276
  }
277
 
278
- function ctc_load_rules() {
279
- var arr = [];
280
- if (1 === loading.rule) return arr;
281
- if (0 === loading.rule) {
282
- loading.rule = 1;
283
- ctc_query_css('rule', null, ctc_setup_rule_menu);
284
- return arr;
 
 
 
285
  }
286
- if (false === ctc_is_empty(ctcAjax.rule)) {
287
- $.each(ctcAjax.rule, function(key, value) {
288
- var obj = { label: value.replace(/\d+/g, from_ascii), value: key };
289
- arr.push(obj);
290
- });
 
 
291
  }
292
- return arr.sort(function (a, b) {
293
- if (a.label > b.label)
294
  return 1;
295
- if (a.label < b.label)
296
  return -1;
297
  return 0;
298
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  }
300
- function ctc_render_child_rule_input(qsid, rule, seq) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  var html = '',
302
- value = (ctc_is_empty(ctcAjax.sel_val[qsid])
303
- || ctc_is_empty(ctcAjax.sel_val[qsid].value)
304
- || ctc_is_empty(ctcAjax.sel_val[qsid].value[rule]) ? '' : ctcAjax.sel_val[qsid].value[rule]),
305
- oldRuleObj = ctc_decode_value(rule, ('undefined' == typeof value ? '' : value['parnt'])),
306
- oldRuleFlag = (false === ctc_is_empty(value['i_parnt']) && value['i_parnt']) ?
307
  ctcAjax.important_label : '',
308
- newRuleObj = ctc_decode_value(rule, ('undefined' == typeof value ? '' : value['child'])),
309
- newRuleFlag = (false === ctc_is_empty(value['i_child']) && value['i_child']) ? 1 : 0,
310
  impid = 'ctc_' + seq + '_child_' + rule + '_i_' + qsid;
311
- if (false === ctc_is_empty(ctcAjax.sel_val[qsid])) {
312
- html += '<div class="ctc-' + ('ovrd' == seq ? 'input' : 'selector' ) + '-row clearfix">' + lf;
313
- html += '<div class="ctc-input-cell">' + ('ovrd' == seq ? rule.replace(/\d+/g, from_ascii) : ctcAjax.sel_val[qsid].selector
314
  + '<br/><a href="#" class="ctc-selector-edit" id="ctc_selector_edit_' + qsid + '" >' + ctcAjax.edit_txt + '</a> '
315
- + (ctc_is_empty(oldRuleObj.orig) ? ctcAjax.child_only_txt : ''))
316
  + '</div>' + lf;
317
- if ('ovrd' == seq) {
318
  html += '<div class="ctc-parent-value ctc-input-cell" id="ctc_' + seq + '_parent_' + rule + '_' + qsid + '">'
319
- + (ctc_is_empty(oldRuleObj.orig) ? '[no value]' : oldRuleObj.orig + oldRuleFlag) + '</div>' + lf;
320
  }
321
  html += '<div class="ctc-input-cell">' + lf;
322
- if (false === ctc_is_empty(oldRuleObj.names)){
323
- $.each(oldRuleObj.names, function(ndx, newname) {
324
- newname = (ctc_is_empty(newname) ? '' : newname);
325
  html += '<div class="ctc-child-input-cell">' + lf;
326
  var id = 'ctc_' + seq + '_child_' + rule + '_' + qsid + newname,
327
  newval;
328
- if (false === (newval = newRuleObj.values.shift()) ){
329
  newval = '';
330
  }
331
 
332
- html += (ctc_is_empty(newname) ? '' : ctcAjax.field_labels[newname] + ':<br/>')
333
  + '<input type="text" id="' + id + '" name="' + id + '" class="ctc-child-value'
334
- + ((newname + rule).toString().match(/color/) ? ' color-picker' : '')
335
- + ((newname).toString().match(/url/) ? ' ctc-input-wide' : '')
336
- + '" value="' + esc_quot(newval) + '" />' + lf;
337
  html += '</div>' + lf;
338
- });
339
  html += '<label for="' + impid + '"><input type="checkbox" id="' + impid + '" name="' + impid + '" value="1" '
340
- + (1 === newRuleFlag ? 'checked' : '') + ' />' + ctcAjax.important_label + '</label>' + lf;
341
  }
342
  html += '</div>' + lf;
343
- html += ('ovrd' == seq ? '' : '<div class="ctc-swatch ctc-specific" id="ctc_child_' + rule + '_' + qsid + '_swatch">'
344
  + ctcAjax.swatch_txt + '</div>' + lf
345
  + '<div class="ctc-child-input-cell ctc-button-cell" id="ctc_save_' + rule + '_' + qsid + '_cell">' + lf
346
  + '<input type="button" class="button ctc-save-input" id="ctc_save_' + rule + '_' + qsid
347
- + '" name="ctc_save_' + rule + '_' + qsid + '" value="Save" /></div>' + lf);
348
  html += '</div><!-- end input row -->' + lf;
349
  }
350
  return html;
351
  }
352
- function ctc_render_selector_inputs(qsid) {
353
- if (1 === loading.sel_val) {
354
- return false;
355
- }
356
- if (0 == loading.sel_val) {
357
- loading.sel_val = 1;
358
- ctc_query_css('sel_val', qsid, ctc_render_selector_inputs);
359
- return false;
360
- }
361
- var id, html, val;
362
- if (ctc_is_empty(ctcAjax.sel_val[qsid])) {
363
- $('#ctc_sel_ovrd_rule_inputs').html('')
364
- } else {
365
- if (ctc_is_empty(ctcAjax.sel_val[qsid].seq)) {
366
- $('#ctc_child_load_order_container').html('');
367
  } else {
368
  id = 'ctc_ovrd_child_seq_' + qsid;
369
- val = parseInt(ctcAjax.sel_val[qsid].seq);
370
  html = '<input type="text" id="' + id + '" name="' + id + '" class="ctc-child-value" value="' + val + '" />';
371
- $('#ctc_child_load_order_container').html(html);
372
  }
373
- if (ctc_is_empty(ctcAjax.sel_val[qsid].value)){
374
- $('#ctc_sel_ovrd_rule_inputs').html('');
375
  } else {
376
  html = '';
377
- $.each(ctcAjax.sel_val[qsid].value, function(rule, value) {
378
- html += ctc_render_child_rule_input(qsid, rule, 'ovrd');
379
- });
380
- $('#ctc_sel_ovrd_rule_inputs').html(html).find('.color-picker').each(function() {
381
- ctc_setup_iris(this);
382
- });
383
- ctc_coalesce_inputs('#ctc_child_all_0_swatch');
 
 
 
384
  }
 
 
 
 
 
 
385
  }
 
386
  }
387
- function ctc_render_css_preview(theme) {
388
- if (1 === loading.preview) {
 
389
  return false;
390
  }
391
- if (0 == loading.preview) {
392
- loading.preview = 1;
393
  var theme;
394
- if (!(theme = $(this).attr('id').toString().match(/(child|parnt)/)[1])) {
395
  theme = 'child';
396
  }
397
- ctc_set_notice('')
398
- ctc_query_css('preview', theme, ctc_render_css_preview);
399
  return false;
400
  }
401
- if (2 == loading.preview) {
402
- $('#view_'+theme+'_options_panel').text(ctcAjax.previewResponse);
403
- loading.preview = 0;
404
- }
405
  }
406
- function ctc_render_rule_value_inputs(ruleid) {
407
- if (1 === loading.rule_val) return false;
 
408
 
409
- if (0 == loading.rule_val) {
410
- loading.rule_val = 1;
411
- ctc_query_css('rule_val', ruleid, ctc_render_rule_value_inputs);
412
  return false;
413
  }
414
  var rule = ctcAjax.rule[ruleid],
415
  html = '<div class="ctc-input-row clearfix" id="ctc_rule_row_' + rule + '">' + lf;
416
- if (false === ctc_is_empty(ctcAjax.rule_val[ruleid])){
417
- $.each(ctcAjax.rule_val[ruleid], function(valid, value) {
418
- var oldRuleObj = ctc_decode_value(rule, value);
419
  html += '<div class="ctc-parent-row clearfix" id="ctc_rule_row_' + rule + '_' + valid + '">' + lf;
420
  html += '<div class="ctc-input-cell ctc-parent-value" id="ctc_' + valid + '_parent_' + rule + '_' + valid + '">'
421
  + oldRuleObj.orig + '</div>' + lf;
@@ -431,154 +611,405 @@ jQuery(document).ready(function($){
431
  html += '<div id="ctc_status_val_qry_' + valid + '"></div>' + lf;
432
  html += '<div id="ctc_selector_' + rule + '_' + valid + '_rows"></div>' + lf;
433
  html += '</div></div></div>' + lf;
434
- });
435
  html += '</div>' + lf;
436
  }
437
- $('#ctc_rule_value_inputs').html(html).find('.ctc-swatch').each(function() {
438
- ctc_coalesce_inputs(this);
439
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
  }
441
- function ctc_render_selector_value_inputs(valid) {
442
- if (1 == loading.val_qry) return false;
 
443
  var params,
444
  page_ruleid,
445
- rule = $('#ctc_rule_menu_selected').text().replace(/[^\w\-]/g, to_ascii),
446
  selector,
447
  html = '';
448
- if (0 === loading.val_qry) {
449
- loading.val_qry = 1;
450
  params = { 'rule': rule };
451
- ctc_query_css('val_qry', valid, ctc_render_selector_value_inputs, params);
452
  return false;
453
  }
454
- if (false === ctc_is_empty(ctcAjax.val_qry[valid])){
455
- $.each(ctcAjax.val_qry[valid], function(rule, queries) {
456
  page_rule = rule;
457
- $.each(queries, function(query, selectors) {
458
  html += '<h4 class="ctc-query-heading">' + query + '</h4>' + lf;
459
- if (false === ctc_is_empty(selectors)){
460
- $.each(selectors, function(qsid, data) {
461
  ctcAjax.sel_val[qsid] = data;
462
- html += ctc_render_child_rule_input(qsid, rule, valid);
463
- });
464
  }
465
- });
466
- });
467
  }
468
  selector = '#ctc_selector_' + rule + '_' + valid + '_rows';
469
- $(selector).html(html).find('.color-picker').each(function() {
470
- ctc_setup_iris(this);
471
- });
472
- $(selector).find('.ctc-swatch').each(function() {
473
- ctc_coalesce_inputs(this);
474
- });
475
 
476
  }
477
- function ctc_query_css(obj, key, callback, params) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
478
  var postdata = { 'ctc_query_obj' : obj, 'ctc_query_key': key },
479
- status_sel = '#ctc_status_' + obj + ('val_qry' == obj ? '_' + key : '');
480
 
481
- if ('object' === typeof params) {
482
- $.each(params, function(key, val){
483
  postdata['ctc_query_' + key] = val;
484
- });
485
  }
486
- $('.ctc-status-icon').remove();
487
- $(status_sel).append('<span class="ctc-status-icon spinner"></span>');
488
- $('.spinner').show();
489
  // add wp ajax action to array
490
- postdata['action'] = 'ctc_query';
491
- postdata['_wpnonce'] = $('#_wpnonce').val();
 
 
 
492
  // ajax post input data
 
 
493
  $.post(
494
  // get ajax url from localized object
495
  ctcAjax.ajaxurl,
496
  //Data
497
  postdata,
498
  //on success function
499
- function(response){
500
- //console.log(response);
501
  // hide spinner
502
- loading[obj] = 2;
503
- $('.ctc-status-icon').removeClass('spinner');
504
  // show check mark
505
- if (ctc_is_empty(response)) {
506
- $('.ctc-status-icon').addClass('failure');
507
- if ('preview' == obj) {
508
  ctcAjax.previewResponse = ctcAjax.css_fail_txt;
509
- callback(key);
510
  }
511
  } else {
512
- $('.ctc-status-icon').addClass('success');
513
- if ('preview' == obj) {
514
- ctcAjax.previewResponse = response.shift().data;
515
- } else {
 
 
 
 
516
  // update data objects
517
- ctc_update_cache(response);
518
- }
519
- if ('function' === typeof callback) {
520
- callback(key);
 
521
  }
522
- return false;
523
  }
524
- },'json'
525
- ).fail(function(){
526
  // hide spinner
527
- $('.ctc-status-icon').removeClass('spinner');
528
  // show check mark
529
- $('.ctc-status-icon').addClass('failure');
530
- if ('preview' == obj) {
531
  ctcAjax.previewResponse = ctcAjax.css_fail_txt;
532
- loading[obj] = 2;
533
- callback(key);
534
  } else {
535
- loading[obj] = 0;
536
  }
537
 
538
- });
539
  return false;
540
  }
541
- function ctc_save(obj) {
 
 
 
 
542
  var postdata = {},
543
  $selector, $query, $imports, $rule,
544
- id = $(obj).attr('id'), newsel;
545
- if (ctc_is_empty(saveEvents[id])) {
546
- saveEvents[id] = 0;
547
- }
548
- saveEvents[id]++;
549
  // disable the button until ajax returns
550
- $(obj).prop('disabled', true);
551
  // clear previous success/fail icons
552
- $('.ctc-status-icon').remove();
553
  // show spinner
554
- $(obj).parent('.ctc-textarea-button-cell, .ctc-button-cell').append('<span class="ctc-status-icon spinner"></span>');
555
- $('.spinner').show();
556
- if (($selector = $('#ctc_new_selectors')) && 'ctc_save_new_selectors' == $(obj).attr('id')) {
 
 
557
  postdata['ctc_new_selectors'] = $selector.val();
558
- if ($query = $('#ctc_sel_ovrd_query_selected')) {
559
  postdata['ctc_sel_ovrd_query'] = $query.text();
560
  }
561
- } else if (($imports = $('#ctc_child_imports')) && 'ctc_save_imports' == $(obj).attr('id')) {
562
  postdata['ctc_child_imports'] = $imports.val();
563
  } else {
564
  // coalesce inputs
565
- postdata = ctc_coalesce_inputs(obj);
566
  }
 
567
  // add rename selector value if it exists
568
- $('#ctc_sel_ovrd_selector_selected').find('#ctc_rewrite_selector').each(function(){
569
- newsel = $('#ctc_rewrite_selector').val(),
570
- origsel = $('#ctc_rewrite_selector_orig').val();
571
- if (ctc_is_empty(newsel) || !newsel.toString().match(/\w/)) {
572
  newsel = origsel;
573
  } else {
574
  postdata['ctc_rewrite_selector'] = newsel;
575
  }
576
- $('.ctc-rewrite-toggle').text(ctcAjax.rename_txt);
577
- $('#ctc_sel_ovrd_selector_selected').html(newsel);
578
- });
579
  // add wp ajax action to array
580
- postdata['action'] = 'ctc_update';
581
- postdata['_wpnonce'] = $('#_wpnonce').val();
 
 
 
 
582
  // ajax post input data
583
  $.post(
584
  // get ajax url from localized object
@@ -586,468 +1017,323 @@ jQuery(document).ready(function($){
586
  //Data
587
  postdata,
588
  //on success function
589
- function(response){
590
- //console.log(response);
591
  // release button
592
- $(obj).prop('disabled', false);
593
  // hide spinner
594
- $('.ctc-status-icon').removeClass('spinner');
595
  // show check mark
596
- if (ctc_is_empty(response)) {
597
- $('.ctc-status-icon').addClass('failure');
598
  } else {
599
- $('.ctc-status-icon').addClass('success');
600
- $('#ctc_new_selectors').val('');
 
 
 
 
 
 
601
  // update data objects
602
- ctc_update_cache(response);
603
- ctc_setup_menus();
604
- if (false === ctc_is_empty(rewrite_id)) {
605
- ctc_set_selector(rewrite_id, rewrite_sel);
 
 
 
 
 
606
  rewrite_id = rewrite_sel = null;
607
  }
 
 
 
 
608
  }
609
  return false;
610
  }, 'json'
611
- ).fail(function(){
612
  // release button
613
- $(obj).prop('disabled', false);
614
  // hide spinner
615
- $('.ctc-status-icon').removeClass('spinner');
616
  // show check mark
617
- $('.ctc-status-icon').addClass('failure');
618
- });
619
  return false;
620
  }
621
- function ctc_decode_value(rule, value) {
622
- value = ('undefined' == typeof value ? '' : value);
623
- var obj = { 'orig': value };
624
- if (rule.toString().match(/^border(\-(top|right|bottom|left))?$/)) {
625
- var params = value.toString().split(/ +/);
626
- obj['names'] = [
627
- '_border_width',
628
- '_border_style',
629
- '_border_color',
630
- ];
631
- obj['values'] = [
632
- ('undefined' == typeof params[0] ? '' : params[0]),
633
- ('undefined' == typeof params[1] ? '' : params[1]),
634
- ('undefined' == typeof params[2] ? '' : params[2])
635
- ];
636
- } else if (rule.toString().match(/^background\-image/)) {
637
- obj['names'] = [
638
- '_background_url',
639
- '_background_origin',
640
- '_background_color1',
641
- '_background_color2'
642
- ];
643
- obj['values'] = ['','','',''];
644
- if (false === (ctc_is_empty(value)) && !(value.toString().match(/(url|none)/))) {
645
- var params = value.toString().split(/:/);
646
- obj['values'][1] = ('undefined' == typeof params[0] ? '' : params[0]);
647
- obj['values'][2] = ('undefined' == typeof params[1] ? '' : params[1]);
648
- obj['values'][3] = ('undefined' == typeof params[3] ? '' : params[3]);
649
- obj['orig'] = [ obj['values'][1], obj['values'][2], obj['values'][3] ].join(' '); // display "origin color1 color2"
650
- } else {
651
- obj['values'][0] = value;
652
- }
653
- } else {
654
- obj['names'] = [''];
655
- obj['values'] = [ value ];
656
- }
657
- return obj;
658
- }
659
- function ctc_set_query(value) {
660
- currentQuery = value;
661
- $('#ctc_sel_ovrd_query').val('');
662
- $('#ctc_sel_ovrd_query_selected').text(value);
663
- $('#ctc_sel_ovrd_selector').val('');
664
- $('#ctc_sel_ovrd_selector_selected').html('&nbsp;');
665
- $('#ctc_sel_ovrd_rule_inputs').html('');
666
- ctc_setup_selector_menu(value);
667
- ctc_coalesce_inputs('#ctc_child_all_0_swatch');
668
- $('#ctc_new_selector_row').show();
669
- }
670
- function ctc_set_selector(value,label) {
671
- $('#ctc_sel_ovrd_selector').val('');
672
- $('#ctc_sel_ovrd_selector_selected').text(label);
673
- $('#ctc_sel_ovrd_qsid').val(value);
674
- currentSel = value;
675
- if (1 != loading.sel_val) loading.sel_val = 0;
676
- ctc_render_selector_inputs(value);
677
- $('.ctc-rewrite-toggle').text(ctcAjax.rename_txt);
678
- $('#ctc_sel_ovrd_new_rule, #ctc_sel_ovrd_rule_header,#ctc_sel_ovrd_rule_inputs_container,#ctc_sel_ovrd_rule_inputs,.ctc-rewrite-toggle').show();
679
- }
680
- function ctc_set_rule(value,label) {
681
- $('#ctc_rule_menu').val('');
682
- $('#ctc_rule_menu_selected').text(label);
683
- if (1 != loading.rule_val) loading.rule_val = 0;
684
- ctc_render_rule_value_inputs(value);
685
- $('.ctc-rewrite-toggle').text(ctcAjax.rename_txt);
686
- $('#ctc_rule_value_inputs,#ctc_input_row_rule_header').show();
687
- }
688
- function ctc_setup_query_menu() {
689
- ctc_queries = ctc_load_queries();
690
- $('#ctc_sel_ovrd_query').autocomplete({
691
- source: ctc_queries,
692
- minLength: 0,
693
- selectFirst: true,
694
- autoFocus: true,
695
- select: function(e, ui) {
696
- ctc_set_query(ui.item.value);
697
- return false;
698
- },
699
- focus: function(e) {
700
- e.preventDefault();
701
- }
702
- });
703
- }
704
- function ctc_setup_selector_menu(query) {
705
- ctc_selectors = ctc_load_selectors(query);
706
- $('#ctc_sel_ovrd_selector').autocomplete({
707
- source: ctc_selectors,
708
- selectFirst: true,
709
- autoFocus: true,
710
- select: function(e, ui) {
711
- ctc_set_selector(ui.item.value, ui.item.label);
712
- return false;
713
- },
714
- focus: function(e) { e.preventDefault(); }
715
- });
716
- }
717
- function ctc_setup_rule_menu() {
718
- ctc_rules = ctc_load_rules();
719
- $('#ctc_rule_menu').autocomplete({
720
- source: ctc_rules,
721
- //minLength: 0,
722
- selectFirst: true,
723
- autoFocus: true,
724
- select: function(e, ui) {
725
- ctc_set_rule(ui.item.value, ui.item.label);
726
- return false;
727
- },
728
- focus: function(e) { e.preventDefault(); }
729
- });
730
- }
731
- function ctc_filtered_rules(request, response) {
732
- var arr = [],
733
- noval = (ctc_is_empty(ctcAjax.sel_val[currentSel])) || (ctc_is_empty(ctcAjax.sel_val[currentSel].value));
734
- if (ctc_is_empty(ctc_rules)) {
735
- ctc_rules = ctc_load_rules();
736
- }
737
- $.each(ctc_rules, function(key, val){
738
- var skip = false,
739
- matcher = new RegExp( $.ui.autocomplete.escapeRegex( request.term ), "i" );
740
- if (matcher.test( val.label )) {
741
- if (false === noval) {
742
- // skip rule if in current selector array
743
- $.each(ctcAjax.sel_val[currentSel].value, function(rule, value) {
744
- if (val.label == rule.replace(/\d+/g, from_ascii)) {
745
- skip = true;
746
- return false;
747
- }
748
- });
749
- if (skip) {
750
- return;
751
  }
752
- }
753
- // add rule
754
- arr.push(val);
755
- }
756
- });
757
- response(arr);
758
- }
759
- function ctc_setup_new_rule_menu() {
760
- $('#ctc_new_rule_menu').autocomplete({
761
- source: ctc_filtered_rules,
762
- //minLength: 0,
763
- selectFirst: true,
764
- autoFocus: true,
765
- select: function(e, ui) {
766
- e.preventDefault();
767
- var n = $(ctc_render_child_rule_input(currentSel, ui.item.label.replace(/[^\w\-]/g, to_ascii), 'ovrd'));
768
- $('#ctc_sel_ovrd_rule_inputs').append(n);
769
- $('#ctc_new_rule_menu').val('');
770
- if (ctc_is_empty(ctcAjax.sel_val[currentSel].value)) {
771
- ctcAjax.sel_val[currentSel]['value'] = {};
772
- }
773
- ctcAjax.sel_val[currentSel].value[ui.item.label] = {'child': ''};
774
- n.find('input[type="text"]').each(function(ndx, el){
775
- if ($(el).hasClass('color-picker'))
776
- ctc_setup_iris(el);
777
- $(el).focus();
778
- });
779
- return false;
780
- },
781
- focus: function(e) { e.preventDefault(); }
782
- });
783
- }
784
- function ctc_setup_menus() {
785
- ctc_setup_query_menu();
786
- ctc_setup_selector_menu(currentQuery);
787
- ctc_setup_rule_menu();
788
- ctc_setup_new_rule_menu();
789
- }
790
- function ctc_theme_exists(testslug, testtype) {
791
- var exists = false;
792
- $.each(ctcAjax.themes, function(type, theme){
793
- $.each(theme, function(slug, data){
794
- if (slug == testslug && ('parnt' == type || 'new' == testtype)) {
795
- exists = true;
796
- return false;
797
- }
798
- });
799
- if (exists) return false;
800
- });
801
- return exists;
802
- }
803
- function autogen_slugs() {
804
- var parent = $('#ctc_theme_parnt').val(),
805
- slug = slugbase = parent + '-child',
806
- name = ctcAjax.themes.parnt[parent].Name + ' Child',
807
- suffix = '',
808
- padded = '',
809
- pad = '00';
810
- while (ctc_theme_exists(slug, 'new')) {
811
- suffix = ('' == suffix ? 2 : suffix + 1);
812
- padded = pad.substring(0, pad.length - suffix.toString().length) + suffix.toString();
813
- slug = slugbase + padded;
814
- }
815
- testslug = slug;
816
- testname = name + (padded.length ? ' ' + padded : '');
817
- }
818
- function ctc_set_notice(noticearr) {
819
- var errorHtml = '';
820
- if (false === ctc_is_empty(noticearr)) {
821
- $.each(noticearr, function(type, list){
822
- errorHtml += '<div class="' + type + '"><ul>' + lf;
823
- $(list).each(function(ndx, el){
824
- errorHtml += '<li>' + el.toString() + '</li>' + lf;
825
- });
826
- errorHtml += '</ul></div>';
827
- });
828
- }
829
- $('#ctc_error_notice').html(errorHtml);
830
- }
831
- function ctc_validate() {
832
- var regex = /[^\w\-]/,
833
- newslug = $('#ctc_child_template').val().toString().replace(regex).toLowerCase(),
834
- slug = $('#ctc_theme_child').val().toString().replace(regex).toLowerCase(),
835
- type = $('input[name=ctc_child_type]:checked').val(),
836
- errors = [];
837
- if ('new' == type) slug = newslug;
838
- if (ctc_theme_exists(slug, type)) {
839
- errors.push(ctcAjax.theme_exists_txt.toString().replace(/%s/, slug));
840
- }
841
- if ('' === slug) {
842
- errors.push(ctcAjax.inval_theme_txt);
843
- }
844
- if ('' === $('#ctc_child_name').val()) {
845
- errors.push(ctcAjax.inval_name_txt);
846
- }
847
- if (errors.length) {
848
- ctc_set_notice({'error': errors});
849
- return false;
850
- }
851
- return true;
852
- }
853
- function ctc_set_parent_menu(obj) {
854
- $('#ctc_theme_parent').parents('.ctc-input-row').first().append('<span class="ctc-status-icon spinner"></span>');
855
- $('.spinner').show();
856
- document.location='?page=' + ctcAjax.page + '&ctc_parent=' + obj.value;
857
- }
858
- function ctc_set_child_menu(obj) {
859
- if (false === ctc_is_empty(ctcAjax.themes.child[obj.value])) {
860
- $('#ctc_child_name').val(ctcAjax.themes.child[obj.value].Name);
861
- $('#ctc_child_author').val(ctcAjax.themes.child[obj.value].Author);
862
- $('#ctc_child_version').val(ctcAjax.themes.child[obj.value].Version);
863
- }
864
- }
865
- function fade_update_notice() {
866
- $('.updated, .error').slideUp('slow', function(){ $('.updated').remove(); });
867
- }
868
- function ctc_set_addl_css() {
869
- var template = $('#ctc_theme_parnt').val(),
870
- theme_uri = ctcAjax.theme_uri.replace(/^https?:\/\//, ''),
871
- homeurl = ctcAjax.homeurl.replace(/^https?/, ctcAjax.ssl ? 'https' : 'http'),
872
- url = homeurl + '?preview=1&p=x&template=' + template + '&stylesheet=' + template,
873
- regex = new RegExp("<link rel=[\"']stylesheet[\"'][^>]+?" + theme_uri + '/' + template + '/(.+?\\.css)[^>]+?>', 'g'),
874
- additional;
875
- if (ctc_is_empty(template)) return;
876
- $.get(url, function(data){
877
- //console.log(data);
878
- while (additional = regex.exec(data)){
879
- if ('style.css' == additional[1]) break; // bail after main stylesheet
880
- if (additional[1].match(/bootstrap/)) continue; // don't autoselect Bootstrap stylesheets
881
- ctcAjax.addl_css.push(additional[1]);
882
- $('.ctc_checkbox').each(function(ndx,el){
883
- if ($(this).val() == additional[1]) $(this).prop('checked', true);
884
- });
885
  }
886
- });
887
- }
888
- function ctc_focus_panel(id) {
889
- var panelid = id + '_panel';
890
- $('.nav-tab').removeClass('nav-tab-active');
891
- $('.ctc-option-panel').removeClass('ctc-option-panel-active');
892
- $('.ctc-selector-container').hide();
893
- $(id).addClass('nav-tab-active');
894
- $('.ctc-option-panel-container').scrollTop(0);
895
- $(panelid).addClass('ctc-option-panel-active');
896
  }
897
- function ctc_selector_edit(obj) {
898
- var qsid = $(obj).attr('id').match(/_(\d+)$/)[1],
899
- q = ctcAjax.sel_val[qsid].query,
900
- s = ctcAjax.sel_val[qsid].selector,
901
- id = '#query_selector_options';
902
- ctc_set_query(q);
903
- ctc_set_selector(qsid, s);
904
- ctc_focus_panel(id);
905
- }
906
- function ctc_selector_input_toggle(obj) {
907
- var origval;
908
- if ($('#ctc_rewrite_selector').length) {
909
- origval = $('#ctc_rewrite_selector_orig').val();
910
- $('#ctc_sel_ovrd_selector_selected').text(origval);
911
- $(obj).text(ctcAjax.rename_txt);
912
- } else {
913
- origval = $('#ctc_sel_ovrd_selector_selected').text();
914
- $('#ctc_sel_ovrd_selector_selected').html('<input id="ctc_rewrite_selector" name="ctc_rewrite_selector" type="text" value="'
915
- + esc_quot(origval) + '" autocomplete="off" /><input id="ctc_rewrite_selector_orig" name="ctc_rewrite_selector_orig" type="hidden" value="'
916
- + esc_quot(origval) + '"/>');
917
- $(obj).text(ctcAjax.cancel_txt);
918
- }
919
  }
920
  // initialize vars
921
  var lf = "\n",
922
- currentQuery = 'base',
923
- currentSel,
924
- saveEvents = {},
925
  rewrite_id,
926
  rewrite_sel,
927
- quot_regex = new RegExp('"', 'g'),
928
  testslug = '',
929
  testname = '',
930
- // ajax semaphores: 0 = reload, 1 = loading, 2 = loaded
931
- loading = {
932
- 'rule': 2,
933
- 'sel_ndx': 2,
934
- 'val_qry': 0,
935
- 'rule_val': 0,
936
- 'sel_val': 0,
937
- 'preview': 0
 
 
 
 
 
 
 
 
 
 
938
  },
939
- ctc_selectors = [],
940
- ctc_queries = [],
941
- ctc_rules = [];
 
942
  // -- end var definitions
943
 
944
- // initialize theme menus
945
  autogen_slugs();
946
- $.widget('ctc.themeMenu', $.ui.selectmenu, {
 
 
 
947
  _renderItem: function( ul, item ) {
948
  var li = $( "<li>" );
949
- $('#ctc_theme_option_' + item.value).detach().appendTo(li);
950
  return li.appendTo( ul );
951
  }
952
- });
953
- $('#ctc_theme_parnt').themeMenu({
954
  select: function( event, ui ) {
955
- ctc_set_parent_menu(ui.item);
956
  }
957
- });
958
- if ( ctc_is_empty( ctcAjax.themes.child ) ) {
959
- $('#ctc_child_name').val(testname);
960
- $('#ctc_child_template').val(testslug);
961
  } else {
962
- $('#ctc_theme_child').themeMenu({
963
  select: function( event, ui ) {
964
- ctc_set_child_menu(ui.item);
965
  }
966
- });
 
967
  }
968
-
969
  // bind event handlers
 
 
 
 
 
 
 
970
 
971
- $('.ctc-option-panel-container').on('focus', '.color-picker', function(){
972
- ctc_set_notice('')
973
- $('.color-picker').not(this).iris('hide');
974
- $(this).iris('toggle');
975
- $('.iris-picker').css({'position':'absolute', 'z-index':10});
976
- });
977
-
978
- $('.ctc-option-panel-container').on('change', '.ctc-child-value, input[type=checkbox]', function() {
979
- ctc_coalesce_inputs(this);
980
- });
981
 
982
- $('.ctc-option-panel-container').on('click', '.ctc-selector-handle', function(e) {
983
  e.preventDefault();
984
- ctc_set_notice('')
985
- var id = $(this).attr('id').toString().replace('_close', ''),
986
- valid = id.toString().match(/_(\d+)$/)[1];
987
- if ($('#' + id + '_container').is(':hidden')) {
988
- if (1 != loading.val_qry) loading.val_qry = 0;
989
- ctc_render_selector_value_inputs(valid);
990
  }
991
- $('#' + id + '_container').fadeToggle('fast');
992
- $('.ctc-selector-container').not('#' + id + '_container').fadeOut('fast');
993
- });
994
- $('.nav-tab').on('click', function(e){
995
  e.preventDefault();
996
  // clear the notice box
997
- ctc_set_notice('');
998
- $('.ctc-status-icon').remove();
999
- var id = '#' + $(this).attr('id');
1000
- ctc_focus_panel(id);
1001
- });
1002
- $('#view_child_options,#view_parnt_options').on('click', ctc_render_css_preview);
1003
- $('#ctc_load_form').on('submit', function() {
1004
- return (ctc_validate() && confirm(ctcAjax.load_txt) ) ;
1005
- });
1006
- $(document).on('click', '.ctc-save-input', function(e) {
1007
- ctc_save(this);
1008
- });
1009
- $(document).on('click', '.ctc-selector-edit', function(e) {
1010
- ctc_selector_edit(this);
1011
- });
1012
- $(document).on('click', '.ctc-rewrite-toggle', function(e) {
1013
  e.preventDefault();
1014
- ctc_selector_input_toggle(this);
1015
- });
1016
- $(document).on('click', '.ctc-section-toggle', function(e){
1017
- $(this).toggleClass('open');
1018
- var id = $(this).attr('id') + '_content';
1019
- $('#' + id).slideToggle('fast');
1020
- });
1021
- $(document).on('click', '.ctc-live-preview', function(e) {
1022
- e.stopImmediatePropagation();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1023
  e.preventDefault();
1024
- document.location = $(this).prop('href');
1025
- return false;
1026
- });
1027
- $(document).on('change', '#ctc_configtype', function(e) {
1028
- var val = $(this).val();
1029
- if (ctc_is_empty(val) || 'theme' == val) {
1030
- $('.ctc-theme-only').stop().slideDown('fast');
1031
  } else {
1032
- $('.ctc-theme-only').stop().slideUp('fast');
 
 
1033
  }
 
 
1034
  });
1035
- $('#ctc_theme_child,#ctc_theme_child-button,#ctc_child_type_existing').on('focus click', function(){
1036
- $('#ctc_child_type_existing').prop('checked', true);
1037
- $('#ctc_child_type_new').prop('checked', false);
1038
- $('#ctc_child_template').val('');
1039
- });
1040
- $('#ctc_child_type_new,#ctc_child_template').on('focus click', function(){
1041
- $('#ctc_child_type_existing').prop('checked', false);
1042
- $('#ctc_child_type_new').prop('checked', true);
1043
- $('#ctc_child_name').val(testname);
1044
- $('#ctc_child_template').val(testslug);
1045
- });
1046
- // initialize menus
1047
- ctc_setup_menus();
1048
- ctc_set_query(currentQuery);
1049
- ctc_set_addl_css();
1050
- // turn on submit buttons
1051
- $('input[type=submit],input[type=button]').prop('disabled', false);
1052
- setTimeout(fade_update_notice, 6000);
1053
- });
2
  * Script: chld-thm-cfg.js
3
  * Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
4
  * Description: Handles jQuery, AJAX and other UI
5
+ * Version: 1.6.4
6
  * Author: Lilaea Media
7
  * Author URI: http://www.lilaeamedia.com/
8
  * License: GPLv2
9
  * Copyright (C) 2014-2015 Lilaea Media
10
  */
11
+ jQuery( document ).ready( function( $ ) {
12
 
13
  // initialize functions
14
+ function esc_quot( str ) {
15
+ return is_empty( str ) ? str : str.toString().replace( quot_regex, '&quot;' );
16
  }
17
+
18
+ function from_ascii( str ) {
19
+ var ascii = parseInt( str ),
20
+ chr = String.fromCharCode( ascii )
 
 
 
 
 
 
 
 
 
 
 
21
  return chr;
22
  }
23
+
24
+ function to_ascii( str ) {
25
+ var ascii = str.charCodeAt( 0 );
26
  return ascii;
27
  }
28
+
29
+ function theme_exists( testslug, testtype ) {
30
+ var exists = false;
31
+ $.each( ctcAjax.themes, function( type, theme ) {
32
+ $.each( theme, function( slug, data ) {
33
+ if ( slug == testslug && ( 'parnt' == type || 'new' == testtype ) ) {
34
+ exists = true;
35
+ return false;
36
+ }
37
+ } );
38
+ if ( exists ) return false;
39
+ } );
40
+ return exists;
41
+ }
42
+
43
+ function validate() {
44
+ var regex = /[^\w\-]/,
45
+ newslug = $( '#ctc_child_template' ).val().toString().replace( regex ).toLowerCase(),
46
+ slug = $( '#ctc_theme_child' ).val().toString().replace( regex ).toLowerCase(),
47
+ type = $( 'input[name=ctc_child_type]:checked' ).val(),
48
+ errors = [];
49
+ if ( 'new' == type ) slug = newslug;
50
+ if ( theme_exists( slug, type ) ) {
51
+ errors.push( ctcAjax.theme_exists_txt.toString().replace( /%s/, slug ) );
52
+ }
53
+ if ( '' === slug ) {
54
+ errors.push( ctcAjax.inval_theme_txt );
55
+ }
56
+ if ( '' === $( '#ctc_child_name' ).val() ) {
57
+ errors.push( ctcAjax.inval_name_txt );
58
+ }
59
+ if ( errors.length ) {
60
+ set_notice( {'error': errors} );
61
+ return false;
62
+ }
63
+ return true;
64
+ }
65
+
66
+ function autogen_slugs() {
67
+ if ( $( '#ctc_theme_parnt' ).length ) {
68
+ var parent = $( '#ctc_theme_parnt' ).val(),
69
+ slug = slugbase = parent + '-child',
70
+ name = ctcAjax.themes.parnt[parent].Name + ' Child',
71
+ suffix = '',
72
+ padded = '',
73
+ pad = '00';
74
+ while ( theme_exists( slug, 'new' ) ) {
75
+ suffix = ( '' == suffix ? 2 : suffix + 1 );
76
+ padded = pad.substring( 0, pad.length - suffix.toString().length ) + suffix.toString();
77
+ slug = slugbase + padded;
78
+ }
79
+ testslug = slug;
80
+ testname = name + ( padded.length ? ' ' + padded : '' );
81
+ }
82
+ }
83
+
84
+ function focus_panel( id ) {
85
+ var panelid = id + '_panel';
86
+ $( '.nav-tab' ).removeClass( 'nav-tab-active' );
87
+ $( '.ctc-option-panel' ).removeClass( 'ctc-option-panel-active' );
88
+ $( '.ctc-selector-container' ).hide();
89
+ $( id ).addClass( 'nav-tab-active' );
90
+ $( '.ctc-option-panel-container' ).scrollTop( 0 );
91
+ $( panelid ).addClass( 'ctc-option-panel-active' );
92
+ }
93
+
94
+ function selector_input_toggle( obj ) {
95
+ var origval;
96
+ if ( $( '#ctc_rewrite_selector' ).length ) {
97
+ origval = $( '#ctc_rewrite_selector_orig' ).val();
98
+ $( '#ctc_sel_ovrd_selector_selected' ).text( origval );
99
+ $( obj ).text( ctcAjax.rename_txt );
100
+ } else {
101
+ origval = $( '#ctc_sel_ovrd_selector_selected' ).text();
102
+ $( '#ctc_sel_ovrd_selector_selected' ).html( '<textarea id="ctc_rewrite_selector" name="ctc_rewrite_selector" autocomplete="off"></textarea><input id="ctc_rewrite_selector_orig" name="ctc_rewrite_selector_orig" type="hidden" value="'
103
+ + esc_quot( origval ) + '"/>' );
104
+ $( '#ctc_rewrite_selector' ).val( origval );
105
+ $( obj ).text( ctcAjax.cancel_txt );
106
+ }
107
+ }
108
+
109
+ function fade_update_notice() {
110
+ $( '.updated, .error' ).slideUp( 'slow', function() { $( '.updated' ).remove(); } );
111
+ }
112
+
113
+ function coalesce_inputs( obj ) {
114
  var regex = /^(ctc_(ovrd|\d+)_(parent|child)_([0-9a-z\-]+)_(\d+))(_\w+)?$/,
115
+ container = $( obj ).parents( '.ctc-selector-row, .ctc-parent-row' ).first(),
116
+ swatch = container.find( '.ctc-swatch' ).first(),
117
  cssrules = { 'parent': {}, 'child': {} },
118
  gradient = {
119
  'parent': {
130
  has_gradient = { 'child': false, 'parent': false },
131
  postdata = {};
132
  // set up objects for all neighboring inputs
133
+ container.find( '.ctc-parent-value, .ctc-child-value' ).each( function() {
134
+ var inputid = $( this ).attr( 'id' ),
135
+ inputparts = inputid.toString().match( regex ),
136
  inputseq = inputparts[2],
137
  inputtheme = inputparts[3],
138
+ inputrule = ( 'undefined' == typeof inputparts[4] ? '' : inputparts[4] ),
139
  qsid = inputparts[5],
140
+ rulepart = ( 'undefined' == typeof inputparts[6] ? '' : inputparts[6] ),
141
+ value = ( 'parent' == inputtheme ? $( this ).text().replace( /!$/, '' ) : $( this ).val() ),
142
  important = 'ctc_' + inputseq + '_child_' + inputrule + '_i_' + qsid,
143
  parts, subparts;
144
+ if ( false === is_empty( $( this ).data( 'color' ) ) ) {
145
+ value = $( this ).data( 'color' );
146
+ $( this ).data( 'color', null );
147
  }
148
+ //console.log( 'id: ' + inputid + ' value: ' + value );
149
+ if ( 'child' == inputtheme ) {
150
  postdata[inputid] = value;
151
+ postdata[important] = ( $( '#' + important ).is( ':checked' ) ) ? 1 : 0;
152
  }
153
+ /*if ( '' === value ) {
154
+ $( '#'+important ).prop( 'checked', false );
155
  return;
156
  }*/
157
+ if ( '' != value ) {
158
  // handle specific inputs
159
+ if ( false === is_empty( rulepart ) ) {
160
+ //console.log( 'rulepart: ' + rulepart + ' value: ' + value );
161
+ switch( rulepart ) {
162
  case '_border_width':
163
+ cssrules[inputtheme][inputrule + '-width'] = ( 'none' == value ? 0 : value );
164
  break;
165
  case '_border_style':
166
  cssrules[inputtheme][inputrule + '-style'] = value;
169
  cssrules[inputtheme][inputrule + '-color'] = value;
170
  break;
171
  case '_background_url':
172
+ cssrules[inputtheme]['background-image'] = image_url( inputtheme, value );
173
  break;
174
  case '_background_color':
175
  cssrules[inputtheme]['background-color'] = obj.value;
189
  }
190
  } else {
191
  // handle borders
192
+ if ( parts = inputrule.toString().match( /^border(\-(top|right|bottom|left))?$/ ) && !value.match( /none/ ) ) {
193
+ subparts = value.toString().split( / +/ );
194
  cssrules[inputtheme][inputrule + '-width'] = 'undefined' == typeof subparts[0] ? '' : subparts[0];
195
  cssrules[inputtheme][inputrule + '-style'] = 'undefined' == typeof subparts[1] ? '' : subparts[1];
196
  cssrules[inputtheme][inputrule + '-color'] = 'undefined' == typeof subparts[2] ? '' : subparts[2];
197
  // handle background images
198
+ } else if ( 'background-image' == inputrule && !value.match( /none/ ) ) {
199
+ if ( value.toString().match( /url\(/ ) ) {
200
+ cssrules[inputtheme]['background-image'] = image_url( inputtheme, value );
201
  } else {
202
+ subparts = value.toString().split( / +/ );
203
+ if ( subparts.length > 2 ) {
204
  gradient[inputtheme].origin = 'undefined' == typeof subparts[0] ? 'top' : subparts[0];
205
  gradient[inputtheme].start = 'undefined' == typeof subparts[1] ? 'transparent' : subparts[1];
206
  gradient[inputtheme].end = 'undefined' == typeof subparts[2] ? 'transparent' : subparts[2];
209
  cssrules[inputtheme]['background-image'] = value;
210
  }
211
  }
212
+ } else if ( 'seq' != inputrule ) {
213
  cssrules[inputtheme][inputrule] = value;
214
  }
215
  }
216
  }
217
+ } );
218
  // update swatch
219
+ if ( 'undefined' != typeof swatch && false === is_empty( swatch.attr( 'id' ) ) ) {
220
+ swatch.removeAttr( 'style' );
221
+ if ( has_gradient.parent ) { swatch.ctcgrad( gradient.parent.origin, [gradient.parent.start, gradient.parent.end] ); }
222
+ swatch.css( cssrules.parent );
223
+ if ( !( swatch.attr( 'id' ).toString().match( /parent/ ) ) ) {
224
+ if ( has_gradient.child ) { swatch.ctcgrad( gradient.child.origin, [gradient.child.start, gradient.child.end] ); }
225
+ swatch.css( cssrules.child );
226
  }
227
+ swatch.css( {'z-index':-1} );
228
  }
229
  return postdata;
230
  }
231
+
232
+ function decode_value( rule, value ) {
233
+ value = ( 'undefined' == typeof value ? '' : value );
234
+ var obj = { 'orig': value };
235
+ if ( rule.toString().match( /^border(\-(top|right|bottom|left))?$/ ) ) {
236
+ var params = value.toString().split( / +/ );
237
+ obj['names'] = [
238
+ '_border_width',
239
+ '_border_style',
240
+ '_border_color',
241
+ ];
242
+ obj['values'] = [
243
+ ( 'undefined' == typeof params[0] ? '' : params[0] ),
244
+ ( 'undefined' == typeof params[1] ? '' : params[1] ),
245
+ ( 'undefined' == typeof params[2] ? '' : params[2] )
246
+ ];
247
+ } else if ( rule.toString().match( /^background\-image/ ) ) {
248
+ obj['names'] = [
249
+ '_background_url',
250
+ '_background_origin',
251
+ '_background_color1',
252
+ '_background_color2'
253
+ ];
254
+ obj['values'] = ['', '', '', ''];
255
+ if ( false === ( is_empty( value ) ) && !( value.toString().match( /(url|none)/ ) ) ) {
256
+ var params = value.toString().split( /:/ );
257
+ obj['values'][1] = ( 'undefined' == typeof params[0] ? '' : params[0] );
258
+ obj['values'][2] = ( 'undefined' == typeof params[1] ? '' : params[1] );
259
+ obj['values'][3] = ( 'undefined' == typeof params[3] ? '' : params[3] );
260
+ obj['orig'] = [ obj['values'][1], obj['values'][2], obj['values'][3] ].join( ' ' ); // display "origin color1 color2"
261
+ } else {
262
+ obj['values'][0] = value;
 
 
 
 
 
 
 
 
 
 
 
263
  }
264
+ } else {
265
+ obj['names'] = [''];
266
+ obj['values'] = [ value ];
267
+ }
268
+ return obj;
269
  }
270
+
271
+ function image_url( theme, value ) {
272
+ var parts = value.toString().match( /url\(['" ]*(.+?)['" ]*\)/ ),
273
+ path = is_empty( parts ) ? null : parts[1],
274
+ url = ctcAjax.theme_uri + '/' + ( 'parent' == theme ? ctcAjax.parnt : ctcAjax.child ) + '/',
275
  image_url;
276
+ if ( !path ) {
277
  return false;
278
+ } else if ( path.toString().match( /^(data:|https?:|\/)/ ) ) {
279
  image_url = value;
280
  } else {
281
  image_url = 'url(' + url + path + ')';
282
  }
283
  return image_url;
284
  }
285
+
286
+ function is_empty( obj ) {
287
+ // first bail when definitely empty or undefined ( true ) NOTE: numeric zero returns false !
288
+ if ( 'undefined' == typeof obj || false === obj || null === obj || '' === obj ) { return true; }
289
+ // then, if this is bool, string or number it must not be empty ( false )
290
+ if ( true === obj || "string" === typeof obj || "number" === typeof obj ) { return false; }
291
  // check for object type to be safe
292
+ if ( "object" === typeof obj ) {
293
  // Use a standard for in loop
294
+ for ( var x in obj ) {
295
  // A for in will iterate over members on the prototype
296
  // chain as well, but Object.getOwnPropertyNames returns
297
  // only those directly on the object, so use hasOwnProperty.
298
+ if ( obj.hasOwnProperty( x ) ) {
299
+ // any value means not empty ( false )
300
  return false;
301
  }
302
  }
303
+ // no properties, so return empty ( true )
304
  return true;
305
  }
306
  // this must be an unsupported datatype, so return not empty
307
  return false;
308
 
309
  }
310
+
311
+ function prune_if_empty( qsid ) {
312
+ //console.log( 'prune_if_empty' );
313
+ //console.log( semaphore );
314
+ if ( "object" === typeof ctcAjax.sel_val[qsid] && "object" === typeof ctcAjax.sel_val[qsid].value ) {
315
+ for ( var rule in ctcAjax.sel_val[qsid].value ) {
316
+ if ( ctcAjax.sel_val[qsid].value.hasOwnProperty( rule ) ) {
317
+ if ( false === is_empty( ctcAjax.sel_val[qsid].value[rule].child )
318
+ || false === is_empty( ctcAjax.sel_val[qsid].value[rule].parnt ) ) {
319
+ return qsid;
320
+ }
321
+ }
322
+ }
323
+ }
324
+ delete ctcAjax.sel_val[qsid];
325
+ return false;
326
+ }
327
+
328
+ function load_menus() {
329
+ semaphore.rld_rule = 1;
330
+ semaphore.rld_sel = 1;
331
+ load_queries();
332
+ load_rules();
333
+ }
334
+
335
+ function load_queries() {
336
+ //console.log( 'load queries' );
337
+ //console.log( semaphore );
338
+ if ( 1 === semaphore.sel_ndx ) return;
339
+ if ( 0 === semaphore.sel_ndx || 1 == semaphore.rld_sel ) { // {
340
  // retrieve from server
341
+ //console.log( ' loading queries...' );
342
+ semaphore.sel_ndx = 1;
343
+ semaphore.rld_sel = 0;
344
+ query_css( 'sel_ndx', null, load_queries );
345
+ return;
346
  }
347
+ //console.log( 'queries loaded. building menu source ...' );
348
+ cache_queries = [];
349
+ if ( false === is_empty( ctcAjax.sel_ndx ) ) {
350
+ $.each( ctcAjax.sel_ndx, function( key, value ) {
351
  var obj = { label: key, value: key };
352
+ cache_queries.push( obj );
353
+ } );
354
  }
355
+ setup_query_menu();
356
+ load_selectors();
357
  }
358
+
359
+ function load_selectors() {
360
+ //console.log( 'load selectors' );
361
+ //console.log( semaphore );
362
+ if ( 1 === semaphore.sel_ndx ) return;
363
+ if ( 0 === semaphore.sel_ndx ) {
364
+ //console.log( ' loading selectors...' );
365
  // retrieve from server
366
+ semaphore.sel_ndx = 1;
367
+ query_css( 'sel_ndx', current_query, load_selectors );
368
+ return;
369
  }
370
+ //console.log( 'selectors loaded. building menu source ...' );
371
+ cache_selectors = [];
372
+ if ( false === is_empty( ctcAjax.sel_ndx ) ) {
373
+ $.each( ctcAjax.sel_ndx[current_query], function( key, value ) {
374
  var obj = { label: key, value: value };
375
+ cache_selectors.push( obj );
376
+ } );
377
+ }
378
+ setup_selector_menu();
379
+ if ( semaphore.set_sel ) {
380
+ // selector semaphore set, set selector menu value
381
+ // this also triggers selector value refresh
382
+ semaphore.set_sel = 0;
383
+ set_selector( current_qsid, null );
384
  }
 
385
  }
386
 
387
+ function load_rules() {
388
+ //console.log( 'load rules' );
389
+ //console.log( semaphore );
390
+ if ( 1 === semaphore.rule ) return;
391
+ if ( 0 === semaphore.rule || 1 == semaphore.rld_rule ) {
392
+ //console.log( ' loading rules...' );
393
+ semaphore.rule = 1;
394
+ semaphore.rld_rule = 0;
395
+ query_css( 'rule', null, load_rules );
396
+ return;
397
  }
398
+ //console.log( 'rules loaded. building menu source ...' );
399
+ cache_rules = [];
400
+ if ( false === is_empty( ctcAjax.rule ) ) {
401
+ $.each( ctcAjax.rule, function( key, value ) {
402
+ var obj = { label: value.replace( /\d+/g, from_ascii ), value: key };
403
+ cache_rules.push( obj );
404
+ } );
405
  }
406
+ cache_rules = cache_rules.sort( function ( a, b ) {
407
+ if ( a.label > b.label )
408
  return 1;
409
+ if ( a.label < b.label )
410
  return -1;
411
  return 0;
412
+ } );
413
+ setup_rule_menu();
414
+ setup_new_rule_menu();
415
+ }
416
+
417
+ function load_selector_values( qsid ) {
418
+ //console.log( 'load_selector_values' );
419
+ //console.log( semaphore );
420
+ if ( 1 === semaphore.sel_val ) return false;
421
+ if ( is_empty( ctcAjax.sel_val[ qsid ] ) ) {
422
+ if ( 0 == semaphore.sel_val ) {
423
+ semaphore.sel_val = 1;
424
+ query_css( 'sel_val', qsid, load_selector_values );
425
+ }
426
+ // if semaphore is 2 and sel_val[qsid] does not exist, this selector if invalid
427
+ return false;
428
+ }
429
+ current_qsid = qsid;
430
+ if ( 1 == semaphore.set_qry ) {
431
+ // query semaphore set, set query menu value
432
+ semaphore.set_qry = 0;
433
+ set_query( ctcAjax.sel_val[qsid].query );
434
+ } else if ( 1 == semaphore.new_sel ) {
435
+ // qsid semaphore set, render selector inputs
436
+ semaphore.new_sel = 0;
437
+ render_selector_inputs( qsid );
438
+ }
439
  }
440
+
441
+ function load_filtered_rules( request, response ) {
442
+ var arr = [],
443
+ noval = ( is_empty( ctcAjax.sel_val[current_qsid] ) ) || ( is_empty( ctcAjax.sel_val[current_qsid].value ) );
444
+ if ( is_empty( cache_rules ) ) {
445
+ load_rules();
446
+ }
447
+ $.each( cache_rules, function( key, val ) {
448
+ var skip = false,
449
+ matcher = new RegExp( $.ui.autocomplete.escapeRegex( request.term ), "i" );
450
+ if ( matcher.test( val.label ) ) {
451
+ if ( false === noval ) {
452
+ // skip rule if in current selector array
453
+ $.each( ctcAjax.sel_val[current_qsid].value, function( rule, value ) {
454
+ if ( val.label == rule.replace( /\d+/g, from_ascii ) ) {
455
+ skip = true;
456
+ return false;
457
+ }
458
+ } );
459
+ if ( skip ) {
460
+ return;
461
+ }
462
+ }
463
+ // add rule
464
+ arr.push( val );
465
+ }
466
+ } );
467
+ response( arr );
468
+ }
469
+
470
+ /**
471
+ * The "render" functions inject html into the DOM based on the JSON result of Ajax actions
472
+ */
473
+ function render_child_rule_input( qsid, rule, seq ) {
474
  var html = '',
475
+ value = ( is_empty( ctcAjax.sel_val[qsid] )
476
+ || is_empty( ctcAjax.sel_val[qsid].value )
477
+ || is_empty( ctcAjax.sel_val[qsid].value[rule] ) ? '' : ctcAjax.sel_val[qsid].value[rule] ),
478
+ oldRuleObj = decode_value( rule, ( 'undefined' == typeof value ? '' : value['parnt'] ) ),
479
+ oldRuleFlag = ( false === is_empty( value['i_parnt'] ) && 1 == value['i_parnt'] ) ?
480
  ctcAjax.important_label : '',
481
+ newRuleObj = decode_value( rule, ( 'undefined' == typeof value ? '' : value['child'] ) ),
482
+ newRuleFlag = ( false === is_empty( value['i_child'] ) && 1 == value['i_child'] ) ? 1 : 0,
483
  impid = 'ctc_' + seq + '_child_' + rule + '_i_' + qsid;
484
+ if ( false === is_empty( ctcAjax.sel_val[qsid] ) ) {
485
+ html += '<div class="ctc-' + ( 'ovrd' == seq ? 'input' : 'selector' ) + '-row clearfix">' + lf;
486
+ html += '<div class="ctc-input-cell">' + ( 'ovrd' == seq ? rule.replace( /\d+/g, from_ascii ) : ctcAjax.sel_val[qsid].selector
487
  + '<br/><a href="#" class="ctc-selector-edit" id="ctc_selector_edit_' + qsid + '" >' + ctcAjax.edit_txt + '</a> '
488
+ + ( is_empty( oldRuleObj.orig ) ? ctcAjax.child_only_txt : '' ) )
489
  + '</div>' + lf;
490
+ if ( 'ovrd' == seq ) {
491
  html += '<div class="ctc-parent-value ctc-input-cell" id="ctc_' + seq + '_parent_' + rule + '_' + qsid + '">'
492
+ + ( is_empty( oldRuleObj.orig ) ? '[no value]' : oldRuleObj.orig + oldRuleFlag ) + '</div>' + lf;
493
  }
494
  html += '<div class="ctc-input-cell">' + lf;
495
+ if ( false === is_empty( oldRuleObj.names ) ) {
496
+ $.each( oldRuleObj.names, function( ndx, newname ) {
497
+ newname = ( is_empty( newname ) ? '' : newname );
498
  html += '<div class="ctc-child-input-cell">' + lf;
499
  var id = 'ctc_' + seq + '_child_' + rule + '_' + qsid + newname,
500
  newval;
501
+ if ( false === ( newval = newRuleObj.values.shift() ) ) {
502
  newval = '';
503
  }
504
 
505
+ html += ( is_empty( newname ) ? '' : ctcAjax.field_labels[newname] + ':<br/>' )
506
  + '<input type="text" id="' + id + '" name="' + id + '" class="ctc-child-value'
507
+ + ( ( newname + rule ).toString().match( /color/ ) ? ' color-picker' : '' )
508
+ + ( ( newname ).toString().match( /url/ ) ? ' ctc-input-wide' : '' )
509
+ + '" value="' + esc_quot( newval ) + '" />' + lf;
510
  html += '</div>' + lf;
511
+ } );
512
  html += '<label for="' + impid + '"><input type="checkbox" id="' + impid + '" name="' + impid + '" value="1" '
513
+ + ( 1 === newRuleFlag ? 'checked' : '' ) + ' />' + ctcAjax.important_label + '</label>' + lf;
514
  }
515
  html += '</div>' + lf;
516
+ html += ( 'ovrd' == seq ? '' : '<div class="ctc-swatch ctc-specific" id="ctc_child_' + rule + '_' + qsid + '_swatch">'
517
  + ctcAjax.swatch_txt + '</div>' + lf
518
  + '<div class="ctc-child-input-cell ctc-button-cell" id="ctc_save_' + rule + '_' + qsid + '_cell">' + lf
519
  + '<input type="button" class="button ctc-save-input" id="ctc_save_' + rule + '_' + qsid
520
+ + '" name="ctc_save_' + rule + '_' + qsid + '" value="Save" /></div>' + lf );
521
  html += '</div><!-- end input row -->' + lf;
522
  }
523
  return html;
524
  }
525
+
526
+ function render_selector_inputs( qsid ) {
527
+ //console.log( 'render_selector_inputs' );
528
+ //console.log( semaphore );
529
+ var id, html, val, selector;
530
+ if ( qsid = prune_if_empty( qsid ) ) {
531
+ $( '#ctc_sel_ovrd_qsid' ).val( qsid );
532
+ current_qsid = qsid;
533
+ if ( is_empty( ctcAjax.sel_val[qsid].seq ) ) {
534
+ $( '#ctc_child_load_order_container' ).html( '' );
 
 
 
 
 
535
  } else {
536
  id = 'ctc_ovrd_child_seq_' + qsid;
537
+ val = parseInt( ctcAjax.sel_val[qsid].seq );
538
  html = '<input type="text" id="' + id + '" name="' + id + '" class="ctc-child-value" value="' + val + '" />';
539
+ $( '#ctc_child_load_order_container' ).html( html );
540
  }
541
+ if ( is_empty( ctcAjax.sel_val[qsid].value ) ) {
542
+ $( '#ctc_sel_ovrd_rule_inputs' ).slideUp( function(){ $( '#ctc_sel_ovrd_rule_inputs' ).html( '' ); } );
543
  } else {
544
  html = '';
545
+ $.each( ctcAjax.sel_val[qsid].value, function( rule, value ) {
546
+ html += render_child_rule_input( qsid, rule, 'ovrd' );
547
+ } );
548
+ $( '#ctc_sel_ovrd_rule_inputs' ).html( html ).find( '.color-picker' ).each( function() {
549
+ setup_iris( this );
550
+ } );
551
+ coalesce_inputs( '#ctc_child_all_0_swatch' );
552
+ $( '#ctc_sel_ovrd_selector_selected' ).text( ctcAjax.sel_val[qsid].selector );
553
+ $( '.ctc-rewrite-toggle' ).text( ctcAjax.rename_txt );
554
+ $( '#ctc_sel_ovrd_new_rule, #ctc_sel_ovrd_rule_header, #ctc_sel_ovrd_rule_inputs_container, #ctc_sel_ovrd_rule_inputs, .ctc-rewrite-toggle' ).slideDown();
555
  }
556
+ } else {
557
+ //selector = $( '#ctc_sel_ovrd_selector_selected' ).text();
558
+ //delete ctcAjax.sel_ndx[current_query][selector];
559
+ $( '#ctc_sel_ovrd_selector_selected' ).html( '&nbsp;' );
560
+ $( '#ctc_sel_ovrd_new_rule, #ctc_sel_ovrd_rule_header, #ctc_sel_ovrd_rule_inputs_container, #ctc_sel_ovrd_rule_inputs, .ctc-rewrite-toggle' ).slideUp( function(){ $( '#ctc_sel_ovrd_rule_inputs' ).html( '' ); } );
561
+
562
  }
563
+ html = null; // to garbage;
564
  }
565
+
566
+ function render_css_preview( theme ) {
567
+ if ( 1 === semaphore.preview ) {
568
  return false;
569
  }
570
+ if ( 0 == semaphore.preview ) {
571
+ semaphore.preview = 1;
572
  var theme;
573
+ if ( !( theme = theme.match( /(child|parnt)/ )[1] ) ) {
574
  theme = 'child';
575
  }
576
+ set_notice( '' )
577
+ query_css( 'preview', theme, render_css_preview );
578
  return false;
579
  }
580
+ //console.log(ctcAjax.previewResponse);
581
+ $( '#view_'+theme+'_options_panel' ).text( ctcAjax.previewResponse );
582
+ ctcAjax.previewResponse = null; // send to trash
583
+ semaphore.preview = 0;
584
  }
585
+
586
+ function render_rule_value_inputs( ruleid ) {
587
+ if ( 1 === semaphore.rule_val ) return false;
588
 
589
+ if ( 0 == semaphore.rule_val ) {
590
+ semaphore.rule_val = 1;
591
+ query_css( 'rule_val', ruleid, render_rule_value_inputs );
592
  return false;
593
  }
594
  var rule = ctcAjax.rule[ruleid],
595
  html = '<div class="ctc-input-row clearfix" id="ctc_rule_row_' + rule + '">' + lf;
596
+ if ( false === is_empty( ctcAjax.rule_val[ruleid] ) ) {
597
+ $.each( ctcAjax.rule_val[ruleid], function( valid, value ) {
598
+ var oldRuleObj = decode_value( rule, value );
599
  html += '<div class="ctc-parent-row clearfix" id="ctc_rule_row_' + rule + '_' + valid + '">' + lf;
600
  html += '<div class="ctc-input-cell ctc-parent-value" id="ctc_' + valid + '_parent_' + rule + '_' + valid + '">'
601
  + oldRuleObj.orig + '</div>' + lf;
611
  html += '<div id="ctc_status_val_qry_' + valid + '"></div>' + lf;
612
  html += '<div id="ctc_selector_' + rule + '_' + valid + '_rows"></div>' + lf;
613
  html += '</div></div></div>' + lf;
614
+ } );
615
  html += '</div>' + lf;
616
  }
617
+ $( '#ctc_rule_value_inputs' ).html( html ).find( '.ctc-swatch' ).each( function() {
618
+ coalesce_inputs( this );
619
+ } );
620
+ html = null; // send to the garbage
621
+ }
622
+
623
+ function render_recent() {
624
+ var html = '';
625
+ if ( is_empty( ctcAjax.recent ) ) {
626
+ html += ctcAjax.recent_txt;
627
+ } else {
628
+ //console.log(ctcAjax.recent);
629
+ html += '<ul>' + "\n";
630
+ $.each( ctcAjax.recent, function( ndx, el ) {
631
+ $.each( el, function ( key, value ) {
632
+ html += '<li><a href="#" class="ctc-selector-edit" id="ctc_selector_edit_' + key + '" >'
633
+ + value + '</a></li>' + "\n";
634
+ } );
635
+ } );
636
+ html += '</ul>' + "\n";
637
+ }
638
+ $( '#ctc_recent_selectors' ).html( html );
639
+ html = null; // send to the garbage
640
  }
641
+
642
+ function render_selector_value_inputs( valid ) {
643
+ if ( 1 == semaphore.val_qry ) return false;
644
  var params,
645
  page_ruleid,
646
+ rule = $( '#ctc_rule_menu_selected' ).text().replace( /[^\w\-]/g, to_ascii ),
647
  selector,
648
  html = '';
649
+ if ( 0 === semaphore.val_qry ) {
650
+ semaphore.val_qry = 1;
651
  params = { 'rule': rule };
652
+ query_css( 'val_qry', valid, render_selector_value_inputs, params );
653
  return false;
654
  }
655
+ if ( false === is_empty( ctcAjax.val_qry[valid] ) ) {
656
+ $.each( ctcAjax.val_qry[valid], function( rule, queries ) {
657
  page_rule = rule;
658
+ $.each( queries, function( query, selectors ) {
659
  html += '<h4 class="ctc-query-heading">' + query + '</h4>' + lf;
660
+ if ( false === is_empty( selectors ) ) {
661
+ $.each( selectors, function( qsid, data ) {
662
  ctcAjax.sel_val[qsid] = data;
663
+ html += render_child_rule_input( qsid, rule, valid );
664
+ } );
665
  }
666
+ } );
667
+ } );
668
  }
669
  selector = '#ctc_selector_' + rule + '_' + valid + '_rows';
670
+ $( selector ).html( html ).find( '.color-picker' ).each( function() {
671
+ setup_iris( this );
672
+ } );
673
+ $( selector ).find( '.ctc-swatch' ).each( function() {
674
+ coalesce_inputs( this );
675
+ } );
676
 
677
  }
678
+ /**
679
+ * The "setup" functions initialize jQuery UI widgets
680
+ */
681
+ function setup_iris( obj ) {
682
+ //console.log( 'setting up iris ' + ( 'undefined' != typeof $( obj ).attr( 'id' ) ? $( obj ).attr( 'id' ) : '' ) );
683
+ $( obj ).iris( {
684
+ change: function( e, ui ) {
685
+ //console.log( 'change event '
686
+ //+ ( 'undefined' != typeof $( this ).attr( 'id' ) ? $( this ).attr( 'id' ) : '' )
687
+ //+ ' ' + ui.color.toString() );
688
+ $( obj ).data( 'color', ui.color.toString() );
689
+ coalesce_inputs( obj );
690
+ }
691
+ } );
692
+ }
693
+
694
+ function setup_query_menu() {
695
+ //console.log( 'setup query menu' );
696
+ //console.log( semaphore );
697
+ $( '#ctc_sel_ovrd_query' ).autocomplete( {
698
+ source: cache_queries,
699
+ minLength: 0,
700
+ selectFirst: true,
701
+ autoFocus: true,
702
+ select: function( e, ui ) {
703
+ set_query( ui.item.value );
704
+ return false;
705
+ },
706
+ focus: function( e ) {
707
+ e.preventDefault();
708
+ }
709
+ } );
710
+ }
711
+
712
+ function setup_selector_menu() {
713
+ //console.log( 'setup selector menu' );
714
+ //console.log( semaphore );
715
+ $( '#ctc_sel_ovrd_selector' ).autocomplete( {
716
+ source: cache_selectors,
717
+ selectFirst: true,
718
+ autoFocus: true,
719
+ select: function( e, ui ) {
720
+ set_selector( ui.item.value, ui.item.label );
721
+ return false;
722
+ },
723
+ focus: function( e ) { e.preventDefault(); }
724
+ } );
725
+ }
726
+
727
+ function setup_rule_menu() {
728
+ //console.log( 'setup rule menu' );
729
+ //console.log( semaphore );
730
+ $( '#ctc_rule_menu' ).autocomplete( {
731
+ source: cache_rules,
732
+ //minLength: 0,
733
+ selectFirst: true,
734
+ autoFocus: true,
735
+ select: function( e, ui ) {
736
+ set_rule( ui.item.value, ui.item.label );
737
+ return false;
738
+ },
739
+ focus: function( e ) { e.preventDefault(); }
740
+ } );
741
+ }
742
+
743
+ function setup_new_rule_menu() {
744
+ $( '#ctc_new_rule_menu' ).autocomplete( {
745
+ source: load_filtered_rules,
746
+ //minLength: 0,
747
+ selectFirst: true,
748
+ autoFocus: true,
749
+ select: function( e, ui ) {
750
+ e.preventDefault();
751
+ var n = $( render_child_rule_input( current_qsid, ui.item.label.replace( /[^\w\-]/g, to_ascii ), 'ovrd' ) );
752
+ $( '#ctc_sel_ovrd_rule_inputs' ).append( n );
753
+ $( '#ctc_new_rule_menu' ).val( '' );
754
+ if ( is_empty( ctcAjax.sel_val[current_qsid].value ) ) {
755
+ ctcAjax.sel_val[current_qsid]['value'] = {};
756
+ }
757
+ ctcAjax.sel_val[current_qsid].value[ui.item.label] = {'child': ''};
758
+ n.find( 'input[type="text"]' ).each( function( ndx, el ) {
759
+ if ( $( el ).hasClass( 'color-picker' ) )
760
+ setup_iris( el );
761
+ $( el ).focus();
762
+ } );
763
+ return false;
764
+ },
765
+ focus: function( e ) { e.preventDefault(); }
766
+ } );
767
+ }
768
+ /**
769
+ * The "set" functions apply values to inputs
770
+ */
771
+ function set_existing() {
772
+ if ( $( '#ctc_theme_child' ).length && $( '#ctc_child_type_existing' ).is(':checked') ) {
773
+ var child = $( '#ctc_theme_child' ).val();
774
+ if ( false === is_empty( child ) ) {
775
+ $( '#ctc_child_name' ).val( ctcAjax.themes['child'][child].Name );
776
+ $( '#ctc_child_author' ).val( ctcAjax.themes['child'][child].Author );
777
+ $( '#ctc_child_version' ).val( ctcAjax.themes['child'][child].Version );
778
+ }
779
+ }
780
+ }
781
+
782
+ function set_notice( noticearr ) {
783
+ var errorHtml = '';
784
+ if ( false === is_empty( noticearr ) ) {
785
+ $.each( noticearr, function( type, list ) {
786
+ errorHtml += '<div class="' + type + '"><ul>' + lf;
787
+ $( list ).each( function( ndx, el ) {
788
+ errorHtml += '<li>' + el.toString() + '</li>' + lf;
789
+ } );
790
+ errorHtml += '</ul></div>';
791
+ } );
792
+ }
793
+ $( '#ctc_error_notice' ).html( errorHtml );
794
+ }
795
+
796
+ function set_parent_menu( obj ) {
797
+ $( '#ctc_theme_parent' ).parents( '.ctc-input-row' ).first().append( '<span class="ctc-status-icon spinner"></span>' );
798
+ $( '.spinner' ).show();
799
+ document.location='?page=' + ctcAjax.page + '&ctc_parent=' + obj.value;
800
+ }
801
+
802
+ function set_child_menu( obj ) {
803
+ if ( false === is_empty( ctcAjax.themes.child[obj.value] ) ) {
804
+ $( '#ctc_child_name' ).val( ctcAjax.themes.child[obj.value].Name );
805
+ $( '#ctc_child_author' ).val( ctcAjax.themes.child[obj.value].Author );
806
+ $( '#ctc_child_version' ).val( ctcAjax.themes.child[obj.value].Version );
807
+ }
808
+ }
809
+
810
+ function set_query( value ) {
811
+ current_query = value;
812
+ $( '#ctc_sel_ovrd_query' ).val( '' );
813
+ $( '#ctc_sel_ovrd_query_selected' ).text( value );
814
+ $( '#ctc_sel_ovrd_selector' ).val( '' );
815
+ $( '#ctc_sel_ovrd_selector_selected' ).html( '&nbsp;' );
816
+ $( '#ctc_sel_ovrd_rule_inputs' ).html( '' );
817
+ load_selectors();
818
+ }
819
+
820
+ function set_selector( value, label ) {
821
+ $( '#ctc_sel_ovrd_selector' ).val( '' );
822
+ if ( 1 != semaphore.sel_val ) semaphore.sel_val = 0;
823
+ current_qsid = value;
824
+ // set flag to render inputs after qsid values load
825
+ semaphore.new_sel = 1;
826
+ load_selector_values( value );
827
+ }
828
+
829
+ function set_rule( value, label ) {
830
+ $( '#ctc_rule_menu' ).val( '' );
831
+ $( '#ctc_rule_menu_selected' ).text( label );
832
+ if ( 1 != semaphore.rule_val ) semaphore.rule_val = 0;
833
+ render_rule_value_inputs( value );
834
+ $( '.ctc-rewrite-toggle' ).text( ctcAjax.rename_txt );
835
+ $( '#ctc_rule_value_inputs, #ctc_input_row_rule_header' ).show();
836
+ }
837
+
838
+ function set_qsid( obj ) {
839
+ //console.log( 'set_qsid' );
840
+ //console.log( semaphore );
841
+ var qsid = $( obj ).attr( 'id' ).match( /_(\d+)$/ )[1];
842
+ focus_panel( '#query_selector_options' );
843
+ // set flag to load selector (qsid) values if empty
844
+ semaphore.sel_val = 0;
845
+ // set flags to set menu values after qsid values load
846
+ semaphore.set_sel = semaphore.set_qry = 1;
847
+ current_qsid = qsid;
848
+ load_selector_values( qsid );
849
+ }
850
+
851
+ /**
852
+ * slurp website home page and parse header for linked stylesheets
853
+ * set these to be parsed as "default" stylesheets
854
+ */
855
+ function set_addl_css() {
856
+
857
+ var template = $( '#ctc_theme_parnt' ).val(),
858
+ theme_uri = ctcAjax.theme_uri.replace( /^https?:\/\//, '' ),
859
+ homeurl = ctcAjax.homeurl.replace( /^https?/, ctcAjax.ssl ? 'https' : 'http' ),
860
+ url = homeurl + '?preview=1&p=x&template=' + template + '&stylesheet=' + template,
861
+ regex = new RegExp( "<link rel=[\"']stylesheet[\"'][^>]+?" + theme_uri + '/' + template + '/(.+?\\.css)[^>]+?>', 'g' ),
862
+ additional;
863
+ if ( is_empty( template ) ) return;
864
+ if ( template != ctcAjax.parnt ) {
865
+ $.get( url, function( data ) {
866
+ //console.log( data );
867
+ while ( additional = regex.exec( data ) ) {
868
+ if ( 'style.css' == additional[1] ) break; // bail after main stylesheet
869
+ if ( additional[1].match( /bootstrap/ ) ) continue; // don't autoselect Bootstrap stylesheets
870
+ $( '.ctc_checkbox' ).each( function( ndx, el ) {
871
+ if ( $( this ).val() == additional[1] ) $( this ).prop( 'checked', true );
872
+ } );
873
+ }
874
+ data = null; // send page to garbage
875
+ } );
876
+ } else {
877
+ //console.log('existing... using addl_css array');
878
+ $( ctcAjax.addl_css ).each( function( ndx, el ) {
879
+ $( '#ctc_stylesheet_files .ctc_checkbox' ).each( function( index, elem ) {
880
+ if ( $( this ).val() == el ) $( this ).prop( 'checked', true );
881
+ //console.log($( this ).val() + ' <> ' + el);
882
+ } );
883
+ });
884
+ }
885
+ }
886
+
887
+ /**
888
+ * Retrieve data from server and execute callback on completion
889
+ * Previously set semaphores control the callback behavior
890
+ */
891
+ function query_css( obj, key, callback, params ) {
892
  var postdata = { 'ctc_query_obj' : obj, 'ctc_query_key': key },
893
+ status_sel = '#ctc_status_' + obj + ( 'val_qry' == obj ? '_' + key : '' );
894
 
895
+ if ( 'object' === typeof params ) {
896
+ $.each( params, function( key, val ) {
897
  postdata['ctc_query_' + key] = val;
898
+ } );
899
  }
900
+ $( '.query-icon' ).remove();
901
+ $( status_sel ).append( '<span class="ctc-status-icon spinner query-icon"></span>' );
902
+ $( '.spinner' ).show();
903
  // add wp ajax action to array
904
+ //console.log( $( '#ctc_action' ).val() );
905
+ postdata['action'] = ( false === is_empty( $( '#ctc_action' ).val() )
906
+ && 'plugin' == $( '#ctc_action' ).val() ) ?
907
+ 'ctc_plgqry' : 'ctc_query';
908
+ postdata['_wpnonce'] = $( '#_wpnonce' ).val();
909
  // ajax post input data
910
+ //console.log( 'query_css postdata:' );
911
+ //console.log( postdata );
912
  $.post(
913
  // get ajax url from localized object
914
  ctcAjax.ajaxurl,
915
  //Data
916
  postdata,
917
  //on success function
918
+ function( response ) {
919
+ //console.log( response );
920
  // hide spinner
921
+ semaphore[obj] = 2;
922
+ //$( '.ctc-status-icon' ).removeClass( 'spinner' );
923
  // show check mark
924
+ if ( is_empty( response ) ) {
925
+ $( '.query-icon' ).addClass( 'failure' );
926
+ if ( 'preview' == obj ) {
927
  ctcAjax.previewResponse = ctcAjax.css_fail_txt;
928
+ callback( key );
929
  }
930
  } else {
931
+ $( '.ctc-status-icon' ).addClass( 'success' );
932
+ if ( 1 == semaphore.refresh ) {
933
+ //console.log( 'cache reset flag set. resetting caches...');
934
+ semaphore.refresh = 0;
935
+ // configuration has changed, wipe out the cache arrays
936
+ reset_caches();
937
+ }
938
+ //console.log( 'updating cache from ' + obj + ' query');
939
  // update data objects
940
+ update_cache( response );
941
+ response = null;
942
+ render_recent();
943
+ if ( 'function' === typeof callback ) {
944
+ callback( key );
945
  }
 
946
  }
947
+ }, 'json'
948
+ ).fail( function() {
949
  // hide spinner
950
+ $( '.query-icon' ).removeClass( 'spinner' );
951
  // show check mark
952
+ $( '.query-icon' ).addClass( 'failure' );
953
+ if ( 'preview' == obj ) {
954
  ctcAjax.previewResponse = ctcAjax.css_fail_txt;
955
+ semaphore[obj] = 2;
956
+ callback( key );
957
  } else {
958
+ semaphore[obj] = 0;
959
  }
960
 
961
+ } );
962
  return false;
963
  }
964
+ /**
965
+ * Post data to server for saving and execute callback on completion
966
+ * Previously set semaphores control the callback behavior
967
+ */
968
+ function save( obj, callback ) {
969
  var postdata = {},
970
  $selector, $query, $imports, $rule,
971
+ id = $( obj ).attr( 'id' ), newsel;
972
+
 
 
 
973
  // disable the button until ajax returns
974
+ $( obj ).prop( 'disabled', true );
975
  // clear previous success/fail icons
976
+ $( '.save-icon' ).remove();
977
  // show spinner
978
+ $( obj ).parent( '.ctc-textarea-button-cell, .ctc-button-cell' ).append( '<span class="ctc-status-icon spinner save-icon"></span>' );
979
+ if ( id.match(/ctc_configtype/) ) {
980
+ $( obj ).parents( '.ctc-input-row' ).first().append( '<span class="ctc-status-icon spinner save-icon"></span>' );
981
+ postdata[ 'ctc_configtype' ] = $( obj ).val();
982
+ } else if ( ( $selector = $( '#ctc_new_selectors' ) ) && 'ctc_save_new_selectors' == $( obj ).attr( 'id' ) ) {
983
  postdata['ctc_new_selectors'] = $selector.val();
984
+ if ( $query = $( '#ctc_sel_ovrd_query_selected' ) ) {
985
  postdata['ctc_sel_ovrd_query'] = $query.text();
986
  }
987
+ } else if ( ( $imports = $( '#ctc_child_imports' ) ) && 'ctc_save_imports' == $( obj ).attr( 'id' ) ) {
988
  postdata['ctc_child_imports'] = $imports.val();
989
  } else {
990
  // coalesce inputs
991
+ postdata = coalesce_inputs( obj );
992
  }
993
+ $( '.save-icon' ).show();
994
  // add rename selector value if it exists
995
+ $( '#ctc_sel_ovrd_selector_selected' ).find( '#ctc_rewrite_selector' ).each( function() {
996
+ newsel = $( '#ctc_rewrite_selector' ).val(),
997
+ origsel = $( '#ctc_rewrite_selector_orig' ).val();
998
+ if ( is_empty( newsel ) || !newsel.toString().match( /\w/ ) ) {
999
  newsel = origsel;
1000
  } else {
1001
  postdata['ctc_rewrite_selector'] = newsel;
1002
  }
1003
+ $( '.ctc-rewrite-toggle' ).text( ctcAjax.rename_txt );
1004
+ $( '#ctc_sel_ovrd_selector_selected' ).html( newsel );
1005
+ } );
1006
  // add wp ajax action to array
1007
+ //console.log( $( '#ctc_action' ).val() );
1008
+ postdata['action'] = ( false === is_empty( $( '#ctc_action' ).val() )
1009
+ && 'plugin' == $( '#ctc_action' ).val() ) ?
1010
+ 'ctc_plugin' : 'ctc_update';
1011
+ postdata['_wpnonce'] = $( '#_wpnonce' ).val();
1012
+ //console.log( postdata );
1013
  // ajax post input data
1014
  $.post(
1015
  // get ajax url from localized object
1017
  //Data
1018
  postdata,
1019
  //on success function
1020
+ function( response ) {
1021
+ //console.log( response );
1022
  // release button
1023
+ $( obj ).prop( 'disabled', false );
1024
  // hide spinner
1025
+ $( '.save-icon' ).removeClass( 'spinner' );
1026
  // show check mark
1027
+ if ( is_empty( response ) ) {
1028
+ $( '.save-icon' ).addClass( 'failure' );
1029
  } else {
1030
+ $( '#ctc_new_selectors' ).val( '' );
1031
+ if ( 1 == semaphore.refresh ) {
1032
+ //console.log( 'cache reset flag set. resetting caches...');
1033
+ semaphore.refresh = 0;
1034
+ // configuration has changed, wipe out the cache arrays
1035
+ reset_caches();
1036
+ }
1037
+ //console.log( 'updating cache from ' + id + ' save');
1038
  // update data objects
1039
+ update_cache( response );
1040
+ response = null;
1041
+ if ( is_empty( rewrite_id ) ) {
1042
+ if ( current_qsid ) {
1043
+ render_selector_inputs( current_qsid );
1044
+ render_recent();
1045
+ }
1046
+ } else {
1047
+ set_selector( rewrite_id, rewrite_sel );
1048
  rewrite_id = rewrite_sel = null;
1049
  }
1050
+ $( '.save-icon' ).addClass( 'success' );
1051
+ if ( 'function' === typeof callback ) {
1052
+ callback();
1053
+ }
1054
  }
1055
  return false;
1056
  }, 'json'
1057
+ ).fail( function() {
1058
  // release button
1059
+ $( obj ).prop( 'disabled', false );
1060
  // hide spinner
1061
+ $( '.save-icon' ).removeClass( 'spinner' );
1062
  // show check mark
1063
+ $( '.save-icon' ).addClass( 'failure' );
1064
+ } );
1065
  return false;
1066
  }
1067
+
1068
+ function update_cache( response ) {
1069
+ //console.log( 'update_cache' );
1070
+ //console.log( response );
1071
+ //console.log( semaphore );
1072
+ $( response ).each( function() {
1073
+ switch ( this.obj ) {
1074
+ case 'imports':
1075
+ ctcAjax.imports = this.data;
1076
+ break;
1077
+
1078
+ case 'rule_val':
1079
+ ctcAjax.rule_val[this.key] = this.data;
1080
+ break;
1081
+
1082
+ case 'val_qry':
1083
+ ctcAjax.val_qry[this.key] = this.data;
1084
+ break;
1085
+
1086
+ case 'rule':
1087
+ ctcAjax.rule = this.data;
1088
+ break;
1089
+
1090
+ case 'sel_ndx':
1091
+ if ( is_empty( this.key ) ) {
1092
+ ctcAjax.sel_ndx = this.data;
1093
+ } else if ( 'qsid' == this.key ) {
1094
+ if ( is_empty( ctcAjax.sel_ndx[this.data.query] ) ) {
1095
+ ctcAjax.sel_ndx[this.data.query] = {}
1096
+ }
1097
+ ctcAjax.sel_ndx[this.data.query][this.data.selector] = this.data.qsid;
1098
+ } else {
1099
+ ctcAjax.sel_ndx[this.key] = this.data;
1100
+ current_query = this.key;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1101
  }
1102
+ break;
1103
+
1104
+ case 'sel_val':
1105
+ ctcAjax.sel_val[this.key] = this.data;
1106
+ current_qsid = this.key;
1107
+ break;
1108
+
1109
+ case 'rewrite':
1110
+ current_qsid = this.key;
1111
+ rewrite_id = this.key;
1112
+ rewrite_sel = this.data;
1113
+ break;
1114
+
1115
+ case 'recent':
1116
+ ctcAjax.recent = this.data;
1117
+ break;
1118
+
1119
+ case 'stylesheets':
1120
+ $( '#ctc_stylesheet_files').html( this.data );
1121
+ break;
1122
+
1123
+ case 'backups':
1124
+ $( '#ctc_backup_files').html( this.data );
1125
+ break;
1126
+
1127
+ case 'addl_css':
1128
+ ctcAjax.addl_css = this.data;
1129
+ //console.log('addl_css');
1130
+ //console.log(this.data);
1131
+ break;
1132
+
1133
+ case 'preview':
1134
+ case 'all_styles':
1135
+ // refresh preview
1136
+ ctcAjax.previewResponse = this.data;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1137
  }
1138
+ } );
1139
+ response = null; // send to garbage
 
 
 
 
 
 
 
 
1140
  }
1141
+
1142
+ function reset_caches() {
1143
+ //console.log('resetting caches...');
1144
+ current_query = 'base';
1145
+ current_qsid = null;
1146
+ cache_selectors = [];
1147
+ cache_queries = [];
1148
+ cache_rules = [];
1149
+
1150
+ semaphore[ 'rld_rule' ] = 1; // force rule reload
1151
+ semaphore[ 'rld_sel' ] = 1; // force sel_ndx reload
1152
+ semaphore[ 'set_qry' ] = 1; // set query on qsid load
1153
+
1154
+ ctcAjax.imports = [];
1155
+ ctcAjax.recent = {};
1156
+ ctcAjax.rule = {};
1157
+ ctcAjax.sel_ndx = {};
1158
+ ctcAjax.val_qry = {};
1159
+ ctcAjax.rule_val = {};
1160
+ ctcAjax.sel_val = {};
1161
+ //console.log('caches reset. loading menus...');
1162
+ load_menus();
1163
  }
1164
  // initialize vars
1165
  var lf = "\n",
1166
+ quot_regex = new RegExp( '"', 'g' ),
 
 
1167
  rewrite_id,
1168
  rewrite_sel,
 
1169
  testslug = '',
1170
  testname = '',
1171
+ current_query = 'base',
1172
+ current_qsid,
1173
+ semaphore = {
1174
+ // status flags: 0 = load, 1 = loading, 2 = loaded
1175
+ 'rule': 0, // rules
1176
+ 'sel_ndx': 0, // index of queries/selectors
1177
+ 'val_qry': 0, // values by qsid
1178
+ 'rule_val': 0, // values by rule
1179
+ 'sel_val': 0, // qsids (query/selector ids) by value
1180
+ 'preview': 0, // stylesheet preview
1181
+ 'recent': 0, // recent edits
1182
+ // these control behavior of ajax callbacks
1183
+ 'rld_rule': 0, // force rule reload
1184
+ 'rld_sel': 0, // force sel_ndx reload
1185
+ 'set_qry': 0, // set query on qsid load
1186
+ 'set_sel': 0, // set selector on sel load
1187
+ 'new_sel': 0, // render new inputs on qsid load
1188
+ 'refresh': 0 // reset caches on load
1189
  },
1190
+ // these caches are used as the source for autocomplete menus
1191
+ cache_selectors = [],
1192
+ cache_queries = [],
1193
+ cache_rules = [];
1194
  // -- end var definitions
1195
 
1196
+ // auto populate parent/child tab values
1197
  autogen_slugs();
1198
+ set_existing();
1199
+ // initialize theme menus
1200
+ if ( !$( '#ctc_theme_parnt' ).is( 'input' ) ) {
1201
+ $.widget( 'ctc.themeMenu', $.ui.selectmenu, {
1202
  _renderItem: function( ul, item ) {
1203
  var li = $( "<li>" );
1204
+ $( '#ctc_theme_option_' + item.value ).detach().appendTo( li );
1205
  return li.appendTo( ul );
1206
  }
1207
+ } );
1208
+ $( '#ctc_theme_parnt' ).themeMenu( {
1209
  select: function( event, ui ) {
1210
+ set_parent_menu( ui.item );
1211
  }
1212
+ } );
1213
+ if ( is_empty( ctcAjax.themes.child ) ) {
1214
+ $( '#ctc_child_name' ).val( testname );
1215
+ $( '#ctc_child_template' ).val( testslug );
1216
  } else {
1217
+ $( '#ctc_theme_child' ).themeMenu( {
1218
  select: function( event, ui ) {
1219
+ set_child_menu( ui.item );
1220
  }
1221
+ } );
1222
+ }
1223
  }
 
1224
  // bind event handlers
1225
+ // these elements get replaced so use delegated events
1226
+ $( '#ctc_main' ).on( 'focus', '.color-picker', function() { //'.ctc-option-panel-container'
1227
+ set_notice( '' )
1228
+ $( '.color-picker' ).not( this ).iris( 'hide' );
1229
+ $( this ).iris( 'toggle' );
1230
+ $( '.iris-picker' ).css( {'position':'absolute', 'z-index':10} );
1231
+ } );
1232
 
1233
+ $( '#ctc_main' ).on( 'change', '.ctc-child-value, input[type=checkbox]', function() { //'.ctc-option-panel-container',
1234
+ coalesce_inputs( this );
1235
+ } );
 
 
 
 
 
 
 
1236
 
1237
+ $( '#ctc_main' ).on( 'click', '.ctc-selector-handle', function( e ) { //'.ctc-option-panel-container'
1238
  e.preventDefault();
1239
+ set_notice( '' )
1240
+ var id = $( this ).attr( 'id' ).toString().replace( '_close', '' ),
1241
+ valid = id.toString().match( /_(\d+)$/ )[1];
1242
+ if ( $( '#' + id + '_container' ).is( ':hidden' ) ) {
1243
+ if ( 1 != semaphore.val_qry ) semaphore.val_qry = 0;
1244
+ render_selector_value_inputs( valid );
1245
  }
1246
+ $( '#' + id + '_container' ).fadeToggle( 'fast' );
1247
+ $( '.ctc-selector-container' ).not( '#' + id + '_container' ).fadeOut( 'fast' );
1248
+ } );
1249
+ $( '#ctc_main' ).on( 'click', '.nav-tab', function( e ) {
1250
  e.preventDefault();
1251
  // clear the notice box
1252
+ set_notice( '' );
1253
+ $( '.ctc-status-icon' ).remove();
1254
+ var id = '#' + $( this ).attr( 'id' );
1255
+ focus_panel( id );
1256
+ } );
1257
+ $( '#ctc_main' ).on( 'click', '.ctc-save-input', function( e ) {
1258
+ save( this , load_menus); // refresh menus after updating data
1259
+ } );
1260
+ $( '#ctc_main' ).on( 'click', '.ctc-selector-edit', function( e ) {
1261
+ set_qsid( this );
1262
+ } );
1263
+ $( '#ctc_main' ).on( 'click', '.ctc-rewrite-toggle', function( e ) {
 
 
 
 
1264
  e.preventDefault();
1265
+ selector_input_toggle( this );
1266
+ } );
1267
+ $( '#ctc_main' ).on( 'click', '.ctc-section-toggle', function( e ) {
1268
+ $( this ).toggleClass( 'open' );
1269
+ var id = $( this ).attr( 'id' ) + '_content';
1270
+ $( '#' + id ).slideToggle( 'fast' );
1271
+ } );
1272
+ $( '#ctc_main' ).on( 'click', '#ctc_copy_selector', function( e ) {
1273
+ var txt = $( '#ctc_sel_ovrd_selector_selected' ).text().trim();
1274
+ if ( false === is_empty( txt ) )
1275
+ $( '#ctc_new_selectors' ).val( $( '#ctc_new_selectors' ).val() + "\n" + txt + " {\n\n}" );
1276
+ } );
1277
+ $( '#ctc_configtype' ).on( 'change', function( e ) {
1278
+ var val = $( this ).val();
1279
+ if ( is_empty( val ) || 'theme' == val ) {
1280
+ $( '.ctc-theme-only, .ctc-themeonly-container' ).removeClass( 'ctc-disabled' );
1281
+ $( '.ctc-theme-only, .ctc-themeonly-container input' ).prop( 'disabled', false );
1282
+ $( '#ctc_theme_parnt, #ctc_theme_child' ).themeMenu( 'enable' );
1283
+ } else {
1284
+ $( '.ctc-theme-only, .ctc-themeonly-container' ).addClass( 'ctc-disabled' );
1285
+ $( '.ctc-theme-only, .ctc-themeonly-container input' ).prop( 'disabled', true );
1286
+ $( '#ctc_theme_parnt, #ctc_theme_child' ).themeMenu( 'disable' );
1287
+ }
1288
+ }); // these elements are not replaced so use direct selector events
1289
+ $( '#view_child_options, #view_parnt_options' ).on( 'click', function(e){ render_css_preview( $( this ).attr( 'id' ) ); } );
1290
+ $( '#ctc_load_form' ).on( 'submit', function() {
1291
+ return ( validate() && confirm( ctcAjax.load_txt ) ) ;
1292
+ } );
1293
+ $( '#ctc_theme_child, #ctc_theme_child-button, #ctc_child_type_existing' ).on( 'focus click', function() {
1294
+ // change the inputs to use existing child theme
1295
+ $( '#ctc_child_type_existing' ).prop( 'checked', true );
1296
+ $( '#ctc_child_type_new' ).prop( 'checked', false );
1297
+ $( '#ctc_child_template' ).val( '' );
1298
+ set_existing();
1299
+ } );
1300
+ $( '#ctc_child_type_new, #ctc_child_template' ).on( 'focus click', function() {
1301
+ // change the inputs to use new child theme
1302
+ $( '#ctc_child_type_existing' ).prop( 'checked', false );
1303
+ $( '#ctc_child_type_new' ).prop( 'checked', true );
1304
+ $( '#ctc_child_name' ).val( testname );
1305
+ $( '#ctc_child_template' ).val( testslug );
1306
+ } );
1307
+ $( '#recent_edits' ).on( 'click', function(e){
1308
  e.preventDefault();
1309
+ $( '.wrap' ).css( { 'overflow':'hidden' } );
1310
+ if ( $( '.ctc-recent-container' ).is( ':visible' ) ) {
1311
+ $( this ).removeClass( 'open' );
1312
+ $( '.ctc-recent-container' ).stop().animate( { 'right': -200 }, function() { $( this ).hide(); } );
1313
+ $( '.ctc-option-panel' ).css( { 'width': '95%' } );
 
 
1314
  } else {
1315
+ $( this ).addClass( 'open' );
1316
+ $( '.ctc-recent-container' ).stop().css( { 'right': -200 } ).show().animate( { 'right': 0 } );
1317
+ $( '.ctc-option-panel' ).css( { 'width': '80%' } );
1318
  }
1319
+ $( '.wrap' ).css( { 'overflow':'inherit' } );
1320
+ return false;
1321
  });
1322
+ $( '.ctc-live-preview' ).on( 'click', function( e ) {
1323
+ e.stopImmediatePropagation();
1324
+ e.preventDefault();
1325
+ document.location = $( this ).prop( 'href' );
1326
+ return false;
1327
+ } );
1328
+ // initialize autoselect menus
1329
+ load_menus();
1330
+ set_query( current_query );
1331
+ // mark additional linked stylesheets for parsing
1332
+ set_addl_css();
1333
+ // show last 25 selectors edited
1334
+ render_recent();
1335
+ // turn on submit buttons (disabled until everything is loaded to prevent errors)
1336
+ $( 'input[type=submit], input[type=button]' ).prop( 'disabled', false );
1337
+ // disappear any notices after 6 seconds
1338
+ setTimeout( fade_update_notice, 15000 );
1339
+ } );
 
js/chld-thm-cfg.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(t){function e(t){return o(t)?t:t.toString().replace(G,"&quot;")}function c(e){t(e).iris({change:function(c,a){t(e).data("color",a.color.toString()),l(e)}})}function a(t){var e=parseInt(t),c=String.fromCharCode(e);return c}function n(t){var e=t.charCodeAt(0);return e}function l(e){var c=/^(ctc_(ovrd|\d+)_(parent|child)_([0-9a-z\-]+)_(\d+))(_\w+)?$/,a=t(e).parents(".ctc-selector-row, .ctc-parent-row").first(),n=a.find(".ctc-swatch").first(),l={parent:{},child:{}},r={parent:{origin:"",start:"",end:""},child:{origin:"",start:"",end:""}},s={child:!1,parent:!1},_={};return a.find(".ctc-parent-value, .ctc-child-value").each(function(){var a,n,u=t(this).attr("id"),d=u.toString().match(c),v=d[2],p=d[3],h="undefined"==typeof d[4]?"":d[4],f=d[5],x="undefined"==typeof d[6]?"":d[6],m="parent"==p?t(this).text().replace(/!$/,""):t(this).val(),g="ctc_"+v+"_child_"+h+"_i_"+f;if(!1===o(t(this).data("color"))&&(m=t(this).data("color"),t(this).data("color",null)),"child"==p&&(_[u]=m,_[g]=t("#"+g).is(":checked")?1:0),""!=m)if(!1===o(x))switch(x){case"_border_width":l[p][h+"-width"]=m;break;case"_border_style":l[p][h+"-style"]=m;break;case"_border_color":l[p][h+"-color"]=m;break;case"_background_url":l[p]["background-image"]=i(p,m);break;case"_background_color":l[p]["background-color"]=e.value;break;case"_background_color1":r[p].start=m,s[p]=!0;break;case"_background_color2":r[p].end=m,s[p]=!0;break;case"_background_origin":r[p].origin=m,s[p]=!0}else(a=h.toString().match(/^border(\-(top|right|bottom|left))?$/)&&!m.match(/none/))?(n=m.toString().split(/ +/),l[p][h+"-width"]="undefined"==typeof n[0]?"":n[0],l[p][h+"-style"]="undefined"==typeof n[1]?"":n[1],l[p][h+"-color"]="undefined"==typeof n[2]?"":n[2]):"background-image"!=h||m.match(/none/)?"seq"!=h&&(l[p][h]=m):m.toString().match(/url\(/)?l[p]["background-image"]=i(p,m):(n=m.toString().split(/ +/),n.length>2?(r[p].origin="undefined"==typeof n[0]?"top":n[0],r[p].start="undefined"==typeof n[1]?"transparent":n[1],r[p].end="undefined"==typeof n[2]?"transparent":n[2],s[p]=!0):l[p]["background-image"]=m)}),"undefined"!=typeof n&&!1===o(n.attr("id"))&&(n.removeAttr("style"),s.parent&&n.ctcgrad(r.parent.origin,[r.parent.start,r.parent.end]),n.css(l.parent),n.attr("id").toString().match(/parent/)||(s.child&&n.ctcgrad(r.child.origin,[r.child.start,r.child.end]),n.css(l.child)),n.css({"z-index":-1})),_}function r(e){var c,a,n;t(e).each(function(){switch(this.obj){case"imports":ctcAjax.imports=this.data;break;case"rule_val":ctcAjax.rule_val[this.key]=this.data,n=this.key;break;case"val_qry":ctcAjax.val_qry[this.key]=this.data;break;case"rule":ctcAjax.rule=this.data;break;case"sel_ndx":o(this.key)?ctcAjax.sel_ndx=this.data:"qsid"==this.key?(o(ctcAjax.sel_ndx[this.data.query])&&(ctcAjax.sel_ndx[this.data.query]={}),ctcAjax.sel_ndx[this.data.query][this.data.selector]=this.data.qsid):(ctcAjax.sel_ndx[this.key]=this.data,c=this.key);break;case"sel_val":ctcAjax.sel_val[this.key]=this.data,a=this.key;break;case"rewrite":P=this.key,U=this.data}})}function i(t,e){var c,a=e.toString().match(/url\(['" ]*(.+?)['" ]*\)/),n=o(a)?null:a[1],l=ctcAjax.theme_uri+"/"+("parent"==t?ctcAjax.parnt:ctcAjax.child)+"/";return n?c=n.toString().match(/^(data:|https?:|\/)/)?e:"url("+l+n+")":!1}function o(t){if("undefined"==typeof t||!1===t||null===t||""===t)return!0;if(!0===t||"string"==typeof t||"number"==typeof t)return!1;if("object"==typeof t){for(var e in t)if(t.hasOwnProperty(e))return!1;return!0}return!1}function s(){var e=[];return 1===K.sel_ndx?e:0===K.sel_ndx?(K.sel_ndx=1,x("sel_ndx",null,b),e):(!1===o(ctcAjax.sel_ndx)&&t.each(ctcAjax.sel_ndx,function(t){var c={label:t,value:t};e.push(c)}),e)}function _(e){var c=[];return 1===K.sel_ndx?c:0===K.sel_ndx?(K.sel_ndx=1,x("sel_ndx",e,A),c):(!1===o(ctcAjax.sel_ndx[e])&&t.each(ctcAjax.sel_ndx[e],function(t,e){var a={label:t,value:e};c.push(a)}),c)}function u(){var e=[];return 1===K.rule?e:0===K.rule?(K.rule=1,x("rule",null,k),e):(!1===o(ctcAjax.rule)&&t.each(ctcAjax.rule,function(t,c){var n={label:c.replace(/\d+/g,a),value:t};e.push(n)}),e.sort(function(t,e){return t.label>e.label?1:t.label<e.label?-1:0}))}function d(c,n,l){var r="",i=o(ctcAjax.sel_val[c])||o(ctcAjax.sel_val[c].value)||o(ctcAjax.sel_val[c].value[n])?"":ctcAjax.sel_val[c].value[n],s=g(n,"undefined"==typeof i?"":i.parnt),_=!1===o(i.i_parnt)&&i.i_parnt?ctcAjax.important_label:"",u=g(n,"undefined"==typeof i?"":i.child),d=!1===o(i.i_child)&&i.i_child?1:0,v="ctc_"+l+"_child_"+n+"_i_"+c;return!1===o(ctcAjax.sel_val[c])&&(r+='<div class="ctc-'+("ovrd"==l?"input":"selector")+'-row clearfix">'+Q,r+='<div class="ctc-input-cell">'+("ovrd"==l?n.replace(/\d+/g,a):ctcAjax.sel_val[c].selector+'<br/><a href="#" class="ctc-selector-edit" id="ctc_selector_edit_'+c+'" >'+ctcAjax.edit_txt+"</a> "+(o(s.orig)?ctcAjax.child_only_txt:""))+"</div>"+Q,"ovrd"==l&&(r+='<div class="ctc-parent-value ctc-input-cell" id="ctc_'+l+"_parent_"+n+"_"+c+'">'+(o(s.orig)?"[no value]":s.orig+_)+"</div>"+Q),r+='<div class="ctc-input-cell">'+Q,!1===o(s.names)&&(t.each(s.names,function(t,a){a=o(a)?"":a,r+='<div class="ctc-child-input-cell">'+Q;var i,s="ctc_"+l+"_child_"+n+"_"+c+a;!1===(i=u.values.shift())&&(i=""),r+=(o(a)?"":ctcAjax.field_labels[a]+":<br/>")+'<input type="text" id="'+s+'" name="'+s+'" class="ctc-child-value'+((a+n).toString().match(/color/)?" color-picker":"")+(a.toString().match(/url/)?" ctc-input-wide":"")+'" value="'+e(i)+'" />'+Q,r+="</div>"+Q}),r+='<label for="'+v+'"><input type="checkbox" id="'+v+'" name="'+v+'" value="1" '+(1===d?"checked":"")+" />"+ctcAjax.important_label+"</label>"+Q),r+="</div>"+Q,r+="ovrd"==l?"":'<div class="ctc-swatch ctc-specific" id="ctc_child_'+n+"_"+c+'_swatch">'+ctcAjax.swatch_txt+"</div>"+Q+'<div class="ctc-child-input-cell ctc-button-cell" id="ctc_save_'+n+"_"+c+'_cell">'+Q+'<input type="button" class="button ctc-save-input" id="ctc_save_'+n+"_"+c+'" name="ctc_save_'+n+"_"+c+'" value="Save" /></div>'+Q,r+="</div><!-- end input row -->"+Q),r}function v(e){if(1===K.sel_val)return!1;if(0==K.sel_val)return K.sel_val=1,x("sel_val",e,v),!1;var a,n,r;o(ctcAjax.sel_val[e])?t("#ctc_sel_ovrd_rule_inputs").html(""):(o(ctcAjax.sel_val[e].seq)?t("#ctc_child_load_order_container").html(""):(a="ctc_ovrd_child_seq_"+e,r=parseInt(ctcAjax.sel_val[e].seq),n='<input type="text" id="'+a+'" name="'+a+'" class="ctc-child-value" value="'+r+'" />',t("#ctc_child_load_order_container").html(n)),o(ctcAjax.sel_val[e].value)?t("#ctc_sel_ovrd_rule_inputs").html(""):(n="",t.each(ctcAjax.sel_val[e].value,function(t){n+=d(e,t,"ovrd")}),t("#ctc_sel_ovrd_rule_inputs").html(n).find(".color-picker").each(function(){c(this)}),l("#ctc_child_all_0_swatch")))}function p(e){if(1===K.preview)return!1;if(0==K.preview){K.preview=1;var e;return(e=t(this).attr("id").toString().match(/(child|parnt)/)[1])||(e="child"),R(""),x("preview",e,p),!1}2==K.preview&&(t("#view_"+e+"_options_panel").text(ctcAjax.previewResponse),K.preview=0)}function h(e){if(1===K.rule_val)return!1;if(0==K.rule_val)return K.rule_val=1,x("rule_val",e,h),!1;var c=ctcAjax.rule[e],a='<div class="ctc-input-row clearfix" id="ctc_rule_row_'+c+'">'+Q;!1===o(ctcAjax.rule_val[e])&&(t.each(ctcAjax.rule_val[e],function(t,e){var n=g(c,e);a+='<div class="ctc-parent-row clearfix" id="ctc_rule_row_'+c+"_"+t+'">'+Q,a+='<div class="ctc-input-cell ctc-parent-value" id="ctc_'+t+"_parent_"+c+"_"+t+'">'+n.orig+"</div>"+Q,a+='<div class="ctc-input-cell">'+Q,a+='<div class="ctc-swatch ctc-specific" id="ctc_'+t+"_parent_"+c+"_"+t+'_swatch">'+ctcAjax.swatch_txt+"</div></div>"+Q,a+='<div class="ctc-input-cell"><a href="#" class="ctc-selector-handle" id="ctc_selector_'+c+"_"+t+'">'+ctcAjax.selector_txt+"</a></div>"+Q,a+='<div id="ctc_selector_'+c+"_"+t+'_container" class="ctc-selector-container">'+Q,a+='<a href="#" id="ctc_selector_'+c+"_"+t+'_close" class="ctc-selector-handle ctc-exit" title="'+ctcAjax.close_txt+'"></a>',a+='<div id="ctc_selector_'+c+"_"+t+'_inner_container" class="ctc-selector-inner-container clearfix">'+Q,a+='<div id="ctc_status_val_qry_'+t+'"></div>'+Q,a+='<div id="ctc_selector_'+c+"_"+t+'_rows"></div>'+Q,a+="</div></div></div>"+Q}),a+="</div>"+Q),t("#ctc_rule_value_inputs").html(a).find(".ctc-swatch").each(function(){l(this)})}function f(e){if(1==K.val_qry)return!1;var a,r,i=t("#ctc_rule_menu_selected").text().replace(/[^\w\-]/g,n),s="";return 0===K.val_qry?(K.val_qry=1,a={rule:i},x("val_qry",e,f,a),!1):(!1===o(ctcAjax.val_qry[e])&&t.each(ctcAjax.val_qry[e],function(c,a){page_rule=c,t.each(a,function(a,n){s+='<h4 class="ctc-query-heading">'+a+"</h4>"+Q,!1===o(n)&&t.each(n,function(t,a){ctcAjax.sel_val[t]=a,s+=d(t,c,e)})})}),r="#ctc_selector_"+i+"_"+e+"_rows",t(r).html(s).find(".color-picker").each(function(){c(this)}),void t(r).find(".ctc-swatch").each(function(){l(this)}))}function x(e,c,a,n){var l={ctc_query_obj:e,ctc_query_key:c},i="#ctc_status_"+e+("val_qry"==e?"_"+c:"");return"object"==typeof n&&t.each(n,function(t,e){l["ctc_query_"+t]=e}),t(".ctc-status-icon").remove(),t(i).append('<span class="ctc-status-icon spinner"></span>'),t(".spinner").show(),l.action="ctc_query",l._wpnonce=t("#_wpnonce").val(),t.post(ctcAjax.ajaxurl,l,function(n){return K[e]=2,t(".ctc-status-icon").removeClass("spinner"),o(n)?(t(".ctc-status-icon").addClass("failure"),void("preview"==e&&(ctcAjax.previewResponse=ctcAjax.css_fail_txt,a(c)))):(t(".ctc-status-icon").addClass("success"),"preview"==e?ctcAjax.previewResponse=n.shift().data:r(n),"function"==typeof a&&a(c),!1)},"json").fail(function(){t(".ctc-status-icon").removeClass("spinner"),t(".ctc-status-icon").addClass("failure"),"preview"==e?(ctcAjax.previewResponse=ctcAjax.css_fail_txt,K[e]=2,a(c)):K[e]=0}),!1}function m(e){var c,a,n,i,s={},_=t(e).attr("id");return o(B[_])&&(B[_]=0),B[_]++,t(e).prop("disabled",!0),t(".ctc-status-icon").remove(),t(e).parent(".ctc-textarea-button-cell, .ctc-button-cell").append('<span class="ctc-status-icon spinner"></span>'),t(".spinner").show(),(c=t("#ctc_new_selectors"))&&"ctc_save_new_selectors"==t(e).attr("id")?(s.ctc_new_selectors=c.val(),(a=t("#ctc_sel_ovrd_query_selected"))&&(s.ctc_sel_ovrd_query=a.text())):(n=t("#ctc_child_imports"))&&"ctc_save_imports"==t(e).attr("id")?s.ctc_child_imports=n.val():s=l(e),t("#ctc_sel_ovrd_selector_selected").find("#ctc_rewrite_selector").each(function(){i=t("#ctc_rewrite_selector").val(),origsel=t("#ctc_rewrite_selector_orig").val(),o(i)||!i.toString().match(/\w/)?i=origsel:s.ctc_rewrite_selector=i,t(".ctc-rewrite-toggle").text(ctcAjax.rename_txt),t("#ctc_sel_ovrd_selector_selected").html(i)}),s.action="ctc_update",s._wpnonce=t("#_wpnonce").val(),t.post(ctcAjax.ajaxurl,s,function(c){return t(e).prop("disabled",!1),t(".ctc-status-icon").removeClass("spinner"),o(c)?t(".ctc-status-icon").addClass("failure"):(t(".ctc-status-icon").addClass("success"),t("#ctc_new_selectors").val(""),r(c),C(),!1===o(P)&&(y(P,U),P=U=null)),!1},"json").fail(function(){t(e).prop("disabled",!1),t(".ctc-status-icon").removeClass("spinner"),t(".ctc-status-icon").addClass("failure")}),!1}function g(t,e){e="undefined"==typeof e?"":e;var c={orig:e};if(t.toString().match(/^border(\-(top|right|bottom|left))?$/)){var a=e.toString().split(/ +/);c.names=["_border_width","_border_style","_border_color"],c.values=["undefined"==typeof a[0]?"":a[0],"undefined"==typeof a[1]?"":a[1],"undefined"==typeof a[2]?"":a[2]]}else if(t.toString().match(/^background\-image/))if(c.names=["_background_url","_background_origin","_background_color1","_background_color2"],c.values=["","","",""],!1!==o(e)||e.toString().match(/(url|none)/))c.values[0]=e;else{var a=e.toString().split(/:/);c.values[1]="undefined"==typeof a[0]?"":a[0],c.values[2]="undefined"==typeof a[1]?"":a[1],c.values[3]="undefined"==typeof a[3]?"":a[3],c.orig=[c.values[1],c.values[2],c.values[3]].join(" ")}else c.names=[""],c.values=[e];return c}function w(e){V=e,t("#ctc_sel_ovrd_query").val(""),t("#ctc_sel_ovrd_query_selected").text(e),t("#ctc_sel_ovrd_selector").val(""),t("#ctc_sel_ovrd_selector_selected").html("&nbsp;"),t("#ctc_sel_ovrd_rule_inputs").html(""),A(e),l("#ctc_child_all_0_swatch"),t("#ctc_new_selector_row").show()}function y(e,c){t("#ctc_sel_ovrd_selector").val(""),t("#ctc_sel_ovrd_selector_selected").text(c),t("#ctc_sel_ovrd_qsid").val(e),O=e,1!=K.sel_val&&(K.sel_val=0),v(e),t(".ctc-rewrite-toggle").text(ctcAjax.rename_txt),t("#ctc_sel_ovrd_new_rule, #ctc_sel_ovrd_rule_header,#ctc_sel_ovrd_rule_inputs_container,#ctc_sel_ovrd_rule_inputs,.ctc-rewrite-toggle").show()}function j(e,c){t("#ctc_rule_menu").val(""),t("#ctc_rule_menu_selected").text(c),1!=K.rule_val&&(K.rule_val=0),h(e),t(".ctc-rewrite-toggle").text(ctcAjax.rename_txt),t("#ctc_rule_value_inputs,#ctc_input_row_rule_header").show()}function b(){X=s(),t("#ctc_sel_ovrd_query").autocomplete({source:X,minLength:0,selectFirst:!0,autoFocus:!0,select:function(t,e){return w(e.item.value),!1},focus:function(t){t.preventDefault()}})}function A(e){W=_(e),t("#ctc_sel_ovrd_selector").autocomplete({source:W,selectFirst:!0,autoFocus:!0,select:function(t,e){return y(e.item.value,e.item.label),!1},focus:function(t){t.preventDefault()}})}function k(){Y=u(),t("#ctc_rule_menu").autocomplete({source:Y,selectFirst:!0,autoFocus:!0,select:function(t,e){return j(e.item.value,e.item.label),!1},focus:function(t){t.preventDefault()}})}function q(e,c){var n=[],l=o(ctcAjax.sel_val[O])||o(ctcAjax.sel_val[O].value);o(Y)&&(Y=u()),t.each(Y,function(c,r){var i=!1,o=new RegExp(t.ui.autocomplete.escapeRegex(e.term),"i");if(o.test(r.label)){if(!1===l&&(t.each(ctcAjax.sel_val[O].value,function(t){return r.label==t.replace(/\d+/g,a)?(i=!0,!1):void 0}),i))return;n.push(r)}}),c(n)}function S(){t("#ctc_new_rule_menu").autocomplete({source:q,selectFirst:!0,autoFocus:!0,select:function(e,a){e.preventDefault();var l=t(d(O,a.item.label.replace(/[^\w\-]/g,n),"ovrd"));return t("#ctc_sel_ovrd_rule_inputs").append(l),t("#ctc_new_rule_menu").val(""),o(ctcAjax.sel_val[O].value)&&(ctcAjax.sel_val[O].value={}),ctcAjax.sel_val[O].value[a.item.label]={child:""},l.find('input[type="text"]').each(function(e,a){t(a).hasClass("color-picker")&&c(a),t(a).focus()}),!1},focus:function(t){t.preventDefault()}})}function C(){b(),A(V),k(),S()}function D(e,c){var a=!1;return t.each(ctcAjax.themes,function(n,l){return t.each(l,function(t){return t!=e||"parnt"!=n&&"new"!=c?void 0:(a=!0,!1)}),a?!1:void 0}),a}function F(){for(var e=t("#ctc_theme_parnt").val(),c=slugbase=e+"-child",a=ctcAjax.themes.parnt[e].Name+" Child",n="",l="",r="00";D(c,"new");)n=""==n?2:n+1,l=r.substring(0,r.length-n.toString().length)+n.toString(),c=slugbase+l;H=c,J=a+(l.length?" "+l:"")}function R(e){var c="";!1===o(e)&&t.each(e,function(e,a){c+='<div class="'+e+'"><ul>'+Q,t(a).each(function(t,e){c+="<li>"+e.toString()+"</li>"+Q}),c+="</ul></div>"}),t("#ctc_error_notice").html(c)}function T(){var e=/[^\w\-]/,c=t("#ctc_child_template").val().toString().replace(e).toLowerCase(),a=t("#ctc_theme_child").val().toString().replace(e).toLowerCase(),n=t("input[name=ctc_child_type]:checked").val(),l=[];return"new"==n&&(a=c),D(a,n)&&l.push(ctcAjax.theme_exists_txt.toString().replace(/%s/,a)),""===a&&l.push(ctcAjax.inval_theme_txt),""===t("#ctc_child_name").val()&&l.push(ctcAjax.inval_name_txt),l.length?(R({error:l}),!1):!0}function $(e){t("#ctc_theme_parent").parents(".ctc-input-row").first().append('<span class="ctc-status-icon spinner"></span>'),t(".spinner").show(),document.location="?page="+ctcAjax.page+"&ctc_parent="+e.value}function I(e){!1===o(ctcAjax.themes.child[e.value])&&(t("#ctc_child_name").val(ctcAjax.themes.child[e.value].Name),t("#ctc_child_author").val(ctcAjax.themes.child[e.value].Author),t("#ctc_child_version").val(ctcAjax.themes.child[e.value].Version))}function z(){t(".updated, .error").slideUp("slow",function(){t(".updated").remove()})}function E(){var e,c=t("#ctc_theme_parnt").val(),a=ctcAjax.theme_uri.replace(/^https?:\/\//,""),n=ctcAjax.homeurl.replace(/^https?/,ctcAjax.ssl?"https":"http"),l=n+"?preview=1&p=x&template="+c+"&stylesheet="+c,r=new RegExp("<link rel=[\"']stylesheet[\"'][^>]+?"+a+"/"+c+"/(.+?\\.css)[^>]+?>","g");o(c)||t.get(l,function(c){for(;(e=r.exec(c))&&"style.css"!=e[1];)e[1].match(/bootstrap/)||(ctcAjax.addl_css.push(e[1]),t(".ctc_checkbox").each(function(){t(this).val()==e[1]&&t(this).prop("checked",!0)}))})}function L(e){var c=e+"_panel";t(".nav-tab").removeClass("nav-tab-active"),t(".ctc-option-panel").removeClass("ctc-option-panel-active"),t(".ctc-selector-container").hide(),t(e).addClass("nav-tab-active"),t(".ctc-option-panel-container").scrollTop(0),t(c).addClass("ctc-option-panel-active")}function M(e){var c=t(e).attr("id").match(/_(\d+)$/)[1],a=ctcAjax.sel_val[c].query,n=ctcAjax.sel_val[c].selector,l="#query_selector_options";w(a),y(c,n),L(l)}function N(c){var a;t("#ctc_rewrite_selector").length?(a=t("#ctc_rewrite_selector_orig").val(),t("#ctc_sel_ovrd_selector_selected").text(a),t(c).text(ctcAjax.rename_txt)):(a=t("#ctc_sel_ovrd_selector_selected").text(),t("#ctc_sel_ovrd_selector_selected").html('<input id="ctc_rewrite_selector" name="ctc_rewrite_selector" type="text" value="'+e(a)+'" autocomplete="off" /><input id="ctc_rewrite_selector_orig" name="ctc_rewrite_selector_orig" type="hidden" value="'+e(a)+'"/>'),t(c).text(ctcAjax.cancel_txt))}var O,P,U,Q="\n",V="base",B={},G=new RegExp('"',"g"),H="",J="",K={rule:2,sel_ndx:2,val_qry:0,rule_val:0,sel_val:0,preview:0},W=[],X=[],Y=[];F(),t.widget("ctc.themeMenu",t.ui.selectmenu,{_renderItem:function(e,c){var a=t("<li>");return t("#ctc_theme_option_"+c.value).detach().appendTo(a),a.appendTo(e)}}),t("#ctc_theme_parnt").themeMenu({select:function(t,e){$(e.item)}}),o(ctcAjax.themes.child)?(t("#ctc_child_name").val(J),t("#ctc_child_template").val(H)):t("#ctc_theme_child").themeMenu({select:function(t,e){I(e.item)}}),t(".ctc-option-panel-container").on("focus",".color-picker",function(){R(""),t(".color-picker").not(this).iris("hide"),t(this).iris("toggle"),t(".iris-picker").css({position:"absolute","z-index":10})}),t(".ctc-option-panel-container").on("change",".ctc-child-value, input[type=checkbox]",function(){l(this)}),t(".ctc-option-panel-container").on("click",".ctc-selector-handle",function(e){e.preventDefault(),R("");var c=t(this).attr("id").toString().replace("_close",""),a=c.toString().match(/_(\d+)$/)[1];t("#"+c+"_container").is(":hidden")&&(1!=K.val_qry&&(K.val_qry=0),f(a)),t("#"+c+"_container").fadeToggle("fast"),t(".ctc-selector-container").not("#"+c+"_container").fadeOut("fast")}),t(".nav-tab").on("click",function(e){e.preventDefault(),R(""),t(".ctc-status-icon").remove();var c="#"+t(this).attr("id");L(c)}),t("#view_child_options,#view_parnt_options").on("click",p),t("#ctc_load_form").on("submit",function(){return T()&&confirm(ctcAjax.load_txt)}),t(document).on("click",".ctc-save-input",function(){m(this)}),t(document).on("click",".ctc-selector-edit",function(){M(this)}),t(document).on("click",".ctc-rewrite-toggle",function(t){t.preventDefault(),N(this)}),t(document).on("click",".ctc-section-toggle",function(){t(this).toggleClass("open");var e=t(this).attr("id")+"_content";t("#"+e).slideToggle("fast")}),t(document).on("click",".ctc-live-preview",function(e){return e.stopImmediatePropagation(),e.preventDefault(),document.location=t(this).prop("href"),!1}),t(document).on("change","#ctc_configtype",function(){var e=t(this).val();o(e)||"theme"==e?t(".ctc-theme-only").stop().slideDown("fast"):t(".ctc-theme-only").stop().slideUp("fast")}),t("#ctc_theme_child,#ctc_theme_child-button,#ctc_child_type_existing").on("focus click",function(){t("#ctc_child_type_existing").prop("checked",!0),t("#ctc_child_type_new").prop("checked",!1),t("#ctc_child_template").val("")}),t("#ctc_child_type_new,#ctc_child_template").on("focus click",function(){t("#ctc_child_type_existing").prop("checked",!1),t("#ctc_child_type_new").prop("checked",!0),t("#ctc_child_name").val(J),t("#ctc_child_template").val(H)}),C(),w(V),E(),t("input[type=submit],input[type=button]").prop("disabled",!1),setTimeout(z,6e3)});
1
+ jQuery(document).ready(function(e){function t(e){return v(e)?e:e.toString().replace(K,"&quot;")}function c(e){var t=parseInt(e),c=String.fromCharCode(t);return c}function a(e){var t=e.charCodeAt(0);return t}function l(t,c){var a=!1;return e.each(ctcAjax.themes,function(l,n){return e.each(n,function(e){return e!=t||"parnt"!=l&&"new"!=c?void 0:(a=!0,!1)}),a?!1:void 0}),a}function n(){var t=/[^\w\-]/,c=e("#ctc_child_template").val().toString().replace(t).toLowerCase(),a=e("#ctc_theme_child").val().toString().replace(t).toLowerCase(),n=e("input[name=ctc_child_type]:checked").val(),r=[];return"new"==n&&(a=c),l(a,n)&&r.push(ctcAjax.theme_exists_txt.toString().replace(/%s/,a)),""===a&&r.push(ctcAjax.inval_theme_txt),""===e("#ctc_child_name").val()&&r.push(ctcAjax.inval_name_txt),r.length?($({error:r}),!1):!0}function r(){if(e("#ctc_theme_parnt").length){for(var t=e("#ctc_theme_parnt").val(),c=slugbase=t+"-child",a=ctcAjax.themes.parnt[t].Name+" Child",n="",r="",i="00";l(c,"new");)n=""==n?2:n+1,r=i.substring(0,i.length-n.toString().length)+n.toString(),c=slugbase+r;W=c,X=a+(r.length?" "+r:"")}}function i(t){var c=t+"_panel";e(".nav-tab").removeClass("nav-tab-active"),e(".ctc-option-panel").removeClass("ctc-option-panel-active"),e(".ctc-selector-container").hide(),e(t).addClass("nav-tab-active"),e(".ctc-option-panel-container").scrollTop(0),e(c).addClass("ctc-option-panel-active")}function s(c){var a;e("#ctc_rewrite_selector").length?(a=e("#ctc_rewrite_selector_orig").val(),e("#ctc_sel_ovrd_selector_selected").text(a),e(c).text(ctcAjax.rename_txt)):(a=e("#ctc_sel_ovrd_selector_selected").text(),e("#ctc_sel_ovrd_selector_selected").html('<textarea id="ctc_rewrite_selector" name="ctc_rewrite_selector" autocomplete="off"></textarea><input id="ctc_rewrite_selector_orig" name="ctc_rewrite_selector_orig" type="hidden" value="'+t(a)+'"/>'),e("#ctc_rewrite_selector").val(a),e(c).text(ctcAjax.cancel_txt))}function o(){e(".updated, .error").slideUp("slow",function(){e(".updated").remove()})}function _(t){var c=/^(ctc_(ovrd|\d+)_(parent|child)_([0-9a-z\-]+)_(\d+))(_\w+)?$/,a=e(t).parents(".ctc-selector-row, .ctc-parent-row").first(),l=a.find(".ctc-swatch").first(),n={parent:{},child:{}},r={parent:{origin:"",start:"",end:""},child:{origin:"",start:"",end:""}},i={child:!1,parent:!1},s={};return a.find(".ctc-parent-value, .ctc-child-value").each(function(){var a,l,o=e(this).attr("id"),_=o.toString().match(c),u=_[2],h=_[3],p="undefined"==typeof _[4]?"":_[4],f=_[5],x="undefined"==typeof _[6]?"":_[6],m="parent"==h?e(this).text().replace(/!$/,""):e(this).val(),g="ctc_"+u+"_child_"+p+"_i_"+f;if(!1===v(e(this).data("color"))&&(m=e(this).data("color"),e(this).data("color",null)),"child"==h&&(s[o]=m,s[g]=e("#"+g).is(":checked")?1:0),""!=m)if(!1===v(x))switch(x){case"_border_width":n[h][p+"-width"]="none"==m?0:m;break;case"_border_style":n[h][p+"-style"]=m;break;case"_border_color":n[h][p+"-color"]=m;break;case"_background_url":n[h]["background-image"]=d(h,m);break;case"_background_color":n[h]["background-color"]=t.value;break;case"_background_color1":r[h].start=m,i[h]=!0;break;case"_background_color2":r[h].end=m,i[h]=!0;break;case"_background_origin":r[h].origin=m,i[h]=!0}else(a=p.toString().match(/^border(\-(top|right|bottom|left))?$/)&&!m.match(/none/))?(l=m.toString().split(/ +/),n[h][p+"-width"]="undefined"==typeof l[0]?"":l[0],n[h][p+"-style"]="undefined"==typeof l[1]?"":l[1],n[h][p+"-color"]="undefined"==typeof l[2]?"":l[2]):"background-image"!=p||m.match(/none/)?"seq"!=p&&(n[h][p]=m):m.toString().match(/url\(/)?n[h]["background-image"]=d(h,m):(l=m.toString().split(/ +/),l.length>2?(r[h].origin="undefined"==typeof l[0]?"top":l[0],r[h].start="undefined"==typeof l[1]?"transparent":l[1],r[h].end="undefined"==typeof l[2]?"transparent":l[2],i[h]=!0):n[h]["background-image"]=m)}),"undefined"!=typeof l&&!1===v(l.attr("id"))&&(l.removeAttr("style"),i.parent&&l.ctcgrad(r.parent.origin,[r.parent.start,r.parent.end]),l.css(n.parent),l.attr("id").toString().match(/parent/)||(i.child&&l.ctcgrad(r.child.origin,[r.child.start,r.child.end]),l.css(n.child)),l.css({"z-index":-1})),s}function u(e,t){t="undefined"==typeof t?"":t;var c={orig:t};if(e.toString().match(/^border(\-(top|right|bottom|left))?$/)){var a=t.toString().split(/ +/);c.names=["_border_width","_border_style","_border_color"],c.values=["undefined"==typeof a[0]?"":a[0],"undefined"==typeof a[1]?"":a[1],"undefined"==typeof a[2]?"":a[2]]}else if(e.toString().match(/^background\-image/))if(c.names=["_background_url","_background_origin","_background_color1","_background_color2"],c.values=["","","",""],!1!==v(t)||t.toString().match(/(url|none)/))c.values[0]=t;else{var a=t.toString().split(/:/);c.values[1]="undefined"==typeof a[0]?"":a[0],c.values[2]="undefined"==typeof a[1]?"":a[1],c.values[3]="undefined"==typeof a[3]?"":a[3],c.orig=[c.values[1],c.values[2],c.values[3]].join(" ")}else c.names=[""],c.values=[t];return c}function d(e,t){var c,a=t.toString().match(/url\(['" ]*(.+?)['" ]*\)/),l=v(a)?null:a[1],n=ctcAjax.theme_uri+"/"+("parent"==e?ctcAjax.parnt:ctcAjax.child)+"/";return l?c=l.toString().match(/^(data:|https?:|\/)/)?t:"url("+n+l+")":!1}function v(e){if("undefined"==typeof e||!1===e||null===e||""===e)return!0;if(!0===e||"string"==typeof e||"number"==typeof e)return!1;if("object"==typeof e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0}return!1}function h(e){if("object"==typeof ctcAjax.sel_val[e]&&"object"==typeof ctcAjax.sel_val[e].value)for(var t in ctcAjax.sel_val[e].value)if(ctcAjax.sel_val[e].value.hasOwnProperty(t)&&(!1===v(ctcAjax.sel_val[e].value[t].child)||!1===v(ctcAjax.sel_val[e].value[t].parnt)))return e;return delete ctcAjax.sel_val[e],!1}function p(){Z.rld_rule=1,Z.rld_sel=1,f(),m()}function f(){if(1!==Z.sel_ndx){if(0===Z.sel_ndx||1==Z.rld_sel)return Z.sel_ndx=1,Z.rld_sel=0,void P("sel_ndx",null,f);tt=[],!1===v(ctcAjax.sel_ndx)&&e.each(ctcAjax.sel_ndx,function(e){var t={label:e,value:e};tt.push(t)}),C(),x()}}function x(){if(1!==Z.sel_ndx){if(0===Z.sel_ndx)return Z.sel_ndx=1,void P("sel_ndx",Y,x);et=[],!1===v(ctcAjax.sel_ndx)&&e.each(ctcAjax.sel_ndx[Y],function(e,t){var c={label:e,value:t};et.push(c)}),D(),Z.set_sel&&(Z.set_sel=0,E(H,null))}}function m(){if(1!==Z.rule){if(0===Z.rule||1==Z.rld_rule)return Z.rule=1,Z.rld_rule=0,void P("rule",null,m);ct=[],!1===v(ctcAjax.rule)&&e.each(ctcAjax.rule,function(e,t){var a={label:t.replace(/\d+/g,c),value:e};ct.push(a)}),ct=ct.sort(function(e,t){return e.label>t.label?1:e.label<t.label?-1:0}),R(),F()}}function g(e){return 1===Z.sel_val?!1:v(ctcAjax.sel_val[e])?(0==Z.sel_val&&(Z.sel_val=1,P("sel_val",e,g)),!1):(H=e,void(1==Z.set_qry?(Z.set_qry=0,z(ctcAjax.sel_val[e].query)):1==Z.new_sel&&(Z.new_sel=0,w(e))))}function y(t,a){var l=[],n=v(ctcAjax.sel_val[H])||v(ctcAjax.sel_val[H].value);v(ct)&&m(),e.each(ct,function(a,r){var i=!1,s=new RegExp(e.ui.autocomplete.escapeRegex(t.term),"i");if(s.test(r.label)){if(!1===n&&(e.each(ctcAjax.sel_val[H].value,function(e){return r.label==e.replace(/\d+/g,c)?(i=!0,!1):void 0}),i))return;l.push(r)}}),a(l)}function j(a,l,n){var r="",i=v(ctcAjax.sel_val[a])||v(ctcAjax.sel_val[a].value)||v(ctcAjax.sel_val[a].value[l])?"":ctcAjax.sel_val[a].value[l],s=u(l,"undefined"==typeof i?"":i.parnt),o=!1===v(i.i_parnt)&&1==i.i_parnt?ctcAjax.important_label:"",_=u(l,"undefined"==typeof i?"":i.child),d=!1===v(i.i_child)&&1==i.i_child?1:0,h="ctc_"+n+"_child_"+l+"_i_"+a;return!1===v(ctcAjax.sel_val[a])&&(r+='<div class="ctc-'+("ovrd"==n?"input":"selector")+'-row clearfix">'+J,r+='<div class="ctc-input-cell">'+("ovrd"==n?l.replace(/\d+/g,c):ctcAjax.sel_val[a].selector+'<br/><a href="#" class="ctc-selector-edit" id="ctc_selector_edit_'+a+'" >'+ctcAjax.edit_txt+"</a> "+(v(s.orig)?ctcAjax.child_only_txt:""))+"</div>"+J,"ovrd"==n&&(r+='<div class="ctc-parent-value ctc-input-cell" id="ctc_'+n+"_parent_"+l+"_"+a+'">'+(v(s.orig)?"[no value]":s.orig+o)+"</div>"+J),r+='<div class="ctc-input-cell">'+J,!1===v(s.names)&&(e.each(s.names,function(e,c){c=v(c)?"":c,r+='<div class="ctc-child-input-cell">'+J;var i,s="ctc_"+n+"_child_"+l+"_"+a+c;!1===(i=_.values.shift())&&(i=""),r+=(v(c)?"":ctcAjax.field_labels[c]+":<br/>")+'<input type="text" id="'+s+'" name="'+s+'" class="ctc-child-value'+((c+l).toString().match(/color/)?" color-picker":"")+(c.toString().match(/url/)?" ctc-input-wide":"")+'" value="'+t(i)+'" />'+J,r+="</div>"+J}),r+='<label for="'+h+'"><input type="checkbox" id="'+h+'" name="'+h+'" value="1" '+(1===d?"checked":"")+" />"+ctcAjax.important_label+"</label>"+J),r+="</div>"+J,r+="ovrd"==n?"":'<div class="ctc-swatch ctc-specific" id="ctc_child_'+l+"_"+a+'_swatch">'+ctcAjax.swatch_txt+"</div>"+J+'<div class="ctc-child-input-cell ctc-button-cell" id="ctc_save_'+l+"_"+a+'_cell">'+J+'<input type="button" class="button ctc-save-input" id="ctc_save_'+l+"_"+a+'" name="ctc_save_'+l+"_"+a+'" value="Save" /></div>'+J,r+="</div><!-- end input row -->"+J),r}function w(t){var c,a,l;(t=h(t))?(e("#ctc_sel_ovrd_qsid").val(t),H=t,v(ctcAjax.sel_val[t].seq)?e("#ctc_child_load_order_container").html(""):(c="ctc_ovrd_child_seq_"+t,l=parseInt(ctcAjax.sel_val[t].seq),a='<input type="text" id="'+c+'" name="'+c+'" class="ctc-child-value" value="'+l+'" />',e("#ctc_child_load_order_container").html(a)),v(ctcAjax.sel_val[t].value)?e("#ctc_sel_ovrd_rule_inputs").slideUp(function(){e("#ctc_sel_ovrd_rule_inputs").html("")}):(a="",e.each(ctcAjax.sel_val[t].value,function(e){a+=j(t,e,"ovrd")}),e("#ctc_sel_ovrd_rule_inputs").html(a).find(".color-picker").each(function(){S(this)}),_("#ctc_child_all_0_swatch"),e("#ctc_sel_ovrd_selector_selected").text(ctcAjax.sel_val[t].selector),e(".ctc-rewrite-toggle").text(ctcAjax.rename_txt),e("#ctc_sel_ovrd_new_rule, #ctc_sel_ovrd_rule_header, #ctc_sel_ovrd_rule_inputs_container, #ctc_sel_ovrd_rule_inputs, .ctc-rewrite-toggle").slideDown())):(e("#ctc_sel_ovrd_selector_selected").html("&nbsp;"),e("#ctc_sel_ovrd_new_rule, #ctc_sel_ovrd_rule_header, #ctc_sel_ovrd_rule_inputs_container, #ctc_sel_ovrd_rule_inputs, .ctc-rewrite-toggle").slideUp(function(){e("#ctc_sel_ovrd_rule_inputs").html("")})),a=null}function A(t){if(1===Z.preview)return!1;if(0==Z.preview){Z.preview=1;var t;return(t=t.match(/(child|parnt)/)[1])||(t="child"),$(""),P("preview",t,A),!1}e("#view_"+t+"_options_panel").text(ctcAjax.previewResponse),ctcAjax.previewResponse=null,Z.preview=0}function b(t){if(1===Z.rule_val)return!1;if(0==Z.rule_val)return Z.rule_val=1,P("rule_val",t,b),!1;var c=ctcAjax.rule[t],a='<div class="ctc-input-row clearfix" id="ctc_rule_row_'+c+'">'+J;!1===v(ctcAjax.rule_val[t])&&(e.each(ctcAjax.rule_val[t],function(e,t){var l=u(c,t);a+='<div class="ctc-parent-row clearfix" id="ctc_rule_row_'+c+"_"+e+'">'+J,a+='<div class="ctc-input-cell ctc-parent-value" id="ctc_'+e+"_parent_"+c+"_"+e+'">'+l.orig+"</div>"+J,a+='<div class="ctc-input-cell">'+J,a+='<div class="ctc-swatch ctc-specific" id="ctc_'+e+"_parent_"+c+"_"+e+'_swatch">'+ctcAjax.swatch_txt+"</div></div>"+J,a+='<div class="ctc-input-cell"><a href="#" class="ctc-selector-handle" id="ctc_selector_'+c+"_"+e+'">'+ctcAjax.selector_txt+"</a></div>"+J,a+='<div id="ctc_selector_'+c+"_"+e+'_container" class="ctc-selector-container">'+J,a+='<a href="#" id="ctc_selector_'+c+"_"+e+'_close" class="ctc-selector-handle ctc-exit" title="'+ctcAjax.close_txt+'"></a>',a+='<div id="ctc_selector_'+c+"_"+e+'_inner_container" class="ctc-selector-inner-container clearfix">'+J,a+='<div id="ctc_status_val_qry_'+e+'"></div>'+J,a+='<div id="ctc_selector_'+c+"_"+e+'_rows"></div>'+J,a+="</div></div></div>"+J}),a+="</div>"+J),e("#ctc_rule_value_inputs").html(a).find(".ctc-swatch").each(function(){_(this)}),a=null}function k(){var t="";v(ctcAjax.recent)?t+=ctcAjax.recent_txt:(t+="<ul>\n",e.each(ctcAjax.recent,function(c,a){e.each(a,function(e,c){t+='<li><a href="#" class="ctc-selector-edit" id="ctc_selector_edit_'+e+'" >'+c+"</a></li>\n"})}),t+="</ul>\n"),e("#ctc_recent_selectors").html(t),t=null}function q(t){if(1==Z.val_qry)return!1;var c,l,n=e("#ctc_rule_menu_selected").text().replace(/[^\w\-]/g,a),r="";return 0===Z.val_qry?(Z.val_qry=1,c={rule:n},P("val_qry",t,q,c),!1):(!1===v(ctcAjax.val_qry[t])&&e.each(ctcAjax.val_qry[t],function(c,a){page_rule=c,e.each(a,function(a,l){r+='<h4 class="ctc-query-heading">'+a+"</h4>"+J,!1===v(l)&&e.each(l,function(e,a){ctcAjax.sel_val[e]=a,r+=j(e,c,t)})})}),l="#ctc_selector_"+n+"_"+t+"_rows",e(l).html(r).find(".color-picker").each(function(){S(this)}),void e(l).find(".ctc-swatch").each(function(){_(this)}))}function S(t){e(t).iris({change:function(c,a){e(t).data("color",a.color.toString()),_(t)}})}function C(){e("#ctc_sel_ovrd_query").autocomplete({source:tt,minLength:0,selectFirst:!0,autoFocus:!0,select:function(e,t){return z(t.item.value),!1},focus:function(e){e.preventDefault()}})}function D(){e("#ctc_sel_ovrd_selector").autocomplete({source:et,selectFirst:!0,autoFocus:!0,select:function(e,t){return E(t.item.value,t.item.label),!1},focus:function(e){e.preventDefault()}})}function R(){e("#ctc_rule_menu").autocomplete({source:ct,selectFirst:!0,autoFocus:!0,select:function(e,t){return L(t.item.value,t.item.label),!1},focus:function(e){e.preventDefault()}})}function F(){e("#ctc_new_rule_menu").autocomplete({source:y,selectFirst:!0,autoFocus:!0,select:function(t,c){t.preventDefault();var l=e(j(H,c.item.label.replace(/[^\w\-]/g,a),"ovrd"));return e("#ctc_sel_ovrd_rule_inputs").append(l),e("#ctc_new_rule_menu").val(""),v(ctcAjax.sel_val[H].value)&&(ctcAjax.sel_val[H].value={}),ctcAjax.sel_val[H].value[c.item.label]={child:""},l.find('input[type="text"]').each(function(t,c){e(c).hasClass("color-picker")&&S(c),e(c).focus()}),!1},focus:function(e){e.preventDefault()}})}function T(){if(e("#ctc_theme_child").length&&e("#ctc_child_type_existing").is(":checked")){var t=e("#ctc_theme_child").val();!1===v(t)&&(e("#ctc_child_name").val(ctcAjax.themes.child[t].Name),e("#ctc_child_author").val(ctcAjax.themes.child[t].Author),e("#ctc_child_version").val(ctcAjax.themes.child[t].Version))}}function $(t){var c="";!1===v(t)&&e.each(t,function(t,a){c+='<div class="'+t+'"><ul>'+J,e(a).each(function(e,t){c+="<li>"+t.toString()+"</li>"+J}),c+="</ul></div>"}),e("#ctc_error_notice").html(c)}function M(t){e("#ctc_theme_parent").parents(".ctc-input-row").first().append('<span class="ctc-status-icon spinner"></span>'),e(".spinner").show(),document.location="?page="+ctcAjax.page+"&ctc_parent="+t.value}function I(t){!1===v(ctcAjax.themes.child[t.value])&&(e("#ctc_child_name").val(ctcAjax.themes.child[t.value].Name),e("#ctc_child_author").val(ctcAjax.themes.child[t.value].Author),e("#ctc_child_version").val(ctcAjax.themes.child[t.value].Version))}function z(t){Y=t,e("#ctc_sel_ovrd_query").val(""),e("#ctc_sel_ovrd_query_selected").text(t),e("#ctc_sel_ovrd_selector").val(""),e("#ctc_sel_ovrd_selector_selected").html("&nbsp;"),e("#ctc_sel_ovrd_rule_inputs").html(""),x()}function E(t){e("#ctc_sel_ovrd_selector").val(""),1!=Z.sel_val&&(Z.sel_val=0),H=t,Z.new_sel=1,g(t)}function L(t,c){e("#ctc_rule_menu").val(""),e("#ctc_rule_menu_selected").text(c),1!=Z.rule_val&&(Z.rule_val=0),b(t),e(".ctc-rewrite-toggle").text(ctcAjax.rename_txt),e("#ctc_rule_value_inputs, #ctc_input_row_rule_header").show()}function N(t){var c=e(t).attr("id").match(/_(\d+)$/)[1];i("#query_selector_options"),Z.sel_val=0,Z.set_sel=Z.set_qry=1,H=c,g(c)}function O(){var t,c=e("#ctc_theme_parnt").val(),a=ctcAjax.theme_uri.replace(/^https?:\/\//,""),l=ctcAjax.homeurl.replace(/^https?/,ctcAjax.ssl?"https":"http"),n=l+"?preview=1&p=x&template="+c+"&stylesheet="+c,r=new RegExp("<link rel=[\"']stylesheet[\"'][^>]+?"+a+"/"+c+"/(.+?\\.css)[^>]+?>","g");v(c)||(c!=ctcAjax.parnt?e.get(n,function(c){for(;(t=r.exec(c))&&"style.css"!=t[1];)t[1].match(/bootstrap/)||e(".ctc_checkbox").each(function(){e(this).val()==t[1]&&e(this).prop("checked",!0)});c=null}):e(ctcAjax.addl_css).each(function(t,c){e("#ctc_stylesheet_files .ctc_checkbox").each(function(){e(this).val()==c&&e(this).prop("checked",!0)})}))}function P(t,c,a,l){var n={ctc_query_obj:t,ctc_query_key:c},r="#ctc_status_"+t+("val_qry"==t?"_"+c:"");return"object"==typeof l&&e.each(l,function(e,t){n["ctc_query_"+e]=t}),e(".query-icon").remove(),e(r).append('<span class="ctc-status-icon spinner query-icon"></span>'),e(".spinner").show(),n.action=!1===v(e("#ctc_action").val())&&"plugin"==e("#ctc_action").val()?"ctc_plgqry":"ctc_query",n._wpnonce=e("#_wpnonce").val(),e.post(ctcAjax.ajaxurl,n,function(l){Z[t]=2,v(l)?(e(".query-icon").addClass("failure"),"preview"==t&&(ctcAjax.previewResponse=ctcAjax.css_fail_txt,a(c))):(e(".ctc-status-icon").addClass("success"),1==Z.refresh&&(Z.refresh=0,Q()),V(l),l=null,k(),"function"==typeof a&&a(c))},"json").fail(function(){e(".query-icon").removeClass("spinner"),e(".query-icon").addClass("failure"),"preview"==t?(ctcAjax.previewResponse=ctcAjax.css_fail_txt,Z[t]=2,a(c)):Z[t]=0}),!1}function U(t,c){var a,l,n,r,i={},s=e(t).attr("id");return e(t).prop("disabled",!0),e(".save-icon").remove(),e(t).parent(".ctc-textarea-button-cell, .ctc-button-cell").append('<span class="ctc-status-icon spinner save-icon"></span>'),s.match(/ctc_configtype/)?(e(t).parents(".ctc-input-row").first().append('<span class="ctc-status-icon spinner save-icon"></span>'),i.ctc_configtype=e(t).val()):(a=e("#ctc_new_selectors"))&&"ctc_save_new_selectors"==e(t).attr("id")?(i.ctc_new_selectors=a.val(),(l=e("#ctc_sel_ovrd_query_selected"))&&(i.ctc_sel_ovrd_query=l.text())):(n=e("#ctc_child_imports"))&&"ctc_save_imports"==e(t).attr("id")?i.ctc_child_imports=n.val():i=_(t),e(".save-icon").show(),e("#ctc_sel_ovrd_selector_selected").find("#ctc_rewrite_selector").each(function(){r=e("#ctc_rewrite_selector").val(),origsel=e("#ctc_rewrite_selector_orig").val(),v(r)||!r.toString().match(/\w/)?r=origsel:i.ctc_rewrite_selector=r,e(".ctc-rewrite-toggle").text(ctcAjax.rename_txt),e("#ctc_sel_ovrd_selector_selected").html(r)}),i.action=!1===v(e("#ctc_action").val())&&"plugin"==e("#ctc_action").val()?"ctc_plugin":"ctc_update",i._wpnonce=e("#_wpnonce").val(),e.post(ctcAjax.ajaxurl,i,function(a){return e(t).prop("disabled",!1),e(".save-icon").removeClass("spinner"),v(a)?e(".save-icon").addClass("failure"):(e("#ctc_new_selectors").val(""),1==Z.refresh&&(Z.refresh=0,Q()),V(a),a=null,v(B)?H&&(w(H),k()):(E(B,G),B=G=null),e(".save-icon").addClass("success"),"function"==typeof c&&c()),!1},"json").fail(function(){e(t).prop("disabled",!1),e(".save-icon").removeClass("spinner"),e(".save-icon").addClass("failure")}),!1}function V(t){e(t).each(function(){switch(this.obj){case"imports":ctcAjax.imports=this.data;break;case"rule_val":ctcAjax.rule_val[this.key]=this.data;break;case"val_qry":ctcAjax.val_qry[this.key]=this.data;break;case"rule":ctcAjax.rule=this.data;break;case"sel_ndx":v(this.key)?ctcAjax.sel_ndx=this.data:"qsid"==this.key?(v(ctcAjax.sel_ndx[this.data.query])&&(ctcAjax.sel_ndx[this.data.query]={}),ctcAjax.sel_ndx[this.data.query][this.data.selector]=this.data.qsid):(ctcAjax.sel_ndx[this.key]=this.data,Y=this.key);break;case"sel_val":ctcAjax.sel_val[this.key]=this.data,H=this.key;break;case"rewrite":H=this.key,B=this.key,G=this.data;break;case"recent":ctcAjax.recent=this.data;break;case"stylesheets":e("#ctc_stylesheet_files").html(this.data);break;case"backups":e("#ctc_backup_files").html(this.data);break;case"addl_css":ctcAjax.addl_css=this.data;break;case"preview":case"all_styles":ctcAjax.previewResponse=this.data}}),t=null}function Q(){Y="base",H=null,et=[],tt=[],ct=[],Z.rld_rule=1,Z.rld_sel=1,Z.set_qry=1,ctcAjax.imports=[],ctcAjax.recent={},ctcAjax.rule={},ctcAjax.sel_ndx={},ctcAjax.val_qry={},ctcAjax.rule_val={},ctcAjax.sel_val={},p()}var B,G,H,J="\n",K=new RegExp('"',"g"),W="",X="",Y="base",Z={rule:0,sel_ndx:0,val_qry:0,rule_val:0,sel_val:0,preview:0,recent:0,rld_rule:0,rld_sel:0,set_qry:0,set_sel:0,new_sel:0,refresh:0},et=[],tt=[],ct=[];r(),T(),e("#ctc_theme_parnt").is("input")||(e.widget("ctc.themeMenu",e.ui.selectmenu,{_renderItem:function(t,c){var a=e("<li>");return e("#ctc_theme_option_"+c.value).detach().appendTo(a),a.appendTo(t)}}),e("#ctc_theme_parnt").themeMenu({select:function(e,t){M(t.item)}}),v(ctcAjax.themes.child)?(e("#ctc_child_name").val(X),e("#ctc_child_template").val(W)):e("#ctc_theme_child").themeMenu({select:function(e,t){I(t.item)}})),e("#ctc_main").on("focus",".color-picker",function(){$(""),e(".color-picker").not(this).iris("hide"),e(this).iris("toggle"),e(".iris-picker").css({position:"absolute","z-index":10})}),e("#ctc_main").on("change",".ctc-child-value, input[type=checkbox]",function(){_(this)}),e("#ctc_main").on("click",".ctc-selector-handle",function(t){t.preventDefault(),$("");var c=e(this).attr("id").toString().replace("_close",""),a=c.toString().match(/_(\d+)$/)[1];e("#"+c+"_container").is(":hidden")&&(1!=Z.val_qry&&(Z.val_qry=0),q(a)),e("#"+c+"_container").fadeToggle("fast"),e(".ctc-selector-container").not("#"+c+"_container").fadeOut("fast")}),e("#ctc_main").on("click",".nav-tab",function(t){t.preventDefault(),$(""),e(".ctc-status-icon").remove();var c="#"+e(this).attr("id");i(c)}),e("#ctc_main").on("click",".ctc-save-input",function(){U(this,p)}),e("#ctc_main").on("click",".ctc-selector-edit",function(){N(this)}),e("#ctc_main").on("click",".ctc-rewrite-toggle",function(e){e.preventDefault(),s(this)}),e("#ctc_main").on("click",".ctc-section-toggle",function(){e(this).toggleClass("open");var t=e(this).attr("id")+"_content";e("#"+t).slideToggle("fast")}),e("#ctc_main").on("click","#ctc_copy_selector",function(){var t=e("#ctc_sel_ovrd_selector_selected").text().trim();!1===v(t)&&e("#ctc_new_selectors").val(e("#ctc_new_selectors").val()+"\n"+t+" {\n\n}")}),e("#ctc_configtype").on("change",function(){var t=e(this).val();v(t)||"theme"==t?(e(".ctc-theme-only, .ctc-themeonly-container").removeClass("ctc-disabled"),e(".ctc-theme-only, .ctc-themeonly-container input").prop("disabled",!1),e("#ctc_theme_parnt, #ctc_theme_child").themeMenu("enable")):(e(".ctc-theme-only, .ctc-themeonly-container").addClass("ctc-disabled"),e(".ctc-theme-only, .ctc-themeonly-container input").prop("disabled",!0),e("#ctc_theme_parnt, #ctc_theme_child").themeMenu("disable"))}),e("#view_child_options, #view_parnt_options").on("click",function(){A(e(this).attr("id"))}),e("#ctc_load_form").on("submit",function(){return n()&&confirm(ctcAjax.load_txt)}),e("#ctc_theme_child, #ctc_theme_child-button, #ctc_child_type_existing").on("focus click",function(){e("#ctc_child_type_existing").prop("checked",!0),e("#ctc_child_type_new").prop("checked",!1),e("#ctc_child_template").val(""),T()}),e("#ctc_child_type_new, #ctc_child_template").on("focus click",function(){e("#ctc_child_type_existing").prop("checked",!1),e("#ctc_child_type_new").prop("checked",!0),e("#ctc_child_name").val(X),e("#ctc_child_template").val(W)}),e("#recent_edits").on("click",function(t){return t.preventDefault(),e(".wrap").css({overflow:"hidden"}),e(".ctc-recent-container").is(":visible")?(e(this).removeClass("open"),e(".ctc-recent-container").stop().animate({right:-200},function(){e(this).hide()}),e(".ctc-option-panel").css({width:"95%"})):(e(this).addClass("open"),e(".ctc-recent-container").stop().css({right:-200}).show().animate({right:0}),e(".ctc-option-panel").css({width:"80%"})),e(".wrap").css({overflow:"inherit"}),!1}),e(".ctc-live-preview").on("click",function(t){return t.stopImmediatePropagation(),t.preventDefault(),document.location=e(this).prop("href"),!1}),p(),z(Y),O(),k(),e("input[type=submit], input[type=button]").prop("disabled",!1),setTimeout(o,15e3)});
js/jquery-ui-selectmenu.js CHANGED
@@ -307,7 +307,7 @@ $.Widget.prototype = {
307
  this.element
308
  .unbind( this.eventNamespace )
309
  .removeData( this.widgetFullName )
310
- // support: jquery <1.6.3
311
  // http://bugs.jquery.com/ticket/9413
312
  .removeData( $.camelCase( this.widgetFullName ) );
313
  this.widget()
307
  this.element
308
  .unbind( this.eventNamespace )
309
  .removeData( this.widgetFullName )
310
+ // support: jquery <1.6.4
311
  // http://bugs.jquery.com/ticket/9413
312
  .removeData( $.camelCase( this.widgetFullName ) );
313
  this.widget()
lang/chld_thm_cfg.pot CHANGED
@@ -1,218 +1,239 @@
1
- # Copyright (C) 2014 Child Theme Configurator
2
  # This file is distributed under the same license as the Child Theme Configurator package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Child Theme Configurator 1.6.1\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/child-theme-configurator\n"
7
- "POT-Creation-Date: 2014-12-06 03:55:35+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
- "PO-Revision-Date: 2014-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
- #. #-#-#-#-# chld_thm_cfg.pot (Child Theme Configurator 1.6.1) #-#-#-#-#
16
  #. Plugin Name of the plugin/theme
17
- #: child-theme-configurator.php:54 includes/forms/main.php:23
 
18
  msgid "Child Theme Configurator"
19
  msgstr ""
20
 
21
- #: child-theme-configurator.php:55
 
22
  msgid "Child Themes"
23
  msgstr ""
24
 
25
- #: includes/class-ctc-ui.php:139
 
 
 
 
26
  msgid "Child Theme files modified successfully."
27
  msgstr ""
28
 
29
- #: includes/class-ctc-ui.php:141
30
  msgid ""
31
  "Child Theme <strong>%s</strong> has been generated successfully.\n"
32
  " "
33
  msgstr ""
34
 
35
- #: includes/class-ctc-ui.php:144
36
  msgid "IMPORTANT:"
37
  msgstr ""
38
 
39
- #: includes/class-ctc-ui.php:144 includes/forms/themepreview.php:16
40
- #: includes/forms/themepreview.php:17
41
- msgid "Live Preview"
42
  msgstr ""
43
 
44
  #: includes/class-ctc-ui.php:144
45
- msgid "Test your child theme"
46
  msgstr ""
47
 
48
  #: includes/class-ctc-ui.php:144
 
 
 
 
 
 
 
 
 
 
 
 
49
  msgid "before activating."
50
  msgstr ""
51
 
52
- #: includes/class-ctc.php:126
53
  msgid "URL/None"
54
  msgstr ""
55
 
56
- #: includes/class-ctc.php:127
57
  msgid "Origin"
58
  msgstr ""
59
 
60
- #: includes/class-ctc.php:128
61
  msgid "Color 1"
62
  msgstr ""
63
 
64
- #: includes/class-ctc.php:129
65
  msgid "Color 2"
66
  msgstr ""
67
 
68
- #: includes/class-ctc.php:130
69
- msgid "Width"
70
  msgstr ""
71
 
72
- #: includes/class-ctc.php:131
73
  msgid "Style"
74
  msgstr ""
75
 
76
- #: includes/class-ctc.php:132
77
  msgid "Color"
78
  msgstr ""
79
 
80
- #: includes/class-ctc.php:134
81
  msgid "Are you sure? This will replace your current settings."
82
  msgstr ""
83
 
84
- #: includes/class-ctc.php:136 includes/forms/query-selector.php:35
85
- #: includes/forms/rule-value.php:28
86
  msgid "Sample"
87
  msgstr ""
88
 
89
- #: includes/class-ctc.php:137
90
  msgid "<span style=\"font-size:10px\">!</span>"
91
  msgstr ""
92
 
93
- #: includes/class-ctc.php:138 includes/forms/rule-value.php:31
94
  msgid "Selectors"
95
  msgstr ""
96
 
97
- #: includes/class-ctc.php:139
98
  msgid "Close"
99
  msgstr ""
100
 
101
- #: includes/class-ctc.php:140
102
  msgid "Edit"
103
  msgstr ""
104
 
105
- #: includes/class-ctc.php:141
106
  msgid "Cancel"
107
  msgstr ""
108
 
109
- #: includes/class-ctc.php:142
110
  msgid "Rename"
111
  msgstr ""
112
 
113
- #: includes/class-ctc.php:143
114
  msgid "The stylesheet cannot be displayed."
115
  msgstr ""
116
 
117
- #: includes/class-ctc.php:144
118
  msgid "(Child Only)"
119
  msgstr ""
120
 
121
- #: includes/class-ctc.php:145
122
- msgid "Please enter a valid Child Theme"
123
  msgstr ""
124
 
125
- #: includes/class-ctc.php:146
126
- msgid "Please enter a valid Child Theme name"
127
  msgstr ""
128
 
129
- #: includes/class-ctc.php:147
130
  msgid "<strong>%s</strong> exists. Please enter a different Child Theme"
131
  msgstr ""
132
 
133
- #: includes/class-ctc.php:307
 
 
 
 
134
  msgid "Zip file creation failed."
135
  msgstr ""
136
 
137
- #: includes/class-ctc.php:342
138
  msgid "The Functions file is required and cannot be deleted."
139
  msgstr ""
140
 
141
- #: includes/class-ctc.php:422
142
  msgid "You do not have permission to configure child themes."
143
  msgstr ""
144
 
145
- #: includes/class-ctc.php:446
146
- msgid "%s does not exist. Please select a valid Parent Theme"
147
  msgstr ""
148
 
149
- #: includes/class-ctc.php:449
150
- msgid "Please select a valid Parent Theme"
151
  msgstr ""
152
 
153
- #: includes/class-ctc.php:454
154
- msgid "Please enter a valid Child Theme template name"
155
  msgstr ""
156
 
157
- #: includes/class-ctc.php:459
158
- msgid ""
159
- "<strong>%s</strong> exists. Please enter a different Child Theme template "
160
- "name"
161
  msgstr ""
162
 
163
- #: includes/class-ctc.php:485
164
- msgid "Please enter a valid Child Theme directory"
165
  msgstr ""
166
 
167
- #: includes/class-ctc.php:489 includes/class-ctc.php:1033
168
- msgid "Your theme directories are not writable."
 
 
169
  msgstr ""
170
 
171
- #: includes/class-ctc.php:523 includes/class-ctc.php:1042
172
  msgid "Your stylesheet is not writable."
173
  msgstr ""
174
 
175
- #: includes/class-ctc.php:723
176
  msgid "Could not copy file."
177
  msgstr ""
178
 
179
- #: includes/class-ctc.php:798
180
  msgid "Could not set write permissions."
181
  msgstr ""
182
 
183
- #: includes/class-ctc.php:869
184
  msgid "There were errors while resetting permissions."
185
  msgstr ""
186
 
187
- #: includes/class-ctc.php:906
188
  msgid "Could not upload file."
189
  msgstr ""
190
 
191
- #: includes/class-ctc.php:986
192
  msgid ""
193
  "Child Theme Configurator is unable to write to the stylesheet. This can be "
194
  "resolved using one of the following options:<ol>"
195
  msgstr ""
196
 
197
- #: includes/class-ctc.php:988
198
  msgid ""
199
  "<li>Temporarily make the stylesheet writable by clicking the button below. "
200
  "You should change this back when you are finished editing for security by "
201
  "clicking \"Make read-only\" under the \"Files\" tab.</li>"
202
  msgstr ""
203
 
204
- #: includes/class-ctc.php:990
205
  msgid "Temporarily make stylesheet writable"
206
  msgstr ""
207
 
208
- #: includes/class-ctc.php:991
209
  msgid ""
210
  "<li><a target=\"_blank\" href=\"http://codex.wordpress.org/Editing_wp-"
211
  "config.php#WordPress_Upgrade_Constants\" title=\"Editin wp-config.php\">Add "
212
  "your FTP/SSH credentials to the WordPress config file</a>.</li>"
213
  msgstr ""
214
 
215
- #: includes/class-ctc.php:993
216
  msgid ""
217
  "<li><a target=\"_blank\" href=\"http://technet.microsoft.com/en-us/library/"
218
  "cc771170\" title=\"Setting Application Pool Identity\">Assign WordPress to "
@@ -220,7 +241,7 @@ msgid ""
220
  "li>"
221
  msgstr ""
222
 
223
- #: includes/class-ctc.php:994
224
  msgid ""
225
  "<li><a target=\"_blank\" href=\"http://codex.wordpress.org/"
226
  "Changing_File_Permissions\" title=\"Changing File Permissions\">Set the "
@@ -228,11 +249,11 @@ msgid ""
228
  "li>"
229
  msgstr ""
230
 
231
- #: includes/class-ctc.php:996
232
  msgid "<li>Run PHP under Apache with suEXEC (contact your web host).</li>"
233
  msgstr ""
234
 
235
- #: includes/class-ctc.php:1004
236
  msgid ""
237
  "This Child Theme is not owned by your website account. It may have been "
238
  "created by a prior version of this plugin or by another program. Moving "
@@ -241,30 +262,150 @@ msgid ""
241
  "below."
242
  msgstr ""
243
 
244
- #: includes/class-ctc.php:1006
245
  msgid "Correct Child Theme Permissions"
246
  msgstr ""
247
 
248
- #: includes/class-ctc.php:1013
249
  msgid ""
250
- "Child Theme Configurator has changed the way it handles the parent "
251
- "stylesheet. Please set your preferences below and click \"Generate Child "
252
- "Theme Files\" to update your configuration."
253
  msgstr ""
254
 
255
- #: includes/forms/at-import.php:12
256
- msgid "@import Statements"
 
 
 
 
257
  msgstr ""
258
 
259
- #: includes/forms/at-import.php:16 includes/forms/query-selector.php:43
260
- #: includes/forms/query-selector.php:83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  msgid "Save"
262
  msgstr ""
263
 
 
 
 
 
264
  #: includes/forms/backup.php:8
265
  msgid "Backup"
266
  msgstr ""
267
 
 
 
 
 
268
  #: includes/forms/fileform.php:7
269
  msgid ""
270
  "The Theme editor has been disabled. Template files must be edited offline."
@@ -274,47 +415,47 @@ msgstr ""
274
  msgid "Click here to edit template files using the Theme Editor"
275
  msgstr ""
276
 
277
- #: includes/forms/fileform.php:21
278
  msgid "Parent Templates"
279
  msgstr ""
280
 
281
- #: includes/forms/fileform.php:21
282
  msgid "Child Theme Files"
283
  msgstr ""
284
 
285
- #: includes/forms/fileform.php:26
286
  msgid "Copy PHP template files from the parent theme by selecting them here."
287
  msgstr ""
288
 
289
- #: includes/forms/fileform.php:29
290
  msgid ""
291
  "CAUTION: If your child theme is active, the child theme version of the file "
292
  "will be used instead of the parent immediately after it is copied."
293
  msgstr ""
294
 
295
- #: includes/forms/fileform.php:31
296
  msgid "The %s file is generated separately and cannot be copied here."
297
  msgstr ""
298
 
299
- #: includes/forms/fileform.php:41
300
  msgid "Delete child theme templates by selecting them here."
301
  msgstr ""
302
 
303
- #: includes/forms/fileform.php:42
304
  msgid ""
305
  "Delete child theme templates or make them writable by selecting them here. "
306
  "Writable files are displayed in <span style=\"color:red\">red</span>."
307
  msgstr ""
308
 
309
- #: includes/forms/fileform.php:55
310
  msgid "Make Selected Writable"
311
  msgstr ""
312
 
313
- #: includes/forms/fileform.php:59
314
  msgid "Copy Selected to Child Theme"
315
  msgstr ""
316
 
317
- #: includes/forms/fileform.php:59 includes/forms/images.php:20
318
  msgid "Delete Selected"
319
  msgstr ""
320
 
@@ -381,158 +522,160 @@ msgstr ""
381
  msgid "version"
382
  msgstr ""
383
 
384
- #: includes/forms/parent-child.php:20
385
  msgid "Parent Theme"
386
  msgstr ""
387
 
388
- #: includes/forms/parent-child.php:28
389
  msgid "Child Theme"
390
  msgstr ""
391
 
392
- #: includes/forms/parent-child.php:35
393
  msgid "Create New Child Theme"
394
  msgstr ""
395
 
396
- #: includes/forms/parent-child.php:44
397
  msgid "Use Existing Child Theme"
398
  msgstr ""
399
 
400
- #: includes/forms/parent-child.php:49
401
  msgid "Theme Slug"
402
  msgstr ""
403
 
404
- #: includes/forms/parent-child.php:59
405
  msgid "Child Theme Name"
406
  msgstr ""
407
 
408
- #: includes/forms/parent-child.php:63
409
  msgid "Theme Name"
410
  msgstr ""
411
 
412
- #: includes/forms/parent-child.php:69 includes/forms/parent-child.php:73
413
  msgid "Author"
414
  msgstr ""
415
 
416
- #: includes/forms/parent-child.php:78 includes/forms/parent-child.php:82
417
  msgid "Version"
418
  msgstr ""
419
 
420
- #: includes/forms/parent-child.php:88
421
  msgid "Copy Parent Theme Menus, Widgets and other Options"
422
  msgstr ""
423
 
424
- #: includes/forms/parent-child.php:95 includes/forms/parent-child.php:110
425
- #: includes/forms/parent-child.php:143
426
  msgid "NOTE:"
427
  msgstr ""
428
 
429
- #: includes/forms/parent-child.php:97
430
  msgid "This will overwrite child theme options you may have already set."
431
  msgstr ""
432
 
433
- #: includes/forms/parent-child.php:103
434
- msgid "Backup current stylesheet"
435
- msgstr ""
436
-
437
- #: includes/forms/parent-child.php:112
438
- msgid ""
439
- "This creates a copy of the current stylesheet before applying changes. You "
440
- "can remove old backup files using the Files tab."
441
- msgstr ""
442
-
443
- #: includes/forms/parent-child.php:121
444
  msgid "Parent stylesheet handling:"
445
  msgstr ""
446
 
447
- #: includes/forms/parent-child.php:127
448
  msgid "&lt;link&gt; (default)"
449
  msgstr ""
450
 
451
- #: includes/forms/parent-child.php:133 includes/forms/tabs.php:22
452
  msgid "@import"
453
  msgstr ""
454
 
455
- #: includes/forms/parent-child.php:139
456
  msgid "none (handled by theme)"
457
  msgstr ""
458
 
459
- #: includes/forms/parent-child.php:144
460
  msgid ""
461
  "This theme does not currently enqueue the stylesheet and must use the "
462
  "@import option to render correctly."
463
  msgstr ""
464
 
465
- #: includes/forms/parent-child.php:146
466
  msgid ""
467
  "Select @import for older themes that do not enqueue the stylesheet. Select "
468
  "'none' if core styles are automatically loaded for child themes. Select '&lt;"
469
  "link&gt;' if unsure."
470
  msgstr ""
471
 
472
- #: includes/forms/parent-child.php:152
473
- msgid "Reset/Restore from backup:"
474
- msgstr ""
475
-
476
- #: includes/forms/parent-child.php:158
477
- msgid "Leave unchanged"
478
  msgstr ""
479
 
480
- #: includes/forms/parent-child.php:164
481
- msgid "Reset all"
 
 
482
  msgstr ""
483
 
484
- #: includes/forms/parent-child.php:172
485
- msgid "Restore backup from"
486
  msgstr ""
487
 
488
- #: includes/forms/parent-child.php:184
489
- msgid "Parse additional stylesheets:"
490
  msgstr ""
491
 
492
- #: includes/forms/parent-child.php:188
493
- msgid ""
494
- "Stylesheets that are currently being loaded by the parent theme are "
495
- "automatically selected below (except for Bootstrap stylesheets which add a "
496
- "large amount data to the configuration). To further reduce overhead, select "
497
- "only the additional stylesheets you wish to customize."
498
  msgstr ""
499
 
500
- #: includes/forms/parent-child.php:207
501
  msgid "Generate/Rebuild Child Theme Files"
502
  msgstr ""
503
 
504
- #: includes/forms/query-selector.php:11
505
  msgid "Query"
506
  msgstr ""
507
 
508
- #: includes/forms/query-selector.php:22
509
  msgid "Selector"
510
  msgstr ""
511
 
512
- #: includes/forms/query-selector.php:50 includes/forms/rule-value.php:12
 
 
 
 
513
  msgid "Rule"
514
  msgstr ""
515
 
516
- #: includes/forms/query-selector.php:53
517
  msgid "Parent Value"
518
  msgstr ""
519
 
520
- #: includes/forms/query-selector.php:56
521
  msgid "Child Value"
522
  msgstr ""
523
 
524
- #: includes/forms/query-selector.php:62
525
  msgid "New Rule"
526
  msgstr ""
527
 
528
- #: includes/forms/query-selector.php:72
529
  msgid "Order"
530
  msgstr ""
531
 
532
- #: includes/forms/query-selector.php:79
 
 
 
 
533
  msgid "Raw CSS"
534
  msgstr ""
535
 
 
 
 
 
 
 
 
 
 
 
536
  #: includes/forms/related.php:1
537
  msgid "New user?"
538
  msgstr ""
@@ -542,14 +685,14 @@ msgid "Click help"
542
  msgstr ""
543
 
544
  #: includes/forms/related.php:1
545
- msgid "Get CTC for Plugins and other tools"
546
  msgstr ""
547
 
548
  #: includes/forms/related.php:1
549
  msgid "Lilaea Media - Responsive Tools for a Mobile World"
550
  msgstr ""
551
 
552
- #: includes/forms/rule-value.php:25
553
  msgid "Value"
554
  msgstr ""
555
 
@@ -585,14 +728,26 @@ msgstr ""
585
  msgid "By: "
586
  msgstr ""
587
 
 
 
 
 
 
 
 
 
 
 
 
 
588
  #. Plugin URI of the plugin/theme
589
  msgid "http://www.lilaeamedia.com/plugins/child-theme-configurator/"
590
  msgstr ""
591
 
592
  #. Description of the plugin/theme
593
  msgid ""
594
- "Create a Child Theme from any installed Theme. Each CSS selector, rule and "
595
- "value can then be searched, previewed and modified."
596
  msgstr ""
597
 
598
  #. Author of the plugin/theme
1
+ # Copyright (C) 2015 Child Theme Configurator
2
  # This file is distributed under the same license as the Child Theme Configurator package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Child Theme Configurator 1.6.3\n"
6
  "Report-Msgid-Bugs-To: http://wordpress.org/tag/child-theme-configurator\n"
7
+ "POT-Creation-Date: 2015-01-18 07:32:28+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
15
+ #. #-#-#-#-# chld_thm_cfg.pot (Child Theme Configurator 1.6.3) #-#-#-#-#
16
  #. Plugin Name of the plugin/theme
17
+ #: child-theme-configurator.php:64 child-theme-configurator.php:74
18
+ #: includes/forms/main.php:23
19
  msgid "Child Theme Configurator"
20
  msgstr ""
21
 
22
+ #: child-theme-configurator.php:65 child-theme-configurator.php:75
23
+ #: child-theme-configurator.php:85
24
  msgid "Child Themes"
25
  msgstr ""
26
 
27
+ #: child-theme-configurator.php:99
28
+ msgid "Child Theme Configurator requires WordPress version %s or later."
29
+ msgstr ""
30
+
31
+ #: includes/class-ctc-ui.php:136
32
  msgid "Child Theme files modified successfully."
33
  msgstr ""
34
 
35
+ #: includes/class-ctc-ui.php:139
36
  msgid ""
37
  "Child Theme <strong>%s</strong> has been generated successfully.\n"
38
  " "
39
  msgstr ""
40
 
41
+ #: includes/class-ctc-ui.php:142
42
  msgid "IMPORTANT:"
43
  msgstr ""
44
 
45
+ #: includes/class-ctc-ui.php:144 includes/forms/themepreview.php:20
46
+ msgid "Go to Themes"
 
47
  msgstr ""
48
 
49
  #: includes/class-ctc-ui.php:144
50
+ msgid "Network enable"
51
  msgstr ""
52
 
53
  #: includes/class-ctc-ui.php:144
54
+ msgid "your child theme."
55
+ msgstr ""
56
+
57
+ #: includes/class-ctc-ui.php:146 includes/forms/themepreview.php:18
58
+ msgid "Live Preview"
59
+ msgstr ""
60
+
61
+ #: includes/class-ctc-ui.php:146
62
+ msgid "Test your child theme"
63
+ msgstr ""
64
+
65
+ #: includes/class-ctc-ui.php:146
66
  msgid "before activating."
67
  msgstr ""
68
 
69
+ #: includes/class-ctc.php:136
70
  msgid "URL/None"
71
  msgstr ""
72
 
73
+ #: includes/class-ctc.php:137
74
  msgid "Origin"
75
  msgstr ""
76
 
77
+ #: includes/class-ctc.php:138
78
  msgid "Color 1"
79
  msgstr ""
80
 
81
+ #: includes/class-ctc.php:139
82
  msgid "Color 2"
83
  msgstr ""
84
 
85
+ #: includes/class-ctc.php:140
86
+ msgid "Width/None"
87
  msgstr ""
88
 
89
+ #: includes/class-ctc.php:141
90
  msgid "Style"
91
  msgstr ""
92
 
93
+ #: includes/class-ctc.php:142
94
  msgid "Color"
95
  msgstr ""
96
 
97
+ #: includes/class-ctc.php:145
98
  msgid "Are you sure? This will replace your current settings."
99
  msgstr ""
100
 
101
+ #: includes/class-ctc.php:146 includes/forms/query-selector.php:37
102
+ #: includes/forms/rule-value.php:29
103
  msgid "Sample"
104
  msgstr ""
105
 
106
+ #: includes/class-ctc.php:147
107
  msgid "<span style=\"font-size:10px\">!</span>"
108
  msgstr ""
109
 
110
+ #: includes/class-ctc.php:148 includes/forms/rule-value.php:32
111
  msgid "Selectors"
112
  msgstr ""
113
 
114
+ #: includes/class-ctc.php:149
115
  msgid "Close"
116
  msgstr ""
117
 
118
+ #: includes/class-ctc.php:150
119
  msgid "Edit"
120
  msgstr ""
121
 
122
+ #: includes/class-ctc.php:151
123
  msgid "Cancel"
124
  msgstr ""
125
 
126
+ #: includes/class-ctc.php:152
127
  msgid "Rename"
128
  msgstr ""
129
 
130
+ #: includes/class-ctc.php:153
131
  msgid "The stylesheet cannot be displayed."
132
  msgstr ""
133
 
134
+ #: includes/class-ctc.php:154
135
  msgid "(Child Only)"
136
  msgstr ""
137
 
138
+ #: includes/class-ctc.php:155
139
+ msgid "Please enter a valid Child Theme."
140
  msgstr ""
141
 
142
+ #: includes/class-ctc.php:156
143
+ msgid "Please enter a valid Child Theme name."
144
  msgstr ""
145
 
146
+ #: includes/class-ctc.php:157
147
  msgid "<strong>%s</strong> exists. Please enter a different Child Theme"
148
  msgstr ""
149
 
150
+ #: includes/class-ctc.php:158
151
+ msgid "No recent edits."
152
+ msgstr ""
153
+
154
+ #: includes/class-ctc.php:344
155
  msgid "Zip file creation failed."
156
  msgstr ""
157
 
158
+ #: includes/class-ctc.php:380
159
  msgid "The Functions file is required and cannot be deleted."
160
  msgstr ""
161
 
162
+ #: includes/class-ctc.php:461
163
  msgid "You do not have permission to configure child themes."
164
  msgstr ""
165
 
166
+ #: includes/class-ctc.php:492
167
+ msgid "%s does not exist. Please select a valid Parent Theme."
168
  msgstr ""
169
 
170
+ #: includes/class-ctc.php:496
171
+ msgid "Please select a valid Parent Theme."
172
  msgstr ""
173
 
174
+ #: includes/class-ctc.php:499
175
+ msgid "Please enter a valid Child Theme directory."
176
  msgstr ""
177
 
178
+ #: includes/class-ctc.php:505
179
+ msgid "Your theme directories are not writable."
 
 
180
  msgstr ""
181
 
182
+ #: includes/class-ctc.php:512
183
+ msgid "Please enter a valid Child Theme template name."
184
  msgstr ""
185
 
186
+ #: includes/class-ctc.php:517
187
+ msgid ""
188
+ "<strong>%s</strong> exists. Please enter a different Child Theme template "
189
+ "name."
190
  msgstr ""
191
 
192
+ #: includes/class-ctc.php:574
193
  msgid "Your stylesheet is not writable."
194
  msgstr ""
195
 
196
+ #: includes/class-ctc.php:810
197
  msgid "Could not copy file."
198
  msgstr ""
199
 
200
+ #: includes/class-ctc.php:894
201
  msgid "Could not set write permissions."
202
  msgstr ""
203
 
204
+ #: includes/class-ctc.php:967
205
  msgid "There were errors while resetting permissions."
206
  msgstr ""
207
 
208
+ #: includes/class-ctc.php:1006
209
  msgid "Could not upload file."
210
  msgstr ""
211
 
212
+ #: includes/class-ctc.php:1089
213
  msgid ""
214
  "Child Theme Configurator is unable to write to the stylesheet. This can be "
215
  "resolved using one of the following options:<ol>"
216
  msgstr ""
217
 
218
+ #: includes/class-ctc.php:1092
219
  msgid ""
220
  "<li>Temporarily make the stylesheet writable by clicking the button below. "
221
  "You should change this back when you are finished editing for security by "
222
  "clicking \"Make read-only\" under the \"Files\" tab.</li>"
223
  msgstr ""
224
 
225
+ #: includes/class-ctc.php:1095
226
  msgid "Temporarily make stylesheet writable"
227
  msgstr ""
228
 
229
+ #: includes/class-ctc.php:1096
230
  msgid ""
231
  "<li><a target=\"_blank\" href=\"http://codex.wordpress.org/Editing_wp-"
232
  "config.php#WordPress_Upgrade_Constants\" title=\"Editin wp-config.php\">Add "
233
  "your FTP/SSH credentials to the WordPress config file</a>.</li>"
234
  msgstr ""
235
 
236
+ #: includes/class-ctc.php:1098
237
  msgid ""
238
  "<li><a target=\"_blank\" href=\"http://technet.microsoft.com/en-us/library/"
239
  "cc771170\" title=\"Setting Application Pool Identity\">Assign WordPress to "
241
  "li>"
242
  msgstr ""
243
 
244
+ #: includes/class-ctc.php:1099
245
  msgid ""
246
  "<li><a target=\"_blank\" href=\"http://codex.wordpress.org/"
247
  "Changing_File_Permissions\" title=\"Changing File Permissions\">Set the "
249
  "li>"
250
  msgstr ""
251
 
252
+ #: includes/class-ctc.php:1101
253
  msgid "<li>Run PHP under Apache with suEXEC (contact your web host).</li>"
254
  msgstr ""
255
 
256
+ #: includes/class-ctc.php:1110
257
  msgid ""
258
  "This Child Theme is not owned by your website account. It may have been "
259
  "created by a prior version of this plugin or by another program. Moving "
262
  "below."
263
  msgstr ""
264
 
265
+ #: includes/class-ctc.php:1113
266
  msgid "Correct Child Theme Permissions"
267
  msgstr ""
268
 
269
+ #: includes/class-ctc.php:1120
270
  msgid ""
271
+ "Child Theme Configurator needs to update its interal data. Please set your "
272
+ "preferences below and click \"Generate Child Theme Files\" to update your "
273
+ "configuration."
274
  msgstr ""
275
 
276
+ #: includes/class-ctc.php:1128
277
+ msgid ""
278
+ "Child Theme Configurator did not detect any configuration data, either "
279
+ "because this is the first time it has been used, or because a previously "
280
+ "configured Child Theme has been removed. Please set your preferences below "
281
+ "and click \"Generate Child Theme Files\"."
282
  msgstr ""
283
 
284
+ #: includes/forms/addl_css.php:7 includes/forms/parent-child.php:175
285
+ msgid "Parse additional stylesheets:"
286
+ msgstr ""
287
+
288
+ #: includes/forms/addl_css.php:11 includes/forms/parent-child.php:179
289
+ msgid ""
290
+ "Stylesheets that are currently being loaded by the parent theme are "
291
+ "automatically selected below (except for Bootstrap stylesheets which add a "
292
+ "large amount data to the configuration). To further reduce overhead, select "
293
+ "only the additional stylesheets you wish to customize."
294
+ msgstr ""
295
+
296
+ #: includes/forms/addl_panels.php:6
297
+ msgid "Reload"
298
+ msgstr ""
299
+
300
+ #: includes/forms/addl_panels.php:11 includes/help/help_en_US.php:211
301
+ msgid "Learn more about CTC Pro"
302
+ msgstr ""
303
+
304
+ #: includes/forms/addl_panels.php:12
305
+ msgid "Customizing WordPress Themes just got even easier."
306
+ msgstr ""
307
+
308
+ #: includes/forms/addl_panels.php:13
309
+ msgid ""
310
+ "Thousands of users have already seen the benefits of using Child Theme "
311
+ "Configurator. If you spend any amount of time customizing WordPress, CTC Pro "
312
+ "will help maximize your productivity."
313
+ msgstr ""
314
+
315
+ #: includes/forms/addl_panels.php:14
316
+ msgid "Designed by Developers Who Use It Every Day."
317
+ msgstr ""
318
+
319
+ #: includes/forms/addl_panels.php:15
320
+ msgid ""
321
+ "We've packed in more features to make design work quicker and easier with "
322
+ "<strong>Child Theme Configurator Pro."
323
+ msgstr ""
324
+
325
+ #: includes/forms/addl_panels.php:17
326
+ msgid "Custom Plugin Stylesheets"
327
+ msgstr ""
328
+
329
+ #: includes/forms/addl_panels.php:18
330
+ msgid ""
331
+ "Use the top-rated CTC interface to take control of your site's plugin "
332
+ "styles. All new design makes it much easier to get the results you want."
333
+ msgstr ""
334
+
335
+ #: includes/forms/addl_panels.php:19
336
+ msgid "Links to all styles in a single view"
337
+ msgstr ""
338
+
339
+ #: includes/forms/addl_panels.php:19
340
+ msgid ""
341
+ "Use the \"All Styles\" panel to find the selector you wish to edit from a "
342
+ "single combined list."
343
+ msgstr ""
344
+
345
+ #: includes/forms/addl_panels.php:20
346
+ msgid "Most recent edits"
347
+ msgstr ""
348
+
349
+ #: includes/forms/addl_panels.php:20
350
+ msgid "Return to recently edited selectors from a toggleable sidebar."
351
+ msgstr ""
352
+
353
+ #: includes/forms/addl_panels.php:21
354
+ msgid "Free Upgrades"
355
+ msgstr ""
356
+
357
+ #: includes/forms/addl_panels.php:22
358
+ msgid ""
359
+ "Your Update Key gives you access to new Pro features as soon as they are "
360
+ "released."
361
+ msgstr ""
362
+
363
+ #: includes/forms/addl_panels.php:23
364
+ msgid "Top-rated Online Support"
365
+ msgstr ""
366
+
367
+ #: includes/forms/addl_panels.php:24
368
+ msgid "Online Documentation"
369
+ msgstr ""
370
+
371
+ #: includes/forms/addl_panels.php:25
372
+ msgid "Tutorial Videos"
373
+ msgstr ""
374
+
375
+ #: includes/forms/addl_panels.php:27
376
+ msgid ""
377
+ "For a limited time we are offering Child Theme Configurator Pro for a "
378
+ "special introductory price."
379
+ msgstr ""
380
+
381
+ #: includes/forms/addl_panels.php:28
382
+ msgid "Buy CTC Pro"
383
+ msgstr ""
384
+
385
+ #: includes/forms/addl_panels.php:28
386
+ msgid "Buy Now - Only $12.95 USD"
387
+ msgstr ""
388
+
389
+ #: includes/forms/addl_tabs.php:8
390
+ msgid "Get CTC Pro"
391
+ msgstr ""
392
+
393
+ #: includes/forms/at-import.php:15 includes/forms/query-selector.php:85
394
  msgid "Save"
395
  msgstr ""
396
 
397
+ #: includes/forms/at-import.php:18
398
+ msgid "@import Statements"
399
+ msgstr ""
400
+
401
  #: includes/forms/backup.php:8
402
  msgid "Backup"
403
  msgstr ""
404
 
405
+ #: includes/forms/backups.php:10 includes/forms/parent-child.php:162
406
+ msgid "Restore backup from"
407
+ msgstr ""
408
+
409
  #: includes/forms/fileform.php:7
410
  msgid ""
411
  "The Theme editor has been disabled. Template files must be edited offline."
415
  msgid "Click here to edit template files using the Theme Editor"
416
  msgstr ""
417
 
418
+ #: includes/forms/fileform.php:22
419
  msgid "Parent Templates"
420
  msgstr ""
421
 
422
+ #: includes/forms/fileform.php:22
423
  msgid "Child Theme Files"
424
  msgstr ""
425
 
426
+ #: includes/forms/fileform.php:27
427
  msgid "Copy PHP template files from the parent theme by selecting them here."
428
  msgstr ""
429
 
430
+ #: includes/forms/fileform.php:30
431
  msgid ""
432
  "CAUTION: If your child theme is active, the child theme version of the file "
433
  "will be used instead of the parent immediately after it is copied."
434
  msgstr ""
435
 
436
+ #: includes/forms/fileform.php:32
437
  msgid "The %s file is generated separately and cannot be copied here."
438
  msgstr ""
439
 
440
+ #: includes/forms/fileform.php:42
441
  msgid "Delete child theme templates by selecting them here."
442
  msgstr ""
443
 
444
+ #: includes/forms/fileform.php:43
445
  msgid ""
446
  "Delete child theme templates or make them writable by selecting them here. "
447
  "Writable files are displayed in <span style=\"color:red\">red</span>."
448
  msgstr ""
449
 
450
+ #: includes/forms/fileform.php:56
451
  msgid "Make Selected Writable"
452
  msgstr ""
453
 
454
+ #: includes/forms/fileform.php:60
455
  msgid "Copy Selected to Child Theme"
456
  msgstr ""
457
 
458
+ #: includes/forms/fileform.php:60 includes/forms/images.php:20
459
  msgid "Delete Selected"
460
  msgstr ""
461
 
522
  msgid "version"
523
  msgstr ""
524
 
525
+ #: includes/forms/parent-child.php:17
526
  msgid "Parent Theme"
527
  msgstr ""
528
 
529
+ #: includes/forms/parent-child.php:25
530
  msgid "Child Theme"
531
  msgstr ""
532
 
533
+ #: includes/forms/parent-child.php:32
534
  msgid "Create New Child Theme"
535
  msgstr ""
536
 
537
+ #: includes/forms/parent-child.php:41
538
  msgid "Use Existing Child Theme"
539
  msgstr ""
540
 
541
+ #: includes/forms/parent-child.php:46
542
  msgid "Theme Slug"
543
  msgstr ""
544
 
545
+ #: includes/forms/parent-child.php:56
546
  msgid "Child Theme Name"
547
  msgstr ""
548
 
549
+ #: includes/forms/parent-child.php:60
550
  msgid "Theme Name"
551
  msgstr ""
552
 
553
+ #: includes/forms/parent-child.php:65 includes/forms/parent-child.php:69
554
  msgid "Author"
555
  msgstr ""
556
 
557
+ #: includes/forms/parent-child.php:74 includes/forms/parent-child.php:78
558
  msgid "Version"
559
  msgstr ""
560
 
561
+ #: includes/forms/parent-child.php:83
562
  msgid "Copy Parent Theme Menus, Widgets and other Options"
563
  msgstr ""
564
 
565
+ #: includes/forms/parent-child.php:90 includes/forms/parent-child.php:120
566
+ #: includes/forms/parent-child.php:136
567
  msgid "NOTE:"
568
  msgstr ""
569
 
570
+ #: includes/forms/parent-child.php:92
571
  msgid "This will overwrite child theme options you may have already set."
572
  msgstr ""
573
 
574
+ #: includes/forms/parent-child.php:98
 
 
 
 
 
 
 
 
 
 
575
  msgid "Parent stylesheet handling:"
576
  msgstr ""
577
 
578
+ #: includes/forms/parent-child.php:104
579
  msgid "&lt;link&gt; (default)"
580
  msgstr ""
581
 
582
+ #: includes/forms/parent-child.php:110 includes/forms/tabs.php:22
583
  msgid "@import"
584
  msgstr ""
585
 
586
+ #: includes/forms/parent-child.php:116
587
  msgid "none (handled by theme)"
588
  msgstr ""
589
 
590
+ #: includes/forms/parent-child.php:121
591
  msgid ""
592
  "This theme does not currently enqueue the stylesheet and must use the "
593
  "@import option to render correctly."
594
  msgstr ""
595
 
596
+ #: includes/forms/parent-child.php:123
597
  msgid ""
598
  "Select @import for older themes that do not enqueue the stylesheet. Select "
599
  "'none' if core styles are automatically loaded for child themes. Select '&lt;"
600
  "link&gt;' if unsure."
601
  msgstr ""
602
 
603
+ #: includes/forms/parent-child.php:129
604
+ msgid "Backup current stylesheet"
 
 
 
 
605
  msgstr ""
606
 
607
+ #: includes/forms/parent-child.php:138
608
+ msgid ""
609
+ "This creates a copy of the current stylesheet before applying changes. You "
610
+ "can remove old backup files using the Files tab."
611
  msgstr ""
612
 
613
+ #: includes/forms/parent-child.php:143
614
+ msgid "Reset/Restore from backup:"
615
  msgstr ""
616
 
617
+ #: includes/forms/parent-child.php:149
618
+ msgid "Leave unchanged"
619
  msgstr ""
620
 
621
+ #: includes/forms/parent-child.php:155
622
+ msgid "Reset all"
 
 
 
 
623
  msgstr ""
624
 
625
+ #: includes/forms/parent-child.php:198
626
  msgid "Generate/Rebuild Child Theme Files"
627
  msgstr ""
628
 
629
+ #: includes/forms/query-selector.php:13
630
  msgid "Query"
631
  msgstr ""
632
 
633
+ #: includes/forms/query-selector.php:24
634
  msgid "Selector"
635
  msgstr ""
636
 
637
+ #: includes/forms/query-selector.php:45
638
+ msgid "Save Child Values"
639
+ msgstr ""
640
+
641
+ #: includes/forms/query-selector.php:52 includes/forms/rule-value.php:13
642
  msgid "Rule"
643
  msgstr ""
644
 
645
+ #: includes/forms/query-selector.php:55
646
  msgid "Parent Value"
647
  msgstr ""
648
 
649
+ #: includes/forms/query-selector.php:58
650
  msgid "Child Value"
651
  msgstr ""
652
 
653
+ #: includes/forms/query-selector.php:64
654
  msgid "New Rule"
655
  msgstr ""
656
 
657
+ #: includes/forms/query-selector.php:74
658
  msgid "Order"
659
  msgstr ""
660
 
661
+ #: includes/forms/query-selector.php:83
662
+ msgid "Copy Selector"
663
+ msgstr ""
664
+
665
+ #: includes/forms/query-selector.php:88
666
  msgid "Raw CSS"
667
  msgstr ""
668
 
669
+ #: includes/forms/query-selector.php:90
670
+ msgid "Use to enter shorthand CSS or new @media queries and selectors."
671
+ msgstr ""
672
+
673
+ #: includes/forms/query-selector.php:90
674
+ msgid ""
675
+ "Values entered here are merged into existing child styles or added to the "
676
+ "child stylesheet if they do not exist in the parent."
677
+ msgstr ""
678
+
679
  #: includes/forms/related.php:1
680
  msgid "New user?"
681
  msgstr ""
685
  msgstr ""
686
 
687
  #: includes/forms/related.php:1
688
+ msgid "Get CTC Pro and other tools"
689
  msgstr ""
690
 
691
  #: includes/forms/related.php:1
692
  msgid "Lilaea Media - Responsive Tools for a Mobile World"
693
  msgstr ""
694
 
695
+ #: includes/forms/rule-value.php:26
696
  msgid "Value"
697
  msgstr ""
698
 
728
  msgid "By: "
729
  msgstr ""
730
 
731
+ #: includes/forms/themepreview.php:16
732
+ msgid "Preview"
733
+ msgstr ""
734
+
735
+ #: includes/forms/themepreview.php:17
736
+ msgid " in default Site"
737
+ msgstr ""
738
+
739
+ #: includes/forms/themepreview.php:21
740
+ msgid "Not Network Enabled"
741
+ msgstr ""
742
+
743
  #. Plugin URI of the plugin/theme
744
  msgid "http://www.lilaeamedia.com/plugins/child-theme-configurator/"
745
  msgstr ""
746
 
747
  #. Description of the plugin/theme
748
  msgid ""
749
+ "Create a Child Theme and customize the stylesheet as you wish. Search, "
750
+ "preview and modify any selector, rule or value using this fast CSS editor."
751
  msgstr ""
752
 
753
  #. Author of the plugin/theme
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
4
  Tags: child theme, customize, CSS, responsive, css editor, theme generator, stylesheet, customizer
5
  Requires at least: 3.9
6
  Tested up to: 4.1
7
- Stable tag: 1.6.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -42,13 +42,13 @@ When you are ready, just activate the Child Theme and your WordPress site takes
42
  * Uses WP Filesystem API – will not create files you cannot remove
43
  * Nag-free, no-strings-attached user experience
44
 
45
- = Not just for themes but plugins too! =
46
 
47
- We offer a premium extension that brings the CSS editing power of Child Theme Configurator to any WordPress Plugin installed on your website. The Child Theme Configurator Plugin Extension scans your plugins and creates custom CSS in your Child Theme.
48
 
49
- https://www.youtube.com/watch?v=mJ3i6gsuL1E
50
 
51
- Learn more at http://www.lilaeamedia.com/plugins/child-theme-plugin-styles
52
 
53
  = Build your WordPress website exactly the way you want it. =
54
 
@@ -149,10 +149,7 @@ Many of these options can be copied over to the child theme by checking "Copy Pa
149
 
150
  If you want to set different options you can either apply them after you activate the child theme using the theme customizer, or by using the "Live Preview" under Appearance > Themes.
151
 
152
- * Menus: Go to Appearance > Menus and click the "Locations" tab. By default, the primary menu will generate the links automatically from the existing pages. Select your customized Menu from the dropdown and click "Use New Menu." This will replace the default menu and you will see the correct links.
153
- * Header: Go to Appearance > Header. Some themes will show the "Title" and "Tagline" from your "General Settings" by default. Click "Choose Image" and find the header from the Media Library or upload a new image. This will replace default with your custom image.
154
- * Background: Go to Appearance > Background and choose a new background color or image.
155
- * Options: Every theme handles options in its own way. Most often, they will create a set of options and store them in the WordPress database. Some options are specific to the active theme (or child theme), and some are specific to the parent theme only (meaning the child theme CANNOT override them). You will have to find out from the theme author which are which.
156
 
157
  = How do I add Web Fonts? =
158
 
@@ -259,10 +256,17 @@ https://www.youtube.com/watch?v=iBiiAgsK4G4
259
  7. Files tab
260
 
261
  == Changelog ==
 
 
 
 
 
 
262
  = 1.6.3 =
263
  * New Feature: Better child theme handling for multisite. Moved interface to Themes menu and check for network enabled.
264
  * Fix: Restrict child theme configurator access to install_themes capability
265
  * Fix: Preview links to Themes admin if not network enabled to prevent 'Cheatin, uh?' error.
 
266
 
267
  = 1.6.2.1 =
268
  * Fix: Regular expression introduced in version 1.6.2 parses selectors incorrectly.
@@ -282,7 +286,7 @@ https://www.youtube.com/watch?v=iBiiAgsK4G4
282
 
283
  = 1.6.0 =
284
  * New Feature: option to load parent stylesheet using wp_enqueue_style (link), @import or none. Thanks to cmwwebfx and Shapeshifter3 for pushing me on this
285
- * New Feature: automatically-generated child theme slug and name
286
  * New Feature: restore from backup and reset options
287
  * New Feature: backup files to "Child Theme Files" on Files Tab so they can be deleted
288
  * New Feature: Added new theme chooser select menu with screenshot, theme info and link to live preview.
@@ -447,8 +451,6 @@ https://www.youtube.com/watch?v=iBiiAgsK4G4
447
 
448
  == Upgrade Notice ==
449
 
450
- v.1.6.3 **IMPORTANT:** As of v.1.6.3, only users with "install_themes" capability have access to the Child Theme Configurator. This resolves permission issues with both multisite and single site installs. **MULTISITE USERS:** The Admin HAS MOVED to Network Admin > Themes > Child Themes for better handling for multisite (network) installs. See changelog for details.
451
-
452
  == Override Parent Styles ==
453
 
454
  There are two ways to identify and override parent styles. The Child Theme Configurator lets you search styles by CSS selector and by rule. If you wish to change a specific CSS selector (e.g., h1), use the "Query/Selector" tab. If you have a specific CSS value you wish to change site-wide (e.g., the color of the type), use the "Rule/Value" tab.
4
  Tags: child theme, customize, CSS, responsive, css editor, theme generator, stylesheet, customizer
5
  Requires at least: 3.9
6
  Tested up to: 4.1
7
+ Stable tag: 1.6.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
42
  * Uses WP Filesystem API – will not create files you cannot remove
43
  * Nag-free, no-strings-attached user experience
44
 
45
+ = Introducing Child Theme Configurator PRO =
46
 
47
+ Apply the CSS editing power of Child Theme Configurator to any WordPress Plugin installed on your website. Child Theme Configurator PRO scans your plugins and lets you customize their stylesheets. We’ve added more features to make design work quicker and easier with PRO.
48
 
49
+ https://www.youtube.com/watch?v=Yj8lxF1knTo
50
 
51
+ Learn more at http://www.lilaeamedia.com/child-theme-configurator-pro
52
 
53
  = Build your WordPress website exactly the way you want it. =
54
 
149
 
150
  If you want to set different options you can either apply them after you activate the child theme using the theme customizer, or by using the "Live Preview" under Appearance > Themes.
151
 
152
+ Every theme handles options in its own way. Most often, they will create a set of options and store them in the WordPress database. Some options are specific to the active theme (or child theme), and some are specific to the parent theme only (meaning the child theme CANNOT override them). You will have to find out from the theme author which are which.
 
 
 
153
 
154
  = How do I add Web Fonts? =
155
 
256
  7. Files tab
257
 
258
  == Changelog ==
259
+ = 1.6.4 =
260
+ * New Feature: Copy selector button for Raw CSS textarea on Query/Selector tab.
261
+ * Fix: Menus rendering incorrectly for RTL locales
262
+ * Fix: Border-top etc. not being written correctly to stylesheet
263
+ * Fix: Refactored ajax semaphore logic and flow
264
+
265
  = 1.6.3 =
266
  * New Feature: Better child theme handling for multisite. Moved interface to Themes menu and check for network enabled.
267
  * Fix: Restrict child theme configurator access to install_themes capability
268
  * Fix: Preview links to Themes admin if not network enabled to prevent 'Cheatin, uh?' error.
269
+ * Fix: only users with "install_themes" capability have access to the Child Theme Configurator. This resolves permission issues with both multisite and single site installs. **MULTISITE USERS:** The Admin HAS MOVED to Network Admin > Themes > Child Themes for better handling for multisite (network) installs.
270
 
271
  = 1.6.2.1 =
272
  * Fix: Regular expression introduced in version 1.6.2 parses selectors incorrectly.
286
 
287
  = 1.6.0 =
288
  * New Feature: option to load parent stylesheet using wp_enqueue_style (link), @import or none. Thanks to cmwwebfx and Shapeshifter3 for pushing me on this
289
+ * New Feature: automatically-generated slug and name
290
  * New Feature: restore from backup and reset options
291
  * New Feature: backup files to "Child Theme Files" on Files Tab so they can be deleted
292
  * New Feature: Added new theme chooser select menu with screenshot, theme info and link to live preview.
451
 
452
  == Upgrade Notice ==
453
 
 
 
454
  == Override Parent Styles ==
455
 
456
  There are two ways to identify and override parent styles. The Child Theme Configurator lets you search styles by CSS selector and by rule. If you wish to change a specific CSS selector (e.g., h1), use the "Query/Selector" tab. If you have a specific CSS value you wish to change site-wide (e.g., the color of the type), use the "Rule/Value" tab.