Child Theme Configurator - Version 1.0.0

Version Description

  • Initial release.

=

Download this release

Release Info

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

Code changes from version 1.3.4 to 1.0.0

child-theme-configurator.php CHANGED
@@ -5,26 +5,22 @@ if ( !defined('ABSPATH')) exit;
5
  /*
6
  Plugin Name: Child Theme Configurator
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
- Description: Create a Child Theme from any installed Theme. Each CSS selector, rule and value can then be searched, previewed and modified.
9
- Version: 1.3.4
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
13
  Domain Path: /lang
14
  License: GPLv2
15
- Copyright (C) 2014 Lilaea Media
16
  */
17
 
 
18
  defined('LF') or define('LF', "\n");
19
- define('CHLD_THM_CFG_VERSION', '1.3.4');
20
- define('CHLD_THM_CFG_MAX_SELECTORS', '5000');
21
- define('CHLD_THM_CFG_MAX_RECURSE_LOOPS', '100');
22
 
23
- if (is_admin()):
24
- include_once( 'includes/class-ctc.php' );
25
- global $chld_thm_cfg;
26
- $chld_thm_cfg = new Child_Theme_Configurator( __FILE__ );
27
- endif;
28
 
29
  register_uninstall_hook( __FILE__ , 'child_theme_configurator_delete_plugin');
30
  function child_theme_configurator_delete_plugin() {
5
  /*
6
  Plugin Name: Child Theme Configurator
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
+ Description: Create Child Theme from any Theme or Stylesheet
9
+ Version: 1.0
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
13
  Domain Path: /lang
14
  License: GPLv2
15
+ Copyright (C) 2013 Lilaea Media
16
  */
17
 
18
+ defined('CHLD_THM_CFG_NS') or define('CHLD_THM_CFG_NS', 'chld_thm_cfg');
19
  defined('LF') or define('LF', "\n");
 
 
 
20
 
21
+ require_once( 'includes/class-ctc.php' );
22
+ global $chld_thm_cfg;
23
+ $chld_thm_cfg = new Child_Theme_Configurator( __FILE__ );
 
 
24
 
25
  register_uninstall_hook( __FILE__ , 'child_theme_configurator_delete_plugin');
26
  function child_theme_configurator_delete_plugin() {
css/chld-thm-cfg.css CHANGED
@@ -1,192 +1,151 @@
1
-
2
  .nav-tab, .nav-tab:focus, .nav-tab:active {
3
  outline: none;
4
  }
5
-
6
  .nav-tab-active {
7
- /*background-color:#f9f9f9;*/
8
  }
9
-
10
  .ctc-option-panel-container {
11
- position: relative;
12
- min-height: 600px;
13
- max-height: 800px;
14
- overflow: auto;
15
- border-bottom: 1px solid #f9f9f9;
16
  }
17
-
18
- #view_child_options_panel, #view_parnt_options_panel {
19
- white-space: pre;
20
- overflow: auto;
21
- font-family: monospace;
22
- word-wrap: normal;
23
  }
24
-
25
  .ctc-option-panel {
26
  visibility: hidden;
27
- position: absolute;
28
- width: 96%;
29
- top: 0;
30
- left: 0;
31
- padding: 10px 2%;
32
  }
33
-
34
  .ctc-option-panel-active {
35
  visibility: visible;
36
  }
37
-
38
  .ctc-swatch {
39
- display: block;
40
- float: left;
41
- font-size: 16px;
42
- padding: 0;
43
- line-height: 1;
44
- overflow: hidden;
45
  }
46
-
47
  .ctc-hidden {
48
- display: none;
49
  }
50
-
51
  .ctc-swatch.ctc-specific {
52
- min-height: 60px;
53
- max-height: 100px;
54
- max-width: 100px;
55
- margin: 0 2% 0 0;/*color:#7f7f7f;
 
 
 
56
  border: 1px solid #ddd;*/
 
57
  }
58
-
59
  .ctc-parent-row {
60
- clear: both;
61
- position: relative;
62
- margin: 4px 0;
63
  }
64
-
65
  .ctc-parent-value {
66
  }
67
-
68
  .ctc-input-cell {
69
- display: block;
70
- float: left;
71
- width: 25%;
72
- max-width: 250px;
73
- margin-right: 2.13%;
74
  }
75
-
76
  .ctc-input-cell-wide {
77
- display: block;
78
- float: left;
79
- width: 70%;
80
- margin-right: 2.13%;
81
  }
82
-
83
  .ctc-input-cell-wide textarea {
84
- width: 100%;
85
- height: 200px;
86
- white-space: pre;
87
- overflow: auto;
88
- font-family: monospace;
89
- word-wrap: normal;
90
  }
91
-
92
  .ctc-save-input {
93
  }
94
-
95
  .ctc-button-cell, .ctc-input-cell.ctc-button-cell {
96
- width: 85px;
97
  }
98
-
99
  .ctc-textarea-button-cell {
100
- margin: 15px 0;
101
- width: 85px;
102
  }
103
-
104
  .ctc-selector-link {
105
  }
106
-
107
  .ctc-selector-handle {
108
  }
109
- .ctc-rewrite-toggle {
110
- font-size:0.8em;
111
- padding-left:1em;
112
- display:none;
113
- outline:none;
114
- }
115
  .ctc-selector-container {
116
- clear: both;
117
- background: #f9f9f9;
118
- border: 1px solid #ddd;
119
- padding: 10px;
120
- min-height: 300px;
121
- max-height: 500px;
122
- position: absolute;
123
- width: 90%;
124
  overflow: auto;
125
- left: 0;
126
- top: 30px;
127
- display: none;
128
- z-index: 99999;
129
- -moz-box-shadow: 1px 2px 10px rgba(51,51,51,0.4);
130
- -webkit-box-shadow: 1px 2px 10px rgba(51,51,51,0.4);
131
- box-shadow: 1px 2px 10px rgba(51,51,51,0.4);
132
  }
133
-
134
  .ctc-query-heading {
135
  }
136
-
137
  .ctc-selector-row {
138
- clear: both;
139
  margin: 0;
140
- padding: 8px 0;
141
  border-top: 1px solid #ddd;
142
  border-bottom: 1px solid #fff;
143
  }
144
-
145
  .ctc-input-row {
146
- clear: both;
147
- margin: 4px 0;
148
- padding: 4px 0;
149
  border-bottom: 1px solid #ddd;
150
  }
151
-
152
  .ctc-selector-value {
153
  }
154
-
155
  .ctc-selector-cell {
156
- float: left;
157
- width: 30%;
158
- margin-right: 2%;
159
  }
160
-
161
  .ctc-child-input-cell {
162
- display: block;
163
- float: left;
164
- margin-right: 2.13%;
 
165
  }
166
-
167
  .ctc-child-input-cell-container {
168
- float: left;
169
- width: 40%;
170
- margin-right: 2%;
171
  }
172
-
173
  .ctc-child-input-cell-container label {
174
- float: left;
175
- clear: both;
176
- width: 100px;
177
- margin-right: 2%;
178
  }
179
-
180
  .ctc-child-input-cell input[type="text"] {
181
- /*width:60px;*/
182
- }
183
- .ctc-select {
184
- max-width:100%;
185
  }
186
  .ctc-child-input-cell input[type="text"].ctc-input-wide {
187
- width: 200px;
188
  }
189
-
190
  .clearfix:after, .clearfix:before {
191
  content: ' ';
192
  display: table;
@@ -201,3 +160,4 @@
201
  .ie7 .clearfix {
202
  zoom: 1;
203
  }
 
 
1
  .nav-tab, .nav-tab:focus, .nav-tab:active {
2
  outline: none;
3
  }
 
4
  .nav-tab-active {
5
+ /*background-color:#f9f9f9;*/
6
  }
 
7
  .ctc-option-panel-container {
8
+ position:relative;
9
+ min-height:600px;
10
+ max-height:800px;
11
+ overflow:auto;
 
12
  }
13
+ #preview_options_panel {
14
+ white-space:pre;
15
+ overflow:auto;
16
+ font-family:monospace;
17
+ word-wrap:normal;
 
18
  }
 
19
  .ctc-option-panel {
20
  visibility: hidden;
21
+ position:absolute;
22
+ width:96%;
23
+ top:0;
24
+ left:0;
25
+ padding:10px 2%;
26
  }
 
27
  .ctc-option-panel-active {
28
  visibility: visible;
29
  }
 
30
  .ctc-swatch {
31
+ display:block;
32
+ float:left;
 
 
 
 
33
  }
 
34
  .ctc-hidden {
35
+ display:none;
36
  }
 
37
  .ctc-swatch.ctc-specific {
38
+ min-height:60px;
39
+ max-height:100px;
40
+ max-width:100px;
41
+ margin:0 2% 0 0;
42
+ padding:0;
43
+ line-height:1;
44
+ /*color:#7f7f7f;
45
  border: 1px solid #ddd;*/
46
+ overflow: hidden;
47
  }
 
48
  .ctc-parent-row {
49
+ clear:both;
50
+ position:relative;
51
+ margin:4px 0;
52
  }
 
53
  .ctc-parent-value {
54
  }
 
55
  .ctc-input-cell {
56
+ display:block;
57
+ float:left;
58
+ width:25%;
59
+ max-width:250px;
60
+ margin-right:2.13%;
61
  }
 
62
  .ctc-input-cell-wide {
63
+ display:block;
64
+ float:left;
65
+ width:70%;
66
+ margin-right:2.13%;
67
  }
 
68
  .ctc-input-cell-wide textarea {
69
+ width:100%;
70
+ height:200px;
71
+ white-space:pre;
72
+ overflow:auto;
73
+ font-family:monospace;
74
+ word-wrap:normal;
75
  }
 
76
  .ctc-save-input {
77
  }
 
78
  .ctc-button-cell, .ctc-input-cell.ctc-button-cell {
79
+ width:80px;
80
  }
 
81
  .ctc-textarea-button-cell {
82
+ margin:15px 0;
83
+ width:80px;
84
  }
 
85
  .ctc-selector-link {
86
  }
 
87
  .ctc-selector-handle {
88
  }
 
 
 
 
 
 
89
  .ctc-selector-container {
90
+ clear:both;
91
+ background:#f9f9f9;
92
+ border:1px solid #ddd;
93
+ padding:10px;
94
+ min-height:300px;
95
+ max-height:500px;
96
+ position:absolute;
97
+ width:90%;
98
  overflow: auto;
99
+ left:0;
100
+ top:30px;
101
+ display:none;
102
+ z-index:99999;
 
 
 
103
  }
 
104
  .ctc-query-heading {
105
  }
 
106
  .ctc-selector-row {
107
+ clear:both;
108
  margin: 0;
109
+ padding:8px 0;
110
  border-top: 1px solid #ddd;
111
  border-bottom: 1px solid #fff;
112
  }
 
113
  .ctc-input-row {
114
+ clear:both;
115
+ margin:4px 0;
116
+ padding:4px 0;
117
  border-bottom: 1px solid #ddd;
118
  }
 
119
  .ctc-selector-value {
120
  }
 
121
  .ctc-selector-cell {
122
+ float:left;
123
+ width:30%;
124
+ margin-right:2%;
125
  }
 
126
  .ctc-child-input-cell {
127
+ display:block;
128
+ float:left;
129
+ margin-right:2.13%;
130
+
131
  }
 
132
  .ctc-child-input-cell-container {
133
+ float:left;
134
+ width:40%;
135
+ margin-right:2%;
136
  }
 
137
  .ctc-child-input-cell-container label {
138
+ float:left;
139
+ clear:both;
140
+ width:100px;
141
+ margin-right:2%;
142
  }
 
143
  .ctc-child-input-cell input[type="text"] {
144
+ width:60px;
 
 
 
145
  }
146
  .ctc-child-input-cell input[type="text"].ctc-input-wide {
147
+ width:200px;
148
  }
 
149
  .clearfix:after, .clearfix:before {
150
  content: ' ';
151
  display: table;
160
  .ie7 .clearfix {
161
  zoom: 1;
162
  }
163
+
includes/class-ctc-css.php CHANGED
@@ -6,424 +6,260 @@ if ( !defined('ABSPATH')) exit;
6
  Class: Child_Theme_Configurator_CSS
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Handles all CSS output, parsing, normalization
9
- Version: 1.3.4
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
13
  Domain Path: /lang
14
  License: GPLv2
15
- Copyright (C) 2014 Lilaea Media
16
  */
17
  class Child_Theme_Configurator_CSS {
18
- var $version;
19
- // data dictionaries
20
- var $dict_query; // @media queries and 'base'
21
- var $dict_sel; // selectors
22
- var $dict_qs; // query/selector lookup
23
- var $dict_rule; // css rules
24
- var $dict_val; // css values
25
- var $dict_seq; // child load order (priority)
26
- // hierarchies
27
- var $sel_ndx; // query => selector hierarchy
28
- var $val_ndx; // selector => rule => value hierarchy
29
- // key counters
30
- var $qskey; // counter for dict_qs
31
- var $querykey; // counter for dict_query
32
- var $selkey; // counter for dict_sel
33
- var $rulekey; // counter for dict_rule
34
- var $valkey; // counter for dict_val
35
- // miscellaneous properties
36
- var $imports; // @import rules
37
- var $updates; // temporary update cache
38
- var $child; // child theme slug
39
- var $parnt; // parent theme slug
40
- var $configtype; // theme or plugin extension
41
- var $child_name; // child theme name
42
- var $child_author; // stylesheet author
43
- var $child_version; // stylesheet version
44
 
45
  function __construct() {
46
- // scalars
47
- $this->version = '1.3.4';
48
- $this->querykey = 0;
49
- $this->selkey = 0;
50
- $this->qskey = 0;
51
- $this->rulekey = 0;
52
- $this->valkey = 0;
53
- $this->child = '';
54
- $this->parnt = '';
55
- $this->configtype = 'theme';
56
- $this->child_name = '';
57
- $this->child_author = 'Child Theme Configurator by Lilaea Media';
58
- $this->child_version = '1.0';
59
- // multi-dim arrays
60
- $this->dict_qs = array();
61
- $this->dict_sel = array();
62
- $this->dict_query = array();
63
- $this->dict_rule = array();
64
- $this->dict_val = array();
65
- $this->dict_seq = array();
66
  $this->sel_ndx = array();
67
  $this->val_ndx = array();
68
- $this->imports = array('child' => array(), 'parnt' => array());
 
69
  $this->updates = array();
70
  }
71
 
72
- /*
73
- * get_prop
74
- * Getter interface (data sliced different ways depending on objname)
75
- */
76
- function get_prop($objname, $params = null) {
 
 
77
  switch ($objname):
78
  case 'updates':
79
- return $this->obj_to_utf8($this->updates);
80
  case 'imports':
81
- 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());
82
  case 'sel_ndx':
83
- return $this->obj_to_utf8($this->denorm_sel_ndx(empty($params['key'])?null:$params['key']));
84
- case 'rule_val':
85
- return empty($params['key']) ? array() : $this->denorm_rule_val($params['key']);
86
- case 'val_qry':
87
- if (isset($params['rule']) && isset($this->dict_rule[$params['rule']])):
88
- return empty($params['key']) ?
89
- array() : $this->denorm_val_query($params['key'], $params['rule']);
90
- endif;
91
- case 'sel_val':
92
- return empty($params['key']) ?
93
- array() : $this->denorm_sel_val($params['key']);
94
- case 'rule':
95
- return $this->obj_to_utf8(array_flip($this->dict_rule));
96
- case 'child':
97
- return $this->child;
98
- case 'parnt':
99
- return $this->parnt;
100
- case 'configtype':
101
- return $this->configtype;
102
- case 'child_name':
103
- return $this->child_name;
104
  case 'author':
105
- return $this->child_author;
106
- case 'version':
107
- return $this->child_version;
108
- case 'preview':
109
- $template = (empty($params['key']) || 'child' == $params['key']) ? 'child' : 'parnt';
110
- return $this->get_raw_css($template);
111
  endswitch;
112
  return false;
113
  }
114
 
115
- /*
116
- * set_prop
117
- * Setter interface (scalar values only)
118
- */
119
- function set_prop($prop, $value) {
120
- if (is_scalar($this->{$prop}))
121
- $this->{$prop} = $value;
122
- else return false;
 
 
123
  }
124
-
125
- function get_raw_css($template = 'child') {
126
- if ($styles = $this->read_stylesheet($template)):
127
- if (preg_match("/\}[\w\#\.]/", $styles)): // prettify compressed CSS
128
- $styles = preg_replace("/\*\/\s*/s", "*/\n", $styles); // end comment
129
- $styles = preg_replace("/\{\s*/s", " {\n ", $styles); // open brace
130
- $styles = preg_replace("/;\s*/s", ";\n ", $styles); // semicolon
131
- $styles = preg_replace("/\s*\}\s*/s", "\n}\n", $styles); // close brace
132
  endif;
133
- return $styles;
134
- endif;
135
- }
136
-
137
- function get_css_header() {
138
- $parnt = $this->get_prop('parnt');
139
- return '/*' . LF
140
- . 'Theme Name: ' . $this->get_prop('child_name') . LF
141
- . 'Template: ' . $parnt . LF
142
- . 'Author: ' . $this->get_prop('author'). LF
143
- . 'Version: ' . $this->get_prop('version') . LF
144
- . 'Updated: ' . current_time('mysql') . LF
145
- . '*/' . LF . LF
146
- . '@charset "UTF-8";' . LF
147
- . '@import url(\'../' . $parnt . '/style.css\');' . LF;
148
- }
149
-
150
- function get_child_target($file = 'style.css') {
151
- return get_theme_root() . '/' . $this->get_prop('child') . '/' . $file;
152
- }
153
- function get_parent_source($file = 'style.css') {
154
- return get_theme_root() . '/' . $this->get_prop('parnt') . '/' . $file;
155
- }
156
-
157
- /*
158
- * update_arrays
159
- * accepts CSS properties as raw strings and normilizes into
160
- * CTC object arrays, creating update cache in the process.
161
- * Update cache is returned to UI via AJAX to refresh page
162
- */
163
- function update_arrays($template, $query, $sel, $rule = null, $value = null, $important = 0, $seq = null) {
164
- // normalize selector styling
165
- $sel = implode(', ', preg_split('#\s*,\s*#s', trim($sel)));
166
- // add selector and query to index
167
- if (!isset($this->dict_query[$query])) $this->dict_query[$query] = ++$this->querykey;
168
- if (!isset($this->dict_sel[$sel])) $this->dict_sel[$sel] = ++$this->selkey;
169
- if (!isset($this->sel_ndx[$this->dict_query[$query]][$this->dict_sel[$sel]])):
170
- // increment key number
171
- $this->sel_ndx[$this->dict_query[$query]][$this->dict_sel[$sel]] = ++$this->qskey;
172
-
173
- $this->dict_qs[$this->qskey]['s'] = $this->dict_sel[$sel];
174
- $this->dict_qs[$this->qskey]['q'] = $this->dict_query[$query];
175
- // tell the UI to update a single cached query/selector lookup by passing 'qsid' as the key
176
- // (normally the entire array is replaced):
177
- $this->updates[] = array(
178
- 'obj' => 'sel_ndx',
179
- 'key' => 'qsid',
180
- 'data' => array(
181
- 'query' => $query,
182
- 'selector' => $sel,
183
- 'qsid' => $this->qskey,
184
- ),
185
- );
186
- endif;
187
- if (!isset($this->dict_seq[$this->qskey]))
188
- $this->dict_seq[$this->qskey] = $this->qskey;
189
- // set data and value
190
- if ($rule):
191
- if (!isset($this->dict_rule[$rule])):
192
- $this->dict_rule[$rule] = ++$this->rulekey;
193
- // tell the UI to update a single cached rule:
194
- $this->updates[] = array(
195
- 'obj' => 'rule',
196
- 'key' => $this->rulekey,
197
- 'data' => $rule,
198
- );
199
  endif;
200
- $qsid = $this->sel_ndx[$this->dict_query[$query]][$this->dict_sel[$sel]];
201
- $ruleid = $this->dict_rule[$rule];
202
- if (!isset($this->dict_val[$value])):
203
- $this->dict_val[$value] = ++$this->valkey;
 
 
 
204
  endif;
205
- $this->val_ndx[$qsid][$ruleid][$template] = $this->dict_val[$value];
206
- // set the important flag for this value
207
- $this->val_ndx[$qsid][$ruleid]['i_' . $template] = $important;
208
- // tell the UI to add a single cached query/selector data array:
209
- $updatearr = array(
210
- 'obj' => 'sel_val',
211
- 'key' => $qsid,
212
- 'data' => $this->denorm_sel_val($qsid),
213
- );
214
- $this->updates[] = $updatearr;
215
- if (isset($seq)): // this is a renamed selector
216
- $this->dict_seq[$qsid] = $seq;
217
- $this->updates[] = array(
218
- 'obj' => 'rewrite',
219
- 'key' => $qsid,
220
- 'data' => $sel,
221
- );
 
222
  endif;
223
  endif;
224
  }
225
-
226
- /*
227
- * reset_updates
228
- * clears temporary update cache
229
- */
230
- function reset_updates() {
231
- $this->updates = array();
232
- }
233
-
234
- function read_stylesheet($template = 'child') {
235
- $source = $this->get_prop($template);
236
- $configtype = $this->get_prop('configtype');
237
- if (empty($source) || !is_scalar($source)) return false;
238
- $stylesheets = array();
239
- $themedir = get_theme_root() . '/' . $source;
240
- if ('parnt' == $template && (empty($configtype) || 'theme' == $configtype) && isset($_POST['ctc_scan_subdirs'])):
241
- $stylesheets = $this->recurse_directory($themedir);
242
- else:
243
- $stylesheets[] = apply_filters('chld_thm_cfg_' . $template, $themedir . '/style.css', $this);
 
 
 
 
244
  endif;
245
-
246
- // read stylesheets
247
- $styles = '';
248
- foreach ($stylesheets as $stylesheet):
249
- if ($stylesheet_verified = $this->is_file_ok($stylesheet, 'read')):
250
- $import_url = preg_replace('%^' . preg_quote($themedir) . '/%', '', $stylesheet_verified);
251
- $styles .= @file_get_contents($stylesheet_verified) . "\n";
252
- if ($styles && isset($_POST['ctc_scan_subdirs']) && 'parnt' == $template && (empty($configtype) || 'theme' == $configtype) && 'style.css' != $import_url):
253
- $this->imports['child']["@import url('../" . $source . '/' . $import_url . "')"] = 1;
254
-
255
- // convert relative urls to absolute
256
- $this->convert_parent_rel_url_to_abs_url($import_url, $styles);
257
- endif;
258
- endif;
259
- endforeach;
260
- return $styles;
261
  }
262
 
263
- function recurse_directory($rootdir, $ext = 'css') {
264
- $files = array();
265
- $dirs = array($rootdir);
266
- $loops = 0;
267
- while(count($dirs) && $loops < CHLD_THM_CFG_MAX_RECURSE_LOOPS):
268
- $loops++;
269
- $dir = array_shift($dirs);
270
- if ($handle = opendir($dir)):
271
- while (false !== ($file = readdir($handle))):
272
- if (preg_match("/^\./", $file)) continue;
273
- $filepath = $dir . '/' . $file;
274
- if (is_dir($filepath)):
275
- array_unshift($dirs, $filepath);
276
- elseif (is_file($filepath) && preg_match("/\.".$ext."$/", $filepath)):
277
- $files[] = $filepath;
278
- endif;
279
- endwhile;
280
- closedir($handle);
281
- endif;
282
- endwhile;
283
- return $files;
284
  }
285
 
286
- function convert_parent_rel_url_to_abs_url($url, &$styles) {
287
- $source = $this->get_prop('parnt');
288
- $spliton = '%[/\\\\]%';
289
- $dirname = dirname($url);
290
- $dirs = preg_split($spliton, $dirname);
291
- $dds = '';
292
- $themeuri = get_theme_root_uri();
293
- while (count($dirs)):
294
- $thisdir = array_pop($dirs);
295
- $upone = implode('/', $dirs);
296
- $dds .= '\.\.\/';
297
- $regex = '%url\([\'" ]*' . $dds . '(.+?)[\'" ]*\)%';
298
- $fullurl = $themeuri . '/' . $source . '/' . $upone . ('' == $upone ? '' : '/' );
299
- $styles = preg_replace($regex, "url(" . $fullurl . "$1)", $styles);
300
- endwhile;
301
  }
302
- /*
303
- * parse_post_data
304
- * Parse user form input into separate properties and pass to update_arrays
305
- */
306
- function parse_post_data() {
307
- if (isset($_POST['ctc_new_selectors'])):
308
-
309
- $this->parse_css('child', LF . $this->parse_css_input($_POST['ctc_new_selectors']),
310
- (isset($_POST['ctc_sel_ovrd_query'])?trim($_POST['ctc_sel_ovrd_query']):null), false);
311
- elseif (isset($_POST['ctc_child_imports'])):
312
- $this->imports['child'] = array();
313
- $this->parse_css('child', $this->parse_css_input($_POST['ctc_child_imports']));
314
- else:
315
- $newselector = isset($_POST['ctc_rewrite_selector']) ? sanitize_text_field($this->parse_css_input(($_POST['ctc_rewrite_selector']))) : NULL;
316
- // set the custom sequence value
317
- foreach (preg_grep('#^ctc_ovrd_child_seq_#', array_keys($_POST)) as $post_key):
318
- if (preg_match('#^ctc_ovrd_child_seq_(\d+)$#', $post_key, $matches)):
319
- $qsid = $matches[1];
320
- $this->dict_seq[$qsid] = intval($_POST[$post_key]);
 
 
 
 
 
 
 
 
 
 
 
321
  endif;
322
- endforeach;
323
- $parts = array();
324
- foreach (preg_grep('#^ctc_(ovrd|\d+)_child#', array_keys($_POST)) as $post_key):
325
- if (preg_match('#^ctc_(ovrd|\d+)_child_([\w\-]+?)_(\d+?)(_(.+))?$#', $post_key, $matches)):
326
- $valid = $matches[1];
327
- $rule = $matches[2];
328
- if (null == $rule || !isset($this->dict_rule[$rule])) continue;
329
- $ruleid = $this->dict_rule[$rule];
330
- $qsid = $matches[3];
331
- $value = sanitize_text_field($this->parse_css_input(($_POST[$post_key])));
332
- $important = $this->is_important($value);
333
- if (!empty($_POST['ctc_' . $valid . '_child_' . $rule . '_i_' . $qsid])) $important = 1;
334
-
335
- $selarr = $this->denorm_query_sel($qsid);
336
- if (!empty($matches[5])):
337
- $parts[$qsid][$rule][$matches[5]] = $value;
338
- $parts[$qsid][$rule]['important'] = $important;
339
- $parts[$qsid][$rule]['query'] = $selarr['query'];
340
- $parts[$qsid][$rule]['selector'] = $selarr['selector'];
341
- else:
342
- if ($newselector && $newselector != $selarr['selector']):
343
- // If this is a renamed selector, add new selector to array
344
- // and clear original child selector values.
345
- // Passing the sequence in the last argument serves two purposes:
346
- // 1. sets sequence for new renamed selector.
347
- // 2. tells the update_arrays function to flag this as a
348
- // renamed selector to pass back in result array.
349
- $this->update_arrays('child', $selarr['query'], $newselector,
350
- $rule, trim($value), $important, $this->dict_seq[$qsid]);
351
- $this->update_arrays('child', $selarr['query'], $selarr['selector'], $rule, '');
352
- else:
353
- // Otherwise, just update with the new values:
354
- $this->update_arrays('child', $selarr['query'], $selarr['selector'],
355
- $rule, trim($value), $important);
356
- endif;
357
- endif;
358
  endif;
359
- endforeach;
360
- foreach ($parts as $qsid => $rule_arr):
361
- foreach ($rule_arr as $rule => $rule_part):
362
- if ('background' == $rule):
363
- $value = $rule_part['background_url'];
364
- elseif ('background-image' == $rule):
365
- if (empty($rule_part['background_url'])):
366
- if (empty($rule_part['background_color2'])):
367
- $value = '';
368
- else:
369
- $value = implode(':', array(
370
- $rule_part['background_origin'],
371
- $rule_part['background_color1'], '0%',
372
- $rule_part['background_color2'], '100%'
373
- ));
374
- endif;
375
- else:
376
- $value = $rule_part['background_url'];
377
- endif;
378
- elseif (preg_match('#^border(\-(top|right|bottom|left))?$#', $rule)):
379
- $value = implode(' ', array(
380
- $rule_part['border_width'],
381
- $rule_part['border_style'],
382
- $rule_part['border_color']
383
- ));
384
- else:
385
- $value = '';
386
- endif;
387
- if ($newselector && $newselector != $rule_part['selector']):
388
- $this->update_arrays('child', $rule_part['query'], $newselector,
389
- $rule, trim($value), $rule_part['important'], $this->dict_seq[$qsid]);
390
- $this->update_arrays('child', $rule_part['query'], $rule_part['selector'], $rule, '');
391
- else:
392
- $this->update_arrays('child', $rule_part['query'], $rule_part['selector'],
393
- $rule, trim($value), $rule_part['important']);
394
- endif;
395
- endforeach;
396
- endforeach;
397
  endif;
398
  }
399
 
400
- /*
401
- * parse_css_input
402
- * Normalize raw user CSS input so that the parser can read it.
403
- * TODO: this is a stub for future use
404
- */
405
- function parse_css_input($styles) {
406
- return stripslashes($styles);
407
- }
408
-
409
- /*
410
- * parse_css_file
411
- * reads stylesheet to get WordPress meta data and passes rest to parse_css
412
- */
413
- function parse_css_file($template) {
414
- $styles = $this->read_stylesheet($template);
415
- // get theme name
416
- $regex = '#Theme Name:\s*(.+?)\n#i';
417
- preg_match($regex, $styles, $matches);
418
- $child_name = $this->get_prop('child_name');
419
- if (!empty($matches[1]) && 'child' == $template && empty($child_name)) $this->set_prop('child_name', $matches[1]);
420
- $this->parse_css($template, $styles);
421
- }
422
-
423
- /*
424
- * parse_css
425
- * accepts raw CSS as text and parses into separate properties
426
- */
427
  function parse_css($template, $styles, $basequery = null, $parse_imports = true) {
428
  if (false === strpos($basequery, '@')):
429
  $basequery = 'base';
@@ -437,12 +273,8 @@ class Child_Theme_Configurator_CSS {
437
  if ($parse_imports):
438
  $regex = '#(\@import.+?);#';
439
  preg_match_all($regex, $styles, $matches);
440
- foreach (preg_grep('#style\.css#', $matches[1], PREG_GREP_INVERT) as $import)
441
- $this->imports[$template][$import] = 1;
442
- $this->updates[] = array(
443
- 'obj' => 'imports',
444
- 'data' => array_keys($this->imports[$template]),
445
- );
446
  endif;
447
  // break into @ segments
448
  $regex = '#(\@media.+?)\{(.*?\})\s*\}#s';
@@ -452,6 +284,7 @@ class Child_Theme_Configurator_CSS {
452
  endforeach;
453
  // remove rulesets from styles
454
  $ruleset[$basequery] = preg_replace($regex, '', $styles);
 
455
  foreach ($ruleset as $query => $segment):
456
  // make sure there is semicolon before closing brace
457
  $segment = preg_replace('#(\})#', ";$1", $segment);
@@ -459,14 +292,15 @@ class Child_Theme_Configurator_CSS {
459
  preg_match_all($regex, $segment, $matches);
460
  foreach($matches[1] as $sel):
461
  $stuff = array_shift($matches[2]);
 
 
462
  $this->update_arrays($template, $query, $sel);
 
463
  foreach (explode(';', $stuff) as $ruleval):
464
- if ($this->qskey > CHLD_THM_CFG_MAX_SELECTORS) break;
465
  if (false === strpos($ruleval, ':')) continue;
466
  list($rule, $value) = explode(':', $ruleval, 2);
467
  $rule = trim($rule);
468
- $rule = preg_replace_callback("/[^\w\-]/", array($this, 'to_ascii'), $rule);
469
- $value = stripslashes(trim($value));
470
 
471
  $rules = $values = array();
472
  // save important flag
@@ -498,60 +332,49 @@ class Child_Theme_Configurator_CSS {
498
  $value = $this->encode_gradient($value);
499
  endif;
500
  // normalize common vendor prefixes
501
- $rule = preg_replace('#(\-(o|ms|moz|webkit)\-)?(box\-sizing|font\-smoothing|border\-radius|box\-shadow|transition)#', "$3", $rule);
502
  $this->update_arrays($template, $query, $sel, $rule, $value, $important);
503
  endforeach;
504
  endforeach;
505
  endforeach;
506
  endforeach;
507
  }
508
-
509
- /*
510
- * write_css
511
- * converts normalized CSS object data into stylesheet.
512
- * Preserves selector sequence and !important flags of parent stylesheet.
513
- * @media query blocks are sorted using internal heuristics (see sort_queries)
514
- * New selectors are appended to the end of each media query block.
515
- */
516
- function write_css($backup = false) {
517
  // write new stylesheet
518
- $output = apply_filters('chld_thm_cfg_css_header', $this->get_css_header(), $this);
519
- $imports = $this->get_prop('imports');
520
- if (!empty($imports)):
521
- foreach ($imports as $import):
 
 
 
 
 
 
522
  $output .= $import . ';' . LF;
523
  endforeach;
524
  endif;
525
  $output .= LF;
526
- // turn the dictionaries into indexes (value => id into id => value):
527
- $rulearr = array_flip($this->dict_rule);
528
- $valarr = array_flip($this->dict_val);
529
- $selarr = array_flip($this->dict_sel);
530
  foreach ($this->sort_queries() as $query => $sort_order):
 
 
531
  $has_selector = 0;
532
  $sel_output = '';
533
- $selectors = $this->sel_ndx[$this->dict_query[$query]];
534
- uasort($selectors, array($this, 'cmp_seq'));
535
  if ('base' != $query) $sel_output .= $query . ' {' . LF;
536
- foreach ($selectors as $selid => $qsid):
537
  $has_value = 0;
538
- $sel = $selarr[$selid];
539
- if (!empty($this->val_ndx[$qsid])):
540
- $shorthand = array();
541
- foreach ($this->val_ndx[$qsid] as $ruleid => $valid):
542
- if (isset($valid['child']) && isset($valarr[$valid['child']]) && '' !== $valarr[$valid['child']]):
543
  if (! $has_value):
544
- $sel_output .= isset($this->dict_seq[$qsid])?'/*' . $this->dict_seq[$qsid] . '*/' . LF:''; // show load order
545
  $sel_output .= $sel . ' {' . LF;
546
  $has_value = 1;
547
  $has_selector = 1;
548
  endif;
549
- $important_parnt = empty($valid['i_parnt']) ? 0 : 1;
550
- $important = isset($valid['i_child']) ? $valid['i_child'] : $important_parnt;
551
- $sel_output .= $this->add_vendor_rules($rulearr[$ruleid], stripslashes($valarr[$valid['child']]), $shorthand, $important);
552
  endif;
553
  endforeach;
554
- $sel_output .= $this->encode_shorthand($shorthand); // . ($important ? ' !important' : '');
555
  if ($has_value):
556
  $sel_output .= '}' . LF;
557
  endif;
@@ -560,46 +383,34 @@ class Child_Theme_Configurator_CSS {
560
  if ('base' != $query) $sel_output .= '}' . LF;
561
  if ($has_selector) $output .= $sel_output;
562
  endforeach;
563
- $stylesheet = apply_filters('chld_thm_cfg_target', $this->get_child_target(), $this);
564
- if ($stylesheet_verified = $this->is_file_ok($stylesheet, 'write')):
565
- // backup current stylesheet
566
- if ($backup && is_file($stylesheet_verified)):
567
- $timestamp = date('YmdHis', current_time('timestamp'));
568
- $bakfile = preg_replace("/\.css$/", '', $stylesheet_verified) . '-' . $timestamp . '.css';
569
- if (false === file_put_contents($bakfile, file_get_contents($stylesheet_verified))) return false;
570
- endif;
571
- // write new stylesheet
572
- if (false === file_put_contents($stylesheet_verified, $output)) return false;
573
- return true;
574
- endif;
575
- return false;
576
  }
577
 
578
- /*
579
- * add_vendor_rules
580
- * Applies vendor prefixes to rules/values
581
- * These are based on commonly used practices and not all vendor prefixed are supported
582
- * TODO: verify this logic against vendor and W3C documentation
583
- */
584
- function add_vendor_rules($rule, $value, &$shorthand, $important = 0) {
585
  $rules = '';
586
- if ('filter' == $rule && (false !== strpos($value, 'progid:DXImageTransform.Microsoft.Gradient'))) return;
587
- $importantstr = $important ? ' !important' : '';
588
- if (preg_match("/^(margin|padding)\-(top|right|bottom|left)$/", $rule, $matches)):
589
- $shorthand[$matches[1]][$matches[2]] = $value . $importantstr;
590
- return '';
591
- elseif (preg_match("/^(box\-sizing|font\-smoothing|border\-radius|box\-shadow|transition)$/", $rule)):
592
  foreach(array('moz', 'webkit', 'o') as $prefix):
593
- $rules .= ' -' . $prefix . '-' . $rule . ': ' . $value . $importantstr . ';' . LF;
594
  endforeach;
595
- $rules .= ' ' . $rule . ': ' . $value . $importantstr . ';' . LF;
596
  elseif ('background-image' == $rule):
597
  // gradient?
598
  if ($gradient = $this->decode_gradient($value)):
599
  // standard gradient
600
  foreach(array('moz', 'webkit', 'o', 'ms') as $prefix):
601
  $rules .= ' background-image: -' . $prefix . '-' . 'linear-gradient(' . $gradient['origin'] . ', '
602
- . $gradient['color1'] . ', ' . $gradient['color2'] . ')' . $importantstr . ';' . LF;
603
  endforeach;
604
  // W3C standard gradient
605
  // rotate origin 90 degrees
@@ -613,7 +424,7 @@ class Child_Theme_Configurator_CSS {
613
  $org = 'to ' . implode(' ', $dirs);
614
  endif;
615
  $rules .= ' background-image: linear-gradient(' . $org . ', '
616
- . $gradient['color1'] . ', ' . $gradient['color2'] . ')' . $importantstr . ';' . LF;
617
 
618
  // legacy webkit gradient - we'll add if there is demand
619
  // '-webkit-gradient(linear,' .$origin . ', ' . $color1 . ', '. $color2 . ')';
@@ -622,173 +433,18 @@ class Child_Theme_Configurator_CSS {
622
  $type = (in_array($gradient['origin'], array('left', 'right', '0deg', '180deg')) ? 1 : 0);
623
  $color1 = preg_replace("/^#/", '#00', $gradient['color1']);
624
  $rules .= ' filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=' . $type . ', StartColorStr="'
625
- . strtoupper($color1) . '", EndColorStr="' . strtoupper($gradient['color2']) . '")' . $importantstr . ';' . LF;
626
  else:
627
  // url or other value
628
- $rules .= ' ' . $rule . ': ' . $value . $importantstr . ';' . LF;
629
  endif;
630
  else:
631
- $rule = preg_replace_callback("/\d+/", array($this, 'from_ascii'), $rule);
632
- $rules .= ' ' . $rule . ': ' . $value . $importantstr . ';' . LF;
633
- endif;
634
- return $rules;
635
- }
636
-
637
- /*
638
- * normalize_background
639
- * parses background shorthand value and returns
640
- * normalized rule/value pairs for each property
641
- */
642
- function normalize_background($value, &$rules, &$values){
643
- if (false !== strpos($value, 'gradient')):
644
- // only supporting linear syntax
645
- if (preg_match('#(linear\-|Microsoft\.)#', $value)):
646
- $values[] = $value;
647
- $rules[] = 'background-image';
648
- endif;
649
- else:
650
- $regex = '#(url *\([^\)]+\))#';
651
- if (preg_match($regex, $value, $matches)) $url = $matches[1];
652
- $parts = preg_split($regex, $value);
653
-
654
- if (count($parts) == 1):
655
- // this is a named color or single hex color or none
656
- $part = str_replace(' ', '', $parts[0]);
657
- $rules[] = 'none' == $part ? 'background' : 'background-color';
658
- $values[] = $part;
659
- else:
660
- $rules[] = 'background-image';
661
- $values[] = $url;
662
- if (!empty($parts[0]) && '' !== $parts[0]):
663
- $rules[] = 'background-color';
664
- $values[] = trim($parts[0]);
665
- endif;
666
- $position = array();
667
- foreach(preg_split('/ +/', trim($parts[1])) as $part):
668
- if ('' === $part) continue; // empty($part) ||
669
- if (false === strpos($part, 'repeat')):
670
- $position[] = $part;
671
- else:
672
- $rules[] = 'background-repeat';
673
- $values[] = $part;
674
- endif;
675
- endforeach;
676
- if (count($position)):
677
- $rules[] = 'background-position';
678
- $values[] = implode(' ', $position);
679
- endif;
680
- endif;
681
- endif;
682
- }
683
-
684
- /*
685
- * normalize_font
686
- * parses font shorthand value and returns
687
- * normalized rule/value pairs for each property
688
- */
689
- function normalize_font($value, &$rules, &$values) {
690
- $regex = '#^((\d+|bold|normal) )?((italic|normal) )?(([\d\.]+(px|r?em|%))[\/ ])?(([\d\.]+(px|r?em|%)?) )?(.+)$#is';
691
- preg_match($regex, $value, $parts);
692
- if (!empty($parts[2])):
693
- $rules[] = 'font-weight';
694
- $values[] = $parts[2];
695
- endif;
696
- if (!empty($parts[4])):
697
- $rules[] = 'font-style';
698
- $values[] = $parts[4];
699
- endif;
700
- if (!empty($parts[6])):
701
- $rules[] = 'font-size';
702
- $values[] = $parts[6];
703
- endif;
704
- if (!empty($parts[9])):
705
- $rules[] = 'line-height';
706
- $values[] = $parts[9];
707
- endif;
708
- if (!empty($parts[11])):
709
- $rules[] = 'font-family';
710
- $values[] = $parts[11];
711
  endif;
712
- }
713
-
714
- /*
715
- * normalize_margin_padding
716
- * parses margin or padding shorthand value and returns
717
- * normalized rule/value pairs for each property
718
- * TODO: reassemble into shorthand when writing CSS file
719
- */
720
- function normalize_margin_padding($rule, $value, &$rules, &$values) {
721
- $parts = preg_split("/ +/", trim($value));
722
- if (!isset($parts[1])) $parts[1] = $parts[0];
723
- if (!isset($parts[2])) $parts[2] = $parts[0];
724
- if (!isset($parts[3])) $parts[3] = $parts[1];
725
- $rules[0] = $rule . '-top';
726
- $values[0] = $parts[0];
727
- $rules[1] = $rule . '-right';
728
- $values[1] = $parts[1];
729
- $rules[2] = $rule . '-bottom';
730
- $values[2] = $parts[2];
731
- $rules[3] = $rule . '-left';
732
- $values[3] = $parts[3];
733
- }
734
-
735
- function encode_shorthand($shorthand) {
736
- $rules = '';
737
- $importantstr = ' !important';
738
- foreach (array_keys($shorthand) as $key):
739
- $important = array();
740
- $rule = array();
741
- $importantct = 0;
742
- // which sides do we have and are they important?
743
- foreach($shorthand[$key] as $side => $val):
744
- $ict = 0;
745
- $rule[$side] = trim(preg_replace('/'.$importantstr.'/', '', $val, 1, $ict));
746
- $important[$side] = $ict;
747
- $importantct += $ict;
748
- endforeach;
749
- // shorthand must have 4 explicit values and all must have same priority
750
- if (4 == count($rule) && (0 == $importantct || 4 == $importantct )):
751
- // let's try to condense the values into as few as possible, starting with the top value
752
- $parts = array();
753
- $parts[0] = $rule['top'];
754
- // if left is not the same as right, we must use all 4 values
755
- if ($rule['left'] !== $rule['right']):
756
- $parts[3] = $rule['left'];
757
- $parts[2] = $rule['bottom'];
758
- $parts[1] = $rule['right'];
759
- endif;
760
- // if top is not the same as bottom, we must use at least 3 values
761
- if ($rule['bottom'] !== $rule['top']):
762
- $parts[2] = $rule['bottom'];
763
- $parts[1] = $rule['right'];
764
- endif;
765
- // if top is not the same as right, we must use at least 2 values
766
- if ($rule['right'] !== $rule['top']):
767
- $parts[1] = $rule['right'];
768
- endif;
769
- // the order of the sides is critical: top right bottom left
770
- ksort($parts);
771
- $shorthandstr = implode(' ', $parts);
772
- // if important counter is > 0, it must be == 4, add flag
773
- $rules .= ' ' . $key . ': ' . $shorthandstr . ($importantct ? ' ' . $importantstr : '') . ';' . LF;
774
- else:
775
- // otherwise return separate rule for each side
776
- foreach ($rule as $side => $value):
777
- $rules .= ' ' . $key . '-' . $side . ': ' . $value . ($important[$side] ? $importantstr : '') . ';' . LF;
778
- endforeach;
779
- endif;
780
- endforeach;
781
  return $rules;
782
  }
783
-
784
- /*
785
- * encode_gradient
786
- * Normalize linear gradients from a bazillion formats into standard CTC syntax:
787
- * Currently only supports two-color linear gradients with no inner stops.
788
- * TODO: legacy webkit? more gradients?
789
- */
790
  function encode_gradient($value) {
791
- $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';
792
  $param = $parts = array();
793
  preg_match($regex, $value, $parts);
794
  if (empty($parts[13])):
@@ -816,19 +472,12 @@ class Child_Theme_Configurator_CSS {
816
  $param[2] = '0%';
817
  $param[4] = '100%';
818
  endif;
819
- if (isset($parts[7]) && isset($parts[10])):
820
- $param[1] = $parts[7];
821
- $param[3] = $parts[10];
822
- ksort($param);
823
- return implode(':', $param);
824
- else: return $value;
825
- endif;
826
  }
827
 
828
- /*
829
- * decode_border
830
- * De-normalize CTC border syntax into separate properties.
831
- */
832
  function decode_border($value) {
833
  if (preg_match('#^(0|none)#i', $value)):
834
  $parts[0] = $value;
@@ -842,145 +491,101 @@ class Child_Theme_Configurator_CSS {
842
  'color' => empty($parts[2])?'':$parts[2],
843
  );
844
  }
845
-
846
- /*
847
- * decode_gradient
848
- * Decode CTC gradient syntax into separate properties.
849
- */
850
  function decode_gradient($value) {
851
  $parts = explode(':', $value, 5);
852
- if (5 == count($parts)):
853
  return array(
854
- 'origin' => empty($parts[0]) ? '' : $parts[0],
855
- 'color1' => empty($parts[1]) ? '' : $parts[1],
856
- 'stop1' => empty($parts[2]) ? '' : $parts[2],
857
- 'color2' => empty($parts[3]) ? '' : $parts[3],
858
- 'stop2' => empty($parts[4]) ? '' : $parts[4],
859
  );
 
 
860
  endif;
861
- return false;
862
- }
863
-
864
- /*
865
- * denorm_rule_val
866
- * Return array of unique values corresponding to specific rule
867
- */
868
- function denorm_rule_val($ruleid) {
869
- $rule_sel_arr = array();
870
- $val_arr = array_flip($this->dict_val);
871
- foreach ($this->val_ndx as $selid => $rules):
872
- if (!isset($rules[$ruleid])) continue;
873
- foreach ($rules[$ruleid] as $theme => $val):
874
- if (!isset($val_arr[$val]) || '' === $val_arr[$val]) continue;
875
- $rule_sel_arr[$val] = $val_arr[$val];
876
- endforeach;
877
- endforeach;
878
- return $rule_sel_arr;
879
  }
880
-
881
- /*
882
- * denorm_val_query
883
- * Return array of queries, selectors, rules, and values corresponding to
884
- * specific rule/value combo grouped by query, selector
885
- */
886
- function denorm_val_query($valid, $rule) {
887
- $value_query_arr = array();
888
- foreach ($this->val_ndx as $qsid => $rules):
889
- foreach ($rules as $ruleid => $values):
890
- if ($ruleid != $this->dict_rule[$rule]) continue;
891
- foreach ($values as $name => $val):
892
- if ('i' == $name || $val != $valid) continue;
893
- $selarr = $this->denorm_query_sel($qsid);
894
- $valarr = $this->denorm_sel_val($qsid);
895
- $value_query_arr[$rule][$selarr['query']][$qsid] = $valarr;
896
- endforeach;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
897
  endforeach;
898
- endforeach;
899
- return $value_query_arr;
900
- }
901
-
902
- /*
903
- * denorm_query_sel
904
- * Return id, query and selector values of a specific qsid (query-selector ID)
905
- */
906
- function denorm_query_sel($qsid) {
907
- $queryarr = array_flip($this->dict_query);
908
- $selarr = array_flip($this->dict_sel);
909
- $this->dict_seq[$qsid] = isset($this->dict_seq[$qsid]) ? $this->dict_seq[$qsid] : $qsid;
910
- return array(
911
- 'id' => $qsid,
912
- 'query' => $queryarr[$this->dict_qs[$qsid]['q']],
913
- 'selector' => $selarr[$this->dict_qs[$qsid]['s']],
914
- 'seq' => $this->dict_seq[$qsid],
915
- );
916
- }
917
-
918
- /*
919
- * denorm_sel_val
920
- * Return array of rules, and values matching specific qsid (query-selector ID)
921
- * grouped by query, selector
922
- */
923
- function denorm_sel_val($qsid) {
924
- $selarr = $this->denorm_query_sel($qsid);
925
- $valarr = array_flip($this->dict_val);
926
- $rulearr = array_flip($this->dict_rule);
927
- if (isset($this->val_ndx[$qsid]) && is_array($this->val_ndx[$qsid])):
928
- foreach ($this->val_ndx[$qsid] as $ruleid => $values):
929
- foreach ($values as $name => $val):
930
- if ('i_parnt' == $name || 'i_child' == $name):
931
- $selarr['value'][$rulearr[$ruleid]][$name] = (empty($val) ? 0 : 1);
932
- elseif (!isset($valarr[$val]) || '' === $valarr[$val]):
933
- continue;
934
  else:
935
- $selarr['value'][$rulearr[$ruleid]][$name] = $valarr[$val];
936
  endif;
 
 
937
  endforeach;
938
- // add load order
939
- endforeach;
940
  endif;
941
- return $selarr;
942
- }
943
-
944
- /*
945
- * denorm_sel_ndx
946
- * Return denormalized array containing query and selector heirarchy
947
- */
948
- function denorm_sel_ndx($query = null) {
949
- $sel_ndx_norm = array();
950
- $queryarr = array_flip($this->dict_query);
951
- $selarr = array_flip($this->dict_sel);
952
- foreach($this->sel_ndx as $queryid => $sel):
953
- foreach($sel as $selid => $qsid):
954
- $sel_ndx_norm[$queryarr[$queryid]][$selarr[$selid]] = $qsid;
955
- endforeach;
956
- endforeach;
957
- return empty($query) ? $sel_ndx_norm : $sel_ndx_norm[$query];
958
  }
959
-
960
  /*
961
- * is_important
962
  * Strip important flag from value ref and return boolean
963
- * Value is updated because it is a ref
964
  */
965
  function is_important(&$value) {
966
  $important = 0;
967
- $value = trim(str_ireplace('!important', '', $value, $important));
968
  return $important;
969
  }
970
 
971
- /*
972
- * sort_queries
973
- * De-normalize query data and return array sorted as follows:
974
- * base
975
- * @media max-width queries in descending order
976
- * other @media queries in no particular order
977
- * @media min-width queries in ascending order
978
- */
979
  function sort_queries() {
980
  $queries = array();
981
- $queryarr = array_flip($this->dict_query);
982
- foreach (array_keys($this->sel_ndx) as $queryid):
983
- $query = $queryarr[$queryid];
984
  if ('base' == $query):
985
  $queries['base'] = -999999;
986
  continue;
@@ -988,61 +593,11 @@ class Child_Theme_Configurator_CSS {
988
  if (preg_match("/((min|max)(\-device)?\-width)\s*:\s*(\d+)/", $query, $matches)):
989
  $queries[$query] = 'min-width' == $matches[1] ? $matches[4] : -$matches[4];
990
  else:
991
- $queries[$query] = $queryid - 10000;
992
  endif;
993
  endforeach;
994
  asort($queries);
995
  return $queries;
996
  }
997
-
998
- // sort selectors based on dict_seq if exists, otherwise qsid
999
- function cmp_seq($a, $b) {
1000
- $cmpa = isset($this->dict_seq[$a])?$this->dict_seq[$a]:$a;
1001
- $cmpb = isset($this->dict_seq[$b])?$this->dict_seq[$b]:$b;
1002
- if ($cmpa == $cmpb) return 0;
1003
- return ($cmpa < $cmpb) ? -1 : 1;
1004
- }
1005
-
1006
- /*
1007
- * obj_to_utf8
1008
- * sets object data to UTF8
1009
- * and stringifies NULLs
1010
- */
1011
- function obj_to_utf8($data) {
1012
-
1013
- if (is_object($data)) {
1014
- $data = get_object_vars($data);
1015
- }
1016
- if (is_array($data)) {
1017
- return array_map(array(&$this, __FUNCTION__), $data);
1018
- }
1019
- else {
1020
- return is_null( $data ) ? '' : utf8_encode($data);
1021
- }
1022
- }
1023
-
1024
- function to_ascii($matches) {
1025
- return ord($matches[0]);
1026
- }
1027
-
1028
- function from_ascii($matches) {
1029
- return chr($matches[0]);
1030
- }
1031
-
1032
- /* is_file_ok
1033
- * verify file exists and is in valid location
1034
- */
1035
- function is_file_ok($stylesheet, $permission = 'read') {
1036
- // remove any ../ manipulations
1037
- $stylesheet = preg_replace("%\.\./%", '/', $stylesheet);
1038
- if ('read' == $permission && !is_file($stylesheet)) return false;
1039
- // sanity check for php files
1040
- if (preg_match('%php$%', $stylesheet)) return false;
1041
- // check if in themes dir;
1042
- if (preg_match('%^' . preg_quote(get_theme_root()) . '%', $stylesheet)) return $stylesheet;
1043
- // check if in plugins dir
1044
- if (preg_match('%^' . preg_quote(WP_PLUGIN_DIR) . '%', $stylesheet)) return $stylesheet;
1045
- return false;
1046
- }
1047
  }
1048
  ?>
6
  Class: Child_Theme_Configurator_CSS
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Handles all CSS output, parsing, normalization
9
+ Version: 1.0
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
13
  Domain Path: /lang
14
  License: GPLv2
15
+ Copyright (C) 2013 Lilaea Media
16
  */
17
  class Child_Theme_Configurator_CSS {
18
+
19
+ var $sel_ndx;
20
+ var $val_ndx;
21
+ var $data;
22
+ var $imports;
23
+ var $keynum;
24
+ var $updates;
25
+ var $author;
26
+ var $child_theme;
27
+ var $parent_theme;
28
+ var $child_theme_name;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
  function __construct() {
31
+ $this->keynum = 0;
32
+ $this->child_theme = '';
33
+ $this->parent_theme = '';
34
+ $this->child_theme_name = '';
35
+ $this->author = 'Child Theme Configurator by Lilaea Media';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  $this->sel_ndx = array();
37
  $this->val_ndx = array();
38
+ $this->data = array();
39
+ $this->imports = array();
40
  $this->updates = array();
41
  }
42
 
43
+ function set_property($prop, $value) {
44
+ if (is_scalar($this->{$prop}))
45
+ $this->{$prop} = $value;
46
+ else return false;
47
+ }
48
+
49
+ function get_property($objname, $selnum = null) {
50
  switch ($objname):
51
  case 'updates':
52
+ return $this->obj_to_utf8($this->updates[$this->child_theme]);
53
  case 'imports':
54
+ return $this->obj_to_utf8($this->imports);
55
  case 'sel_ndx':
56
+ return $this->obj_to_utf8($this->sel_ndx);
57
+ case 'val_ndx':
58
+ return $this->obj_to_utf8($this->val_ndx);
59
+ case 'child_theme':
60
+ return $this->child_theme;
61
+ case 'parent_theme':
62
+ return $this->parent_theme;
63
+ case 'child_theme_name':
64
+ return $this->child_theme_name;
 
 
 
 
 
 
 
 
 
 
 
 
65
  case 'author':
66
+ return $this->author;
67
+ case 'data':
68
+ return ($selnum ? $this->obj_to_utf8($this->data[$selnum]) : $this->obj_to_utf8($this->data));
 
 
 
69
  endswitch;
70
  return false;
71
  }
72
 
73
+ function obj_to_utf8($data) {
74
+ if (is_object($data)) {
75
+ $data = get_object_vars($data);
76
+ }
77
+ if (is_array($data)) {
78
+ return array_map(array(&$this, __FUNCTION__), $data);
79
+ }
80
+ else {
81
+ return is_null( $data ) ? '' : utf8_encode($data);
82
+ }
83
  }
84
+
85
+ function normalize_background($value, &$rules, &$values){
86
+ if (false !== strpos($value, 'gradient')):
87
+ // only supporting linear syntax
88
+ if (preg_match('#(linear\-|Microsoft\.)#', $value)):
89
+ $values[] = $value;
90
+ $rules[] = 'background-image';
 
91
  endif;
92
+ else:
93
+ $regex = '#^(\#\w{3,6})? *(url\([^\)]+\))?(.+)?$#';
94
+ preg_match($regex, $value, $parts);
95
+ if (empty($parts[1]) && empty($parts[2])):
96
+ // this is a named color or single hex color
97
+ $parts[1] = $parts[3];
98
+ unset($parts[3]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  endif;
100
+ if (!empty($parts[1])):
101
+ if ('none' != $parts[1]):
102
+ $rules[] = 'background-color';
103
+ else:
104
+ $rules[] = 'background';
105
+ endif;
106
+ $values[] = $parts[1];
107
  endif;
108
+ if (!empty($parts[2])):
109
+ $rules[] = 'background-image';
110
+ $values[] = $parts[2];
111
+ endif;
112
+ if (!empty($parts[3])):
113
+ $position = array();
114
+ foreach(preg_split('/ +/', trim($parts[3])) as $part):
115
+ if (false === strpos($part, 'repeat')):
116
+ $position[] = $part;
117
+ else:
118
+ $rules[] = 'background-repeat';
119
+ $values[] = $part;
120
+ endif;
121
+ endforeach;
122
+ if (count($position)):
123
+ $rules[] = 'background-position';
124
+ $values[] = implode(' ', $position);
125
+ endif;
126
  endif;
127
  endif;
128
  }
129
+
130
+ function normalize_font($value, &$rules, &$values) {
131
+ $regex = '#^((\d+|bold|normal) )?((italic|normal) )?(([\d\.]+(px|r?em|%))[\/ ])?(([\d\.]+(px|r?em|%)?) )?(.+)$#is';
132
+ preg_match($regex, $value, $parts);
133
+ if (!empty($parts[2])):
134
+ $rules[] = 'font-weight';
135
+ $values[] = $parts[2];
136
+ endif;
137
+ if (!empty($parts[4])):
138
+ $rules[] = 'font-style';
139
+ $values[] = $parts[4];
140
+ endif;
141
+ if (!empty($parts[6])):
142
+ $rules[] = 'font-size';
143
+ $values[] = $parts[6];
144
+ endif;
145
+ if (!empty($parts[9])):
146
+ $rules[] = 'line-height';
147
+ $values[] = $parts[9];
148
+ endif;
149
+ if (!empty($parts[11])):
150
+ $rules[] = 'font-family';
151
+ $values[] = $parts[11];
152
  endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  }
154
 
155
+ function normalize_margin_padding($rule, $value, &$rules, &$values) {
156
+ $parts = preg_split("/ +/", trim($value));
157
+ if (empty($parts[1])) $parts[1] = $parts[0];
158
+ if (empty($parts[2])) $parts[2] = $parts[0];
159
+ if (empty($parts[3])) $parts[3] = $parts[1];
160
+ $rules[0] = $rule . '-top';
161
+ $values[0] = $parts[0];
162
+ $rules[1] = $rule . '-right';
163
+ $values[1] = $parts[1];
164
+ $rules[2] = $rule . '-bottom';
165
+ $values[2] = $parts[2];
166
+ $rules[3] = $rule . '-left';
167
+ $values[3] = $parts[3];
 
 
 
 
 
 
 
 
168
  }
169
 
170
+
171
+ function parse_css_file($obj) {
172
+ if (empty($this->{$obj}) || !is_scalar($this->{$obj})) return false;
173
+ $stylesheet = get_theme_root() . '/' . $this->{$obj} . '/style.css';
174
+ // read parent stylesheet
175
+ if (!is_file($stylesheet)) return false;
176
+ $styles = file_get_contents($stylesheet);
177
+ // get theme name
178
+ $regex = '#Theme Name:\s*(.+?)\n#i';
179
+ preg_match($regex, $styles, $matches);
180
+ if (empty($matches[1])) return false;
181
+ $this->set_property('child_theme_name', $matches[1]);
182
+ $this->parse_css($this->{$obj}, $styles);
 
 
183
  }
184
+ function reset_updates() {
185
+ $this->updates = array();
186
+ }
187
+ function update_arrays($template, $query, $sel, $rule = null, $value = null, $important = null, $old_value = null) {
188
+ // add selector and query to index
189
+ if (!isset($this->sel_ndx[$query][$sel])):
190
+ // increment key number
191
+ $this->sel_ndx[$query][$sel] = ++$this->keynum;
192
+ $this->data[$this->sel_ndx[$query][$sel]]['selector'] = $sel;
193
+ $this->data[$this->sel_ndx[$query][$sel]]['query'] = $query;
194
+ $this->updates[$template]['insert'][] = array(
195
+ 'selector' => $sel,
196
+ 'query' => $query,
197
+ 'selnum' => $this->sel_ndx[$query][$sel],
198
+ );
199
+ endif;
200
+ // det data and value
201
+ if ($rule):
202
+ $selnum = $this->sel_ndx[$query][$sel];
203
+ if ('' == $value && isset($old_value) && '' != $old_value):
204
+ $this->data[$selnum]['value'][$rule][$template] = '';
205
+ unset($this->val_ndx[$template][$rule][$value][$query][$selnum]);
206
+ if (isset($this->val_ndx[$template][$rule][$old_value][$query][$selnum])):
207
+ unset($this->val_ndx[$template][$rule][$old_value][$query][$selnum]);
208
+ $delete = array(
209
+ 'rule' => $rule,
210
+ 'value' => $old_value,
211
+ 'query' => $query,
212
+ 'selnum' => $selnum,
213
+ );
214
  endif;
215
+ if (isset($this->val_ndx[$template][$rule][$old_value][$query])
216
+ && !count($this->val_ndx[$template][$rule][$old_value][$query])):
217
+ unset($this->val_ndx[$template][$rule][$old_value][$query]);
218
+ $delete = array(
219
+ 'rule' => $rule,
220
+ 'value' => $old_value,
221
+ 'query' => $query,
222
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  endif;
224
+ if (isset($this->val_ndx[$template][$rule][$old_value])
225
+ && !count($this->val_ndx[$template][$rule][$old_value])):
226
+ unset($this->val_ndx[$template][$rule][$old_value]);
227
+ $delete = array(
228
+ 'rule' => $rule,
229
+ 'value' => $old_value,
230
+ );
231
+ endif;
232
+ if (isset($this->val_ndx[$template][$rule])
233
+ && !count($this->val_ndx[$template][$rule])):
234
+ unset($this->val_ndx[$template][$rule]);
235
+ $delete = array(
236
+ 'rule' => $rule,
237
+ );
238
+ endif;
239
+ $this->updates[$template]['del'][] = $delete;
240
+ $this->updates[$template]['update'][] = array(
241
+ 'rule' => $rule,
242
+ 'value' => '',
243
+ 'query' => $query,
244
+ 'selnum' => $selnum,
245
+ 'important' => '',
246
+ );
247
+ else:
248
+ // add values to data array
249
+ $this->data[$selnum]['value'][$rule][$template] = $value . ($important?' !important':'');
250
+ // add rule and values to index
251
+ $this->val_ndx[$template][$rule][$value][$query][$selnum] = 0;
252
+ $this->updates[$template]['update'][] = array(
253
+ 'rule' => $rule,
254
+ 'value' => $value,
255
+ 'query' => $query,
256
+ 'selnum' => $selnum,
257
+ 'important' => $important,
258
+ );
259
+ endif;
 
 
260
  endif;
261
  }
262
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  function parse_css($template, $styles, $basequery = null, $parse_imports = true) {
264
  if (false === strpos($basequery, '@')):
265
  $basequery = 'base';
273
  if ($parse_imports):
274
  $regex = '#(\@import.+?);#';
275
  preg_match_all($regex, $styles, $matches);
276
+ $this->imports[$template] = preg_grep('#style\.css#', $matches[1], PREG_GREP_INVERT);
277
+ $this->updates[$template]['imports'] = $this->imports[$template];
 
 
 
 
278
  endif;
279
  // break into @ segments
280
  $regex = '#(\@media.+?)\{(.*?\})\s*\}#s';
284
  endforeach;
285
  // remove rulesets from styles
286
  $ruleset[$basequery] = preg_replace($regex, '', $styles);
287
+ //echo 'template: ' . $template . ' styles: ' . $styles . ' basequery: ' . $basequery . LF;
288
  foreach ($ruleset as $query => $segment):
289
  // make sure there is semicolon before closing brace
290
  $segment = preg_replace('#(\})#', ";$1", $segment);
292
  preg_match_all($regex, $segment, $matches);
293
  foreach($matches[1] as $sel):
294
  $stuff = array_shift($matches[2]);
295
+ // normalize selector styling
296
+ $sel = implode(', ', preg_split('#\s*,\s*#s', trim($sel)));
297
  $this->update_arrays($template, $query, $sel);
298
+ //echo 'query: ' . $query . ' sel: ' . $sel . ' selnum: ' . $selnum . LF;
299
  foreach (explode(';', $stuff) as $ruleval):
 
300
  if (false === strpos($ruleval, ':')) continue;
301
  list($rule, $value) = explode(':', $ruleval, 2);
302
  $rule = trim($rule);
303
+ $value = trim($value);
 
304
 
305
  $rules = $values = array();
306
  // save important flag
332
  $value = $this->encode_gradient($value);
333
  endif;
334
  // normalize common vendor prefixes
335
+ $rule = preg_replace('#(\-(o|ms|moz|webkit)\-)?(border\-radius|box\-shadow|transition)#', "$3", $rule);
336
  $this->update_arrays($template, $query, $sel, $rule, $value, $important);
337
  endforeach;
338
  endforeach;
339
  endforeach;
340
  endforeach;
341
  }
342
+
343
+ function write_css() {
 
 
 
 
 
 
 
344
  // write new stylesheet
345
+ $output = '/*' . LF;
346
+ $output .= 'Theme Name: ' . $this->child_theme_name . LF;
347
+ $output .= 'Template: ' . $this->parent_theme . LF;
348
+ $output .= 'Author: ' . $this->author . LF;
349
+ $output .= 'Version: 1.0' . LF;
350
+ $output .= '*/' . LF . LF;
351
+ $output .= '@charset "UTF-8";' . LF;
352
+ $output .= '@import url(\'../' . $this->parent_theme . '/style.css\');' . LF;
353
+ if (!empty($this->imports[$this->child_theme])):
354
+ foreach ($this->imports[$this->child_theme] as $import):
355
  $output .= $import . ';' . LF;
356
  endforeach;
357
  endif;
358
  $output .= LF;
 
 
 
 
359
  foreach ($this->sort_queries() as $query => $sort_order):
360
+ $selector = $this->sel_ndx[$query];
361
+ asort($selector);
362
  $has_selector = 0;
363
  $sel_output = '';
 
 
364
  if ('base' != $query) $sel_output .= $query . ' {' . LF;
365
+ foreach ($selector as $sel => $selnum):
366
  $has_value = 0;
367
+ if (!empty($this->data[$selnum]['value'])):
368
+ foreach ($this->data[$selnum]['value'] as $rule => $value):
369
+ if (isset($value[$this->child_theme]) && '' != $value[$this->child_theme]):
 
 
370
  if (! $has_value):
 
371
  $sel_output .= $sel . ' {' . LF;
372
  $has_value = 1;
373
  $has_selector = 1;
374
  endif;
375
+ $sel_output .= $this->add_vendor_rules($rule, $value[$this->child_theme]);
 
 
376
  endif;
377
  endforeach;
 
378
  if ($has_value):
379
  $sel_output .= '}' . LF;
380
  endif;
383
  if ('base' != $query) $sel_output .= '}' . LF;
384
  if ($has_selector) $output .= $sel_output;
385
  endforeach;
386
+ $themedir = get_theme_root() . '/' . $this->child_theme;
387
+
388
+ $stylesheet = $themedir . '/style.css';
389
+ if (!is_dir($themedir)):
390
+ mkdir($themedir, 0755);
391
+ endif;
392
+ // backup current stylesheet if no backup exists
393
+ if (is_file($stylesheet) && !is_file($stylesheet . '.bak')):
394
+ file_put_contents($stylesheet . '.bak', file_get_contents($stylesheet));
395
+ endif;
396
+ // write new stylesheet
397
+ file_put_contents($stylesheet, $output);
 
398
  }
399
 
400
+ function add_vendor_rules($rule, $value) {
 
 
 
 
 
 
401
  $rules = '';
402
+ if (preg_match("/^(border\-radius|box\-shadow|transition)$/", $rule)):
 
 
 
 
 
403
  foreach(array('moz', 'webkit', 'o') as $prefix):
404
+ $rules .= ' -' . $prefix . '-' . $rule . ': ' . $value . ';' . LF;
405
  endforeach;
406
+ $rules .= ' ' . $rule . ': ' . $value . ';' . LF;
407
  elseif ('background-image' == $rule):
408
  // gradient?
409
  if ($gradient = $this->decode_gradient($value)):
410
  // standard gradient
411
  foreach(array('moz', 'webkit', 'o', 'ms') as $prefix):
412
  $rules .= ' background-image: -' . $prefix . '-' . 'linear-gradient(' . $gradient['origin'] . ', '
413
+ . $gradient['color1'] . ', ' . $gradient['color2'] . ');' . LF;
414
  endforeach;
415
  // W3C standard gradient
416
  // rotate origin 90 degrees
424
  $org = 'to ' . implode(' ', $dirs);
425
  endif;
426
  $rules .= ' background-image: linear-gradient(' . $org . ', '
427
+ . $gradient['color1'] . ', ' . $gradient['color2'] . ');' . LF;
428
 
429
  // legacy webkit gradient - we'll add if there is demand
430
  // '-webkit-gradient(linear,' .$origin . ', ' . $color1 . ', '. $color2 . ')';
433
  $type = (in_array($gradient['origin'], array('left', 'right', '0deg', '180deg')) ? 1 : 0);
434
  $color1 = preg_replace("/^#/", '#00', $gradient['color1']);
435
  $rules .= ' filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=' . $type . ', StartColorStr="'
436
+ . strtoupper($color1) . '", EndColorStr="' . strtoupper($gradient['color2']) . '");' . LF;
437
  else:
438
  // url or other value
439
+ $rules .= ' ' . $rule . ': ' . $value . ';' . LF;
440
  endif;
441
  else:
442
+ $rules .= ' ' . $rule . ': ' . $value . ';' . LF;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
443
  endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
  return $rules;
445
  }
 
 
 
 
 
 
 
446
  function encode_gradient($value) {
447
+ $regex = '#gradient[^\)]*?\((((top|bottom|left|right)?( (top|bottom|left|right))?|\d+deg),)?([^\)]*[\'"]?(\#\w{3,8}|rgba?\([\d, ]+?\))( \d+%)?)([^\)]*[\'"]?(\#\w{3,8}|rgba?\([\d, ]+?\))( \d+%)?)([^\)]*gradienttype=[\'"]?(\d)[\'"]?)?[^\)]*\)#i';
448
  $param = $parts = array();
449
  preg_match($regex, $value, $parts);
450
  if (empty($parts[13])):
472
  $param[2] = '0%';
473
  $param[4] = '100%';
474
  endif;
475
+ $param[1] = $parts[7];
476
+ $param[3] = $parts[10];
477
+ ksort($param);
478
+ return implode(':', $param);
 
 
 
479
  }
480
 
 
 
 
 
481
  function decode_border($value) {
482
  if (preg_match('#^(0|none)#i', $value)):
483
  $parts[0] = $value;
491
  'color' => empty($parts[2])?'':$parts[2],
492
  );
493
  }
494
+
 
 
 
 
495
  function decode_gradient($value) {
496
  $parts = explode(':', $value, 5);
497
+ if (count($parts) == 5):
498
  return array(
499
+ 'origin' => empty($parts[0])?'':$parts[0],
500
+ 'color1' => empty($parts[1])?'':$parts[1],
501
+ 'stop1' => empty($parts[2])?'':$parts[2],
502
+ 'color2' => empty($parts[3])?'':$parts[3],
503
+ 'stop2' => empty($parts[4])?'':$parts[4],
504
  );
505
+ else:
506
+ return false;
507
  endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
508
  }
509
+
510
+ function parse_post_data() {
511
+ if (isset($_POST['ctc_new_selectors'])):
512
+ $this->parse_css($this->child_theme, LF . $_POST['ctc_new_selectors'], (isset($_POST['ctc_sel_ovrd_query'])?trim($_POST['ctc_sel_ovrd_query']):null), false);
513
+ elseif (isset($_POST['ctc_child_imports'])):
514
+ $this->parse_css($this->child_theme, $_POST['ctc_child_imports']);
515
+ else:
516
+ $parts = array();
517
+ foreach (preg_grep('#^ctc_(ovrd_)?child#', array_keys($_POST)) as $post_key):
518
+ if (preg_match('#^ctc_(ovrd_)?child_([\w\-]+?)_(\d+?)(_(.+))?$#', $post_key, $matches)):
519
+ $rule = $matches[2];
520
+ $selnum = $matches[3];
521
+ $value = sanitize_text_field($_POST[$post_key]);
522
+ if (isset($this->data[$selnum]['value'][$rule]) && isset($this->data[$selnum]['value'][$rule][$this->child_theme])):
523
+ $child_value = $this->data[$selnum]['value'][$rule][$this->child_theme];
524
+ else:
525
+ $child_value = $this->data[$selnum]['value'][$rule][$this->child_theme] = '';
526
+ endif;
527
+ if (isset($this->data[$selnum]['value'][$rule][$this->parent_theme])):
528
+ $parent_value = $this->data[$selnum]['value'][$rule][$this->parent_theme];
529
+ else:
530
+ $parent_value = $this->data[$selnum]['value'][$rule][$this->parent_theme] = '';
531
+ endif;
532
+ $important = $this->is_important($parent_value) ? ' !important' : '';
533
+ $query = $this->data[$selnum]['query'];
534
+ if (!empty($matches[5])):
535
+ $parts[$selnum][$rule][$matches[5]] = $value;
536
+ $parts[$selnum][$rule]['important'] = $important;
537
+ $parts[$selnum][$rule]['query'] = $query;
538
+ else:
539
+ $this->update_arrays($this->child_theme, $query, $this->data[$selnum]['selector'],
540
+ $rule, $value, $important, $child_value);
541
+ endif;
542
+ endif;
543
  endforeach;
544
+ foreach ($parts as $selnum => $rule_arr):
545
+ foreach ($rule_arr as $rule => $rule_part):
546
+ if ('background' == $rule):
547
+ $value = $rule_part['background_url'];
548
+ elseif ('background-image' == $rule):
549
+ if (empty($rule_part['background_url'])):
550
+ if (empty($rule_part['background_color2'])):
551
+ $value = '';
552
+ else:
553
+ $value = implode(':', array(
554
+ $rule_part['background_origin'],
555
+ $rule_part['background_color1'], '0%',
556
+ $rule_part['background_color2'], '100%'
557
+ ));
558
+ endif;
559
+ else:
560
+ $value = $rule_part['background_url'];
561
+ endif;
562
+ elseif (preg_match('#^border(\-(top|right|bottom|left))?$#', $rule)):
563
+ $value = implode(' ', array(
564
+ $rule_part['border_width'],
565
+ $rule_part['border_style'],
566
+ $rule_part['border_color']
567
+ ));
 
 
 
 
 
 
 
 
 
 
 
 
568
  else:
569
+ $value = '';
570
  endif;
571
+ $this->update_arrays($this->child_theme, $rule_part['query'], $this->data[$selnum]['selector'],
572
+ $rule, $value, $rule_part['important'], $child_value);
573
  endforeach;
574
+ endforeach;
 
575
  endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
576
  }
 
577
  /*
 
578
  * Strip important flag from value ref and return boolean
 
579
  */
580
  function is_important(&$value) {
581
  $important = 0;
582
+ $value = str_replace('!important', '', $value, $important);
583
  return $important;
584
  }
585
 
 
 
 
 
 
 
 
 
586
  function sort_queries() {
587
  $queries = array();
588
+ foreach (array_keys($this->sel_ndx) as $query):
 
 
589
  if ('base' == $query):
590
  $queries['base'] = -999999;
591
  continue;
593
  if (preg_match("/((min|max)(\-device)?\-width)\s*:\s*(\d+)/", $query, $matches)):
594
  $queries[$query] = 'min-width' == $matches[1] ? $matches[4] : -$matches[4];
595
  else:
596
+ $queries[$query] = 0;
597
  endif;
598
  endforeach;
599
  asort($queries);
600
  return $queries;
601
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
602
  }
603
  ?>
includes/class-ctc-ui.php CHANGED
@@ -1,173 +1,115 @@
1
  <?php
2
  // Exit if accessed directly
3
  if ( !defined('ABSPATH')) exit;
 
4
  /*
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.3.4
9
  Author: Lilaea Media
10
  Author URI: http://www.lilaeamedia.com/
11
  Text Domain: chld_thm_cfg
12
  Domain Path: /lang
13
  License: GPLv2
14
- Copyright (C) 2014 Lilaea Media
15
  */
16
  class Child_Theme_Configurator_UI {
17
  var $swatch_text;
18
- var $themes;
19
- var $extLink;
20
-
21
  function __construct() {
22
- $this->swatch_text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
23
- $this->extLink = '<a href="http://www.lilaeamedia.com/plugins/child-theme-configurator-plugins/" target="_blank" title="' . __('Easily customize your plugins with the CTC Plugin Extension', 'chld_thm_cfg') . '" style="float:right">' . __('Use this to customize your plugins', 'chld_thm_cfg') . '</a>';
24
  }
25
 
26
  function render_options() {
27
  global $chld_thm_cfg;
28
- $css = $chld_thm_cfg->css;
29
- $themes = $chld_thm_cfg->themes;
30
- $parent = $css->get_prop('parnt');
31
- $child = $css->get_prop('child');
32
- $configtype = $css->get_prop('configtype');
33
- $hidechild = (count($themes['child']) ? '' : 'style="display:none"');
34
- $imports = $css->get_prop('imports');
35
- $id = 0;
36
  ?>
37
 
38
  <div class="wrap">
39
- <div id="icon-tools" class="icon32"></div><?php echo $this->extLink; ?>
40
  <h2><?php echo $chld_thm_cfg->pluginName; ?></h2>
41
- <div id="ctc_error_notice">
42
- <?php $this->settings_errors(); ?>
43
- </div>
44
  <?php
45
  $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'parent_child_options';
46
  ?>
47
- <h2 class="nav-tab-wrapper"> <a id="parent_child_options" href="?page=<?php echo $chld_thm_cfg->menuName; ?>&amp;tab=parent_child_options"
 
48
  class="nav-tab<?php echo 'parent_child_options' == $active_tab ? ' nav-tab-active' : ''; ?>">
49
- <?php _e('Parent/Child', 'chld_thm_cfg'); ?>
50
- </a> <a id="query_selector_options" href="?page=<?php echo $chld_thm_cfg->menuName; ?>&amp;tab=query_selector_options"
51
- class="nav-tab<?php echo 'query_selector_options' == $active_tab ? ' nav-tab-active' : ''; ?>" <?php echo $hidechild; ?>>
52
- <?php _e('Query/Selector', 'chld_thm_cfg'); ?>
53
- </a> <a id="rule_value_options" href="?page=<?php echo $chld_thm_cfg->menuName; ?>&amp;tab=rule_value_options"
54
- class="nav-tab<?php echo 'rule_value_options' == $active_tab ? ' nav-tab-active' : ''; ?>" <?php echo $hidechild; ?>>
55
- <?php _e('Rule/Value', 'chld_thm_cfg'); ?>
56
- </a> <a id="import_options" href="?page=<?php echo $chld_thm_cfg->menuName; ?>&amp;tab=import_options"
57
- class="nav-tab<?php echo 'import_options' == $active_tab ? ' nav-tab-active' : ''; ?>" <?php echo $hidechild; ?>>
58
- <?php _e('@import', 'chld_thm_cfg'); ?>
59
- </a> <a id="view_child_options" href="?page=<?php echo $chld_thm_cfg->menuName; ?>&amp;tab=view_child_options"
60
- class="nav-tab<?php echo 'view_child_options' == $active_tab ? ' nav-tab-active' : ''; ?>" <?php echo $hidechild; ?>>
61
- <?php _e('View Child CSS', 'chld_thm_cfg'); ?>
62
- </a> <a id="view_parnt_options" href="?page=<?php echo $chld_thm_cfg->menuName; ?>&amp;tab=view_parnt_options"
63
- class="nav-tab<?php echo 'view_parnt_options' == $active_tab ? ' nav-tab-active' : ''; ?>" <?php echo $hidechild; ?>>
64
- <?php _e('View Parent CSS', 'chld_thm_cfg'); ?>
65
- </a><?php do_action('chld_thm_cfg_tabs', $chld_thm_cfg, $active_tab, $hidechild);?> <i id="ctc_status_preview"></i></h2>
 
 
66
  <div class="ctc-option-panel-container">
67
  <div id="parent_child_options_panel" class="ctc-option-panel<?php echo 'parent_child_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>">
68
  <form id="ctc_load_form" method="post" action="">
69
  <?php wp_nonce_field( 'ctc_update' ); ?>
70
- <div class="ctc-input-row clearfix" id="input_row_parnt">
71
- <div class="ctc-input-cell">
72
- <label>
73
- <?php _e('Parent Theme', 'chld_thm_cfg'); ?>
74
- </label>
75
- </div>
76
- <div class="ctc-input-cell">
77
- <select class="ctc-select" id="ctc_theme_parnt" name="ctc_theme_parnt">
78
- <?php echo $chld_thm_cfg->render_menu('parnt', $parent); ?>
79
- </select>
80
- </div>
81
- </div>
82
- <div class="ctc-input-row clearfix" id="input_row_child">
83
- <div class="ctc-input-cell">
84
- <label>
85
- <?php _e('Child Theme', 'chld_thm_cfg'); ?>
86
- </label>
87
- </div>
88
- <div class="ctc-input-cell">
89
- <input class="ctc-radio" id="ctc_child_type_new" name="ctc_child_type" type="radio" value="new"
90
- <?php echo (!empty($hidechild) ? 'checked' : ''); ?>
91
- <?php echo $hidechild;?> />
92
- <label for="ctc_child_type_new">
93
- <?php _e('Create New Child Theme', 'chld_thm_cfg'); ?>
94
- </label>
95
- </div>
96
- <div class="ctc-input-cell">
97
- <input class="ctc-radio" id="ctc_child_type_existing" name="ctc_child_type" type="radio" value="existing"
98
- <?php echo (empty($hidechild) ? 'checked' : ''); ?>
99
- <?php echo $hidechild; ?>/>
100
- &nbsp;
101
- <label for="ctc_child_type_existing" <?php echo $hidechild;?>>
102
- <?php _e('Use Existing Child Theme', 'chld_thm_cfg'); ?>
103
- </label>
104
- </div>
105
- <div class="ctc-input-cell" style="clear:both">
106
- <label>&nbsp;</label>
107
- </div>
108
- <div class="ctc-input-cell" >
109
- <input class="ctc_text" id="ctc_child_template" name="ctc_child_template" type="text" placeholder="<?php _e('Theme Slug', 'chld_thm_cfg'); ?>" autocomplete="off"/>
110
- </div>
111
- <div class="ctc-input-cell">
112
- <select class="ctc-select" id="ctc_theme_child" name="ctc_theme_child" <?php echo $hidechild; ?>>
113
- <?php echo $chld_thm_cfg->render_menu('child', $child); ?>
114
- </select>
115
- </div>
116
- </div>
117
- <div class="ctc-input-row clearfix" id="input_row_child_name">
118
  <div class="ctc-input-cell">
119
  <label>
120
- <?php _e('Child Theme Name', 'chld_thm_cfg'); ?>
121
  </label>
122
  </div>
123
  <div class="ctc-input-cell">
124
- <input class="ctc_text" id="ctc_child_name" name="ctc_child_name" type="text"
125
- value="<?php echo esc_attr($css->get_prop('child_name')); ?>" placeholder="<?php _e('Theme Name', 'chld_thm_cfg'); ?>" autocomplete="off" />
126
  </div>
127
  </div>
128
- <?php if ('' == $hidechild) do_action('chld_thm_cfg_controls', $chld_thm_cfg); ?>
129
- <div class="ctc-input-row clearfix" id="input_row_child_template">
130
  <div class="ctc-input-cell">
131
  <label>
132
- <?php _e('Author', 'chld_thm_cfg'); ?>
133
  </label>
134
  </div>
135
  <div class="ctc-input-cell">
136
- <input class="ctc_text" id="ctc_child_author" name="ctc_child_author" type="text"
137
- value="<?php echo esc_attr($css->get_prop('author')); ?>" placeholder="<?php _e('Author', 'chld_thm_cfg'); ?>" autocomplete="off" />
138
  </div>
139
  </div>
140
  <div class="ctc-input-row clearfix" id="input_row_child_template">
141
  <div class="ctc-input-cell">
142
  <label>
143
- <?php _e('Version', 'chld_thm_cfg'); ?>
144
  </label>
145
  </div>
146
  <div class="ctc-input-cell">
147
- <input class="ctc_text" id="ctc_child_version" name="ctc_child_version" type="text"
148
- value="<?php echo esc_attr($css->get_prop('version')); ?>" placeholder="<?php _e('Version', 'chld_thm_cfg'); ?>" autocomplete="off" />
149
  </div>
150
  </div>
151
- <div class="ctc-input-row clearfix" id="input_row_child_template">
152
  <div class="ctc-input-cell">
153
  <label>
154
- <?php _e('Backup Stylesheet', 'chld_thm_cfg'); ?>
155
  </label>
156
  </div>
157
  <div class="ctc-input-cell">
158
- <input class="ctc_checkbox" id="ctc_backup" name="ctc_backup" type="checkbox"
159
- value="1" />
160
  </div>
161
  </div>
162
  <div class="ctc-input-row clearfix" id="input_row_child_template">
163
  <div class="ctc-input-cell">
164
  <label>
165
- <?php _e('Scan Parent Theme<br/>for Additional Stylesheets', 'chld_thm_cfg'); ?>
166
  </label>
167
  </div>
168
  <div class="ctc-input-cell">
169
- <input class="ctc_checkbox" id="ctc_scan_subdirs" name="ctc_scan_subdirs" type="checkbox"
170
- value="1" />
171
  </div>
172
  </div>
173
  <div class="ctc-input-row clearfix" id="input_row_child_template">
@@ -175,158 +117,138 @@ class Child_Theme_Configurator_UI {
175
  <label>&nbsp;</label>
176
  </div>
177
  <div class="ctc-input-cell">
178
- <input class="ctc_submit button button-primary" id="ctc_load_styles" name="ctc_load_styles" type="submit"
179
- value="<?php _e('Generate Child Theme Files', 'chld_thm_cfg'); ?>" disabled />
180
  </div>
181
  </div>
182
  </form>
183
  </div>
184
- <div id="rule_value_options_panel"
185
- class="ctc-option-panel<?php echo 'rule_value_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>>
186
  <form id="ctc_rule_value_form" method="post" action="">
187
  <?php wp_nonce_field( 'ctc_update' ); ?>
188
  <div class="ctc-input-row clearfix" id="ctc_input_row_rule_menu">
189
  <div class="ctc-input-cell"> <strong>
190
- <?php _e('Rule', 'chld_thm_cfg'); ?>
191
  </strong> </div>
192
  <div class="ctc-input-cell" id="ctc_rule_menu_selected">&nbsp;</div>
193
- <div id="ctc_status_rule_val"></div>
194
  <div class="ctc-input-cell">
195
  <div class="ui-widget">
196
  <input id="ctc_rule_menu"/>
197
- <div id="ctc_status_rule"></div>
198
  </div>
199
  </div>
200
  </div>
201
  <div class="ctc-input-row clearfix" id="ctc_input_row_rule_header" style="display:none">
202
  <div class="ctc-input-cell"> <strong>
203
- <?php _e('Value', 'chld_thm_cfg'); ?>
204
  </strong> </div>
205
  <div class="ctc-input-cell"> <strong>
206
- <?php _e('Sample', 'chld_thm_cfg'); ?>
207
  </strong> </div>
208
  <div class="ctc-input-cell"> <strong>
209
- <?php _e('Selectors', 'chld_thm_cfg'); ?>
210
  </strong> </div>
211
  </div>
212
  <div class="ctc-rule-value-input-container clearfix" id="ctc_rule_value_inputs" style="display:none"> </div>
213
  </form>
214
  </div>
215
- <div id="query_selector_options_panel"
216
- class="ctc-option-panel<?php echo 'query_selector_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>>
217
  <form id="ctc_query_selector_form" method="post" action="">
218
  <div class="ctc-input-row clearfix" id="input_row_query">
219
  <div class="ctc-input-cell"> <strong>
220
- <?php _e('Query', 'chld_thm_cfg'); ?>
221
  </strong> </div>
222
  <div class="ctc-input-cell" id="ctc_sel_ovrd_query_selected">&nbsp;</div>
223
  <div class="ctc-input-cell">
224
  <div class="ui-widget">
225
- <input id="ctc_sel_ovrd_query" />
226
  </div>
227
  </div>
228
  </div>
229
  <div class="ctc-input-row clearfix" id="input_row_selector">
230
  <div class="ctc-input-cell"> <strong>
231
- <?php _e('Selector', 'chld_thm_cfg'); ?>
232
- </strong> <a href="#" class="ctc-rewrite-toggle"></a></div>
233
  <div class="ctc-input-cell" id="ctc_sel_ovrd_selector_selected">&nbsp;</div>
234
  <div class="ctc-input-cell">
235
  <div class="ui-widget">
236
- <input id="ctc_sel_ovrd_selector" />
237
- <div id="ctc_status_sel_ndx"></div>
238
  </div>
239
  </div>
240
  </div>
241
  <div class="ctc-selector-row clearfix" id="ctc_sel_ovrd_rule_inputs_container" style="display:none">
242
  <div class="ctc-input-row clearfix">
243
  <div class="ctc-input-cell"><strong>
244
- <?php _e('Sample', 'chld_thm_cfg'); ?>
245
  </strong></div>
246
  <div class="ctc-input-cell clearfix" style="max-height:150px;overflow:hidden">
247
  <div class="ctc-swatch" id="ctc_child_all_0_swatch"><?php echo $this->swatch_text; ?></div>
248
  </div>
249
- <div id="ctc_status_sel_val"></div>
250
  <div class="ctc-input-cell ctc-button-cell" id="ctc_save_query_selector_cell">
251
- <input type="button" class="button button-primary ctc-save-input" id="ctc_save_query_selector"
252
- name="ctc_save_query_selector" value="Save" disabled />
253
- <input type="hidden" id="ctc_sel_ovrd_qsid"
254
- name="ctc_sel_ovrd_qsid" value="" />
255
  </div>
256
  </div>
257
  <div class="ctc-input-row clearfix" id="ctc_sel_ovrd_rule_header" style="display:none">
258
  <div class="ctc-input-cell"> <strong>
259
- <?php _e('Rule', 'chld_thm_cfg'); ?>
260
  </strong> </div>
261
  <div class="ctc-input-cell"> <strong>
262
- <?php _e('Parent Value', 'chld_thm_cfg'); ?>
263
  </strong> </div>
264
  <div class="ctc-input-cell"> <strong>
265
- <?php _e('Child Value', 'chld_thm_cfg'); ?>
266
  </strong> </div>
267
  </div>
268
  <div id="ctc_sel_ovrd_rule_inputs" style="display:none"> </div>
269
  <div class="ctc-input-row clearfix" id="ctc_sel_ovrd_new_rule" style="display:none">
270
- <div class="ctc-input-cell"> <strong>
271
- <?php _e('New Rule', 'chld_thm_cfg'); ?>
272
- </strong> </div>
273
- <div class="ctc-input-cell">
274
- <div class="ui-widget">
275
- <input id="ctc_new_rule_menu" />
276
- </div>
277
- </div>
278
- </div>
279
- <div class="ctc-input-row clearfix" id="input_row_selector">
280
- <div class="ctc-input-cell"> <strong>
281
- <?php _e('Order', 'chld_thm_cfg'); ?>
282
- </strong> </div>
283
- <div class="ctc-input-cell" id="ctc_child_load_order_container">&nbsp;</div>
284
- </div>
285
- </div>
286
- <div class="ctc-selector-row clearfix" id="ctc_new_selector_row">
287
  <div class="ctc-input-cell"> <strong>
288
- <?php _e('Raw CSS', 'chld_thm_cfg'); ?>
289
- </strong>
290
- <div class="ctc-textarea-button-cell" id="ctc_save_query_selector_cell">
291
- <input type="button" class="button ctc-save-input" id="ctc_save_new_selectors"
292
- name="ctc_save_new_selectors" value="Save" disabled />
293
  </div>
294
  </div>
295
- <div class="ctc-input-cell-wide">
296
- <textarea id="ctc_new_selectors" name="ctc_new_selectors" wrap="off"></textarea>
297
- </div>
298
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
299
  </form>
300
  </div>
301
- <div id="import_options_panel"
302
- class="ctc-option-panel<?php echo 'import_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>>
303
  <form id="ctc_import_form" method="post" action="">
304
  <?php wp_nonce_field( 'ctc_update' ); ?>
305
- <div class="ctc-input-row clearfix" id="ctc_child_imports_row">
306
- <div class="ctc-input-cell"> <strong>
307
- <?php _e('@import Statements', 'chld_thm_cfg'); ?>
308
- </strong>
309
- <div class="ctc-textarea-button-cell" id="ctc_save_imports_cell">
310
- <input type="button" class="button ctc-save-input" id="ctc_save_imports"
311
- name="ctc_save_imports" value="Save" disabled />
 
312
  </div>
313
- </div>
314
- <div class="ctc-input-cell-wide">
315
- <textarea id="ctc_child_imports" name="ctc_child_imports" wrap="off">
316
- <?php if (!empty($imports)):
317
- foreach ($imports as $import):
318
  echo esc_textarea($import . ';' . LF);
319
- endforeach; endif;?>
320
- </textarea>
321
  </div>
322
- </div>
323
  </form>
324
  </div>
325
- <div id="view_child_options_panel"
326
- class="ctc-option-panel<?php echo 'view_child_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>> </div>
327
- <div id="view_parnt_options_panel"
328
- class="ctc-option-panel<?php echo 'view_parnt_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>" <?php echo $hidechild; ?>> </div>
329
- <?php do_action('chld_thm_cfg_panels', $chld_thm_cfg, $active_tab, $hidechild); ?>
330
  </div>
331
  </div>
332
  <style type="text/css">
@@ -352,6 +274,24 @@ class Child_Theme_Configurator_UI {
352
  <?php
353
  }
354
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  function settings_errors() {
356
  global $chld_thm_cfg;
357
  if (count($chld_thm_cfg->errors)):
@@ -362,12 +302,9 @@ class Child_Theme_Configurator_UI {
362
  echo '</ul></div>' . LF;
363
  elseif (isset($_GET['updated'])):
364
  echo '<div class="updated"><p>' . LF
365
- . apply_filters('chld_thm_cfg_update_msg', sprintf(__('Child Theme <strong>%s</strong> has been generated successfully.', 'chld_thm_cfg'),
366
- $chld_thm_cfg->css->get_prop('child_name')), $chld_thm_cfg) . LF
367
- . '</p>';
368
-
369
- if ( 9 == $_GET['updated']) echo '<p>' . __('Please verify the imports below and remove any imports that are not needed by the front end, such as admin or configuration stylesheets.', 'chld_thm_cfg') . '</p>' . LF;
370
- echo '</div>' . LF;
371
  endif;
372
  }
373
 
@@ -380,110 +317,88 @@ class Child_Theme_Configurator_UI {
380
  if ( $screen->id != $chld_thm_cfg->hook )
381
  return;
382
  // Add help tabs
383
-
384
- $screen->add_help_tab( array(
385
- 'id' => 'ctc_tutorial',
386
- 'title' => __( 'Tutorial Video', 'chld_thm_cfg' ),
387
- 'content' => __('<iframe width="480" height="270" src="//www.youtube.com/embed/xL2HkWQxgOA?rel=0&modestbranding=1" frameborder="0" allowfullscreen></iframe>', 'chld_thm_cfg'),
388
- ) );
389
-
390
-
391
  $screen->add_help_tab( array(
392
  'id' => 'ctc_getting_started',
393
- 'title' => __( 'Start Here', 'chld_thm_cfg' ),
394
  'content' => __( '
395
  <p>The first step is to create a child theme and import your parent theme styles into the configurator.</p>
396
  <ol><li>Select an existing parent theme from the menu.</li>
397
- <li>Select "New" or "Existing" child theme.
398
- <ul><li>If creating a new theme, enter a "slug" (lower case, no spaces). This is used to name the theme directory and identify the theme to WordPress.</li>
399
- <li>If using an existing theme, select a child theme from the menu.</li></ul></li>
400
- <li>Enter a Name for the child theme.</li>
401
  <li>Enter an author for the child theme.</li>
402
- <li>Enter the child theme version number.</li>
403
- <li>If your theme uses multiple stylesheets, check "Scan Parent Theme for additional stylesheets.</li>
404
- <li>Click "Generate Child Theme." If you are loading an existing child theme, The Child Theme Configurator will create a backup of your existing stylesheet in the theme directory.</li></ol>
405
- ', 'chld_thm_cfg'
406
  ),
407
  ) );
408
 
409
  $screen->add_help_tab( array(
410
  'id' => 'ctc_query_selector',
411
- 'title' => __( 'Query/Selector', 'chld_thm_cfg' ),
412
  'content' => __( '
413
  <p>There are two ways to identify and override parent styles. The Child Theme Configurator lets you search styles by <strong>selector</strong> and by <strong>rule</strong>. If you wish to change a specific selector (e.g., h1), use the "Query/Selector" tab. If you have a specific value you wish to change site-wide (e.g., the color of the type), use the "Rule/Value" tab.</p>
414
  <p>The Query/Selector tab lets you find specific selectors and edit them. First, find the query that contains the selector you wish to edit by typing in the <strong>Query</strong> autoselect box. Select by clicking with the mouse or by pressing the "Enter" or "Tab" keys. Selectors are in the <strong>base</strong> query by default.</p>
415
  <p>Next, find the selector by typing in the <strong>Selector</strong> autoselect box. Select by clicking with the mouse or by pressing the "Enter" or "Tab" keys.</p>
416
  <p>This will load all of the rules for that selector with the Parent values on the left and the Child values inputs on the right. Any existing child values will be automatically populated. There is also a Sample preview that displays the combination of Parent and Child overrides. Note that the <strong>border</strong> and <strong>background-image</strong> get special treatment.</p>
417
- <p>The "Order" field contains the original sequence of the selector in the parent theme stylesheet. You can change the selector order sequence by entering a lower or higher number in the "Order" field. You can also force style overrides (so called "!important" flag) by checking the "!" box next to each input. Please use judiciously.</p>
418
  <p>Click "Save" to update the child stylesheet and save your changes to the WordPress admin.</p>
419
- ', 'chld_thm_cfg'
420
  ),
421
  ) );
422
 
423
  $screen->add_help_tab( array(
424
  'id' => 'ctc_rule_value',
425
- 'title' => __( 'Rule/Value', 'chld_thm_cfg' ),
426
  'content' => __( '
427
  <p>There are two ways to identify and override parent styles. The Child Theme Configurator lets you search styles by <strong>selector</strong> and by <strong>rule</strong>. If you wish to change a specific selector (e.g., h1), use the "Query/Selector" tab. If you have a specific value you wish to change site-wide (e.g., the color of the type), use the "Rule/Value" tab.</p>
428
  <p>The Rule/Value tab lets you find specific values for a given rule and then edit that value for individual selectors that use that rule/value combination. First, find the rule you wish to override by typing in the <strong>Rule</strong> autoselect box. Select by clicking with the mouse or by pressing the "Enter" or "Tab" keys.</p>
429
  <p>This will load all of the unique values that exist for that rule in the parent stylesheet with a Sample preview for that value. If there are values that exist in the child stylesheet that do not exist in the parent stylesheet, they will be displayed as well.</p>
430
  <p>For each unique value, click the "Selectors" link to view a list of selectors that use that rule/value combination, grouped by query with a Sample preview of the value and inputs for the child value. Any existing child values will be automatically populated.</p>
431
  <p>Click "Save" to update the child stylesheet and save your changes to the WordPress admin.</p>
432
- ', 'chld_thm_cfg'
433
  ),
434
  ) );
435
 
436
  $screen->add_help_tab( array(
437
  'id' => 'ctc_new_styles',
438
- 'title' => __( 'Add New Styles', 'chld_thm_cfg' ),
439
  'content' => __( '
440
  <p>If you wish to add additional rules to a given selector, first load the selector using the Query/Selector tab. Then find the rule you wish to override by typing in the <strong>New Rule</strong> autoselect box. Select by clicking with the mouse or by pressing the "Enter" or "Tab" keys. This will add a new input row to the selector inputs.</p>
441
  <p>If you wish to add completely new selectors, or even new @media queries, you can enter free-form CSS in the "New Selector" textarea. Be aware that your syntax must be correct (i.e., balanced curly braces, etc.) for the parser to load the new styles. You will know it is invalid because a red "X" will appear next to the save button.</p>
442
  <p>If you prefer to use shorthand syntax for rules and values instead of the inputs provided by the Child Theme Configurator, you can enter them here as well. The parser will convert your input into normalized CSS code automatically.</p>
443
- ', 'chld_thm_cfg'
444
  ),
445
  ) );
446
 
447
  $screen->add_help_tab( array(
448
  'id' => 'ctc_imports',
449
- 'title' => __( '@imports', 'chld_thm_cfg' ),
450
  'content' => __( '
451
  <p>You can add additional stylesheets and web fonts by typing @import rules into the textarea on the @import tab. <strong>Important: The Child Theme Configurator adds the @import rule that loads the Parent Theme\'s stylesheet automatically. Do not need to add it here.</strong></p>
452
- <p><strong>Important:</strong> If you chose "Scan Parent Theme for additional stylesheets," the Child Theme Configurator automically places @import rules for the additional stylesheets here. Be sure to delete any imports that are not needed by the front end, such as admin or configuration stylesheets.</p>
453
  <p>Below is an example that loads a local custom stylesheet (you would have to add the "fonts" directory and stylesheet) as well as the web font "Open Sans" from Google Web Fonts:</p>
454
  <blockquote><pre><code>
455
  @import url(fonts/stylesheet.css);
456
  @import url(http://fonts.googleapis.com/css?family=Open+Sans:400,400italic,700,700italic);
457
  </code></pre></blockquote>
458
- ', 'chld_thm_cfg'
459
  ),
460
  ) );
461
 
462
  $screen->add_help_tab( array(
463
  'id' => 'ctc_preview',
464
- 'title' => __( 'Preview and Activate', 'chld_thm_cfg' ),
465
  'content' => __( '
466
- <p>Click the View Child or Parent CSS tab to reference the stylesheet code. To preview the stylesheet as a WordPress theme follow these steps:</p>
467
  <ol><li>Navigate to Appearance > Themes in the WordPress Admin. You will now see the new Child Theme as one of the installed Themes.</li>
468
  <li>Click "Live Preview" below the new Child Theme to see it in action.</li>
469
  <li>When you are ready to take the Child Theme live, click "Activate."</li></ol>
470
- ', 'chld_thm_cfg'
471
  ),
472
  ) );
473
 
474
  $screen->add_help_tab( array(
475
  'id' => 'ctc_faq',
476
- 'title' => __( 'FAQs', 'chld_thm_cfg' ),
477
  'content' => __( '
478
- <h5>Does it work with Plugins?</h5>
479
- <p>We offer a premium extension to let you 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>
480
- <h5 id="doesnt_work">Why doesn’t this work with my (insert theme vendor here) theme?</h5>
481
- <p>Some themes (particularly commercial themes) do not adhere to the Theme Development guidelines set forth by WordPress.org, and do not automatically load child theme stylesheets or php files. This is unfortunate, because it effectively prohibits the webmaster from adding any customizations (other than those made through the admin theme options) that will survive past an upgrade.</p>
482
- <p>Contact the vendor directly to ask for this core functionality. It is our opinion that ALL themes (especially commercial ones) must pass the Theme Unit Tests outlined by WordPress.org.</p>
483
- <h5 id="menus-broken">Why are my menus displaying incorrectly when I activate the new child theme?</h5>
484
- <p>The child theme creates a new instance in the WordPress options data and the menus have to be assigned. Go to Appearance &gt; Menus and assign locations to each of the menus for the new Child Theme.</p>
485
- <h5 "preview-not-loading">Why do the preview tabs return "Stylesheet could not be displayed"?</h5>
486
- <p>You have to configure at least one child theme from the Parent/Child tab for the preview to display.</p>
487
  <h5 id="specific_color">How do I change a specific color/font style/background?</h5>
488
  <p>You can override a specific value globally using the Rule/Value tab. See Rule/Value, above.</p>
489
  <h5 id="add_styles">How do I add styles that aren\'t in the Parent Theme?</h5>
@@ -492,8 +407,6 @@ class Child_Theme_Configurator_UI {
492
  <p>You shouldn\'t really "remove" a style from the Parent. You can, however, set the rule to "inherit," "none," or zero (depending on the rule). This will negate the Parent value. Some experimentation may be necessary.</p>
493
  <h5 id="remove_styles">How do I remove a style from the Child Theme?</h5>
494
  <p>Delete the value from the input for the rule you wish to remove. The Child Theme Configurator only adds overrides for rules that contain values.</p>
495
- <h5 id="important_flag">How do I set the !important flag?</h5>
496
- <p>We always recommend relying on good cascading design over global overrides. To that end, you have ability to change the load order of child theme styles by entering a value in the "Order" field. And yes, you can now set rules as important by checking the "!" box next to each input. Please use judiciously.</p>
497
  <h5 id="gradients">How do I create cross-browser gradients?</h5>
498
  <p>The Child Theme Configurator automatically generates the vendor prefixes and filters to display gradients across most browsers. It uses a normalized syntax and only supports two colors without intermediate stops. The inputs consist of origin (e.g., top, left, 135deg, etc.), start color and end color. The browser-specific syntax is generated automatically when you save these values. <strong>Note:</strong> For Internet Explorer, a filter rule approximates the gradient but can only be horizontal (origin top) or vertical (origin left). The legacy webkit-gradient syntax is not supported.</p>
499
  <h5 id="responsive">How do I make my Theme responsive?</h5>
@@ -506,13 +419,13 @@ class Child_Theme_Configurator_UI {
506
  <p>You can also create a secondary stylesheet that contains @font-face rules and import it using the @import tab. <strong>Note:</strong> Currently the Child Theme Configurator does not generate previews of imported web fonts, but will in a later release.</p>
507
  <h5 id="functions_file">Where is the functions.php file?</h5>
508
  <p>You can add your own functions.php file, and any other files and directories you need for your Child Theme. The Child Theme Configurator helps you identify and override the Parent stylesheet without touching the other files.</p>
509
- ', 'chld_thm_cfg'
510
  ),
511
  ) );
512
 
513
  $screen->add_help_tab( array(
514
  'id' => 'ctc_glossary',
515
- 'title' => __( 'Glossary', 'chld_thm_cfg' ),
516
  'content' => __( '
517
  <h3 id="terms">Glossary</h3>
518
  <ul><li id="parent_theme"><strong>Parent Theme</strong> The WordPress Theme you wish to edit. WordPress first loads the Child Theme, then loads the Parent Theme. If a style exists in the Child Theme, it overrides the Parent Theme.</li>
@@ -526,22 +439,18 @@ class Child_Theme_Configurator_UI {
526
  </ul></li>
527
  <li id="override"><strong>Override</strong> When a selector exists in both the Child Theme and the Parent Theme, the Child Theme takes priority over the Parent theme. This is where the Child Theme Configurator stands out: it helps you create <strong>exact overrides</strong> of selectors from the Parent Theme, eliminating hours of trial and error.</li>
528
  </ul>
529
- ', 'chld_thm_cfg'
530
  ),
531
  ) );
532
 
533
  // Set help sidebar
534
  $screen->set_help_sidebar(
535
  '
536
- <h4>Now it works with plugins, too!</h4>
537
- <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>
538
  <ul>
539
- <li><a href="http://www.lilaeamedia.com/about/contact/">' . __( 'Contact us', 'chld_thm_cfg' ) . '</a></li>
540
- <li><a href="http://www.lilaeamedia.com/plugins/child-theme-configurator">' . __( 'Plugin Website', 'chld_thm_cfg' ) . '</a></li>
541
- <li><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8QE5YJ8WE96AJ">' . __( 'Donate', 'chld_thm_cfg' ) . '</a></li>
542
- <li><a href="http://wordpress.org/support/view/plugin-reviews/child-theme-configurator?rate=5#postform">' . __( 'Give Us 5 Stars', 'chld_thm_cfg' ) . '</a></li>
543
- <li><a href="http://codex.wordpress.org/Child_Themes">' . __( 'WordPress Codex', 'chld_thm_cfg' ) . '</a></li>
544
- <li><a href="http://wordpress.stackexchange.com/">' . __( 'WordPress Answers', 'chld_thm_cfg' ) . '</a></li>
545
  </ul>
546
  '
547
  );
1
  <?php
2
  // Exit if accessed directly
3
  if ( !defined('ABSPATH')) exit;
4
+
5
  /*
6
  Class: Child_Theme_Configurator_UI
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Handles the plugin User Interface
9
+ Version: 1.0
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
13
  Domain Path: /lang
14
  License: GPLv2
15
+ Copyright (C) 2013 Lilaea Media
16
  */
17
  class Child_Theme_Configurator_UI {
18
  var $swatch_text;
 
 
 
19
  function __construct() {
20
+ $this->swatch_text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.';
 
21
  }
22
 
23
  function render_options() {
24
  global $chld_thm_cfg;
25
+ $css = $chld_thm_cfg->css;
26
+ $parent = $css->get_property('parent_theme');
27
+ $child = $css->get_property('child_theme');
28
+ $imports= $css->get_property('imports');
29
+ $id = 0;
 
 
 
30
  ?>
31
 
32
  <div class="wrap">
33
+ <div id="icon-tools" class="icon32"></div>
34
  <h2><?php echo $chld_thm_cfg->pluginName; ?></h2>
35
+ <?php $this->settings_errors(); ?>
 
 
36
  <?php
37
  $active_tab = isset( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : 'parent_child_options';
38
  ?>
39
+ <h2 class="nav-tab-wrapper">
40
+ <a id="parent_child_options" href="?page=<?php echo $chld_thm_cfg->menuName; ?>&amp;tab=parent_child_options"
41
  class="nav-tab<?php echo 'parent_child_options' == $active_tab ? ' nav-tab-active' : ''; ?>">
42
+ <?php _e('Parent/Child', $chld_thm_cfg->ns); ?>
43
+ </a>
44
+ <a id="query_selector_options" href="?page=<?php echo $chld_thm_cfg->menuName; ?>&amp;tab=query_selector_options"
45
+ class="nav-tab<?php echo 'query_selector_options' == $active_tab ? ' nav-tab-active' : ''; ?>">
46
+ <?php _e('Query/Selector', $chld_thm_cfg->ns); ?>
47
+ </a>
48
+ <a id="rule_value_options" href="?page=<?php echo $chld_thm_cfg->menuName; ?>&amp;tab=rule_value_options"
49
+ class="nav-tab<?php echo 'rule_value_options' == $active_tab ? ' nav-tab-active' : ''; ?>">
50
+ <?php _e('Rule/Value', $chld_thm_cfg->ns); ?>
51
+ </a>
52
+ <a id="import_options" href="?page=<?php echo $chld_thm_cfg->menuName; ?>&amp;tab=import_options"
53
+ class="nav-tab<?php echo 'import_options' == $active_tab ? ' nav-tab-active' : ''; ?>">
54
+ <?php _e('@import', $chld_thm_cfg->ns); ?>
55
+ </a>
56
+ <a id="preview_options" href="?page=<?php echo $chld_thm_cfg->menuName; ?>&amp;tab=preview_options"
57
+ class="nav-tab<?php echo 'preview_options' == $active_tab ? ' nav-tab-active' : ''; ?>">
58
+ <?php _e('Preview CSS', $chld_thm_cfg->ns); ?>
59
+ </a>
60
+ </h2>
61
  <div class="ctc-option-panel-container">
62
  <div id="parent_child_options_panel" class="ctc-option-panel<?php echo 'parent_child_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>">
63
  <form id="ctc_load_form" method="post" action="">
64
  <?php wp_nonce_field( 'ctc_update' ); ?>
65
+ <div class="ctc-input-row clearfix" id="input_row_parent_theme">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  <div class="ctc-input-cell">
67
  <label>
68
+ <?php _e('Parent Theme', $chld_thm_cfg->ns); ?>
69
  </label>
70
  </div>
71
  <div class="ctc-input-cell">
72
+ <?php $this->render_theme_dropdown(); ?>
 
73
  </div>
74
  </div>
75
+ <div class="ctc-input-row clearfix" id="input_row_child_theme">
 
76
  <div class="ctc-input-cell">
77
  <label>
78
+ <?php _e('Child Theme', $chld_thm_cfg->ns); ?>
79
  </label>
80
  </div>
81
  <div class="ctc-input-cell">
82
+ <?php $this->render_theme_dropdown(true); ?>
 
83
  </div>
84
  </div>
85
  <div class="ctc-input-row clearfix" id="input_row_child_template">
86
  <div class="ctc-input-cell">
87
  <label>
88
+ <?php _e('Author', $chld_thm_cfg->ns); ?>
89
  </label>
90
  </div>
91
  <div class="ctc-input-cell">
92
+ <input class="ctc_text" id="ctc_theme_author" name="ctc_theme_author" type="text" value="<? echo $css->get_property('author'); ?>"/>
 
93
  </div>
94
  </div>
95
+ <div class="ctc-input-row clearfix" id="input_row_child_name">
96
  <div class="ctc-input-cell">
97
  <label>
98
+ <?php _e('New Child Theme Name', $chld_thm_cfg->ns); ?>
99
  </label>
100
  </div>
101
  <div class="ctc-input-cell">
102
+ <input class="ctc_text" id="ctc_child_name" name="ctc_child_name" type="text"/>
 
103
  </div>
104
  </div>
105
  <div class="ctc-input-row clearfix" id="input_row_child_template">
106
  <div class="ctc-input-cell">
107
  <label>
108
+ <?php _e('New Child Theme Slug', $chld_thm_cfg->ns); ?>
109
  </label>
110
  </div>
111
  <div class="ctc-input-cell">
112
+ <input class="ctc_text" id="ctc_child_template" name="ctc_child_template" type="text"/>
 
113
  </div>
114
  </div>
115
  <div class="ctc-input-row clearfix" id="input_row_child_template">
117
  <label>&nbsp;</label>
118
  </div>
119
  <div class="ctc-input-cell">
120
+ <input class="ctc_submit button button-primary" id="ctc_load_styles" name="ctc_load_styles" type="submit"
121
+ value="<?php _e('Load Styles', $chld_thm_cfg->ns); ?>" />
122
  </div>
123
  </div>
124
  </form>
125
  </div>
126
+ <div id="rule_value_options_panel" class="ctc-option-panel<?php echo 'rule_value_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>">
 
127
  <form id="ctc_rule_value_form" method="post" action="">
128
  <?php wp_nonce_field( 'ctc_update' ); ?>
129
  <div class="ctc-input-row clearfix" id="ctc_input_row_rule_menu">
130
  <div class="ctc-input-cell"> <strong>
131
+ <?php _e('Rule', $chld_thm_cfg->ns); ?>
132
  </strong> </div>
133
  <div class="ctc-input-cell" id="ctc_rule_menu_selected">&nbsp;</div>
 
134
  <div class="ctc-input-cell">
135
  <div class="ui-widget">
136
  <input id="ctc_rule_menu"/>
 
137
  </div>
138
  </div>
139
  </div>
140
  <div class="ctc-input-row clearfix" id="ctc_input_row_rule_header" style="display:none">
141
  <div class="ctc-input-cell"> <strong>
142
+ <?php _e('Value', $chld_thm_cfg->ns); ?>
143
  </strong> </div>
144
  <div class="ctc-input-cell"> <strong>
145
+ <?php _e('Sample', $chld_thm_cfg->ns); ?>
146
  </strong> </div>
147
  <div class="ctc-input-cell"> <strong>
148
+ <?php _e('Selectors', $chld_thm_cfg->ns); ?>
149
  </strong> </div>
150
  </div>
151
  <div class="ctc-rule-value-input-container clearfix" id="ctc_rule_value_inputs" style="display:none"> </div>
152
  </form>
153
  </div>
154
+ <div id="query_selector_options_panel" class="ctc-option-panel<?php echo 'query_selector_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>">
 
155
  <form id="ctc_query_selector_form" method="post" action="">
156
  <div class="ctc-input-row clearfix" id="input_row_query">
157
  <div class="ctc-input-cell"> <strong>
158
+ <?php _e('Query', $chld_thm_cfg->ns); ?>
159
  </strong> </div>
160
  <div class="ctc-input-cell" id="ctc_sel_ovrd_query_selected">&nbsp;</div>
161
  <div class="ctc-input-cell">
162
  <div class="ui-widget">
163
+ <input id="ctc_sel_ovrd_query"/>
164
  </div>
165
  </div>
166
  </div>
167
  <div class="ctc-input-row clearfix" id="input_row_selector">
168
  <div class="ctc-input-cell"> <strong>
169
+ <?php _e('Selector', $chld_thm_cfg->ns); ?>
170
+ </strong> </div>
171
  <div class="ctc-input-cell" id="ctc_sel_ovrd_selector_selected">&nbsp;</div>
172
  <div class="ctc-input-cell">
173
  <div class="ui-widget">
174
+ <input id="ctc_sel_ovrd_selector"/>
 
175
  </div>
176
  </div>
177
  </div>
178
  <div class="ctc-selector-row clearfix" id="ctc_sel_ovrd_rule_inputs_container" style="display:none">
179
  <div class="ctc-input-row clearfix">
180
  <div class="ctc-input-cell"><strong>
181
+ <?php _e('Sample', $chld_thm_cfg->ns); ?>
182
  </strong></div>
183
  <div class="ctc-input-cell clearfix" style="max-height:150px;overflow:hidden">
184
  <div class="ctc-swatch" id="ctc_child_all_0_swatch"><?php echo $this->swatch_text; ?></div>
185
  </div>
 
186
  <div class="ctc-input-cell ctc-button-cell" id="ctc_save_query_selector_cell">
187
+ <input type="button" class="button ctc-save-input" id="ctc_save_query_selector"
188
+ name="ctc_save_query_selector" value="Save" />
189
+ <input type="hidden" id="ctc_sel_ovrd_selnum"
190
+ name="ctc_sel_ovrd_selnum" value="" />
191
  </div>
192
  </div>
193
  <div class="ctc-input-row clearfix" id="ctc_sel_ovrd_rule_header" style="display:none">
194
  <div class="ctc-input-cell"> <strong>
195
+ <?php _e('Rule', $chld_thm_cfg->ns); ?>
196
  </strong> </div>
197
  <div class="ctc-input-cell"> <strong>
198
+ <?php _e('Parent Value', $chld_thm_cfg->ns); ?>
199
  </strong> </div>
200
  <div class="ctc-input-cell"> <strong>
201
+ <?php _e('Child Value', $chld_thm_cfg->ns); ?>
202
  </strong> </div>
203
  </div>
204
  <div id="ctc_sel_ovrd_rule_inputs" style="display:none"> </div>
205
  <div class="ctc-input-row clearfix" id="ctc_sel_ovrd_new_rule" style="display:none">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  <div class="ctc-input-cell"> <strong>
207
+ <?php _e('New Rule', $chld_thm_cfg->ns); ?>
208
+ </strong> </div>
209
+ <div class="ctc-input-cell">
210
+ <div class="ui-widget">
211
+ <input id="ctc_new_rule_menu"/>
212
  </div>
213
  </div>
 
 
 
214
  </div>
215
+ </div>
216
+ <div class="ctc-selector-row clearfix" id="ctc_new_selector_row">
217
+ <div class="ctc-input-cell"> <strong>
218
+ <?php _e('New Selector(s)', $chld_thm_cfg->ns); ?>
219
+ </strong>
220
+ <div class="ctc-textarea-button-cell" id="ctc_save_query_selector_cell">
221
+ <input type="button" class="button ctc-save-input" id="ctc_save_new_selectors"
222
+ name="ctc_save_new_selectors" value="Save" />
223
+ </div>
224
+ </div>
225
+ <div class="ctc-input-cell-wide"> <textarea id="ctc_new_selectors" name="ctc_new_selectors" wrap="off"></textarea> </div>
226
+ </div>
227
  </form>
228
  </div>
229
+ <div id="import_options_panel" class="ctc-option-panel<?php echo 'import_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>">
 
230
  <form id="ctc_import_form" method="post" action="">
231
  <?php wp_nonce_field( 'ctc_update' ); ?>
232
+ <div class="ctc-input-row clearfix" id="ctc_child_imports_row">
233
+ <div class="ctc-input-cell"> <strong>
234
+ <?php _e('@import Statements', $chld_thm_cfg->ns); ?>
235
+ </strong>
236
+ <div class="ctc-textarea-button-cell" id="ctc_save_imports_cell">
237
+ <input type="button" class="button ctc-save-input" id="ctc_save_imports"
238
+ name="ctc_save_imports" value="Save" />
239
+ </div>
240
  </div>
241
+ <div class="ctc-input-cell-wide"> <textarea id="ctc_child_imports" name="ctc_child_imports" wrap="off">
242
+ <?php if (!empty($imports[$child])):
243
+ foreach ($imports[$child] as $import):
 
 
244
  echo esc_textarea($import . ';' . LF);
245
+ endforeach; endif;?></textarea> </div>
246
+
247
  </div>
 
248
  </form>
249
  </div>
250
+ <div id="preview_options_panel" class="ctc-option-panel<?php echo 'preview_options' == $active_tab ? ' ctc-option-panel-active' : ''; ?>">
251
+ </div>
 
 
 
252
  </div>
253
  </div>
254
  <style type="text/css">
274
  <?php
275
  }
276
 
277
+ function render_theme_dropdown($child = false) {
278
+ global $chld_thm_cfg;
279
+ echo '<select class="chld-thm-cfg-select" id="ctc_theme_' . ($child?'child':'parent') . '" name="ctc_theme_' . ($child?'child':'parent') . '">' . LF;
280
+ if ($child):
281
+ echo '<option value="new">New Theme</option>' . LF;
282
+ endif;
283
+ foreach (wp_get_themes() as $theme):
284
+ $parent = $theme->parent();
285
+ if ($child !== empty($parent)):
286
+ $template = $child ? $theme->get_stylesheet() : $theme->get_template();
287
+ echo '<option value="' . $template . '"'
288
+ . ($template == $chld_thm_cfg->css->get_property($child?'child_theme':'parent_theme') ? ' selected' : '')
289
+ . '>' . $theme->get('Name') . '</option>' . LF;
290
+ endif;
291
+ endforeach;
292
+ echo '</select>' . LF;
293
+ }
294
+
295
  function settings_errors() {
296
  global $chld_thm_cfg;
297
  if (count($chld_thm_cfg->errors)):
302
  echo '</ul></div>' . LF;
303
  elseif (isset($_GET['updated'])):
304
  echo '<div class="updated"><p>' . LF
305
+ . __('Child Theme', $chld_thm_cfg->ns) . ' <strong>' . $chld_thm_cfg->css->get_property('child_theme_name')
306
+ . '</strong> ' . __('has been updated.', $chld_thm_cfg->ns) . LF
307
+ . '</p></div>' . LF;
 
 
 
308
  endif;
309
  }
310
 
317
  if ( $screen->id != $chld_thm_cfg->hook )
318
  return;
319
  // Add help tabs
 
 
 
 
 
 
 
 
320
  $screen->add_help_tab( array(
321
  'id' => 'ctc_getting_started',
322
+ 'title' => __( 'Start Here', $chld_thm_cfg->ns ),
323
  'content' => __( '
324
  <p>The first step is to create a child theme and import your parent theme styles into the configurator.</p>
325
  <ol><li>Select an existing parent theme from the menu.</li>
326
+ <li>Select an existing child theme from the menu, or "New Theme" if you are creating one from scratch.</li>
 
 
 
327
  <li>Enter an author for the child theme.</li>
328
+ <li>If this is a new theme, enter a Name.</li>
329
+ <li>If this is a new theme, enter a "slug" (lower case, no spaces). This is used to name the theme directory and identify the theme to WordPress.</li>
330
+ <li>Click "Load Styles." If you are loading an existing child theme, The Child Theme Configurator will create a backup of your existing stylesheet in the theme directory.</li></ol>
331
+ ', $chld_thm_cfg->ns
332
  ),
333
  ) );
334
 
335
  $screen->add_help_tab( array(
336
  'id' => 'ctc_query_selector',
337
+ 'title' => __( 'Query/Selector', $chld_thm_cfg->ns ),
338
  'content' => __( '
339
  <p>There are two ways to identify and override parent styles. The Child Theme Configurator lets you search styles by <strong>selector</strong> and by <strong>rule</strong>. If you wish to change a specific selector (e.g., h1), use the "Query/Selector" tab. If you have a specific value you wish to change site-wide (e.g., the color of the type), use the "Rule/Value" tab.</p>
340
  <p>The Query/Selector tab lets you find specific selectors and edit them. First, find the query that contains the selector you wish to edit by typing in the <strong>Query</strong> autoselect box. Select by clicking with the mouse or by pressing the "Enter" or "Tab" keys. Selectors are in the <strong>base</strong> query by default.</p>
341
  <p>Next, find the selector by typing in the <strong>Selector</strong> autoselect box. Select by clicking with the mouse or by pressing the "Enter" or "Tab" keys.</p>
342
  <p>This will load all of the rules for that selector with the Parent values on the left and the Child values inputs on the right. Any existing child values will be automatically populated. There is also a Sample preview that displays the combination of Parent and Child overrides. Note that the <strong>border</strong> and <strong>background-image</strong> get special treatment.</p>
 
343
  <p>Click "Save" to update the child stylesheet and save your changes to the WordPress admin.</p>
344
+ ', $chld_thm_cfg->ns
345
  ),
346
  ) );
347
 
348
  $screen->add_help_tab( array(
349
  'id' => 'ctc_rule_value',
350
+ 'title' => __( 'Rule/Value', $chld_thm_cfg->ns ),
351
  'content' => __( '
352
  <p>There are two ways to identify and override parent styles. The Child Theme Configurator lets you search styles by <strong>selector</strong> and by <strong>rule</strong>. If you wish to change a specific selector (e.g., h1), use the "Query/Selector" tab. If you have a specific value you wish to change site-wide (e.g., the color of the type), use the "Rule/Value" tab.</p>
353
  <p>The Rule/Value tab lets you find specific values for a given rule and then edit that value for individual selectors that use that rule/value combination. First, find the rule you wish to override by typing in the <strong>Rule</strong> autoselect box. Select by clicking with the mouse or by pressing the "Enter" or "Tab" keys.</p>
354
  <p>This will load all of the unique values that exist for that rule in the parent stylesheet with a Sample preview for that value. If there are values that exist in the child stylesheet that do not exist in the parent stylesheet, they will be displayed as well.</p>
355
  <p>For each unique value, click the "Selectors" link to view a list of selectors that use that rule/value combination, grouped by query with a Sample preview of the value and inputs for the child value. Any existing child values will be automatically populated.</p>
356
  <p>Click "Save" to update the child stylesheet and save your changes to the WordPress admin.</p>
357
+ ', $chld_thm_cfg->ns
358
  ),
359
  ) );
360
 
361
  $screen->add_help_tab( array(
362
  'id' => 'ctc_new_styles',
363
+ 'title' => __( 'Add New Styles', $chld_thm_cfg->ns ),
364
  'content' => __( '
365
  <p>If you wish to add additional rules to a given selector, first load the selector using the Query/Selector tab. Then find the rule you wish to override by typing in the <strong>New Rule</strong> autoselect box. Select by clicking with the mouse or by pressing the "Enter" or "Tab" keys. This will add a new input row to the selector inputs.</p>
366
  <p>If you wish to add completely new selectors, or even new @media queries, you can enter free-form CSS in the "New Selector" textarea. Be aware that your syntax must be correct (i.e., balanced curly braces, etc.) for the parser to load the new styles. You will know it is invalid because a red "X" will appear next to the save button.</p>
367
  <p>If you prefer to use shorthand syntax for rules and values instead of the inputs provided by the Child Theme Configurator, you can enter them here as well. The parser will convert your input into normalized CSS code automatically.</p>
368
+ ', $chld_thm_cfg->ns
369
  ),
370
  ) );
371
 
372
  $screen->add_help_tab( array(
373
  'id' => 'ctc_imports',
374
+ 'title' => __( '@imports', $chld_thm_cfg->ns ),
375
  'content' => __( '
376
  <p>You can add additional stylesheets and web fonts by typing @import rules into the textarea on the @import tab. <strong>Important: The Child Theme Configurator adds the @import rule that loads the Parent Theme\'s stylesheet automatically. Do not need to add it here.</strong></p>
 
377
  <p>Below is an example that loads a local custom stylesheet (you would have to add the "fonts" directory and stylesheet) as well as the web font "Open Sans" from Google Web Fonts:</p>
378
  <blockquote><pre><code>
379
  @import url(fonts/stylesheet.css);
380
  @import url(http://fonts.googleapis.com/css?family=Open+Sans:400,400italic,700,700italic);
381
  </code></pre></blockquote>
382
+ ', $chld_thm_cfg->ns
383
  ),
384
  ) );
385
 
386
  $screen->add_help_tab( array(
387
  'id' => 'ctc_preview',
388
+ 'title' => __( 'Preview and Activate', $chld_thm_cfg->ns ),
389
  'content' => __( '
390
+ <p>Click the Preview CSS tab to see your new masterpiece as CSS code. To preview the stylesheet as a WordPress theme follow these steps:</p>
391
  <ol><li>Navigate to Appearance > Themes in the WordPress Admin. You will now see the new Child Theme as one of the installed Themes.</li>
392
  <li>Click "Live Preview" below the new Child Theme to see it in action.</li>
393
  <li>When you are ready to take the Child Theme live, click "Activate."</li></ol>
394
+ ', $chld_thm_cfg->ns
395
  ),
396
  ) );
397
 
398
  $screen->add_help_tab( array(
399
  'id' => 'ctc_faq',
400
+ 'title' => __( 'FAQs', $chld_thm_cfg->ns ),
401
  'content' => __( '
 
 
 
 
 
 
 
 
 
402
  <h5 id="specific_color">How do I change a specific color/font style/background?</h5>
403
  <p>You can override a specific value globally using the Rule/Value tab. See Rule/Value, above.</p>
404
  <h5 id="add_styles">How do I add styles that aren\'t in the Parent Theme?</h5>
407
  <p>You shouldn\'t really "remove" a style from the Parent. You can, however, set the rule to "inherit," "none," or zero (depending on the rule). This will negate the Parent value. Some experimentation may be necessary.</p>
408
  <h5 id="remove_styles">How do I remove a style from the Child Theme?</h5>
409
  <p>Delete the value from the input for the rule you wish to remove. The Child Theme Configurator only adds overrides for rules that contain values.</p>
 
 
410
  <h5 id="gradients">How do I create cross-browser gradients?</h5>
411
  <p>The Child Theme Configurator automatically generates the vendor prefixes and filters to display gradients across most browsers. It uses a normalized syntax and only supports two colors without intermediate stops. The inputs consist of origin (e.g., top, left, 135deg, etc.), start color and end color. The browser-specific syntax is generated automatically when you save these values. <strong>Note:</strong> For Internet Explorer, a filter rule approximates the gradient but can only be horizontal (origin top) or vertical (origin left). The legacy webkit-gradient syntax is not supported.</p>
412
  <h5 id="responsive">How do I make my Theme responsive?</h5>
419
  <p>You can also create a secondary stylesheet that contains @font-face rules and import it using the @import tab. <strong>Note:</strong> Currently the Child Theme Configurator does not generate previews of imported web fonts, but will in a later release.</p>
420
  <h5 id="functions_file">Where is the functions.php file?</h5>
421
  <p>You can add your own functions.php file, and any other files and directories you need for your Child Theme. The Child Theme Configurator helps you identify and override the Parent stylesheet without touching the other files.</p>
422
+ ', $chld_thm_cfg->ns
423
  ),
424
  ) );
425
 
426
  $screen->add_help_tab( array(
427
  'id' => 'ctc_glossary',
428
+ 'title' => __( 'Glossary', $chld_thm_cfg->ns ),
429
  'content' => __( '
430
  <h3 id="terms">Glossary</h3>
431
  <ul><li id="parent_theme"><strong>Parent Theme</strong> The WordPress Theme you wish to edit. WordPress first loads the Child Theme, then loads the Parent Theme. If a style exists in the Child Theme, it overrides the Parent Theme.</li>
439
  </ul></li>
440
  <li id="override"><strong>Override</strong> When a selector exists in both the Child Theme and the Parent Theme, the Child Theme takes priority over the Parent theme. This is where the Child Theme Configurator stands out: it helps you create <strong>exact overrides</strong> of selectors from the Parent Theme, eliminating hours of trial and error.</li>
441
  </ul>
442
+ ', $chld_thm_cfg->ns
443
  ),
444
  ) );
445
 
446
  // Set help sidebar
447
  $screen->set_help_sidebar(
448
  '
 
 
449
  <ul>
450
+ <li><a href="http://www.lilaeamedia.com/about/contact/">' . __( 'Contact us', $chld_thm_cfg->ns ) . '</a></li>
451
+ <li><a href="http://www.lilaeamedia.com/plugins/child-theme-configurator">' . __( 'Plugin Website', $chld_thm_cfg->ns ) . '</a></li>
452
+ <li><a href="http://codex.wordpress.org/Child_Themes">' . __( 'WordPress Codex', $chld_thm_cfg->ns ) . '</a></li>
453
+ <li><a href="http://wordpress.stackexchange.com/">' . __( 'WordPress Answers', $chld_thm_cfg->ns ) . '</a></li>
 
 
454
  </ul>
455
  '
456
  );
includes/class-ctc.php CHANGED
@@ -6,18 +6,19 @@ 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.3.4
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
13
  Domain Path: /lang
14
  License: GPLv2
15
- Copyright (C) 2014 Lilaea Media
16
  */
17
  require_once('class-ctc-ui.php');
18
  require_once('class-ctc-css.php');
19
  class Child_Theme_Configurator {
20
 
 
21
  var $css;
22
  var $optionsName;
23
  var $menuName;
@@ -26,33 +27,29 @@ class Child_Theme_Configurator {
26
  var $shortName;
27
  var $ns;
28
  var $ui;
29
- var $themes;
30
  var $errors;
31
  var $hook;
32
  var $is_ajax;
33
- var $updated;
34
- var $image_formats;
35
  function __construct($file) {
36
  $this->dir = dirname( $file );
37
- $this->optionsName = 'chld_thm_cfg_options';
38
- $this->menuName = 'chld_thm_cfg_menu';
39
- $lang_dir = $this->dir . '/lang';
40
- load_plugin_textdomain('chld_thm_cfg', false, $lang_dir, $lang_dir);
 
 
41
 
42
- $this->pluginName = __('Child Theme Configurator', 'chld_thm_cfg');
43
- $this->shortName = __('Child Themes', 'chld_thm_cfg');
44
- $this->pluginPath = $this->dir . '/';
45
- $this->pluginURL = plugin_dir_url($file);
46
- $this->image_formats = array('jpg','jpeg','gif','png','JPG','JPEG','GIF','PNG');
47
 
48
  // setup plugin hooks
49
- add_action('admin_menu', array(&$this, 'admin_menu'));
50
- add_action('admin_enqueue_scripts', array(&$this, 'enqueue_scripts'));
51
- add_action('wp_ajax_ctc_update', array(&$this, 'ajax_save_postdata' ));
52
- add_action('wp_ajax_ctc_query', array(&$this, 'ajax_query_css' ));
53
- add_action('chld_thm_cfg_addl_files', array(&$this, 'add_functions_file'), 10, 2);
54
- add_action('chld_thm_cfg_addl_files', array(&$this, 'copy_screenshot'), 10, 2);
55
- //add_action('update_option_' . $this->optionsName, array(&$this, 'update_redirect'), 10);
56
  }
57
 
58
  function admin_menu() {
@@ -67,48 +64,35 @@ class Child_Theme_Configurator {
67
  wp_enqueue_style('chld-thm-cfg-admin', $this->pluginURL . 'css/chld-thm-cfg.css');
68
  wp_enqueue_script('iris');
69
  wp_enqueue_script('ctc-thm-cfg-ctcgrad', $this->pluginURL . 'js/ctcgrad.min.js', array('iris'), '1.0');
70
- wp_enqueue_script('chld-thm-cfg-admin', $this->pluginURL . 'js/chld-thm-cfg.min.js',
71
  array('jquery-ui-autocomplete'), '1.0', true);
72
  wp_localize_script( 'chld-thm-cfg-admin', 'ctcAjax',
73
- apply_filters('chld_thm_cfg_localize_script', array(
74
- 'ajaxurl' => admin_url( 'admin-ajax.php' ),
75
- 'theme_uri' => get_theme_root_uri(),
76
- 'themes' => $this->themes,
77
- 'source' => apply_filters('chld_thm_cfg_source_uri', get_theme_root_uri() . '/'
78
- . $this->css->get_prop('parnt') . '/style.css', $this->css),
79
- 'target' => apply_filters('chld_thm_cfg_target_uri', get_theme_root_uri() . '/'
80
- . $this->css->get_prop('child') . '/style.css', $this->css),
81
- 'parnt' => $this->css->get_prop('parnt'),
82
- 'child' => $this->css->get_prop('child'),
83
- 'imports' => $this->css->get_prop('imports'),
84
- 'rule' => $this->css->get_prop('rule'),
85
- 'sel_ndx' => $this->css->get_prop('sel_ndx'),
86
- 'val_qry' => array(),
87
- 'rule_val' => array(),
88
- 'sel_val' => array(),
89
- 'field_labels' => array(
90
- '_background_url' => __('URL/None', 'chld_thm_cfg'),
91
- '_background_origin' => __('Origin', 'chld_thm_cfg'),
92
- '_background_color1' => __('Color 1', 'chld_thm_cfg'),
93
- '_background_color2' => __('Color 2', 'chld_thm_cfg'),
94
- '_border_width' => __('Width', 'chld_thm_cfg'),
95
- '_border_style' => __('Style', 'chld_thm_cfg'),
96
- '_border_color' => __('Color', 'chld_thm_cfg'),
97
  ),
98
- 'load_txt' => __('Are you sure? This will replace your current settings.', 'chld_thm_cfg'),
99
- 'swatch_txt' => $this->ui->swatch_text,
100
- 'swatch_label' => __('Sample', 'chld_thm_cfg'),
101
- 'important_label' => __('<span style="font-size:10px">!</span>', 'chld_thm_cfg'),
102
- 'selector_txt' => __('Selectors', 'chld_thm_cfg'),
103
- 'close_txt' => __('Close', 'chld_thm_cfg'),
104
- 'edit_txt' => __('Edit', 'chld_thm_cfg'),
105
- 'cancel_txt' => __('Cancel', 'chld_thm_cfg'),
106
- 'rename_txt' => __('Rename', 'chld_thm_cfg'),
107
- 'css_fail_txt' => __('The stylesheet cannot be displayed.', 'chld_thm_cfg'),
108
- 'child_only_txt' => __('(Child Only)', 'chld_thm_cfg'),
109
- 'inval_theme_txt' => __('Please enter a valid Child Theme', 'chld_thm_cfg'),
110
- 'inval_name_txt' => __('Please enter a valid Child Theme name', 'chld_thm_cfg'),
111
- 'theme_exists_txt' => __('<strong>%s</strong> exists. Please enter a different Child Theme', 'chld_thm_cfg'),
112
  )));
113
  endif;
114
  }
@@ -118,209 +102,95 @@ class Child_Theme_Configurator {
118
  }
119
 
120
  function ctc_page_init () {
121
- $this->get_themes();
122
- $this->load_config();
123
- do_action('chld_thm_cfg_forms', $this); // hook for custom forms
124
- $this->write_config();
125
  $this->ui = new Child_Theme_Configurator_UI();
126
  $this->ui->render_help_tabs();
 
127
  }
128
-
129
- function get_themes() {
130
- $this->themes = array('child' => array(), 'parnt' => array());
131
- foreach (wp_get_themes() as $theme):
132
- $parent = $theme->parent();
133
- if (empty($parent)):
134
- $slug = $theme->get_template();
135
- $this->themes['parnt'][$slug] = array('Name' => $theme->get('Name'));
136
- else:
137
- $slug = $theme->get_stylesheet();
138
- $this->themes['child'][$slug] = array('Name' => $theme->get('Name'), 'Author' => $theme->get('Author'), 'Version' => $theme->get('Version'));
139
- endif;
140
- endforeach;
141
  }
142
-
143
- function validate_post($action = 'ctc_update', $noncefield = '_wpnonce') {
144
  return ('POST' == $_SERVER['REQUEST_METHOD']
145
  && current_user_can('edit_theme_options')
146
- && ($this->is_ajax ? check_ajax_referer( $action, $noncefield, false ) : check_admin_referer($action, $noncefield, false )));
147
  }
148
 
149
  function ajax_save_postdata() {
150
  $this->is_ajax = true;
151
  if ($this->validate_post()):
152
- $this->load_config();
153
  $this->css->parse_post_data();
154
  $this->css->write_css();
155
- $result = $this->css->get_prop('updates');
156
- // clear updates so they aren't saved in options object
157
  $this->css->reset_updates();
158
  update_option($this->optionsName, $this->css);
159
- // send all updates back to browser to update cache
160
  die(json_encode($result));
161
  else:
162
  die(0);
163
  endif;
164
  }
165
 
166
- function ajax_query_css() {
167
- $this->is_ajax = true;
168
- if ($this->validate_post()):
169
- $this->load_config();
170
- $regex = "/^ctc_query_/";
171
- foreach(preg_grep($regex, array_keys($_POST)) as $key):
172
- $name = preg_replace($regex, '', $key);
173
- $param[$name] = sanitize_text_field($_POST[$key]);
174
- endforeach;
175
- if (!empty($param['obj'])):
176
- $result = array(
177
- array(
178
- 'key' => isset($param['key'])?$param['key']:'',
179
- 'obj' => $param['obj'],
180
- 'data' => $this->css->get_prop($param['obj'], $param),
181
- ),
182
- );
183
- die(json_encode($result));
184
- endif;
185
- endif;
186
- die(0);
187
- }
188
-
189
- function load_config() {
190
- if (!($this->css = get_option($this->optionsName))
191
- || !is_object($this->css)
192
- // upgrade to v.1.1.1
193
- || !($version = $this->css->get_prop('version'))
194
- )
195
-
196
- $this->css = new Child_Theme_Configurator_CSS();
197
- }
198
-
199
- function write_config() {
200
- if (!isset($_POST['ctc_load_styles'])) return false;
201
- $this->errors = array();
202
- if (current_user_can('install_themes') && $this->validate_post()):
203
- foreach (array(
204
- 'ctc_theme_parnt',
205
- 'ctc_child_type',
206
- 'ctc_theme_child',
207
- 'ctc_child_name',
208
- 'ctc_configtype',
209
- 'ctc_child_template',
210
- 'ctc_child_author',
211
- 'ctc_child_version') as $postfield):
212
- $varparts = explode('_', $postfield);
213
- $varname = end($varparts);
214
- ${$varname} = empty($_POST[$postfield])?'':sanitize_text_field($_POST[$postfield]);
215
- endforeach;
216
- if ($parnt):
217
- if (! $this->check_theme_exists($parnt)):
218
- $this->errors[] = sprintf(__('%s does not exist. Please select a valid Parent Theme', 'chld_thm_cfg'), $parnt);
219
  endif;
220
- else:
221
- $this->errors[] = __('Please select a valid Parent Theme', 'chld_thm_cfg');
222
  endif;
223
- if ('new' == $type):
224
- $configtype = 'theme'; // no custom stylesheets until style.css exists!
225
- $child = strtolower(preg_replace("%[^\w\-]%", '', $template));
226
- if ($this->check_theme_exists($child)):
227
- $this->errors[] = sprintf(__('<strong>%s</strong> exists. Please enter a different Child Theme template name', 'chld_thm_cfg'), $child);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  endif;
229
  endif;
230
- if (empty($child)):
231
- $this->errors[] = __('Please enter a valid Child Theme template name', 'chld_thm_cfg');
232
- endif;
233
- if (empty($name)):
234
- $this->errors[] = __('Please enter a valid Child Theme name', 'chld_thm_cfg');
235
- endif;
236
- if (false === $this->verify_child_theme($child)):
237
- $this->errors[] = __('Your theme directories are not writable. Please adjust permissions and try again.', 'chld_thm_cfg');
238
- endif;
239
- else:
240
- $this->errors[] = __('You do not have permission to configure child themes.', 'chld_thm_cfg');
241
- endif;
242
- if (empty($this->errors)):
243
- $this->css = new Child_Theme_Configurator_CSS();
244
- $this->css->set_prop('parnt', $parnt);
245
- $this->css->set_prop('child', $child);
246
- $this->css->set_prop('child_name', $name);
247
- $this->css->set_prop('child_author', $author);
248
- $this->css->set_prop('child_version', $version);
249
- $this->css->set_prop('configtype', $configtype);
250
- do_action('chld_thm_cfg_addl_files', $this); // hook for add'l plugin files and subdirectories
251
- $this->css->parse_css_file('parnt');
252
- $this->css->parse_css_file('child');
253
- if (false === $this->css->write_css(isset($_POST['ctc_backup']))):
254
- $this->errors[] = __('Your stylesheet is not writable. Please adjust permissions and try again.', 'chld_thm_cfg');
255
- return false;
256
- endif;
257
- $this->css->reset_updates();
258
  update_option($this->optionsName, $this->css);
259
- do_action('chld_thm_cfg_addl_options', $this); // hook for add'l plugin options
260
- $msg = isset($_POST['ctc_scan_subdirs']) ? '9&tab=import_options' : 1;
261
- $this->update_redirect($msg);
262
- endif;
263
- //$this->errors[] = sprintf(__('Child Theme %s was unchanged.', 'chld_thm_cfg'), $name, $this->optionsName);
264
- }
265
-
266
- function render_menu($template = 'child', $selected = null) {
267
- $menu = '<option value="">Select</option>' . LF;
268
- foreach ($this->themes[$template] as $slug => $theme):
269
- $menu .= '<option value="' . $slug . '"' . ($slug == $selected ? ' selected' : '') . '>'
270
- . $slug . ' - "' . $theme['Name'] . '"' . '</option>' . LF;
271
- endforeach;
272
- return $menu;
273
  }
274
 
275
  function check_theme_exists($theme) {
276
- return in_array($theme, array_keys(wp_get_themes()));
277
  }
278
 
279
- /*
280
- * TODO: this is a stub for future use
281
- */
282
  function sanitize_options($input) {
283
  return $input;
284
  }
285
 
286
- function update_redirect($msg = 1) {
287
  if (empty($this->is_ajax)):
288
- wp_safe_redirect(admin_url('tools.php?page=' . $this->menuName . '&updated=' . $msg));
289
- die();
290
  endif;
291
  }
292
-
293
- function verify_child_theme($child) {
294
- $themedir = get_theme_root();
295
- if (! is_writable($themedir)) return false;
296
- $childdir = $themedir . '/' . $child;
297
 
298
- if (! is_dir($childdir)):
299
- if (! mkdir($childdir, 0755)):
300
- return false;
301
- endif;
302
- elseif (! is_writable($childdir)):
303
- return false;
304
- endif;
305
- }
306
-
307
- function add_functions_file($obj){
308
- // add functions.php file
309
- $file = $obj->css->is_file_ok($obj->css->get_child_target('functions.php'));
310
- if ($file && !file_exists($file)):
311
- if (false === file_put_contents($file,
312
- "<?php\n// Exit if accessed directly\nif ( !defined('ABSPATH')) exit;\n\n/* Add custom functions below */")) return false;
313
- endif;
314
- }
315
-
316
- function copy_screenshot($obj) {
317
- foreach ($this->image_formats as $ext):
318
- if ($screenshot_parent = $obj->css->is_file_ok($obj->css->get_parent_source('screenshot.' . $ext))) break;
319
- endforeach;
320
- $screenshot_child = $obj->css->get_child_target('screenshot.' . $ext);
321
- if ($screenshot_parent && $screenshot_child && !file_exists($screenshot_child)):
322
- if (false === file_put_contents($screenshot_child,
323
- @file_get_contents($screenshot_parent))) return false;
324
- endif;
325
- }
326
  }
6
  Class: Child_Theme_Configurator
7
  Plugin URI: http://www.lilaeamedia.com/plugins/child-theme-configurator/
8
  Description: Main Controller Class
9
+ Version: 1.0
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
13
  Domain Path: /lang
14
  License: GPLv2
15
+ Copyright (C) 2013 Lilaea Media
16
  */
17
  require_once('class-ctc-ui.php');
18
  require_once('class-ctc-css.php');
19
  class Child_Theme_Configurator {
20
 
21
+ var $version = '1.0';
22
  var $css;
23
  var $optionsName;
24
  var $menuName;
27
  var $shortName;
28
  var $ns;
29
  var $ui;
 
30
  var $errors;
31
  var $hook;
32
  var $is_ajax;
33
+
 
34
  function __construct($file) {
35
  $this->dir = dirname( $file );
36
+ $this->ns = CHLD_THM_CFG_NS;
37
+ $this->optionsName = $this->ns . '_options';
38
+ $this->menuName = $this->ns . '_menu';
39
+
40
+ $lang_dir = $this->dir . '/lang';
41
+ load_plugin_textdomain($this->ns, false, $lang_dir, $lang_dir);
42
 
43
+ $this->pluginName = __('Child Theme Configurator', $this->ns);
44
+ $this->shortName = __('Child Themes', $this->ns);
45
+ $this->pluginPath = $this->dir . '/';
46
+ $this->pluginURL = plugin_dir_url($file);
 
47
 
48
  // setup plugin hooks
49
+ add_action('admin_menu', array(&$this, 'admin_menu'));
50
+ add_action('admin_enqueue_scripts', array(&$this, 'enqueue_scripts'));
51
+ add_action('wp_ajax_ctc_update', array(&$this, 'ajax_save_postdata' ));
52
+ add_action('update_option_' . $this->optionsName, array(&$this, 'update_redirect'), 10);
 
 
 
53
  }
54
 
55
  function admin_menu() {
64
  wp_enqueue_style('chld-thm-cfg-admin', $this->pluginURL . 'css/chld-thm-cfg.css');
65
  wp_enqueue_script('iris');
66
  wp_enqueue_script('ctc-thm-cfg-ctcgrad', $this->pluginURL . 'js/ctcgrad.min.js', array('iris'), '1.0');
67
+ wp_enqueue_script('chld-thm-cfg-admin', $this->pluginURL . 'js/chld-thm-cfg.min.js',
68
  array('jquery-ui-autocomplete'), '1.0', true);
69
  wp_localize_script( 'chld-thm-cfg-admin', 'ctcAjax',
70
+ apply_filters('ctc_localize_script', array(
71
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
72
+ 'theme_uri' => get_theme_root_uri(),
73
+ 'load_msg' => __('Are you sure? This will replace your current settings.', $this->ns),
74
+ 'parent_theme' => $this->css->get_property('parent_theme'),
75
+ 'child_theme' => $this->css->get_property('child_theme'),
76
+ 'data' => $this->css->get_property('data'),
77
+ 'imports' => $this->css->get_property('imports'),
78
+ 'sel_ndx' => $this->css->get_property('sel_ndx'),
79
+ 'val_ndx' => $this->css->get_property('val_ndx'),
80
+ 'labels' => array(
81
+ '_background_url' => __('URL/None', $this->ns),
82
+ '_background_origin' => __('Origin', $this->ns),
83
+ '_background_color1' => __('Color 1', $this->ns),
84
+ '_background_color2' => __('Color 2', $this->ns),
85
+ '_border_width' => __('Width', $this->ns),
86
+ '_border_style' => __('Style', $this->ns),
87
+ '_border_color' => __('Color', $this->ns),
 
 
 
 
 
 
88
  ),
89
+ 'swatch_text' => $this->ui->swatch_text,
90
+ 'swatch_label' => __('Sample', $this->ns),
91
+ 'selector_text' => __('Selectors', $this->ns),
92
+ 'close_text' => __('Close', $this->ns),
93
+ 'new_query' => __('New Query', $this->ns),
94
+ 'new_selector' => __('New Selector', $this->ns),
95
+ 'css_fail' => __('The stylesheet cannot be displayed.', $this->ns),
 
 
 
 
 
 
 
96
  )));
97
  endif;
98
  }
102
  }
103
 
104
  function ctc_page_init () {
105
+ $this->load_css();
 
 
 
106
  $this->ui = new Child_Theme_Configurator_UI();
107
  $this->ui->render_help_tabs();
108
+ $this->handle_inputs();
109
  }
110
+ function load_css() {
111
+ if (!($this->css = get_option($this->optionsName)))
112
+ $this->css = new Child_Theme_Configurator_CSS();
 
 
 
 
 
 
 
 
 
 
113
  }
114
+ function validate_post() {
 
115
  return ('POST' == $_SERVER['REQUEST_METHOD']
116
  && current_user_can('edit_theme_options')
117
+ && ($this->is_ajax ? check_ajax_referer( 'ctc_update', '_wpnonce', false ) : check_admin_referer( 'ctc_update', '_wpnonce', false )));
118
  }
119
 
120
  function ajax_save_postdata() {
121
  $this->is_ajax = true;
122
  if ($this->validate_post()):
123
+ $this->load_css();
124
  $this->css->parse_post_data();
125
  $this->css->write_css();
126
+ $result = $this->css->get_property('updates');
 
127
  $this->css->reset_updates();
128
  update_option($this->optionsName, $this->css);
 
129
  die(json_encode($result));
130
  else:
131
  die(0);
132
  endif;
133
  }
134
 
135
+ function handle_inputs() {
136
+ if (isset($_POST['ctc_load_styles']) && current_user_can('install_themes') && $this->validate_post()):
137
+ $author = '';
138
+ if (isset($_POST['ctc_theme_parent'])):
139
+ $theme = sanitize_text_field($_POST['ctc_theme_parent']);
140
+ if (! $this->check_theme_exists($theme)):
141
+ $this->errors[] = sprintf(__('%s does not exist. Please select a valid Parent Theme', $this->ns), $theme);
142
+ return false;
143
+ else:
144
+ $this->css->set_property('parent_theme', $theme);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  endif;
 
 
146
  endif;
147
+ if (isset($_POST['ctc_theme_child'])):
148
+ $theme = sanitize_text_field($_POST['ctc_theme_child']);
149
+ $theme_name = empty($_POST['ctc_child_name']) ? '' : sanitize_text_field($_POST['ctc_child_name']);
150
+ if ('new' == $theme):
151
+ $theme = empty($_POST['ctc_child_template']) ? '' :
152
+ strtolower(preg_replace("%\W%", '', sanitize_text_field($_POST['ctc_child_template'])));
153
+ if (empty($theme)):
154
+ $this->errors[] = __('Please enter a valid Child Theme template name', $this->ns);
155
+ return false;
156
+ elseif ($this->check_theme_exists($theme)):
157
+ $this->errors[] = sprintf(__('%s exists. Please enter a different Child Theme template name', $this->ns), $theme);
158
+ return false;
159
+ elseif (empty($theme_name)):
160
+ $this->errors[] = sprintf(__('Please enter a valid Child Theme name', $this->ns), $theme_name);
161
+ return false;
162
+ endif;
163
+ elseif (!$this->check_theme_exists($theme)):
164
+ $this->errors[] = sprintf(__('%s does not exist. Please select a valid Child Theme', $this->ns), $theme);
165
+ return false;
166
+ endif;
167
+ $this->css->set_property('child_theme', $theme);
168
+ $this->css->set_property('child_theme_name', $theme_name);
169
+ if (isset($_POST['ctc_theme_author'])):
170
+ $this->css->set_property('author', sanitize_text_field($_POST['ctc_theme_author']));
171
  endif;
172
  endif;
173
+ $this->css->parse_css_file('parent_theme');
174
+ $this->css->parse_css_file('child_theme');
175
+ $this->css->write_css();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  update_option($this->optionsName, $this->css);
177
+ endif;
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  }
179
 
180
  function check_theme_exists($theme) {
181
+ return in_array(strtolower($theme), array_keys(wp_get_themes()));
182
  }
183
 
 
 
 
184
  function sanitize_options($input) {
185
  return $input;
186
  }
187
 
188
+ function update_redirect() {
189
  if (empty($this->is_ajax)):
190
+ wp_safe_redirect(admin_url('tools.php?page=' . $this->menuName . '&updated=true'));
191
+ exit();
192
  endif;
193
  }
 
 
 
 
 
194
 
195
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  }
js/chld-thm-cfg.js CHANGED
@@ -2,20 +2,16 @@
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.3.4
6
  * Author: Lilaea Media
7
  * Author URI: http://www.lilaeamedia.com/
8
  * License: GPLv2
9
  * Copyright (C) 2013 Lilaea Media
10
  */
11
- jQuery(document).ready(function($){
12
 
13
  var lf = "\n",
14
- currentQuery = 'base',
15
- currentSel,
16
- saveEvents = {},
17
- rewrite_id,
18
- rewrite_sel,
19
  // initialize functions
20
  ctc_setup_iris = function(obj) {
21
  $(obj).iris({
@@ -24,21 +20,13 @@ jQuery(document).ready(function($){
24
  }
25
  });
26
  },
27
- from_ascii = function(str) {
28
- var ascii = parseInt(str),
29
- chr = String.fromCharCode(ascii)
30
- return chr;
31
- },
32
- to_ascii = function(str) {
33
- var ascii = str.charCodeAt(0);
34
- return ascii;
35
- },
36
  ctc_coalesce_inputs = function(obj) {
37
- var regex = /^(ctc_(ovrd|\d+)_(parent|child)_([0-9a-z\-]+)_(\d+))(_\w+)?$/,
38
  $container = $(obj).parents('.ctc-selector-row, .ctc-parent-row').first(),
39
  $swatch = $container.find('.ctc-swatch').first(),
40
- cssrules = { 'parent': {}, 'child': {} },
41
- gradient = {
42
  'parent': {
43
  'origin': '',
44
  'start': '',
@@ -51,27 +39,21 @@ jQuery(document).ready(function($){
51
  }
52
  },
53
  has_gradient = { 'child': false, 'parent': false },
54
- postdata = {};
55
  // set up objects for all neighboring inputs
56
  $container.find('.ctc-parent-value, .ctc-child-value').each(function(){
57
  var inputid = $(this).attr('id'),
58
- inputparts = inputid.toString().match(regex),
59
- inputseq = inputparts[2],
60
  inputtheme = inputparts[3],
61
- inputrule = ('undefined' == typeof inputparts[4] ? '' : inputparts[4]),
62
- qsid = inputparts[5],
63
- rulepart = ('undefined' == typeof inputparts[6] ? '' : inputparts[6]),
64
  value = ('parent' == inputtheme ? $(this).text() : $(this).val()),
65
- important = 'ctc_' + inputseq + '_child_' + inputrule + '_i_' + qsid,
66
  parts, subparts;
67
  if ('child' == inputtheme) {
68
  postdata[inputid] = value;
69
- postdata[important] = ($('#' + important).is(':checked')) ? 1 : 0;
70
  }
71
- /*if ('' === value) {
72
- $('#'+important).prop('checked', false);
73
- return;
74
- }*/
75
  // handle specific inputs
76
  if (false === ctc_is_empty(rulepart)) {
77
  switch(rulepart) {
@@ -105,21 +87,21 @@ jQuery(document).ready(function($){
105
  }
106
  } else {
107
  // handle borders
108
- if (parts = inputrule.toString().match(/^border(\-(top|right|bottom|left))?$/) && !value.match(/none/)) {
109
- subparts = value.toString().split(/ +/);
110
- cssrules[inputtheme][inputrule + '-width'] = 'undefined' == typeof subparts[0] ? '' : subparts[0];
111
- cssrules[inputtheme][inputrule + '-style'] = 'undefined' == typeof subparts[1] ? '' : subparts[1];
112
- cssrules[inputtheme][inputrule + '-color'] = 'undefined' == typeof subparts[2] ? '' : subparts[2];
113
  // handle background images
114
  } else if ( 'background-image' == inputrule ) {
115
- if (value.toString().match(/url\(/)) {
116
  cssrules[inputtheme]['background-image'] = ctc_image_url(inputtheme, value);
117
  } else {
118
- subparts = value.toString().split(/ +/);
119
  if (subparts.length > 2) {
120
- gradient[inputtheme].origin = 'undefined' == typeof subparts[0] ? 'top' : subparts[0];
121
- gradient[inputtheme].start = 'undefined' == typeof subparts[1] ? 'transparent' : subparts[1];
122
- gradient[inputtheme].end = 'undefined' == typeof subparts[2] ? 'transparent' : subparts[2];
123
  has_gradient[inputtheme] = true;
124
  } else {
125
  cssrules[inputtheme]['background-image'] = value;
@@ -131,71 +113,91 @@ jQuery(document).ready(function($){
131
  }
132
  });
133
  // update swatch
134
- if ('undefined' != typeof $swatch && false === ctc_is_empty($swatch.attr('id'))) {
135
  $($swatch).removeAttr('style');
136
  if (has_gradient.parent) { $($swatch).ctcgrad(gradient.parent.origin, [gradient.parent.start, gradient.parent.end]); }
137
  $($swatch).css(cssrules.parent);
138
- if (!($swatch.attr('id').toString().match(/parent/))){
139
  if (has_gradient.child) { $($swatch).ctcgrad(gradient.child.origin, [gradient.child.start, gradient.child.end]); }
140
  $($swatch).css(cssrules.child);
141
  }
142
  }
143
  return postdata;
144
  },
145
- ctc_update_cache = function(response) {
146
- var currQuery, currSelId, currRuleId;
147
- $(response).each(function(){
148
- switch (this.obj) {
149
- case 'imports':
150
- ctcAjax.imports = this.data;
151
- break;
152
-
153
- case 'rule_val':
154
- ctcAjax.rule_val[this.key] = this.data;
155
- currRuleId = this.key;
156
- break;
157
-
158
- case 'val_qry':
159
- ctcAjax.val_qry[this.key] = this.data;
160
- break;
161
-
162
- case 'rule':
163
- ctcAjax.rule = this.data;
164
- break;
165
-
166
- case 'sel_ndx':
167
- if (ctc_is_empty(this.key)) {
168
- ctcAjax.sel_ndx = this.data;
169
- } else if ('qsid' == this.key) {
170
- if (ctc_is_empty(ctcAjax.sel_ndx[this.data.query])) {
171
- ctcAjax.sel_ndx[this.data.query] = {}
172
- }
173
- ctcAjax.sel_ndx[this.data.query][this.data.selector] = this.data.qsid;
174
- } else {
175
- ctcAjax.sel_ndx[this.key] = this.data;
176
- currQuery = this.key;
177
- }
178
- break;
179
-
180
- case 'sel_val':
181
- ctcAjax.sel_val[this.key] = this.data;
182
- currSelId = this.key;
183
- break;
184
- case 'rewrite':
185
- rewrite_id = this.key;
186
- rewrite_sel = this.data;
187
- break;
188
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  },
191
  ctc_image_url = function(theme, value) {
192
- var parts = value.toString().match(/url\(['" ]*(.+?)['" ]*\)/),
193
- path = ctc_is_empty(parts) ? null : parts[1],
194
- url = ctcAjax.theme_uri + '/' + ('parent' == theme ? ctcAjax.parnt : ctcAjax.child) + '/',
195
  image_url;
196
  if (!path) {
197
  return false;
198
- } else if (path.toString().match(/^(https?:|\/)/)) {
199
  image_url = value;
200
  } else {
201
  image_url = 'url(' + url + path + ')';
@@ -204,8 +206,8 @@ jQuery(document).ready(function($){
204
  },
205
 
206
  ctc_is_empty = function(obj) {
207
- // first bail when definitely empty or undefined (true) NOTE: zero is not empty
208
- if ('undefined' == typeof obj || false === obj || null === obj || '' === obj) { return true; }
209
  // then, if this is bool, string or number it must not be empty (false)
210
  if (true === obj || "string" === typeof obj || "number" === typeof obj) { return false; }
211
  // thanks to Abena Kuttin for Win safe version
@@ -231,16 +233,9 @@ jQuery(document).ready(function($){
231
 
232
  ctc_load_queries = function() {
233
  var arr = [];
234
- if (1 === loading.sel_ndx) return arr;
235
- if (0 === loading.sel_ndx) { // {
236
- // retrieve from server
237
- loading.sel_ndx = 1;
238
- ctc_query_css('sel_ndx', null, ctc_setup_query_menu);
239
- return arr;
240
- }
241
- if (false === ctc_is_empty(ctcAjax.sel_ndx)) {
242
  $.each(ctcAjax.sel_ndx, function(key, value) {
243
- var obj = { label: key, value: key };
244
  arr.push(obj);
245
  });
246
  }
@@ -249,18 +244,9 @@ jQuery(document).ready(function($){
249
 
250
  ctc_load_selectors = function(query) {
251
  var arr = [];
252
- if (1 === loading.sel_ndx) {
253
- return arr;
254
- }
255
- if (0 === loading.sel_ndx) {
256
- // retrieve from server
257
- loading.sel_ndx = 1;
258
- ctc_query_css('sel_ndx', query, ctc_setup_selector_menu);
259
- return arr;
260
- }
261
- if (false === ctc_is_empty(ctcAjax.sel_ndx[query])) {
262
  $.each(ctcAjax.sel_ndx[query], function(key, value) {
263
- var obj = { label: key, value: value };
264
  arr.push(obj);
265
  });
266
  }
@@ -268,276 +254,145 @@ jQuery(document).ready(function($){
268
  },
269
 
270
  ctc_load_rules = function() {
271
- var arr = [];
272
- if (1 === loading.rule) return arr;
273
- if (0 === loading.rule) {
274
- loading.rule = 1;
275
- ctc_query_css('rule', null, ctc_setup_rule_menu);
276
- return arr;
277
  }
278
- if (false === ctc_is_empty(ctcAjax.rule)) {
279
- $.each(ctcAjax.rule, function(key, value) {
280
- var obj = { label: value.replace(/\d+/g, from_ascii), value: key };
281
- arr.push(obj);
282
  });
283
  }
284
- return arr.sort(function (a, b) {
285
- if (a.label > b.label)
286
- return 1;
287
- if (a.label < b.label)
288
- return -1;
289
- return 0;
290
  });
 
 
 
 
 
 
291
  },
292
 
293
- ctc_render_child_rule_input = function(qsid, rule, seq) {
294
- var html = '',
295
- value = (ctc_is_empty(ctcAjax.sel_val[qsid])
296
- || ctc_is_empty(ctcAjax.sel_val[qsid].value)
297
- || ctc_is_empty(ctcAjax.sel_val[qsid].value[rule]) ? '' : ctcAjax.sel_val[qsid].value[rule]),
298
- oldRuleObj = ctc_decode_value(rule, ('undefined' == typeof value ? '' : value['parnt'])),
299
- oldRuleFlag = (false === ctc_is_empty(value['i_parnt']) && value['i_parnt']) ?
300
- ctcAjax.important_label : '',
301
- newRuleObj = ctc_decode_value(rule, ('undefined' == typeof value ? '' : value['child'])),
302
- newRuleFlag = (false === ctc_is_empty(value['i_child']) && value['i_child']) ? 1 : 0,
303
- impid = 'ctc_' + seq + '_child_' + rule + '_i_' + qsid;
304
- if (false === ctc_is_empty(ctcAjax.sel_val[qsid])) {
305
- html += '<div class="ctc-' + ('ovrd' == seq ? 'input' : 'selector' ) + '-row clearfix">' + lf;
306
- html += '<div class="ctc-input-cell">' + ('ovrd' == seq ? rule.replace(/\d+/g, from_ascii) : ctcAjax.sel_val[qsid].selector
307
- + '<br/><a href="#" class="ctc-selector-edit" id="ctc_selector_edit_' + qsid + '" >' + ctcAjax.edit_txt + '</a> '
308
- + (ctc_is_empty(oldRuleObj.orig) ? ctcAjax.child_only_txt : ''))
309
- + '</div>' + lf;
310
- if ('ovrd' == seq) {
311
- html += '<div class="ctc-parent-value ctc-input-cell" id="ctc_' + seq + '_parent_' + rule + '_' + qsid + '">'
312
- + (ctc_is_empty(oldRuleObj.orig) ? '[no value]' : oldRuleObj.orig + oldRuleFlag) + '</div>' + lf;
313
- }
314
- html += '<div class="ctc-input-cell">' + lf;
315
- if (false === ctc_is_empty(oldRuleObj.names)){
316
- $.each(oldRuleObj.names, function(ndx, newname) {
317
- newname = (ctc_is_empty(newname) ? '' : newname);
318
- html += '<div class="ctc-child-input-cell">' + lf;
319
- var id = 'ctc_' + seq + '_child_' + rule + '_' + qsid + newname,
320
- newval;
321
- if (false === (newval = newRuleObj.values.shift()) ){
322
- newval = '';
323
- }
324
 
325
- html += (ctc_is_empty(newname) ? '' : ctcAjax.field_labels[newname] + ':<br/>')
326
- + '<input type="text" id="' + id + '" name="' + id + '" class="ctc-child-value'
327
- + ((newname + rule).toString().match(/color/) ? ' color-picker' : '')
328
- + ((newname).toString().match(/url/) ? ' ctc-input-wide' : '')
329
- + '" value="' + newval + '" />' + lf;
330
- html += '</div>' + lf;
331
- });
332
- html += '<label for="' + impid + '"><input type="checkbox" id="' + impid + '" name="' + impid + '" value="1" '
333
- + (1 === newRuleFlag ? 'checked' : '') + ' />' + ctcAjax.important_label + '</label>' + lf;
334
- }
335
- html += '</div>' + lf;
336
- html += ('ovrd' == seq ? '' : '<div class="ctc-swatch ctc-specific" id="ctc_child_' + rule + '_' + qsid + '_swatch">'
337
- + ctcAjax.swatch_txt + '</div>' + lf
338
- + '<div class="ctc-child-input-cell ctc-button-cell" id="ctc_save_' + rule + '_' + qsid + '_cell">' + lf
339
- + '<input type="button" class="button ctc-save-input" id="ctc_save_' + rule + '_' + qsid
340
- + '" name="ctc_save_' + rule + '_' + qsid + '" value="Save" /></div>' + lf);
341
- html += '</div><!-- end input row -->' + lf;
342
  }
 
 
 
 
 
 
 
343
  return html;
344
  },
345
- ctc_render_selector_inputs = function(qsid) {
346
- if (1 === loading.sel_val) {
347
- return false;
348
- }
349
- if (0 == loading.sel_val) {
350
- loading.sel_val = 1;
351
- ctc_query_css('sel_val', qsid, ctc_render_selector_inputs);
352
- return false;
353
- }
354
- var id, html, val;
355
- if (ctc_is_empty(ctcAjax.sel_val[qsid])) {
356
- $('#ctc_sel_ovrd_rule_inputs').html('')
357
- } else {
358
- if (ctc_is_empty(ctcAjax.sel_val[qsid].seq)) {
359
- $('#ctc_child_load_order_container').html('');
360
- } else {
361
- id = 'ctc_ovrd_child_seq_' + qsid;
362
- val = parseInt(ctcAjax.sel_val[qsid].seq);
363
- html = '<input type="text" id="' + id + '" name="' + id + '" class="ctc-child-value" value="' + val + '" />';
364
- $('#ctc_child_load_order_container').html(html);
365
- }
366
- if (ctc_is_empty(ctcAjax.sel_val[qsid].value)){
367
- $('#ctc_sel_ovrd_rule_inputs').html('');
368
- } else {
369
- html = '';
370
- $.each(ctcAjax.sel_val[qsid].value, function(rule, value) {
371
- html += ctc_render_child_rule_input(qsid, rule, 'ovrd');
372
- });
373
- $('#ctc_sel_ovrd_rule_inputs').html(html).find('.color-picker').each(function() {
374
- ctc_setup_iris(this);
375
- });
376
- ctc_coalesce_inputs('#ctc_child_all_0_swatch');
377
- }
378
- }
379
- }
380
- ctc_render_css_preview = function(theme) {
381
- if (1 === loading.preview) {
382
- return false;
383
- }
384
- if (0 == loading.preview) {
385
- loading.preview = 1;
386
- var theme;
387
- if (!(theme = $(this).attr('id').toString().match(/(child|parnt)/)[1])) {
388
- theme = 'child';
389
- }
390
- ctc_set_notice('')
391
- ctc_query_css('preview', theme, ctc_render_css_preview);
392
- return false;
393
- }
394
- if (2 == loading.preview) {
395
- $('#view_'+theme+'_options_panel').text(ctcAjax.previewResponse);
396
- loading.preview = 0;
397
- }
398
- },
399
- ctc_render_rule_value_inputs = function(ruleid) {
400
- if (1 === loading.rule_val) return false;
401
-
402
- if (0 == loading.rule_val) {
403
- loading.rule_val = 1;
404
- ctc_query_css('rule_val', ruleid, ctc_render_rule_value_inputs);
405
- return false;
406
- }
407
- var rule = ctcAjax.rule[ruleid],
408
- html = '<div class="ctc-input-row clearfix" id="ctc_rule_row_' + rule + '">' + lf;
409
- if (false === ctc_is_empty(ctcAjax.rule_val[ruleid])){
410
- $.each(ctcAjax.rule_val[ruleid], function(valid, value) {
411
- var oldRuleObj = ctc_decode_value(rule, value);
412
- html += '<div class="ctc-parent-row clearfix" id="ctc_rule_row_' + rule + '_' + valid + '">' + lf;
413
- html += '<div class="ctc-input-cell ctc-parent-value" id="ctc_' + valid + '_parent_' + rule + '_' + valid + '">'
414
- + oldRuleObj.orig + '</div>' + lf;
415
- html += '<div class="ctc-input-cell">' + lf;
416
- html += '<div class="ctc-swatch ctc-specific" id="ctc_' + valid + '_parent_' + rule + '_' + valid + '_swatch">'
417
- + ctcAjax.swatch_txt + '</div></div>' + lf;
418
- html += '<div class="ctc-input-cell"><a href="#" class="ctc-selector-handle" id="ctc_selector_' + rule + '_' + valid + '">'
419
- + ctcAjax.selector_txt + '</a></div>' + lf;
420
- html += '<div id="ctc_selector_' + rule + '_' + valid + '_container" class="ctc-selector-container clearfix">' + lf;
421
- html += '<a href="#" id="ctc_selector_' + rule + '_' + valid + '_close" class="ctc-selector-handle" style="float:right">'
422
- + ctcAjax.close_txt + '</a><div id="ctc_status_val_qry_' + valid + '"></div>' + lf;
423
- html += '<div id="ctc_selector_' + rule + '_' + valid + '_rows"></div>' + lf;
424
- html += '</div></div>' + lf;
425
  });
426
- html += '</div>' + lf;
427
  }
428
- $('#ctc_rule_value_inputs').html(html).find('.ctc-swatch').each(function() {
429
- ctc_coalesce_inputs(this);
430
  });
431
- },
 
432
 
433
- ctc_render_selector_value_inputs = function(valid) {
434
- if (1 == loading.val_qry) return false;
435
- var params,
436
- page_ruleid,
437
- rule = $('#ctc_rule_menu_selected').text().replace(/[^\w\-]/g, to_ascii),
438
- selector,
439
- html = '';
440
- if (0 === loading.val_qry) {
441
- loading.val_qry = 1;
442
- params = { 'rule': rule };
443
- ctc_query_css('val_qry', valid, ctc_render_selector_value_inputs, params);
444
- return false;
445
- }
446
- if (false === ctc_is_empty(ctcAjax.val_qry[valid])){
447
- $.each(ctcAjax.val_qry[valid], function(rule, queries) {
448
- page_rule = rule;
449
- $.each(queries, function(query, selectors) {
450
- html += '<h4 class="ctc-query-heading">' + query + '</h4>' + lf;
451
- if (false === ctc_is_empty(selectors)){
452
- $.each(selectors, function(qsid, data) {
453
- ctcAjax.sel_val[qsid] = data;
454
- html += ctc_render_child_rule_input(qsid, rule, valid);
455
- });
456
- }
457
- });
 
 
 
458
  });
459
- }
460
- selector = '#ctc_selector_' + rule + '_' + valid + '_rows';
461
- $(selector).html(html).find('.color-picker').each(function() {
462
  ctc_setup_iris(this);
463
  });
464
- $(selector).find('.ctc-swatch').each(function() {
465
  ctc_coalesce_inputs(this);
466
  });
467
-
468
  },
469
- ctc_query_css = function(obj, key, callback, params) {
470
- var postdata = { 'ctc_query_obj' : obj, 'ctc_query_key': key },
471
- status_sel = '#ctc_status_' + obj + ('val_qry' == obj ? '_' + key : '');
472
-
473
- if ('object' === typeof params) {
474
- $.each(params, function(key, val){
475
- postdata['ctc_query_' + key] = val;
 
 
 
 
 
 
 
476
  });
477
  }
478
- $('.ctc-status-icon').remove();
479
- $(status_sel).append('<span class="ctc-status-icon spinner"></span>');
480
- $('.spinner').show();
481
- // add wp ajax action to array
482
- postdata['action'] = 'ctc_query';
483
- postdata['_wpnonce'] = $('#_wpnonce').val();
484
- // ajax post input data
485
- $.post(
486
- // get ajax url from localized object
487
- ctcAjax.ajaxurl,
488
- //Data
489
- postdata,
490
- //on success function
491
- function(response){
492
- // console.log(response);
493
- // hide spinner
494
- loading[obj] = 2;
495
- $('.ctc-status-icon').removeClass('spinner');
496
- // show check mark
497
- if (ctc_is_empty(response)) {
498
- $('.ctc-status-icon').addClass('failure');
499
- if ('preview' == obj) {
500
- ctcAjax.previewResponse = ctcAjax.css_fail_txt;
501
- callback(key);
502
- }
503
- } else {
504
- $('.ctc-status-icon').addClass('success');
505
- if ('preview' == obj) {
506
- ctcAjax.previewResponse = response.shift().data;
507
- } else {
508
- // update data objects
509
- ctc_update_cache(response);
510
- }
511
- if ('function' === typeof callback) {
512
- callback(key);
513
- }
514
- return false;
515
- }
516
- },'json'
517
- ).fail(function(){
518
- // hide spinner
519
- $('.ctc-status-icon').removeClass('spinner');
520
- // show check mark
521
- $('.ctc-status-icon').addClass('failure');
522
- if ('preview' == obj) {
523
- ctcAjax.previewResponse = ctcAjax.css_fail_txt;
524
- loading[obj] = 2;
525
- callback(key);
526
- } else {
527
- loading[obj] = 0;
528
- }
529
-
530
- });
531
- return false;
532
  },
 
533
  ctc_save = function(obj) {
534
  var postdata = {},
535
- $selector, $query, $imports, $rule,
536
- id = $(obj).attr('id'), newsel;
537
- if (ctc_is_empty(saveEvents[id])) {
538
- saveEvents[id] = 0;
539
- }
540
- saveEvents[id]++;
541
  // disable the button until ajax returns
542
  $(obj).prop('disabled', true);
543
  // clear previous success/fail icons
@@ -556,18 +411,6 @@ jQuery(document).ready(function($){
556
  // coalesce inputs
557
  postdata = ctc_coalesce_inputs(obj);
558
  }
559
- // add rename selector value if it exists
560
- $('#ctc_sel_ovrd_selector_selected').find('#ctc_rewrite_selector').each(function(){
561
- newsel = $('#ctc_rewrite_selector').val(),
562
- origsel = $('#ctc_rewrite_selector_orig').val();
563
- if (ctc_is_empty(newsel) || !newsel.toString().match(/\w/)) {
564
- newsel = origsel;
565
- } else {
566
- postdata['ctc_rewrite_selector'] = newsel;
567
- }
568
- $('.ctc-rewrite-toggle').text(ctcAjax.rename_txt);
569
- $('#ctc_sel_ovrd_selector_selected').html(newsel);
570
- });
571
  // add wp ajax action to array
572
  postdata['action'] = 'ctc_update';
573
  postdata['_wpnonce'] = $('#_wpnonce').val();
@@ -579,7 +422,6 @@ jQuery(document).ready(function($){
579
  postdata,
580
  //on success function
581
  function(response){
582
- // console.log(response);
583
  // release button
584
  $(obj).prop('disabled', false);
585
  // hide spinner
@@ -591,15 +433,11 @@ jQuery(document).ready(function($){
591
  $('.ctc-status-icon').addClass('success');
592
  $('#ctc_new_selectors').val('');
593
  // update data objects
594
- ctc_update_cache(response);
595
- ctc_setup_menus();
596
- if (false === ctc_is_empty(rewrite_id)) {
597
- ctc_set_selector(rewrite_id, rewrite_sel);
598
- rewrite_id = rewrite_sel = null;
599
- }
600
  }
601
  return false;
602
- }, 'json'
 
603
  ).fail(function(){
604
  // release button
605
  $(obj).prop('disabled', false);
@@ -610,22 +448,38 @@ jQuery(document).ready(function($){
610
  });
611
  return false;
612
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
613
  ctc_decode_value = function(rule, value) {
614
- value = ('undefined' == typeof value ? '' : value);
615
  var obj = { 'orig': value };
616
- if (rule.toString().match(/^border(\-(top|right|bottom|left))?$/)) {
617
- var params = value.toString().split(/ +/);
618
  obj['names'] = [
619
  '_border_width',
620
  '_border_style',
621
  '_border_color',
622
  ];
623
  obj['values'] = [
624
- ('undefined' == typeof params[0] ? '' : params[0]),
625
- ('undefined' == typeof params[1] ? '' : params[1]),
626
- ('undefined' == typeof params[2] ? '' : params[2])
627
  ];
628
- } else if (rule.toString().match(/^background\-image/)) {
629
  obj['names'] = [
630
  '_background_url',
631
  '_background_origin',
@@ -633,11 +487,11 @@ jQuery(document).ready(function($){
633
  '_background_color2'
634
  ];
635
  obj['values'] = ['','','',''];
636
- if (false === (ctc_is_empty(value)) && !(value.toString().match(/url/))) {
637
- var params = value.toString().split(/:/);
638
- obj['values'][1] = ('undefined' == typeof params[0] ? '' : params[0]);
639
- obj['values'][2] = ('undefined' == typeof params[1] ? '' : params[1]);
640
- obj['values'][3] = ('undefined' == typeof params[3] ? '' : params[3]);
641
  obj['orig'] = [ obj['values'][1], obj['values'][2], obj['values'][3] ].join(' '); // display "origin color1 color2"
642
  } else {
643
  obj['values'][0] = value;
@@ -649,303 +503,129 @@ jQuery(document).ready(function($){
649
  return obj;
650
  },
651
 
652
- ctc_set_query = function(value) {
653
- currentQuery = value;
654
  $('#ctc_sel_ovrd_query').val('');
655
- $('#ctc_sel_ovrd_query_selected').text(value);
656
- $('#ctc_sel_ovrd_selector').val('');
657
- $('#ctc_sel_ovrd_selector_selected').html('&nbsp;');
658
- $('#ctc_sel_ovrd_rule_inputs').html('');
659
- ctc_setup_selector_menu(value);
660
- ctc_coalesce_inputs('#ctc_child_all_0_swatch');
661
  $('#ctc_new_selector_row').show();
662
  },
663
 
664
  ctc_set_selector = function(value,label) {
665
  $('#ctc_sel_ovrd_selector').val('');
666
  $('#ctc_sel_ovrd_selector_selected').text(label);
667
- $('#ctc_sel_ovrd_qsid').val(value);
668
- currentSel = value;
669
- if (1 != loading.sel_val) loading.sel_val = 0;
670
  ctc_render_selector_inputs(value);
671
- $('.ctc-rewrite-toggle').text(ctcAjax.rename_txt);
672
- $('#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();
673
  },
674
 
675
  ctc_set_rule = function(value,label) {
676
  $('#ctc_rule_menu').val('');
677
  $('#ctc_rule_menu_selected').text(label);
678
- if (1 != loading.rule_val) loading.rule_val = 0;
679
  ctc_render_rule_value_inputs(value);
680
- $('.ctc-rewrite-toggle').text(ctcAjax.rename_txt);
681
  $('#ctc_rule_value_inputs,#ctc_input_row_rule_header').show();
682
  },
683
- ctc_setup_query_menu = function() {
684
- ctc_queries = ctc_load_queries();
685
- $('#ctc_sel_ovrd_query').autocomplete({
686
- source: ctc_queries,
687
- minLength: 0,
688
- selectFirst: true,
689
- autoFocus: true,
690
- select: function(e, ui) {
691
- ctc_set_query(ui.item.value);
692
- return false;
693
- },
694
- focus: function(e) { e.preventDefault(); }
695
- });
696
- },
697
- ctc_setup_selector_menu = function(query) {
698
- ctc_selectors = ctc_load_selectors(query);
699
- $('#ctc_sel_ovrd_selector').autocomplete({
700
- source: ctc_selectors,
701
- selectFirst: true,
702
- autoFocus: true,
703
- select: function(e, ui) {
704
- ctc_set_selector(ui.item.value, ui.item.label);
705
- return false;
706
- },
707
- focus: function(e) { e.preventDefault(); }
708
- });
709
- },
710
- ctc_setup_rule_menu = function() {
711
- ctc_rules = ctc_load_rules();
712
- $('#ctc_rule_menu').autocomplete({
713
- source: ctc_rules,
714
- //minLength: 0,
715
- selectFirst: true,
716
- autoFocus: true,
717
- select: function(e, ui) {
718
- ctc_set_rule(ui.item.value, ui.item.label);
719
- return false;
720
- },
721
- focus: function(e) { e.preventDefault(); }
722
- });
723
- },
724
- ctc_filtered_rules = function(request, response) {
725
- var arr = [],
726
- noval = (ctc_is_empty(ctcAjax.sel_val[currentSel])) || (ctc_is_empty(ctcAjax.sel_val[currentSel].value));
727
- if (ctc_is_empty(ctc_rules)) {
728
- ctc_rules = ctc_load_rules();
729
- }
730
- $.each(ctc_rules, function(key, val){
731
- var skip = false,
732
- matcher = new RegExp( $.ui.autocomplete.escapeRegex( request.term ), "i" );
733
- if (matcher.test( val.label )) {
734
- if (false === noval) {
735
- // skip rule if in current selector array
736
- $.each(ctcAjax.sel_val[currentSel].value, function(rule, value) {
737
- if (val.label == rule.replace(/\d+/g, from_ascii)) {
738
- skip = true;
739
- return false;
740
- }
741
- });
742
- if (skip) {
743
- return;
744
- }
745
- }
746
- // add rule
747
- arr.push(val);
748
- }
749
- });
750
- response(arr);
751
- },
752
- ctc_setup_new_rule_menu = function() {
753
- $('#ctc_new_rule_menu').autocomplete({
754
- source: ctc_filtered_rules,
755
- //minLength: 0,
756
- selectFirst: true,
757
- autoFocus: true,
758
- select: function(e, ui) {
759
- e.preventDefault();
760
- var n = $(ctc_render_child_rule_input(currentSel, ui.item.label.replace(/[^\w\-]/g, to_ascii), 'ovrd'));
761
- $('#ctc_sel_ovrd_rule_inputs').append(n);
762
- $('#ctc_new_rule_menu').val('');
763
- if (ctc_is_empty(ctcAjax.sel_val[currentSel].value)) {
764
- ctcAjax.sel_val[currentSel]['value'] = {};
765
- }
766
- ctcAjax.sel_val[currentSel].value[ui.item.label] = {'child': ''};
767
- n.find('input[type="text"]').each(function(ndx, el){
768
- if ($(el).hasClass('color-picker'))
769
- ctc_setup_iris(el);
770
- $(el).focus();
771
- });
772
- return false;
773
- },
774
- focus: function(e) { e.preventDefault(); }
775
- });
776
- },
777
- ctc_setup_menus = function() {
778
- ctc_setup_query_menu();
779
- ctc_setup_selector_menu(currentQuery);
780
- ctc_setup_rule_menu();
781
- ctc_setup_new_rule_menu();
782
- },
783
- ctc_theme_exists = function(testslug, testtype) {
784
- var exists = false;
785
- $.each(ctcAjax.themes, function(type, theme){
786
- $.each(theme, function(slug, data){
787
- if (slug == testslug && ('parnt' == type || 'new' == testtype)) {
788
- exists = true;
789
- return false;
790
- }
791
- });
792
- if (exists) return false;
793
- });
794
- return exists;
795
- },
796
-
797
- ctc_set_notice = function(noticearr) {
798
- var errorHtml = '';
799
- if (false === ctc_is_empty(noticearr)) {
800
- $.each(noticearr, function(type, list){
801
- errorHtml += '<div class="' + type + '"><ul>' + lf;
802
- $(list).each(function(ndx, el){
803
- errorHtml += '<li>' + el.toString() + '</li>' + lf;
804
- });
805
- errorHtml += '</ul></div>';
806
- });
807
- }
808
- $('#ctc_error_notice').html(errorHtml);
809
- },
810
- ctc_validate = function() {
811
- var regex = /[^\w\-]/,
812
- newslug = $('#ctc_child_template').val().toString().replace(regex).toLowerCase(),
813
- slug = $('#ctc_theme_child').val().toString().replace(regex).toLowerCase(),
814
- type = $('input[name=ctc_child_type]:checked').val(),
815
- errors = [];
816
- if ('new' == type) slug = newslug;
817
- if (ctc_theme_exists(slug, type)) {
818
- errors.push(ctcAjax.theme_exists_txt.toString().replace(/%s/, slug));
819
- }
820
- if ('' === slug) {
821
- errors.push(ctcAjax.inval_theme_txt);
822
- }
823
- if ('' === $('#ctc_child_name').val()) {
824
- errors.push(ctcAjax.inval_name_txt);
825
- }
826
- if (errors.length) {
827
- ctc_set_notice({'error': errors});
828
- return false;
829
- }
830
- return true;
831
- },
832
- ctc_set_theme_menu = function(e) {
833
- var slug = $('#ctc_theme_child').val();
834
- if (false === ctc_is_empty(ctcAjax.themes.child[slug])) {
835
- $('#ctc_child_name').val(ctcAjax.themes.child[slug].Name);
836
- $('#ctc_child_author').val(ctcAjax.themes.child[slug].Author);
837
- $('#ctc_child_version').val(ctcAjax.themes.child[slug].Version);
838
- }
839
- },
840
- fade_update_notice = function() {
841
- $('.updated, .error').slideUp('slow', function(){ $('.updated').remove(); });
842
- },
843
- ctc_focus_panel = function(id) {
844
- var panelid = id + '_panel';
845
- $('.nav-tab').removeClass('nav-tab-active');
846
- $('.ctc-option-panel').removeClass('ctc-option-panel-active');
847
- $('.ctc-selector-container').hide();
848
- $(id).addClass('nav-tab-active');
849
- $('.ctc-option-panel-container').scrollTop(0);
850
- $(panelid).addClass('ctc-option-panel-active');
851
- },
852
- ctc_selector_edit = function(obj) {
853
- var qsid = $(obj).attr('id').match(/_(\d+)$/)[1],
854
- q = ctcAjax.sel_val[qsid].query,
855
- s = ctcAjax.sel_val[qsid].selector,
856
- id = '#query_selector_options';
857
- ctc_set_query(q);
858
- ctc_set_selector(qsid, s);
859
- ctc_focus_panel(id);
860
- },
861
- ctc_selector_input_toggle = function(obj) {
862
- var origval;
863
- if ($('#ctc_rewrite_selector').length) {
864
- origval = $('#ctc_rewrite_selector_orig').val();
865
- $('#ctc_sel_ovrd_selector_selected').text(origval);
866
- $(obj).text(ctcAjax.rename_txt);
867
- } else {
868
- origval = $('#ctc_sel_ovrd_selector_selected').text();
869
- $('#ctc_sel_ovrd_selector_selected').html('<input id="ctc_rewrite_selector" name="ctc_rewrite_selector" type="text" value="'
870
- + origval + '" autocomplete="off" /><input id="ctc_rewrite_selector_orig" name="ctc_rewrite_selector_orig" type="hidden" value="'
871
- + origval + '"/>');
872
- $(obj).text(ctcAjax.cancel_txt);
873
- }
874
- }
875
  // initialize vars
876
- // ajax semaphores: 0 = reload, 1 = loading, 2 = loaded
877
- loading = {
878
- 'rule': 2,
879
- 'sel_ndx': 2,
880
- 'val_qry': 0,
881
- 'rule_val': 0,
882
- 'sel_val': 0,
883
- 'preview': 0
884
- },
885
-
886
- ctc_selectors = [],
887
- ctc_queries = [],
888
- ctc_rules = [];
889
- // -- end var definitions
890
-
891
- // initialize Iris color picker
892
  $('.color-picker').each(function() {
893
  ctc_setup_iris(this);
894
  });
895
- // bind event handlers
896
  $('.ctc-option-panel-container').on('focus', '.color-picker', function(){
897
- ctc_set_notice('')
898
  $(this).iris('toggle');
899
  $('.iris-picker').css({'position':'absolute', 'z-index':10});
900
  });
901
  $('.ctc-option-panel-container').on('focus', 'input', function() {
902
- ctc_set_notice('')
903
  $('.color-picker').not(this).iris('hide');
904
  });
905
- $('.ctc-option-panel-container').on('change', '.ctc-child-value, input[type=checkbox]', function() {
906
  ctc_coalesce_inputs(this);
907
  });
908
  $('.ctc-option-panel-container').on('click', '.ctc-selector-handle', function(e) {
909
  e.preventDefault();
910
- ctc_set_notice('')
911
- var id = $(this).attr('id').toString().replace('_close', ''),
912
- valid = id.toString().match(/_(\d+)$/)[1];
913
- if ($('#' + id + '_container').is(':hidden')) {
914
- if (1 != loading.val_qry) loading.val_qry = 0;
915
- ctc_render_selector_value_inputs(valid);
916
- }
917
  $('#' + id + '_container').fadeToggle('fast');
918
  $('.ctc-selector-container').not('#' + id + '_container').fadeOut('fast');
919
  });
920
  $('.nav-tab').on('click', function(e){
921
  e.preventDefault();
922
- // clear the notice box
923
- ctc_set_notice('');
924
- $('.ctc-status-icon').remove();
925
- var id = '#' + $(this).attr('id');
926
- ctc_focus_panel(id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
927
  });
928
- $('#view_child_options,#view_parnt_options').on('click', ctc_render_css_preview);
929
- $('#ctc_load_form').on('submit', function() {
930
- return (ctc_validate() && confirm(ctcAjax.load_txt) ) ;
931
  });
932
- $('#parent_child_options_panel').on('change', '#ctc_theme_child', ctc_set_theme_menu );
933
  $(document).on('click', '.ctc-save-input', function(e) {
934
  ctc_save(this);
935
  });
936
- $(document).on('click', '.ctc-selector-edit', function(e) {
937
- ctc_selector_edit(this);
 
 
 
 
 
 
 
 
938
  });
939
- $(document).on('click', '.ctc-rewrite-toggle', function(e) {
940
- e.preventDefault();
941
- ctc_selector_input_toggle(this);
942
- });//ctc_rewrite_toggle
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
943
 
944
- // initialize menus
945
- ctc_setup_menus();
946
- ctc_set_query(currentQuery);
947
- $('input[type=submit],input[type=button]').prop('disabled', false);
948
- setTimeout(fade_update_notice, 6000);
949
- });
950
-
951
-
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.0
6
  * Author: Lilaea Media
7
  * Author URI: http://www.lilaeamedia.com/
8
  * License: GPLv2
9
  * Copyright (C) 2013 Lilaea Media
10
  */
11
+ (function($){
12
 
13
  var lf = "\n",
14
+
 
 
 
 
15
  // initialize functions
16
  ctc_setup_iris = function(obj) {
17
  $(obj).iris({
20
  }
21
  });
22
  },
23
+
 
 
 
 
 
 
 
 
24
  ctc_coalesce_inputs = function(obj) {
25
+ var regex = /^(ctc_(ovrd_)?(parent|child)_([a-z\-]+)_(\d+))(_\w+)?$/,
26
  $container = $(obj).parents('.ctc-selector-row, .ctc-parent-row').first(),
27
  $swatch = $container.find('.ctc-swatch').first(),
28
+ cssrules = { 'parent': {}, 'child': {} },
29
+ gradient = {
30
  'parent': {
31
  'origin': '',
32
  'start': '',
39
  }
40
  },
41
  has_gradient = { 'child': false, 'parent': false },
42
+ postdata = {};
43
  // set up objects for all neighboring inputs
44
  $container.find('.ctc-parent-value, .ctc-child-value').each(function(){
45
  var inputid = $(this).attr('id'),
46
+ inputparts = inputid.match(regex),
 
47
  inputtheme = inputparts[3],
48
+ inputrule = (undefined == inputparts[4] ? '' : inputparts[4]),
49
+ selnum = inputparts[5],
50
+ rulepart = (undefined == inputparts[6] ? '' : inputparts[6]),
51
  value = ('parent' == inputtheme ? $(this).text() : $(this).val()),
 
52
  parts, subparts;
53
  if ('child' == inputtheme) {
54
  postdata[inputid] = value;
 
55
  }
56
+ if (ctc_is_empty(value)) return;
 
 
 
57
  // handle specific inputs
58
  if (false === ctc_is_empty(rulepart)) {
59
  switch(rulepart) {
87
  }
88
  } else {
89
  // handle borders
90
+ if (parts = inputrule.match(/^border(\-(top|right|bottom|left))?$/) && !value.match(/none/)) {
91
+ subparts = value.split(/ +/);
92
+ cssrules[inputtheme][inputrule + '-width'] = undefined == subparts[0] ? '' : subparts[0];
93
+ cssrules[inputtheme][inputrule + '-style'] = undefined == subparts[1] ? '' : subparts[1];
94
+ cssrules[inputtheme][inputrule + '-color'] = undefined == subparts[2] ? '' : subparts[2];
95
  // handle background images
96
  } else if ( 'background-image' == inputrule ) {
97
+ if (value.match(/url\(/)) {
98
  cssrules[inputtheme]['background-image'] = ctc_image_url(inputtheme, value);
99
  } else {
100
+ subparts = value.split(/ +/);
101
  if (subparts.length > 2) {
102
+ gradient[inputtheme].origin = undefined == subparts[0] ? 'top' : subparts[0];
103
+ gradient[inputtheme].start = undefined == subparts[1] ? 'transparent' : subparts[1];
104
+ gradient[inputtheme].end = undefined == subparts[2] ? 'transparent' : subparts[2];
105
  has_gradient[inputtheme] = true;
106
  } else {
107
  cssrules[inputtheme]['background-image'] = value;
113
  }
114
  });
115
  // update swatch
116
+ if (undefined != $swatch) {
117
  $($swatch).removeAttr('style');
118
  if (has_gradient.parent) { $($swatch).ctcgrad(gradient.parent.origin, [gradient.parent.start, gradient.parent.end]); }
119
  $($swatch).css(cssrules.parent);
120
+ if (!($swatch.attr('id').match(/parent/))){
121
  if (has_gradient.child) { $($swatch).ctcgrad(gradient.child.origin, [gradient.child.start, gradient.child.end]); }
122
  $($swatch).css(cssrules.child);
123
  }
124
  }
125
  return postdata;
126
  },
127
+ ctc_apply_updates = function(obj) {
128
+ var currQuery, currSelnum, currRule;
129
+ if (undefined != obj.imports) {
130
+ ctcAjax.imports[ctcAjax.child_theme] = obj.imports;
131
+ }
132
+ $(obj.del).each(function(){
133
+ if (undefined != this.selnum) {
134
+ delete ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value][this.query][this.selnum];
135
+ } else if (undefined != this.query) {
136
+ delete ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value][this.query];
137
+ } else if (undefined != this.value) {
138
+ delete ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value];
139
+ } else if (undefined != this.rule) {
140
+ delete ctcAjax.val_ndx[ctcAjax.child_theme][this.rule];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  }
142
+ if (undefined != this.query) currQuery = this.query;
143
+ if (undefined != this.selnum) currSelnum = this.selnum;
144
+ if (undefined != this.rule) currRule = this.rule;
145
+ });
146
+ $(obj.insert).each(function(){
147
+ ctcAjax.sel_ndx[this.query][this.selector] = this.selnum;
148
+ ctcAjax.data[this.selnum] = {
149
+ 'selector': this.selector,
150
+ 'query': this.query,
151
+ 'value': {}
152
+ };
153
+ if (undefined != this.query) currQuery = this.query;
154
+ if (undefined != this.selnum) currSelnum = this.selnum;
155
+ if (undefined != this.rule) currRule = this.rule;
156
  });
157
+ $(obj.update).each(function(){
158
+ if (undefined == ctcAjax.val_ndx[ctcAjax.child_theme]) {
159
+ ctcAjax.val_ndx[ctcAjax.child_theme] = {};
160
+ }
161
+ if (undefined == ctcAjax.val_ndx[ctcAjax.child_theme][this.rule]) {
162
+ ctcAjax.val_ndx[ctcAjax.child_theme][this.rule] = {};
163
+ }
164
+ if (this.value && undefined == ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value]) {
165
+ ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value] = {};
166
+ }
167
+ if (this.value && undefined == ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value][this.query]) {
168
+ ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value][this.query] = {};
169
+ }
170
+ if (this.value && undefined == ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value][this.query][this.selnum]) {
171
+ ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value][this.query][this.selnum] = 0;
172
+ }
173
+ if (this.rule && undefined == ctcAjax.data[this.selnum].value[this.rule]) {
174
+ ctcAjax.data[this.selnum].value[this.rule] = {};
175
+ //ctcAjax.val_ndx[ctcAjax.child_theme][this.rule] = {};
176
+ }
177
+ ctcAjax.data[this.selnum].value[this.rule][ctcAjax.child_theme] = this.value + (this.important > 0 ? ' !important':'');
178
+ if (undefined != this.query) currQuery = this.query;
179
+ if (undefined != this.selnum) currSelnum = this.selnum;
180
+ if (undefined != this.rule) currRule = this.rule;
181
+ });
182
+ // refresh page with new values if available
183
+ if (currQuery) {
184
+ ctc_set_query(currQuery, currQuery);
185
+ }
186
+ if (currSelnum) {
187
+ ctc_set_selector(currSelnum, ctcAjax.data[currSelnum].selector);
188
+ }
189
+ if (currRule) {
190
+ ctc_set_rule(currRule, currRule);
191
+ }
192
  },
193
  ctc_image_url = function(theme, value) {
194
+ var parts = value.match(/url\([" ]*(.+?)[" ]*\)/),
195
+ path = (undefined == parts ? null : parts[1]),
196
+ url = ctcAjax.theme_uri + '/' + ('parent' == theme ? ctcAjax.parent_theme : ctcAjax.child_theme) + '/',
197
  image_url;
198
  if (!path) {
199
  return false;
200
+ } else if (path.match(/^(http:|\/)/)) {
201
  image_url = value;
202
  } else {
203
  image_url = 'url(' + url + path + ')';
206
  },
207
 
208
  ctc_is_empty = function(obj) {
209
+ // first bail when definitely empty or undefined (true)
210
+ if (undefined == obj || false === obj || null === obj || '' === obj || 0 === obj) { return true; }
211
  // then, if this is bool, string or number it must not be empty (false)
212
  if (true === obj || "string" === typeof obj || "number" === typeof obj) { return false; }
213
  // thanks to Abena Kuttin for Win safe version
233
 
234
  ctc_load_queries = function() {
235
  var arr = [];
236
+ if (false === ctc_is_empty(ctcAjax.sel_ndx)){
 
 
 
 
 
 
 
237
  $.each(ctcAjax.sel_ndx, function(key, value) {
238
+ obj = { label: key, value: key };
239
  arr.push(obj);
240
  });
241
  }
244
 
245
  ctc_load_selectors = function(query) {
246
  var arr = [];
247
+ if (false === ctc_is_empty(ctcAjax.sel_ndx[query])){
 
 
 
 
 
 
 
 
 
248
  $.each(ctcAjax.sel_ndx[query], function(key, value) {
249
+ obj = { label: key, value: value };
250
  arr.push(obj);
251
  });
252
  }
254
  },
255
 
256
  ctc_load_rules = function() {
257
+ var obj = {},
258
+ arr = [];
259
+ if (false === ctc_is_empty(ctcAjax.val_ndx[ctcAjax.parent_theme])) {
260
+ $.each(ctcAjax.val_ndx[ctcAjax.parent_theme], function(key, value) {
261
+ obj[key]++;
262
+ });
263
  }
264
+ if (false === ctc_is_empty(ctcAjax.val_ndx[ctcAjax.child_theme])) {
265
+ $.each(ctcAjax.val_ndx[ctcAjax.child_theme], function(key, value) {
266
+ obj[key]++;
 
267
  });
268
  }
269
+ $.each(['border-width', 'border-style', 'border-color', 'padding', 'margin', 'background', 'font'], function() {
270
+ obj[this]++;
 
 
 
 
271
  });
272
+ if (false === ctc_is_empty(obj)){
273
+ $.each(obj, function(key, value) {
274
+ arr.push(key);
275
+ });
276
+ }
277
+ return arr.sort();
278
  },
279
 
280
+ ctc_render_child_rule_input = function(selnum, rule, specific) {
281
+ var html = '',
282
+ value = (undefined == ctcAjax.data[selnum].value || undefined == ctcAjax.data[selnum].value[rule] ? '' : ctcAjax.data[selnum].value[rule]),
283
+ oldRuleObj = ctc_decode_value(rule, (undefined == value ? '' : value[ctcAjax.parent_theme])),
284
+ newRuleObj = ctc_decode_value(rule, (undefined == value ? '' : value[ctcAjax.child_theme]));
285
+ if (value) {
286
+ unique_rule_value[rule + '%%' + value[ctcAjax.parent_theme]] = 1;
287
+ unique_rule_value[rule + '%%' + value[ctcAjax.child_theme]] = 1;
288
+ }
289
+ html += '<div class="ctc-' + (specific ? 'selector' : 'input' ) + '-row clearfix">' + lf;
290
+ html += '<div class="ctc-input-cell">' + (specific ? ctcAjax.data[selnum].selector : rule) + '</div>' + lf;
291
+ html += '<div class="ctc-parent-value' + (specific ? ' ctc-hidden' : ' ctc-input-cell') +'" id="ctc_parent_' + rule + '_' + selnum + '">'
292
+ + (ctc_is_empty(oldRuleObj.orig) ? '[no value]' : oldRuleObj.orig) + '</div>' + lf;
293
+ html += '<div class="ctc-input-cell">' + lf;
294
+ if (false === ctc_is_empty(oldRuleObj.names)){
295
+ $.each(oldRuleObj.names, function(ndx, newname) {
296
+ newname = (ctc_is_empty(newname) ? '' : newname);
297
+ html += '<div class="ctc-child-input-cell">' + lf;
298
+ var id = 'ctc_' + (specific? '' : 'ovrd_') + 'child_' + rule + '_' + selnum + newname,
299
+ newval;
300
+ if (!(newval = newRuleObj.values.shift()) ){
301
+ newval = '';
302
+ }
 
 
 
 
 
 
 
 
303
 
304
+ html += (ctc_is_empty(newname) ? '' : ctcAjax.labels[newname] + ':<br/>')
305
+ + '<input type="text" id="' + id + '" name="' + id + '" class="ctc-child-value'
306
+ + ((newname + rule).match(/color/) ? ' color-picker' : '')
307
+ + ((newname).match(/url/) ? ' ctc-input-wide' : '')
308
+ + '" value="' + newval + '" />' + lf;
309
+ html += '</div>' + lf;
310
+ });
 
 
 
 
 
 
 
 
 
 
311
  }
312
+ html += '</div>' + lf;
313
+ html += (specific ? '<div class="ctc-swatch ctc-specific" id="ctc_child_' + rule + '_' + selnum + '_swatch">'
314
+ + ctcAjax.swatch_text + '</div>' + lf
315
+ + '<div class="ctc-child-input-cell ctc-button-cell" id="ctc_save_' + rule + '_' + selnum + '_cell">' + lf
316
+ + '<input type="button" class="button ctc-save-input" id="ctc_save_' + rule + '_' + selnum
317
+ + '" name="ctc_save_' + rule + '_' + selnum + '" value="Save" /></div>' + lf : '');
318
+ html += '</div><!-- end input row -->' + lf;
319
  return html;
320
  },
321
+
322
+ ctc_render_selector_inputs = function(selnum) {
323
+ if (undefined == ctcAjax.data[selnum].value) return;
324
+ var html = '', counter = 0;
325
+ if (false === ctc_is_empty(ctcAjax.data[selnum].value)){
326
+ $.each(ctcAjax.data[selnum].value, function(rule, value) {
327
+ html += ctc_render_child_rule_input(selnum, rule, false);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
  });
 
329
  }
330
+ $('#ctc_sel_ovrd_rule_inputs').html(html).find('.color-picker').each(function() {
331
+ ctc_setup_iris(this);
332
  });
333
+ ctc_coalesce_inputs('#ctc_child_all_0_swatch');
334
+ }
335
 
336
+ ctc_render_rule_value_inputs = function(rule) {
337
+ var html = '<div class="ctc-input-row clearfix" id="ctc_rule_row_' + rule + '">' + lf,
338
+ valID = 0,
339
+ themes = {parent: ctcAjax.parent_theme, child: ctcAjax.child_theme};
340
+ unique_rule_value = {},
341
+
342
+ $.each(themes, function(ndx, theme) {
343
+ if (ctc_is_empty(ctcAjax.val_ndx[theme]) || undefined == ctcAjax.val_ndx[theme][rule]) return;
344
+ $.each(ctcAjax.val_ndx[theme][rule], function(value, sel) {
345
+ if (unique_rule_value[rule + '%%' + value]) {
346
+ return;
347
+ } else {
348
+ valID++;
349
+ oldRuleObj = ctc_decode_value(rule, value),
350
+ html += '<div class="ctc-parent-row clearfix" id="ctc_rule_row_' + rule + '_' + valID + '">' + lf;
351
+ html += '<div class="ctc-input-cell ctc-parent-value" id="ctc_parent_' + rule + '_' + valID + '">'
352
+ + oldRuleObj.orig + '</div>' + lf;
353
+ html += '<div class="ctc-input-cell">' + lf;
354
+ html += '<div class="ctc-swatch ctc-specific" id="ctc_parent_'+rule+'_' + valID + '_swatch">'
355
+ + ctcAjax.swatch_text + '</div></div>' + lf;
356
+ html += '<div class="ctc-input-cell"><a href="#" class="ctc-selector-handle" id="ctc_selector_' + rule + '_' + valID + '">'
357
+ + ctcAjax.selector_text + '</a></div>' + lf;
358
+ html += '<div id="ctc_selector_' + rule + '_' + valID + '_container" class="ctc-selector-container clearfix">' + lf;
359
+ html += '<a href="#" id="ctc_selector_' + rule + '_' + valID + '_close" class="ctc-selector-handle" style="float:right">'
360
+ + ctcAjax.close_text + '</a>' + lf;
361
+ html += ctc_render_selector_value_inputs(rule, sel);
362
+ html += '</div></div>' + lf;
363
+ }
364
  });
365
+ });
366
+ html += '</div>' + lf;
367
+ $('#ctc_rule_value_inputs').html(html).find('.color-picker').each(function() {
368
  ctc_setup_iris(this);
369
  });
370
+ $('#ctc_rule_value_inputs').find('.ctc-swatch').each(function() {
371
  ctc_coalesce_inputs(this);
372
  });
 
373
  },
374
+
375
+ ctc_render_selector_value_inputs = function(rule, sel) {
376
+ var html = '', lastquery = '', query;
377
+ if (false === ctc_is_empty(sel)){
378
+ $.each(sel, function(query, selectors) {
379
+ if (query != lastquery) {
380
+ lastquery = query;
381
+ html += '<h4 class="ctc-query-heading">' + query + '</h4>' + lf; //queryparts[1]
382
+ }
383
+ if (false === ctc_is_empty(selectors)){
384
+ $.each(selectors, function(selnum, zero) {
385
+ html += ctc_render_child_rule_input(selnum, rule, true);
386
+ });
387
+ }
388
  });
389
  }
390
+ return html;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
391
  },
392
+
393
  ctc_save = function(obj) {
394
  var postdata = {},
395
+ $selector, $query, $imports, $rule;
 
 
 
 
 
396
  // disable the button until ajax returns
397
  $(obj).prop('disabled', true);
398
  // clear previous success/fail icons
411
  // coalesce inputs
412
  postdata = ctc_coalesce_inputs(obj);
413
  }
 
 
 
 
 
 
 
 
 
 
 
 
414
  // add wp ajax action to array
415
  postdata['action'] = 'ctc_update';
416
  postdata['_wpnonce'] = $('#_wpnonce').val();
422
  postdata,
423
  //on success function
424
  function(response){
 
425
  // release button
426
  $(obj).prop('disabled', false);
427
  // hide spinner
433
  $('.ctc-status-icon').addClass('success');
434
  $('#ctc_new_selectors').val('');
435
  // update data objects
436
+ ctc_apply_updates(response);
 
 
 
 
 
437
  }
438
  return false;
439
+ },
440
+ 'json'
441
  ).fail(function(){
442
  // release button
443
  $(obj).prop('disabled', false);
448
  });
449
  return false;
450
  },
451
+
452
+ ctc_serialize = function(obj) {
453
+ var serialized;
454
+ if (undefined == obj) {
455
+ serialized = '';
456
+ } else if ('string' === typeof obj || 'number' === typeof obj) {
457
+ serialized = obj;
458
+ } else if ('object' === typeof obj) {
459
+ serialized = '';
460
+ $.each(obj, function(ndx,el){
461
+ serialized += ndx + ': ' + el + ',' + "\n";
462
+ });
463
+ }
464
+ return serialized;
465
+ },
466
+
467
  ctc_decode_value = function(rule, value) {
468
+ value = (undefined == value ? '' : value);
469
  var obj = { 'orig': value };
470
+ if (rule.match(/^border(\-(top|right|bottom|left))?$/)) {
471
+ var params = value.split(/ +/);
472
  obj['names'] = [
473
  '_border_width',
474
  '_border_style',
475
  '_border_color',
476
  ];
477
  obj['values'] = [
478
+ (undefined == params[0] ? '' : params[0]),
479
+ (undefined == params[1] ? '' : params[1]),
480
+ (undefined == params[2] ? '' : params[2])
481
  ];
482
+ } else if (rule.match(/^background\-image/)) {
483
  obj['names'] = [
484
  '_background_url',
485
  '_background_origin',
487
  '_background_color2'
488
  ];
489
  obj['values'] = ['','','',''];
490
+ if (value.match(/:/)) {
491
+ var params = value.split(/:/);
492
+ obj['values'][1] = (undefined == params[0] ? '' : params[0]);
493
+ obj['values'][2] = (undefined == params[1] ? '' : params[1]);
494
+ obj['values'][3] = (undefined == params[3] ? '' : params[3]);
495
  obj['orig'] = [ obj['values'][1], obj['values'][2], obj['values'][3] ].join(' '); // display "origin color1 color2"
496
  } else {
497
  obj['values'][0] = value;
503
  return obj;
504
  },
505
 
506
+ ctc_set_query = function(value, label) {
 
507
  $('#ctc_sel_ovrd_query').val('');
508
+ $('#ctc_sel_ovrd_query_selected').text(label);
509
+ ctc_selectors = ctc_load_selectors(value);
510
+ $('#ctc_sel_ovrd_selector').autocomplete('option', { source: ctc_selectors });
 
 
 
511
  $('#ctc_new_selector_row').show();
512
  },
513
 
514
  ctc_set_selector = function(value,label) {
515
  $('#ctc_sel_ovrd_selector').val('');
516
  $('#ctc_sel_ovrd_selector_selected').text(label);
517
+ $('#ctc_sel_ovrd_selnum').val(value);
 
 
518
  ctc_render_selector_inputs(value);
519
+ $('#ctc_sel_ovrd_new_rule, #ctc_sel_ovrd_rule_header,#ctc_sel_ovrd_rule_inputs_container,#ctc_sel_ovrd_rule_inputs').show();
 
520
  },
521
 
522
  ctc_set_rule = function(value,label) {
523
  $('#ctc_rule_menu').val('');
524
  $('#ctc_rule_menu_selected').text(label);
 
525
  ctc_render_rule_value_inputs(value);
 
526
  $('#ctc_rule_value_inputs,#ctc_input_row_rule_header').show();
527
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
528
  // initialize vars
529
+ ctc_selectors = [],
530
+ ctc_queries = ctc_load_queries(),
531
+ ctc_rules = ctc_load_rules(),
532
+ unique_rule_value = {},
533
+ toggles = {};
534
+
535
+ // initialize tools
 
 
 
 
 
 
 
 
 
536
  $('.color-picker').each(function() {
537
  ctc_setup_iris(this);
538
  });
 
539
  $('.ctc-option-panel-container').on('focus', '.color-picker', function(){
 
540
  $(this).iris('toggle');
541
  $('.iris-picker').css({'position':'absolute', 'z-index':10});
542
  });
543
  $('.ctc-option-panel-container').on('focus', 'input', function() {
 
544
  $('.color-picker').not(this).iris('hide');
545
  });
546
+ $('.ctc-option-panel-container').on('change', '.ctc-child-value', function() {
547
  ctc_coalesce_inputs(this);
548
  });
549
  $('.ctc-option-panel-container').on('click', '.ctc-selector-handle', function(e) {
550
  e.preventDefault();
551
+ var id = $(this).attr('id').replace('_close', '');
 
 
 
 
 
 
552
  $('#' + id + '_container').fadeToggle('fast');
553
  $('.ctc-selector-container').not('#' + id + '_container').fadeOut('fast');
554
  });
555
  $('.nav-tab').on('click', function(e){
556
  e.preventDefault();
557
+ var id = '#' + $(this).attr('id'), panelid = id + '_panel';
558
+ $('.nav-tab').removeClass('nav-tab-active');
559
+ $('.ctc-option-panel').removeClass('ctc-option-panel-active');
560
+ $('.ctc-selector-container').hide();
561
+ $(id).addClass('nav-tab-active');
562
+ $('.ctc-option-panel-container').scrollTop(0);
563
+ $(panelid).addClass('ctc-option-panel-active');
564
+ });
565
+ $('#preview_options').on('click', function(e){
566
+ var stamp = new Date().getTime(),
567
+ css_uri = ctcAjax.theme_uri + '/' + ctcAjax.child_theme + '/style.css?' + stamp;
568
+ $.get(
569
+ css_uri,
570
+ function(response){
571
+ $('#preview_options_panel').text(response);
572
+ }
573
+ ).fail(function(){
574
+ $('#preview_options_panel').text(ctcAjax.css_fail);
575
+ });
576
  });
577
+ $('#ctc_load_form').on('submit', function(e) {
578
+ return confirm(ctcAjax.load_msg);
 
579
  });
 
580
  $(document).on('click', '.ctc-save-input', function(e) {
581
  ctc_save(this);
582
  });
583
+ $('#ctc_sel_ovrd_query').autocomplete({
584
+ source: ctc_queries,
585
+ minLength: 0,
586
+ selectFirst: true,
587
+ autoFocus: true,
588
+ select: function(e, ui) {
589
+ ctc_set_query(ui.item.value, ui.item.label);
590
+ return false;
591
+ },
592
+ focus: function(e) { e.preventDefault(); }
593
  });
594
+ $('#ctc_sel_ovrd_selector').autocomplete({
595
+ source: ctc_selectors,
596
+ selectFirst: true,
597
+ autoFocus: true,
598
+ select: function(e, ui) {
599
+ ctc_set_selector(ui.item.value, ui.item.label);
600
+ return false;
601
+ },
602
+ focus: function(e) { e.preventDefault(); }
603
+ });
604
+ $('#ctc_rule_menu').autocomplete({
605
+ source: ctc_rules,
606
+ //minLength: 0,
607
+ selectFirst: true,
608
+ autoFocus: true,
609
+ select: function(e, ui) {
610
+ ctc_set_rule(ui.item.value, ui.item.label);
611
+ return false;
612
+ },
613
+ focus: function(e) { e.preventDefault(); }
614
+ });
615
+ $('#ctc_new_rule_menu').autocomplete({
616
+ source: ctc_rules,
617
+ //minLength: 0,
618
+ selectFirst: true,
619
+ autoFocus: true,
620
+ select: function(e, ui) {
621
+ var sel = $('#ctc_sel_ovrd_selnum').val();
622
+ $('#ctc_sel_ovrd_rule_inputs').append(ctc_render_child_rule_input(sel, ui.item.value, false)).find('.color-picker').each(function() {
623
+ ctc_setup_iris(this);
624
+ });
625
+ $('#ctc_new_rule_menu').val('');
626
+ return false;
627
+ },
628
+ focus: function(e) { e.preventDefault(); }
629
+ });
630
+ })(jQuery);
631
 
 
 
 
 
 
 
 
 
js/chld-thm-cfg.min.js CHANGED
@@ -2,10 +2,10 @@
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.3.4
6
  * Author: Lilaea Media
7
  * Author URI: http://www.lilaeamedia.com/
8
  * License: GPLv2
9
  * Copyright (C) 2013 Lilaea Media
10
  */
11
- ;jQuery(document).ready(function(c){var l="\n",s="base",h,b={},p,q,k=function(t){c(t).iris({change:function(){f(t)}})},e=function(v){var t=parseInt(v),u=String.fromCharCode(t);return u},m=function(u){var t=u.charCodeAt(0);return t},f=function(z){var v=/^(ctc_(ovrd|\d+)_(parent|child)_([0-9a-z\-]+)_(\d+))(_\w+)?$/,A=c(z).parents(".ctc-selector-row, .ctc-parent-row").first(),y=A.find(".ctc-swatch").first(),x={parent:{},child:{}},w={parent:{origin:"",start:"",end:""},child:{origin:"",start:"",end:""}},u={child:false,parent:false},t={};A.find(".ctc-parent-value, .ctc-child-value").each(function(){var I=c(this).attr("id"),B=I.toString().match(v),J=B[2],C=B[3],L=("undefined"==typeof B[4]?"":B[4]),H=B[5],G=("undefined"==typeof B[6]?"":B[6]),K=("parent"==C?c(this).text():c(this).val()),D="ctc_"+J+"_child_"+L+"_i_"+H,F,E;if("child"==C){t[I]=K;t[D]=(c("#"+D).is(":checked"))?1:0}if(false===r(G)){switch(G){case"_border_width":x[C][L+"-width"]=K;break;case"_border_style":x[C][L+"-style"]=K;break;case"_border_color":x[C][L+"-color"]=K;break;case"_background_url":x[C]["background-image"]=i(C,K);break;case"_background_color":x[C]["background-color"]=z.value;break;case"_background_color1":w[C].start=K;u[C]=true;break;case"_background_color2":w[C].end=K;u[C]=true;break;case"_background_origin":w[C].origin=K;u[C]=true;break}}else{if(F=L.toString().match(/^border(\-(top|right|bottom|left))?$/)&&!K.match(/none/)){E=K.toString().split(/ +/);x[C][L+"-width"]="undefined"==typeof E[0]?"":E[0];x[C][L+"-style"]="undefined"==typeof E[1]?"":E[1];x[C][L+"-color"]="undefined"==typeof E[2]?"":E[2]}else{if("background-image"==L){if(K.toString().match(/url\(/)){x[C]["background-image"]=i(C,K)}else{E=K.toString().split(/ +/);if(E.length>2){w[C].origin="undefined"==typeof E[0]?"top":E[0];w[C].start="undefined"==typeof E[1]?"transparent":E[1];w[C].end="undefined"==typeof E[2]?"transparent":E[2];u[C]=true}else{x[C]["background-image"]=K}}}else{x[C][L]=K}}}});if("undefined"!=typeof y&&false===r(y.attr("id"))){c(y).removeAttr("style");if(u.parent){c(y).ctcgrad(w.parent.origin,[w.parent.start,w.parent.end])}c(y).css(x.parent);if(!(y.attr("id").toString().match(/parent/))){if(u.child){c(y).ctcgrad(w.child.origin,[w.child.start,w.child.end])}c(y).css(x.child)}}return t},n=function(u){var t,v,w;c(u).each(function(){switch(this.obj){case"imports":ctcAjax.imports=this.data;break;case"rule_val":ctcAjax.rule_val[this.key]=this.data;w=this.key;break;case"val_qry":ctcAjax.val_qry[this.key]=this.data;break;case"rule":ctcAjax.rule=this.data;break;case"sel_ndx":if(r(this.key)){ctcAjax.sel_ndx=this.data}else{if("qsid"==this.key){if(r(ctcAjax.sel_ndx[this.data.query])){ctcAjax.sel_ndx[this.data.query]={}}ctcAjax.sel_ndx[this.data.query][this.data.selector]=this.data.qsid}else{ctcAjax.sel_ndx[this.key]=this.data;t=this.key}}break;case"sel_val":ctcAjax.sel_val[this.key]=this.data;v=this.key;break;case"rewrite":p=this.key;q=this.data;break}})},i=function(x,u){var w=u.toString().match(/url\([" ]*(.+?)[" ]*\)/),v=r(w)?null:w[1],t=ctcAjax.theme_uri+"/"+("parent"==x?ctcAjax.parnt:ctcAjax.child)+"/",y;if(!v){return false}else{if(v.toString().match(/^(https?:|\/)/)){y=u}else{y="url("+t+v+")"}}return y},r=function(u){if("undefined"==typeof u||false===u||null===u||""===u){return true}if(true===u||"string"===typeof u||"number"===typeof u){return false}if("object"===typeof u){for(var t in u){if(u.hasOwnProperty(t)){return false}}return true}return false},a=function(){var t=[];if(1===loading.sel_ndx){return t}if(0===loading.sel_ndx){loading.sel_ndx=1;ctc_query_css("sel_ndx",null,ctc_setup_query_menu);return t}if(false===r(ctcAjax.sel_ndx)){c.each(ctcAjax.sel_ndx,function(u,v){var w={label:u,value:u};t.push(w)})}return t},o=function(u){var t=[];if(1===loading.sel_ndx){return t}if(0===loading.sel_ndx){loading.sel_ndx=1;ctc_query_css("sel_ndx",u,ctc_setup_selector_menu);return t}if(false===r(ctcAjax.sel_ndx[u])){c.each(ctcAjax.sel_ndx[u],function(v,w){var x={label:v,value:w};t.push(x)})}return t},d=function(){var t=[];if(1===loading.rule){return t}if(0===loading.rule){loading.rule=1;ctc_query_css("rule",null,ctc_setup_rule_menu);return t}if(false===r(ctcAjax.rule)){c.each(ctcAjax.rule,function(u,v){var w={label:v.replace(/\d+/g,e),value:u};t.push(w)})}return t.sort(function(v,u){if(v.label>u.label){return 1}if(v.label<u.label){return -1}return 0})},j=function(x,z,C){var v="",A=(r(ctcAjax.sel_val[x])||r(ctcAjax.sel_val[x].value)||r(ctcAjax.sel_val[x].value[z])?"":ctcAjax.sel_val[x].value[z]),u=ctc_decode_value(z,("undefined"==typeof A?"":A.parnt)),y=(false===r(A.i_parnt)&&A.i_parnt)?ctcAjax.important_label:"",w=ctc_decode_value(z,("undefined"==typeof A?"":A.child)),t=(false===r(A.i_child)&&A.i_child)?1:0,B="ctc_"+C+"_child_"+z+"_i_"+x;if(false===r(ctcAjax.sel_val[x])){v+='<div class="ctc-'+("ovrd"==C?"input":"selector")+'-row clearfix">'+l;v+='<div class="ctc-input-cell">'+("ovrd"==C?z.replace(/\d+/g,e):ctcAjax.sel_val[x].selector+'<br/><a href="#" class="ctc-selector-edit" id="ctc_selector_edit_'+x+'" >'+ctcAjax.edit_txt+"</a> "+(r(u.orig)?ctcAjax.child_only_txt:""))+"</div>"+l;if("ovrd"==C){v+='<div class="ctc-parent-value ctc-input-cell" id="ctc_'+C+"_parent_"+z+"_"+x+'">'+(r(u.orig)?"[no value]":u.orig+y)+"</div>"+l}v+='<div class="ctc-input-cell">'+l;if(false===r(u.names)){c.each(u.names,function(D,E){E=(r(E)?"":E);v+='<div class="ctc-child-input-cell">'+l;var G="ctc_"+C+"_child_"+z+"_"+x+E,F;if(false===(F=w.values.shift())){F=""}v+=(r(E)?"":ctcAjax.field_labels[E]+":<br/>")+'<input type="text" id="'+G+'" name="'+G+'" class="ctc-child-value'+((E+z).toString().match(/color/)?" color-picker":"")+((E).toString().match(/url/)?" ctc-input-wide":"")+'" value="'+F+'" />'+l;v+="</div>"+l});v+='<label for="'+B+'"><input type="checkbox" id="'+B+'" name="'+B+'" value="1" '+(1===t?"checked":"")+" />"+ctcAjax.important_label+"</label>"+l}v+="</div>"+l;v+=("ovrd"==C?"":'<div class="ctc-swatch ctc-specific" id="ctc_child_'+z+"_"+x+'_swatch">'+ctcAjax.swatch_txt+"</div>"+l+'<div class="ctc-child-input-cell ctc-button-cell" id="ctc_save_'+z+"_"+x+'_cell">'+l+'<input type="button" class="button ctc-save-input" id="ctc_save_'+z+"_"+x+'" name="ctc_save_'+z+"_"+x+'" value="Save" /></div>'+l);v+="</div><!-- end input row -->"+l}return v},g=function(t){if(1===loading.sel_val){return false}if(0==loading.sel_val){loading.sel_val=1;ctc_query_css("sel_val",t,g);return false}var w,u,v;if(r(ctcAjax.sel_val[t])){c("#ctc_sel_ovrd_rule_inputs").html("")}else{if(r(ctcAjax.sel_val[t].seq)){c("#ctc_child_load_order_container").html("")}else{w="ctc_ovrd_child_seq_"+t;v=parseInt(ctcAjax.sel_val[t].seq);u='<input type="text" id="'+w+'" name="'+w+'" class="ctc-child-value" value="'+v+'" />';c("#ctc_child_load_order_container").html(u)}if(r(ctcAjax.sel_val[t].value)){c("#ctc_sel_ovrd_rule_inputs").html("")}else{u="";c.each(ctcAjax.sel_val[t].value,function(y,x){u+=j(t,y,"ovrd")});c("#ctc_sel_ovrd_rule_inputs").html(u).find(".color-picker").each(function(){k(this)});f("#ctc_child_all_0_swatch")}}};ctc_render_css_preview=function(t){if(1===loading.preview){return false}if(0==loading.preview){loading.preview=1;var t;if(!(t=c(this).attr("id").toString().match(/(child|parnt)/)[1])){t="child"}ctc_set_notice("");ctc_query_css("preview",t,ctc_render_css_preview);return false}if(2==loading.preview){c("#view_"+t+"_options_panel").text(ctcAjax.previewResponse);loading.preview=0}},ctc_render_rule_value_inputs=function(u){if(1===loading.rule_val){return false}if(0==loading.rule_val){loading.rule_val=1;ctc_query_css("rule_val",u,ctc_render_rule_value_inputs);return false}var v=ctcAjax.rule[u],t='<div class="ctc-input-row clearfix" id="ctc_rule_row_'+v+'">'+l;if(false===r(ctcAjax.rule_val[u])){c.each(ctcAjax.rule_val[u],function(x,y){var w=ctc_decode_value(v,y);t+='<div class="ctc-parent-row clearfix" id="ctc_rule_row_'+v+"_"+x+'">'+l;t+='<div class="ctc-input-cell ctc-parent-value" id="ctc_'+x+"_parent_"+v+"_"+x+'">'+w.orig+"</div>"+l;t+='<div class="ctc-input-cell">'+l;t+='<div class="ctc-swatch ctc-specific" id="ctc_'+x+"_parent_"+v+"_"+x+'_swatch">'+ctcAjax.swatch_txt+"</div></div>"+l;t+='<div class="ctc-input-cell"><a href="#" class="ctc-selector-handle" id="ctc_selector_'+v+"_"+x+'">'+ctcAjax.selector_txt+"</a></div>"+l;t+='<div id="ctc_selector_'+v+"_"+x+'_container" class="ctc-selector-container clearfix">'+l;t+='<a href="#" id="ctc_selector_'+v+"_"+x+'_close" class="ctc-selector-handle" style="float:right">'+ctcAjax.close_txt+'</a><div id="ctc_status_val_qry_'+x+'"></div>'+l;t+='<div id="ctc_selector_'+v+"_"+x+'_rows"></div>'+l;t+="</div></div>"+l});t+="</div>"+l}c("#ctc_rule_value_inputs").html(t).find(".ctc-swatch").each(function(){f(this)})},ctc_render_selector_value_inputs=function(w){if(1==loading.val_qry){return false}var y,u,x=c("#ctc_rule_menu_selected").text().replace(/[^\w\-]/g,m),t,v="";if(0===loading.val_qry){loading.val_qry=1;y={rule:x};ctc_query_css("val_qry",w,ctc_render_selector_value_inputs,y);return false}if(false===r(ctcAjax.val_qry[w])){c.each(ctcAjax.val_qry[w],function(A,z){page_rule=A;c.each(z,function(C,B){v+='<h4 class="ctc-query-heading">'+C+"</h4>"+l;if(false===r(B)){c.each(B,function(D,E){ctcAjax.sel_val[D]=E;v+=j(D,A,w)})}})})}t="#ctc_selector_"+x+"_"+w+"_rows";c(t).html(v).find(".color-picker").each(function(){k(this)});c(t).find(".ctc-swatch").each(function(){f(this)})},ctc_query_css=function(v,u,y,w){var t={ctc_query_obj:v,ctc_query_key:u},x="#ctc_status_"+v+("val_qry"==v?"_"+u:"");if("object"===typeof w){c.each(w,function(z,A){t["ctc_query_"+z]=A})}c(".ctc-status-icon").remove();c(x).append('<span class="ctc-status-icon spinner"></span>');c(".spinner").show();t.action="ctc_query";t._wpnonce=c("#_wpnonce").val();c.post(ctcAjax.ajaxurl,t,function(z){loading[v]=2;c(".ctc-status-icon").removeClass("spinner");if(r(z)){c(".ctc-status-icon").addClass("failure");if("preview"==v){ctcAjax.previewResponse=ctcAjax.css_fail_txt;y(u)}}else{c(".ctc-status-icon").addClass("success");if("preview"==v){ctcAjax.previewResponse=z.shift().data}else{n(z)}if("function"===typeof y){y(u)}return false}},"json").fail(function(){c(".ctc-status-icon").removeClass("spinner");c(".ctc-status-icon").addClass("failure");if("preview"==v){ctcAjax.previewResponse=ctcAjax.css_fail_txt;loading[v]=2;y(u)}else{loading[v]=0}});return false},ctc_save=function(y){var w={},z,v,t,u,A=c(y).attr("id"),x;if(r(b[A])){b[A]=0}b[A]++;c(y).prop("disabled",true);c(".ctc-status-icon").remove();c(y).parent(".ctc-textarea-button-cell, .ctc-button-cell").append('<span class="ctc-status-icon spinner"></span>');c(".spinner").show();if((z=c("#ctc_new_selectors"))&&"ctc_save_new_selectors"==c(y).attr("id")){w.ctc_new_selectors=z.val();if(v=c("#ctc_sel_ovrd_query_selected")){w.ctc_sel_ovrd_query=v.text()}}else{if((t=c("#ctc_child_imports"))&&"ctc_save_imports"==c(y).attr("id")){w.ctc_child_imports=t.val()}else{w=f(y)}}c("#ctc_sel_ovrd_selector_selected").find("#ctc_rewrite_selector").each(function(){x=c("#ctc_rewrite_selector").val(),origsel=c("#ctc_rewrite_selector_orig").val();if(r(x)||!x.toString().match(/\w/)){x=origsel}else{w.ctc_rewrite_selector=x}c(".ctc-rewrite-toggle").text(ctcAjax.rename_txt);c("#ctc_sel_ovrd_selector_selected").html(x)});w.action="ctc_update";w._wpnonce=c("#_wpnonce").val();c.post(ctcAjax.ajaxurl,w,function(B){c(y).prop("disabled",false);c(".ctc-status-icon").removeClass("spinner");if(r(B)){c(".ctc-status-icon").addClass("failure")}else{c(".ctc-status-icon").addClass("success");c("#ctc_new_selectors").val("");n(B);ctc_setup_menus();if(false===r(p)){ctc_set_selector(p,q);p=q=null}}return false},"json").fail(function(){c(y).prop("disabled",false);c(".ctc-status-icon").removeClass("spinner");c(".ctc-status-icon").addClass("failure")});return false},ctc_decode_value=function(v,t){t=("undefined"==typeof t?"":t);var u={orig:t};if(v.toString().match(/^border(\-(top|right|bottom|left))?$/)){var w=t.toString().split(/ +/);u.names=["_border_width","_border_style","_border_color"];u.values=[("undefined"==typeof w[0]?"":w[0]),("undefined"==typeof w[1]?"":w[1]),("undefined"==typeof w[2]?"":w[2])]}else{if(v.toString().match(/^background\-image/)){u.names=["_background_url","_background_origin","_background_color1","_background_color2"];u.values=["","","",""];if(false===(r(t))&&!(t.toString().match(/url/))){var w=t.toString().split(/:/);u.values[1]=("undefined"==typeof w[0]?"":w[0]);u.values[2]=("undefined"==typeof w[1]?"":w[1]);u.values[3]=("undefined"==typeof w[3]?"":w[3]);u.orig=[u.values[1],u.values[2],u.values[3]].join(" ")}else{u.values[0]=t}}else{u.names=[""];u.values=[t]}}return u},ctc_set_query=function(t){s=t;c("#ctc_sel_ovrd_query").val("");c("#ctc_sel_ovrd_query_selected").text(t);c("#ctc_sel_ovrd_selector").val("");c("#ctc_sel_ovrd_selector_selected").html("&nbsp;");c("#ctc_sel_ovrd_rule_inputs").html("");ctc_setup_selector_menu(t);f("#ctc_child_all_0_swatch");c("#ctc_new_selector_row").show()},ctc_set_selector=function(u,t){c("#ctc_sel_ovrd_selector").val("");c("#ctc_sel_ovrd_selector_selected").text(t);c("#ctc_sel_ovrd_qsid").val(u);h=u;if(1!=loading.sel_val){loading.sel_val=0}g(u);c(".ctc-rewrite-toggle").text(ctcAjax.rename_txt);c("#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()},ctc_set_rule=function(u,t){c("#ctc_rule_menu").val("");c("#ctc_rule_menu_selected").text(t);if(1!=loading.rule_val){loading.rule_val=0}ctc_render_rule_value_inputs(u);c(".ctc-rewrite-toggle").text(ctcAjax.rename_txt);c("#ctc_rule_value_inputs,#ctc_input_row_rule_header").show()},ctc_setup_query_menu=function(){ctc_queries=a();c("#ctc_sel_ovrd_query").autocomplete({source:ctc_queries,minLength:0,selectFirst:true,autoFocus:true,select:function(u,t){ctc_set_query(t.item.value);return false},focus:function(t){t.preventDefault()}})},ctc_setup_selector_menu=function(t){ctc_selectors=o(t);c("#ctc_sel_ovrd_selector").autocomplete({source:ctc_selectors,selectFirst:true,autoFocus:true,select:function(v,u){ctc_set_selector(u.item.value,u.item.label);return false},focus:function(u){u.preventDefault()}})},ctc_setup_rule_menu=function(){ctc_rules=d();c("#ctc_rule_menu").autocomplete({source:ctc_rules,selectFirst:true,autoFocus:true,select:function(u,t){ctc_set_rule(t.item.value,t.item.label);return false},focus:function(t){t.preventDefault()}})},ctc_filtered_rules=function(w,u){var t=[],v=(r(ctcAjax.sel_val[h]))||(r(ctcAjax.sel_val[h].value));if(r(ctc_rules)){ctc_rules=d()}c.each(ctc_rules,function(x,A){var y=false,z=new RegExp(c.ui.autocomplete.escapeRegex(w.term),"i");if(z.test(A.label)){if(false===v){c.each(ctcAjax.sel_val[h].value,function(C,B){if(A.label==C.replace(/\d+/g,e)){y=true;return false}});if(y){return}}t.push(A)}});u(t)},ctc_setup_new_rule_menu=function(){c("#ctc_new_rule_menu").autocomplete({source:ctc_filtered_rules,selectFirst:true,autoFocus:true,select:function(u,t){u.preventDefault();var v=c(j(h,t.item.label.replace(/[^\w\-]/g,m),"ovrd"));c("#ctc_sel_ovrd_rule_inputs").append(v);c("#ctc_new_rule_menu").val("");if(r(ctcAjax.sel_val[h].value)){ctcAjax.sel_val[h]["value"]={}}ctcAjax.sel_val[h].value[t.item.label]={child:""};v.find('input[type="text"]').each(function(w,x){if(c(x).hasClass("color-picker")){k(x)}c(x).focus()});return false},focus:function(t){t.preventDefault()}})},ctc_setup_menus=function(){ctc_setup_query_menu();ctc_setup_selector_menu(s);ctc_setup_rule_menu();ctc_setup_new_rule_menu()},ctc_theme_exists=function(t,u){var v=false;c.each(ctcAjax.themes,function(w,x){c.each(x,function(y,z){if(y==t&&("parnt"==w||"new"==u)){v=true;return false}});if(v){return false}});return v},ctc_set_notice=function(t){var u="";if(false===r(t)){c.each(t,function(v,w){u+='<div class="'+v+'"><ul>'+l;c(w).each(function(x,y){u+="<li>"+y.toString()+"</li>"+l});u+="</ul></div>"})}c("#ctc_error_notice").html(u)},ctc_validate=function(){var w=/[^\w\-]/,u=c("#ctc_child_template").val().toString().replace(w).toLowerCase(),t=c("#ctc_theme_child").val().toString().replace(w).toLowerCase(),v=c("input[name=ctc_child_type]:checked").val(),x=[];if("new"==v){t=u}if(ctc_theme_exists(t,v)){x.push(ctcAjax.theme_exists_txt.toString().replace(/%s/,t))}if(""===t){x.push(ctcAjax.inval_theme_txt)}if(""===c("#ctc_child_name").val()){x.push(ctcAjax.inval_name_txt)}if(x.length){ctc_set_notice({error:x});return false}return true},ctc_set_theme_menu=function(u){var t=c("#ctc_theme_child").val();if(false===r(ctcAjax.themes.child[t])){c("#ctc_child_name").val(ctcAjax.themes.child[t].Name);c("#ctc_child_author").val(ctcAjax.themes.child[t].Author);c("#ctc_child_version").val(ctcAjax.themes.child[t].Version)}},fade_update_notice=function(){c(".updated, .error").slideUp("slow",function(){c(".updated").remove()})},ctc_focus_panel=function(u){var t=u+"_panel";c(".nav-tab").removeClass("nav-tab-active");c(".ctc-option-panel").removeClass("ctc-option-panel-active");c(".ctc-selector-container").hide();c(u).addClass("nav-tab-active");c(".ctc-option-panel-container").scrollTop(0);c(t).addClass("ctc-option-panel-active")},ctc_selector_edit=function(w){var t=c(w).attr("id").match(/_(\d+)$/)[1],v=ctcAjax.sel_val[t].query,u=ctcAjax.sel_val[t].selector,x="#query_selector_options";ctc_set_query(v);ctc_set_selector(t,u);ctc_focus_panel(x)},ctc_selector_input_toggle=function(u){var t;if(c("#ctc_rewrite_selector").length){t=c("#ctc_rewrite_selector_orig").val();c("#ctc_sel_ovrd_selector_selected").text(t);c(u).text(ctcAjax.rename_txt)}else{t=c("#ctc_sel_ovrd_selector_selected").text();c("#ctc_sel_ovrd_selector_selected").html('<input id="ctc_rewrite_selector" name="ctc_rewrite_selector" type="text" value="'+t+'" autocomplete="off" /><input id="ctc_rewrite_selector_orig" name="ctc_rewrite_selector_orig" type="hidden" value="'+t+'"/>');c(u).text(ctcAjax.cancel_txt)}};loading={rule:2,sel_ndx:2,val_qry:0,rule_val:0,sel_val:0,preview:0},ctc_selectors=[],ctc_queries=[],ctc_rules=[];c(".color-picker").each(function(){k(this)});c(".ctc-option-panel-container").on("focus",".color-picker",function(){ctc_set_notice("");c(this).iris("toggle");c(".iris-picker").css({position:"absolute","z-index":10})});c(".ctc-option-panel-container").on("focus","input",function(){ctc_set_notice("");c(".color-picker").not(this).iris("hide")});c(".ctc-option-panel-container").on("change",".ctc-child-value, input[type=checkbox]",function(){f(this)});c(".ctc-option-panel-container").on("click",".ctc-selector-handle",function(u){u.preventDefault();ctc_set_notice("");var v=c(this).attr("id").toString().replace("_close",""),t=v.toString().match(/_(\d+)$/)[1];if(c("#"+v+"_container").is(":hidden")){if(1!=loading.val_qry){loading.val_qry=0}ctc_render_selector_value_inputs(t)}c("#"+v+"_container").fadeToggle("fast");c(".ctc-selector-container").not("#"+v+"_container").fadeOut("fast")});c(".nav-tab").on("click",function(t){t.preventDefault();ctc_set_notice("");c(".ctc-status-icon").remove();var u="#"+c(this).attr("id");ctc_focus_panel(u)});c("#view_child_options,#view_parnt_options").on("click",ctc_render_css_preview);c("#ctc_load_form").on("submit",function(){return(ctc_validate()&&confirm(ctcAjax.load_txt))});c("#parent_child_options_panel").on("change","#ctc_theme_child",ctc_set_theme_menu);c(document).on("click",".ctc-save-input",function(t){ctc_save(this)});c(document).on("click",".ctc-selector-edit",function(t){ctc_selector_edit(this)});c(document).on("click",".ctc-rewrite-toggle",function(t){t.preventDefault();ctc_selector_input_toggle(this)});ctc_setup_menus();ctc_set_query(s);c("input[type=submit],input[type=button]").prop("disabled",false);setTimeout(fade_update_notice,6000)});
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.0
6
  * Author: Lilaea Media
7
  * Author URI: http://www.lilaeamedia.com/
8
  * License: GPLv2
9
  * Copyright (C) 2013 Lilaea Media
10
  */
11
+ (function(e){var k="\n",l=function(m){e(m).iris({change:function(){h(m)}})},h=function(s){var o=/^(ctc_(ovrd_)?(parent|child)_([a-z\-]+)_(\d+))(_\w+)?$/,t=e(s).parents(".ctc-selector-row, .ctc-parent-row").first(),r=t.find(".ctc-swatch").first(),q={parent:{},child:{}},p={parent:{origin:"",start:"",end:""},child:{origin:"",start:"",end:""}},n={child:false,parent:false},m={};t.find(".ctc-parent-value, .ctc-child-value").each(function(){var z=e(this).attr("id"),u=z.match(o),v=u[3],C=(undefined==u[4]?"":u[4]),A=u[5],y=(undefined==u[6]?"":u[6]),B=("parent"==v?e(this).text():e(this).val()),x,w;if("child"==v){m[z]=B}if(a(B)){return}if(false===a(y)){switch(y){case"_border_width":q[v][C+"-width"]=B;break;case"_border_style":q[v][C+"-style"]=B;break;case"_border_color":q[v][C+"-color"]=B;break;case"_background_url":q[v]["background-image"]=b(v,B);break;case"_background_color":q[v]["background-color"]=s.value;break;case"_background_color1":p[v].start=B;n[v]=true;break;case"_background_color2":p[v].end=B;n[v]=true;break;case"_background_origin":p[v].origin=B;n[v]=true;break}}else{if(x=C.match(/^border(\-(top|right|bottom|left))?$/)&&!B.match(/none/)){w=B.split(/ +/);q[v][C+"-width"]=undefined==w[0]?"":w[0];q[v][C+"-style"]=undefined==w[1]?"":w[1];q[v][C+"-color"]=undefined==w[2]?"":w[2]}else{if("background-image"==C){if(B.match(/url\(/)){q[v]["background-image"]=b(v,B)}else{w=B.split(/ +/);if(w.length>2){p[v].origin=undefined==w[0]?"top":w[0];p[v].start=undefined==w[1]?"transparent":w[1];p[v].end=undefined==w[2]?"transparent":w[2];n[v]=true}else{q[v]["background-image"]=B}}}else{q[v][C]=B}}}});if(undefined!=r){e(r).removeAttr("style");if(n.parent){e(r).ctcgrad(p.parent.origin,[p.parent.start,p.parent.end])}e(r).css(q.parent);if(!(r.attr("id").match(/parent/))){if(n.child){e(r).ctcgrad(p.child.origin,[p.child.start,p.child.end])}e(r).css(q.child)}}return m},j=function(p){var o,m,n;if(undefined!=p.imports){ctcAjax.imports[ctcAjax.child_theme]=p.imports}e(p.del).each(function(){if(undefined!=this.selnum){delete ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value][this.query][this.selnum]}else{if(undefined!=this.query){delete ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value][this.query]}else{if(undefined!=this.value){delete ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value]}else{if(undefined!=this.rule){delete ctcAjax.val_ndx[ctcAjax.child_theme][this.rule]}}}}if(undefined!=this.query){o=this.query}if(undefined!=this.selnum){m=this.selnum}if(undefined!=this.rule){n=this.rule}});e(p.insert).each(function(){ctcAjax.sel_ndx[this.query][this.selector]=this.selnum;ctcAjax.data[this.selnum]={selector:this.selector,query:this.query,value:{}};if(undefined!=this.query){o=this.query}if(undefined!=this.selnum){m=this.selnum}if(undefined!=this.rule){n=this.rule}});e(p.update).each(function(){if(undefined==ctcAjax.val_ndx[ctcAjax.child_theme]){ctcAjax.val_ndx[ctcAjax.child_theme]={}}if(undefined==ctcAjax.val_ndx[ctcAjax.child_theme][this.rule]){ctcAjax.val_ndx[ctcAjax.child_theme][this.rule]={}}if(this.value&&undefined==ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value]){ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value]={}}if(this.value&&undefined==ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value][this.query]){ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value][this.query]={}}if(this.value&&undefined==ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value][this.query][this.selnum]){ctcAjax.val_ndx[ctcAjax.child_theme][this.rule][this.value][this.query][this.selnum]=0}if(this.rule&&undefined==ctcAjax.data[this.selnum].value[this.rule]){ctcAjax.data[this.selnum].value[this.rule]={}}ctcAjax.data[this.selnum].value[this.rule][ctcAjax.child_theme]=this.value+(this.important>0?" !important":"");if(undefined!=this.query){o=this.query}if(undefined!=this.selnum){m=this.selnum}if(undefined!=this.rule){n=this.rule}});if(o){ctc_set_query(o,o)}if(m){ctc_set_selector(m,ctcAjax.data[m].selector)}if(n){ctc_set_rule(n,n)}},b=function(q,n){var p=n.match(/url\([" ]*(.+?)[" ]*\)/),o=(undefined==p?null:p[1]),m=ctcAjax.theme_uri+"/"+("parent"==q?ctcAjax.parent_theme:ctcAjax.child_theme)+"/",r;if(!o){return false}else{if(o.match(/^(http:|\/)/)){r=n}else{r="url("+m+o+")"}}return r},a=function(n){if(undefined==n||false===n||null===n||""===n||0===n){return true}if(true===n||"string"===typeof n||"number"===typeof n){return false}if("object"===typeof n){for(var m in n){if(n.hasOwnProperty(m)){return false}}return true}return false},g=function(){var m=[];if(false===a(ctcAjax.sel_ndx)){e.each(ctcAjax.sel_ndx,function(n,o){obj={label:n,value:n};m.push(obj)})}return m},d=function(n){var m=[];if(false===a(ctcAjax.sel_ndx[n])){e.each(ctcAjax.sel_ndx[n],function(o,p){obj={label:o,value:p};m.push(obj)})}return m},i=function(){var n={},m=[];if(false===a(ctcAjax.val_ndx[ctcAjax.parent_theme])){e.each(ctcAjax.val_ndx[ctcAjax.parent_theme],function(o,p){n[o]++})}if(false===a(ctcAjax.val_ndx[ctcAjax.child_theme])){e.each(ctcAjax.val_ndx[ctcAjax.child_theme],function(o,p){n[o]++})}e.each(["border-width","border-style","border-color","padding","margin","background","font"],function(){n[this]++});if(false===a(n)){e.each(n,function(o,p){m.push(o)})}return m.sort()},f=function(r,s,n){var o="",q=(undefined==ctcAjax.data[r].value||undefined==ctcAjax.data[r].value[s]?"":ctcAjax.data[r].value[s]),p=ctc_decode_value(s,(undefined==q?"":q[ctcAjax.parent_theme])),m=ctc_decode_value(s,(undefined==q?"":q[ctcAjax.child_theme]));if(q){unique_rule_value[s+"%%"+q[ctcAjax.parent_theme]]=1;unique_rule_value[s+"%%"+q[ctcAjax.child_theme]]=1}o+='<div class="ctc-'+(n?"selector":"input")+'-row clearfix">'+k;o+='<div class="ctc-input-cell">'+(n?ctcAjax.data[r].selector:s)+"</div>"+k;o+='<div class="ctc-parent-value'+(n?" ctc-hidden":" ctc-input-cell")+'" id="ctc_parent_'+s+"_"+r+'">'+(a(p.orig)?"[no value]":p.orig)+"</div>"+k;o+='<div class="ctc-input-cell">'+k;if(false===a(p.names)){e.each(p.names,function(t,u){u=(a(u)?"":u);o+='<div class="ctc-child-input-cell">'+k;var w="ctc_"+(n?"":"ovrd_")+"child_"+s+"_"+r+u,v;if(!(v=m.values.shift())){v=""}o+=(a(u)?"":ctcAjax.labels[u]+":<br/>")+'<input type="text" id="'+w+'" name="'+w+'" class="ctc-child-value'+((u+s).match(/color/)?" color-picker":"")+((u).match(/url/)?" ctc-input-wide":"")+'" value="'+v+'" />'+k;o+="</div>"+k})}o+="</div>"+k;o+=(n?'<div class="ctc-swatch ctc-specific" id="ctc_child_'+s+"_"+r+'_swatch">'+ctcAjax.swatch_text+"</div>"+k+'<div class="ctc-child-input-cell ctc-button-cell" id="ctc_save_'+s+"_"+r+'_cell">'+k+'<input type="button" class="button ctc-save-input" id="ctc_save_'+s+"_"+r+'" name="ctc_save_'+s+"_"+r+'" value="Save" /></div>'+k:"");o+="</div><!-- end input row -->"+k;return o},c=function(o){if(undefined==ctcAjax.data[o].value){return}var n="",m=0;if(false===a(ctcAjax.data[o].value)){e.each(ctcAjax.data[o].value,function(q,p){n+=f(o,q,false)})}e("#ctc_sel_ovrd_rule_inputs").html(n).find(".color-picker").each(function(){l(this)});h("#ctc_child_all_0_swatch")};ctc_render_rule_value_inputs=function(p){var n='<div class="ctc-input-row clearfix" id="ctc_rule_row_'+p+'">'+k,o=0,m={parent:ctcAjax.parent_theme,child:ctcAjax.child_theme};unique_rule_value={},e.each(m,function(q,r){if(a(ctcAjax.val_ndx[r])||undefined==ctcAjax.val_ndx[r][p]){return}e.each(ctcAjax.val_ndx[r][p],function(t,s){if(unique_rule_value[p+"%%"+t]){return}else{o++;oldRuleObj=ctc_decode_value(p,t),n+='<div class="ctc-parent-row clearfix" id="ctc_rule_row_'+p+"_"+o+'">'+k;n+='<div class="ctc-input-cell ctc-parent-value" id="ctc_parent_'+p+"_"+o+'">'+oldRuleObj.orig+"</div>"+k;n+='<div class="ctc-input-cell">'+k;n+='<div class="ctc-swatch ctc-specific" id="ctc_parent_'+p+"_"+o+'_swatch">'+ctcAjax.swatch_text+"</div></div>"+k;n+='<div class="ctc-input-cell"><a href="#" class="ctc-selector-handle" id="ctc_selector_'+p+"_"+o+'">'+ctcAjax.selector_text+"</a></div>"+k;n+='<div id="ctc_selector_'+p+"_"+o+'_container" class="ctc-selector-container clearfix">'+k;n+='<a href="#" id="ctc_selector_'+p+"_"+o+'_close" class="ctc-selector-handle" style="float:right">'+ctcAjax.close_text+"</a>"+k;n+=ctc_render_selector_value_inputs(p,s);n+="</div></div>"+k}})});n+="</div>"+k;e("#ctc_rule_value_inputs").html(n).find(".color-picker").each(function(){l(this)});e("#ctc_rule_value_inputs").find(".ctc-swatch").each(function(){h(this)})},ctc_render_selector_value_inputs=function(q,o){var m="",p="",n;if(false===a(o)){e.each(o,function(s,r){if(s!=p){p=s;m+='<h4 class="ctc-query-heading">'+s+"</h4>"+k}if(false===a(r)){e.each(r,function(u,t){m+=f(u,q,true)})}})}return m},ctc_save=function(q){var p={},r,o,m,n;e(q).prop("disabled",true);e(".ctc-status-icon").remove();e(q).parent(".ctc-textarea-button-cell, .ctc-button-cell").append('<span class="ctc-status-icon spinner"></span>');e(".spinner").show();if((r=e("#ctc_new_selectors"))&&"ctc_save_new_selectors"==e(q).attr("id")){p.ctc_new_selectors=r.val();if(o=e("#ctc_sel_ovrd_query_selected")){p.ctc_sel_ovrd_query=o.text()}}else{if((m=e("#ctc_child_imports"))&&"ctc_save_imports"==e(q).attr("id")){p.ctc_child_imports=m.val()}else{p=h(q)}}p.action="ctc_update";p._wpnonce=e("#_wpnonce").val();e.post(ctcAjax.ajaxurl,p,function(s){e(q).prop("disabled",false);e(".ctc-status-icon").removeClass("spinner");if(a(s)){e(".ctc-status-icon").addClass("failure")}else{e(".ctc-status-icon").addClass("success");e("#ctc_new_selectors").val("");j(s)}return false},"json").fail(function(){e(q).prop("disabled",false);e(".ctc-status-icon").removeClass("spinner");e(".ctc-status-icon").addClass("failure")});return false},ctc_serialize=function(n){var m;if(undefined==n){m=""}else{if("string"===typeof n||"number"===typeof n){m=n}else{if("object"===typeof n){m="";e.each(n,function(o,p){m+=o+": "+p+",\n"})}}}return m},ctc_decode_value=function(o,m){m=(undefined==m?"":m);var n={orig:m};if(o.match(/^border(\-(top|right|bottom|left))?$/)){var p=m.split(/ +/);n.names=["_border_width","_border_style","_border_color"];n.values=[(undefined==p[0]?"":p[0]),(undefined==p[1]?"":p[1]),(undefined==p[2]?"":p[2])]}else{if(o.match(/^background\-image/)){n.names=["_background_url","_background_origin","_background_color1","_background_color2"];n.values=["","","",""];if(m.match(/:/)){var p=m.split(/:/);n.values[1]=(undefined==p[0]?"":p[0]);n.values[2]=(undefined==p[1]?"":p[1]);n.values[3]=(undefined==p[3]?"":p[3]);n.orig=[n.values[1],n.values[2],n.values[3]].join(" ")}else{n.values[0]=m}}else{n.names=[""];n.values=[m]}}return n},ctc_set_query=function(n,m){e("#ctc_sel_ovrd_query").val("");e("#ctc_sel_ovrd_query_selected").text(m);ctc_selectors=d(n);e("#ctc_sel_ovrd_selector").autocomplete("option",{source:ctc_selectors});e("#ctc_new_selector_row").show()},ctc_set_selector=function(n,m){e("#ctc_sel_ovrd_selector").val("");e("#ctc_sel_ovrd_selector_selected").text(m);e("#ctc_sel_ovrd_selnum").val(n);c(n);e("#ctc_sel_ovrd_new_rule, #ctc_sel_ovrd_rule_header,#ctc_sel_ovrd_rule_inputs_container,#ctc_sel_ovrd_rule_inputs").show()},ctc_set_rule=function(n,m){e("#ctc_rule_menu").val("");e("#ctc_rule_menu_selected").text(m);ctc_render_rule_value_inputs(n);e("#ctc_rule_value_inputs,#ctc_input_row_rule_header").show()},ctc_selectors=[],ctc_queries=g(),ctc_rules=i(),unique_rule_value={},toggles={};e(".color-picker").each(function(){l(this)});e(".ctc-option-panel-container").on("focus",".color-picker",function(){e(this).iris("toggle");e(".iris-picker").css({position:"absolute","z-index":10})});e(".ctc-option-panel-container").on("focus","input",function(){e(".color-picker").not(this).iris("hide")});e(".ctc-option-panel-container").on("change",".ctc-child-value",function(){h(this)});e(".ctc-option-panel-container").on("click",".ctc-selector-handle",function(m){m.preventDefault();var n=e(this).attr("id").replace("_close","");e("#"+n+"_container").fadeToggle("fast");e(".ctc-selector-container").not("#"+n+"_container").fadeOut("fast")});e(".nav-tab").on("click",function(n){n.preventDefault();var o="#"+e(this).attr("id"),m=o+"_panel";e(".nav-tab").removeClass("nav-tab-active");e(".ctc-option-panel").removeClass("ctc-option-panel-active");e(".ctc-selector-container").hide();e(o).addClass("nav-tab-active");e(".ctc-option-panel-container").scrollTop(0);e(m).addClass("ctc-option-panel-active")});e("#preview_options").on("click",function(o){var m=new Date().getTime(),n=ctcAjax.theme_uri+"/"+ctcAjax.child_theme+"/style.css?"+m;e.get(n,function(p){e("#preview_options_panel").text(p)}).fail(function(){e("#preview_options_panel").text(ctcAjax.css_fail)})});e("#ctc_load_form").on("submit",function(m){return confirm(ctcAjax.load_msg)});e(document).on("click",".ctc-save-input",function(m){ctc_save(this)});e("#ctc_sel_ovrd_query").autocomplete({source:ctc_queries,minLength:0,selectFirst:true,autoFocus:true,select:function(n,m){ctc_set_query(m.item.value,m.item.label);return false},focus:function(m){m.preventDefault()}});e("#ctc_sel_ovrd_selector").autocomplete({source:ctc_selectors,selectFirst:true,autoFocus:true,select:function(n,m){ctc_set_selector(m.item.value,m.item.label);return false},focus:function(m){m.preventDefault()}});e("#ctc_rule_menu").autocomplete({source:ctc_rules,selectFirst:true,autoFocus:true,select:function(n,m){ctc_set_rule(m.item.value,m.item.label);return false},focus:function(m){m.preventDefault()}});e("#ctc_new_rule_menu").autocomplete({source:ctc_rules,selectFirst:true,autoFocus:true,select:function(o,n){var m=e("#ctc_sel_ovrd_selnum").val();e("#ctc_sel_ovrd_rule_inputs").append(f(m,n.item.value,false)).find(".color-picker").each(function(){l(this)});e("#ctc_new_rule_menu").val("");return false},focus:function(m){m.preventDefault()}})})(jQuery);
lang/chld_thm_cfg.pot CHANGED
@@ -1,553 +1,14 @@
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.2.2\n"
6
- "Report-Msgid-Bugs-To: http://wordpress.org/tag/child-theme-configurator\n"
7
- "POT-Creation-Date: 2014-02-15 19:13:22+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
- #: includes/class-ctc-ui.php:46
16
- msgid "Parent/Child"
17
- msgstr ""
18
-
19
- #: includes/class-ctc-ui.php:49 includes/class-ctc-ui.php:390
20
- msgid "Query/Selector"
21
- msgstr ""
22
-
23
- #: includes/class-ctc-ui.php:52 includes/class-ctc-ui.php:404
24
- msgid "Rule/Value"
25
- msgstr ""
26
-
27
- #: includes/class-ctc-ui.php:55
28
- msgid "@import"
29
- msgstr ""
30
-
31
- #: includes/class-ctc-ui.php:58
32
- msgid "View Child CSS"
33
- msgstr ""
34
-
35
- #: includes/class-ctc-ui.php:61
36
- msgid "View Parent CSS"
37
- msgstr ""
38
-
39
- #: includes/class-ctc-ui.php:70
40
- msgid "Parent Theme"
41
- msgstr ""
42
-
43
- #: includes/class-ctc-ui.php:82
44
- msgid "Child Theme"
45
- msgstr ""
46
-
47
- #: includes/class-ctc-ui.php:90
48
- msgid "Create New Child Theme"
49
- msgstr ""
50
-
51
- #: includes/class-ctc-ui.php:99
52
- msgid "Use Existing Child Theme"
53
- msgstr ""
54
-
55
- #: includes/class-ctc-ui.php:117
56
- msgid "Child Theme Name"
57
- msgstr ""
58
-
59
- #: includes/class-ctc-ui.php:128
60
- msgid "Author"
61
- msgstr ""
62
-
63
- #: includes/class-ctc-ui.php:139
64
- msgid "Version"
65
- msgstr ""
66
-
67
- #: includes/class-ctc-ui.php:150
68
- msgid "Backup Stylesheet"
69
- msgstr ""
70
-
71
- #: includes/class-ctc-ui.php:164
72
- msgid "Generate Child Theme"
73
- msgstr ""
74
-
75
- #: includes/class-ctc-ui.php:175 includes/class-ctc-ui.php:244
76
- msgid "Rule"
77
- msgstr ""
78
-
79
- #: includes/class-ctc-ui.php:188
80
- msgid "Value"
81
- msgstr ""
82
-
83
- #: includes/class-ctc-ui.php:191 includes/class-ctc-ui.php:229
84
- #: includes/class-ctc.php:94
85
- msgid "Sample"
86
- msgstr ""
87
-
88
- #: includes/class-ctc-ui.php:194 includes/class-ctc.php:96
89
- msgid "Selectors"
90
- msgstr ""
91
-
92
- #: includes/class-ctc-ui.php:205
93
- msgid "Query"
94
- msgstr ""
95
-
96
- #: includes/class-ctc-ui.php:216
97
- msgid "Selector"
98
- msgstr ""
99
-
100
- #: includes/class-ctc-ui.php:247
101
- msgid "Parent Value"
102
- msgstr ""
103
-
104
- #: includes/class-ctc-ui.php:250
105
- msgid "Child Value"
106
- msgstr ""
107
-
108
- #: includes/class-ctc-ui.php:256
109
- msgid "New Rule"
110
- msgstr ""
111
-
112
- #: includes/class-ctc-ui.php:266
113
- msgid "Order"
114
- msgstr ""
115
-
116
- #: includes/class-ctc-ui.php:273
117
- msgid "Raw CSS"
118
- msgstr ""
119
-
120
- #: includes/class-ctc-ui.php:292
121
- msgid "@import Statements"
122
- msgstr ""
123
-
124
- #: includes/class-ctc-ui.php:348
125
- msgid "Child Theme <strong>%s</strong> has been generated successfully."
126
- msgstr ""
127
-
128
- #: includes/class-ctc-ui.php:366
129
- msgid "Tutorial Video"
130
- msgstr ""
131
-
132
- #: includes/class-ctc-ui.php:367
133
- msgid ""
134
- "<iframe width=\"480\" height=\"270\" src=\"//www.youtube.com/embed/"
135
- "xL2HkWQxgOA?rel=0&modestbranding=1\" frameborder=\"0\" allowfullscreen></"
136
- "iframe>"
137
- msgstr ""
138
-
139
- #: includes/class-ctc-ui.php:373
140
- msgid "Start Here"
141
- msgstr ""
142
-
143
- #: includes/class-ctc-ui.php:374
144
- msgid ""
145
- "\n"
146
- "<p>The first step is to create a child theme and import your parent theme "
147
- "styles into the configurator.</p>\n"
148
- "<ol><li>Select an existing parent theme from the menu.</li>\n"
149
- "<li>Select \"New\" or \"Existing\" child theme.\n"
150
- "<ul><li>If creating a new theme, enter a \"slug\" (lower case, no spaces). "
151
- "This is used to name the theme directory and identify the theme to WordPress."
152
- "</li>\n"
153
- "<li>If using an existing theme, select a child theme from the menu.</li></"
154
- "ul></li>\n"
155
- "<li>Enter a Name for the child theme.</li>\n"
156
- "<li>Enter an author for the child theme.</li>\n"
157
- "<li>Enter the child theme version number.</li>\n"
158
- "<li>Click \"Generate Child Theme.\" If you are loading an existing child "
159
- "theme, The Child Theme Configurator will create a backup of your existing "
160
- "stylesheet in the theme directory.</li></ol>\n"
161
- "\t\t\t\t "
162
- msgstr ""
163
-
164
- #: includes/class-ctc-ui.php:391
165
- msgid ""
166
- "\n"
167
- "<p>There are two ways to identify and override parent styles. The Child "
168
- "Theme Configurator lets you search styles by <strong>selector</strong> and "
169
- "by <strong>rule</strong>. If you wish to change a specific selector (e.g., "
170
- "h1), use the \"Query/Selector\" tab. If you have a specific value you wish "
171
- "to change site-wide (e.g., the color of the type), use the \"Rule/Value\" "
172
- "tab.</p>\n"
173
- "<p>The Query/Selector tab lets you find specific selectors and edit them. "
174
- "First, find the query that contains the selector you wish to edit by typing "
175
- "in the <strong>Query</strong> autoselect box. Select by clicking with the "
176
- "mouse or by pressing the \"Enter\" or \"Tab\" keys. Selectors are in the "
177
- "<strong>base</strong> query by default.</p>\n"
178
- "<p>Next, find the selector by typing in the <strong>Selector</strong> "
179
- "autoselect box. Select by clicking with the mouse or by pressing the \"Enter"
180
- "\" or \"Tab\" keys.</p>\n"
181
- "<p>This will load all of the rules for that selector with the Parent values "
182
- "on the left and the Child values inputs on the right. Any existing child "
183
- "values will be automatically populated. There is also a Sample preview that "
184
- "displays the combination of Parent and Child overrides. Note that the "
185
- "<strong>border</strong> and <strong>background-image</strong> get special "
186
- "treatment.</p>\n"
187
- "<p>The \"Order\" field contains the original sequence of the selector in the "
188
- "parent theme stylesheet. You can change the selector order sequence by "
189
- "entering a lower or higher number in the \"Order\" field. You can also force "
190
- "style overrides (so called \"!important\" flag) by checking the \"!\" box "
191
- "next to each input. Please use judiciously.</p>\n"
192
- "<p>Click \"Save\" to update the child stylesheet and save your changes to "
193
- "the WordPress admin.</p>\n"
194
- "\t\t\t\t "
195
- msgstr ""
196
-
197
- #: includes/class-ctc-ui.php:405
198
- msgid ""
199
- "\n"
200
- "<p>There are two ways to identify and override parent styles. The Child "
201
- "Theme Configurator lets you search styles by <strong>selector</strong> and "
202
- "by <strong>rule</strong>. If you wish to change a specific selector (e.g., "
203
- "h1), use the \"Query/Selector\" tab. If you have a specific value you wish "
204
- "to change site-wide (e.g., the color of the type), use the \"Rule/Value\" "
205
- "tab.</p>\n"
206
- "<p>The Rule/Value tab lets you find specific values for a given rule and "
207
- "then edit that value for individual selectors that use that rule/value "
208
- "combination. First, find the rule you wish to override by typing in the "
209
- "<strong>Rule</strong> autoselect box. Select by clicking with the mouse or "
210
- "by pressing the \"Enter\" or \"Tab\" keys.</p>\n"
211
- "<p>This will load all of the unique values that exist for that rule in the "
212
- "parent stylesheet with a Sample preview for that value. If there are values "
213
- "that exist in the child stylesheet that do not exist in the parent "
214
- "stylesheet, they will be displayed as well.</p>\n"
215
- "<p>For each unique value, click the \"Selectors\" link to view a list of "
216
- "selectors that use that rule/value combination, grouped by query with a "
217
- "Sample preview of the value and inputs for the child value. Any existing "
218
- "child values will be automatically populated.</p>\n"
219
- "<p>Click \"Save\" to update the child stylesheet and save your changes to "
220
- "the WordPress admin.</p>\n"
221
- "\t\t\t\t "
222
- msgstr ""
223
-
224
- #: includes/class-ctc-ui.php:417
225
- msgid "Add New Styles"
226
- msgstr ""
227
-
228
- #: includes/class-ctc-ui.php:418
229
- msgid ""
230
- "\n"
231
- "<p>If you wish to add additional rules to a given selector, first load the "
232
- "selector using the Query/Selector tab. Then find the rule you wish to "
233
- "override by typing in the <strong>New Rule</strong> autoselect box. Select "
234
- "by clicking with the mouse or by pressing the \"Enter\" or \"Tab\" keys. "
235
- "This will add a new input row to the selector inputs.</p>\n"
236
- "<p>If you wish to add completely new selectors, or even new @media queries, "
237
- "you can enter free-form CSS in the \"New Selector\" textarea. Be aware that "
238
- "your syntax must be correct (i.e., balanced curly braces, etc.) for the "
239
- "parser to load the new styles. You will know it is invalid because a red \"X"
240
- "\" will appear next to the save button.</p>\n"
241
- "<p>If you prefer to use shorthand syntax for rules and values instead of the "
242
- "inputs provided by the Child Theme Configurator, you can enter them here as "
243
- "well. The parser will convert your input into normalized CSS code "
244
- "automatically.</p>\n"
245
- "\t\t\t\t "
246
- msgstr ""
247
-
248
- #: includes/class-ctc-ui.php:428
249
- msgid "@imports"
250
- msgstr ""
251
-
252
- #: includes/class-ctc-ui.php:429
253
- msgid ""
254
- "\n"
255
- "<p>You can add additional stylesheets and web fonts by typing @import rules "
256
- "into the textarea on the @import tab. <strong>Important: The Child Theme "
257
- "Configurator adds the @import rule that loads the Parent Theme's stylesheet "
258
- "automatically. Do not need to add it here.</strong></p>\n"
259
- "<p>Below is an example that loads a local custom stylesheet (you would have "
260
- "to add the \"fonts\" directory and stylesheet) as well as the web font "
261
- "\"Open Sans\" from Google Web Fonts:</p>\n"
262
- "<blockquote><pre><code>\n"
263
- "@import url(fonts/stylesheet.css);\n"
264
- "@import url(http://fonts.googleapis.com/css?family=Open"
265
- "+Sans:400,400italic,700,700italic);\n"
266
- "</code></pre></blockquote>\n"
267
- "\t\t\t\t "
268
- msgstr ""
269
-
270
- #: includes/class-ctc-ui.php:442
271
- msgid "Preview and Activate"
272
- msgstr ""
273
-
274
- #: includes/class-ctc-ui.php:443
275
- msgid ""
276
- "\n"
277
- "<p>Click the View Child or Parent CSS tab to reference the stylesheet code. "
278
- "To preview the stylesheet as a WordPress theme follow these steps:</p>\n"
279
- "<ol><li>Navigate to Appearance > Themes in the WordPress Admin. You will now "
280
- "see the new Child Theme as one of the installed Themes.</li>\n"
281
- "<li>Click \"Live Preview\" below the new Child Theme to see it in action.</"
282
- "li>\n"
283
- "<li>When you are ready to take the Child Theme live, click \"Activate.\"</"
284
- "li></ol>\n"
285
- "\t\t\t\t "
286
- msgstr ""
287
-
288
- #: includes/class-ctc-ui.php:454
289
- msgid "FAQs"
290
- msgstr ""
291
-
292
- #: includes/class-ctc-ui.php:455
293
- msgid ""
294
- "\n"
295
- "<h5 id=\"specific_color\">How do I change a specific color/font style/"
296
- "background?</h5>\n"
297
- "<p>You can override a specific value globally using the Rule/Value tab. See "
298
- "Rule/Value, above.</p>\n"
299
- "<h5 id=\"add_styles\">How do I add styles that aren't in the Parent Theme?</"
300
- "h5>\n"
301
- "<p>You can add queries and selectors using the \"New Selector(s)\" textarea "
302
- "on the Query/Selector tab. See Query/Selector, above.</p>\n"
303
- "<h5 id=\"add_styles\">How do I remove a style from the Parent Theme?</h5>\n"
304
- "<p>You shouldn't really \"remove\" a style from the Parent. You can, "
305
- "however, set the rule to \"inherit,\" \"none,\" or zero (depending on the "
306
- "rule). This will negate the Parent value. Some experimentation may be "
307
- "necessary.</p>\n"
308
- "<h5 id=\"remove_styles\">How do I remove a style from the Child Theme?</h5>\n"
309
- "<p>Delete the value from the input for the rule you wish to remove. The "
310
- "Child Theme Configurator only adds overrides for rules that contain values.</"
311
- "p>\n"
312
- "<h5 id=\"important_flag\">How do I set the !important flag?</h5>\n"
313
- "<p>We always recommend relying on good cascading design over global "
314
- "overrides. To that end, you have ability to change the load order of child "
315
- "theme styles by entering a value in the \"Order\" field. And yes, you can "
316
- "now set rules as important by checking the \"!\" box next to each input. "
317
- "Please use judiciously.</p>\n"
318
- "<h5 id=\"gradients\">How do I create cross-browser gradients?</h5>\n"
319
- "<p>The Child Theme Configurator automatically generates the vendor prefixes "
320
- "and filters to display gradients across most browsers. It uses a normalized "
321
- "syntax and only supports two colors without intermediate stops. The inputs "
322
- "consist of origin (e.g., top, left, 135deg, etc.), start color and end "
323
- "color. The browser-specific syntax is generated automatically when you save "
324
- "these values. <strong>Note:</strong> For Internet Explorer, a filter rule "
325
- "approximates the gradient but can only be horizontal (origin top) or "
326
- "vertical (origin left). The legacy webkit-gradient syntax is not supported.</"
327
- "p>\n"
328
- "<h5 id=\"responsive\">How do I make my Theme responsive?</h5>\n"
329
- "<p>This topic is beyond the scope of this document. The short answer is to "
330
- "use a responsive Parent Theme. Some common characteristics of responsive "
331
- "design are:\n"
332
- "<ul><li>Avoiding fixed width and height values. Using max- and min-height "
333
- "values and percentages are ways to make your designs respond to the viewer's "
334
- "browser size.</li>\n"
335
- "<li>Combining floats and clears with inline and relative positions allow the "
336
- "elements to adjust gracefully to their container's width.</li>\n"
337
- "<li>Showing and hiding content with Javascript.</li></ul>\n"
338
- "<h5 id=\"web_fonts\">How do I add Web Fonts?</h5>\n"
339
- "<p>The easiest method is to paste the @import code provided by Google, Font "
340
- "Squirrel or any other Web Font site into the @import tab. The fonts will "
341
- "then be available to use as a value of the <strong>font-family</strong> "
342
- "rule. Be sure you understand the license for any embedded fonts.</p>\n"
343
- "<p>You can also create a secondary stylesheet that contains @font-face rules "
344
- "and import it using the @import tab. <strong>Note:</strong> Currently the "
345
- "Child Theme Configurator does not generate previews of imported web fonts, "
346
- "but will in a later release.</p>\n"
347
- "<h5 id=\"functions_file\">Where is the functions.php file?</h5>\n"
348
- "<p>You can add your own functions.php file, and any other files and "
349
- "directories you need for your Child Theme. The Child Theme Configurator "
350
- "helps you identify and override the Parent stylesheet without touching the "
351
- "other files.</p>\n"
352
- " "
353
- msgstr ""
354
-
355
- #: includes/class-ctc-ui.php:484
356
- msgid "Glossary"
357
- msgstr ""
358
-
359
- #: includes/class-ctc-ui.php:485
360
- msgid ""
361
- "\n"
362
- "<h3 id=\"terms\">Glossary</h3>\n"
363
- "<ul><li id=\"parent_theme\"><strong>Parent Theme</strong> The WordPress "
364
- "Theme you wish to edit. WordPress first loads the Child Theme, then loads "
365
- "the Parent Theme. If a style exists in the Child Theme, it overrides the "
366
- "Parent Theme.</li>\n"
367
- " <li id=\"child_theme\"><strong>Child Theme</strong> New Theme based on "
368
- "Parent Theme. You can create any number of Child Themes from a single Parent "
369
- "Theme.</li>\n"
370
- " <li id=\"class\"><strong>Class</strong> A term used to organize objects. "
371
- "For example, a &lt;div&gt; might be assigned the \"blue-text\" class. The "
372
- "stylesheet might then assign the \"color: blue;\" rule to members of the "
373
- "\"blue-text\" class. Thus, the &lt;div&gt; would display text as blue in the "
374
- "browser.</li>\n"
375
- " <li id=\"selector\"><strong>Selector</strong> One or more html elements, "
376
- "classes, ids or other terms used to identify groups of objects.</li>\n"
377
- " <li id=\"rule\"><strong>Rule</strong> One of many standardized attributes "
378
- "used to tell the browser how to display objects matching a given selector. "
379
- "Examples are <strong>color</strong>, <strong>background-image</strong> and "
380
- "<strong>font-size</strong>.</li>\n"
381
- "<li id=\"at-rule\"><strong>At-rule</strong> CSS browser instruction to "
382
- "extend default functionality. The Child Theme Configurator supports two At-"
383
- "rules:\n"
384
- "<ul> <li id=\"import\"><strong>@import</strong> Instructs the browser to "
385
- "load additional CSS information from an external source.</li>\n"
386
- " <li id=\"query\"><strong>@media (Media Query)</strong> Identifies blocks of "
387
- "styles that are used only when certain browser characteristics are true. "
388
- "Examples are max-width, screen and print.</li>\n"
389
- "</ul></li>\n"
390
- " <li id=\"override\"><strong>Override</strong> When a selector exists in "
391
- "both the Child Theme and the Parent Theme, the Child Theme takes priority "
392
- "over the Parent theme. This is where the Child Theme Configurator stands "
393
- "out: it helps you create <strong>exact overrides</strong> of selectors from "
394
- "the Parent Theme, eliminating hours of trial and error.</li>\n"
395
- " </ul> \n"
396
- "\t\t\t\t "
397
- msgstr ""
398
-
399
- #: includes/class-ctc-ui.php:506
400
- msgid "Contact us"
401
- msgstr ""
402
-
403
- #: includes/class-ctc-ui.php:507
404
- msgid "Plugin Website"
405
- msgstr ""
406
-
407
- #: includes/class-ctc-ui.php:508
408
- msgid "Donate"
409
- msgstr ""
410
-
411
- #: includes/class-ctc-ui.php:509
412
- msgid "Give Us 5 Stars"
413
- msgstr ""
414
-
415
- #: includes/class-ctc-ui.php:510
416
- msgid "WordPress Codex"
417
- msgstr ""
418
-
419
- #: includes/class-ctc-ui.php:511
420
- msgid "WordPress Answers"
421
- msgstr ""
422
-
423
- #. #-#-#-#-# ctc.pot.txt (Child Theme Configurator 1.2.2) #-#-#-#-#
424
- #. Plugin Name of the plugin/theme
425
- #: includes/class-ctc.php:43
426
- msgid "Child Theme Configurator"
427
- msgstr ""
428
-
429
- #: includes/class-ctc.php:44
430
- msgid "Child Themes"
431
- msgstr ""
432
-
433
- #: includes/class-ctc.php:84
434
- msgid "URL/None"
435
- msgstr ""
436
-
437
- #: includes/class-ctc.php:85
438
- msgid "Origin"
439
- msgstr ""
440
-
441
- #: includes/class-ctc.php:86
442
- msgid "Color 1"
443
- msgstr ""
444
-
445
- #: includes/class-ctc.php:87
446
- msgid "Color 2"
447
- msgstr ""
448
-
449
- #: includes/class-ctc.php:88
450
- msgid "Width"
451
- msgstr ""
452
-
453
- #: includes/class-ctc.php:89
454
- msgid "Style"
455
- msgstr ""
456
-
457
- #: includes/class-ctc.php:90
458
- msgid "Color"
459
- msgstr ""
460
-
461
- #: includes/class-ctc.php:92
462
- msgid "Are you sure? This will replace your current settings."
463
- msgstr ""
464
-
465
- #: includes/class-ctc.php:95
466
- msgid "<span style=\"font-size:10px\">!</span>"
467
- msgstr ""
468
-
469
- #: includes/class-ctc.php:97
470
- msgid "Close"
471
- msgstr ""
472
-
473
- #: includes/class-ctc.php:98
474
- msgid "Edit"
475
- msgstr ""
476
-
477
- #: includes/class-ctc.php:99
478
- msgid "Cancel"
479
- msgstr ""
480
-
481
- #: includes/class-ctc.php:100
482
- msgid "Rename"
483
- msgstr ""
484
-
485
- #: includes/class-ctc.php:101
486
- msgid "The stylesheet cannot be displayed."
487
- msgstr ""
488
-
489
- #: includes/class-ctc.php:102
490
- msgid "(Child Only)"
491
- msgstr ""
492
-
493
- #: includes/class-ctc.php:103
494
- msgid "Please enter a valid Child Theme"
495
- msgstr ""
496
-
497
- #: includes/class-ctc.php:104 includes/class-ctc.php:223
498
- msgid "Please enter a valid Child Theme name"
499
- msgstr ""
500
-
501
- #: includes/class-ctc.php:105
502
- msgid "<strong>%s</strong> exists. Please enter a different Child Theme"
503
- msgstr ""
504
-
505
- #: includes/class-ctc.php:208
506
- msgid "%s does not exist. Please select a valid Parent Theme"
507
- msgstr ""
508
-
509
- #: includes/class-ctc.php:211
510
- msgid "Please select a valid Parent Theme"
511
- msgstr ""
512
-
513
- #: includes/class-ctc.php:216
514
- msgid ""
515
- "<strong>%s</strong> exists. Please enter a different Child Theme template "
516
- "name"
517
- msgstr ""
518
-
519
- #: includes/class-ctc.php:220
520
- msgid "Please enter a valid Child Theme template name"
521
- msgstr ""
522
-
523
- #: includes/class-ctc.php:226
524
- msgid "You do not have permission to configure child themes."
525
- msgstr ""
526
-
527
- #: includes/class-ctc.php:238
528
- msgid ""
529
- "Your theme directory is not writable. Please adjust permissions and try "
530
- "again."
531
- msgstr ""
532
-
533
- #: includes/class-ctc.php:245
534
- msgid "Child Theme %s was unchanged."
535
- msgstr ""
536
-
537
- #. Plugin URI of the plugin/theme
538
- msgid "http://www.lilaeamedia.com/plugins/child-theme-configurator/"
539
- msgstr ""
540
-
541
- #. Description of the plugin/theme
542
- msgid ""
543
- "Create a Child Theme from any installed Theme. Each CSS selector, rule and "
544
- "value can then be searched, previewed and modified."
545
- msgstr ""
546
-
547
- #. Author of the plugin/theme
548
- msgid "Lilaea Media"
549
- msgstr ""
550
-
551
- #. Author URI of the plugin/theme
552
- msgid "http://www.lilaeamedia.com/"
553
- msgstr ""
1
+ # Copyright (C) 2013 Lilaea Media LLC
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.0.0\n"
6
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/intelliwidget\n"
7
+ "POT-Creation-Date: 2013-10-16 00:01+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: 2013-MO-DA HO:MI+ZONE\n"
12
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
  "Language-Team: LANGUAGE <LL@li.org>\n"
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -2,24 +2,19 @@
2
  Contributors: lilaeamedia
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8QE5YJ8WE96AJ
4
  Tags: child theme, custom theme, CSS, responsive design, CSS editor, theme generator
5
- Requires at least: 3.7
6
- Tested up to: 3.8.2
7
- Stable tag: 1.3.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
- Create a Child Theme from any installed Theme. Each CSS selector, rule and value can then be searched, previewed and modified.
12
 
13
  == Description ==
14
 
15
- Created by Lilaea Media, the team that brought you IntelliWidget, the Child Theme Configurator provides a new approach to WordPress stylesheets. The Child Theme Configurator lets you identify and override only the Parent Theme style attributes you want to change. It gives you unlimited control over your WordPress look and feel while leaving your Parent Theme untouched.
16
-
17
- = Now it works with plugins! =
18
-
19
- We offer a premium extension to let you 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. Learn more at http://www.lilaeamedia.com/plugins/child-theme-plugin-styles
20
-
21
- The Child Theme Configurator parses and indexes a Theme's stylesheet so that every media query, selector, rule and value are at your fingertips. Second, it shows you how each change you make will look before you commit it to the Child Theme.Finally, it saves your work so that you can fine-tune your Child Theme without the risk of losing your edits.
22
 
 
23
  You can create any number of Child Themes from any existing Parent Theme. The Child Theme Configurator lets you choose from your installed themes (even existing Child Themes) and save the results in your Themes directory.
24
 
25
  When you are ready, just activate the Child Theme and your WordPress site takes on the new look and feel automatically.
@@ -37,6 +32,7 @@ Why create Child Themes using the Child Theme Configurator?
37
  * Import web fonts and use them in place of Theme fonts
38
  * Save hours of development time
39
 
 
40
  == Installation ==
41
 
42
  1. Download the Child Theme Configurator plugin archive and unzip it.
@@ -45,87 +41,31 @@ Why create Child Themes using the Child Theme Configurator?
45
 
46
  == Frequently Asked Questions ==
47
 
48
- = Does it work with plugins? =
49
-
50
- We offer a premium extension to let you 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. Learn more at http://www.lilaeamedia.com/plugins/child-theme-plugin-styles
51
-
52
- = Is there a tutorial? =
53
-
54
- https://www.youtube.com/watch?v=xL2HkWQxgOA
55
-
56
- = Why doesn't this work with my (insert theme vendor here) theme? =
57
-
58
- Some themes (particularly commercial themes) do not adhere to the Theme Development guidelines set forth by WordPress.org, and do not automatically load child theme stylesheets or php files. This is unfortunate, because it effectively prohibits the webmaster from adding any customizations (other than those made through the admin theme options) that will survive past an upgrade.
59
-
60
- Contact the vendor directly to ask for this core functionality. It is our opinion that ALL themes (especially commercial ones) must pass the Theme Unit Tests outlined by WordPress.org.
61
-
62
- = Why doesn't the Parent Theme have any styles when I "View Parent CSS"? =
63
-
64
- Your Parent theme is probably using a non-standard location for the stylesheets. Check "Scan Parent Theme for additional stylesheets" on the Parent/Child tab and load the Child Theme again.
65
-
66
- = Why is everything backwards? =
67
-
68
- More than likely you selected "Scan Parent Theme for additional stylesheets" and your theme uses a "right-to-left" (rtl) stylesheet. Go to the @imports tab and remove the rtl stylesheet from the list of imported stylesheets.
69
-
70
- = Where is it in the Admin? =
71
-
72
- The Child Theme Configurator can be found under the "Tools" menu in the WordPress Admin. Click "Child Themes" to get started.
73
- Click the "Help" tab at the top right for a quick reference.
74
 
75
- = Where are the styles? The configurator doesn't show anything! =
76
 
77
- All of the styles are loaded dynamically. You must start typing in the text boxes to select styles to edit.
78
- "Base" is the query group that contains styles that are not associated with any particular "At-rule."
79
 
80
- Start by clicking the "Query/Selector" tab and typing "base" in the first box. You can then start typing in the second box to retrieve the style selectors to edit.
81
 
82
- = Why do the preview tabs return "Stylesheet could not be displayed"? =
83
 
84
- You have to load a child theme from the Parent/Child tab for the preview to display. This can also happen when your WP_CONTENT_URL is different than $bloginfo('site_url'). Ajax cannot make cross-domain requests by default. Check that your Settings > General > "WordPress Address (URL)" value is correct. (Often caused by missing "www" in the domain.)
85
 
86
- = Can I edit the Child Theme stylesheet manually offline or by using the Editor or do I have to use the Configurator? =
87
 
88
- You can make any manual changes you wish to the stylesheet. Just make sure you import the revised stylesheet using the Parent/Child panel or the Configurator will overwrite your changes the next time you use it. Just follow the steps as usual but select the "Use Existing Child Theme" radio button as the "Child Theme" option. The Configurator will automatically update its internal data from the new stylesheet.
89
 
90
- = Why are my menus displaying incorrectly when I activate the new child theme? =
91
-
92
- The child theme creates a new instance in the WordPress options data and the menus have to be assigned. Go to Appearance > Menus and assign locations to each of the menus for the new Child Theme.
93
-
94
- = If the parent theme changes (e.g., upgrade), do I have to update the child theme? =
95
-
96
- No. This is the point of using child themes. Changes to the parent theme are automatically inherited by the child theme.
97
-
98
- A child theme is not a "copy" of the parent theme. It is a special feature of WordPress that let's you override specific styles and functions leaving the rest of the theme intact. The only time you need to make changes after an upgrade is if the parent removes or changes style or function names. Quality themes should identify any deprecated functions or styles in the upgrade notes so that child theme users can make adjustments accordingly.
99
-
100
- = Where are the .php files? =
101
-
102
- The configurator automatically adds a blank functions.php file to the child theme directory. You can add any additional files and directories you need for your Child Theme. The Child Theme Configurator helps you identify and override selectors in the Parent stylesheet without touching the other files.
103
-
104
- = How do I change a specific color/font style/background? =
105
-
106
- You can override a specific value globally using the Rule/Value tab. See Rule/Value, above.
107
-
108
- = How do I add styles that aren't in the Parent Theme? =
109
-
110
- You can add queries and selectors using the "Raw CSS" textarea on the Query/Selector tab. See Query/Selector, above.
111
-
112
- = How do I remove a style from the Parent Theme? =
113
-
114
- You shouldn't really "remove" a style from the Parent. You can, however, set the rule to "inherit," "none," or zero (depending on the rule). This will negate the Parent value. Some experimentation may be necessary.
115
-
116
- = How do I remove a style from the Child Theme? =
117
 
118
  Delete the value from the input for the rule you wish to remove. The Child Theme Configurator only adds overrides for rules that contain values.
119
 
120
- = How do I set the !important flag? =
121
-
122
- We always recommend relying on good cascading design over global overrides. To that end, you have ability to change the load order of child theme styles by entering a value in the "Order" field. And yes, you can now set rules as important by checking the "!" box next to each input. Please use judiciously.
123
-
124
- = How do I create cross-browser gradients? =
125
 
126
  The Child Theme Configurator uses a standardized syntax for gradients and only supports two-color gradients without intermediate stops. The inputs consist of origin (e.g., top, left, 135deg, etc.), start color and end color. The browser-specific syntax is generated automatically when you save these values. See Caveats, below, for more information.
127
 
128
- = How do I make my Theme responsive? =
129
 
130
  This topic is beyond the scope of this document. The short answer is to use a responsive Parent Theme. Some common characteristics of responsive design are:
131
 
@@ -133,9 +73,9 @@ This topic is beyond the scope of this document. The short answer is to use a re
133
  * Combining floats and clears with inline and relative positions allow the elements to adjust gracefully to their container's width.
134
  * Showing and hiding content with Javascript.
135
 
136
- = How do I add Web Fonts? =
137
 
138
- The easiest method is to paste the @import code provided by Google, Font Squirrel or any other Web Font site into the @import tab. The fonts will then be available to use as a value of the font-family rule. Be sure you understand the license for any embedded fonts.
139
 
140
  You can also create a secondary stylesheet that contains @font-face rules and import it using the @import tab.
141
 
@@ -149,111 +89,26 @@ You can also create a secondary stylesheet that contains @font-face rules and im
149
 
150
  == Changelog ==
151
 
152
- = 1.3.4 =
153
- * Fixes a bug with the way the @import data is stored that threw errors on php 5.3 and corrupted v1.3.2 @import data.
154
-
155
- = 1.3.3 =
156
- * New Feature: option to scan parent theme for additional stylesheets. This allows CTC to be used with themes such as "Responsive" by CyberChimps.
157
- * New Feature: automatically copies parent theme screenshot to child.
158
-
159
- = 1.3.2 =
160
- * Fixed unquoted regex pattern in file path security check function. Thanks to buzcuz for reporting this.
161
-
162
- = 1.3.1 =
163
- * Updated help tab content. Added additional sanitization of source and target file paths.
164
-
165
- = 1.3.0 =
166
- * Changed CSS preview to retrieve directly from WordPress Admin instead of remote http GET to prevent caching issues.
167
- * Added loading icon for CSS preview.
168
- * Fixed JS type error on backup toggle.
169
- * Improved extensibility throughout.
170
-
171
- = 1.2.3 =
172
- * Replace PHP short tags with standard codes.
173
-
174
- = 1.2.2 =
175
- * New Features: You can now rename selectors in place from the Query/Selector panel. Made stylesheet backup optional. Bugs fixed: Incorrect parsing of background position when '0', fixed type error when background image url value is removed.
176
-
177
- = 1.2.1 =
178
- * Bugs fixed: "star hack" rules no longer throwing js error. Important flag now works on borders and gradients.
179
-
180
- = 1.2.0 =
181
- * New features: Link to Query/Selector tab from specific Rule/Value selector, new rule focus on adding new rule. Bugs fixed: clear Query/Selector inputs when loaded selector is empty, use latest min.js script.
182
-
183
- = 1.1.9 =
184
- * Added check for writability before attempting to create child theme files to avoid fatal error on servers not running suEXEC. Fixed a bug in the ctc_update_cache function that was throwing a fatal JS error when new media queries were saved via the Raw CSS input. Configurator now adds functions.php file to child theme when it does not exist.
185
-
186
- = 1.1.8 =
187
- * Added reorder sequence and important flag functionality. Fixed bug where multiple inputs with same selector/rule combo were assigned the same id. Fixed bug in the shorthand encoding routine.
188
-
189
- = 1.1.7 =
190
- * Added tutorial video to help tabs.
191
-
192
- = 1.1.6 =
193
- * Added call to reset_updates() before update_option() to prevent serialization errors.
194
-
195
- = 1.1.5 =
196
- * Query/Selector panel now defaults to 'base'
197
- * Fixed bug causing background-image with full urls (http://) to be parsed as gradients
198
- * Fixed bug causing rule menu to throw error when selector has no rules
199
-
200
- = 1.1.4 =
201
- * Fixed sort bug in shorthand parser that was returning rules in wrong order
202
-
203
- = 1.1.3 =
204
- * Fixed bug that assumed lowercase only for theme slugs. (Thanks to timk)
205
- * Fixed update redirect to execute on first run
206
-
207
- = 1.1.2 =
208
- * Small bug fix to javascript (casting number to string)
209
-
210
- = 1.1.1 =
211
- * Fixed major bug where inputs containing '0' were being ignored
212
- * Removed "no leading digits" requirement for theme slug
213
- * Change query sort function to keep parent order of queries without device width rules
214
- * Fixed gettext calls to use static namespace parameter
215
- * Auto populate child theme inputs when existing theme is selected
216
- * Correctly remove border when values are blanked
217
- * Fixed duplicate "new rule" bug on Query/Selector panel
218
- * added timestamp to backup file
219
- * Added encode_shorthand function to recombine margin/padding values when all 4 sides are present
220
-
221
- = 1.1.0 =
222
- * Corrected parsing for certain backgrounds and gradients (e.g., supports hsla color syntax)
223
- * Handle empty selectors
224
- * Ajax load for menus and updates
225
- * Clean up Parent/Child form UI and validation
226
- * Streamlined UI overall
227
-
228
- = 1.0.1 =
229
- * Updates to Readme.txt
230
 
231
  = 1.0.0 =
232
  * Initial release.
233
 
234
  == Upgrade Notice ==
235
- = 1.3.3+ =
236
- * This version adds the ability to parse additional stylesheets from the Parent theme as well as the main style.css file.
 
237
 
238
  == Create Your Child Theme ==
239
 
240
  The first step is to create a child theme and import your parent theme styles into the configurator.
241
 
242
  1. Select an existing parent theme from the menu.
243
- 2. Select "New" or "Existing" child theme.
244
- * If creating a new theme, enter a "slug" (lower case, no spaces). This is used to name the theme directory and identify the theme to WordPress.
245
- * If using an existing theme, select a child theme from the menu.
246
- 3. Enter a Name for the child theme.
247
- 4. Enter an author for the child theme.
248
- 5. Enter the child theme version number.
249
- 6. Check "Backup Stylesheet" if you want to backup original version of child stylesheet.
250
- 7. Check "Scan Parent Theme for Additional Stylesheets" if your theme uses multiple stylesheets or if the the stylesheets are in a non-standard location. For example, the "Responsive" theme puts the stylesheets in a subdirectory named "core."
251
- 8. Click "Generate Child Theme Files."
252
-
253
- If you are loading an existing child theme and checked "Backup Stylesheet," the Child Theme Configurator will create a backup of your existing stylesheet in the theme directory.
254
-
255
- If you checked "Scan Parent Theme for additional stylesheets," the "@import" tab will appear automatically. Important: Any additional stylesheets are added as imports here. If your theme has a "right-to-left" stylesheet, it will appear here as well. Remove any @import statements that are not needed by the front end, such as admin or configuration stylesheets.
256
-
257
 
258
  == Override Parent Styles ==
259
 
@@ -266,8 +121,6 @@ Next, find the selector by typing in the Selector autoselect box. Select by clic
266
 
267
  This will load all of the rules for that selector with the Parent values on the left and the Child values inputs on the right. Any existing child values will be automatically populated. There is also a Sample preview that displays the combination of Parent and Child overrides. Note that the border and background-image get special treatment.
268
 
269
- The "Order" field contains the original sequence of the selector in the parent theme stylesheet. You can change the selector order sequence by entering a lower or higher number in the "Order" field. You can also force style overrides (so called "!important" flag) by checking the "!" box next to each input. Please use judiciously.
270
-
271
  Click "Save" to update the child stylesheet and save your changes to the WordPress admin.
272
 
273
  = Rule/Value =
@@ -292,10 +145,7 @@ If you prefer to use shorthand syntax for rules and values instead of the inputs
292
 
293
  You can add additional stylesheets and web fonts by typing @import rules into the textarea on the @import tab. Important: The Child Theme Configurator adds the @import rule that loads the Parent Theme's stylesheet automatically. Do not need to add it here.
294
 
295
- If you checked "Scan Parent Theme for additional stylesheets" when you created your child theme, the "@import" tab will appear automatically. Important: By default, any additional stylesheets are added as imports. If your theme has a "right-to-left" stylesheet, it will appear here as well. In many cases, the theme will automatically load the additional stylesheets, so you do not need to import them (for example, the "Responsive" theme). Remove any @import statements that are not needed by the front end, such as admin or configuration stylesheets, or, as in the case described above, any stylesheets that are automatically loaded by the Theme.
296
-
297
  == Preview and Activate ==
298
-
299
  Click the Preview CSS tab to see your new masterpiece as CSS code. To preview the stylesheet as a WordPress theme follow these steps:
300
 
301
  1. Navigate to Appearance > Themes in the WordPress Admin. You will now see the new Child Theme as one of the installed Themes.
@@ -313,5 +163,3 @@ Click the Preview CSS tab to see your new masterpiece as CSS code. To preview th
313
  == Documentation ==
314
 
315
  Go to http://www.lilaeamedia.com/plugins/child-theme-configurator
316
-
317
- Copyright: (C) 2014 Lilaea Media
2
  Contributors: lilaeamedia
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8QE5YJ8WE96AJ
4
  Tags: child theme, custom theme, CSS, responsive design, CSS editor, theme generator
5
+ Requires at least: 3.5
6
+ Tested up to: 3.8
7
+ Stable tag: 1.0.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
+ Create a Child Theme from any installed Theme by parsing and indexing its stylesheet. Each selector, rule and value can then be searched, previewed and modified.
12
 
13
  == Description ==
14
 
15
+ Created by Lilaea Media, the team that brought you IntelliWidget, the Child Theme Configurator provides a new approach to WordPress stylesheets. The Childe Theme Configurator lets you identify and override only the Parent Theme style attributes you want to change. It gives you unlimited control over your WordPress look and feel while leaving your Parent Theme untouched.
 
 
 
 
 
 
16
 
17
+ The Child Theme Configurator attacks this challenge from a new angle. First, it parses and indexes a Theme's stylesheet so that every media query, selector, rule and value are at your fingertips. Second, it shows you how each change you make will look before you commit it to the Child Theme.Finally, it saves your work so that you can fine-tune your Child Theme without the risk of losing your edits.
18
  You can create any number of Child Themes from any existing Parent Theme. The Child Theme Configurator lets you choose from your installed themes (even existing Child Themes) and save the results in your Themes directory.
19
 
20
  When you are ready, just activate the Child Theme and your WordPress site takes on the new look and feel automatically.
32
  * Import web fonts and use them in place of Theme fonts
33
  * Save hours of development time
34
 
35
+
36
  == Installation ==
37
 
38
  1. Download the Child Theme Configurator plugin archive and unzip it.
41
 
42
  == Frequently Asked Questions ==
43
 
44
+ = Where is the functions.php file? =
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
+ You can add your own functions.php file, and any other files and directories you need for your Child Theme. The Child Theme Configurator helps you identify and override selectors in the Parent stylesheet without touching the other files.
47
 
48
+ = How Do I change a specific color/font style/background? =
 
49
 
50
+ You can override a specific value globally using the Rule/Value tab. See "Rule/Value," below.
51
 
52
+ = How Do I add styles that aren't in the Parent Theme? =
53
 
54
+ You can add queries and selectors using the "New Selector(s)" textarea on the Query/Selector tab. See "Query/Selector," below.
55
 
56
+ = How Do I remove a style from the Parent Theme? =
57
 
58
+ You can't really "remove" a style from the Parent. You can, however, set the rule to "inherit," "none," or zero (depending on the rule). This will negate the Parent value. Some experimentation may be necessary.
59
 
60
+ = How Do I remove a style from the Child Theme? =
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
  Delete the value from the input for the rule you wish to remove. The Child Theme Configurator only adds overrides for rules that contain values.
63
 
64
+ = How Do I create cross-browser gradients? =
 
 
 
 
65
 
66
  The Child Theme Configurator uses a standardized syntax for gradients and only supports two-color gradients without intermediate stops. The inputs consist of origin (e.g., top, left, 135deg, etc.), start color and end color. The browser-specific syntax is generated automatically when you save these values. See Caveats, below, for more information.
67
 
68
+ = How Do I make my Theme responsive? =
69
 
70
  This topic is beyond the scope of this document. The short answer is to use a responsive Parent Theme. Some common characteristics of responsive design are:
71
 
73
  * Combining floats and clears with inline and relative positions allow the elements to adjust gracefully to their container's width.
74
  * Showing and hiding content with Javascript.
75
 
76
+ = How Do I add Web Fonts? =
77
 
78
+ The easiest method is to paste the @import code provided by Google, Font Squirrel or any other Web Font site into the @import tab. The fonts will then be available to use as a value of the font-family rule. Be sure you understand the license for any embedded fonts.
79
 
80
  You can also create a secondary stylesheet that contains @font-face rules and import it using the @import tab.
81
 
89
 
90
  == Changelog ==
91
 
92
+ == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
 
94
  = 1.0.0 =
95
  * Initial release.
96
 
97
  == Upgrade Notice ==
98
+
99
+ = 1.0.0 =
100
+ * Initial release.
101
 
102
  == Create Your Child Theme ==
103
 
104
  The first step is to create a child theme and import your parent theme styles into the configurator.
105
 
106
  1. Select an existing parent theme from the menu.
107
+ 2. Select an existing child theme from the menu, or "New Theme" if you are creating one from scratch.
108
+ 3. Enter an author for the child theme.
109
+ 4. If this is a new theme, enter a Name.
110
+ 5. If this is a new theme, enter a "slug" (lower case, no spaces). This is used to name the theme directory and identify the theme to WordPress.
111
+ 6. Click "Load Styles." If you are loading an existing child theme, The Child Theme Configurator will create a backup of your existing stylesheet in the theme directory.
 
 
 
 
 
 
 
 
 
112
 
113
  == Override Parent Styles ==
114
 
121
 
122
  This will load all of the rules for that selector with the Parent values on the left and the Child values inputs on the right. Any existing child values will be automatically populated. There is also a Sample preview that displays the combination of Parent and Child overrides. Note that the border and background-image get special treatment.
123
 
 
 
124
  Click "Save" to update the child stylesheet and save your changes to the WordPress admin.
125
 
126
  = Rule/Value =
145
 
146
  You can add additional stylesheets and web fonts by typing @import rules into the textarea on the @import tab. Important: The Child Theme Configurator adds the @import rule that loads the Parent Theme's stylesheet automatically. Do not need to add it here.
147
 
 
 
148
  == Preview and Activate ==
 
149
  Click the Preview CSS tab to see your new masterpiece as CSS code. To preview the stylesheet as a WordPress theme follow these steps:
150
 
151
  1. Navigate to Appearance > Themes in the WordPress Admin. You will now see the new Child Theme as one of the installed Themes.
163
  == Documentation ==
164
 
165
  Go to http://www.lilaeamedia.com/plugins/child-theme-configurator
 
 
screenshot-1.jpg CHANGED
Binary file
screenshot-2.jpg CHANGED
Binary file
screenshot-3.jpg CHANGED
Binary file
screenshot-4.jpg CHANGED
Binary file
screenshot-5.jpg CHANGED
Binary file