Version Description
- New: Option to reset all settings.
- New: Option to enable debug mode to help when responding to support tickets.
Download this release
Release Info
Developer | pdclark |
Plugin | Styles |
Version | 1.1.7 |
Comparing to | |
See all releases |
Code changes from version 1.1.6 to 1.1.7
- classes/csstidy/class.csstidy.php +1241 -1241
- classes/csstidy/class.csstidy_ctype.php +45 -45
- classes/csstidy/class.csstidy_optimise.php +936 -936
- classes/csstidy/class.csstidy_print.php +408 -408
- classes/csstidy/cssparse.css +117 -117
- classes/csstidy/cssparsed.css +28 -28
- classes/csstidy/data-wp.inc.php +75 -75
- classes/csstidy/data.inc.php +661 -661
- classes/csstidy/lang.inc.php +311 -311
- classes/edd-sl-plugin-updater.php +139 -139
- classes/styles-admin.php +403 -199
- classes/styles-child-theme.php +157 -157
- classes/styles-child-updatable.php +194 -194
- classes/styles-child.php +111 -111
- classes/styles-control-background-color.php +57 -57
- classes/styles-control-border-bottom-color.php +12 -12
- classes/styles-control-border-color.php +28 -28
- classes/styles-control-border-left-color.php +12 -12
- classes/styles-control-border-right-color.php +12 -12
- classes/styles-control-border-top-color.php +12 -12
- classes/styles-control-color.php +56 -56
- classes/styles-control-text.php +173 -173
- classes/styles-control.php +231 -231
- classes/styles-css.php +122 -122
- classes/styles-customize.php +180 -180
- classes/styles-debug.php +168 -0
- classes/styles-font-menu/classes/markdown/License.text +36 -36
- classes/styles-font-menu/classes/markdown/License.txt +36 -36
- classes/styles-font-menu/classes/markdown/PHP Markdown Extra Readme.txt +879 -879
- classes/styles-font-menu/classes/markdown/PHP Markdown Readme.txt +785 -785
- classes/styles-font-menu/classes/markdown/markdown.php +1742 -1742
- classes/styles-font-menu/classes/sfm-admin.php +54 -54
- classes/styles-font-menu/classes/sfm-group-google.php +188 -188
- classes/styles-font-menu/classes/sfm-group-standard.php +56 -56
- classes/styles-font-menu/classes/sfm-group.php +38 -38
- classes/styles-font-menu/classes/sfm-image-preview.php +145 -145
- classes/styles-font-menu/classes/sfm-plugin.php +172 -172
- classes/styles-font-menu/classes/sfm-single-google.php +261 -261
- classes/styles-font-menu/classes/sfm-single-standard.php +114 -114
- classes/styles-font-menu/css/styles-font-menu.css +45 -45
- classes/styles-font-menu/js/chosen/chosen.css +430 -430
- classes/styles-font-menu/js/chosen/chosen.jquery.js +1166 -1166
- classes/styles-font-menu/js/chosen/chosen.jquery.min.js +1 -1
- classes/styles-font-menu/js/chosen/chosen.min.css +2 -2
- classes/styles-font-menu/js/google-fonts-api-fallback.json +0 -1
classes/csstidy/class.csstidy.php
CHANGED
@@ -1,1241 +1,1241 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* CSSTidy - CSS Parser and Optimiser
|
5 |
-
*
|
6 |
-
* CSS Parser class
|
7 |
-
*
|
8 |
-
* Copyright 2005, 2006, 2007 Florian Schmitz
|
9 |
-
*
|
10 |
-
* This file is part of CSSTidy.
|
11 |
-
*
|
12 |
-
* CSSTidy is free software; you can redistribute it and/or modify
|
13 |
-
* it under the terms of the GNU Lesser General Public License as published by
|
14 |
-
* the Free Software Foundation; either version 2.1 of the License, or
|
15 |
-
* (at your option) any later version.
|
16 |
-
*
|
17 |
-
* CSSTidy is distributed in the hope that it will be useful,
|
18 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
19 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
20 |
-
* GNU Lesser General Public License for more details.
|
21 |
-
*
|
22 |
-
* You should have received a copy of the GNU Lesser General Public License
|
23 |
-
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
24 |
-
*
|
25 |
-
* @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
|
26 |
-
* @package csstidy
|
27 |
-
* @author Florian Schmitz (floele at gmail dot com) 2005-2007
|
28 |
-
* @author Brett Zamir (brettz9 at yahoo dot com) 2007
|
29 |
-
* @author Nikolay Matsievsky (speed at webo dot name) 2009-2010
|
30 |
-
* @author Cedric Morin (cedric at yterium dot com) 2010
|
31 |
-
*/
|
32 |
-
/**
|
33 |
-
* Defines ctype functions if required
|
34 |
-
*
|
35 |
-
* @version 1.0
|
36 |
-
*/
|
37 |
-
require_once('class.csstidy_ctype.php');
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Various CSS data needed for correct optimisations etc.
|
41 |
-
*
|
42 |
-
* @version 1.3
|
43 |
-
*/
|
44 |
-
require('data.inc.php');
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Contains a class for printing CSS code
|
48 |
-
*
|
49 |
-
* @version 1.0
|
50 |
-
*/
|
51 |
-
require('class.csstidy_print.php');
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Contains a class for optimising CSS code
|
55 |
-
*
|
56 |
-
* @version 1.0
|
57 |
-
*/
|
58 |
-
require('class.csstidy_optimise.php');
|
59 |
-
|
60 |
-
/**
|
61 |
-
* CSS Parser class
|
62 |
-
*
|
63 |
-
|
64 |
-
* This class represents a CSS parser which reads CSS code and saves it in an array.
|
65 |
-
* In opposite to most other CSS parsers, it does not use regular expressions and
|
66 |
-
* thus has full CSS2 support and a higher reliability.
|
67 |
-
* Additional to that it applies some optimisations and fixes to the CSS code.
|
68 |
-
* An online version should be available here: http://cdburnerxp.se/cssparse/css_optimiser.php
|
69 |
-
* @package csstidy
|
70 |
-
* @author Florian Schmitz (floele at gmail dot com) 2005-2006
|
71 |
-
* @version 1.3.1
|
72 |
-
*/
|
73 |
-
class csstidy {
|
74 |
-
|
75 |
-
/**
|
76 |
-
* Saves the parsed CSS. This array is empty if preserve_css is on.
|
77 |
-
* @var array
|
78 |
-
* @access public
|
79 |
-
*/
|
80 |
-
var $css = array();
|
81 |
-
/**
|
82 |
-
* Saves the parsed CSS (raw)
|
83 |
-
* @var array
|
84 |
-
* @access private
|
85 |
-
*/
|
86 |
-
var $tokens = array();
|
87 |
-
/**
|
88 |
-
* Printer class
|
89 |
-
* @see csstidy_print
|
90 |
-
* @var object
|
91 |
-
* @access public
|
92 |
-
*/
|
93 |
-
var $print;
|
94 |
-
/**
|
95 |
-
* Optimiser class
|
96 |
-
* @see csstidy_optimise
|
97 |
-
* @var object
|
98 |
-
* @access private
|
99 |
-
*/
|
100 |
-
var $optimise;
|
101 |
-
/**
|
102 |
-
* Saves the CSS charset (@charset)
|
103 |
-
* @var string
|
104 |
-
* @access private
|
105 |
-
*/
|
106 |
-
var $charset = '';
|
107 |
-
/**
|
108 |
-
* Saves all @import URLs
|
109 |
-
* @var array
|
110 |
-
* @access private
|
111 |
-
*/
|
112 |
-
var $import = array();
|
113 |
-
/**
|
114 |
-
* Saves the namespace
|
115 |
-
* @var string
|
116 |
-
* @access private
|
117 |
-
*/
|
118 |
-
var $namespace = '';
|
119 |
-
/**
|
120 |
-
* Contains the version of csstidy
|
121 |
-
* @var string
|
122 |
-
* @access private
|
123 |
-
*/
|
124 |
-
var $version = '1.3';
|
125 |
-
/**
|
126 |
-
* Stores the settings
|
127 |
-
* @var array
|
128 |
-
* @access private
|
129 |
-
*/
|
130 |
-
var $settings = array();
|
131 |
-
/**
|
132 |
-
* Saves the parser-status.
|
133 |
-
*
|
134 |
-
* Possible values:
|
135 |
-
* - is = in selector
|
136 |
-
* - ip = in property
|
137 |
-
* - iv = in value
|
138 |
-
* - instr = in string (started at " or ' or ( )
|
139 |
-
* - ic = in comment (ignore everything)
|
140 |
-
* - at = in @-block
|
141 |
-
*
|
142 |
-
* @var string
|
143 |
-
* @access private
|
144 |
-
*/
|
145 |
-
var $status = 'is';
|
146 |
-
/**
|
147 |
-
* Saves the current at rule (@media)
|
148 |
-
* @var string
|
149 |
-
* @access private
|
150 |
-
*/
|
151 |
-
var $at = '';
|
152 |
-
/**
|
153 |
-
* Saves the current selector
|
154 |
-
* @var string
|
155 |
-
* @access private
|
156 |
-
*/
|
157 |
-
var $selector = '';
|
158 |
-
/**
|
159 |
-
* Saves the current property
|
160 |
-
* @var string
|
161 |
-
* @access private
|
162 |
-
*/
|
163 |
-
var $property = '';
|
164 |
-
/**
|
165 |
-
* Saves the position of , in selectors
|
166 |
-
* @var array
|
167 |
-
* @access private
|
168 |
-
*/
|
169 |
-
var $sel_separate = array();
|
170 |
-
/**
|
171 |
-
* Saves the current value
|
172 |
-
* @var string
|
173 |
-
* @access private
|
174 |
-
*/
|
175 |
-
var $value = '';
|
176 |
-
/**
|
177 |
-
* Saves the current sub-value
|
178 |
-
*
|
179 |
-
* Example for a subvalue:
|
180 |
-
* background:url(foo.png) red no-repeat;
|
181 |
-
* "url(foo.png)", "red", and "no-repeat" are subvalues,
|
182 |
-
* seperated by whitespace
|
183 |
-
* @var string
|
184 |
-
* @access private
|
185 |
-
*/
|
186 |
-
var $sub_value = '';
|
187 |
-
/**
|
188 |
-
* Array which saves all subvalues for a property.
|
189 |
-
* @var array
|
190 |
-
* @see sub_value
|
191 |
-
* @access private
|
192 |
-
*/
|
193 |
-
var $sub_value_arr = array();
|
194 |
-
/**
|
195 |
-
* Saves the stack of characters that opened the current strings
|
196 |
-
* @var array
|
197 |
-
* @access private
|
198 |
-
*/
|
199 |
-
var $str_char = array();
|
200 |
-
var $cur_string = array();
|
201 |
-
/**
|
202 |
-
* Status from which the parser switched to ic or instr
|
203 |
-
* @var array
|
204 |
-
* @access private
|
205 |
-
*/
|
206 |
-
var $from = array();
|
207 |
-
/**
|
208 |
-
/**
|
209 |
-
* =true if in invalid at-rule
|
210 |
-
* @var bool
|
211 |
-
* @access private
|
212 |
-
*/
|
213 |
-
var $invalid_at = false;
|
214 |
-
/**
|
215 |
-
* =true if something has been added to the current selector
|
216 |
-
* @var bool
|
217 |
-
* @access private
|
218 |
-
*/
|
219 |
-
var $added = false;
|
220 |
-
/**
|
221 |
-
* Array which saves the message log
|
222 |
-
* @var array
|
223 |
-
* @access private
|
224 |
-
*/
|
225 |
-
var $log = array();
|
226 |
-
/**
|
227 |
-
* Saves the line number
|
228 |
-
* @var integer
|
229 |
-
* @access private
|
230 |
-
*/
|
231 |
-
var $line = 1;
|
232 |
-
/**
|
233 |
-
* Marks if we need to leave quotes for a string
|
234 |
-
* @var array
|
235 |
-
* @access private
|
236 |
-
*/
|
237 |
-
var $quoted_string = array();
|
238 |
-
|
239 |
-
/**
|
240 |
-
* List of tokens
|
241 |
-
* @var string
|
242 |
-
*/
|
243 |
-
var $tokens_list = "";
|
244 |
-
/**
|
245 |
-
* Loads standard template and sets default settings
|
246 |
-
* @access private
|
247 |
-
* @version 1.3
|
248 |
-
*/
|
249 |
-
function csstidy() {
|
250 |
-
$this->settings['remove_bslash'] = true;
|
251 |
-
$this->settings['compress_colors'] = true;
|
252 |
-
$this->settings['compress_font-weight'] = true;
|
253 |
-
$this->settings['lowercase_s'] = false;
|
254 |
-
/*
|
255 |
-
1 common shorthands optimization
|
256 |
-
2 + font property optimization
|
257 |
-
3 + background property optimization
|
258 |
-
*/
|
259 |
-
$this->settings['optimise_shorthands'] = 1;
|
260 |
-
$this->settings['remove_last_;'] = true;
|
261 |
-
/* rewrite all properties with low case, better for later gzip OK, safe*/
|
262 |
-
$this->settings['case_properties'] = 1;
|
263 |
-
/* sort properties in alpabetic order, better for later gzip
|
264 |
-
* but can cause trouble in case of overiding same propertie or using hack
|
265 |
-
*/
|
266 |
-
$this->settings['sort_properties'] = false;
|
267 |
-
/*
|
268 |
-
1, 3, 5, etc -- enable sorting selectors inside @media: a{}b{}c{}
|
269 |
-
2, 5, 8, etc -- enable sorting selectors inside one CSS declaration: a,b,c{}
|
270 |
-
preserve order by default cause it can break functionnality
|
271 |
-
*/
|
272 |
-
$this->settings['sort_selectors'] = 0;
|
273 |
-
/* is dangeroues to be used: CSS is broken sometimes */
|
274 |
-
$this->settings['merge_selectors'] = 0;
|
275 |
-
/* preserve or not browser hacks */
|
276 |
-
$this->settings['discard_invalid_selectors'] = false;
|
277 |
-
$this->settings['discard_invalid_properties'] = false;
|
278 |
-
$this->settings['css_level'] = 'CSS2.1';
|
279 |
-
$this->settings['preserve_css'] = false;
|
280 |
-
$this->settings['timestamp'] = false;
|
281 |
-
$this->settings['template'] = ''; // say that propertie exist
|
282 |
-
$this->set_cfg('template','default'); // call load_template
|
283 |
-
$this->optimise = new csstidy_optimise($this);
|
284 |
-
|
285 |
-
$this->tokens_list = & $GLOBALS['csstidy']['tokens'];
|
286 |
-
}
|
287 |
-
|
288 |
-
/**
|
289 |
-
* Get the value of a setting.
|
290 |
-
* @param string $setting
|
291 |
-
* @access public
|
292 |
-
* @return mixed
|
293 |
-
* @version 1.0
|
294 |
-
*/
|
295 |
-
function get_cfg($setting) {
|
296 |
-
if (isset($this->settings[$setting])) {
|
297 |
-
return $this->settings[$setting];
|
298 |
-
}
|
299 |
-
return false;
|
300 |
-
}
|
301 |
-
|
302 |
-
/**
|
303 |
-
* Load a template
|
304 |
-
* @param string $template used by set_cfg to load a template via a configuration setting
|
305 |
-
* @access private
|
306 |
-
* @version 1.4
|
307 |
-
*/
|
308 |
-
function _load_template($template) {
|
309 |
-
switch ($template) {
|
310 |
-
case 'default':
|
311 |
-
$this->load_template('default');
|
312 |
-
break;
|
313 |
-
|
314 |
-
case 'highest':
|
315 |
-
$this->load_template('highest_compression');
|
316 |
-
break;
|
317 |
-
|
318 |
-
case 'high':
|
319 |
-
$this->load_template('high_compression');
|
320 |
-
break;
|
321 |
-
|
322 |
-
case 'low':
|
323 |
-
$this->load_template('low_compression');
|
324 |
-
break;
|
325 |
-
|
326 |
-
default:
|
327 |
-
$this->load_template($template);
|
328 |
-
break;
|
329 |
-
}
|
330 |
-
}
|
331 |
-
|
332 |
-
/**
|
333 |
-
* Set the value of a setting.
|
334 |
-
* @param string $setting
|
335 |
-
* @param mixed $value
|
336 |
-
* @access public
|
337 |
-
* @return bool
|
338 |
-
* @version 1.0
|
339 |
-
*/
|
340 |
-
function set_cfg($setting, $value=null) {
|
341 |
-
if (is_array($setting) && $value === null) {
|
342 |
-
foreach ($setting as $setprop => $setval) {
|
343 |
-
$this->settings[$setprop] = $setval;
|
344 |
-
}
|
345 |
-
if (array_key_exists('template', $setting)) {
|
346 |
-
$this->_load_template($this->settings['template']);
|
347 |
-
}
|
348 |
-
return true;
|
349 |
-
} else if (isset($this->settings[$setting]) && $value !== '') {
|
350 |
-
$this->settings[$setting] = $value;
|
351 |
-
if ($setting === 'template') {
|
352 |
-
$this->_load_template($this->settings['template']);
|
353 |
-
}
|
354 |
-
return true;
|
355 |
-
}
|
356 |
-
return false;
|
357 |
-
}
|
358 |
-
|
359 |
-
/**
|
360 |
-
* Adds a token to $this->tokens
|
361 |
-
* @param mixed $type
|
362 |
-
* @param string $data
|
363 |
-
* @param bool $do add a token even if preserve_css is off
|
364 |
-
* @access private
|
365 |
-
* @version 1.0
|
366 |
-
*/
|
367 |
-
function _add_token($type, $data, $do = false) {
|
368 |
-
if ($this->get_cfg('preserve_css') || $do) {
|
369 |
-
$this->tokens[] = array($type, ($type == COMMENT) ? $data : trim($data));
|
370 |
-
}
|
371 |
-
}
|
372 |
-
|
373 |
-
/**
|
374 |
-
* Add a message to the message log
|
375 |
-
* @param string $message
|
376 |
-
* @param string $type
|
377 |
-
* @param integer $line
|
378 |
-
* @access private
|
379 |
-
* @version 1.0
|
380 |
-
*/
|
381 |
-
function log($message, $type, $line = -1) {
|
382 |
-
if ($line === -1) {
|
383 |
-
$line = $this->line;
|
384 |
-
}
|
385 |
-
$line = intval($line);
|
386 |
-
$add = array('m' => $message, 't' => $type);
|
387 |
-
if (!isset($this->log[$line]) || !in_array($add, $this->log[$line])) {
|
388 |
-
$this->log[$line][] = $add;
|
389 |
-
}
|
390 |
-
}
|
391 |
-
|
392 |
-
/**
|
393 |
-
* Parse unicode notations and find a replacement character
|
394 |
-
* @param string $string
|
395 |
-
* @param integer $i
|
396 |
-
* @access private
|
397 |
-
* @return string
|
398 |
-
* @version 1.2
|
399 |
-
*/
|
400 |
-
function _unicode(&$string, &$i) {
|
401 |
-
++$i;
|
402 |
-
$add = '';
|
403 |
-
$replaced = false;
|
404 |
-
|
405 |
-
while ($i < strlen($string) && (ctype_xdigit($string{$i}) || ctype_space($string{$i})) && strlen($add) < 6) {
|
406 |
-
$add .= $string{$i};
|
407 |
-
|
408 |
-
if (ctype_space($string{$i})) {
|
409 |
-
break;
|
410 |
-
}
|
411 |
-
$i++;
|
412 |
-
}
|
413 |
-
|
414 |
-
if (hexdec($add) > 47 && hexdec($add) < 58 || hexdec($add) > 64 && hexdec($add) < 91 || hexdec($add) > 96 && hexdec($add) < 123) {
|
415 |
-
$this->log('Replaced unicode notation: Changed \\' . $add . ' to ' . chr(hexdec($add)), 'Information');
|
416 |
-
$add = chr(hexdec($add));
|
417 |
-
$replaced = true;
|
418 |
-
} else {
|
419 |
-
$add = trim('\\' . $add);
|
420 |
-
}
|
421 |
-
|
422 |
-
if (@ctype_xdigit($string{$i + 1}) && ctype_space($string{$i})
|
423 |
-
&& !$replaced || !ctype_space($string{$i})) {
|
424 |
-
$i--;
|
425 |
-
}
|
426 |
-
|
427 |
-
if ($add !== '\\' || !$this->get_cfg('remove_bslash') || strpos($this->tokens_list, $string{$i + 1}) !== false) {
|
428 |
-
return $add;
|
429 |
-
}
|
430 |
-
|
431 |
-
if ($add === '\\') {
|
432 |
-
$this->log('Removed unnecessary backslash', 'Information');
|
433 |
-
}
|
434 |
-
return '';
|
435 |
-
}
|
436 |
-
|
437 |
-
/**
|
438 |
-
* Write formatted output to a file
|
439 |
-
* @param string $filename
|
440 |
-
* @param string $doctype when printing formatted, is a shorthand for the document type
|
441 |
-
* @param bool $externalcss when printing formatted, indicates whether styles to be attached internally or as an external stylesheet
|
442 |
-
* @param string $title when printing formatted, is the title to be added in the head of the document
|
443 |
-
* @param string $lang when printing formatted, gives a two-letter language code to be added to the output
|
444 |
-
* @access public
|
445 |
-
* @version 1.4
|
446 |
-
*/
|
447 |
-
function write_page($filename, $doctype='xhtml1.1', $externalcss=true, $title='', $lang='en') {
|
448 |
-
$this->write($filename, true);
|
449 |
-
}
|
450 |
-
|
451 |
-
/**
|
452 |
-
* Write plain output to a file
|
453 |
-
* @param string $filename
|
454 |
-
* @param bool $formatted whether to print formatted or not
|
455 |
-
* @param string $doctype when printing formatted, is a shorthand for the document type
|
456 |
-
* @param bool $externalcss when printing formatted, indicates whether styles to be attached internally or as an external stylesheet
|
457 |
-
* @param string $title when printing formatted, is the title to be added in the head of the document
|
458 |
-
* @param string $lang when printing formatted, gives a two-letter language code to be added to the output
|
459 |
-
* @param bool $pre_code whether to add pre and code tags around the code (for light HTML formatted templates)
|
460 |
-
* @access public
|
461 |
-
* @version 1.4
|
462 |
-
*/
|
463 |
-
function write($filename, $formatted=false, $doctype='xhtml1.1', $externalcss=true, $title='', $lang='en', $pre_code=true) {
|
464 |
-
$filename .= ( $formatted) ? '.xhtml' : '.css';
|
465 |
-
|
466 |
-
if (!is_dir('temp')) {
|
467 |
-
$madedir = mkdir('temp');
|
468 |
-
if (!$madedir) {
|
469 |
-
print 'Could not make directory "temp" in ' . dirname(__FILE__);
|
470 |
-
exit;
|
471 |
-
}
|
472 |
-
}
|
473 |
-
$handle = fopen('temp/' . $filename, 'w');
|
474 |
-
if ($handle) {
|
475 |
-
if (!$formatted) {
|
476 |
-
fwrite($handle, $this->print->plain());
|
477 |
-
} else {
|
478 |
-
fwrite($handle, $this->print->formatted_page($doctype, $externalcss, $title, $lang, $pre_code));
|
479 |
-
}
|
480 |
-
}
|
481 |
-
fclose($handle);
|
482 |
-
}
|
483 |
-
|
484 |
-
/**
|
485 |
-
* Loads a new template
|
486 |
-
* @param string $content either filename (if $from_file == true), content of a template file, "high_compression", "highest_compression", "low_compression", or "default"
|
487 |
-
* @param bool $from_file uses $content as filename if true
|
488 |
-
* @access public
|
489 |
-
* @version 1.1
|
490 |
-
* @see http://csstidy.sourceforge.net/templates.php
|
491 |
-
*/
|
492 |
-
function load_template($content, $from_file=true) {
|
493 |
-
$predefined_templates = & $GLOBALS['csstidy']['predefined_templates'];
|
494 |
-
if ($content === 'high_compression' || $content === 'default' || $content === 'highest_compression' || $content === 'low_compression') {
|
495 |
-
$this->template = $predefined_templates[$content];
|
496 |
-
return;
|
497 |
-
}
|
498 |
-
|
499 |
-
|
500 |
-
if ($from_file) {
|
501 |
-
$content = strip_tags(file_get_contents($content), '<span>');
|
502 |
-
}
|
503 |
-
$content = str_replace("\r\n", "\n", $content); // Unify newlines (because the output also only uses \n)
|
504 |
-
$template = explode('|', $content);
|
505 |
-
|
506 |
-
for ($i = 0; $i < count($template); $i++) {
|
507 |
-
$this->template[$i] = $template[$i];
|
508 |
-
}
|
509 |
-
}
|
510 |
-
|
511 |
-
/**
|
512 |
-
* Starts parsing from URL
|
513 |
-
* @param string $url
|
514 |
-
* @access public
|
515 |
-
* @version 1.0
|
516 |
-
*/
|
517 |
-
function parse_from_url($url) {
|
518 |
-
return $this->parse(@file_get_contents($url));
|
519 |
-
}
|
520 |
-
|
521 |
-
/**
|
522 |
-
* Checks if there is a token at the current position
|
523 |
-
* @param string $string
|
524 |
-
* @param integer $i
|
525 |
-
* @access public
|
526 |
-
* @version 1.11
|
527 |
-
*/
|
528 |
-
function is_token(&$string, $i) {
|
529 |
-
return (strpos($this->tokens_list, $string{$i}) !== false && !csstidy::escaped($string, $i));
|
530 |
-
}
|
531 |
-
|
532 |
-
/**
|
533 |
-
* Parses CSS in $string. The code is saved as array in $this->css
|
534 |
-
* @param string $string the CSS code
|
535 |
-
* @access public
|
536 |
-
* @return bool
|
537 |
-
* @version 1.1
|
538 |
-
*/
|
539 |
-
function parse($string) {
|
540 |
-
// Temporarily set locale to en_US in order to handle floats properly
|
541 |
-
$old = @setlocale(LC_ALL, 0);
|
542 |
-
@setlocale(LC_ALL, 'C');
|
543 |
-
|
544 |
-
// PHP bug? Settings need to be refreshed in PHP4
|
545 |
-
$this->print = new csstidy_print($this);
|
546 |
-
//$this->optimise = new csstidy_optimise($this);
|
547 |
-
|
548 |
-
$all_properties = & $GLOBALS['csstidy']['all_properties'];
|
549 |
-
$at_rules = & $GLOBALS['csstidy']['at_rules'];
|
550 |
-
$quoted_string_properties = & $GLOBALS['csstidy']['quoted_string_properties'];
|
551 |
-
|
552 |
-
$this->css = array();
|
553 |
-
$this->print->input_css = $string;
|
554 |
-
$string = str_replace("\r\n", "\n", $string) . ' ';
|
555 |
-
$cur_comment = '';
|
556 |
-
|
557 |
-
for ($i = 0, $size = strlen($string); $i < $size; $i++) {
|
558 |
-
if ($string{$i} === "\n" || $string{$i} === "\r") {
|
559 |
-
++$this->line;
|
560 |
-
}
|
561 |
-
|
562 |
-
switch ($this->status) {
|
563 |
-
/* Case in at-block */
|
564 |
-
case 'at':
|
565 |
-
if (csstidy::is_token($string, $i)) {
|
566 |
-
if ($string{$i} === '/' && @$string{$i + 1} === '*') {
|
567 |
-
$this->status = 'ic';
|
568 |
-
++$i;
|
569 |
-
$this->from[] = 'at';
|
570 |
-
} elseif ($string{$i} === '{') {
|
571 |
-
$this->status = 'is';
|
572 |
-
$this->at = $this->css_new_media_section($this->at);
|
573 |
-
$this->_add_token(AT_START, $this->at);
|
574 |
-
} elseif ($string{$i} === ',') {
|
575 |
-
$this->at = trim($this->at) . ',';
|
576 |
-
} elseif ($string{$i} === '\\') {
|
577 |
-
$this->at .= $this->_unicode($string, $i);
|
578 |
-
}
|
579 |
-
// fix for complicated media, i.e @media screen and (-webkit-min-device-pixel-ratio:1.5)
|
580 |
-
// '/' is included for ratios in Opera: (-o-min-device-pixel-ratio: 3/2)
|
581 |
-
elseif (in_array($string{$i}, array('(', ')', ':', '.', '/'))) {
|
582 |
-
$this->at .= $string{$i};
|
583 |
-
}
|
584 |
-
} else {
|
585 |
-
$lastpos = strlen($this->at) - 1;
|
586 |
-
if (!( (ctype_space($this->at{$lastpos}) || csstidy::is_token($this->at, $lastpos) && $this->at{$lastpos} === ',') && ctype_space($string{$i}))) {
|
587 |
-
$this->at .= $string{$i};
|
588 |
-
}
|
589 |
-
}
|
590 |
-
break;
|
591 |
-
|
592 |
-
/* Case in-selector */
|
593 |
-
case 'is':
|
594 |
-
if (csstidy::is_token($string, $i)) {
|
595 |
-
if ($string{$i} === '/' && @$string{$i + 1} === '*' && trim($this->selector) == '') {
|
596 |
-
$this->status = 'ic';
|
597 |
-
++$i;
|
598 |
-
$this->from[] = 'is';
|
599 |
-
} elseif ($string{$i} === '@' && trim($this->selector) == '') {
|
600 |
-
// Check for at-rule
|
601 |
-
$this->invalid_at = true;
|
602 |
-
foreach ($at_rules as $name => $type) {
|
603 |
-
if (!strcasecmp(substr($string, $i + 1, strlen($name)), $name)) {
|
604 |
-
($type === 'at') ? $this->at = '@' . $name : $this->selector = '@' . $name;
|
605 |
-
$this->status = $type;
|
606 |
-
$i += strlen($name);
|
607 |
-
$this->invalid_at = false;
|
608 |
-
}
|
609 |
-
}
|
610 |
-
|
611 |
-
if ($this->invalid_at) {
|
612 |
-
$this->selector = '@';
|
613 |
-
$invalid_at_name = '';
|
614 |
-
for ($j = $i + 1; $j < $size; ++$j) {
|
615 |
-
if (!ctype_alpha($string{$j})) {
|
616 |
-
break;
|
617 |
-
}
|
618 |
-
$invalid_at_name .= $string{$j};
|
619 |
-
}
|
620 |
-
$this->log('Invalid @-rule: ' . $invalid_at_name . ' (removed)', 'Warning');
|
621 |
-
}
|
622 |
-
} elseif (($string{$i} === '"' || $string{$i} === "'")) {
|
623 |
-
$this->cur_string[] = $string{$i};
|
624 |
-
$this->status = 'instr';
|
625 |
-
$this->str_char[] = $string{$i};
|
626 |
-
$this->from[] = 'is';
|
627 |
-
/* fixing CSS3 attribute selectors, i.e. a[href$=".mp3" */
|
628 |
-
$this->quoted_string[] = ($string{$i - 1} == '=' );
|
629 |
-
} elseif ($this->invalid_at && $string{$i} === ';') {
|
630 |
-
$this->invalid_at = false;
|
631 |
-
$this->status = 'is';
|
632 |
-
} elseif ($string{$i} === '{') {
|
633 |
-
$this->status = 'ip';
|
634 |
-
if($this->at == '') {
|
635 |
-
$this->at = $this->css_new_media_section(DEFAULT_AT);
|
636 |
-
}
|
637 |
-
$this->selector = $this->css_new_selector($this->at,$this->selector);
|
638 |
-
$this->_add_token(SEL_START, $this->selector);
|
639 |
-
$this->added = false;
|
640 |
-
} elseif ($string{$i} === '}') {
|
641 |
-
$this->_add_token(AT_END, $this->at);
|
642 |
-
$this->at = '';
|
643 |
-
$this->selector = '';
|
644 |
-
$this->sel_separate = array();
|
645 |
-
} elseif ($string{$i} === ',') {
|
646 |
-
$this->selector = trim($this->selector) . ',';
|
647 |
-
$this->sel_separate[] = strlen($this->selector);
|
648 |
-
} elseif ($string{$i} === '\\') {
|
649 |
-
$this->selector .= $this->_unicode($string, $i);
|
650 |
-
} elseif ($string{$i} === '*' && @in_array($string{$i + 1}, array('.', '#', '[', ':'))) {
|
651 |
-
// remove unnecessary universal selector, FS#147
|
652 |
-
} else {
|
653 |
-
$this->selector .= $string{$i};
|
654 |
-
}
|
655 |
-
} else {
|
656 |
-
$lastpos = strlen($this->selector) - 1;
|
657 |
-
if ($lastpos == -1 || !( (ctype_space($this->selector{$lastpos}) || csstidy::is_token($this->selector, $lastpos) && $this->selector{$lastpos} === ',') && ctype_space($string{$i}))) {
|
658 |
-
$this->selector .= $string{$i};
|
659 |
-
}
|
660 |
-
else if (ctype_space($string{$i}) && $this->get_cfg('preserve_css') && !$this->get_cfg('merge_selectors')) {
|
661 |
-
$this->selector .= $string{$i};
|
662 |
-
}
|
663 |
-
}
|
664 |
-
break;
|
665 |
-
|
666 |
-
/* Case in-property */
|
667 |
-
case 'ip':
|
668 |
-
if (csstidy::is_token($string, $i)) {
|
669 |
-
if (($string{$i} === ':' || $string{$i} === '=') && $this->property != '') {
|
670 |
-
$this->status = 'iv';
|
671 |
-
if (!$this->get_cfg('discard_invalid_properties') || csstidy::property_is_valid($this->property)) {
|
672 |
-
$this->property = $this->css_new_property($this->at,$this->selector,$this->property);
|
673 |
-
$this->_add_token(PROPERTY, $this->property);
|
674 |
-
}
|
675 |
-
} elseif ($string{$i} === '/' && @$string{$i + 1} === '*' && $this->property == '') {
|
676 |
-
$this->status = 'ic';
|
677 |
-
++$i;
|
678 |
-
$this->from[] = 'ip';
|
679 |
-
} elseif ($string{$i} === '}') {
|
680 |
-
$this->explode_selectors();
|
681 |
-
$this->status = 'is';
|
682 |
-
$this->invalid_at = false;
|
683 |
-
$this->_add_token(SEL_END, $this->selector);
|
684 |
-
$this->selector = '';
|
685 |
-
$this->property = '';
|
686 |
-
} elseif ($string{$i} === ';') {
|
687 |
-
$this->property = '';
|
688 |
-
} elseif ($string{$i} === '\\') {
|
689 |
-
$this->property .= $this->_unicode($string, $i);
|
690 |
-
}
|
691 |
-
// else this is dumb IE a hack, keep it
|
692 |
-
elseif ($this->property=='' AND !ctype_space($string{$i})) {
|
693 |
-
$this->property .= $string{$i};
|
694 |
-
}
|
695 |
-
}
|
696 |
-
elseif (!ctype_space($string{$i})) {
|
697 |
-
$this->property .= $string{$i};
|
698 |
-
}
|
699 |
-
break;
|
700 |
-
|
701 |
-
/* Case in-value */
|
702 |
-
case 'iv':
|
703 |
-
$pn = (($string{$i} === "\n" || $string{$i} === "\r") && $this->property_is_next($string, $i + 1) || $i == strlen($string) - 1);
|
704 |
-
if ((csstidy::is_token($string, $i) || $pn) && (!($string{$i} == ',' && !ctype_space($string{$i+1})))) {
|
705 |
-
if ($string{$i} === '/' && @$string{$i + 1} === '*') {
|
706 |
-
$this->status = 'ic';
|
707 |
-
++$i;
|
708 |
-
$this->from[] = 'iv';
|
709 |
-
} elseif (($string{$i} === '"' || $string{$i} === "'" || $string{$i} === '(')) {
|
710 |
-
$this->cur_string[] = $string{$i};
|
711 |
-
$this->str_char[] = ($string{$i} === '(') ? ')' : $string{$i};
|
712 |
-
$this->status = 'instr';
|
713 |
-
$this->from[] = 'iv';
|
714 |
-
$this->quoted_string[] = in_array(strtolower($this->property), $quoted_string_properties);
|
715 |
-
} elseif ($string{$i} === ',') {
|
716 |
-
$this->sub_value = trim($this->sub_value) . ',';
|
717 |
-
} elseif ($string{$i} === '\\') {
|
718 |
-
$this->sub_value .= $this->_unicode($string, $i);
|
719 |
-
} elseif ($string{$i} === ';' || $pn) {
|
720 |
-
if ($this->selector{0} === '@' && isset($at_rules[substr($this->selector, 1)]) && $at_rules[substr($this->selector, 1)] === 'iv') {
|
721 |
-
$this->status = 'is';
|
722 |
-
|
723 |
-
switch ($this->selector) {
|
724 |
-
case '@charset':
|
725 |
-
/* Add quotes to charset */
|
726 |
-
$this->sub_value_arr[] = '"' . trim($this->sub_value) . '"';
|
727 |
-
$this->charset = $this->sub_value_arr[0];
|
728 |
-
break;
|
729 |
-
case '@namespace':
|
730 |
-
/* Add quotes to namespace */
|
731 |
-
$this->sub_value_arr[] = '"' . trim($this->sub_value) . '"';
|
732 |
-
$this->namespace = implode(' ', $this->sub_value_arr);
|
733 |
-
break;
|
734 |
-
case '@import':
|
735 |
-
$this->sub_value = trim($this->sub_value);
|
736 |
-
|
737 |
-
if (empty($this->sub_value_arr)) {
|
738 |
-
// Quote URLs in imports only if they're not already inside url() and not already quoted.
|
739 |
-
if (substr($this->sub_value, 0, 4) != 'url(') {
|
740 |
-
if (!($this->sub_value{0} == substr($this->sub_value, -1) && in_array($this->sub_value{0}, array("'", '"')))) {
|
741 |
-
$this->sub_value = '"' . $this->sub_value . '"';
|
742 |
-
}
|
743 |
-
}
|
744 |
-
}
|
745 |
-
|
746 |
-
$this->sub_value_arr[] = $this->sub_value;
|
747 |
-
$this->import[] = implode(' ', $this->sub_value_arr);
|
748 |
-
break;
|
749 |
-
}
|
750 |
-
|
751 |
-
$this->sub_value_arr = array();
|
752 |
-
$this->sub_value = '';
|
753 |
-
$this->selector = '';
|
754 |
-
$this->sel_separate = array();
|
755 |
-
} else {
|
756 |
-
$this->status = 'ip';
|
757 |
-
}
|
758 |
-
} elseif ($string{$i} !== '}') {
|
759 |
-
$this->sub_value .= $string{$i};
|
760 |
-
}
|
761 |
-
if (($string{$i} === '}' || $string{$i} === ';' || $pn) && !empty($this->selector)) {
|
762 |
-
if ($this->at == '') {
|
763 |
-
$this->at = $this->css_new_media_section(DEFAULT_AT);
|
764 |
-
}
|
765 |
-
|
766 |
-
// case settings
|
767 |
-
if ($this->get_cfg('lowercase_s')) {
|
768 |
-
$this->selector = strtolower($this->selector);
|
769 |
-
}
|
770 |
-
$this->property = strtolower($this->property);
|
771 |
-
|
772 |
-
$this->optimise->subvalue();
|
773 |
-
if ($this->sub_value != '') {
|
774 |
-
if (substr($this->sub_value, 0, 6) == 'format') {
|
775 |
-
$format_strings = csstidy::parse_string_list(substr($this->sub_value, 7, -1));
|
776 |
-
if (!$format_strings) {
|
777 |
-
$this->sub_value = "";
|
778 |
-
}
|
779 |
-
else {
|
780 |
-
$this->sub_value = "format(";
|
781 |
-
|
782 |
-
foreach ($format_strings as $format_string) {
|
783 |
-
$this->sub_value .= '"' . str_replace('"', '\\"', $format_string) . '",';
|
784 |
-
}
|
785 |
-
|
786 |
-
$this->sub_value = substr($this->sub_value, 0, -1) . ")";
|
787 |
-
}
|
788 |
-
}
|
789 |
-
if ($this->sub_value != '') {
|
790 |
-
$this->sub_value_arr[] = $this->sub_value;
|
791 |
-
}
|
792 |
-
$this->sub_value = '';
|
793 |
-
}
|
794 |
-
|
795 |
-
$this->value = array_shift($this->sub_value_arr);
|
796 |
-
while(count($this->sub_value_arr)){
|
797 |
-
//$this->value .= (substr($this->value,-1,1)==','?'':' ').array_shift($this->sub_value_arr);
|
798 |
-
$this->value .= ' '.array_shift($this->sub_value_arr);
|
799 |
-
}
|
800 |
-
|
801 |
-
$this->optimise->value();
|
802 |
-
|
803 |
-
$valid = csstidy::property_is_valid($this->property);
|
804 |
-
if ((!$this->invalid_at || $this->get_cfg('preserve_css')) && (!$this->get_cfg('discard_invalid_properties') || $valid)) {
|
805 |
-
$this->css_add_property($this->at, $this->selector, $this->property, $this->value);
|
806 |
-
$this->_add_token(VALUE, $this->value);
|
807 |
-
$this->optimise->shorthands();
|
808 |
-
}
|
809 |
-
if (!$valid) {
|
810 |
-
if ($this->get_cfg('discard_invalid_properties')) {
|
811 |
-
$this->log('Removed invalid property: ' . $this->property, 'Warning');
|
812 |
-
} else {
|
813 |
-
$this->log('Invalid property in ' . strtoupper($this->get_cfg('css_level')) . ': ' . $this->property, 'Warning');
|
814 |
-
}
|
815 |
-
}
|
816 |
-
|
817 |
-
$this->property = '';
|
818 |
-
$this->sub_value_arr = array();
|
819 |
-
$this->value = '';
|
820 |
-
}
|
821 |
-
if ($string{$i} === '}') {
|
822 |
-
$this->explode_selectors();
|
823 |
-
$this->_add_token(SEL_END, $this->selector);
|
824 |
-
$this->status = 'is';
|
825 |
-
$this->invalid_at = false;
|
826 |
-
$this->selector = '';
|
827 |
-
}
|
828 |
-
} elseif (!$pn) {
|
829 |
-
$this->sub_value .= $string{$i};
|
830 |
-
|
831 |
-
if (ctype_space($string{$i}) || $string{$i} == ',') {
|
832 |
-
$this->optimise->subvalue();
|
833 |
-
if ($this->sub_value != '') {
|
834 |
-
$this->sub_value_arr[] = $this->sub_value;
|
835 |
-
$this->sub_value = '';
|
836 |
-
}
|
837 |
-
}
|
838 |
-
}
|
839 |
-
break;
|
840 |
-
|
841 |
-
/* Case in string */
|
842 |
-
case 'instr':
|
843 |
-
$_str_char = $this->str_char[count($this->str_char)-1];
|
844 |
-
$_cur_string = $this->cur_string[count($this->cur_string)-1];
|
845 |
-
$temp_add = $string{$i};
|
846 |
-
|
847 |
-
// Add another string to the stack. Strings can't be nested inside of quotes, only parentheses, but
|
848 |
-
// parentheticals can be nested more than once.
|
849 |
-
if ($_str_char === ")" && ($string{$i} === "(" || $string{$i} === '"' || $string{$i} === '\'') && !csstidy::escaped($string, $i)) {
|
850 |
-
$this->cur_string[] = $string{$i};
|
851 |
-
$this->str_char[] = $string{$i} == "(" ? ")" : $string{$i};
|
852 |
-
$this->from[] = 'instr';
|
853 |
-
$this->quoted_string[] = !($string{$i} === "(");
|
854 |
-
continue;
|
855 |
-
}
|
856 |
-
|
857 |
-
if ($_str_char !== ")" && ($string{$i} === "\n" || $string{$i} === "\r") && !($string{$i - 1} === '\\' && !csstidy::escaped($string, $i - 1))) {
|
858 |
-
$temp_add = "\\A";
|
859 |
-
$this->log('Fixed incorrect newline in string', 'Warning');
|
860 |
-
}
|
861 |
-
|
862 |
-
$_cur_string .= $temp_add;
|
863 |
-
|
864 |
-
if ($string{$i} === $_str_char && !csstidy::escaped($string, $i)) {
|
865 |
-
$_quoted_string = array_pop($this->quoted_string);
|
866 |
-
|
867 |
-
$this->status = array_pop($this->from);
|
868 |
-
|
869 |
-
if (!preg_match('|[' . implode('', $GLOBALS['csstidy']['whitespace']) . ']|uis', $_cur_string) && $this->property !== 'content') {
|
870 |
-
if (!$_quoted_string) {
|
871 |
-
if ($_str_char !== ')') {
|
872 |
-
// Convert properties like
|
873 |
-
// font-family: 'Arial';
|
874 |
-
// to
|
875 |
-
// font-family: Arial;
|
876 |
-
// or
|
877 |
-
// url("abc")
|
878 |
-
// to
|
879 |
-
// url(abc)
|
880 |
-
$_cur_string = substr($_cur_string, 1, -1);
|
881 |
-
}
|
882 |
-
} else {
|
883 |
-
$_quoted_string = false;
|
884 |
-
}
|
885 |
-
}
|
886 |
-
|
887 |
-
array_pop($this->cur_string);
|
888 |
-
array_pop($this->str_char);
|
889 |
-
|
890 |
-
if ($_str_char === ")") {
|
891 |
-
$_cur_string = "(" . trim(substr($_cur_string, 1, -1)) . ")";
|
892 |
-
}
|
893 |
-
|
894 |
-
if ($this->status === 'iv') {
|
895 |
-
if (!$_quoted_string){
|
896 |
-
if (strpos($_cur_string,',')!==false)
|
897 |
-
// we can on only remove space next to ','
|
898 |
-
$_cur_string = implode(',',array_map('trim',explode(',',$_cur_string)));
|
899 |
-
// and multiple spaces (too expensive)
|
900 |
-
if (strpos($_cur_string,' ')!==false)
|
901 |
-
$_cur_string = preg_replace(",\s+,"," ",$_cur_string);
|
902 |
-
}
|
903 |
-
$this->sub_value .= $_cur_string;
|
904 |
-
} elseif ($this->status === 'is') {
|
905 |
-
$this->selector .= $_cur_string;
|
906 |
-
} elseif ($this->status === 'instr') {
|
907 |
-
$this->cur_string[count($this->cur_string)-1] .= $_cur_string;
|
908 |
-
}
|
909 |
-
}
|
910 |
-
else {
|
911 |
-
$this->cur_string[count($this->cur_string)-1] = $_cur_string;
|
912 |
-
}
|
913 |
-
break;
|
914 |
-
|
915 |
-
/* Case in-comment */
|
916 |
-
case 'ic':
|
917 |
-
if ($string{$i} === '*' && $string{$i + 1} === '/') {
|
918 |
-
$this->status = array_pop($this->from);
|
919 |
-
$i++;
|
920 |
-
$this->_add_token(COMMENT, $cur_comment);
|
921 |
-
$cur_comment = '';
|
922 |
-
} else {
|
923 |
-
$cur_comment .= $string{$i};
|
924 |
-
}
|
925 |
-
break;
|
926 |
-
}
|
927 |
-
}
|
928 |
-
|
929 |
-
$this->optimise->postparse();
|
930 |
-
|
931 |
-
$this->print->_reset();
|
932 |
-
|
933 |
-
@setlocale(LC_ALL, $old); // Set locale back to original setting
|
934 |
-
|
935 |
-
return!(empty($this->css) && empty($this->import) && empty($this->charset) && empty($this->tokens) && empty($this->namespace));
|
936 |
-
}
|
937 |
-
|
938 |
-
/**
|
939 |
-
* Explodes selectors
|
940 |
-
* @access private
|
941 |
-
* @version 1.0
|
942 |
-
*/
|
943 |
-
function explode_selectors() {
|
944 |
-
// Explode multiple selectors
|
945 |
-
if ($this->get_cfg('merge_selectors') === 1) {
|
946 |
-
$new_sels = array();
|
947 |
-
$lastpos = 0;
|
948 |
-
$this->sel_separate[] = strlen($this->selector);
|
949 |
-
foreach ($this->sel_separate as $num => $pos) {
|
950 |
-
if ($num == count($this->sel_separate) - 1) {
|
951 |
-
$pos += 1;
|
952 |
-
}
|
953 |
-
|
954 |
-
$new_sels[] = substr($this->selector, $lastpos, $pos - $lastpos - 1);
|
955 |
-
$lastpos = $pos;
|
956 |
-
}
|
957 |
-
|
958 |
-
if (count($new_sels) > 1) {
|
959 |
-
foreach ($new_sels as $selector) {
|
960 |
-
if (isset($this->css[$this->at][$this->selector])) {
|
961 |
-
$this->merge_css_blocks($this->at, $selector, $this->css[$this->at][$this->selector]);
|
962 |
-
}
|
963 |
-
}
|
964 |
-
unset($this->css[$this->at][$this->selector]);
|
965 |
-
}
|
966 |
-
}
|
967 |
-
$this->sel_separate = array();
|
968 |
-
}
|
969 |
-
|
970 |
-
/**
|
971 |
-
* Checks if a character is escaped (and returns true if it is)
|
972 |
-
* @param string $string
|
973 |
-
* @param integer $pos
|
974 |
-
* @access public
|
975 |
-
* @return bool
|
976 |
-
* @version 1.02
|
977 |
-
*/
|
978 |
-
static function escaped(&$string, $pos) {
|
979 |
-
return!(@($string{$pos - 1} !== '\\') || csstidy::escaped($string, $pos - 1));
|
980 |
-
}
|
981 |
-
|
982 |
-
/**
|
983 |
-
* Adds a property with value to the existing CSS code
|
984 |
-
* @param string $media
|
985 |
-
* @param string $selector
|
986 |
-
* @param string $property
|
987 |
-
* @param string $new_val
|
988 |
-
* @access private
|
989 |
-
* @version 1.2
|
990 |
-
*/
|
991 |
-
function css_add_property($media, $selector, $property, $new_val) {
|
992 |
-
if ($this->get_cfg('preserve_css') || trim($new_val) == '') {
|
993 |
-
return;
|
994 |
-
}
|
995 |
-
|
996 |
-
$this->added = true;
|
997 |
-
if (isset($this->css[$media][$selector][$property])) {
|
998 |
-
if ((csstidy::is_important($this->css[$media][$selector][$property]) && csstidy::is_important($new_val)) || !csstidy::is_important($this->css[$media][$selector][$property])) {
|
999 |
-
$this->css[$media][$selector][$property] = trim($new_val);
|
1000 |
-
}
|
1001 |
-
} else {
|
1002 |
-
$this->css[$media][$selector][$property] = trim($new_val);
|
1003 |
-
}
|
1004 |
-
}
|
1005 |
-
|
1006 |
-
/**
|
1007 |
-
* Start a new media section.
|
1008 |
-
* Check if the media is not already known,
|
1009 |
-
* else rename it with extra spaces
|
1010 |
-
* to avoid merging
|
1011 |
-
*
|
1012 |
-
* @param string $media
|
1013 |
-
* @return string
|
1014 |
-
*/
|
1015 |
-
function css_new_media_section($media){
|
1016 |
-
if($this->get_cfg('preserve_css')) {
|
1017 |
-
return $media;
|
1018 |
-
}
|
1019 |
-
|
1020 |
-
// if the last @media is the same as this
|
1021 |
-
// keep it
|
1022 |
-
if (!$this->css OR !is_array($this->css) OR empty($this->css)){
|
1023 |
-
return $media;
|
1024 |
-
}
|
1025 |
-
end($this->css);
|
1026 |
-
list($at,) = each($this->css);
|
1027 |
-
if ($at == $media){
|
1028 |
-
return $media;
|
1029 |
-
}
|
1030 |
-
while (isset($this->css[$media]))
|
1031 |
-
if (is_numeric($media))
|
1032 |
-
$media++;
|
1033 |
-
else
|
1034 |
-
$media .= " ";
|
1035 |
-
return $media;
|
1036 |
-
}
|
1037 |
-
|
1038 |
-
/**
|
1039 |
-
* Start a new selector.
|
1040 |
-
* If already referenced in this media section,
|
1041 |
-
* rename it with extra space to avoid merging
|
1042 |
-
* except if merging is required,
|
1043 |
-
* or last selector is the same (merge siblings)
|
1044 |
-
*
|
1045 |
-
* never merge @font-face
|
1046 |
-
*
|
1047 |
-
* @param string $media
|
1048 |
-
* @param string $selector
|
1049 |
-
* @return string
|
1050 |
-
*/
|
1051 |
-
function css_new_selector($media,$selector){
|
1052 |
-
if($this->get_cfg('preserve_css')) {
|
1053 |
-
return $selector;
|
1054 |
-
}
|
1055 |
-
$selector = trim($selector);
|
1056 |
-
if (strncmp($selector,"@font-face",10)!=0){
|
1057 |
-
if ($this->settings['merge_selectors'] != false)
|
1058 |
-
return $selector;
|
1059 |
-
|
1060 |
-
if (!$this->css OR !isset($this->css[$media]) OR !$this->css[$media])
|
1061 |
-
return $selector;
|
1062 |
-
|
1063 |
-
// if last is the same, keep it
|
1064 |
-
end($this->css[$media]);
|
1065 |
-
list($sel,) = each($this->css[$media]);
|
1066 |
-
if ($sel == $selector){
|
1067 |
-
return $selector;
|
1068 |
-
}
|
1069 |
-
}
|
1070 |
-
|
1071 |
-
while (isset($this->css[$media][$selector]))
|
1072 |
-
$selector .= " ";
|
1073 |
-
return $selector;
|
1074 |
-
}
|
1075 |
-
|
1076 |
-
/**
|
1077 |
-
* Start a new propertie.
|
1078 |
-
* If already references in this selector,
|
1079 |
-
* rename it with extra space to avoid override
|
1080 |
-
*
|
1081 |
-
* @param string $media
|
1082 |
-
* @param string $selector
|
1083 |
-
* @param string $property
|
1084 |
-
* @return string
|
1085 |
-
*/
|
1086 |
-
function css_new_property($media, $selector, $property){
|
1087 |
-
if($this->get_cfg('preserve_css')) {
|
1088 |
-
return $property;
|
1089 |
-
}
|
1090 |
-
if (!$this->css OR !isset($this->css[$media][$selector]) OR !$this->css[$media][$selector])
|
1091 |
-
return $property;
|
1092 |
-
|
1093 |
-
while (isset($this->css[$media][$selector][$property]))
|
1094 |
-
$property .= " ";
|
1095 |
-
|
1096 |
-
return $property;
|
1097 |
-
}
|
1098 |
-
|
1099 |
-
/**
|
1100 |
-
* Adds CSS to an existing media/selector
|
1101 |
-
* @param string $media
|
1102 |
-
* @param string $selector
|
1103 |
-
* @param array $css_add
|
1104 |
-
* @access private
|
1105 |
-
* @version 1.1
|
1106 |
-
*/
|
1107 |
-
function merge_css_blocks($media, $selector, $css_add) {
|
1108 |
-
foreach ($css_add as $property => $value) {
|
1109 |
-
$this->css_add_property($media, $selector, $property, $value, false);
|
1110 |
-
}
|
1111 |
-
}
|
1112 |
-
|
1113 |
-
/**
|
1114 |
-
* Checks if $value is !important.
|
1115 |
-
* @param string $value
|
1116 |
-
* @return bool
|
1117 |
-
* @access public
|
1118 |
-
* @version 1.0
|
1119 |
-
*/
|
1120 |
-
static function is_important(&$value) {
|
1121 |
-
return (!strcasecmp(substr(str_replace($GLOBALS['csstidy']['whitespace'], '', $value), -10, 10), '!important'));
|
1122 |
-
}
|
1123 |
-
|
1124 |
-
/**
|
1125 |
-
* Returns a value without !important
|
1126 |
-
* @param string $value
|
1127 |
-
* @return string
|
1128 |
-
* @access public
|
1129 |
-
* @version 1.0
|
1130 |
-
*/
|
1131 |
-
static function gvw_important($value) {
|
1132 |
-
if (csstidy::is_important($value)) {
|
1133 |
-
$value = trim($value);
|
1134 |
-
$value = substr($value, 0, -9);
|
1135 |
-
$value = trim($value);
|
1136 |
-
$value = substr($value, 0, -1);
|
1137 |
-
$value = trim($value);
|
1138 |
-
return $value;
|
1139 |
-
}
|
1140 |
-
return $value;
|
1141 |
-
}
|
1142 |
-
|
1143 |
-
/**
|
1144 |
-
* Checks if the next word in a string from pos is a CSS property
|
1145 |
-
* @param string $istring
|
1146 |
-
* @param integer $pos
|
1147 |
-
* @return bool
|
1148 |
-
* @access private
|
1149 |
-
* @version 1.2
|
1150 |
-
*/
|
1151 |
-
function property_is_next($istring, $pos) {
|
1152 |
-
$all_properties = & $GLOBALS['csstidy']['all_properties'];
|
1153 |
-
$istring = substr($istring, $pos, strlen($istring) - $pos);
|
1154 |
-
$pos = strpos($istring, ':');
|
1155 |
-
if ($pos === false) {
|
1156 |
-
return false;
|
1157 |
-
}
|
1158 |
-
$istring = strtolower(trim(substr($istring, 0, $pos)));
|
1159 |
-
if (isset($all_properties[$istring])) {
|
1160 |
-
$this->log('Added semicolon to the end of declaration', 'Warning');
|
1161 |
-
return true;
|
1162 |
-
}
|
1163 |
-
return false;
|
1164 |
-
}
|
1165 |
-
|
1166 |
-
/**
|
1167 |
-
* Checks if a property is valid
|
1168 |
-
* @param string $property
|
1169 |
-
* @return bool;
|
1170 |
-
* @access public
|
1171 |
-
* @version 1.0
|
1172 |
-
*/
|
1173 |
-
function property_is_valid($property) {
|
1174 |
-
if (in_array(trim($property), $GLOBALS['csstidy']['multiple_properties'])) $property = trim($property);
|
1175 |
-
$all_properties = & $GLOBALS['csstidy']['all_properties'];
|
1176 |
-
return (isset($all_properties[$property]) && strpos($all_properties[$property], strtoupper($this->get_cfg('css_level'))) !== false );
|
1177 |
-
}
|
1178 |
-
|
1179 |
-
/**
|
1180 |
-
* Accepts a list of strings (e.g., the argument to format() in a @font-face src property)
|
1181 |
-
* and returns a list of the strings. Converts things like:
|
1182 |
-
*
|
1183 |
-
* format(abc) => format("abc")
|
1184 |
-
* format(abc def) => format("abc","def")
|
1185 |
-
* format(abc "def") => format("abc","def")
|
1186 |
-
* format(abc, def, ghi) => format("abc","def","ghi")
|
1187 |
-
* format("abc",'def') => format("abc","def")
|
1188 |
-
* format("abc, def, ghi") => format("abc, def, ghi")
|
1189 |
-
*
|
1190 |
-
* @param string
|
1191 |
-
* @return array
|
1192 |
-
*/
|
1193 |
-
|
1194 |
-
function parse_string_list($value) {
|
1195 |
-
$value = trim($value);
|
1196 |
-
|
1197 |
-
// Case: empty
|
1198 |
-
if (!$value) return array();
|
1199 |
-
|
1200 |
-
$strings = array();
|
1201 |
-
|
1202 |
-
$in_str = false;
|
1203 |
-
$current_string = "";
|
1204 |
-
|
1205 |
-
for ($i = 0, $_len = strlen($value); $i < $_len; $i++) {
|
1206 |
-
if (($value{$i} == "," || $value{$i} === " ") && $in_str === true) {
|
1207 |
-
$in_str = false;
|
1208 |
-
$strings[] = $current_string;
|
1209 |
-
$current_string = "";
|
1210 |
-
}
|
1211 |
-
else if ($value{$i} == '"' || $value{$i} == "'"){
|
1212 |
-
if ($in_str === $value{$i}) {
|
1213 |
-
$strings[] = $current_string;
|
1214 |
-
$in_str = false;
|
1215 |
-
$current_string = "";
|
1216 |
-
continue;
|
1217 |
-
}
|
1218 |
-
else if (!$in_str) {
|
1219 |
-
$in_str = $value{$i};
|
1220 |
-
}
|
1221 |
-
}
|
1222 |
-
else {
|
1223 |
-
if ($in_str){
|
1224 |
-
$current_string .= $value{$i};
|
1225 |
-
}
|
1226 |
-
else {
|
1227 |
-
if (!preg_match("/[\s,]/", $value{$i})) {
|
1228 |
-
$in_str = true;
|
1229 |
-
$current_string = $value{$i};
|
1230 |
-
}
|
1231 |
-
}
|
1232 |
-
}
|
1233 |
-
}
|
1234 |
-
|
1235 |
-
if ($current_string) {
|
1236 |
-
$strings[] = $current_string;
|
1237 |
-
}
|
1238 |
-
|
1239 |
-
return $strings;
|
1240 |
-
}
|
1241 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* CSSTidy - CSS Parser and Optimiser
|
5 |
+
*
|
6 |
+
* CSS Parser class
|
7 |
+
*
|
8 |
+
* Copyright 2005, 2006, 2007 Florian Schmitz
|
9 |
+
*
|
10 |
+
* This file is part of CSSTidy.
|
11 |
+
*
|
12 |
+
* CSSTidy is free software; you can redistribute it and/or modify
|
13 |
+
* it under the terms of the GNU Lesser General Public License as published by
|
14 |
+
* the Free Software Foundation; either version 2.1 of the License, or
|
15 |
+
* (at your option) any later version.
|
16 |
+
*
|
17 |
+
* CSSTidy is distributed in the hope that it will be useful,
|
18 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
19 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
20 |
+
* GNU Lesser General Public License for more details.
|
21 |
+
*
|
22 |
+
* You should have received a copy of the GNU Lesser General Public License
|
23 |
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
24 |
+
*
|
25 |
+
* @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
|
26 |
+
* @package csstidy
|
27 |
+
* @author Florian Schmitz (floele at gmail dot com) 2005-2007
|
28 |
+
* @author Brett Zamir (brettz9 at yahoo dot com) 2007
|
29 |
+
* @author Nikolay Matsievsky (speed at webo dot name) 2009-2010
|
30 |
+
* @author Cedric Morin (cedric at yterium dot com) 2010
|
31 |
+
*/
|
32 |
+
/**
|
33 |
+
* Defines ctype functions if required
|
34 |
+
*
|
35 |
+
* @version 1.0
|
36 |
+
*/
|
37 |
+
require_once('class.csstidy_ctype.php');
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Various CSS data needed for correct optimisations etc.
|
41 |
+
*
|
42 |
+
* @version 1.3
|
43 |
+
*/
|
44 |
+
require('data.inc.php');
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Contains a class for printing CSS code
|
48 |
+
*
|
49 |
+
* @version 1.0
|
50 |
+
*/
|
51 |
+
require('class.csstidy_print.php');
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Contains a class for optimising CSS code
|
55 |
+
*
|
56 |
+
* @version 1.0
|
57 |
+
*/
|
58 |
+
require('class.csstidy_optimise.php');
|
59 |
+
|
60 |
+
/**
|
61 |
+
* CSS Parser class
|
62 |
+
*
|
63 |
+
|
64 |
+
* This class represents a CSS parser which reads CSS code and saves it in an array.
|
65 |
+
* In opposite to most other CSS parsers, it does not use regular expressions and
|
66 |
+
* thus has full CSS2 support and a higher reliability.
|
67 |
+
* Additional to that it applies some optimisations and fixes to the CSS code.
|
68 |
+
* An online version should be available here: http://cdburnerxp.se/cssparse/css_optimiser.php
|
69 |
+
* @package csstidy
|
70 |
+
* @author Florian Schmitz (floele at gmail dot com) 2005-2006
|
71 |
+
* @version 1.3.1
|
72 |
+
*/
|
73 |
+
class csstidy {
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Saves the parsed CSS. This array is empty if preserve_css is on.
|
77 |
+
* @var array
|
78 |
+
* @access public
|
79 |
+
*/
|
80 |
+
var $css = array();
|
81 |
+
/**
|
82 |
+
* Saves the parsed CSS (raw)
|
83 |
+
* @var array
|
84 |
+
* @access private
|
85 |
+
*/
|
86 |
+
var $tokens = array();
|
87 |
+
/**
|
88 |
+
* Printer class
|
89 |
+
* @see csstidy_print
|
90 |
+
* @var object
|
91 |
+
* @access public
|
92 |
+
*/
|
93 |
+
var $print;
|
94 |
+
/**
|
95 |
+
* Optimiser class
|
96 |
+
* @see csstidy_optimise
|
97 |
+
* @var object
|
98 |
+
* @access private
|
99 |
+
*/
|
100 |
+
var $optimise;
|
101 |
+
/**
|
102 |
+
* Saves the CSS charset (@charset)
|
103 |
+
* @var string
|
104 |
+
* @access private
|
105 |
+
*/
|
106 |
+
var $charset = '';
|
107 |
+
/**
|
108 |
+
* Saves all @import URLs
|
109 |
+
* @var array
|
110 |
+
* @access private
|
111 |
+
*/
|
112 |
+
var $import = array();
|
113 |
+
/**
|
114 |
+
* Saves the namespace
|
115 |
+
* @var string
|
116 |
+
* @access private
|
117 |
+
*/
|
118 |
+
var $namespace = '';
|
119 |
+
/**
|
120 |
+
* Contains the version of csstidy
|
121 |
+
* @var string
|
122 |
+
* @access private
|
123 |
+
*/
|
124 |
+
var $version = '1.3';
|
125 |
+
/**
|
126 |
+
* Stores the settings
|
127 |
+
* @var array
|
128 |
+
* @access private
|
129 |
+
*/
|
130 |
+
var $settings = array();
|
131 |
+
/**
|
132 |
+
* Saves the parser-status.
|
133 |
+
*
|
134 |
+
* Possible values:
|
135 |
+
* - is = in selector
|
136 |
+
* - ip = in property
|
137 |
+
* - iv = in value
|
138 |
+
* - instr = in string (started at " or ' or ( )
|
139 |
+
* - ic = in comment (ignore everything)
|
140 |
+
* - at = in @-block
|
141 |
+
*
|
142 |
+
* @var string
|
143 |
+
* @access private
|
144 |
+
*/
|
145 |
+
var $status = 'is';
|
146 |
+
/**
|
147 |
+
* Saves the current at rule (@media)
|
148 |
+
* @var string
|
149 |
+
* @access private
|
150 |
+
*/
|
151 |
+
var $at = '';
|
152 |
+
/**
|
153 |
+
* Saves the current selector
|
154 |
+
* @var string
|
155 |
+
* @access private
|
156 |
+
*/
|
157 |
+
var $selector = '';
|
158 |
+
/**
|
159 |
+
* Saves the current property
|
160 |
+
* @var string
|
161 |
+
* @access private
|
162 |
+
*/
|
163 |
+
var $property = '';
|
164 |
+
/**
|
165 |
+
* Saves the position of , in selectors
|
166 |
+
* @var array
|
167 |
+
* @access private
|
168 |
+
*/
|
169 |
+
var $sel_separate = array();
|
170 |
+
/**
|
171 |
+
* Saves the current value
|
172 |
+
* @var string
|
173 |
+
* @access private
|
174 |
+
*/
|
175 |
+
var $value = '';
|
176 |
+
/**
|
177 |
+
* Saves the current sub-value
|
178 |
+
*
|
179 |
+
* Example for a subvalue:
|
180 |
+
* background:url(foo.png) red no-repeat;
|
181 |
+
* "url(foo.png)", "red", and "no-repeat" are subvalues,
|
182 |
+
* seperated by whitespace
|
183 |
+
* @var string
|
184 |
+
* @access private
|
185 |
+
*/
|
186 |
+
var $sub_value = '';
|
187 |
+
/**
|
188 |
+
* Array which saves all subvalues for a property.
|
189 |
+
* @var array
|
190 |
+
* @see sub_value
|
191 |
+
* @access private
|
192 |
+
*/
|
193 |
+
var $sub_value_arr = array();
|
194 |
+
/**
|
195 |
+
* Saves the stack of characters that opened the current strings
|
196 |
+
* @var array
|
197 |
+
* @access private
|
198 |
+
*/
|
199 |
+
var $str_char = array();
|
200 |
+
var $cur_string = array();
|
201 |
+
/**
|
202 |
+
* Status from which the parser switched to ic or instr
|
203 |
+
* @var array
|
204 |
+
* @access private
|
205 |
+
*/
|
206 |
+
var $from = array();
|
207 |
+
/**
|
208 |
+
/**
|
209 |
+
* =true if in invalid at-rule
|
210 |
+
* @var bool
|
211 |
+
* @access private
|
212 |
+
*/
|
213 |
+
var $invalid_at = false;
|
214 |
+
/**
|
215 |
+
* =true if something has been added to the current selector
|
216 |
+
* @var bool
|
217 |
+
* @access private
|
218 |
+
*/
|
219 |
+
var $added = false;
|
220 |
+
/**
|
221 |
+
* Array which saves the message log
|
222 |
+
* @var array
|
223 |
+
* @access private
|
224 |
+
*/
|
225 |
+
var $log = array();
|
226 |
+
/**
|
227 |
+
* Saves the line number
|
228 |
+
* @var integer
|
229 |
+
* @access private
|
230 |
+
*/
|
231 |
+
var $line = 1;
|
232 |
+
/**
|
233 |
+
* Marks if we need to leave quotes for a string
|
234 |
+
* @var array
|
235 |
+
* @access private
|
236 |
+
*/
|
237 |
+
var $quoted_string = array();
|
238 |
+
|
239 |
+
/**
|
240 |
+
* List of tokens
|
241 |
+
* @var string
|
242 |
+
*/
|
243 |
+
var $tokens_list = "";
|
244 |
+
/**
|
245 |
+
* Loads standard template and sets default settings
|
246 |
+
* @access private
|
247 |
+
* @version 1.3
|
248 |
+
*/
|
249 |
+
function csstidy() {
|
250 |
+
$this->settings['remove_bslash'] = true;
|
251 |
+
$this->settings['compress_colors'] = true;
|
252 |
+
$this->settings['compress_font-weight'] = true;
|
253 |
+
$this->settings['lowercase_s'] = false;
|
254 |
+
/*
|
255 |
+
1 common shorthands optimization
|
256 |
+
2 + font property optimization
|
257 |
+
3 + background property optimization
|
258 |
+
*/
|
259 |
+
$this->settings['optimise_shorthands'] = 1;
|
260 |
+
$this->settings['remove_last_;'] = true;
|
261 |
+
/* rewrite all properties with low case, better for later gzip OK, safe*/
|
262 |
+
$this->settings['case_properties'] = 1;
|
263 |
+
/* sort properties in alpabetic order, better for later gzip
|
264 |
+
* but can cause trouble in case of overiding same propertie or using hack
|
265 |
+
*/
|
266 |
+
$this->settings['sort_properties'] = false;
|
267 |
+
/*
|
268 |
+
1, 3, 5, etc -- enable sorting selectors inside @media: a{}b{}c{}
|
269 |
+
2, 5, 8, etc -- enable sorting selectors inside one CSS declaration: a,b,c{}
|
270 |
+
preserve order by default cause it can break functionnality
|
271 |
+
*/
|
272 |
+
$this->settings['sort_selectors'] = 0;
|
273 |
+
/* is dangeroues to be used: CSS is broken sometimes */
|
274 |
+
$this->settings['merge_selectors'] = 0;
|
275 |
+
/* preserve or not browser hacks */
|
276 |
+
$this->settings['discard_invalid_selectors'] = false;
|
277 |
+
$this->settings['discard_invalid_properties'] = false;
|
278 |
+
$this->settings['css_level'] = 'CSS2.1';
|
279 |
+
$this->settings['preserve_css'] = false;
|
280 |
+
$this->settings['timestamp'] = false;
|
281 |
+
$this->settings['template'] = ''; // say that propertie exist
|
282 |
+
$this->set_cfg('template','default'); // call load_template
|
283 |
+
$this->optimise = new csstidy_optimise($this);
|
284 |
+
|
285 |
+
$this->tokens_list = & $GLOBALS['csstidy']['tokens'];
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Get the value of a setting.
|
290 |
+
* @param string $setting
|
291 |
+
* @access public
|
292 |
+
* @return mixed
|
293 |
+
* @version 1.0
|
294 |
+
*/
|
295 |
+
function get_cfg($setting) {
|
296 |
+
if (isset($this->settings[$setting])) {
|
297 |
+
return $this->settings[$setting];
|
298 |
+
}
|
299 |
+
return false;
|
300 |
+
}
|
301 |
+
|
302 |
+
/**
|
303 |
+
* Load a template
|
304 |
+
* @param string $template used by set_cfg to load a template via a configuration setting
|
305 |
+
* @access private
|
306 |
+
* @version 1.4
|
307 |
+
*/
|
308 |
+
function _load_template($template) {
|
309 |
+
switch ($template) {
|
310 |
+
case 'default':
|
311 |
+
$this->load_template('default');
|
312 |
+
break;
|
313 |
+
|
314 |
+
case 'highest':
|
315 |
+
$this->load_template('highest_compression');
|
316 |
+
break;
|
317 |
+
|
318 |
+
case 'high':
|
319 |
+
$this->load_template('high_compression');
|
320 |
+
break;
|
321 |
+
|
322 |
+
case 'low':
|
323 |
+
$this->load_template('low_compression');
|
324 |
+
break;
|
325 |
+
|
326 |
+
default:
|
327 |
+
$this->load_template($template);
|
328 |
+
break;
|
329 |
+
}
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* Set the value of a setting.
|
334 |
+
* @param string $setting
|
335 |
+
* @param mixed $value
|
336 |
+
* @access public
|
337 |
+
* @return bool
|
338 |
+
* @version 1.0
|
339 |
+
*/
|
340 |
+
function set_cfg($setting, $value=null) {
|
341 |
+
if (is_array($setting) && $value === null) {
|
342 |
+
foreach ($setting as $setprop => $setval) {
|
343 |
+
$this->settings[$setprop] = $setval;
|
344 |
+
}
|
345 |
+
if (array_key_exists('template', $setting)) {
|
346 |
+
$this->_load_template($this->settings['template']);
|
347 |
+
}
|
348 |
+
return true;
|
349 |
+
} else if (isset($this->settings[$setting]) && $value !== '') {
|
350 |
+
$this->settings[$setting] = $value;
|
351 |
+
if ($setting === 'template') {
|
352 |
+
$this->_load_template($this->settings['template']);
|
353 |
+
}
|
354 |
+
return true;
|
355 |
+
}
|
356 |
+
return false;
|
357 |
+
}
|
358 |
+
|
359 |
+
/**
|
360 |
+
* Adds a token to $this->tokens
|
361 |
+
* @param mixed $type
|
362 |
+
* @param string $data
|
363 |
+
* @param bool $do add a token even if preserve_css is off
|
364 |
+
* @access private
|
365 |
+
* @version 1.0
|
366 |
+
*/
|
367 |
+
function _add_token($type, $data, $do = false) {
|
368 |
+
if ($this->get_cfg('preserve_css') || $do) {
|
369 |
+
$this->tokens[] = array($type, ($type == COMMENT) ? $data : trim($data));
|
370 |
+
}
|
371 |
+
}
|
372 |
+
|
373 |
+
/**
|
374 |
+
* Add a message to the message log
|
375 |
+
* @param string $message
|
376 |
+
* @param string $type
|
377 |
+
* @param integer $line
|
378 |
+
* @access private
|
379 |
+
* @version 1.0
|
380 |
+
*/
|
381 |
+
function log($message, $type, $line = -1) {
|
382 |
+
if ($line === -1) {
|
383 |
+
$line = $this->line;
|
384 |
+
}
|
385 |
+
$line = intval($line);
|
386 |
+
$add = array('m' => $message, 't' => $type);
|
387 |
+
if (!isset($this->log[$line]) || !in_array($add, $this->log[$line])) {
|
388 |
+
$this->log[$line][] = $add;
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
/**
|
393 |
+
* Parse unicode notations and find a replacement character
|
394 |
+
* @param string $string
|
395 |
+
* @param integer $i
|
396 |
+
* @access private
|
397 |
+
* @return string
|
398 |
+
* @version 1.2
|
399 |
+
*/
|
400 |
+
function _unicode(&$string, &$i) {
|
401 |
+
++$i;
|
402 |
+
$add = '';
|
403 |
+
$replaced = false;
|
404 |
+
|
405 |
+
while ($i < strlen($string) && (ctype_xdigit($string{$i}) || ctype_space($string{$i})) && strlen($add) < 6) {
|
406 |
+
$add .= $string{$i};
|
407 |
+
|
408 |
+
if (ctype_space($string{$i})) {
|
409 |
+
break;
|
410 |
+
}
|
411 |
+
$i++;
|
412 |
+
}
|
413 |
+
|
414 |
+
if (hexdec($add) > 47 && hexdec($add) < 58 || hexdec($add) > 64 && hexdec($add) < 91 || hexdec($add) > 96 && hexdec($add) < 123) {
|
415 |
+
$this->log('Replaced unicode notation: Changed \\' . $add . ' to ' . chr(hexdec($add)), 'Information');
|
416 |
+
$add = chr(hexdec($add));
|
417 |
+
$replaced = true;
|
418 |
+
} else {
|
419 |
+
$add = trim('\\' . $add);
|
420 |
+
}
|
421 |
+
|
422 |
+
if (@ctype_xdigit($string{$i + 1}) && ctype_space($string{$i})
|
423 |
+
&& !$replaced || !ctype_space($string{$i})) {
|
424 |
+
$i--;
|
425 |
+
}
|
426 |
+
|
427 |
+
if ($add !== '\\' || !$this->get_cfg('remove_bslash') || strpos($this->tokens_list, $string{$i + 1}) !== false) {
|
428 |
+
return $add;
|
429 |
+
}
|
430 |
+
|
431 |
+
if ($add === '\\') {
|
432 |
+
$this->log('Removed unnecessary backslash', 'Information');
|
433 |
+
}
|
434 |
+
return '';
|
435 |
+
}
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Write formatted output to a file
|
439 |
+
* @param string $filename
|
440 |
+
* @param string $doctype when printing formatted, is a shorthand for the document type
|
441 |
+
* @param bool $externalcss when printing formatted, indicates whether styles to be attached internally or as an external stylesheet
|
442 |
+
* @param string $title when printing formatted, is the title to be added in the head of the document
|
443 |
+
* @param string $lang when printing formatted, gives a two-letter language code to be added to the output
|
444 |
+
* @access public
|
445 |
+
* @version 1.4
|
446 |
+
*/
|
447 |
+
function write_page($filename, $doctype='xhtml1.1', $externalcss=true, $title='', $lang='en') {
|
448 |
+
$this->write($filename, true);
|
449 |
+
}
|
450 |
+
|
451 |
+
/**
|
452 |
+
* Write plain output to a file
|
453 |
+
* @param string $filename
|
454 |
+
* @param bool $formatted whether to print formatted or not
|
455 |
+
* @param string $doctype when printing formatted, is a shorthand for the document type
|
456 |
+
* @param bool $externalcss when printing formatted, indicates whether styles to be attached internally or as an external stylesheet
|
457 |
+
* @param string $title when printing formatted, is the title to be added in the head of the document
|
458 |
+
* @param string $lang when printing formatted, gives a two-letter language code to be added to the output
|
459 |
+
* @param bool $pre_code whether to add pre and code tags around the code (for light HTML formatted templates)
|
460 |
+
* @access public
|
461 |
+
* @version 1.4
|
462 |
+
*/
|
463 |
+
function write($filename, $formatted=false, $doctype='xhtml1.1', $externalcss=true, $title='', $lang='en', $pre_code=true) {
|
464 |
+
$filename .= ( $formatted) ? '.xhtml' : '.css';
|
465 |
+
|
466 |
+
if (!is_dir('temp')) {
|
467 |
+
$madedir = mkdir('temp');
|
468 |
+
if (!$madedir) {
|
469 |
+
print 'Could not make directory "temp" in ' . dirname(__FILE__);
|
470 |
+
exit;
|
471 |
+
}
|
472 |
+
}
|
473 |
+
$handle = fopen('temp/' . $filename, 'w');
|
474 |
+
if ($handle) {
|
475 |
+
if (!$formatted) {
|
476 |
+
fwrite($handle, $this->print->plain());
|
477 |
+
} else {
|
478 |
+
fwrite($handle, $this->print->formatted_page($doctype, $externalcss, $title, $lang, $pre_code));
|
479 |
+
}
|
480 |
+
}
|
481 |
+
fclose($handle);
|
482 |
+
}
|
483 |
+
|
484 |
+
/**
|
485 |
+
* Loads a new template
|
486 |
+
* @param string $content either filename (if $from_file == true), content of a template file, "high_compression", "highest_compression", "low_compression", or "default"
|
487 |
+
* @param bool $from_file uses $content as filename if true
|
488 |
+
* @access public
|
489 |
+
* @version 1.1
|
490 |
+
* @see http://csstidy.sourceforge.net/templates.php
|
491 |
+
*/
|
492 |
+
function load_template($content, $from_file=true) {
|
493 |
+
$predefined_templates = & $GLOBALS['csstidy']['predefined_templates'];
|
494 |
+
if ($content === 'high_compression' || $content === 'default' || $content === 'highest_compression' || $content === 'low_compression') {
|
495 |
+
$this->template = $predefined_templates[$content];
|
496 |
+
return;
|
497 |
+
}
|
498 |
+
|
499 |
+
|
500 |
+
if ($from_file) {
|
501 |
+
$content = strip_tags(file_get_contents($content), '<span>');
|
502 |
+
}
|
503 |
+
$content = str_replace("\r\n", "\n", $content); // Unify newlines (because the output also only uses \n)
|
504 |
+
$template = explode('|', $content);
|
505 |
+
|
506 |
+
for ($i = 0; $i < count($template); $i++) {
|
507 |
+
$this->template[$i] = $template[$i];
|
508 |
+
}
|
509 |
+
}
|
510 |
+
|
511 |
+
/**
|
512 |
+
* Starts parsing from URL
|
513 |
+
* @param string $url
|
514 |
+
* @access public
|
515 |
+
* @version 1.0
|
516 |
+
*/
|
517 |
+
function parse_from_url($url) {
|
518 |
+
return $this->parse(@file_get_contents($url));
|
519 |
+
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Checks if there is a token at the current position
|
523 |
+
* @param string $string
|
524 |
+
* @param integer $i
|
525 |
+
* @access public
|
526 |
+
* @version 1.11
|
527 |
+
*/
|
528 |
+
function is_token(&$string, $i) {
|
529 |
+
return (strpos($this->tokens_list, $string{$i}) !== false && !csstidy::escaped($string, $i));
|
530 |
+
}
|
531 |
+
|
532 |
+
/**
|
533 |
+
* Parses CSS in $string. The code is saved as array in $this->css
|
534 |
+
* @param string $string the CSS code
|
535 |
+
* @access public
|
536 |
+
* @return bool
|
537 |
+
* @version 1.1
|
538 |
+
*/
|
539 |
+
function parse($string) {
|
540 |
+
// Temporarily set locale to en_US in order to handle floats properly
|
541 |
+
$old = @setlocale(LC_ALL, 0);
|
542 |
+
@setlocale(LC_ALL, 'C');
|
543 |
+
|
544 |
+
// PHP bug? Settings need to be refreshed in PHP4
|
545 |
+
$this->print = new csstidy_print($this);
|
546 |
+
//$this->optimise = new csstidy_optimise($this);
|
547 |
+
|
548 |
+
$all_properties = & $GLOBALS['csstidy']['all_properties'];
|
549 |
+
$at_rules = & $GLOBALS['csstidy']['at_rules'];
|
550 |
+
$quoted_string_properties = & $GLOBALS['csstidy']['quoted_string_properties'];
|
551 |
+
|
552 |
+
$this->css = array();
|
553 |
+
$this->print->input_css = $string;
|
554 |
+
$string = str_replace("\r\n", "\n", $string) . ' ';
|
555 |
+
$cur_comment = '';
|
556 |
+
|
557 |
+
for ($i = 0, $size = strlen($string); $i < $size; $i++) {
|
558 |
+
if ($string{$i} === "\n" || $string{$i} === "\r") {
|
559 |
+
++$this->line;
|
560 |
+
}
|
561 |
+
|
562 |
+
switch ($this->status) {
|
563 |
+
/* Case in at-block */
|
564 |
+
case 'at':
|
565 |
+
if (csstidy::is_token($string, $i)) {
|
566 |
+
if ($string{$i} === '/' && @$string{$i + 1} === '*') {
|
567 |
+
$this->status = 'ic';
|
568 |
+
++$i;
|
569 |
+
$this->from[] = 'at';
|
570 |
+
} elseif ($string{$i} === '{') {
|
571 |
+
$this->status = 'is';
|
572 |
+
$this->at = $this->css_new_media_section($this->at);
|
573 |
+
$this->_add_token(AT_START, $this->at);
|
574 |
+
} elseif ($string{$i} === ',') {
|
575 |
+
$this->at = trim($this->at) . ',';
|
576 |
+
} elseif ($string{$i} === '\\') {
|
577 |
+
$this->at .= $this->_unicode($string, $i);
|
578 |
+
}
|
579 |
+
// fix for complicated media, i.e @media screen and (-webkit-min-device-pixel-ratio:1.5)
|
580 |
+
// '/' is included for ratios in Opera: (-o-min-device-pixel-ratio: 3/2)
|
581 |
+
elseif (in_array($string{$i}, array('(', ')', ':', '.', '/'))) {
|
582 |
+
$this->at .= $string{$i};
|
583 |
+
}
|
584 |
+
} else {
|
585 |
+
$lastpos = strlen($this->at) - 1;
|
586 |
+
if (!( (ctype_space($this->at{$lastpos}) || csstidy::is_token($this->at, $lastpos) && $this->at{$lastpos} === ',') && ctype_space($string{$i}))) {
|
587 |
+
$this->at .= $string{$i};
|
588 |
+
}
|
589 |
+
}
|
590 |
+
break;
|
591 |
+
|
592 |
+
/* Case in-selector */
|
593 |
+
case 'is':
|
594 |
+
if (csstidy::is_token($string, $i)) {
|
595 |
+
if ($string{$i} === '/' && @$string{$i + 1} === '*' && trim($this->selector) == '') {
|
596 |
+
$this->status = 'ic';
|
597 |
+
++$i;
|
598 |
+
$this->from[] = 'is';
|
599 |
+
} elseif ($string{$i} === '@' && trim($this->selector) == '') {
|
600 |
+
// Check for at-rule
|
601 |
+
$this->invalid_at = true;
|
602 |
+
foreach ($at_rules as $name => $type) {
|
603 |
+
if (!strcasecmp(substr($string, $i + 1, strlen($name)), $name)) {
|
604 |
+
($type === 'at') ? $this->at = '@' . $name : $this->selector = '@' . $name;
|
605 |
+
$this->status = $type;
|
606 |
+
$i += strlen($name);
|
607 |
+
$this->invalid_at = false;
|
608 |
+
}
|
609 |
+
}
|
610 |
+
|
611 |
+
if ($this->invalid_at) {
|
612 |
+
$this->selector = '@';
|
613 |
+
$invalid_at_name = '';
|
614 |
+
for ($j = $i + 1; $j < $size; ++$j) {
|
615 |
+
if (!ctype_alpha($string{$j})) {
|
616 |
+
break;
|
617 |
+
}
|
618 |
+
$invalid_at_name .= $string{$j};
|
619 |
+
}
|
620 |
+
$this->log('Invalid @-rule: ' . $invalid_at_name . ' (removed)', 'Warning');
|
621 |
+
}
|
622 |
+
} elseif (($string{$i} === '"' || $string{$i} === "'")) {
|
623 |
+
$this->cur_string[] = $string{$i};
|
624 |
+
$this->status = 'instr';
|
625 |
+
$this->str_char[] = $string{$i};
|
626 |
+
$this->from[] = 'is';
|
627 |
+
/* fixing CSS3 attribute selectors, i.e. a[href$=".mp3" */
|
628 |
+
$this->quoted_string[] = ($string{$i - 1} == '=' );
|
629 |
+
} elseif ($this->invalid_at && $string{$i} === ';') {
|
630 |
+
$this->invalid_at = false;
|
631 |
+
$this->status = 'is';
|
632 |
+
} elseif ($string{$i} === '{') {
|
633 |
+
$this->status = 'ip';
|
634 |
+
if($this->at == '') {
|
635 |
+
$this->at = $this->css_new_media_section(DEFAULT_AT);
|
636 |
+
}
|
637 |
+
$this->selector = $this->css_new_selector($this->at,$this->selector);
|
638 |
+
$this->_add_token(SEL_START, $this->selector);
|
639 |
+
$this->added = false;
|
640 |
+
} elseif ($string{$i} === '}') {
|
641 |
+
$this->_add_token(AT_END, $this->at);
|
642 |
+
$this->at = '';
|
643 |
+
$this->selector = '';
|
644 |
+
$this->sel_separate = array();
|
645 |
+
} elseif ($string{$i} === ',') {
|
646 |
+
$this->selector = trim($this->selector) . ',';
|
647 |
+
$this->sel_separate[] = strlen($this->selector);
|
648 |
+
} elseif ($string{$i} === '\\') {
|
649 |
+
$this->selector .= $this->_unicode($string, $i);
|
650 |
+
} elseif ($string{$i} === '*' && @in_array($string{$i + 1}, array('.', '#', '[', ':'))) {
|
651 |
+
// remove unnecessary universal selector, FS#147
|
652 |
+
} else {
|
653 |
+
$this->selector .= $string{$i};
|
654 |
+
}
|
655 |
+
} else {
|
656 |
+
$lastpos = strlen($this->selector) - 1;
|
657 |
+
if ($lastpos == -1 || !( (ctype_space($this->selector{$lastpos}) || csstidy::is_token($this->selector, $lastpos) && $this->selector{$lastpos} === ',') && ctype_space($string{$i}))) {
|
658 |
+
$this->selector .= $string{$i};
|
659 |
+
}
|
660 |
+
else if (ctype_space($string{$i}) && $this->get_cfg('preserve_css') && !$this->get_cfg('merge_selectors')) {
|
661 |
+
$this->selector .= $string{$i};
|
662 |
+
}
|
663 |
+
}
|
664 |
+
break;
|
665 |
+
|
666 |
+
/* Case in-property */
|
667 |
+
case 'ip':
|
668 |
+
if (csstidy::is_token($string, $i)) {
|
669 |
+
if (($string{$i} === ':' || $string{$i} === '=') && $this->property != '') {
|
670 |
+
$this->status = 'iv';
|
671 |
+
if (!$this->get_cfg('discard_invalid_properties') || csstidy::property_is_valid($this->property)) {
|
672 |
+
$this->property = $this->css_new_property($this->at,$this->selector,$this->property);
|
673 |
+
$this->_add_token(PROPERTY, $this->property);
|
674 |
+
}
|
675 |
+
} elseif ($string{$i} === '/' && @$string{$i + 1} === '*' && $this->property == '') {
|
676 |
+
$this->status = 'ic';
|
677 |
+
++$i;
|
678 |
+
$this->from[] = 'ip';
|
679 |
+
} elseif ($string{$i} === '}') {
|
680 |
+
$this->explode_selectors();
|
681 |
+
$this->status = 'is';
|
682 |
+
$this->invalid_at = false;
|
683 |
+
$this->_add_token(SEL_END, $this->selector);
|
684 |
+
$this->selector = '';
|
685 |
+
$this->property = '';
|
686 |
+
} elseif ($string{$i} === ';') {
|
687 |
+
$this->property = '';
|
688 |
+
} elseif ($string{$i} === '\\') {
|
689 |
+
$this->property .= $this->_unicode($string, $i);
|
690 |
+
}
|
691 |
+
// else this is dumb IE a hack, keep it
|
692 |
+
elseif ($this->property=='' AND !ctype_space($string{$i})) {
|
693 |
+
$this->property .= $string{$i};
|
694 |
+
}
|
695 |
+
}
|
696 |
+
elseif (!ctype_space($string{$i})) {
|
697 |
+
$this->property .= $string{$i};
|
698 |
+
}
|
699 |
+
break;
|
700 |
+
|
701 |
+
/* Case in-value */
|
702 |
+
case 'iv':
|
703 |
+
$pn = (($string{$i} === "\n" || $string{$i} === "\r") && $this->property_is_next($string, $i + 1) || $i == strlen($string) - 1);
|
704 |
+
if ((csstidy::is_token($string, $i) || $pn) && (!($string{$i} == ',' && !ctype_space($string{$i+1})))) {
|
705 |
+
if ($string{$i} === '/' && @$string{$i + 1} === '*') {
|
706 |
+
$this->status = 'ic';
|
707 |
+
++$i;
|
708 |
+
$this->from[] = 'iv';
|
709 |
+
} elseif (($string{$i} === '"' || $string{$i} === "'" || $string{$i} === '(')) {
|
710 |
+
$this->cur_string[] = $string{$i};
|
711 |
+
$this->str_char[] = ($string{$i} === '(') ? ')' : $string{$i};
|
712 |
+
$this->status = 'instr';
|
713 |
+
$this->from[] = 'iv';
|
714 |
+
$this->quoted_string[] = in_array(strtolower($this->property), $quoted_string_properties);
|
715 |
+
} elseif ($string{$i} === ',') {
|
716 |
+
$this->sub_value = trim($this->sub_value) . ',';
|
717 |
+
} elseif ($string{$i} === '\\') {
|
718 |
+
$this->sub_value .= $this->_unicode($string, $i);
|
719 |
+
} elseif ($string{$i} === ';' || $pn) {
|
720 |
+
if ($this->selector{0} === '@' && isset($at_rules[substr($this->selector, 1)]) && $at_rules[substr($this->selector, 1)] === 'iv') {
|
721 |
+
$this->status = 'is';
|
722 |
+
|
723 |
+
switch ($this->selector) {
|
724 |
+
case '@charset':
|
725 |
+
/* Add quotes to charset */
|
726 |
+
$this->sub_value_arr[] = '"' . trim($this->sub_value) . '"';
|
727 |
+
$this->charset = $this->sub_value_arr[0];
|
728 |
+
break;
|
729 |
+
case '@namespace':
|
730 |
+
/* Add quotes to namespace */
|
731 |
+
$this->sub_value_arr[] = '"' . trim($this->sub_value) . '"';
|
732 |
+
$this->namespace = implode(' ', $this->sub_value_arr);
|
733 |
+
break;
|
734 |
+
case '@import':
|
735 |
+
$this->sub_value = trim($this->sub_value);
|
736 |
+
|
737 |
+
if (empty($this->sub_value_arr)) {
|
738 |
+
// Quote URLs in imports only if they're not already inside url() and not already quoted.
|
739 |
+
if (substr($this->sub_value, 0, 4) != 'url(') {
|
740 |
+
if (!($this->sub_value{0} == substr($this->sub_value, -1) && in_array($this->sub_value{0}, array("'", '"')))) {
|
741 |
+
$this->sub_value = '"' . $this->sub_value . '"';
|
742 |
+
}
|
743 |
+
}
|
744 |
+
}
|
745 |
+
|
746 |
+
$this->sub_value_arr[] = $this->sub_value;
|
747 |
+
$this->import[] = implode(' ', $this->sub_value_arr);
|
748 |
+
break;
|
749 |
+
}
|
750 |
+
|
751 |
+
$this->sub_value_arr = array();
|
752 |
+
$this->sub_value = '';
|
753 |
+
$this->selector = '';
|
754 |
+
$this->sel_separate = array();
|
755 |
+
} else {
|
756 |
+
$this->status = 'ip';
|
757 |
+
}
|
758 |
+
} elseif ($string{$i} !== '}') {
|
759 |
+
$this->sub_value .= $string{$i};
|
760 |
+
}
|
761 |
+
if (($string{$i} === '}' || $string{$i} === ';' || $pn) && !empty($this->selector)) {
|
762 |
+
if ($this->at == '') {
|
763 |
+
$this->at = $this->css_new_media_section(DEFAULT_AT);
|
764 |
+
}
|
765 |
+
|
766 |
+
// case settings
|
767 |
+
if ($this->get_cfg('lowercase_s')) {
|
768 |
+
$this->selector = strtolower($this->selector);
|
769 |
+
}
|
770 |
+
$this->property = strtolower($this->property);
|
771 |
+
|
772 |
+
$this->optimise->subvalue();
|
773 |
+
if ($this->sub_value != '') {
|
774 |
+
if (substr($this->sub_value, 0, 6) == 'format') {
|
775 |
+
$format_strings = csstidy::parse_string_list(substr($this->sub_value, 7, -1));
|
776 |
+
if (!$format_strings) {
|
777 |
+
$this->sub_value = "";
|
778 |
+
}
|
779 |
+
else {
|
780 |
+
$this->sub_value = "format(";
|
781 |
+
|
782 |
+
foreach ($format_strings as $format_string) {
|
783 |
+
$this->sub_value .= '"' . str_replace('"', '\\"', $format_string) . '",';
|
784 |
+
}
|
785 |
+
|
786 |
+
$this->sub_value = substr($this->sub_value, 0, -1) . ")";
|
787 |
+
}
|
788 |
+
}
|
789 |
+
if ($this->sub_value != '') {
|
790 |
+
$this->sub_value_arr[] = $this->sub_value;
|
791 |
+
}
|
792 |
+
$this->sub_value = '';
|
793 |
+
}
|
794 |
+
|
795 |
+
$this->value = array_shift($this->sub_value_arr);
|
796 |
+
while(count($this->sub_value_arr)){
|
797 |
+
//$this->value .= (substr($this->value,-1,1)==','?'':' ').array_shift($this->sub_value_arr);
|
798 |
+
$this->value .= ' '.array_shift($this->sub_value_arr);
|
799 |
+
}
|
800 |
+
|
801 |
+
$this->optimise->value();
|
802 |
+
|
803 |
+
$valid = csstidy::property_is_valid($this->property);
|
804 |
+
if ((!$this->invalid_at || $this->get_cfg('preserve_css')) && (!$this->get_cfg('discard_invalid_properties') || $valid)) {
|
805 |
+
$this->css_add_property($this->at, $this->selector, $this->property, $this->value);
|
806 |
+
$this->_add_token(VALUE, $this->value);
|
807 |
+
$this->optimise->shorthands();
|
808 |
+
}
|
809 |
+
if (!$valid) {
|
810 |
+
if ($this->get_cfg('discard_invalid_properties')) {
|
811 |
+
$this->log('Removed invalid property: ' . $this->property, 'Warning');
|
812 |
+
} else {
|
813 |
+
$this->log('Invalid property in ' . strtoupper($this->get_cfg('css_level')) . ': ' . $this->property, 'Warning');
|
814 |
+
}
|
815 |
+
}
|
816 |
+
|
817 |
+
$this->property = '';
|
818 |
+
$this->sub_value_arr = array();
|
819 |
+
$this->value = '';
|
820 |
+
}
|
821 |
+
if ($string{$i} === '}') {
|
822 |
+
$this->explode_selectors();
|
823 |
+
$this->_add_token(SEL_END, $this->selector);
|
824 |
+
$this->status = 'is';
|
825 |
+
$this->invalid_at = false;
|
826 |
+
$this->selector = '';
|
827 |
+
}
|
828 |
+
} elseif (!$pn) {
|
829 |
+
$this->sub_value .= $string{$i};
|
830 |
+
|
831 |
+
if (ctype_space($string{$i}) || $string{$i} == ',') {
|
832 |
+
$this->optimise->subvalue();
|
833 |
+
if ($this->sub_value != '') {
|
834 |
+
$this->sub_value_arr[] = $this->sub_value;
|
835 |
+
$this->sub_value = '';
|
836 |
+
}
|
837 |
+
}
|
838 |
+
}
|
839 |
+
break;
|
840 |
+
|
841 |
+
/* Case in string */
|
842 |
+
case 'instr':
|
843 |
+
$_str_char = $this->str_char[count($this->str_char)-1];
|
844 |
+
$_cur_string = $this->cur_string[count($this->cur_string)-1];
|
845 |
+
$temp_add = $string{$i};
|
846 |
+
|
847 |
+
// Add another string to the stack. Strings can't be nested inside of quotes, only parentheses, but
|
848 |
+
// parentheticals can be nested more than once.
|
849 |
+
if ($_str_char === ")" && ($string{$i} === "(" || $string{$i} === '"' || $string{$i} === '\'') && !csstidy::escaped($string, $i)) {
|
850 |
+
$this->cur_string[] = $string{$i};
|
851 |
+
$this->str_char[] = $string{$i} == "(" ? ")" : $string{$i};
|
852 |
+
$this->from[] = 'instr';
|
853 |
+
$this->quoted_string[] = !($string{$i} === "(");
|
854 |
+
continue;
|
855 |
+
}
|
856 |
+
|
857 |
+
if ($_str_char !== ")" && ($string{$i} === "\n" || $string{$i} === "\r") && !($string{$i - 1} === '\\' && !csstidy::escaped($string, $i - 1))) {
|
858 |
+
$temp_add = "\\A";
|
859 |
+
$this->log('Fixed incorrect newline in string', 'Warning');
|
860 |
+
}
|
861 |
+
|
862 |
+
$_cur_string .= $temp_add;
|
863 |
+
|
864 |
+
if ($string{$i} === $_str_char && !csstidy::escaped($string, $i)) {
|
865 |
+
$_quoted_string = array_pop($this->quoted_string);
|
866 |
+
|
867 |
+
$this->status = array_pop($this->from);
|
868 |
+
|
869 |
+
if (!preg_match('|[' . implode('', $GLOBALS['csstidy']['whitespace']) . ']|uis', $_cur_string) && $this->property !== 'content') {
|
870 |
+
if (!$_quoted_string) {
|
871 |
+
if ($_str_char !== ')') {
|
872 |
+
// Convert properties like
|
873 |
+
// font-family: 'Arial';
|
874 |
+
// to
|
875 |
+
// font-family: Arial;
|
876 |
+
// or
|
877 |
+
// url("abc")
|
878 |
+
// to
|
879 |
+
// url(abc)
|
880 |
+
$_cur_string = substr($_cur_string, 1, -1);
|
881 |
+
}
|
882 |
+
} else {
|
883 |
+
$_quoted_string = false;
|
884 |
+
}
|
885 |
+
}
|
886 |
+
|
887 |
+
array_pop($this->cur_string);
|
888 |
+
array_pop($this->str_char);
|
889 |
+
|
890 |
+
if ($_str_char === ")") {
|
891 |
+
$_cur_string = "(" . trim(substr($_cur_string, 1, -1)) . ")";
|
892 |
+
}
|
893 |
+
|
894 |
+
if ($this->status === 'iv') {
|
895 |
+
if (!$_quoted_string){
|
896 |
+
if (strpos($_cur_string,',')!==false)
|
897 |
+
// we can on only remove space next to ','
|
898 |
+
$_cur_string = implode(',',array_map('trim',explode(',',$_cur_string)));
|
899 |
+
// and multiple spaces (too expensive)
|
900 |
+
if (strpos($_cur_string,' ')!==false)
|
901 |
+
$_cur_string = preg_replace(",\s+,"," ",$_cur_string);
|
902 |
+
}
|
903 |
+
$this->sub_value .= $_cur_string;
|
904 |
+
} elseif ($this->status === 'is') {
|
905 |
+
$this->selector .= $_cur_string;
|
906 |
+
} elseif ($this->status === 'instr') {
|
907 |
+
$this->cur_string[count($this->cur_string)-1] .= $_cur_string;
|
908 |
+
}
|
909 |
+
}
|
910 |
+
else {
|
911 |
+
$this->cur_string[count($this->cur_string)-1] = $_cur_string;
|
912 |
+
}
|
913 |
+
break;
|
914 |
+
|
915 |
+
/* Case in-comment */
|
916 |
+
case 'ic':
|
917 |
+
if ($string{$i} === '*' && $string{$i + 1} === '/') {
|
918 |
+
$this->status = array_pop($this->from);
|
919 |
+
$i++;
|
920 |
+
$this->_add_token(COMMENT, $cur_comment);
|
921 |
+
$cur_comment = '';
|
922 |
+
} else {
|
923 |
+
$cur_comment .= $string{$i};
|
924 |
+
}
|
925 |
+
break;
|
926 |
+
}
|
927 |
+
}
|
928 |
+
|
929 |
+
$this->optimise->postparse();
|
930 |
+
|
931 |
+
$this->print->_reset();
|
932 |
+
|
933 |
+
@setlocale(LC_ALL, $old); // Set locale back to original setting
|
934 |
+
|
935 |
+
return!(empty($this->css) && empty($this->import) && empty($this->charset) && empty($this->tokens) && empty($this->namespace));
|
936 |
+
}
|
937 |
+
|
938 |
+
/**
|
939 |
+
* Explodes selectors
|
940 |
+
* @access private
|
941 |
+
* @version 1.0
|
942 |
+
*/
|
943 |
+
function explode_selectors() {
|
944 |
+
// Explode multiple selectors
|
945 |
+
if ($this->get_cfg('merge_selectors') === 1) {
|
946 |
+
$new_sels = array();
|
947 |
+
$lastpos = 0;
|
948 |
+
$this->sel_separate[] = strlen($this->selector);
|
949 |
+
foreach ($this->sel_separate as $num => $pos) {
|
950 |
+
if ($num == count($this->sel_separate) - 1) {
|
951 |
+
$pos += 1;
|
952 |
+
}
|
953 |
+
|
954 |
+
$new_sels[] = substr($this->selector, $lastpos, $pos - $lastpos - 1);
|
955 |
+
$lastpos = $pos;
|
956 |
+
}
|
957 |
+
|
958 |
+
if (count($new_sels) > 1) {
|
959 |
+
foreach ($new_sels as $selector) {
|
960 |
+
if (isset($this->css[$this->at][$this->selector])) {
|
961 |
+
$this->merge_css_blocks($this->at, $selector, $this->css[$this->at][$this->selector]);
|
962 |
+
}
|
963 |
+
}
|
964 |
+
unset($this->css[$this->at][$this->selector]);
|
965 |
+
}
|
966 |
+
}
|
967 |
+
$this->sel_separate = array();
|
968 |
+
}
|
969 |
+
|
970 |
+
/**
|
971 |
+
* Checks if a character is escaped (and returns true if it is)
|
972 |
+
* @param string $string
|
973 |
+
* @param integer $pos
|
974 |
+
* @access public
|
975 |
+
* @return bool
|
976 |
+
* @version 1.02
|
977 |
+
*/
|
978 |
+
static function escaped(&$string, $pos) {
|
979 |
+
return!(@($string{$pos - 1} !== '\\') || csstidy::escaped($string, $pos - 1));
|
980 |
+
}
|
981 |
+
|
982 |
+
/**
|
983 |
+
* Adds a property with value to the existing CSS code
|
984 |
+
* @param string $media
|
985 |
+
* @param string $selector
|
986 |
+
* @param string $property
|
987 |
+
* @param string $new_val
|
988 |
+
* @access private
|
989 |
+
* @version 1.2
|
990 |
+
*/
|
991 |
+
function css_add_property($media, $selector, $property, $new_val) {
|
992 |
+
if ($this->get_cfg('preserve_css') || trim($new_val) == '') {
|
993 |
+
return;
|
994 |
+
}
|
995 |
+
|
996 |
+
$this->added = true;
|
997 |
+
if (isset($this->css[$media][$selector][$property])) {
|
998 |
+
if ((csstidy::is_important($this->css[$media][$selector][$property]) && csstidy::is_important($new_val)) || !csstidy::is_important($this->css[$media][$selector][$property])) {
|
999 |
+
$this->css[$media][$selector][$property] = trim($new_val);
|
1000 |
+
}
|
1001 |
+
} else {
|
1002 |
+
$this->css[$media][$selector][$property] = trim($new_val);
|
1003 |
+
}
|
1004 |
+
}
|
1005 |
+
|
1006 |
+
/**
|
1007 |
+
* Start a new media section.
|
1008 |
+
* Check if the media is not already known,
|
1009 |
+
* else rename it with extra spaces
|
1010 |
+
* to avoid merging
|
1011 |
+
*
|
1012 |
+
* @param string $media
|
1013 |
+
* @return string
|
1014 |
+
*/
|
1015 |
+
function css_new_media_section($media){
|
1016 |
+
if($this->get_cfg('preserve_css')) {
|
1017 |
+
return $media;
|
1018 |
+
}
|
1019 |
+
|
1020 |
+
// if the last @media is the same as this
|
1021 |
+
// keep it
|
1022 |
+
if (!$this->css OR !is_array($this->css) OR empty($this->css)){
|
1023 |
+
return $media;
|
1024 |
+
}
|
1025 |
+
end($this->css);
|
1026 |
+
list($at,) = each($this->css);
|
1027 |
+
if ($at == $media){
|
1028 |
+
return $media;
|
1029 |
+
}
|
1030 |
+
while (isset($this->css[$media]))
|
1031 |
+
if (is_numeric($media))
|
1032 |
+
$media++;
|
1033 |
+
else
|
1034 |
+
$media .= " ";
|
1035 |
+
return $media;
|
1036 |
+
}
|
1037 |
+
|
1038 |
+
/**
|
1039 |
+
* Start a new selector.
|
1040 |
+
* If already referenced in this media section,
|
1041 |
+
* rename it with extra space to avoid merging
|
1042 |
+
* except if merging is required,
|
1043 |
+
* or last selector is the same (merge siblings)
|
1044 |
+
*
|
1045 |
+
* never merge @font-face
|
1046 |
+
*
|
1047 |
+
* @param string $media
|
1048 |
+
* @param string $selector
|
1049 |
+
* @return string
|
1050 |
+
*/
|
1051 |
+
function css_new_selector($media,$selector){
|
1052 |
+
if($this->get_cfg('preserve_css')) {
|
1053 |
+
return $selector;
|
1054 |
+
}
|
1055 |
+
$selector = trim($selector);
|
1056 |
+
if (strncmp($selector,"@font-face",10)!=0){
|
1057 |
+
if ($this->settings['merge_selectors'] != false)
|
1058 |
+
return $selector;
|
1059 |
+
|
1060 |
+
if (!$this->css OR !isset($this->css[$media]) OR !$this->css[$media])
|
1061 |
+
return $selector;
|
1062 |
+
|
1063 |
+
// if last is the same, keep it
|
1064 |
+
end($this->css[$media]);
|
1065 |
+
list($sel,) = each($this->css[$media]);
|
1066 |
+
if ($sel == $selector){
|
1067 |
+
return $selector;
|
1068 |
+
}
|
1069 |
+
}
|
1070 |
+
|
1071 |
+
while (isset($this->css[$media][$selector]))
|
1072 |
+
$selector .= " ";
|
1073 |
+
return $selector;
|
1074 |
+
}
|
1075 |
+
|
1076 |
+
/**
|
1077 |
+
* Start a new propertie.
|
1078 |
+
* If already references in this selector,
|
1079 |
+
* rename it with extra space to avoid override
|
1080 |
+
*
|
1081 |
+
* @param string $media
|
1082 |
+
* @param string $selector
|
1083 |
+
* @param string $property
|
1084 |
+
* @return string
|
1085 |
+
*/
|
1086 |
+
function css_new_property($media, $selector, $property){
|
1087 |
+
if($this->get_cfg('preserve_css')) {
|
1088 |
+
return $property;
|
1089 |
+
}
|
1090 |
+
if (!$this->css OR !isset($this->css[$media][$selector]) OR !$this->css[$media][$selector])
|
1091 |
+
return $property;
|
1092 |
+
|
1093 |
+
while (isset($this->css[$media][$selector][$property]))
|
1094 |
+
$property .= " ";
|
1095 |
+
|
1096 |
+
return $property;
|
1097 |
+
}
|
1098 |
+
|
1099 |
+
/**
|
1100 |
+
* Adds CSS to an existing media/selector
|
1101 |
+
* @param string $media
|
1102 |
+
* @param string $selector
|
1103 |
+
* @param array $css_add
|
1104 |
+
* @access private
|
1105 |
+
* @version 1.1
|
1106 |
+
*/
|
1107 |
+
function merge_css_blocks($media, $selector, $css_add) {
|
1108 |
+
foreach ($css_add as $property => $value) {
|
1109 |
+
$this->css_add_property($media, $selector, $property, $value, false);
|
1110 |
+
}
|
1111 |
+
}
|
1112 |
+
|
1113 |
+
/**
|
1114 |
+
* Checks if $value is !important.
|
1115 |
+
* @param string $value
|
1116 |
+
* @return bool
|
1117 |
+
* @access public
|
1118 |
+
* @version 1.0
|
1119 |
+
*/
|
1120 |
+
static function is_important(&$value) {
|
1121 |
+
return (!strcasecmp(substr(str_replace($GLOBALS['csstidy']['whitespace'], '', $value), -10, 10), '!important'));
|
1122 |
+
}
|
1123 |
+
|
1124 |
+
/**
|
1125 |
+
* Returns a value without !important
|
1126 |
+
* @param string $value
|
1127 |
+
* @return string
|
1128 |
+
* @access public
|
1129 |
+
* @version 1.0
|
1130 |
+
*/
|
1131 |
+
static function gvw_important($value) {
|
1132 |
+
if (csstidy::is_important($value)) {
|
1133 |
+
$value = trim($value);
|
1134 |
+
$value = substr($value, 0, -9);
|
1135 |
+
$value = trim($value);
|
1136 |
+
$value = substr($value, 0, -1);
|
1137 |
+
$value = trim($value);
|
1138 |
+
return $value;
|
1139 |
+
}
|
1140 |
+
return $value;
|
1141 |
+
}
|
1142 |
+
|
1143 |
+
/**
|
1144 |
+
* Checks if the next word in a string from pos is a CSS property
|
1145 |
+
* @param string $istring
|
1146 |
+
* @param integer $pos
|
1147 |
+
* @return bool
|
1148 |
+
* @access private
|
1149 |
+
* @version 1.2
|
1150 |
+
*/
|
1151 |
+
function property_is_next($istring, $pos) {
|
1152 |
+
$all_properties = & $GLOBALS['csstidy']['all_properties'];
|
1153 |
+
$istring = substr($istring, $pos, strlen($istring) - $pos);
|
1154 |
+
$pos = strpos($istring, ':');
|
1155 |
+
if ($pos === false) {
|
1156 |
+
return false;
|
1157 |
+
}
|
1158 |
+
$istring = strtolower(trim(substr($istring, 0, $pos)));
|
1159 |
+
if (isset($all_properties[$istring])) {
|
1160 |
+
$this->log('Added semicolon to the end of declaration', 'Warning');
|
1161 |
+
return true;
|
1162 |
+
}
|
1163 |
+
return false;
|
1164 |
+
}
|
1165 |
+
|
1166 |
+
/**
|
1167 |
+
* Checks if a property is valid
|
1168 |
+
* @param string $property
|
1169 |
+
* @return bool;
|
1170 |
+
* @access public
|
1171 |
+
* @version 1.0
|
1172 |
+
*/
|
1173 |
+
function property_is_valid($property) {
|
1174 |
+
if (in_array(trim($property), $GLOBALS['csstidy']['multiple_properties'])) $property = trim($property);
|
1175 |
+
$all_properties = & $GLOBALS['csstidy']['all_properties'];
|
1176 |
+
return (isset($all_properties[$property]) && strpos($all_properties[$property], strtoupper($this->get_cfg('css_level'))) !== false );
|
1177 |
+
}
|
1178 |
+
|
1179 |
+
/**
|
1180 |
+
* Accepts a list of strings (e.g., the argument to format() in a @font-face src property)
|
1181 |
+
* and returns a list of the strings. Converts things like:
|
1182 |
+
*
|
1183 |
+
* format(abc) => format("abc")
|
1184 |
+
* format(abc def) => format("abc","def")
|
1185 |
+
* format(abc "def") => format("abc","def")
|
1186 |
+
* format(abc, def, ghi) => format("abc","def","ghi")
|
1187 |
+
* format("abc",'def') => format("abc","def")
|
1188 |
+
* format("abc, def, ghi") => format("abc, def, ghi")
|
1189 |
+
*
|
1190 |
+
* @param string
|
1191 |
+
* @return array
|
1192 |
+
*/
|
1193 |
+
|
1194 |
+
function parse_string_list($value) {
|
1195 |
+
$value = trim($value);
|
1196 |
+
|
1197 |
+
// Case: empty
|
1198 |
+
if (!$value) return array();
|
1199 |
+
|
1200 |
+
$strings = array();
|
1201 |
+
|
1202 |
+
$in_str = false;
|
1203 |
+
$current_string = "";
|
1204 |
+
|
1205 |
+
for ($i = 0, $_len = strlen($value); $i < $_len; $i++) {
|
1206 |
+
if (($value{$i} == "," || $value{$i} === " ") && $in_str === true) {
|
1207 |
+
$in_str = false;
|
1208 |
+
$strings[] = $current_string;
|
1209 |
+
$current_string = "";
|
1210 |
+
}
|
1211 |
+
else if ($value{$i} == '"' || $value{$i} == "'"){
|
1212 |
+
if ($in_str === $value{$i}) {
|
1213 |
+
$strings[] = $current_string;
|
1214 |
+
$in_str = false;
|
1215 |
+
$current_string = "";
|
1216 |
+
continue;
|
1217 |
+
}
|
1218 |
+
else if (!$in_str) {
|
1219 |
+
$in_str = $value{$i};
|
1220 |
+
}
|
1221 |
+
}
|
1222 |
+
else {
|
1223 |
+
if ($in_str){
|
1224 |
+
$current_string .= $value{$i};
|
1225 |
+
}
|
1226 |
+
else {
|
1227 |
+
if (!preg_match("/[\s,]/", $value{$i})) {
|
1228 |
+
$in_str = true;
|
1229 |
+
$current_string = $value{$i};
|
1230 |
+
}
|
1231 |
+
}
|
1232 |
+
}
|
1233 |
+
}
|
1234 |
+
|
1235 |
+
if ($current_string) {
|
1236 |
+
$strings[] = $current_string;
|
1237 |
+
}
|
1238 |
+
|
1239 |
+
return $strings;
|
1240 |
+
}
|
1241 |
+
}
|
classes/csstidy/class.csstidy_ctype.php
CHANGED
@@ -1,46 +1,46 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* CSSTidy - CSS Parser and Optimiser
|
5 |
-
*
|
6 |
-
* CSS ctype functions
|
7 |
-
* Defines some functions that can be not defined.
|
8 |
-
*
|
9 |
-
* This file is part of CSSTidy.
|
10 |
-
*
|
11 |
-
* CSSTidy is free software; you can redistribute it and/or modify
|
12 |
-
* it under the terms of the GNU General Public License as published by
|
13 |
-
* the Free Software Foundation; either version 2 of the License, or
|
14 |
-
* (at your option) any later version.
|
15 |
-
*
|
16 |
-
* CSSTidy is distributed in the hope that it will be useful,
|
17 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19 |
-
* GNU General Public License for more details.
|
20 |
-
*
|
21 |
-
* You should have received a copy of the GNU General Public License
|
22 |
-
* along with CSSTidy; if not, write to the Free Software
|
23 |
-
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
24 |
-
*
|
25 |
-
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
26 |
-
* @package csstidy
|
27 |
-
* @author Nikolay Matsievsky (speed at webo dot name) 2009-2010
|
28 |
-
* @version 1.0
|
29 |
-
*/
|
30 |
-
/* ctype_space Check for whitespace character(s) */
|
31 |
-
if (!function_exists('ctype_space')) {
|
32 |
-
|
33 |
-
function ctype_space($text) {
|
34 |
-
return!preg_match("/[^\s\r\n\t\f]/", $text);
|
35 |
-
}
|
36 |
-
|
37 |
-
}
|
38 |
-
/* ctype_alpha Check for alphabetic character(s) */
|
39 |
-
if (!function_exists('ctype_alpha')) {
|
40 |
-
|
41 |
-
function ctype_alpha($text) {
|
42 |
-
return preg_match("/[a-zA-Z]/", $text);
|
43 |
-
}
|
44 |
-
|
45 |
-
}
|
46 |
?>
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* CSSTidy - CSS Parser and Optimiser
|
5 |
+
*
|
6 |
+
* CSS ctype functions
|
7 |
+
* Defines some functions that can be not defined.
|
8 |
+
*
|
9 |
+
* This file is part of CSSTidy.
|
10 |
+
*
|
11 |
+
* CSSTidy is free software; you can redistribute it and/or modify
|
12 |
+
* it under the terms of the GNU General Public License as published by
|
13 |
+
* the Free Software Foundation; either version 2 of the License, or
|
14 |
+
* (at your option) any later version.
|
15 |
+
*
|
16 |
+
* CSSTidy is distributed in the hope that it will be useful,
|
17 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19 |
+
* GNU General Public License for more details.
|
20 |
+
*
|
21 |
+
* You should have received a copy of the GNU General Public License
|
22 |
+
* along with CSSTidy; if not, write to the Free Software
|
23 |
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
24 |
+
*
|
25 |
+
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
26 |
+
* @package csstidy
|
27 |
+
* @author Nikolay Matsievsky (speed at webo dot name) 2009-2010
|
28 |
+
* @version 1.0
|
29 |
+
*/
|
30 |
+
/* ctype_space Check for whitespace character(s) */
|
31 |
+
if (!function_exists('ctype_space')) {
|
32 |
+
|
33 |
+
function ctype_space($text) {
|
34 |
+
return!preg_match("/[^\s\r\n\t\f]/", $text);
|
35 |
+
}
|
36 |
+
|
37 |
+
}
|
38 |
+
/* ctype_alpha Check for alphabetic character(s) */
|
39 |
+
if (!function_exists('ctype_alpha')) {
|
40 |
+
|
41 |
+
function ctype_alpha($text) {
|
42 |
+
return preg_match("/[a-zA-Z]/", $text);
|
43 |
+
}
|
44 |
+
|
45 |
+
}
|
46 |
?>
|
classes/csstidy/class.csstidy_optimise.php
CHANGED
@@ -1,936 +1,936 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* CSSTidy - CSS Parser and Optimiser
|
5 |
-
*
|
6 |
-
* CSS Optimising Class
|
7 |
-
* This class optimises CSS data generated by csstidy.
|
8 |
-
*
|
9 |
-
* Copyright 2005, 2006, 2007 Florian Schmitz
|
10 |
-
*
|
11 |
-
* This file is part of CSSTidy.
|
12 |
-
*
|
13 |
-
* CSSTidy is free software; you can redistribute it and/or modify
|
14 |
-
* it under the terms of the GNU Lesser General Public License as published by
|
15 |
-
* the Free Software Foundation; either version 2.1 of the License, or
|
16 |
-
* (at your option) any later version.
|
17 |
-
*
|
18 |
-
* CSSTidy is distributed in the hope that it will be useful,
|
19 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
20 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
21 |
-
* GNU Lesser General Public License for more details.
|
22 |
-
*
|
23 |
-
* You should have received a copy of the GNU Lesser General Public License
|
24 |
-
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
25 |
-
*
|
26 |
-
* @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
|
27 |
-
* @package csstidy
|
28 |
-
* @author Florian Schmitz (floele at gmail dot com) 2005-2007
|
29 |
-
* @author Brett Zamir (brettz9 at yahoo dot com) 2007
|
30 |
-
* @author Nikolay Matsievsky (speed at webo dot name) 2009-2010
|
31 |
-
*/
|
32 |
-
|
33 |
-
/**
|
34 |
-
* CSS Optimising Class
|
35 |
-
*
|
36 |
-
* This class optimises CSS data generated by csstidy.
|
37 |
-
*
|
38 |
-
* @package csstidy
|
39 |
-
* @author Florian Schmitz (floele at gmail dot com) 2005-2006
|
40 |
-
* @version 1.0
|
41 |
-
*/
|
42 |
-
class csstidy_optimise {
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Constructor
|
46 |
-
* @param array $css contains the class csstidy
|
47 |
-
* @access private
|
48 |
-
* @version 1.0
|
49 |
-
*/
|
50 |
-
function csstidy_optimise(&$css) {
|
51 |
-
$this->parser = & $css;
|
52 |
-
$this->css = & $css->css;
|
53 |
-
$this->sub_value = & $css->sub_value;
|
54 |
-
$this->at = & $css->at;
|
55 |
-
$this->selector = & $css->selector;
|
56 |
-
$this->property = & $css->property;
|
57 |
-
$this->value = & $css->value;
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Optimises $css after parsing
|
62 |
-
* @access public
|
63 |
-
* @version 1.0
|
64 |
-
*/
|
65 |
-
function postparse() {
|
66 |
-
if ($this->parser->get_cfg('preserve_css')) {
|
67 |
-
return;
|
68 |
-
}
|
69 |
-
|
70 |
-
if ($this->parser->get_cfg('merge_selectors') === 2) {
|
71 |
-
foreach ($this->css as $medium => $value) {
|
72 |
-
$this->merge_selectors($this->css[$medium]);
|
73 |
-
}
|
74 |
-
}
|
75 |
-
|
76 |
-
if ($this->parser->get_cfg('discard_invalid_selectors')) {
|
77 |
-
foreach ($this->css as $medium => $value) {
|
78 |
-
$this->discard_invalid_selectors($this->css[$medium]);
|
79 |
-
}
|
80 |
-
}
|
81 |
-
|
82 |
-
if ($this->parser->get_cfg('optimise_shorthands') > 0) {
|
83 |
-
foreach ($this->css as $medium => $value) {
|
84 |
-
foreach ($value as $selector => $value1) {
|
85 |
-
$this->css[$medium][$selector] = csstidy_optimise::merge_4value_shorthands($this->css[$medium][$selector]);
|
86 |
-
|
87 |
-
if ($this->parser->get_cfg('optimise_shorthands') < 2) {
|
88 |
-
continue;
|
89 |
-
}
|
90 |
-
|
91 |
-
$this->css[$medium][$selector] = csstidy_optimise::merge_font($this->css[$medium][$selector]);
|
92 |
-
|
93 |
-
if ($this->parser->get_cfg('optimise_shorthands') < 3) {
|
94 |
-
continue;
|
95 |
-
}
|
96 |
-
|
97 |
-
$this->css[$medium][$selector] = csstidy_optimise::merge_bg($this->css[$medium][$selector]);
|
98 |
-
if (empty($this->css[$medium][$selector])) {
|
99 |
-
unset($this->css[$medium][$selector]);
|
100 |
-
}
|
101 |
-
}
|
102 |
-
}
|
103 |
-
}
|
104 |
-
}
|
105 |
-
|
106 |
-
/**
|
107 |
-
* Optimises values
|
108 |
-
* @access public
|
109 |
-
* @version 1.0
|
110 |
-
*/
|
111 |
-
function value() {
|
112 |
-
$shorthands = & $GLOBALS['csstidy']['shorthands'];
|
113 |
-
|
114 |
-
// optimise shorthand properties
|
115 |
-
if (isset($shorthands[$this->property])) {
|
116 |
-
$temp = csstidy_optimise::shorthand($this->value); // FIXME - move
|
117 |
-
if ($temp != $this->value) {
|
118 |
-
$this->parser->log('Optimised shorthand notation (' . $this->property . '): Changed "' . $this->value . '" to "' . $temp . '"', 'Information');
|
119 |
-
}
|
120 |
-
$this->value = $temp;
|
121 |
-
}
|
122 |
-
|
123 |
-
// Remove whitespace at ! important
|
124 |
-
if ($this->value != $this->compress_important($this->value)) {
|
125 |
-
$this->parser->log('Optimised !important', 'Information');
|
126 |
-
}
|
127 |
-
}
|
128 |
-
|
129 |
-
/**
|
130 |
-
* Optimises shorthands
|
131 |
-
* @access public
|
132 |
-
* @version 1.0
|
133 |
-
*/
|
134 |
-
function shorthands() {
|
135 |
-
$shorthands = & $GLOBALS['csstidy']['shorthands'];
|
136 |
-
|
137 |
-
if (!$this->parser->get_cfg('optimise_shorthands') || $this->parser->get_cfg('preserve_css')) {
|
138 |
-
return;
|
139 |
-
}
|
140 |
-
|
141 |
-
if ($this->property === 'font' && $this->parser->get_cfg('optimise_shorthands') > 1) {
|
142 |
-
$this->css[$this->at][$this->selector]['font']='';
|
143 |
-
$this->parser->merge_css_blocks($this->at, $this->selector, csstidy_optimise::dissolve_short_font($this->value));
|
144 |
-
}
|
145 |
-
if ($this->property === 'background' && $this->parser->get_cfg('optimise_shorthands') > 2) {
|
146 |
-
$this->css[$this->at][$this->selector]['background']='';
|
147 |
-
$this->parser->merge_css_blocks($this->at, $this->selector, csstidy_optimise::dissolve_short_bg($this->value));
|
148 |
-
}
|
149 |
-
if (isset($shorthands[$this->property])) {
|
150 |
-
$this->parser->merge_css_blocks($this->at, $this->selector, csstidy_optimise::dissolve_4value_shorthands($this->property, $this->value));
|
151 |
-
if (is_array($shorthands[$this->property])) {
|
152 |
-
$this->css[$this->at][$this->selector][$this->property] = '';
|
153 |
-
}
|
154 |
-
}
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* Optimises a sub-value
|
159 |
-
* @access public
|
160 |
-
* @version 1.0
|
161 |
-
*/
|
162 |
-
function subvalue() {
|
163 |
-
$replace_colors = & $GLOBALS['csstidy']['replace_colors'];
|
164 |
-
|
165 |
-
$this->sub_value = trim($this->sub_value);
|
166 |
-
if ($this->sub_value == '') { // caution : '0'
|
167 |
-
return;
|
168 |
-
}
|
169 |
-
|
170 |
-
$important = '';
|
171 |
-
if (csstidy::is_important($this->sub_value)) {
|
172 |
-
$important = '!important';
|
173 |
-
}
|
174 |
-
$this->sub_value = csstidy::gvw_important($this->sub_value);
|
175 |
-
|
176 |
-
// Compress font-weight
|
177 |
-
if ($this->property === 'font-weight' && $this->parser->get_cfg('compress_font-weight')) {
|
178 |
-
if ($this->sub_value === 'bold') {
|
179 |
-
$this->sub_value = '700';
|
180 |
-
$this->parser->log('Optimised font-weight: Changed "bold" to "700"', 'Information');
|
181 |
-
} else if ($this->sub_value === 'normal') {
|
182 |
-
$this->sub_value = '400';
|
183 |
-
$this->parser->log('Optimised font-weight: Changed "normal" to "400"', 'Information');
|
184 |
-
}
|
185 |
-
}
|
186 |
-
|
187 |
-
$temp = $this->compress_numbers($this->sub_value);
|
188 |
-
if (strcasecmp($temp, $this->sub_value) !== 0) {
|
189 |
-
if (strlen($temp) > strlen($this->sub_value)) {
|
190 |
-
$this->parser->log('Fixed invalid number: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Warning');
|
191 |
-
} else {
|
192 |
-
$this->parser->log('Optimised number: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Information');
|
193 |
-
}
|
194 |
-
$this->sub_value = $temp;
|
195 |
-
}
|
196 |
-
if ($this->parser->get_cfg('compress_colors')) {
|
197 |
-
$temp = $this->cut_color($this->sub_value);
|
198 |
-
if ($temp !== $this->sub_value) {
|
199 |
-
if (isset($replace_colors[$this->sub_value])) {
|
200 |
-
$this->parser->log('Fixed invalid color name: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Warning');
|
201 |
-
} else {
|
202 |
-
$this->parser->log('Optimised color: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Information');
|
203 |
-
}
|
204 |
-
$this->sub_value = $temp;
|
205 |
-
}
|
206 |
-
}
|
207 |
-
$this->sub_value .= $important;
|
208 |
-
}
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Compresses shorthand values. Example: margin:1px 1px 1px 1px -> margin:1px
|
212 |
-
* @param string $value
|
213 |
-
* @access public
|
214 |
-
* @return string
|
215 |
-
* @version 1.0
|
216 |
-
*/
|
217 |
-
function shorthand($value) {
|
218 |
-
$important = '';
|
219 |
-
if (csstidy::is_important($value)) {
|
220 |
-
$values = csstidy::gvw_important($value);
|
221 |
-
$important = '!important';
|
222 |
-
}
|
223 |
-
else
|
224 |
-
$values = $value;
|
225 |
-
|
226 |
-
$values = explode(' ', $values);
|
227 |
-
switch (count($values)) {
|
228 |
-
case 4:
|
229 |
-
if ($values[0] == $values[1] && $values[0] == $values[2] && $values[0] == $values[3]) {
|
230 |
-
return $values[0] . $important;
|
231 |
-
} elseif ($values[1] == $values[3] && $values[0] == $values[2]) {
|
232 |
-
return $values[0] . ' ' . $values[1] . $important;
|
233 |
-
} elseif ($values[1] == $values[3]) {
|
234 |
-
return $values[0] . ' ' . $values[1] . ' ' . $values[2] . $important;
|
235 |
-
}
|
236 |
-
break;
|
237 |
-
|
238 |
-
case 3:
|
239 |
-
if ($values[0] == $values[1] && $values[0] == $values[2]) {
|
240 |
-
return $values[0] . $important;
|
241 |
-
} elseif ($values[0] == $values[2]) {
|
242 |
-
return $values[0] . ' ' . $values[1] . $important;
|
243 |
-
}
|
244 |
-
break;
|
245 |
-
|
246 |
-
case 2:
|
247 |
-
if ($values[0] == $values[1]) {
|
248 |
-
return $values[0] . $important;
|
249 |
-
}
|
250 |
-
break;
|
251 |
-
}
|
252 |
-
|
253 |
-
return $value;
|
254 |
-
}
|
255 |
-
|
256 |
-
/**
|
257 |
-
* Removes unnecessary whitespace in ! important
|
258 |
-
* @param string $string
|
259 |
-
* @return string
|
260 |
-
* @access public
|
261 |
-
* @version 1.1
|
262 |
-
*/
|
263 |
-
function compress_important(&$string) {
|
264 |
-
if (csstidy::is_important($string)) {
|
265 |
-
$string = csstidy::gvw_important($string) . '!important';
|
266 |
-
}
|
267 |
-
return $string;
|
268 |
-
}
|
269 |
-
|
270 |
-
/**
|
271 |
-
* Color compression function. Converts all rgb() values to #-values and uses the short-form if possible. Also replaces 4 color names by #-values.
|
272 |
-
* @param string $color
|
273 |
-
* @return string
|
274 |
-
* @version 1.1
|
275 |
-
*/
|
276 |
-
function cut_color($color) {
|
277 |
-
$replace_colors = & $GLOBALS['csstidy']['replace_colors'];
|
278 |
-
|
279 |
-
// rgb(0,0,0) -> #000000 (or #000 in this case later)
|
280 |
-
if (strtolower(substr($color, 0, 4)) === 'rgb(') {
|
281 |
-
$color_tmp = substr($color, 4, strlen($color) - 5);
|
282 |
-
$color_tmp = explode(',', $color_tmp);
|
283 |
-
for ($i = 0; $i < count($color_tmp); $i++) {
|
284 |
-
$color_tmp[$i] = trim($color_tmp[$i]);
|
285 |
-
if (substr($color_tmp[$i], -1) === '%') {
|
286 |
-
$color_tmp[$i] = round((255 * $color_tmp[$i]) / 100);
|
287 |
-
}
|
288 |
-
if ($color_tmp[$i] > 255)
|
289 |
-
$color_tmp[$i] = 255;
|
290 |
-
}
|
291 |
-
$color = '#';
|
292 |
-
for ($i = 0; $i < 3; $i++) {
|
293 |
-
if ($color_tmp[$i] < 16) {
|
294 |
-
$color .= '0' . dechex($color_tmp[$i]);
|
295 |
-
} else {
|
296 |
-
$color .= dechex($color_tmp[$i]);
|
297 |
-
}
|
298 |
-
}
|
299 |
-
}
|
300 |
-
|
301 |
-
// Fix bad color names
|
302 |
-
if (isset($replace_colors[strtolower($color)])) {
|
303 |
-
$color = $replace_colors[strtolower($color)];
|
304 |
-
}
|
305 |
-
|
306 |
-
// #aabbcc -> #abc
|
307 |
-
if (strlen($color) == 7) {
|
308 |
-
$color_temp = strtolower($color);
|
309 |
-
if ($color_temp{0} === '#' && $color_temp{1} == $color_temp{2} && $color_temp{3} == $color_temp{4} && $color_temp{5} == $color_temp{6}) {
|
310 |
-
$color = '#' . $color{1} . $color{3} . $color{5};
|
311 |
-
}
|
312 |
-
}
|
313 |
-
|
314 |
-
switch (strtolower($color)) {
|
315 |
-
/* color name -> hex code */
|
316 |
-
case 'black': return '#000';
|
317 |
-
case 'fuchsia': return '#f0f';
|
318 |
-
case 'white': return '#fff';
|
319 |
-
case 'yellow': return '#ff0';
|
320 |
-
|
321 |
-
/* hex code -> color name */
|
322 |
-
case '#800000': return 'maroon';
|
323 |
-
case '#ffa500': return 'orange';
|
324 |
-
case '#808000': return 'olive';
|
325 |
-
case '#800080': return 'purple';
|
326 |
-
case '#008000': return 'green';
|
327 |
-
case '#000080': return 'navy';
|
328 |
-
case '#008080': return 'teal';
|
329 |
-
case '#c0c0c0': return 'silver';
|
330 |
-
case '#808080': return 'gray';
|
331 |
-
case '#f00': return 'red';
|
332 |
-
}
|
333 |
-
|
334 |
-
return $color;
|
335 |
-
}
|
336 |
-
|
337 |
-
/**
|
338 |
-
* Compresses numbers (ie. 1.0 becomes 1 or 1.100 becomes 1.1 )
|
339 |
-
* @param string $subvalue
|
340 |
-
* @return string
|
341 |
-
* @version 1.2
|
342 |
-
*/
|
343 |
-
function compress_numbers($subvalue) {
|
344 |
-
$unit_values = & $GLOBALS['csstidy']['unit_values'];
|
345 |
-
$color_values = & $GLOBALS['csstidy']['color_values'];
|
346 |
-
|
347 |
-
// for font:1em/1em sans-serif...;
|
348 |
-
if ($this->property === 'font') {
|
349 |
-
$temp = explode('/', $subvalue);
|
350 |
-
} else {
|
351 |
-
$temp = array($subvalue);
|
352 |
-
}
|
353 |
-
for ($l = 0; $l < count($temp); $l++) {
|
354 |
-
// if we are not dealing with a number at this point, do not optimise anything
|
355 |
-
$number = $this->AnalyseCssNumber($temp[$l]);
|
356 |
-
if ($number === false) {
|
357 |
-
return $subvalue;
|
358 |
-
}
|
359 |
-
|
360 |
-
// Fix bad colors
|
361 |
-
if (in_array($this->property, $color_values)) {
|
362 |
-
if (strlen($temp[$l]) == 3 || strlen($temp[$l]) == 6) {
|
363 |
-
$temp[$l] = '#' . $temp[$l];
|
364 |
-
}
|
365 |
-
else {
|
366 |
-
$temp[$l] = "0";
|
367 |
-
}
|
368 |
-
continue;
|
369 |
-
}
|
370 |
-
|
371 |
-
if (abs($number[0]) > 0) {
|
372 |
-
if ($number[1] == '' && in_array($this->property, $unit_values, true)) {
|
373 |
-
$number[1] = 'px';
|
374 |
-
}
|
375 |
-
} else {
|
376 |
-
$number[1] = '';
|
377 |
-
}
|
378 |
-
|
379 |
-
$temp[$l] = $number[0] . $number[1];
|
380 |
-
}
|
381 |
-
|
382 |
-
return ((count($temp) > 1) ? $temp[0] . '/' . $temp[1] : $temp[0]);
|
383 |
-
}
|
384 |
-
|
385 |
-
/**
|
386 |
-
* Checks if a given string is a CSS valid number. If it is,
|
387 |
-
* an array containing the value and unit is returned
|
388 |
-
* @param string $string
|
389 |
-
* @return array ('unit' if unit is found or '' if no unit exists, number value) or false if no number
|
390 |
-
*/
|
391 |
-
function AnalyseCssNumber($string) {
|
392 |
-
// most simple checks first
|
393 |
-
if (strlen($string) == 0 || ctype_alpha($string{0})) {
|
394 |
-
return false;
|
395 |
-
}
|
396 |
-
|
397 |
-
$units = & $GLOBALS['csstidy']['units'];
|
398 |
-
$return = array(0, '');
|
399 |
-
|
400 |
-
$return[0] = floatval($string);
|
401 |
-
if (abs($return[0]) > 0 && abs($return[0]) < 1) {
|
402 |
-
if ($return[0] < 0) {
|
403 |
-
$return[0] = '-' . ltrim(substr($return[0], 1), '0');
|
404 |
-
} else {
|
405 |
-
$return[0] = ltrim($return[0], '0');
|
406 |
-
}
|
407 |
-
}
|
408 |
-
|
409 |
-
// Look for unit and split from value if exists
|
410 |
-
foreach ($units as $unit) {
|
411 |
-
$expectUnitAt = strlen($string) - strlen($unit);
|
412 |
-
if (!($unitInString = stristr($string, $unit))) { // mb_strpos() fails with "false"
|
413 |
-
continue;
|
414 |
-
}
|
415 |
-
$actualPosition = strpos($string, $unitInString);
|
416 |
-
if ($expectUnitAt === $actualPosition) {
|
417 |
-
$return[1] = $unit;
|
418 |
-
$string = substr($string, 0, - strlen($unit));
|
419 |
-
break;
|
420 |
-
}
|
421 |
-
}
|
422 |
-
if (!is_numeric($string)) {
|
423 |
-
return false;
|
424 |
-
}
|
425 |
-
return $return;
|
426 |
-
}
|
427 |
-
|
428 |
-
/**
|
429 |
-
* Merges selectors with same properties. Example: a{color:red} b{color:red} -> a,b{color:red}
|
430 |
-
* Very basic and has at least one bug. Hopefully there is a replacement soon.
|
431 |
-
* @param array $array
|
432 |
-
* @return array
|
433 |
-
* @access public
|
434 |
-
* @version 1.2
|
435 |
-
*/
|
436 |
-
function merge_selectors(&$array) {
|
437 |
-
$css = $array;
|
438 |
-
foreach ($css as $key => $value) {
|
439 |
-
if (!isset($css[$key])) {
|
440 |
-
continue;
|
441 |
-
}
|
442 |
-
$newsel = '';
|
443 |
-
|
444 |
-
// Check if properties also exist in another selector
|
445 |
-
$keys = array();
|
446 |
-
// PHP bug (?) without $css = $array; here
|
447 |
-
foreach ($css as $selector => $vali) {
|
448 |
-
if ($selector == $key) {
|
449 |
-
continue;
|
450 |
-
}
|
451 |
-
|
452 |
-
if ($css[$key] === $vali) {
|
453 |
-
$keys[] = $selector;
|
454 |
-
}
|
455 |
-
}
|
456 |
-
|
457 |
-
if (!empty($keys)) {
|
458 |
-
$newsel = $key;
|
459 |
-
unset($css[$key]);
|
460 |
-
foreach ($keys as $selector) {
|
461 |
-
unset($css[$selector]);
|
462 |
-
$newsel .= ',' . $selector;
|
463 |
-
}
|
464 |
-
$css[$newsel] = $value;
|
465 |
-
}
|
466 |
-
}
|
467 |
-
$array = $css;
|
468 |
-
}
|
469 |
-
|
470 |
-
/**
|
471 |
-
* Removes invalid selectors and their corresponding rule-sets as
|
472 |
-
* defined by 4.1.7 in REC-CSS2. This is a very rudimentary check
|
473 |
-
* and should be replaced by a full-blown parsing algorithm or
|
474 |
-
* regular expression
|
475 |
-
* @version 1.4
|
476 |
-
*/
|
477 |
-
function discard_invalid_selectors(&$array) {
|
478 |
-
$invalid = array('+' => true, '~' => true, ',' => true, '>' => true);
|
479 |
-
foreach ($array as $selector => $decls) {
|
480 |
-
$ok = true;
|
481 |
-
$selectors = array_map('trim', explode(',', $selector));
|
482 |
-
foreach ($selectors as $s) {
|
483 |
-
$simple_selectors = preg_split('/\s*[+>~\s]\s*/', $s);
|
484 |
-
foreach ($simple_selectors as $ss) {
|
485 |
-
if ($ss === '')
|
486 |
-
$ok = false;
|
487 |
-
// could also check $ss for internal structure,
|
488 |
-
// but that probably would be too slow
|
489 |
-
}
|
490 |
-
}
|
491 |
-
if (!$ok)
|
492 |
-
unset($array[$selector]);
|
493 |
-
}
|
494 |
-
}
|
495 |
-
|
496 |
-
/**
|
497 |
-
* Dissolves properties like padding:10px 10px 10px to padding-top:10px;padding-bottom:10px;...
|
498 |
-
* @param string $property
|
499 |
-
* @param string $value
|
500 |
-
* @return array
|
501 |
-
* @version 1.0
|
502 |
-
* @see merge_4value_shorthands()
|
503 |
-
*/
|
504 |
-
function dissolve_4value_shorthands($property, $value) {
|
505 |
-
$shorthands = & $GLOBALS['csstidy']['shorthands'];
|
506 |
-
if (!is_array($shorthands[$property])) {
|
507 |
-
$return[$property] = $value;
|
508 |
-
return $return;
|
509 |
-
}
|
510 |
-
|
511 |
-
$important = '';
|
512 |
-
if (csstidy::is_important($value)) {
|
513 |
-
$value = csstidy::gvw_important($value);
|
514 |
-
$important = '!important';
|
515 |
-
}
|
516 |
-
$values = explode(' ', $value);
|
517 |
-
|
518 |
-
|
519 |
-
$return = array();
|
520 |
-
if (count($values) == 4) {
|
521 |
-
for ($i = 0; $i < 4; $i++) {
|
522 |
-
$return[$shorthands[$property][$i]] = $values[$i] . $important;
|
523 |
-
}
|
524 |
-
} elseif (count($values) == 3) {
|
525 |
-
$return[$shorthands[$property][0]] = $values[0] . $important;
|
526 |
-
$return[$shorthands[$property][1]] = $values[1] . $important;
|
527 |
-
$return[$shorthands[$property][3]] = $values[1] . $important;
|
528 |
-
$return[$shorthands[$property][2]] = $values[2] . $important;
|
529 |
-
} elseif (count($values) == 2) {
|
530 |
-
for ($i = 0; $i < 4; $i++) {
|
531 |
-
$return[$shorthands[$property][$i]] = (($i % 2 != 0)) ? $values[1] . $important : $values[0] . $important;
|
532 |
-
}
|
533 |
-
} else {
|
534 |
-
for ($i = 0; $i < 4; $i++) {
|
535 |
-
$return[$shorthands[$property][$i]] = $values[0] . $important;
|
536 |
-
}
|
537 |
-
}
|
538 |
-
|
539 |
-
return $return;
|
540 |
-
}
|
541 |
-
|
542 |
-
/**
|
543 |
-
* Explodes a string as explode() does, however, not if $sep is escaped or within a string.
|
544 |
-
* @param string $sep seperator
|
545 |
-
* @param string $string
|
546 |
-
* @return array
|
547 |
-
* @version 1.0
|
548 |
-
*/
|
549 |
-
function explode_ws($sep, $string) {
|
550 |
-
$status = 'st';
|
551 |
-
$to = '';
|
552 |
-
|
553 |
-
$output = array();
|
554 |
-
$num = 0;
|
555 |
-
for ($i = 0, $len = strlen($string); $i < $len; $i++) {
|
556 |
-
switch ($status) {
|
557 |
-
case 'st':
|
558 |
-
if ($string{$i} == $sep && !csstidy::escaped($string, $i)) {
|
559 |
-
++$num;
|
560 |
-
} elseif ($string{$i} === '"' || $string{$i} === '\'' || $string{$i} === '(' && !csstidy::escaped($string, $i)) {
|
561 |
-
$status = 'str';
|
562 |
-
$to = ($string{$i} === '(') ? ')' : $string{$i};
|
563 |
-
(isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
|
564 |
-
} else {
|
565 |
-
(isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
|
566 |
-
}
|
567 |
-
break;
|
568 |
-
|
569 |
-
case 'str':
|
570 |
-
if ($string{$i} == $to && !csstidy::escaped($string, $i)) {
|
571 |
-
$status = 'st';
|
572 |
-
}
|
573 |
-
(isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
|
574 |
-
break;
|
575 |
-
}
|
576 |
-
}
|
577 |
-
|
578 |
-
if (isset($output[0])) {
|
579 |
-
return $output;
|
580 |
-
} else {
|
581 |
-
return array($output);
|
582 |
-
}
|
583 |
-
}
|
584 |
-
|
585 |
-
/**
|
586 |
-
* Merges Shorthand properties again, the opposite of dissolve_4value_shorthands()
|
587 |
-
* @param array $array
|
588 |
-
* @return array
|
589 |
-
* @version 1.2
|
590 |
-
* @see dissolve_4value_shorthands()
|
591 |
-
*/
|
592 |
-
function merge_4value_shorthands($array) {
|
593 |
-
$return = $array;
|
594 |
-
$shorthands = & $GLOBALS['csstidy']['shorthands'];
|
595 |
-
|
596 |
-
foreach ($shorthands as $key => $value) {
|
597 |
-
if (isset($array[$value[0]]) && isset($array[$value[1]])
|
598 |
-
&& isset($array[$value[2]]) && isset($array[$value[3]]) && $value !== 0) {
|
599 |
-
$return[$key] = '';
|
600 |
-
|
601 |
-
$important = '';
|
602 |
-
for ($i = 0; $i < 4; $i++) {
|
603 |
-
$val = $array[$value[$i]];
|
604 |
-
if (csstidy::is_important($val)) {
|
605 |
-
$important = '!important';
|
606 |
-
$return[$key] .= csstidy::gvw_important($val) . ' ';
|
607 |
-
} else {
|
608 |
-
$return[$key] .= $val . ' ';
|
609 |
-
}
|
610 |
-
unset($return[$value[$i]]);
|
611 |
-
}
|
612 |
-
$return[$key] = csstidy_optimise::shorthand(trim($return[$key] . $important));
|
613 |
-
}
|
614 |
-
}
|
615 |
-
return $return;
|
616 |
-
}
|
617 |
-
|
618 |
-
/**
|
619 |
-
* Dissolve background property
|
620 |
-
* @param string $str_value
|
621 |
-
* @return array
|
622 |
-
* @version 1.0
|
623 |
-
* @see merge_bg()
|
624 |
-
* @todo full CSS 3 compliance
|
625 |
-
*/
|
626 |
-
function dissolve_short_bg($str_value) {
|
627 |
-
// don't try to explose background gradient !
|
628 |
-
if (stripos($str_value, "gradient(")!==FALSE)
|
629 |
-
return array('background'=>$str_value);
|
630 |
-
|
631 |
-
$background_prop_default = & $GLOBALS['csstidy']['background_prop_default'];
|
632 |
-
$repeat = array('repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space');
|
633 |
-
$attachment = array('scroll', 'fixed', 'local');
|
634 |
-
$clip = array('border', 'padding');
|
635 |
-
$origin = array('border', 'padding', 'content');
|
636 |
-
$pos = array('top', 'center', 'bottom', 'left', 'right');
|
637 |
-
$important = '';
|
638 |
-
$return = array('background-image' => null, 'background-size' => null, 'background-repeat' => null, 'background-position' => null, 'background-attachment' => null, 'background-clip' => null, 'background-origin' => null, 'background-color' => null);
|
639 |
-
|
640 |
-
if (csstidy::is_important($str_value)) {
|
641 |
-
$important = ' !important';
|
642 |
-
$str_value = csstidy::gvw_important($str_value);
|
643 |
-
}
|
644 |
-
|
645 |
-
$str_value = csstidy_optimise::explode_ws(',', $str_value);
|
646 |
-
for ($i = 0; $i < count($str_value); $i++) {
|
647 |
-
$have['clip'] = false;
|
648 |
-
$have['pos'] = false;
|
649 |
-
$have['color'] = false;
|
650 |
-
$have['bg'] = false;
|
651 |
-
|
652 |
-
if (is_array($str_value[$i])) {
|
653 |
-
$str_value[$i] = $str_value[$i][0];
|
654 |
-
}
|
655 |
-
$str_value[$i] = csstidy_optimise::explode_ws(' ', trim($str_value[$i]));
|
656 |
-
|
657 |
-
for ($j = 0; $j < count($str_value[$i]); $j++) {
|
658 |
-
if ($have['bg'] === false && (substr($str_value[$i][$j], 0, 4) === 'url(' || $str_value[$i][$j] === 'none')) {
|
659 |
-
$return['background-image'] .= $str_value[$i][$j] . ',';
|
660 |
-
$have['bg'] = true;
|
661 |
-
} elseif (in_array($str_value[$i][$j], $repeat, true)) {
|
662 |
-
$return['background-repeat'] .= $str_value[$i][$j] . ',';
|
663 |
-
} elseif (in_array($str_value[$i][$j], $attachment, true)) {
|
664 |
-
$return['background-attachment'] .= $str_value[$i][$j] . ',';
|
665 |
-
} elseif (in_array($str_value[$i][$j], $clip, true) && !$have['clip']) {
|
666 |
-
$return['background-clip'] .= $str_value[$i][$j] . ',';
|
667 |
-
$have['clip'] = true;
|
668 |
-
} elseif (in_array($str_value[$i][$j], $origin, true)) {
|
669 |
-
$return['background-origin'] .= $str_value[$i][$j] . ',';
|
670 |
-
} elseif ($str_value[$i][$j]{0} === '(') {
|
671 |
-
$return['background-size'] .= substr($str_value[$i][$j], 1, -1) . ',';
|
672 |
-
} elseif (in_array($str_value[$i][$j], $pos, true) || is_numeric($str_value[$i][$j]{0}) || $str_value[$i][$j]{0} === null || $str_value[$i][$j]{0} === '-' || $str_value[$i][$j]{0} === '.') {
|
673 |
-
$return['background-position'] .= $str_value[$i][$j];
|
674 |
-
if (!$have['pos'])
|
675 |
-
$return['background-position'] .= ' '; else
|
676 |
-
$return['background-position'].= ',';
|
677 |
-
$have['pos'] = true;
|
678 |
-
}
|
679 |
-
elseif (!$have['color']) {
|
680 |
-
$return['background-color'] .= $str_value[$i][$j] . ',';
|
681 |
-
$have['color'] = true;
|
682 |
-
}
|
683 |
-
}
|
684 |
-
}
|
685 |
-
|
686 |
-
foreach ($background_prop_default as $bg_prop => $default_value) {
|
687 |
-
if ($return[$bg_prop] !== null) {
|
688 |
-
$return[$bg_prop] = substr($return[$bg_prop], 0, -1) . $important;
|
689 |
-
}
|
690 |
-
else
|
691 |
-
$return[$bg_prop] = $default_value . $important;
|
692 |
-
}
|
693 |
-
return $return;
|
694 |
-
}
|
695 |
-
|
696 |
-
/**
|
697 |
-
* Merges all background properties
|
698 |
-
* @param array $input_css
|
699 |
-
* @return array
|
700 |
-
* @version 1.0
|
701 |
-
* @see dissolve_short_bg()
|
702 |
-
* @todo full CSS 3 compliance
|
703 |
-
*/
|
704 |
-
function merge_bg($input_css) {
|
705 |
-
$background_prop_default = & $GLOBALS['csstidy']['background_prop_default'];
|
706 |
-
// Max number of background images. CSS3 not yet fully implemented
|
707 |
-
$number_of_values = @max(count(csstidy_optimise::explode_ws(',', $input_css['background-image'])), count(csstidy_optimise::explode_ws(',', $input_css['background-color'])), 1);
|
708 |
-
// Array with background images to check if BG image exists
|
709 |
-
$bg_img_array = @csstidy_optimise::explode_ws(',', csstidy::gvw_important($input_css['background-image']));
|
710 |
-
$new_bg_value = '';
|
711 |
-
$important = '';
|
712 |
-
|
713 |
-
// if background properties is here and not empty, don't try anything
|
714 |
-
if (isset($input_css['background']) AND $input_css['background'])
|
715 |
-
return $input_css;
|
716 |
-
|
717 |
-
for ($i = 0; $i < $number_of_values; $i++) {
|
718 |
-
foreach ($background_prop_default as $bg_property => $default_value) {
|
719 |
-
// Skip if property does not exist
|
720 |
-
if (!isset($input_css[$bg_property])) {
|
721 |
-
continue;
|
722 |
-
}
|
723 |
-
|
724 |
-
$cur_value = $input_css[$bg_property];
|
725 |
-
// skip all optimisation if gradient() somewhere
|
726 |
-
if (stripos($cur_value, "gradient(")!==FALSE)
|
727 |
-
return $input_css;
|
728 |
-
|
729 |
-
// Skip some properties if there is no background image
|
730 |
-
if ((!isset($bg_img_array[$i]) || $bg_img_array[$i] === 'none')
|
731 |
-
&& ($bg_property === 'background-size' || $bg_property === 'background-position'
|
732 |
-
|| $bg_property === 'background-attachment' || $bg_property === 'background-repeat')) {
|
733 |
-
continue;
|
734 |
-
}
|
735 |
-
|
736 |
-
// Remove !important
|
737 |
-
if (csstidy::is_important($cur_value)) {
|
738 |
-
$important = ' !important';
|
739 |
-
$cur_value = csstidy::gvw_important($cur_value);
|
740 |
-
}
|
741 |
-
|
742 |
-
// Do not add default values
|
743 |
-
if ($cur_value === $default_value) {
|
744 |
-
continue;
|
745 |
-
}
|
746 |
-
|
747 |
-
$temp = csstidy_optimise::explode_ws(',', $cur_value);
|
748 |
-
|
749 |
-
if (isset($temp[$i])) {
|
750 |
-
if ($bg_property === 'background-size') {
|
751 |
-
$new_bg_value .= '(' . $temp[$i] . ') ';
|
752 |
-
} else {
|
753 |
-
$new_bg_value .= $temp[$i] . ' ';
|
754 |
-
}
|
755 |
-
}
|
756 |
-
}
|
757 |
-
|
758 |
-
$new_bg_value = trim($new_bg_value);
|
759 |
-
if ($i != $number_of_values - 1)
|
760 |
-
$new_bg_value .= ',';
|
761 |
-
}
|
762 |
-
|
763 |
-
// Delete all background-properties
|
764 |
-
foreach ($background_prop_default as $bg_property => $default_value) {
|
765 |
-
unset($input_css[$bg_property]);
|
766 |
-
}
|
767 |
-
|
768 |
-
// Add new background property
|
769 |
-
if ($new_bg_value !== '')
|
770 |
-
$input_css['background'] = $new_bg_value . $important;
|
771 |
-
elseif(isset ($input_css['background']))
|
772 |
-
$input_css['background'] = 'none';
|
773 |
-
|
774 |
-
return $input_css;
|
775 |
-
}
|
776 |
-
|
777 |
-
/**
|
778 |
-
* Dissolve font property
|
779 |
-
* @param string $str_value
|
780 |
-
* @return array
|
781 |
-
* @version 1.3
|
782 |
-
* @see merge_font()
|
783 |
-
*/
|
784 |
-
function dissolve_short_font($str_value) {
|
785 |
-
$font_prop_default = & $GLOBALS['csstidy']['font_prop_default'];
|
786 |
-
$font_weight = array('normal', 'bold', 'bolder', 'lighter', 100, 200, 300, 400, 500, 600, 700, 800, 900);
|
787 |
-
$font_variant = array('normal', 'small-caps');
|
788 |
-
$font_style = array('normal', 'italic', 'oblique');
|
789 |
-
$important = '';
|
790 |
-
$return = array('font-style' => null, 'font-variant' => null, 'font-weight' => null, 'font-size' => null, 'line-height' => null, 'font-family' => null);
|
791 |
-
|
792 |
-
if (csstidy::is_important($str_value)) {
|
793 |
-
$important = '!important';
|
794 |
-
$str_value = csstidy::gvw_important($str_value);
|
795 |
-
}
|
796 |
-
|
797 |
-
$have['style'] = false;
|
798 |
-
$have['variant'] = false;
|
799 |
-
$have['weight'] = false;
|
800 |
-
$have['size'] = false;
|
801 |
-
// Detects if font-family consists of several words w/o quotes
|
802 |
-
$multiwords = false;
|
803 |
-
|
804 |
-
// Workaround with multiple font-family
|
805 |
-
$str_value = csstidy_optimise::explode_ws(',', trim($str_value));
|
806 |
-
|
807 |
-
$str_value[0] = csstidy_optimise::explode_ws(' ', trim($str_value[0]));
|
808 |
-
|
809 |
-
for ($j = 0; $j < count($str_value[0]); $j++) {
|
810 |
-
if ($have['weight'] === false && in_array($str_value[0][$j], $font_weight)) {
|
811 |
-
$return['font-weight'] = $str_value[0][$j];
|
812 |
-
$have['weight'] = true;
|
813 |
-
} elseif ($have['variant'] === false && in_array($str_value[0][$j], $font_variant)) {
|
814 |
-
$return['font-variant'] = $str_value[0][$j];
|
815 |
-
$have['variant'] = true;
|
816 |
-
} elseif ($have['style'] === false && in_array($str_value[0][$j], $font_style)) {
|
817 |
-
$return['font-style'] = $str_value[0][$j];
|
818 |
-
$have['style'] = true;
|
819 |
-
} elseif ($have['size'] === false && (is_numeric($str_value[0][$j]{0}) || $str_value[0][$j]{0} === null || $str_value[0][$j]{0} === '.')) {
|
820 |
-
$size = csstidy_optimise::explode_ws('/', trim($str_value[0][$j]));
|
821 |
-
$return['font-size'] = $size[0];
|
822 |
-
if (isset($size[1])) {
|
823 |
-
$return['line-height'] = $size[1];
|
824 |
-
} else {
|
825 |
-
$return['line-height'] = ''; // don't add 'normal' !
|
826 |
-
}
|
827 |
-
$have['size'] = true;
|
828 |
-
} else {
|
829 |
-
if (isset($return['font-family'])) {
|
830 |
-
$return['font-family'] .= ' ' . $str_value[0][$j];
|
831 |
-
$multiwords = true;
|
832 |
-
} else {
|
833 |
-
$return['font-family'] = $str_value[0][$j];
|
834 |
-
}
|
835 |
-
}
|
836 |
-
}
|
837 |
-
// add quotes if we have several qords in font-family
|
838 |
-
if ($multiwords !== false) {
|
839 |
-
$return['font-family'] = '"' . $return['font-family'] . '"';
|
840 |
-
}
|
841 |
-
$i = 1;
|
842 |
-
while (isset($str_value[$i])) {
|
843 |
-
$return['font-family'] .= ',' . trim($str_value[$i]);
|
844 |
-
$i++;
|
845 |
-
}
|
846 |
-
|
847 |
-
// Fix for 100 and more font-size
|
848 |
-
if ($have['size'] === false && isset($return['font-weight']) &&
|
849 |
-
is_numeric($return['font-weight']{0})) {
|
850 |
-
$return['font-size'] = $return['font-weight'];
|
851 |
-
unset($return['font-weight']);
|
852 |
-
}
|
853 |
-
|
854 |
-
foreach ($font_prop_default as $font_prop => $default_value) {
|
855 |
-
if ($return[$font_prop] !== null) {
|
856 |
-
$return[$font_prop] = $return[$font_prop] . $important;
|
857 |
-
}
|
858 |
-
else
|
859 |
-
$return[$font_prop] = $default_value . $important;
|
860 |
-
}
|
861 |
-
return $return;
|
862 |
-
}
|
863 |
-
|
864 |
-
/**
|
865 |
-
* Merges all fonts properties
|
866 |
-
* @param array $input_css
|
867 |
-
* @return array
|
868 |
-
* @version 1.3
|
869 |
-
* @see dissolve_short_font()
|
870 |
-
*/
|
871 |
-
function merge_font($input_css) {
|
872 |
-
$font_prop_default = & $GLOBALS['csstidy']['font_prop_default'];
|
873 |
-
$new_font_value = '';
|
874 |
-
$important = '';
|
875 |
-
// Skip if not font-family and font-size set
|
876 |
-
if (isset($input_css['font-family']) && isset($input_css['font-size'])) {
|
877 |
-
// fix several words in font-family - add quotes
|
878 |
-
if (isset($input_css['font-family'])) {
|
879 |
-
$families = explode(",", $input_css['font-family']);
|
880 |
-
$result_families = array();
|
881 |
-
foreach ($families as $family) {
|
882 |
-
$family = trim($family);
|
883 |
-
$len = strlen($family);
|
884 |
-
if (strpos($family, " ") &&
|
885 |
-
!(($family{0} == '"' && $family{$len - 1} == '"') ||
|
886 |
-
($family{0} == "'" && $family{$len - 1} == "'"))) {
|
887 |
-
$family = '"' . $family . '"';
|
888 |
-
}
|
889 |
-
$result_families[] = $family;
|
890 |
-
}
|
891 |
-
$input_css['font-family'] = implode(",", $result_families);
|
892 |
-
}
|
893 |
-
foreach ($font_prop_default as $font_property => $default_value) {
|
894 |
-
|
895 |
-
// Skip if property does not exist
|
896 |
-
if (!isset($input_css[$font_property])) {
|
897 |
-
continue;
|
898 |
-
}
|
899 |
-
|
900 |
-
$cur_value = $input_css[$font_property];
|
901 |
-
|
902 |
-
// Skip if default value is used
|
903 |
-
if ($cur_value === $default_value) {
|
904 |
-
continue;
|
905 |
-
}
|
906 |
-
|
907 |
-
// Remove !important
|
908 |
-
if (csstidy::is_important($cur_value)) {
|
909 |
-
$important = '!important';
|
910 |
-
$cur_value = csstidy::gvw_important($cur_value);
|
911 |
-
}
|
912 |
-
|
913 |
-
$new_font_value .= $cur_value;
|
914 |
-
// Add delimiter
|
915 |
-
$new_font_value .= ( $font_property === 'font-size' &&
|
916 |
-
isset($input_css['line-height'])) ? '/' : ' ';
|
917 |
-
}
|
918 |
-
|
919 |
-
$new_font_value = trim($new_font_value);
|
920 |
-
|
921 |
-
// Delete all font-properties
|
922 |
-
foreach ($font_prop_default as $font_property => $default_value) {
|
923 |
-
if ($font_property!=='font' OR !$new_font_value)
|
924 |
-
unset($input_css[$font_property]);
|
925 |
-
}
|
926 |
-
|
927 |
-
// Add new font property
|
928 |
-
if ($new_font_value !== '') {
|
929 |
-
$input_css['font'] = $new_font_value . $important;
|
930 |
-
}
|
931 |
-
}
|
932 |
-
|
933 |
-
return $input_css;
|
934 |
-
}
|
935 |
-
|
936 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* CSSTidy - CSS Parser and Optimiser
|
5 |
+
*
|
6 |
+
* CSS Optimising Class
|
7 |
+
* This class optimises CSS data generated by csstidy.
|
8 |
+
*
|
9 |
+
* Copyright 2005, 2006, 2007 Florian Schmitz
|
10 |
+
*
|
11 |
+
* This file is part of CSSTidy.
|
12 |
+
*
|
13 |
+
* CSSTidy is free software; you can redistribute it and/or modify
|
14 |
+
* it under the terms of the GNU Lesser General Public License as published by
|
15 |
+
* the Free Software Foundation; either version 2.1 of the License, or
|
16 |
+
* (at your option) any later version.
|
17 |
+
*
|
18 |
+
* CSSTidy is distributed in the hope that it will be useful,
|
19 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
20 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
21 |
+
* GNU Lesser General Public License for more details.
|
22 |
+
*
|
23 |
+
* You should have received a copy of the GNU Lesser General Public License
|
24 |
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
25 |
+
*
|
26 |
+
* @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
|
27 |
+
* @package csstidy
|
28 |
+
* @author Florian Schmitz (floele at gmail dot com) 2005-2007
|
29 |
+
* @author Brett Zamir (brettz9 at yahoo dot com) 2007
|
30 |
+
* @author Nikolay Matsievsky (speed at webo dot name) 2009-2010
|
31 |
+
*/
|
32 |
+
|
33 |
+
/**
|
34 |
+
* CSS Optimising Class
|
35 |
+
*
|
36 |
+
* This class optimises CSS data generated by csstidy.
|
37 |
+
*
|
38 |
+
* @package csstidy
|
39 |
+
* @author Florian Schmitz (floele at gmail dot com) 2005-2006
|
40 |
+
* @version 1.0
|
41 |
+
*/
|
42 |
+
class csstidy_optimise {
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Constructor
|
46 |
+
* @param array $css contains the class csstidy
|
47 |
+
* @access private
|
48 |
+
* @version 1.0
|
49 |
+
*/
|
50 |
+
function csstidy_optimise(&$css) {
|
51 |
+
$this->parser = & $css;
|
52 |
+
$this->css = & $css->css;
|
53 |
+
$this->sub_value = & $css->sub_value;
|
54 |
+
$this->at = & $css->at;
|
55 |
+
$this->selector = & $css->selector;
|
56 |
+
$this->property = & $css->property;
|
57 |
+
$this->value = & $css->value;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Optimises $css after parsing
|
62 |
+
* @access public
|
63 |
+
* @version 1.0
|
64 |
+
*/
|
65 |
+
function postparse() {
|
66 |
+
if ($this->parser->get_cfg('preserve_css')) {
|
67 |
+
return;
|
68 |
+
}
|
69 |
+
|
70 |
+
if ($this->parser->get_cfg('merge_selectors') === 2) {
|
71 |
+
foreach ($this->css as $medium => $value) {
|
72 |
+
$this->merge_selectors($this->css[$medium]);
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
if ($this->parser->get_cfg('discard_invalid_selectors')) {
|
77 |
+
foreach ($this->css as $medium => $value) {
|
78 |
+
$this->discard_invalid_selectors($this->css[$medium]);
|
79 |
+
}
|
80 |
+
}
|
81 |
+
|
82 |
+
if ($this->parser->get_cfg('optimise_shorthands') > 0) {
|
83 |
+
foreach ($this->css as $medium => $value) {
|
84 |
+
foreach ($value as $selector => $value1) {
|
85 |
+
$this->css[$medium][$selector] = csstidy_optimise::merge_4value_shorthands($this->css[$medium][$selector]);
|
86 |
+
|
87 |
+
if ($this->parser->get_cfg('optimise_shorthands') < 2) {
|
88 |
+
continue;
|
89 |
+
}
|
90 |
+
|
91 |
+
$this->css[$medium][$selector] = csstidy_optimise::merge_font($this->css[$medium][$selector]);
|
92 |
+
|
93 |
+
if ($this->parser->get_cfg('optimise_shorthands') < 3) {
|
94 |
+
continue;
|
95 |
+
}
|
96 |
+
|
97 |
+
$this->css[$medium][$selector] = csstidy_optimise::merge_bg($this->css[$medium][$selector]);
|
98 |
+
if (empty($this->css[$medium][$selector])) {
|
99 |
+
unset($this->css[$medium][$selector]);
|
100 |
+
}
|
101 |
+
}
|
102 |
+
}
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Optimises values
|
108 |
+
* @access public
|
109 |
+
* @version 1.0
|
110 |
+
*/
|
111 |
+
function value() {
|
112 |
+
$shorthands = & $GLOBALS['csstidy']['shorthands'];
|
113 |
+
|
114 |
+
// optimise shorthand properties
|
115 |
+
if (isset($shorthands[$this->property])) {
|
116 |
+
$temp = csstidy_optimise::shorthand($this->value); // FIXME - move
|
117 |
+
if ($temp != $this->value) {
|
118 |
+
$this->parser->log('Optimised shorthand notation (' . $this->property . '): Changed "' . $this->value . '" to "' . $temp . '"', 'Information');
|
119 |
+
}
|
120 |
+
$this->value = $temp;
|
121 |
+
}
|
122 |
+
|
123 |
+
// Remove whitespace at ! important
|
124 |
+
if ($this->value != $this->compress_important($this->value)) {
|
125 |
+
$this->parser->log('Optimised !important', 'Information');
|
126 |
+
}
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Optimises shorthands
|
131 |
+
* @access public
|
132 |
+
* @version 1.0
|
133 |
+
*/
|
134 |
+
function shorthands() {
|
135 |
+
$shorthands = & $GLOBALS['csstidy']['shorthands'];
|
136 |
+
|
137 |
+
if (!$this->parser->get_cfg('optimise_shorthands') || $this->parser->get_cfg('preserve_css')) {
|
138 |
+
return;
|
139 |
+
}
|
140 |
+
|
141 |
+
if ($this->property === 'font' && $this->parser->get_cfg('optimise_shorthands') > 1) {
|
142 |
+
$this->css[$this->at][$this->selector]['font']='';
|
143 |
+
$this->parser->merge_css_blocks($this->at, $this->selector, csstidy_optimise::dissolve_short_font($this->value));
|
144 |
+
}
|
145 |
+
if ($this->property === 'background' && $this->parser->get_cfg('optimise_shorthands') > 2) {
|
146 |
+
$this->css[$this->at][$this->selector]['background']='';
|
147 |
+
$this->parser->merge_css_blocks($this->at, $this->selector, csstidy_optimise::dissolve_short_bg($this->value));
|
148 |
+
}
|
149 |
+
if (isset($shorthands[$this->property])) {
|
150 |
+
$this->parser->merge_css_blocks($this->at, $this->selector, csstidy_optimise::dissolve_4value_shorthands($this->property, $this->value));
|
151 |
+
if (is_array($shorthands[$this->property])) {
|
152 |
+
$this->css[$this->at][$this->selector][$this->property] = '';
|
153 |
+
}
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Optimises a sub-value
|
159 |
+
* @access public
|
160 |
+
* @version 1.0
|
161 |
+
*/
|
162 |
+
function subvalue() {
|
163 |
+
$replace_colors = & $GLOBALS['csstidy']['replace_colors'];
|
164 |
+
|
165 |
+
$this->sub_value = trim($this->sub_value);
|
166 |
+
if ($this->sub_value == '') { // caution : '0'
|
167 |
+
return;
|
168 |
+
}
|
169 |
+
|
170 |
+
$important = '';
|
171 |
+
if (csstidy::is_important($this->sub_value)) {
|
172 |
+
$important = '!important';
|
173 |
+
}
|
174 |
+
$this->sub_value = csstidy::gvw_important($this->sub_value);
|
175 |
+
|
176 |
+
// Compress font-weight
|
177 |
+
if ($this->property === 'font-weight' && $this->parser->get_cfg('compress_font-weight')) {
|
178 |
+
if ($this->sub_value === 'bold') {
|
179 |
+
$this->sub_value = '700';
|
180 |
+
$this->parser->log('Optimised font-weight: Changed "bold" to "700"', 'Information');
|
181 |
+
} else if ($this->sub_value === 'normal') {
|
182 |
+
$this->sub_value = '400';
|
183 |
+
$this->parser->log('Optimised font-weight: Changed "normal" to "400"', 'Information');
|
184 |
+
}
|
185 |
+
}
|
186 |
+
|
187 |
+
$temp = $this->compress_numbers($this->sub_value);
|
188 |
+
if (strcasecmp($temp, $this->sub_value) !== 0) {
|
189 |
+
if (strlen($temp) > strlen($this->sub_value)) {
|
190 |
+
$this->parser->log('Fixed invalid number: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Warning');
|
191 |
+
} else {
|
192 |
+
$this->parser->log('Optimised number: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Information');
|
193 |
+
}
|
194 |
+
$this->sub_value = $temp;
|
195 |
+
}
|
196 |
+
if ($this->parser->get_cfg('compress_colors')) {
|
197 |
+
$temp = $this->cut_color($this->sub_value);
|
198 |
+
if ($temp !== $this->sub_value) {
|
199 |
+
if (isset($replace_colors[$this->sub_value])) {
|
200 |
+
$this->parser->log('Fixed invalid color name: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Warning');
|
201 |
+
} else {
|
202 |
+
$this->parser->log('Optimised color: Changed "' . $this->sub_value . '" to "' . $temp . '"', 'Information');
|
203 |
+
}
|
204 |
+
$this->sub_value = $temp;
|
205 |
+
}
|
206 |
+
}
|
207 |
+
$this->sub_value .= $important;
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Compresses shorthand values. Example: margin:1px 1px 1px 1px -> margin:1px
|
212 |
+
* @param string $value
|
213 |
+
* @access public
|
214 |
+
* @return string
|
215 |
+
* @version 1.0
|
216 |
+
*/
|
217 |
+
function shorthand($value) {
|
218 |
+
$important = '';
|
219 |
+
if (csstidy::is_important($value)) {
|
220 |
+
$values = csstidy::gvw_important($value);
|
221 |
+
$important = '!important';
|
222 |
+
}
|
223 |
+
else
|
224 |
+
$values = $value;
|
225 |
+
|
226 |
+
$values = explode(' ', $values);
|
227 |
+
switch (count($values)) {
|
228 |
+
case 4:
|
229 |
+
if ($values[0] == $values[1] && $values[0] == $values[2] && $values[0] == $values[3]) {
|
230 |
+
return $values[0] . $important;
|
231 |
+
} elseif ($values[1] == $values[3] && $values[0] == $values[2]) {
|
232 |
+
return $values[0] . ' ' . $values[1] . $important;
|
233 |
+
} elseif ($values[1] == $values[3]) {
|
234 |
+
return $values[0] . ' ' . $values[1] . ' ' . $values[2] . $important;
|
235 |
+
}
|
236 |
+
break;
|
237 |
+
|
238 |
+
case 3:
|
239 |
+
if ($values[0] == $values[1] && $values[0] == $values[2]) {
|
240 |
+
return $values[0] . $important;
|
241 |
+
} elseif ($values[0] == $values[2]) {
|
242 |
+
return $values[0] . ' ' . $values[1] . $important;
|
243 |
+
}
|
244 |
+
break;
|
245 |
+
|
246 |
+
case 2:
|
247 |
+
if ($values[0] == $values[1]) {
|
248 |
+
return $values[0] . $important;
|
249 |
+
}
|
250 |
+
break;
|
251 |
+
}
|
252 |
+
|
253 |
+
return $value;
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Removes unnecessary whitespace in ! important
|
258 |
+
* @param string $string
|
259 |
+
* @return string
|
260 |
+
* @access public
|
261 |
+
* @version 1.1
|
262 |
+
*/
|
263 |
+
function compress_important(&$string) {
|
264 |
+
if (csstidy::is_important($string)) {
|
265 |
+
$string = csstidy::gvw_important($string) . '!important';
|
266 |
+
}
|
267 |
+
return $string;
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Color compression function. Converts all rgb() values to #-values and uses the short-form if possible. Also replaces 4 color names by #-values.
|
272 |
+
* @param string $color
|
273 |
+
* @return string
|
274 |
+
* @version 1.1
|
275 |
+
*/
|
276 |
+
function cut_color($color) {
|
277 |
+
$replace_colors = & $GLOBALS['csstidy']['replace_colors'];
|
278 |
+
|
279 |
+
// rgb(0,0,0) -> #000000 (or #000 in this case later)
|
280 |
+
if (strtolower(substr($color, 0, 4)) === 'rgb(') {
|
281 |
+
$color_tmp = substr($color, 4, strlen($color) - 5);
|
282 |
+
$color_tmp = explode(',', $color_tmp);
|
283 |
+
for ($i = 0; $i < count($color_tmp); $i++) {
|
284 |
+
$color_tmp[$i] = trim($color_tmp[$i]);
|
285 |
+
if (substr($color_tmp[$i], -1) === '%') {
|
286 |
+
$color_tmp[$i] = round((255 * $color_tmp[$i]) / 100);
|
287 |
+
}
|
288 |
+
if ($color_tmp[$i] > 255)
|
289 |
+
$color_tmp[$i] = 255;
|
290 |
+
}
|
291 |
+
$color = '#';
|
292 |
+
for ($i = 0; $i < 3; $i++) {
|
293 |
+
if ($color_tmp[$i] < 16) {
|
294 |
+
$color .= '0' . dechex($color_tmp[$i]);
|
295 |
+
} else {
|
296 |
+
$color .= dechex($color_tmp[$i]);
|
297 |
+
}
|
298 |
+
}
|
299 |
+
}
|
300 |
+
|
301 |
+
// Fix bad color names
|
302 |
+
if (isset($replace_colors[strtolower($color)])) {
|
303 |
+
$color = $replace_colors[strtolower($color)];
|
304 |
+
}
|
305 |
+
|
306 |
+
// #aabbcc -> #abc
|
307 |
+
if (strlen($color) == 7) {
|
308 |
+
$color_temp = strtolower($color);
|
309 |
+
if ($color_temp{0} === '#' && $color_temp{1} == $color_temp{2} && $color_temp{3} == $color_temp{4} && $color_temp{5} == $color_temp{6}) {
|
310 |
+
$color = '#' . $color{1} . $color{3} . $color{5};
|
311 |
+
}
|
312 |
+
}
|
313 |
+
|
314 |
+
switch (strtolower($color)) {
|
315 |
+
/* color name -> hex code */
|
316 |
+
case 'black': return '#000';
|
317 |
+
case 'fuchsia': return '#f0f';
|
318 |
+
case 'white': return '#fff';
|
319 |
+
case 'yellow': return '#ff0';
|
320 |
+
|
321 |
+
/* hex code -> color name */
|
322 |
+
case '#800000': return 'maroon';
|
323 |
+
case '#ffa500': return 'orange';
|
324 |
+
case '#808000': return 'olive';
|
325 |
+
case '#800080': return 'purple';
|
326 |
+
case '#008000': return 'green';
|
327 |
+
case '#000080': return 'navy';
|
328 |
+
case '#008080': return 'teal';
|
329 |
+
case '#c0c0c0': return 'silver';
|
330 |
+
case '#808080': return 'gray';
|
331 |
+
case '#f00': return 'red';
|
332 |
+
}
|
333 |
+
|
334 |
+
return $color;
|
335 |
+
}
|
336 |
+
|
337 |
+
/**
|
338 |
+
* Compresses numbers (ie. 1.0 becomes 1 or 1.100 becomes 1.1 )
|
339 |
+
* @param string $subvalue
|
340 |
+
* @return string
|
341 |
+
* @version 1.2
|
342 |
+
*/
|
343 |
+
function compress_numbers($subvalue) {
|
344 |
+
$unit_values = & $GLOBALS['csstidy']['unit_values'];
|
345 |
+
$color_values = & $GLOBALS['csstidy']['color_values'];
|
346 |
+
|
347 |
+
// for font:1em/1em sans-serif...;
|
348 |
+
if ($this->property === 'font') {
|
349 |
+
$temp = explode('/', $subvalue);
|
350 |
+
} else {
|
351 |
+
$temp = array($subvalue);
|
352 |
+
}
|
353 |
+
for ($l = 0; $l < count($temp); $l++) {
|
354 |
+
// if we are not dealing with a number at this point, do not optimise anything
|
355 |
+
$number = $this->AnalyseCssNumber($temp[$l]);
|
356 |
+
if ($number === false) {
|
357 |
+
return $subvalue;
|
358 |
+
}
|
359 |
+
|
360 |
+
// Fix bad colors
|
361 |
+
if (in_array($this->property, $color_values)) {
|
362 |
+
if (strlen($temp[$l]) == 3 || strlen($temp[$l]) == 6) {
|
363 |
+
$temp[$l] = '#' . $temp[$l];
|
364 |
+
}
|
365 |
+
else {
|
366 |
+
$temp[$l] = "0";
|
367 |
+
}
|
368 |
+
continue;
|
369 |
+
}
|
370 |
+
|
371 |
+
if (abs($number[0]) > 0) {
|
372 |
+
if ($number[1] == '' && in_array($this->property, $unit_values, true)) {
|
373 |
+
$number[1] = 'px';
|
374 |
+
}
|
375 |
+
} else {
|
376 |
+
$number[1] = '';
|
377 |
+
}
|
378 |
+
|
379 |
+
$temp[$l] = $number[0] . $number[1];
|
380 |
+
}
|
381 |
+
|
382 |
+
return ((count($temp) > 1) ? $temp[0] . '/' . $temp[1] : $temp[0]);
|
383 |
+
}
|
384 |
+
|
385 |
+
/**
|
386 |
+
* Checks if a given string is a CSS valid number. If it is,
|
387 |
+
* an array containing the value and unit is returned
|
388 |
+
* @param string $string
|
389 |
+
* @return array ('unit' if unit is found or '' if no unit exists, number value) or false if no number
|
390 |
+
*/
|
391 |
+
function AnalyseCssNumber($string) {
|
392 |
+
// most simple checks first
|
393 |
+
if (strlen($string) == 0 || ctype_alpha($string{0})) {
|
394 |
+
return false;
|
395 |
+
}
|
396 |
+
|
397 |
+
$units = & $GLOBALS['csstidy']['units'];
|
398 |
+
$return = array(0, '');
|
399 |
+
|
400 |
+
$return[0] = floatval($string);
|
401 |
+
if (abs($return[0]) > 0 && abs($return[0]) < 1) {
|
402 |
+
if ($return[0] < 0) {
|
403 |
+
$return[0] = '-' . ltrim(substr($return[0], 1), '0');
|
404 |
+
} else {
|
405 |
+
$return[0] = ltrim($return[0], '0');
|
406 |
+
}
|
407 |
+
}
|
408 |
+
|
409 |
+
// Look for unit and split from value if exists
|
410 |
+
foreach ($units as $unit) {
|
411 |
+
$expectUnitAt = strlen($string) - strlen($unit);
|
412 |
+
if (!($unitInString = stristr($string, $unit))) { // mb_strpos() fails with "false"
|
413 |
+
continue;
|
414 |
+
}
|
415 |
+
$actualPosition = strpos($string, $unitInString);
|
416 |
+
if ($expectUnitAt === $actualPosition) {
|
417 |
+
$return[1] = $unit;
|
418 |
+
$string = substr($string, 0, - strlen($unit));
|
419 |
+
break;
|
420 |
+
}
|
421 |
+
}
|
422 |
+
if (!is_numeric($string)) {
|
423 |
+
return false;
|
424 |
+
}
|
425 |
+
return $return;
|
426 |
+
}
|
427 |
+
|
428 |
+
/**
|
429 |
+
* Merges selectors with same properties. Example: a{color:red} b{color:red} -> a,b{color:red}
|
430 |
+
* Very basic and has at least one bug. Hopefully there is a replacement soon.
|
431 |
+
* @param array $array
|
432 |
+
* @return array
|
433 |
+
* @access public
|
434 |
+
* @version 1.2
|
435 |
+
*/
|
436 |
+
function merge_selectors(&$array) {
|
437 |
+
$css = $array;
|
438 |
+
foreach ($css as $key => $value) {
|
439 |
+
if (!isset($css[$key])) {
|
440 |
+
continue;
|
441 |
+
}
|
442 |
+
$newsel = '';
|
443 |
+
|
444 |
+
// Check if properties also exist in another selector
|
445 |
+
$keys = array();
|
446 |
+
// PHP bug (?) without $css = $array; here
|
447 |
+
foreach ($css as $selector => $vali) {
|
448 |
+
if ($selector == $key) {
|
449 |
+
continue;
|
450 |
+
}
|
451 |
+
|
452 |
+
if ($css[$key] === $vali) {
|
453 |
+
$keys[] = $selector;
|
454 |
+
}
|
455 |
+
}
|
456 |
+
|
457 |
+
if (!empty($keys)) {
|
458 |
+
$newsel = $key;
|
459 |
+
unset($css[$key]);
|
460 |
+
foreach ($keys as $selector) {
|
461 |
+
unset($css[$selector]);
|
462 |
+
$newsel .= ',' . $selector;
|
463 |
+
}
|
464 |
+
$css[$newsel] = $value;
|
465 |
+
}
|
466 |
+
}
|
467 |
+
$array = $css;
|
468 |
+
}
|
469 |
+
|
470 |
+
/**
|
471 |
+
* Removes invalid selectors and their corresponding rule-sets as
|
472 |
+
* defined by 4.1.7 in REC-CSS2. This is a very rudimentary check
|
473 |
+
* and should be replaced by a full-blown parsing algorithm or
|
474 |
+
* regular expression
|
475 |
+
* @version 1.4
|
476 |
+
*/
|
477 |
+
function discard_invalid_selectors(&$array) {
|
478 |
+
$invalid = array('+' => true, '~' => true, ',' => true, '>' => true);
|
479 |
+
foreach ($array as $selector => $decls) {
|
480 |
+
$ok = true;
|
481 |
+
$selectors = array_map('trim', explode(',', $selector));
|
482 |
+
foreach ($selectors as $s) {
|
483 |
+
$simple_selectors = preg_split('/\s*[+>~\s]\s*/', $s);
|
484 |
+
foreach ($simple_selectors as $ss) {
|
485 |
+
if ($ss === '')
|
486 |
+
$ok = false;
|
487 |
+
// could also check $ss for internal structure,
|
488 |
+
// but that probably would be too slow
|
489 |
+
}
|
490 |
+
}
|
491 |
+
if (!$ok)
|
492 |
+
unset($array[$selector]);
|
493 |
+
}
|
494 |
+
}
|
495 |
+
|
496 |
+
/**
|
497 |
+
* Dissolves properties like padding:10px 10px 10px to padding-top:10px;padding-bottom:10px;...
|
498 |
+
* @param string $property
|
499 |
+
* @param string $value
|
500 |
+
* @return array
|
501 |
+
* @version 1.0
|
502 |
+
* @see merge_4value_shorthands()
|
503 |
+
*/
|
504 |
+
function dissolve_4value_shorthands($property, $value) {
|
505 |
+
$shorthands = & $GLOBALS['csstidy']['shorthands'];
|
506 |
+
if (!is_array($shorthands[$property])) {
|
507 |
+
$return[$property] = $value;
|
508 |
+
return $return;
|
509 |
+
}
|
510 |
+
|
511 |
+
$important = '';
|
512 |
+
if (csstidy::is_important($value)) {
|
513 |
+
$value = csstidy::gvw_important($value);
|
514 |
+
$important = '!important';
|
515 |
+
}
|
516 |
+
$values = explode(' ', $value);
|
517 |
+
|
518 |
+
|
519 |
+
$return = array();
|
520 |
+
if (count($values) == 4) {
|
521 |
+
for ($i = 0; $i < 4; $i++) {
|
522 |
+
$return[$shorthands[$property][$i]] = $values[$i] . $important;
|
523 |
+
}
|
524 |
+
} elseif (count($values) == 3) {
|
525 |
+
$return[$shorthands[$property][0]] = $values[0] . $important;
|
526 |
+
$return[$shorthands[$property][1]] = $values[1] . $important;
|
527 |
+
$return[$shorthands[$property][3]] = $values[1] . $important;
|
528 |
+
$return[$shorthands[$property][2]] = $values[2] . $important;
|
529 |
+
} elseif (count($values) == 2) {
|
530 |
+
for ($i = 0; $i < 4; $i++) {
|
531 |
+
$return[$shorthands[$property][$i]] = (($i % 2 != 0)) ? $values[1] . $important : $values[0] . $important;
|
532 |
+
}
|
533 |
+
} else {
|
534 |
+
for ($i = 0; $i < 4; $i++) {
|
535 |
+
$return[$shorthands[$property][$i]] = $values[0] . $important;
|
536 |
+
}
|
537 |
+
}
|
538 |
+
|
539 |
+
return $return;
|
540 |
+
}
|
541 |
+
|
542 |
+
/**
|
543 |
+
* Explodes a string as explode() does, however, not if $sep is escaped or within a string.
|
544 |
+
* @param string $sep seperator
|
545 |
+
* @param string $string
|
546 |
+
* @return array
|
547 |
+
* @version 1.0
|
548 |
+
*/
|
549 |
+
function explode_ws($sep, $string) {
|
550 |
+
$status = 'st';
|
551 |
+
$to = '';
|
552 |
+
|
553 |
+
$output = array();
|
554 |
+
$num = 0;
|
555 |
+
for ($i = 0, $len = strlen($string); $i < $len; $i++) {
|
556 |
+
switch ($status) {
|
557 |
+
case 'st':
|
558 |
+
if ($string{$i} == $sep && !csstidy::escaped($string, $i)) {
|
559 |
+
++$num;
|
560 |
+
} elseif ($string{$i} === '"' || $string{$i} === '\'' || $string{$i} === '(' && !csstidy::escaped($string, $i)) {
|
561 |
+
$status = 'str';
|
562 |
+
$to = ($string{$i} === '(') ? ')' : $string{$i};
|
563 |
+
(isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
|
564 |
+
} else {
|
565 |
+
(isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
|
566 |
+
}
|
567 |
+
break;
|
568 |
+
|
569 |
+
case 'str':
|
570 |
+
if ($string{$i} == $to && !csstidy::escaped($string, $i)) {
|
571 |
+
$status = 'st';
|
572 |
+
}
|
573 |
+
(isset($output[$num])) ? $output[$num] .= $string{$i} : $output[$num] = $string{$i};
|
574 |
+
break;
|
575 |
+
}
|
576 |
+
}
|
577 |
+
|
578 |
+
if (isset($output[0])) {
|
579 |
+
return $output;
|
580 |
+
} else {
|
581 |
+
return array($output);
|
582 |
+
}
|
583 |
+
}
|
584 |
+
|
585 |
+
/**
|
586 |
+
* Merges Shorthand properties again, the opposite of dissolve_4value_shorthands()
|
587 |
+
* @param array $array
|
588 |
+
* @return array
|
589 |
+
* @version 1.2
|
590 |
+
* @see dissolve_4value_shorthands()
|
591 |
+
*/
|
592 |
+
function merge_4value_shorthands($array) {
|
593 |
+
$return = $array;
|
594 |
+
$shorthands = & $GLOBALS['csstidy']['shorthands'];
|
595 |
+
|
596 |
+
foreach ($shorthands as $key => $value) {
|
597 |
+
if (isset($array[$value[0]]) && isset($array[$value[1]])
|
598 |
+
&& isset($array[$value[2]]) && isset($array[$value[3]]) && $value !== 0) {
|
599 |
+
$return[$key] = '';
|
600 |
+
|
601 |
+
$important = '';
|
602 |
+
for ($i = 0; $i < 4; $i++) {
|
603 |
+
$val = $array[$value[$i]];
|
604 |
+
if (csstidy::is_important($val)) {
|
605 |
+
$important = '!important';
|
606 |
+
$return[$key] .= csstidy::gvw_important($val) . ' ';
|
607 |
+
} else {
|
608 |
+
$return[$key] .= $val . ' ';
|
609 |
+
}
|
610 |
+
unset($return[$value[$i]]);
|
611 |
+
}
|
612 |
+
$return[$key] = csstidy_optimise::shorthand(trim($return[$key] . $important));
|
613 |
+
}
|
614 |
+
}
|
615 |
+
return $return;
|
616 |
+
}
|
617 |
+
|
618 |
+
/**
|
619 |
+
* Dissolve background property
|
620 |
+
* @param string $str_value
|
621 |
+
* @return array
|
622 |
+
* @version 1.0
|
623 |
+
* @see merge_bg()
|
624 |
+
* @todo full CSS 3 compliance
|
625 |
+
*/
|
626 |
+
function dissolve_short_bg($str_value) {
|
627 |
+
// don't try to explose background gradient !
|
628 |
+
if (stripos($str_value, "gradient(")!==FALSE)
|
629 |
+
return array('background'=>$str_value);
|
630 |
+
|
631 |
+
$background_prop_default = & $GLOBALS['csstidy']['background_prop_default'];
|
632 |
+
$repeat = array('repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'space');
|
633 |
+
$attachment = array('scroll', 'fixed', 'local');
|
634 |
+
$clip = array('border', 'padding');
|
635 |
+
$origin = array('border', 'padding', 'content');
|
636 |
+
$pos = array('top', 'center', 'bottom', 'left', 'right');
|
637 |
+
$important = '';
|
638 |
+
$return = array('background-image' => null, 'background-size' => null, 'background-repeat' => null, 'background-position' => null, 'background-attachment' => null, 'background-clip' => null, 'background-origin' => null, 'background-color' => null);
|
639 |
+
|
640 |
+
if (csstidy::is_important($str_value)) {
|
641 |
+
$important = ' !important';
|
642 |
+
$str_value = csstidy::gvw_important($str_value);
|
643 |
+
}
|
644 |
+
|
645 |
+
$str_value = csstidy_optimise::explode_ws(',', $str_value);
|
646 |
+
for ($i = 0; $i < count($str_value); $i++) {
|
647 |
+
$have['clip'] = false;
|
648 |
+
$have['pos'] = false;
|
649 |
+
$have['color'] = false;
|
650 |
+
$have['bg'] = false;
|
651 |
+
|
652 |
+
if (is_array($str_value[$i])) {
|
653 |
+
$str_value[$i] = $str_value[$i][0];
|
654 |
+
}
|
655 |
+
$str_value[$i] = csstidy_optimise::explode_ws(' ', trim($str_value[$i]));
|
656 |
+
|
657 |
+
for ($j = 0; $j < count($str_value[$i]); $j++) {
|
658 |
+
if ($have['bg'] === false && (substr($str_value[$i][$j], 0, 4) === 'url(' || $str_value[$i][$j] === 'none')) {
|
659 |
+
$return['background-image'] .= $str_value[$i][$j] . ',';
|
660 |
+
$have['bg'] = true;
|
661 |
+
} elseif (in_array($str_value[$i][$j], $repeat, true)) {
|
662 |
+
$return['background-repeat'] .= $str_value[$i][$j] . ',';
|
663 |
+
} elseif (in_array($str_value[$i][$j], $attachment, true)) {
|
664 |
+
$return['background-attachment'] .= $str_value[$i][$j] . ',';
|
665 |
+
} elseif (in_array($str_value[$i][$j], $clip, true) && !$have['clip']) {
|
666 |
+
$return['background-clip'] .= $str_value[$i][$j] . ',';
|
667 |
+
$have['clip'] = true;
|
668 |
+
} elseif (in_array($str_value[$i][$j], $origin, true)) {
|
669 |
+
$return['background-origin'] .= $str_value[$i][$j] . ',';
|
670 |
+
} elseif ($str_value[$i][$j]{0} === '(') {
|
671 |
+
$return['background-size'] .= substr($str_value[$i][$j], 1, -1) . ',';
|
672 |
+
} elseif (in_array($str_value[$i][$j], $pos, true) || is_numeric($str_value[$i][$j]{0}) || $str_value[$i][$j]{0} === null || $str_value[$i][$j]{0} === '-' || $str_value[$i][$j]{0} === '.') {
|
673 |
+
$return['background-position'] .= $str_value[$i][$j];
|
674 |
+
if (!$have['pos'])
|
675 |
+
$return['background-position'] .= ' '; else
|
676 |
+
$return['background-position'].= ',';
|
677 |
+
$have['pos'] = true;
|
678 |
+
}
|
679 |
+
elseif (!$have['color']) {
|
680 |
+
$return['background-color'] .= $str_value[$i][$j] . ',';
|
681 |
+
$have['color'] = true;
|
682 |
+
}
|
683 |
+
}
|
684 |
+
}
|
685 |
+
|
686 |
+
foreach ($background_prop_default as $bg_prop => $default_value) {
|
687 |
+
if ($return[$bg_prop] !== null) {
|
688 |
+
$return[$bg_prop] = substr($return[$bg_prop], 0, -1) . $important;
|
689 |
+
}
|
690 |
+
else
|
691 |
+
$return[$bg_prop] = $default_value . $important;
|
692 |
+
}
|
693 |
+
return $return;
|
694 |
+
}
|
695 |
+
|
696 |
+
/**
|
697 |
+
* Merges all background properties
|
698 |
+
* @param array $input_css
|
699 |
+
* @return array
|
700 |
+
* @version 1.0
|
701 |
+
* @see dissolve_short_bg()
|
702 |
+
* @todo full CSS 3 compliance
|
703 |
+
*/
|
704 |
+
function merge_bg($input_css) {
|
705 |
+
$background_prop_default = & $GLOBALS['csstidy']['background_prop_default'];
|
706 |
+
// Max number of background images. CSS3 not yet fully implemented
|
707 |
+
$number_of_values = @max(count(csstidy_optimise::explode_ws(',', $input_css['background-image'])), count(csstidy_optimise::explode_ws(',', $input_css['background-color'])), 1);
|
708 |
+
// Array with background images to check if BG image exists
|
709 |
+
$bg_img_array = @csstidy_optimise::explode_ws(',', csstidy::gvw_important($input_css['background-image']));
|
710 |
+
$new_bg_value = '';
|
711 |
+
$important = '';
|
712 |
+
|
713 |
+
// if background properties is here and not empty, don't try anything
|
714 |
+
if (isset($input_css['background']) AND $input_css['background'])
|
715 |
+
return $input_css;
|
716 |
+
|
717 |
+
for ($i = 0; $i < $number_of_values; $i++) {
|
718 |
+
foreach ($background_prop_default as $bg_property => $default_value) {
|
719 |
+
// Skip if property does not exist
|
720 |
+
if (!isset($input_css[$bg_property])) {
|
721 |
+
continue;
|
722 |
+
}
|
723 |
+
|
724 |
+
$cur_value = $input_css[$bg_property];
|
725 |
+
// skip all optimisation if gradient() somewhere
|
726 |
+
if (stripos($cur_value, "gradient(")!==FALSE)
|
727 |
+
return $input_css;
|
728 |
+
|
729 |
+
// Skip some properties if there is no background image
|
730 |
+
if ((!isset($bg_img_array[$i]) || $bg_img_array[$i] === 'none')
|
731 |
+
&& ($bg_property === 'background-size' || $bg_property === 'background-position'
|
732 |
+
|| $bg_property === 'background-attachment' || $bg_property === 'background-repeat')) {
|
733 |
+
continue;
|
734 |
+
}
|
735 |
+
|
736 |
+
// Remove !important
|
737 |
+
if (csstidy::is_important($cur_value)) {
|
738 |
+
$important = ' !important';
|
739 |
+
$cur_value = csstidy::gvw_important($cur_value);
|
740 |
+
}
|
741 |
+
|
742 |
+
// Do not add default values
|
743 |
+
if ($cur_value === $default_value) {
|
744 |
+
continue;
|
745 |
+
}
|
746 |
+
|
747 |
+
$temp = csstidy_optimise::explode_ws(',', $cur_value);
|
748 |
+
|
749 |
+
if (isset($temp[$i])) {
|
750 |
+
if ($bg_property === 'background-size') {
|
751 |
+
$new_bg_value .= '(' . $temp[$i] . ') ';
|
752 |
+
} else {
|
753 |
+
$new_bg_value .= $temp[$i] . ' ';
|
754 |
+
}
|
755 |
+
}
|
756 |
+
}
|
757 |
+
|
758 |
+
$new_bg_value = trim($new_bg_value);
|
759 |
+
if ($i != $number_of_values - 1)
|
760 |
+
$new_bg_value .= ',';
|
761 |
+
}
|
762 |
+
|
763 |
+
// Delete all background-properties
|
764 |
+
foreach ($background_prop_default as $bg_property => $default_value) {
|
765 |
+
unset($input_css[$bg_property]);
|
766 |
+
}
|
767 |
+
|
768 |
+
// Add new background property
|
769 |
+
if ($new_bg_value !== '')
|
770 |
+
$input_css['background'] = $new_bg_value . $important;
|
771 |
+
elseif(isset ($input_css['background']))
|
772 |
+
$input_css['background'] = 'none';
|
773 |
+
|
774 |
+
return $input_css;
|
775 |
+
}
|
776 |
+
|
777 |
+
/**
|
778 |
+
* Dissolve font property
|
779 |
+
* @param string $str_value
|
780 |
+
* @return array
|
781 |
+
* @version 1.3
|
782 |
+
* @see merge_font()
|
783 |
+
*/
|
784 |
+
function dissolve_short_font($str_value) {
|
785 |
+
$font_prop_default = & $GLOBALS['csstidy']['font_prop_default'];
|
786 |
+
$font_weight = array('normal', 'bold', 'bolder', 'lighter', 100, 200, 300, 400, 500, 600, 700, 800, 900);
|
787 |
+
$font_variant = array('normal', 'small-caps');
|
788 |
+
$font_style = array('normal', 'italic', 'oblique');
|
789 |
+
$important = '';
|
790 |
+
$return = array('font-style' => null, 'font-variant' => null, 'font-weight' => null, 'font-size' => null, 'line-height' => null, 'font-family' => null);
|
791 |
+
|
792 |
+
if (csstidy::is_important($str_value)) {
|
793 |
+
$important = '!important';
|
794 |
+
$str_value = csstidy::gvw_important($str_value);
|
795 |
+
}
|
796 |
+
|
797 |
+
$have['style'] = false;
|
798 |
+
$have['variant'] = false;
|
799 |
+
$have['weight'] = false;
|
800 |
+
$have['size'] = false;
|
801 |
+
// Detects if font-family consists of several words w/o quotes
|
802 |
+
$multiwords = false;
|
803 |
+
|
804 |
+
// Workaround with multiple font-family
|
805 |
+
$str_value = csstidy_optimise::explode_ws(',', trim($str_value));
|
806 |
+
|
807 |
+
$str_value[0] = csstidy_optimise::explode_ws(' ', trim($str_value[0]));
|
808 |
+
|
809 |
+
for ($j = 0; $j < count($str_value[0]); $j++) {
|
810 |
+
if ($have['weight'] === false && in_array($str_value[0][$j], $font_weight)) {
|
811 |
+
$return['font-weight'] = $str_value[0][$j];
|
812 |
+
$have['weight'] = true;
|
813 |
+
} elseif ($have['variant'] === false && in_array($str_value[0][$j], $font_variant)) {
|
814 |
+
$return['font-variant'] = $str_value[0][$j];
|
815 |
+
$have['variant'] = true;
|
816 |
+
} elseif ($have['style'] === false && in_array($str_value[0][$j], $font_style)) {
|
817 |
+
$return['font-style'] = $str_value[0][$j];
|
818 |
+
$have['style'] = true;
|
819 |
+
} elseif ($have['size'] === false && (is_numeric($str_value[0][$j]{0}) || $str_value[0][$j]{0} === null || $str_value[0][$j]{0} === '.')) {
|
820 |
+
$size = csstidy_optimise::explode_ws('/', trim($str_value[0][$j]));
|
821 |
+
$return['font-size'] = $size[0];
|
822 |
+
if (isset($size[1])) {
|
823 |
+
$return['line-height'] = $size[1];
|
824 |
+
} else {
|
825 |
+
$return['line-height'] = ''; // don't add 'normal' !
|
826 |
+
}
|
827 |
+
$have['size'] = true;
|
828 |
+
} else {
|
829 |
+
if (isset($return['font-family'])) {
|
830 |
+
$return['font-family'] .= ' ' . $str_value[0][$j];
|
831 |
+
$multiwords = true;
|
832 |
+
} else {
|
833 |
+
$return['font-family'] = $str_value[0][$j];
|
834 |
+
}
|
835 |
+
}
|
836 |
+
}
|
837 |
+
// add quotes if we have several qords in font-family
|
838 |
+
if ($multiwords !== false) {
|
839 |
+
$return['font-family'] = '"' . $return['font-family'] . '"';
|
840 |
+
}
|
841 |
+
$i = 1;
|
842 |
+
while (isset($str_value[$i])) {
|
843 |
+
$return['font-family'] .= ',' . trim($str_value[$i]);
|
844 |
+
$i++;
|
845 |
+
}
|
846 |
+
|
847 |
+
// Fix for 100 and more font-size
|
848 |
+
if ($have['size'] === false && isset($return['font-weight']) &&
|
849 |
+
is_numeric($return['font-weight']{0})) {
|
850 |
+
$return['font-size'] = $return['font-weight'];
|
851 |
+
unset($return['font-weight']);
|
852 |
+
}
|
853 |
+
|
854 |
+
foreach ($font_prop_default as $font_prop => $default_value) {
|
855 |
+
if ($return[$font_prop] !== null) {
|
856 |
+
$return[$font_prop] = $return[$font_prop] . $important;
|
857 |
+
}
|
858 |
+
else
|
859 |
+
$return[$font_prop] = $default_value . $important;
|
860 |
+
}
|
861 |
+
return $return;
|
862 |
+
}
|
863 |
+
|
864 |
+
/**
|
865 |
+
* Merges all fonts properties
|
866 |
+
* @param array $input_css
|
867 |
+
* @return array
|
868 |
+
* @version 1.3
|
869 |
+
* @see dissolve_short_font()
|
870 |
+
*/
|
871 |
+
function merge_font($input_css) {
|
872 |
+
$font_prop_default = & $GLOBALS['csstidy']['font_prop_default'];
|
873 |
+
$new_font_value = '';
|
874 |
+
$important = '';
|
875 |
+
// Skip if not font-family and font-size set
|
876 |
+
if (isset($input_css['font-family']) && isset($input_css['font-size'])) {
|
877 |
+
// fix several words in font-family - add quotes
|
878 |
+
if (isset($input_css['font-family'])) {
|
879 |
+
$families = explode(",", $input_css['font-family']);
|
880 |
+
$result_families = array();
|
881 |
+
foreach ($families as $family) {
|
882 |
+
$family = trim($family);
|
883 |
+
$len = strlen($family);
|
884 |
+
if (strpos($family, " ") &&
|
885 |
+
!(($family{0} == '"' && $family{$len - 1} == '"') ||
|
886 |
+
($family{0} == "'" && $family{$len - 1} == "'"))) {
|
887 |
+
$family = '"' . $family . '"';
|
888 |
+
}
|
889 |
+
$result_families[] = $family;
|
890 |
+
}
|
891 |
+
$input_css['font-family'] = implode(",", $result_families);
|
892 |
+
}
|
893 |
+
foreach ($font_prop_default as $font_property => $default_value) {
|
894 |
+
|
895 |
+
// Skip if property does not exist
|
896 |
+
if (!isset($input_css[$font_property])) {
|
897 |
+
continue;
|
898 |
+
}
|
899 |
+
|
900 |
+
$cur_value = $input_css[$font_property];
|
901 |
+
|
902 |
+
// Skip if default value is used
|
903 |
+
if ($cur_value === $default_value) {
|
904 |
+
continue;
|
905 |
+
}
|
906 |
+
|
907 |
+
// Remove !important
|
908 |
+
if (csstidy::is_important($cur_value)) {
|
909 |
+
$important = '!important';
|
910 |
+
$cur_value = csstidy::gvw_important($cur_value);
|
911 |
+
}
|
912 |
+
|
913 |
+
$new_font_value .= $cur_value;
|
914 |
+
// Add delimiter
|
915 |
+
$new_font_value .= ( $font_property === 'font-size' &&
|
916 |
+
isset($input_css['line-height'])) ? '/' : ' ';
|
917 |
+
}
|
918 |
+
|
919 |
+
$new_font_value = trim($new_font_value);
|
920 |
+
|
921 |
+
// Delete all font-properties
|
922 |
+
foreach ($font_prop_default as $font_property => $default_value) {
|
923 |
+
if ($font_property!=='font' OR !$new_font_value)
|
924 |
+
unset($input_css[$font_property]);
|
925 |
+
}
|
926 |
+
|
927 |
+
// Add new font property
|
928 |
+
if ($new_font_value !== '') {
|
929 |
+
$input_css['font'] = $new_font_value . $important;
|
930 |
+
}
|
931 |
+
}
|
932 |
+
|
933 |
+
return $input_css;
|
934 |
+
}
|
935 |
+
|
936 |
+
}
|
classes/csstidy/class.csstidy_print.php
CHANGED
@@ -1,408 +1,408 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* CSSTidy - CSS Parser and Optimiser
|
5 |
-
*
|
6 |
-
* CSS Printing class
|
7 |
-
* This class prints CSS data generated by csstidy.
|
8 |
-
*
|
9 |
-
* Copyright 2005, 2006, 2007 Florian Schmitz
|
10 |
-
*
|
11 |
-
* This file is part of CSSTidy.
|
12 |
-
*
|
13 |
-
* CSSTidy is free software; you can redistribute it and/or modify
|
14 |
-
* it under the terms of the GNU Lesser General Public License as published by
|
15 |
-
* the Free Software Foundation; either version 2.1 of the License, or
|
16 |
-
* (at your option) any later version.
|
17 |
-
*
|
18 |
-
* CSSTidy is distributed in the hope that it will be useful,
|
19 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
20 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
21 |
-
* GNU Lesser General Public License for more details.
|
22 |
-
*
|
23 |
-
* You should have received a copy of the GNU Lesser General Public License
|
24 |
-
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
25 |
-
*
|
26 |
-
* @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
|
27 |
-
* @package csstidy
|
28 |
-
* @author Florian Schmitz (floele at gmail dot com) 2005-2007
|
29 |
-
* @author Brett Zamir (brettz9 at yahoo dot com) 2007
|
30 |
-
* @author Cedric Morin (cedric at yterium dot com) 2010
|
31 |
-
*/
|
32 |
-
|
33 |
-
/**
|
34 |
-
* CSS Printing class
|
35 |
-
*
|
36 |
-
* This class prints CSS data generated by csstidy.
|
37 |
-
*
|
38 |
-
* @package csstidy
|
39 |
-
* @author Florian Schmitz (floele at gmail dot com) 2005-2006
|
40 |
-
* @version 1.0.1
|
41 |
-
*/
|
42 |
-
class csstidy_print {
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Saves the input CSS string
|
46 |
-
* @var string
|
47 |
-
* @access private
|
48 |
-
*/
|
49 |
-
var $input_css = '';
|
50 |
-
/**
|
51 |
-
* Saves the formatted CSS string
|
52 |
-
* @var string
|
53 |
-
* @access public
|
54 |
-
*/
|
55 |
-
var $output_css = '';
|
56 |
-
/**
|
57 |
-
* Saves the formatted CSS string (plain text)
|
58 |
-
* @var string
|
59 |
-
* @access public
|
60 |
-
*/
|
61 |
-
var $output_css_plain = '';
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Constructor
|
65 |
-
* @param array $css contains the class csstidy
|
66 |
-
* @access private
|
67 |
-
* @version 1.0
|
68 |
-
*/
|
69 |
-
function csstidy_print(&$css) {
|
70 |
-
$this->parser = & $css;
|
71 |
-
$this->css = & $css->css;
|
72 |
-
$this->template = & $css->template;
|
73 |
-
$this->tokens = & $css->tokens;
|
74 |
-
$this->charset = & $css->charset;
|
75 |
-
$this->import = & $css->import;
|
76 |
-
$this->namespace = & $css->namespace;
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Resets output_css and output_css_plain (new css code)
|
81 |
-
* @access private
|
82 |
-
* @version 1.0
|
83 |
-
*/
|
84 |
-
function _reset() {
|
85 |
-
$this->output_css = '';
|
86 |
-
$this->output_css_plain = '';
|
87 |
-
}
|
88 |
-
|
89 |
-
/**
|
90 |
-
* Returns the CSS code as plain text
|
91 |
-
* @param string $default_media default @media to add to selectors without any @media
|
92 |
-
* @return string
|
93 |
-
* @access public
|
94 |
-
* @version 1.0
|
95 |
-
*/
|
96 |
-
function plain($default_media='') {
|
97 |
-
$this->_print(true, $default_media);
|
98 |
-
return $this->output_css_plain;
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* Returns the formatted CSS code
|
103 |
-
* @param string $default_media default @media to add to selectors without any @media
|
104 |
-
* @return string
|
105 |
-
* @access public
|
106 |
-
* @version 1.0
|
107 |
-
*/
|
108 |
-
function formatted($default_media='') {
|
109 |
-
$this->_print(false, $default_media);
|
110 |
-
return $this->output_css;
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Returns the formatted CSS code to make a complete webpage
|
115 |
-
* @param string $doctype shorthand for the document type
|
116 |
-
* @param bool $externalcss indicates whether styles to be attached internally or as an external stylesheet
|
117 |
-
* @param string $title title to be added in the head of the document
|
118 |
-
* @param string $lang two-letter language code to be added to the output
|
119 |
-
* @return string
|
120 |
-
* @access public
|
121 |
-
* @version 1.4
|
122 |
-
*/
|
123 |
-
function formatted_page($doctype='xhtml1.1', $externalcss=true, $title='', $lang='en') {
|
124 |
-
switch ($doctype) {
|
125 |
-
case 'xhtml1.0strict':
|
126 |
-
$doctype_output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
127 |
-
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
|
128 |
-
break;
|
129 |
-
case 'xhtml1.1':
|
130 |
-
default:
|
131 |
-
$doctype_output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
132 |
-
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
|
133 |
-
break;
|
134 |
-
}
|
135 |
-
|
136 |
-
$output = $cssparsed = '';
|
137 |
-
$this->output_css_plain = & $output;
|
138 |
-
|
139 |
-
$output .= $doctype_output . "\n" . '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="' . $lang . '"';
|
140 |
-
$output .= ( $doctype === 'xhtml1.1') ? '>' : ' lang="' . $lang . '">';
|
141 |
-
$output .= "\n<head>\n <title>$title</title>";
|
142 |
-
|
143 |
-
if ($externalcss) {
|
144 |
-
$output .= "\n <style type=\"text/css\">\n";
|
145 |
-
$cssparsed = file_get_contents('cssparsed.css');
|
146 |
-
$output .= $cssparsed; // Adds an invisible BOM or something, but not in css_optimised.php
|
147 |
-
$output .= "\n</style>";
|
148 |
-
} else {
|
149 |
-
$output .= "\n" . ' <link rel="stylesheet" type="text/css" href="cssparsed.css" />';
|
150 |
-
// }
|
151 |
-
}
|
152 |
-
$output .= "\n</head>\n<body><code id=\"copytext\">";
|
153 |
-
$output .= $this->formatted();
|
154 |
-
$output .= '</code>' . "\n" . '</body></html>';
|
155 |
-
return $this->output_css_plain;
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Returns the formatted CSS Code and saves it into $this->output_css and $this->output_css_plain
|
160 |
-
* @param bool $plain plain text or not
|
161 |
-
* @param string $default_media default @media to add to selectors without any @media
|
162 |
-
* @access private
|
163 |
-
* @version 2.0
|
164 |
-
*/
|
165 |
-
function _print($plain = false, $default_media='') {
|
166 |
-
if ($this->output_css && $this->output_css_plain) {
|
167 |
-
return;
|
168 |
-
}
|
169 |
-
|
170 |
-
$output = '';
|
171 |
-
if (!$this->parser->get_cfg('preserve_css')) {
|
172 |
-
$this->_convert_raw_css($default_media);
|
173 |
-
}
|
174 |
-
|
175 |
-
$template = & $this->template;
|
176 |
-
|
177 |
-
if ($plain) {
|
178 |
-
$template = array_map('strip_tags', $template);
|
179 |
-
}
|
180 |
-
|
181 |
-
if ($this->parser->get_cfg('timestamp')) {
|
182 |
-
array_unshift($this->tokens, array(COMMENT, ' CSSTidy ' . $this->parser->version . ': ' . date('r') . ' '));
|
183 |
-
}
|
184 |
-
|
185 |
-
if (!empty($this->charset)) {
|
186 |
-
$output .= $template[0] . '@charset ' . $template[5] . $this->charset . $template[6];
|
187 |
-
}
|
188 |
-
|
189 |
-
if (!empty($this->import)) {
|
190 |
-
for ($i = 0, $size = count($this->import); $i < $size; $i++) {
|
191 |
-
$import_components = explode(' ', $this->import[$i]);
|
192 |
-
if (substr($import_components[0], 0, 4) === 'url(' && substr($import_components[0], -1, 1) === ')') {
|
193 |
-
$import_components[0] = '\'' . trim(substr($import_components[0], 4, -1), "'\"") . '\'';
|
194 |
-
$this->import[$i] = implode(' ', $import_components);
|
195 |
-
$this->parser->log('Optimised @import : Removed "url("', 'Information');
|
196 |
-
}
|
197 |
-
$output .= $template[0] . '@import ' . $template[5] . $this->import[$i] . $template[6];
|
198 |
-
}
|
199 |
-
}
|
200 |
-
|
201 |
-
if (!empty($this->namespace)) {
|
202 |
-
if (substr($this->namespace, 0, 4) === 'url(' && substr($this->namespace, -1, 1) === ')') {
|
203 |
-
$this->namespace = '\'' . substr($this->namespace, 4, -1) . '\'';
|
204 |
-
$this->parser->log('Optimised @namespace : Removed "url("', 'Information');
|
205 |
-
}
|
206 |
-
$output .= $template[0] . '@namespace ' . $template[5] . $this->namespace . $template[6];
|
207 |
-
}
|
208 |
-
|
209 |
-
$output .= $template[13];
|
210 |
-
$in_at_out = '';
|
211 |
-
$out = & $output;
|
212 |
-
|
213 |
-
foreach ($this->tokens as $key => $token) {
|
214 |
-
switch ($token[0]) {
|
215 |
-
case AT_START:
|
216 |
-
$out .= $template[0] . $this->_htmlsp($token[1], $plain) . $template[1];
|
217 |
-
$out = & $in_at_out;
|
218 |
-
break;
|
219 |
-
|
220 |
-
case SEL_START:
|
221 |
-
if ($this->parser->get_cfg('lowercase_s'))
|
222 |
-
$token[1] = strtolower($token[1]);
|
223 |
-
$out .= ( $token[1]{0} !== '@') ? $template[2] . $this->_htmlsp($token[1], $plain) : $template[0] . $this->_htmlsp($token[1], $plain);
|
224 |
-
$out .= $template[3];
|
225 |
-
break;
|
226 |
-
|
227 |
-
case PROPERTY:
|
228 |
-
if ($this->parser->get_cfg('case_properties') === 2) {
|
229 |
-
$token[1] = strtoupper($token[1]);
|
230 |
-
} elseif ($this->parser->get_cfg('case_properties') === 1) {
|
231 |
-
$token[1] = strtolower($token[1]);
|
232 |
-
}
|
233 |
-
$out .= $template[4] . $this->_htmlsp($token[1], $plain) . ':' . $template[5];
|
234 |
-
break;
|
235 |
-
|
236 |
-
case VALUE:
|
237 |
-
$out .= $this->_htmlsp($token[1], $plain);
|
238 |
-
if ($this->_seeknocomment($key, 1) == SEL_END && $this->parser->get_cfg('remove_last_;')) {
|
239 |
-
$out .= str_replace(';', '', $template[6]);
|
240 |
-
} else {
|
241 |
-
$out .= $template[6];
|
242 |
-
}
|
243 |
-
break;
|
244 |
-
|
245 |
-
case SEL_END:
|
246 |
-
$out .= $template[7];
|
247 |
-
if ($this->_seeknocomment($key, 1) != AT_END)
|
248 |
-
$out .= $template[8];
|
249 |
-
break;
|
250 |
-
|
251 |
-
case AT_END:
|
252 |
-
$out = & $output;
|
253 |
-
$out .= $template[10] . str_replace("\n", "\n" . $template[10], $in_at_out);
|
254 |
-
$in_at_out = '';
|
255 |
-
$out .= $template[9];
|
256 |
-
break;
|
257 |
-
|
258 |
-
case COMMENT:
|
259 |
-
$out .= $template[11] . '/*' . $this->_htmlsp($token[1], $plain) . '*/' . $template[12];
|
260 |
-
break;
|
261 |
-
}
|
262 |
-
}
|
263 |
-
|
264 |
-
$output = trim($output);
|
265 |
-
|
266 |
-
if (!$plain) {
|
267 |
-
$this->output_css = $output;
|
268 |
-
$this->_print(true);
|
269 |
-
} else {
|
270 |
-
// If using spaces in the template, don't want these to appear in the plain output
|
271 |
-
$this->output_css_plain = str_replace(' ', '', $output);
|
272 |
-
}
|
273 |
-
}
|
274 |
-
|
275 |
-
/**
|
276 |
-
* Gets the next token type which is $move away from $key, excluding comments
|
277 |
-
* @param integer $key current position
|
278 |
-
* @param integer $move move this far
|
279 |
-
* @return mixed a token type
|
280 |
-
* @access private
|
281 |
-
* @version 1.0
|
282 |
-
*/
|
283 |
-
function _seeknocomment($key, $move) {
|
284 |
-
$go = ($move > 0) ? 1 : -1;
|
285 |
-
for ($i = $key + 1; abs($key - $i) - 1 < abs($move); $i += $go) {
|
286 |
-
if (!isset($this->tokens[$i])) {
|
287 |
-
return;
|
288 |
-
}
|
289 |
-
if ($this->tokens[$i][0] == COMMENT) {
|
290 |
-
$move += 1;
|
291 |
-
continue;
|
292 |
-
}
|
293 |
-
return $this->tokens[$i][0];
|
294 |
-
}
|
295 |
-
}
|
296 |
-
|
297 |
-
/**
|
298 |
-
* Converts $this->css array to a raw array ($this->tokens)
|
299 |
-
* @param string $default_media default @media to add to selectors without any @media
|
300 |
-
* @access private
|
301 |
-
* @version 1.0
|
302 |
-
*/
|
303 |
-
function _convert_raw_css($default_media='') {
|
304 |
-
$this->tokens = array();
|
305 |
-
|
306 |
-
foreach ($this->css as $medium => $val) {
|
307 |
-
if ($this->parser->get_cfg('sort_selectors'))
|
308 |
-
ksort($val);
|
309 |
-
if (intval($medium) < DEFAULT_AT) {
|
310 |
-
$this->parser->_add_token(AT_START, $medium, true);
|
311 |
-
}
|
312 |
-
elseif ($default_media) {
|
313 |
-
$this->parser->_add_token(AT_START, $default_media, true);
|
314 |
-
}
|
315 |
-
|
316 |
-
foreach ($val as $selector => $vali) {
|
317 |
-
if ($this->parser->get_cfg('sort_properties'))
|
318 |
-
ksort($vali);
|
319 |
-
$this->parser->_add_token(SEL_START, $selector, true);
|
320 |
-
|
321 |
-
foreach ($vali as $property => $valj) {
|
322 |
-
$this->parser->_add_token(PROPERTY, $property, true);
|
323 |
-
$this->parser->_add_token(VALUE, $valj, true);
|
324 |
-
}
|
325 |
-
|
326 |
-
$this->parser->_add_token(SEL_END, $selector, true);
|
327 |
-
}
|
328 |
-
|
329 |
-
if (intval($medium) < DEFAULT_AT) {
|
330 |
-
$this->parser->_add_token(AT_END, $medium, true);
|
331 |
-
}
|
332 |
-
elseif ($default_media) {
|
333 |
-
$this->parser->_add_token(AT_END, $default_media, true);
|
334 |
-
}
|
335 |
-
}
|
336 |
-
}
|
337 |
-
|
338 |
-
/**
|
339 |
-
* Same as htmlspecialchars, only that chars are not replaced if $plain !== true. This makes print_code() cleaner.
|
340 |
-
* @param string $string
|
341 |
-
* @param bool $plain
|
342 |
-
* @return string
|
343 |
-
* @see csstidy_print::_print()
|
344 |
-
* @access private
|
345 |
-
* @version 1.0
|
346 |
-
*/
|
347 |
-
function _htmlsp($string, $plain) {
|
348 |
-
if (!$plain) {
|
349 |
-
return htmlspecialchars($string, ENT_QUOTES, 'utf-8');
|
350 |
-
}
|
351 |
-
return $string;
|
352 |
-
}
|
353 |
-
|
354 |
-
/**
|
355 |
-
* Get compression ratio
|
356 |
-
* @access public
|
357 |
-
* @return float
|
358 |
-
* @version 1.2
|
359 |
-
*/
|
360 |
-
function get_ratio() {
|
361 |
-
if (!$this->output_css_plain) {
|
362 |
-
$this->formatted();
|
363 |
-
}
|
364 |
-
return round((strlen($this->input_css) - strlen($this->output_css_plain)) / strlen($this->input_css), 3) * 100;
|
365 |
-
}
|
366 |
-
|
367 |
-
/**
|
368 |
-
* Get difference between the old and new code in bytes and prints the code if necessary.
|
369 |
-
* @access public
|
370 |
-
* @return string
|
371 |
-
* @version 1.1
|
372 |
-
*/
|
373 |
-
function get_diff() {
|
374 |
-
if (!$this->output_css_plain) {
|
375 |
-
$this->formatted();
|
376 |
-
}
|
377 |
-
|
378 |
-
$diff = strlen($this->output_css_plain) - strlen($this->input_css);
|
379 |
-
|
380 |
-
if ($diff > 0) {
|
381 |
-
return '+' . $diff;
|
382 |
-
} elseif ($diff == 0) {
|
383 |
-
return '+-' . $diff;
|
384 |
-
}
|
385 |
-
|
386 |
-
return $diff;
|
387 |
-
}
|
388 |
-
|
389 |
-
/**
|
390 |
-
* Get the size of either input or output CSS in KB
|
391 |
-
* @param string $loc default is "output"
|
392 |
-
* @access public
|
393 |
-
* @return integer
|
394 |
-
* @version 1.0
|
395 |
-
*/
|
396 |
-
function size($loc = 'output') {
|
397 |
-
if ($loc === 'output' && !$this->output_css) {
|
398 |
-
$this->formatted();
|
399 |
-
}
|
400 |
-
|
401 |
-
if ($loc === 'input') {
|
402 |
-
return (strlen($this->input_css) / 1000);
|
403 |
-
} else {
|
404 |
-
return (strlen($this->output_css_plain) / 1000);
|
405 |
-
}
|
406 |
-
}
|
407 |
-
|
408 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* CSSTidy - CSS Parser and Optimiser
|
5 |
+
*
|
6 |
+
* CSS Printing class
|
7 |
+
* This class prints CSS data generated by csstidy.
|
8 |
+
*
|
9 |
+
* Copyright 2005, 2006, 2007 Florian Schmitz
|
10 |
+
*
|
11 |
+
* This file is part of CSSTidy.
|
12 |
+
*
|
13 |
+
* CSSTidy is free software; you can redistribute it and/or modify
|
14 |
+
* it under the terms of the GNU Lesser General Public License as published by
|
15 |
+
* the Free Software Foundation; either version 2.1 of the License, or
|
16 |
+
* (at your option) any later version.
|
17 |
+
*
|
18 |
+
* CSSTidy is distributed in the hope that it will be useful,
|
19 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
20 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
21 |
+
* GNU Lesser General Public License for more details.
|
22 |
+
*
|
23 |
+
* You should have received a copy of the GNU Lesser General Public License
|
24 |
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
25 |
+
*
|
26 |
+
* @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
|
27 |
+
* @package csstidy
|
28 |
+
* @author Florian Schmitz (floele at gmail dot com) 2005-2007
|
29 |
+
* @author Brett Zamir (brettz9 at yahoo dot com) 2007
|
30 |
+
* @author Cedric Morin (cedric at yterium dot com) 2010
|
31 |
+
*/
|
32 |
+
|
33 |
+
/**
|
34 |
+
* CSS Printing class
|
35 |
+
*
|
36 |
+
* This class prints CSS data generated by csstidy.
|
37 |
+
*
|
38 |
+
* @package csstidy
|
39 |
+
* @author Florian Schmitz (floele at gmail dot com) 2005-2006
|
40 |
+
* @version 1.0.1
|
41 |
+
*/
|
42 |
+
class csstidy_print {
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Saves the input CSS string
|
46 |
+
* @var string
|
47 |
+
* @access private
|
48 |
+
*/
|
49 |
+
var $input_css = '';
|
50 |
+
/**
|
51 |
+
* Saves the formatted CSS string
|
52 |
+
* @var string
|
53 |
+
* @access public
|
54 |
+
*/
|
55 |
+
var $output_css = '';
|
56 |
+
/**
|
57 |
+
* Saves the formatted CSS string (plain text)
|
58 |
+
* @var string
|
59 |
+
* @access public
|
60 |
+
*/
|
61 |
+
var $output_css_plain = '';
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Constructor
|
65 |
+
* @param array $css contains the class csstidy
|
66 |
+
* @access private
|
67 |
+
* @version 1.0
|
68 |
+
*/
|
69 |
+
function csstidy_print(&$css) {
|
70 |
+
$this->parser = & $css;
|
71 |
+
$this->css = & $css->css;
|
72 |
+
$this->template = & $css->template;
|
73 |
+
$this->tokens = & $css->tokens;
|
74 |
+
$this->charset = & $css->charset;
|
75 |
+
$this->import = & $css->import;
|
76 |
+
$this->namespace = & $css->namespace;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Resets output_css and output_css_plain (new css code)
|
81 |
+
* @access private
|
82 |
+
* @version 1.0
|
83 |
+
*/
|
84 |
+
function _reset() {
|
85 |
+
$this->output_css = '';
|
86 |
+
$this->output_css_plain = '';
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Returns the CSS code as plain text
|
91 |
+
* @param string $default_media default @media to add to selectors without any @media
|
92 |
+
* @return string
|
93 |
+
* @access public
|
94 |
+
* @version 1.0
|
95 |
+
*/
|
96 |
+
function plain($default_media='') {
|
97 |
+
$this->_print(true, $default_media);
|
98 |
+
return $this->output_css_plain;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Returns the formatted CSS code
|
103 |
+
* @param string $default_media default @media to add to selectors without any @media
|
104 |
+
* @return string
|
105 |
+
* @access public
|
106 |
+
* @version 1.0
|
107 |
+
*/
|
108 |
+
function formatted($default_media='') {
|
109 |
+
$this->_print(false, $default_media);
|
110 |
+
return $this->output_css;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Returns the formatted CSS code to make a complete webpage
|
115 |
+
* @param string $doctype shorthand for the document type
|
116 |
+
* @param bool $externalcss indicates whether styles to be attached internally or as an external stylesheet
|
117 |
+
* @param string $title title to be added in the head of the document
|
118 |
+
* @param string $lang two-letter language code to be added to the output
|
119 |
+
* @return string
|
120 |
+
* @access public
|
121 |
+
* @version 1.4
|
122 |
+
*/
|
123 |
+
function formatted_page($doctype='xhtml1.1', $externalcss=true, $title='', $lang='en') {
|
124 |
+
switch ($doctype) {
|
125 |
+
case 'xhtml1.0strict':
|
126 |
+
$doctype_output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
127 |
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
|
128 |
+
break;
|
129 |
+
case 'xhtml1.1':
|
130 |
+
default:
|
131 |
+
$doctype_output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
132 |
+
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
|
133 |
+
break;
|
134 |
+
}
|
135 |
+
|
136 |
+
$output = $cssparsed = '';
|
137 |
+
$this->output_css_plain = & $output;
|
138 |
+
|
139 |
+
$output .= $doctype_output . "\n" . '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="' . $lang . '"';
|
140 |
+
$output .= ( $doctype === 'xhtml1.1') ? '>' : ' lang="' . $lang . '">';
|
141 |
+
$output .= "\n<head>\n <title>$title</title>";
|
142 |
+
|
143 |
+
if ($externalcss) {
|
144 |
+
$output .= "\n <style type=\"text/css\">\n";
|
145 |
+
$cssparsed = file_get_contents('cssparsed.css');
|
146 |
+
$output .= $cssparsed; // Adds an invisible BOM or something, but not in css_optimised.php
|
147 |
+
$output .= "\n</style>";
|
148 |
+
} else {
|
149 |
+
$output .= "\n" . ' <link rel="stylesheet" type="text/css" href="cssparsed.css" />';
|
150 |
+
// }
|
151 |
+
}
|
152 |
+
$output .= "\n</head>\n<body><code id=\"copytext\">";
|
153 |
+
$output .= $this->formatted();
|
154 |
+
$output .= '</code>' . "\n" . '</body></html>';
|
155 |
+
return $this->output_css_plain;
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Returns the formatted CSS Code and saves it into $this->output_css and $this->output_css_plain
|
160 |
+
* @param bool $plain plain text or not
|
161 |
+
* @param string $default_media default @media to add to selectors without any @media
|
162 |
+
* @access private
|
163 |
+
* @version 2.0
|
164 |
+
*/
|
165 |
+
function _print($plain = false, $default_media='') {
|
166 |
+
if ($this->output_css && $this->output_css_plain) {
|
167 |
+
return;
|
168 |
+
}
|
169 |
+
|
170 |
+
$output = '';
|
171 |
+
if (!$this->parser->get_cfg('preserve_css')) {
|
172 |
+
$this->_convert_raw_css($default_media);
|
173 |
+
}
|
174 |
+
|
175 |
+
$template = & $this->template;
|
176 |
+
|
177 |
+
if ($plain) {
|
178 |
+
$template = array_map('strip_tags', $template);
|
179 |
+
}
|
180 |
+
|
181 |
+
if ($this->parser->get_cfg('timestamp')) {
|
182 |
+
array_unshift($this->tokens, array(COMMENT, ' CSSTidy ' . $this->parser->version . ': ' . date('r') . ' '));
|
183 |
+
}
|
184 |
+
|
185 |
+
if (!empty($this->charset)) {
|
186 |
+
$output .= $template[0] . '@charset ' . $template[5] . $this->charset . $template[6];
|
187 |
+
}
|
188 |
+
|
189 |
+
if (!empty($this->import)) {
|
190 |
+
for ($i = 0, $size = count($this->import); $i < $size; $i++) {
|
191 |
+
$import_components = explode(' ', $this->import[$i]);
|
192 |
+
if (substr($import_components[0], 0, 4) === 'url(' && substr($import_components[0], -1, 1) === ')') {
|
193 |
+
$import_components[0] = '\'' . trim(substr($import_components[0], 4, -1), "'\"") . '\'';
|
194 |
+
$this->import[$i] = implode(' ', $import_components);
|
195 |
+
$this->parser->log('Optimised @import : Removed "url("', 'Information');
|
196 |
+
}
|
197 |
+
$output .= $template[0] . '@import ' . $template[5] . $this->import[$i] . $template[6];
|
198 |
+
}
|
199 |
+
}
|
200 |
+
|
201 |
+
if (!empty($this->namespace)) {
|
202 |
+
if (substr($this->namespace, 0, 4) === 'url(' && substr($this->namespace, -1, 1) === ')') {
|
203 |
+
$this->namespace = '\'' . substr($this->namespace, 4, -1) . '\'';
|
204 |
+
$this->parser->log('Optimised @namespace : Removed "url("', 'Information');
|
205 |
+
}
|
206 |
+
$output .= $template[0] . '@namespace ' . $template[5] . $this->namespace . $template[6];
|
207 |
+
}
|
208 |
+
|
209 |
+
$output .= $template[13];
|
210 |
+
$in_at_out = '';
|
211 |
+
$out = & $output;
|
212 |
+
|
213 |
+
foreach ($this->tokens as $key => $token) {
|
214 |
+
switch ($token[0]) {
|
215 |
+
case AT_START:
|
216 |
+
$out .= $template[0] . $this->_htmlsp($token[1], $plain) . $template[1];
|
217 |
+
$out = & $in_at_out;
|
218 |
+
break;
|
219 |
+
|
220 |
+
case SEL_START:
|
221 |
+
if ($this->parser->get_cfg('lowercase_s'))
|
222 |
+
$token[1] = strtolower($token[1]);
|
223 |
+
$out .= ( $token[1]{0} !== '@') ? $template[2] . $this->_htmlsp($token[1], $plain) : $template[0] . $this->_htmlsp($token[1], $plain);
|
224 |
+
$out .= $template[3];
|
225 |
+
break;
|
226 |
+
|
227 |
+
case PROPERTY:
|
228 |
+
if ($this->parser->get_cfg('case_properties') === 2) {
|
229 |
+
$token[1] = strtoupper($token[1]);
|
230 |
+
} elseif ($this->parser->get_cfg('case_properties') === 1) {
|
231 |
+
$token[1] = strtolower($token[1]);
|
232 |
+
}
|
233 |
+
$out .= $template[4] . $this->_htmlsp($token[1], $plain) . ':' . $template[5];
|
234 |
+
break;
|
235 |
+
|
236 |
+
case VALUE:
|
237 |
+
$out .= $this->_htmlsp($token[1], $plain);
|
238 |
+
if ($this->_seeknocomment($key, 1) == SEL_END && $this->parser->get_cfg('remove_last_;')) {
|
239 |
+
$out .= str_replace(';', '', $template[6]);
|
240 |
+
} else {
|
241 |
+
$out .= $template[6];
|
242 |
+
}
|
243 |
+
break;
|
244 |
+
|
245 |
+
case SEL_END:
|
246 |
+
$out .= $template[7];
|
247 |
+
if ($this->_seeknocomment($key, 1) != AT_END)
|
248 |
+
$out .= $template[8];
|
249 |
+
break;
|
250 |
+
|
251 |
+
case AT_END:
|
252 |
+
$out = & $output;
|
253 |
+
$out .= $template[10] . str_replace("\n", "\n" . $template[10], $in_at_out);
|
254 |
+
$in_at_out = '';
|
255 |
+
$out .= $template[9];
|
256 |
+
break;
|
257 |
+
|
258 |
+
case COMMENT:
|
259 |
+
$out .= $template[11] . '/*' . $this->_htmlsp($token[1], $plain) . '*/' . $template[12];
|
260 |
+
break;
|
261 |
+
}
|
262 |
+
}
|
263 |
+
|
264 |
+
$output = trim($output);
|
265 |
+
|
266 |
+
if (!$plain) {
|
267 |
+
$this->output_css = $output;
|
268 |
+
$this->_print(true);
|
269 |
+
} else {
|
270 |
+
// If using spaces in the template, don't want these to appear in the plain output
|
271 |
+
$this->output_css_plain = str_replace(' ', '', $output);
|
272 |
+
}
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* Gets the next token type which is $move away from $key, excluding comments
|
277 |
+
* @param integer $key current position
|
278 |
+
* @param integer $move move this far
|
279 |
+
* @return mixed a token type
|
280 |
+
* @access private
|
281 |
+
* @version 1.0
|
282 |
+
*/
|
283 |
+
function _seeknocomment($key, $move) {
|
284 |
+
$go = ($move > 0) ? 1 : -1;
|
285 |
+
for ($i = $key + 1; abs($key - $i) - 1 < abs($move); $i += $go) {
|
286 |
+
if (!isset($this->tokens[$i])) {
|
287 |
+
return;
|
288 |
+
}
|
289 |
+
if ($this->tokens[$i][0] == COMMENT) {
|
290 |
+
$move += 1;
|
291 |
+
continue;
|
292 |
+
}
|
293 |
+
return $this->tokens[$i][0];
|
294 |
+
}
|
295 |
+
}
|
296 |
+
|
297 |
+
/**
|
298 |
+
* Converts $this->css array to a raw array ($this->tokens)
|
299 |
+
* @param string $default_media default @media to add to selectors without any @media
|
300 |
+
* @access private
|
301 |
+
* @version 1.0
|
302 |
+
*/
|
303 |
+
function _convert_raw_css($default_media='') {
|
304 |
+
$this->tokens = array();
|
305 |
+
|
306 |
+
foreach ($this->css as $medium => $val) {
|
307 |
+
if ($this->parser->get_cfg('sort_selectors'))
|
308 |
+
ksort($val);
|
309 |
+
if (intval($medium) < DEFAULT_AT) {
|
310 |
+
$this->parser->_add_token(AT_START, $medium, true);
|
311 |
+
}
|
312 |
+
elseif ($default_media) {
|
313 |
+
$this->parser->_add_token(AT_START, $default_media, true);
|
314 |
+
}
|
315 |
+
|
316 |
+
foreach ($val as $selector => $vali) {
|
317 |
+
if ($this->parser->get_cfg('sort_properties'))
|
318 |
+
ksort($vali);
|
319 |
+
$this->parser->_add_token(SEL_START, $selector, true);
|
320 |
+
|
321 |
+
foreach ($vali as $property => $valj) {
|
322 |
+
$this->parser->_add_token(PROPERTY, $property, true);
|
323 |
+
$this->parser->_add_token(VALUE, $valj, true);
|
324 |
+
}
|
325 |
+
|
326 |
+
$this->parser->_add_token(SEL_END, $selector, true);
|
327 |
+
}
|
328 |
+
|
329 |
+
if (intval($medium) < DEFAULT_AT) {
|
330 |
+
$this->parser->_add_token(AT_END, $medium, true);
|
331 |
+
}
|
332 |
+
elseif ($default_media) {
|
333 |
+
$this->parser->_add_token(AT_END, $default_media, true);
|
334 |
+
}
|
335 |
+
}
|
336 |
+
}
|
337 |
+
|
338 |
+
/**
|
339 |
+
* Same as htmlspecialchars, only that chars are not replaced if $plain !== true. This makes print_code() cleaner.
|
340 |
+
* @param string $string
|
341 |
+
* @param bool $plain
|
342 |
+
* @return string
|
343 |
+
* @see csstidy_print::_print()
|
344 |
+
* @access private
|
345 |
+
* @version 1.0
|
346 |
+
*/
|
347 |
+
function _htmlsp($string, $plain) {
|
348 |
+
if (!$plain) {
|
349 |
+
return htmlspecialchars($string, ENT_QUOTES, 'utf-8');
|
350 |
+
}
|
351 |
+
return $string;
|
352 |
+
}
|
353 |
+
|
354 |
+
/**
|
355 |
+
* Get compression ratio
|
356 |
+
* @access public
|
357 |
+
* @return float
|
358 |
+
* @version 1.2
|
359 |
+
*/
|
360 |
+
function get_ratio() {
|
361 |
+
if (!$this->output_css_plain) {
|
362 |
+
$this->formatted();
|
363 |
+
}
|
364 |
+
return round((strlen($this->input_css) - strlen($this->output_css_plain)) / strlen($this->input_css), 3) * 100;
|
365 |
+
}
|
366 |
+
|
367 |
+
/**
|
368 |
+
* Get difference between the old and new code in bytes and prints the code if necessary.
|
369 |
+
* @access public
|
370 |
+
* @return string
|
371 |
+
* @version 1.1
|
372 |
+
*/
|
373 |
+
function get_diff() {
|
374 |
+
if (!$this->output_css_plain) {
|
375 |
+
$this->formatted();
|
376 |
+
}
|
377 |
+
|
378 |
+
$diff = strlen($this->output_css_plain) - strlen($this->input_css);
|
379 |
+
|
380 |
+
if ($diff > 0) {
|
381 |
+
return '+' . $diff;
|
382 |
+
} elseif ($diff == 0) {
|
383 |
+
return '+-' . $diff;
|
384 |
+
}
|
385 |
+
|
386 |
+
return $diff;
|
387 |
+
}
|
388 |
+
|
389 |
+
/**
|
390 |
+
* Get the size of either input or output CSS in KB
|
391 |
+
* @param string $loc default is "output"
|
392 |
+
* @access public
|
393 |
+
* @return integer
|
394 |
+
* @version 1.0
|
395 |
+
*/
|
396 |
+
function size($loc = 'output') {
|
397 |
+
if ($loc === 'output' && !$this->output_css) {
|
398 |
+
$this->formatted();
|
399 |
+
}
|
400 |
+
|
401 |
+
if ($loc === 'input') {
|
402 |
+
return (strlen($this->input_css) / 1000);
|
403 |
+
} else {
|
404 |
+
return (strlen($this->output_css_plain) / 1000);
|
405 |
+
}
|
406 |
+
}
|
407 |
+
|
408 |
+
}
|
classes/csstidy/cssparse.css
CHANGED
@@ -1,118 +1,118 @@
|
|
1 |
-
@import url("cssparsed.css");
|
2 |
-
|
3 |
-
html, body {
|
4 |
-
font:0.8em Verdana,Helvetica,sans-serif;
|
5 |
-
background:#F8F8F6;
|
6 |
-
}
|
7 |
-
|
8 |
-
code {
|
9 |
-
font-size:1.2em;
|
10 |
-
}
|
11 |
-
|
12 |
-
div#rightcol {
|
13 |
-
padding-left:32em;
|
14 |
-
}
|
15 |
-
|
16 |
-
fieldset {
|
17 |
-
display:block;
|
18 |
-
margin:0.5em 0;
|
19 |
-
padding:1em;
|
20 |
-
border:solid #7284AB 2px;
|
21 |
-
}
|
22 |
-
fieldset.code_output {
|
23 |
-
display:inline;
|
24 |
-
}
|
25 |
-
|
26 |
-
h1 {
|
27 |
-
font-size:2em;
|
28 |
-
}
|
29 |
-
|
30 |
-
small {
|
31 |
-
font-size:0.7em;
|
32 |
-
}
|
33 |
-
|
34 |
-
fieldset#field_input {
|
35 |
-
float:left;
|
36 |
-
margin:0 0.5em 1em 0;
|
37 |
-
}
|
38 |
-
|
39 |
-
fieldset#options,fieldset#code_layout {
|
40 |
-
width:31em;
|
41 |
-
}
|
42 |
-
|
43 |
-
input#submit {
|
44 |
-
clear:both;
|
45 |
-
display:block;
|
46 |
-
margin:1em;
|
47 |
-
}
|
48 |
-
|
49 |
-
select {
|
50 |
-
margin:2px 0 0;
|
51 |
-
}
|
52 |
-
|
53 |
-
label.block {
|
54 |
-
display:block;
|
55 |
-
}
|
56 |
-
|
57 |
-
legend {
|
58 |
-
background:#c4E1C3;
|
59 |
-
padding:2px 4px;
|
60 |
-
border:dashed 1px;
|
61 |
-
}
|
62 |
-
|
63 |
-
textarea#css_text {
|
64 |
-
width:27em;
|
65 |
-
height:370px;
|
66 |
-
display:block;
|
67 |
-
margin-right:1em;
|
68 |
-
}
|
69 |
-
|
70 |
-
.help {
|
71 |
-
cursor:help;
|
72 |
-
}
|
73 |
-
|
74 |
-
p.important {
|
75 |
-
border:solid 1px red;
|
76 |
-
font-weight:bold;
|
77 |
-
padding:1em;
|
78 |
-
background:white;
|
79 |
-
}
|
80 |
-
|
81 |
-
p {
|
82 |
-
margin:1em 0;
|
83 |
-
}
|
84 |
-
|
85 |
-
dl {
|
86 |
-
padding-left:0.5em;
|
87 |
-
}
|
88 |
-
|
89 |
-
dt {
|
90 |
-
font-weight:bold;
|
91 |
-
margin:0;
|
92 |
-
float:left;
|
93 |
-
clear:both;
|
94 |
-
height:1.5em;
|
95 |
-
}
|
96 |
-
|
97 |
-
dd {
|
98 |
-
margin:0 0 0 4em;
|
99 |
-
height:1.5em;
|
100 |
-
}
|
101 |
-
|
102 |
-
fieldset#messages {
|
103 |
-
background:white;
|
104 |
-
padding:0 0 0 1em;
|
105 |
-
}
|
106 |
-
|
107 |
-
fieldset#messages div {
|
108 |
-
height:10em;
|
109 |
-
overflow:auto;
|
110 |
-
}
|
111 |
-
|
112 |
-
dd.Warning {
|
113 |
-
color:orange;
|
114 |
-
}
|
115 |
-
|
116 |
-
dd.Information {
|
117 |
-
color:green;
|
118 |
}
|
1 |
+
@import url("cssparsed.css");
|
2 |
+
|
3 |
+
html, body {
|
4 |
+
font:0.8em Verdana,Helvetica,sans-serif;
|
5 |
+
background:#F8F8F6;
|
6 |
+
}
|
7 |
+
|
8 |
+
code {
|
9 |
+
font-size:1.2em;
|
10 |
+
}
|
11 |
+
|
12 |
+
div#rightcol {
|
13 |
+
padding-left:32em;
|
14 |
+
}
|
15 |
+
|
16 |
+
fieldset {
|
17 |
+
display:block;
|
18 |
+
margin:0.5em 0;
|
19 |
+
padding:1em;
|
20 |
+
border:solid #7284AB 2px;
|
21 |
+
}
|
22 |
+
fieldset.code_output {
|
23 |
+
display:inline;
|
24 |
+
}
|
25 |
+
|
26 |
+
h1 {
|
27 |
+
font-size:2em;
|
28 |
+
}
|
29 |
+
|
30 |
+
small {
|
31 |
+
font-size:0.7em;
|
32 |
+
}
|
33 |
+
|
34 |
+
fieldset#field_input {
|
35 |
+
float:left;
|
36 |
+
margin:0 0.5em 1em 0;
|
37 |
+
}
|
38 |
+
|
39 |
+
fieldset#options,fieldset#code_layout {
|
40 |
+
width:31em;
|
41 |
+
}
|
42 |
+
|
43 |
+
input#submit {
|
44 |
+
clear:both;
|
45 |
+
display:block;
|
46 |
+
margin:1em;
|
47 |
+
}
|
48 |
+
|
49 |
+
select {
|
50 |
+
margin:2px 0 0;
|
51 |
+
}
|
52 |
+
|
53 |
+
label.block {
|
54 |
+
display:block;
|
55 |
+
}
|
56 |
+
|
57 |
+
legend {
|
58 |
+
background:#c4E1C3;
|
59 |
+
padding:2px 4px;
|
60 |
+
border:dashed 1px;
|
61 |
+
}
|
62 |
+
|
63 |
+
textarea#css_text {
|
64 |
+
width:27em;
|
65 |
+
height:370px;
|
66 |
+
display:block;
|
67 |
+
margin-right:1em;
|
68 |
+
}
|
69 |
+
|
70 |
+
.help {
|
71 |
+
cursor:help;
|
72 |
+
}
|
73 |
+
|
74 |
+
p.important {
|
75 |
+
border:solid 1px red;
|
76 |
+
font-weight:bold;
|
77 |
+
padding:1em;
|
78 |
+
background:white;
|
79 |
+
}
|
80 |
+
|
81 |
+
p {
|
82 |
+
margin:1em 0;
|
83 |
+
}
|
84 |
+
|
85 |
+
dl {
|
86 |
+
padding-left:0.5em;
|
87 |
+
}
|
88 |
+
|
89 |
+
dt {
|
90 |
+
font-weight:bold;
|
91 |
+
margin:0;
|
92 |
+
float:left;
|
93 |
+
clear:both;
|
94 |
+
height:1.5em;
|
95 |
+
}
|
96 |
+
|
97 |
+
dd {
|
98 |
+
margin:0 0 0 4em;
|
99 |
+
height:1.5em;
|
100 |
+
}
|
101 |
+
|
102 |
+
fieldset#messages {
|
103 |
+
background:white;
|
104 |
+
padding:0 0 0 1em;
|
105 |
+
}
|
106 |
+
|
107 |
+
fieldset#messages div {
|
108 |
+
height:10em;
|
109 |
+
overflow:auto;
|
110 |
+
}
|
111 |
+
|
112 |
+
dd.Warning {
|
113 |
+
color:orange;
|
114 |
+
}
|
115 |
+
|
116 |
+
dd.Information {
|
117 |
+
color:green;
|
118 |
}
|
classes/csstidy/cssparsed.css
CHANGED
@@ -1,29 +1,29 @@
|
|
1 |
-
code#copytext {
|
2 |
-
white-space: pre;
|
3 |
-
font-family: Verdana;
|
4 |
-
}
|
5 |
-
|
6 |
-
.at {
|
7 |
-
color:darkblue;
|
8 |
-
}
|
9 |
-
|
10 |
-
.format {
|
11 |
-
color:gray;
|
12 |
-
}
|
13 |
-
|
14 |
-
.property {
|
15 |
-
color:green;
|
16 |
-
}
|
17 |
-
|
18 |
-
.selector {
|
19 |
-
color:blue;
|
20 |
-
}
|
21 |
-
|
22 |
-
.value {
|
23 |
-
color:red;
|
24 |
-
left: 500px;
|
25 |
-
}
|
26 |
-
|
27 |
-
.comment {
|
28 |
-
color:orange;
|
29 |
}
|
1 |
+
code#copytext {
|
2 |
+
white-space: pre;
|
3 |
+
font-family: Verdana;
|
4 |
+
}
|
5 |
+
|
6 |
+
.at {
|
7 |
+
color:darkblue;
|
8 |
+
}
|
9 |
+
|
10 |
+
.format {
|
11 |
+
color:gray;
|
12 |
+
}
|
13 |
+
|
14 |
+
.property {
|
15 |
+
color:green;
|
16 |
+
}
|
17 |
+
|
18 |
+
.selector {
|
19 |
+
color:blue;
|
20 |
+
}
|
21 |
+
|
22 |
+
.value {
|
23 |
+
color:red;
|
24 |
+
left: 500px;
|
25 |
+
}
|
26 |
+
|
27 |
+
.comment {
|
28 |
+
color:orange;
|
29 |
}
|
classes/csstidy/data-wp.inc.php
CHANGED
@@ -1,75 +1,75 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
unset( $GLOBALS['csstidy']['all_properties']['binding'] );
|
4 |
-
|
5 |
-
$GLOBALS['csstidy']['all_properties']['text-size-adjust'] = 'CSS3.0';
|
6 |
-
|
7 |
-
// Support browser prefixes for properties only in the latest CSS draft
|
8 |
-
foreach ( $GLOBALS['csstidy']['all_properties'] as $property => $levels ) {
|
9 |
-
if ( strpos( $levels, "," ) === false ) {
|
10 |
-
$GLOBALS['csstidy']['all_properties']['-moz-' . $property] = $levels;
|
11 |
-
$GLOBALS['csstidy']['all_properties']['-webkit-' . $property] = $levels;
|
12 |
-
$GLOBALS['csstidy']['all_properties']['-ms-' . $property] = $levels;
|
13 |
-
$GLOBALS['csstidy']['all_properties']['-o-' . $property] = $levels;
|
14 |
-
$GLOBALS['csstidy']['all_properties']['-khtml-' . $property] = $levels;
|
15 |
-
|
16 |
-
if ( in_array( $property, $GLOBALS['csstidy']['unit_values'] ) ) {
|
17 |
-
$GLOBALS['csstidy']['unit_values'][] = '-moz-' . $property;
|
18 |
-
$GLOBALS['csstidy']['unit_values'][] = '-webkit-' . $property;
|
19 |
-
$GLOBALS['csstidy']['unit_values'][] = '-ms-' . $property;
|
20 |
-
$GLOBALS['csstidy']['unit_values'][] = '-o-' . $property;
|
21 |
-
$GLOBALS['csstidy']['unit_values'][] = '-khtml-' . $property;
|
22 |
-
}
|
23 |
-
|
24 |
-
if ( in_array( $property, $GLOBALS['csstidy']['color_values'] ) ) {
|
25 |
-
$GLOBALS['csstidy']['color_values'][] = '-moz-' . $property;
|
26 |
-
$GLOBALS['csstidy']['color_values'][] = '-webkit-' . $property;
|
27 |
-
$GLOBALS['csstidy']['color_values'][] = '-ms-' . $property;
|
28 |
-
$GLOBALS['csstidy']['color_values'][] = '-o-' . $property;
|
29 |
-
$GLOBALS['csstidy']['color_values'][] = '-khtml-' . $property;
|
30 |
-
}
|
31 |
-
}
|
32 |
-
}
|
33 |
-
|
34 |
-
foreach ( $GLOBALS['csstidy']['multiple_properties'] as $property ) {
|
35 |
-
if ( '-' != $property[0] ) {
|
36 |
-
$GLOBALS['csstidy']['multiple_properties'][] = '-o-' . $property;
|
37 |
-
$GLOBALS['csstidy']['multiple_properties'][] = '-ms-' . $property;
|
38 |
-
$GLOBALS['csstidy']['multiple_properties'][] = '-webkit-' . $property;
|
39 |
-
$GLOBALS['csstidy']['multiple_properties'][] = '-moz-' . $property;
|
40 |
-
$GLOBALS['csstidy']['multiple_properties'][] = '-khtml-' . $property;
|
41 |
-
}
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* CSS Animation
|
46 |
-
*
|
47 |
-
* @see https://developer.mozilla.org/en/CSS/CSS_animations
|
48 |
-
*/
|
49 |
-
$GLOBALS['csstidy']['at_rules']['-webkit-keyframes'] = 'at';
|
50 |
-
$GLOBALS['csstidy']['at_rules']['-moz-keyframes'] = 'at';
|
51 |
-
$GLOBALS['csstidy']['at_rules']['-ms-keyframes'] = 'at';
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Non-standard CSS properties. They're not part of any spec, but we say
|
55 |
-
* they're in all of them so that we can support them.
|
56 |
-
*/
|
57 |
-
$GLOBALS['csstidy']['all_properties']['-webkit-filter'] = 'CSS2.0,CSS2.1,CSS3.0';
|
58 |
-
$GLOBALS['csstidy']['all_properties']['-moz-filter'] = 'CSS2.0,CSS2.1,CSS3.0';
|
59 |
-
$GLOBALS['csstidy']['all_properties']['-ms-filter'] = 'CSS2.0,CSS2.1,CSS3.0';
|
60 |
-
$GLOBALS['csstidy']['all_properties']['filter'] = 'CSS2.0,CSS2.1,CSS3.0';
|
61 |
-
$GLOBALS['csstidy']['all_properties']['scrollbar-face-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
62 |
-
$GLOBALS['csstidy']['all_properties']['-ms-interpolation-mode'] = 'CSS2.0,CSS2.1,CSS3.0';
|
63 |
-
$GLOBALS['csstidy']['all_properties']['text-rendering'] = 'CSS2.0,CSS2.1,CSS3.0';
|
64 |
-
$GLOBALS['csstidy']['all_properties']['-webkit-transform-origin-x'] = 'CSS3.0';
|
65 |
-
$GLOBALS['csstidy']['all_properties']['-webkit-transform-origin-y'] = 'CSS3.0';
|
66 |
-
$GLOBALS['csstidy']['all_properties']['-webkit-transform-origin-z'] = 'CSS3.0';
|
67 |
-
$GLOBALS['csstidy']['all_properties']['-webkit-font-smoothing'] = 'CSS3.0';
|
68 |
-
$GLOBALS['csstidy']['all_properties']['-font-smooth'] = 'CSS3.0';
|
69 |
-
$GLOBALS['csstidy']['all_properties']['-o-object-fit'] = 'CSS3.0';
|
70 |
-
$GLOBALS['csstidy']['all_properties']['object-fit'] = 'CSS3.0';
|
71 |
-
$GLOBALS['csstidy']['all_properties']['-o-object-position'] = 'CSS3.0';
|
72 |
-
$GLOBALS['csstidy']['all_properties']['object-position'] = 'CSS3.0';
|
73 |
-
$GLOBALS['csstidy']['all_properties']['text-overflow'] = 'CSS3.0';
|
74 |
-
$GLOBALS['csstidy']['all_properties']['zoom'] = 'CSS3.0';
|
75 |
-
|
1 |
+
<?php
|
2 |
+
|
3 |
+
unset( $GLOBALS['csstidy']['all_properties']['binding'] );
|
4 |
+
|
5 |
+
$GLOBALS['csstidy']['all_properties']['text-size-adjust'] = 'CSS3.0';
|
6 |
+
|
7 |
+
// Support browser prefixes for properties only in the latest CSS draft
|
8 |
+
foreach ( $GLOBALS['csstidy']['all_properties'] as $property => $levels ) {
|
9 |
+
if ( strpos( $levels, "," ) === false ) {
|
10 |
+
$GLOBALS['csstidy']['all_properties']['-moz-' . $property] = $levels;
|
11 |
+
$GLOBALS['csstidy']['all_properties']['-webkit-' . $property] = $levels;
|
12 |
+
$GLOBALS['csstidy']['all_properties']['-ms-' . $property] = $levels;
|
13 |
+
$GLOBALS['csstidy']['all_properties']['-o-' . $property] = $levels;
|
14 |
+
$GLOBALS['csstidy']['all_properties']['-khtml-' . $property] = $levels;
|
15 |
+
|
16 |
+
if ( in_array( $property, $GLOBALS['csstidy']['unit_values'] ) ) {
|
17 |
+
$GLOBALS['csstidy']['unit_values'][] = '-moz-' . $property;
|
18 |
+
$GLOBALS['csstidy']['unit_values'][] = '-webkit-' . $property;
|
19 |
+
$GLOBALS['csstidy']['unit_values'][] = '-ms-' . $property;
|
20 |
+
$GLOBALS['csstidy']['unit_values'][] = '-o-' . $property;
|
21 |
+
$GLOBALS['csstidy']['unit_values'][] = '-khtml-' . $property;
|
22 |
+
}
|
23 |
+
|
24 |
+
if ( in_array( $property, $GLOBALS['csstidy']['color_values'] ) ) {
|
25 |
+
$GLOBALS['csstidy']['color_values'][] = '-moz-' . $property;
|
26 |
+
$GLOBALS['csstidy']['color_values'][] = '-webkit-' . $property;
|
27 |
+
$GLOBALS['csstidy']['color_values'][] = '-ms-' . $property;
|
28 |
+
$GLOBALS['csstidy']['color_values'][] = '-o-' . $property;
|
29 |
+
$GLOBALS['csstidy']['color_values'][] = '-khtml-' . $property;
|
30 |
+
}
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
foreach ( $GLOBALS['csstidy']['multiple_properties'] as $property ) {
|
35 |
+
if ( '-' != $property[0] ) {
|
36 |
+
$GLOBALS['csstidy']['multiple_properties'][] = '-o-' . $property;
|
37 |
+
$GLOBALS['csstidy']['multiple_properties'][] = '-ms-' . $property;
|
38 |
+
$GLOBALS['csstidy']['multiple_properties'][] = '-webkit-' . $property;
|
39 |
+
$GLOBALS['csstidy']['multiple_properties'][] = '-moz-' . $property;
|
40 |
+
$GLOBALS['csstidy']['multiple_properties'][] = '-khtml-' . $property;
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* CSS Animation
|
46 |
+
*
|
47 |
+
* @see https://developer.mozilla.org/en/CSS/CSS_animations
|
48 |
+
*/
|
49 |
+
$GLOBALS['csstidy']['at_rules']['-webkit-keyframes'] = 'at';
|
50 |
+
$GLOBALS['csstidy']['at_rules']['-moz-keyframes'] = 'at';
|
51 |
+
$GLOBALS['csstidy']['at_rules']['-ms-keyframes'] = 'at';
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Non-standard CSS properties. They're not part of any spec, but we say
|
55 |
+
* they're in all of them so that we can support them.
|
56 |
+
*/
|
57 |
+
$GLOBALS['csstidy']['all_properties']['-webkit-filter'] = 'CSS2.0,CSS2.1,CSS3.0';
|
58 |
+
$GLOBALS['csstidy']['all_properties']['-moz-filter'] = 'CSS2.0,CSS2.1,CSS3.0';
|
59 |
+
$GLOBALS['csstidy']['all_properties']['-ms-filter'] = 'CSS2.0,CSS2.1,CSS3.0';
|
60 |
+
$GLOBALS['csstidy']['all_properties']['filter'] = 'CSS2.0,CSS2.1,CSS3.0';
|
61 |
+
$GLOBALS['csstidy']['all_properties']['scrollbar-face-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
62 |
+
$GLOBALS['csstidy']['all_properties']['-ms-interpolation-mode'] = 'CSS2.0,CSS2.1,CSS3.0';
|
63 |
+
$GLOBALS['csstidy']['all_properties']['text-rendering'] = 'CSS2.0,CSS2.1,CSS3.0';
|
64 |
+
$GLOBALS['csstidy']['all_properties']['-webkit-transform-origin-x'] = 'CSS3.0';
|
65 |
+
$GLOBALS['csstidy']['all_properties']['-webkit-transform-origin-y'] = 'CSS3.0';
|
66 |
+
$GLOBALS['csstidy']['all_properties']['-webkit-transform-origin-z'] = 'CSS3.0';
|
67 |
+
$GLOBALS['csstidy']['all_properties']['-webkit-font-smoothing'] = 'CSS3.0';
|
68 |
+
$GLOBALS['csstidy']['all_properties']['-font-smooth'] = 'CSS3.0';
|
69 |
+
$GLOBALS['csstidy']['all_properties']['-o-object-fit'] = 'CSS3.0';
|
70 |
+
$GLOBALS['csstidy']['all_properties']['object-fit'] = 'CSS3.0';
|
71 |
+
$GLOBALS['csstidy']['all_properties']['-o-object-position'] = 'CSS3.0';
|
72 |
+
$GLOBALS['csstidy']['all_properties']['object-position'] = 'CSS3.0';
|
73 |
+
$GLOBALS['csstidy']['all_properties']['text-overflow'] = 'CSS3.0';
|
74 |
+
$GLOBALS['csstidy']['all_properties']['zoom'] = 'CSS3.0';
|
75 |
+
|
classes/csstidy/data.inc.php
CHANGED
@@ -1,661 +1,661 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Various CSS Data for CSSTidy
|
4 |
-
*
|
5 |
-
* This file is part of CSSTidy.
|
6 |
-
*
|
7 |
-
* CSSTidy is free software; you can redistribute it and/or modify
|
8 |
-
* it under the terms of the GNU General Public License as published by
|
9 |
-
* the Free Software Foundation; either version 2 of the License, or
|
10 |
-
* (at your option) any later version.
|
11 |
-
*
|
12 |
-
* CSSTidy is distributed in the hope that it will be useful,
|
13 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
* GNU General Public License for more details.
|
16 |
-
*
|
17 |
-
* You should have received a copy of the GNU General Public License
|
18 |
-
* along with CSSTidy; if not, write to the Free Software
|
19 |
-
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
20 |
-
*
|
21 |
-
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
22 |
-
* @package csstidy
|
23 |
-
* @author Florian Schmitz (floele at gmail dot com) 2005
|
24 |
-
* @author Nikolay Matsievsky (speed at webo dot name) 2010
|
25 |
-
*/
|
26 |
-
|
27 |
-
define('AT_START', 1);
|
28 |
-
define('AT_END', 2);
|
29 |
-
define('SEL_START', 3);
|
30 |
-
define('SEL_END', 4);
|
31 |
-
define('PROPERTY', 5);
|
32 |
-
define('VALUE', 6);
|
33 |
-
define('COMMENT', 7);
|
34 |
-
define('DEFAULT_AT', 41);
|
35 |
-
|
36 |
-
/**
|
37 |
-
* All whitespace allowed in CSS
|
38 |
-
*
|
39 |
-
* @global array $GLOBALS['csstidy']['whitespace']
|
40 |
-
* @version 1.0
|
41 |
-
*/
|
42 |
-
$GLOBALS['csstidy']['whitespace'] = array(' ',"\n","\t","\r","\x0B");
|
43 |
-
|
44 |
-
/**
|
45 |
-
* All CSS tokens used by csstidy
|
46 |
-
*
|
47 |
-
* @global string $GLOBALS['csstidy']['tokens']
|
48 |
-
* @version 1.0
|
49 |
-
*/
|
50 |
-
$GLOBALS['csstidy']['tokens'] = '/@}{;:=\'"(,\\!$%&)*+.<>?[]^`|~';
|
51 |
-
|
52 |
-
/**
|
53 |
-
* All CSS units (CSS 3 units included)
|
54 |
-
*
|
55 |
-
* @see compress_numbers()
|
56 |
-
* @global array $GLOBALS['csstidy']['units']
|
57 |
-
* @version 1.0
|
58 |
-
*/
|
59 |
-
$GLOBALS['csstidy']['units'] = array('in','cm','mm','pt','pc','px','rem','em','%','ex','gd','vw','vh','vm','deg','grad','rad','ms','s','khz','hz');
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Available at-rules
|
63 |
-
*
|
64 |
-
* @global array $GLOBALS['csstidy']['at_rules']
|
65 |
-
* @version 1.0
|
66 |
-
*/
|
67 |
-
$GLOBALS['csstidy']['at_rules'] = array('page' => 'is','font-face' => 'is','charset' => 'iv', 'import' => 'iv','namespace' => 'iv','media' => 'at','keyframes' => 'at');
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Properties that need a value with unit
|
71 |
-
*
|
72 |
-
* @todo CSS3 properties
|
73 |
-
* @see compress_numbers();
|
74 |
-
* @global array $GLOBALS['csstidy']['unit_values']
|
75 |
-
* @version 1.2
|
76 |
-
*/
|
77 |
-
$GLOBALS['csstidy']['unit_values'] = array ('background', 'background-position', 'background-size', 'border', 'border-top', 'border-right', 'border-bottom', 'border-left', 'border-width',
|
78 |
-
'border-top-width', 'border-right-width', 'border-left-width', 'border-bottom-width', 'bottom', 'border-spacing', 'column-gap', 'column-width',
|
79 |
-
'font-size', 'height', 'left', 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', 'max-height',
|
80 |
-
'max-width', 'min-height', 'min-width', 'outline', 'outline-width', 'padding', 'padding-top', 'padding-right',
|
81 |
-
'padding-bottom', 'padding-left', 'perspective', 'right', 'top', 'text-indent', 'letter-spacing', 'word-spacing', 'width');
|
82 |
-
|
83 |
-
/**
|
84 |
-
* Properties that allow <color> as value
|
85 |
-
*
|
86 |
-
* @todo CSS3 properties
|
87 |
-
* @see compress_numbers();
|
88 |
-
* @global array $GLOBALS['csstidy']['color_values']
|
89 |
-
* @version 1.0
|
90 |
-
*/
|
91 |
-
$GLOBALS['csstidy']['color_values'] = array();
|
92 |
-
$GLOBALS['csstidy']['color_values'][] = 'background-color';
|
93 |
-
$GLOBALS['csstidy']['color_values'][] = 'border-color';
|
94 |
-
$GLOBALS['csstidy']['color_values'][] = 'border-top-color';
|
95 |
-
$GLOBALS['csstidy']['color_values'][] = 'border-right-color';
|
96 |
-
$GLOBALS['csstidy']['color_values'][] = 'border-bottom-color';
|
97 |
-
$GLOBALS['csstidy']['color_values'][] = 'border-left-color';
|
98 |
-
$GLOBALS['csstidy']['color_values'][] = 'color';
|
99 |
-
$GLOBALS['csstidy']['color_values'][] = 'outline-color';
|
100 |
-
$GLOBALS['csstidy']['color_values'][] = 'column-rule-color';
|
101 |
-
|
102 |
-
/**
|
103 |
-
* Default values for the background properties
|
104 |
-
*
|
105 |
-
* @todo Possibly property names will change during CSS3 development
|
106 |
-
* @global array $GLOBALS['csstidy']['background_prop_default']
|
107 |
-
* @see dissolve_short_bg()
|
108 |
-
* @see merge_bg()
|
109 |
-
* @version 1.0
|
110 |
-
*/
|
111 |
-
$GLOBALS['csstidy']['background_prop_default'] = array();
|
112 |
-
$GLOBALS['csstidy']['background_prop_default']['background-image'] = 'none';
|
113 |
-
$GLOBALS['csstidy']['background_prop_default']['background-size'] = 'auto';
|
114 |
-
$GLOBALS['csstidy']['background_prop_default']['background-repeat'] = 'repeat';
|
115 |
-
$GLOBALS['csstidy']['background_prop_default']['background-position'] = '0 0';
|
116 |
-
$GLOBALS['csstidy']['background_prop_default']['background-attachment'] = 'scroll';
|
117 |
-
$GLOBALS['csstidy']['background_prop_default']['background-clip'] = 'border';
|
118 |
-
$GLOBALS['csstidy']['background_prop_default']['background-origin'] = 'padding';
|
119 |
-
$GLOBALS['csstidy']['background_prop_default']['background-color'] = 'transparent';
|
120 |
-
|
121 |
-
/**
|
122 |
-
* Default values for the font properties
|
123 |
-
*
|
124 |
-
* @global array $GLOBALS['csstidy']['font_prop_default']
|
125 |
-
* @see merge_fonts()
|
126 |
-
* @version 1.3
|
127 |
-
*/
|
128 |
-
$GLOBALS['csstidy']['font_prop_default'] = array();
|
129 |
-
$GLOBALS['csstidy']['font_prop_default']['font-style'] = 'normal';
|
130 |
-
$GLOBALS['csstidy']['font_prop_default']['font-variant'] = 'normal';
|
131 |
-
$GLOBALS['csstidy']['font_prop_default']['font-weight'] = 'normal';
|
132 |
-
$GLOBALS['csstidy']['font_prop_default']['font-size'] = '';
|
133 |
-
$GLOBALS['csstidy']['font_prop_default']['line-height'] = '';
|
134 |
-
$GLOBALS['csstidy']['font_prop_default']['font-family'] = '';
|
135 |
-
|
136 |
-
/**
|
137 |
-
* A list of non-W3C color names which get replaced by their hex-codes
|
138 |
-
*
|
139 |
-
* @global array $GLOBALS['csstidy']['replace_colors']
|
140 |
-
* @see cut_color()
|
141 |
-
* @version 1.0
|
142 |
-
*/
|
143 |
-
$GLOBALS['csstidy']['replace_colors'] = array();
|
144 |
-
$GLOBALS['csstidy']['replace_colors']['aliceblue'] = '#f0f8ff';
|
145 |
-
$GLOBALS['csstidy']['replace_colors']['antiquewhite'] = '#faebd7';
|
146 |
-
$GLOBALS['csstidy']['replace_colors']['aquamarine'] = '#7fffd4';
|
147 |
-
$GLOBALS['csstidy']['replace_colors']['azure'] = '#f0ffff';
|
148 |
-
$GLOBALS['csstidy']['replace_colors']['beige'] = '#f5f5dc';
|
149 |
-
$GLOBALS['csstidy']['replace_colors']['bisque'] = '#ffe4c4';
|
150 |
-
$GLOBALS['csstidy']['replace_colors']['blanchedalmond'] = '#ffebcd';
|
151 |
-
$GLOBALS['csstidy']['replace_colors']['blueviolet'] = '#8a2be2';
|
152 |
-
$GLOBALS['csstidy']['replace_colors']['brown'] = '#a52a2a';
|
153 |
-
$GLOBALS['csstidy']['replace_colors']['burlywood'] = '#deb887';
|
154 |
-
$GLOBALS['csstidy']['replace_colors']['cadetblue'] = '#5f9ea0';
|
155 |
-
$GLOBALS['csstidy']['replace_colors']['chartreuse'] = '#7fff00';
|
156 |
-
$GLOBALS['csstidy']['replace_colors']['chocolate'] = '#d2691e';
|
157 |
-
$GLOBALS['csstidy']['replace_colors']['coral'] = '#ff7f50';
|
158 |
-
$GLOBALS['csstidy']['replace_colors']['cornflowerblue'] = '#6495ed';
|
159 |
-
$GLOBALS['csstidy']['replace_colors']['cornsilk'] = '#fff8dc';
|
160 |
-
$GLOBALS['csstidy']['replace_colors']['crimson'] = '#dc143c';
|
161 |
-
$GLOBALS['csstidy']['replace_colors']['cyan'] = '#00ffff';
|
162 |
-
$GLOBALS['csstidy']['replace_colors']['darkblue'] = '#00008b';
|
163 |
-
$GLOBALS['csstidy']['replace_colors']['darkcyan'] = '#008b8b';
|
164 |
-
$GLOBALS['csstidy']['replace_colors']['darkgoldenrod'] = '#b8860b';
|
165 |
-
$GLOBALS['csstidy']['replace_colors']['darkgray'] = '#a9a9a9';
|
166 |
-
$GLOBALS['csstidy']['replace_colors']['darkgreen'] = '#006400';
|
167 |
-
$GLOBALS['csstidy']['replace_colors']['darkkhaki'] = '#bdb76b';
|
168 |
-
$GLOBALS['csstidy']['replace_colors']['darkmagenta'] = '#8b008b';
|
169 |
-
$GLOBALS['csstidy']['replace_colors']['darkolivegreen'] = '#556b2f';
|
170 |
-
$GLOBALS['csstidy']['replace_colors']['darkorange'] = '#ff8c00';
|
171 |
-
$GLOBALS['csstidy']['replace_colors']['darkorchid'] = '#9932cc';
|
172 |
-
$GLOBALS['csstidy']['replace_colors']['darkred'] = '#8b0000';
|
173 |
-
$GLOBALS['csstidy']['replace_colors']['darksalmon'] = '#e9967a';
|
174 |
-
$GLOBALS['csstidy']['replace_colors']['darkseagreen'] = '#8fbc8f';
|
175 |
-
$GLOBALS['csstidy']['replace_colors']['darkslateblue'] = '#483d8b';
|
176 |
-
$GLOBALS['csstidy']['replace_colors']['darkslategray'] = '#2f4f4f';
|
177 |
-
$GLOBALS['csstidy']['replace_colors']['darkturquoise'] = '#00ced1';
|
178 |
-
$GLOBALS['csstidy']['replace_colors']['darkviolet'] = '#9400d3';
|
179 |
-
$GLOBALS['csstidy']['replace_colors']['deeppink'] = '#ff1493';
|
180 |
-
$GLOBALS['csstidy']['replace_colors']['deepskyblue'] = '#00bfff';
|
181 |
-
$GLOBALS['csstidy']['replace_colors']['dimgray'] = '#696969';
|
182 |
-
$GLOBALS['csstidy']['replace_colors']['dodgerblue'] = '#1e90ff';
|
183 |
-
$GLOBALS['csstidy']['replace_colors']['feldspar'] = '#d19275';
|
184 |
-
$GLOBALS['csstidy']['replace_colors']['firebrick'] = '#b22222';
|
185 |
-
$GLOBALS['csstidy']['replace_colors']['floralwhite'] = '#fffaf0';
|
186 |
-
$GLOBALS['csstidy']['replace_colors']['forestgreen'] = '#228b22';
|
187 |
-
$GLOBALS['csstidy']['replace_colors']['gainsboro'] = '#dcdcdc';
|
188 |
-
$GLOBALS['csstidy']['replace_colors']['ghostwhite'] = '#f8f8ff';
|
189 |
-
$GLOBALS['csstidy']['replace_colors']['gold'] = '#ffd700';
|
190 |
-
$GLOBALS['csstidy']['replace_colors']['goldenrod'] = '#daa520';
|
191 |
-
$GLOBALS['csstidy']['replace_colors']['greenyellow'] = '#adff2f';
|
192 |
-
$GLOBALS['csstidy']['replace_colors']['honeydew'] = '#f0fff0';
|
193 |
-
$GLOBALS['csstidy']['replace_colors']['hotpink'] = '#ff69b4';
|
194 |
-
$GLOBALS['csstidy']['replace_colors']['indianred'] = '#cd5c5c';
|
195 |
-
$GLOBALS['csstidy']['replace_colors']['indigo'] = '#4b0082';
|
196 |
-
$GLOBALS['csstidy']['replace_colors']['ivory'] = '#fffff0';
|
197 |
-
$GLOBALS['csstidy']['replace_colors']['khaki'] = '#f0e68c';
|
198 |
-
$GLOBALS['csstidy']['replace_colors']['lavender'] = '#e6e6fa';
|
199 |
-
$GLOBALS['csstidy']['replace_colors']['lavenderblush'] = '#fff0f5';
|
200 |
-
$GLOBALS['csstidy']['replace_colors']['lawngreen'] = '#7cfc00';
|
201 |
-
$GLOBALS['csstidy']['replace_colors']['lemonchiffon'] = '#fffacd';
|
202 |
-
$GLOBALS['csstidy']['replace_colors']['lightblue'] = '#add8e6';
|
203 |
-
$GLOBALS['csstidy']['replace_colors']['lightcoral'] = '#f08080';
|
204 |
-
$GLOBALS['csstidy']['replace_colors']['lightcyan'] = '#e0ffff';
|
205 |
-
$GLOBALS['csstidy']['replace_colors']['lightgoldenrodyellow'] = '#fafad2';
|
206 |
-
$GLOBALS['csstidy']['replace_colors']['lightgrey'] = '#d3d3d3';
|
207 |
-
$GLOBALS['csstidy']['replace_colors']['lightgreen'] = '#90ee90';
|
208 |
-
$GLOBALS['csstidy']['replace_colors']['lightpink'] = '#ffb6c1';
|
209 |
-
$GLOBALS['csstidy']['replace_colors']['lightsalmon'] = '#ffa07a';
|
210 |
-
$GLOBALS['csstidy']['replace_colors']['lightseagreen'] = '#20b2aa';
|
211 |
-
$GLOBALS['csstidy']['replace_colors']['lightskyblue'] = '#87cefa';
|
212 |
-
$GLOBALS['csstidy']['replace_colors']['lightslateblue'] = '#8470ff';
|
213 |
-
$GLOBALS['csstidy']['replace_colors']['lightslategray'] = '#778899';
|
214 |
-
$GLOBALS['csstidy']['replace_colors']['lightsteelblue'] = '#b0c4de';
|
215 |
-
$GLOBALS['csstidy']['replace_colors']['lightyellow'] = '#ffffe0';
|
216 |
-
$GLOBALS['csstidy']['replace_colors']['limegreen'] = '#32cd32';
|
217 |
-
$GLOBALS['csstidy']['replace_colors']['linen'] = '#faf0e6';
|
218 |
-
$GLOBALS['csstidy']['replace_colors']['magenta'] = '#ff00ff';
|
219 |
-
$GLOBALS['csstidy']['replace_colors']['mediumaquamarine'] = '#66cdaa';
|
220 |
-
$GLOBALS['csstidy']['replace_colors']['mediumblue'] = '#0000cd';
|
221 |
-
$GLOBALS['csstidy']['replace_colors']['mediumorchid'] = '#ba55d3';
|
222 |
-
$GLOBALS['csstidy']['replace_colors']['mediumpurple'] = '#9370d8';
|
223 |
-
$GLOBALS['csstidy']['replace_colors']['mediumseagreen'] = '#3cb371';
|
224 |
-
$GLOBALS['csstidy']['replace_colors']['mediumslateblue'] = '#7b68ee';
|
225 |
-
$GLOBALS['csstidy']['replace_colors']['mediumspringgreen'] = '#00fa9a';
|
226 |
-
$GLOBALS['csstidy']['replace_colors']['mediumturquoise'] = '#48d1cc';
|
227 |
-
$GLOBALS['csstidy']['replace_colors']['mediumvioletred'] = '#c71585';
|
228 |
-
$GLOBALS['csstidy']['replace_colors']['midnightblue'] = '#191970';
|
229 |
-
$GLOBALS['csstidy']['replace_colors']['mintcream'] = '#f5fffa';
|
230 |
-
$GLOBALS['csstidy']['replace_colors']['mistyrose'] = '#ffe4e1';
|
231 |
-
$GLOBALS['csstidy']['replace_colors']['moccasin'] = '#ffe4b5';
|
232 |
-
$GLOBALS['csstidy']['replace_colors']['navajowhite'] = '#ffdead';
|
233 |
-
$GLOBALS['csstidy']['replace_colors']['oldlace'] = '#fdf5e6';
|
234 |
-
$GLOBALS['csstidy']['replace_colors']['olivedrab'] = '#6b8e23';
|
235 |
-
$GLOBALS['csstidy']['replace_colors']['orangered'] = '#ff4500';
|
236 |
-
$GLOBALS['csstidy']['replace_colors']['orchid'] = '#da70d6';
|
237 |
-
$GLOBALS['csstidy']['replace_colors']['palegoldenrod'] = '#eee8aa';
|
238 |
-
$GLOBALS['csstidy']['replace_colors']['palegreen'] = '#98fb98';
|
239 |
-
$GLOBALS['csstidy']['replace_colors']['paleturquoise'] = '#afeeee';
|
240 |
-
$GLOBALS['csstidy']['replace_colors']['palevioletred'] = '#d87093';
|
241 |
-
$GLOBALS['csstidy']['replace_colors']['papayawhip'] = '#ffefd5';
|
242 |
-
$GLOBALS['csstidy']['replace_colors']['peachpuff'] = '#ffdab9';
|
243 |
-
$GLOBALS['csstidy']['replace_colors']['peru'] = '#cd853f';
|
244 |
-
$GLOBALS['csstidy']['replace_colors']['pink'] = '#ffc0cb';
|
245 |
-
$GLOBALS['csstidy']['replace_colors']['plum'] = '#dda0dd';
|
246 |
-
$GLOBALS['csstidy']['replace_colors']['powderblue'] = '#b0e0e6';
|
247 |
-
$GLOBALS['csstidy']['replace_colors']['rosybrown'] = '#bc8f8f';
|
248 |
-
$GLOBALS['csstidy']['replace_colors']['royalblue'] = '#4169e1';
|
249 |
-
$GLOBALS['csstidy']['replace_colors']['saddlebrown'] = '#8b4513';
|
250 |
-
$GLOBALS['csstidy']['replace_colors']['salmon'] = '#fa8072';
|
251 |
-
$GLOBALS['csstidy']['replace_colors']['sandybrown'] = '#f4a460';
|
252 |
-
$GLOBALS['csstidy']['replace_colors']['seagreen'] = '#2e8b57';
|
253 |
-
$GLOBALS['csstidy']['replace_colors']['seashell'] = '#fff5ee';
|
254 |
-
$GLOBALS['csstidy']['replace_colors']['sienna'] = '#a0522d';
|
255 |
-
$GLOBALS['csstidy']['replace_colors']['skyblue'] = '#87ceeb';
|
256 |
-
$GLOBALS['csstidy']['replace_colors']['slateblue'] = '#6a5acd';
|
257 |
-
$GLOBALS['csstidy']['replace_colors']['slategray'] = '#708090';
|
258 |
-
$GLOBALS['csstidy']['replace_colors']['snow'] = '#fffafa';
|
259 |
-
$GLOBALS['csstidy']['replace_colors']['springgreen'] = '#00ff7f';
|
260 |
-
$GLOBALS['csstidy']['replace_colors']['steelblue'] = '#4682b4';
|
261 |
-
$GLOBALS['csstidy']['replace_colors']['tan'] = '#d2b48c';
|
262 |
-
$GLOBALS['csstidy']['replace_colors']['thistle'] = '#d8bfd8';
|
263 |
-
$GLOBALS['csstidy']['replace_colors']['tomato'] = '#ff6347';
|
264 |
-
$GLOBALS['csstidy']['replace_colors']['turquoise'] = '#40e0d0';
|
265 |
-
$GLOBALS['csstidy']['replace_colors']['violet'] = '#ee82ee';
|
266 |
-
$GLOBALS['csstidy']['replace_colors']['violetred'] = '#d02090';
|
267 |
-
$GLOBALS['csstidy']['replace_colors']['wheat'] = '#f5deb3';
|
268 |
-
$GLOBALS['csstidy']['replace_colors']['whitesmoke'] = '#f5f5f5';
|
269 |
-
$GLOBALS['csstidy']['replace_colors']['yellowgreen'] = '#9acd32';
|
270 |
-
|
271 |
-
/**
|
272 |
-
* A list of all shorthand properties that are devided into four properties and/or have four subvalues
|
273 |
-
*
|
274 |
-
* @global array $GLOBALS['csstidy']['shorthands']
|
275 |
-
* @todo Are there new ones in CSS3?
|
276 |
-
* @see dissolve_4value_shorthands()
|
277 |
-
* @see merge_4value_shorthands()
|
278 |
-
* @version 1.0
|
279 |
-
*/
|
280 |
-
$GLOBALS['csstidy']['shorthands'] = array();
|
281 |
-
$GLOBALS['csstidy']['shorthands']['border-color'] = array('border-top-color','border-right-color','border-bottom-color','border-left-color');
|
282 |
-
$GLOBALS['csstidy']['shorthands']['border-style'] = array('border-top-style','border-right-style','border-bottom-style','border-left-style');
|
283 |
-
$GLOBALS['csstidy']['shorthands']['border-width'] = array('border-top-width','border-right-width','border-bottom-width','border-left-width');
|
284 |
-
$GLOBALS['csstidy']['shorthands']['margin'] = array('margin-top','margin-right','margin-bottom','margin-left');
|
285 |
-
$GLOBALS['csstidy']['shorthands']['padding'] = array('padding-top','padding-right','padding-bottom','padding-left');
|
286 |
-
$GLOBALS['csstidy']['shorthands']['-moz-border-radius'] = 0;
|
287 |
-
|
288 |
-
/**
|
289 |
-
* All CSS Properties. Needed for csstidy::property_is_next()
|
290 |
-
*
|
291 |
-
* @global array $GLOBALS['csstidy']['all_properties']
|
292 |
-
* @todo Add CSS3 properties
|
293 |
-
* @version 1.0
|
294 |
-
* @see csstidy::property_is_next()
|
295 |
-
*/
|
296 |
-
$GLOBALS['csstidy']['all_properties']['alignment-adjust'] = 'CSS3.0';
|
297 |
-
$GLOBALS['csstidy']['all_properties']['alignment-baseline'] = 'CSS3.0';
|
298 |
-
$GLOBALS['csstidy']['all_properties']['animation'] = 'CSS3.0';
|
299 |
-
$GLOBALS['csstidy']['all_properties']['animation-delay'] = 'CSS3.0';
|
300 |
-
$GLOBALS['csstidy']['all_properties']['animation-direction'] = 'CSS3.0';
|
301 |
-
$GLOBALS['csstidy']['all_properties']['animation-duration'] = 'CSS3.0';
|
302 |
-
$GLOBALS['csstidy']['all_properties']['animation-iteration-count'] = 'CSS3.0';
|
303 |
-
$GLOBALS['csstidy']['all_properties']['animation-name'] = 'CSS3.0';
|
304 |
-
$GLOBALS['csstidy']['all_properties']['animation-play-state'] = 'CSS3.0';
|
305 |
-
$GLOBALS['csstidy']['all_properties']['animation-timing-function'] = 'CSS3.0';
|
306 |
-
$GLOBALS['csstidy']['all_properties']['appearance'] = 'CSS3.0';
|
307 |
-
$GLOBALS['csstidy']['all_properties']['azimuth'] = 'CSS2.0,CSS2.1,CSS3.0';
|
308 |
-
$GLOBALS['csstidy']['all_properties']['backface-visibility'] = 'CSS3.0';
|
309 |
-
$GLOBALS['csstidy']['all_properties']['background'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
310 |
-
$GLOBALS['csstidy']['all_properties']['background-attachment'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
311 |
-
$GLOBALS['csstidy']['all_properties']['background-clip'] = 'CSS3.0';
|
312 |
-
$GLOBALS['csstidy']['all_properties']['background-color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
313 |
-
$GLOBALS['csstidy']['all_properties']['background-image'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
314 |
-
$GLOBALS['csstidy']['all_properties']['background-origin'] = 'CSS3.0';
|
315 |
-
$GLOBALS['csstidy']['all_properties']['background-position'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
316 |
-
$GLOBALS['csstidy']['all_properties']['background-repeat'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
317 |
-
$GLOBALS['csstidy']['all_properties']['background-size'] = 'CSS3.0';
|
318 |
-
$GLOBALS['csstidy']['all_properties']['baseline-shift'] = 'CSS3.0';
|
319 |
-
$GLOBALS['csstidy']['all_properties']['binding'] = 'CSS3.0';
|
320 |
-
$GLOBALS['csstidy']['all_properties']['bleed'] = 'CSS3.0';
|
321 |
-
$GLOBALS['csstidy']['all_properties']['bookmark-label'] = 'CSS3.0';
|
322 |
-
$GLOBALS['csstidy']['all_properties']['bookmark-level'] = 'CSS3.0';
|
323 |
-
$GLOBALS['csstidy']['all_properties']['bookmark-state'] = 'CSS3.0';
|
324 |
-
$GLOBALS['csstidy']['all_properties']['bookmark-target'] = 'CSS3.0';
|
325 |
-
$GLOBALS['csstidy']['all_properties']['border'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
326 |
-
$GLOBALS['csstidy']['all_properties']['border-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
327 |
-
$GLOBALS['csstidy']['all_properties']['border-bottom-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
328 |
-
$GLOBALS['csstidy']['all_properties']['border-bottom-left-radius'] = 'CSS3.0';
|
329 |
-
$GLOBALS['csstidy']['all_properties']['border-bottom-right-radius'] = 'CSS3.0';
|
330 |
-
$GLOBALS['csstidy']['all_properties']['border-bottom-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
331 |
-
$GLOBALS['csstidy']['all_properties']['border-bottom-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
332 |
-
$GLOBALS['csstidy']['all_properties']['border-collapse'] = 'CSS2.0,CSS2.1,CSS3.0';
|
333 |
-
$GLOBALS['csstidy']['all_properties']['border-color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
334 |
-
$GLOBALS['csstidy']['all_properties']['border-image'] = 'CSS3.0';
|
335 |
-
$GLOBALS['csstidy']['all_properties']['border-image-outset'] = 'CSS3.0';
|
336 |
-
$GLOBALS['csstidy']['all_properties']['border-image-repeat'] = 'CSS3.0';
|
337 |
-
$GLOBALS['csstidy']['all_properties']['border-image-slice'] = 'CSS3.0';
|
338 |
-
$GLOBALS['csstidy']['all_properties']['border-image-source'] = 'CSS3.0';
|
339 |
-
$GLOBALS['csstidy']['all_properties']['border-image-width'] = 'CSS3.0';
|
340 |
-
$GLOBALS['csstidy']['all_properties']['border-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
341 |
-
$GLOBALS['csstidy']['all_properties']['border-left-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
342 |
-
$GLOBALS['csstidy']['all_properties']['border-left-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
343 |
-
$GLOBALS['csstidy']['all_properties']['border-left-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
344 |
-
$GLOBALS['csstidy']['all_properties']['border-radius'] = 'CSS3.0';
|
345 |
-
$GLOBALS['csstidy']['all_properties']['border-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
346 |
-
$GLOBALS['csstidy']['all_properties']['border-right-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
347 |
-
$GLOBALS['csstidy']['all_properties']['border-right-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
348 |
-
$GLOBALS['csstidy']['all_properties']['border-right-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
349 |
-
$GLOBALS['csstidy']['all_properties']['border-spacing'] = 'CSS2.0,CSS2.1,CSS3.0';
|
350 |
-
$GLOBALS['csstidy']['all_properties']['border-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
351 |
-
$GLOBALS['csstidy']['all_properties']['border-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
352 |
-
$GLOBALS['csstidy']['all_properties']['border-top-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
353 |
-
$GLOBALS['csstidy']['all_properties']['border-top-left-radius'] = 'CSS3.0';
|
354 |
-
$GLOBALS['csstidy']['all_properties']['border-top-right-radius'] = 'CSS3.0';
|
355 |
-
$GLOBALS['csstidy']['all_properties']['border-top-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
356 |
-
$GLOBALS['csstidy']['all_properties']['border-top-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
357 |
-
$GLOBALS['csstidy']['all_properties']['border-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
358 |
-
$GLOBALS['csstidy']['all_properties']['bottom'] = 'CSS2.0,CSS2.1,CSS3.0';
|
359 |
-
$GLOBALS['csstidy']['all_properties']['box-decoration-break'] = 'CSS3.0';
|
360 |
-
$GLOBALS['csstidy']['all_properties']['box-shadow'] = 'CSS3.0';
|
361 |
-
$GLOBALS['csstidy']['all_properties']['box-sizing'] = 'CSS3.0';
|
362 |
-
$GLOBALS['csstidy']['all_properties']['break-after'] = 'CSS3.0';
|
363 |
-
$GLOBALS['csstidy']['all_properties']['break-before'] = 'CSS3.0';
|
364 |
-
$GLOBALS['csstidy']['all_properties']['break-inside'] = 'CSS3.0';
|
365 |
-
$GLOBALS['csstidy']['all_properties']['caption-side'] = 'CSS2.0,CSS2.1,CSS3.0';
|
366 |
-
$GLOBALS['csstidy']['all_properties']['clear'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
367 |
-
$GLOBALS['csstidy']['all_properties']['clip'] = 'CSS2.0,CSS2.1,CSS3.0';
|
368 |
-
$GLOBALS['csstidy']['all_properties']['color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
369 |
-
$GLOBALS['csstidy']['all_properties']['color-profile'] = 'CSS3.0';
|
370 |
-
$GLOBALS['csstidy']['all_properties']['column-count'] = 'CSS3.0';
|
371 |
-
$GLOBALS['csstidy']['all_properties']['column-fill'] = 'CSS3.0';
|
372 |
-
$GLOBALS['csstidy']['all_properties']['column-gap'] = 'CSS3.0';
|
373 |
-
$GLOBALS['csstidy']['all_properties']['column-rule'] = 'CSS3.0';
|
374 |
-
$GLOBALS['csstidy']['all_properties']['column-rule-color'] = 'CSS3.0';
|
375 |
-
$GLOBALS['csstidy']['all_properties']['column-rule-style'] = 'CSS3.0';
|
376 |
-
$GLOBALS['csstidy']['all_properties']['column-rule-width'] = 'CSS3.0';
|
377 |
-
$GLOBALS['csstidy']['all_properties']['column-span'] = 'CSS3.0';
|
378 |
-
$GLOBALS['csstidy']['all_properties']['column-width'] = 'CSS3.0';
|
379 |
-
$GLOBALS['csstidy']['all_properties']['columns'] = 'CSS3.0';
|
380 |
-
$GLOBALS['csstidy']['all_properties']['content'] = 'CSS2.0,CSS2.1,CSS3.0';
|
381 |
-
$GLOBALS['csstidy']['all_properties']['counter-increment'] = 'CSS2.0,CSS2.1,CSS3.0';
|
382 |
-
$GLOBALS['csstidy']['all_properties']['counter-reset'] = 'CSS2.0,CSS2.1,CSS3.0';
|
383 |
-
$GLOBALS['csstidy']['all_properties']['crop'] = 'CSS3.0';
|
384 |
-
$GLOBALS['csstidy']['all_properties']['cue'] = 'CSS2.0,CSS2.1,CSS3.0';
|
385 |
-
$GLOBALS['csstidy']['all_properties']['cue-after'] = 'CSS2.0,CSS2.1,CSS3.0';
|
386 |
-
$GLOBALS['csstidy']['all_properties']['cue-before'] = 'CSS2.0,CSS2.1,CSS3.0';
|
387 |
-
$GLOBALS['csstidy']['all_properties']['cursor'] = 'CSS2.0,CSS2.1,CSS3.0';
|
388 |
-
$GLOBALS['csstidy']['all_properties']['direction'] = 'CSS2.0,CSS2.1,CSS3.0';
|
389 |
-
$GLOBALS['csstidy']['all_properties']['display'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
390 |
-
$GLOBALS['csstidy']['all_properties']['dominant-baseline'] = 'CSS3.0';
|
391 |
-
$GLOBALS['csstidy']['all_properties']['drop-initial-after-adjust'] = 'CSS3.0';
|
392 |
-
$GLOBALS['csstidy']['all_properties']['drop-initial-after-align'] = 'CSS3.0';
|
393 |
-
$GLOBALS['csstidy']['all_properties']['drop-initial-before-adjust'] = 'CSS3.0';
|
394 |
-
$GLOBALS['csstidy']['all_properties']['drop-initial-before-align'] = 'CSS3.0';
|
395 |
-
$GLOBALS['csstidy']['all_properties']['drop-initial-size'] = 'CSS3.0';
|
396 |
-
$GLOBALS['csstidy']['all_properties']['drop-initial-value'] = 'CSS3.0';
|
397 |
-
$GLOBALS['csstidy']['all_properties']['elevation'] = 'CSS2.0,CSS2.1,CSS3.0';
|
398 |
-
$GLOBALS['csstidy']['all_properties']['empty-cells'] = 'CSS2.0,CSS2.1,CSS3.0';
|
399 |
-
$GLOBALS['csstidy']['all_properties']['fit'] = 'CSS3.0';
|
400 |
-
$GLOBALS['csstidy']['all_properties']['fit-position'] = 'CSS3.0';
|
401 |
-
$GLOBALS['csstidy']['all_properties']['flex-align'] = 'CSS3.0';
|
402 |
-
$GLOBALS['csstidy']['all_properties']['flex-flow'] = 'CSS3.0';
|
403 |
-
$GLOBALS['csstidy']['all_properties']['flex-line-pack'] = 'CSS3.0';
|
404 |
-
$GLOBALS['csstidy']['all_properties']['flex-order'] = 'CSS3.0';
|
405 |
-
$GLOBALS['csstidy']['all_properties']['flex-pack'] = 'CSS3.0';
|
406 |
-
$GLOBALS['csstidy']['all_properties']['float'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
407 |
-
$GLOBALS['csstidy']['all_properties']['float-offset'] = 'CSS3.0';
|
408 |
-
$GLOBALS['csstidy']['all_properties']['font'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
409 |
-
$GLOBALS['csstidy']['all_properties']['font-family'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
410 |
-
$GLOBALS['csstidy']['all_properties']['font-size'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
411 |
-
$GLOBALS['csstidy']['all_properties']['font-size-adjust'] = 'CSS2.0,CSS3.0';
|
412 |
-
$GLOBALS['csstidy']['all_properties']['font-stretch'] = 'CSS2.0,CSS3.0';
|
413 |
-
$GLOBALS['csstidy']['all_properties']['font-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
414 |
-
$GLOBALS['csstidy']['all_properties']['font-variant'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
415 |
-
$GLOBALS['csstidy']['all_properties']['font-weight'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
416 |
-
$GLOBALS['csstidy']['all_properties']['grid-columns'] = 'CSS3.0';
|
417 |
-
$GLOBALS['csstidy']['all_properties']['grid-rows'] = 'CSS3.0';
|
418 |
-
$GLOBALS['csstidy']['all_properties']['hanging-punctuation'] = 'CSS3.0';
|
419 |
-
$GLOBALS['csstidy']['all_properties']['height'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
420 |
-
$GLOBALS['csstidy']['all_properties']['hyphenate-after'] = 'CSS3.0';
|
421 |
-
$GLOBALS['csstidy']['all_properties']['hyphenate-before'] = 'CSS3.0';
|
422 |
-
$GLOBALS['csstidy']['all_properties']['hyphenate-character'] = 'CSS3.0';
|
423 |
-
$GLOBALS['csstidy']['all_properties']['hyphenate-lines'] = 'CSS3.0';
|
424 |
-
$GLOBALS['csstidy']['all_properties']['hyphenate-resource'] = 'CSS3.0';
|
425 |
-
$GLOBALS['csstidy']['all_properties']['hyphens'] = 'CSS3.0';
|
426 |
-
$GLOBALS['csstidy']['all_properties']['icon'] = 'CSS3.0';
|
427 |
-
$GLOBALS['csstidy']['all_properties']['image-orientation'] = 'CSS3.0';
|
428 |
-
$GLOBALS['csstidy']['all_properties']['image-rendering'] = 'CSS3.0';
|
429 |
-
$GLOBALS['csstidy']['all_properties']['image-resolution'] = 'CSS3.0';
|
430 |
-
$GLOBALS['csstidy']['all_properties']['inline-box-align'] = 'CSS3.0';
|
431 |
-
$GLOBALS['csstidy']['all_properties']['left'] = 'CSS2.0,CSS2.1,CSS3.0';
|
432 |
-
$GLOBALS['csstidy']['all_properties']['letter-spacing'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
433 |
-
$GLOBALS['csstidy']['all_properties']['line-break'] = 'CSS3.0';
|
434 |
-
$GLOBALS['csstidy']['all_properties']['line-height'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
435 |
-
$GLOBALS['csstidy']['all_properties']['line-stacking'] = 'CSS3.0';
|
436 |
-
$GLOBALS['csstidy']['all_properties']['line-stacking-ruby'] = 'CSS3.0';
|
437 |
-
$GLOBALS['csstidy']['all_properties']['line-stacking-shift'] = 'CSS3.0';
|
438 |
-
$GLOBALS['csstidy']['all_properties']['line-stacking-strategy'] = 'CSS3.0';
|
439 |
-
$GLOBALS['csstidy']['all_properties']['list-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
440 |
-
$GLOBALS['csstidy']['all_properties']['list-style-image'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
441 |
-
$GLOBALS['csstidy']['all_properties']['list-style-position'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
442 |
-
$GLOBALS['csstidy']['all_properties']['list-style-type'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
443 |
-
$GLOBALS['csstidy']['all_properties']['margin'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
444 |
-
$GLOBALS['csstidy']['all_properties']['margin-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
445 |
-
$GLOBALS['csstidy']['all_properties']['margin-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
446 |
-
$GLOBALS['csstidy']['all_properties']['margin-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
447 |
-
$GLOBALS['csstidy']['all_properties']['margin-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
448 |
-
$GLOBALS['csstidy']['all_properties']['marker-offset'] = 'CSS3.0';
|
449 |
-
$GLOBALS['csstidy']['all_properties']['marks'] = 'CSS2.0,CSS3.0';
|
450 |
-
$GLOBALS['csstidy']['all_properties']['marquee-direction'] = 'CSS3.0';
|
451 |
-
$GLOBALS['csstidy']['all_properties']['marquee-loop'] = 'CSS3.0';
|
452 |
-
$GLOBALS['csstidy']['all_properties']['marquee-play-count'] = 'CSS3.0';
|
453 |
-
$GLOBALS['csstidy']['all_properties']['marquee-speed'] = 'CSS3.0';
|
454 |
-
$GLOBALS['csstidy']['all_properties']['marquee-style'] = 'CSS3.0';
|
455 |
-
$GLOBALS['csstidy']['all_properties']['max-height'] = 'CSS2.0,CSS2.1,CSS3.0';
|
456 |
-
$GLOBALS['csstidy']['all_properties']['max-width'] = 'CSS2.0,CSS2.1,CSS3.0';
|
457 |
-
$GLOBALS['csstidy']['all_properties']['min-height'] = 'CSS2.0,CSS2.1,CSS3.0';
|
458 |
-
$GLOBALS['csstidy']['all_properties']['min-width'] = 'CSS2.0,CSS2.1,CSS3.0';
|
459 |
-
$GLOBALS['csstidy']['all_properties']['move-to'] = 'CSS3.0';
|
460 |
-
$GLOBALS['csstidy']['all_properties']['nav-down'] = 'CSS3.0';
|
461 |
-
$GLOBALS['csstidy']['all_properties']['nav-index'] = 'CSS3.0';
|
462 |
-
$GLOBALS['csstidy']['all_properties']['nav-left'] = 'CSS3.0';
|
463 |
-
$GLOBALS['csstidy']['all_properties']['nav-right'] = 'CSS3.0';
|
464 |
-
$GLOBALS['csstidy']['all_properties']['nav-up'] = 'CSS3.0';
|
465 |
-
$GLOBALS['csstidy']['all_properties']['opacity'] = 'CSS3.0';
|
466 |
-
$GLOBALS['csstidy']['all_properties']['orphans'] = 'CSS2.0,CSS2.1,CSS3.0';
|
467 |
-
$GLOBALS['csstidy']['all_properties']['outline'] = 'CSS2.0,CSS2.1,CSS3.0';
|
468 |
-
$GLOBALS['csstidy']['all_properties']['outline-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
469 |
-
$GLOBALS['csstidy']['all_properties']['outline-offset'] = 'CSS3.0';
|
470 |
-
$GLOBALS['csstidy']['all_properties']['outline-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
471 |
-
$GLOBALS['csstidy']['all_properties']['outline-width'] = 'CSS2.0,CSS2.1,CSS3.0';
|
472 |
-
$GLOBALS['csstidy']['all_properties']['overflow'] = 'CSS2.0,CSS2.1,CSS3.0';
|
473 |
-
$GLOBALS['csstidy']['all_properties']['overflow-style'] = 'CSS3.0';
|
474 |
-
$GLOBALS['csstidy']['all_properties']['overflow-wrap'] = 'CSS3.0';
|
475 |
-
$GLOBALS['csstidy']['all_properties']['overflow-x'] = 'CSS3.0';
|
476 |
-
$GLOBALS['csstidy']['all_properties']['overflow-y'] = 'CSS3.0';
|
477 |
-
$GLOBALS['csstidy']['all_properties']['padding'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
478 |
-
$GLOBALS['csstidy']['all_properties']['padding-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
479 |
-
$GLOBALS['csstidy']['all_properties']['padding-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
480 |
-
$GLOBALS['csstidy']['all_properties']['padding-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
481 |
-
$GLOBALS['csstidy']['all_properties']['padding-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
482 |
-
$GLOBALS['csstidy']['all_properties']['page'] = 'CSS2.0,CSS3.0';
|
483 |
-
$GLOBALS['csstidy']['all_properties']['page-break-after'] = 'CSS2.0,CSS2.1,CSS3.0';
|
484 |
-
$GLOBALS['csstidy']['all_properties']['page-break-before'] = 'CSS2.0,CSS2.1,CSS3.0';
|
485 |
-
$GLOBALS['csstidy']['all_properties']['page-break-inside'] = 'CSS2.0,CSS2.1,CSS3.0';
|
486 |
-
$GLOBALS['csstidy']['all_properties']['page-policy'] = 'CSS3.0';
|
487 |
-
$GLOBALS['csstidy']['all_properties']['pause'] = 'CSS2.0,CSS2.1,CSS3.0';
|
488 |
-
$GLOBALS['csstidy']['all_properties']['pause-after'] = 'CSS2.0,CSS2.1,CSS3.0';
|
489 |
-
$GLOBALS['csstidy']['all_properties']['pause-before'] = 'CSS2.0,CSS2.1,CSS3.0';
|
490 |
-
$GLOBALS['csstidy']['all_properties']['perspective'] = 'CSS3.0';
|
491 |
-
$GLOBALS['csstidy']['all_properties']['perspective-origin'] = 'CSS3.0';
|
492 |
-
$GLOBALS['csstidy']['all_properties']['phonemes'] = 'CSS3.0';
|
493 |
-
$GLOBALS['csstidy']['all_properties']['pitch'] = 'CSS2.0,CSS2.1,CSS3.0';
|
494 |
-
$GLOBALS['csstidy']['all_properties']['pitch-range'] = 'CSS2.0,CSS2.1,CSS3.0';
|
495 |
-
$GLOBALS['csstidy']['all_properties']['play-during'] = 'CSS2.0,CSS2.1,CSS3.0';
|
496 |
-
$GLOBALS['csstidy']['all_properties']['position'] = 'CSS2.0,CSS2.1,CSS3.0';
|
497 |
-
$GLOBALS['csstidy']['all_properties']['presentation-level'] = 'CSS3.0';
|
498 |
-
$GLOBALS['csstidy']['all_properties']['punctuation-trim'] = 'CSS3.0';
|
499 |
-
$GLOBALS['csstidy']['all_properties']['quotes'] = 'CSS2.0,CSS2.1,CSS3.0';
|
500 |
-
$GLOBALS['csstidy']['all_properties']['rendering-intent'] = 'CSS3.0';
|
501 |
-
$GLOBALS['csstidy']['all_properties']['resize'] = 'CSS3.0';
|
502 |
-
$GLOBALS['csstidy']['all_properties']['rest'] = 'CSS3.0';
|
503 |
-
$GLOBALS['csstidy']['all_properties']['rest-after'] = 'CSS3.0';
|
504 |
-
$GLOBALS['csstidy']['all_properties']['rest-before'] = 'CSS3.0';
|
505 |
-
$GLOBALS['csstidy']['all_properties']['richness'] = 'CSS2.0,CSS2.1,CSS3.0';
|
506 |
-
$GLOBALS['csstidy']['all_properties']['right'] = 'CSS2.0,CSS2.1,CSS3.0';
|
507 |
-
$GLOBALS['csstidy']['all_properties']['rotation'] = 'CSS3.0';
|
508 |
-
$GLOBALS['csstidy']['all_properties']['rotation-point'] = 'CSS3.0';
|
509 |
-
$GLOBALS['csstidy']['all_properties']['ruby-align'] = 'CSS3.0';
|
510 |
-
$GLOBALS['csstidy']['all_properties']['ruby-overhang'] = 'CSS3.0';
|
511 |
-
$GLOBALS['csstidy']['all_properties']['ruby-position'] = 'CSS3.0';
|
512 |
-
$GLOBALS['csstidy']['all_properties']['ruby-span'] = 'CSS3.0';
|
513 |
-
$GLOBALS['csstidy']['all_properties']['size'] = 'CSS2.0,CSS3.0';
|
514 |
-
$GLOBALS['csstidy']['all_properties']['speak'] = 'CSS2.0,CSS2.1,CSS3.0';
|
515 |
-
$GLOBALS['csstidy']['all_properties']['speak-header'] = 'CSS2.0,CSS2.1,CSS3.0';
|
516 |
-
$GLOBALS['csstidy']['all_properties']['speak-numeral'] = 'CSS2.0,CSS2.1,CSS3.0';
|
517 |
-
$GLOBALS['csstidy']['all_properties']['speak-punctuation'] = 'CSS2.0,CSS2.1,CSS3.0';
|
518 |
-
$GLOBALS['csstidy']['all_properties']['speech-rate'] = 'CSS2.0,CSS2.1,CSS3.0';
|
519 |
-
$GLOBALS['csstidy']['all_properties']['src'] = 'CSS3.0';
|
520 |
-
$GLOBALS['csstidy']['all_properties']['stress'] = 'CSS2.0,CSS2.1,CSS3.0';
|
521 |
-
$GLOBALS['csstidy']['all_properties']['string-set'] = 'CSS3.0';
|
522 |
-
$GLOBALS['csstidy']['all_properties']['tab-size'] = 'CSS3.0';
|
523 |
-
$GLOBALS['csstidy']['all_properties']['table-layout'] = 'CSS2.0,CSS2.1,CSS3.0';
|
524 |
-
$GLOBALS['csstidy']['all_properties']['target'] = 'CSS3.0';
|
525 |
-
$GLOBALS['csstidy']['all_properties']['target-name'] = 'CSS3.0';
|
526 |
-
$GLOBALS['csstidy']['all_properties']['target-new'] = 'CSS3.0';
|
527 |
-
$GLOBALS['csstidy']['all_properties']['target-position'] = 'CSS3.0';
|
528 |
-
$GLOBALS['csstidy']['all_properties']['text-align'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
529 |
-
$GLOBALS['csstidy']['all_properties']['text-align-last'] = 'CSS3.0';
|
530 |
-
$GLOBALS['csstidy']['all_properties']['text-decoration'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
531 |
-
$GLOBALS['csstidy']['all_properties']['text-decoration-color'] = 'CSS3.0';
|
532 |
-
$GLOBALS['csstidy']['all_properties']['text-decoration-line'] = 'CSS3.0';
|
533 |
-
$GLOBALS['csstidy']['all_properties']['text-decoration-skip'] = 'CSS3.0';
|
534 |
-
$GLOBALS['csstidy']['all_properties']['text-decoration-style'] = 'CSS3.0';
|
535 |
-
$GLOBALS['csstidy']['all_properties']['text-emphasis'] = 'CSS3.0';
|
536 |
-
$GLOBALS['csstidy']['all_properties']['text-emphasis-color'] = 'CSS3.0';
|
537 |
-
$GLOBALS['csstidy']['all_properties']['text-emphasis-position'] = 'CSS3.0';
|
538 |
-
$GLOBALS['csstidy']['all_properties']['text-emphasis-style'] = 'CSS3.0';
|
539 |
-
$GLOBALS['csstidy']['all_properties']['text-height'] = 'CSS3.0';
|
540 |
-
$GLOBALS['csstidy']['all_properties']['text-indent'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
541 |
-
$GLOBALS['csstidy']['all_properties']['text-justify'] = 'CSS3.0';
|
542 |
-
$GLOBALS['csstidy']['all_properties']['text-outline'] = 'CSS3.0';
|
543 |
-
$GLOBALS['csstidy']['all_properties']['text-shadow'] = 'CSS2.0,CSS3.0';
|
544 |
-
$GLOBALS['csstidy']['all_properties']['text-space-collapse'] = 'CSS3.0';
|
545 |
-
$GLOBALS['csstidy']['all_properties']['text-transform'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
546 |
-
$GLOBALS['csstidy']['all_properties']['text-underline-position'] = 'CSS3.0';
|
547 |
-
$GLOBALS['csstidy']['all_properties']['text-wrap'] = 'CSS3.0';
|
548 |
-
$GLOBALS['csstidy']['all_properties']['top'] = 'CSS2.0,CSS2.1,CSS3.0';
|
549 |
-
$GLOBALS['csstidy']['all_properties']['transform'] = 'CSS3.0';
|
550 |
-
$GLOBALS['csstidy']['all_properties']['transform-origin'] = 'CSS3.0';
|
551 |
-
$GLOBALS['csstidy']['all_properties']['transform-style'] = 'CSS3.0';
|
552 |
-
$GLOBALS['csstidy']['all_properties']['transition'] = 'CSS3.0';
|
553 |
-
$GLOBALS['csstidy']['all_properties']['transition-delay'] = 'CSS3.0';
|
554 |
-
$GLOBALS['csstidy']['all_properties']['transition-duration'] = 'CSS3.0';
|
555 |
-
$GLOBALS['csstidy']['all_properties']['transition-property'] = 'CSS3.0';
|
556 |
-
$GLOBALS['csstidy']['all_properties']['transition-timing-function'] = 'CSS3.0';
|
557 |
-
$GLOBALS['csstidy']['all_properties']['unicode-bidi'] = 'CSS2.0,CSS2.1,CSS3.0';
|
558 |
-
$GLOBALS['csstidy']['all_properties']['vertical-align'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
559 |
-
$GLOBALS['csstidy']['all_properties']['visibility'] = 'CSS2.0,CSS2.1,CSS3.0';
|
560 |
-
$GLOBALS['csstidy']['all_properties']['voice-balance'] = 'CSS3.0';
|
561 |
-
$GLOBALS['csstidy']['all_properties']['voice-duration'] = 'CSS3.0';
|
562 |
-
$GLOBALS['csstidy']['all_properties']['voice-family'] = 'CSS2.0,CSS2.1,CSS3.0';
|
563 |
-
$GLOBALS['csstidy']['all_properties']['voice-pitch'] = 'CSS3.0';
|
564 |
-
$GLOBALS['csstidy']['all_properties']['voice-pitch-range'] = 'CSS3.0';
|
565 |
-
$GLOBALS['csstidy']['all_properties']['voice-rate'] = 'CSS3.0';
|
566 |
-
$GLOBALS['csstidy']['all_properties']['voice-stress'] = 'CSS3.0';
|
567 |
-
$GLOBALS['csstidy']['all_properties']['voice-volume'] = 'CSS3.0';
|
568 |
-
$GLOBALS['csstidy']['all_properties']['volume'] = 'CSS2.0,CSS2.1,CSS3.0';
|
569 |
-
$GLOBALS['csstidy']['all_properties']['white-space'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
570 |
-
$GLOBALS['csstidy']['all_properties']['widows'] = 'CSS2.0,CSS2.1,CSS3.0';
|
571 |
-
$GLOBALS['csstidy']['all_properties']['width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
572 |
-
$GLOBALS['csstidy']['all_properties']['word-break'] = 'CSS3.0';
|
573 |
-
$GLOBALS['csstidy']['all_properties']['word-spacing'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
574 |
-
$GLOBALS['csstidy']['all_properties']['word-wrap'] = 'CSS3.0';
|
575 |
-
$GLOBALS['csstidy']['all_properties']['z-index'] = 'CSS2.0,CSS2.1,CSS3.0';
|
576 |
-
|
577 |
-
/**
|
578 |
-
* An array containing all properties that can accept a quoted string as a value.
|
579 |
-
*
|
580 |
-
* @global array $GLOBALS['csstidy']['quoted_string_properties']
|
581 |
-
*/
|
582 |
-
$GLOBALS['csstidy']['quoted_string_properties'] = array('content', 'font', 'font-family', 'quotes');
|
583 |
-
|
584 |
-
/**
|
585 |
-
* An array containing all properties that can be defined multiple times without being overwritten.
|
586 |
-
* All unit values are included so that units like rem can be supported with fallbacks to px or em.
|
587 |
-
*
|
588 |
-
* @global array $GLOBALS['csstidy']['quoted_string_properties']
|
589 |
-
*/
|
590 |
-
$GLOBALS['csstidy']['multiple_properties'] = array_merge( $GLOBALS['csstidy']['color_values'], $GLOBALS['csstidy']['unit_values'], array('transition') );
|
591 |
-
|
592 |
-
/**
|
593 |
-
* An array containing all predefined templates.
|
594 |
-
*
|
595 |
-
* @global array $GLOBALS['csstidy']['predefined_templates']
|
596 |
-
* @version 1.0
|
597 |
-
* @see csstidy::load_template()
|
598 |
-
*/
|
599 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="at">'; //string before @rule
|
600 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span> <span class="format">{</span>'."\n"; //bracket after @-rule
|
601 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="selector">'; //string before selector
|
602 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span> <span class="format">{</span>'."\n"; //bracket after selector
|
603 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="property">'; //string before property
|
604 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span><span class="value">'; //string after property+before value
|
605 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span><span class="format">;</span>'."\n"; //string after value
|
606 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="format">}</span>'; //closing bracket - selector
|
607 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = "\n\n"; //space between blocks {...}
|
608 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = "\n".'<span class="format">}</span>'. "\n\n"; //closing bracket @-rule
|
609 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = ''; //indent in @-rule
|
610 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="comment">'; // before comment
|
611 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span>'."\n"; // after comment
|
612 |
-
$GLOBALS['csstidy']['predefined_templates']['default'][] = "\n"; // after last line @-rule
|
613 |
-
|
614 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="at">';
|
615 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span> <span class="format">{</span>'."\n";
|
616 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="selector">';
|
617 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="format">{</span>';
|
618 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="property">';
|
619 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="value">';
|
620 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="format">;</span>';
|
621 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="format">}</span>';
|
622 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = "\n";
|
623 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = "\n". '<span class="format">}'."\n".'</span>';
|
624 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '';
|
625 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="comment">'; // before comment
|
626 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span>'; // after comment
|
627 |
-
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = "\n";
|
628 |
-
|
629 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="at">';
|
630 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">{</span>';
|
631 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="selector">';
|
632 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">{</span>';
|
633 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="property">';
|
634 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="value">';
|
635 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">;</span>';
|
636 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="format">}</span>';
|
637 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '';
|
638 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="format">}</span>';
|
639 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '';
|
640 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="comment">'; // before comment
|
641 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span>'; // after comment
|
642 |
-
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '';
|
643 |
-
|
644 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '<span class="at">';
|
645 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span> <span class="format">{</span>'."\n";
|
646 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '<span class="selector">';
|
647 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span>'."\n".'<span class="format">{</span>'."\n";
|
648 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = ' <span class="property">';
|
649 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span><span class="value">';
|
650 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span><span class="format">;</span>'."\n";
|
651 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '<span class="format">}</span>';
|
652 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = "\n\n";
|
653 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = "\n".'<span class="format">}</span>'."\n\n";
|
654 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = ' ';
|
655 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '<span class="comment">'; // before comment
|
656 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span>'."\n"; // after comment
|
657 |
-
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = "\n";
|
658 |
-
|
659 |
-
require dirname( __FILE__ ) . '/data-wp.inc.php';
|
660 |
-
|
661 |
-
?>
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Various CSS Data for CSSTidy
|
4 |
+
*
|
5 |
+
* This file is part of CSSTidy.
|
6 |
+
*
|
7 |
+
* CSSTidy is free software; you can redistribute it and/or modify
|
8 |
+
* it under the terms of the GNU General Public License as published by
|
9 |
+
* the Free Software Foundation; either version 2 of the License, or
|
10 |
+
* (at your option) any later version.
|
11 |
+
*
|
12 |
+
* CSSTidy is distributed in the hope that it will be useful,
|
13 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
+
* GNU General Public License for more details.
|
16 |
+
*
|
17 |
+
* You should have received a copy of the GNU General Public License
|
18 |
+
* along with CSSTidy; if not, write to the Free Software
|
19 |
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
20 |
+
*
|
21 |
+
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
22 |
+
* @package csstidy
|
23 |
+
* @author Florian Schmitz (floele at gmail dot com) 2005
|
24 |
+
* @author Nikolay Matsievsky (speed at webo dot name) 2010
|
25 |
+
*/
|
26 |
+
|
27 |
+
define('AT_START', 1);
|
28 |
+
define('AT_END', 2);
|
29 |
+
define('SEL_START', 3);
|
30 |
+
define('SEL_END', 4);
|
31 |
+
define('PROPERTY', 5);
|
32 |
+
define('VALUE', 6);
|
33 |
+
define('COMMENT', 7);
|
34 |
+
define('DEFAULT_AT', 41);
|
35 |
+
|
36 |
+
/**
|
37 |
+
* All whitespace allowed in CSS
|
38 |
+
*
|
39 |
+
* @global array $GLOBALS['csstidy']['whitespace']
|
40 |
+
* @version 1.0
|
41 |
+
*/
|
42 |
+
$GLOBALS['csstidy']['whitespace'] = array(' ',"\n","\t","\r","\x0B");
|
43 |
+
|
44 |
+
/**
|
45 |
+
* All CSS tokens used by csstidy
|
46 |
+
*
|
47 |
+
* @global string $GLOBALS['csstidy']['tokens']
|
48 |
+
* @version 1.0
|
49 |
+
*/
|
50 |
+
$GLOBALS['csstidy']['tokens'] = '/@}{;:=\'"(,\\!$%&)*+.<>?[]^`|~';
|
51 |
+
|
52 |
+
/**
|
53 |
+
* All CSS units (CSS 3 units included)
|
54 |
+
*
|
55 |
+
* @see compress_numbers()
|
56 |
+
* @global array $GLOBALS['csstidy']['units']
|
57 |
+
* @version 1.0
|
58 |
+
*/
|
59 |
+
$GLOBALS['csstidy']['units'] = array('in','cm','mm','pt','pc','px','rem','em','%','ex','gd','vw','vh','vm','deg','grad','rad','ms','s','khz','hz');
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Available at-rules
|
63 |
+
*
|
64 |
+
* @global array $GLOBALS['csstidy']['at_rules']
|
65 |
+
* @version 1.0
|
66 |
+
*/
|
67 |
+
$GLOBALS['csstidy']['at_rules'] = array('page' => 'is','font-face' => 'is','charset' => 'iv', 'import' => 'iv','namespace' => 'iv','media' => 'at','keyframes' => 'at');
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Properties that need a value with unit
|
71 |
+
*
|
72 |
+
* @todo CSS3 properties
|
73 |
+
* @see compress_numbers();
|
74 |
+
* @global array $GLOBALS['csstidy']['unit_values']
|
75 |
+
* @version 1.2
|
76 |
+
*/
|
77 |
+
$GLOBALS['csstidy']['unit_values'] = array ('background', 'background-position', 'background-size', 'border', 'border-top', 'border-right', 'border-bottom', 'border-left', 'border-width',
|
78 |
+
'border-top-width', 'border-right-width', 'border-left-width', 'border-bottom-width', 'bottom', 'border-spacing', 'column-gap', 'column-width',
|
79 |
+
'font-size', 'height', 'left', 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', 'max-height',
|
80 |
+
'max-width', 'min-height', 'min-width', 'outline', 'outline-width', 'padding', 'padding-top', 'padding-right',
|
81 |
+
'padding-bottom', 'padding-left', 'perspective', 'right', 'top', 'text-indent', 'letter-spacing', 'word-spacing', 'width');
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Properties that allow <color> as value
|
85 |
+
*
|
86 |
+
* @todo CSS3 properties
|
87 |
+
* @see compress_numbers();
|
88 |
+
* @global array $GLOBALS['csstidy']['color_values']
|
89 |
+
* @version 1.0
|
90 |
+
*/
|
91 |
+
$GLOBALS['csstidy']['color_values'] = array();
|
92 |
+
$GLOBALS['csstidy']['color_values'][] = 'background-color';
|
93 |
+
$GLOBALS['csstidy']['color_values'][] = 'border-color';
|
94 |
+
$GLOBALS['csstidy']['color_values'][] = 'border-top-color';
|
95 |
+
$GLOBALS['csstidy']['color_values'][] = 'border-right-color';
|
96 |
+
$GLOBALS['csstidy']['color_values'][] = 'border-bottom-color';
|
97 |
+
$GLOBALS['csstidy']['color_values'][] = 'border-left-color';
|
98 |
+
$GLOBALS['csstidy']['color_values'][] = 'color';
|
99 |
+
$GLOBALS['csstidy']['color_values'][] = 'outline-color';
|
100 |
+
$GLOBALS['csstidy']['color_values'][] = 'column-rule-color';
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Default values for the background properties
|
104 |
+
*
|
105 |
+
* @todo Possibly property names will change during CSS3 development
|
106 |
+
* @global array $GLOBALS['csstidy']['background_prop_default']
|
107 |
+
* @see dissolve_short_bg()
|
108 |
+
* @see merge_bg()
|
109 |
+
* @version 1.0
|
110 |
+
*/
|
111 |
+
$GLOBALS['csstidy']['background_prop_default'] = array();
|
112 |
+
$GLOBALS['csstidy']['background_prop_default']['background-image'] = 'none';
|
113 |
+
$GLOBALS['csstidy']['background_prop_default']['background-size'] = 'auto';
|
114 |
+
$GLOBALS['csstidy']['background_prop_default']['background-repeat'] = 'repeat';
|
115 |
+
$GLOBALS['csstidy']['background_prop_default']['background-position'] = '0 0';
|
116 |
+
$GLOBALS['csstidy']['background_prop_default']['background-attachment'] = 'scroll';
|
117 |
+
$GLOBALS['csstidy']['background_prop_default']['background-clip'] = 'border';
|
118 |
+
$GLOBALS['csstidy']['background_prop_default']['background-origin'] = 'padding';
|
119 |
+
$GLOBALS['csstidy']['background_prop_default']['background-color'] = 'transparent';
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Default values for the font properties
|
123 |
+
*
|
124 |
+
* @global array $GLOBALS['csstidy']['font_prop_default']
|
125 |
+
* @see merge_fonts()
|
126 |
+
* @version 1.3
|
127 |
+
*/
|
128 |
+
$GLOBALS['csstidy']['font_prop_default'] = array();
|
129 |
+
$GLOBALS['csstidy']['font_prop_default']['font-style'] = 'normal';
|
130 |
+
$GLOBALS['csstidy']['font_prop_default']['font-variant'] = 'normal';
|
131 |
+
$GLOBALS['csstidy']['font_prop_default']['font-weight'] = 'normal';
|
132 |
+
$GLOBALS['csstidy']['font_prop_default']['font-size'] = '';
|
133 |
+
$GLOBALS['csstidy']['font_prop_default']['line-height'] = '';
|
134 |
+
$GLOBALS['csstidy']['font_prop_default']['font-family'] = '';
|
135 |
+
|
136 |
+
/**
|
137 |
+
* A list of non-W3C color names which get replaced by their hex-codes
|
138 |
+
*
|
139 |
+
* @global array $GLOBALS['csstidy']['replace_colors']
|
140 |
+
* @see cut_color()
|
141 |
+
* @version 1.0
|
142 |
+
*/
|
143 |
+
$GLOBALS['csstidy']['replace_colors'] = array();
|
144 |
+
$GLOBALS['csstidy']['replace_colors']['aliceblue'] = '#f0f8ff';
|
145 |
+
$GLOBALS['csstidy']['replace_colors']['antiquewhite'] = '#faebd7';
|
146 |
+
$GLOBALS['csstidy']['replace_colors']['aquamarine'] = '#7fffd4';
|
147 |
+
$GLOBALS['csstidy']['replace_colors']['azure'] = '#f0ffff';
|
148 |
+
$GLOBALS['csstidy']['replace_colors']['beige'] = '#f5f5dc';
|
149 |
+
$GLOBALS['csstidy']['replace_colors']['bisque'] = '#ffe4c4';
|
150 |
+
$GLOBALS['csstidy']['replace_colors']['blanchedalmond'] = '#ffebcd';
|
151 |
+
$GLOBALS['csstidy']['replace_colors']['blueviolet'] = '#8a2be2';
|
152 |
+
$GLOBALS['csstidy']['replace_colors']['brown'] = '#a52a2a';
|
153 |
+
$GLOBALS['csstidy']['replace_colors']['burlywood'] = '#deb887';
|
154 |
+
$GLOBALS['csstidy']['replace_colors']['cadetblue'] = '#5f9ea0';
|
155 |
+
$GLOBALS['csstidy']['replace_colors']['chartreuse'] = '#7fff00';
|
156 |
+
$GLOBALS['csstidy']['replace_colors']['chocolate'] = '#d2691e';
|
157 |
+
$GLOBALS['csstidy']['replace_colors']['coral'] = '#ff7f50';
|
158 |
+
$GLOBALS['csstidy']['replace_colors']['cornflowerblue'] = '#6495ed';
|
159 |
+
$GLOBALS['csstidy']['replace_colors']['cornsilk'] = '#fff8dc';
|
160 |
+
$GLOBALS['csstidy']['replace_colors']['crimson'] = '#dc143c';
|
161 |
+
$GLOBALS['csstidy']['replace_colors']['cyan'] = '#00ffff';
|
162 |
+
$GLOBALS['csstidy']['replace_colors']['darkblue'] = '#00008b';
|
163 |
+
$GLOBALS['csstidy']['replace_colors']['darkcyan'] = '#008b8b';
|
164 |
+
$GLOBALS['csstidy']['replace_colors']['darkgoldenrod'] = '#b8860b';
|
165 |
+
$GLOBALS['csstidy']['replace_colors']['darkgray'] = '#a9a9a9';
|
166 |
+
$GLOBALS['csstidy']['replace_colors']['darkgreen'] = '#006400';
|
167 |
+
$GLOBALS['csstidy']['replace_colors']['darkkhaki'] = '#bdb76b';
|
168 |
+
$GLOBALS['csstidy']['replace_colors']['darkmagenta'] = '#8b008b';
|
169 |
+
$GLOBALS['csstidy']['replace_colors']['darkolivegreen'] = '#556b2f';
|
170 |
+
$GLOBALS['csstidy']['replace_colors']['darkorange'] = '#ff8c00';
|
171 |
+
$GLOBALS['csstidy']['replace_colors']['darkorchid'] = '#9932cc';
|
172 |
+
$GLOBALS['csstidy']['replace_colors']['darkred'] = '#8b0000';
|
173 |
+
$GLOBALS['csstidy']['replace_colors']['darksalmon'] = '#e9967a';
|
174 |
+
$GLOBALS['csstidy']['replace_colors']['darkseagreen'] = '#8fbc8f';
|
175 |
+
$GLOBALS['csstidy']['replace_colors']['darkslateblue'] = '#483d8b';
|
176 |
+
$GLOBALS['csstidy']['replace_colors']['darkslategray'] = '#2f4f4f';
|
177 |
+
$GLOBALS['csstidy']['replace_colors']['darkturquoise'] = '#00ced1';
|
178 |
+
$GLOBALS['csstidy']['replace_colors']['darkviolet'] = '#9400d3';
|
179 |
+
$GLOBALS['csstidy']['replace_colors']['deeppink'] = '#ff1493';
|
180 |
+
$GLOBALS['csstidy']['replace_colors']['deepskyblue'] = '#00bfff';
|
181 |
+
$GLOBALS['csstidy']['replace_colors']['dimgray'] = '#696969';
|
182 |
+
$GLOBALS['csstidy']['replace_colors']['dodgerblue'] = '#1e90ff';
|
183 |
+
$GLOBALS['csstidy']['replace_colors']['feldspar'] = '#d19275';
|
184 |
+
$GLOBALS['csstidy']['replace_colors']['firebrick'] = '#b22222';
|
185 |
+
$GLOBALS['csstidy']['replace_colors']['floralwhite'] = '#fffaf0';
|
186 |
+
$GLOBALS['csstidy']['replace_colors']['forestgreen'] = '#228b22';
|
187 |
+
$GLOBALS['csstidy']['replace_colors']['gainsboro'] = '#dcdcdc';
|
188 |
+
$GLOBALS['csstidy']['replace_colors']['ghostwhite'] = '#f8f8ff';
|
189 |
+
$GLOBALS['csstidy']['replace_colors']['gold'] = '#ffd700';
|
190 |
+
$GLOBALS['csstidy']['replace_colors']['goldenrod'] = '#daa520';
|
191 |
+
$GLOBALS['csstidy']['replace_colors']['greenyellow'] = '#adff2f';
|
192 |
+
$GLOBALS['csstidy']['replace_colors']['honeydew'] = '#f0fff0';
|
193 |
+
$GLOBALS['csstidy']['replace_colors']['hotpink'] = '#ff69b4';
|
194 |
+
$GLOBALS['csstidy']['replace_colors']['indianred'] = '#cd5c5c';
|
195 |
+
$GLOBALS['csstidy']['replace_colors']['indigo'] = '#4b0082';
|
196 |
+
$GLOBALS['csstidy']['replace_colors']['ivory'] = '#fffff0';
|
197 |
+
$GLOBALS['csstidy']['replace_colors']['khaki'] = '#f0e68c';
|
198 |
+
$GLOBALS['csstidy']['replace_colors']['lavender'] = '#e6e6fa';
|
199 |
+
$GLOBALS['csstidy']['replace_colors']['lavenderblush'] = '#fff0f5';
|
200 |
+
$GLOBALS['csstidy']['replace_colors']['lawngreen'] = '#7cfc00';
|
201 |
+
$GLOBALS['csstidy']['replace_colors']['lemonchiffon'] = '#fffacd';
|
202 |
+
$GLOBALS['csstidy']['replace_colors']['lightblue'] = '#add8e6';
|
203 |
+
$GLOBALS['csstidy']['replace_colors']['lightcoral'] = '#f08080';
|
204 |
+
$GLOBALS['csstidy']['replace_colors']['lightcyan'] = '#e0ffff';
|
205 |
+
$GLOBALS['csstidy']['replace_colors']['lightgoldenrodyellow'] = '#fafad2';
|
206 |
+
$GLOBALS['csstidy']['replace_colors']['lightgrey'] = '#d3d3d3';
|
207 |
+
$GLOBALS['csstidy']['replace_colors']['lightgreen'] = '#90ee90';
|
208 |
+
$GLOBALS['csstidy']['replace_colors']['lightpink'] = '#ffb6c1';
|
209 |
+
$GLOBALS['csstidy']['replace_colors']['lightsalmon'] = '#ffa07a';
|
210 |
+
$GLOBALS['csstidy']['replace_colors']['lightseagreen'] = '#20b2aa';
|
211 |
+
$GLOBALS['csstidy']['replace_colors']['lightskyblue'] = '#87cefa';
|
212 |
+
$GLOBALS['csstidy']['replace_colors']['lightslateblue'] = '#8470ff';
|
213 |
+
$GLOBALS['csstidy']['replace_colors']['lightslategray'] = '#778899';
|
214 |
+
$GLOBALS['csstidy']['replace_colors']['lightsteelblue'] = '#b0c4de';
|
215 |
+
$GLOBALS['csstidy']['replace_colors']['lightyellow'] = '#ffffe0';
|
216 |
+
$GLOBALS['csstidy']['replace_colors']['limegreen'] = '#32cd32';
|
217 |
+
$GLOBALS['csstidy']['replace_colors']['linen'] = '#faf0e6';
|
218 |
+
$GLOBALS['csstidy']['replace_colors']['magenta'] = '#ff00ff';
|
219 |
+
$GLOBALS['csstidy']['replace_colors']['mediumaquamarine'] = '#66cdaa';
|
220 |
+
$GLOBALS['csstidy']['replace_colors']['mediumblue'] = '#0000cd';
|
221 |
+
$GLOBALS['csstidy']['replace_colors']['mediumorchid'] = '#ba55d3';
|
222 |
+
$GLOBALS['csstidy']['replace_colors']['mediumpurple'] = '#9370d8';
|
223 |
+
$GLOBALS['csstidy']['replace_colors']['mediumseagreen'] = '#3cb371';
|
224 |
+
$GLOBALS['csstidy']['replace_colors']['mediumslateblue'] = '#7b68ee';
|
225 |
+
$GLOBALS['csstidy']['replace_colors']['mediumspringgreen'] = '#00fa9a';
|
226 |
+
$GLOBALS['csstidy']['replace_colors']['mediumturquoise'] = '#48d1cc';
|
227 |
+
$GLOBALS['csstidy']['replace_colors']['mediumvioletred'] = '#c71585';
|
228 |
+
$GLOBALS['csstidy']['replace_colors']['midnightblue'] = '#191970';
|
229 |
+
$GLOBALS['csstidy']['replace_colors']['mintcream'] = '#f5fffa';
|
230 |
+
$GLOBALS['csstidy']['replace_colors']['mistyrose'] = '#ffe4e1';
|
231 |
+
$GLOBALS['csstidy']['replace_colors']['moccasin'] = '#ffe4b5';
|
232 |
+
$GLOBALS['csstidy']['replace_colors']['navajowhite'] = '#ffdead';
|
233 |
+
$GLOBALS['csstidy']['replace_colors']['oldlace'] = '#fdf5e6';
|
234 |
+
$GLOBALS['csstidy']['replace_colors']['olivedrab'] = '#6b8e23';
|
235 |
+
$GLOBALS['csstidy']['replace_colors']['orangered'] = '#ff4500';
|
236 |
+
$GLOBALS['csstidy']['replace_colors']['orchid'] = '#da70d6';
|
237 |
+
$GLOBALS['csstidy']['replace_colors']['palegoldenrod'] = '#eee8aa';
|
238 |
+
$GLOBALS['csstidy']['replace_colors']['palegreen'] = '#98fb98';
|
239 |
+
$GLOBALS['csstidy']['replace_colors']['paleturquoise'] = '#afeeee';
|
240 |
+
$GLOBALS['csstidy']['replace_colors']['palevioletred'] = '#d87093';
|
241 |
+
$GLOBALS['csstidy']['replace_colors']['papayawhip'] = '#ffefd5';
|
242 |
+
$GLOBALS['csstidy']['replace_colors']['peachpuff'] = '#ffdab9';
|
243 |
+
$GLOBALS['csstidy']['replace_colors']['peru'] = '#cd853f';
|
244 |
+
$GLOBALS['csstidy']['replace_colors']['pink'] = '#ffc0cb';
|
245 |
+
$GLOBALS['csstidy']['replace_colors']['plum'] = '#dda0dd';
|
246 |
+
$GLOBALS['csstidy']['replace_colors']['powderblue'] = '#b0e0e6';
|
247 |
+
$GLOBALS['csstidy']['replace_colors']['rosybrown'] = '#bc8f8f';
|
248 |
+
$GLOBALS['csstidy']['replace_colors']['royalblue'] = '#4169e1';
|
249 |
+
$GLOBALS['csstidy']['replace_colors']['saddlebrown'] = '#8b4513';
|
250 |
+
$GLOBALS['csstidy']['replace_colors']['salmon'] = '#fa8072';
|
251 |
+
$GLOBALS['csstidy']['replace_colors']['sandybrown'] = '#f4a460';
|
252 |
+
$GLOBALS['csstidy']['replace_colors']['seagreen'] = '#2e8b57';
|
253 |
+
$GLOBALS['csstidy']['replace_colors']['seashell'] = '#fff5ee';
|
254 |
+
$GLOBALS['csstidy']['replace_colors']['sienna'] = '#a0522d';
|
255 |
+
$GLOBALS['csstidy']['replace_colors']['skyblue'] = '#87ceeb';
|
256 |
+
$GLOBALS['csstidy']['replace_colors']['slateblue'] = '#6a5acd';
|
257 |
+
$GLOBALS['csstidy']['replace_colors']['slategray'] = '#708090';
|
258 |
+
$GLOBALS['csstidy']['replace_colors']['snow'] = '#fffafa';
|
259 |
+
$GLOBALS['csstidy']['replace_colors']['springgreen'] = '#00ff7f';
|
260 |
+
$GLOBALS['csstidy']['replace_colors']['steelblue'] = '#4682b4';
|
261 |
+
$GLOBALS['csstidy']['replace_colors']['tan'] = '#d2b48c';
|
262 |
+
$GLOBALS['csstidy']['replace_colors']['thistle'] = '#d8bfd8';
|
263 |
+
$GLOBALS['csstidy']['replace_colors']['tomato'] = '#ff6347';
|
264 |
+
$GLOBALS['csstidy']['replace_colors']['turquoise'] = '#40e0d0';
|
265 |
+
$GLOBALS['csstidy']['replace_colors']['violet'] = '#ee82ee';
|
266 |
+
$GLOBALS['csstidy']['replace_colors']['violetred'] = '#d02090';
|
267 |
+
$GLOBALS['csstidy']['replace_colors']['wheat'] = '#f5deb3';
|
268 |
+
$GLOBALS['csstidy']['replace_colors']['whitesmoke'] = '#f5f5f5';
|
269 |
+
$GLOBALS['csstidy']['replace_colors']['yellowgreen'] = '#9acd32';
|
270 |
+
|
271 |
+
/**
|
272 |
+
* A list of all shorthand properties that are devided into four properties and/or have four subvalues
|
273 |
+
*
|
274 |
+
* @global array $GLOBALS['csstidy']['shorthands']
|
275 |
+
* @todo Are there new ones in CSS3?
|
276 |
+
* @see dissolve_4value_shorthands()
|
277 |
+
* @see merge_4value_shorthands()
|
278 |
+
* @version 1.0
|
279 |
+
*/
|
280 |
+
$GLOBALS['csstidy']['shorthands'] = array();
|
281 |
+
$GLOBALS['csstidy']['shorthands']['border-color'] = array('border-top-color','border-right-color','border-bottom-color','border-left-color');
|
282 |
+
$GLOBALS['csstidy']['shorthands']['border-style'] = array('border-top-style','border-right-style','border-bottom-style','border-left-style');
|
283 |
+
$GLOBALS['csstidy']['shorthands']['border-width'] = array('border-top-width','border-right-width','border-bottom-width','border-left-width');
|
284 |
+
$GLOBALS['csstidy']['shorthands']['margin'] = array('margin-top','margin-right','margin-bottom','margin-left');
|
285 |
+
$GLOBALS['csstidy']['shorthands']['padding'] = array('padding-top','padding-right','padding-bottom','padding-left');
|
286 |
+
$GLOBALS['csstidy']['shorthands']['-moz-border-radius'] = 0;
|
287 |
+
|
288 |
+
/**
|
289 |
+
* All CSS Properties. Needed for csstidy::property_is_next()
|
290 |
+
*
|
291 |
+
* @global array $GLOBALS['csstidy']['all_properties']
|
292 |
+
* @todo Add CSS3 properties
|
293 |
+
* @version 1.0
|
294 |
+
* @see csstidy::property_is_next()
|
295 |
+
*/
|
296 |
+
$GLOBALS['csstidy']['all_properties']['alignment-adjust'] = 'CSS3.0';
|
297 |
+
$GLOBALS['csstidy']['all_properties']['alignment-baseline'] = 'CSS3.0';
|
298 |
+
$GLOBALS['csstidy']['all_properties']['animation'] = 'CSS3.0';
|
299 |
+
$GLOBALS['csstidy']['all_properties']['animation-delay'] = 'CSS3.0';
|
300 |
+
$GLOBALS['csstidy']['all_properties']['animation-direction'] = 'CSS3.0';
|
301 |
+
$GLOBALS['csstidy']['all_properties']['animation-duration'] = 'CSS3.0';
|
302 |
+
$GLOBALS['csstidy']['all_properties']['animation-iteration-count'] = 'CSS3.0';
|
303 |
+
$GLOBALS['csstidy']['all_properties']['animation-name'] = 'CSS3.0';
|
304 |
+
$GLOBALS['csstidy']['all_properties']['animation-play-state'] = 'CSS3.0';
|
305 |
+
$GLOBALS['csstidy']['all_properties']['animation-timing-function'] = 'CSS3.0';
|
306 |
+
$GLOBALS['csstidy']['all_properties']['appearance'] = 'CSS3.0';
|
307 |
+
$GLOBALS['csstidy']['all_properties']['azimuth'] = 'CSS2.0,CSS2.1,CSS3.0';
|
308 |
+
$GLOBALS['csstidy']['all_properties']['backface-visibility'] = 'CSS3.0';
|
309 |
+
$GLOBALS['csstidy']['all_properties']['background'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
310 |
+
$GLOBALS['csstidy']['all_properties']['background-attachment'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
311 |
+
$GLOBALS['csstidy']['all_properties']['background-clip'] = 'CSS3.0';
|
312 |
+
$GLOBALS['csstidy']['all_properties']['background-color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
313 |
+
$GLOBALS['csstidy']['all_properties']['background-image'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
314 |
+
$GLOBALS['csstidy']['all_properties']['background-origin'] = 'CSS3.0';
|
315 |
+
$GLOBALS['csstidy']['all_properties']['background-position'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
316 |
+
$GLOBALS['csstidy']['all_properties']['background-repeat'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
317 |
+
$GLOBALS['csstidy']['all_properties']['background-size'] = 'CSS3.0';
|
318 |
+
$GLOBALS['csstidy']['all_properties']['baseline-shift'] = 'CSS3.0';
|
319 |
+
$GLOBALS['csstidy']['all_properties']['binding'] = 'CSS3.0';
|
320 |
+
$GLOBALS['csstidy']['all_properties']['bleed'] = 'CSS3.0';
|
321 |
+
$GLOBALS['csstidy']['all_properties']['bookmark-label'] = 'CSS3.0';
|
322 |
+
$GLOBALS['csstidy']['all_properties']['bookmark-level'] = 'CSS3.0';
|
323 |
+
$GLOBALS['csstidy']['all_properties']['bookmark-state'] = 'CSS3.0';
|
324 |
+
$GLOBALS['csstidy']['all_properties']['bookmark-target'] = 'CSS3.0';
|
325 |
+
$GLOBALS['csstidy']['all_properties']['border'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
326 |
+
$GLOBALS['csstidy']['all_properties']['border-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
327 |
+
$GLOBALS['csstidy']['all_properties']['border-bottom-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
328 |
+
$GLOBALS['csstidy']['all_properties']['border-bottom-left-radius'] = 'CSS3.0';
|
329 |
+
$GLOBALS['csstidy']['all_properties']['border-bottom-right-radius'] = 'CSS3.0';
|
330 |
+
$GLOBALS['csstidy']['all_properties']['border-bottom-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
331 |
+
$GLOBALS['csstidy']['all_properties']['border-bottom-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
332 |
+
$GLOBALS['csstidy']['all_properties']['border-collapse'] = 'CSS2.0,CSS2.1,CSS3.0';
|
333 |
+
$GLOBALS['csstidy']['all_properties']['border-color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
334 |
+
$GLOBALS['csstidy']['all_properties']['border-image'] = 'CSS3.0';
|
335 |
+
$GLOBALS['csstidy']['all_properties']['border-image-outset'] = 'CSS3.0';
|
336 |
+
$GLOBALS['csstidy']['all_properties']['border-image-repeat'] = 'CSS3.0';
|
337 |
+
$GLOBALS['csstidy']['all_properties']['border-image-slice'] = 'CSS3.0';
|
338 |
+
$GLOBALS['csstidy']['all_properties']['border-image-source'] = 'CSS3.0';
|
339 |
+
$GLOBALS['csstidy']['all_properties']['border-image-width'] = 'CSS3.0';
|
340 |
+
$GLOBALS['csstidy']['all_properties']['border-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
341 |
+
$GLOBALS['csstidy']['all_properties']['border-left-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
342 |
+
$GLOBALS['csstidy']['all_properties']['border-left-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
343 |
+
$GLOBALS['csstidy']['all_properties']['border-left-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
344 |
+
$GLOBALS['csstidy']['all_properties']['border-radius'] = 'CSS3.0';
|
345 |
+
$GLOBALS['csstidy']['all_properties']['border-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
346 |
+
$GLOBALS['csstidy']['all_properties']['border-right-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
347 |
+
$GLOBALS['csstidy']['all_properties']['border-right-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
348 |
+
$GLOBALS['csstidy']['all_properties']['border-right-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
349 |
+
$GLOBALS['csstidy']['all_properties']['border-spacing'] = 'CSS2.0,CSS2.1,CSS3.0';
|
350 |
+
$GLOBALS['csstidy']['all_properties']['border-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
351 |
+
$GLOBALS['csstidy']['all_properties']['border-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
352 |
+
$GLOBALS['csstidy']['all_properties']['border-top-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
353 |
+
$GLOBALS['csstidy']['all_properties']['border-top-left-radius'] = 'CSS3.0';
|
354 |
+
$GLOBALS['csstidy']['all_properties']['border-top-right-radius'] = 'CSS3.0';
|
355 |
+
$GLOBALS['csstidy']['all_properties']['border-top-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
356 |
+
$GLOBALS['csstidy']['all_properties']['border-top-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
357 |
+
$GLOBALS['csstidy']['all_properties']['border-width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
358 |
+
$GLOBALS['csstidy']['all_properties']['bottom'] = 'CSS2.0,CSS2.1,CSS3.0';
|
359 |
+
$GLOBALS['csstidy']['all_properties']['box-decoration-break'] = 'CSS3.0';
|
360 |
+
$GLOBALS['csstidy']['all_properties']['box-shadow'] = 'CSS3.0';
|
361 |
+
$GLOBALS['csstidy']['all_properties']['box-sizing'] = 'CSS3.0';
|
362 |
+
$GLOBALS['csstidy']['all_properties']['break-after'] = 'CSS3.0';
|
363 |
+
$GLOBALS['csstidy']['all_properties']['break-before'] = 'CSS3.0';
|
364 |
+
$GLOBALS['csstidy']['all_properties']['break-inside'] = 'CSS3.0';
|
365 |
+
$GLOBALS['csstidy']['all_properties']['caption-side'] = 'CSS2.0,CSS2.1,CSS3.0';
|
366 |
+
$GLOBALS['csstidy']['all_properties']['clear'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
367 |
+
$GLOBALS['csstidy']['all_properties']['clip'] = 'CSS2.0,CSS2.1,CSS3.0';
|
368 |
+
$GLOBALS['csstidy']['all_properties']['color'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
369 |
+
$GLOBALS['csstidy']['all_properties']['color-profile'] = 'CSS3.0';
|
370 |
+
$GLOBALS['csstidy']['all_properties']['column-count'] = 'CSS3.0';
|
371 |
+
$GLOBALS['csstidy']['all_properties']['column-fill'] = 'CSS3.0';
|
372 |
+
$GLOBALS['csstidy']['all_properties']['column-gap'] = 'CSS3.0';
|
373 |
+
$GLOBALS['csstidy']['all_properties']['column-rule'] = 'CSS3.0';
|
374 |
+
$GLOBALS['csstidy']['all_properties']['column-rule-color'] = 'CSS3.0';
|
375 |
+
$GLOBALS['csstidy']['all_properties']['column-rule-style'] = 'CSS3.0';
|
376 |
+
$GLOBALS['csstidy']['all_properties']['column-rule-width'] = 'CSS3.0';
|
377 |
+
$GLOBALS['csstidy']['all_properties']['column-span'] = 'CSS3.0';
|
378 |
+
$GLOBALS['csstidy']['all_properties']['column-width'] = 'CSS3.0';
|
379 |
+
$GLOBALS['csstidy']['all_properties']['columns'] = 'CSS3.0';
|
380 |
+
$GLOBALS['csstidy']['all_properties']['content'] = 'CSS2.0,CSS2.1,CSS3.0';
|
381 |
+
$GLOBALS['csstidy']['all_properties']['counter-increment'] = 'CSS2.0,CSS2.1,CSS3.0';
|
382 |
+
$GLOBALS['csstidy']['all_properties']['counter-reset'] = 'CSS2.0,CSS2.1,CSS3.0';
|
383 |
+
$GLOBALS['csstidy']['all_properties']['crop'] = 'CSS3.0';
|
384 |
+
$GLOBALS['csstidy']['all_properties']['cue'] = 'CSS2.0,CSS2.1,CSS3.0';
|
385 |
+
$GLOBALS['csstidy']['all_properties']['cue-after'] = 'CSS2.0,CSS2.1,CSS3.0';
|
386 |
+
$GLOBALS['csstidy']['all_properties']['cue-before'] = 'CSS2.0,CSS2.1,CSS3.0';
|
387 |
+
$GLOBALS['csstidy']['all_properties']['cursor'] = 'CSS2.0,CSS2.1,CSS3.0';
|
388 |
+
$GLOBALS['csstidy']['all_properties']['direction'] = 'CSS2.0,CSS2.1,CSS3.0';
|
389 |
+
$GLOBALS['csstidy']['all_properties']['display'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
390 |
+
$GLOBALS['csstidy']['all_properties']['dominant-baseline'] = 'CSS3.0';
|
391 |
+
$GLOBALS['csstidy']['all_properties']['drop-initial-after-adjust'] = 'CSS3.0';
|
392 |
+
$GLOBALS['csstidy']['all_properties']['drop-initial-after-align'] = 'CSS3.0';
|
393 |
+
$GLOBALS['csstidy']['all_properties']['drop-initial-before-adjust'] = 'CSS3.0';
|
394 |
+
$GLOBALS['csstidy']['all_properties']['drop-initial-before-align'] = 'CSS3.0';
|
395 |
+
$GLOBALS['csstidy']['all_properties']['drop-initial-size'] = 'CSS3.0';
|
396 |
+
$GLOBALS['csstidy']['all_properties']['drop-initial-value'] = 'CSS3.0';
|
397 |
+
$GLOBALS['csstidy']['all_properties']['elevation'] = 'CSS2.0,CSS2.1,CSS3.0';
|
398 |
+
$GLOBALS['csstidy']['all_properties']['empty-cells'] = 'CSS2.0,CSS2.1,CSS3.0';
|
399 |
+
$GLOBALS['csstidy']['all_properties']['fit'] = 'CSS3.0';
|
400 |
+
$GLOBALS['csstidy']['all_properties']['fit-position'] = 'CSS3.0';
|
401 |
+
$GLOBALS['csstidy']['all_properties']['flex-align'] = 'CSS3.0';
|
402 |
+
$GLOBALS['csstidy']['all_properties']['flex-flow'] = 'CSS3.0';
|
403 |
+
$GLOBALS['csstidy']['all_properties']['flex-line-pack'] = 'CSS3.0';
|
404 |
+
$GLOBALS['csstidy']['all_properties']['flex-order'] = 'CSS3.0';
|
405 |
+
$GLOBALS['csstidy']['all_properties']['flex-pack'] = 'CSS3.0';
|
406 |
+
$GLOBALS['csstidy']['all_properties']['float'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
407 |
+
$GLOBALS['csstidy']['all_properties']['float-offset'] = 'CSS3.0';
|
408 |
+
$GLOBALS['csstidy']['all_properties']['font'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
409 |
+
$GLOBALS['csstidy']['all_properties']['font-family'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
410 |
+
$GLOBALS['csstidy']['all_properties']['font-size'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
411 |
+
$GLOBALS['csstidy']['all_properties']['font-size-adjust'] = 'CSS2.0,CSS3.0';
|
412 |
+
$GLOBALS['csstidy']['all_properties']['font-stretch'] = 'CSS2.0,CSS3.0';
|
413 |
+
$GLOBALS['csstidy']['all_properties']['font-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
414 |
+
$GLOBALS['csstidy']['all_properties']['font-variant'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
415 |
+
$GLOBALS['csstidy']['all_properties']['font-weight'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
416 |
+
$GLOBALS['csstidy']['all_properties']['grid-columns'] = 'CSS3.0';
|
417 |
+
$GLOBALS['csstidy']['all_properties']['grid-rows'] = 'CSS3.0';
|
418 |
+
$GLOBALS['csstidy']['all_properties']['hanging-punctuation'] = 'CSS3.0';
|
419 |
+
$GLOBALS['csstidy']['all_properties']['height'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
420 |
+
$GLOBALS['csstidy']['all_properties']['hyphenate-after'] = 'CSS3.0';
|
421 |
+
$GLOBALS['csstidy']['all_properties']['hyphenate-before'] = 'CSS3.0';
|
422 |
+
$GLOBALS['csstidy']['all_properties']['hyphenate-character'] = 'CSS3.0';
|
423 |
+
$GLOBALS['csstidy']['all_properties']['hyphenate-lines'] = 'CSS3.0';
|
424 |
+
$GLOBALS['csstidy']['all_properties']['hyphenate-resource'] = 'CSS3.0';
|
425 |
+
$GLOBALS['csstidy']['all_properties']['hyphens'] = 'CSS3.0';
|
426 |
+
$GLOBALS['csstidy']['all_properties']['icon'] = 'CSS3.0';
|
427 |
+
$GLOBALS['csstidy']['all_properties']['image-orientation'] = 'CSS3.0';
|
428 |
+
$GLOBALS['csstidy']['all_properties']['image-rendering'] = 'CSS3.0';
|
429 |
+
$GLOBALS['csstidy']['all_properties']['image-resolution'] = 'CSS3.0';
|
430 |
+
$GLOBALS['csstidy']['all_properties']['inline-box-align'] = 'CSS3.0';
|
431 |
+
$GLOBALS['csstidy']['all_properties']['left'] = 'CSS2.0,CSS2.1,CSS3.0';
|
432 |
+
$GLOBALS['csstidy']['all_properties']['letter-spacing'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
433 |
+
$GLOBALS['csstidy']['all_properties']['line-break'] = 'CSS3.0';
|
434 |
+
$GLOBALS['csstidy']['all_properties']['line-height'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
435 |
+
$GLOBALS['csstidy']['all_properties']['line-stacking'] = 'CSS3.0';
|
436 |
+
$GLOBALS['csstidy']['all_properties']['line-stacking-ruby'] = 'CSS3.0';
|
437 |
+
$GLOBALS['csstidy']['all_properties']['line-stacking-shift'] = 'CSS3.0';
|
438 |
+
$GLOBALS['csstidy']['all_properties']['line-stacking-strategy'] = 'CSS3.0';
|
439 |
+
$GLOBALS['csstidy']['all_properties']['list-style'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
440 |
+
$GLOBALS['csstidy']['all_properties']['list-style-image'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
441 |
+
$GLOBALS['csstidy']['all_properties']['list-style-position'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
442 |
+
$GLOBALS['csstidy']['all_properties']['list-style-type'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
443 |
+
$GLOBALS['csstidy']['all_properties']['margin'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
444 |
+
$GLOBALS['csstidy']['all_properties']['margin-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
445 |
+
$GLOBALS['csstidy']['all_properties']['margin-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
446 |
+
$GLOBALS['csstidy']['all_properties']['margin-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
447 |
+
$GLOBALS['csstidy']['all_properties']['margin-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
448 |
+
$GLOBALS['csstidy']['all_properties']['marker-offset'] = 'CSS3.0';
|
449 |
+
$GLOBALS['csstidy']['all_properties']['marks'] = 'CSS2.0,CSS3.0';
|
450 |
+
$GLOBALS['csstidy']['all_properties']['marquee-direction'] = 'CSS3.0';
|
451 |
+
$GLOBALS['csstidy']['all_properties']['marquee-loop'] = 'CSS3.0';
|
452 |
+
$GLOBALS['csstidy']['all_properties']['marquee-play-count'] = 'CSS3.0';
|
453 |
+
$GLOBALS['csstidy']['all_properties']['marquee-speed'] = 'CSS3.0';
|
454 |
+
$GLOBALS['csstidy']['all_properties']['marquee-style'] = 'CSS3.0';
|
455 |
+
$GLOBALS['csstidy']['all_properties']['max-height'] = 'CSS2.0,CSS2.1,CSS3.0';
|
456 |
+
$GLOBALS['csstidy']['all_properties']['max-width'] = 'CSS2.0,CSS2.1,CSS3.0';
|
457 |
+
$GLOBALS['csstidy']['all_properties']['min-height'] = 'CSS2.0,CSS2.1,CSS3.0';
|
458 |
+
$GLOBALS['csstidy']['all_properties']['min-width'] = 'CSS2.0,CSS2.1,CSS3.0';
|
459 |
+
$GLOBALS['csstidy']['all_properties']['move-to'] = 'CSS3.0';
|
460 |
+
$GLOBALS['csstidy']['all_properties']['nav-down'] = 'CSS3.0';
|
461 |
+
$GLOBALS['csstidy']['all_properties']['nav-index'] = 'CSS3.0';
|
462 |
+
$GLOBALS['csstidy']['all_properties']['nav-left'] = 'CSS3.0';
|
463 |
+
$GLOBALS['csstidy']['all_properties']['nav-right'] = 'CSS3.0';
|
464 |
+
$GLOBALS['csstidy']['all_properties']['nav-up'] = 'CSS3.0';
|
465 |
+
$GLOBALS['csstidy']['all_properties']['opacity'] = 'CSS3.0';
|
466 |
+
$GLOBALS['csstidy']['all_properties']['orphans'] = 'CSS2.0,CSS2.1,CSS3.0';
|
467 |
+
$GLOBALS['csstidy']['all_properties']['outline'] = 'CSS2.0,CSS2.1,CSS3.0';
|
468 |
+
$GLOBALS['csstidy']['all_properties']['outline-color'] = 'CSS2.0,CSS2.1,CSS3.0';
|
469 |
+
$GLOBALS['csstidy']['all_properties']['outline-offset'] = 'CSS3.0';
|
470 |
+
$GLOBALS['csstidy']['all_properties']['outline-style'] = 'CSS2.0,CSS2.1,CSS3.0';
|
471 |
+
$GLOBALS['csstidy']['all_properties']['outline-width'] = 'CSS2.0,CSS2.1,CSS3.0';
|
472 |
+
$GLOBALS['csstidy']['all_properties']['overflow'] = 'CSS2.0,CSS2.1,CSS3.0';
|
473 |
+
$GLOBALS['csstidy']['all_properties']['overflow-style'] = 'CSS3.0';
|
474 |
+
$GLOBALS['csstidy']['all_properties']['overflow-wrap'] = 'CSS3.0';
|
475 |
+
$GLOBALS['csstidy']['all_properties']['overflow-x'] = 'CSS3.0';
|
476 |
+
$GLOBALS['csstidy']['all_properties']['overflow-y'] = 'CSS3.0';
|
477 |
+
$GLOBALS['csstidy']['all_properties']['padding'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
478 |
+
$GLOBALS['csstidy']['all_properties']['padding-bottom'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
479 |
+
$GLOBALS['csstidy']['all_properties']['padding-left'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
480 |
+
$GLOBALS['csstidy']['all_properties']['padding-right'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
481 |
+
$GLOBALS['csstidy']['all_properties']['padding-top'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
482 |
+
$GLOBALS['csstidy']['all_properties']['page'] = 'CSS2.0,CSS3.0';
|
483 |
+
$GLOBALS['csstidy']['all_properties']['page-break-after'] = 'CSS2.0,CSS2.1,CSS3.0';
|
484 |
+
$GLOBALS['csstidy']['all_properties']['page-break-before'] = 'CSS2.0,CSS2.1,CSS3.0';
|
485 |
+
$GLOBALS['csstidy']['all_properties']['page-break-inside'] = 'CSS2.0,CSS2.1,CSS3.0';
|
486 |
+
$GLOBALS['csstidy']['all_properties']['page-policy'] = 'CSS3.0';
|
487 |
+
$GLOBALS['csstidy']['all_properties']['pause'] = 'CSS2.0,CSS2.1,CSS3.0';
|
488 |
+
$GLOBALS['csstidy']['all_properties']['pause-after'] = 'CSS2.0,CSS2.1,CSS3.0';
|
489 |
+
$GLOBALS['csstidy']['all_properties']['pause-before'] = 'CSS2.0,CSS2.1,CSS3.0';
|
490 |
+
$GLOBALS['csstidy']['all_properties']['perspective'] = 'CSS3.0';
|
491 |
+
$GLOBALS['csstidy']['all_properties']['perspective-origin'] = 'CSS3.0';
|
492 |
+
$GLOBALS['csstidy']['all_properties']['phonemes'] = 'CSS3.0';
|
493 |
+
$GLOBALS['csstidy']['all_properties']['pitch'] = 'CSS2.0,CSS2.1,CSS3.0';
|
494 |
+
$GLOBALS['csstidy']['all_properties']['pitch-range'] = 'CSS2.0,CSS2.1,CSS3.0';
|
495 |
+
$GLOBALS['csstidy']['all_properties']['play-during'] = 'CSS2.0,CSS2.1,CSS3.0';
|
496 |
+
$GLOBALS['csstidy']['all_properties']['position'] = 'CSS2.0,CSS2.1,CSS3.0';
|
497 |
+
$GLOBALS['csstidy']['all_properties']['presentation-level'] = 'CSS3.0';
|
498 |
+
$GLOBALS['csstidy']['all_properties']['punctuation-trim'] = 'CSS3.0';
|
499 |
+
$GLOBALS['csstidy']['all_properties']['quotes'] = 'CSS2.0,CSS2.1,CSS3.0';
|
500 |
+
$GLOBALS['csstidy']['all_properties']['rendering-intent'] = 'CSS3.0';
|
501 |
+
$GLOBALS['csstidy']['all_properties']['resize'] = 'CSS3.0';
|
502 |
+
$GLOBALS['csstidy']['all_properties']['rest'] = 'CSS3.0';
|
503 |
+
$GLOBALS['csstidy']['all_properties']['rest-after'] = 'CSS3.0';
|
504 |
+
$GLOBALS['csstidy']['all_properties']['rest-before'] = 'CSS3.0';
|
505 |
+
$GLOBALS['csstidy']['all_properties']['richness'] = 'CSS2.0,CSS2.1,CSS3.0';
|
506 |
+
$GLOBALS['csstidy']['all_properties']['right'] = 'CSS2.0,CSS2.1,CSS3.0';
|
507 |
+
$GLOBALS['csstidy']['all_properties']['rotation'] = 'CSS3.0';
|
508 |
+
$GLOBALS['csstidy']['all_properties']['rotation-point'] = 'CSS3.0';
|
509 |
+
$GLOBALS['csstidy']['all_properties']['ruby-align'] = 'CSS3.0';
|
510 |
+
$GLOBALS['csstidy']['all_properties']['ruby-overhang'] = 'CSS3.0';
|
511 |
+
$GLOBALS['csstidy']['all_properties']['ruby-position'] = 'CSS3.0';
|
512 |
+
$GLOBALS['csstidy']['all_properties']['ruby-span'] = 'CSS3.0';
|
513 |
+
$GLOBALS['csstidy']['all_properties']['size'] = 'CSS2.0,CSS3.0';
|
514 |
+
$GLOBALS['csstidy']['all_properties']['speak'] = 'CSS2.0,CSS2.1,CSS3.0';
|
515 |
+
$GLOBALS['csstidy']['all_properties']['speak-header'] = 'CSS2.0,CSS2.1,CSS3.0';
|
516 |
+
$GLOBALS['csstidy']['all_properties']['speak-numeral'] = 'CSS2.0,CSS2.1,CSS3.0';
|
517 |
+
$GLOBALS['csstidy']['all_properties']['speak-punctuation'] = 'CSS2.0,CSS2.1,CSS3.0';
|
518 |
+
$GLOBALS['csstidy']['all_properties']['speech-rate'] = 'CSS2.0,CSS2.1,CSS3.0';
|
519 |
+
$GLOBALS['csstidy']['all_properties']['src'] = 'CSS3.0';
|
520 |
+
$GLOBALS['csstidy']['all_properties']['stress'] = 'CSS2.0,CSS2.1,CSS3.0';
|
521 |
+
$GLOBALS['csstidy']['all_properties']['string-set'] = 'CSS3.0';
|
522 |
+
$GLOBALS['csstidy']['all_properties']['tab-size'] = 'CSS3.0';
|
523 |
+
$GLOBALS['csstidy']['all_properties']['table-layout'] = 'CSS2.0,CSS2.1,CSS3.0';
|
524 |
+
$GLOBALS['csstidy']['all_properties']['target'] = 'CSS3.0';
|
525 |
+
$GLOBALS['csstidy']['all_properties']['target-name'] = 'CSS3.0';
|
526 |
+
$GLOBALS['csstidy']['all_properties']['target-new'] = 'CSS3.0';
|
527 |
+
$GLOBALS['csstidy']['all_properties']['target-position'] = 'CSS3.0';
|
528 |
+
$GLOBALS['csstidy']['all_properties']['text-align'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
529 |
+
$GLOBALS['csstidy']['all_properties']['text-align-last'] = 'CSS3.0';
|
530 |
+
$GLOBALS['csstidy']['all_properties']['text-decoration'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
531 |
+
$GLOBALS['csstidy']['all_properties']['text-decoration-color'] = 'CSS3.0';
|
532 |
+
$GLOBALS['csstidy']['all_properties']['text-decoration-line'] = 'CSS3.0';
|
533 |
+
$GLOBALS['csstidy']['all_properties']['text-decoration-skip'] = 'CSS3.0';
|
534 |
+
$GLOBALS['csstidy']['all_properties']['text-decoration-style'] = 'CSS3.0';
|
535 |
+
$GLOBALS['csstidy']['all_properties']['text-emphasis'] = 'CSS3.0';
|
536 |
+
$GLOBALS['csstidy']['all_properties']['text-emphasis-color'] = 'CSS3.0';
|
537 |
+
$GLOBALS['csstidy']['all_properties']['text-emphasis-position'] = 'CSS3.0';
|
538 |
+
$GLOBALS['csstidy']['all_properties']['text-emphasis-style'] = 'CSS3.0';
|
539 |
+
$GLOBALS['csstidy']['all_properties']['text-height'] = 'CSS3.0';
|
540 |
+
$GLOBALS['csstidy']['all_properties']['text-indent'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
541 |
+
$GLOBALS['csstidy']['all_properties']['text-justify'] = 'CSS3.0';
|
542 |
+
$GLOBALS['csstidy']['all_properties']['text-outline'] = 'CSS3.0';
|
543 |
+
$GLOBALS['csstidy']['all_properties']['text-shadow'] = 'CSS2.0,CSS3.0';
|
544 |
+
$GLOBALS['csstidy']['all_properties']['text-space-collapse'] = 'CSS3.0';
|
545 |
+
$GLOBALS['csstidy']['all_properties']['text-transform'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
546 |
+
$GLOBALS['csstidy']['all_properties']['text-underline-position'] = 'CSS3.0';
|
547 |
+
$GLOBALS['csstidy']['all_properties']['text-wrap'] = 'CSS3.0';
|
548 |
+
$GLOBALS['csstidy']['all_properties']['top'] = 'CSS2.0,CSS2.1,CSS3.0';
|
549 |
+
$GLOBALS['csstidy']['all_properties']['transform'] = 'CSS3.0';
|
550 |
+
$GLOBALS['csstidy']['all_properties']['transform-origin'] = 'CSS3.0';
|
551 |
+
$GLOBALS['csstidy']['all_properties']['transform-style'] = 'CSS3.0';
|
552 |
+
$GLOBALS['csstidy']['all_properties']['transition'] = 'CSS3.0';
|
553 |
+
$GLOBALS['csstidy']['all_properties']['transition-delay'] = 'CSS3.0';
|
554 |
+
$GLOBALS['csstidy']['all_properties']['transition-duration'] = 'CSS3.0';
|
555 |
+
$GLOBALS['csstidy']['all_properties']['transition-property'] = 'CSS3.0';
|
556 |
+
$GLOBALS['csstidy']['all_properties']['transition-timing-function'] = 'CSS3.0';
|
557 |
+
$GLOBALS['csstidy']['all_properties']['unicode-bidi'] = 'CSS2.0,CSS2.1,CSS3.0';
|
558 |
+
$GLOBALS['csstidy']['all_properties']['vertical-align'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
559 |
+
$GLOBALS['csstidy']['all_properties']['visibility'] = 'CSS2.0,CSS2.1,CSS3.0';
|
560 |
+
$GLOBALS['csstidy']['all_properties']['voice-balance'] = 'CSS3.0';
|
561 |
+
$GLOBALS['csstidy']['all_properties']['voice-duration'] = 'CSS3.0';
|
562 |
+
$GLOBALS['csstidy']['all_properties']['voice-family'] = 'CSS2.0,CSS2.1,CSS3.0';
|
563 |
+
$GLOBALS['csstidy']['all_properties']['voice-pitch'] = 'CSS3.0';
|
564 |
+
$GLOBALS['csstidy']['all_properties']['voice-pitch-range'] = 'CSS3.0';
|
565 |
+
$GLOBALS['csstidy']['all_properties']['voice-rate'] = 'CSS3.0';
|
566 |
+
$GLOBALS['csstidy']['all_properties']['voice-stress'] = 'CSS3.0';
|
567 |
+
$GLOBALS['csstidy']['all_properties']['voice-volume'] = 'CSS3.0';
|
568 |
+
$GLOBALS['csstidy']['all_properties']['volume'] = 'CSS2.0,CSS2.1,CSS3.0';
|
569 |
+
$GLOBALS['csstidy']['all_properties']['white-space'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
570 |
+
$GLOBALS['csstidy']['all_properties']['widows'] = 'CSS2.0,CSS2.1,CSS3.0';
|
571 |
+
$GLOBALS['csstidy']['all_properties']['width'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
572 |
+
$GLOBALS['csstidy']['all_properties']['word-break'] = 'CSS3.0';
|
573 |
+
$GLOBALS['csstidy']['all_properties']['word-spacing'] = 'CSS1.0,CSS2.0,CSS2.1,CSS3.0';
|
574 |
+
$GLOBALS['csstidy']['all_properties']['word-wrap'] = 'CSS3.0';
|
575 |
+
$GLOBALS['csstidy']['all_properties']['z-index'] = 'CSS2.0,CSS2.1,CSS3.0';
|
576 |
+
|
577 |
+
/**
|
578 |
+
* An array containing all properties that can accept a quoted string as a value.
|
579 |
+
*
|
580 |
+
* @global array $GLOBALS['csstidy']['quoted_string_properties']
|
581 |
+
*/
|
582 |
+
$GLOBALS['csstidy']['quoted_string_properties'] = array('content', 'font', 'font-family', 'quotes');
|
583 |
+
|
584 |
+
/**
|
585 |
+
* An array containing all properties that can be defined multiple times without being overwritten.
|
586 |
+
* All unit values are included so that units like rem can be supported with fallbacks to px or em.
|
587 |
+
*
|
588 |
+
* @global array $GLOBALS['csstidy']['quoted_string_properties']
|
589 |
+
*/
|
590 |
+
$GLOBALS['csstidy']['multiple_properties'] = array_merge( $GLOBALS['csstidy']['color_values'], $GLOBALS['csstidy']['unit_values'], array('transition') );
|
591 |
+
|
592 |
+
/**
|
593 |
+
* An array containing all predefined templates.
|
594 |
+
*
|
595 |
+
* @global array $GLOBALS['csstidy']['predefined_templates']
|
596 |
+
* @version 1.0
|
597 |
+
* @see csstidy::load_template()
|
598 |
+
*/
|
599 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="at">'; //string before @rule
|
600 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span> <span class="format">{</span>'."\n"; //bracket after @-rule
|
601 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="selector">'; //string before selector
|
602 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span> <span class="format">{</span>'."\n"; //bracket after selector
|
603 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="property">'; //string before property
|
604 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span><span class="value">'; //string after property+before value
|
605 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span><span class="format">;</span>'."\n"; //string after value
|
606 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="format">}</span>'; //closing bracket - selector
|
607 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = "\n\n"; //space between blocks {...}
|
608 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = "\n".'<span class="format">}</span>'. "\n\n"; //closing bracket @-rule
|
609 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = ''; //indent in @-rule
|
610 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = '<span class="comment">'; // before comment
|
611 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = '</span>'."\n"; // after comment
|
612 |
+
$GLOBALS['csstidy']['predefined_templates']['default'][] = "\n"; // after last line @-rule
|
613 |
+
|
614 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="at">';
|
615 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span> <span class="format">{</span>'."\n";
|
616 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="selector">';
|
617 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="format">{</span>';
|
618 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="property">';
|
619 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="value">';
|
620 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span><span class="format">;</span>';
|
621 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="format">}</span>';
|
622 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = "\n";
|
623 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = "\n". '<span class="format">}'."\n".'</span>';
|
624 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '';
|
625 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '<span class="comment">'; // before comment
|
626 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = '</span>'; // after comment
|
627 |
+
$GLOBALS['csstidy']['predefined_templates']['high_compression'][] = "\n";
|
628 |
+
|
629 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="at">';
|
630 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">{</span>';
|
631 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="selector">';
|
632 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">{</span>';
|
633 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="property">';
|
634 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="value">';
|
635 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span><span class="format">;</span>';
|
636 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="format">}</span>';
|
637 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '';
|
638 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="format">}</span>';
|
639 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '';
|
640 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '<span class="comment">'; // before comment
|
641 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '</span>'; // after comment
|
642 |
+
$GLOBALS['csstidy']['predefined_templates']['highest_compression'][] = '';
|
643 |
+
|
644 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '<span class="at">';
|
645 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span> <span class="format">{</span>'."\n";
|
646 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '<span class="selector">';
|
647 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span>'."\n".'<span class="format">{</span>'."\n";
|
648 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = ' <span class="property">';
|
649 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span><span class="value">';
|
650 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span><span class="format">;</span>'."\n";
|
651 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '<span class="format">}</span>';
|
652 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = "\n\n";
|
653 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = "\n".'<span class="format">}</span>'."\n\n";
|
654 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = ' ';
|
655 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '<span class="comment">'; // before comment
|
656 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = '</span>'."\n"; // after comment
|
657 |
+
$GLOBALS['csstidy']['predefined_templates']['low_compression'][] = "\n";
|
658 |
+
|
659 |
+
require dirname( __FILE__ ) . '/data-wp.inc.php';
|
660 |
+
|
661 |
+
?>
|
classes/csstidy/lang.inc.php
CHANGED
@@ -1,311 +1,311 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Localization of CSS Optimiser Interface of CSSTidy
|
5 |
-
*
|
6 |
-
* Copyright 2005, 2006, 2007 Florian Schmitz
|
7 |
-
*
|
8 |
-
* This file is part of CSSTidy.
|
9 |
-
*
|
10 |
-
* CSSTidy is free software; you can redistribute it and/or modify
|
11 |
-
* it under the terms of the GNU Lesser General Public License as published by
|
12 |
-
* the Free Software Foundation; either version 2.1 of the License, or
|
13 |
-
* (at your option) any later version.
|
14 |
-
*
|
15 |
-
* CSSTidy is distributed in the hope that it will be useful,
|
16 |
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17 |
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18 |
-
* GNU Lesser General Public License for more details.
|
19 |
-
*
|
20 |
-
* You should have received a copy of the GNU Lesser General Public License
|
21 |
-
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
22 |
-
*
|
23 |
-
* @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
|
24 |
-
* @package csstidy
|
25 |
-
* @author Florian Schmitz (floele at gmail dot com) 2005-2007
|
26 |
-
* @author Brett Zamir (brettz9 at yahoo dot com) 2007
|
27 |
-
*/
|
28 |
-
|
29 |
-
|
30 |
-
if(isset($_GET['lang'])) {
|
31 |
-
$l = $_GET['lang'];
|
32 |
-
}
|
33 |
-
else if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
34 |
-
$l = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
35 |
-
$l = strtolower(substr($l, 0, 2));
|
36 |
-
}
|
37 |
-
else {
|
38 |
-
$l = '';
|
39 |
-
}
|
40 |
-
|
41 |
-
$l = (in_array($l, array('de', 'fr', 'zh'))) ? $l : 'en';
|
42 |
-
|
43 |
-
// note 5 in all but French, and 40 in all are orphaned
|
44 |
-
|
45 |
-
$lang = array();
|
46 |
-
$lang['en'][0] = 'CSS Formatter and Optimiser/Optimizer (based on CSSTidy ';
|
47 |
-
$lang['en'][1] = 'CSS Formatter and Optimiser';
|
48 |
-
$lang['en'][2] = '(based on';
|
49 |
-
$lang['en'][3] = '(plaintext)';
|
50 |
-
$lang['en'][4] = 'Important Note:';
|
51 |
-
$lang['en'][6] = 'Your code should be well-formed. This is <strong>not a validator</strong> which points out errors in your CSS code. To make sure that your code is valid, use the <a href="http://jigsaw.w3.org/css-validator/">W3C Validator</a>.';
|
52 |
-
$lang['en'][7] = 'all comments are removed';
|
53 |
-
$lang['en'][8] = 'CSS Input:';
|
54 |
-
$lang['en'][9] = 'CSS-Code:';
|
55 |
-
$lang['en'][10] = 'CSS from URL:';
|
56 |
-
$lang['en'][11] = 'Code Layout:';
|
57 |
-
$lang['en'][12] = 'Compression (code layout):';
|
58 |
-
$lang['en'][13] = 'Highest (no readability, smallest size)';
|
59 |
-
$lang['en'][14] = 'High (moderate readability, smaller size)';
|
60 |
-
$lang['en'][15] = 'Standard (balance between readability and size)';
|
61 |
-
$lang['en'][16] = 'Low (higher readability)';
|
62 |
-
$lang['en'][17] = 'Custom (enter below)';
|
63 |
-
$lang['en'][18] = 'Custom <a href="http://csstidy.sourceforge.net/templates.php">template</a>';
|
64 |
-
$lang['en'][19] = 'Options';
|
65 |
-
$lang['en'][20] = 'Sort Selectors (caution)';
|
66 |
-
$lang['en'][21] = 'Sort Properties';
|
67 |
-
$lang['en'][22] = 'Regroup selectors';
|
68 |
-
$lang['en'][23] = 'Optimise shorthands';
|
69 |
-
$lang['en'][24] = 'Compress colors';
|
70 |
-
$lang['en'][25] = 'Lowercase selectors';
|
71 |
-
$lang['en'][26] = 'Case for properties:';
|
72 |
-
$lang['en'][27] = 'Lowercase';
|
73 |
-
$lang['en'][28] = 'No or invalid CSS input or wrong URL!';
|
74 |
-
$lang['en'][29] = 'Uppercase';
|
75 |
-
$lang['en'][30] = 'lowercase elementnames needed for XHTML';
|
76 |
-
$lang['en'][31] = 'Remove unnecessary backslashes';
|
77 |
-
$lang['en'][32] = 'convert !important-hack';
|
78 |
-
$lang['en'][33] = 'Output as file';
|
79 |
-
$lang['en'][34] = 'Bigger compression because of smaller newlines (copy & paste doesn\'t work)';
|
80 |
-
$lang['en'][35] = 'Process CSS';
|
81 |
-
$lang['en'][36] = 'Compression Ratio';
|
82 |
-
$lang['en'][37] = 'Input';
|
83 |
-
$lang['en'][38] = 'Output';
|
84 |
-
$lang['en'][39] = 'Language';
|
85 |
-
$lang['en'][41] = 'Attention: This may change the behaviour of your CSS Code!';
|
86 |
-
$lang['en'][42] = 'Remove last ;';
|
87 |
-
$lang['en'][43] = 'Discard invalid properties';
|
88 |
-
$lang['en'][44] = 'Only safe optimisations';
|
89 |
-
$lang['en'][45] = 'Compress font-weight';
|
90 |
-
$lang['en'][46] = 'Save comments';
|
91 |
-
$lang['en'][47] = 'Do not change anything';
|
92 |
-
$lang['en'][48] = 'Only seperate selectors (split at ,)';
|
93 |
-
$lang['en'][49] = 'Merge selectors with the same properties (fast)';
|
94 |
-
$lang['en'][50] = 'Merge selectors intelligently (slow)';
|
95 |
-
$lang['en'][51] = 'Preserve CSS';
|
96 |
-
$lang['en'][52] = 'Save comments, hacks, etc. Most optimisations can *not* be applied if this is enabled.';
|
97 |
-
$lang['en'][53] = 'None';
|
98 |
-
$lang['en'][54] = 'Don\'t optimise';
|
99 |
-
$lang['en'][55] = 'Safe optimisations';
|
100 |
-
$lang['en'][56] = 'All optimisations';
|
101 |
-
$lang['en'][57] = 'Add timestamp';
|
102 |
-
$lang['en'][58] = 'Copy to clipboard';
|
103 |
-
$lang['en'][59] = 'Back to top';
|
104 |
-
$lang['en'][60] = 'Your browser doesn\'t support copy to clipboard.';
|
105 |
-
$lang['en'][61] = 'For bugs and suggestions feel free to';
|
106 |
-
$lang['en'][62] = 'contact me';
|
107 |
-
$lang['en'][63] = 'Output CSS code as complete HTML document';
|
108 |
-
$lang['en'][64] = 'Code';
|
109 |
-
$lang['en'][65] = 'CSS to style CSS output';
|
110 |
-
$lang['en'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
|
111 |
-
|
112 |
-
|
113 |
-
$lang['de'][0] = 'CSS Formatierer und Optimierer (basierend auf CSSTidy ';
|
114 |
-
$lang['de'][1] = 'CSS Formatierer und Optimierer';
|
115 |
-
$lang['de'][2] = '(basierend auf';
|
116 |
-
$lang['de'][3] = '(Textversion)';
|
117 |
-
$lang['de'][4] = 'Wichtiger Hinweis:';
|
118 |
-
$lang['de'][6] = 'Der CSS Code sollte wohlgeformt sein. Der CSS Code wird <strong>nicht auf Gültigkeit überprüft</strong>. Um sicherzugehen dass dein Code valide ist, benutze den <a href="http://jigsaw.w3.org/css-validator/">W3C Validierungsservice</a>.';
|
119 |
-
$lang['de'][7] = 'alle Kommentare werden entfernt';
|
120 |
-
$lang['de'][8] = 'CSS Eingabe:';
|
121 |
-
$lang['de'][9] = 'CSS-Code:';
|
122 |
-
$lang['de'][10] = 'CSS von URL:';
|
123 |
-
$lang['de'][11] = 'Code Layout:';
|
124 |
-
$lang['de'][12] = 'Komprimierung (Code Layout):';
|
125 |
-
$lang['de'][13] = 'Höchste (keine Lesbarkeit, niedrigste Größe)';
|
126 |
-
$lang['de'][14] = 'Hoch (mittelmäßige Lesbarkeit, geringe Größe)';
|
127 |
-
$lang['de'][15] = 'Standard (Kompromiss zwischen Lesbarkeit und Größe)';
|
128 |
-
$lang['de'][16] = 'Niedrig (höhere Lesbarkeit)';
|
129 |
-
$lang['de'][17] = 'Benutzerdefiniert (unten eingeben)';
|
130 |
-
$lang['de'][18] = 'Benutzerdefinierte <a href="http://csstidy.sourceforge.net/templates.php">Vorlage</a>';
|
131 |
-
$lang['de'][19] = 'Optionen';
|
132 |
-
$lang['de'][20] = 'Selektoren sortieren (Vorsicht)';
|
133 |
-
$lang['de'][21] = 'Eigenschaften sortieren';
|
134 |
-
$lang['de'][22] = 'Selektoren umgruppieren';
|
135 |
-
$lang['de'][23] = 'Shorthands optimieren';
|
136 |
-
$lang['de'][24] = 'Farben komprimieren';
|
137 |
-
$lang['de'][25] = 'Selektoren in Kleinbuchstaben';
|
138 |
-
$lang['de'][26] = 'Groß-/Kleinschreibung für Eigenschaften';
|
139 |
-
$lang['de'][27] = 'Kleinbuchstaben';
|
140 |
-
$lang['de'][28] = 'Keine oder ungültige CSS Eingabe oder falsche URL!';
|
141 |
-
$lang['de'][29] = 'Großbuchstaben';
|
142 |
-
$lang['de'][30] = 'kleingeschriebene Elementnamen benötigt für XHTML';
|
143 |
-
$lang['de'][31] = 'Unnötige Backslashes entfernen';
|
144 |
-
$lang['de'][32] = '!important-Hack konvertieren';
|
145 |
-
$lang['de'][33] = 'Als Datei ausgeben';
|
146 |
-
$lang['de'][34] = 'Größere Komprimierung augrund von kleineren Neuezeile-Zeichen';
|
147 |
-
$lang['de'][35] = 'CSS verarbeiten';
|
148 |
-
$lang['de'][36] = 'Komprimierungsrate';
|
149 |
-
$lang['de'][37] = 'Eingabe';
|
150 |
-
$lang['de'][38] = 'Ausgabe';
|
151 |
-
$lang['de'][39] = 'Sprache';
|
152 |
-
$lang['de'][41] = 'Achtung: Dies könnte das Verhalten ihres CSS-Codes verändern!';
|
153 |
-
$lang['de'][42] = 'Letztes ; entfernen';
|
154 |
-
$lang['de'][43] = 'Ungültige Eigenschaften entfernen';
|
155 |
-
$lang['de'][44] = 'Nur sichere Optimierungen';
|
156 |
-
$lang['de'][45] = 'font-weight komprimieren';
|
157 |
-
$lang['de'][46] = 'Kommentare beibehalten';
|
158 |
-
$lang['de'][47] = 'Nichts ändern';
|
159 |
-
$lang['de'][48] = 'Selektoren nur trennen (am Komma)';
|
160 |
-
$lang['de'][49] = 'Selektoren mit gleichen Eigenschaften zusammenfassen (schnell)';
|
161 |
-
$lang['de'][50] = 'Selektoren intelligent zusammenfassen (langsam!)';
|
162 |
-
$lang['de'][51] = 'CSS erhalten';
|
163 |
-
$lang['de'][52] = 'Kommentare, Hacks, etc. speichern. Viele Optimierungen sind dann aber nicht mehr möglich.';
|
164 |
-
$lang['de'][53] = 'Keine';
|
165 |
-
$lang['de'][54] = 'Nicht optimieren';
|
166 |
-
$lang['de'][55] = 'Sichere Optimierungen';
|
167 |
-
$lang['de'][56] = 'Alle Optimierungen';
|
168 |
-
$lang['de'][57] = 'Zeitstempel hinzufügen';
|
169 |
-
$lang['de'][58] = 'Copy to clipboard';
|
170 |
-
$lang['de'][59] = 'Back to top';
|
171 |
-
$lang['de'][60] = 'Your browser doesn\'t support copy to clipboard.';
|
172 |
-
$lang['de'][61] = 'For bugs and suggestions feel free to';
|
173 |
-
$lang['de'][62] = 'contact me';
|
174 |
-
$lang['de'][63] = 'Output CSS code as complete HTML document';
|
175 |
-
$lang['de'][64] = 'Code';
|
176 |
-
$lang['de'][65] = 'CSS to style CSS output';
|
177 |
-
$lang['de'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
|
178 |
-
|
179 |
-
|
180 |
-
$lang['fr'][0] = 'CSS Formatteur et Optimiseur (basé sur CSSTidy ';
|
181 |
-
$lang['fr'][1] = 'CSS Formatteur et Optimiseur';
|
182 |
-
$lang['fr'][2] = '(basé sur ';
|
183 |
-
$lang['fr'][3] = '(Version texte)';
|
184 |
-
$lang['fr'][4] = 'Note Importante :';
|
185 |
-
$lang['fr'][6] = 'Votre code doit être valide. Ce n’est <strong>pas un validateur</strong> qui signale les erreurs dans votre code CSS. Pour être sûr que votre code est correct, utilisez le validateur : <a href="http://jigsaw.w3.org/css-validator/">W3C Validator</a>.';
|
186 |
-
$lang['fr'][7] = 'tous les commentaires sont enlevés';
|
187 |
-
$lang['fr'][8] = 'Champ CSS :';
|
188 |
-
$lang['fr'][9] = 'Code CSS :';
|
189 |
-
$lang['fr'][10] = 'CSS en provenance d’une URL :<br />';
|
190 |
-
$lang['fr'][11] = 'Mise en page du code :';
|
191 |
-
$lang['fr'][12] = 'Compression (mise en page du code) :';
|
192 |
-
$lang['fr'][13] = 'La plus élevée (aucune lisibilité, taille minimale)';
|
193 |
-
$lang['fr'][14] = 'Élevée (lisibilité modérée, petite taille)';
|
194 |
-
$lang['fr'][15] = 'Normale (équilibre entre lisibilité et taille)';
|
195 |
-
$lang['fr'][16] = 'Faible (lisibilité élevée)';
|
196 |
-
$lang['fr'][17] = 'Sur mesure (entrer ci-dessous)';
|
197 |
-
$lang['fr'][18] = '<a href="http://csstidy.sourceforge.net/templates.php">Gabarit</a> sur mesure';
|
198 |
-
$lang['fr'][19] = 'Options';
|
199 |
-
$lang['fr'][20] = 'Trier les sélecteurs (attention)';
|
200 |
-
$lang['fr'][21] = 'Trier les propriétés';
|
201 |
-
$lang['fr'][22] = 'Regrouper les sélecteurs';
|
202 |
-
$lang['fr'][23] = 'Propriétés raccourcies';
|
203 |
-
$lang['fr'][24] = 'Compresser les couleurs';
|
204 |
-
$lang['fr'][25] = 'Sélecteurs en minuscules';
|
205 |
-
$lang['fr'][26] = 'Case pour les propriétés :';
|
206 |
-
$lang['fr'][27] = 'Minuscule';
|
207 |
-
$lang['fr'][28] = 'CSS non valide ou URL incorrecte !';
|
208 |
-
$lang['fr'][29] = 'Majuscule';
|
209 |
-
$lang['fr'][30] = 'les noms des éléments en minuscules (indispensables pour XHTML)';
|
210 |
-
$lang['fr'][31] = 'enlever les antislashs inutiles';
|
211 |
-
$lang['fr'][32] = 'convertir !important-hack';
|
212 |
-
$lang['fr'][33] = 'Sauver en tant que fichier';
|
213 |
-
$lang['fr'][34] = 'Meilleure compression grâce aux caractères de saut de ligne plus petits (copier & coller ne marche pas)';
|
214 |
-
$lang['fr'][35] = 'Compresser la CSS';
|
215 |
-
$lang['fr'][36] = 'Facteur de Compression';
|
216 |
-
$lang['fr'][37] = 'Entrée';
|
217 |
-
$lang['fr'][38] = 'Sortie';
|
218 |
-
$lang['fr'][39] = 'Langue';
|
219 |
-
$lang['fr'][41] = 'Attention : ceci peut changer le comportement de votre code CSS !';
|
220 |
-
$lang['fr'][42] = 'Enlever le dernier ;';
|
221 |
-
$lang['fr'][43] = 'Supprimer les propriétés non valide';
|
222 |
-
$lang['fr'][44] = 'Seulement les optimisations sûres';
|
223 |
-
$lang['fr'][45] = 'Compresser font-weight';
|
224 |
-
$lang['fr'][46] = 'Sauvegarder les commentaires ';
|
225 |
-
$lang['fr'][47] = 'Ne rien changer';
|
226 |
-
$lang['fr'][48] = 'Sépare les sélecteurs (sépare au niveau de ,)';
|
227 |
-
$lang['fr'][49] = 'Fusionne les sélecteurs avec les mêmes propriétés (rapide)';
|
228 |
-
$lang['fr'][50] = 'Fusionne les sélecteurs intelligemment (lent)';
|
229 |
-
$lang['fr'][51] = 'Préserver la CSS';
|
230 |
-
$lang['fr'][52] = 'Sauvegarder les commentaires, hacks, etc. La plupart des optimisations ne peuvent *pas* être appliquées si cela est activé.';
|
231 |
-
$lang['fr'][53] = 'Aucun';
|
232 |
-
$lang['fr'][54] = 'Ne pas optimiser';
|
233 |
-
$lang['fr'][55] = 'Optimisations sûres';
|
234 |
-
$lang['fr'][56] = 'Toutes les optimisations';
|
235 |
-
$lang['fr'][57] = 'Ajouter un timestamp';
|
236 |
-
$lang['fr'][58] = 'Copier dans le presse-papiers';
|
237 |
-
$lang['fr'][59] = 'Retour en haut';
|
238 |
-
$lang['fr'][60] = 'Votre navigateur ne suporte pas la copie vers le presse-papiers.';
|
239 |
-
$lang['fr'][61] = 'Pour signaler des bugs ou pour des suggestions,';
|
240 |
-
$lang['fr'][62] = 'contactez-moi';
|
241 |
-
$lang['fr'][63] = 'Sauver le code CSS comme document complet HTML';
|
242 |
-
$lang['fr'][64] = 'Code';
|
243 |
-
$lang['fr'][65] = 'CSS pour colorier la sortie CSS';
|
244 |
-
$lang['fr'][66] = 'Vous devez aller dans about:config dans votre barre d’adresse, selectionner \'signed.applets.codebase_principal_support\' dans le champ Filtre et attribuez-lui la valeur \'true\' pour utiliser cette fonctionnalité; toutefois, soyez conscient que cela augmente les risques de sécurité.';
|
245 |
-
|
246 |
-
|
247 |
-
$lang['zh'][0] = 'CSS整形與最佳化工具(使用 CSSTidy ';
|
248 |
-
$lang['zh'][1] = 'CSS整形與最佳化工具';
|
249 |
-
$lang['zh'][2] = '(使用';
|
250 |
-
$lang['zh'][3] = '(純文字)';
|
251 |
-
$lang['zh'][4] = '重要事項:';
|
252 |
-
$lang['zh'][6] = '你的原始碼必須是良構的(well-formed). 這個工具<strong>沒有內建驗證器(validator)</strong>. 驗證器能夠指出你CSS原始碼裡的錯誤. 請使用 <a href="http://jigsaw.w3.org/css-validator/">W3C 驗證器</a>, 確保你的原始碼合乎規範.';
|
253 |
-
$lang['zh'][7] = '所有註解都移除了';
|
254 |
-
$lang['zh'][8] = 'CSS 輸入:';
|
255 |
-
$lang['zh'][9] = 'CSS 原始碼:';
|
256 |
-
$lang['zh'][10] = 'CSS 檔案網址(URL):';
|
257 |
-
$lang['zh'][11] = '原始碼規劃:';
|
258 |
-
$lang['zh'][12] = '壓縮程度(原始碼規劃):';
|
259 |
-
$lang['zh'][13] = '最高 (沒有辦法讀, 檔案最小)';
|
260 |
-
$lang['zh'][14] = '高 (適度的可讀性, 檔案小)';
|
261 |
-
$lang['zh'][15] = '標準 (兼顧可讀性與檔案大小)';
|
262 |
-
$lang['zh'][16] = '低 (注重可讀性)';
|
263 |
-
$lang['zh'][17] = '自訂 (在下方設定)';
|
264 |
-
$lang['zh'][18] = '自訂<a href="http://csstidy.sourceforge.net/templates.php">樣板</a>';
|
265 |
-
$lang['zh'][19] = '選項';
|
266 |
-
$lang['zh'][20] = '整理選擇符(請謹慎使用)';
|
267 |
-
$lang['zh'][21] = '整理屬性';
|
268 |
-
$lang['zh'][22] = '重組選擇符';
|
269 |
-
$lang['zh'][23] = '速記法(shorthand)最佳化';
|
270 |
-
$lang['zh'][24] = '壓縮色彩語法';
|
271 |
-
$lang['zh'][25] = '改用小寫選擇符';
|
272 |
-
$lang['zh'][26] = '屬性的字形:';
|
273 |
-
$lang['zh'][27] = '小寫';
|
274 |
-
$lang['zh'][28] = '沒有輸入CSS, 語法不符合規定, 或是網址錯誤!';
|
275 |
-
$lang['zh'][29] = '大寫';
|
276 |
-
$lang['zh'][30] = 'XHTML必須使用小寫的元素名稱';
|
277 |
-
$lang['zh'][31] = '移除不必要的反斜線';
|
278 |
-
$lang['zh'][32] = '轉換 !important-hack';
|
279 |
-
$lang['zh'][33] = '輸出成檔案形式';
|
280 |
-
$lang['zh'][34] = '由於比較少換行字元, 會有更大的壓縮比率(複製&貼上沒有用)';
|
281 |
-
$lang['zh'][35] = '執行';
|
282 |
-
$lang['zh'][36] = '壓縮比率';
|
283 |
-
$lang['zh'][37] = '輸入';
|
284 |
-
$lang['zh'][38] = '輸出';
|
285 |
-
$lang['zh'][39] = '語言';
|
286 |
-
$lang['zh'][41] = '注意: 這或許會變更你CSS原始碼的行為!';
|
287 |
-
$lang['zh'][42] = '除去最後一個分號';
|
288 |
-
$lang['zh'][43] = '拋棄不符合規定的屬性';
|
289 |
-
$lang['zh'][44] = '只安全地最佳化';
|
290 |
-
$lang['zh'][45] = '壓縮 font-weight';
|
291 |
-
$lang['zh'][46] = '保留註解';
|
292 |
-
$lang['zh'][47] = '什麼都不要改';
|
293 |
-
$lang['zh'][48] = '只分開原本用逗號分隔的選擇符';
|
294 |
-
$lang['zh'][49] = '合併有相同屬性的選擇符(快速)';
|
295 |
-
$lang['zh'][50] = '聰明地合併選擇符(慢速)';
|
296 |
-
$lang['zh'][51] = '保護CSS';
|
297 |
-
$lang['zh'][52] = '保留註解與 hack 等等. 如果啟用這個選項, 大多數的最佳化程序都不會執行.';
|
298 |
-
$lang['zh'][53] = '不改變';
|
299 |
-
$lang['zh'][54] = '不做最佳化';
|
300 |
-
$lang['zh'][55] = '安全地最佳化';
|
301 |
-
$lang['zh'][56] = '全部最佳化';
|
302 |
-
$lang['zh'][57] = '加上時間戳記';
|
303 |
-
$lang['zh'][58] = '复制到剪贴板';
|
304 |
-
$lang['zh'][59] = '回到页面上方';
|
305 |
-
$lang['zh'][60] = '你的浏览器不支持复制到剪贴板。';
|
306 |
-
$lang['zh'][61] = '如果程序有错误或你有建议,欢迎';
|
307 |
-
$lang['zh'][62] = '和我联系';
|
308 |
-
$lang['zh'][63] = 'Output CSS code as complete HTML document';
|
309 |
-
$lang['zh'][64] = '代码';
|
310 |
-
$lang['zh'][65] = 'CSS to style CSS output';
|
311 |
-
$lang['zh'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Localization of CSS Optimiser Interface of CSSTidy
|
5 |
+
*
|
6 |
+
* Copyright 2005, 2006, 2007 Florian Schmitz
|
7 |
+
*
|
8 |
+
* This file is part of CSSTidy.
|
9 |
+
*
|
10 |
+
* CSSTidy is free software; you can redistribute it and/or modify
|
11 |
+
* it under the terms of the GNU Lesser General Public License as published by
|
12 |
+
* the Free Software Foundation; either version 2.1 of the License, or
|
13 |
+
* (at your option) any later version.
|
14 |
+
*
|
15 |
+
* CSSTidy is distributed in the hope that it will be useful,
|
16 |
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17 |
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18 |
+
* GNU Lesser General Public License for more details.
|
19 |
+
*
|
20 |
+
* You should have received a copy of the GNU Lesser General Public License
|
21 |
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
22 |
+
*
|
23 |
+
* @license http://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
|
24 |
+
* @package csstidy
|
25 |
+
* @author Florian Schmitz (floele at gmail dot com) 2005-2007
|
26 |
+
* @author Brett Zamir (brettz9 at yahoo dot com) 2007
|
27 |
+
*/
|
28 |
+
|
29 |
+
|
30 |
+
if(isset($_GET['lang'])) {
|
31 |
+
$l = $_GET['lang'];
|
32 |
+
}
|
33 |
+
else if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
34 |
+
$l = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
|
35 |
+
$l = strtolower(substr($l, 0, 2));
|
36 |
+
}
|
37 |
+
else {
|
38 |
+
$l = '';
|
39 |
+
}
|
40 |
+
|
41 |
+
$l = (in_array($l, array('de', 'fr', 'zh'))) ? $l : 'en';
|
42 |
+
|
43 |
+
// note 5 in all but French, and 40 in all are orphaned
|
44 |
+
|
45 |
+
$lang = array();
|
46 |
+
$lang['en'][0] = 'CSS Formatter and Optimiser/Optimizer (based on CSSTidy ';
|
47 |
+
$lang['en'][1] = 'CSS Formatter and Optimiser';
|
48 |
+
$lang['en'][2] = '(based on';
|
49 |
+
$lang['en'][3] = '(plaintext)';
|
50 |
+
$lang['en'][4] = 'Important Note:';
|
51 |
+
$lang['en'][6] = 'Your code should be well-formed. This is <strong>not a validator</strong> which points out errors in your CSS code. To make sure that your code is valid, use the <a href="http://jigsaw.w3.org/css-validator/">W3C Validator</a>.';
|
52 |
+
$lang['en'][7] = 'all comments are removed';
|
53 |
+
$lang['en'][8] = 'CSS Input:';
|
54 |
+
$lang['en'][9] = 'CSS-Code:';
|
55 |
+
$lang['en'][10] = 'CSS from URL:';
|
56 |
+
$lang['en'][11] = 'Code Layout:';
|
57 |
+
$lang['en'][12] = 'Compression (code layout):';
|
58 |
+
$lang['en'][13] = 'Highest (no readability, smallest size)';
|
59 |
+
$lang['en'][14] = 'High (moderate readability, smaller size)';
|
60 |
+
$lang['en'][15] = 'Standard (balance between readability and size)';
|
61 |
+
$lang['en'][16] = 'Low (higher readability)';
|
62 |
+
$lang['en'][17] = 'Custom (enter below)';
|
63 |
+
$lang['en'][18] = 'Custom <a href="http://csstidy.sourceforge.net/templates.php">template</a>';
|
64 |
+
$lang['en'][19] = 'Options';
|
65 |
+
$lang['en'][20] = 'Sort Selectors (caution)';
|
66 |
+
$lang['en'][21] = 'Sort Properties';
|
67 |
+
$lang['en'][22] = 'Regroup selectors';
|
68 |
+
$lang['en'][23] = 'Optimise shorthands';
|
69 |
+
$lang['en'][24] = 'Compress colors';
|
70 |
+
$lang['en'][25] = 'Lowercase selectors';
|
71 |
+
$lang['en'][26] = 'Case for properties:';
|
72 |
+
$lang['en'][27] = 'Lowercase';
|
73 |
+
$lang['en'][28] = 'No or invalid CSS input or wrong URL!';
|
74 |
+
$lang['en'][29] = 'Uppercase';
|
75 |
+
$lang['en'][30] = 'lowercase elementnames needed for XHTML';
|
76 |
+
$lang['en'][31] = 'Remove unnecessary backslashes';
|
77 |
+
$lang['en'][32] = 'convert !important-hack';
|
78 |
+
$lang['en'][33] = 'Output as file';
|
79 |
+
$lang['en'][34] = 'Bigger compression because of smaller newlines (copy & paste doesn\'t work)';
|
80 |
+
$lang['en'][35] = 'Process CSS';
|
81 |
+
$lang['en'][36] = 'Compression Ratio';
|
82 |
+
$lang['en'][37] = 'Input';
|
83 |
+
$lang['en'][38] = 'Output';
|
84 |
+
$lang['en'][39] = 'Language';
|
85 |
+
$lang['en'][41] = 'Attention: This may change the behaviour of your CSS Code!';
|
86 |
+
$lang['en'][42] = 'Remove last ;';
|
87 |
+
$lang['en'][43] = 'Discard invalid properties';
|
88 |
+
$lang['en'][44] = 'Only safe optimisations';
|
89 |
+
$lang['en'][45] = 'Compress font-weight';
|
90 |
+
$lang['en'][46] = 'Save comments';
|
91 |
+
$lang['en'][47] = 'Do not change anything';
|
92 |
+
$lang['en'][48] = 'Only seperate selectors (split at ,)';
|
93 |
+
$lang['en'][49] = 'Merge selectors with the same properties (fast)';
|
94 |
+
$lang['en'][50] = 'Merge selectors intelligently (slow)';
|
95 |
+
$lang['en'][51] = 'Preserve CSS';
|
96 |
+
$lang['en'][52] = 'Save comments, hacks, etc. Most optimisations can *not* be applied if this is enabled.';
|
97 |
+
$lang['en'][53] = 'None';
|
98 |
+
$lang['en'][54] = 'Don\'t optimise';
|
99 |
+
$lang['en'][55] = 'Safe optimisations';
|
100 |
+
$lang['en'][56] = 'All optimisations';
|
101 |
+
$lang['en'][57] = 'Add timestamp';
|
102 |
+
$lang['en'][58] = 'Copy to clipboard';
|
103 |
+
$lang['en'][59] = 'Back to top';
|
104 |
+
$lang['en'][60] = 'Your browser doesn\'t support copy to clipboard.';
|
105 |
+
$lang['en'][61] = 'For bugs and suggestions feel free to';
|
106 |
+
$lang['en'][62] = 'contact me';
|
107 |
+
$lang['en'][63] = 'Output CSS code as complete HTML document';
|
108 |
+
$lang['en'][64] = 'Code';
|
109 |
+
$lang['en'][65] = 'CSS to style CSS output';
|
110 |
+
$lang['en'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
|
111 |
+
|
112 |
+
|
113 |
+
$lang['de'][0] = 'CSS Formatierer und Optimierer (basierend auf CSSTidy ';
|
114 |
+
$lang['de'][1] = 'CSS Formatierer und Optimierer';
|
115 |
+
$lang['de'][2] = '(basierend auf';
|
116 |
+
$lang['de'][3] = '(Textversion)';
|
117 |
+
$lang['de'][4] = 'Wichtiger Hinweis:';
|
118 |
+
$lang['de'][6] = 'Der CSS Code sollte wohlgeformt sein. Der CSS Code wird <strong>nicht auf Gültigkeit überprüft</strong>. Um sicherzugehen dass dein Code valide ist, benutze den <a href="http://jigsaw.w3.org/css-validator/">W3C Validierungsservice</a>.';
|
119 |
+
$lang['de'][7] = 'alle Kommentare werden entfernt';
|
120 |
+
$lang['de'][8] = 'CSS Eingabe:';
|
121 |
+
$lang['de'][9] = 'CSS-Code:';
|
122 |
+
$lang['de'][10] = 'CSS von URL:';
|
123 |
+
$lang['de'][11] = 'Code Layout:';
|
124 |
+
$lang['de'][12] = 'Komprimierung (Code Layout):';
|
125 |
+
$lang['de'][13] = 'Höchste (keine Lesbarkeit, niedrigste Größe)';
|
126 |
+
$lang['de'][14] = 'Hoch (mittelmäßige Lesbarkeit, geringe Größe)';
|
127 |
+
$lang['de'][15] = 'Standard (Kompromiss zwischen Lesbarkeit und Größe)';
|
128 |
+
$lang['de'][16] = 'Niedrig (höhere Lesbarkeit)';
|
129 |
+
$lang['de'][17] = 'Benutzerdefiniert (unten eingeben)';
|
130 |
+
$lang['de'][18] = 'Benutzerdefinierte <a href="http://csstidy.sourceforge.net/templates.php">Vorlage</a>';
|
131 |
+
$lang['de'][19] = 'Optionen';
|
132 |
+
$lang['de'][20] = 'Selektoren sortieren (Vorsicht)';
|
133 |
+
$lang['de'][21] = 'Eigenschaften sortieren';
|
134 |
+
$lang['de'][22] = 'Selektoren umgruppieren';
|
135 |
+
$lang['de'][23] = 'Shorthands optimieren';
|
136 |
+
$lang['de'][24] = 'Farben komprimieren';
|
137 |
+
$lang['de'][25] = 'Selektoren in Kleinbuchstaben';
|
138 |
+
$lang['de'][26] = 'Groß-/Kleinschreibung für Eigenschaften';
|
139 |
+
$lang['de'][27] = 'Kleinbuchstaben';
|
140 |
+
$lang['de'][28] = 'Keine oder ungültige CSS Eingabe oder falsche URL!';
|
141 |
+
$lang['de'][29] = 'Großbuchstaben';
|
142 |
+
$lang['de'][30] = 'kleingeschriebene Elementnamen benötigt für XHTML';
|
143 |
+
$lang['de'][31] = 'Unnötige Backslashes entfernen';
|
144 |
+
$lang['de'][32] = '!important-Hack konvertieren';
|
145 |
+
$lang['de'][33] = 'Als Datei ausgeben';
|
146 |
+
$lang['de'][34] = 'Größere Komprimierung augrund von kleineren Neuezeile-Zeichen';
|
147 |
+
$lang['de'][35] = 'CSS verarbeiten';
|
148 |
+
$lang['de'][36] = 'Komprimierungsrate';
|
149 |
+
$lang['de'][37] = 'Eingabe';
|
150 |
+
$lang['de'][38] = 'Ausgabe';
|
151 |
+
$lang['de'][39] = 'Sprache';
|
152 |
+
$lang['de'][41] = 'Achtung: Dies könnte das Verhalten ihres CSS-Codes verändern!';
|
153 |
+
$lang['de'][42] = 'Letztes ; entfernen';
|
154 |
+
$lang['de'][43] = 'Ungültige Eigenschaften entfernen';
|
155 |
+
$lang['de'][44] = 'Nur sichere Optimierungen';
|
156 |
+
$lang['de'][45] = 'font-weight komprimieren';
|
157 |
+
$lang['de'][46] = 'Kommentare beibehalten';
|
158 |
+
$lang['de'][47] = 'Nichts ändern';
|
159 |
+
$lang['de'][48] = 'Selektoren nur trennen (am Komma)';
|
160 |
+
$lang['de'][49] = 'Selektoren mit gleichen Eigenschaften zusammenfassen (schnell)';
|
161 |
+
$lang['de'][50] = 'Selektoren intelligent zusammenfassen (langsam!)';
|
162 |
+
$lang['de'][51] = 'CSS erhalten';
|
163 |
+
$lang['de'][52] = 'Kommentare, Hacks, etc. speichern. Viele Optimierungen sind dann aber nicht mehr möglich.';
|
164 |
+
$lang['de'][53] = 'Keine';
|
165 |
+
$lang['de'][54] = 'Nicht optimieren';
|
166 |
+
$lang['de'][55] = 'Sichere Optimierungen';
|
167 |
+
$lang['de'][56] = 'Alle Optimierungen';
|
168 |
+
$lang['de'][57] = 'Zeitstempel hinzufügen';
|
169 |
+
$lang['de'][58] = 'Copy to clipboard';
|
170 |
+
$lang['de'][59] = 'Back to top';
|
171 |
+
$lang['de'][60] = 'Your browser doesn\'t support copy to clipboard.';
|
172 |
+
$lang['de'][61] = 'For bugs and suggestions feel free to';
|
173 |
+
$lang['de'][62] = 'contact me';
|
174 |
+
$lang['de'][63] = 'Output CSS code as complete HTML document';
|
175 |
+
$lang['de'][64] = 'Code';
|
176 |
+
$lang['de'][65] = 'CSS to style CSS output';
|
177 |
+
$lang['de'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
|
178 |
+
|
179 |
+
|
180 |
+
$lang['fr'][0] = 'CSS Formatteur et Optimiseur (basé sur CSSTidy ';
|
181 |
+
$lang['fr'][1] = 'CSS Formatteur et Optimiseur';
|
182 |
+
$lang['fr'][2] = '(basé sur ';
|
183 |
+
$lang['fr'][3] = '(Version texte)';
|
184 |
+
$lang['fr'][4] = 'Note Importante :';
|
185 |
+
$lang['fr'][6] = 'Votre code doit être valide. Ce n’est <strong>pas un validateur</strong> qui signale les erreurs dans votre code CSS. Pour être sûr que votre code est correct, utilisez le validateur : <a href="http://jigsaw.w3.org/css-validator/">W3C Validator</a>.';
|
186 |
+
$lang['fr'][7] = 'tous les commentaires sont enlevés';
|
187 |
+
$lang['fr'][8] = 'Champ CSS :';
|
188 |
+
$lang['fr'][9] = 'Code CSS :';
|
189 |
+
$lang['fr'][10] = 'CSS en provenance d’une URL :<br />';
|
190 |
+
$lang['fr'][11] = 'Mise en page du code :';
|
191 |
+
$lang['fr'][12] = 'Compression (mise en page du code) :';
|
192 |
+
$lang['fr'][13] = 'La plus élevée (aucune lisibilité, taille minimale)';
|
193 |
+
$lang['fr'][14] = 'Élevée (lisibilité modérée, petite taille)';
|
194 |
+
$lang['fr'][15] = 'Normale (équilibre entre lisibilité et taille)';
|
195 |
+
$lang['fr'][16] = 'Faible (lisibilité élevée)';
|
196 |
+
$lang['fr'][17] = 'Sur mesure (entrer ci-dessous)';
|
197 |
+
$lang['fr'][18] = '<a href="http://csstidy.sourceforge.net/templates.php">Gabarit</a> sur mesure';
|
198 |
+
$lang['fr'][19] = 'Options';
|
199 |
+
$lang['fr'][20] = 'Trier les sélecteurs (attention)';
|
200 |
+
$lang['fr'][21] = 'Trier les propriétés';
|
201 |
+
$lang['fr'][22] = 'Regrouper les sélecteurs';
|
202 |
+
$lang['fr'][23] = 'Propriétés raccourcies';
|
203 |
+
$lang['fr'][24] = 'Compresser les couleurs';
|
204 |
+
$lang['fr'][25] = 'Sélecteurs en minuscules';
|
205 |
+
$lang['fr'][26] = 'Case pour les propriétés :';
|
206 |
+
$lang['fr'][27] = 'Minuscule';
|
207 |
+
$lang['fr'][28] = 'CSS non valide ou URL incorrecte !';
|
208 |
+
$lang['fr'][29] = 'Majuscule';
|
209 |
+
$lang['fr'][30] = 'les noms des éléments en minuscules (indispensables pour XHTML)';
|
210 |
+
$lang['fr'][31] = 'enlever les antislashs inutiles';
|
211 |
+
$lang['fr'][32] = 'convertir !important-hack';
|
212 |
+
$lang['fr'][33] = 'Sauver en tant que fichier';
|
213 |
+
$lang['fr'][34] = 'Meilleure compression grâce aux caractères de saut de ligne plus petits (copier & coller ne marche pas)';
|
214 |
+
$lang['fr'][35] = 'Compresser la CSS';
|
215 |
+
$lang['fr'][36] = 'Facteur de Compression';
|
216 |
+
$lang['fr'][37] = 'Entrée';
|
217 |
+
$lang['fr'][38] = 'Sortie';
|
218 |
+
$lang['fr'][39] = 'Langue';
|
219 |
+
$lang['fr'][41] = 'Attention : ceci peut changer le comportement de votre code CSS !';
|
220 |
+
$lang['fr'][42] = 'Enlever le dernier ;';
|
221 |
+
$lang['fr'][43] = 'Supprimer les propriétés non valide';
|
222 |
+
$lang['fr'][44] = 'Seulement les optimisations sûres';
|
223 |
+
$lang['fr'][45] = 'Compresser font-weight';
|
224 |
+
$lang['fr'][46] = 'Sauvegarder les commentaires ';
|
225 |
+
$lang['fr'][47] = 'Ne rien changer';
|
226 |
+
$lang['fr'][48] = 'Sépare les sélecteurs (sépare au niveau de ,)';
|
227 |
+
$lang['fr'][49] = 'Fusionne les sélecteurs avec les mêmes propriétés (rapide)';
|
228 |
+
$lang['fr'][50] = 'Fusionne les sélecteurs intelligemment (lent)';
|
229 |
+
$lang['fr'][51] = 'Préserver la CSS';
|
230 |
+
$lang['fr'][52] = 'Sauvegarder les commentaires, hacks, etc. La plupart des optimisations ne peuvent *pas* être appliquées si cela est activé.';
|
231 |
+
$lang['fr'][53] = 'Aucun';
|
232 |
+
$lang['fr'][54] = 'Ne pas optimiser';
|
233 |
+
$lang['fr'][55] = 'Optimisations sûres';
|
234 |
+
$lang['fr'][56] = 'Toutes les optimisations';
|
235 |
+
$lang['fr'][57] = 'Ajouter un timestamp';
|
236 |
+
$lang['fr'][58] = 'Copier dans le presse-papiers';
|
237 |
+
$lang['fr'][59] = 'Retour en haut';
|
238 |
+
$lang['fr'][60] = 'Votre navigateur ne suporte pas la copie vers le presse-papiers.';
|
239 |
+
$lang['fr'][61] = 'Pour signaler des bugs ou pour des suggestions,';
|
240 |
+
$lang['fr'][62] = 'contactez-moi';
|
241 |
+
$lang['fr'][63] = 'Sauver le code CSS comme document complet HTML';
|
242 |
+
$lang['fr'][64] = 'Code';
|
243 |
+
$lang['fr'][65] = 'CSS pour colorier la sortie CSS';
|
244 |
+
$lang['fr'][66] = 'Vous devez aller dans about:config dans votre barre d’adresse, selectionner \'signed.applets.codebase_principal_support\' dans le champ Filtre et attribuez-lui la valeur \'true\' pour utiliser cette fonctionnalité; toutefois, soyez conscient que cela augmente les risques de sécurité.';
|
245 |
+
|
246 |
+
|
247 |
+
$lang['zh'][0] = 'CSS整形與最佳化工具(使用 CSSTidy ';
|
248 |
+
$lang['zh'][1] = 'CSS整形與最佳化工具';
|
249 |
+
$lang['zh'][2] = '(使用';
|
250 |
+
$lang['zh'][3] = '(純文字)';
|
251 |
+
$lang['zh'][4] = '重要事項:';
|
252 |
+
$lang['zh'][6] = '你的原始碼必須是良構的(well-formed). 這個工具<strong>沒有內建驗證器(validator)</strong>. 驗證器能夠指出你CSS原始碼裡的錯誤. 請使用 <a href="http://jigsaw.w3.org/css-validator/">W3C 驗證器</a>, 確保你的原始碼合乎規範.';
|
253 |
+
$lang['zh'][7] = '所有註解都移除了';
|
254 |
+
$lang['zh'][8] = 'CSS 輸入:';
|
255 |
+
$lang['zh'][9] = 'CSS 原始碼:';
|
256 |
+
$lang['zh'][10] = 'CSS 檔案網址(URL):';
|
257 |
+
$lang['zh'][11] = '原始碼規劃:';
|
258 |
+
$lang['zh'][12] = '壓縮程度(原始碼規劃):';
|
259 |
+
$lang['zh'][13] = '最高 (沒有辦法讀, 檔案最小)';
|
260 |
+
$lang['zh'][14] = '高 (適度的可讀性, 檔案小)';
|
261 |
+
$lang['zh'][15] = '標準 (兼顧可讀性與檔案大小)';
|
262 |
+
$lang['zh'][16] = '低 (注重可讀性)';
|
263 |
+
$lang['zh'][17] = '自訂 (在下方設定)';
|
264 |
+
$lang['zh'][18] = '自訂<a href="http://csstidy.sourceforge.net/templates.php">樣板</a>';
|
265 |
+
$lang['zh'][19] = '選項';
|
266 |
+
$lang['zh'][20] = '整理選擇符(請謹慎使用)';
|
267 |
+
$lang['zh'][21] = '整理屬性';
|
268 |
+
$lang['zh'][22] = '重組選擇符';
|
269 |
+
$lang['zh'][23] = '速記法(shorthand)最佳化';
|
270 |
+
$lang['zh'][24] = '壓縮色彩語法';
|
271 |
+
$lang['zh'][25] = '改用小寫選擇符';
|
272 |
+
$lang['zh'][26] = '屬性的字形:';
|
273 |
+
$lang['zh'][27] = '小寫';
|
274 |
+
$lang['zh'][28] = '沒有輸入CSS, 語法不符合規定, 或是網址錯誤!';
|
275 |
+
$lang['zh'][29] = '大寫';
|
276 |
+
$lang['zh'][30] = 'XHTML必須使用小寫的元素名稱';
|
277 |
+
$lang['zh'][31] = '移除不必要的反斜線';
|
278 |
+
$lang['zh'][32] = '轉換 !important-hack';
|
279 |
+
$lang['zh'][33] = '輸出成檔案形式';
|
280 |
+
$lang['zh'][34] = '由於比較少換行字元, 會有更大的壓縮比率(複製&貼上沒有用)';
|
281 |
+
$lang['zh'][35] = '執行';
|
282 |
+
$lang['zh'][36] = '壓縮比率';
|
283 |
+
$lang['zh'][37] = '輸入';
|
284 |
+
$lang['zh'][38] = '輸出';
|
285 |
+
$lang['zh'][39] = '語言';
|
286 |
+
$lang['zh'][41] = '注意: 這或許會變更你CSS原始碼的行為!';
|
287 |
+
$lang['zh'][42] = '除去最後一個分號';
|
288 |
+
$lang['zh'][43] = '拋棄不符合規定的屬性';
|
289 |
+
$lang['zh'][44] = '只安全地最佳化';
|
290 |
+
$lang['zh'][45] = '壓縮 font-weight';
|
291 |
+
$lang['zh'][46] = '保留註解';
|
292 |
+
$lang['zh'][47] = '什麼都不要改';
|
293 |
+
$lang['zh'][48] = '只分開原本用逗號分隔的選擇符';
|
294 |
+
$lang['zh'][49] = '合併有相同屬性的選擇符(快速)';
|
295 |
+
$lang['zh'][50] = '聰明地合併選擇符(慢速)';
|
296 |
+
$lang['zh'][51] = '保護CSS';
|
297 |
+
$lang['zh'][52] = '保留註解與 hack 等等. 如果啟用這個選項, 大多數的最佳化程序都不會執行.';
|
298 |
+
$lang['zh'][53] = '不改變';
|
299 |
+
$lang['zh'][54] = '不做最佳化';
|
300 |
+
$lang['zh'][55] = '安全地最佳化';
|
301 |
+
$lang['zh'][56] = '全部最佳化';
|
302 |
+
$lang['zh'][57] = '加上時間戳記';
|
303 |
+
$lang['zh'][58] = '复制到剪贴板';
|
304 |
+
$lang['zh'][59] = '回到页面上方';
|
305 |
+
$lang['zh'][60] = '你的浏览器不支持复制到剪贴板。';
|
306 |
+
$lang['zh'][61] = '如果程序有错误或你有建议,欢迎';
|
307 |
+
$lang['zh'][62] = '和我联系';
|
308 |
+
$lang['zh'][63] = 'Output CSS code as complete HTML document';
|
309 |
+
$lang['zh'][64] = '代码';
|
310 |
+
$lang['zh'][65] = 'CSS to style CSS output';
|
311 |
+
$lang['zh'][66] = 'You need to go to about:config in your URL bar, select \'signed.applets.codebase_principal_support\' in the filter field, and set its value to true in order to use this feature; however, be aware that doing so increases security risks.';
|
classes/edd-sl-plugin-updater.php
CHANGED
@@ -1,140 +1,140 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
// uncomment this line for testing
|
4 |
-
//set_site_transient( 'update_plugins', null );
|
5 |
-
|
6 |
-
/**
|
7 |
-
* Allows plugins to use their own update API.
|
8 |
-
*
|
9 |
-
* @author Pippin Williamson
|
10 |
-
* @version 1.0
|
11 |
-
*/
|
12 |
-
class EDD_SL_Plugin_Updater {
|
13 |
-
private $api_url = '';
|
14 |
-
private $api_data = array();
|
15 |
-
private $name = '';
|
16 |
-
private $slug = '';
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Class constructor.
|
20 |
-
*
|
21 |
-
* @uses plugin_basename()
|
22 |
-
* @uses hook()
|
23 |
-
*
|
24 |
-
* @param string $_api_url The URL pointing to the custom API endpoint.
|
25 |
-
* @param string $_plugin_file Path to the plugin file.
|
26 |
-
* @param array $_api_data Optional data to send with API calls.
|
27 |
-
* @return void
|
28 |
-
*/
|
29 |
-
function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
|
30 |
-
$this->api_url = trailingslashit( $_api_url );
|
31 |
-
$this->api_data = urlencode_deep( $_api_data );
|
32 |
-
$this->name = plugin_basename( $_plugin_file );
|
33 |
-
$this->slug = basename( $_plugin_file, '.php');
|
34 |
-
$this->version = $_api_data['version'];
|
35 |
-
|
36 |
-
// Set up hooks.
|
37 |
-
$this->hook();
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Set up Wordpress filters to hook into WP's update process.
|
42 |
-
*
|
43 |
-
* @uses add_filter()
|
44 |
-
*
|
45 |
-
* @return void
|
46 |
-
*/
|
47 |
-
private function hook() {
|
48 |
-
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'pre_set_site_transient_update_plugins_filter' ) );
|
49 |
-
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3);
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Check for Updates at the defined API endpoint and modify the update array.
|
54 |
-
*
|
55 |
-
* This function dives into the update api just when Wordpress creates its update array,
|
56 |
-
* then adds a custom API call and injects the custom plugin data retrieved from the API.
|
57 |
-
* It is reassembled from parts of the native Wordpress plugin update code.
|
58 |
-
* See wp-includes/update.php line 121 for the original wp_update_plugins() function.
|
59 |
-
*
|
60 |
-
* @uses api_request()
|
61 |
-
*
|
62 |
-
* @param array $_transient_data Update array build by Wordpress.
|
63 |
-
* @return array Modified update array with custom plugin data.
|
64 |
-
*/
|
65 |
-
function pre_set_site_transient_update_plugins_filter( $_transient_data ) {
|
66 |
-
|
67 |
-
|
68 |
-
if( empty( $_transient_data ) ) return $_transient_data;
|
69 |
-
|
70 |
-
$to_send = array( 'slug' => $this->slug );
|
71 |
-
|
72 |
-
$api_response = $this->api_request( 'plugin_latest_version', $to_send );
|
73 |
-
|
74 |
-
if( false !== $api_response && is_object( $api_response ) ) {
|
75 |
-
if( version_compare( $this->version, $api_response->new_version, '<' ) )
|
76 |
-
$_transient_data->response[$this->name] = $api_response;
|
77 |
-
}
|
78 |
-
return $_transient_data;
|
79 |
-
}
|
80 |
-
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Updates information on the "View version x.x details" page with custom data.
|
84 |
-
*
|
85 |
-
* @uses api_request()
|
86 |
-
*
|
87 |
-
* @param mixed $_data
|
88 |
-
* @param string $_action
|
89 |
-
* @param object $_args
|
90 |
-
* @return object $_data
|
91 |
-
*/
|
92 |
-
function plugins_api_filter( $_data, $_action = '', $_args = null ) {
|
93 |
-
if ( ( $_action != 'plugin_information' ) || !isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) return $_data;
|
94 |
-
|
95 |
-
$to_send = array( 'slug' => $this->slug );
|
96 |
-
|
97 |
-
$api_response = $this->api_request( 'plugin_information', $to_send );
|
98 |
-
if ( false !== $api_response ) $_data = $api_response;
|
99 |
-
|
100 |
-
return $_data;
|
101 |
-
}
|
102 |
-
|
103 |
-
/**
|
104 |
-
* Calls the API and, if successfull, returns the object delivered by the API.
|
105 |
-
*
|
106 |
-
* @uses get_bloginfo()
|
107 |
-
* @uses wp_remote_post()
|
108 |
-
* @uses is_wp_error()
|
109 |
-
*
|
110 |
-
* @param string $_action The requested action.
|
111 |
-
* @param array $_data Parameters for the API action.
|
112 |
-
* @return false||object
|
113 |
-
*/
|
114 |
-
private function api_request( $_action, $_data ) {
|
115 |
-
|
116 |
-
global $wp_version;
|
117 |
-
|
118 |
-
$data = array_merge( $this->api_data, $_data );
|
119 |
-
if( $data['slug'] != $this->slug )
|
120 |
-
return;
|
121 |
-
|
122 |
-
$api_params = array(
|
123 |
-
'edd_action' => 'get_version',
|
124 |
-
'license' => $data['license'],
|
125 |
-
'name' => $data['item_name'],
|
126 |
-
'slug' => $this->slug,
|
127 |
-
'author' => $data['author']
|
128 |
-
);
|
129 |
-
$request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
|
130 |
-
|
131 |
-
if ( !is_wp_error( $request ) ):
|
132 |
-
$request = json_decode( wp_remote_retrieve_body( $request ) );
|
133 |
-
if( $request )
|
134 |
-
$request->sections = maybe_unserialize( $request->sections );
|
135 |
-
return $request;
|
136 |
-
else:
|
137 |
-
return false;
|
138 |
-
endif;
|
139 |
-
}
|
140 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// uncomment this line for testing
|
4 |
+
//set_site_transient( 'update_plugins', null );
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Allows plugins to use their own update API.
|
8 |
+
*
|
9 |
+
* @author Pippin Williamson
|
10 |
+
* @version 1.0
|
11 |
+
*/
|
12 |
+
class EDD_SL_Plugin_Updater {
|
13 |
+
private $api_url = '';
|
14 |
+
private $api_data = array();
|
15 |
+
private $name = '';
|
16 |
+
private $slug = '';
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Class constructor.
|
20 |
+
*
|
21 |
+
* @uses plugin_basename()
|
22 |
+
* @uses hook()
|
23 |
+
*
|
24 |
+
* @param string $_api_url The URL pointing to the custom API endpoint.
|
25 |
+
* @param string $_plugin_file Path to the plugin file.
|
26 |
+
* @param array $_api_data Optional data to send with API calls.
|
27 |
+
* @return void
|
28 |
+
*/
|
29 |
+
function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
|
30 |
+
$this->api_url = trailingslashit( $_api_url );
|
31 |
+
$this->api_data = urlencode_deep( $_api_data );
|
32 |
+
$this->name = plugin_basename( $_plugin_file );
|
33 |
+
$this->slug = basename( $_plugin_file, '.php');
|
34 |
+
$this->version = $_api_data['version'];
|
35 |
+
|
36 |
+
// Set up hooks.
|
37 |
+
$this->hook();
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Set up Wordpress filters to hook into WP's update process.
|
42 |
+
*
|
43 |
+
* @uses add_filter()
|
44 |
+
*
|
45 |
+
* @return void
|
46 |
+
*/
|
47 |
+
private function hook() {
|
48 |
+
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'pre_set_site_transient_update_plugins_filter' ) );
|
49 |
+
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3);
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Check for Updates at the defined API endpoint and modify the update array.
|
54 |
+
*
|
55 |
+
* This function dives into the update api just when Wordpress creates its update array,
|
56 |
+
* then adds a custom API call and injects the custom plugin data retrieved from the API.
|
57 |
+
* It is reassembled from parts of the native Wordpress plugin update code.
|
58 |
+
* See wp-includes/update.php line 121 for the original wp_update_plugins() function.
|
59 |
+
*
|
60 |
+
* @uses api_request()
|
61 |
+
*
|
62 |
+
* @param array $_transient_data Update array build by Wordpress.
|
63 |
+
* @return array Modified update array with custom plugin data.
|
64 |
+
*/
|
65 |
+
function pre_set_site_transient_update_plugins_filter( $_transient_data ) {
|
66 |
+
|
67 |
+
|
68 |
+
if( empty( $_transient_data ) ) return $_transient_data;
|
69 |
+
|
70 |
+
$to_send = array( 'slug' => $this->slug );
|
71 |
+
|
72 |
+
$api_response = $this->api_request( 'plugin_latest_version', $to_send );
|
73 |
+
|
74 |
+
if( false !== $api_response && is_object( $api_response ) ) {
|
75 |
+
if( version_compare( $this->version, $api_response->new_version, '<' ) )
|
76 |
+
$_transient_data->response[$this->name] = $api_response;
|
77 |
+
}
|
78 |
+
return $_transient_data;
|
79 |
+
}
|
80 |
+
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Updates information on the "View version x.x details" page with custom data.
|
84 |
+
*
|
85 |
+
* @uses api_request()
|
86 |
+
*
|
87 |
+
* @param mixed $_data
|
88 |
+
* @param string $_action
|
89 |
+
* @param object $_args
|
90 |
+
* @return object $_data
|
91 |
+
*/
|
92 |
+
function plugins_api_filter( $_data, $_action = '', $_args = null ) {
|
93 |
+
if ( ( $_action != 'plugin_information' ) || !isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) return $_data;
|
94 |
+
|
95 |
+
$to_send = array( 'slug' => $this->slug );
|
96 |
+
|
97 |
+
$api_response = $this->api_request( 'plugin_information', $to_send );
|
98 |
+
if ( false !== $api_response ) $_data = $api_response;
|
99 |
+
|
100 |
+
return $_data;
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Calls the API and, if successfull, returns the object delivered by the API.
|
105 |
+
*
|
106 |
+
* @uses get_bloginfo()
|
107 |
+
* @uses wp_remote_post()
|
108 |
+
* @uses is_wp_error()
|
109 |
+
*
|
110 |
+
* @param string $_action The requested action.
|
111 |
+
* @param array $_data Parameters for the API action.
|
112 |
+
* @return false||object
|
113 |
+
*/
|
114 |
+
private function api_request( $_action, $_data ) {
|
115 |
+
|
116 |
+
global $wp_version;
|
117 |
+
|
118 |
+
$data = array_merge( $this->api_data, $_data );
|
119 |
+
if( $data['slug'] != $this->slug )
|
120 |
+
return;
|
121 |
+
|
122 |
+
$api_params = array(
|
123 |
+
'edd_action' => 'get_version',
|
124 |
+
'license' => $data['license'],
|
125 |
+
'name' => $data['item_name'],
|
126 |
+
'slug' => $this->slug,
|
127 |
+
'author' => $data['author']
|
128 |
+
);
|
129 |
+
$request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
|
130 |
+
|
131 |
+
if ( !is_wp_error( $request ) ):
|
132 |
+
$request = json_decode( wp_remote_retrieve_body( $request ) );
|
133 |
+
if( $request )
|
134 |
+
$request->sections = maybe_unserialize( $request->sections );
|
135 |
+
return $request;
|
136 |
+
else:
|
137 |
+
return false;
|
138 |
+
endif;
|
139 |
+
}
|
140 |
}
|
classes/styles-admin.php
CHANGED
@@ -1,200 +1,404 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class Styles_Admin {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var Styles_Plugin
|
7 |
-
*/
|
8 |
-
var $plugin;
|
9 |
-
|
10 |
-
/**
|
11 |
-
*
|
12 |
-
*/
|
13 |
-
var $
|
14 |
-
|
15 |
-
/**
|
16 |
-
*
|
17 |
-
*/
|
18 |
-
var $
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
);
|
24 |
-
|
25 |
-
/**
|
26 |
-
*
|
27 |
-
*/
|
28 |
-
var $
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
//
|
46 |
-
add_action( '
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
*
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
*
|
81 |
-
*
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
)
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Styles_Admin {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var Styles_Plugin
|
7 |
+
*/
|
8 |
+
var $plugin;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var array All sections
|
12 |
+
*/
|
13 |
+
var $sections;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var array All settings
|
17 |
+
*/
|
18 |
+
var $settings;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Admin notices
|
22 |
+
*/
|
23 |
+
var $notices = array();
|
24 |
+
|
25 |
+
/**
|
26 |
+
* List of theme slugs we know have styles plugins on wordpress.org
|
27 |
+
*/
|
28 |
+
var $default_themes = array(
|
29 |
+
'twentyten',
|
30 |
+
'twentyeleven',
|
31 |
+
'twentytwelve',
|
32 |
+
'twentythirteen',
|
33 |
+
);
|
34 |
+
|
35 |
+
function __construct( $plugin ) {
|
36 |
+
$this->plugin = $plugin;
|
37 |
+
|
38 |
+
// Settings
|
39 |
+
$this->sections_init();
|
40 |
+
$this->settings_init();
|
41 |
+
|
42 |
+
add_action( 'admin_init', array( $this, 'register_settings' ) );
|
43 |
+
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
|
44 |
+
|
45 |
+
// Notices
|
46 |
+
add_action( 'admin_init', array( $this, 'install_default_themes_notice' ), 20 );
|
47 |
+
add_action( 'admin_init', array( $this, 'activate_notice' ), 30 );
|
48 |
+
add_action( 'admin_notices', array( $this, 'admin_notices' ) );
|
49 |
+
add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_notices' ), 11 );
|
50 |
+
|
51 |
+
// Scripts
|
52 |
+
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
|
53 |
+
|
54 |
+
// Plugin Meta
|
55 |
+
add_filter( 'plugin_action_links_' . STYLES_BASENAME, array( $this, 'plugin_action_links' ) );
|
56 |
+
add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
|
57 |
+
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Enqueue admin stylesheet
|
62 |
+
* Adds the blue "Customize" button to the plugin row.
|
63 |
+
*/
|
64 |
+
public function admin_enqueue_scripts() {
|
65 |
+
wp_enqueue_style( 'storm-styles-admin', plugins_url('css/styles-admin.css', STYLES_BASENAME), array(), $this->plugin->version, 'all' );
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Populate $this->sections with all section arguements
|
70 |
+
*
|
71 |
+
* @return void
|
72 |
+
*/
|
73 |
+
public function sections_init() {
|
74 |
+
$this->sections = array(
|
75 |
+
'general' => __( 'General', 'styles' ),
|
76 |
+
);
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Populate $this->settings with all settings arguements
|
81 |
+
*
|
82 |
+
* @return void
|
83 |
+
*/
|
84 |
+
public function settings_init() {
|
85 |
+
$this->settings = array(
|
86 |
+
|
87 |
+
'debug_mode' => array(
|
88 |
+
'title' => __( 'Debug Mode', 'styles' ),
|
89 |
+
'description' => __( 'Allow information about your settings and WordPress setup to be viewed by Styles support.', 'styles' ),
|
90 |
+
'default' => 0,
|
91 |
+
'type' => 'radio',
|
92 |
+
'section' => 'general',
|
93 |
+
'class' => '',
|
94 |
+
'choices' => array(
|
95 |
+
'Enable' => 1,
|
96 |
+
'Disable' => 0,
|
97 |
+
),
|
98 |
+
),
|
99 |
+
|
100 |
+
'delete_settings' => array(
|
101 |
+
'title' => __( 'Reset Settings', 'styles' ),
|
102 |
+
'description' => __( 'Type DELETE into this field and save to verify a reset of all Styles settings.', 'styles' ),
|
103 |
+
'default' => '',
|
104 |
+
'type' => 'input',
|
105 |
+
'section' => 'general',
|
106 |
+
),
|
107 |
+
|
108 |
+
);
|
109 |
+
}
|
110 |
+
|
111 |
+
public function admin_menu() {
|
112 |
+
|
113 |
+
add_options_page(
|
114 |
+
'Styles', // Page title
|
115 |
+
'Styles', // Menu title
|
116 |
+
'manage_options', // Capability
|
117 |
+
'styles', // Menu slug
|
118 |
+
array( $this, 'admin_options' ) // Page display callback
|
119 |
+
);
|
120 |
+
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Output the options page view.
|
125 |
+
*
|
126 |
+
* @return null Outputs views/admin-options.php and exits.
|
127 |
+
*/
|
128 |
+
function admin_options() {
|
129 |
+
$this->plugin->get_view( 'admin-options' );
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Register settings
|
134 |
+
*/
|
135 |
+
public function register_settings() {
|
136 |
+
|
137 |
+
register_setting( 'styles', 'storm-styles', array ( $this, 'validate_settings' ) );
|
138 |
+
|
139 |
+
foreach ( $this->sections as $slug => $title ) {
|
140 |
+
add_settings_section(
|
141 |
+
$slug,
|
142 |
+
$title,
|
143 |
+
null, // Section display callback
|
144 |
+
'styles'
|
145 |
+
);
|
146 |
+
}
|
147 |
+
|
148 |
+
foreach ( $this->settings as $id => $setting ) {
|
149 |
+
$setting['id'] = $id;
|
150 |
+
$this->create_setting( $setting );
|
151 |
+
}
|
152 |
+
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Create settings field
|
157 |
+
*
|
158 |
+
* @since 1.0
|
159 |
+
*/
|
160 |
+
public function create_setting( $args = array() ) {
|
161 |
+
|
162 |
+
$defaults = array(
|
163 |
+
'id' => 'default_field',
|
164 |
+
'title' => __( 'Default Field', 'styles' ),
|
165 |
+
'description' => __( 'Default description.', 'styles' ),
|
166 |
+
'default' => '',
|
167 |
+
'type' => 'text',
|
168 |
+
'section' => 'general',
|
169 |
+
'choices' => array(),
|
170 |
+
'class' => ''
|
171 |
+
);
|
172 |
+
|
173 |
+
extract( wp_parse_args( $args, $defaults ) );
|
174 |
+
|
175 |
+
$field_args = array(
|
176 |
+
'type' => $type,
|
177 |
+
'id' => $id,
|
178 |
+
'description' => $description,
|
179 |
+
'default' => $default,
|
180 |
+
'choices' => $choices,
|
181 |
+
'label_for' => $id,
|
182 |
+
'class' => $class
|
183 |
+
);
|
184 |
+
|
185 |
+
add_settings_field(
|
186 |
+
$id,
|
187 |
+
$title,
|
188 |
+
array( $this, 'display_setting' ),
|
189 |
+
'styles',
|
190 |
+
$section,
|
191 |
+
$field_args
|
192 |
+
);
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Load view for setting, passing arguments
|
197 |
+
*/
|
198 |
+
public function display_setting( $args = array() ) {
|
199 |
+
|
200 |
+
$id = $type = $default = false;
|
201 |
+
extract( $args, EXTR_IF_EXISTS );
|
202 |
+
|
203 |
+
$options = get_option( 'storm-styles' );
|
204 |
+
|
205 |
+
if ( !isset( $options[$id] ) ) {
|
206 |
+
$options[$id] = $default;
|
207 |
+
}
|
208 |
+
|
209 |
+
$args['option_value'] = $options[ $id ];
|
210 |
+
$args['option_name'] = 'storm-styles' . '[' . $id . ']';
|
211 |
+
|
212 |
+
$template = 'setting-' . $type;
|
213 |
+
|
214 |
+
$this->plugin->get_view( $template, $args );
|
215 |
+
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Validate settings
|
220 |
+
*/
|
221 |
+
public function validate_settings( $input ) {
|
222 |
+
|
223 |
+
// Combine input with general settings
|
224 |
+
$input = array_merge( (array) get_option('storm-styles'), $input );
|
225 |
+
|
226 |
+
if ( isset( $input['delete_settings'] ) && 'DELETE' == $input['delete_settings'] ) {
|
227 |
+
$this->delete_settings();
|
228 |
+
$input['delete_settings'] = false;
|
229 |
+
|
230 |
+
$this->notices[] = '<p>Styles settings have been deleted.</p>';
|
231 |
+
}
|
232 |
+
|
233 |
+
// Todo: Sanatize.
|
234 |
+
return $input;
|
235 |
+
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* Add additional links to the plugin actions.
|
240 |
+
* For example, "Settings"
|
241 |
+
*/
|
242 |
+
public function plugin_action_links( $links ) {
|
243 |
+
|
244 |
+
$links['settings'] = '<a href="' . admin_url( 'options-general.php?page=styles' ) . '">Settings</a>';
|
245 |
+
|
246 |
+
return $links;
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* Add additional links to the plugin row
|
251 |
+
* For example, "Customize"
|
252 |
+
*
|
253 |
+
* Change the title of "Visit plugin site"
|
254 |
+
*/
|
255 |
+
public function plugin_row_meta( $meta, $basename ) {
|
256 |
+
if ( STYLES_BASENAME == $basename ) {
|
257 |
+
$meta[2] = str_replace( 'Visit plugin site', 'Get More Themes', $meta[2] );
|
258 |
+
$meta[] = '<a class="button button-primary" href="' . admin_url( 'customize.php' ) . '">Customize Theme</a>';
|
259 |
+
}
|
260 |
+
return $meta;
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Notice for novice users.
|
265 |
+
*
|
266 |
+
* If a default theme is active, but no Styles add-on is active,
|
267 |
+
* display a prompt with a link to install the add-on from wordpress.org
|
268 |
+
*
|
269 |
+
* Does not run if:
|
270 |
+
* Active template is not in $this->default_themes
|
271 |
+
* Any active or inactive plugin declares support for the current theme
|
272 |
+
* `styles_disable_notices` filter returns true
|
273 |
+
* Example: <code>add_filter( 'styles_disable_notices', '__return_true' );</code>
|
274 |
+
*/
|
275 |
+
public function install_default_themes_notice() {
|
276 |
+
if (
|
277 |
+
apply_filters( 'styles_disable_notices', false )
|
278 |
+
|| $this->is_plugin_update_or_delete()
|
279 |
+
|| !in_array( get_stylesheet(), $this->default_themes ) // Active theme is a parent and default
|
280 |
+
) {
|
281 |
+
return false;
|
282 |
+
}
|
283 |
+
|
284 |
+
$plugin_installed = false;
|
285 |
+
if ( is_a( $this->plugin->child, 'Styles_Child' ) ) {
|
286 |
+
|
287 |
+
$all_styles_plugins = array_merge( (array) $this->plugin->child->plugins, (array) $this->plugin->child->inactive_plugins );
|
288 |
+
|
289 |
+
foreach ( $all_styles_plugins as $plugin ) {
|
290 |
+
if ( $plugin->is_target_theme_active() ) {
|
291 |
+
// This plugin is for the active theme, but is inactive
|
292 |
+
$plugin_installed = true;
|
293 |
+
}
|
294 |
+
}
|
295 |
+
}
|
296 |
+
|
297 |
+
if ( !$plugin_installed ) {
|
298 |
+
$theme = wp_get_theme();
|
299 |
+
$slug = 'styles-' . get_template();
|
300 |
+
$url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $slug ), 'install-plugin_' . $slug );
|
301 |
+
$this->notices[] = "<p>Styles is almost ready! To add theme options for <strong>{$theme->name}</strong>, please <a href='$url'>install Styles: {$theme->name}</a>.</p>";
|
302 |
+
return true;
|
303 |
+
}
|
304 |
+
}
|
305 |
+
|
306 |
+
/**
|
307 |
+
* Notice for novice users.
|
308 |
+
*
|
309 |
+
* If an inactive plugin declares support for the currently active theme,
|
310 |
+
* display a notice with a link to active the plugin.
|
311 |
+
*
|
312 |
+
* Does not run if:
|
313 |
+
* `styles_disable_notices` filter returns true
|
314 |
+
* Example: <code>add_filter( 'styles_disable_notices', '__return_true' );</code>
|
315 |
+
*/
|
316 |
+
public function activate_notice() {
|
317 |
+
if (
|
318 |
+
apply_filters( 'styles_disable_notices', false )
|
319 |
+
|| $this->is_plugin_update_or_delete()
|
320 |
+
|| !is_a( $this->plugin->child, 'Styles_Child' ) // No child plugins installed
|
321 |
+
) {
|
322 |
+
return false;
|
323 |
+
}
|
324 |
+
|
325 |
+
foreach ( (array) $this->plugin->child->inactive_plugins as $plugin ) {
|
326 |
+
if ( $plugin->is_target_theme_active() ) {
|
327 |
+
// This plugin is for the active theme, but is inactive
|
328 |
+
$theme_name = $plugin->theme->get('Name');
|
329 |
+
$url = wp_nonce_url(self_admin_url('plugins.php?action=activate&plugin=' . $plugin->plugin_basename ), 'activate-plugin_' . $plugin->plugin_basename );
|
330 |
+
$this->notices[] = "<p><strong>{$plugin->name}</strong> is installed, but not active. To add Styles support for $theme_name, please <a href='$url'>activate {$plugin->name}</a>.</p>";
|
331 |
+
}
|
332 |
+
}
|
333 |
+
|
334 |
+
}
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Check whether we're on a screen for updating or deleting plugins.
|
338 |
+
* If we are, return false to disable notices.
|
339 |
+
*/
|
340 |
+
public function is_plugin_update_or_delete() {
|
341 |
+
if ( 'update.php' == basename( $_SERVER['PHP_SELF'] )
|
342 |
+
|| ( isset( $_GET['action'] ) && 'delete-selected' == $_GET['action'] )
|
343 |
+
|| !current_user_can('install_plugins')
|
344 |
+
){
|
345 |
+
return true;
|
346 |
+
}else {
|
347 |
+
return false;
|
348 |
+
}
|
349 |
+
}
|
350 |
+
|
351 |
+
/**
|
352 |
+
* Output all notices that have been added to the $this->notices array
|
353 |
+
*/
|
354 |
+
public function admin_notices() {
|
355 |
+
foreach( $this->notices as $key => $message ) {
|
356 |
+
echo "<div class='updated fade' id='styles-$key'>$message</div>";
|
357 |
+
}
|
358 |
+
}
|
359 |
+
|
360 |
+
/**
|
361 |
+
* Allows notices to display in the customize.php sidebar
|
362 |
+
*
|
363 |
+
* @return null Passes $this->notices array to styles-customize-controls.js
|
364 |
+
*/
|
365 |
+
public function customize_notices() {
|
366 |
+
wp_localize_script( 'styles-customize-controls', 'wp_styles_notices', $this->notices );
|
367 |
+
}
|
368 |
+
|
369 |
+
/**
|
370 |
+
* Delete all Styles settings.
|
371 |
+
* @return void
|
372 |
+
*/
|
373 |
+
public function delete_settings() {
|
374 |
+
global $wpdb;
|
375 |
+
|
376 |
+
if( is_multisite() ){
|
377 |
+
|
378 |
+
// Site network: remove options from each blog
|
379 |
+
$blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
|
380 |
+
if( $blog_ids ){
|
381 |
+
|
382 |
+
foreach( $blog_ids as $id ) {
|
383 |
+
switch_to_blog( $id );
|
384 |
+
|
385 |
+
// $wpdb->options is new for each blog, so we're duplicating SQL in the loop
|
386 |
+
$sql = "DELETE from $wpdb->options WHERE option_name LIKE 'storm-styles-%'";
|
387 |
+
$sql = "DELETE from $wpdb->options WHERE option_name LIKE '\_transient%storm-styles-%'";
|
388 |
+
$wpdb->query( $sql );
|
389 |
+
|
390 |
+
restore_current_blog();
|
391 |
+
}
|
392 |
+
|
393 |
+
}
|
394 |
+
|
395 |
+
}else {
|
396 |
+
// Single site
|
397 |
+
$sql = "DELETE from $wpdb->options WHERE option_name LIKE 'storm-styles-%'";
|
398 |
+
$sql = "DELETE from $wpdb->options WHERE option_name LIKE '\_transient%storm-styles-%'";
|
399 |
+
$wpdb->query( $sql );
|
400 |
+
}
|
401 |
+
|
402 |
+
}
|
403 |
+
|
404 |
}
|
classes/styles-child-theme.php
CHANGED
@@ -1,158 +1,158 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class Styles_Child_Theme extends Styles_Child_Updatable {
|
4 |
-
|
5 |
-
var $template;
|
6 |
-
var $styles_css;
|
7 |
-
|
8 |
-
public function __construct( $args ) {
|
9 |
-
parent::__construct( $args );
|
10 |
-
|
11 |
-
$this->template = str_replace( ' ', '-', strtolower( $this->item_name ) );
|
12 |
-
$this->styles_css = dirname( $this->plugin_file ) . '/style.css';
|
13 |
-
$this->plugin_theme_name = trim( str_replace( 'Styles:', '', $this->name ) );
|
14 |
-
|
15 |
-
$this->theme = wp_get_theme();
|
16 |
-
|
17 |
-
add_filter( 'styles_css_output', array( $this, 'styles_css_output' ) );
|
18 |
-
}
|
19 |
-
|
20 |
-
public function is_target_parent_or_child_theme_active() {
|
21 |
-
return ( $this->is_target_theme_active() || $this->is_target_parent_theme_active() );
|
22 |
-
}
|
23 |
-
|
24 |
-
public function is_target_parent_theme_active() {
|
25 |
-
if ( !is_a( $this->theme->parent() , 'WP_Theme') ) { return false; }
|
26 |
-
|
27 |
-
// Do parent or child theme header name == Styles plugin "Style Item" header?
|
28 |
-
// WARNING: Don't use this option. It's likely to change.
|
29 |
-
if ( $this->theme_name_equals_plugin_item_name( $this->theme->parent() ) ) { return true; }
|
30 |
-
|
31 |
-
// Do parent or child theme header name == Styles plugin header name?
|
32 |
-
if ( $this->theme_name_equals_plugin_name( $this->theme->parent() ) ) { return true; }
|
33 |
-
|
34 |
-
// Does the parent or child directory name == Styles directory name?
|
35 |
-
if ( $this->theme_directory_name_equals_plugin_directory_name( $this->theme->parent() ) ) { return true; }
|
36 |
-
|
37 |
-
return false;
|
38 |
-
}
|
39 |
-
|
40 |
-
public function is_target_theme_active() {
|
41 |
-
// Do parent or child theme header name == Styles plugin "Style Item" header?
|
42 |
-
// WARNING: Don't use this option. It's likely to change.
|
43 |
-
if ( $this->theme_name_equals_plugin_item_name( $this->theme ) ) { return true; }
|
44 |
-
|
45 |
-
// Do parent or child theme header name == Styles plugin header name?
|
46 |
-
if ( $this->theme_name_equals_plugin_name( $this->theme ) ) { return true; }
|
47 |
-
|
48 |
-
// Does the parent or child directory name == Styles directory name?
|
49 |
-
if ( $this->theme_directory_name_equals_plugin_directory_name( $this->theme ) ) { return true; }
|
50 |
-
|
51 |
-
return false;
|
52 |
-
}
|
53 |
-
|
54 |
-
/**
|
55 |
-
* Do parent or child theme header name == Styles plugin "Style Item" header?
|
56 |
-
* (Case insensitive)
|
57 |
-
*
|
58 |
-
* For example:
|
59 |
-
* Theme Name: Some Parent or Child Theme
|
60 |
-
* Styles Item: Some Parent or Child Theme
|
61 |
-
*
|
62 |
-
* This is an override for **weird edge cases** where the Styles plugin name
|
63 |
-
* or folder name can't match the theme name or folder name.
|
64 |
-
*
|
65 |
-
* Warning: Don't use this. It's likely to change.
|
66 |
-
*/
|
67 |
-
public function theme_name_equals_plugin_item_name( $theme ) {
|
68 |
-
if ( !is_a( $theme, 'WP_Theme') ) { return false; }
|
69 |
-
|
70 |
-
// Strip spacing and special characters in theme names
|
71 |
-
// Allows "Twenty Twelve" to match "TwentyTwelve"
|
72 |
-
$santatized_item_name = $this->sanatize_name( $this->item_name );
|
73 |
-
$santatized_theme_name = $this->sanatize_name( $theme->get('Name') );
|
74 |
-
|
75 |
-
if ( 0 === strcasecmp( $santatized_item_name, $santatized_theme_name ) ) { return true; }
|
76 |
-
return false;
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Do parent or child theme header name == Styles plugin header name?
|
81 |
-
* (Case insensitive)
|
82 |
-
*
|
83 |
-
* For example:
|
84 |
-
* Theme Name: Some Parent or Child Theme
|
85 |
-
* Plugin Name: Styles: Some Parent or Child Theme
|
86 |
-
*
|
87 |
-
* ...would return true.
|
88 |
-
*
|
89 |
-
* "Theme Name" is in the theme header.
|
90 |
-
* "Plugin Name" is in the Styles plugin header.
|
91 |
-
*/
|
92 |
-
public function theme_name_equals_plugin_name( $theme ) {
|
93 |
-
if ( !is_a( $theme, 'WP_Theme') ) { return false; }
|
94 |
-
|
95 |
-
// Strip spacing and special characters in theme names
|
96 |
-
// Allows "Twenty Twelve" to match "TwentyTwelve"
|
97 |
-
$santatized_plugin_name = $this->sanatize_name( $this->plugin_theme_name );
|
98 |
-
$santatized_theme_name = $this->sanatize_name( $theme->get('Name') );
|
99 |
-
|
100 |
-
if ( 0 === strcasecmp( $santatized_plugin_name, $santatized_theme_name ) ) { return true; }
|
101 |
-
return false;
|
102 |
-
}
|
103 |
-
|
104 |
-
/**
|
105 |
-
* Does the parent or child directory name == Styles directory name?
|
106 |
-
* (Case insensitive)
|
107 |
-
*
|
108 |
-
* For example:
|
109 |
-
* Theme directory: some-parent-or-child-theme
|
110 |
-
* Plugin directory: styles-some-parent-or-child-theme
|
111 |
-
*/
|
112 |
-
public function theme_directory_name_equals_plugin_directory_name( $theme ) {
|
113 |
-
if ( !is_a( $theme, 'WP_Theme') ) { return false; }
|
114 |
-
if ( 0 === strcasecmp( $this->get_plugin_directory_name(), $theme->stylesheet ) ) { return true; }
|
115 |
-
return false;
|
116 |
-
}
|
117 |
-
|
118 |
-
public function get_plugin_directory_name() {
|
119 |
-
if ( isset( $this->plugin_directory_name ) ) {
|
120 |
-
return $this->plugin_directory_name;
|
121 |
-
}
|
122 |
-
$plugin_directory_name = basename( dirname( $this->plugin_file ) );
|
123 |
-
|
124 |
-
// Strip 'styles-' from the plugin directory name
|
125 |
-
$remove = 'styles-';
|
126 |
-
if ( $remove == strtolower( substr($plugin_directory_name, 0, strlen( $remove ) ) ) ) {
|
127 |
-
$plugin_directory_name = substr($plugin_directory_name, strlen( $remove ) );
|
128 |
-
}
|
129 |
-
|
130 |
-
$this->plugin_directory_name = $plugin_directory_name;
|
131 |
-
return $this->plugin_directory_name;
|
132 |
-
}
|
133 |
-
|
134 |
-
public function sanatize_name( $name ) {
|
135 |
-
return preg_replace( '/[^a-zA-Z0-9]/', '', $name );
|
136 |
-
}
|
137 |
-
|
138 |
-
public function get_json_path() {
|
139 |
-
if ( $this->is_target_parent_or_child_theme_active() ) {
|
140 |
-
$json_file = dirname( $this->plugin_file ) . '/customize.json';
|
141 |
-
return $json_file;
|
142 |
-
}else {
|
143 |
-
return false;
|
144 |
-
}
|
145 |
-
}
|
146 |
-
|
147 |
-
/**
|
148 |
-
* If styles.css exists in the plugin folder, prepend it to final CSS output
|
149 |
-
*/
|
150 |
-
public function styles_css_output( $css ) {
|
151 |
-
if ( $this->is_target_parent_or_child_theme_active() && file_exists( $this->styles_css ) ) {
|
152 |
-
$css = file_get_contents( $this->styles_css ) . $css;
|
153 |
-
}
|
154 |
-
|
155 |
-
return $css;
|
156 |
-
}
|
157 |
-
|
158 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Styles_Child_Theme extends Styles_Child_Updatable {
|
4 |
+
|
5 |
+
var $template;
|
6 |
+
var $styles_css;
|
7 |
+
|
8 |
+
public function __construct( $args ) {
|
9 |
+
parent::__construct( $args );
|
10 |
+
|
11 |
+
$this->template = str_replace( ' ', '-', strtolower( $this->item_name ) );
|
12 |
+
$this->styles_css = dirname( $this->plugin_file ) . '/style.css';
|
13 |
+
$this->plugin_theme_name = trim( str_replace( 'Styles:', '', $this->name ) );
|
14 |
+
|
15 |
+
$this->theme = wp_get_theme();
|
16 |
+
|
17 |
+
add_filter( 'styles_css_output', array( $this, 'styles_css_output' ) );
|
18 |
+
}
|
19 |
+
|
20 |
+
public function is_target_parent_or_child_theme_active() {
|
21 |
+
return ( $this->is_target_theme_active() || $this->is_target_parent_theme_active() );
|
22 |
+
}
|
23 |
+
|
24 |
+
public function is_target_parent_theme_active() {
|
25 |
+
if ( !is_a( $this->theme->parent() , 'WP_Theme') ) { return false; }
|
26 |
+
|
27 |
+
// Do parent or child theme header name == Styles plugin "Style Item" header?
|
28 |
+
// WARNING: Don't use this option. It's likely to change.
|
29 |
+
if ( $this->theme_name_equals_plugin_item_name( $this->theme->parent() ) ) { return true; }
|
30 |
+
|
31 |
+
// Do parent or child theme header name == Styles plugin header name?
|
32 |
+
if ( $this->theme_name_equals_plugin_name( $this->theme->parent() ) ) { return true; }
|
33 |
+
|
34 |
+
// Does the parent or child directory name == Styles directory name?
|
35 |
+
if ( $this->theme_directory_name_equals_plugin_directory_name( $this->theme->parent() ) ) { return true; }
|
36 |
+
|
37 |
+
return false;
|
38 |
+
}
|
39 |
+
|
40 |
+
public function is_target_theme_active() {
|
41 |
+
// Do parent or child theme header name == Styles plugin "Style Item" header?
|
42 |
+
// WARNING: Don't use this option. It's likely to change.
|
43 |
+
if ( $this->theme_name_equals_plugin_item_name( $this->theme ) ) { return true; }
|
44 |
+
|
45 |
+
// Do parent or child theme header name == Styles plugin header name?
|
46 |
+
if ( $this->theme_name_equals_plugin_name( $this->theme ) ) { return true; }
|
47 |
+
|
48 |
+
// Does the parent or child directory name == Styles directory name?
|
49 |
+
if ( $this->theme_directory_name_equals_plugin_directory_name( $this->theme ) ) { return true; }
|
50 |
+
|
51 |
+
return false;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Do parent or child theme header name == Styles plugin "Style Item" header?
|
56 |
+
* (Case insensitive)
|
57 |
+
*
|
58 |
+
* For example:
|
59 |
+
* Theme Name: Some Parent or Child Theme
|
60 |
+
* Styles Item: Some Parent or Child Theme
|
61 |
+
*
|
62 |
+
* This is an override for **weird edge cases** where the Styles plugin name
|
63 |
+
* or folder name can't match the theme name or folder name.
|
64 |
+
*
|
65 |
+
* Warning: Don't use this. It's likely to change.
|
66 |
+
*/
|
67 |
+
public function theme_name_equals_plugin_item_name( $theme ) {
|
68 |
+
if ( !is_a( $theme, 'WP_Theme') ) { return false; }
|
69 |
+
|
70 |
+
// Strip spacing and special characters in theme names
|
71 |
+
// Allows "Twenty Twelve" to match "TwentyTwelve"
|
72 |
+
$santatized_item_name = $this->sanatize_name( $this->item_name );
|
73 |
+
$santatized_theme_name = $this->sanatize_name( $theme->get('Name') );
|
74 |
+
|
75 |
+
if ( 0 === strcasecmp( $santatized_item_name, $santatized_theme_name ) ) { return true; }
|
76 |
+
return false;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Do parent or child theme header name == Styles plugin header name?
|
81 |
+
* (Case insensitive)
|
82 |
+
*
|
83 |
+
* For example:
|
84 |
+
* Theme Name: Some Parent or Child Theme
|
85 |
+
* Plugin Name: Styles: Some Parent or Child Theme
|
86 |
+
*
|
87 |
+
* ...would return true.
|
88 |
+
*
|
89 |
+
* "Theme Name" is in the theme header.
|
90 |
+
* "Plugin Name" is in the Styles plugin header.
|
91 |
+
*/
|
92 |
+
public function theme_name_equals_plugin_name( $theme ) {
|
93 |
+
if ( !is_a( $theme, 'WP_Theme') ) { return false; }
|
94 |
+
|
95 |
+
// Strip spacing and special characters in theme names
|
96 |
+
// Allows "Twenty Twelve" to match "TwentyTwelve"
|
97 |
+
$santatized_plugin_name = $this->sanatize_name( $this->plugin_theme_name );
|
98 |
+
$santatized_theme_name = $this->sanatize_name( $theme->get('Name') );
|
99 |
+
|
100 |
+
if ( 0 === strcasecmp( $santatized_plugin_name, $santatized_theme_name ) ) { return true; }
|
101 |
+
return false;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Does the parent or child directory name == Styles directory name?
|
106 |
+
* (Case insensitive)
|
107 |
+
*
|
108 |
+
* For example:
|
109 |
+
* Theme directory: some-parent-or-child-theme
|
110 |
+
* Plugin directory: styles-some-parent-or-child-theme
|
111 |
+
*/
|
112 |
+
public function theme_directory_name_equals_plugin_directory_name( $theme ) {
|
113 |
+
if ( !is_a( $theme, 'WP_Theme') ) { return false; }
|
114 |
+
if ( 0 === strcasecmp( $this->get_plugin_directory_name(), $theme->stylesheet ) ) { return true; }
|
115 |
+
return false;
|
116 |
+
}
|
117 |
+
|
118 |
+
public function get_plugin_directory_name() {
|
119 |
+
if ( isset( $this->plugin_directory_name ) ) {
|
120 |
+
return $this->plugin_directory_name;
|
121 |
+
}
|
122 |
+
$plugin_directory_name = basename( dirname( $this->plugin_file ) );
|
123 |
+
|
124 |
+
// Strip 'styles-' from the plugin directory name
|
125 |
+
$remove = 'styles-';
|
126 |
+
if ( $remove == strtolower( substr($plugin_directory_name, 0, strlen( $remove ) ) ) ) {
|
127 |
+
$plugin_directory_name = substr($plugin_directory_name, strlen( $remove ) );
|
128 |
+
}
|
129 |
+
|
130 |
+
$this->plugin_directory_name = $plugin_directory_name;
|
131 |
+
return $this->plugin_directory_name;
|
132 |
+
}
|
133 |
+
|
134 |
+
public function sanatize_name( $name ) {
|
135 |
+
return preg_replace( '/[^a-zA-Z0-9]/', '', $name );
|
136 |
+
}
|
137 |
+
|
138 |
+
public function get_json_path() {
|
139 |
+
if ( $this->is_target_parent_or_child_theme_active() ) {
|
140 |
+
$json_file = dirname( $this->plugin_file ) . '/customize.json';
|
141 |
+
return $json_file;
|
142 |
+
}else {
|
143 |
+
return false;
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* If styles.css exists in the plugin folder, prepend it to final CSS output
|
149 |
+
*/
|
150 |
+
public function styles_css_output( $css ) {
|
151 |
+
if ( $this->is_target_parent_or_child_theme_active() && file_exists( $this->styles_css ) ) {
|
152 |
+
$css = file_get_contents( $this->styles_css ) . $css;
|
153 |
+
}
|
154 |
+
|
155 |
+
return $css;
|
156 |
+
}
|
157 |
+
|
158 |
}
|
classes/styles-child-updatable.php
CHANGED
@@ -1,195 +1,195 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists( 'EDD_SL_Plugin_Updater' ) ) {
|
4 |
-
require dirname( __FILE__ ) . '/edd-sl-plugin-updater.php';
|
5 |
-
}
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Allow child plugins to update through WordPress updater
|
9 |
-
*/
|
10 |
-
class Styles_Child_Updatable {
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var EDD_SL_Plugin_Updater
|
14 |
-
*/
|
15 |
-
private $updater;
|
16 |
-
private $updates;
|
17 |
-
private $license_option_key;
|
18 |
-
|
19 |
-
var $plugin_file;
|
20 |
-
var $plugin_basename;
|
21 |
-
var $api_url;
|
22 |
-
|
23 |
-
var $default_args = array(
|
24 |
-
'api_url' => 'http://stylesplugin.com',
|
25 |
-
);
|
26 |
-
|
27 |
-
public function __construct( $args ) {
|
28 |
-
$args = wp_parse_args( $args, $this->default_args );
|
29 |
-
|
30 |
-
$this->updates = !empty( $args['styles updates'] );
|
31 |
-
$this->license_option_key = dirname( $args['slug'] ) . '-' . 'license';
|
32 |
-
$this->plugin_file = WP_PLUGIN_DIR . '/' . $args['slug'];
|
33 |
-
$this->plugin_basename = $args[ 'slug' ];
|
34 |
-
$this->item_name = $this->maybe_guess_item_name( $args );
|
35 |
-
$this->api_url = $args['api_url'];
|
36 |
-
$this->name = $args['Name'];
|
37 |
-
|
38 |
-
$this->init_updater( $args );
|
39 |
-
}
|
40 |
-
|
41 |
-
public function maybe_guess_item_name( $args ) {
|
42 |
-
if ( !empty( $args['styles item'] ) ) {
|
43 |
-
return $args['styles item'];
|
44 |
-
}
|
45 |
-
|
46 |
-
return trim( str_replace( 'Styles:', '', $args['Title'] ) );
|
47 |
-
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Initialize EDD Updater and licensing if updates are enabled
|
51 |
-
*/
|
52 |
-
public function init_updater( $args ) {
|
53 |
-
if ( !$this->updates ) { return; }
|
54 |
-
|
55 |
-
// License activation hooks
|
56 |
-
add_action( 'plugin_action_links_' . $this->plugin_basename, array( $this, 'plugin_action_links' ), 10, 4 );
|
57 |
-
add_action( 'admin_init', array( $this, 'register_setting') );
|
58 |
-
|
59 |
-
add_action( 'admin_init', array( $this, 'activate_license') );
|
60 |
-
add_action( 'admin_init', array( $this, 'deactivate_license') );
|
61 |
-
|
62 |
-
add_filter( 'styles_license_form_plugins', array( $this, 'styles_license_form_plugins' ) );
|
63 |
-
|
64 |
-
// EDD Plugin Updater
|
65 |
-
$edd_api_data = array(
|
66 |
-
'author' => $args['AuthorName'],
|
67 |
-
'version' => $args['Version'],
|
68 |
-
'license' => get_option( $this->license_option_key ),
|
69 |
-
'item_name' => $this->item_name, // match EDD item post_title
|
70 |
-
);
|
71 |
-
|
72 |
-
$this->updater = new EDD_SL_Plugin_Updater( $args['api_url'], $this->plugin_file, $edd_api_data );
|
73 |
-
|
74 |
-
}
|
75 |
-
|
76 |
-
public function styles_license_form_plugins( $plugins ) {
|
77 |
-
$plugins[] = array(
|
78 |
-
'name' => $this->name,
|
79 |
-
'license_option_key' => $this->license_option_key,
|
80 |
-
);
|
81 |
-
|
82 |
-
return $plugins;
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Add a license link to the plugin actions
|
87 |
-
* Skips free plugins
|
88 |
-
*
|
89 |
-
* @param $value
|
90 |
-
* @return array
|
91 |
-
*/
|
92 |
-
function plugin_action_links( $actions, $plugin_file, $plugin_data, $context ) {
|
93 |
-
if ( !current_user_can( 'manage_options' ) ) { return $actions; }
|
94 |
-
|
95 |
-
$admin_url = admin_url( '
|
96 |
-
|
97 |
-
$actions[ sizeof( $actions ) ] = '<a href="' . $admin_url . '" title="' . esc_html__( 'Styles Licenses', 'styles' ) . '">' . esc_html__( 'Licenses', 'styles' ) . '</a>';
|
98 |
-
|
99 |
-
return $actions;
|
100 |
-
}
|
101 |
-
|
102 |
-
/**
|
103 |
-
* Creates settings in options table
|
104 |
-
*/
|
105 |
-
function register_setting() {
|
106 |
-
register_setting( 'styles_licenses', $this->license_option_key, array( $this, 'sanitize_license' ) );
|
107 |
-
}
|
108 |
-
|
109 |
-
function sanitize_license( $new ) {
|
110 |
-
|
111 |
-
$old = get_option( $this->license_option_key );
|
112 |
-
|
113 |
-
if( $old && $old != $new ) {
|
114 |
-
// new license has been entered, so must reactivate
|
115 |
-
delete_option( $option_key . '_status' );
|
116 |
-
}
|
117 |
-
|
118 |
-
return $new;
|
119 |
-
}
|
120 |
-
|
121 |
-
function activate_license() {
|
122 |
-
|
123 |
-
// listen for our activate button to be clicked
|
124 |
-
if( isset( $_POST['edd_license_activate'] ) ) {
|
125 |
-
|
126 |
-
// run a quick security check
|
127 |
-
if( ! check_admin_referer( 'edd_sample_nonce', 'edd_sample_nonce' ) )
|
128 |
-
return; // get out if we didn't click the Activate button
|
129 |
-
|
130 |
-
// retrieve the license from the database
|
131 |
-
$license = trim( get_option( $this->license_option_key ) );
|
132 |
-
|
133 |
-
// data to send in our API request
|
134 |
-
$api_params = array(
|
135 |
-
'edd_action'=> 'activate_license',
|
136 |
-
'license' => $license,
|
137 |
-
'item_name' => urlencode( $this->item_name ) // the name of our product in EDD
|
138 |
-
);
|
139 |
-
|
140 |
-
// Call the custom API.
|
141 |
-
$response = wp_remote_get( add_query_arg( $api_params, $this->api_url ), array( 'timeout' => 15, 'sslverify' => false ) );
|
142 |
-
|
143 |
-
// make sure the response came back okay
|
144 |
-
if ( is_wp_error( $response ) )
|
145 |
-
return false;
|
146 |
-
|
147 |
-
// decode the license data
|
148 |
-
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
149 |
-
|
150 |
-
// $license_data->license will be either "active" or "inactive"
|
151 |
-
|
152 |
-
update_option( $this->license_option_key . '_status', $license_data->license );
|
153 |
-
|
154 |
-
}
|
155 |
-
}
|
156 |
-
|
157 |
-
function deactivate_license() {
|
158 |
-
|
159 |
-
// listen for our activate button to be clicked
|
160 |
-
if( isset( $_POST['edd_license_deactivate'] ) ) {
|
161 |
-
|
162 |
-
// run a quick security check
|
163 |
-
if( ! check_admin_referer( 'edd_sample_nonce', 'edd_sample_nonce' ) )
|
164 |
-
return; // get out if we didn't click the Activate button
|
165 |
-
|
166 |
-
// retrieve the license from the database
|
167 |
-
$license = trim( get_option( $this->license_option_key ) );
|
168 |
-
|
169 |
-
// data to send in our API request
|
170 |
-
$api_params = array(
|
171 |
-
'edd_action'=> 'deactivate_license',
|
172 |
-
'license' => $license,
|
173 |
-
'item_name' => urlencode( $this->item_name ) // the name of our product in EDD
|
174 |
-
);
|
175 |
-
|
176 |
-
// Call the custom API.
|
177 |
-
$response = wp_remote_get( add_query_arg( $api_params, $this->api_url ), array( 'timeout' => 15, 'sslverify' => false ) );
|
178 |
-
|
179 |
-
// make sure the response came back okay
|
180 |
-
if ( is_wp_error( $response ) ) {
|
181 |
-
return false;
|
182 |
-
}
|
183 |
-
|
184 |
-
// decode the license data
|
185 |
-
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
186 |
-
|
187 |
-
// $license_data->license will be either "deactivated" or "failed"
|
188 |
-
if( $license_data->license == 'deactivated' ) {
|
189 |
-
delete_option( $this->license_option_key . '_status' );
|
190 |
-
}
|
191 |
-
|
192 |
-
}
|
193 |
-
}
|
194 |
-
|
195 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( !class_exists( 'EDD_SL_Plugin_Updater' ) ) {
|
4 |
+
require dirname( __FILE__ ) . '/edd-sl-plugin-updater.php';
|
5 |
+
}
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Allow child plugins to update through WordPress updater
|
9 |
+
*/
|
10 |
+
class Styles_Child_Updatable {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var EDD_SL_Plugin_Updater
|
14 |
+
*/
|
15 |
+
private $updater;
|
16 |
+
private $updates;
|
17 |
+
private $license_option_key;
|
18 |
+
|
19 |
+
var $plugin_file;
|
20 |
+
var $plugin_basename;
|
21 |
+
var $api_url;
|
22 |
+
|
23 |
+
var $default_args = array(
|
24 |
+
'api_url' => 'http://stylesplugin.com',
|
25 |
+
);
|
26 |
+
|
27 |
+
public function __construct( $args ) {
|
28 |
+
$args = wp_parse_args( $args, $this->default_args );
|
29 |
+
|
30 |
+
$this->updates = !empty( $args['styles updates'] );
|
31 |
+
$this->license_option_key = dirname( $args['slug'] ) . '-' . 'license';
|
32 |
+
$this->plugin_file = WP_PLUGIN_DIR . '/' . $args['slug'];
|
33 |
+
$this->plugin_basename = $args[ 'slug' ];
|
34 |
+
$this->item_name = $this->maybe_guess_item_name( $args );
|
35 |
+
$this->api_url = $args['api_url'];
|
36 |
+
$this->name = $args['Name'];
|
37 |
+
|
38 |
+
$this->init_updater( $args );
|
39 |
+
}
|
40 |
+
|
41 |
+
public function maybe_guess_item_name( $args ) {
|
42 |
+
if ( !empty( $args['styles item'] ) ) {
|
43 |
+
return $args['styles item'];
|
44 |
+
}
|
45 |
+
|
46 |
+
return trim( str_replace( 'Styles:', '', $args['Title'] ) );
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Initialize EDD Updater and licensing if updates are enabled
|
51 |
+
*/
|
52 |
+
public function init_updater( $args ) {
|
53 |
+
if ( !$this->updates ) { return; }
|
54 |
+
|
55 |
+
// License activation hooks
|
56 |
+
add_action( 'plugin_action_links_' . $this->plugin_basename, array( $this, 'plugin_action_links' ), 10, 4 );
|
57 |
+
add_action( 'admin_init', array( $this, 'register_setting') );
|
58 |
+
|
59 |
+
add_action( 'admin_init', array( $this, 'activate_license') );
|
60 |
+
add_action( 'admin_init', array( $this, 'deactivate_license') );
|
61 |
+
|
62 |
+
add_filter( 'styles_license_form_plugins', array( $this, 'styles_license_form_plugins' ) );
|
63 |
+
|
64 |
+
// EDD Plugin Updater
|
65 |
+
$edd_api_data = array(
|
66 |
+
'author' => $args['AuthorName'],
|
67 |
+
'version' => $args['Version'],
|
68 |
+
'license' => get_option( $this->license_option_key ),
|
69 |
+
'item_name' => $this->item_name, // match EDD item post_title
|
70 |
+
);
|
71 |
+
|
72 |
+
$this->updater = new EDD_SL_Plugin_Updater( $args['api_url'], $this->plugin_file, $edd_api_data );
|
73 |
+
|
74 |
+
}
|
75 |
+
|
76 |
+
public function styles_license_form_plugins( $plugins ) {
|
77 |
+
$plugins[] = array(
|
78 |
+
'name' => $this->name,
|
79 |
+
'license_option_key' => $this->license_option_key,
|
80 |
+
);
|
81 |
+
|
82 |
+
return $plugins;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Add a license link to the plugin actions
|
87 |
+
* Skips free plugins
|
88 |
+
*
|
89 |
+
* @param $value
|
90 |
+
* @return array
|
91 |
+
*/
|
92 |
+
function plugin_action_links( $actions, $plugin_file, $plugin_data, $context ) {
|
93 |
+
if ( !current_user_can( 'manage_options' ) ) { return $actions; }
|
94 |
+
|
95 |
+
$admin_url = admin_url( 'options-general.php?page=styles' );
|
96 |
+
|
97 |
+
$actions[ sizeof( $actions ) ] = '<a href="' . $admin_url . '" title="' . esc_html__( 'Styles Licenses', 'styles' ) . '">' . esc_html__( 'Licenses', 'styles' ) . '</a>';
|
98 |
+
|
99 |
+
return $actions;
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Creates settings in options table
|
104 |
+
*/
|
105 |
+
function register_setting() {
|
106 |
+
register_setting( 'styles_licenses', $this->license_option_key, array( $this, 'sanitize_license' ) );
|
107 |
+
}
|
108 |
+
|
109 |
+
function sanitize_license( $new ) {
|
110 |
+
|
111 |
+
$old = get_option( $this->license_option_key );
|
112 |
+
|
113 |
+
if( $old && $old != $new ) {
|
114 |
+
// new license has been entered, so must reactivate
|
115 |
+
delete_option( $option_key . '_status' );
|
116 |
+
}
|
117 |
+
|
118 |
+
return $new;
|
119 |
+
}
|
120 |
+
|
121 |
+
function activate_license() {
|
122 |
+
|
123 |
+
// listen for our activate button to be clicked
|
124 |
+
if( isset( $_POST['edd_license_activate'] ) ) {
|
125 |
+
|
126 |
+
// run a quick security check
|
127 |
+
if( ! check_admin_referer( 'edd_sample_nonce', 'edd_sample_nonce' ) )
|
128 |
+
return; // get out if we didn't click the Activate button
|
129 |
+
|
130 |
+
// retrieve the license from the database
|
131 |
+
$license = trim( get_option( $this->license_option_key ) );
|
132 |
+
|
133 |
+
// data to send in our API request
|
134 |
+
$api_params = array(
|
135 |
+
'edd_action'=> 'activate_license',
|
136 |
+
'license' => $license,
|
137 |
+
'item_name' => urlencode( $this->item_name ) // the name of our product in EDD
|
138 |
+
);
|
139 |
+
|
140 |
+
// Call the custom API.
|
141 |
+
$response = wp_remote_get( add_query_arg( $api_params, $this->api_url ), array( 'timeout' => 15, 'sslverify' => false ) );
|
142 |
+
|
143 |
+
// make sure the response came back okay
|
144 |
+
if ( is_wp_error( $response ) )
|
145 |
+
return false;
|
146 |
+
|
147 |
+
// decode the license data
|
148 |
+
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
149 |
+
|
150 |
+
// $license_data->license will be either "active" or "inactive"
|
151 |
+
|
152 |
+
update_option( $this->license_option_key . '_status', $license_data->license );
|
153 |
+
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
+
function deactivate_license() {
|
158 |
+
|
159 |
+
// listen for our activate button to be clicked
|
160 |
+
if( isset( $_POST['edd_license_deactivate'] ) ) {
|
161 |
+
|
162 |
+
// run a quick security check
|
163 |
+
if( ! check_admin_referer( 'edd_sample_nonce', 'edd_sample_nonce' ) )
|
164 |
+
return; // get out if we didn't click the Activate button
|
165 |
+
|
166 |
+
// retrieve the license from the database
|
167 |
+
$license = trim( get_option( $this->license_option_key ) );
|
168 |
+
|
169 |
+
// data to send in our API request
|
170 |
+
$api_params = array(
|
171 |
+
'edd_action'=> 'deactivate_license',
|
172 |
+
'license' => $license,
|
173 |
+
'item_name' => urlencode( $this->item_name ) // the name of our product in EDD
|
174 |
+
);
|
175 |
+
|
176 |
+
// Call the custom API.
|
177 |
+
$response = wp_remote_get( add_query_arg( $api_params, $this->api_url ), array( 'timeout' => 15, 'sslverify' => false ) );
|
178 |
+
|
179 |
+
// make sure the response came back okay
|
180 |
+
if ( is_wp_error( $response ) ) {
|
181 |
+
return false;
|
182 |
+
}
|
183 |
+
|
184 |
+
// decode the license data
|
185 |
+
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
186 |
+
|
187 |
+
// $license_data->license will be either "deactivated" or "failed"
|
188 |
+
if( $license_data->license == 'deactivated' ) {
|
189 |
+
delete_option( $this->license_option_key . '_status' );
|
190 |
+
}
|
191 |
+
|
192 |
+
}
|
193 |
+
}
|
194 |
+
|
195 |
}
|
classes/styles-child.php
CHANGED
@@ -1,112 +1,112 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Detect and initialize plugins meant to extend Styles in common ways
|
5 |
-
* For example, add customize.json for a theme
|
6 |
-
*/
|
7 |
-
class Styles_Child {
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Styles_Plugin
|
11 |
-
*/
|
12 |
-
var $plugin;
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Array of plugin objects
|
16 |
-
* @var array
|
17 |
-
*/
|
18 |
-
var $plugins = array();
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Array of inactive plugin objects
|
22 |
-
* @var array
|
23 |
-
*/
|
24 |
-
var $inactive_plugins = array();
|
25 |
-
|
26 |
-
public function __construct( $plugin ) {
|
27 |
-
$this->plugin = $plugin;
|
28 |
-
|
29 |
-
add_action( 'plugins_loaded', array( $this, 'plugins_loaded'), 20 );
|
30 |
-
add_filter( 'extra_plugin_headers', array( $this, 'extra_plugin_headers') );
|
31 |
-
add_action( 'update_option_active_plugins', array( $this, 'update_option_active_plugins' ) );
|
32 |
-
|
33 |
-
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
34 |
-
$this->update_option_active_plugins();
|
35 |
-
}
|
36 |
-
}
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Additional headers
|
40 |
-
*
|
41 |
-
* @return array plugin header search terms
|
42 |
-
*/
|
43 |
-
public function extra_plugin_headers( $headers ) {
|
44 |
-
$headers['Styles Class'] = 'styles class';
|
45 |
-
$headers['Styles Item'] = 'styles item';
|
46 |
-
$headers['Styles Updates'] = 'styles updates';
|
47 |
-
|
48 |
-
return $headers;
|
49 |
-
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* Build $this->plugins, a list of Styles child plugins based on plugin headers
|
53 |
-
*
|
54 |
-
* @return void
|
55 |
-
*/
|
56 |
-
public function plugins_loaded( $plugins ) {
|
57 |
-
if ( !function_exists( 'is_plugin_active') ) {
|
58 |
-
include_once ABSPATH . 'wp-admin/includes/plugin.php';
|
59 |
-
}
|
60 |
-
|
61 |
-
foreach ( $this->get_plugins_meta() as $meta ) {
|
62 |
-
|
63 |
-
$class = $meta['styles class'];
|
64 |
-
|
65 |
-
if ( class_exists( $class ) ) {
|
66 |
-
// For example,
|
67 |
-
// new Styles_Child_Theme( $meta )
|
68 |
-
if ( is_plugin_active( $meta['slug'] ) ) {
|
69 |
-
$this->plugins[] = new $class( $meta );
|
70 |
-
}else {
|
71 |
-
$this->inactive_plugins[] = new $class( $meta );
|
72 |
-
}
|
73 |
-
}
|
74 |
-
}
|
75 |
-
}
|
76 |
-
|
77 |
-
public function get_plugins_meta() {
|
78 |
-
$child_plugins_meta = get_site_transient( 'styles_child_plugins' );
|
79 |
-
|
80 |
-
if ( false !== $child_plugins_meta ) {
|
81 |
-
return $child_plugins_meta;
|
82 |
-
}
|
83 |
-
|
84 |
-
if ( !function_exists( 'get_plugins') ) {
|
85 |
-
require_once ABSPATH . '/wp-admin/includes/plugin.php';
|
86 |
-
}
|
87 |
-
|
88 |
-
$child_plugins_meta = array();
|
89 |
-
|
90 |
-
foreach ( get_plugins() as $slug => $meta ) {
|
91 |
-
// Only include Styles child plugins with styles_class set in header
|
92 |
-
if ( empty( $meta['styles class'] ) ) { continue; }
|
93 |
-
|
94 |
-
$meta['slug'] = $slug;
|
95 |
-
|
96 |
-
$child_plugins_meta[] = $meta;
|
97 |
-
}
|
98 |
-
|
99 |
-
// Refresh plugin list and metadata every 6 hours (or on activate/deactivate)
|
100 |
-
set_site_transient( 'styles_child_plugins', $child_plugins_meta, 60*60*6 );
|
101 |
-
|
102 |
-
return $child_plugins_meta;
|
103 |
-
}
|
104 |
-
|
105 |
-
/**
|
106 |
-
* Clear child plugins transient cache any time plugins are activated or deactivated.
|
107 |
-
*/
|
108 |
-
public function update_option_active_plugins() {
|
109 |
-
delete_site_transient( 'styles_child_plugins' );
|
110 |
-
}
|
111 |
-
|
112 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Detect and initialize plugins meant to extend Styles in common ways
|
5 |
+
* For example, add customize.json for a theme
|
6 |
+
*/
|
7 |
+
class Styles_Child {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Styles_Plugin
|
11 |
+
*/
|
12 |
+
var $plugin;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Array of plugin objects
|
16 |
+
* @var array
|
17 |
+
*/
|
18 |
+
var $plugins = array();
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Array of inactive plugin objects
|
22 |
+
* @var array
|
23 |
+
*/
|
24 |
+
var $inactive_plugins = array();
|
25 |
+
|
26 |
+
public function __construct( $plugin ) {
|
27 |
+
$this->plugin = $plugin;
|
28 |
+
|
29 |
+
add_action( 'plugins_loaded', array( $this, 'plugins_loaded'), 20 );
|
30 |
+
add_filter( 'extra_plugin_headers', array( $this, 'extra_plugin_headers') );
|
31 |
+
add_action( 'update_option_active_plugins', array( $this, 'update_option_active_plugins' ) );
|
32 |
+
|
33 |
+
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
|
34 |
+
$this->update_option_active_plugins();
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Additional headers
|
40 |
+
*
|
41 |
+
* @return array plugin header search terms
|
42 |
+
*/
|
43 |
+
public function extra_plugin_headers( $headers ) {
|
44 |
+
$headers['Styles Class'] = 'styles class';
|
45 |
+
$headers['Styles Item'] = 'styles item';
|
46 |
+
$headers['Styles Updates'] = 'styles updates';
|
47 |
+
|
48 |
+
return $headers;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Build $this->plugins, a list of Styles child plugins based on plugin headers
|
53 |
+
*
|
54 |
+
* @return void
|
55 |
+
*/
|
56 |
+
public function plugins_loaded( $plugins ) {
|
57 |
+
if ( !function_exists( 'is_plugin_active') ) {
|
58 |
+
include_once ABSPATH . 'wp-admin/includes/plugin.php';
|
59 |
+
}
|
60 |
+
|
61 |
+
foreach ( $this->get_plugins_meta() as $meta ) {
|
62 |
+
|
63 |
+
$class = $meta['styles class'];
|
64 |
+
|
65 |
+
if ( class_exists( $class ) ) {
|
66 |
+
// For example,
|
67 |
+
// new Styles_Child_Theme( $meta )
|
68 |
+
if ( is_plugin_active( $meta['slug'] ) ) {
|
69 |
+
$this->plugins[] = new $class( $meta );
|
70 |
+
}else {
|
71 |
+
$this->inactive_plugins[] = new $class( $meta );
|
72 |
+
}
|
73 |
+
}
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
public function get_plugins_meta() {
|
78 |
+
$child_plugins_meta = get_site_transient( 'styles_child_plugins' );
|
79 |
+
|
80 |
+
if ( false !== $child_plugins_meta ) {
|
81 |
+
return $child_plugins_meta;
|
82 |
+
}
|
83 |
+
|
84 |
+
if ( !function_exists( 'get_plugins') ) {
|
85 |
+
require_once ABSPATH . '/wp-admin/includes/plugin.php';
|
86 |
+
}
|
87 |
+
|
88 |
+
$child_plugins_meta = array();
|
89 |
+
|
90 |
+
foreach ( get_plugins() as $slug => $meta ) {
|
91 |
+
// Only include Styles child plugins with styles_class set in header
|
92 |
+
if ( empty( $meta['styles class'] ) ) { continue; }
|
93 |
+
|
94 |
+
$meta['slug'] = $slug;
|
95 |
+
|
96 |
+
$child_plugins_meta[] = $meta;
|
97 |
+
}
|
98 |
+
|
99 |
+
// Refresh plugin list and metadata every 6 hours (or on activate/deactivate)
|
100 |
+
set_site_transient( 'styles_child_plugins', $child_plugins_meta, 60*60*6 );
|
101 |
+
|
102 |
+
return $child_plugins_meta;
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Clear child plugins transient cache any time plugins are activated or deactivated.
|
107 |
+
*/
|
108 |
+
public function update_option_active_plugins() {
|
109 |
+
delete_site_transient( 'styles_child_plugins' );
|
110 |
+
}
|
111 |
+
|
112 |
}
|
classes/styles-control-background-color.php
CHANGED
@@ -1,58 +1,58 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class Styles_Control_Background_Color extends Styles_Control {
|
4 |
-
var $suffix = 'background color';
|
5 |
-
var $template = '$selector { background-color: $value; }';
|
6 |
-
|
7 |
-
public function __construct( $group, $element ) {
|
8 |
-
parent::__construct( $group, $element );
|
9 |
-
}
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Register item with $wp_customize
|
13 |
-
*/
|
14 |
-
public function add_item() {
|
15 |
-
global $wp_customize;
|
16 |
-
|
17 |
-
$wp_customize->add_setting( $this->setting, $this->get_setting_args() );
|
18 |
-
|
19 |
-
$control = new WP_Customize_Color_Control(
|
20 |
-
$wp_customize,
|
21 |
-
Styles_Helpers::get_control_id( $this->id ),
|
22 |
-
$this->get_control_args()
|
23 |
-
);
|
24 |
-
$wp_customize->add_control( $control );
|
25 |
-
}
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Return CSS based on setting value
|
29 |
-
*/
|
30 |
-
public function get_css(){
|
31 |
-
$value = $this->get_element_setting_value();
|
32 |
-
|
33 |
-
$css = '';
|
34 |
-
if ( $value ) {
|
35 |
-
$args = array(
|
36 |
-
'template' => $this->template,
|
37 |
-
'value' => $value,
|
38 |
-
);
|
39 |
-
$css = $this->apply_template( $args );
|
40 |
-
}
|
41 |
-
|
42 |
-
// Filter effects final CSS output, but not postMessage updates
|
43 |
-
return apply_filters( 'styles_css_background_color', $css );
|
44 |
-
}
|
45 |
-
|
46 |
-
public function post_message( $js ) {
|
47 |
-
$selector = str_replace( "'", "\'", $this->selector );
|
48 |
-
|
49 |
-
$js .= str_replace(
|
50 |
-
array( '@setting@', '@selector@' ),
|
51 |
-
array( $this->setting, $selector ),
|
52 |
-
file_get_contents( STYLES_DIR . '/js/post-message-part-background-color.js' )
|
53 |
-
);
|
54 |
-
|
55 |
-
return $js . PHP_EOL;
|
56 |
-
}
|
57 |
-
|
58 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Styles_Control_Background_Color extends Styles_Control {
|
4 |
+
var $suffix = 'background color';
|
5 |
+
var $template = '$selector { background-color: $value; }';
|
6 |
+
|
7 |
+
public function __construct( $group, $element ) {
|
8 |
+
parent::__construct( $group, $element );
|
9 |
+
}
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Register item with $wp_customize
|
13 |
+
*/
|
14 |
+
public function add_item() {
|
15 |
+
global $wp_customize;
|
16 |
+
|
17 |
+
$wp_customize->add_setting( $this->setting, $this->get_setting_args() );
|
18 |
+
|
19 |
+
$control = new WP_Customize_Color_Control(
|
20 |
+
$wp_customize,
|
21 |
+
Styles_Helpers::get_control_id( $this->id ),
|
22 |
+
$this->get_control_args()
|
23 |
+
);
|
24 |
+
$wp_customize->add_control( $control );
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Return CSS based on setting value
|
29 |
+
*/
|
30 |
+
public function get_css(){
|
31 |
+
$value = $this->get_element_setting_value();
|
32 |
+
|
33 |
+
$css = '';
|
34 |
+
if ( $value ) {
|
35 |
+
$args = array(
|
36 |
+
'template' => $this->template,
|
37 |
+
'value' => $value,
|
38 |
+
);
|
39 |
+
$css = $this->apply_template( $args );
|
40 |
+
}
|
41 |
+
|
42 |
+
// Filter effects final CSS output, but not postMessage updates
|
43 |
+
return apply_filters( 'styles_css_background_color', $css );
|
44 |
+
}
|
45 |
+
|
46 |
+
public function post_message( $js ) {
|
47 |
+
$selector = str_replace( "'", "\'", $this->selector );
|
48 |
+
|
49 |
+
$js .= str_replace(
|
50 |
+
array( '@setting@', '@selector@' ),
|
51 |
+
array( $this->setting, $selector ),
|
52 |
+
file_get_contents( STYLES_DIR . '/js/post-message-part-background-color.js' )
|
53 |
+
);
|
54 |
+
|
55 |
+
return $js . PHP_EOL;
|
56 |
+
}
|
57 |
+
|
58 |
}
|
classes/styles-control-border-bottom-color.php
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists( 'Styles_Control_Border_Color' ) ) {
|
3 |
-
require_once dirname( __FILE__ ) . '/styles-control-border-color.php';
|
4 |
-
}
|
5 |
-
|
6 |
-
class Styles_Control_Border_Bottom_Color extends Styles_Control_Border_Color {
|
7 |
-
var $property = 'border-bottom-color';
|
8 |
-
var $suffix = 'bottom border color';
|
9 |
-
|
10 |
-
public function __construct( $group, $element ) {
|
11 |
-
parent::__construct( $group, $element );
|
12 |
-
}
|
13 |
}
|
1 |
+
<?php
|
2 |
+
if ( !class_exists( 'Styles_Control_Border_Color' ) ) {
|
3 |
+
require_once dirname( __FILE__ ) . '/styles-control-border-color.php';
|
4 |
+
}
|
5 |
+
|
6 |
+
class Styles_Control_Border_Bottom_Color extends Styles_Control_Border_Color {
|
7 |
+
var $property = 'border-bottom-color';
|
8 |
+
var $suffix = 'bottom border color';
|
9 |
+
|
10 |
+
public function __construct( $group, $element ) {
|
11 |
+
parent::__construct( $group, $element );
|
12 |
+
}
|
13 |
}
|
classes/styles-control-border-color.php
CHANGED
@@ -1,29 +1,29 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists( 'Styles_Control_Color' ) ) {
|
4 |
-
require_once dirname( __FILE__ ) . '/styles-control-color.php';
|
5 |
-
}
|
6 |
-
|
7 |
-
class Styles_Control_Border_Color extends Styles_Control_Color {
|
8 |
-
var $suffix = 'border color';
|
9 |
-
var $property = 'border-color';
|
10 |
-
var $template = '$selector { $property: $value; }';
|
11 |
-
|
12 |
-
public function __construct( $group, $element ) {
|
13 |
-
parent::__construct( $group, $element );
|
14 |
-
|
15 |
-
// Replace $property in $template for child classes
|
16 |
-
$this->template = str_replace( '$property', $this->property, $this->template );
|
17 |
-
}
|
18 |
-
|
19 |
-
public function post_message( $js ) {
|
20 |
-
$js .= str_replace(
|
21 |
-
array( '@setting@', '@selector@', '@property@' ),
|
22 |
-
array( $this->setting, $this->jquery_selector(), $this->property ),
|
23 |
-
file_get_contents( STYLES_DIR . '/js/post-message-part-border-color.js' )
|
24 |
-
);
|
25 |
-
|
26 |
-
return $js . PHP_EOL;
|
27 |
-
}
|
28 |
-
|
29 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( !class_exists( 'Styles_Control_Color' ) ) {
|
4 |
+
require_once dirname( __FILE__ ) . '/styles-control-color.php';
|
5 |
+
}
|
6 |
+
|
7 |
+
class Styles_Control_Border_Color extends Styles_Control_Color {
|
8 |
+
var $suffix = 'border color';
|
9 |
+
var $property = 'border-color';
|
10 |
+
var $template = '$selector { $property: $value; }';
|
11 |
+
|
12 |
+
public function __construct( $group, $element ) {
|
13 |
+
parent::__construct( $group, $element );
|
14 |
+
|
15 |
+
// Replace $property in $template for child classes
|
16 |
+
$this->template = str_replace( '$property', $this->property, $this->template );
|
17 |
+
}
|
18 |
+
|
19 |
+
public function post_message( $js ) {
|
20 |
+
$js .= str_replace(
|
21 |
+
array( '@setting@', '@selector@', '@property@' ),
|
22 |
+
array( $this->setting, $this->jquery_selector(), $this->property ),
|
23 |
+
file_get_contents( STYLES_DIR . '/js/post-message-part-border-color.js' )
|
24 |
+
);
|
25 |
+
|
26 |
+
return $js . PHP_EOL;
|
27 |
+
}
|
28 |
+
|
29 |
}
|
classes/styles-control-border-left-color.php
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists( 'Styles_Control_Border_Color' ) ) {
|
3 |
-
require_once dirname( __FILE__ ) . '/styles-control-border-color.php';
|
4 |
-
}
|
5 |
-
|
6 |
-
class Styles_Control_Border_Left_Color extends Styles_Control_Border_Color {
|
7 |
-
var $property = 'border-left-color';
|
8 |
-
var $suffix = 'left border color';
|
9 |
-
|
10 |
-
public function __construct( $group, $element ) {
|
11 |
-
parent::__construct( $group, $element );
|
12 |
-
}
|
13 |
}
|
1 |
+
<?php
|
2 |
+
if ( !class_exists( 'Styles_Control_Border_Color' ) ) {
|
3 |
+
require_once dirname( __FILE__ ) . '/styles-control-border-color.php';
|
4 |
+
}
|
5 |
+
|
6 |
+
class Styles_Control_Border_Left_Color extends Styles_Control_Border_Color {
|
7 |
+
var $property = 'border-left-color';
|
8 |
+
var $suffix = 'left border color';
|
9 |
+
|
10 |
+
public function __construct( $group, $element ) {
|
11 |
+
parent::__construct( $group, $element );
|
12 |
+
}
|
13 |
}
|
classes/styles-control-border-right-color.php
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists( 'Styles_Control_Border_Color' ) ) {
|
3 |
-
require_once dirname( __FILE__ ) . '/styles-control-border-color.php';
|
4 |
-
}
|
5 |
-
|
6 |
-
class Styles_Control_Border_Right_Color extends Styles_Control_Border_Color {
|
7 |
-
var $property = 'border-right-color';
|
8 |
-
var $suffix = 'right border color';
|
9 |
-
|
10 |
-
public function __construct( $group, $element ) {
|
11 |
-
parent::__construct( $group, $element );
|
12 |
-
}
|
13 |
}
|
1 |
+
<?php
|
2 |
+
if ( !class_exists( 'Styles_Control_Border_Color' ) ) {
|
3 |
+
require_once dirname( __FILE__ ) . '/styles-control-border-color.php';
|
4 |
+
}
|
5 |
+
|
6 |
+
class Styles_Control_Border_Right_Color extends Styles_Control_Border_Color {
|
7 |
+
var $property = 'border-right-color';
|
8 |
+
var $suffix = 'right border color';
|
9 |
+
|
10 |
+
public function __construct( $group, $element ) {
|
11 |
+
parent::__construct( $group, $element );
|
12 |
+
}
|
13 |
}
|
classes/styles-control-border-top-color.php
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists( 'Styles_Control_Border_Color' ) ) {
|
3 |
-
require_once dirname( __FILE__ ) . '/styles-control-border-color.php';
|
4 |
-
}
|
5 |
-
|
6 |
-
class Styles_Control_Border_Top_Color extends Styles_Control_Border_Color {
|
7 |
-
var $property = 'border-top-color';
|
8 |
-
var $suffix = 'top border color';
|
9 |
-
|
10 |
-
public function __construct( $group, $element ) {
|
11 |
-
parent::__construct( $group, $element );
|
12 |
-
}
|
13 |
}
|
1 |
+
<?php
|
2 |
+
if ( !class_exists( 'Styles_Control_Border_Color' ) ) {
|
3 |
+
require_once dirname( __FILE__ ) . '/styles-control-border-color.php';
|
4 |
+
}
|
5 |
+
|
6 |
+
class Styles_Control_Border_Top_Color extends Styles_Control_Border_Color {
|
7 |
+
var $property = 'border-top-color';
|
8 |
+
var $suffix = 'top border color';
|
9 |
+
|
10 |
+
public function __construct( $group, $element ) {
|
11 |
+
parent::__construct( $group, $element );
|
12 |
+
}
|
13 |
}
|
classes/styles-control-color.php
CHANGED
@@ -1,57 +1,57 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class Styles_Control_Color extends Styles_Control {
|
4 |
-
var $suffix = 'text color';
|
5 |
-
var $template = '$selector { color: $value; }';
|
6 |
-
|
7 |
-
public function __construct( $group, $element ) {
|
8 |
-
parent::__construct( $group, $element );
|
9 |
-
}
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Register item with $wp_customize
|
13 |
-
*/
|
14 |
-
public function add_item() {
|
15 |
-
global $wp_customize;
|
16 |
-
|
17 |
-
$wp_customize->add_setting( $this->setting, $this->get_setting_args() );
|
18 |
-
|
19 |
-
$control = new WP_Customize_Color_Control(
|
20 |
-
$wp_customize,
|
21 |
-
Styles_Helpers::get_control_id( $this->id ),
|
22 |
-
$this->get_control_args()
|
23 |
-
);
|
24 |
-
$wp_customize->add_control( $control );
|
25 |
-
}
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Return CSS based on setting value
|
29 |
-
*/
|
30 |
-
public function get_css(){
|
31 |
-
$selector = $this->selector;
|
32 |
-
$value = $this->get_element_setting_value();
|
33 |
-
|
34 |
-
$css = '';
|
35 |
-
if ( $value ) {
|
36 |
-
$args = array(
|
37 |
-
'template' => $this->template,
|
38 |
-
'value' => $value,
|
39 |
-
);
|
40 |
-
$css = $this->apply_template( $args );
|
41 |
-
}
|
42 |
-
|
43 |
-
// Filter effects final CSS output, but not postMessage updates
|
44 |
-
return apply_filters( 'styles_css_color', $css );
|
45 |
-
}
|
46 |
-
|
47 |
-
public function post_message( $js ) {
|
48 |
-
$js .= str_replace(
|
49 |
-
array( '@setting@', '@selector@' ),
|
50 |
-
array( $this->setting, $this->jquery_selector() ),
|
51 |
-
file_get_contents( STYLES_DIR . '/js/post-message-part-color.js' )
|
52 |
-
);
|
53 |
-
|
54 |
-
return $js . PHP_EOL;
|
55 |
-
}
|
56 |
-
|
57 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Styles_Control_Color extends Styles_Control {
|
4 |
+
var $suffix = 'text color';
|
5 |
+
var $template = '$selector { color: $value; }';
|
6 |
+
|
7 |
+
public function __construct( $group, $element ) {
|
8 |
+
parent::__construct( $group, $element );
|
9 |
+
}
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Register item with $wp_customize
|
13 |
+
*/
|
14 |
+
public function add_item() {
|
15 |
+
global $wp_customize;
|
16 |
+
|
17 |
+
$wp_customize->add_setting( $this->setting, $this->get_setting_args() );
|
18 |
+
|
19 |
+
$control = new WP_Customize_Color_Control(
|
20 |
+
$wp_customize,
|
21 |
+
Styles_Helpers::get_control_id( $this->id ),
|
22 |
+
$this->get_control_args()
|
23 |
+
);
|
24 |
+
$wp_customize->add_control( $control );
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Return CSS based on setting value
|
29 |
+
*/
|
30 |
+
public function get_css(){
|
31 |
+
$selector = $this->selector;
|
32 |
+
$value = $this->get_element_setting_value();
|
33 |
+
|
34 |
+
$css = '';
|
35 |
+
if ( $value ) {
|
36 |
+
$args = array(
|
37 |
+
'template' => $this->template,
|
38 |
+
'value' => $value,
|
39 |
+
);
|
40 |
+
$css = $this->apply_template( $args );
|
41 |
+
}
|
42 |
+
|
43 |
+
// Filter effects final CSS output, but not postMessage updates
|
44 |
+
return apply_filters( 'styles_css_color', $css );
|
45 |
+
}
|
46 |
+
|
47 |
+
public function post_message( $js ) {
|
48 |
+
$js .= str_replace(
|
49 |
+
array( '@setting@', '@selector@' ),
|
50 |
+
array( $this->setting, $this->jquery_selector() ),
|
51 |
+
file_get_contents( STYLES_DIR . '/js/post-message-part-color.js' )
|
52 |
+
);
|
53 |
+
|
54 |
+
return $js . PHP_EOL;
|
55 |
+
}
|
56 |
+
|
57 |
}
|
classes/styles-control-text.php
CHANGED
@@ -1,174 +1,174 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
require_once dirname( __FILE__ ) . '/styles-font-menu/plugin.php';
|
4 |
-
|
5 |
-
class Styles_Control_Text extends Styles_Control {
|
6 |
-
var $suffix = 'text';
|
7 |
-
|
8 |
-
// CSS Templates
|
9 |
-
var $template = '$selector { $value }';
|
10 |
-
var $template_font_size = 'font-size: $valuepx;';
|
11 |
-
var $template_font_family = 'font-family: $value;';
|
12 |
-
|
13 |
-
public function __construct( $group, $element ) {
|
14 |
-
parent::__construct( $group, $element );
|
15 |
-
|
16 |
-
if ( !empty( $element['template_font_size'] ) ) {
|
17 |
-
$this->template_font_size = $element['template_font_size'];
|
18 |
-
}
|
19 |
-
|
20 |
-
if ( !empty( $element['template_font_family'] ) ) {
|
21 |
-
$this->template_font_family = $element['template_font_family'];
|
22 |
-
}
|
23 |
-
|
24 |
-
}
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Register item with $wp_customize
|
28 |
-
*/
|
29 |
-
public function add_item() {
|
30 |
-
global $wp_customize;
|
31 |
-
|
32 |
-
$args_size = $this->get_setting_args( 'font_size' );
|
33 |
-
$setting_size = $this->setting . '[font_size]';
|
34 |
-
|
35 |
-
$args_family = $this->get_setting_args( 'font_family' );
|
36 |
-
// unset( $args_family['transport'] );
|
37 |
-
$setting_family = $this->setting . '[font_family]';
|
38 |
-
|
39 |
-
$wp_customize->add_setting( $setting_size, $args_size );
|
40 |
-
$wp_customize->add_setting( $setting_family, $args_family );
|
41 |
-
|
42 |
-
$control_args = $this->get_control_args();
|
43 |
-
$control_args['settings'] = array(
|
44 |
-
'font_size' => $setting_size,
|
45 |
-
'font_family' => $setting_family,
|
46 |
-
);
|
47 |
-
|
48 |
-
$control = new Styles_Customize_Text_Control(
|
49 |
-
$wp_customize,
|
50 |
-
Styles_Helpers::get_control_id( $this->id ),
|
51 |
-
$control_args
|
52 |
-
);
|
53 |
-
$wp_customize->add_control( $control );
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Return CSS based on setting value
|
58 |
-
*
|
59 |
-
* @return string
|
60 |
-
*/
|
61 |
-
public function get_css(){
|
62 |
-
$value = $this->get_element_setting_value();
|
63 |
-
|
64 |
-
$css = $this->get_css_font_size( $value );
|
65 |
-
$css .= $this->get_css_font_family( $value );
|
66 |
-
|
67 |
-
if ( !empty( $css ) ) {
|
68 |
-
$args = array(
|
69 |
-
'template' => $this->template,
|
70 |
-
'value' => $css,
|
71 |
-
);
|
72 |
-
$css = $this->apply_template( $args );
|
73 |
-
}
|
74 |
-
|
75 |
-
// Filter effects final CSS output, but not postMessage updates
|
76 |
-
return apply_filters( 'styles_css_text', $css );
|
77 |
-
}
|
78 |
-
|
79 |
-
public function get_css_font_size( $value ) {
|
80 |
-
if ( is_array( $value ) ) { $value = $value['font_size']; }
|
81 |
-
|
82 |
-
$css = '';
|
83 |
-
if ( $value ) {
|
84 |
-
$args = array(
|
85 |
-
'template' => $this->template_font_size,
|
86 |
-
'value' => $value,
|
87 |
-
);
|
88 |
-
$css = $this->apply_template( $args );
|
89 |
-
}
|
90 |
-
|
91 |
-
// Filter effects final CSS output, but not postMessage updates
|
92 |
-
return apply_filters( 'styles_css_font_size', $css );
|
93 |
-
}
|
94 |
-
|
95 |
-
public function get_css_font_family( $value = false ) {
|
96 |
-
if ( !$value ) { return ''; }
|
97 |
-
if ( is_array( $value ) ) { $value = $value['font_family']; }
|
98 |
-
|
99 |
-
// Todo: Validate this!!!
|
100 |
-
$font = json_decode( $value );
|
101 |
-
if ( !empty( $font->family ) ) {
|
102 |
-
$value = $font->family;
|
103 |
-
}
|
104 |
-
|
105 |
-
if ( isset( $font->import_family ) ) {
|
106 |
-
$styles = Styles_Plugin::get_instance();
|
107 |
-
$styles->css->google_fonts[ $value ] = "@import url(//fonts.googleapis.com/css?family={$font->import_family});\r";
|
108 |
-
}
|
109 |
-
|
110 |
-
$css = '';
|
111 |
-
if ( $value ) {
|
112 |
-
$args = array(
|
113 |
-
'template' => $this->template_font_family,
|
114 |
-
'value' => $value,
|
115 |
-
);
|
116 |
-
$css = $this->apply_template( $args );
|
117 |
-
}
|
118 |
-
|
119 |
-
// Filter effects final CSS output, but not postMessage updates
|
120 |
-
return apply_filters( 'styles_css_font_family', $css );
|
121 |
-
}
|
122 |
-
|
123 |
-
public function post_message( $js ) {
|
124 |
-
$setting_font_size = $this->setting . '[font_size]';
|
125 |
-
$setting_font_family = $this->setting . '[font_family]';
|
126 |
-
$selector = str_replace( "'", "\'", $this->selector );
|
127 |
-
|
128 |
-
$js .= str_replace(
|
129 |
-
array( '@setting_font_size@', '@setting_font_family@', '@selector@' ),
|
130 |
-
array( $setting_font_size, $setting_font_family, $selector ),
|
131 |
-
file_get_contents( STYLES_DIR . '/js/post-message-part-text.js' )
|
132 |
-
);
|
133 |
-
|
134 |
-
return $js . PHP_EOL;
|
135 |
-
}
|
136 |
-
|
137 |
-
}
|
138 |
-
|
139 |
-
if (class_exists('WP_Customize_Control')) :
|
140 |
-
|
141 |
-
class Styles_Customize_Text_Control extends WP_Customize_Control {
|
142 |
-
public $type = 'text_formatting';
|
143 |
-
|
144 |
-
public function render_content() {
|
145 |
-
?>
|
146 |
-
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
|
147 |
-
<?php
|
148 |
-
$this->font_size();
|
149 |
-
$this->font_family();
|
150 |
-
}
|
151 |
-
|
152 |
-
public function font_size() {
|
153 |
-
$saved_value = $this->value( 'font_size' );
|
154 |
-
|
155 |
-
?>
|
156 |
-
<label>
|
157 |
-
<input type="text" placeholder="Size" value="<?php echo esc_attr( $saved_value ); ?>" <?php $this->link( 'font_size' ); ?> class="styles-font-size"/> px
|
158 |
-
</label>
|
159 |
-
<?php
|
160 |
-
}
|
161 |
-
|
162 |
-
public function font_family() {
|
163 |
-
$saved_value = $this->value( 'font_family' );
|
164 |
-
|
165 |
-
ob_start();
|
166 |
-
$this->link( 'font_family' );
|
167 |
-
$attributes = ob_get_clean();
|
168 |
-
|
169 |
-
do_action( 'styles_font_menu', $attributes, $saved_value );
|
170 |
-
|
171 |
-
}
|
172 |
-
}
|
173 |
-
|
174 |
endif;
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once dirname( __FILE__ ) . '/styles-font-menu/plugin.php';
|
4 |
+
|
5 |
+
class Styles_Control_Text extends Styles_Control {
|
6 |
+
var $suffix = 'text';
|
7 |
+
|
8 |
+
// CSS Templates
|
9 |
+
var $template = '$selector { $value }';
|
10 |
+
var $template_font_size = 'font-size: $valuepx;';
|
11 |
+
var $template_font_family = 'font-family: $value;';
|
12 |
+
|
13 |
+
public function __construct( $group, $element ) {
|
14 |
+
parent::__construct( $group, $element );
|
15 |
+
|
16 |
+
if ( !empty( $element['template_font_size'] ) ) {
|
17 |
+
$this->template_font_size = $element['template_font_size'];
|
18 |
+
}
|
19 |
+
|
20 |
+
if ( !empty( $element['template_font_family'] ) ) {
|
21 |
+
$this->template_font_family = $element['template_font_family'];
|
22 |
+
}
|
23 |
+
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Register item with $wp_customize
|
28 |
+
*/
|
29 |
+
public function add_item() {
|
30 |
+
global $wp_customize;
|
31 |
+
|
32 |
+
$args_size = $this->get_setting_args( 'font_size' );
|
33 |
+
$setting_size = $this->setting . '[font_size]';
|
34 |
+
|
35 |
+
$args_family = $this->get_setting_args( 'font_family' );
|
36 |
+
// unset( $args_family['transport'] );
|
37 |
+
$setting_family = $this->setting . '[font_family]';
|
38 |
+
|
39 |
+
$wp_customize->add_setting( $setting_size, $args_size );
|
40 |
+
$wp_customize->add_setting( $setting_family, $args_family );
|
41 |
+
|
42 |
+
$control_args = $this->get_control_args();
|
43 |
+
$control_args['settings'] = array(
|
44 |
+
'font_size' => $setting_size,
|
45 |
+
'font_family' => $setting_family,
|
46 |
+
);
|
47 |
+
|
48 |
+
$control = new Styles_Customize_Text_Control(
|
49 |
+
$wp_customize,
|
50 |
+
Styles_Helpers::get_control_id( $this->id ),
|
51 |
+
$control_args
|
52 |
+
);
|
53 |
+
$wp_customize->add_control( $control );
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Return CSS based on setting value
|
58 |
+
*
|
59 |
+
* @return string
|
60 |
+
*/
|
61 |
+
public function get_css(){
|
62 |
+
$value = $this->get_element_setting_value();
|
63 |
+
|
64 |
+
$css = $this->get_css_font_size( $value );
|
65 |
+
$css .= $this->get_css_font_family( $value );
|
66 |
+
|
67 |
+
if ( !empty( $css ) ) {
|
68 |
+
$args = array(
|
69 |
+
'template' => $this->template,
|
70 |
+
'value' => $css,
|
71 |
+
);
|
72 |
+
$css = $this->apply_template( $args );
|
73 |
+
}
|
74 |
+
|
75 |
+
// Filter effects final CSS output, but not postMessage updates
|
76 |
+
return apply_filters( 'styles_css_text', $css );
|
77 |
+
}
|
78 |
+
|
79 |
+
public function get_css_font_size( $value ) {
|
80 |
+
if ( is_array( $value ) ) { $value = $value['font_size']; }
|
81 |
+
|
82 |
+
$css = '';
|
83 |
+
if ( $value ) {
|
84 |
+
$args = array(
|
85 |
+
'template' => $this->template_font_size,
|
86 |
+
'value' => $value,
|
87 |
+
);
|
88 |
+
$css = $this->apply_template( $args );
|
89 |
+
}
|
90 |
+
|
91 |
+
// Filter effects final CSS output, but not postMessage updates
|
92 |
+
return apply_filters( 'styles_css_font_size', $css );
|
93 |
+
}
|
94 |
+
|
95 |
+
public function get_css_font_family( $value = false ) {
|
96 |
+
if ( !$value ) { return ''; }
|
97 |
+
if ( is_array( $value ) ) { $value = $value['font_family']; }
|
98 |
+
|
99 |
+
// Todo: Validate this!!!
|
100 |
+
$font = json_decode( $value );
|
101 |
+
if ( !empty( $font->family ) ) {
|
102 |
+
$value = $font->family;
|
103 |
+
}
|
104 |
+
|
105 |
+
if ( isset( $font->import_family ) ) {
|
106 |
+
$styles = Styles_Plugin::get_instance();
|
107 |
+
$styles->css->google_fonts[ $value ] = "@import url(//fonts.googleapis.com/css?family={$font->import_family});\r";
|
108 |
+
}
|
109 |
+
|
110 |
+
$css = '';
|
111 |
+
if ( $value ) {
|
112 |
+
$args = array(
|
113 |
+
'template' => $this->template_font_family,
|
114 |
+
'value' => $value,
|
115 |
+
);
|
116 |
+
$css = $this->apply_template( $args );
|
117 |
+
}
|
118 |
+
|
119 |
+
// Filter effects final CSS output, but not postMessage updates
|
120 |
+
return apply_filters( 'styles_css_font_family', $css );
|
121 |
+
}
|
122 |
+
|
123 |
+
public function post_message( $js ) {
|
124 |
+
$setting_font_size = $this->setting . '[font_size]';
|
125 |
+
$setting_font_family = $this->setting . '[font_family]';
|
126 |
+
$selector = str_replace( "'", "\'", $this->selector );
|
127 |
+
|
128 |
+
$js .= str_replace(
|
129 |
+
array( '@setting_font_size@', '@setting_font_family@', '@selector@' ),
|
130 |
+
array( $setting_font_size, $setting_font_family, $selector ),
|
131 |
+
file_get_contents( STYLES_DIR . '/js/post-message-part-text.js' )
|
132 |
+
);
|
133 |
+
|
134 |
+
return $js . PHP_EOL;
|
135 |
+
}
|
136 |
+
|
137 |
+
}
|
138 |
+
|
139 |
+
if (class_exists('WP_Customize_Control')) :
|
140 |
+
|
141 |
+
class Styles_Customize_Text_Control extends WP_Customize_Control {
|
142 |
+
public $type = 'text_formatting';
|
143 |
+
|
144 |
+
public function render_content() {
|
145 |
+
?>
|
146 |
+
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
|
147 |
+
<?php
|
148 |
+
$this->font_size();
|
149 |
+
$this->font_family();
|
150 |
+
}
|
151 |
+
|
152 |
+
public function font_size() {
|
153 |
+
$saved_value = $this->value( 'font_size' );
|
154 |
+
|
155 |
+
?>
|
156 |
+
<label>
|
157 |
+
<input type="text" placeholder="Size" value="<?php echo esc_attr( $saved_value ); ?>" <?php $this->link( 'font_size' ); ?> class="styles-font-size"/> px
|
158 |
+
</label>
|
159 |
+
<?php
|
160 |
+
}
|
161 |
+
|
162 |
+
public function font_family() {
|
163 |
+
$saved_value = $this->value( 'font_family' );
|
164 |
+
|
165 |
+
ob_start();
|
166 |
+
$this->link( 'font_family' );
|
167 |
+
$attributes = ob_get_clean();
|
168 |
+
|
169 |
+
do_action( 'styles_font_menu', $attributes, $saved_value );
|
170 |
+
|
171 |
+
}
|
172 |
+
}
|
173 |
+
|
174 |
endif;
|
classes/styles-control.php
CHANGED
@@ -1,232 +1,232 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
abstract class Styles_Control {
|
4 |
-
|
5 |
-
var $group_priority = 1;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Default setting value
|
9 |
-
*/
|
10 |
-
var $default = '';
|
11 |
-
|
12 |
-
// From $element
|
13 |
-
var $selector;
|
14 |
-
var $type;
|
15 |
-
var $label;
|
16 |
-
var $priority;
|
17 |
-
var $id;
|
18 |
-
var $setting;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Template CSS for $selector and $value to be filled into
|
22 |
-
*
|
23 |
-
* @var string
|
24 |
-
**/
|
25 |
-
public $template;
|
26 |
-
|
27 |
-
public function __construct( $group, $element ) {
|
28 |
-
$this->group = $group;
|
29 |
-
$this->element = $element;
|
30 |
-
|
31 |
-
if ( !empty( $element['template'] ) ) {
|
32 |
-
$this->template = $element['template'];
|
33 |
-
}
|
34 |
-
|
35 |
-
if ( !empty( $element['default'] ) ) {
|
36 |
-
$this->default = $element['default'];
|
37 |
-
}
|
38 |
-
|
39 |
-
if ( empty( $this->label) ) {
|
40 |
-
$this->label = $this->selector;
|
41 |
-
}
|
42 |
-
|
43 |
-
foreach( array( 'selector', 'type', 'label', 'priority' ) as $key ) {
|
44 |
-
if ( isset( $element[$key] ) ) {
|
45 |
-
$this->$key = $element[$key];
|
46 |
-
}
|
47 |
-
}
|
48 |
-
|
49 |
-
$this->append_suffix_to_label();
|
50 |
-
$this->maybe_add_important_to_template();
|
51 |
-
|
52 |
-
$this->id = $this->get_element_id(); // must call append_suffix_to_label first
|
53 |
-
$this->setting = $this->get_setting_id(); // must call append_suffix_to_label first
|
54 |
-
|
55 |
-
if ( empty( $this->selector ) ) { return false; }
|
56 |
-
|
57 |
-
// postMessage javascript callback
|
58 |
-
if ( 'postMessage' == $this->get_transport() ) {
|
59 |
-
add_filter( 'styles_customize_preview', array( $this, 'post_message' ) );
|
60 |
-
}
|
61 |
-
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Register control and setting with $wp_customize
|
66 |
-
* @return null
|
67 |
-
*/
|
68 |
-
abstract public function add_item();
|
69 |
-
|
70 |
-
/**
|
71 |
-
* Return args passed into $wp_customize->add_control()
|
72 |
-
* @return array
|
73 |
-
*/
|
74 |
-
public function get_control_args() {
|
75 |
-
$args = array(
|
76 |
-
'label' => __( $this->label, 'styles' ),
|
77 |
-
'section' => $this->group,
|
78 |
-
'settings' => $this->setting,
|
79 |
-
'priority' => $this->priority . $this->group_priority,
|
80 |
-
);
|
81 |
-
return $args;
|
82 |
-
}
|
83 |
-
|
84 |
-
/**
|
85 |
-
* Return args passed into $wp_customize->add_control()
|
86 |
-
* @return array
|
87 |
-
*/
|
88 |
-
public function get_setting_args( $subsetting = null ) {
|
89 |
-
$default = null;
|
90 |
-
if ( ! empty( $subsetting ) ) {
|
91 |
-
if ( isset( $this->default[$subsetting] ) ) {
|
92 |
-
$default = $this->default[$subsetting];
|
93 |
-
}
|
94 |
-
}
|
95 |
-
else if ( ! is_array( $this->default ) ) {
|
96 |
-
$default = $this->default;
|
97 |
-
}
|
98 |
-
$args = array(
|
99 |
-
'default' => $default,
|
100 |
-
'type' => 'option',
|
101 |
-
'capability' => 'edit_theme_options',
|
102 |
-
'transport' => $this->get_transport(),
|
103 |
-
);
|
104 |
-
return $args;
|
105 |
-
}
|
106 |
-
|
107 |
-
public function append_suffix_to_label() {
|
108 |
-
if ( !empty( $this->element['suffix'] ) ) {
|
109 |
-
|
110 |
-
// A custom suffix has been set in the JSON
|
111 |
-
$this->suffix = $this->element['suffix'];
|
112 |
-
|
113 |
-
}else if ( !empty( $this->suffix ) ){
|
114 |
-
|
115 |
-
// No custom suffix set
|
116 |
-
|
117 |
-
// Add indications for pseudo-selectors
|
118 |
-
if ( false !== strpos( $this->selector, ':hover' ) ) {
|
119 |
-
|
120 |
-
// Prepend "hover" if in selector
|
121 |
-
$this->suffix = 'hover ' . $this->suffix;
|
122 |
-
|
123 |
-
}else if ( false !== strpos( $this->selector, ':focus' ) ) {
|
124 |
-
|
125 |
-
// Prepend "focus" if in selector
|
126 |
-
$this->suffix = 'focused ' . $this->suffix;
|
127 |
-
|
128 |
-
}else if ( false !== strpos( $this->selector, ':active' ) ) {
|
129 |
-
|
130 |
-
// Prepend "focus" if in selector
|
131 |
-
$this->suffix = 'active ' . $this->suffix;
|
132 |
-
|
133 |
-
}
|
134 |
-
|
135 |
-
}
|
136 |
-
|
137 |
-
// We have some suffix; append it to the label
|
138 |
-
if ( !empty( $this->suffix ) ) {
|
139 |
-
$this->label .= '::' . $this->suffix;
|
140 |
-
}
|
141 |
-
|
142 |
-
}
|
143 |
-
|
144 |
-
/**
|
145 |
-
* If important is set to "true" in the element JSON,
|
146 |
-
* add !important to CSS template
|
147 |
-
*/
|
148 |
-
public function maybe_add_important_to_template() {
|
149 |
-
if ( isset( $this->element['important'] ) && !empty( $this->element['important'] ) ) {
|
150 |
-
$this->template = str_replace( ';', ' !important;', $this->template );
|
151 |
-
}
|
152 |
-
}
|
153 |
-
|
154 |
-
/**
|
155 |
-
* @param array $element Values related to this control, like CSS selector and control type
|
156 |
-
* @return string Unique, sanatized ID for this element based on label and type
|
157 |
-
*/
|
158 |
-
public function get_element_id() {
|
159 |
-
$key = trim( sanitize_key( $this->label . '_' . $this->type ), '_' );
|
160 |
-
return str_replace( '-', '_', $key );
|
161 |
-
}
|
162 |
-
|
163 |
-
/**
|
164 |
-
* @param string $group Name of Customizer group this element is in
|
165 |
-
* @param string $id unique element ID
|
166 |
-
* @return string $setting_id unique setting ID for use in form input names
|
167 |
-
*/
|
168 |
-
public function get_setting_id() {
|
169 |
-
$group = $this->group;
|
170 |
-
$id = str_replace( '-', '_', trim( $this->id, '_' ) );
|
171 |
-
|
172 |
-
$setting_id = Styles_Helpers::get_option_key() . "[$group][$id]";
|
173 |
-
|
174 |
-
return $setting_id;
|
175 |
-
}
|
176 |
-
|
177 |
-
public function get_element_setting_value() {
|
178 |
-
$settings = get_option( Styles_Helpers::get_option_key() );
|
179 |
-
|
180 |
-
$group_id = Styles_Helpers::get_group_id( $this->group );
|
181 |
-
|
182 |
-
$value = false;
|
183 |
-
|
184 |
-
if ( isset( $settings[ $group_id ][ $this->id ] ) ) {
|
185 |
-
$value = $settings[ $group_id ][ $this->id ];
|
186 |
-
}
|
187 |
-
|
188 |
-
if ( !empty( $value ) ) {
|
189 |
-
return $value;
|
190 |
-
}else {
|
191 |
-
return false;
|
192 |
-
}
|
193 |
-
}
|
194 |
-
|
195 |
-
public function get_transport() {
|
196 |
-
$transport = 'refresh';
|
197 |
-
|
198 |
-
if (
|
199 |
-
method_exists( $this, 'post_message' )
|
200 |
-
&& empty( $this->element['template'] ) // No custom CSS template set
|
201 |
-
&& false == strpos( $this->selector, ':' ) // jQuery doesn't understand pseudo-selectors like :hover and :focus
|
202 |
-
) {
|
203 |
-
// postMessage supported
|
204 |
-
$transport = 'postMessage';
|
205 |
-
}
|
206 |
-
|
207 |
-
return $transport;
|
208 |
-
}
|
209 |
-
|
210 |
-
public function apply_template( $args ) {
|
211 |
-
$template = $args['template'];
|
212 |
-
unset( $args['template'] );
|
213 |
-
|
214 |
-
foreach ( $args as $key => $value ) {
|
215 |
-
$template = str_replace( '$'.$key, $value, $template );
|
216 |
-
}
|
217 |
-
|
218 |
-
$template = str_replace( '$selector', $this->selector, $template );
|
219 |
-
|
220 |
-
return $template;
|
221 |
-
}
|
222 |
-
|
223 |
-
/**
|
224 |
-
* Convert CSS selector into jQuery-compatible selector
|
225 |
-
*/
|
226 |
-
public function jquery_selector() {
|
227 |
-
$selector = str_replace( "'", "\'", $this->selector );
|
228 |
-
|
229 |
-
return $selector;
|
230 |
-
}
|
231 |
-
|
232 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
abstract class Styles_Control {
|
4 |
+
|
5 |
+
var $group_priority = 1;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Default setting value
|
9 |
+
*/
|
10 |
+
var $default = '';
|
11 |
+
|
12 |
+
// From $element
|
13 |
+
var $selector;
|
14 |
+
var $type;
|
15 |
+
var $label;
|
16 |
+
var $priority;
|
17 |
+
var $id;
|
18 |
+
var $setting;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Template CSS for $selector and $value to be filled into
|
22 |
+
*
|
23 |
+
* @var string
|
24 |
+
**/
|
25 |
+
public $template;
|
26 |
+
|
27 |
+
public function __construct( $group, $element ) {
|
28 |
+
$this->group = $group;
|
29 |
+
$this->element = $element;
|
30 |
+
|
31 |
+
if ( !empty( $element['template'] ) ) {
|
32 |
+
$this->template = $element['template'];
|
33 |
+
}
|
34 |
+
|
35 |
+
if ( !empty( $element['default'] ) ) {
|
36 |
+
$this->default = $element['default'];
|
37 |
+
}
|
38 |
+
|
39 |
+
if ( empty( $this->label) ) {
|
40 |
+
$this->label = $this->selector;
|
41 |
+
}
|
42 |
+
|
43 |
+
foreach( array( 'selector', 'type', 'label', 'priority' ) as $key ) {
|
44 |
+
if ( isset( $element[$key] ) ) {
|
45 |
+
$this->$key = $element[$key];
|
46 |
+
}
|
47 |
+
}
|
48 |
+
|
49 |
+
$this->append_suffix_to_label();
|
50 |
+
$this->maybe_add_important_to_template();
|
51 |
+
|
52 |
+
$this->id = $this->get_element_id(); // must call append_suffix_to_label first
|
53 |
+
$this->setting = $this->get_setting_id(); // must call append_suffix_to_label first
|
54 |
+
|
55 |
+
if ( empty( $this->selector ) ) { return false; }
|
56 |
+
|
57 |
+
// postMessage javascript callback
|
58 |
+
if ( 'postMessage' == $this->get_transport() ) {
|
59 |
+
add_filter( 'styles_customize_preview', array( $this, 'post_message' ) );
|
60 |
+
}
|
61 |
+
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Register control and setting with $wp_customize
|
66 |
+
* @return null
|
67 |
+
*/
|
68 |
+
abstract public function add_item();
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Return args passed into $wp_customize->add_control()
|
72 |
+
* @return array
|
73 |
+
*/
|
74 |
+
public function get_control_args() {
|
75 |
+
$args = array(
|
76 |
+
'label' => __( $this->label, 'styles' ),
|
77 |
+
'section' => $this->group,
|
78 |
+
'settings' => $this->setting,
|
79 |
+
'priority' => $this->priority . $this->group_priority,
|
80 |
+
);
|
81 |
+
return $args;
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Return args passed into $wp_customize->add_control()
|
86 |
+
* @return array
|
87 |
+
*/
|
88 |
+
public function get_setting_args( $subsetting = null ) {
|
89 |
+
$default = null;
|
90 |
+
if ( ! empty( $subsetting ) ) {
|
91 |
+
if ( isset( $this->default[$subsetting] ) ) {
|
92 |
+
$default = $this->default[$subsetting];
|
93 |
+
}
|
94 |
+
}
|
95 |
+
else if ( ! is_array( $this->default ) ) {
|
96 |
+
$default = $this->default;
|
97 |
+
}
|
98 |
+
$args = array(
|
99 |
+
'default' => $default,
|
100 |
+
'type' => 'option',
|
101 |
+
'capability' => 'edit_theme_options',
|
102 |
+
'transport' => $this->get_transport(),
|
103 |
+
);
|
104 |
+
return $args;
|
105 |
+
}
|
106 |
+
|
107 |
+
public function append_suffix_to_label() {
|
108 |
+
if ( !empty( $this->element['suffix'] ) ) {
|
109 |
+
|
110 |
+
// A custom suffix has been set in the JSON
|
111 |
+
$this->suffix = $this->element['suffix'];
|
112 |
+
|
113 |
+
}else if ( !empty( $this->suffix ) ){
|
114 |
+
|
115 |
+
// No custom suffix set
|
116 |
+
|
117 |
+
// Add indications for pseudo-selectors
|
118 |
+
if ( false !== strpos( $this->selector, ':hover' ) ) {
|
119 |
+
|
120 |
+
// Prepend "hover" if in selector
|
121 |
+
$this->suffix = 'hover ' . $this->suffix;
|
122 |
+
|
123 |
+
}else if ( false !== strpos( $this->selector, ':focus' ) ) {
|
124 |
+
|
125 |
+
// Prepend "focus" if in selector
|
126 |
+
$this->suffix = 'focused ' . $this->suffix;
|
127 |
+
|
128 |
+
}else if ( false !== strpos( $this->selector, ':active' ) ) {
|
129 |
+
|
130 |
+
// Prepend "focus" if in selector
|
131 |
+
$this->suffix = 'active ' . $this->suffix;
|
132 |
+
|
133 |
+
}
|
134 |
+
|
135 |
+
}
|
136 |
+
|
137 |
+
// We have some suffix; append it to the label
|
138 |
+
if ( !empty( $this->suffix ) ) {
|
139 |
+
$this->label .= '::' . $this->suffix;
|
140 |
+
}
|
141 |
+
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* If important is set to "true" in the element JSON,
|
146 |
+
* add !important to CSS template
|
147 |
+
*/
|
148 |
+
public function maybe_add_important_to_template() {
|
149 |
+
if ( isset( $this->element['important'] ) && !empty( $this->element['important'] ) ) {
|
150 |
+
$this->template = str_replace( ';', ' !important;', $this->template );
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* @param array $element Values related to this control, like CSS selector and control type
|
156 |
+
* @return string Unique, sanatized ID for this element based on label and type
|
157 |
+
*/
|
158 |
+
public function get_element_id() {
|
159 |
+
$key = trim( sanitize_key( $this->label . '_' . $this->type ), '_' );
|
160 |
+
return str_replace( '-', '_', $key );
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* @param string $group Name of Customizer group this element is in
|
165 |
+
* @param string $id unique element ID
|
166 |
+
* @return string $setting_id unique setting ID for use in form input names
|
167 |
+
*/
|
168 |
+
public function get_setting_id() {
|
169 |
+
$group = $this->group;
|
170 |
+
$id = str_replace( '-', '_', trim( $this->id, '_' ) );
|
171 |
+
|
172 |
+
$setting_id = Styles_Helpers::get_option_key() . "[$group][$id]";
|
173 |
+
|
174 |
+
return $setting_id;
|
175 |
+
}
|
176 |
+
|
177 |
+
public function get_element_setting_value() {
|
178 |
+
$settings = get_option( Styles_Helpers::get_option_key() );
|
179 |
+
|
180 |
+
$group_id = Styles_Helpers::get_group_id( $this->group );
|
181 |
+
|
182 |
+
$value = false;
|
183 |
+
|
184 |
+
if ( isset( $settings[ $group_id ][ $this->id ] ) ) {
|
185 |
+
$value = $settings[ $group_id ][ $this->id ];
|
186 |
+
}
|
187 |
+
|
188 |
+
if ( !empty( $value ) ) {
|
189 |
+
return $value;
|
190 |
+
}else {
|
191 |
+
return false;
|
192 |
+
}
|
193 |
+
}
|
194 |
+
|
195 |
+
public function get_transport() {
|
196 |
+
$transport = 'refresh';
|
197 |
+
|
198 |
+
if (
|
199 |
+
method_exists( $this, 'post_message' )
|
200 |
+
&& empty( $this->element['template'] ) // No custom CSS template set
|
201 |
+
&& false == strpos( $this->selector, ':' ) // jQuery doesn't understand pseudo-selectors like :hover and :focus
|
202 |
+
) {
|
203 |
+
// postMessage supported
|
204 |
+
$transport = 'postMessage';
|
205 |
+
}
|
206 |
+
|
207 |
+
return $transport;
|
208 |
+
}
|
209 |
+
|
210 |
+
public function apply_template( $args ) {
|
211 |
+
$template = $args['template'];
|
212 |
+
unset( $args['template'] );
|
213 |
+
|
214 |
+
foreach ( $args as $key => $value ) {
|
215 |
+
$template = str_replace( '$'.$key, $value, $template );
|
216 |
+
}
|
217 |
+
|
218 |
+
$template = str_replace( '$selector', $this->selector, $template );
|
219 |
+
|
220 |
+
return $template;
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Convert CSS selector into jQuery-compatible selector
|
225 |
+
*/
|
226 |
+
public function jquery_selector() {
|
227 |
+
$selector = str_replace( "'", "\'", $this->selector );
|
228 |
+
|
229 |
+
return $selector;
|
230 |
+
}
|
231 |
+
|
232 |
}
|
classes/styles-css.php
CHANGED
@@ -1,122 +1,122 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class Styles_CSS {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var Styles_Plugin
|
7 |
-
*/
|
8 |
-
var $plugin;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @import declarations to be added to top of CSS
|
12 |
-
*
|
13 |
-
* @var string
|
14 |
-
*/
|
15 |
-
public $google_fonts = array();
|
16 |
-
|
17 |
-
function __construct( $plugin ) {
|
18 |
-
$this->plugin = $plugin;
|
19 |
-
|
20 |
-
add_filter( 'styles_pre_get_css', array( $this, 'selector_prefix' ) );
|
21 |
-
|
22 |
-
}
|
23 |
-
|
24 |
-
public function selector_prefix( $element ) {
|
25 |
-
if ( !empty( $element['selector'] ) ) {
|
26 |
-
$selector_array = explode( ',', $element['selector'] );
|
27 |
-
|
28 |
-
foreach( $selector_array as &$sub_selector ) {
|
29 |
-
|
30 |
-
if ( 'body' == $sub_selector ) {
|
31 |
-
// body selector without class; add it
|
32 |
-
$sub_selector = $sub_selector . '.' . $this->plugin->body_class;
|
33 |
-
}else if ( 'body ' == substr( $sub_selector, 0 ) ){
|
34 |
-
// body selector with sub-item without class
|
35 |
-
$sub_selector = str_replace( 'body ', 'body'. $this->plugin->body_class . ' ', $sub_selector );
|
36 |
-
}else if ( 'html' == substr( $sub_selector, 0 ) || 'body' == substr( $sub_selector, 0 ) ) {
|
37 |
-
// html or body selector
|
38 |
-
continue;
|
39 |
-
}else {
|
40 |
-
// All others, prepend body class
|
41 |
-
$sub_selector = '.' . $this->plugin->body_class . ' ' . $sub_selector;
|
42 |
-
}
|
43 |
-
|
44 |
-
}
|
45 |
-
|
46 |
-
$element['selector'] = implode( ',', $selector_array );
|
47 |
-
}
|
48 |
-
|
49 |
-
return $element;
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Rebuild CSS
|
54 |
-
*
|
55 |
-
* Cache check called in Styles_Plugin::get_css to avoid initializing this class
|
56 |
-
*/
|
57 |
-
public function get_css() {
|
58 |
-
global $wp_customize;
|
59 |
-
|
60 |
-
$css = '';
|
61 |
-
|
62 |
-
$this->plugin->customize_register( $wp_customize );
|
63 |
-
|
64 |
-
foreach ( $this->plugin->customize->get_settings() as $group => $elements ) {
|
65 |
-
foreach ( $elements as $element ) {
|
66 |
-
if ( $class = Styles_Helpers::get_element_class( $element ) ) {
|
67 |
-
|
68 |
-
$element = apply_filters( 'styles_pre_get_css', $element );
|
69 |
-
$control = new $class( $group, $element );
|
70 |
-
|
71 |
-
$css .= $control->get_css();
|
72 |
-
}
|
73 |
-
}
|
74 |
-
}
|
75 |
-
|
76 |
-
$css = apply_filters( 'styles_css_output', $css );
|
77 |
-
|
78 |
-
$css = implode( '', $this->google_fonts ) . $css;
|
79 |
-
|
80 |
-
$css = $this->minify( $css );
|
81 |
-
|
82 |
-
update_option( Styles_Helpers::get_option_key( 'css' ), $css );
|
83 |
-
|
84 |
-
return $css;
|
85 |
-
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Minimize CSS output using CSS Tidy.
|
90 |
-
*
|
91 |
-
* @see styles_css_output filter
|
92 |
-
* @author JetPack by Automattic
|
93 |
-
*/
|
94 |
-
public function minify( $css ) {
|
95 |
-
// Allow minification to be disabled with add_filter( 'styles_minify_css', '__return_false' );
|
96 |
-
if ( !apply_filters( 'styles_minify_css', true ) ) {
|
97 |
-
return $css;
|
98 |
-
}
|
99 |
-
|
100 |
-
if ( !class_exists( 'csstidy') ) {
|
101 |
-
include dirname( __FILE__ ) . '/csstidy/class.csstidy.php';
|
102 |
-
}
|
103 |
-
|
104 |
-
$csstidy = new csstidy();
|
105 |
-
$csstidy->optimize = new csstidy_optimise( $csstidy );
|
106 |
-
|
107 |
-
$csstidy->set_cfg( 'remove_bslash', false );
|
108 |
-
$csstidy->set_cfg( 'compress_colors', true );
|
109 |
-
$csstidy->set_cfg( 'compress_font-weight', true );
|
110 |
-
$csstidy->set_cfg( 'remove_last_;', true );
|
111 |
-
$csstidy->set_cfg( 'case_properties', true );
|
112 |
-
$csstidy->set_cfg( 'discard_invalid_properties', true );
|
113 |
-
$csstidy->set_cfg( 'css_level', 'CSS3.0' );
|
114 |
-
$csstidy->set_cfg( 'template', 'highest');
|
115 |
-
$csstidy->parse( $css );
|
116 |
-
|
117 |
-
$css = $csstidy->print->plain();
|
118 |
-
|
119 |
-
return $css;
|
120 |
-
}
|
121 |
-
|
122 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Styles_CSS {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var Styles_Plugin
|
7 |
+
*/
|
8 |
+
var $plugin;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @import declarations to be added to top of CSS
|
12 |
+
*
|
13 |
+
* @var string
|
14 |
+
*/
|
15 |
+
public $google_fonts = array();
|
16 |
+
|
17 |
+
function __construct( $plugin ) {
|
18 |
+
$this->plugin = $plugin;
|
19 |
+
|
20 |
+
add_filter( 'styles_pre_get_css', array( $this, 'selector_prefix' ) );
|
21 |
+
|
22 |
+
}
|
23 |
+
|
24 |
+
public function selector_prefix( $element ) {
|
25 |
+
if ( !empty( $element['selector'] ) ) {
|
26 |
+
$selector_array = explode( ',', $element['selector'] );
|
27 |
+
|
28 |
+
foreach( $selector_array as &$sub_selector ) {
|
29 |
+
|
30 |
+
if ( 'body' == $sub_selector ) {
|
31 |
+
// body selector without class; add it
|
32 |
+
$sub_selector = $sub_selector . '.' . $this->plugin->body_class;
|
33 |
+
}else if ( 'body ' == substr( $sub_selector, 0 ) ){
|
34 |
+
// body selector with sub-item without class
|
35 |
+
$sub_selector = str_replace( 'body ', 'body'. $this->plugin->body_class . ' ', $sub_selector );
|
36 |
+
}else if ( 'html' == substr( $sub_selector, 0 ) || 'body' == substr( $sub_selector, 0 ) ) {
|
37 |
+
// html or body selector
|
38 |
+
continue;
|
39 |
+
}else {
|
40 |
+
// All others, prepend body class
|
41 |
+
$sub_selector = '.' . $this->plugin->body_class . ' ' . $sub_selector;
|
42 |
+
}
|
43 |
+
|
44 |
+
}
|
45 |
+
|
46 |
+
$element['selector'] = implode( ',', $selector_array );
|
47 |
+
}
|
48 |
+
|
49 |
+
return $element;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Rebuild CSS
|
54 |
+
*
|
55 |
+
* Cache check called in Styles_Plugin::get_css to avoid initializing this class
|
56 |
+
*/
|
57 |
+
public function get_css() {
|
58 |
+
global $wp_customize;
|
59 |
+
|
60 |
+
$css = '';
|
61 |
+
|
62 |
+
$this->plugin->customize_register( $wp_customize );
|
63 |
+
|
64 |
+
foreach ( $this->plugin->customize->get_settings() as $group => $elements ) {
|
65 |
+
foreach ( $elements as $element ) {
|
66 |
+
if ( $class = Styles_Helpers::get_element_class( $element ) ) {
|
67 |
+
|
68 |
+
$element = apply_filters( 'styles_pre_get_css', $element );
|
69 |
+
$control = new $class( $group, $element );
|
70 |
+
|
71 |
+
$css .= $control->get_css();
|
72 |
+
}
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
$css = apply_filters( 'styles_css_output', $css );
|
77 |
+
|
78 |
+
$css = implode( '', $this->google_fonts ) . $css;
|
79 |
+
|
80 |
+
$css = $this->minify( $css );
|
81 |
+
|
82 |
+
update_option( Styles_Helpers::get_option_key( 'css' ), $css );
|
83 |
+
|
84 |
+
return $css;
|
85 |
+
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Minimize CSS output using CSS Tidy.
|
90 |
+
*
|
91 |
+
* @see styles_css_output filter
|
92 |
+
* @author JetPack by Automattic
|
93 |
+
*/
|
94 |
+
public function minify( $css ) {
|
95 |
+
// Allow minification to be disabled with add_filter( 'styles_minify_css', '__return_false' );
|
96 |
+
if ( !apply_filters( 'styles_minify_css', true ) ) {
|
97 |
+
return $css;
|
98 |
+
}
|
99 |
+
|
100 |
+
if ( !class_exists( 'csstidy') ) {
|
101 |
+
include dirname( __FILE__ ) . '/csstidy/class.csstidy.php';
|
102 |
+
}
|
103 |
+
|
104 |
+
$csstidy = new csstidy();
|
105 |
+
$csstidy->optimize = new csstidy_optimise( $csstidy );
|
106 |
+
|
107 |
+
$csstidy->set_cfg( 'remove_bslash', false );
|
108 |
+
$csstidy->set_cfg( 'compress_colors', true );
|
109 |
+
$csstidy->set_cfg( 'compress_font-weight', true );
|
110 |
+
$csstidy->set_cfg( 'remove_last_;', true );
|
111 |
+
$csstidy->set_cfg( 'case_properties', true );
|
112 |
+
$csstidy->set_cfg( 'discard_invalid_properties', true );
|
113 |
+
$csstidy->set_cfg( 'css_level', 'CSS3.0' );
|
114 |
+
$csstidy->set_cfg( 'template', 'highest');
|
115 |
+
$csstidy->parse( $css );
|
116 |
+
|
117 |
+
$css = $csstidy->print->plain();
|
118 |
+
|
119 |
+
return $css;
|
120 |
+
}
|
121 |
+
|
122 |
+
}
|
classes/styles-customize.php
CHANGED
@@ -1,181 +1,181 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class Styles_Customize {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var Styles_Plugin
|
7 |
-
*/
|
8 |
-
var $plugin;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Customize settings loaded from customize.json in plugin or theme
|
12 |
-
* @var array
|
13 |
-
*/
|
14 |
-
var $settings = array();
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Styles_Control objects that register with wp_customize
|
18 |
-
*
|
19 |
-
* @var array contains Styles_Control objects
|
20 |
-
*/
|
21 |
-
var $controls;
|
22 |
-
|
23 |
-
function __construct( $plugin ) {
|
24 |
-
$this->plugin = &$plugin;
|
25 |
-
|
26 |
-
add_action( 'customize_register', array( $this, 'add_sections' ), 10 );
|
27 |
-
add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_enqueue' ) );
|
28 |
-
add_action( 'customize_preview_init', array( $this, 'customize_preview_init' ) );
|
29 |
-
|
30 |
-
// Load settings from various sources with filters
|
31 |
-
add_filter( 'styles_json_files', array( $this, 'load_settings_from_child_plugin' ), 50 );
|
32 |
-
add_filter( 'styles_json_files', array( $this, 'load_settings_from_theme' ), 70 );
|
33 |
-
|
34 |
-
// Set storm-styles option to not autoload; does nothing if setting already exists
|
35 |
-
add_option( Styles_Helpers::get_option_key(), '', '', 'no' );
|
36 |
-
|
37 |
-
}
|
38 |
-
|
39 |
-
public function customize_preview_init() {
|
40 |
-
add_action( 'wp_footer', array( $this, 'preview_js' ) );
|
41 |
-
}
|
42 |
-
|
43 |
-
public function customize_controls_enqueue() {
|
44 |
-
|
45 |
-
// Stylesheets
|
46 |
-
wp_enqueue_style( 'styles-customize', plugins_url( '/css/styles-customize.css', STYLES_BASENAME ), array(), $this->plugin->version );
|
47 |
-
|
48 |
-
// Javascript
|
49 |
-
wp_enqueue_script( 'styles-customize-controls', plugins_url( '/js/styles-customize-controls.js', STYLES_BASENAME ), array(), $this->plugin->version );
|
50 |
-
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Output javascript for WP Customizer preview postMessage transport
|
55 |
-
*/
|
56 |
-
public function preview_js() {
|
57 |
-
// Ensure dependencies have been output by now.
|
58 |
-
wp_print_scripts( array( 'jquery', 'customize-preview' ) );
|
59 |
-
|
60 |
-
?>
|
61 |
-
<script>
|
62 |
-
( function( $ ){
|
63 |
-
|
64 |
-
<?php echo apply_filters( 'styles_customize_preview', '' ) ?>
|
65 |
-
|
66 |
-
} )( jQuery );
|
67 |
-
</script>
|
68 |
-
<?php
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Register sections with WordPress theme customizer in WordPress 3.4+
|
73 |
-
* e.g., General, Header, Footer, Content, Sidebar
|
74 |
-
*/
|
75 |
-
function add_sections( $wp_customize ) {
|
76 |
-
global $wp_customize;
|
77 |
-
|
78 |
-
$i = 950;
|
79 |
-
foreach ( (array) $this->get_settings() as $group => $elements ) {
|
80 |
-
$i++;
|
81 |
-
|
82 |
-
// Groups
|
83 |
-
$group_id = Styles_Helpers::get_group_id( $group );
|
84 |
-
$has_section = (bool) $wp_customize->get_section( $group_id );
|
85 |
-
if ( ! $has_section ) {
|
86 |
-
$wp_customize->add_section( $group_id, array(
|
87 |
-
'title' => __( $group, 'storm' ),
|
88 |
-
'priority' => $i,
|
89 |
-
) );
|
90 |
-
}
|
91 |
-
|
92 |
-
$this->add_items( $group_id, $elements );
|
93 |
-
}
|
94 |
-
}
|
95 |
-
|
96 |
-
|
97 |
-
/**
|
98 |
-
* Register individual customize fields in WordPress 3.4+
|
99 |
-
* Settings & Controls are within each class (type calls different classes)
|
100 |
-
*/
|
101 |
-
public function add_items( $group_id, $elements, $add_item = true ) {
|
102 |
-
static $i;
|
103 |
-
foreach ( (array) $elements as $element ) {
|
104 |
-
$i++;
|
105 |
-
$element['priority'] = $i;
|
106 |
-
if ( $class = Styles_Helpers::get_element_class( $element ) ) {
|
107 |
-
|
108 |
-
// PHP <= 5.2 support
|
109 |
-
// Otherwise, would be: $class::add_item( $group_id, $element );
|
110 |
-
$control = new $class( $group_id, $element );
|
111 |
-
|
112 |
-
if ( $add_item ) {
|
113 |
-
$control->add_item();
|
114 |
-
}
|
115 |
-
|
116 |
-
$this->controls[] = $control;
|
117 |
-
}
|
118 |
-
}
|
119 |
-
|
120 |
-
}
|
121 |
-
|
122 |
-
/**
|
123 |
-
* Load settings as JSON either from transient / API or theme file
|
124 |
-
*
|
125 |
-
* @return array
|
126 |
-
*/
|
127 |
-
public function get_settings() {
|
128 |
-
|
129 |
-
// Return cached settings if they've already been processed
|
130 |
-
if ( !empty( $this->settings ) ) {
|
131 |
-
return $this->settings;
|
132 |
-
}
|
133 |
-
|
134 |
-
// Plugin Authors: Filter to provide arbitrary JSON file paths
|
135 |
-
foreach( (array) apply_filters( 'styles_json_files', array() ) as $json_file ) {
|
136 |
-
$this->settings = $this->load_settings_from_json_file( $json_file, $this->settings );
|
137 |
-
}
|
138 |
-
|
139 |
-
// Last-second filter to edit settings as PHP array instead of JSON
|
140 |
-
return apply_filters( 'styles_settings', $this->settings );
|
141 |
-
}
|
142 |
-
|
143 |
-
/**
|
144 |
-
* Load settings from plugin that inherits a Styles class,
|
145 |
-
* like Styles_Child_Theme, which expects customize.json to be in plugin directory
|
146 |
-
*/
|
147 |
-
public function load_settings_from_child_plugin( $json_files ) {
|
148 |
-
|
149 |
-
// Plugins that declare styles class: XXX in header
|
150 |
-
foreach( (array) $this->plugin->child->plugins as $plugin ) {
|
151 |
-
// Class contains method get_json_path()
|
152 |
-
if( method_exists( $plugin, 'get_json_path' ) ) {
|
153 |
-
$json_files[] = $plugin->get_json_path();
|
154 |
-
}
|
155 |
-
}
|
156 |
-
|
157 |
-
return $json_files;
|
158 |
-
}
|
159 |
-
|
160 |
-
/**
|
161 |
-
* Load settings from theme file formatted as JSON
|
162 |
-
*/
|
163 |
-
public function load_settings_from_theme( $json_files ) {
|
164 |
-
$json_files[] = get_stylesheet_directory() . '/customize.json';
|
165 |
-
return $json_files;
|
166 |
-
}
|
167 |
-
|
168 |
-
public function load_settings_from_json_file( $json_file, $default_settings = array() ) {
|
169 |
-
$settings = array();
|
170 |
-
if ( file_exists( $json_file ) ) {
|
171 |
-
$json = preg_replace('!/\*.*?\*/!s', '', file_get_contents( $json_file ) ); // strip comments before decoding
|
172 |
-
$settings = json_decode( $json, true );
|
173 |
-
|
174 |
-
if ( $json_error = Styles_Helpers::get_json_error( $json_file, $settings ) ) {
|
175 |
-
wp_die( $json_error );
|
176 |
-
}
|
177 |
-
}
|
178 |
-
return wp_parse_args( $settings, $default_settings );
|
179 |
-
}
|
180 |
-
|
181 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Styles_Customize {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var Styles_Plugin
|
7 |
+
*/
|
8 |
+
var $plugin;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Customize settings loaded from customize.json in plugin or theme
|
12 |
+
* @var array
|
13 |
+
*/
|
14 |
+
var $settings = array();
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Styles_Control objects that register with wp_customize
|
18 |
+
*
|
19 |
+
* @var array contains Styles_Control objects
|
20 |
+
*/
|
21 |
+
var $controls;
|
22 |
+
|
23 |
+
function __construct( $plugin ) {
|
24 |
+
$this->plugin = &$plugin;
|
25 |
+
|
26 |
+
add_action( 'customize_register', array( $this, 'add_sections' ), 10 );
|
27 |
+
add_action( 'customize_controls_enqueue_scripts', array( $this, 'customize_controls_enqueue' ) );
|
28 |
+
add_action( 'customize_preview_init', array( $this, 'customize_preview_init' ) );
|
29 |
+
|
30 |
+
// Load settings from various sources with filters
|
31 |
+
add_filter( 'styles_json_files', array( $this, 'load_settings_from_child_plugin' ), 50 );
|
32 |
+
add_filter( 'styles_json_files', array( $this, 'load_settings_from_theme' ), 70 );
|
33 |
+
|
34 |
+
// Set storm-styles option to not autoload; does nothing if setting already exists
|
35 |
+
add_option( Styles_Helpers::get_option_key(), '', '', 'no' );
|
36 |
+
|
37 |
+
}
|
38 |
+
|
39 |
+
public function customize_preview_init() {
|
40 |
+
add_action( 'wp_footer', array( $this, 'preview_js' ) );
|
41 |
+
}
|
42 |
+
|
43 |
+
public function customize_controls_enqueue() {
|
44 |
+
|
45 |
+
// Stylesheets
|
46 |
+
wp_enqueue_style( 'styles-customize', plugins_url( '/css/styles-customize.css', STYLES_BASENAME ), array(), $this->plugin->version );
|
47 |
+
|
48 |
+
// Javascript
|
49 |
+
wp_enqueue_script( 'styles-customize-controls', plugins_url( '/js/styles-customize-controls.js', STYLES_BASENAME ), array(), $this->plugin->version );
|
50 |
+
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Output javascript for WP Customizer preview postMessage transport
|
55 |
+
*/
|
56 |
+
public function preview_js() {
|
57 |
+
// Ensure dependencies have been output by now.
|
58 |
+
wp_print_scripts( array( 'jquery', 'customize-preview' ) );
|
59 |
+
|
60 |
+
?>
|
61 |
+
<script>
|
62 |
+
( function( $ ){
|
63 |
+
|
64 |
+
<?php echo apply_filters( 'styles_customize_preview', '' ) ?>
|
65 |
+
|
66 |
+
} )( jQuery );
|
67 |
+
</script>
|
68 |
+
<?php
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Register sections with WordPress theme customizer in WordPress 3.4+
|
73 |
+
* e.g., General, Header, Footer, Content, Sidebar
|
74 |
+
*/
|
75 |
+
function add_sections( $wp_customize ) {
|
76 |
+
global $wp_customize;
|
77 |
+
|
78 |
+
$i = 950;
|
79 |
+
foreach ( (array) $this->get_settings() as $group => $elements ) {
|
80 |
+
$i++;
|
81 |
+
|
82 |
+
// Groups
|
83 |
+
$group_id = Styles_Helpers::get_group_id( $group );
|
84 |
+
$has_section = (bool) $wp_customize->get_section( $group_id );
|
85 |
+
if ( ! $has_section ) {
|
86 |
+
$wp_customize->add_section( $group_id, array(
|
87 |
+
'title' => __( $group, 'storm' ),
|
88 |
+
'priority' => $i,
|
89 |
+
) );
|
90 |
+
}
|
91 |
+
|
92 |
+
$this->add_items( $group_id, $elements );
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Register individual customize fields in WordPress 3.4+
|
99 |
+
* Settings & Controls are within each class (type calls different classes)
|
100 |
+
*/
|
101 |
+
public function add_items( $group_id, $elements, $add_item = true ) {
|
102 |
+
static $i;
|
103 |
+
foreach ( (array) $elements as $element ) {
|
104 |
+
$i++;
|
105 |
+
$element['priority'] = $i;
|
106 |
+
if ( $class = Styles_Helpers::get_element_class( $element ) ) {
|
107 |
+
|
108 |
+
// PHP <= 5.2 support
|
109 |
+
// Otherwise, would be: $class::add_item( $group_id, $element );
|
110 |
+
$control = new $class( $group_id, $element );
|
111 |
+
|
112 |
+
if ( $add_item ) {
|
113 |
+
$control->add_item();
|
114 |
+
}
|
115 |
+
|
116 |
+
$this->controls[] = $control;
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Load settings as JSON either from transient / API or theme file
|
124 |
+
*
|
125 |
+
* @return array
|
126 |
+
*/
|
127 |
+
public function get_settings() {
|
128 |
+
|
129 |
+
// Return cached settings if they've already been processed
|
130 |
+
if ( !empty( $this->settings ) ) {
|
131 |
+
return $this->settings;
|
132 |
+
}
|
133 |
+
|
134 |
+
// Plugin Authors: Filter to provide arbitrary JSON file paths
|
135 |
+
foreach( (array) apply_filters( 'styles_json_files', array() ) as $json_file ) {
|
136 |
+
$this->settings = $this->load_settings_from_json_file( $json_file, $this->settings );
|
137 |
+
}
|
138 |
+
|
139 |
+
// Last-second filter to edit settings as PHP array instead of JSON
|
140 |
+
return apply_filters( 'styles_settings', $this->settings );
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Load settings from plugin that inherits a Styles class,
|
145 |
+
* like Styles_Child_Theme, which expects customize.json to be in plugin directory
|
146 |
+
*/
|
147 |
+
public function load_settings_from_child_plugin( $json_files ) {
|
148 |
+
|
149 |
+
// Plugins that declare styles class: XXX in header
|
150 |
+
foreach( (array) $this->plugin->child->plugins as $plugin ) {
|
151 |
+
// Class contains method get_json_path()
|
152 |
+
if( method_exists( $plugin, 'get_json_path' ) ) {
|
153 |
+
$json_files[] = $plugin->get_json_path();
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
+
return $json_files;
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Load settings from theme file formatted as JSON
|
162 |
+
*/
|
163 |
+
public function load_settings_from_theme( $json_files ) {
|
164 |
+
$json_files[] = get_stylesheet_directory() . '/customize.json';
|
165 |
+
return $json_files;
|
166 |
+
}
|
167 |
+
|
168 |
+
public function load_settings_from_json_file( $json_file, $default_settings = array() ) {
|
169 |
+
$settings = array();
|
170 |
+
if ( file_exists( $json_file ) ) {
|
171 |
+
$json = preg_replace('!/\*.*?\*/!s', '', file_get_contents( $json_file ) ); // strip comments before decoding
|
172 |
+
$settings = json_decode( $json, true );
|
173 |
+
|
174 |
+
if ( $json_error = Styles_Helpers::get_json_error( $json_file, $settings ) ) {
|
175 |
+
wp_die( $json_error );
|
176 |
+
}
|
177 |
+
}
|
178 |
+
return wp_parse_args( $settings, $default_settings );
|
179 |
+
}
|
180 |
+
|
181 |
}
|
classes/styles-debug.php
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Output helpful information for remote debug.
|
5 |
+
*/
|
6 |
+
class Styles_Debug {
|
7 |
+
|
8 |
+
public function __construct() {
|
9 |
+
|
10 |
+
add_action( 'wp_ajax_styles-debug', array( $this, 'wp_ajax_styles_debug' ) );
|
11 |
+
add_action( 'wp_ajax_nopriv_styles-debug', array( $this, 'wp_ajax_styles_debug' ) );
|
12 |
+
|
13 |
+
add_action( 'wp_ajax_styles-functions', array( $this, 'wp_ajax_functions' ) );
|
14 |
+
add_action( 'wp_ajax_nopriv_styles-functions', array( $this, 'wp_ajax_functions' ) );
|
15 |
+
|
16 |
+
add_action( 'wp_ajax_styles-errors', array( $this, 'wp_ajax_errors' ) );
|
17 |
+
add_action( 'wp_ajax_nopriv_styles-errors', array( $this, 'wp_ajax_errors' ) );
|
18 |
+
|
19 |
+
}
|
20 |
+
|
21 |
+
public function wp_ajax_styles_debug() {
|
22 |
+
|
23 |
+
echo $this->settings_table( $this->get_settings() );
|
24 |
+
|
25 |
+
exit;
|
26 |
+
}
|
27 |
+
|
28 |
+
public function settings_table( $settings ) {
|
29 |
+
?>
|
30 |
+
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
|
31 |
+
<style>
|
32 |
+
th { vertical-align: top; font-weight: bold; min-width: 250px;}
|
33 |
+
</style>
|
34 |
+
|
35 |
+
<table>
|
36 |
+
<tr><th>key</th><th>setting</th>
|
37 |
+
|
38 |
+
<?php
|
39 |
+
foreach( $settings as $key => $setting ) {
|
40 |
+
?>
|
41 |
+
<tr>
|
42 |
+
<th><?php echo $key ?></th>
|
43 |
+
<td><pre><?php print_r( $setting ); ?></pre></td>
|
44 |
+
</tr>
|
45 |
+
<?php
|
46 |
+
}
|
47 |
+
echo '</table>';
|
48 |
+
|
49 |
+
}
|
50 |
+
|
51 |
+
public function get_settings() {
|
52 |
+
$settings = array_merge(
|
53 |
+
$this->get_stylesheet_settings(),
|
54 |
+
$this->get_debug_settings(),
|
55 |
+
$this->get_network_settings(),
|
56 |
+
$this->get_plugin_settings(),
|
57 |
+
$this->get_styles_settings()
|
58 |
+
);
|
59 |
+
|
60 |
+
return $settings;
|
61 |
+
}
|
62 |
+
|
63 |
+
public function get_stylesheet_settings() {
|
64 |
+
return array(
|
65 |
+
'stylesheet' => get_stylesheet(),
|
66 |
+
'template' => get_template(),
|
67 |
+
);
|
68 |
+
}
|
69 |
+
|
70 |
+
public function get_debug_settings() {
|
71 |
+
return array(
|
72 |
+
'WPLANG' => WPLANG,
|
73 |
+
'WP_DEBUG' => WP_DEBUG ? 'true' : 'false',
|
74 |
+
'CONCATENATE_SCRIPTS' => CONCATENATE_SCRIPTS ? 'true' : 'false',
|
75 |
+
'SCRIPT_DEBUG' => SCRIPT_DEBUG ? 'true' : 'false',
|
76 |
+
'memory_limit' => ini_get( 'memory_limit' ),
|
77 |
+
'max_execution_time' => ini_get( 'max_execution_time' ),
|
78 |
+
);
|
79 |
+
}
|
80 |
+
|
81 |
+
public function get_network_settings() {
|
82 |
+
$settings['network'] = array(
|
83 |
+
'is_multisite' => is_multisite() ? 'true' : 'false',
|
84 |
+
'SUBDOMAIN_INSTALL' => SUBDOMAIN_INSTALL ? 'true' : 'false',
|
85 |
+
);
|
86 |
+
|
87 |
+
return $settings;
|
88 |
+
}
|
89 |
+
|
90 |
+
public function get_plugin_settings() {
|
91 |
+
return array(
|
92 |
+
'active_plugins' => $this->get_active_plugins(),
|
93 |
+
'mu_plugins' => wp_list_pluck( get_mu_plugins(), 'Name' ),
|
94 |
+
);
|
95 |
+
}
|
96 |
+
|
97 |
+
public function get_styles_settings() {
|
98 |
+
global $wpdb;
|
99 |
+
|
100 |
+
$settings['storm-styles'] = maybe_serialize( get_option( 'storm-styles' ) );
|
101 |
+
|
102 |
+
// Get theme options
|
103 |
+
$query = "SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'storm-styles-%';";
|
104 |
+
$option_keys = $wpdb->get_col( $query );
|
105 |
+
|
106 |
+
foreach ( $option_keys as $option_key ) {
|
107 |
+
$settings[ $option_key ] = maybe_serialize( get_option( $option_key ) );
|
108 |
+
}
|
109 |
+
|
110 |
+
return $settings;
|
111 |
+
}
|
112 |
+
|
113 |
+
public function get_active_plugins() {
|
114 |
+
$all_plugins = apply_filters( 'all_plugins', get_plugins() );
|
115 |
+
$active_plugins = array();
|
116 |
+
|
117 |
+
foreach ( (array) $all_plugins as $plugin_file => $plugin_data ) {
|
118 |
+
if ( is_plugin_active( $plugin_file ) || is_plugin_active_for_network( $plugin_file ) ) {
|
119 |
+
$active_plugins[ $plugin_file ] = $plugin_data;
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
$plugin_names = wp_list_pluck( $all_plugins, 'Name' );
|
124 |
+
$plugin_versions = wp_list_pluck( $all_plugins, 'Version' );
|
125 |
+
|
126 |
+
foreach( $plugin_versions as $key => $version) {
|
127 |
+
$plugin_names[ $key ] .= ' ' . $version;
|
128 |
+
}
|
129 |
+
|
130 |
+
return array_values( $plugin_names );
|
131 |
+
|
132 |
+
}
|
133 |
+
|
134 |
+
public function wp_ajax_functions() {
|
135 |
+
$functions_php = get_stylesheet_directory() . '/functions.php';
|
136 |
+
if ( file_exists( $functions_php ) ) {
|
137 |
+
$functions_php = file_get_contents( $functions_php );
|
138 |
+
}else {
|
139 |
+
$functions_php = false;
|
140 |
+
}
|
141 |
+
|
142 |
+
header( 'Content-Type: text/plain' );
|
143 |
+
echo $functions_php;
|
144 |
+
|
145 |
+
exit;
|
146 |
+
}
|
147 |
+
|
148 |
+
public function wp_ajax_errors() {
|
149 |
+
$error_log = ini_get( 'error_log' );
|
150 |
+
|
151 |
+
if ( file_exists( $error_log ) && is_readable( $error_log ) ) {
|
152 |
+
header( 'Content-Type: text/plain' );
|
153 |
+
|
154 |
+
$file = fopen( $error_log, 'r' );
|
155 |
+
$count = 0;
|
156 |
+
|
157 |
+
while( $count < 200 ) {
|
158 |
+
echo fgets($file);
|
159 |
+
$count++;
|
160 |
+
}
|
161 |
+
|
162 |
+
exit;
|
163 |
+
}
|
164 |
+
|
165 |
+
exit( 'Cannot read error log.' );
|
166 |
+
}
|
167 |
+
|
168 |
+
}
|
classes/styles-font-menu/classes/markdown/License.text
CHANGED
@@ -1,36 +1,36 @@
|
|
1 |
-
PHP Markdown
|
2 |
-
Copyright (c) 2004-2013 Michel Fortin
|
3 |
-
<http://michelf.ca/>
|
4 |
-
All rights reserved.
|
5 |
-
|
6 |
-
Based on Markdown
|
7 |
-
Copyright (c) 2003-2006 John Gruber
|
8 |
-
<http://daringfireball.net/>
|
9 |
-
All rights reserved.
|
10 |
-
|
11 |
-
Redistribution and use in source and binary forms, with or without
|
12 |
-
modification, are permitted provided that the following conditions are
|
13 |
-
met:
|
14 |
-
|
15 |
-
* Redistributions of source code must retain the above copyright notice,
|
16 |
-
this list of conditions and the following disclaimer.
|
17 |
-
|
18 |
-
* Redistributions in binary form must reproduce the above copyright
|
19 |
-
notice, this list of conditions and the following disclaimer in the
|
20 |
-
documentation and/or other materials provided with the distribution.
|
21 |
-
|
22 |
-
* Neither the name "Markdown" nor the names of its contributors may
|
23 |
-
be used to endorse or promote products derived from this software
|
24 |
-
without specific prior written permission.
|
25 |
-
|
26 |
-
This software is provided by the copyright holders and contributors "as
|
27 |
-
is" and any express or implied warranties, including, but not limited
|
28 |
-
to, the implied warranties of merchantability and fitness for a
|
29 |
-
particular purpose are disclaimed. In no event shall the copyright owner
|
30 |
-
or contributors be liable for any direct, indirect, incidental, special,
|
31 |
-
exemplary, or consequential damages (including, but not limited to,
|
32 |
-
procurement of substitute goods or services; loss of use, data, or
|
33 |
-
profits; or business interruption) however caused and on any theory of
|
34 |
-
liability, whether in contract, strict liability, or tort (including
|
35 |
-
negligence or otherwise) arising in any way out of the use of this
|
36 |
-
software, even if advised of the possibility of such damage.
|
1 |
+
PHP Markdown
|
2 |
+
Copyright (c) 2004-2013 Michel Fortin
|
3 |
+
<http://michelf.ca/>
|
4 |
+
All rights reserved.
|
5 |
+
|
6 |
+
Based on Markdown
|
7 |
+
Copyright (c) 2003-2006 John Gruber
|
8 |
+
<http://daringfireball.net/>
|
9 |
+
All rights reserved.
|
10 |
+
|
11 |
+
Redistribution and use in source and binary forms, with or without
|
12 |
+
modification, are permitted provided that the following conditions are
|
13 |
+
met:
|
14 |
+
|
15 |
+
* Redistributions of source code must retain the above copyright notice,
|
16 |
+
this list of conditions and the following disclaimer.
|
17 |
+
|
18 |
+
* Redistributions in binary form must reproduce the above copyright
|
19 |
+
notice, this list of conditions and the following disclaimer in the
|
20 |
+
documentation and/or other materials provided with the distribution.
|
21 |
+
|
22 |
+
* Neither the name "Markdown" nor the names of its contributors may
|
23 |
+
be used to endorse or promote products derived from this software
|
24 |
+
without specific prior written permission.
|
25 |
+
|
26 |
+
This software is provided by the copyright holders and contributors "as
|
27 |
+
is" and any express or implied warranties, including, but not limited
|
28 |
+
to, the implied warranties of merchantability and fitness for a
|
29 |
+
particular purpose are disclaimed. In no event shall the copyright owner
|
30 |
+
or contributors be liable for any direct, indirect, incidental, special,
|
31 |
+
exemplary, or consequential damages (including, but not limited to,
|
32 |
+
procurement of substitute goods or services; loss of use, data, or
|
33 |
+
profits; or business interruption) however caused and on any theory of
|
34 |
+
liability, whether in contract, strict liability, or tort (including
|
35 |
+
negligence or otherwise) arising in any way out of the use of this
|
36 |
+
software, even if advised of the possibility of such damage.
|
classes/styles-font-menu/classes/markdown/License.txt
CHANGED
@@ -1,36 +1,36 @@
|
|
1 |
-
PHP Markdown & Extra
|
2 |
-
Copyright (c) 2004-2013 Michel Fortin
|
3 |
-
<http://michelf.ca/>
|
4 |
-
All rights reserved.
|
5 |
-
|
6 |
-
Based on Markdown
|
7 |
-
Copyright (c) 2003-2006 John Gruber
|
8 |
-
<http://daringfireball.net/>
|
9 |
-
All rights reserved.
|
10 |
-
|
11 |
-
Redistribution and use in source and binary forms, with or without
|
12 |
-
modification, are permitted provided that the following conditions are
|
13 |
-
met:
|
14 |
-
|
15 |
-
* Redistributions of source code must retain the above copyright notice,
|
16 |
-
this list of conditions and the following disclaimer.
|
17 |
-
|
18 |
-
* Redistributions in binary form must reproduce the above copyright
|
19 |
-
notice, this list of conditions and the following disclaimer in the
|
20 |
-
documentation and/or other materials provided with the distribution.
|
21 |
-
|
22 |
-
* Neither the name "Markdown" nor the names of its contributors may
|
23 |
-
be used to endorse or promote products derived from this software
|
24 |
-
without specific prior written permission.
|
25 |
-
|
26 |
-
This software is provided by the copyright holders and contributors "as
|
27 |
-
is" and any express or implied warranties, including, but not limited
|
28 |
-
to, the implied warranties of merchantability and fitness for a
|
29 |
-
particular purpose are disclaimed. In no event shall the copyright owner
|
30 |
-
or contributors be liable for any direct, indirect, incidental, special,
|
31 |
-
exemplary, or consequential damages (including, but not limited to,
|
32 |
-
procurement of substitute goods or services; loss of use, data, or
|
33 |
-
profits; or business interruption) however caused and on any theory of
|
34 |
-
liability, whether in contract, strict liability, or tort (including
|
35 |
-
negligence or otherwise) arising in any way out of the use of this
|
36 |
-
software, even if advised of the possibility of such damage.
|
1 |
+
PHP Markdown & Extra
|
2 |
+
Copyright (c) 2004-2013 Michel Fortin
|
3 |
+
<http://michelf.ca/>
|
4 |
+
All rights reserved.
|
5 |
+
|
6 |
+
Based on Markdown
|
7 |
+
Copyright (c) 2003-2006 John Gruber
|
8 |
+
<http://daringfireball.net/>
|
9 |
+
All rights reserved.
|
10 |
+
|
11 |
+
Redistribution and use in source and binary forms, with or without
|
12 |
+
modification, are permitted provided that the following conditions are
|
13 |
+
met:
|
14 |
+
|
15 |
+
* Redistributions of source code must retain the above copyright notice,
|
16 |
+
this list of conditions and the following disclaimer.
|
17 |
+
|
18 |
+
* Redistributions in binary form must reproduce the above copyright
|
19 |
+
notice, this list of conditions and the following disclaimer in the
|
20 |
+
documentation and/or other materials provided with the distribution.
|
21 |
+
|
22 |
+
* Neither the name "Markdown" nor the names of its contributors may
|
23 |
+
be used to endorse or promote products derived from this software
|
24 |
+
without specific prior written permission.
|
25 |
+
|
26 |
+
This software is provided by the copyright holders and contributors "as
|
27 |
+
is" and any express or implied warranties, including, but not limited
|
28 |
+
to, the implied warranties of merchantability and fitness for a
|
29 |
+
particular purpose are disclaimed. In no event shall the copyright owner
|
30 |
+
or contributors be liable for any direct, indirect, incidental, special,
|
31 |
+
exemplary, or consequential damages (including, but not limited to,
|
32 |
+
procurement of substitute goods or services; loss of use, data, or
|
33 |
+
profits; or business interruption) however caused and on any theory of
|
34 |
+
liability, whether in contract, strict liability, or tort (including
|
35 |
+
negligence or otherwise) arising in any way out of the use of this
|
36 |
+
software, even if advised of the possibility of such damage.
|
classes/styles-font-menu/classes/markdown/PHP Markdown Extra Readme.txt
CHANGED
@@ -1,879 +1,879 @@
|
|
1 |
-
PHP Markdown Extra
|
2 |
-
==================
|
3 |
-
|
4 |
-
Version 1.2.7 - 11 Apr 2013
|
5 |
-
|
6 |
-
by Michel Fortin
|
7 |
-
<http://michelf.ca/>
|
8 |
-
|
9 |
-
based on Markdown by John Gruber
|
10 |
-
<http://daringfireball.net/>
|
11 |
-
|
12 |
-
|
13 |
-
Introduction
|
14 |
-
------------
|
15 |
-
|
16 |
-
This is a special version of PHP Markdown with extra features. See
|
17 |
-
<http://michelf.com/projects/php-markdown/extra/> for details.
|
18 |
-
|
19 |
-
Markdown is a text-to-HTML conversion tool for web writers. Markdown
|
20 |
-
allows you to write using an easy-to-read, easy-to-write plain text
|
21 |
-
format, then convert it to structurally valid XHTML (or HTML).
|
22 |
-
|
23 |
-
"Markdown" is two things: a plain text markup syntax, and a software
|
24 |
-
tool, written in Perl, that converts the plain text markup to HTML.
|
25 |
-
PHP Markdown is a port to PHP of the original Markdown program by
|
26 |
-
John Gruber.
|
27 |
-
|
28 |
-
PHP Markdown can work as a plug-in for WordPress, as a modifier for
|
29 |
-
the Smarty templating engine, or as a replacement for Textile
|
30 |
-
formatting in any software that supports Textile.
|
31 |
-
|
32 |
-
Full documentation of Markdown's syntax is available on John's
|
33 |
-
Markdown page: <http://daringfireball.net/projects/markdown/>
|
34 |
-
|
35 |
-
|
36 |
-
Installation and Requirement
|
37 |
-
----------------------------
|
38 |
-
|
39 |
-
PHP Markdown requires PHP version 4.0.5 or later.
|
40 |
-
|
41 |
-
Before PHP 5.3.7, pcre.backtrack_limit defaults to 100 000, which is too small
|
42 |
-
in many situations. You might need to set it to higher values. Later PHP
|
43 |
-
releases defaults to 1 000 000, which is usually fine.
|
44 |
-
|
45 |
-
|
46 |
-
### WordPress ###
|
47 |
-
|
48 |
-
PHP Markdown works with [WordPress][wp], version 1.2 or later.
|
49 |
-
|
50 |
-
[wp]: http://wordpress.org/
|
51 |
-
|
52 |
-
1. To use PHP Markdown with WordPress, place the "markdown.php" file
|
53 |
-
in the "plugins" folder. This folder is located inside
|
54 |
-
"wp-content" at the root of your site:
|
55 |
-
|
56 |
-
(site home)/wp-content/plugins/
|
57 |
-
|
58 |
-
2. Activate the plugin with the administrative interface of
|
59 |
-
WordPress. In the "Plugins" section you will now find Markdown.
|
60 |
-
To activate the plugin, click on the "Activate" button on the
|
61 |
-
same line as Markdown. Your entries will now be formatted by
|
62 |
-
PHP Markdown.
|
63 |
-
|
64 |
-
3. To post Markdown content, you'll first have to disable the
|
65 |
-
"visual" editor in the User section of WordPress.
|
66 |
-
|
67 |
-
You can configure PHP Markdown to not apply to the comments on your
|
68 |
-
WordPress weblog. See the "Configuration" section below.
|
69 |
-
|
70 |
-
It is not possible at this time to apply a different set of
|
71 |
-
filters to different entries. All your entries will be formatted by
|
72 |
-
PHP Markdown. This is a limitation of WordPress. If your old entries
|
73 |
-
are written in HTML (as opposed to another formatting syntax, like
|
74 |
-
Textile), they'll probably stay fine after installing Markdown.
|
75 |
-
|
76 |
-
|
77 |
-
### Replacing Textile in TextPattern ###
|
78 |
-
|
79 |
-
[TextPattern][tp] use [Textile][tx] to format your text. You can
|
80 |
-
replace Textile by Markdown in TextPattern without having to change
|
81 |
-
any code by using the *Textile Compatibility Mode*. This may work
|
82 |
-
with other software that expect Textile too.
|
83 |
-
|
84 |
-
[tx]: http://www.textism.com/tools/textile/
|
85 |
-
[tp]: http://www.textpattern.com/
|
86 |
-
|
87 |
-
1. Rename the "markdown.php" file to "classTextile.php". This will
|
88 |
-
make PHP Markdown behave as if it was the actual Textile parser.
|
89 |
-
|
90 |
-
2. Replace the "classTextile.php" file TextPattern installed in your
|
91 |
-
web directory. It can be found in the "lib" directory:
|
92 |
-
|
93 |
-
(site home)/textpattern/lib/
|
94 |
-
|
95 |
-
Contrary to Textile, Markdown does not convert quotes to curly ones
|
96 |
-
and does not convert multiple hyphens (`--` and `---`) into en- and
|
97 |
-
em-dashes. If you use PHP Markdown in Textile Compatibility Mode, you
|
98 |
-
can solve this problem by installing the "smartypants.php" file from
|
99 |
-
[PHP SmartyPants][psp] beside the "classTextile.php" file. The Textile
|
100 |
-
Compatibility Mode function will use SmartyPants automatically without
|
101 |
-
further modification.
|
102 |
-
|
103 |
-
[psp]: http://michelf.ca/projects/php-smartypants/
|
104 |
-
|
105 |
-
|
106 |
-
### In Your Own Programs ###
|
107 |
-
|
108 |
-
You can use PHP Markdown easily in your current PHP program. Simply
|
109 |
-
include the file and then call the Markdown function on the text you
|
110 |
-
want to convert:
|
111 |
-
|
112 |
-
include_once "markdown.php";
|
113 |
-
$my_html = Markdown($my_text);
|
114 |
-
|
115 |
-
If you wish to use PHP Markdown with another text filter function
|
116 |
-
built to parse HTML, you should filter the text *after* the Markdown
|
117 |
-
function call. This is an example with [PHP SmartyPants][psp]:
|
118 |
-
|
119 |
-
$my_html = SmartyPants(Markdown($my_text));
|
120 |
-
|
121 |
-
|
122 |
-
### With Smarty ###
|
123 |
-
|
124 |
-
If your program use the [Smarty][sm] template engine, PHP Markdown
|
125 |
-
can now be used as a modifier for your templates. Rename "markdown.php"
|
126 |
-
to "modifier.markdown.php" and put it in your smarty plugins folder.
|
127 |
-
|
128 |
-
[sm]: http://smarty.php.net/
|
129 |
-
|
130 |
-
If you are using MovableType 3.1 or later, the Smarty plugin folder is
|
131 |
-
located at `(MT CGI root)/php/extlib/smarty/plugins`. This will allow
|
132 |
-
Markdown to work on dynamic pages.
|
133 |
-
|
134 |
-
|
135 |
-
### Updating Markdown in Other Programs ###
|
136 |
-
|
137 |
-
Many web applications now ship with PHP Markdown, or have plugins to
|
138 |
-
perform the conversion to HTML. You can update PHP Markdown -- or
|
139 |
-
replace it with PHP Markdown Extra -- in many of these programs by
|
140 |
-
swapping the old "markdown.php" file for the new one.
|
141 |
-
|
142 |
-
Here is a short non-exhaustive list of some programs and where they
|
143 |
-
hide the "markdown.php" file.
|
144 |
-
|
145 |
-
| Program | Path to Markdown
|
146 |
-
| ------- | ----------------
|
147 |
-
| [Pivot][] | `(site home)/pivot/includes/markdown/`
|
148 |
-
|
149 |
-
If you're unsure if you can do this with your application, ask the
|
150 |
-
developer, or wait for the developer to update his application or
|
151 |
-
plugin with the new version of PHP Markdown.
|
152 |
-
|
153 |
-
[Pivot]: http://pivotlog.net/
|
154 |
-
|
155 |
-
|
156 |
-
Configuration
|
157 |
-
-------------
|
158 |
-
|
159 |
-
By default, PHP Markdown produces XHTML output for tags with empty
|
160 |
-
elements. E.g.:
|
161 |
-
|
162 |
-
<br />
|
163 |
-
|
164 |
-
Markdown can be configured to produce HTML-style tags; e.g.:
|
165 |
-
|
166 |
-
<br>
|
167 |
-
|
168 |
-
To do this, you must edit the "MARKDOWN_EMPTY_ELEMENT_SUFFIX"
|
169 |
-
definition below the "Global default settings" header at the start of
|
170 |
-
the "markdown.php" file.
|
171 |
-
|
172 |
-
|
173 |
-
### WordPress-Specific Settings ###
|
174 |
-
|
175 |
-
By default, the Markdown plugin applies to both posts and comments on
|
176 |
-
your WordPress weblog. To deactivate one or the other, edit the
|
177 |
-
`MARKDOWN_WP_POSTS` or `MARKDOWN_WP_COMMENTS` definitions under the
|
178 |
-
"WordPress settings" header at the start of the "markdown.php" file.
|
179 |
-
|
180 |
-
|
181 |
-
Bugs
|
182 |
-
----
|
183 |
-
|
184 |
-
To file bug reports please send email to:
|
185 |
-
<michel.fortin@michelf.ca>
|
186 |
-
|
187 |
-
Please include with your report: (1) the example input; (2) the output you
|
188 |
-
expected; (3) the output PHP Markdown actually produced.
|
189 |
-
|
190 |
-
If you have a problem where Markdown gives you an empty result, first check
|
191 |
-
that the backtrack limit is not too low by running `php --info | grep pcre`.
|
192 |
-
See Installation and Requirement above for details.
|
193 |
-
|
194 |
-
|
195 |
-
Version History
|
196 |
-
---------------
|
197 |
-
|
198 |
-
Extra 1.2.7 (11 Apr 2013):
|
199 |
-
|
200 |
-
* Added optional class and id attributes to images and links using the same
|
201 |
-
syntax as for headers:
|
202 |
-
|
203 |
-
[link](url){#id .class}
|
204 |
-
![img](url){#id .class}
|
205 |
-
|
206 |
-
It work too for reference-style links and images. In this case you need
|
207 |
-
to put those attributes at the reference definition:
|
208 |
-
|
209 |
-
[link][linkref] or [linkref]
|
210 |
-
![img][linkref]
|
211 |
-
|
212 |
-
[linkref]: url "optional title" {#id .class}
|
213 |
-
|
214 |
-
* Fixed a PHP notice message triggered when some table column separator
|
215 |
-
markers are missing on the separator line below column headers.
|
216 |
-
|
217 |
-
|
218 |
-
1.0.1q (11 Apr 2013):
|
219 |
-
|
220 |
-
* Fixed a small mistake that could cause the parser to retain an invalid
|
221 |
-
state related to parsing links across multiple runs. This was never
|
222 |
-
observed (that I know of), but it's still worth fixing.
|
223 |
-
|
224 |
-
|
225 |
-
Extra 1.2.6 (13 Jan 2013):
|
226 |
-
|
227 |
-
* Headers can now have a class attribute. You can add a class inside the
|
228 |
-
extra attribute block which can optionally be put after a header:
|
229 |
-
|
230 |
-
### Header ### {#id .class1 .class2}
|
231 |
-
|
232 |
-
Spaces between components in the brace is optional.
|
233 |
-
|
234 |
-
* Fenced code blocks can also have a class and an id attribute. If you only
|
235 |
-
need to apply a class (typically to indicate the language of a code
|
236 |
-
snippet), you can write it like this:
|
237 |
-
|
238 |
-
~~~ html
|
239 |
-
<b>bold</b>
|
240 |
-
~~~
|
241 |
-
|
242 |
-
or like this:
|
243 |
-
|
244 |
-
~~~ .html
|
245 |
-
<b>bold</b>
|
246 |
-
~~~
|
247 |
-
|
248 |
-
There is a new configuration option `MARKDOWN_CODE_CLASS_PREFIX` you can
|
249 |
-
use if you need to append a prefix to the class name.
|
250 |
-
|
251 |
-
You might also opt to use an extra attribute block just like for headers:
|
252 |
-
|
253 |
-
~~~ {.html #id .codeclass}
|
254 |
-
<b>bold</b>
|
255 |
-
~~~
|
256 |
-
|
257 |
-
Note that class names added this way are not affected by the
|
258 |
-
MARKDOWN_CODE_CLASS_PREFIX.
|
259 |
-
|
260 |
-
A code block creates a `pre` HTML element containing a `code` element.
|
261 |
-
The `code` HTML element is the one that receives the attribute. If for
|
262 |
-
some reason you need attributes to be applied to the enclosing `pre`
|
263 |
-
element instead, you can set the MARKDOWN_CODE_ATTR_ON_PRE configuration
|
264 |
-
variable to true.
|
265 |
-
|
266 |
-
* Fixed an issue were consecutive fenced code blocks containing HTML-like
|
267 |
-
code would confuse the parser.
|
268 |
-
|
269 |
-
* Multiple references to the same footnote are now allowed.
|
270 |
-
|
271 |
-
* Fixed an issue where no_markup mode was ineffective.
|
272 |
-
|
273 |
-
|
274 |
-
1.0.1p (13 Jan 2013):
|
275 |
-
|
276 |
-
* Fixed an issue where some XML-style empty tags (such as `<br/>`) were not
|
277 |
-
recognized correctly as such when inserted into Markdown-formatted text.
|
278 |
-
|
279 |
-
* The following HTML 5 elements are treated as block elements when at the
|
280 |
-
root of an HTML block: `article`, `section`, `nav`, `aside`, `hgroup`,
|
281 |
-
`header`, `footer`, and `figure`. `svg` too.
|
282 |
-
|
283 |
-
|
284 |
-
1.0.1o (8 Jan 2012):
|
285 |
-
|
286 |
-
* Silenced a new warning introduced around PHP 5.3 complaining about
|
287 |
-
POSIX characters classes not being implemented. PHP Markdown does not
|
288 |
-
use POSIX character classes, but it nevertheless trigged that warning.
|
289 |
-
|
290 |
-
|
291 |
-
Extra 1.2.5 (8 Jan 2012):
|
292 |
-
|
293 |
-
* Fixed an issue preventing fenced code blocks indented inside lists items
|
294 |
-
and elsewhere from being interpreted correctly.
|
295 |
-
|
296 |
-
* Fixed an issue where HTML tags inside fenced code blocks were sometime
|
297 |
-
not encoded with entities.
|
298 |
-
|
299 |
-
|
300 |
-
1.0.1n (10 Oct 2009):
|
301 |
-
|
302 |
-
* Enabled reference-style shortcut links. Now you can write reference-style
|
303 |
-
links with less brakets:
|
304 |
-
|
305 |
-
This is [my website].
|
306 |
-
|
307 |
-
[my website]: http://example.com/
|
308 |
-
|
309 |
-
This was added in the 1.0.2 betas, but commented out in the 1.0.1 branch,
|
310 |
-
waiting for the feature to be officialized. [But half of the other Markdown
|
311 |
-
implementations are supporting this syntax][half], so it makes sense for
|
312 |
-
compatibility's sake to allow it in PHP Markdown too.
|
313 |
-
|
314 |
-
[half]: http://babelmark.bobtfish.net/?markdown=This+is+%5Bmy+website%5D.%0D%0A%09%09%0D%0A%5Bmy+website%5D%3A+http%3A%2F%2Fexample.com%2F%0D%0A&src=1&dest=2
|
315 |
-
|
316 |
-
* Now accepting many valid email addresses in autolinks that were
|
317 |
-
previously rejected, such as:
|
318 |
-
|
319 |
-
<abc+mailbox/department=shipping@example.com>
|
320 |
-
<!#$%&'*+-/=?^_`.{|}~@example.com>
|
321 |
-
<"abc@def"@example.com>
|
322 |
-
<"Fred Bloggs"@example.com>
|
323 |
-
<jsmith@[192.0.2.1]>
|
324 |
-
|
325 |
-
* Now accepting spaces in URLs for inline and reference-style links. Such
|
326 |
-
URLs need to be surrounded by angle brakets. For instance:
|
327 |
-
|
328 |
-
[link text](<http://url/with space> "optional title")
|
329 |
-
|
330 |
-
[link text][ref]
|
331 |
-
[ref]: <http://url/with space> "optional title"
|
332 |
-
|
333 |
-
There is still a quirk which may prevent this from working correctly with
|
334 |
-
relative URLs in inline-style links however.
|
335 |
-
|
336 |
-
* Fix for adjacent list of different kind where the second list could
|
337 |
-
end as a sublist of the first when not separated by an empty line.
|
338 |
-
|
339 |
-
* Fixed a bug where inline-style links wouldn't be recognized when the link
|
340 |
-
definition contains a line break between the url and the title.
|
341 |
-
|
342 |
-
* Fixed a bug where tags where the name contains an underscore aren't parsed
|
343 |
-
correctly.
|
344 |
-
|
345 |
-
* Fixed some corner-cases mixing underscore-ephasis and asterisk-emphasis.
|
346 |
-
|
347 |
-
|
348 |
-
Extra 1.2.4 (10 Oct 2009):
|
349 |
-
|
350 |
-
* Fixed a problem where unterminated tags in indented code blocks could
|
351 |
-
prevent proper escaping of characaters in the code block.
|
352 |
-
|
353 |
-
|
354 |
-
Extra 1.2.3 (31 Dec 2008):
|
355 |
-
|
356 |
-
* In WordPress pages featuring more than one post, footnote id prefixes are
|
357 |
-
now automatically applied with the current post ID to avoid clashes
|
358 |
-
between footnotes belonging to different posts.
|
359 |
-
|
360 |
-
* Fix for a bug introduced in Extra 1.2 where block-level HTML tags where
|
361 |
-
not detected correctly, thus the addition of erroneous `<p>` tags and
|
362 |
-
interpretation of their content as Markdown-formatted instead of
|
363 |
-
HTML-formatted.
|
364 |
-
|
365 |
-
|
366 |
-
Extra 1.2.2 (21 Jun 2008):
|
367 |
-
|
368 |
-
* Fixed a problem where abbreviation definitions, footnote
|
369 |
-
definitions and link references were stripped inside
|
370 |
-
fenced code blocks.
|
371 |
-
|
372 |
-
* Fixed a bug where characters such as `"` in abbreviation
|
373 |
-
definitions weren't properly encoded to HTML entities.
|
374 |
-
|
375 |
-
* Fixed a bug where double quotes `"` were not correctly encoded
|
376 |
-
as HTML entities when used inside a footnote reference id.
|
377 |
-
|
378 |
-
|
379 |
-
1.0.1m (21 Jun 2008):
|
380 |
-
|
381 |
-
* Lists can now have empty items.
|
382 |
-
|
383 |
-
* Rewrote the emphasis and strong emphasis parser to fix some issues
|
384 |
-
with odly placed and overlong markers.
|
385 |
-
|
386 |
-
|
387 |
-
Extra 1.2.1 (27 May 2008):
|
388 |
-
|
389 |
-
* Fixed a problem where Markdown headers and horizontal rules were
|
390 |
-
transformed into their HTML equivalent inside fenced code blocks.
|
391 |
-
|
392 |
-
|
393 |
-
Extra 1.2 (11 May 2008):
|
394 |
-
|
395 |
-
* Added fenced code block syntax which don't require indentation
|
396 |
-
and can start and end with blank lines. A fenced code block
|
397 |
-
starts with a line of consecutive tilde (~) and ends on the
|
398 |
-
next line with the same number of consecutive tilde. Here's an
|
399 |
-
example:
|
400 |
-
|
401 |
-
~~~~~~~~~~~~
|
402 |
-
Hello World!
|
403 |
-
~~~~~~~~~~~~
|
404 |
-
|
405 |
-
* Rewrote parts of the HTML block parser to better accomodate
|
406 |
-
fenced code blocks.
|
407 |
-
|
408 |
-
* Footnotes may now be referenced from within another footnote.
|
409 |
-
|
410 |
-
* Added programatically-settable parser property `predef_attr` for
|
411 |
-
predefined attribute definitions.
|
412 |
-
|
413 |
-
* Fixed an issue where an indented code block preceded by a blank
|
414 |
-
line containing some other whitespace would confuse the HTML
|
415 |
-
block parser into creating an HTML block when it should have
|
416 |
-
been code.
|
417 |
-
|
418 |
-
|
419 |
-
1.0.1l (11 May 2008):
|
420 |
-
|
421 |
-
* Now removing the UTF-8 BOM at the start of a document, if present.
|
422 |
-
|
423 |
-
* Now accepting capitalized URI schemes (such as HTTP:) in automatic
|
424 |
-
links, such as `<HTTP://EXAMPLE.COM/>`.
|
425 |
-
|
426 |
-
* Fixed a problem where `<hr@example.com>` was seen as a horizontal
|
427 |
-
rule instead of an automatic link.
|
428 |
-
|
429 |
-
* Fixed an issue where some characters in Markdown-generated HTML
|
430 |
-
attributes weren't properly escaped with entities.
|
431 |
-
|
432 |
-
* Fix for code blocks as first element of a list item. Previously,
|
433 |
-
this didn't create any code block for item 2:
|
434 |
-
|
435 |
-
* Item 1 (regular paragraph)
|
436 |
-
|
437 |
-
* Item 2 (code block)
|
438 |
-
|
439 |
-
* A code block starting on the second line of a document wasn't seen
|
440 |
-
as a code block. This has been fixed.
|
441 |
-
|
442 |
-
* Added programatically-settable parser properties `predef_urls` and
|
443 |
-
`predef_titles` for predefined URLs and titles for reference-style
|
444 |
-
links. To use this, your PHP code must call the parser this way:
|
445 |
-
|
446 |
-
$parser = new Markdwon_Parser;
|
447 |
-
$parser->predef_urls = array('linkref' => 'http://example.com');
|
448 |
-
$html = $parser->transform($text);
|
449 |
-
|
450 |
-
You can then use the URL as a normal link reference:
|
451 |
-
|
452 |
-
[my link][linkref]
|
453 |
-
[my link][linkRef]
|
454 |
-
|
455 |
-
Reference names in the parser properties *must* be lowercase.
|
456 |
-
Reference names in the Markdown source may have any case.
|
457 |
-
|
458 |
-
* Added `setup` and `teardown` methods which can be used by subclassers
|
459 |
-
as hook points to arrange the state of some parser variables before and
|
460 |
-
after parsing.
|
461 |
-
|
462 |
-
|
463 |
-
Extra 1.1.7 (26 Sep 2007):
|
464 |
-
|
465 |
-
1.0.1k (26 Sep 2007):
|
466 |
-
|
467 |
-
* Fixed a problem introduced in 1.0.1i where three or more identical
|
468 |
-
uppercase letters, as well as a few other symbols, would trigger
|
469 |
-
a horizontal line.
|
470 |
-
|
471 |
-
|
472 |
-
Extra 1.1.6 (4 Sep 2007):
|
473 |
-
|
474 |
-
1.0.1j (4 Sep 2007):
|
475 |
-
|
476 |
-
* Fixed a problem introduced in 1.0.1i where the closing `code` and
|
477 |
-
`pre` tags at the end of a code block were appearing in the wrong
|
478 |
-
order.
|
479 |
-
|
480 |
-
* Overriding configuration settings by defining constants from an
|
481 |
-
external before markdown.php is included is now possible without
|
482 |
-
producing a PHP warning.
|
483 |
-
|
484 |
-
|
485 |
-
Extra 1.1.5 (31 Aug 2007):
|
486 |
-
|
487 |
-
1.0.1i (31 Aug 2007):
|
488 |
-
|
489 |
-
* Fixed a problem where an escaped backslash before a code span
|
490 |
-
would prevent the code span from being created. This should now
|
491 |
-
work as expected:
|
492 |
-
|
493 |
-
Litteral backslash: \\`code span`
|
494 |
-
|
495 |
-
* Overall speed improvements, especially with long documents.
|
496 |
-
|
497 |
-
|
498 |
-
Extra 1.1.4 (3 Aug 2007):
|
499 |
-
|
500 |
-
1.0.1h (3 Aug 2007):
|
501 |
-
|
502 |
-
* Added two properties (`no_markup` and `no_entities`) to the parser
|
503 |
-
allowing HTML tags and entities to be disabled.
|
504 |
-
|
505 |
-
* Fix for a problem introduced in 1.0.1g where posting comments in
|
506 |
-
WordPress would trigger PHP warnings and cause some markup to be
|
507 |
-
incorrectly filtered by the kses filter in WordPress.
|
508 |
-
|
509 |
-
|
510 |
-
Extra 1.1.3 (3 Jul 2007):
|
511 |
-
|
512 |
-
* Fixed a performance problem when parsing some invalid HTML as an HTML
|
513 |
-
block which was resulting in too much recusion and a segmentation fault
|
514 |
-
for long documents.
|
515 |
-
|
516 |
-
* The markdown="" attribute now accepts unquoted values.
|
517 |
-
|
518 |
-
* Fixed an issue where underscore-emphasis didn't work when applied on the
|
519 |
-
first or the last word of an element having the markdown="1" or
|
520 |
-
markdown="span" attribute set unless there was some surrounding whitespace.
|
521 |
-
This didn't work:
|
522 |
-
|
523 |
-
<p markdown="1">_Hello_ _world_</p>
|
524 |
-
|
525 |
-
Now it does produce emphasis as expected.
|
526 |
-
|
527 |
-
* Fixed an issue preventing footnotes from working when the parser's
|
528 |
-
footnote id prefix variable (fn_id_prefix) is not empty.
|
529 |
-
|
530 |
-
* Fixed a performance problem where the regular expression for strong
|
531 |
-
emphasis introduced in version 1.1 could sometime be long to process,
|
532 |
-
give slightly wrong results, and in some circumstances could remove
|
533 |
-
entirely the content for a whole paragraph.
|
534 |
-
|
535 |
-
* Fixed an issue were abbreviations tags could be incorrectly added
|
536 |
-
inside URLs and title of links.
|
537 |
-
|
538 |
-
* Placing footnote markers inside a link, resulting in two nested links, is
|
539 |
-
no longer allowed.
|
540 |
-
|
541 |
-
|
542 |
-
1.0.1g (3 Jul 2007):
|
543 |
-
|
544 |
-
* Fix for PHP 5 compiled without the mbstring module. Previous fix to
|
545 |
-
calculate the length of UTF-8 strings in `detab` when `mb_strlen` is
|
546 |
-
not available was only working with PHP 4.
|
547 |
-
|
548 |
-
* Fixed a problem with WordPress 2.x where full-content posts in RSS feeds
|
549 |
-
were not processed correctly by Markdown.
|
550 |
-
|
551 |
-
* Now supports URLs containing literal parentheses for inline links
|
552 |
-
and images, such as:
|
553 |
-
|
554 |
-
[WIMP](http://en.wikipedia.org/wiki/WIMP_(computing))
|
555 |
-
|
556 |
-
Such parentheses may be arbitrarily nested, but must be
|
557 |
-
balanced. Unbalenced parentheses are allowed however when the URL
|
558 |
-
when escaped or when the URL is enclosed in angle brakets `<>`.
|
559 |
-
|
560 |
-
* Fixed a performance problem where the regular expression for strong
|
561 |
-
emphasis introduced in version 1.0.1d could sometime be long to process,
|
562 |
-
give slightly wrong results, and in some circumstances could remove
|
563 |
-
entirely the content for a whole paragraph.
|
564 |
-
|
565 |
-
* Some change in version 1.0.1d made possible the incorrect nesting of
|
566 |
-
anchors within each other. This is now fixed.
|
567 |
-
|
568 |
-
* Fixed a rare issue where certain MD5 hashes in the content could
|
569 |
-
be changed to their corresponding text. For instance, this:
|
570 |
-
|
571 |
-
The MD5 value for "+" is "26b17225b626fb9238849fd60eabdf60".
|
572 |
-
|
573 |
-
was incorrectly changed to this in previous versions of PHP Markdown:
|
574 |
-
|
575 |
-
<p>The MD5 value for "+" is "+".</p>
|
576 |
-
|
577 |
-
* Now convert escaped characters to their numeric character
|
578 |
-
references equivalent.
|
579 |
-
|
580 |
-
This fix an integration issue with SmartyPants and backslash escapes.
|
581 |
-
Since Markdown and SmartyPants have some escapable characters in common,
|
582 |
-
it was sometime necessary to escape them twice. Previously, two
|
583 |
-
backslashes were sometime required to prevent Markdown from "eating" the
|
584 |
-
backslash before SmartyPants sees it:
|
585 |
-
|
586 |
-
Here are two hyphens: \\--
|
587 |
-
|
588 |
-
Now, only one backslash will do:
|
589 |
-
|
590 |
-
Here are two hyphens: \--
|
591 |
-
|
592 |
-
|
593 |
-
Extra 1.1.2 (7 Feb 2007)
|
594 |
-
|
595 |
-
* Fixed an issue where headers preceded too closely by a paragraph
|
596 |
-
(with no blank line separating them) where put inside the paragraph.
|
597 |
-
|
598 |
-
* Added the missing TextileRestricted method that was added to regular
|
599 |
-
PHP Markdown since 1.0.1d but which I forgot to add to Extra.
|
600 |
-
|
601 |
-
|
602 |
-
1.0.1f (7 Feb 2007):
|
603 |
-
|
604 |
-
* Fixed an issue with WordPress where manually-entered excerpts, but
|
605 |
-
not the auto-generated ones, would contain nested paragraphs.
|
606 |
-
|
607 |
-
* Fixed an issue introduced in 1.0.1d where headers and blockquotes
|
608 |
-
preceded too closely by a paragraph (not separated by a blank line)
|
609 |
-
where incorrectly put inside the paragraph.
|
610 |
-
|
611 |
-
* Fixed an issue introduced in 1.0.1d in the tokenizeHTML method where
|
612 |
-
two consecutive code spans would be merged into one when together they
|
613 |
-
form a valid tag in a multiline paragraph.
|
614 |
-
|
615 |
-
* Fixed an long-prevailing issue where blank lines in code blocks would
|
616 |
-
be doubled when the code block is in a list item.
|
617 |
-
|
618 |
-
This was due to the list processing functions relying on artificially
|
619 |
-
doubled blank lines to correctly determine when list items should
|
620 |
-
contain block-level content. The list item processing model was thus
|
621 |
-
changed to avoid the need for double blank lines.
|
622 |
-
|
623 |
-
* Fixed an issue with `<% asp-style %>` instructions used as inline
|
624 |
-
content where the opening `<` was encoded as `<`.
|
625 |
-
|
626 |
-
* Fixed a parse error occuring when PHP is configured to accept
|
627 |
-
ASP-style delimiters as boundaries for PHP scripts.
|
628 |
-
|
629 |
-
* Fixed a bug introduced in 1.0.1d where underscores in automatic links
|
630 |
-
got swapped with emphasis tags.
|
631 |
-
|
632 |
-
|
633 |
-
Extra 1.1.1 (28 Dec 2006)
|
634 |
-
|
635 |
-
* Fixed a problem where whitespace at the end of the line of an atx-style
|
636 |
-
header would cause tailing `#` to appear as part of the header's content.
|
637 |
-
This was caused by a small error in the regex that handles the definition
|
638 |
-
for the id attribute in PHP Markdown Extra.
|
639 |
-
|
640 |
-
* Fixed a problem where empty abbreviations definitions would eat the
|
641 |
-
following line as its definition.
|
642 |
-
|
643 |
-
* Fixed an issue with calling the Markdown parser repetitivly with text
|
644 |
-
containing footnotes. The footnote hashes were not reinitialized properly.
|
645 |
-
|
646 |
-
|
647 |
-
1.0.1e (28 Dec 2006)
|
648 |
-
|
649 |
-
* Added support for internationalized domain names for email addresses in
|
650 |
-
automatic link. Improved the speed at which email addresses are converted
|
651 |
-
to entities. Thanks to Milian Wolff for his optimisations.
|
652 |
-
|
653 |
-
* Made deterministic the conversion to entities of email addresses in
|
654 |
-
automatic links. This means that a given email address will always be
|
655 |
-
encoded the same way.
|
656 |
-
|
657 |
-
* PHP Markdown will now use its own function to calculate the length of an
|
658 |
-
UTF-8 string in `detab` when `mb_strlen` is not available instead of
|
659 |
-
giving a fatal error.
|
660 |
-
|
661 |
-
|
662 |
-
Extra 1.1 (1 Dec 2006)
|
663 |
-
|
664 |
-
* Added a syntax for footnotes.
|
665 |
-
|
666 |
-
* Added an experimental syntax to define abbreviations.
|
667 |
-
|
668 |
-
|
669 |
-
1.0.1d (1 Dec 2006)
|
670 |
-
|
671 |
-
* Fixed a bug where inline images always had an empty title attribute. The
|
672 |
-
title attribute is now present only when explicitly defined.
|
673 |
-
|
674 |
-
* Link references definitions can now have an empty title, previously if the
|
675 |
-
title was defined but left empty the link definition was ignored. This can
|
676 |
-
be useful if you want an empty title attribute in images to hide the
|
677 |
-
tooltip in Internet Explorer.
|
678 |
-
|
679 |
-
* Made `detab` aware of UTF-8 characters. UTF-8 multi-byte sequences are now
|
680 |
-
correctly mapped to one character instead of the number of bytes.
|
681 |
-
|
682 |
-
* Fixed a small bug with WordPress where WordPress' default filter `wpautop`
|
683 |
-
was not properly deactivated on comment text, resulting in hard line breaks
|
684 |
-
where Markdown do not prescribes them.
|
685 |
-
|
686 |
-
* Added a `TextileRestrited` method to the textile compatibility mode. There
|
687 |
-
is no restriction however, as Markdown does not have a restricted mode at
|
688 |
-
this point. This should make PHP Markdown work again in the latest
|
689 |
-
versions of TextPattern.
|
690 |
-
|
691 |
-
* Converted PHP Markdown to a object-oriented design.
|
692 |
-
|
693 |
-
* Changed span and block gamut methods so that they loop over a
|
694 |
-
customizable list of methods. This makes subclassing the parser a more
|
695 |
-
interesting option for creating syntax extensions.
|
696 |
-
|
697 |
-
* Also added a "document" gamut loop which can be used to hook document-level
|
698 |
-
methods (like for striping link definitions).
|
699 |
-
|
700 |
-
* Changed all methods which were inserting HTML code so that they now return
|
701 |
-
a hashed representation of the code. New methods `hashSpan` and `hashBlock`
|
702 |
-
are used to hash respectivly span- and block-level generated content. This
|
703 |
-
has a couple of significant effects:
|
704 |
-
|
705 |
-
1. It prevents invalid nesting of Markdown-generated elements which
|
706 |
-
could occur occuring with constructs like `*something [link*][1]`.
|
707 |
-
2. It prevents problems occuring with deeply nested lists on which
|
708 |
-
paragraphs were ill-formed.
|
709 |
-
3. It removes the need to call `hashHTMLBlocks` twice during the the
|
710 |
-
block gamut.
|
711 |
-
|
712 |
-
Hashes are turned back to HTML prior output.
|
713 |
-
|
714 |
-
* Made the block-level HTML parser smarter using a specially-crafted regular
|
715 |
-
expression capable of handling nested tags.
|
716 |
-
|
717 |
-
* Solved backtick issues in tag attributes by rewriting the HTML tokenizer to
|
718 |
-
be aware of code spans. All these lines should work correctly now:
|
719 |
-
|
720 |
-
<span attr='`ticks`'>bar</span>
|
721 |
-
<span attr='``double ticks``'>bar</span>
|
722 |
-
`<test a="` content of attribute `">`
|
723 |
-
|
724 |
-
* Changed the parsing of HTML comments to match simply from `<!--` to `-->`
|
725 |
-
instead using of the more complicated SGML-style rule with paired `--`.
|
726 |
-
This is how most browsers parse comments and how XML defines them too.
|
727 |
-
|
728 |
-
* `<address>` has been added to the list of block-level elements and is now
|
729 |
-
treated as an HTML block instead of being wrapped within paragraph tags.
|
730 |
-
|
731 |
-
* Now only trim trailing newlines from code blocks, instead of trimming
|
732 |
-
all trailing whitespace characters.
|
733 |
-
|
734 |
-
* Fixed bug where this:
|
735 |
-
|
736 |
-
[text](http://m.com "title" )
|
737 |
-
|
738 |
-
wasn't working as expected, because the parser wasn't allowing for spaces
|
739 |
-
before the closing paren.
|
740 |
-
|
741 |
-
* Filthy hack to support markdown='1' in div tags.
|
742 |
-
|
743 |
-
* _DoAutoLinks() now supports the 'dict://' URL scheme.
|
744 |
-
|
745 |
-
* PHP- and ASP-style processor instructions are now protected as
|
746 |
-
raw HTML blocks.
|
747 |
-
|
748 |
-
<? ... ?>
|
749 |
-
<% ... %>
|
750 |
-
|
751 |
-
* Fix for escaped backticks still triggering code spans:
|
752 |
-
|
753 |
-
There are two raw backticks here: \` and here: \`, not a code span
|
754 |
-
|
755 |
-
|
756 |
-
Extra 1.0 - 5 September 2005
|
757 |
-
|
758 |
-
* Added support for setting the id attributes for headers like this:
|
759 |
-
|
760 |
-
Header 1 {#header1}
|
761 |
-
========
|
762 |
-
|
763 |
-
## Header 2 ## {#header2}
|
764 |
-
|
765 |
-
This only work only for headers for now.
|
766 |
-
|
767 |
-
* Tables will now work correctly as the first element of a definition
|
768 |
-
list. For example, this input:
|
769 |
-
|
770 |
-
Term
|
771 |
-
|
772 |
-
: Header | Header
|
773 |
-
------- | -------
|
774 |
-
Cell | Cell
|
775 |
-
|
776 |
-
used to produce no definition list and a table where the first
|
777 |
-
header was named ": Header". This is now fixed.
|
778 |
-
|
779 |
-
* Fix for a problem where a paragraph following a table was not
|
780 |
-
placed between `<p>` tags.
|
781 |
-
|
782 |
-
|
783 |
-
Extra 1.0b4 - 1 August 2005
|
784 |
-
|
785 |
-
* Fixed some issues where whitespace around HTML blocks were trigging
|
786 |
-
empty paragraph tags.
|
787 |
-
|
788 |
-
* Fixed an HTML block parsing issue that would cause a block element
|
789 |
-
following a code span or block with unmatched opening bracket to be
|
790 |
-
placed inside a paragraph.
|
791 |
-
|
792 |
-
* Removed some PHP notices that could appear when parsing definition
|
793 |
-
lists and tables with PHP notice reporting flag set.
|
794 |
-
|
795 |
-
|
796 |
-
Extra 1.0b3 - 29 July 2005
|
797 |
-
|
798 |
-
* Definition lists now require a blank line before each term. Solves
|
799 |
-
an ambiguity where the last line of lazy-indented definitions could
|
800 |
-
be mistaken by PHP Markdown as a new term in the list.
|
801 |
-
|
802 |
-
* Definition lists now support multiple terms per definition.
|
803 |
-
|
804 |
-
* Some special tags were replaced in the output by their md5 hash
|
805 |
-
key. Things such as this now work as expected:
|
806 |
-
|
807 |
-
## Header <?php echo $number ?> ##
|
808 |
-
|
809 |
-
|
810 |
-
Extra 1.0b2 - 26 July 2005
|
811 |
-
|
812 |
-
* Definition lists can now take two or more definitions for one term.
|
813 |
-
This should have been the case before, but a bug prevented this
|
814 |
-
from working right.
|
815 |
-
|
816 |
-
* Fixed a problem where single column table with a pipe only at the
|
817 |
-
end where not parsed as table. Here is such a table:
|
818 |
-
|
819 |
-
| header
|
820 |
-
| ------
|
821 |
-
| cell
|
822 |
-
|
823 |
-
* Fixed problems with empty cells in the first column of a table with
|
824 |
-
no leading pipe, like this one:
|
825 |
-
|
826 |
-
header | header
|
827 |
-
------ | ------
|
828 |
-
| cell
|
829 |
-
|
830 |
-
* Code spans containing pipes did not within a table. This is now
|
831 |
-
fixed by parsing code spans before splitting rows into cells.
|
832 |
-
|
833 |
-
* Added the pipe character to the backlash escape character lists.
|
834 |
-
|
835 |
-
Extra 1.0b1 (25 Jun 2005)
|
836 |
-
|
837 |
-
* First public release of PHP Markdown Extra.
|
838 |
-
|
839 |
-
|
840 |
-
Copyright and License
|
841 |
-
---------------------
|
842 |
-
|
843 |
-
PHP Markdown & Extra
|
844 |
-
Copyright (c) 2004-2013 Michel Fortin
|
845 |
-
<http://michelf.ca/>
|
846 |
-
All rights reserved.
|
847 |
-
|
848 |
-
Based on Markdown
|
849 |
-
Copyright (c) 2003-2005 John Gruber
|
850 |
-
<http://daringfireball.net/>
|
851 |
-
All rights reserved.
|
852 |
-
|
853 |
-
Redistribution and use in source and binary forms, with or without
|
854 |
-
modification, are permitted provided that the following conditions are
|
855 |
-
met:
|
856 |
-
|
857 |
-
* Redistributions of source code must retain the above copyright
|
858 |
-
notice, this list of conditions and the following disclaimer.
|
859 |
-
|
860 |
-
* Redistributions in binary form must reproduce the above copyright
|
861 |
-
notice, this list of conditions and the following disclaimer in the
|
862 |
-
documentation and/or other materials provided with the
|
863 |
-
distribution.
|
864 |
-
|
865 |
-
* Neither the name "Markdown" nor the names of its contributors may
|
866 |
-
be used to endorse or promote products derived from this software
|
867 |
-
without specific prior written permission.
|
868 |
-
|
869 |
-
This software is provided by the copyright holders and contributors "as
|
870 |
-
is" and any express or implied warranties, including, but not limited
|
871 |
-
to, the implied warranties of merchantability and fitness for a
|
872 |
-
particular purpose are disclaimed. In no event shall the copyright owner
|
873 |
-
or contributors be liable for any direct, indirect, incidental, special,
|
874 |
-
exemplary, or consequential damages (including, but not limited to,
|
875 |
-
procurement of substitute goods or services; loss of use, data, or
|
876 |
-
profits; or business interruption) however caused and on any theory of
|
877 |
-
liability, whether in contract, strict liability, or tort (including
|
878 |
-
negligence or otherwise) arising in any way out of the use of this
|
879 |
-
software, even if advised of the possibility of such damage.
|
1 |
+
PHP Markdown Extra
|
2 |
+
==================
|
3 |
+
|
4 |
+
Version 1.2.7 - 11 Apr 2013
|
5 |
+
|
6 |
+
by Michel Fortin
|
7 |
+
<http://michelf.ca/>
|
8 |
+
|
9 |
+
based on Markdown by John Gruber
|
10 |
+
<http://daringfireball.net/>
|
11 |
+
|
12 |
+
|
13 |
+
Introduction
|
14 |
+
------------
|
15 |
+
|
16 |
+
This is a special version of PHP Markdown with extra features. See
|
17 |
+
<http://michelf.com/projects/php-markdown/extra/> for details.
|
18 |
+
|
19 |
+
Markdown is a text-to-HTML conversion tool for web writers. Markdown
|
20 |
+
allows you to write using an easy-to-read, easy-to-write plain text
|
21 |
+
format, then convert it to structurally valid XHTML (or HTML).
|
22 |
+
|
23 |
+
"Markdown" is two things: a plain text markup syntax, and a software
|
24 |
+
tool, written in Perl, that converts the plain text markup to HTML.
|
25 |
+
PHP Markdown is a port to PHP of the original Markdown program by
|
26 |
+
John Gruber.
|
27 |
+
|
28 |
+
PHP Markdown can work as a plug-in for WordPress, as a modifier for
|
29 |
+
the Smarty templating engine, or as a replacement for Textile
|
30 |
+
formatting in any software that supports Textile.
|
31 |
+
|
32 |
+
Full documentation of Markdown's syntax is available on John's
|
33 |
+
Markdown page: <http://daringfireball.net/projects/markdown/>
|
34 |
+
|
35 |
+
|
36 |
+
Installation and Requirement
|
37 |
+
----------------------------
|
38 |
+
|
39 |
+
PHP Markdown requires PHP version 4.0.5 or later.
|
40 |
+
|
41 |
+
Before PHP 5.3.7, pcre.backtrack_limit defaults to 100 000, which is too small
|
42 |
+
in many situations. You might need to set it to higher values. Later PHP
|
43 |
+
releases defaults to 1 000 000, which is usually fine.
|
44 |
+
|
45 |
+
|
46 |
+
### WordPress ###
|
47 |
+
|
48 |
+
PHP Markdown works with [WordPress][wp], version 1.2 or later.
|
49 |
+
|
50 |
+
[wp]: http://wordpress.org/
|
51 |
+
|
52 |
+
1. To use PHP Markdown with WordPress, place the "markdown.php" file
|
53 |
+
in the "plugins" folder. This folder is located inside
|
54 |
+
"wp-content" at the root of your site:
|
55 |
+
|
56 |
+
(site home)/wp-content/plugins/
|
57 |
+
|
58 |
+
2. Activate the plugin with the administrative interface of
|
59 |
+
WordPress. In the "Plugins" section you will now find Markdown.
|
60 |
+
To activate the plugin, click on the "Activate" button on the
|
61 |
+
same line as Markdown. Your entries will now be formatted by
|
62 |
+
PHP Markdown.
|
63 |
+
|
64 |
+
3. To post Markdown content, you'll first have to disable the
|
65 |
+
"visual" editor in the User section of WordPress.
|
66 |
+
|
67 |
+
You can configure PHP Markdown to not apply to the comments on your
|
68 |
+
WordPress weblog. See the "Configuration" section below.
|
69 |
+
|
70 |
+
It is not possible at this time to apply a different set of
|
71 |
+
filters to different entries. All your entries will be formatted by
|
72 |
+
PHP Markdown. This is a limitation of WordPress. If your old entries
|
73 |
+
are written in HTML (as opposed to another formatting syntax, like
|
74 |
+
Textile), they'll probably stay fine after installing Markdown.
|
75 |
+
|
76 |
+
|
77 |
+
### Replacing Textile in TextPattern ###
|
78 |
+
|
79 |
+
[TextPattern][tp] use [Textile][tx] to format your text. You can
|
80 |
+
replace Textile by Markdown in TextPattern without having to change
|
81 |
+
any code by using the *Textile Compatibility Mode*. This may work
|
82 |
+
with other software that expect Textile too.
|
83 |
+
|
84 |
+
[tx]: http://www.textism.com/tools/textile/
|
85 |
+
[tp]: http://www.textpattern.com/
|
86 |
+
|
87 |
+
1. Rename the "markdown.php" file to "classTextile.php". This will
|
88 |
+
make PHP Markdown behave as if it was the actual Textile parser.
|
89 |
+
|
90 |
+
2. Replace the "classTextile.php" file TextPattern installed in your
|
91 |
+
web directory. It can be found in the "lib" directory:
|
92 |
+
|
93 |
+
(site home)/textpattern/lib/
|
94 |
+
|
95 |
+
Contrary to Textile, Markdown does not convert quotes to curly ones
|
96 |
+
and does not convert multiple hyphens (`--` and `---`) into en- and
|
97 |
+
em-dashes. If you use PHP Markdown in Textile Compatibility Mode, you
|
98 |
+
can solve this problem by installing the "smartypants.php" file from
|
99 |
+
[PHP SmartyPants][psp] beside the "classTextile.php" file. The Textile
|
100 |
+
Compatibility Mode function will use SmartyPants automatically without
|
101 |
+
further modification.
|
102 |
+
|
103 |
+
[psp]: http://michelf.ca/projects/php-smartypants/
|
104 |
+
|
105 |
+
|
106 |
+
### In Your Own Programs ###
|
107 |
+
|
108 |
+
You can use PHP Markdown easily in your current PHP program. Simply
|
109 |
+
include the file and then call the Markdown function on the text you
|
110 |
+
want to convert:
|
111 |
+
|
112 |
+
include_once "markdown.php";
|
113 |
+
$my_html = Markdown($my_text);
|
114 |
+
|
115 |
+
If you wish to use PHP Markdown with another text filter function
|
116 |
+
built to parse HTML, you should filter the text *after* the Markdown
|
117 |
+
function call. This is an example with [PHP SmartyPants][psp]:
|
118 |
+
|
119 |
+
$my_html = SmartyPants(Markdown($my_text));
|
120 |
+
|
121 |
+
|
122 |
+
### With Smarty ###
|
123 |
+
|
124 |
+
If your program use the [Smarty][sm] template engine, PHP Markdown
|
125 |
+
can now be used as a modifier for your templates. Rename "markdown.php"
|
126 |
+
to "modifier.markdown.php" and put it in your smarty plugins folder.
|
127 |
+
|
128 |
+
[sm]: http://smarty.php.net/
|
129 |
+
|
130 |
+
If you are using MovableType 3.1 or later, the Smarty plugin folder is
|
131 |
+
located at `(MT CGI root)/php/extlib/smarty/plugins`. This will allow
|
132 |
+
Markdown to work on dynamic pages.
|
133 |
+
|
134 |
+
|
135 |
+
### Updating Markdown in Other Programs ###
|
136 |
+
|
137 |
+
Many web applications now ship with PHP Markdown, or have plugins to
|
138 |
+
perform the conversion to HTML. You can update PHP Markdown -- or
|
139 |
+
replace it with PHP Markdown Extra -- in many of these programs by
|
140 |
+
swapping the old "markdown.php" file for the new one.
|
141 |
+
|
142 |
+
Here is a short non-exhaustive list of some programs and where they
|
143 |
+
hide the "markdown.php" file.
|
144 |
+
|
145 |
+
| Program | Path to Markdown
|
146 |
+
| ------- | ----------------
|
147 |
+
| [Pivot][] | `(site home)/pivot/includes/markdown/`
|
148 |
+
|
149 |
+
If you're unsure if you can do this with your application, ask the
|
150 |
+
developer, or wait for the developer to update his application or
|
151 |
+
plugin with the new version of PHP Markdown.
|
152 |
+
|
153 |
+
[Pivot]: http://pivotlog.net/
|
154 |
+
|
155 |
+
|
156 |
+
Configuration
|
157 |
+
-------------
|
158 |
+
|
159 |
+
By default, PHP Markdown produces XHTML output for tags with empty
|
160 |
+
elements. E.g.:
|
161 |
+
|
162 |
+
<br />
|
163 |
+
|
164 |
+
Markdown can be configured to produce HTML-style tags; e.g.:
|
165 |
+
|
166 |
+
<br>
|
167 |
+
|
168 |
+
To do this, you must edit the "MARKDOWN_EMPTY_ELEMENT_SUFFIX"
|
169 |
+
definition below the "Global default settings" header at the start of
|
170 |
+
the "markdown.php" file.
|
171 |
+
|
172 |
+
|
173 |
+
### WordPress-Specific Settings ###
|
174 |
+
|
175 |
+
By default, the Markdown plugin applies to both posts and comments on
|
176 |
+
your WordPress weblog. To deactivate one or the other, edit the
|
177 |
+
`MARKDOWN_WP_POSTS` or `MARKDOWN_WP_COMMENTS` definitions under the
|
178 |
+
"WordPress settings" header at the start of the "markdown.php" file.
|
179 |
+
|
180 |
+
|
181 |
+
Bugs
|
182 |
+
----
|
183 |
+
|
184 |
+
To file bug reports please send email to:
|
185 |
+
<michel.fortin@michelf.ca>
|
186 |
+
|
187 |
+
Please include with your report: (1) the example input; (2) the output you
|
188 |
+
expected; (3) the output PHP Markdown actually produced.
|
189 |
+
|
190 |
+
If you have a problem where Markdown gives you an empty result, first check
|
191 |
+
that the backtrack limit is not too low by running `php --info | grep pcre`.
|
192 |
+
See Installation and Requirement above for details.
|
193 |
+
|
194 |
+
|
195 |
+
Version History
|
196 |
+
---------------
|
197 |
+
|
198 |
+
Extra 1.2.7 (11 Apr 2013):
|
199 |
+
|
200 |
+
* Added optional class and id attributes to images and links using the same
|
201 |
+
syntax as for headers:
|
202 |
+
|
203 |
+
[link](url){#id .class}
|
204 |
+
![img](url){#id .class}
|
205 |
+
|
206 |
+
It work too for reference-style links and images. In this case you need
|
207 |
+
to put those attributes at the reference definition:
|
208 |
+
|
209 |
+
[link][linkref] or [linkref]
|
210 |
+
![img][linkref]
|
211 |
+
|
212 |
+
[linkref]: url "optional title" {#id .class}
|
213 |
+
|
214 |
+
* Fixed a PHP notice message triggered when some table column separator
|
215 |
+
markers are missing on the separator line below column headers.
|
216 |
+
|
217 |
+
|
218 |
+
1.0.1q (11 Apr 2013):
|
219 |
+
|
220 |
+
* Fixed a small mistake that could cause the parser to retain an invalid
|
221 |
+
state related to parsing links across multiple runs. This was never
|
222 |
+
observed (that I know of), but it's still worth fixing.
|
223 |
+
|
224 |
+
|
225 |
+
Extra 1.2.6 (13 Jan 2013):
|
226 |
+
|
227 |
+
* Headers can now have a class attribute. You can add a class inside the
|
228 |
+
extra attribute block which can optionally be put after a header:
|
229 |
+
|
230 |
+
### Header ### {#id .class1 .class2}
|
231 |
+
|
232 |
+
Spaces between components in the brace is optional.
|
233 |
+
|
234 |
+
* Fenced code blocks can also have a class and an id attribute. If you only
|
235 |
+
need to apply a class (typically to indicate the language of a code
|
236 |
+
snippet), you can write it like this:
|
237 |
+
|
238 |
+
~~~ html
|
239 |
+
<b>bold</b>
|
240 |
+
~~~
|
241 |
+
|
242 |
+
or like this:
|
243 |
+
|
244 |
+
~~~ .html
|
245 |
+
<b>bold</b>
|
246 |
+
~~~
|
247 |
+
|
248 |
+
There is a new configuration option `MARKDOWN_CODE_CLASS_PREFIX` you can
|
249 |
+
use if you need to append a prefix to the class name.
|
250 |
+
|
251 |
+
You might also opt to use an extra attribute block just like for headers:
|
252 |
+
|
253 |
+
~~~ {.html #id .codeclass}
|
254 |
+
<b>bold</b>
|
255 |
+
~~~
|
256 |
+
|
257 |
+
Note that class names added this way are not affected by the
|
258 |
+
MARKDOWN_CODE_CLASS_PREFIX.
|
259 |
+
|
260 |
+
A code block creates a `pre` HTML element containing a `code` element.
|
261 |
+
The `code` HTML element is the one that receives the attribute. If for
|
262 |
+
some reason you need attributes to be applied to the enclosing `pre`
|
263 |
+
element instead, you can set the MARKDOWN_CODE_ATTR_ON_PRE configuration
|
264 |
+
variable to true.
|
265 |
+
|
266 |
+
* Fixed an issue were consecutive fenced code blocks containing HTML-like
|
267 |
+
code would confuse the parser.
|
268 |
+
|
269 |
+
* Multiple references to the same footnote are now allowed.
|
270 |
+
|
271 |
+
* Fixed an issue where no_markup mode was ineffective.
|
272 |
+
|
273 |
+
|
274 |
+
1.0.1p (13 Jan 2013):
|
275 |
+
|
276 |
+
* Fixed an issue where some XML-style empty tags (such as `<br/>`) were not
|
277 |
+
recognized correctly as such when inserted into Markdown-formatted text.
|
278 |
+
|
279 |
+
* The following HTML 5 elements are treated as block elements when at the
|
280 |
+
root of an HTML block: `article`, `section`, `nav`, `aside`, `hgroup`,
|
281 |
+
`header`, `footer`, and `figure`. `svg` too.
|
282 |
+
|
283 |
+
|
284 |
+
1.0.1o (8 Jan 2012):
|
285 |
+
|
286 |
+
* Silenced a new warning introduced around PHP 5.3 complaining about
|
287 |
+
POSIX characters classes not being implemented. PHP Markdown does not
|
288 |
+
use POSIX character classes, but it nevertheless trigged that warning.
|
289 |
+
|
290 |
+
|
291 |
+
Extra 1.2.5 (8 Jan 2012):
|
292 |
+
|
293 |
+
* Fixed an issue preventing fenced code blocks indented inside lists items
|
294 |
+
and elsewhere from being interpreted correctly.
|
295 |
+
|
296 |
+
* Fixed an issue where HTML tags inside fenced code blocks were sometime
|
297 |
+
not encoded with entities.
|
298 |
+
|
299 |
+
|
300 |
+
1.0.1n (10 Oct 2009):
|
301 |
+
|
302 |
+
* Enabled reference-style shortcut links. Now you can write reference-style
|
303 |
+
links with less brakets:
|
304 |
+
|
305 |
+
This is [my website].
|
306 |
+
|
307 |
+
[my website]: http://example.com/
|
308 |
+
|
309 |
+
This was added in the 1.0.2 betas, but commented out in the 1.0.1 branch,
|
310 |
+
waiting for the feature to be officialized. [But half of the other Markdown
|
311 |
+
implementations are supporting this syntax][half], so it makes sense for
|
312 |
+
compatibility's sake to allow it in PHP Markdown too.
|
313 |
+
|
314 |
+
[half]: http://babelmark.bobtfish.net/?markdown=This+is+%5Bmy+website%5D.%0D%0A%09%09%0D%0A%5Bmy+website%5D%3A+http%3A%2F%2Fexample.com%2F%0D%0A&src=1&dest=2
|
315 |
+
|
316 |
+
* Now accepting many valid email addresses in autolinks that were
|
317 |
+
previously rejected, such as:
|
318 |
+
|
319 |
+
<abc+mailbox/department=shipping@example.com>
|
320 |
+
<!#$%&'*+-/=?^_`.{|}~@example.com>
|
321 |
+
<"abc@def"@example.com>
|
322 |
+
<"Fred Bloggs"@example.com>
|
323 |
+
<jsmith@[192.0.2.1]>
|
324 |
+
|
325 |
+
* Now accepting spaces in URLs for inline and reference-style links. Such
|
326 |
+
URLs need to be surrounded by angle brakets. For instance:
|
327 |
+
|
328 |
+
[link text](<http://url/with space> "optional title")
|
329 |
+
|
330 |
+
[link text][ref]
|
331 |
+
[ref]: <http://url/with space> "optional title"
|
332 |
+
|
333 |
+
There is still a quirk which may prevent this from working correctly with
|
334 |
+
relative URLs in inline-style links however.
|
335 |
+
|
336 |
+
* Fix for adjacent list of different kind where the second list could
|
337 |
+
end as a sublist of the first when not separated by an empty line.
|
338 |
+
|
339 |
+
* Fixed a bug where inline-style links wouldn't be recognized when the link
|
340 |
+
definition contains a line break between the url and the title.
|
341 |
+
|
342 |
+
* Fixed a bug where tags where the name contains an underscore aren't parsed
|
343 |
+
correctly.
|
344 |
+
|
345 |
+
* Fixed some corner-cases mixing underscore-ephasis and asterisk-emphasis.
|
346 |
+
|
347 |
+
|
348 |
+
Extra 1.2.4 (10 Oct 2009):
|
349 |
+
|
350 |
+
* Fixed a problem where unterminated tags in indented code blocks could
|
351 |
+
prevent proper escaping of characaters in the code block.
|
352 |
+
|
353 |
+
|
354 |
+
Extra 1.2.3 (31 Dec 2008):
|
355 |
+
|
356 |
+
* In WordPress pages featuring more than one post, footnote id prefixes are
|
357 |
+
now automatically applied with the current post ID to avoid clashes
|
358 |
+
between footnotes belonging to different posts.
|
359 |
+
|
360 |
+
* Fix for a bug introduced in Extra 1.2 where block-level HTML tags where
|
361 |
+
not detected correctly, thus the addition of erroneous `<p>` tags and
|
362 |
+
interpretation of their content as Markdown-formatted instead of
|
363 |
+
HTML-formatted.
|
364 |
+
|
365 |
+
|
366 |
+
Extra 1.2.2 (21 Jun 2008):
|
367 |
+
|
368 |
+
* Fixed a problem where abbreviation definitions, footnote
|
369 |
+
definitions and link references were stripped inside
|
370 |
+
fenced code blocks.
|
371 |
+
|
372 |
+
* Fixed a bug where characters such as `"` in abbreviation
|
373 |
+
definitions weren't properly encoded to HTML entities.
|
374 |
+
|
375 |
+
* Fixed a bug where double quotes `"` were not correctly encoded
|
376 |
+
as HTML entities when used inside a footnote reference id.
|
377 |
+
|
378 |
+
|
379 |
+
1.0.1m (21 Jun 2008):
|
380 |
+
|
381 |
+
* Lists can now have empty items.
|
382 |
+
|
383 |
+
* Rewrote the emphasis and strong emphasis parser to fix some issues
|
384 |
+
with odly placed and overlong markers.
|
385 |
+
|
386 |
+
|
387 |
+
Extra 1.2.1 (27 May 2008):
|
388 |
+
|
389 |
+
* Fixed a problem where Markdown headers and horizontal rules were
|
390 |
+
transformed into their HTML equivalent inside fenced code blocks.
|
391 |
+
|
392 |
+
|
393 |
+
Extra 1.2 (11 May 2008):
|
394 |
+
|
395 |
+
* Added fenced code block syntax which don't require indentation
|
396 |
+
and can start and end with blank lines. A fenced code block
|
397 |
+
starts with a line of consecutive tilde (~) and ends on the
|
398 |
+
next line with the same number of consecutive tilde. Here's an
|
399 |
+
example:
|
400 |
+
|
401 |
+
~~~~~~~~~~~~
|
402 |
+
Hello World!
|
403 |
+
~~~~~~~~~~~~
|
404 |
+
|
405 |
+
* Rewrote parts of the HTML block parser to better accomodate
|
406 |
+
fenced code blocks.
|
407 |
+
|
408 |
+
* Footnotes may now be referenced from within another footnote.
|
409 |
+
|
410 |
+
* Added programatically-settable parser property `predef_attr` for
|
411 |
+
predefined attribute definitions.
|
412 |
+
|
413 |
+
* Fixed an issue where an indented code block preceded by a blank
|
414 |
+
line containing some other whitespace would confuse the HTML
|
415 |
+
block parser into creating an HTML block when it should have
|
416 |
+
been code.
|
417 |
+
|
418 |
+
|
419 |
+
1.0.1l (11 May 2008):
|
420 |
+
|
421 |
+
* Now removing the UTF-8 BOM at the start of a document, if present.
|
422 |
+
|
423 |
+
* Now accepting capitalized URI schemes (such as HTTP:) in automatic
|
424 |
+
links, such as `<HTTP://EXAMPLE.COM/>`.
|
425 |
+
|
426 |
+
* Fixed a problem where `<hr@example.com>` was seen as a horizontal
|
427 |
+
rule instead of an automatic link.
|
428 |
+
|
429 |
+
* Fixed an issue where some characters in Markdown-generated HTML
|
430 |
+
attributes weren't properly escaped with entities.
|
431 |
+
|
432 |
+
* Fix for code blocks as first element of a list item. Previously,
|
433 |
+
this didn't create any code block for item 2:
|
434 |
+
|
435 |
+
* Item 1 (regular paragraph)
|
436 |
+
|
437 |
+
* Item 2 (code block)
|
438 |
+
|
439 |
+
* A code block starting on the second line of a document wasn't seen
|
440 |
+
as a code block. This has been fixed.
|
441 |
+
|
442 |
+
* Added programatically-settable parser properties `predef_urls` and
|
443 |
+
`predef_titles` for predefined URLs and titles for reference-style
|
444 |
+
links. To use this, your PHP code must call the parser this way:
|
445 |
+
|
446 |
+
$parser = new Markdwon_Parser;
|
447 |
+
$parser->predef_urls = array('linkref' => 'http://example.com');
|
448 |
+
$html = $parser->transform($text);
|
449 |
+
|
450 |
+
You can then use the URL as a normal link reference:
|
451 |
+
|
452 |
+
[my link][linkref]
|
453 |
+
[my link][linkRef]
|
454 |
+
|
455 |
+
Reference names in the parser properties *must* be lowercase.
|
456 |
+
Reference names in the Markdown source may have any case.
|
457 |
+
|
458 |
+
* Added `setup` and `teardown` methods which can be used by subclassers
|
459 |
+
as hook points to arrange the state of some parser variables before and
|
460 |
+
after parsing.
|
461 |
+
|
462 |
+
|
463 |
+
Extra 1.1.7 (26 Sep 2007):
|
464 |
+
|
465 |
+
1.0.1k (26 Sep 2007):
|
466 |
+
|
467 |
+
* Fixed a problem introduced in 1.0.1i where three or more identical
|
468 |
+
uppercase letters, as well as a few other symbols, would trigger
|
469 |
+
a horizontal line.
|
470 |
+
|
471 |
+
|
472 |
+
Extra 1.1.6 (4 Sep 2007):
|
473 |
+
|
474 |
+
1.0.1j (4 Sep 2007):
|
475 |
+
|
476 |
+
* Fixed a problem introduced in 1.0.1i where the closing `code` and
|
477 |
+
`pre` tags at the end of a code block were appearing in the wrong
|
478 |
+
order.
|
479 |
+
|
480 |
+
* Overriding configuration settings by defining constants from an
|
481 |
+
external before markdown.php is included is now possible without
|
482 |
+
producing a PHP warning.
|
483 |
+
|
484 |
+
|
485 |
+
Extra 1.1.5 (31 Aug 2007):
|
486 |
+
|
487 |
+
1.0.1i (31 Aug 2007):
|
488 |
+
|
489 |
+
* Fixed a problem where an escaped backslash before a code span
|
490 |
+
would prevent the code span from being created. This should now
|
491 |
+
work as expected:
|
492 |
+
|
493 |
+
Litteral backslash: \\`code span`
|
494 |
+
|
495 |
+
* Overall speed improvements, especially with long documents.
|
496 |
+
|
497 |
+
|
498 |
+
Extra 1.1.4 (3 Aug 2007):
|
499 |
+
|
500 |
+
1.0.1h (3 Aug 2007):
|
501 |
+
|
502 |
+
* Added two properties (`no_markup` and `no_entities`) to the parser
|
503 |
+
allowing HTML tags and entities to be disabled.
|
504 |
+
|
505 |
+
* Fix for a problem introduced in 1.0.1g where posting comments in
|
506 |
+
WordPress would trigger PHP warnings and cause some markup to be
|
507 |
+
incorrectly filtered by the kses filter in WordPress.
|
508 |
+
|
509 |
+
|
510 |
+
Extra 1.1.3 (3 Jul 2007):
|
511 |
+
|
512 |
+
* Fixed a performance problem when parsing some invalid HTML as an HTML
|
513 |
+
block which was resulting in too much recusion and a segmentation fault
|
514 |
+
for long documents.
|
515 |
+
|
516 |
+
* The markdown="" attribute now accepts unquoted values.
|
517 |
+
|
518 |
+
* Fixed an issue where underscore-emphasis didn't work when applied on the
|
519 |
+
first or the last word of an element having the markdown="1" or
|
520 |
+
markdown="span" attribute set unless there was some surrounding whitespace.
|
521 |
+
This didn't work:
|
522 |
+
|
523 |
+
<p markdown="1">_Hello_ _world_</p>
|
524 |
+
|
525 |
+
Now it does produce emphasis as expected.
|
526 |
+
|
527 |
+
* Fixed an issue preventing footnotes from working when the parser's
|
528 |
+
footnote id prefix variable (fn_id_prefix) is not empty.
|
529 |
+
|
530 |
+
* Fixed a performance problem where the regular expression for strong
|
531 |
+
emphasis introduced in version 1.1 could sometime be long to process,
|
532 |
+
give slightly wrong results, and in some circumstances could remove
|
533 |
+
entirely the content for a whole paragraph.
|
534 |
+
|
535 |
+
* Fixed an issue were abbreviations tags could be incorrectly added
|
536 |
+
inside URLs and title of links.
|
537 |
+
|
538 |
+
* Placing footnote markers inside a link, resulting in two nested links, is
|
539 |
+
no longer allowed.
|
540 |
+
|
541 |
+
|
542 |
+
1.0.1g (3 Jul 2007):
|
543 |
+
|
544 |
+
* Fix for PHP 5 compiled without the mbstring module. Previous fix to
|
545 |
+
calculate the length of UTF-8 strings in `detab` when `mb_strlen` is
|
546 |
+
not available was only working with PHP 4.
|
547 |
+
|
548 |
+
* Fixed a problem with WordPress 2.x where full-content posts in RSS feeds
|
549 |
+
were not processed correctly by Markdown.
|
550 |
+
|
551 |
+
* Now supports URLs containing literal parentheses for inline links
|
552 |
+
and images, such as:
|
553 |
+
|
554 |
+
[WIMP](http://en.wikipedia.org/wiki/WIMP_(computing))
|
555 |
+
|
556 |
+
Such parentheses may be arbitrarily nested, but must be
|
557 |
+
balanced. Unbalenced parentheses are allowed however when the URL
|
558 |
+
when escaped or when the URL is enclosed in angle brakets `<>`.
|
559 |
+
|
560 |
+
* Fixed a performance problem where the regular expression for strong
|
561 |
+
emphasis introduced in version 1.0.1d could sometime be long to process,
|
562 |
+
give slightly wrong results, and in some circumstances could remove
|
563 |
+
entirely the content for a whole paragraph.
|
564 |
+
|
565 |
+
* Some change in version 1.0.1d made possible the incorrect nesting of
|
566 |
+
anchors within each other. This is now fixed.
|
567 |
+
|
568 |
+
* Fixed a rare issue where certain MD5 hashes in the content could
|
569 |
+
be changed to their corresponding text. For instance, this:
|
570 |
+
|
571 |
+
The MD5 value for "+" is "26b17225b626fb9238849fd60eabdf60".
|
572 |
+
|
573 |
+
was incorrectly changed to this in previous versions of PHP Markdown:
|
574 |
+
|
575 |
+
<p>The MD5 value for "+" is "+".</p>
|
576 |
+
|
577 |
+
* Now convert escaped characters to their numeric character
|
578 |
+
references equivalent.
|
579 |
+
|
580 |
+
This fix an integration issue with SmartyPants and backslash escapes.
|
581 |
+
Since Markdown and SmartyPants have some escapable characters in common,
|
582 |
+
it was sometime necessary to escape them twice. Previously, two
|
583 |
+
backslashes were sometime required to prevent Markdown from "eating" the
|
584 |
+
backslash before SmartyPants sees it:
|
585 |
+
|
586 |
+
Here are two hyphens: \\--
|
587 |
+
|
588 |
+
Now, only one backslash will do:
|
589 |
+
|
590 |
+
Here are two hyphens: \--
|
591 |
+
|
592 |
+
|
593 |
+
Extra 1.1.2 (7 Feb 2007)
|
594 |
+
|
595 |
+
* Fixed an issue where headers preceded too closely by a paragraph
|
596 |
+
(with no blank line separating them) where put inside the paragraph.
|
597 |
+
|
598 |
+
* Added the missing TextileRestricted method that was added to regular
|
599 |
+
PHP Markdown since 1.0.1d but which I forgot to add to Extra.
|
600 |
+
|
601 |
+
|
602 |
+
1.0.1f (7 Feb 2007):
|
603 |
+
|
604 |
+
* Fixed an issue with WordPress where manually-entered excerpts, but
|
605 |
+
not the auto-generated ones, would contain nested paragraphs.
|
606 |
+
|
607 |
+
* Fixed an issue introduced in 1.0.1d where headers and blockquotes
|
608 |
+
preceded too closely by a paragraph (not separated by a blank line)
|
609 |
+
where incorrectly put inside the paragraph.
|
610 |
+
|
611 |
+
* Fixed an issue introduced in 1.0.1d in the tokenizeHTML method where
|
612 |
+
two consecutive code spans would be merged into one when together they
|
613 |
+
form a valid tag in a multiline paragraph.
|
614 |
+
|
615 |
+
* Fixed an long-prevailing issue where blank lines in code blocks would
|
616 |
+
be doubled when the code block is in a list item.
|
617 |
+
|
618 |
+
This was due to the list processing functions relying on artificially
|
619 |
+
doubled blank lines to correctly determine when list items should
|
620 |
+
contain block-level content. The list item processing model was thus
|
621 |
+
changed to avoid the need for double blank lines.
|
622 |
+
|
623 |
+
* Fixed an issue with `<% asp-style %>` instructions used as inline
|
624 |
+
content where the opening `<` was encoded as `<`.
|
625 |
+
|
626 |
+
* Fixed a parse error occuring when PHP is configured to accept
|
627 |
+
ASP-style delimiters as boundaries for PHP scripts.
|
628 |
+
|
629 |
+
* Fixed a bug introduced in 1.0.1d where underscores in automatic links
|
630 |
+
got swapped with emphasis tags.
|
631 |
+
|
632 |
+
|
633 |
+
Extra 1.1.1 (28 Dec 2006)
|
634 |
+
|
635 |
+
* Fixed a problem where whitespace at the end of the line of an atx-style
|
636 |
+
header would cause tailing `#` to appear as part of the header's content.
|
637 |
+
This was caused by a small error in the regex that handles the definition
|
638 |
+
for the id attribute in PHP Markdown Extra.
|
639 |
+
|
640 |
+
* Fixed a problem where empty abbreviations definitions would eat the
|
641 |
+
following line as its definition.
|
642 |
+
|
643 |
+
* Fixed an issue with calling the Markdown parser repetitivly with text
|
644 |
+
containing footnotes. The footnote hashes were not reinitialized properly.
|
645 |
+
|
646 |
+
|
647 |
+
1.0.1e (28 Dec 2006)
|
648 |
+
|
649 |
+
* Added support for internationalized domain names for email addresses in
|
650 |
+
automatic link. Improved the speed at which email addresses are converted
|
651 |
+
to entities. Thanks to Milian Wolff for his optimisations.
|
652 |
+
|
653 |
+
* Made deterministic the conversion to entities of email addresses in
|
654 |
+
automatic links. This means that a given email address will always be
|
655 |
+
encoded the same way.
|
656 |
+
|
657 |
+
* PHP Markdown will now use its own function to calculate the length of an
|
658 |
+
UTF-8 string in `detab` when `mb_strlen` is not available instead of
|
659 |
+
giving a fatal error.
|
660 |
+
|
661 |
+
|
662 |
+
Extra 1.1 (1 Dec 2006)
|
663 |
+
|
664 |
+
* Added a syntax for footnotes.
|
665 |
+
|
666 |
+
* Added an experimental syntax to define abbreviations.
|
667 |
+
|
668 |
+
|
669 |
+
1.0.1d (1 Dec 2006)
|
670 |
+
|
671 |
+
* Fixed a bug where inline images always had an empty title attribute. The
|
672 |
+
title attribute is now present only when explicitly defined.
|
673 |
+
|
674 |
+
* Link references definitions can now have an empty title, previously if the
|
675 |
+
title was defined but left empty the link definition was ignored. This can
|
676 |
+
be useful if you want an empty title attribute in images to hide the
|
677 |
+
tooltip in Internet Explorer.
|
678 |
+
|
679 |
+
* Made `detab` aware of UTF-8 characters. UTF-8 multi-byte sequences are now
|
680 |
+
correctly mapped to one character instead of the number of bytes.
|
681 |
+
|
682 |
+
* Fixed a small bug with WordPress where WordPress' default filter `wpautop`
|
683 |
+
was not properly deactivated on comment text, resulting in hard line breaks
|
684 |
+
where Markdown do not prescribes them.
|
685 |
+
|
686 |
+
* Added a `TextileRestrited` method to the textile compatibility mode. There
|
687 |
+
is no restriction however, as Markdown does not have a restricted mode at
|
688 |
+
this point. This should make PHP Markdown work again in the latest
|
689 |
+
versions of TextPattern.
|
690 |
+
|
691 |
+
* Converted PHP Markdown to a object-oriented design.
|
692 |
+
|
693 |
+
* Changed span and block gamut methods so that they loop over a
|
694 |
+
customizable list of methods. This makes subclassing the parser a more
|
695 |
+
interesting option for creating syntax extensions.
|
696 |
+
|
697 |
+
* Also added a "document" gamut loop which can be used to hook document-level
|
698 |
+
methods (like for striping link definitions).
|
699 |
+
|
700 |
+
* Changed all methods which were inserting HTML code so that they now return
|
701 |
+
a hashed representation of the code. New methods `hashSpan` and `hashBlock`
|
702 |
+
are used to hash respectivly span- and block-level generated content. This
|
703 |
+
has a couple of significant effects:
|
704 |
+
|
705 |
+
1. It prevents invalid nesting of Markdown-generated elements which
|
706 |
+
could occur occuring with constructs like `*something [link*][1]`.
|
707 |
+
2. It prevents problems occuring with deeply nested lists on which
|
708 |
+
paragraphs were ill-formed.
|
709 |
+
3. It removes the need to call `hashHTMLBlocks` twice during the the
|
710 |
+
block gamut.
|
711 |
+
|
712 |
+
Hashes are turned back to HTML prior output.
|
713 |
+
|
714 |
+
* Made the block-level HTML parser smarter using a specially-crafted regular
|
715 |
+
expression capable of handling nested tags.
|
716 |
+
|
717 |
+
* Solved backtick issues in tag attributes by rewriting the HTML tokenizer to
|
718 |
+
be aware of code spans. All these lines should work correctly now:
|
719 |
+
|
720 |
+
<span attr='`ticks`'>bar</span>
|
721 |
+
<span attr='``double ticks``'>bar</span>
|
722 |
+
`<test a="` content of attribute `">`
|
723 |
+
|
724 |
+
* Changed the parsing of HTML comments to match simply from `<!--` to `-->`
|
725 |
+
instead using of the more complicated SGML-style rule with paired `--`.
|
726 |
+
This is how most browsers parse comments and how XML defines them too.
|
727 |
+
|
728 |
+
* `<address>` has been added to the list of block-level elements and is now
|
729 |
+
treated as an HTML block instead of being wrapped within paragraph tags.
|
730 |
+
|
731 |
+
* Now only trim trailing newlines from code blocks, instead of trimming
|
732 |
+
all trailing whitespace characters.
|
733 |
+
|
734 |
+
* Fixed bug where this:
|
735 |
+
|
736 |
+
[text](http://m.com "title" )
|
737 |
+
|
738 |
+
wasn't working as expected, because the parser wasn't allowing for spaces
|
739 |
+
before the closing paren.
|
740 |
+
|
741 |
+
* Filthy hack to support markdown='1' in div tags.
|
742 |
+
|
743 |
+
* _DoAutoLinks() now supports the 'dict://' URL scheme.
|
744 |
+
|
745 |
+
* PHP- and ASP-style processor instructions are now protected as
|
746 |
+
raw HTML blocks.
|
747 |
+
|
748 |
+
<? ... ?>
|
749 |
+
<% ... %>
|
750 |
+
|
751 |
+
* Fix for escaped backticks still triggering code spans:
|
752 |
+
|
753 |
+
There are two raw backticks here: \` and here: \`, not a code span
|
754 |
+
|
755 |
+
|
756 |
+
Extra 1.0 - 5 September 2005
|
757 |
+
|
758 |
+
* Added support for setting the id attributes for headers like this:
|
759 |
+
|
760 |
+
Header 1 {#header1}
|
761 |
+
========
|
762 |
+
|
763 |
+
## Header 2 ## {#header2}
|
764 |
+
|
765 |
+
This only work only for headers for now.
|
766 |
+
|
767 |
+
* Tables will now work correctly as the first element of a definition
|
768 |
+
list. For example, this input:
|
769 |
+
|
770 |
+
Term
|
771 |
+
|
772 |
+
: Header | Header
|
773 |
+
------- | -------
|
774 |
+
Cell | Cell
|
775 |
+
|
776 |
+
used to produce no definition list and a table where the first
|
777 |
+
header was named ": Header". This is now fixed.
|
778 |
+
|
779 |
+
* Fix for a problem where a paragraph following a table was not
|
780 |
+
placed between `<p>` tags.
|
781 |
+
|
782 |
+
|
783 |
+
Extra 1.0b4 - 1 August 2005
|
784 |
+
|
785 |
+
* Fixed some issues where whitespace around HTML blocks were trigging
|
786 |
+
empty paragraph tags.
|
787 |
+
|
788 |
+
* Fixed an HTML block parsing issue that would cause a block element
|
789 |
+
following a code span or block with unmatched opening bracket to be
|
790 |
+
placed inside a paragraph.
|
791 |
+
|
792 |
+
* Removed some PHP notices that could appear when parsing definition
|
793 |
+
lists and tables with PHP notice reporting flag set.
|
794 |
+
|
795 |
+
|
796 |
+
Extra 1.0b3 - 29 July 2005
|
797 |
+
|
798 |
+
* Definition lists now require a blank line before each term. Solves
|
799 |
+
an ambiguity where the last line of lazy-indented definitions could
|
800 |
+
be mistaken by PHP Markdown as a new term in the list.
|
801 |
+
|
802 |
+
* Definition lists now support multiple terms per definition.
|
803 |
+
|
804 |
+
* Some special tags were replaced in the output by their md5 hash
|
805 |
+
key. Things such as this now work as expected:
|
806 |
+
|
807 |
+
## Header <?php echo $number ?> ##
|
808 |
+
|
809 |
+
|
810 |
+
Extra 1.0b2 - 26 July 2005
|
811 |
+
|
812 |
+
* Definition lists can now take two or more definitions for one term.
|
813 |
+
This should have been the case before, but a bug prevented this
|
814 |
+
from working right.
|
815 |
+
|
816 |
+
* Fixed a problem where single column table with a pipe only at the
|
817 |
+
end where not parsed as table. Here is such a table:
|
818 |
+
|
819 |
+
| header
|
820 |
+
| ------
|
821 |
+
| cell
|
822 |
+
|
823 |
+
* Fixed problems with empty cells in the first column of a table with
|
824 |
+
no leading pipe, like this one:
|
825 |
+
|
826 |
+
header | header
|
827 |
+
------ | ------
|
828 |
+
| cell
|
829 |
+
|
830 |
+
* Code spans containing pipes did not within a table. This is now
|
831 |
+
fixed by parsing code spans before splitting rows into cells.
|
832 |
+
|
833 |
+
* Added the pipe character to the backlash escape character lists.
|
834 |
+
|
835 |
+
Extra 1.0b1 (25 Jun 2005)
|
836 |
+
|
837 |
+
* First public release of PHP Markdown Extra.
|
838 |
+
|
839 |
+
|
840 |
+
Copyright and License
|
841 |
+
---------------------
|
842 |
+
|
843 |
+
PHP Markdown & Extra
|
844 |
+
Copyright (c) 2004-2013 Michel Fortin
|
845 |
+
<http://michelf.ca/>
|
846 |
+
All rights reserved.
|
847 |
+
|
848 |
+
Based on Markdown
|
849 |
+
Copyright (c) 2003-2005 John Gruber
|
850 |
+
<http://daringfireball.net/>
|
851 |
+
All rights reserved.
|
852 |
+
|
853 |
+
Redistribution and use in source and binary forms, with or without
|
854 |
+
modification, are permitted provided that the following conditions are
|
855 |
+
met:
|
856 |
+
|
857 |
+
* Redistributions of source code must retain the above copyright
|
858 |
+
notice, this list of conditions and the following disclaimer.
|
859 |
+
|
860 |
+
* Redistributions in binary form must reproduce the above copyright
|
861 |
+
notice, this list of conditions and the following disclaimer in the
|
862 |
+
documentation and/or other materials provided with the
|
863 |
+
distribution.
|
864 |
+
|
865 |
+
* Neither the name "Markdown" nor the names of its contributors may
|
866 |
+
be used to endorse or promote products derived from this software
|
867 |
+
without specific prior written permission.
|
868 |
+
|
869 |
+
This software is provided by the copyright holders and contributors "as
|
870 |
+
is" and any express or implied warranties, including, but not limited
|
871 |
+
to, the implied warranties of merchantability and fitness for a
|
872 |
+
particular purpose are disclaimed. In no event shall the copyright owner
|
873 |
+
or contributors be liable for any direct, indirect, incidental, special,
|
874 |
+
exemplary, or consequential damages (including, but not limited to,
|
875 |
+
procurement of substitute goods or services; loss of use, data, or
|
876 |
+
profits; or business interruption) however caused and on any theory of
|
877 |
+
liability, whether in contract, strict liability, or tort (including
|
878 |
+
negligence or otherwise) arising in any way out of the use of this
|
879 |
+
software, even if advised of the possibility of such damage.
|
classes/styles-font-menu/classes/markdown/PHP Markdown Readme.txt
CHANGED
@@ -1,785 +1,785 @@
|
|
1 |
-
PHP Markdown
|
2 |
-
============
|
3 |
-
|
4 |
-
Version 1.0.1p - 11 Apr 2013
|
5 |
-
|
6 |
-
by Michel Fortin
|
7 |
-
<http://michelf.ca/>
|
8 |
-
|
9 |
-
based on work by John Gruber
|
10 |
-
<http://daringfireball.net/>
|
11 |
-
|
12 |
-
|
13 |
-
Introduction
|
14 |
-
------------
|
15 |
-
|
16 |
-
Markdown is a text-to-HTML conversion tool for web writers. Markdown
|
17 |
-
allows you to write using an easy-to-read, easy-to-write plain text
|
18 |
-
format, then convert it to structurally valid XHTML (or HTML).
|
19 |
-
|
20 |
-
"Markdown" is two things: a plain text markup syntax, and a software
|
21 |
-
tool, written in Perl, that converts the plain text markup to HTML.
|
22 |
-
PHP Markdown is a port to PHP of the original Markdown program by
|
23 |
-
John Gruber.
|
24 |
-
|
25 |
-
PHP Markdown can work as a plug-in for WordPress, as a modifier for
|
26 |
-
the Smarty templating engine, or as a replacement for Textile
|
27 |
-
formatting in any software that supports Textile.
|
28 |
-
|
29 |
-
Full documentation of Markdown's syntax is available on John's
|
30 |
-
Markdown page: <http://daringfireball.net/projects/markdown/>
|
31 |
-
|
32 |
-
|
33 |
-
Installation and Requirement
|
34 |
-
----------------------------
|
35 |
-
|
36 |
-
PHP Markdown requires PHP version 4.0.5 or later.
|
37 |
-
|
38 |
-
Before PHP 5.3.7, pcre.backtrack_limit defaults to 100 000, which is too small
|
39 |
-
in many situations. You might need to set it to higher values. Later PHP
|
40 |
-
releases defaults to 1 000 000, which is usually fine.
|
41 |
-
|
42 |
-
|
43 |
-
### WordPress ###
|
44 |
-
|
45 |
-
PHP Markdown works with [WordPress][wp], version 1.2 or later.
|
46 |
-
|
47 |
-
[wp]: http://wordpress.org/
|
48 |
-
|
49 |
-
1. To use PHP Markdown with WordPress, place the "markdown.php" file
|
50 |
-
in the "plugins" folder. This folder is located inside
|
51 |
-
"wp-content" at the root of your site:
|
52 |
-
|
53 |
-
(site home)/wp-content/plugins/
|
54 |
-
|
55 |
-
2. Activate the plugin with the administrative interface of
|
56 |
-
WordPress. In the "Plugins" section you will now find Markdown.
|
57 |
-
To activate the plugin, click on the "Activate" button on the
|
58 |
-
same line as Markdown. Your entries will now be formatted by
|
59 |
-
PHP Markdown.
|
60 |
-
|
61 |
-
3. To post Markdown content, you'll first have to disable the
|
62 |
-
"visual" editor in the User section of WordPress.
|
63 |
-
|
64 |
-
You can configure PHP Markdown to not apply to the comments on your
|
65 |
-
WordPress weblog. See the "Configuration" section below.
|
66 |
-
|
67 |
-
It is not possible at this time to apply a different set of
|
68 |
-
filters to different entries. All your entries will be formatted by
|
69 |
-
PHP Markdown. This is a limitation of WordPress. If your old entries
|
70 |
-
are written in HTML (as opposed to another formatting syntax, like
|
71 |
-
Textile), they'll probably stay fine after installing Markdown.
|
72 |
-
|
73 |
-
|
74 |
-
### Replacing Textile in TextPattern ###
|
75 |
-
|
76 |
-
[TextPattern][tp] use [Textile][tx] to format your text. You can
|
77 |
-
replace Textile by Markdown in TextPattern without having to change
|
78 |
-
any code by using the *Textile Compatibility Mode*. This may work
|
79 |
-
with other software that expect Textile too.
|
80 |
-
|
81 |
-
[tx]: http://www.textism.com/tools/textile/
|
82 |
-
[tp]: http://www.textpattern.com/
|
83 |
-
|
84 |
-
1. Rename the "markdown.php" file to "classTextile.php". This will
|
85 |
-
make PHP Markdown behave as if it was the actual Textile parser.
|
86 |
-
|
87 |
-
2. Replace the "classTextile.php" file TextPattern installed in your
|
88 |
-
web directory. It can be found in the "lib" directory:
|
89 |
-
|
90 |
-
(site home)/textpattern/lib/
|
91 |
-
|
92 |
-
Contrary to Textile, Markdown does not convert quotes to curly ones
|
93 |
-
and does not convert multiple hyphens (`--` and `---`) into en- and
|
94 |
-
em-dashes. If you use PHP Markdown in Textile Compatibility Mode, you
|
95 |
-
can solve this problem by installing the "smartypants.php" file from
|
96 |
-
[PHP SmartyPants][psp] beside the "classTextile.php" file. The Textile
|
97 |
-
Compatibility Mode function will use SmartyPants automatically without
|
98 |
-
further modification.
|
99 |
-
|
100 |
-
[psp]: http://michelf.ca/projects/php-smartypants/
|
101 |
-
|
102 |
-
|
103 |
-
### Updating Markdown in Other Programs ###
|
104 |
-
|
105 |
-
Many web applications now ship with PHP Markdown, or have plugins to
|
106 |
-
perform the conversion to HTML. You can update PHP Markdown in many of
|
107 |
-
these programs by swapping the old "markdown.php" file for the new one.
|
108 |
-
|
109 |
-
Here is a short non-exhaustive list of some programs and where they
|
110 |
-
hide the "markdown.php" file.
|
111 |
-
|
112 |
-
| Program | Path to Markdown
|
113 |
-
| ------- | ----------------
|
114 |
-
| [Pivot][] | `(site home)/pivot/includes/markdown/markdown.php`
|
115 |
-
|
116 |
-
If you're unsure if you can do this with your application, ask the
|
117 |
-
developer, or wait for the developer to update his application or
|
118 |
-
plugin with the new version of PHP Markdown.
|
119 |
-
|
120 |
-
[Pivot]: http://pivotlog.net/
|
121 |
-
|
122 |
-
|
123 |
-
### In Your Own Programs ###
|
124 |
-
|
125 |
-
You can use PHP Markdown easily in your current PHP program. Simply
|
126 |
-
include the file and then call the Markdown function on the text you
|
127 |
-
want to convert:
|
128 |
-
|
129 |
-
include_once "markdown.php";
|
130 |
-
$my_html = Markdown($my_text);
|
131 |
-
|
132 |
-
If you wish to use PHP Markdown with another text filter function
|
133 |
-
built to parse HTML, you should filter the text *after* the Markdown
|
134 |
-
function call. This is an example with [PHP SmartyPants][psp]:
|
135 |
-
|
136 |
-
$my_html = SmartyPants(Markdown($my_text));
|
137 |
-
|
138 |
-
|
139 |
-
### With Smarty ###
|
140 |
-
|
141 |
-
If your program use the [Smarty][sm] template engine, PHP Markdown
|
142 |
-
can now be used as a modifier for your templates. Rename "markdown.php"
|
143 |
-
to "modifier.markdown.php" and put it in your smarty plugins folder.
|
144 |
-
|
145 |
-
[sm]: http://smarty.php.net/
|
146 |
-
|
147 |
-
If you are using MovableType 3.1 or later, the Smarty plugin folder is
|
148 |
-
located at `(MT CGI root)/php/extlib/smarty/plugins`. This will allow
|
149 |
-
Markdown to work on dynamic pages.
|
150 |
-
|
151 |
-
|
152 |
-
Configuration
|
153 |
-
-------------
|
154 |
-
|
155 |
-
By default, PHP Markdown produces XHTML output for tags with empty
|
156 |
-
elements. E.g.:
|
157 |
-
|
158 |
-
<br />
|
159 |
-
|
160 |
-
Markdown can be configured to produce HTML-style tags; e.g.:
|
161 |
-
|
162 |
-
<br>
|
163 |
-
|
164 |
-
To do this, you must edit the "MARKDOWN_EMPTY_ELEMENT_SUFFIX"
|
165 |
-
definition below the "Global default settings" header at the start of
|
166 |
-
the "markdown.php" file.
|
167 |
-
|
168 |
-
|
169 |
-
### WordPress-Specific Settings ###
|
170 |
-
|
171 |
-
By default, the Markdown plugin applies to both posts and comments on
|
172 |
-
your WordPress weblog. To deactivate one or the other, edit the
|
173 |
-
`MARKDOWN_WP_POSTS` or `MARKDOWN_WP_COMMENTS` definitions under the
|
174 |
-
"WordPress settings" header at the start of the "markdown.php" file.
|
175 |
-
|
176 |
-
|
177 |
-
Bugs
|
178 |
-
----
|
179 |
-
|
180 |
-
To file bug reports please send email to:
|
181 |
-
<michel.fortin@michelf.ca>
|
182 |
-
|
183 |
-
Please include with your report: (1) the example input; (2) the output you
|
184 |
-
expected; (3) the output PHP Markdown actually produced.
|
185 |
-
|
186 |
-
If you have a problem where Markdown gives you an empty result, first check
|
187 |
-
that the backtrack limit is not too low by running `php --info | grep pcre`.
|
188 |
-
See Installation and Requirement above for details.
|
189 |
-
|
190 |
-
|
191 |
-
Version History
|
192 |
-
---------------
|
193 |
-
|
194 |
-
1.0.1q (11 Apr 2013):
|
195 |
-
|
196 |
-
* Fixed a small mistake that could cause the parser to retain an invalid
|
197 |
-
state related to parsing links across multiple runs. This was never
|
198 |
-
observed (that I know of), but it's still worth fixing.
|
199 |
-
|
200 |
-
|
201 |
-
1.0.1p (13 Jan 2013):
|
202 |
-
|
203 |
-
* Fixed an issue where some XML-style empty tags (such as `<br/>`) were not
|
204 |
-
recognized correctly as such when inserted into Markdown-formatted text.
|
205 |
-
|
206 |
-
* The following HTML 5 elements are treated as block elements when at the
|
207 |
-
root of an HTML block: `article`, `section`, `nav`, `aside`, `hgroup`,
|
208 |
-
`header`, `footer`, and `figure`. `svg` too.
|
209 |
-
|
210 |
-
|
211 |
-
1.0.1o (8 Jan 2012):
|
212 |
-
|
213 |
-
* Silenced a new warning introduced around PHP 5.3 complaining about
|
214 |
-
POSIX characters classes not being implemented. PHP Markdown does not
|
215 |
-
use POSIX character classes, but it nevertheless trigged that warning.
|
216 |
-
|
217 |
-
|
218 |
-
1.0.1n (10 Oct 2009):
|
219 |
-
|
220 |
-
* Enabled reference-style shortcut links. Now you can write reference-style
|
221 |
-
links with less brakets:
|
222 |
-
|
223 |
-
This is [my website].
|
224 |
-
|
225 |
-
[my website]: http://example.com/
|
226 |
-
|
227 |
-
This was added in the 1.0.2 betas, but commented out in the 1.0.1 branch,
|
228 |
-
waiting for the feature to be officialized. [But half of the other Markdown
|
229 |
-
implementations are supporting this syntax][half], so it makes sense for
|
230 |
-
compatibility's sake to allow it in PHP Markdown too.
|
231 |
-
|
232 |
-
[half]: http://babelmark.bobtfish.net/?markdown=This+is+%5Bmy+website%5D.%0D%0A%09%09%0D%0A%5Bmy+website%5D%3A+http%3A%2F%2Fexample.com%2F%0D%0A&src=1&dest=2
|
233 |
-
|
234 |
-
* Now accepting many valid email addresses in autolinks that were
|
235 |
-
previously rejected, such as:
|
236 |
-
|
237 |
-
<abc+mailbox/department=shipping@example.com>
|
238 |
-
<!#$%&'*+-/=?^_`.{|}~@example.com>
|
239 |
-
<"abc@def"@example.com>
|
240 |
-
<"Fred Bloggs"@example.com>
|
241 |
-
<jsmith@[192.0.2.1]>
|
242 |
-
|
243 |
-
* Now accepting spaces in URLs for inline and reference-style links. Such
|
244 |
-
URLs need to be surrounded by angle brakets. For instance:
|
245 |
-
|
246 |
-
[link text](<http://url/with space> "optional title")
|
247 |
-
|
248 |
-
[link text][ref]
|
249 |
-
[ref]: <http://url/with space> "optional title"
|
250 |
-
|
251 |
-
There is still a quirk which may prevent this from working correctly with
|
252 |
-
relative URLs in inline-style links however.
|
253 |
-
|
254 |
-
* Fix for adjacent list of different kind where the second list could
|
255 |
-
end as a sublist of the first when not separated by an empty line.
|
256 |
-
|
257 |
-
* Fixed a bug where inline-style links wouldn't be recognized when the link
|
258 |
-
definition contains a line break between the url and the title.
|
259 |
-
|
260 |
-
* Fixed a bug where tags where the name contains an underscore aren't parsed
|
261 |
-
correctly.
|
262 |
-
|
263 |
-
* Fixed some corner-cases mixing underscore-ephasis and asterisk-emphasis.
|
264 |
-
|
265 |
-
|
266 |
-
1.0.1m (21 Jun 2008):
|
267 |
-
|
268 |
-
* Lists can now have empty items.
|
269 |
-
|
270 |
-
* Rewrote the emphasis and strong emphasis parser to fix some issues
|
271 |
-
with odly placed and overlong markers.
|
272 |
-
|
273 |
-
|
274 |
-
1.0.1l (11 May 2008):
|
275 |
-
|
276 |
-
* Now removing the UTF-8 BOM at the start of a document, if present.
|
277 |
-
|
278 |
-
* Now accepting capitalized URI schemes (such as HTTP:) in automatic
|
279 |
-
links, such as `<HTTP://EXAMPLE.COM/>`.
|
280 |
-
|
281 |
-
* Fixed a problem where `<hr@example.com>` was seen as a horizontal
|
282 |
-
rule instead of an automatic link.
|
283 |
-
|
284 |
-
* Fixed an issue where some characters in Markdown-generated HTML
|
285 |
-
attributes weren't properly escaped with entities.
|
286 |
-
|
287 |
-
* Fix for code blocks as first element of a list item. Previously,
|
288 |
-
this didn't create any code block for item 2:
|
289 |
-
|
290 |
-
* Item 1 (regular paragraph)
|
291 |
-
|
292 |
-
* Item 2 (code block)
|
293 |
-
|
294 |
-
* A code block starting on the second line of a document wasn't seen
|
295 |
-
as a code block. This has been fixed.
|
296 |
-
|
297 |
-
* Added programatically-settable parser properties `predef_urls` and
|
298 |
-
`predef_titles` for predefined URLs and titles for reference-style
|
299 |
-
links. To use this, your PHP code must call the parser this way:
|
300 |
-
|
301 |
-
$parser = new Markdwon_Parser;
|
302 |
-
$parser->predef_urls = array('linkref' => 'http://example.com');
|
303 |
-
$html = $parser->transform($text);
|
304 |
-
|
305 |
-
You can then use the URL as a normal link reference:
|
306 |
-
|
307 |
-
[my link][linkref]
|
308 |
-
[my link][linkRef]
|
309 |
-
|
310 |
-
Reference names in the parser properties *must* be lowercase.
|
311 |
-
Reference names in the Markdown source may have any case.
|
312 |
-
|
313 |
-
* Added `setup` and `teardown` methods which can be used by subclassers
|
314 |
-
as hook points to arrange the state of some parser variables before and
|
315 |
-
after parsing.
|
316 |
-
|
317 |
-
|
318 |
-
1.0.1k (26 Sep 2007):
|
319 |
-
|
320 |
-
* Fixed a problem introduced in 1.0.1i where three or more identical
|
321 |
-
uppercase letters, as well as a few other symbols, would trigger
|
322 |
-
a horizontal line.
|
323 |
-
|
324 |
-
|
325 |
-
1.0.1j (4 Sep 2007):
|
326 |
-
|
327 |
-
* Fixed a problem introduced in 1.0.1i where the closing `code` and
|
328 |
-
`pre` tags at the end of a code block were appearing in the wrong
|
329 |
-
order.
|
330 |
-
|
331 |
-
* Overriding configuration settings by defining constants from an
|
332 |
-
external before markdown.php is included is now possible without
|
333 |
-
producing a PHP warning.
|
334 |
-
|
335 |
-
|
336 |
-
1.0.1i (31 Aug 2007):
|
337 |
-
|
338 |
-
* Fixed a problem where an escaped backslash before a code span
|
339 |
-
would prevent the code span from being created. This should now
|
340 |
-
work as expected:
|
341 |
-
|
342 |
-
Litteral backslash: \\`code span`
|
343 |
-
|
344 |
-
* Overall speed improvements, especially with long documents.
|
345 |
-
|
346 |
-
|
347 |
-
1.0.1h (3 Aug 2007):
|
348 |
-
|
349 |
-
* Added two properties (`no_markup` and `no_entities`) to the parser
|
350 |
-
allowing HTML tags and entities to be disabled.
|
351 |
-
|
352 |
-
* Fix for a problem introduced in 1.0.1g where posting comments in
|
353 |
-
WordPress would trigger PHP warnings and cause some markup to be
|
354 |
-
incorrectly filtered by the kses filter in WordPress.
|
355 |
-
|
356 |
-
|
357 |
-
1.0.1g (3 Jul 2007):
|
358 |
-
|
359 |
-
* Fix for PHP 5 compiled without the mbstring module. Previous fix to
|
360 |
-
calculate the length of UTF-8 strings in `detab` when `mb_strlen` is
|
361 |
-
not available was only working with PHP 4.
|
362 |
-
|
363 |
-
* Fixed a problem with WordPress 2.x where full-content posts in RSS feeds
|
364 |
-
were not processed correctly by Markdown.
|
365 |
-
|
366 |
-
* Now supports URLs containing literal parentheses for inline links
|
367 |
-
and images, such as:
|
368 |
-
|
369 |
-
[WIMP](http://en.wikipedia.org/wiki/WIMP_(computing))
|
370 |
-
|
371 |
-
Such parentheses may be arbitrarily nested, but must be
|
372 |
-
balanced. Unbalenced parentheses are allowed however when the URL
|
373 |
-
when escaped or when the URL is enclosed in angle brakets `<>`.
|
374 |
-
|
375 |
-
* Fixed a performance problem where the regular expression for strong
|
376 |
-
emphasis introduced in version 1.0.1d could sometime be long to process,
|
377 |
-
give slightly wrong results, and in some circumstances could remove
|
378 |
-
entirely the content for a whole paragraph.
|
379 |
-
|
380 |
-
* Some change in version 1.0.1d made possible the incorrect nesting of
|
381 |
-
anchors within each other. This is now fixed.
|
382 |
-
|
383 |
-
* Fixed a rare issue where certain MD5 hashes in the content could
|
384 |
-
be changed to their corresponding text. For instance, this:
|
385 |
-
|
386 |
-
The MD5 value for "+" is "26b17225b626fb9238849fd60eabdf60".
|
387 |
-
|
388 |
-
was incorrectly changed to this in previous versions of PHP Markdown:
|
389 |
-
|
390 |
-
<p>The MD5 value for "+" is "+".</p>
|
391 |
-
|
392 |
-
* Now convert escaped characters to their numeric character
|
393 |
-
references equivalent.
|
394 |
-
|
395 |
-
This fix an integration issue with SmartyPants and backslash escapes.
|
396 |
-
Since Markdown and SmartyPants have some escapable characters in common,
|
397 |
-
it was sometime necessary to escape them twice. Previously, two
|
398 |
-
backslashes were sometime required to prevent Markdown from "eating" the
|
399 |
-
backslash before SmartyPants sees it:
|
400 |
-
|
401 |
-
Here are two hyphens: \\--
|
402 |
-
|
403 |
-
Now, only one backslash will do:
|
404 |
-
|
405 |
-
Here are two hyphens: \--
|
406 |
-
|
407 |
-
|
408 |
-
1.0.1f (7 Feb 2007):
|
409 |
-
|
410 |
-
* Fixed an issue with WordPress where manually-entered excerpts, but
|
411 |
-
not the auto-generated ones, would contain nested paragraphs.
|
412 |
-
|
413 |
-
* Fixed an issue introduced in 1.0.1d where headers and blockquotes
|
414 |
-
preceded too closely by a paragraph (not separated by a blank line)
|
415 |
-
where incorrectly put inside the paragraph.
|
416 |
-
|
417 |
-
* Fixed an issue introduced in 1.0.1d in the tokenizeHTML method where
|
418 |
-
two consecutive code spans would be merged into one when together they
|
419 |
-
form a valid tag in a multiline paragraph.
|
420 |
-
|
421 |
-
* Fixed an long-prevailing issue where blank lines in code blocks would
|
422 |
-
be doubled when the code block is in a list item.
|
423 |
-
|
424 |
-
This was due to the list processing functions relying on artificially
|
425 |
-
doubled blank lines to correctly determine when list items should
|
426 |
-
contain block-level content. The list item processing model was thus
|
427 |
-
changed to avoid the need for double blank lines.
|
428 |
-
|
429 |
-
* Fixed an issue with `<% asp-style %>` instructions used as inline
|
430 |
-
content where the opening `<` was encoded as `<`.
|
431 |
-
|
432 |
-
* Fixed a parse error occuring when PHP is configured to accept
|
433 |
-
ASP-style delimiters as boundaries for PHP scripts.
|
434 |
-
|
435 |
-
* Fixed a bug introduced in 1.0.1d where underscores in automatic links
|
436 |
-
got swapped with emphasis tags.
|
437 |
-
|
438 |
-
|
439 |
-
1.0.1e (28 Dec 2006)
|
440 |
-
|
441 |
-
* Added support for internationalized domain names for email addresses in
|
442 |
-
automatic link. Improved the speed at which email addresses are converted
|
443 |
-
to entities. Thanks to Milian Wolff for his optimisations.
|
444 |
-
|
445 |
-
* Made deterministic the conversion to entities of email addresses in
|
446 |
-
automatic links. This means that a given email address will always be
|
447 |
-
encoded the same way.
|
448 |
-
|
449 |
-
* PHP Markdown will now use its own function to calculate the length of an
|
450 |
-
UTF-8 string in `detab` when `mb_strlen` is not available instead of
|
451 |
-
giving a fatal error.
|
452 |
-
|
453 |
-
|
454 |
-
1.0.1d (1 Dec 2006)
|
455 |
-
|
456 |
-
* Fixed a bug where inline images always had an empty title attribute. The
|
457 |
-
title attribute is now present only when explicitly defined.
|
458 |
-
|
459 |
-
* Link references definitions can now have an empty title, previously if the
|
460 |
-
title was defined but left empty the link definition was ignored. This can
|
461 |
-
be useful if you want an empty title attribute in images to hide the
|
462 |
-
tooltip in Internet Explorer.
|
463 |
-
|
464 |
-
* Made `detab` aware of UTF-8 characters. UTF-8 multi-byte sequences are now
|
465 |
-
correctly mapped to one character instead of the number of bytes.
|
466 |
-
|
467 |
-
* Fixed a small bug with WordPress where WordPress' default filter `wpautop`
|
468 |
-
was not properly deactivated on comment text, resulting in hard line breaks
|
469 |
-
where Markdown do not prescribes them.
|
470 |
-
|
471 |
-
* Added a `TextileRestrited` method to the textile compatibility mode. There
|
472 |
-
is no restriction however, as Markdown does not have a restricted mode at
|
473 |
-
this point. This should make PHP Markdown work again in the latest
|
474 |
-
versions of TextPattern.
|
475 |
-
|
476 |
-
* Converted PHP Markdown to a object-oriented design.
|
477 |
-
|
478 |
-
* Changed span and block gamut methods so that they loop over a
|
479 |
-
customizable list of methods. This makes subclassing the parser a more
|
480 |
-
interesting option for creating syntax extensions.
|
481 |
-
|
482 |
-
* Also added a "document" gamut loop which can be used to hook document-level
|
483 |
-
methods (like for striping link definitions).
|
484 |
-
|
485 |
-
* Changed all methods which were inserting HTML code so that they now return
|
486 |
-
a hashed representation of the code. New methods `hashSpan` and `hashBlock`
|
487 |
-
are used to hash respectivly span- and block-level generated content. This
|
488 |
-
has a couple of significant effects:
|
489 |
-
|
490 |
-
1. It prevents invalid nesting of Markdown-generated elements which
|
491 |
-
could occur occuring with constructs like `*something [link*][1]`.
|
492 |
-
2. It prevents problems occuring with deeply nested lists on which
|
493 |
-
paragraphs were ill-formed.
|
494 |
-
3. It removes the need to call `hashHTMLBlocks` twice during the the
|
495 |
-
block gamut.
|
496 |
-
|
497 |
-
Hashes are turned back to HTML prior output.
|
498 |
-
|
499 |
-
* Made the block-level HTML parser smarter using a specially-crafted regular
|
500 |
-
expression capable of handling nested tags.
|
501 |
-
|
502 |
-
* Solved backtick issues in tag attributes by rewriting the HTML tokenizer to
|
503 |
-
be aware of code spans. All these lines should work correctly now:
|
504 |
-
|
505 |
-
<span attr='`ticks`'>bar</span>
|
506 |
-
<span attr='``double ticks``'>bar</span>
|
507 |
-
`<test a="` content of attribute `">`
|
508 |
-
|
509 |
-
* Changed the parsing of HTML comments to match simply from `<!--` to `-->`
|
510 |
-
instead using of the more complicated SGML-style rule with paired `--`.
|
511 |
-
This is how most browsers parse comments and how XML defines them too.
|
512 |
-
|
513 |
-
* `<address>` has been added to the list of block-level elements and is now
|
514 |
-
treated as an HTML block instead of being wrapped within paragraph tags.
|
515 |
-
|
516 |
-
* Now only trim trailing newlines from code blocks, instead of trimming
|
517 |
-
all trailing whitespace characters.
|
518 |
-
|
519 |
-
* Fixed bug where this:
|
520 |
-
|
521 |
-
[text](http://m.com "title" )
|
522 |
-
|
523 |
-
wasn't working as expected, because the parser wasn't allowing for spaces
|
524 |
-
before the closing paren.
|
525 |
-
|
526 |
-
* Filthy hack to support markdown='1' in div tags.
|
527 |
-
|
528 |
-
* _DoAutoLinks() now supports the 'dict://' URL scheme.
|
529 |
-
|
530 |
-
* PHP- and ASP-style processor instructions are now protected as
|
531 |
-
raw HTML blocks.
|
532 |
-
|
533 |
-
<? ... ?>
|
534 |
-
<% ... %>
|
535 |
-
|
536 |
-
* Fix for escaped backticks still triggering code spans:
|
537 |
-
|
538 |
-
There are two raw backticks here: \` and here: \`, not a code span
|
539 |
-
|
540 |
-
|
541 |
-
1.0.1c (9 Dec 2005)
|
542 |
-
|
543 |
-
* Fixed a problem occurring with PHP 5.1.1 due to a small
|
544 |
-
change to strings variable replacement behaviour in
|
545 |
-
this version.
|
546 |
-
|
547 |
-
|
548 |
-
1.0.1b (6 Jun 2005)
|
549 |
-
|
550 |
-
* Fixed a bug where an inline image followed by a reference link would
|
551 |
-
give a completely wrong result.
|
552 |
-
|
553 |
-
* Fix for escaped backticks still triggering code spans:
|
554 |
-
|
555 |
-
There are two raw backticks here: \` and here: \`, not a code span
|
556 |
-
|
557 |
-
* Fix for an ordered list following an unordered list, and the
|
558 |
-
reverse. There is now a loop in _DoList that does the two
|
559 |
-
separately.
|
560 |
-
|
561 |
-
* Fix for nested sub-lists in list-paragraph mode. Previously we got
|
562 |
-
a spurious extra level of `<p>` tags for something like this:
|
563 |
-
|
564 |
-
* this
|
565 |
-
|
566 |
-
* sub
|
567 |
-
|
568 |
-
that
|
569 |
-
|
570 |
-
* Fixed some incorrect behaviour with emphasis. This will now work
|
571 |
-
as it should:
|
572 |
-
|
573 |
-
*test **thing***
|
574 |
-
**test *thing***
|
575 |
-
***thing* test**
|
576 |
-
***thing** test*
|
577 |
-
|
578 |
-
Name: __________
|
579 |
-
Address: _______
|
580 |
-
|
581 |
-
* Correct a small bug in `_TokenizeHTML` where a Doctype declaration
|
582 |
-
was not seen as HTML.
|
583 |
-
|
584 |
-
* Major rewrite of the WordPress integration code that should
|
585 |
-
correct many problems by preventing default WordPress filters from
|
586 |
-
tampering with Markdown-formatted text. More details here:
|
587 |
-
<http://michelf.ca/weblog/2005/wordpress-text-flow-vs-markdown/>
|
588 |
-
|
589 |
-
|
590 |
-
1.0.1a (15 Apr 2005)
|
591 |
-
|
592 |
-
* Fixed an issue where PHP warnings were trigged when converting
|
593 |
-
text with list items running on PHP 4.0.6. This was comming from
|
594 |
-
the `rtrim` function which did not support the second argument
|
595 |
-
prior version 4.1. Replaced by a regular expression.
|
596 |
-
|
597 |
-
* Markdown now filter correctly post excerpts and comment
|
598 |
-
excerpts in WordPress.
|
599 |
-
|
600 |
-
* Automatic links and some code sample were "corrected" by
|
601 |
-
the balenceTag filter in WordPress meant to ensure HTML
|
602 |
-
is well formed. This new version of PHP Markdown postpone this
|
603 |
-
filter so that it runs after Markdown.
|
604 |
-
|
605 |
-
* Blockquote syntax and some code sample were stripped by
|
606 |
-
a new WordPress 1.5 filter meant to remove unwanted HTML
|
607 |
-
in comments. This new version of PHP Markdown postpone this
|
608 |
-
filter so that it runs after Markdown.
|
609 |
-
|
610 |
-
|
611 |
-
1.0.1 (16 Dec 2004):
|
612 |
-
|
613 |
-
* Changed the syntax rules for code blocks and spans. Previously,
|
614 |
-
backslash escapes for special Markdown characters were processed
|
615 |
-
everywhere other than within inline HTML tags. Now, the contents of
|
616 |
-
code blocks and spans are no longer processed for backslash escapes.
|
617 |
-
This means that code blocks and spans are now treated literally,
|
618 |
-
with no special rules to worry about regarding backslashes.
|
619 |
-
|
620 |
-
**IMPORTANT**: This breaks the syntax from all previous versions of
|
621 |
-
Markdown. Code blocks and spans involving backslash characters will
|
622 |
-
now generate different output than before.
|
623 |
-
|
624 |
-
Implementation-wise, this change was made by moving the call to
|
625 |
-
`_EscapeSpecialChars()` from the top-level `Markdown()` function to
|
626 |
-
within `_RunSpanGamut()`.
|
627 |
-
|
628 |
-
* Significants performance improvement in `_DoHeader`, `_Detab`
|
629 |
-
and `_TokenizeHTML`.
|
630 |
-
|
631 |
-
* Added `>`, `+`, and `-` to the list of backslash-escapable
|
632 |
-
characters. These should have been done when these characters
|
633 |
-
were added as unordered list item markers.
|
634 |
-
|
635 |
-
* Inline links using `<` and `>` URL delimiters weren't working:
|
636 |
-
|
637 |
-
like [this](<http://example.com/>)
|
638 |
-
|
639 |
-
Fixed by moving `_DoAutoLinks()` after `_DoAnchors()` in
|
640 |
-
`_RunSpanGamut()`.
|
641 |
-
|
642 |
-
* Fixed bug where auto-links were being processed within code spans:
|
643 |
-
|
644 |
-
like this: `<http://example.com/>`
|
645 |
-
|
646 |
-
Fixed by moving `_DoAutoLinks()` from `_RunBlockGamut()` to
|
647 |
-
`_RunSpanGamut()`.
|
648 |
-
|
649 |
-
* Sort-of fixed a bug where lines in the middle of hard-wrapped
|
650 |
-
paragraphs, which lines look like the start of a list item,
|
651 |
-
would accidentally trigger the creation of a list. E.g. a
|
652 |
-
paragraph that looked like this:
|
653 |
-
|
654 |
-
I recommend upgrading to version
|
655 |
-
8. Oops, now this line is treated
|
656 |
-
as a sub-list.
|
657 |
-
|
658 |
-
This is fixed for top-level lists, but it can still happen for
|
659 |
-
sub-lists. E.g., the following list item will not be parsed
|
660 |
-
properly:
|
661 |
-
|
662 |
-
* I recommend upgrading to version
|
663 |
-
8. Oops, now this line is treated
|
664 |
-
as a sub-list.
|
665 |
-
|
666 |
-
Given Markdown's list-creation rules, I'm not sure this can
|
667 |
-
be fixed.
|
668 |
-
|
669 |
-
* Fix for horizontal rules preceded by 2 or 3 spaces or followed by
|
670 |
-
trailing spaces and tabs.
|
671 |
-
|
672 |
-
* Standalone HTML comments are now handled; previously, they'd get
|
673 |
-
wrapped in a spurious `<p>` tag.
|
674 |
-
|
675 |
-
* `_HashHTMLBlocks()` now tolerates trailing spaces and tabs following
|
676 |
-
HTML comments and `<hr/>` tags.
|
677 |
-
|
678 |
-
* Changed special case pattern for hashing `<hr>` tags in
|
679 |
-
`_HashHTMLBlocks()` so that they must occur within three spaces
|
680 |
-
of left margin. (With 4 spaces or a tab, they should be
|
681 |
-
code blocks, but weren't before this fix.)
|
682 |
-
|
683 |
-
* Auto-linked email address can now optionally contain
|
684 |
-
a 'mailto:' protocol. I.e. these are equivalent:
|
685 |
-
|
686 |
-
<mailto:user@example.com>
|
687 |
-
<user@example.com>
|
688 |
-
|
689 |
-
* Fixed annoying bug where nested lists would wind up with
|
690 |
-
spurious (and invalid) `<p>` tags.
|
691 |
-
|
692 |
-
* Changed `_StripLinkDefinitions()` so that link definitions must
|
693 |
-
occur within three spaces of the left margin. Thus if you indent
|
694 |
-
a link definition by four spaces or a tab, it will now be a code
|
695 |
-
block.
|
696 |
-
|
697 |
-
* You can now write empty links:
|
698 |
-
|
699 |
-
[like this]()
|
700 |
-
|
701 |
-
and they'll be turned into anchor tags with empty href attributes.
|
702 |
-
This should have worked before, but didn't.
|
703 |
-
|
704 |
-
* `***this***` and `___this___` are now turned into
|
705 |
-
|
706 |
-
<strong><em>this</em></strong>
|
707 |
-
|
708 |
-
Instead of
|
709 |
-
|
710 |
-
<strong><em>this</strong></em>
|
711 |
-
|
712 |
-
which isn't valid.
|
713 |
-
|
714 |
-
* Fixed problem for links defined with urls that include parens, e.g.:
|
715 |
-
|
716 |
-
[1]: http://sources.wikipedia.org/wiki/Middle_East_Policy_(Chomsky)
|
717 |
-
|
718 |
-
"Chomsky" was being erroneously treated as the URL's title.
|
719 |
-
|
720 |
-
* Double quotes in the title of an inline link used to give strange
|
721 |
-
results (incorrectly made entities). Fixed.
|
722 |
-
|
723 |
-
* Tabs are now correctly changed into spaces. Previously, only
|
724 |
-
the first tab was converted. In code blocks, the second one was too,
|
725 |
-
but was not always correctly aligned.
|
726 |
-
|
727 |
-
* Fixed a bug where a tab character inserted after a quote on the same
|
728 |
-
line could add a slash before the quotes.
|
729 |
-
|
730 |
-
This is "before" [tab] and "after" a tab.
|
731 |
-
|
732 |
-
Previously gave this result:
|
733 |
-
|
734 |
-
<p>This is \"before\" [tab] and "after" a tab.</p>
|
735 |
-
|
736 |
-
* Removed a call to `htmlentities`. This fixes a bug where multibyte
|
737 |
-
characters present in the title of a link reference could lead to
|
738 |
-
invalid utf-8 characters.
|
739 |
-
|
740 |
-
* Changed a regular expression in `_TokenizeHTML` that could lead to
|
741 |
-
a segmentation fault with PHP 4.3.8 on Linux.
|
742 |
-
|
743 |
-
* Fixed some notices that could show up if PHP error reporting
|
744 |
-
E_NOTICE flag was set.
|
745 |
-
|
746 |
-
|
747 |
-
Copyright and License
|
748 |
-
---------------------
|
749 |
-
|
750 |
-
PHP Markdown
|
751 |
-
Copyright (c) 2004-2013 Michel Fortin
|
752 |
-
<http://michelf.ca/>
|
753 |
-
All rights reserved.
|
754 |
-
|
755 |
-
Based on Markdown
|
756 |
-
Copyright (c) 2003-2006 John Gruber
|
757 |
-
<http://daringfireball.net/>
|
758 |
-
All rights reserved.
|
759 |
-
|
760 |
-
Redistribution and use in source and binary forms, with or without
|
761 |
-
modification, are permitted provided that the following conditions are
|
762 |
-
met:
|
763 |
-
|
764 |
-
* Redistributions of source code must retain the above copyright notice,
|
765 |
-
this list of conditions and the following disclaimer.
|
766 |
-
|
767 |
-
* Redistributions in binary form must reproduce the above copyright
|
768 |
-
notice, this list of conditions and the following disclaimer in the
|
769 |
-
documentation and/or other materials provided with the distribution.
|
770 |
-
|
771 |
-
* Neither the name "Markdown" nor the names of its contributors may
|
772 |
-
be used to endorse or promote products derived from this software
|
773 |
-
without specific prior written permission.
|
774 |
-
|
775 |
-
This software is provided by the copyright holders and contributors "as
|
776 |
-
is" and any express or implied warranties, including, but not limited
|
777 |
-
to, the implied warranties of merchantability and fitness for a
|
778 |
-
particular purpose are disclaimed. In no event shall the copyright owner
|
779 |
-
or contributors be liable for any direct, indirect, incidental, special,
|
780 |
-
exemplary, or consequential damages (including, but not limited to,
|
781 |
-
procurement of substitute goods or services; loss of use, data, or
|
782 |
-
profits; or business interruption) however caused and on any theory of
|
783 |
-
liability, whether in contract, strict liability, or tort (including
|
784 |
-
negligence or otherwise) arising in any way out of the use of this
|
785 |
-
software, even if advised of the possibility of such damage.
|
1 |
+
PHP Markdown
|
2 |
+
============
|
3 |
+
|
4 |
+
Version 1.0.1p - 11 Apr 2013
|
5 |
+
|
6 |
+
by Michel Fortin
|
7 |
+
<http://michelf.ca/>
|
8 |
+
|
9 |
+
based on work by John Gruber
|
10 |
+
<http://daringfireball.net/>
|
11 |
+
|
12 |
+
|
13 |
+
Introduction
|
14 |
+
------------
|
15 |
+
|
16 |
+
Markdown is a text-to-HTML conversion tool for web writers. Markdown
|
17 |
+
allows you to write using an easy-to-read, easy-to-write plain text
|
18 |
+
format, then convert it to structurally valid XHTML (or HTML).
|
19 |
+
|
20 |
+
"Markdown" is two things: a plain text markup syntax, and a software
|
21 |
+
tool, written in Perl, that converts the plain text markup to HTML.
|
22 |
+
PHP Markdown is a port to PHP of the original Markdown program by
|
23 |
+
John Gruber.
|
24 |
+
|
25 |
+
PHP Markdown can work as a plug-in for WordPress, as a modifier for
|
26 |
+
the Smarty templating engine, or as a replacement for Textile
|
27 |
+
formatting in any software that supports Textile.
|
28 |
+
|
29 |
+
Full documentation of Markdown's syntax is available on John's
|
30 |
+
Markdown page: <http://daringfireball.net/projects/markdown/>
|
31 |
+
|
32 |
+
|
33 |
+
Installation and Requirement
|
34 |
+
----------------------------
|
35 |
+
|
36 |
+
PHP Markdown requires PHP version 4.0.5 or later.
|
37 |
+
|
38 |
+
Before PHP 5.3.7, pcre.backtrack_limit defaults to 100 000, which is too small
|
39 |
+
in many situations. You might need to set it to higher values. Later PHP
|
40 |
+
releases defaults to 1 000 000, which is usually fine.
|
41 |
+
|
42 |
+
|
43 |
+
### WordPress ###
|
44 |
+
|
45 |
+
PHP Markdown works with [WordPress][wp], version 1.2 or later.
|
46 |
+
|
47 |
+
[wp]: http://wordpress.org/
|
48 |
+
|
49 |
+
1. To use PHP Markdown with WordPress, place the "markdown.php" file
|
50 |
+
in the "plugins" folder. This folder is located inside
|
51 |
+
"wp-content" at the root of your site:
|
52 |
+
|
53 |
+
(site home)/wp-content/plugins/
|
54 |
+
|
55 |
+
2. Activate the plugin with the administrative interface of
|
56 |
+
WordPress. In the "Plugins" section you will now find Markdown.
|
57 |
+
To activate the plugin, click on the "Activate" button on the
|
58 |
+
same line as Markdown. Your entries will now be formatted by
|
59 |
+
PHP Markdown.
|
60 |
+
|
61 |
+
3. To post Markdown content, you'll first have to disable the
|
62 |
+
"visual" editor in the User section of WordPress.
|
63 |
+
|
64 |
+
You can configure PHP Markdown to not apply to the comments on your
|
65 |
+
WordPress weblog. See the "Configuration" section below.
|
66 |
+
|
67 |
+
It is not possible at this time to apply a different set of
|
68 |
+
filters to different entries. All your entries will be formatted by
|
69 |
+
PHP Markdown. This is a limitation of WordPress. If your old entries
|
70 |
+
are written in HTML (as opposed to another formatting syntax, like
|
71 |
+
Textile), they'll probably stay fine after installing Markdown.
|
72 |
+
|
73 |
+
|
74 |
+
### Replacing Textile in TextPattern ###
|
75 |
+
|
76 |
+
[TextPattern][tp] use [Textile][tx] to format your text. You can
|
77 |
+
replace Textile by Markdown in TextPattern without having to change
|
78 |
+
any code by using the *Textile Compatibility Mode*. This may work
|
79 |
+
with other software that expect Textile too.
|
80 |
+
|
81 |
+
[tx]: http://www.textism.com/tools/textile/
|
82 |
+
[tp]: http://www.textpattern.com/
|
83 |
+
|
84 |
+
1. Rename the "markdown.php" file to "classTextile.php". This will
|
85 |
+
make PHP Markdown behave as if it was the actual Textile parser.
|
86 |
+
|
87 |
+
2. Replace the "classTextile.php" file TextPattern installed in your
|
88 |
+
web directory. It can be found in the "lib" directory:
|
89 |
+
|
90 |
+
(site home)/textpattern/lib/
|
91 |
+
|
92 |
+
Contrary to Textile, Markdown does not convert quotes to curly ones
|
93 |
+
and does not convert multiple hyphens (`--` and `---`) into en- and
|
94 |
+
em-dashes. If you use PHP Markdown in Textile Compatibility Mode, you
|
95 |
+
can solve this problem by installing the "smartypants.php" file from
|
96 |
+
[PHP SmartyPants][psp] beside the "classTextile.php" file. The Textile
|
97 |
+
Compatibility Mode function will use SmartyPants automatically without
|
98 |
+
further modification.
|
99 |
+
|
100 |
+
[psp]: http://michelf.ca/projects/php-smartypants/
|
101 |
+
|
102 |
+
|
103 |
+
### Updating Markdown in Other Programs ###
|
104 |
+
|
105 |
+
Many web applications now ship with PHP Markdown, or have plugins to
|
106 |
+
perform the conversion to HTML. You can update PHP Markdown in many of
|
107 |
+
these programs by swapping the old "markdown.php" file for the new one.
|
108 |
+
|
109 |
+
Here is a short non-exhaustive list of some programs and where they
|
110 |
+
hide the "markdown.php" file.
|
111 |
+
|
112 |
+
| Program | Path to Markdown
|
113 |
+
| ------- | ----------------
|
114 |
+
| [Pivot][] | `(site home)/pivot/includes/markdown/markdown.php`
|
115 |
+
|
116 |
+
If you're unsure if you can do this with your application, ask the
|
117 |
+
developer, or wait for the developer to update his application or
|
118 |
+
plugin with the new version of PHP Markdown.
|
119 |
+
|
120 |
+
[Pivot]: http://pivotlog.net/
|
121 |
+
|
122 |
+
|
123 |
+
### In Your Own Programs ###
|
124 |
+
|
125 |
+
You can use PHP Markdown easily in your current PHP program. Simply
|
126 |
+
include the file and then call the Markdown function on the text you
|
127 |
+
want to convert:
|
128 |
+
|
129 |
+
include_once "markdown.php";
|
130 |
+
$my_html = Markdown($my_text);
|
131 |
+
|
132 |
+
If you wish to use PHP Markdown with another text filter function
|
133 |
+
built to parse HTML, you should filter the text *after* the Markdown
|
134 |
+
function call. This is an example with [PHP SmartyPants][psp]:
|
135 |
+
|
136 |
+
$my_html = SmartyPants(Markdown($my_text));
|
137 |
+
|
138 |
+
|
139 |
+
### With Smarty ###
|
140 |
+
|
141 |
+
If your program use the [Smarty][sm] template engine, PHP Markdown
|
142 |
+
can now be used as a modifier for your templates. Rename "markdown.php"
|
143 |
+
to "modifier.markdown.php" and put it in your smarty plugins folder.
|
144 |
+
|
145 |
+
[sm]: http://smarty.php.net/
|
146 |
+
|
147 |
+
If you are using MovableType 3.1 or later, the Smarty plugin folder is
|
148 |
+
located at `(MT CGI root)/php/extlib/smarty/plugins`. This will allow
|
149 |
+
Markdown to work on dynamic pages.
|
150 |
+
|
151 |
+
|
152 |
+
Configuration
|
153 |
+
-------------
|
154 |
+
|
155 |
+
By default, PHP Markdown produces XHTML output for tags with empty
|
156 |
+
elements. E.g.:
|
157 |
+
|
158 |
+
<br />
|
159 |
+
|
160 |
+
Markdown can be configured to produce HTML-style tags; e.g.:
|
161 |
+
|
162 |
+
<br>
|
163 |
+
|
164 |
+
To do this, you must edit the "MARKDOWN_EMPTY_ELEMENT_SUFFIX"
|
165 |
+
definition below the "Global default settings" header at the start of
|
166 |
+
the "markdown.php" file.
|
167 |
+
|
168 |
+
|
169 |
+
### WordPress-Specific Settings ###
|
170 |
+
|
171 |
+
By default, the Markdown plugin applies to both posts and comments on
|
172 |
+
your WordPress weblog. To deactivate one or the other, edit the
|
173 |
+
`MARKDOWN_WP_POSTS` or `MARKDOWN_WP_COMMENTS` definitions under the
|
174 |
+
"WordPress settings" header at the start of the "markdown.php" file.
|
175 |
+
|
176 |
+
|
177 |
+
Bugs
|
178 |
+
----
|
179 |
+
|
180 |
+
To file bug reports please send email to:
|
181 |
+
<michel.fortin@michelf.ca>
|
182 |
+
|
183 |
+
Please include with your report: (1) the example input; (2) the output you
|
184 |
+
expected; (3) the output PHP Markdown actually produced.
|
185 |
+
|
186 |
+
If you have a problem where Markdown gives you an empty result, first check
|
187 |
+
that the backtrack limit is not too low by running `php --info | grep pcre`.
|
188 |
+
See Installation and Requirement above for details.
|
189 |
+
|
190 |
+
|
191 |
+
Version History
|
192 |
+
---------------
|
193 |
+
|
194 |
+
1.0.1q (11 Apr 2013):
|
195 |
+
|
196 |
+
* Fixed a small mistake that could cause the parser to retain an invalid
|
197 |
+
state related to parsing links across multiple runs. This was never
|
198 |
+
observed (that I know of), but it's still worth fixing.
|
199 |
+
|
200 |
+
|
201 |
+
1.0.1p (13 Jan 2013):
|
202 |
+
|
203 |
+
* Fixed an issue where some XML-style empty tags (such as `<br/>`) were not
|
204 |
+
recognized correctly as such when inserted into Markdown-formatted text.
|
205 |
+
|
206 |
+
* The following HTML 5 elements are treated as block elements when at the
|
207 |
+
root of an HTML block: `article`, `section`, `nav`, `aside`, `hgroup`,
|
208 |
+
`header`, `footer`, and `figure`. `svg` too.
|
209 |
+
|
210 |
+
|
211 |
+
1.0.1o (8 Jan 2012):
|
212 |
+
|
213 |
+
* Silenced a new warning introduced around PHP 5.3 complaining about
|
214 |
+
POSIX characters classes not being implemented. PHP Markdown does not
|
215 |
+
use POSIX character classes, but it nevertheless trigged that warning.
|
216 |
+
|
217 |
+
|
218 |
+
1.0.1n (10 Oct 2009):
|
219 |
+
|
220 |
+
* Enabled reference-style shortcut links. Now you can write reference-style
|
221 |
+
links with less brakets:
|
222 |
+
|
223 |
+
This is [my website].
|
224 |
+
|
225 |
+
[my website]: http://example.com/
|
226 |
+
|
227 |
+
This was added in the 1.0.2 betas, but commented out in the 1.0.1 branch,
|
228 |
+
waiting for the feature to be officialized. [But half of the other Markdown
|
229 |
+
implementations are supporting this syntax][half], so it makes sense for
|
230 |
+
compatibility's sake to allow it in PHP Markdown too.
|
231 |
+
|
232 |
+
[half]: http://babelmark.bobtfish.net/?markdown=This+is+%5Bmy+website%5D.%0D%0A%09%09%0D%0A%5Bmy+website%5D%3A+http%3A%2F%2Fexample.com%2F%0D%0A&src=1&dest=2
|
233 |
+
|
234 |
+
* Now accepting many valid email addresses in autolinks that were
|
235 |
+
previously rejected, such as:
|
236 |
+
|
237 |
+
<abc+mailbox/department=shipping@example.com>
|
238 |
+
<!#$%&'*+-/=?^_`.{|}~@example.com>
|
239 |
+
<"abc@def"@example.com>
|
240 |
+
<"Fred Bloggs"@example.com>
|
241 |
+
<jsmith@[192.0.2.1]>
|
242 |
+
|
243 |
+
* Now accepting spaces in URLs for inline and reference-style links. Such
|
244 |
+
URLs need to be surrounded by angle brakets. For instance:
|
245 |
+
|
246 |
+
[link text](<http://url/with space> "optional title")
|
247 |
+
|
248 |
+
[link text][ref]
|
249 |
+
[ref]: <http://url/with space> "optional title"
|
250 |
+
|
251 |
+
There is still a quirk which may prevent this from working correctly with
|
252 |
+
relative URLs in inline-style links however.
|
253 |
+
|
254 |
+
* Fix for adjacent list of different kind where the second list could
|
255 |
+
end as a sublist of the first when not separated by an empty line.
|
256 |
+
|
257 |
+
* Fixed a bug where inline-style links wouldn't be recognized when the link
|
258 |
+
definition contains a line break between the url and the title.
|
259 |
+
|
260 |
+
* Fixed a bug where tags where the name contains an underscore aren't parsed
|
261 |
+
correctly.
|
262 |
+
|
263 |
+
* Fixed some corner-cases mixing underscore-ephasis and asterisk-emphasis.
|
264 |
+
|
265 |
+
|
266 |
+
1.0.1m (21 Jun 2008):
|
267 |
+
|
268 |
+
* Lists can now have empty items.
|
269 |
+
|
270 |
+
* Rewrote the emphasis and strong emphasis parser to fix some issues
|
271 |
+
with odly placed and overlong markers.
|
272 |
+
|
273 |
+
|
274 |
+
1.0.1l (11 May 2008):
|
275 |
+
|
276 |
+
* Now removing the UTF-8 BOM at the start of a document, if present.
|
277 |
+
|
278 |
+
* Now accepting capitalized URI schemes (such as HTTP:) in automatic
|
279 |
+
links, such as `<HTTP://EXAMPLE.COM/>`.
|
280 |
+
|
281 |
+
* Fixed a problem where `<hr@example.com>` was seen as a horizontal
|
282 |
+
rule instead of an automatic link.
|
283 |
+
|
284 |
+
* Fixed an issue where some characters in Markdown-generated HTML
|
285 |
+
attributes weren't properly escaped with entities.
|
286 |
+
|
287 |
+
* Fix for code blocks as first element of a list item. Previously,
|
288 |
+
this didn't create any code block for item 2:
|
289 |
+
|
290 |
+
* Item 1 (regular paragraph)
|
291 |
+
|
292 |
+
* Item 2 (code block)
|
293 |
+
|
294 |
+
* A code block starting on the second line of a document wasn't seen
|
295 |
+
as a code block. This has been fixed.
|
296 |
+
|
297 |
+
* Added programatically-settable parser properties `predef_urls` and
|
298 |
+
`predef_titles` for predefined URLs and titles for reference-style
|
299 |
+
links. To use this, your PHP code must call the parser this way:
|
300 |
+
|
301 |
+
$parser = new Markdwon_Parser;
|
302 |
+
$parser->predef_urls = array('linkref' => 'http://example.com');
|
303 |
+
$html = $parser->transform($text);
|
304 |
+
|
305 |
+
You can then use the URL as a normal link reference:
|
306 |
+
|
307 |
+
[my link][linkref]
|
308 |
+
[my link][linkRef]
|
309 |
+
|
310 |
+
Reference names in the parser properties *must* be lowercase.
|
311 |
+
Reference names in the Markdown source may have any case.
|
312 |
+
|
313 |
+
* Added `setup` and `teardown` methods which can be used by subclassers
|
314 |
+
as hook points to arrange the state of some parser variables before and
|
315 |
+
after parsing.
|
316 |
+
|
317 |
+
|
318 |
+
1.0.1k (26 Sep 2007):
|
319 |
+
|
320 |
+
* Fixed a problem introduced in 1.0.1i where three or more identical
|
321 |
+
uppercase letters, as well as a few other symbols, would trigger
|
322 |
+
a horizontal line.
|
323 |
+
|
324 |
+
|
325 |
+
1.0.1j (4 Sep 2007):
|
326 |
+
|
327 |
+
* Fixed a problem introduced in 1.0.1i where the closing `code` and
|
328 |
+
`pre` tags at the end of a code block were appearing in the wrong
|
329 |
+
order.
|
330 |
+
|
331 |
+
* Overriding configuration settings by defining constants from an
|
332 |
+
external before markdown.php is included is now possible without
|
333 |
+
producing a PHP warning.
|
334 |
+
|
335 |
+
|
336 |
+
1.0.1i (31 Aug 2007):
|
337 |
+
|
338 |
+
* Fixed a problem where an escaped backslash before a code span
|
339 |
+
would prevent the code span from being created. This should now
|
340 |
+
work as expected:
|
341 |
+
|
342 |
+
Litteral backslash: \\`code span`
|
343 |
+
|
344 |
+
* Overall speed improvements, especially with long documents.
|
345 |
+
|
346 |
+
|
347 |
+
1.0.1h (3 Aug 2007):
|
348 |
+
|
349 |
+
* Added two properties (`no_markup` and `no_entities`) to the parser
|
350 |
+
allowing HTML tags and entities to be disabled.
|
351 |
+
|
352 |
+
* Fix for a problem introduced in 1.0.1g where posting comments in
|
353 |
+
WordPress would trigger PHP warnings and cause some markup to be
|
354 |
+
incorrectly filtered by the kses filter in WordPress.
|
355 |
+
|
356 |
+
|
357 |
+
1.0.1g (3 Jul 2007):
|
358 |
+
|
359 |
+
* Fix for PHP 5 compiled without the mbstring module. Previous fix to
|
360 |
+
calculate the length of UTF-8 strings in `detab` when `mb_strlen` is
|
361 |
+
not available was only working with PHP 4.
|
362 |
+
|
363 |
+
* Fixed a problem with WordPress 2.x where full-content posts in RSS feeds
|
364 |
+
were not processed correctly by Markdown.
|
365 |
+
|
366 |
+
* Now supports URLs containing literal parentheses for inline links
|
367 |
+
and images, such as:
|
368 |
+
|
369 |
+
[WIMP](http://en.wikipedia.org/wiki/WIMP_(computing))
|
370 |
+
|
371 |
+
Such parentheses may be arbitrarily nested, but must be
|
372 |
+
balanced. Unbalenced parentheses are allowed however when the URL
|
373 |
+
when escaped or when the URL is enclosed in angle brakets `<>`.
|
374 |
+
|
375 |
+
* Fixed a performance problem where the regular expression for strong
|
376 |
+
emphasis introduced in version 1.0.1d could sometime be long to process,
|
377 |
+
give slightly wrong results, and in some circumstances could remove
|
378 |
+
entirely the content for a whole paragraph.
|
379 |
+
|
380 |
+
* Some change in version 1.0.1d made possible the incorrect nesting of
|
381 |
+
anchors within each other. This is now fixed.
|
382 |
+
|
383 |
+
* Fixed a rare issue where certain MD5 hashes in the content could
|
384 |
+
be changed to their corresponding text. For instance, this:
|
385 |
+
|
386 |
+
The MD5 value for "+" is "26b17225b626fb9238849fd60eabdf60".
|
387 |
+
|
388 |
+
was incorrectly changed to this in previous versions of PHP Markdown:
|
389 |
+
|
390 |
+
<p>The MD5 value for "+" is "+".</p>
|
391 |
+
|
392 |
+
* Now convert escaped characters to their numeric character
|
393 |
+
references equivalent.
|
394 |
+
|
395 |
+
This fix an integration issue with SmartyPants and backslash escapes.
|
396 |
+
Since Markdown and SmartyPants have some escapable characters in common,
|
397 |
+
it was sometime necessary to escape them twice. Previously, two
|
398 |
+
backslashes were sometime required to prevent Markdown from "eating" the
|
399 |
+
backslash before SmartyPants sees it:
|
400 |
+
|
401 |
+
Here are two hyphens: \\--
|
402 |
+
|
403 |
+
Now, only one backslash will do:
|
404 |
+
|
405 |
+
Here are two hyphens: \--
|
406 |
+
|
407 |
+
|
408 |
+
1.0.1f (7 Feb 2007):
|
409 |
+
|
410 |
+
* Fixed an issue with WordPress where manually-entered excerpts, but
|
411 |
+
not the auto-generated ones, would contain nested paragraphs.
|
412 |
+
|
413 |
+
* Fixed an issue introduced in 1.0.1d where headers and blockquotes
|
414 |
+
preceded too closely by a paragraph (not separated by a blank line)
|
415 |
+
where incorrectly put inside the paragraph.
|
416 |
+
|
417 |
+
* Fixed an issue introduced in 1.0.1d in the tokenizeHTML method where
|
418 |
+
two consecutive code spans would be merged into one when together they
|
419 |
+
form a valid tag in a multiline paragraph.
|
420 |
+
|
421 |
+
* Fixed an long-prevailing issue where blank lines in code blocks would
|
422 |
+
be doubled when the code block is in a list item.
|
423 |
+
|
424 |
+
This was due to the list processing functions relying on artificially
|
425 |
+
doubled blank lines to correctly determine when list items should
|
426 |
+
contain block-level content. The list item processing model was thus
|
427 |
+
changed to avoid the need for double blank lines.
|
428 |
+
|
429 |
+
* Fixed an issue with `<% asp-style %>` instructions used as inline
|
430 |
+
content where the opening `<` was encoded as `<`.
|
431 |
+
|
432 |
+
* Fixed a parse error occuring when PHP is configured to accept
|
433 |
+
ASP-style delimiters as boundaries for PHP scripts.
|
434 |
+
|
435 |
+
* Fixed a bug introduced in 1.0.1d where underscores in automatic links
|
436 |
+
got swapped with emphasis tags.
|
437 |
+
|
438 |
+
|
439 |
+
1.0.1e (28 Dec 2006)
|
440 |
+
|
441 |
+
* Added support for internationalized domain names for email addresses in
|
442 |
+
automatic link. Improved the speed at which email addresses are converted
|
443 |
+
to entities. Thanks to Milian Wolff for his optimisations.
|
444 |
+
|
445 |
+
* Made deterministic the conversion to entities of email addresses in
|
446 |
+
automatic links. This means that a given email address will always be
|
447 |
+
encoded the same way.
|
448 |
+
|
449 |
+
* PHP Markdown will now use its own function to calculate the length of an
|
450 |
+
UTF-8 string in `detab` when `mb_strlen` is not available instead of
|
451 |
+
giving a fatal error.
|
452 |
+
|
453 |
+
|
454 |
+
1.0.1d (1 Dec 2006)
|
455 |
+
|
456 |
+
* Fixed a bug where inline images always had an empty title attribute. The
|
457 |
+
title attribute is now present only when explicitly defined.
|
458 |
+
|
459 |
+
* Link references definitions can now have an empty title, previously if the
|
460 |
+
title was defined but left empty the link definition was ignored. This can
|
461 |
+
be useful if you want an empty title attribute in images to hide the
|
462 |
+
tooltip in Internet Explorer.
|
463 |
+
|
464 |
+
* Made `detab` aware of UTF-8 characters. UTF-8 multi-byte sequences are now
|
465 |
+
correctly mapped to one character instead of the number of bytes.
|
466 |
+
|
467 |
+
* Fixed a small bug with WordPress where WordPress' default filter `wpautop`
|
468 |
+
was not properly deactivated on comment text, resulting in hard line breaks
|
469 |
+
where Markdown do not prescribes them.
|
470 |
+
|
471 |
+
* Added a `TextileRestrited` method to the textile compatibility mode. There
|
472 |
+
is no restriction however, as Markdown does not have a restricted mode at
|
473 |
+
this point. This should make PHP Markdown work again in the latest
|
474 |
+
versions of TextPattern.
|
475 |
+
|
476 |
+
* Converted PHP Markdown to a object-oriented design.
|
477 |
+
|
478 |
+
* Changed span and block gamut methods so that they loop over a
|
479 |
+
customizable list of methods. This makes subclassing the parser a more
|
480 |
+
interesting option for creating syntax extensions.
|
481 |
+
|
482 |
+
* Also added a "document" gamut loop which can be used to hook document-level
|
483 |
+
methods (like for striping link definitions).
|
484 |
+
|
485 |
+
* Changed all methods which were inserting HTML code so that they now return
|
486 |
+
a hashed representation of the code. New methods `hashSpan` and `hashBlock`
|
487 |
+
are used to hash respectivly span- and block-level generated content. This
|
488 |
+
has a couple of significant effects:
|
489 |
+
|
490 |
+
1. It prevents invalid nesting of Markdown-generated elements which
|
491 |
+
could occur occuring with constructs like `*something [link*][1]`.
|
492 |
+
2. It prevents problems occuring with deeply nested lists on which
|
493 |
+
paragraphs were ill-formed.
|
494 |
+
3. It removes the need to call `hashHTMLBlocks` twice during the the
|
495 |
+
block gamut.
|
496 |
+
|
497 |
+
Hashes are turned back to HTML prior output.
|
498 |
+
|
499 |
+
* Made the block-level HTML parser smarter using a specially-crafted regular
|
500 |
+
expression capable of handling nested tags.
|
501 |
+
|
502 |
+
* Solved backtick issues in tag attributes by rewriting the HTML tokenizer to
|
503 |
+
be aware of code spans. All these lines should work correctly now:
|
504 |
+
|
505 |
+
<span attr='`ticks`'>bar</span>
|
506 |
+
<span attr='``double ticks``'>bar</span>
|
507 |
+
`<test a="` content of attribute `">`
|
508 |
+
|
509 |
+
* Changed the parsing of HTML comments to match simply from `<!--` to `-->`
|
510 |
+
instead using of the more complicated SGML-style rule with paired `--`.
|
511 |
+
This is how most browsers parse comments and how XML defines them too.
|
512 |
+
|
513 |
+
* `<address>` has been added to the list of block-level elements and is now
|
514 |
+
treated as an HTML block instead of being wrapped within paragraph tags.
|
515 |
+
|
516 |
+
* Now only trim trailing newlines from code blocks, instead of trimming
|
517 |
+
all trailing whitespace characters.
|
518 |
+
|
519 |
+
* Fixed bug where this:
|
520 |
+
|
521 |
+
[text](http://m.com "title" )
|
522 |
+
|
523 |
+
wasn't working as expected, because the parser wasn't allowing for spaces
|
524 |
+
before the closing paren.
|
525 |
+
|
526 |
+
* Filthy hack to support markdown='1' in div tags.
|
527 |
+
|
528 |
+
* _DoAutoLinks() now supports the 'dict://' URL scheme.
|
529 |
+
|
530 |
+
* PHP- and ASP-style processor instructions are now protected as
|
531 |
+
raw HTML blocks.
|
532 |
+
|
533 |
+
<? ... ?>
|
534 |
+
<% ... %>
|
535 |
+
|
536 |
+
* Fix for escaped backticks still triggering code spans:
|
537 |
+
|
538 |
+
There are two raw backticks here: \` and here: \`, not a code span
|
539 |
+
|
540 |
+
|
541 |
+
1.0.1c (9 Dec 2005)
|
542 |
+
|
543 |
+
* Fixed a problem occurring with PHP 5.1.1 due to a small
|
544 |
+
change to strings variable replacement behaviour in
|
545 |
+
this version.
|
546 |
+
|
547 |
+
|
548 |
+
1.0.1b (6 Jun 2005)
|
549 |
+
|
550 |
+
* Fixed a bug where an inline image followed by a reference link would
|
551 |
+
give a completely wrong result.
|
552 |
+
|
553 |
+
* Fix for escaped backticks still triggering code spans:
|
554 |
+
|
555 |
+
There are two raw backticks here: \` and here: \`, not a code span
|
556 |
+
|
557 |
+
* Fix for an ordered list following an unordered list, and the
|
558 |
+
reverse. There is now a loop in _DoList that does the two
|
559 |
+
separately.
|
560 |
+
|
561 |
+
* Fix for nested sub-lists in list-paragraph mode. Previously we got
|
562 |
+
a spurious extra level of `<p>` tags for something like this:
|
563 |
+
|
564 |
+
* this
|
565 |
+
|
566 |
+
* sub
|
567 |
+
|
568 |
+
that
|
569 |
+
|
570 |
+
* Fixed some incorrect behaviour with emphasis. This will now work
|
571 |
+
as it should:
|
572 |
+
|
573 |
+
*test **thing***
|
574 |
+
**test *thing***
|
575 |
+
***thing* test**
|
576 |
+
***thing** test*
|
577 |
+
|
578 |
+
Name: __________
|
579 |
+
Address: _______
|
580 |
+
|
581 |
+
* Correct a small bug in `_TokenizeHTML` where a Doctype declaration
|
582 |
+
was not seen as HTML.
|
583 |
+
|
584 |
+
* Major rewrite of the WordPress integration code that should
|
585 |
+
correct many problems by preventing default WordPress filters from
|
586 |
+
tampering with Markdown-formatted text. More details here:
|
587 |
+
<http://michelf.ca/weblog/2005/wordpress-text-flow-vs-markdown/>
|
588 |
+
|
589 |
+
|
590 |
+
1.0.1a (15 Apr 2005)
|
591 |
+
|
592 |
+
* Fixed an issue where PHP warnings were trigged when converting
|
593 |
+
text with list items running on PHP 4.0.6. This was comming from
|
594 |
+
the `rtrim` function which did not support the second argument
|
595 |
+
prior version 4.1. Replaced by a regular expression.
|
596 |
+
|
597 |
+
* Markdown now filter correctly post excerpts and comment
|
598 |
+
excerpts in WordPress.
|
599 |
+
|
600 |
+
* Automatic links and some code sample were "corrected" by
|
601 |
+
the balenceTag filter in WordPress meant to ensure HTML
|
602 |
+
is well formed. This new version of PHP Markdown postpone this
|
603 |
+
filter so that it runs after Markdown.
|
604 |
+
|
605 |
+
* Blockquote syntax and some code sample were stripped by
|
606 |
+
a new WordPress 1.5 filter meant to remove unwanted HTML
|
607 |
+
in comments. This new version of PHP Markdown postpone this
|
608 |
+
filter so that it runs after Markdown.
|
609 |
+
|
610 |
+
|
611 |
+
1.0.1 (16 Dec 2004):
|
612 |
+
|
613 |
+
* Changed the syntax rules for code blocks and spans. Previously,
|
614 |
+
backslash escapes for special Markdown characters were processed
|
615 |
+
everywhere other than within inline HTML tags. Now, the contents of
|
616 |
+
code blocks and spans are no longer processed for backslash escapes.
|
617 |
+
This means that code blocks and spans are now treated literally,
|
618 |
+
with no special rules to worry about regarding backslashes.
|
619 |
+
|
620 |
+
**IMPORTANT**: This breaks the syntax from all previous versions of
|
621 |
+
Markdown. Code blocks and spans involving backslash characters will
|
622 |
+
now generate different output than before.
|
623 |
+
|
624 |
+
Implementation-wise, this change was made by moving the call to
|
625 |
+
`_EscapeSpecialChars()` from the top-level `Markdown()` function to
|
626 |
+
within `_RunSpanGamut()`.
|
627 |
+
|
628 |
+
* Significants performance improvement in `_DoHeader`, `_Detab`
|
629 |
+
and `_TokenizeHTML`.
|
630 |
+
|
631 |
+
* Added `>`, `+`, and `-` to the list of backslash-escapable
|
632 |
+
characters. These should have been done when these characters
|
633 |
+
were added as unordered list item markers.
|
634 |
+
|
635 |
+
* Inline links using `<` and `>` URL delimiters weren't working:
|
636 |
+
|
637 |
+
like [this](<http://example.com/>)
|
638 |
+
|
639 |
+
Fixed by moving `_DoAutoLinks()` after `_DoAnchors()` in
|
640 |
+
`_RunSpanGamut()`.
|
641 |
+
|
642 |
+
* Fixed bug where auto-links were being processed within code spans:
|
643 |
+
|
644 |
+
like this: `<http://example.com/>`
|
645 |
+
|
646 |
+
Fixed by moving `_DoAutoLinks()` from `_RunBlockGamut()` to
|
647 |
+
`_RunSpanGamut()`.
|
648 |
+
|
649 |
+
* Sort-of fixed a bug where lines in the middle of hard-wrapped
|
650 |
+
paragraphs, which lines look like the start of a list item,
|
651 |
+
would accidentally trigger the creation of a list. E.g. a
|
652 |
+
paragraph that looked like this:
|
653 |
+
|
654 |
+
I recommend upgrading to version
|
655 |
+
8. Oops, now this line is treated
|
656 |
+
as a sub-list.
|
657 |
+
|
658 |
+
This is fixed for top-level lists, but it can still happen for
|
659 |
+
sub-lists. E.g., the following list item will not be parsed
|
660 |
+
properly:
|
661 |
+
|
662 |
+
* I recommend upgrading to version
|
663 |
+
8. Oops, now this line is treated
|
664 |
+
as a sub-list.
|
665 |
+
|
666 |
+
Given Markdown's list-creation rules, I'm not sure this can
|
667 |
+
be fixed.
|
668 |
+
|
669 |
+
* Fix for horizontal rules preceded by 2 or 3 spaces or followed by
|
670 |
+
trailing spaces and tabs.
|
671 |
+
|
672 |
+
* Standalone HTML comments are now handled; previously, they'd get
|
673 |
+
wrapped in a spurious `<p>` tag.
|
674 |
+
|
675 |
+
* `_HashHTMLBlocks()` now tolerates trailing spaces and tabs following
|
676 |
+
HTML comments and `<hr/>` tags.
|
677 |
+
|
678 |
+
* Changed special case pattern for hashing `<hr>` tags in
|
679 |
+
`_HashHTMLBlocks()` so that they must occur within three spaces
|
680 |
+
of left margin. (With 4 spaces or a tab, they should be
|
681 |
+
code blocks, but weren't before this fix.)
|
682 |
+
|
683 |
+
* Auto-linked email address can now optionally contain
|
684 |
+
a 'mailto:' protocol. I.e. these are equivalent:
|
685 |
+
|
686 |
+
<mailto:user@example.com>
|
687 |
+
<user@example.com>
|
688 |
+
|
689 |
+
* Fixed annoying bug where nested lists would wind up with
|
690 |
+
spurious (and invalid) `<p>` tags.
|
691 |
+
|
692 |
+
* Changed `_StripLinkDefinitions()` so that link definitions must
|
693 |
+
occur within three spaces of the left margin. Thus if you indent
|
694 |
+
a link definition by four spaces or a tab, it will now be a code
|
695 |
+
block.
|
696 |
+
|
697 |
+
* You can now write empty links:
|
698 |
+
|
699 |
+
[like this]()
|
700 |
+
|
701 |
+
and they'll be turned into anchor tags with empty href attributes.
|
702 |
+
This should have worked before, but didn't.
|
703 |
+
|
704 |
+
* `***this***` and `___this___` are now turned into
|
705 |
+
|
706 |
+
<strong><em>this</em></strong>
|
707 |
+
|
708 |
+
Instead of
|
709 |
+
|
710 |
+
<strong><em>this</strong></em>
|
711 |
+
|
712 |
+
which isn't valid.
|
713 |
+
|
714 |
+
* Fixed problem for links defined with urls that include parens, e.g.:
|
715 |
+
|
716 |
+
[1]: http://sources.wikipedia.org/wiki/Middle_East_Policy_(Chomsky)
|
717 |
+
|
718 |
+
"Chomsky" was being erroneously treated as the URL's title.
|
719 |
+
|
720 |
+
* Double quotes in the title of an inline link used to give strange
|
721 |
+
results (incorrectly made entities). Fixed.
|
722 |
+
|
723 |
+
* Tabs are now correctly changed into spaces. Previously, only
|
724 |
+
the first tab was converted. In code blocks, the second one was too,
|
725 |
+
but was not always correctly aligned.
|
726 |
+
|
727 |
+
* Fixed a bug where a tab character inserted after a quote on the same
|
728 |
+
line could add a slash before the quotes.
|
729 |
+
|
730 |
+
This is "before" [tab] and "after" a tab.
|
731 |
+
|
732 |
+
Previously gave this result:
|
733 |
+
|
734 |
+
<p>This is \"before\" [tab] and "after" a tab.</p>
|
735 |
+
|
736 |
+
* Removed a call to `htmlentities`. This fixes a bug where multibyte
|
737 |
+
characters present in the title of a link reference could lead to
|
738 |
+
invalid utf-8 characters.
|
739 |
+
|
740 |
+
* Changed a regular expression in `_TokenizeHTML` that could lead to
|
741 |
+
a segmentation fault with PHP 4.3.8 on Linux.
|
742 |
+
|
743 |
+
* Fixed some notices that could show up if PHP error reporting
|
744 |
+
E_NOTICE flag was set.
|
745 |
+
|
746 |
+
|
747 |
+
Copyright and License
|
748 |
+
---------------------
|
749 |
+
|
750 |
+
PHP Markdown
|
751 |
+
Copyright (c) 2004-2013 Michel Fortin
|
752 |
+
<http://michelf.ca/>
|
753 |
+
All rights reserved.
|
754 |
+
|
755 |
+
Based on Markdown
|
756 |
+
Copyright (c) 2003-2006 John Gruber
|
757 |
+
<http://daringfireball.net/>
|
758 |
+
All rights reserved.
|
759 |
+
|
760 |
+
Redistribution and use in source and binary forms, with or without
|
761 |
+
modification, are permitted provided that the following conditions are
|
762 |
+
met:
|
763 |
+
|
764 |
+
* Redistributions of source code must retain the above copyright notice,
|
765 |
+
this list of conditions and the following disclaimer.
|
766 |
+
|
767 |
+
* Redistributions in binary form must reproduce the above copyright
|
768 |
+
notice, this list of conditions and the following disclaimer in the
|
769 |
+
documentation and/or other materials provided with the distribution.
|
770 |
+
|
771 |
+
* Neither the name "Markdown" nor the names of its contributors may
|
772 |
+
be used to endorse or promote products derived from this software
|
773 |
+
without specific prior written permission.
|
774 |
+
|
775 |
+
This software is provided by the copyright holders and contributors "as
|
776 |
+
is" and any express or implied warranties, including, but not limited
|
777 |
+
to, the implied warranties of merchantability and fitness for a
|
778 |
+
particular purpose are disclaimed. In no event shall the copyright owner
|
779 |
+
or contributors be liable for any direct, indirect, incidental, special,
|
780 |
+
exemplary, or consequential damages (including, but not limited to,
|
781 |
+
procurement of substitute goods or services; loss of use, data, or
|
782 |
+
profits; or business interruption) however caused and on any theory of
|
783 |
+
liability, whether in contract, strict liability, or tort (including
|
784 |
+
negligence or otherwise) arising in any way out of the use of this
|
785 |
+
software, even if advised of the possibility of such damage.
|
classes/styles-font-menu/classes/markdown/markdown.php
CHANGED
@@ -1,1743 +1,1743 @@
|
|
1 |
-
<?php
|
2 |
-
#
|
3 |
-
# Markdown - A text-to-HTML conversion tool for web writers
|
4 |
-
#
|
5 |
-
# PHP Markdown
|
6 |
-
# Copyright (c) 2004-2013 Michel Fortin
|
7 |
-
# <http://michelf.ca/projects/php-markdown/>
|
8 |
-
#
|
9 |
-
# Original Markdown
|
10 |
-
# Copyright (c) 2004-2006 John Gruber
|
11 |
-
# <http://daringfireball.net/projects/markdown/>
|
12 |
-
#
|
13 |
-
|
14 |
-
|
15 |
-
define( 'MARKDOWN_VERSION', "1.0.1q" ); # 11 Apr 2013
|
16 |
-
|
17 |
-
|
18 |
-
#
|
19 |
-
# Global default settings:
|
20 |
-
#
|
21 |
-
|
22 |
-
# Change to ">" for HTML output
|
23 |
-
@define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX', " />");
|
24 |
-
|
25 |
-
# Define the width of a tab for code blocks.
|
26 |
-
@define( 'MARKDOWN_TAB_WIDTH', 4 );
|
27 |
-
|
28 |
-
|
29 |
-
#
|
30 |
-
# WordPress settings:
|
31 |
-
#
|
32 |
-
|
33 |
-
# Change to false to remove Markdown from posts and/or comments.
|
34 |
-
@define( 'MARKDOWN_WP_POSTS', true );
|
35 |
-
@define( 'MARKDOWN_WP_COMMENTS', true );
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
### Standard Function Interface ###
|
40 |
-
|
41 |
-
@define( 'MARKDOWN_PARSER_CLASS', 'Markdown_Parser' );
|
42 |
-
|
43 |
-
function Markdown($text) {
|
44 |
-
#
|
45 |
-
# Initialize the parser and return the result of its transform method.
|
46 |
-
#
|
47 |
-
# Setup static parser variable.
|
48 |
-
static $parser;
|
49 |
-
if (!isset($parser)) {
|
50 |
-
$parser_class = MARKDOWN_PARSER_CLASS;
|
51 |
-
$parser = new $parser_class;
|
52 |
-
}
|
53 |
-
|
54 |
-
# Transform text using parser.
|
55 |
-
return $parser->transform($text);
|
56 |
-
}
|
57 |
-
|
58 |
-
|
59 |
-
### WordPress Plugin Interface ###
|
60 |
-
|
61 |
-
/*
|
62 |
-
Plugin Name: Markdown
|
63 |
-
Plugin URI: http://michelf.ca/projects/php-markdown/
|
64 |
-
Description: <a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.ca/projects/php-markdown/">More...</a>
|
65 |
-
Version: 1.0.1q
|
66 |
-
Author: Michel Fortin
|
67 |
-
Author URI: http://michelf.ca/
|
68 |
-
*/
|
69 |
-
|
70 |
-
if (isset($wp_version)) {
|
71 |
-
# More details about how it works here:
|
72 |
-
# <http://michelf.ca/weblog/2005/wordpress-text-flow-vs-markdown/>
|
73 |
-
|
74 |
-
# Post content and excerpts
|
75 |
-
# - Remove WordPress paragraph generator.
|
76 |
-
# - Run Markdown on excerpt, then remove all tags.
|
77 |
-
# - Add paragraph tag around the excerpt, but remove it for the excerpt rss.
|
78 |
-
if (MARKDOWN_WP_POSTS) {
|
79 |
-
remove_filter('the_content', 'wpautop');
|
80 |
-
remove_filter('the_content_rss', 'wpautop');
|
81 |
-
remove_filter('the_excerpt', 'wpautop');
|
82 |
-
add_filter('the_content', 'Markdown', 6);
|
83 |
-
add_filter('the_content_rss', 'Markdown', 6);
|
84 |
-
add_filter('get_the_excerpt', 'Markdown', 6);
|
85 |
-
add_filter('get_the_excerpt', 'trim', 7);
|
86 |
-
add_filter('the_excerpt', 'mdwp_add_p');
|
87 |
-
add_filter('the_excerpt_rss', 'mdwp_strip_p');
|
88 |
-
|
89 |
-
remove_filter('content_save_pre', 'balanceTags', 50);
|
90 |
-
remove_filter('excerpt_save_pre', 'balanceTags', 50);
|
91 |
-
add_filter('the_content', 'balanceTags', 50);
|
92 |
-
add_filter('get_the_excerpt', 'balanceTags', 9);
|
93 |
-
}
|
94 |
-
|
95 |
-
# Comments
|
96 |
-
# - Remove WordPress paragraph generator.
|
97 |
-
# - Remove WordPress auto-link generator.
|
98 |
-
# - Scramble important tags before passing them to the kses filter.
|
99 |
-
# - Run Markdown on excerpt then remove paragraph tags.
|
100 |
-
if (MARKDOWN_WP_COMMENTS) {
|
101 |
-
remove_filter('comment_text', 'wpautop', 30);
|
102 |
-
remove_filter('comment_text', 'make_clickable');
|
103 |
-
add_filter('pre_comment_content', 'Markdown', 6);
|
104 |
-
add_filter('pre_comment_content', 'mdwp_hide_tags', 8);
|
105 |
-
add_filter('pre_comment_content', 'mdwp_show_tags', 12);
|
106 |
-
add_filter('get_comment_text', 'Markdown', 6);
|
107 |
-
add_filter('get_comment_excerpt', 'Markdown', 6);
|
108 |
-
add_filter('get_comment_excerpt', 'mdwp_strip_p', 7);
|
109 |
-
|
110 |
-
global $mdwp_hidden_tags, $mdwp_placeholders;
|
111 |
-
$mdwp_hidden_tags = explode(' ',
|
112 |
-
'<p> </p> <pre> </pre> <ol> </ol> <ul> </ul> <li> </li>');
|
113 |
-
$mdwp_placeholders = explode(' ', str_rot13(
|
114 |
-
'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '.
|
115 |
-
'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli'));
|
116 |
-
}
|
117 |
-
|
118 |
-
function mdwp_add_p($text) {
|
119 |
-
if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) {
|
120 |
-
$text = '<p>'.$text.'</p>';
|
121 |
-
$text = preg_replace('{\n{2,}}', "</p>\n\n<p>", $text);
|
122 |
-
}
|
123 |
-
return $text;
|
124 |
-
}
|
125 |
-
|
126 |
-
function mdwp_strip_p($t) { return preg_replace('{</?p>}i', '', $t); }
|
127 |
-
|
128 |
-
function mdwp_hide_tags($text) {
|
129 |
-
global $mdwp_hidden_tags, $mdwp_placeholders;
|
130 |
-
return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text);
|
131 |
-
}
|
132 |
-
function mdwp_show_tags($text) {
|
133 |
-
global $mdwp_hidden_tags, $mdwp_placeholders;
|
134 |
-
return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text);
|
135 |
-
}
|
136 |
-
}
|
137 |
-
|
138 |
-
|
139 |
-
### bBlog Plugin Info ###
|
140 |
-
|
141 |
-
function identify_modifier_markdown() {
|
142 |
-
return array(
|
143 |
-
'name' => 'markdown',
|
144 |
-
'type' => 'modifier',
|
145 |
-
'nicename' => 'Markdown',
|
146 |
-
'description' => 'A text-to-HTML conversion tool for web writers',
|
147 |
-
'authors' => 'Michel Fortin and John Gruber',
|
148 |
-
'licence' => 'BSD-like',
|
149 |
-
'version' => MARKDOWN_VERSION,
|
150 |
-
'help' => '<a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.ca/projects/php-markdown/">More...</a>'
|
151 |
-
);
|
152 |
-
}
|
153 |
-
|
154 |
-
|
155 |
-
### Smarty Modifier Interface ###
|
156 |
-
|
157 |
-
function smarty_modifier_markdown($text) {
|
158 |
-
return Markdown($text);
|
159 |
-
}
|
160 |
-
|
161 |
-
|
162 |
-
### Textile Compatibility Mode ###
|
163 |
-
|
164 |
-
# Rename this file to "classTextile.php" and it can replace Textile everywhere.
|
165 |
-
|
166 |
-
if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) {
|
167 |
-
# Try to include PHP SmartyPants. Should be in the same directory.
|
168 |
-
@include_once 'smartypants.php';
|
169 |
-
# Fake Textile class. It calls Markdown instead.
|
170 |
-
class Textile {
|
171 |
-
function TextileThis($text, $lite='', $encode='') {
|
172 |
-
if ($lite == '' && $encode == '') $text = Markdown($text);
|
173 |
-
if (function_exists('SmartyPants')) $text = SmartyPants($text);
|
174 |
-
return $text;
|
175 |
-
}
|
176 |
-
# Fake restricted version: restrictions are not supported for now.
|
177 |
-
function TextileRestricted($text, $lite='', $noimage='') {
|
178 |
-
return $this->TextileThis($text, $lite);
|
179 |
-
}
|
180 |
-
# Workaround to ensure compatibility with TextPattern 4.0.3.
|
181 |
-
function blockLite($text) { return $text; }
|
182 |
-
}
|
183 |
-
}
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
#
|
188 |
-
# Markdown Parser Class
|
189 |
-
#
|
190 |
-
|
191 |
-
class Markdown_Parser {
|
192 |
-
|
193 |
-
### Configuration Variables ###
|
194 |
-
|
195 |
-
# Change to ">" for HTML output.
|
196 |
-
var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX;
|
197 |
-
var $tab_width = MARKDOWN_TAB_WIDTH;
|
198 |
-
|
199 |
-
# Change to `true` to disallow markup or entities.
|
200 |
-
var $no_markup = false;
|
201 |
-
var $no_entities = false;
|
202 |
-
|
203 |
-
# Predefined urls and titles for reference links and images.
|
204 |
-
var $predef_urls = array();
|
205 |
-
var $predef_titles = array();
|
206 |
-
|
207 |
-
|
208 |
-
### Parser Implementation ###
|
209 |
-
|
210 |
-
# Regex to match balanced [brackets].
|
211 |
-
# Needed to insert a maximum bracked depth while converting to PHP.
|
212 |
-
var $nested_brackets_depth = 6;
|
213 |
-
var $nested_brackets_re;
|
214 |
-
|
215 |
-
var $nested_url_parenthesis_depth = 4;
|
216 |
-
var $nested_url_parenthesis_re;
|
217 |
-
|
218 |
-
# Table of hash values for escaped characters:
|
219 |
-
var $escape_chars = '\`*_{}[]()>#+-.!';
|
220 |
-
var $escape_chars_re;
|
221 |
-
|
222 |
-
|
223 |
-
function Markdown_Parser() {
|
224 |
-
#
|
225 |
-
# Constructor function. Initialize appropriate member variables.
|
226 |
-
#
|
227 |
-
$this->_initDetab();
|
228 |
-
$this->prepareItalicsAndBold();
|
229 |
-
|
230 |
-
$this->nested_brackets_re =
|
231 |
-
str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth).
|
232 |
-
str_repeat('\])*', $this->nested_brackets_depth);
|
233 |
-
|
234 |
-
$this->nested_url_parenthesis_re =
|
235 |
-
str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth).
|
236 |
-
str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth);
|
237 |
-
|
238 |
-
$this->escape_chars_re = '['.preg_quote($this->escape_chars).']';
|
239 |
-
|
240 |
-
# Sort document, block, and span gamut in ascendent priority order.
|
241 |
-
asort($this->document_gamut);
|
242 |
-
asort($this->block_gamut);
|
243 |
-
asort($this->span_gamut);
|
244 |
-
}
|
245 |
-
|
246 |
-
|
247 |
-
# Internal hashes used during transformation.
|
248 |
-
var $urls = array();
|
249 |
-
var $titles = array();
|
250 |
-
var $html_hashes = array();
|
251 |
-
|
252 |
-
# Status flag to avoid invalid nesting.
|
253 |
-
var $in_anchor = false;
|
254 |
-
|
255 |
-
|
256 |
-
function setup() {
|
257 |
-
#
|
258 |
-
# Called before the transformation process starts to setup parser
|
259 |
-
# states.
|
260 |
-
#
|
261 |
-
# Clear global hashes.
|
262 |
-
$this->urls = $this->predef_urls;
|
263 |
-
$this->titles = $this->predef_titles;
|
264 |
-
$this->html_hashes = array();
|
265 |
-
|
266 |
-
$this->in_anchor = false;
|
267 |
-
}
|
268 |
-
|
269 |
-
function teardown() {
|
270 |
-
#
|
271 |
-
# Called after the transformation process to clear any variable
|
272 |
-
# which may be taking up memory unnecessarly.
|
273 |
-
#
|
274 |
-
$this->urls = array();
|
275 |
-
$this->titles = array();
|
276 |
-
$this->html_hashes = array();
|
277 |
-
}
|
278 |
-
|
279 |
-
|
280 |
-
function transform($text) {
|
281 |
-
#
|
282 |
-
# Main function. Performs some preprocessing on the input text
|
283 |
-
# and pass it through the document gamut.
|
284 |
-
#
|
285 |
-
$this->setup();
|
286 |
-
|
287 |
-
# Remove UTF-8 BOM and marker character in input, if present.
|
288 |
-
$text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text);
|
289 |
-
|
290 |
-
# Standardize line endings:
|
291 |
-
# DOS to Unix and Mac to Unix
|
292 |
-
$text = preg_replace('{\r\n?}', "\n", $text);
|
293 |
-
|
294 |
-
# Make sure $text ends with a couple of newlines:
|
295 |
-
$text .= "\n\n";
|
296 |
-
|
297 |
-
# Convert all tabs to spaces.
|
298 |
-
$text = $this->detab($text);
|
299 |
-
|
300 |
-
# Turn block-level HTML blocks into hash entries
|
301 |
-
$text = $this->hashHTMLBlocks($text);
|
302 |
-
|
303 |
-
# Strip any lines consisting only of spaces and tabs.
|
304 |
-
# This makes subsequent regexen easier to write, because we can
|
305 |
-
# match consecutive blank lines with /\n+/ instead of something
|
306 |
-
# contorted like /[ ]*\n+/ .
|
307 |
-
$text = preg_replace('/^[ ]+$/m', '', $text);
|
308 |
-
|
309 |
-
# Run document gamut methods.
|
310 |
-
foreach ($this->document_gamut as $method => $priority) {
|
311 |
-
$text = $this->$method($text);
|
312 |
-
}
|
313 |
-
|
314 |
-
$this->teardown();
|
315 |
-
|
316 |
-
return $text . "\n";
|
317 |
-
}
|
318 |
-
|
319 |
-
var $document_gamut = array(
|
320 |
-
# Strip link definitions, store in hashes.
|
321 |
-
"stripLinkDefinitions" => 20,
|
322 |
-
|
323 |
-
"runBasicBlockGamut" => 30,
|
324 |
-
);
|
325 |
-
|
326 |
-
|
327 |
-
function stripLinkDefinitions($text) {
|
328 |
-
#
|
329 |
-
# Strips link definitions from text, stores the URLs and titles in
|
330 |
-
# hash references.
|
331 |
-
#
|
332 |
-
$less_than_tab = $this->tab_width - 1;
|
333 |
-
|
334 |
-
# Link defs are in the form: ^[id]: url "optional title"
|
335 |
-
$text = preg_replace_callback('{
|
336 |
-
^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1
|
337 |
-
[ ]*
|
338 |
-
\n? # maybe *one* newline
|
339 |
-
[ ]*
|
340 |
-
(?:
|
341 |
-
<(.+?)> # url = $2
|
342 |
-
|
|
343 |
-
(\S+?) # url = $3
|
344 |
-
)
|
345 |
-
[ ]*
|
346 |
-
\n? # maybe one newline
|
347 |
-
[ ]*
|
348 |
-
(?:
|
349 |
-
(?<=\s) # lookbehind for whitespace
|
350 |
-
["(]
|
351 |
-
(.*?) # title = $4
|
352 |
-
[")]
|
353 |
-
[ ]*
|
354 |
-
)? # title is optional
|
355 |
-
(?:\n+|\Z)
|
356 |
-
}xm',
|
357 |
-
array(&$this, '_stripLinkDefinitions_callback'),
|
358 |
-
$text);
|
359 |
-
return $text;
|
360 |
-
}
|
361 |
-
function _stripLinkDefinitions_callback($matches) {
|
362 |
-
$link_id = strtolower($matches[1]);
|
363 |
-
$url = $matches[2] == '' ? $matches[3] : $matches[2];
|
364 |
-
$this->urls[$link_id] = $url;
|
365 |
-
$this->titles[$link_id] =& $matches[4];
|
366 |
-
return ''; # String that will replace the block
|
367 |
-
}
|
368 |
-
|
369 |
-
|
370 |
-
function hashHTMLBlocks($text) {
|
371 |
-
if ($this->no_markup) return $text;
|
372 |
-
|
373 |
-
$less_than_tab = $this->tab_width - 1;
|
374 |
-
|
375 |
-
# Hashify HTML blocks:
|
376 |
-
# We only want to do this for block-level HTML tags, such as headers,
|
377 |
-
# lists, and tables. That's because we still want to wrap <p>s around
|
378 |
-
# "paragraphs" that are wrapped in non-block-level tags, such as anchors,
|
379 |
-
# phrase emphasis, and spans. The list of tags we're looking for is
|
380 |
-
# hard-coded:
|
381 |
-
#
|
382 |
-
# * List "a" is made of tags which can be both inline or block-level.
|
383 |
-
# These will be treated block-level when the start tag is alone on
|
384 |
-
# its line, otherwise they're not matched here and will be taken as
|
385 |
-
# inline later.
|
386 |
-
# * List "b" is made of tags which are always block-level;
|
387 |
-
#
|
388 |
-
$block_tags_a_re = 'ins|del';
|
389 |
-
$block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'.
|
390 |
-
'script|noscript|form|fieldset|iframe|math|svg|'.
|
391 |
-
'article|section|nav|aside|hgroup|header|footer|'.
|
392 |
-
'figure';
|
393 |
-
|
394 |
-
# Regular expression for the content of a block tag.
|
395 |
-
$nested_tags_level = 4;
|
396 |
-
$attr = '
|
397 |
-
(?> # optional tag attributes
|
398 |
-
\s # starts with whitespace
|
399 |
-
(?>
|
400 |
-
[^>"/]+ # text outside quotes
|
401 |
-
|
|
402 |
-
/+(?!>) # slash not followed by ">"
|
403 |
-
|
|
404 |
-
"[^"]*" # text inside double quotes (tolerate ">")
|
405 |
-
|
|
406 |
-
\'[^\']*\' # text inside single quotes (tolerate ">")
|
407 |
-
)*
|
408 |
-
)?
|
409 |
-
';
|
410 |
-
$content =
|
411 |
-
str_repeat('
|
412 |
-
(?>
|
413 |
-
[^<]+ # content without tag
|
414 |
-
|
|
415 |
-
<\2 # nested opening tag
|
416 |
-
'.$attr.' # attributes
|
417 |
-
(?>
|
418 |
-
/>
|
419 |
-
|
|
420 |
-
>', $nested_tags_level). # end of opening tag
|
421 |
-
'.*?'. # last level nested tag content
|
422 |
-
str_repeat('
|
423 |
-
</\2\s*> # closing nested tag
|
424 |
-
)
|
425 |
-
|
|
426 |
-
<(?!/\2\s*> # other tags with a different name
|
427 |
-
)
|
428 |
-
)*',
|
429 |
-
$nested_tags_level);
|
430 |
-
$content2 = str_replace('\2', '\3', $content);
|
431 |
-
|
432 |
-
# First, look for nested blocks, e.g.:
|
433 |
-
# <div>
|
434 |
-
# <div>
|
435 |
-
# tags for inner block must be indented.
|
436 |
-
# </div>
|
437 |
-
# </div>
|
438 |
-
#
|
439 |
-
# The outermost tags must start at the left margin for this to match, and
|
440 |
-
# the inner nested divs must be indented.
|
441 |
-
# We need to do this before the next, more liberal match, because the next
|
442 |
-
# match will start at the first `<div>` and stop at the first `</div>`.
|
443 |
-
$text = preg_replace_callback('{(?>
|
444 |
-
(?>
|
445 |
-
(?<=\n\n) # Starting after a blank line
|
446 |
-
| # or
|
447 |
-
\A\n? # the beginning of the doc
|
448 |
-
)
|
449 |
-
( # save in $1
|
450 |
-
|
451 |
-
# Match from `\n<tag>` to `</tag>\n`, handling nested tags
|
452 |
-
# in between.
|
453 |
-
|
454 |
-
[ ]{0,'.$less_than_tab.'}
|
455 |
-
<('.$block_tags_b_re.')# start tag = $2
|
456 |
-
'.$attr.'> # attributes followed by > and \n
|
457 |
-
'.$content.' # content, support nesting
|
458 |
-
</\2> # the matching end tag
|
459 |
-
[ ]* # trailing spaces/tabs
|
460 |
-
(?=\n+|\Z) # followed by a newline or end of document
|
461 |
-
|
462 |
-
| # Special version for tags of group a.
|
463 |
-
|
464 |
-
[ ]{0,'.$less_than_tab.'}
|
465 |
-
<('.$block_tags_a_re.')# start tag = $3
|
466 |
-
'.$attr.'>[ ]*\n # attributes followed by >
|
467 |
-
'.$content2.' # content, support nesting
|
468 |
-
</\3> # the matching end tag
|
469 |
-
[ ]* # trailing spaces/tabs
|
470 |
-
(?=\n+|\Z) # followed by a newline or end of document
|
471 |
-
|
472 |
-
| # Special case just for <hr />. It was easier to make a special
|
473 |
-
# case than to make the other regex more complicated.
|
474 |
-
|
475 |
-
[ ]{0,'.$less_than_tab.'}
|
476 |
-
<(hr) # start tag = $2
|
477 |
-
'.$attr.' # attributes
|
478 |
-
/?> # the matching end tag
|
479 |
-
[ ]*
|
480 |
-
(?=\n{2,}|\Z) # followed by a blank line or end of document
|
481 |
-
|
482 |
-
| # Special case for standalone HTML comments:
|
483 |
-
|
484 |
-
[ ]{0,'.$less_than_tab.'}
|
485 |
-
(?s:
|
486 |
-
<!-- .*? -->
|
487 |
-
)
|
488 |
-
[ ]*
|
489 |
-
(?=\n{2,}|\Z) # followed by a blank line or end of document
|
490 |
-
|
491 |
-
| # PHP and ASP-style processor instructions (<? and <%)
|
492 |
-
|
493 |
-
[ ]{0,'.$less_than_tab.'}
|
494 |
-
(?s:
|
495 |
-
<([?%]) # $2
|
496 |
-
.*?
|
497 |
-
\2>
|
498 |
-
)
|
499 |
-
[ ]*
|
500 |
-
(?=\n{2,}|\Z) # followed by a blank line or end of document
|
501 |
-
|
502 |
-
)
|
503 |
-
)}Sxmi',
|
504 |
-
array(&$this, '_hashHTMLBlocks_callback'),
|
505 |
-
$text);
|
506 |
-
|
507 |
-
return $text;
|
508 |
-
}
|
509 |
-
function _hashHTMLBlocks_callback($matches) {
|
510 |
-
$text = $matches[1];
|
511 |
-
$key = $this->hashBlock($text);
|
512 |
-
return "\n\n$key\n\n";
|
513 |
-
}
|
514 |
-
|
515 |
-
|
516 |
-
function hashPart($text, $boundary = 'X') {
|
517 |
-
#
|
518 |
-
# Called whenever a tag must be hashed when a function insert an atomic
|
519 |
-
# element in the text stream. Passing $text to through this function gives
|
520 |
-
# a unique text-token which will be reverted back when calling unhash.
|
521 |
-
#
|
522 |
-
# The $boundary argument specify what character should be used to surround
|
523 |
-
# the token. By convension, "B" is used for block elements that needs not
|
524 |
-
# to be wrapped into paragraph tags at the end, ":" is used for elements
|
525 |
-
# that are word separators and "X" is used in the general case.
|
526 |
-
#
|
527 |
-
# Swap back any tag hash found in $text so we do not have to `unhash`
|
528 |
-
# multiple times at the end.
|
529 |
-
$text = $this->unhash($text);
|
530 |
-
|
531 |
-
# Then hash the block.
|
532 |
-
static $i = 0;
|
533 |
-
$key = "$boundary\x1A" . ++$i . $boundary;
|
534 |
-
$this->html_hashes[$key] = $text;
|
535 |
-
return $key; # String that will replace the tag.
|
536 |
-
}
|
537 |
-
|
538 |
-
|
539 |
-
function hashBlock($text) {
|
540 |
-
#
|
541 |
-
# Shortcut function for hashPart with block-level boundaries.
|
542 |
-
#
|
543 |
-
return $this->hashPart($text, 'B');
|
544 |
-
}
|
545 |
-
|
546 |
-
|
547 |
-
var $block_gamut = array(
|
548 |
-
#
|
549 |
-
# These are all the transformations that form block-level
|
550 |
-
# tags like paragraphs, headers, and list items.
|
551 |
-
#
|
552 |
-
"doHeaders" => 10,
|
553 |
-
"doHorizontalRules" => 20,
|
554 |
-
|
555 |
-
"doLists" => 40,
|
556 |
-
"doCodeBlocks" => 50,
|
557 |
-
"doBlockQuotes" => 60,
|
558 |
-
);
|
559 |
-
|
560 |
-
function runBlockGamut($text) {
|
561 |
-
#
|
562 |
-
# Run block gamut tranformations.
|
563 |
-
#
|
564 |
-
# We need to escape raw HTML in Markdown source before doing anything
|
565 |
-
# else. This need to be done for each block, and not only at the
|
566 |
-
# begining in the Markdown function since hashed blocks can be part of
|
567 |
-
# list items and could have been indented. Indented blocks would have
|
568 |
-
# been seen as a code block in a previous pass of hashHTMLBlocks.
|
569 |
-
$text = $this->hashHTMLBlocks($text);
|
570 |
-
|
571 |
-
return $this->runBasicBlockGamut($text);
|
572 |
-
}
|
573 |
-
|
574 |
-
function runBasicBlockGamut($text) {
|
575 |
-
#
|
576 |
-
# Run block gamut tranformations, without hashing HTML blocks. This is
|
577 |
-
# useful when HTML blocks are known to be already hashed, like in the first
|
578 |
-
# whole-document pass.
|
579 |
-
#
|
580 |
-
foreach ($this->block_gamut as $method => $priority) {
|
581 |
-
$text = $this->$method($text);
|
582 |
-
}
|
583 |
-
|
584 |
-
# Finally form paragraph and restore hashed blocks.
|
585 |
-
$text = $this->formParagraphs($text);
|
586 |
-
|
587 |
-
return $text;
|
588 |
-
}
|
589 |
-
|
590 |
-
|
591 |
-
function doHorizontalRules($text) {
|
592 |
-
# Do Horizontal Rules:
|
593 |
-
return preg_replace(
|
594 |
-
'{
|
595 |
-
^[ ]{0,3} # Leading space
|
596 |
-
([-*_]) # $1: First marker
|
597 |
-
(?> # Repeated marker group
|
598 |
-
[ ]{0,2} # Zero, one, or two spaces.
|
599 |
-
\1 # Marker character
|
600 |
-
){2,} # Group repeated at least twice
|
601 |
-
[ ]* # Tailing spaces
|
602 |
-
$ # End of line.
|
603 |
-
}mx',
|
604 |
-
"\n".$this->hashBlock("<hr$this->empty_element_suffix")."\n",
|
605 |
-
$text);
|
606 |
-
}
|
607 |
-
|
608 |
-
|
609 |
-
var $span_gamut = array(
|
610 |
-
#
|
611 |
-
# These are all the transformations that occur *within* block-level
|
612 |
-
# tags like paragraphs, headers, and list items.
|
613 |
-
#
|
614 |
-
# Process character escapes, code spans, and inline HTML
|
615 |
-
# in one shot.
|
616 |
-
"parseSpan" => -30,
|
617 |
-
|
618 |
-
# Process anchor and image tags. Images must come first,
|
619 |
-
# because ![foo][f] looks like an anchor.
|
620 |
-
"doImages" => 10,
|
621 |
-
"doAnchors" => 20,
|
622 |
-
|
623 |
-
# Make links out of things like `<http://example.com/>`
|
624 |
-
# Must come after doAnchors, because you can use < and >
|
625 |
-
# delimiters in inline links like [this](<url>).
|
626 |
-
"doAutoLinks" => 30,
|
627 |
-
"encodeAmpsAndAngles" => 40,
|
628 |
-
|
629 |
-
"doItalicsAndBold" => 50,
|
630 |
-
"doHardBreaks" => 60,
|
631 |
-
);
|
632 |
-
|
633 |
-
function runSpanGamut($text) {
|
634 |
-
#
|
635 |
-
# Run span gamut tranformations.
|
636 |
-
#
|
637 |
-
foreach ($this->span_gamut as $method => $priority) {
|
638 |
-
$text = $this->$method($text);
|
639 |
-
}
|
640 |
-
|
641 |
-
return $text;
|
642 |
-
}
|
643 |
-
|
644 |
-
|
645 |
-
function doHardBreaks($text) {
|
646 |
-
# Do hard breaks:
|
647 |
-
return preg_replace_callback('/ {2,}\n/',
|
648 |
-
array(&$this, '_doHardBreaks_callback'), $text);
|
649 |
-
}
|
650 |
-
function _doHardBreaks_callback($matches) {
|
651 |
-
return $this->hashPart("<br$this->empty_element_suffix\n");
|
652 |
-
}
|
653 |
-
|
654 |
-
|
655 |
-
function doAnchors($text) {
|
656 |
-
#
|
657 |
-
# Turn Markdown link shortcuts into XHTML <a> tags.
|
658 |
-
#
|
659 |
-
if ($this->in_anchor) return $text;
|
660 |
-
$this->in_anchor = true;
|
661 |
-
|
662 |
-
#
|
663 |
-
# First, handle reference-style links: [link text] [id]
|
664 |
-
#
|
665 |
-
$text = preg_replace_callback('{
|
666 |
-
( # wrap whole match in $1
|
667 |
-
\[
|
668 |
-
('.$this->nested_brackets_re.') # link text = $2
|
669 |
-
\]
|
670 |
-
|
671 |
-
[ ]? # one optional space
|
672 |
-
(?:\n[ ]*)? # one optional newline followed by spaces
|
673 |
-
|
674 |
-
\[
|
675 |
-
(.*?) # id = $3
|
676 |
-
\]
|
677 |
-
)
|
678 |
-
}xs',
|
679 |
-
array(&$this, '_doAnchors_reference_callback'), $text);
|
680 |
-
|
681 |
-
#
|
682 |
-
# Next, inline-style links: [link text](url "optional title")
|
683 |
-
#
|
684 |
-
$text = preg_replace_callback('{
|
685 |
-
( # wrap whole match in $1
|
686 |
-
\[
|
687 |
-
('.$this->nested_brackets_re.') # link text = $2
|
688 |
-
\]
|
689 |
-
\( # literal paren
|
690 |
-
[ \n]*
|
691 |
-
(?:
|
692 |
-
<(.+?)> # href = $3
|
693 |
-
|
|
694 |
-
('.$this->nested_url_parenthesis_re.') # href = $4
|
695 |
-
)
|
696 |
-
[ \n]*
|
697 |
-
( # $5
|
698 |
-
([\'"]) # quote char = $6
|
699 |
-
(.*?) # Title = $7
|
700 |
-
\6 # matching quote
|
701 |
-
[ \n]* # ignore any spaces/tabs between closing quote and )
|
702 |
-
)? # title is optional
|
703 |
-
\)
|
704 |
-
)
|
705 |
-
}xs',
|
706 |
-
array(&$this, '_doAnchors_inline_callback'), $text);
|
707 |
-
|
708 |
-
#
|
709 |
-
# Last, handle reference-style shortcuts: [link text]
|
710 |
-
# These must come last in case you've also got [link text][1]
|
711 |
-
# or [link text](/foo)
|
712 |
-
#
|
713 |
-
$text = preg_replace_callback('{
|
714 |
-
( # wrap whole match in $1
|
715 |
-
\[
|
716 |
-
([^\[\]]+) # link text = $2; can\'t contain [ or ]
|
717 |
-
\]
|
718 |
-
)
|
719 |
-
}xs',
|
720 |
-
array(&$this, '_doAnchors_reference_callback'), $text);
|
721 |
-
|
722 |
-
$this->in_anchor = false;
|
723 |
-
return $text;
|
724 |
-
}
|
725 |
-
function _doAnchors_reference_callback($matches) {
|
726 |
-
$whole_match = $matches[1];
|
727 |
-
$link_text = $matches[2];
|
728 |
-
$link_id =& $matches[3];
|
729 |
-
|
730 |
-
if ($link_id == "") {
|
731 |
-
# for shortcut links like [this][] or [this].
|
732 |
-
$link_id = $link_text;
|
733 |
-
}
|
734 |
-
|
735 |
-
# lower-case and turn embedded newlines into spaces
|
736 |
-
$link_id = strtolower($link_id);
|
737 |
-
$link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
|
738 |
-
|
739 |
-
if (isset($this->urls[$link_id])) {
|
740 |
-
$url = $this->urls[$link_id];
|
741 |
-
$url = $this->encodeAttribute($url);
|
742 |
-
|
743 |
-
$result = "<a href=\"$url\"";
|
744 |
-
if ( isset( $this->titles[$link_id] ) ) {
|
745 |
-
$title = $this->titles[$link_id];
|
746 |
-
$title = $this->encodeAttribute($title);
|
747 |
-
$result .= " title=\"$title\"";
|
748 |
-
}
|
749 |
-
|
750 |
-
$link_text = $this->runSpanGamut($link_text);
|
751 |
-
$result .= ">$link_text</a>";
|
752 |
-
$result = $this->hashPart($result);
|
753 |
-
}
|
754 |
-
else {
|
755 |
-
$result = $whole_match;
|
756 |
-
}
|
757 |
-
return $result;
|
758 |
-
}
|
759 |
-
function _doAnchors_inline_callback($matches) {
|
760 |
-
$whole_match = $matches[1];
|
761 |
-
$link_text = $this->runSpanGamut($matches[2]);
|
762 |
-
$url = $matches[3] == '' ? $matches[4] : $matches[3];
|
763 |
-
$title =& $matches[7];
|
764 |
-
|
765 |
-
$url = $this->encodeAttribute($url);
|
766 |
-
|
767 |
-
$result = "<a href=\"$url\"";
|
768 |
-
if (isset($title)) {
|
769 |
-
$title = $this->encodeAttribute($title);
|
770 |
-
$result .= " title=\"$title\"";
|
771 |
-
}
|
772 |
-
|
773 |
-
$link_text = $this->runSpanGamut($link_text);
|
774 |
-
$result .= ">$link_text</a>";
|
775 |
-
|
776 |
-
return $this->hashPart($result);
|
777 |
-
}
|
778 |
-
|
779 |
-
|
780 |
-
function doImages($text) {
|
781 |
-
#
|
782 |
-
# Turn Markdown image shortcuts into <img> tags.
|
783 |
-
#
|
784 |
-
#
|
785 |
-
# First, handle reference-style labeled images: ![alt text][id]
|
786 |
-
#
|
787 |
-
$text = preg_replace_callback('{
|
788 |
-
( # wrap whole match in $1
|
789 |
-
!\[
|
790 |
-
('.$this->nested_brackets_re.') # alt text = $2
|
791 |
-
\]
|
792 |
-
|
793 |
-
[ ]? # one optional space
|
794 |
-
(?:\n[ ]*)? # one optional newline followed by spaces
|
795 |
-
|
796 |
-
\[
|
797 |
-
(.*?) # id = $3
|
798 |
-
\]
|
799 |
-
|
800 |
-
)
|
801 |
-
}xs',
|
802 |
-
array(&$this, '_doImages_reference_callback'), $text);
|
803 |
-
|
804 |
-
#
|
805 |
-
# Next, handle inline images: ![alt text](url "optional title")
|
806 |
-
# Don't forget: encode * and _
|
807 |
-
#
|
808 |
-
$text = preg_replace_callback('{
|
809 |
-
( # wrap whole match in $1
|
810 |
-
!\[
|
811 |
-
('.$this->nested_brackets_re.') # alt text = $2
|
812 |
-
\]
|
813 |
-
\s? # One optional whitespace character
|
814 |
-
\( # literal paren
|
815 |
-
[ \n]*
|
816 |
-
(?:
|
817 |
-
<(\S*)> # src url = $3
|
818 |
-
|
|
819 |
-
('.$this->nested_url_parenthesis_re.') # src url = $4
|
820 |
-
)
|
821 |
-
[ \n]*
|
822 |
-
( # $5
|
823 |
-
([\'"]) # quote char = $6
|
824 |
-
(.*?) # title = $7
|
825 |
-
\6 # matching quote
|
826 |
-
[ \n]*
|
827 |
-
)? # title is optional
|
828 |
-
\)
|
829 |
-
)
|
830 |
-
}xs',
|
831 |
-
array(&$this, '_doImages_inline_callback'), $text);
|
832 |
-
|
833 |
-
return $text;
|
834 |
-
}
|
835 |
-
function _doImages_reference_callback($matches) {
|
836 |
-
$whole_match = $matches[1];
|
837 |
-
$alt_text = $matches[2];
|
838 |
-
$link_id = strtolower($matches[3]);
|
839 |
-
|
840 |
-
if ($link_id == "") {
|
841 |
-
$link_id = strtolower($alt_text); # for shortcut links like ![this][].
|
842 |
-
}
|
843 |
-
|
844 |
-
$alt_text = $this->encodeAttribute($alt_text);
|
845 |
-
if (isset($this->urls[$link_id])) {
|
846 |
-
$url = $this->encodeAttribute($this->urls[$link_id]);
|
847 |
-
$result = "<img src=\"$url\" alt=\"$alt_text\"";
|
848 |
-
if (isset($this->titles[$link_id])) {
|
849 |
-
$title = $this->titles[$link_id];
|
850 |
-
$title = $this->encodeAttribute($title);
|
851 |
-
$result .= " title=\"$title\"";
|
852 |
-
}
|
853 |
-
$result .= $this->empty_element_suffix;
|
854 |
-
$result = $this->hashPart($result);
|
855 |
-
}
|
856 |
-
else {
|
857 |
-
# If there's no such link ID, leave intact:
|
858 |
-
$result = $whole_match;
|
859 |
-
}
|
860 |
-
|
861 |
-
return $result;
|
862 |
-
}
|
863 |
-
function _doImages_inline_callback($matches) {
|
864 |
-
$whole_match = $matches[1];
|
865 |
-
$alt_text = $matches[2];
|
866 |
-
$url = $matches[3] == '' ? $matches[4] : $matches[3];
|
867 |
-
$title =& $matches[7];
|
868 |
-
|
869 |
-
$alt_text = $this->encodeAttribute($alt_text);
|
870 |
-
$url = $this->encodeAttribute($url);
|
871 |
-
$result = "<img src=\"$url\" alt=\"$alt_text\"";
|
872 |
-
if (isset($title)) {
|
873 |
-
$title = $this->encodeAttribute($title);
|
874 |
-
$result .= " title=\"$title\""; # $title already quoted
|
875 |
-
}
|
876 |
-
$result .= $this->empty_element_suffix;
|
877 |
-
|
878 |
-
return $this->hashPart($result);
|
879 |
-
}
|
880 |
-
|
881 |
-
|
882 |
-
function doHeaders($text) {
|
883 |
-
# Setext-style headers:
|
884 |
-
# Header 1
|
885 |
-
# ========
|
886 |
-
#
|
887 |
-
# Header 2
|
888 |
-
# --------
|
889 |
-
#
|
890 |
-
$text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
|
891 |
-
array(&$this, '_doHeaders_callback_setext'), $text);
|
892 |
-
|
893 |
-
# atx-style headers:
|
894 |
-
# # Header 1
|
895 |
-
# ## Header 2
|
896 |
-
# ## Header 2 with closing hashes ##
|
897 |
-
# ...
|
898 |
-
# ###### Header 6
|
899 |
-
#
|
900 |
-
$text = preg_replace_callback('{
|
901 |
-
^(\#{1,6}) # $1 = string of #\'s
|
902 |
-
[ ]*
|
903 |
-
(.+?) # $2 = Header text
|
904 |
-
[ ]*
|
905 |
-
\#* # optional closing #\'s (not counted)
|
906 |
-
\n+
|
907 |
-
}xm',
|
908 |
-
array(&$this, '_doHeaders_callback_atx'), $text);
|
909 |
-
|
910 |
-
return $text;
|
911 |
-
}
|
912 |
-
function _doHeaders_callback_setext($matches) {
|
913 |
-
# Terrible hack to check we haven't found an empty list item.
|
914 |
-
if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1]))
|
915 |
-
return $matches[0];
|
916 |
-
|
917 |
-
$level = $matches[2]{0} == '=' ? 1 : 2;
|
918 |
-
$block = "<h$level>".$this->runSpanGamut($matches[1])."</h$level>";
|
919 |
-
return "\n" . $this->hashBlock($block) . "\n\n";
|
920 |
-
}
|
921 |
-
function _doHeaders_callback_atx($matches) {
|
922 |
-
$level = strlen($matches[1]);
|
923 |
-
$block = "<h$level>".$this->runSpanGamut($matches[2])."</h$level>";
|
924 |
-
return "\n" . $this->hashBlock($block) . "\n\n";
|
925 |
-
}
|
926 |
-
|
927 |
-
|
928 |
-
function doLists($text) {
|
929 |
-
#
|
930 |
-
# Form HTML ordered (numbered) and unordered (bulleted) lists.
|
931 |
-
#
|
932 |
-
$less_than_tab = $this->tab_width - 1;
|
933 |
-
|
934 |
-
# Re-usable patterns to match list item bullets and number markers:
|
935 |
-
$marker_ul_re = '[*+-]';
|
936 |
-
$marker_ol_re = '\d+[\.]';
|
937 |
-
$marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
|
938 |
-
|
939 |
-
$markers_relist = array(
|
940 |
-
$marker_ul_re => $marker_ol_re,
|
941 |
-
$marker_ol_re => $marker_ul_re,
|
942 |
-
);
|
943 |
-
|
944 |
-
foreach ($markers_relist as $marker_re => $other_marker_re) {
|
945 |
-
# Re-usable pattern to match any entirel ul or ol list:
|
946 |
-
$whole_list_re = '
|
947 |
-
( # $1 = whole list
|
948 |
-
( # $2
|
949 |
-
([ ]{0,'.$less_than_tab.'}) # $3 = number of spaces
|
950 |
-
('.$marker_re.') # $4 = first list item marker
|
951 |
-
[ ]+
|
952 |
-
)
|
953 |
-
(?s:.+?)
|
954 |
-
( # $5
|
955 |
-
\z
|
956 |
-
|
|
957 |
-
\n{2,}
|
958 |
-
(?=\S)
|
959 |
-
(?! # Negative lookahead for another list item marker
|
960 |
-
[ ]*
|
961 |
-
'.$marker_re.'[ ]+
|
962 |
-
)
|
963 |
-
|
|
964 |
-
(?= # Lookahead for another kind of list
|
965 |
-
\n
|
966 |
-
\3 # Must have the same indentation
|
967 |
-
'.$other_marker_re.'[ ]+
|
968 |
-
)
|
969 |
-
)
|
970 |
-
)
|
971 |
-
'; // mx
|
972 |
-
|
973 |
-
# We use a different prefix before nested lists than top-level lists.
|
974 |
-
# See extended comment in _ProcessListItems().
|
975 |
-
|
976 |
-
if ($this->list_level) {
|
977 |
-
$text = preg_replace_callback('{
|
978 |
-
^
|
979 |
-
'.$whole_list_re.'
|
980 |
-
}mx',
|
981 |
-
array(&$this, '_doLists_callback'), $text);
|
982 |
-
}
|
983 |
-
else {
|
984 |
-
$text = preg_replace_callback('{
|
985 |
-
(?:(?<=\n)\n|\A\n?) # Must eat the newline
|
986 |
-
'.$whole_list_re.'
|
987 |
-
}mx',
|
988 |
-
array(&$this, '_doLists_callback'), $text);
|
989 |
-
}
|
990 |
-
}
|
991 |
-
|
992 |
-
return $text;
|
993 |
-
}
|
994 |
-
function _doLists_callback($matches) {
|
995 |
-
# Re-usable patterns to match list item bullets and number markers:
|
996 |
-
$marker_ul_re = '[*+-]';
|
997 |
-
$marker_ol_re = '\d+[\.]';
|
998 |
-
$marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
|
999 |
-
|
1000 |
-
$list = $matches[1];
|
1001 |
-
$list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol";
|
1002 |
-
|
1003 |
-
$marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
|
1004 |
-
|
1005 |
-
$list .= "\n";
|
1006 |
-
$result = $this->processListItems($list, $marker_any_re);
|
1007 |
-
|
1008 |
-
$result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>");
|
1009 |
-
return "\n". $result ."\n\n";
|
1010 |
-
}
|
1011 |
-
|
1012 |
-
var $list_level = 0;
|
1013 |
-
|
1014 |
-
function processListItems($list_str, $marker_any_re) {
|
1015 |
-
#
|
1016 |
-
# Process the contents of a single ordered or unordered list, splitting it
|
1017 |
-
# into individual list items.
|
1018 |
-
#
|
1019 |
-
# The $this->list_level global keeps track of when we're inside a list.
|
1020 |
-
# Each time we enter a list, we increment it; when we leave a list,
|
1021 |
-
# we decrement. If it's zero, we're not in a list anymore.
|
1022 |
-
#
|
1023 |
-
# We do this because when we're not inside a list, we want to treat
|
1024 |
-
# something like this:
|
1025 |
-
#
|
1026 |
-
# I recommend upgrading to version
|
1027 |
-
# 8. Oops, now this line is treated
|
1028 |
-
# as a sub-list.
|
1029 |
-
#
|
1030 |
-
# As a single paragraph, despite the fact that the second line starts
|
1031 |
-
# with a digit-period-space sequence.
|
1032 |
-
#
|
1033 |
-
# Whereas when we're inside a list (or sub-list), that line will be
|
1034 |
-
# treated as the start of a sub-list. What a kludge, huh? This is
|
1035 |
-
# an aspect of Markdown's syntax that's hard to parse perfectly
|
1036 |
-
# without resorting to mind-reading. Perhaps the solution is to
|
1037 |
-
# change the syntax rules such that sub-lists must start with a
|
1038 |
-
# starting cardinal number; e.g. "1." or "a.".
|
1039 |
-
|
1040 |
-
$this->list_level++;
|
1041 |
-
|
1042 |
-
# trim trailing blank lines:
|
1043 |
-
$list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
|
1044 |
-
|
1045 |
-
$list_str = preg_replace_callback('{
|
1046 |
-
(\n)? # leading line = $1
|
1047 |
-
(^[ ]*) # leading whitespace = $2
|
1048 |
-
('.$marker_any_re.' # list marker and space = $3
|
1049 |
-
(?:[ ]+|(?=\n)) # space only required if item is not empty
|
1050 |
-
)
|
1051 |
-
((?s:.*?)) # list item text = $4
|
1052 |
-
(?:(\n+(?=\n))|\n) # tailing blank line = $5
|
1053 |
-
(?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))
|
1054 |
-
}xm',
|
1055 |
-
array(&$this, '_processListItems_callback'), $list_str);
|
1056 |
-
|
1057 |
-
$this->list_level--;
|
1058 |
-
return $list_str;
|
1059 |
-
}
|
1060 |
-
function _processListItems_callback($matches) {
|
1061 |
-
$item = $matches[4];
|
1062 |
-
$leading_line =& $matches[1];
|
1063 |
-
$leading_space =& $matches[2];
|
1064 |
-
$marker_space = $matches[3];
|
1065 |
-
$tailing_blank_line =& $matches[5];
|
1066 |
-
|
1067 |
-
if ($leading_line || $tailing_blank_line ||
|
1068 |
-
preg_match('/\n{2,}/', $item))
|
1069 |
-
{
|
1070 |
-
# Replace marker with the appropriate whitespace indentation
|
1071 |
-
$item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
|
1072 |
-
$item = $this->runBlockGamut($this->outdent($item)."\n");
|
1073 |
-
}
|
1074 |
-
else {
|
1075 |
-
# Recursion for sub-lists:
|
1076 |
-
$item = $this->doLists($this->outdent($item));
|
1077 |
-
$item = preg_replace('/\n+$/', '', $item);
|
1078 |
-
$item = $this->runSpanGamut($item);
|
1079 |
-
}
|
1080 |
-
|
1081 |
-
return "<li>" . $item . "</li>\n";
|
1082 |
-
}
|
1083 |
-
|
1084 |
-
|
1085 |
-
function doCodeBlocks($text) {
|
1086 |
-
#
|
1087 |
-
# Process Markdown `<pre><code>` blocks.
|
1088 |
-
#
|
1089 |
-
$text = preg_replace_callback('{
|
1090 |
-
(?:\n\n|\A\n?)
|
1091 |
-
( # $1 = the code block -- one or more lines, starting with a space/tab
|
1092 |
-
(?>
|
1093 |
-
[ ]{'.$this->tab_width.'} # Lines must start with a tab or a tab-width of spaces
|
1094 |
-
.*\n+
|
1095 |
-
)+
|
1096 |
-
)
|
1097 |
-
((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
|
1098 |
-
}xm',
|
1099 |
-
array(&$this, '_doCodeBlocks_callback'), $text);
|
1100 |
-
|
1101 |
-
return $text;
|
1102 |
-
}
|
1103 |
-
function _doCodeBlocks_callback($matches) {
|
1104 |
-
$codeblock = $matches[1];
|
1105 |
-
|
1106 |
-
$codeblock = $this->outdent($codeblock);
|
1107 |
-
$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
|
1108 |
-
|
1109 |
-
# trim leading newlines and trailing newlines
|
1110 |
-
$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
|
1111 |
-
|
1112 |
-
$codeblock = "<pre><code>$codeblock\n</code></pre>";
|
1113 |
-
return "\n\n".$this->hashBlock($codeblock)."\n\n";
|
1114 |
-
}
|
1115 |
-
|
1116 |
-
|
1117 |
-
function makeCodeSpan($code) {
|
1118 |
-
#
|
1119 |
-
# Create a code span markup for $code. Called from handleSpanToken.
|
1120 |
-
#
|
1121 |
-
$code = htmlspecialchars(trim($code), ENT_NOQUOTES);
|
1122 |
-
return $this->hashPart("<code>$code</code>");
|
1123 |
-
}
|
1124 |
-
|
1125 |
-
|
1126 |
-
var $em_relist = array(
|
1127 |
-
'' => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?=\S|$)(?![\.,:;]\s)',
|
1128 |
-
'*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
|
1129 |
-
'_' => '(?<=\S|^)(?<!_)_(?!_)',
|
1130 |
-
);
|
1131 |
-
var $strong_relist = array(
|
1132 |
-
'' => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?=\S|$)(?![\.,:;]\s)',
|
1133 |
-
'**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
|
1134 |
-
'__' => '(?<=\S|^)(?<!_)__(?!_)',
|
1135 |
-
);
|
1136 |
-
var $em_strong_relist = array(
|
1137 |
-
'' => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?=\S|$)(?![\.,:;]\s)',
|
1138 |
-
'***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
|
1139 |
-
'___' => '(?<=\S|^)(?<!_)___(?!_)',
|
1140 |
-
);
|
1141 |
-
var $em_strong_prepared_relist;
|
1142 |
-
|
1143 |
-
function prepareItalicsAndBold() {
|
1144 |
-
#
|
1145 |
-
# Prepare regular expressions for searching emphasis tokens in any
|
1146 |
-
# context.
|
1147 |
-
#
|
1148 |
-
foreach ($this->em_relist as $em => $em_re) {
|
1149 |
-
foreach ($this->strong_relist as $strong => $strong_re) {
|
1150 |
-
# Construct list of allowed token expressions.
|
1151 |
-
$token_relist = array();
|
1152 |
-
if (isset($this->em_strong_relist["$em$strong"])) {
|
1153 |
-
$token_relist[] = $this->em_strong_relist["$em$strong"];
|
1154 |
-
}
|
1155 |
-
$token_relist[] = $em_re;
|
1156 |
-
$token_relist[] = $strong_re;
|
1157 |
-
|
1158 |
-
# Construct master expression from list.
|
1159 |
-
$token_re = '{('. implode('|', $token_relist) .')}';
|
1160 |
-
$this->em_strong_prepared_relist["$em$strong"] = $token_re;
|
1161 |
-
}
|
1162 |
-
}
|
1163 |
-
}
|
1164 |
-
|
1165 |
-
function doItalicsAndBold($text) {
|
1166 |
-
$token_stack = array('');
|
1167 |
-
$text_stack = array('');
|
1168 |
-
$em = '';
|
1169 |
-
$strong = '';
|
1170 |
-
$tree_char_em = false;
|
1171 |
-
|
1172 |
-
while (1) {
|
1173 |
-
#
|
1174 |
-
# Get prepared regular expression for seraching emphasis tokens
|
1175 |
-
# in current context.
|
1176 |
-
#
|
1177 |
-
$token_re = $this->em_strong_prepared_relist["$em$strong"];
|
1178 |
-
|
1179 |
-
#
|
1180 |
-
# Each loop iteration search for the next emphasis token.
|
1181 |
-
# Each token is then passed to handleSpanToken.
|
1182 |
-
#
|
1183 |
-
$parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
|
1184 |
-
$text_stack[0] .= $parts[0];
|
1185 |
-
$token =& $parts[1];
|
1186 |
-
$text =& $parts[2];
|
1187 |
-
|
1188 |
-
if (empty($token)) {
|
1189 |
-
# Reached end of text span: empty stack without emitting.
|
1190 |
-
# any more emphasis.
|
1191 |
-
while ($token_stack[0]) {
|
1192 |
-
$text_stack[1] .= array_shift($token_stack);
|
1193 |
-
$text_stack[0] .= array_shift($text_stack);
|
1194 |
-
}
|
1195 |
-
break;
|
1196 |
-
}
|
1197 |
-
|
1198 |
-
$token_len = strlen($token);
|
1199 |
-
if ($tree_char_em) {
|
1200 |
-
# Reached closing marker while inside a three-char emphasis.
|
1201 |
-
if ($token_len == 3) {
|
1202 |
-
# Three-char closing marker, close em and strong.
|
1203 |
-
array_shift($token_stack);
|
1204 |
-
$span = array_shift($text_stack);
|
1205 |
-
$span = $this->runSpanGamut($span);
|
1206 |
-
$span = "<strong><em>$span</em></strong>";
|
1207 |
-
$text_stack[0] .= $this->hashPart($span);
|
1208 |
-
$em = '';
|
1209 |
-
$strong = '';
|
1210 |
-
} else {
|
1211 |
-
# Other closing marker: close one em or strong and
|
1212 |
-
# change current token state to match the other
|
1213 |
-
$token_stack[0] = str_repeat($token{0}, 3-$token_len);
|
1214 |
-
$tag = $token_len == 2 ? "strong" : "em";
|
1215 |
-
$span = $text_stack[0];
|
1216 |
-
$span = $this->runSpanGamut($span);
|
1217 |
-
$span = "<$tag>$span</$tag>";
|
1218 |
-
$text_stack[0] = $this->hashPart($span);
|
1219 |
-
$$tag = ''; # $$tag stands for $em or $strong
|
1220 |
-
}
|
1221 |
-
$tree_char_em = false;
|
1222 |
-
} else if ($token_len == 3) {
|
1223 |
-
if ($em) {
|
1224 |
-
# Reached closing marker for both em and strong.
|
1225 |
-
# Closing strong marker:
|
1226 |
-
for ($i = 0; $i < 2; ++$i) {
|
1227 |
-
$shifted_token = array_shift($token_stack);
|
1228 |
-
$tag = strlen($shifted_token) == 2 ? "strong" : "em";
|
1229 |
-
$span = array_shift($text_stack);
|
1230 |
-
$span = $this->runSpanGamut($span);
|
1231 |
-
$span = "<$tag>$span</$tag>";
|
1232 |
-
$text_stack[0] .= $this->hashPart($span);
|
1233 |
-
$$tag = ''; # $$tag stands for $em or $strong
|
1234 |
-
}
|
1235 |
-
} else {
|
1236 |
-
# Reached opening three-char emphasis marker. Push on token
|
1237 |
-
# stack; will be handled by the special condition above.
|
1238 |
-
$em = $token{0};
|
1239 |
-
$strong = "$em$em";
|
1240 |
-
array_unshift($token_stack, $token);
|
1241 |
-
array_unshift($text_stack, '');
|
1242 |
-
$tree_char_em = true;
|
1243 |
-
}
|
1244 |
-
} else if ($token_len == 2) {
|
1245 |
-
if ($strong) {
|
1246 |
-
# Unwind any dangling emphasis marker:
|
1247 |
-
if (strlen($token_stack[0]) == 1) {
|
1248 |
-
$text_stack[1] .= array_shift($token_stack);
|
1249 |
-
$text_stack[0] .= array_shift($text_stack);
|
1250 |
-
}
|
1251 |
-
# Closing strong marker:
|
1252 |
-
array_shift($token_stack);
|
1253 |
-
$span = array_shift($text_stack);
|
1254 |
-
$span = $this->runSpanGamut($span);
|
1255 |
-
$span = "<strong>$span</strong>";
|
1256 |
-
$text_stack[0] .= $this->hashPart($span);
|
1257 |
-
$strong = '';
|
1258 |
-
} else {
|
1259 |
-
array_unshift($token_stack, $token);
|
1260 |
-
array_unshift($text_stack, '');
|
1261 |
-
$strong = $token;
|
1262 |
-
}
|
1263 |
-
} else {
|
1264 |
-
# Here $token_len == 1
|
1265 |
-
if ($em) {
|
1266 |
-
if (strlen($token_stack[0]) == 1) {
|
1267 |
-
# Closing emphasis marker:
|
1268 |
-
array_shift($token_stack);
|
1269 |
-
$span = array_shift($text_stack);
|
1270 |
-
$span = $this->runSpanGamut($span);
|
1271 |
-
$span = "<em>$span</em>";
|
1272 |
-
$text_stack[0] .= $this->hashPart($span);
|
1273 |
-
$em = '';
|
1274 |
-
} else {
|
1275 |
-
$text_stack[0] .= $token;
|
1276 |
-
}
|
1277 |
-
} else {
|
1278 |
-
array_unshift($token_stack, $token);
|
1279 |
-
array_unshift($text_stack, '');
|
1280 |
-
$em = $token;
|
1281 |
-
}
|
1282 |
-
}
|
1283 |
-
}
|
1284 |
-
return $text_stack[0];
|
1285 |
-
}
|
1286 |
-
|
1287 |
-
|
1288 |
-
function doBlockQuotes($text) {
|
1289 |
-
$text = preg_replace_callback('/
|
1290 |
-
( # Wrap whole match in $1
|
1291 |
-
(?>
|
1292 |
-
^[ ]*>[ ]? # ">" at the start of a line
|
1293 |
-
.+\n # rest of the first line
|
1294 |
-
(.+\n)* # subsequent consecutive lines
|
1295 |
-
\n* # blanks
|
1296 |
-
)+
|
1297 |
-
)
|
1298 |
-
/xm',
|
1299 |
-
array(&$this, '_doBlockQuotes_callback'), $text);
|
1300 |
-
|
1301 |
-
return $text;
|
1302 |
-
}
|
1303 |
-
function _doBlockQuotes_callback($matches) {
|
1304 |
-
$bq = $matches[1];
|
1305 |
-
# trim one level of quoting - trim whitespace-only lines
|
1306 |
-
$bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
|
1307 |
-
$bq = $this->runBlockGamut($bq); # recurse
|
1308 |
-
|
1309 |
-
$bq = preg_replace('/^/m', " ", $bq);
|
1310 |
-
# These leading spaces cause problem with <pre> content,
|
1311 |
-
# so we need to fix that:
|
1312 |
-
$bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx',
|
1313 |
-
array(&$this, '_doBlockQuotes_callback2'), $bq);
|
1314 |
-
|
1315 |
-
return "\n". $this->hashBlock("<blockquote>\n$bq\n</blockquote>")."\n\n";
|
1316 |
-
}
|
1317 |
-
function _doBlockQuotes_callback2($matches) {
|
1318 |
-
$pre = $matches[1];
|
1319 |
-
$pre = preg_replace('/^ /m', '', $pre);
|
1320 |
-
return $pre;
|
1321 |
-
}
|
1322 |
-
|
1323 |
-
|
1324 |
-
function formParagraphs($text) {
|
1325 |
-
#
|
1326 |
-
# Params:
|
1327 |
-
# $text - string to process with html <p> tags
|
1328 |
-
#
|
1329 |
-
# Strip leading and trailing lines:
|
1330 |
-
$text = preg_replace('/\A\n+|\n+\z/', '', $text);
|
1331 |
-
|
1332 |
-
$grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
|
1333 |
-
|
1334 |
-
#
|
1335 |
-
# Wrap <p> tags and unhashify HTML blocks
|
1336 |
-
#
|
1337 |
-
foreach ($grafs as $key => $value) {
|
1338 |
-
if (!preg_match('/^B\x1A[0-9]+B$/', $value)) {
|
1339 |
-
# Is a paragraph.
|
1340 |
-
$value = $this->runSpanGamut($value);
|
1341 |
-
$value = preg_replace('/^([ ]*)/', "<p>", $value);
|
1342 |
-
$value .= "</p>";
|
1343 |
-
$grafs[$key] = $this->unhash($value);
|
1344 |
-
}
|
1345 |
-
else {
|
1346 |
-
# Is a block.
|
1347 |
-
# Modify elements of @grafs in-place...
|
1348 |
-
$graf = $value;
|
1349 |
-
$block = $this->html_hashes[$graf];
|
1350 |
-
$graf = $block;
|
1351 |
-
// if (preg_match('{
|
1352 |
-
// \A
|
1353 |
-
// ( # $1 = <div> tag
|
1354 |
-
// <div \s+
|
1355 |
-
// [^>]*
|
1356 |
-
// \b
|
1357 |
-
// markdown\s*=\s* ([\'"]) # $2 = attr quote char
|
1358 |
-
// 1
|
1359 |
-
// \2
|
1360 |
-
// [^>]*
|
1361 |
-
// >
|
1362 |
-
// )
|
1363 |
-
// ( # $3 = contents
|
1364 |
-
// .*
|
1365 |
-
// )
|
1366 |
-
// (</div>) # $4 = closing tag
|
1367 |
-
// \z
|
1368 |
-
// }xs', $block, $matches))
|
1369 |
-
// {
|
1370 |
-
// list(, $div_open, , $div_content, $div_close) = $matches;
|
1371 |
-
//
|
1372 |
-
// # We can't call Markdown(), because that resets the hash;
|
1373 |
-
// # that initialization code should be pulled into its own sub, though.
|
1374 |
-
// $div_content = $this->hashHTMLBlocks($div_content);
|
1375 |
-
//
|
1376 |
-
// # Run document gamut methods on the content.
|
1377 |
-
// foreach ($this->document_gamut as $method => $priority) {
|
1378 |
-
// $div_content = $this->$method($div_content);
|
1379 |
-
// }
|
1380 |
-
//
|
1381 |
-
// $div_open = preg_replace(
|
1382 |
-
// '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open);
|
1383 |
-
//
|
1384 |
-
// $graf = $div_open . "\n" . $div_content . "\n" . $div_close;
|
1385 |
-
// }
|
1386 |
-
$grafs[$key] = $graf;
|
1387 |
-
}
|
1388 |
-
}
|
1389 |
-
|
1390 |
-
return implode("\n\n", $grafs);
|
1391 |
-
}
|
1392 |
-
|
1393 |
-
|
1394 |
-
function encodeAttribute($text) {
|
1395 |
-
#
|
1396 |
-
# Encode text for a double-quoted HTML attribute. This function
|
1397 |
-
# is *not* suitable for attributes enclosed in single quotes.
|
1398 |
-
#
|
1399 |
-
$text = $this->encodeAmpsAndAngles($text);
|
1400 |
-
$text = str_replace('"', '"', $text);
|
1401 |
-
return $text;
|
1402 |
-
}
|
1403 |
-
|
1404 |
-
|
1405 |
-
function encodeAmpsAndAngles($text) {
|
1406 |
-
#
|
1407 |
-
# Smart processing for ampersands and angle brackets that need to
|
1408 |
-
# be encoded. Valid character entities are left alone unless the
|
1409 |
-
# no-entities mode is set.
|
1410 |
-
#
|
1411 |
-
if ($this->no_entities) {
|
1412 |
-
$text = str_replace('&', '&', $text);
|
1413 |
-
} else {
|
1414 |
-
# Ampersand-encoding based entirely on Nat Irons's Amputator
|
1415 |
-
# MT plugin: <http://bumppo.net/projects/amputator/>
|
1416 |
-
$text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/',
|
1417 |
-
'&', $text);;
|
1418 |
-
}
|
1419 |
-
# Encode remaining <'s
|
1420 |
-
$text = str_replace('<', '<', $text);
|
1421 |
-
|
1422 |
-
return $text;
|
1423 |
-
}
|
1424 |
-
|
1425 |
-
|
1426 |
-
function doAutoLinks($text) {
|
1427 |
-
$text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i',
|
1428 |
-
array(&$this, '_doAutoLinks_url_callback'), $text);
|
1429 |
-
|
1430 |
-
# Email addresses: <address@domain.foo>
|
1431 |
-
$text = preg_replace_callback('{
|
1432 |
-
<
|
1433 |
-
(?:mailto:)?
|
1434 |
-
(
|
1435 |
-
(?:
|
1436 |
-
[-!#$%&\'*+/=?^_`.{|}~\w\x80-\xFF]+
|
1437 |
-
|
|
1438 |
-
".*?"
|
1439 |
-
)
|
1440 |
-
\@
|
1441 |
-
(?:
|
1442 |
-
[-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+
|
1443 |
-
|
|
1444 |
-
\[[\d.a-fA-F:]+\] # IPv4 & IPv6
|
1445 |
-
)
|
1446 |
-
)
|
1447 |
-
>
|
1448 |
-
}xi',
|
1449 |
-
array(&$this, '_doAutoLinks_email_callback'), $text);
|
1450 |
-
|
1451 |
-
return $text;
|
1452 |
-
}
|
1453 |
-
function _doAutoLinks_url_callback($matches) {
|
1454 |
-
$url = $this->encodeAttribute($matches[1]);
|
1455 |
-
$link = "<a href=\"$url\">$url</a>";
|
1456 |
-
return $this->hashPart($link);
|
1457 |
-
}
|
1458 |
-
function _doAutoLinks_email_callback($matches) {
|
1459 |
-
$address = $matches[1];
|
1460 |
-
$link = $this->encodeEmailAddress($address);
|
1461 |
-
return $this->hashPart($link);
|
1462 |
-
}
|
1463 |
-
|
1464 |
-
|
1465 |
-
function encodeEmailAddress($addr) {
|
1466 |
-
#
|
1467 |
-
# Input: an email address, e.g. "foo@example.com"
|
1468 |
-
#
|
1469 |
-
# Output: the email address as a mailto link, with each character
|
1470 |
-
# of the address encoded as either a decimal or hex entity, in
|
1471 |
-
# the hopes of foiling most address harvesting spam bots. E.g.:
|
1472 |
-
#
|
1473 |
-
# <p><a href="mailto:foo
|
1474 |
-
# @example.co
|
1475 |
-
# m">foo@exampl
|
1476 |
-
# e.com</a></p>
|
1477 |
-
#
|
1478 |
-
# Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
|
1479 |
-
# With some optimizations by Milian Wolff.
|
1480 |
-
#
|
1481 |
-
$addr = "mailto:" . $addr;
|
1482 |
-
$chars = preg_split('/(?<!^)(?!$)/', $addr);
|
1483 |
-
$seed = (int)abs(crc32($addr) / strlen($addr)); # Deterministic seed.
|
1484 |
-
|
1485 |
-
foreach ($chars as $key => $char) {
|
1486 |
-
$ord = ord($char);
|
1487 |
-
# Ignore non-ascii chars.
|
1488 |
-
if ($ord < 128) {
|
1489 |
-
$r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
|
1490 |
-
# roughly 10% raw, 45% hex, 45% dec
|
1491 |
-
# '@' *must* be encoded. I insist.
|
1492 |
-
if ($r > 90 && $char != '@') /* do nothing */;
|
1493 |
-
else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';';
|
1494 |
-
else $chars[$key] = '&#'.$ord.';';
|
1495 |
-
}
|
1496 |
-
}
|
1497 |
-
|
1498 |
-
$addr = implode('', $chars);
|
1499 |
-
$text = implode('', array_slice($chars, 7)); # text without `mailto:`
|
1500 |
-
$addr = "<a href=\"$addr\">$text</a>";
|
1501 |
-
|
1502 |
-
return $addr;
|
1503 |
-
}
|
1504 |
-
|
1505 |
-
|
1506 |
-
function parseSpan($str) {
|
1507 |
-
#
|
1508 |
-
# Take the string $str and parse it into tokens, hashing embeded HTML,
|
1509 |
-
# escaped characters and handling code spans.
|
1510 |
-
#
|
1511 |
-
$output = '';
|
1512 |
-
|
1513 |
-
$span_re = '{
|
1514 |
-
(
|
1515 |
-
\\\\'.$this->escape_chars_re.'
|
1516 |
-
|
|
1517 |
-
(?<![`\\\\])
|
1518 |
-
`+ # code span marker
|
1519 |
-
'.( $this->no_markup ? '' : '
|
1520 |
-
|
|
1521 |
-
<!-- .*? --> # comment
|
1522 |
-
|
|
1523 |
-
<\?.*?\?> | <%.*?%> # processing instruction
|
1524 |
-
|
|
1525 |
-
<[!$]?[-a-zA-Z0-9:_]+ # regular tags
|
1526 |
-
(?>
|
1527 |
-
\s
|
1528 |
-
(?>[^"\'>]+|"[^"]*"|\'[^\']*\')*
|
1529 |
-
)?
|
1530 |
-
>
|
1531 |
-
|
|
1532 |
-
<[-a-zA-Z0-9:_]+\s*/> # xml-style empty tag
|
1533 |
-
|
|
1534 |
-
</[-a-zA-Z0-9:_]+\s*> # closing tag
|
1535 |
-
').'
|
1536 |
-
)
|
1537 |
-
}xs';
|
1538 |
-
|
1539 |
-
while (1) {
|
1540 |
-
#
|
1541 |
-
# Each loop iteration seach for either the next tag, the next
|
1542 |
-
# openning code span marker, or the next escaped character.
|
1543 |
-
# Each token is then passed to handleSpanToken.
|
1544 |
-
#
|
1545 |
-
$parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
|
1546 |
-
|
1547 |
-
# Create token from text preceding tag.
|
1548 |
-
if ($parts[0] != "") {
|
1549 |
-
$output .= $parts[0];
|
1550 |
-
}
|
1551 |
-
|
1552 |
-
# Check if we reach the end.
|
1553 |
-
if (isset($parts[1])) {
|
1554 |
-
$output .= $this->handleSpanToken($parts[1], $parts[2]);
|
1555 |
-
$str = $parts[2];
|
1556 |
-
}
|
1557 |
-
else {
|
1558 |
-
break;
|
1559 |
-
}
|
1560 |
-
}
|
1561 |
-
|
1562 |
-
return $output;
|
1563 |
-
}
|
1564 |
-
|
1565 |
-
|
1566 |
-
function handleSpanToken($token, &$str) {
|
1567 |
-
#
|
1568 |
-
# Handle $token provided by parseSpan by determining its nature and
|
1569 |
-
# returning the corresponding value that should replace it.
|
1570 |
-
#
|
1571 |
-
switch ($token{0}) {
|
1572 |
-
case "\\":
|
1573 |
-
return $this->hashPart("&#". ord($token{1}). ";");
|
1574 |
-
case "`":
|
1575 |
-
# Search for end marker in remaining text.
|
1576 |
-
if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
|
1577 |
-
$str, $matches))
|
1578 |
-
{
|
1579 |
-
$str = $matches[2];
|
1580 |
-
$codespan = $this->makeCodeSpan($matches[1]);
|
1581 |
-
return $this->hashPart($codespan);
|
1582 |
-
}
|
1583 |
-
return $token; // return as text since no ending marker found.
|
1584 |
-
default:
|
1585 |
-
return $this->hashPart($token);
|
1586 |
-
}
|
1587 |
-
}
|
1588 |
-
|
1589 |
-
|
1590 |
-
function outdent($text) {
|
1591 |
-
#
|
1592 |
-
# Remove one level of line-leading tabs or spaces
|
1593 |
-
#
|
1594 |
-
return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
|
1595 |
-
}
|
1596 |
-
|
1597 |
-
|
1598 |
-
# String length function for detab. `_initDetab` will create a function to
|
1599 |
-
# hanlde UTF-8 if the default function does not exist.
|
1600 |
-
var $utf8_strlen = 'mb_strlen';
|
1601 |
-
|
1602 |
-
function detab($text) {
|
1603 |
-
#
|
1604 |
-
# Replace tabs with the appropriate amount of space.
|
1605 |
-
#
|
1606 |
-
# For each line we separate the line in blocks delemited by
|
1607 |
-
# tab characters. Then we reconstruct every line by adding the
|
1608 |
-
# appropriate number of space between each blocks.
|
1609 |
-
|
1610 |
-
$text = preg_replace_callback('/^.*\t.*$/m',
|
1611 |
-
array(&$this, '_detab_callback'), $text);
|
1612 |
-
|
1613 |
-
return $text;
|
1614 |
-
}
|
1615 |
-
function _detab_callback($matches) {
|
1616 |
-
$line = $matches[0];
|
1617 |
-
$strlen = $this->utf8_strlen; # strlen function for UTF-8.
|
1618 |
-
|
1619 |
-
# Split in blocks.
|
1620 |
-
$blocks = explode("\t", $line);
|
1621 |
-
# Add each blocks to the line.
|
1622 |
-
$line = $blocks[0];
|
1623 |
-
unset($blocks[0]); # Do not add first block twice.
|
1624 |
-
foreach ($blocks as $block) {
|
1625 |
-
# Calculate amount of space, insert spaces, insert block.
|
1626 |
-
$amount = $this->tab_width -
|
1627 |
-
$strlen($line, 'UTF-8') % $this->tab_width;
|
1628 |
-
$line .= str_repeat(" ", $amount) . $block;
|
1629 |
-
}
|
1630 |
-
return $line;
|
1631 |
-
}
|
1632 |
-
function _initDetab() {
|
1633 |
-
#
|
1634 |
-
# Check for the availability of the function in the `utf8_strlen` property
|
1635 |
-
# (initially `mb_strlen`). If the function is not available, create a
|
1636 |
-
# function that will loosely count the number of UTF-8 characters with a
|
1637 |
-
# regular expression.
|
1638 |
-
#
|
1639 |
-
if (function_exists($this->utf8_strlen)) return;
|
1640 |
-
$this->utf8_strlen = create_function('$text', 'return preg_match_all(
|
1641 |
-
"/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/",
|
1642 |
-
$text, $m);');
|
1643 |
-
}
|
1644 |
-
|
1645 |
-
|
1646 |
-
function unhash($text) {
|
1647 |
-
#
|
1648 |
-
# Swap back in all the tags hashed by _HashHTMLBlocks.
|
1649 |
-
#
|
1650 |
-
return preg_replace_callback('/(.)\x1A[0-9]+\1/',
|
1651 |
-
array(&$this, '_unhash_callback'), $text);
|
1652 |
-
}
|
1653 |
-
function _unhash_callback($matches) {
|
1654 |
-
return $this->html_hashes[$matches[0]];
|
1655 |
-
}
|
1656 |
-
|
1657 |
-
}
|
1658 |
-
|
1659 |
-
/*
|
1660 |
-
|
1661 |
-
PHP Markdown
|
1662 |
-
============
|
1663 |
-
|
1664 |
-
Description
|
1665 |
-
-----------
|
1666 |
-
|
1667 |
-
This is a PHP translation of the original Markdown formatter written in
|
1668 |
-
Perl by John Gruber.
|
1669 |
-
|
1670 |
-
Markdown is a text-to-HTML filter; it translates an easy-to-read /
|
1671 |
-
easy-to-write structured text format into HTML. Markdown's text format
|
1672 |
-
is mostly similar to that of plain text email, and supports features such
|
1673 |
-
as headers, *emphasis*, code blocks, blockquotes, and links.
|
1674 |
-
|
1675 |
-
Markdown's syntax is designed not as a generic markup language, but
|
1676 |
-
specifically to serve as a front-end to (X)HTML. You can use span-level
|
1677 |
-
HTML tags anywhere in a Markdown document, and you can use block level
|
1678 |
-
HTML tags (like <div> and <table> as well).
|
1679 |
-
|
1680 |
-
For more information about Markdown's syntax, see:
|
1681 |
-
|
1682 |
-
<http://daringfireball.net/projects/markdown/>
|
1683 |
-
|
1684 |
-
|
1685 |
-
Bugs
|
1686 |
-
----
|
1687 |
-
|
1688 |
-
To file bug reports please send email to:
|
1689 |
-
|
1690 |
-
<michel.fortin@michelf.ca>
|
1691 |
-
|
1692 |
-
Please include with your report: (1) the example input; (2) the output you
|
1693 |
-
expected; (3) the output Markdown actually produced.
|
1694 |
-
|
1695 |
-
|
1696 |
-
Version History
|
1697 |
-
---------------
|
1698 |
-
|
1699 |
-
See the readme file for detailed release notes for this version.
|
1700 |
-
|
1701 |
-
|
1702 |
-
Copyright and License
|
1703 |
-
---------------------
|
1704 |
-
|
1705 |
-
PHP Markdown
|
1706 |
-
Copyright (c) 2004-2013 Michel Fortin
|
1707 |
-
<http://michelf.ca/>
|
1708 |
-
All rights reserved.
|
1709 |
-
|
1710 |
-
Based on Markdown
|
1711 |
-
Copyright (c) 2003-2006 John Gruber
|
1712 |
-
<http://daringfireball.net/>
|
1713 |
-
All rights reserved.
|
1714 |
-
|
1715 |
-
Redistribution and use in source and binary forms, with or without
|
1716 |
-
modification, are permitted provided that the following conditions are
|
1717 |
-
met:
|
1718 |
-
|
1719 |
-
* Redistributions of source code must retain the above copyright notice,
|
1720 |
-
this list of conditions and the following disclaimer.
|
1721 |
-
|
1722 |
-
* Redistributions in binary form must reproduce the above copyright
|
1723 |
-
notice, this list of conditions and the following disclaimer in the
|
1724 |
-
documentation and/or other materials provided with the distribution.
|
1725 |
-
|
1726 |
-
* Neither the name "Markdown" nor the names of its contributors may
|
1727 |
-
be used to endorse or promote products derived from this software
|
1728 |
-
without specific prior written permission.
|
1729 |
-
|
1730 |
-
This software is provided by the copyright holders and contributors "as
|
1731 |
-
is" and any express or implied warranties, including, but not limited
|
1732 |
-
to, the implied warranties of merchantability and fitness for a
|
1733 |
-
particular purpose are disclaimed. In no event shall the copyright owner
|
1734 |
-
or contributors be liable for any direct, indirect, incidental, special,
|
1735 |
-
exemplary, or consequential damages (including, but not limited to,
|
1736 |
-
procurement of substitute goods or services; loss of use, data, or
|
1737 |
-
profits; or business interruption) however caused and on any theory of
|
1738 |
-
liability, whether in contract, strict liability, or tort (including
|
1739 |
-
negligence or otherwise) arising in any way out of the use of this
|
1740 |
-
software, even if advised of the possibility of such damage.
|
1741 |
-
|
1742 |
-
*/
|
1743 |
?>
|
1 |
+
<?php
|
2 |
+
#
|
3 |
+
# Markdown - A text-to-HTML conversion tool for web writers
|
4 |
+
#
|
5 |
+
# PHP Markdown
|
6 |
+
# Copyright (c) 2004-2013 Michel Fortin
|
7 |
+
# <http://michelf.ca/projects/php-markdown/>
|
8 |
+
#
|
9 |
+
# Original Markdown
|
10 |
+
# Copyright (c) 2004-2006 John Gruber
|
11 |
+
# <http://daringfireball.net/projects/markdown/>
|
12 |
+
#
|
13 |
+
|
14 |
+
|
15 |
+
define( 'MARKDOWN_VERSION', "1.0.1q" ); # 11 Apr 2013
|
16 |
+
|
17 |
+
|
18 |
+
#
|
19 |
+
# Global default settings:
|
20 |
+
#
|
21 |
+
|
22 |
+
# Change to ">" for HTML output
|
23 |
+
@define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX', " />");
|
24 |
+
|
25 |
+
# Define the width of a tab for code blocks.
|
26 |
+
@define( 'MARKDOWN_TAB_WIDTH', 4 );
|
27 |
+
|
28 |
+
|
29 |
+
#
|
30 |
+
# WordPress settings:
|
31 |
+
#
|
32 |
+
|
33 |
+
# Change to false to remove Markdown from posts and/or comments.
|
34 |
+
@define( 'MARKDOWN_WP_POSTS', true );
|
35 |
+
@define( 'MARKDOWN_WP_COMMENTS', true );
|
36 |
+
|
37 |
+
|
38 |
+
|
39 |
+
### Standard Function Interface ###
|
40 |
+
|
41 |
+
@define( 'MARKDOWN_PARSER_CLASS', 'Markdown_Parser' );
|
42 |
+
|
43 |
+
function Markdown($text) {
|
44 |
+
#
|
45 |
+
# Initialize the parser and return the result of its transform method.
|
46 |
+
#
|
47 |
+
# Setup static parser variable.
|
48 |
+
static $parser;
|
49 |
+
if (!isset($parser)) {
|
50 |
+
$parser_class = MARKDOWN_PARSER_CLASS;
|
51 |
+
$parser = new $parser_class;
|
52 |
+
}
|
53 |
+
|
54 |
+
# Transform text using parser.
|
55 |
+
return $parser->transform($text);
|
56 |
+
}
|
57 |
+
|
58 |
+
|
59 |
+
### WordPress Plugin Interface ###
|
60 |
+
|
61 |
+
/*
|
62 |
+
Plugin Name: Markdown
|
63 |
+
Plugin URI: http://michelf.ca/projects/php-markdown/
|
64 |
+
Description: <a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.ca/projects/php-markdown/">More...</a>
|
65 |
+
Version: 1.0.1q
|
66 |
+
Author: Michel Fortin
|
67 |
+
Author URI: http://michelf.ca/
|
68 |
+
*/
|
69 |
+
|
70 |
+
if (isset($wp_version)) {
|
71 |
+
# More details about how it works here:
|
72 |
+
# <http://michelf.ca/weblog/2005/wordpress-text-flow-vs-markdown/>
|
73 |
+
|
74 |
+
# Post content and excerpts
|
75 |
+
# - Remove WordPress paragraph generator.
|
76 |
+
# - Run Markdown on excerpt, then remove all tags.
|
77 |
+
# - Add paragraph tag around the excerpt, but remove it for the excerpt rss.
|
78 |
+
if (MARKDOWN_WP_POSTS) {
|
79 |
+
remove_filter('the_content', 'wpautop');
|
80 |
+
remove_filter('the_content_rss', 'wpautop');
|
81 |
+
remove_filter('the_excerpt', 'wpautop');
|
82 |
+
add_filter('the_content', 'Markdown', 6);
|
83 |
+
add_filter('the_content_rss', 'Markdown', 6);
|
84 |
+
add_filter('get_the_excerpt', 'Markdown', 6);
|
85 |
+
add_filter('get_the_excerpt', 'trim', 7);
|
86 |
+
add_filter('the_excerpt', 'mdwp_add_p');
|
87 |
+
add_filter('the_excerpt_rss', 'mdwp_strip_p');
|
88 |
+
|
89 |
+
remove_filter('content_save_pre', 'balanceTags', 50);
|
90 |
+
remove_filter('excerpt_save_pre', 'balanceTags', 50);
|
91 |
+
add_filter('the_content', 'balanceTags', 50);
|
92 |
+
add_filter('get_the_excerpt', 'balanceTags', 9);
|
93 |
+
}
|
94 |
+
|
95 |
+
# Comments
|
96 |
+
# - Remove WordPress paragraph generator.
|
97 |
+
# - Remove WordPress auto-link generator.
|
98 |
+
# - Scramble important tags before passing them to the kses filter.
|
99 |
+
# - Run Markdown on excerpt then remove paragraph tags.
|
100 |
+
if (MARKDOWN_WP_COMMENTS) {
|
101 |
+
remove_filter('comment_text', 'wpautop', 30);
|
102 |
+
remove_filter('comment_text', 'make_clickable');
|
103 |
+
add_filter('pre_comment_content', 'Markdown', 6);
|
104 |
+
add_filter('pre_comment_content', 'mdwp_hide_tags', 8);
|
105 |
+
add_filter('pre_comment_content', 'mdwp_show_tags', 12);
|
106 |
+
add_filter('get_comment_text', 'Markdown', 6);
|
107 |
+
add_filter('get_comment_excerpt', 'Markdown', 6);
|
108 |
+
add_filter('get_comment_excerpt', 'mdwp_strip_p', 7);
|
109 |
+
|
110 |
+
global $mdwp_hidden_tags, $mdwp_placeholders;
|
111 |
+
$mdwp_hidden_tags = explode(' ',
|
112 |
+
'<p> </p> <pre> </pre> <ol> </ol> <ul> </ul> <li> </li>');
|
113 |
+
$mdwp_placeholders = explode(' ', str_rot13(
|
114 |
+
'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '.
|
115 |
+
'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli'));
|
116 |
+
}
|
117 |
+
|
118 |
+
function mdwp_add_p($text) {
|
119 |
+
if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) {
|
120 |
+
$text = '<p>'.$text.'</p>';
|
121 |
+
$text = preg_replace('{\n{2,}}', "</p>\n\n<p>", $text);
|
122 |
+
}
|
123 |
+
return $text;
|
124 |
+
}
|
125 |
+
|
126 |
+
function mdwp_strip_p($t) { return preg_replace('{</?p>}i', '', $t); }
|
127 |
+
|
128 |
+
function mdwp_hide_tags($text) {
|
129 |
+
global $mdwp_hidden_tags, $mdwp_placeholders;
|
130 |
+
return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text);
|
131 |
+
}
|
132 |
+
function mdwp_show_tags($text) {
|
133 |
+
global $mdwp_hidden_tags, $mdwp_placeholders;
|
134 |
+
return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text);
|
135 |
+
}
|
136 |
+
}
|
137 |
+
|
138 |
+
|
139 |
+
### bBlog Plugin Info ###
|
140 |
+
|
141 |
+
function identify_modifier_markdown() {
|
142 |
+
return array(
|
143 |
+
'name' => 'markdown',
|
144 |
+
'type' => 'modifier',
|
145 |
+
'nicename' => 'Markdown',
|
146 |
+
'description' => 'A text-to-HTML conversion tool for web writers',
|
147 |
+
'authors' => 'Michel Fortin and John Gruber',
|
148 |
+
'licence' => 'BSD-like',
|
149 |
+
'version' => MARKDOWN_VERSION,
|
150 |
+
'help' => '<a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.ca/projects/php-markdown/">More...</a>'
|
151 |
+
);
|
152 |
+
}
|
153 |
+
|
154 |
+
|
155 |
+
### Smarty Modifier Interface ###
|
156 |
+
|
157 |
+
function smarty_modifier_markdown($text) {
|
158 |
+
return Markdown($text);
|
159 |
+
}
|
160 |
+
|
161 |
+
|
162 |
+
### Textile Compatibility Mode ###
|
163 |
+
|
164 |
+
# Rename this file to "classTextile.php" and it can replace Textile everywhere.
|
165 |
+
|
166 |
+
if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) {
|
167 |
+
# Try to include PHP SmartyPants. Should be in the same directory.
|
168 |
+
@include_once 'smartypants.php';
|
169 |
+
# Fake Textile class. It calls Markdown instead.
|
170 |
+
class Textile {
|
171 |
+
function TextileThis($text, $lite='', $encode='') {
|
172 |
+
if ($lite == '' && $encode == '') $text = Markdown($text);
|
173 |
+
if (function_exists('SmartyPants')) $text = SmartyPants($text);
|
174 |
+
return $text;
|
175 |
+
}
|
176 |
+
# Fake restricted version: restrictions are not supported for now.
|
177 |
+
function TextileRestricted($text, $lite='', $noimage='') {
|
178 |
+
return $this->TextileThis($text, $lite);
|
179 |
+
}
|
180 |
+
# Workaround to ensure compatibility with TextPattern 4.0.3.
|
181 |
+
function blockLite($text) { return $text; }
|
182 |
+
}
|
183 |
+
}
|
184 |
+
|
185 |
+
|
186 |
+
|
187 |
+
#
|
188 |
+
# Markdown Parser Class
|
189 |
+
#
|
190 |
+
|
191 |
+
class Markdown_Parser {
|
192 |
+
|
193 |
+
### Configuration Variables ###
|
194 |
+
|
195 |
+
# Change to ">" for HTML output.
|
196 |
+
var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX;
|
197 |
+
var $tab_width = MARKDOWN_TAB_WIDTH;
|
198 |
+
|
199 |
+
# Change to `true` to disallow markup or entities.
|
200 |
+
var $no_markup = false;
|
201 |
+
var $no_entities = false;
|
202 |
+
|
203 |
+
# Predefined urls and titles for reference links and images.
|
204 |
+
var $predef_urls = array();
|
205 |
+
var $predef_titles = array();
|
206 |
+
|
207 |
+
|
208 |
+
### Parser Implementation ###
|
209 |
+
|
210 |
+
# Regex to match balanced [brackets].
|
211 |
+
# Needed to insert a maximum bracked depth while converting to PHP.
|
212 |
+
var $nested_brackets_depth = 6;
|
213 |
+
var $nested_brackets_re;
|
214 |
+
|
215 |
+
var $nested_url_parenthesis_depth = 4;
|
216 |
+
var $nested_url_parenthesis_re;
|
217 |
+
|
218 |
+
# Table of hash values for escaped characters:
|
219 |
+
var $escape_chars = '\`*_{}[]()>#+-.!';
|
220 |
+
var $escape_chars_re;
|
221 |
+
|
222 |
+
|
223 |
+
function Markdown_Parser() {
|
224 |
+
#
|
225 |
+
# Constructor function. Initialize appropriate member variables.
|
226 |
+
#
|
227 |
+
$this->_initDetab();
|
228 |
+
$this->prepareItalicsAndBold();
|
229 |
+
|
230 |
+
$this->nested_brackets_re =
|
231 |
+
str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth).
|
232 |
+
str_repeat('\])*', $this->nested_brackets_depth);
|
233 |
+
|
234 |
+
$this->nested_url_parenthesis_re =
|
235 |
+
str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth).
|
236 |
+
str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth);
|
237 |
+
|
238 |
+
$this->escape_chars_re = '['.preg_quote($this->escape_chars).']';
|
239 |
+
|
240 |
+
# Sort document, block, and span gamut in ascendent priority order.
|
241 |
+
asort($this->document_gamut);
|
242 |
+
asort($this->block_gamut);
|
243 |
+
asort($this->span_gamut);
|
244 |
+
}
|
245 |
+
|
246 |
+
|
247 |
+
# Internal hashes used during transformation.
|
248 |
+
var $urls = array();
|
249 |
+
var $titles = array();
|
250 |
+
var $html_hashes = array();
|
251 |
+
|
252 |
+
# Status flag to avoid invalid nesting.
|
253 |
+
var $in_anchor = false;
|
254 |
+
|
255 |
+
|
256 |
+
function setup() {
|
257 |
+
#
|
258 |
+
# Called before the transformation process starts to setup parser
|
259 |
+
# states.
|
260 |
+
#
|
261 |
+
# Clear global hashes.
|
262 |
+
$this->urls = $this->predef_urls;
|
263 |
+
$this->titles = $this->predef_titles;
|
264 |
+
$this->html_hashes = array();
|
265 |
+
|
266 |
+
$this->in_anchor = false;
|
267 |
+
}
|
268 |
+
|
269 |
+
function teardown() {
|
270 |
+
#
|
271 |
+
# Called after the transformation process to clear any variable
|
272 |
+
# which may be taking up memory unnecessarly.
|
273 |
+
#
|
274 |
+
$this->urls = array();
|
275 |
+
$this->titles = array();
|
276 |
+
$this->html_hashes = array();
|
277 |
+
}
|
278 |
+
|
279 |
+
|
280 |
+
function transform($text) {
|
281 |
+
#
|
282 |
+
# Main function. Performs some preprocessing on the input text
|
283 |
+
# and pass it through the document gamut.
|
284 |
+
#
|
285 |
+
$this->setup();
|
286 |
+
|
287 |
+
# Remove UTF-8 BOM and marker character in input, if present.
|
288 |
+
$text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text);
|
289 |
+
|
290 |
+
# Standardize line endings:
|
291 |
+
# DOS to Unix and Mac to Unix
|
292 |
+
$text = preg_replace('{\r\n?}', "\n", $text);
|
293 |
+
|
294 |
+
# Make sure $text ends with a couple of newlines:
|
295 |
+
$text .= "\n\n";
|
296 |
+
|
297 |
+
# Convert all tabs to spaces.
|
298 |
+
$text = $this->detab($text);
|
299 |
+
|
300 |
+
# Turn block-level HTML blocks into hash entries
|
301 |
+
$text = $this->hashHTMLBlocks($text);
|
302 |
+
|
303 |
+
# Strip any lines consisting only of spaces and tabs.
|
304 |
+
# This makes subsequent regexen easier to write, because we can
|
305 |
+
# match consecutive blank lines with /\n+/ instead of something
|
306 |
+
# contorted like /[ ]*\n+/ .
|
307 |
+
$text = preg_replace('/^[ ]+$/m', '', $text);
|
308 |
+
|
309 |
+
# Run document gamut methods.
|
310 |
+
foreach ($this->document_gamut as $method => $priority) {
|
311 |
+
$text = $this->$method($text);
|
312 |
+
}
|
313 |
+
|
314 |
+
$this->teardown();
|
315 |
+
|
316 |
+
return $text . "\n";
|
317 |
+
}
|
318 |
+
|
319 |
+
var $document_gamut = array(
|
320 |
+
# Strip link definitions, store in hashes.
|
321 |
+
"stripLinkDefinitions" => 20,
|
322 |
+
|
323 |
+
"runBasicBlockGamut" => 30,
|
324 |
+
);
|
325 |
+
|
326 |
+
|
327 |
+
function stripLinkDefinitions($text) {
|
328 |
+
#
|
329 |
+
# Strips link definitions from text, stores the URLs and titles in
|
330 |
+
# hash references.
|
331 |
+
#
|
332 |
+
$less_than_tab = $this->tab_width - 1;
|
333 |
+
|
334 |
+
# Link defs are in the form: ^[id]: url "optional title"
|
335 |
+
$text = preg_replace_callback('{
|
336 |
+
^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1
|
337 |
+
[ ]*
|
338 |
+
\n? # maybe *one* newline
|
339 |
+
[ ]*
|
340 |
+
(?:
|
341 |
+
<(.+?)> # url = $2
|
342 |
+
|
|
343 |
+
(\S+?) # url = $3
|
344 |
+
)
|
345 |
+
[ ]*
|
346 |
+
\n? # maybe one newline
|
347 |
+
[ ]*
|
348 |
+
(?:
|
349 |
+
(?<=\s) # lookbehind for whitespace
|
350 |
+
["(]
|
351 |
+
(.*?) # title = $4
|
352 |
+
[")]
|
353 |
+
[ ]*
|
354 |
+
)? # title is optional
|
355 |
+
(?:\n+|\Z)
|
356 |
+
}xm',
|
357 |
+
array(&$this, '_stripLinkDefinitions_callback'),
|
358 |
+
$text);
|
359 |
+
return $text;
|
360 |
+
}
|
361 |
+
function _stripLinkDefinitions_callback($matches) {
|
362 |
+
$link_id = strtolower($matches[1]);
|
363 |
+
$url = $matches[2] == '' ? $matches[3] : $matches[2];
|
364 |
+
$this->urls[$link_id] = $url;
|
365 |
+
$this->titles[$link_id] =& $matches[4];
|
366 |
+
return ''; # String that will replace the block
|
367 |
+
}
|
368 |
+
|
369 |
+
|
370 |
+
function hashHTMLBlocks($text) {
|
371 |
+
if ($this->no_markup) return $text;
|
372 |
+
|
373 |
+
$less_than_tab = $this->tab_width - 1;
|
374 |
+
|
375 |
+
# Hashify HTML blocks:
|
376 |
+
# We only want to do this for block-level HTML tags, such as headers,
|
377 |
+
# lists, and tables. That's because we still want to wrap <p>s around
|
378 |
+
# "paragraphs" that are wrapped in non-block-level tags, such as anchors,
|
379 |
+
# phrase emphasis, and spans. The list of tags we're looking for is
|
380 |
+
# hard-coded:
|
381 |
+
#
|
382 |
+
# * List "a" is made of tags which can be both inline or block-level.
|
383 |
+
# These will be treated block-level when the start tag is alone on
|
384 |
+
# its line, otherwise they're not matched here and will be taken as
|
385 |
+
# inline later.
|
386 |
+
# * List "b" is made of tags which are always block-level;
|
387 |
+
#
|
388 |
+
$block_tags_a_re = 'ins|del';
|
389 |
+
$block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'.
|
390 |
+
'script|noscript|form|fieldset|iframe|math|svg|'.
|
391 |
+
'article|section|nav|aside|hgroup|header|footer|'.
|
392 |
+
'figure';
|
393 |
+
|
394 |
+
# Regular expression for the content of a block tag.
|
395 |
+
$nested_tags_level = 4;
|
396 |
+
$attr = '
|
397 |
+
(?> # optional tag attributes
|
398 |
+
\s # starts with whitespace
|
399 |
+
(?>
|
400 |
+
[^>"/]+ # text outside quotes
|
401 |
+
|
|
402 |
+
/+(?!>) # slash not followed by ">"
|
403 |
+
|
|
404 |
+
"[^"]*" # text inside double quotes (tolerate ">")
|
405 |
+
|
|
406 |
+
\'[^\']*\' # text inside single quotes (tolerate ">")
|
407 |
+
)*
|
408 |
+
)?
|
409 |
+
';
|
410 |
+
$content =
|
411 |
+
str_repeat('
|
412 |
+
(?>
|
413 |
+
[^<]+ # content without tag
|
414 |
+
|
|
415 |
+
<\2 # nested opening tag
|
416 |
+
'.$attr.' # attributes
|
417 |
+
(?>
|
418 |
+
/>
|
419 |
+
|
|
420 |
+
>', $nested_tags_level). # end of opening tag
|
421 |
+
'.*?'. # last level nested tag content
|
422 |
+
str_repeat('
|
423 |
+
</\2\s*> # closing nested tag
|
424 |
+
)
|
425 |
+
|
|
426 |
+
<(?!/\2\s*> # other tags with a different name
|
427 |
+
)
|
428 |
+
)*',
|
429 |
+
$nested_tags_level);
|
430 |
+
$content2 = str_replace('\2', '\3', $content);
|
431 |
+
|
432 |
+
# First, look for nested blocks, e.g.:
|
433 |
+
# <div>
|
434 |
+
# <div>
|
435 |
+
# tags for inner block must be indented.
|
436 |
+
# </div>
|
437 |
+
# </div>
|
438 |
+
#
|
439 |
+
# The outermost tags must start at the left margin for this to match, and
|
440 |
+
# the inner nested divs must be indented.
|
441 |
+
# We need to do this before the next, more liberal match, because the next
|
442 |
+
# match will start at the first `<div>` and stop at the first `</div>`.
|
443 |
+
$text = preg_replace_callback('{(?>
|
444 |
+
(?>
|
445 |
+
(?<=\n\n) # Starting after a blank line
|
446 |
+
| # or
|
447 |
+
\A\n? # the beginning of the doc
|
448 |
+
)
|
449 |
+
( # save in $1
|
450 |
+
|
451 |
+
# Match from `\n<tag>` to `</tag>\n`, handling nested tags
|
452 |
+
# in between.
|
453 |
+
|
454 |
+
[ ]{0,'.$less_than_tab.'}
|
455 |
+
<('.$block_tags_b_re.')# start tag = $2
|
456 |
+
'.$attr.'> # attributes followed by > and \n
|
457 |
+
'.$content.' # content, support nesting
|
458 |
+
</\2> # the matching end tag
|
459 |
+
[ ]* # trailing spaces/tabs
|
460 |
+
(?=\n+|\Z) # followed by a newline or end of document
|
461 |
+
|
462 |
+
| # Special version for tags of group a.
|
463 |
+
|
464 |
+
[ ]{0,'.$less_than_tab.'}
|
465 |
+
<('.$block_tags_a_re.')# start tag = $3
|
466 |
+
'.$attr.'>[ ]*\n # attributes followed by >
|
467 |
+
'.$content2.' # content, support nesting
|
468 |
+
</\3> # the matching end tag
|
469 |
+
[ ]* # trailing spaces/tabs
|
470 |
+
(?=\n+|\Z) # followed by a newline or end of document
|
471 |
+
|
472 |
+
| # Special case just for <hr />. It was easier to make a special
|
473 |
+
# case than to make the other regex more complicated.
|
474 |
+
|
475 |
+
[ ]{0,'.$less_than_tab.'}
|
476 |
+
<(hr) # start tag = $2
|
477 |
+
'.$attr.' # attributes
|
478 |
+
/?> # the matching end tag
|
479 |
+
[ ]*
|
480 |
+
(?=\n{2,}|\Z) # followed by a blank line or end of document
|
481 |
+
|
482 |
+
| # Special case for standalone HTML comments:
|
483 |
+
|
484 |
+
[ ]{0,'.$less_than_tab.'}
|
485 |
+
(?s:
|
486 |
+
<!-- .*? -->
|
487 |
+
)
|
488 |
+
[ ]*
|
489 |
+
(?=\n{2,}|\Z) # followed by a blank line or end of document
|
490 |
+
|
491 |
+
| # PHP and ASP-style processor instructions (<? and <%)
|
492 |
+
|
493 |
+
[ ]{0,'.$less_than_tab.'}
|
494 |
+
(?s:
|
495 |
+
<([?%]) # $2
|
496 |
+
.*?
|
497 |
+
\2>
|
498 |
+
)
|
499 |
+
[ ]*
|
500 |
+
(?=\n{2,}|\Z) # followed by a blank line or end of document
|
501 |
+
|
502 |
+
)
|
503 |
+
)}Sxmi',
|
504 |
+
array(&$this, '_hashHTMLBlocks_callback'),
|
505 |
+
$text);
|
506 |
+
|
507 |
+
return $text;
|
508 |
+
}
|
509 |
+
function _hashHTMLBlocks_callback($matches) {
|
510 |
+
$text = $matches[1];
|
511 |
+
$key = $this->hashBlock($text);
|
512 |
+
return "\n\n$key\n\n";
|
513 |
+
}
|
514 |
+
|
515 |
+
|
516 |
+
function hashPart($text, $boundary = 'X') {
|
517 |
+
#
|
518 |
+
# Called whenever a tag must be hashed when a function insert an atomic
|
519 |
+
# element in the text stream. Passing $text to through this function gives
|
520 |
+
# a unique text-token which will be reverted back when calling unhash.
|
521 |
+
#
|
522 |
+
# The $boundary argument specify what character should be used to surround
|
523 |
+
# the token. By convension, "B" is used for block elements that needs not
|
524 |
+
# to be wrapped into paragraph tags at the end, ":" is used for elements
|
525 |
+
# that are word separators and "X" is used in the general case.
|
526 |
+
#
|
527 |
+
# Swap back any tag hash found in $text so we do not have to `unhash`
|
528 |
+
# multiple times at the end.
|
529 |
+
$text = $this->unhash($text);
|
530 |
+
|
531 |
+
# Then hash the block.
|
532 |
+
static $i = 0;
|
533 |
+
$key = "$boundary\x1A" . ++$i . $boundary;
|
534 |
+
$this->html_hashes[$key] = $text;
|
535 |
+
return $key; # String that will replace the tag.
|
536 |
+
}
|
537 |
+
|
538 |
+
|
539 |
+
function hashBlock($text) {
|
540 |
+
#
|
541 |
+
# Shortcut function for hashPart with block-level boundaries.
|
542 |
+
#
|
543 |
+
return $this->hashPart($text, 'B');
|
544 |
+
}
|
545 |
+
|
546 |
+
|
547 |
+
var $block_gamut = array(
|
548 |
+
#
|
549 |
+
# These are all the transformations that form block-level
|
550 |
+
# tags like paragraphs, headers, and list items.
|
551 |
+
#
|
552 |
+
"doHeaders" => 10,
|
553 |
+
"doHorizontalRules" => 20,
|
554 |
+
|
555 |
+
"doLists" => 40,
|
556 |
+
"doCodeBlocks" => 50,
|
557 |
+
"doBlockQuotes" => 60,
|
558 |
+
);
|
559 |
+
|
560 |
+
function runBlockGamut($text) {
|
561 |
+
#
|
562 |
+
# Run block gamut tranformations.
|
563 |
+
#
|
564 |
+
# We need to escape raw HTML in Markdown source before doing anything
|
565 |
+
# else. This need to be done for each block, and not only at the
|
566 |
+
# begining in the Markdown function since hashed blocks can be part of
|
567 |
+
# list items and could have been indented. Indented blocks would have
|
568 |
+
# been seen as a code block in a previous pass of hashHTMLBlocks.
|
569 |
+
$text = $this->hashHTMLBlocks($text);
|
570 |
+
|
571 |
+
return $this->runBasicBlockGamut($text);
|
572 |
+
}
|
573 |
+
|
574 |
+
function runBasicBlockGamut($text) {
|
575 |
+
#
|
576 |
+
# Run block gamut tranformations, without hashing HTML blocks. This is
|
577 |
+
# useful when HTML blocks are known to be already hashed, like in the first
|
578 |
+
# whole-document pass.
|
579 |
+
#
|
580 |
+
foreach ($this->block_gamut as $method => $priority) {
|
581 |
+
$text = $this->$method($text);
|
582 |
+
}
|
583 |
+
|
584 |
+
# Finally form paragraph and restore hashed blocks.
|
585 |
+
$text = $this->formParagraphs($text);
|
586 |
+
|
587 |
+
return $text;
|
588 |
+
}
|
589 |
+
|
590 |
+
|
591 |
+
function doHorizontalRules($text) {
|
592 |
+
# Do Horizontal Rules:
|
593 |
+
return preg_replace(
|
594 |
+
'{
|
595 |
+
^[ ]{0,3} # Leading space
|
596 |
+
([-*_]) # $1: First marker
|
597 |
+
(?> # Repeated marker group
|
598 |
+
[ ]{0,2} # Zero, one, or two spaces.
|
599 |
+
\1 # Marker character
|
600 |
+
){2,} # Group repeated at least twice
|
601 |
+
[ ]* # Tailing spaces
|
602 |
+
$ # End of line.
|
603 |
+
}mx',
|
604 |
+
"\n".$this->hashBlock("<hr$this->empty_element_suffix")."\n",
|
605 |
+
$text);
|
606 |
+
}
|
607 |
+
|
608 |
+
|
609 |
+
var $span_gamut = array(
|
610 |
+
#
|
611 |
+
# These are all the transformations that occur *within* block-level
|
612 |
+
# tags like paragraphs, headers, and list items.
|
613 |
+
#
|
614 |
+
# Process character escapes, code spans, and inline HTML
|
615 |
+
# in one shot.
|
616 |
+
"parseSpan" => -30,
|
617 |
+
|
618 |
+
# Process anchor and image tags. Images must come first,
|
619 |
+
# because ![foo][f] looks like an anchor.
|
620 |
+
"doImages" => 10,
|
621 |
+
"doAnchors" => 20,
|
622 |
+
|
623 |
+
# Make links out of things like `<http://example.com/>`
|
624 |
+
# Must come after doAnchors, because you can use < and >
|
625 |
+
# delimiters in inline links like [this](<url>).
|
626 |
+
"doAutoLinks" => 30,
|
627 |
+
"encodeAmpsAndAngles" => 40,
|
628 |
+
|
629 |
+
"doItalicsAndBold" => 50,
|
630 |
+
"doHardBreaks" => 60,
|
631 |
+
);
|
632 |
+
|
633 |
+
function runSpanGamut($text) {
|
634 |
+
#
|
635 |
+
# Run span gamut tranformations.
|
636 |
+
#
|
637 |
+
foreach ($this->span_gamut as $method => $priority) {
|
638 |
+
$text = $this->$method($text);
|
639 |
+
}
|
640 |
+
|
641 |
+
return $text;
|
642 |
+
}
|
643 |
+
|
644 |
+
|
645 |
+
function doHardBreaks($text) {
|
646 |
+
# Do hard breaks:
|
647 |
+
return preg_replace_callback('/ {2,}\n/',
|
648 |
+
array(&$this, '_doHardBreaks_callback'), $text);
|
649 |
+
}
|
650 |
+
function _doHardBreaks_callback($matches) {
|
651 |
+
return $this->hashPart("<br$this->empty_element_suffix\n");
|
652 |
+
}
|
653 |
+
|
654 |
+
|
655 |
+
function doAnchors($text) {
|
656 |
+
#
|
657 |
+
# Turn Markdown link shortcuts into XHTML <a> tags.
|
658 |
+
#
|
659 |
+
if ($this->in_anchor) return $text;
|
660 |
+
$this->in_anchor = true;
|
661 |
+
|
662 |
+
#
|
663 |
+
# First, handle reference-style links: [link text] [id]
|
664 |
+
#
|
665 |
+
$text = preg_replace_callback('{
|
666 |
+
( # wrap whole match in $1
|
667 |
+
\[
|
668 |
+
('.$this->nested_brackets_re.') # link text = $2
|
669 |
+
\]
|
670 |
+
|
671 |
+
[ ]? # one optional space
|
672 |
+
(?:\n[ ]*)? # one optional newline followed by spaces
|
673 |
+
|
674 |
+
\[
|
675 |
+
(.*?) # id = $3
|
676 |
+
\]
|
677 |
+
)
|
678 |
+
}xs',
|
679 |
+
array(&$this, '_doAnchors_reference_callback'), $text);
|
680 |
+
|
681 |
+
#
|
682 |
+
# Next, inline-style links: [link text](url "optional title")
|
683 |
+
#
|
684 |
+
$text = preg_replace_callback('{
|
685 |
+
( # wrap whole match in $1
|
686 |
+
\[
|
687 |
+
('.$this->nested_brackets_re.') # link text = $2
|
688 |
+
\]
|
689 |
+
\( # literal paren
|
690 |
+
[ \n]*
|
691 |
+
(?:
|
692 |
+
<(.+?)> # href = $3
|
693 |
+
|
|
694 |
+
('.$this->nested_url_parenthesis_re.') # href = $4
|
695 |
+
)
|
696 |
+
[ \n]*
|
697 |
+
( # $5
|
698 |
+
([\'"]) # quote char = $6
|
699 |
+
(.*?) # Title = $7
|
700 |
+
\6 # matching quote
|
701 |
+
[ \n]* # ignore any spaces/tabs between closing quote and )
|
702 |
+
)? # title is optional
|
703 |
+
\)
|
704 |
+
)
|
705 |
+
}xs',
|
706 |
+
array(&$this, '_doAnchors_inline_callback'), $text);
|
707 |
+
|
708 |
+
#
|
709 |
+
# Last, handle reference-style shortcuts: [link text]
|
710 |
+
# These must come last in case you've also got [link text][1]
|
711 |
+
# or [link text](/foo)
|
712 |
+
#
|
713 |
+
$text = preg_replace_callback('{
|
714 |
+
( # wrap whole match in $1
|
715 |
+
\[
|
716 |
+
([^\[\]]+) # link text = $2; can\'t contain [ or ]
|
717 |
+
\]
|
718 |
+
)
|
719 |
+
}xs',
|
720 |
+
array(&$this, '_doAnchors_reference_callback'), $text);
|
721 |
+
|
722 |
+
$this->in_anchor = false;
|
723 |
+
return $text;
|
724 |
+
}
|
725 |
+
function _doAnchors_reference_callback($matches) {
|
726 |
+
$whole_match = $matches[1];
|
727 |
+
$link_text = $matches[2];
|
728 |
+
$link_id =& $matches[3];
|
729 |
+
|
730 |
+
if ($link_id == "") {
|
731 |
+
# for shortcut links like [this][] or [this].
|
732 |
+
$link_id = $link_text;
|
733 |
+
}
|
734 |
+
|
735 |
+
# lower-case and turn embedded newlines into spaces
|
736 |
+
$link_id = strtolower($link_id);
|
737 |
+
$link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
|
738 |
+
|
739 |
+
if (isset($this->urls[$link_id])) {
|
740 |
+
$url = $this->urls[$link_id];
|
741 |
+
$url = $this->encodeAttribute($url);
|
742 |
+
|
743 |
+
$result = "<a href=\"$url\"";
|
744 |
+
if ( isset( $this->titles[$link_id] ) ) {
|
745 |
+
$title = $this->titles[$link_id];
|
746 |
+
$title = $this->encodeAttribute($title);
|
747 |
+
$result .= " title=\"$title\"";
|
748 |
+
}
|
749 |
+
|
750 |
+
$link_text = $this->runSpanGamut($link_text);
|
751 |
+
$result .= ">$link_text</a>";
|
752 |
+
$result = $this->hashPart($result);
|
753 |
+
}
|
754 |
+
else {
|
755 |
+
$result = $whole_match;
|
756 |
+
}
|
757 |
+
return $result;
|
758 |
+
}
|
759 |
+
function _doAnchors_inline_callback($matches) {
|
760 |
+
$whole_match = $matches[1];
|
761 |
+
$link_text = $this->runSpanGamut($matches[2]);
|
762 |
+
$url = $matches[3] == '' ? $matches[4] : $matches[3];
|
763 |
+
$title =& $matches[7];
|
764 |
+
|
765 |
+
$url = $this->encodeAttribute($url);
|
766 |
+
|
767 |
+
$result = "<a href=\"$url\"";
|
768 |
+
if (isset($title)) {
|
769 |
+
$title = $this->encodeAttribute($title);
|
770 |
+
$result .= " title=\"$title\"";
|
771 |
+
}
|
772 |
+
|
773 |
+
$link_text = $this->runSpanGamut($link_text);
|
774 |
+
$result .= ">$link_text</a>";
|
775 |
+
|
776 |
+
return $this->hashPart($result);
|
777 |
+
}
|
778 |
+
|
779 |
+
|
780 |
+
function doImages($text) {
|
781 |
+
#
|
782 |
+
# Turn Markdown image shortcuts into <img> tags.
|
783 |
+
#
|
784 |
+
#
|
785 |
+
# First, handle reference-style labeled images: ![alt text][id]
|
786 |
+
#
|
787 |
+
$text = preg_replace_callback('{
|
788 |
+
( # wrap whole match in $1
|
789 |
+
!\[
|
790 |
+
('.$this->nested_brackets_re.') # alt text = $2
|
791 |
+
\]
|
792 |
+
|
793 |
+
[ ]? # one optional space
|
794 |
+
(?:\n[ ]*)? # one optional newline followed by spaces
|
795 |
+
|
796 |
+
\[
|
797 |
+
(.*?) # id = $3
|
798 |
+
\]
|
799 |
+
|
800 |
+
)
|
801 |
+
}xs',
|
802 |
+
array(&$this, '_doImages_reference_callback'), $text);
|
803 |
+
|
804 |
+
#
|
805 |
+
# Next, handle inline images: ![alt text](url "optional title")
|
806 |
+
# Don't forget: encode * and _
|
807 |
+
#
|
808 |
+
$text = preg_replace_callback('{
|
809 |
+
( # wrap whole match in $1
|
810 |
+
!\[
|
811 |
+
('.$this->nested_brackets_re.') # alt text = $2
|
812 |
+
\]
|
813 |
+
\s? # One optional whitespace character
|
814 |
+
\( # literal paren
|
815 |
+
[ \n]*
|
816 |
+
(?:
|
817 |
+
<(\S*)> # src url = $3
|
818 |
+
|
|
819 |
+
('.$this->nested_url_parenthesis_re.') # src url = $4
|
820 |
+
)
|
821 |
+
[ \n]*
|
822 |
+
( # $5
|
823 |
+
([\'"]) # quote char = $6
|
824 |
+
(.*?) # title = $7
|
825 |
+
\6 # matching quote
|
826 |
+
[ \n]*
|
827 |
+
)? # title is optional
|
828 |
+
\)
|
829 |
+
)
|
830 |
+
}xs',
|
831 |
+
array(&$this, '_doImages_inline_callback'), $text);
|
832 |
+
|
833 |
+
return $text;
|
834 |
+
}
|
835 |
+
function _doImages_reference_callback($matches) {
|
836 |
+
$whole_match = $matches[1];
|
837 |
+
$alt_text = $matches[2];
|
838 |
+
$link_id = strtolower($matches[3]);
|
839 |
+
|
840 |
+
if ($link_id == "") {
|
841 |
+
$link_id = strtolower($alt_text); # for shortcut links like ![this][].
|
842 |
+
}
|
843 |
+
|
844 |
+
$alt_text = $this->encodeAttribute($alt_text);
|
845 |
+
if (isset($this->urls[$link_id])) {
|
846 |
+
$url = $this->encodeAttribute($this->urls[$link_id]);
|
847 |
+
$result = "<img src=\"$url\" alt=\"$alt_text\"";
|
848 |
+
if (isset($this->titles[$link_id])) {
|
849 |
+
$title = $this->titles[$link_id];
|
850 |
+
$title = $this->encodeAttribute($title);
|
851 |
+
$result .= " title=\"$title\"";
|
852 |
+
}
|
853 |
+
$result .= $this->empty_element_suffix;
|
854 |
+
$result = $this->hashPart($result);
|
855 |
+
}
|
856 |
+
else {
|
857 |
+
# If there's no such link ID, leave intact:
|
858 |
+
$result = $whole_match;
|
859 |
+
}
|
860 |
+
|
861 |
+
return $result;
|
862 |
+
}
|
863 |
+
function _doImages_inline_callback($matches) {
|
864 |
+
$whole_match = $matches[1];
|
865 |
+
$alt_text = $matches[2];
|
866 |
+
$url = $matches[3] == '' ? $matches[4] : $matches[3];
|
867 |
+
$title =& $matches[7];
|
868 |
+
|
869 |
+
$alt_text = $this->encodeAttribute($alt_text);
|
870 |
+
$url = $this->encodeAttribute($url);
|
871 |
+
$result = "<img src=\"$url\" alt=\"$alt_text\"";
|
872 |
+
if (isset($title)) {
|
873 |
+
$title = $this->encodeAttribute($title);
|
874 |
+
$result .= " title=\"$title\""; # $title already quoted
|
875 |
+
}
|
876 |
+
$result .= $this->empty_element_suffix;
|
877 |
+
|
878 |
+
return $this->hashPart($result);
|
879 |
+
}
|
880 |
+
|
881 |
+
|
882 |
+
function doHeaders($text) {
|
883 |
+
# Setext-style headers:
|
884 |
+
# Header 1
|
885 |
+
# ========
|
886 |
+
#
|
887 |
+
# Header 2
|
888 |
+
# --------
|
889 |
+
#
|
890 |
+
$text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
|
891 |
+
array(&$this, '_doHeaders_callback_setext'), $text);
|
892 |
+
|
893 |
+
# atx-style headers:
|
894 |
+
# # Header 1
|
895 |
+
# ## Header 2
|
896 |
+
# ## Header 2 with closing hashes ##
|
897 |
+
# ...
|
898 |
+
# ###### Header 6
|
899 |
+
#
|
900 |
+
$text = preg_replace_callback('{
|
901 |
+
^(\#{1,6}) # $1 = string of #\'s
|
902 |
+
[ ]*
|
903 |
+
(.+?) # $2 = Header text
|
904 |
+
[ ]*
|
905 |
+
\#* # optional closing #\'s (not counted)
|
906 |
+
\n+
|
907 |
+
}xm',
|
908 |
+
array(&$this, '_doHeaders_callback_atx'), $text);
|
909 |
+
|
910 |
+
return $text;
|
911 |
+
}
|
912 |
+
function _doHeaders_callback_setext($matches) {
|
913 |
+
# Terrible hack to check we haven't found an empty list item.
|
914 |
+
if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1]))
|
915 |
+
return $matches[0];
|
916 |
+
|
917 |
+
$level = $matches[2]{0} == '=' ? 1 : 2;
|
918 |
+
$block = "<h$level>".$this->runSpanGamut($matches[1])."</h$level>";
|
919 |
+
return "\n" . $this->hashBlock($block) . "\n\n";
|
920 |
+
}
|
921 |
+
function _doHeaders_callback_atx($matches) {
|
922 |
+
$level = strlen($matches[1]);
|
923 |
+
$block = "<h$level>".$this->runSpanGamut($matches[2])."</h$level>";
|
924 |
+
return "\n" . $this->hashBlock($block) . "\n\n";
|
925 |
+
}
|
926 |
+
|
927 |
+
|
928 |
+
function doLists($text) {
|
929 |
+
#
|
930 |
+
# Form HTML ordered (numbered) and unordered (bulleted) lists.
|
931 |
+
#
|
932 |
+
$less_than_tab = $this->tab_width - 1;
|
933 |
+
|
934 |
+
# Re-usable patterns to match list item bullets and number markers:
|
935 |
+
$marker_ul_re = '[*+-]';
|
936 |
+
$marker_ol_re = '\d+[\.]';
|
937 |
+
$marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
|
938 |
+
|
939 |
+
$markers_relist = array(
|
940 |
+
$marker_ul_re => $marker_ol_re,
|
941 |
+
$marker_ol_re => $marker_ul_re,
|
942 |
+
);
|
943 |
+
|
944 |
+
foreach ($markers_relist as $marker_re => $other_marker_re) {
|
945 |
+
# Re-usable pattern to match any entirel ul or ol list:
|
946 |
+
$whole_list_re = '
|
947 |
+
( # $1 = whole list
|
948 |
+
( # $2
|
949 |
+
([ ]{0,'.$less_than_tab.'}) # $3 = number of spaces
|
950 |
+
('.$marker_re.') # $4 = first list item marker
|
951 |
+
[ ]+
|
952 |
+
)
|
953 |
+
(?s:.+?)
|
954 |
+
( # $5
|
955 |
+
\z
|
956 |
+
|
|
957 |
+
\n{2,}
|
958 |
+
(?=\S)
|
959 |
+
(?! # Negative lookahead for another list item marker
|
960 |
+
[ ]*
|
961 |
+
'.$marker_re.'[ ]+
|
962 |
+
)
|
963 |
+
|
|
964 |
+
(?= # Lookahead for another kind of list
|
965 |
+
\n
|
966 |
+
\3 # Must have the same indentation
|
967 |
+
'.$other_marker_re.'[ ]+
|
968 |
+
)
|
969 |
+
)
|
970 |
+
)
|
971 |
+
'; // mx
|
972 |
+
|
973 |
+
# We use a different prefix before nested lists than top-level lists.
|
974 |
+
# See extended comment in _ProcessListItems().
|
975 |
+
|
976 |
+
if ($this->list_level) {
|
977 |
+
$text = preg_replace_callback('{
|
978 |
+
^
|
979 |
+
'.$whole_list_re.'
|
980 |
+
}mx',
|
981 |
+
array(&$this, '_doLists_callback'), $text);
|
982 |
+
}
|
983 |
+
else {
|
984 |
+
$text = preg_replace_callback('{
|
985 |
+
(?:(?<=\n)\n|\A\n?) # Must eat the newline
|
986 |
+
'.$whole_list_re.'
|
987 |
+
}mx',
|
988 |
+
array(&$this, '_doLists_callback'), $text);
|
989 |
+
}
|
990 |
+
}
|
991 |
+
|
992 |
+
return $text;
|
993 |
+
}
|
994 |
+
function _doLists_callback($matches) {
|
995 |
+
# Re-usable patterns to match list item bullets and number markers:
|
996 |
+
$marker_ul_re = '[*+-]';
|
997 |
+
$marker_ol_re = '\d+[\.]';
|
998 |
+
$marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
|
999 |
+
|
1000 |
+
$list = $matches[1];
|
1001 |
+
$list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol";
|
1002 |
+
|
1003 |
+
$marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
|
1004 |
+
|
1005 |
+
$list .= "\n";
|
1006 |
+
$result = $this->processListItems($list, $marker_any_re);
|
1007 |
+
|
1008 |
+
$result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>");
|
1009 |
+
return "\n". $result ."\n\n";
|
1010 |
+
}
|
1011 |
+
|
1012 |
+
var $list_level = 0;
|
1013 |
+
|
1014 |
+
function processListItems($list_str, $marker_any_re) {
|
1015 |
+
#
|
1016 |
+
# Process the contents of a single ordered or unordered list, splitting it
|
1017 |
+
# into individual list items.
|
1018 |
+
#
|
1019 |
+
# The $this->list_level global keeps track of when we're inside a list.
|
1020 |
+
# Each time we enter a list, we increment it; when we leave a list,
|
1021 |
+
# we decrement. If it's zero, we're not in a list anymore.
|
1022 |
+
#
|
1023 |
+
# We do this because when we're not inside a list, we want to treat
|
1024 |
+
# something like this:
|
1025 |
+
#
|
1026 |
+
# I recommend upgrading to version
|
1027 |
+
# 8. Oops, now this line is treated
|
1028 |
+
# as a sub-list.
|
1029 |
+
#
|
1030 |
+
# As a single paragraph, despite the fact that the second line starts
|
1031 |
+
# with a digit-period-space sequence.
|
1032 |
+
#
|
1033 |
+
# Whereas when we're inside a list (or sub-list), that line will be
|
1034 |
+
# treated as the start of a sub-list. What a kludge, huh? This is
|
1035 |
+
# an aspect of Markdown's syntax that's hard to parse perfectly
|
1036 |
+
# without resorting to mind-reading. Perhaps the solution is to
|
1037 |
+
# change the syntax rules such that sub-lists must start with a
|
1038 |
+
# starting cardinal number; e.g. "1." or "a.".
|
1039 |
+
|
1040 |
+
$this->list_level++;
|
1041 |
+
|
1042 |
+
# trim trailing blank lines:
|
1043 |
+
$list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
|
1044 |
+
|
1045 |
+
$list_str = preg_replace_callback('{
|
1046 |
+
(\n)? # leading line = $1
|
1047 |
+
(^[ ]*) # leading whitespace = $2
|
1048 |
+
('.$marker_any_re.' # list marker and space = $3
|
1049 |
+
(?:[ ]+|(?=\n)) # space only required if item is not empty
|
1050 |
+
)
|
1051 |
+
((?s:.*?)) # list item text = $4
|
1052 |
+
(?:(\n+(?=\n))|\n) # tailing blank line = $5
|
1053 |
+
(?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))
|
1054 |
+
}xm',
|
1055 |
+
array(&$this, '_processListItems_callback'), $list_str);
|
1056 |
+
|
1057 |
+
$this->list_level--;
|
1058 |
+
return $list_str;
|
1059 |
+
}
|
1060 |
+
function _processListItems_callback($matches) {
|
1061 |
+
$item = $matches[4];
|
1062 |
+
$leading_line =& $matches[1];
|
1063 |
+
$leading_space =& $matches[2];
|
1064 |
+
$marker_space = $matches[3];
|
1065 |
+
$tailing_blank_line =& $matches[5];
|
1066 |
+
|
1067 |
+
if ($leading_line || $tailing_blank_line ||
|
1068 |
+
preg_match('/\n{2,}/', $item))
|
1069 |
+
{
|
1070 |
+
# Replace marker with the appropriate whitespace indentation
|
1071 |
+
$item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
|
1072 |
+
$item = $this->runBlockGamut($this->outdent($item)."\n");
|
1073 |
+
}
|
1074 |
+
else {
|
1075 |
+
# Recursion for sub-lists:
|
1076 |
+
$item = $this->doLists($this->outdent($item));
|
1077 |
+
$item = preg_replace('/\n+$/', '', $item);
|
1078 |
+
$item = $this->runSpanGamut($item);
|
1079 |
+
}
|
1080 |
+
|
1081 |
+
return "<li>" . $item . "</li>\n";
|
1082 |
+
}
|
1083 |
+
|
1084 |
+
|
1085 |
+
function doCodeBlocks($text) {
|
1086 |
+
#
|
1087 |
+
# Process Markdown `<pre><code>` blocks.
|
1088 |
+
#
|
1089 |
+
$text = preg_replace_callback('{
|
1090 |
+
(?:\n\n|\A\n?)
|
1091 |
+
( # $1 = the code block -- one or more lines, starting with a space/tab
|
1092 |
+
(?>
|
1093 |
+
[ ]{'.$this->tab_width.'} # Lines must start with a tab or a tab-width of spaces
|
1094 |
+
.*\n+
|
1095 |
+
)+
|
1096 |
+
)
|
1097 |
+
((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
|
1098 |
+
}xm',
|
1099 |
+
array(&$this, '_doCodeBlocks_callback'), $text);
|
1100 |
+
|
1101 |
+
return $text;
|
1102 |
+
}
|
1103 |
+
function _doCodeBlocks_callback($matches) {
|
1104 |
+
$codeblock = $matches[1];
|
1105 |
+
|
1106 |
+
$codeblock = $this->outdent($codeblock);
|
1107 |
+
$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
|
1108 |
+
|
1109 |
+
# trim leading newlines and trailing newlines
|
1110 |
+
$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
|
1111 |
+
|
1112 |
+
$codeblock = "<pre><code>$codeblock\n</code></pre>";
|
1113 |
+
return "\n\n".$this->hashBlock($codeblock)."\n\n";
|
1114 |
+
}
|
1115 |
+
|
1116 |
+
|
1117 |
+
function makeCodeSpan($code) {
|
1118 |
+
#
|
1119 |
+
# Create a code span markup for $code. Called from handleSpanToken.
|
1120 |
+
#
|
1121 |
+
$code = htmlspecialchars(trim($code), ENT_NOQUOTES);
|
1122 |
+
return $this->hashPart("<code>$code</code>");
|
1123 |
+
}
|
1124 |
+
|
1125 |
+
|
1126 |
+
var $em_relist = array(
|
1127 |
+
'' => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?=\S|$)(?![\.,:;]\s)',
|
1128 |
+
'*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
|
1129 |
+
'_' => '(?<=\S|^)(?<!_)_(?!_)',
|
1130 |
+
);
|
1131 |
+
var $strong_relist = array(
|
1132 |
+
'' => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?=\S|$)(?![\.,:;]\s)',
|
1133 |
+
'**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
|
1134 |
+
'__' => '(?<=\S|^)(?<!_)__(?!_)',
|
1135 |
+
);
|
1136 |
+
var $em_strong_relist = array(
|
1137 |
+
'' => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?=\S|$)(?![\.,:;]\s)',
|
1138 |
+
'***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
|
1139 |
+
'___' => '(?<=\S|^)(?<!_)___(?!_)',
|
1140 |
+
);
|
1141 |
+
var $em_strong_prepared_relist;
|
1142 |
+
|
1143 |
+
function prepareItalicsAndBold() {
|
1144 |
+
#
|
1145 |
+
# Prepare regular expressions for searching emphasis tokens in any
|
1146 |
+
# context.
|
1147 |
+
#
|
1148 |
+
foreach ($this->em_relist as $em => $em_re) {
|
1149 |
+
foreach ($this->strong_relist as $strong => $strong_re) {
|
1150 |
+
# Construct list of allowed token expressions.
|
1151 |
+
$token_relist = array();
|
1152 |
+
if (isset($this->em_strong_relist["$em$strong"])) {
|
1153 |
+
$token_relist[] = $this->em_strong_relist["$em$strong"];
|
1154 |
+
}
|
1155 |
+
$token_relist[] = $em_re;
|
1156 |
+
$token_relist[] = $strong_re;
|
1157 |
+
|
1158 |
+
# Construct master expression from list.
|
1159 |
+
$token_re = '{('. implode('|', $token_relist) .')}';
|
1160 |
+
$this->em_strong_prepared_relist["$em$strong"] = $token_re;
|
1161 |
+
}
|
1162 |
+
}
|
1163 |
+
}
|
1164 |
+
|
1165 |
+
function doItalicsAndBold($text) {
|
1166 |
+
$token_stack = array('');
|
1167 |
+
$text_stack = array('');
|
1168 |
+
$em = '';
|
1169 |
+
$strong = '';
|
1170 |
+
$tree_char_em = false;
|
1171 |
+
|
1172 |
+
while (1) {
|
1173 |
+
#
|
1174 |
+
# Get prepared regular expression for seraching emphasis tokens
|
1175 |
+
# in current context.
|
1176 |
+
#
|
1177 |
+
$token_re = $this->em_strong_prepared_relist["$em$strong"];
|
1178 |
+
|
1179 |
+
#
|
1180 |
+
# Each loop iteration search for the next emphasis token.
|
1181 |
+
# Each token is then passed to handleSpanToken.
|
1182 |
+
#
|
1183 |
+
$parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
|
1184 |
+
$text_stack[0] .= $parts[0];
|
1185 |
+
$token =& $parts[1];
|
1186 |
+
$text =& $parts[2];
|
1187 |
+
|
1188 |
+
if (empty($token)) {
|
1189 |
+
# Reached end of text span: empty stack without emitting.
|
1190 |
+
# any more emphasis.
|
1191 |
+
while ($token_stack[0]) {
|
1192 |
+
$text_stack[1] .= array_shift($token_stack);
|
1193 |
+
$text_stack[0] .= array_shift($text_stack);
|
1194 |
+
}
|
1195 |
+
break;
|
1196 |
+
}
|
1197 |
+
|
1198 |
+
$token_len = strlen($token);
|
1199 |
+
if ($tree_char_em) {
|
1200 |
+
# Reached closing marker while inside a three-char emphasis.
|
1201 |
+
if ($token_len == 3) {
|
1202 |
+
# Three-char closing marker, close em and strong.
|
1203 |
+
array_shift($token_stack);
|
1204 |
+
$span = array_shift($text_stack);
|
1205 |
+
$span = $this->runSpanGamut($span);
|
1206 |
+
$span = "<strong><em>$span</em></strong>";
|
1207 |
+
$text_stack[0] .= $this->hashPart($span);
|
1208 |
+
$em = '';
|
1209 |
+
$strong = '';
|
1210 |
+
} else {
|
1211 |
+
# Other closing marker: close one em or strong and
|
1212 |
+
# change current token state to match the other
|
1213 |
+
$token_stack[0] = str_repeat($token{0}, 3-$token_len);
|
1214 |
+
$tag = $token_len == 2 ? "strong" : "em";
|
1215 |
+
$span = $text_stack[0];
|
1216 |
+
$span = $this->runSpanGamut($span);
|
1217 |
+
$span = "<$tag>$span</$tag>";
|
1218 |
+
$text_stack[0] = $this->hashPart($span);
|
1219 |
+
$$tag = ''; # $$tag stands for $em or $strong
|
1220 |
+
}
|
1221 |
+
$tree_char_em = false;
|
1222 |
+
} else if ($token_len == 3) {
|
1223 |
+
if ($em) {
|
1224 |
+
# Reached closing marker for both em and strong.
|
1225 |
+
# Closing strong marker:
|
1226 |
+
for ($i = 0; $i < 2; ++$i) {
|
1227 |
+
$shifted_token = array_shift($token_stack);
|
1228 |
+
$tag = strlen($shifted_token) == 2 ? "strong" : "em";
|
1229 |
+
$span = array_shift($text_stack);
|
1230 |
+
$span = $this->runSpanGamut($span);
|
1231 |
+
$span = "<$tag>$span</$tag>";
|
1232 |
+
$text_stack[0] .= $this->hashPart($span);
|
1233 |
+
$$tag = ''; # $$tag stands for $em or $strong
|
1234 |
+
}
|
1235 |
+
} else {
|
1236 |
+
# Reached opening three-char emphasis marker. Push on token
|
1237 |
+
# stack; will be handled by the special condition above.
|
1238 |
+
$em = $token{0};
|
1239 |
+
$strong = "$em$em";
|
1240 |
+
array_unshift($token_stack, $token);
|
1241 |
+
array_unshift($text_stack, '');
|
1242 |
+
$tree_char_em = true;
|
1243 |
+
}
|
1244 |
+
} else if ($token_len == 2) {
|
1245 |
+
if ($strong) {
|
1246 |
+
# Unwind any dangling emphasis marker:
|
1247 |
+
if (strlen($token_stack[0]) == 1) {
|
1248 |
+
$text_stack[1] .= array_shift($token_stack);
|
1249 |
+
$text_stack[0] .= array_shift($text_stack);
|
1250 |
+
}
|
1251 |
+
# Closing strong marker:
|
1252 |
+
array_shift($token_stack);
|
1253 |
+
$span = array_shift($text_stack);
|
1254 |
+
$span = $this->runSpanGamut($span);
|
1255 |
+
$span = "<strong>$span</strong>";
|
1256 |
+
$text_stack[0] .= $this->hashPart($span);
|
1257 |
+
$strong = '';
|
1258 |
+
} else {
|
1259 |
+
array_unshift($token_stack, $token);
|
1260 |
+
array_unshift($text_stack, '');
|
1261 |
+
$strong = $token;
|
1262 |
+
}
|
1263 |
+
} else {
|
1264 |
+
# Here $token_len == 1
|
1265 |
+
if ($em) {
|
1266 |
+
if (strlen($token_stack[0]) == 1) {
|
1267 |
+
# Closing emphasis marker:
|
1268 |
+
array_shift($token_stack);
|
1269 |
+
$span = array_shift($text_stack);
|
1270 |
+
$span = $this->runSpanGamut($span);
|
1271 |
+
$span = "<em>$span</em>";
|
1272 |
+
$text_stack[0] .= $this->hashPart($span);
|
1273 |
+
$em = '';
|
1274 |
+
} else {
|
1275 |
+
$text_stack[0] .= $token;
|
1276 |
+
}
|
1277 |
+
} else {
|
1278 |
+
array_unshift($token_stack, $token);
|
1279 |
+
array_unshift($text_stack, '');
|
1280 |
+
$em = $token;
|
1281 |
+
}
|
1282 |
+
}
|
1283 |
+
}
|
1284 |
+
return $text_stack[0];
|
1285 |
+
}
|
1286 |
+
|
1287 |
+
|
1288 |
+
function doBlockQuotes($text) {
|
1289 |
+
$text = preg_replace_callback('/
|
1290 |
+
( # Wrap whole match in $1
|
1291 |
+
(?>
|
1292 |
+
^[ ]*>[ ]? # ">" at the start of a line
|
1293 |
+
.+\n # rest of the first line
|
1294 |
+
(.+\n)* # subsequent consecutive lines
|
1295 |
+
\n* # blanks
|
1296 |
+
)+
|
1297 |
+
)
|
1298 |
+
/xm',
|
1299 |
+
array(&$this, '_doBlockQuotes_callback'), $text);
|
1300 |
+
|
1301 |
+
return $text;
|
1302 |
+
}
|
1303 |
+
function _doBlockQuotes_callback($matches) {
|
1304 |
+
$bq = $matches[1];
|
1305 |
+
# trim one level of quoting - trim whitespace-only lines
|
1306 |
+
$bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
|
1307 |
+
$bq = $this->runBlockGamut($bq); # recurse
|
1308 |
+
|
1309 |
+
$bq = preg_replace('/^/m', " ", $bq);
|
1310 |
+
# These leading spaces cause problem with <pre> content,
|
1311 |
+
# so we need to fix that:
|
1312 |
+
$bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx',
|
1313 |
+
array(&$this, '_doBlockQuotes_callback2'), $bq);
|
1314 |
+
|
1315 |
+
return "\n". $this->hashBlock("<blockquote>\n$bq\n</blockquote>")."\n\n";
|
1316 |
+
}
|
1317 |
+
function _doBlockQuotes_callback2($matches) {
|
1318 |
+
$pre = $matches[1];
|
1319 |
+
$pre = preg_replace('/^ /m', '', $pre);
|
1320 |
+
return $pre;
|
1321 |
+
}
|
1322 |
+
|
1323 |
+
|
1324 |
+
function formParagraphs($text) {
|
1325 |
+
#
|
1326 |
+
# Params:
|
1327 |
+
# $text - string to process with html <p> tags
|
1328 |
+
#
|
1329 |
+
# Strip leading and trailing lines:
|
1330 |
+
$text = preg_replace('/\A\n+|\n+\z/', '', $text);
|
1331 |
+
|
1332 |
+
$grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
|
1333 |
+
|
1334 |
+
#
|
1335 |
+
# Wrap <p> tags and unhashify HTML blocks
|
1336 |
+
#
|
1337 |
+
foreach ($grafs as $key => $value) {
|
1338 |
+
if (!preg_match('/^B\x1A[0-9]+B$/', $value)) {
|
1339 |
+
# Is a paragraph.
|
1340 |
+
$value = $this->runSpanGamut($value);
|
1341 |
+
$value = preg_replace('/^([ ]*)/', "<p>", $value);
|
1342 |
+
$value .= "</p>";
|
1343 |
+
$grafs[$key] = $this->unhash($value);
|
1344 |
+
}
|
1345 |
+
else {
|
1346 |
+
# Is a block.
|
1347 |
+
# Modify elements of @grafs in-place...
|
1348 |
+
$graf = $value;
|
1349 |
+
$block = $this->html_hashes[$graf];
|
1350 |
+
$graf = $block;
|
1351 |
+
// if (preg_match('{
|
1352 |
+
// \A
|
1353 |
+
// ( # $1 = <div> tag
|
1354 |
+
// <div \s+
|
1355 |
+
// [^>]*
|
1356 |
+
// \b
|
1357 |
+
// markdown\s*=\s* ([\'"]) # $2 = attr quote char
|
1358 |
+
// 1
|
1359 |
+
// \2
|
1360 |
+
// [^>]*
|
1361 |
+
// >
|
1362 |
+
// )
|
1363 |
+
// ( # $3 = contents
|
1364 |
+
// .*
|
1365 |
+
// )
|
1366 |
+
// (</div>) # $4 = closing tag
|
1367 |
+
// \z
|
1368 |
+
// }xs', $block, $matches))
|
1369 |
+
// {
|
1370 |
+
// list(, $div_open, , $div_content, $div_close) = $matches;
|
1371 |
+
//
|
1372 |
+
// # We can't call Markdown(), because that resets the hash;
|
1373 |
+
// # that initialization code should be pulled into its own sub, though.
|
1374 |
+
// $div_content = $this->hashHTMLBlocks($div_content);
|
1375 |
+
//
|
1376 |
+
// # Run document gamut methods on the content.
|
1377 |
+
// foreach ($this->document_gamut as $method => $priority) {
|
1378 |
+
// $div_content = $this->$method($div_content);
|
1379 |
+
// }
|
1380 |
+
//
|
1381 |
+
// $div_open = preg_replace(
|
1382 |
+
// '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open);
|
1383 |
+
//
|
1384 |
+
// $graf = $div_open . "\n" . $div_content . "\n" . $div_close;
|
1385 |
+
// }
|
1386 |
+
$grafs[$key] = $graf;
|
1387 |
+
}
|
1388 |
+
}
|
1389 |
+
|
1390 |
+
return implode("\n\n", $grafs);
|
1391 |
+
}
|
1392 |
+
|
1393 |
+
|
1394 |
+
function encodeAttribute($text) {
|
1395 |
+
#
|
1396 |
+
# Encode text for a double-quoted HTML attribute. This function
|
1397 |
+
# is *not* suitable for attributes enclosed in single quotes.
|
1398 |
+
#
|
1399 |
+
$text = $this->encodeAmpsAndAngles($text);
|
1400 |
+
$text = str_replace('"', '"', $text);
|
1401 |
+
return $text;
|
1402 |
+
}
|
1403 |
+
|
1404 |
+
|
1405 |
+
function encodeAmpsAndAngles($text) {
|
1406 |
+
#
|
1407 |
+
# Smart processing for ampersands and angle brackets that need to
|
1408 |
+
# be encoded. Valid character entities are left alone unless the
|
1409 |
+
# no-entities mode is set.
|
1410 |
+
#
|
1411 |
+
if ($this->no_entities) {
|
1412 |
+
$text = str_replace('&', '&', $text);
|
1413 |
+
} else {
|
1414 |
+
# Ampersand-encoding based entirely on Nat Irons's Amputator
|
1415 |
+
# MT plugin: <http://bumppo.net/projects/amputator/>
|
1416 |
+
$text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/',
|
1417 |
+
'&', $text);;
|
1418 |
+
}
|
1419 |
+
# Encode remaining <'s
|
1420 |
+
$text = str_replace('<', '<', $text);
|
1421 |
+
|
1422 |
+
return $text;
|
1423 |
+
}
|
1424 |
+
|
1425 |
+
|
1426 |
+
function doAutoLinks($text) {
|
1427 |
+
$text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i',
|
1428 |
+
array(&$this, '_doAutoLinks_url_callback'), $text);
|
1429 |
+
|
1430 |
+
# Email addresses: <address@domain.foo>
|
1431 |
+
$text = preg_replace_callback('{
|
1432 |
+
<
|
1433 |
+
(?:mailto:)?
|
1434 |
+
(
|
1435 |
+
(?:
|
1436 |
+
[-!#$%&\'*+/=?^_`.{|}~\w\x80-\xFF]+
|
1437 |
+
|
|
1438 |
+
".*?"
|
1439 |
+
)
|
1440 |
+
\@
|
1441 |
+
(?:
|
1442 |
+
[-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+
|
1443 |
+
|
|
1444 |
+
\[[\d.a-fA-F:]+\] # IPv4 & IPv6
|
1445 |
+
)
|
1446 |
+
)
|
1447 |
+
>
|
1448 |
+
}xi',
|
1449 |
+
array(&$this, '_doAutoLinks_email_callback'), $text);
|
1450 |
+
|
1451 |
+
return $text;
|
1452 |
+
}
|
1453 |
+
function _doAutoLinks_url_callback($matches) {
|
1454 |
+
$url = $this->encodeAttribute($matches[1]);
|
1455 |
+
$link = "<a href=\"$url\">$url</a>";
|
1456 |
+
return $this->hashPart($link);
|
1457 |
+
}
|
1458 |
+
function _doAutoLinks_email_callback($matches) {
|
1459 |
+
$address = $matches[1];
|
1460 |
+
$link = $this->encodeEmailAddress($address);
|
1461 |
+
return $this->hashPart($link);
|
1462 |
+
}
|
1463 |
+
|
1464 |
+
|
1465 |
+
function encodeEmailAddress($addr) {
|
1466 |
+
#
|
1467 |
+
# Input: an email address, e.g. "foo@example.com"
|
1468 |
+
#
|
1469 |
+
# Output: the email address as a mailto link, with each character
|
1470 |
+
# of the address encoded as either a decimal or hex entity, in
|
1471 |
+
# the hopes of foiling most address harvesting spam bots. E.g.:
|
1472 |
+
#
|
1473 |
+
# <p><a href="mailto:foo
|
1474 |
+
# @example.co
|
1475 |
+
# m">foo@exampl
|
1476 |
+
# e.com</a></p>
|
1477 |
+
#
|
1478 |
+
# Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
|
1479 |
+
# With some optimizations by Milian Wolff.
|
1480 |
+
#
|
1481 |
+
$addr = "mailto:" . $addr;
|
1482 |
+
$chars = preg_split('/(?<!^)(?!$)/', $addr);
|
1483 |
+
$seed = (int)abs(crc32($addr) / strlen($addr)); # Deterministic seed.
|
1484 |
+
|
1485 |
+
foreach ($chars as $key => $char) {
|
1486 |
+
$ord = ord($char);
|
1487 |
+
# Ignore non-ascii chars.
|
1488 |
+
if ($ord < 128) {
|
1489 |
+
$r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
|
1490 |
+
# roughly 10% raw, 45% hex, 45% dec
|
1491 |
+
# '@' *must* be encoded. I insist.
|
1492 |
+
if ($r > 90 && $char != '@') /* do nothing */;
|
1493 |
+
else if ($r < 45) $chars[$key] = '&#x'.dechex($ord).';';
|
1494 |
+
else $chars[$key] = '&#'.$ord.';';
|
1495 |
+
}
|
1496 |
+
}
|
1497 |
+
|
1498 |
+
$addr = implode('', $chars);
|
1499 |
+
$text = implode('', array_slice($chars, 7)); # text without `mailto:`
|
1500 |
+
$addr = "<a href=\"$addr\">$text</a>";
|
1501 |
+
|
1502 |
+
return $addr;
|
1503 |
+
}
|
1504 |
+
|
1505 |
+
|
1506 |
+
function parseSpan($str) {
|
1507 |
+
#
|
1508 |
+
# Take the string $str and parse it into tokens, hashing embeded HTML,
|
1509 |
+
# escaped characters and handling code spans.
|
1510 |
+
#
|
1511 |
+
$output = '';
|
1512 |
+
|
1513 |
+
$span_re = '{
|
1514 |
+
(
|
1515 |
+
\\\\'.$this->escape_chars_re.'
|
1516 |
+
|
|
1517 |
+
(?<![`\\\\])
|
1518 |
+
`+ # code span marker
|
1519 |
+
'.( $this->no_markup ? '' : '
|
1520 |
+
|
|
1521 |
+
<!-- .*? --> # comment
|
1522 |
+
|
|
1523 |
+
<\?.*?\?> | <%.*?%> # processing instruction
|
1524 |
+
|
|
1525 |
+
<[!$]?[-a-zA-Z0-9:_]+ # regular tags
|
1526 |
+
(?>
|
1527 |
+
\s
|
1528 |
+
(?>[^"\'>]+|"[^"]*"|\'[^\']*\')*
|
1529 |
+
)?
|
1530 |
+
>
|
1531 |
+
|
|
1532 |
+
<[-a-zA-Z0-9:_]+\s*/> # xml-style empty tag
|
1533 |
+
|
|
1534 |
+
</[-a-zA-Z0-9:_]+\s*> # closing tag
|
1535 |
+
').'
|
1536 |
+
)
|
1537 |
+
}xs';
|
1538 |
+
|
1539 |
+
while (1) {
|
1540 |
+
#
|
1541 |
+
# Each loop iteration seach for either the next tag, the next
|
1542 |
+
# openning code span marker, or the next escaped character.
|
1543 |
+
# Each token is then passed to handleSpanToken.
|
1544 |
+
#
|
1545 |
+
$parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
|
1546 |
+
|
1547 |
+
# Create token from text preceding tag.
|
1548 |
+
if ($parts[0] != "") {
|
1549 |
+
$output .= $parts[0];
|
1550 |
+
}
|
1551 |
+
|
1552 |
+
# Check if we reach the end.
|
1553 |
+
if (isset($parts[1])) {
|
1554 |
+
$output .= $this->handleSpanToken($parts[1], $parts[2]);
|
1555 |
+
$str = $parts[2];
|
1556 |
+
}
|
1557 |
+
else {
|
1558 |
+
break;
|
1559 |
+
}
|
1560 |
+
}
|
1561 |
+
|
1562 |
+
return $output;
|
1563 |
+
}
|
1564 |
+
|
1565 |
+
|
1566 |
+
function handleSpanToken($token, &$str) {
|
1567 |
+
#
|
1568 |
+
# Handle $token provided by parseSpan by determining its nature and
|
1569 |
+
# returning the corresponding value that should replace it.
|
1570 |
+
#
|
1571 |
+
switch ($token{0}) {
|
1572 |
+
case "\\":
|
1573 |
+
return $this->hashPart("&#". ord($token{1}). ";");
|
1574 |
+
case "`":
|
1575 |
+
# Search for end marker in remaining text.
|
1576 |
+
if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
|
1577 |
+
$str, $matches))
|
1578 |
+
{
|
1579 |
+
$str = $matches[2];
|
1580 |
+
$codespan = $this->makeCodeSpan($matches[1]);
|
1581 |
+
return $this->hashPart($codespan);
|
1582 |
+
}
|
1583 |
+
return $token; // return as text since no ending marker found.
|
1584 |
+
default:
|
1585 |
+
return $this->hashPart($token);
|
1586 |
+
}
|
1587 |
+
}
|
1588 |
+
|
1589 |
+
|
1590 |
+
function outdent($text) {
|
1591 |
+
#
|
1592 |
+
# Remove one level of line-leading tabs or spaces
|
1593 |
+
#
|
1594 |
+
return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
|
1595 |
+
}
|
1596 |
+
|
1597 |
+
|
1598 |
+
# String length function for detab. `_initDetab` will create a function to
|
1599 |
+
# hanlde UTF-8 if the default function does not exist.
|
1600 |
+
var $utf8_strlen = 'mb_strlen';
|
1601 |
+
|
1602 |
+
function detab($text) {
|
1603 |
+
#
|
1604 |
+
# Replace tabs with the appropriate amount of space.
|
1605 |
+
#
|
1606 |
+
# For each line we separate the line in blocks delemited by
|
1607 |
+
# tab characters. Then we reconstruct every line by adding the
|
1608 |
+
# appropriate number of space between each blocks.
|
1609 |
+
|
1610 |
+
$text = preg_replace_callback('/^.*\t.*$/m',
|
1611 |
+
array(&$this, '_detab_callback'), $text);
|
1612 |
+
|
1613 |
+
return $text;
|
1614 |
+
}
|
1615 |
+
function _detab_callback($matches) {
|
1616 |
+
$line = $matches[0];
|
1617 |
+
$strlen = $this->utf8_strlen; # strlen function for UTF-8.
|
1618 |
+
|
1619 |
+
# Split in blocks.
|
1620 |
+
$blocks = explode("\t", $line);
|
1621 |
+
# Add each blocks to the line.
|
1622 |
+
$line = $blocks[0];
|
1623 |
+
unset($blocks[0]); # Do not add first block twice.
|
1624 |
+
foreach ($blocks as $block) {
|
1625 |
+
# Calculate amount of space, insert spaces, insert block.
|
1626 |
+
$amount = $this->tab_width -
|
1627 |
+
$strlen($line, 'UTF-8') % $this->tab_width;
|
1628 |
+
$line .= str_repeat(" ", $amount) . $block;
|
1629 |
+
}
|
1630 |
+
return $line;
|
1631 |
+
}
|
1632 |
+
function _initDetab() {
|
1633 |
+
#
|
1634 |
+
# Check for the availability of the function in the `utf8_strlen` property
|
1635 |
+
# (initially `mb_strlen`). If the function is not available, create a
|
1636 |
+
# function that will loosely count the number of UTF-8 characters with a
|
1637 |
+
# regular expression.
|
1638 |
+
#
|
1639 |
+
if (function_exists($this->utf8_strlen)) return;
|
1640 |
+
$this->utf8_strlen = create_function('$text', 'return preg_match_all(
|
1641 |
+
"/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/",
|
1642 |
+
$text, $m);');
|
1643 |
+
}
|
1644 |
+
|
1645 |
+
|
1646 |
+
function unhash($text) {
|
1647 |
+
#
|
1648 |
+
# Swap back in all the tags hashed by _HashHTMLBlocks.
|
1649 |
+
#
|
1650 |
+
return preg_replace_callback('/(.)\x1A[0-9]+\1/',
|
1651 |
+
array(&$this, '_unhash_callback'), $text);
|
1652 |
+
}
|
1653 |
+
function _unhash_callback($matches) {
|
1654 |
+
return $this->html_hashes[$matches[0]];
|
1655 |
+
}
|
1656 |
+
|
1657 |
+
}
|
1658 |
+
|
1659 |
+
/*
|
1660 |
+
|
1661 |
+
PHP Markdown
|
1662 |
+
============
|
1663 |
+
|
1664 |
+
Description
|
1665 |
+
-----------
|
1666 |
+
|
1667 |
+
This is a PHP translation of the original Markdown formatter written in
|
1668 |
+
Perl by John Gruber.
|
1669 |
+
|
1670 |
+
Markdown is a text-to-HTML filter; it translates an easy-to-read /
|
1671 |
+
easy-to-write structured text format into HTML. Markdown's text format
|
1672 |
+
is mostly similar to that of plain text email, and supports features such
|
1673 |
+
as headers, *emphasis*, code blocks, blockquotes, and links.
|
1674 |
+
|
1675 |
+
Markdown's syntax is designed not as a generic markup language, but
|
1676 |
+
specifically to serve as a front-end to (X)HTML. You can use span-level
|
1677 |
+
HTML tags anywhere in a Markdown document, and you can use block level
|
1678 |
+
HTML tags (like <div> and <table> as well).
|
1679 |
+
|
1680 |
+
For more information about Markdown's syntax, see:
|
1681 |
+
|
1682 |
+
<http://daringfireball.net/projects/markdown/>
|
1683 |
+
|
1684 |
+
|
1685 |
+
Bugs
|
1686 |
+
----
|
1687 |
+
|
1688 |
+
To file bug reports please send email to:
|
1689 |
+
|
1690 |
+
<michel.fortin@michelf.ca>
|
1691 |
+
|
1692 |
+
Please include with your report: (1) the example input; (2) the output you
|
1693 |
+
expected; (3) the output Markdown actually produced.
|
1694 |
+
|
1695 |
+
|
1696 |
+
Version History
|
1697 |
+
---------------
|
1698 |
+
|
1699 |
+
See the readme file for detailed release notes for this version.
|
1700 |
+
|
1701 |
+
|
1702 |
+
Copyright and License
|
1703 |
+
---------------------
|
1704 |
+
|
1705 |
+
PHP Markdown
|
1706 |
+
Copyright (c) 2004-2013 Michel Fortin
|
1707 |
+
<http://michelf.ca/>
|
1708 |
+
All rights reserved.
|
1709 |
+
|
1710 |
+
Based on Markdown
|
1711 |
+
Copyright (c) 2003-2006 John Gruber
|
1712 |
+
<http://daringfireball.net/>
|
1713 |
+
All rights reserved.
|
1714 |
+
|
1715 |
+
Redistribution and use in source and binary forms, with or without
|
1716 |
+
modification, are permitted provided that the following conditions are
|
1717 |
+
met:
|
1718 |
+
|
1719 |
+
* Redistributions of source code must retain the above copyright notice,
|
1720 |
+
this list of conditions and the following disclaimer.
|
1721 |
+
|
1722 |
+
* Redistributions in binary form must reproduce the above copyright
|
1723 |
+
notice, this list of conditions and the following disclaimer in the
|
1724 |
+
documentation and/or other materials provided with the distribution.
|
1725 |
+
|
1726 |
+
* Neither the name "Markdown" nor the names of its contributors may
|
1727 |
+
be used to endorse or promote products derived from this software
|
1728 |
+
without specific prior written permission.
|
1729 |
+
|
1730 |
+
This software is provided by the copyright holders and contributors "as
|
1731 |
+
is" and any express or implied warranties, including, but not limited
|
1732 |
+
to, the implied warranties of merchantability and fitness for a
|
1733 |
+
particular purpose are disclaimed. In no event shall the copyright owner
|
1734 |
+
or contributors be liable for any direct, indirect, incidental, special,
|
1735 |
+
exemplary, or consequential damages (including, but not limited to,
|
1736 |
+
procurement of substitute goods or services; loss of use, data, or
|
1737 |
+
profits; or business interruption) however caused and on any theory of
|
1738 |
+
liability, whether in contract, strict liability, or tort (including
|
1739 |
+
negligence or otherwise) arising in any way out of the use of this
|
1740 |
+
software, even if advised of the possibility of such damage.
|
1741 |
+
|
1742 |
+
*/
|
1743 |
?>
|
classes/styles-font-menu/classes/sfm-admin.php
CHANGED
@@ -1,55 +1,55 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class SFM_Admin {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var Styles_Font_Menu Pointer to parent/wrapper object.
|
7 |
-
*/
|
8 |
-
var $plugin;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var string Slug for readme at /wp-admin/plugins.php?page=$readme_page_slug
|
12 |
-
*/
|
13 |
-
var $readme_page_slug = 'styles-font-menu';
|
14 |
-
|
15 |
-
public function __construct( $plugin ) {
|
16 |
-
$this->plugin = $plugin;
|
17 |
-
|
18 |
-
// Readme page
|
19 |
-
add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
|
20 |
-
add_action( 'admin_menu', array( $this, 'add_readme_page' ) );
|
21 |
-
add_action( 'network_admin_menu', array( $this, 'add_readme_page' ) );
|
22 |
-
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Add additional links to the plugin row
|
26 |
-
* If we're not running as a plugin, this won't do anything,
|
27 |
-
* because plugin_basename won't match any active plugin path.
|
28 |
-
*/
|
29 |
-
public function plugin_row_meta( $meta, $basename ) {
|
30 |
-
if ( $basename == $this->plugin->plugin_basename ) {
|
31 |
-
$meta[] = '<a href="' . network_admin_url( 'plugins.php?page=' . $this->readme_page_slug ) . '">How to use this plugin</a>';
|
32 |
-
}
|
33 |
-
return $meta;
|
34 |
-
}
|
35 |
-
|
36 |
-
/**
|
37 |
-
* Display readme and working example in WordPress admin
|
38 |
-
* Does not add a menu item
|
39 |
-
* @link /wp-admin/plugins.php?page=styles-font-menu
|
40 |
-
*/
|
41 |
-
public function add_readme_page() {
|
42 |
-
add_submenu_page( null, 'Font Menu', 'Font Menu', 'manage_options', $this->readme_page_slug, array( $this, 'get_view_readme' ) );
|
43 |
-
}
|
44 |
-
|
45 |
-
/**
|
46 |
-
* Display views/readme.php, which modifies readme.md to show a working example.
|
47 |
-
*/
|
48 |
-
public function get_view_readme() {
|
49 |
-
if ( !function_exists( 'Markdown' ) ) {
|
50 |
-
require_once dirname( __FILE__ ) . '/markdown/markdown.php';
|
51 |
-
}
|
52 |
-
$this->plugin->get_view( 'readme' );
|
53 |
-
}
|
54 |
-
|
55 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class SFM_Admin {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var Styles_Font_Menu Pointer to parent/wrapper object.
|
7 |
+
*/
|
8 |
+
var $plugin;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var string Slug for readme at /wp-admin/plugins.php?page=$readme_page_slug
|
12 |
+
*/
|
13 |
+
var $readme_page_slug = 'styles-font-menu';
|
14 |
+
|
15 |
+
public function __construct( $plugin ) {
|
16 |
+
$this->plugin = $plugin;
|
17 |
+
|
18 |
+
// Readme page
|
19 |
+
add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 );
|
20 |
+
add_action( 'admin_menu', array( $this, 'add_readme_page' ) );
|
21 |
+
add_action( 'network_admin_menu', array( $this, 'add_readme_page' ) );
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Add additional links to the plugin row
|
26 |
+
* If we're not running as a plugin, this won't do anything,
|
27 |
+
* because plugin_basename won't match any active plugin path.
|
28 |
+
*/
|
29 |
+
public function plugin_row_meta( $meta, $basename ) {
|
30 |
+
if ( $basename == $this->plugin->plugin_basename ) {
|
31 |
+
$meta[] = '<a href="' . network_admin_url( 'plugins.php?page=' . $this->readme_page_slug ) . '">How to use this plugin</a>';
|
32 |
+
}
|
33 |
+
return $meta;
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Display readme and working example in WordPress admin
|
38 |
+
* Does not add a menu item
|
39 |
+
* @link /wp-admin/plugins.php?page=styles-font-menu
|
40 |
+
*/
|
41 |
+
public function add_readme_page() {
|
42 |
+
add_submenu_page( null, 'Font Menu', 'Font Menu', 'manage_options', $this->readme_page_slug, array( $this, 'get_view_readme' ) );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Display views/readme.php, which modifies readme.md to show a working example.
|
47 |
+
*/
|
48 |
+
public function get_view_readme() {
|
49 |
+
if ( !function_exists( 'Markdown' ) ) {
|
50 |
+
require_once dirname( __FILE__ ) . '/markdown/markdown.php';
|
51 |
+
}
|
52 |
+
$this->plugin->get_view( 'readme' );
|
53 |
+
}
|
54 |
+
|
55 |
}
|
classes/styles-font-menu/classes/sfm-group-google.php
CHANGED
@@ -1,189 +1,189 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class SFM_Group_Google extends SFM_Group {
|
4 |
-
|
5 |
-
const font_api_url = 'https://www.googleapis.com/webfonts/v1/webfonts';
|
6 |
-
const import_template = "@import url(//fonts.googleapis.com/css?family=@import_family@);/r";
|
7 |
-
|
8 |
-
/**
|
9 |
-
* @example Override with <code>add_filter( 'styles_google_fonts_cache_interval', function(){ return 60*60*24*1; } );</code>
|
10 |
-
* @var int Seconds before cache expires. Defaults to 15 days.
|
11 |
-
*/
|
12 |
-
var $cache_interval;
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @var stdClass Response from Google API listing all fonts
|
16 |
-
*/
|
17 |
-
protected $font_data;
|
18 |
-
|
19 |
-
/**
|
20 |
-
* @var array Array of SFM_Single_Google instances instantiated from $font_data
|
21 |
-
*/
|
22 |
-
protected $fonts;
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @var string CSS for display of font previews in the menu.
|
26 |
-
*/
|
27 |
-
protected $menu_css;
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Values to pass to javascript
|
31 |
-
*/
|
32 |
-
protected $option_values;
|
33 |
-
|
34 |
-
/**
|
35 |
-
* @var string path to JSON backup of Google API response. In case API fails or is unavailable.
|
36 |
-
*/
|
37 |
-
protected $api_fallback_file;
|
38 |
-
|
39 |
-
public function __construct() {
|
40 |
-
$this->cache_interval = apply_filters( 'styles_google_fonts_cache_interval', 60*60*24*15 ); // 15 days
|
41 |
-
$this->api_fallback_file = dirname( dirname( __FILE__ ) ) . '/js/google-fonts-api-fallback.json';
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Fires when accessing $this->font_data from outside the class.
|
46 |
-
*/
|
47 |
-
public function get_font_data() {
|
48 |
-
// If we already processed fonts, return them.
|
49 |
-
if ( !empty( $this->font_data ) ) {
|
50 |
-
return $this->font_data;
|
51 |
-
}
|
52 |
-
|
53 |
-
// If fonts are cached in the transient, return them.
|
54 |
-
$this->font_data = get_transient( 'styles_google_fonts' );
|
55 |
-
if ( false !== $this->font_data ) {
|
56 |
-
return $this->font_data;
|
57 |
-
}
|
58 |
-
|
59 |
-
/**
|
60 |
-
* If no cache, try connecting to Google API
|
61 |
-
* Requires API key be set:
|
62 |
-
*
|
63 |
-
* @example
|
64 |
-
* add_filter( 'styles_google_font_api', create_function('', "return 'XXXXXXXX';" ) );
|
65 |
-
*/
|
66 |
-
$this->font_data = $this->remote_get_google_api();
|
67 |
-
|
68 |
-
// If Google API failed, use the fallback file.
|
69 |
-
if ( !is_object( $this->font_data ) || !is_array( $this->font_data->items ) ) {
|
70 |
-
$this->font_data = $this->get_api_fallback();
|
71 |
-
return $this->font_data;
|
72 |
-
}
|
73 |
-
|
74 |
-
// API returned some good data. Cache it to the transient
|
75 |
-
// and update the fallback file.
|
76 |
-
set_transient( 'styles_google_font_data', $this->font_data, $this->cache_interval );
|
77 |
-
$this->set_api_fallback();
|
78 |
-
|
79 |
-
return $this->font_data;
|
80 |
-
}
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Fires when accessing $this->fonts from outside the class.
|
84 |
-
*/
|
85 |
-
public function get_fonts() {
|
86 |
-
if ( !empty( $this->fonts ) ) { return $this->fonts; }
|
87 |
-
|
88 |
-
$fonts = array();
|
89 |
-
|
90 |
-
foreach ( (array) $this->get_font_data()->items as $font ){
|
91 |
-
// Exclude non-latin fonts
|
92 |
-
if ( !in_array('latin', $font->subsets ) ) { continue; }
|
93 |
-
|
94 |
-
$fonts[] = new SFM_Single_Google( array(
|
95 |
-
'family' => $font->family,
|
96 |
-
'name' => $font->family,
|
97 |
-
'variants' => $font->variants,
|
98 |
-
'files' => $font->files,
|
99 |
-
) );
|
100 |
-
|
101 |
-
}
|
102 |
-
|
103 |
-
$this->fonts = $fonts;
|
104 |
-
|
105 |
-
return $this->fonts;
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* Get individual font by name
|
110 |
-
*
|
111 |
-
* @return SFM_Single_Google
|
112 |
-
*/
|
113 |
-
public function get_font_by_name( $name ) {
|
114 |
-
if ( empty( $name ) ) {
|
115 |
-
wp_die( 'Please specify a font family to preview.');
|
116 |
-
}
|
117 |
-
|
118 |
-
foreach ( $this->get_fonts() as $font ) {
|
119 |
-
if ( $name == $font->family ) {
|
120 |
-
return $font;
|
121 |
-
}
|
122 |
-
}
|
123 |
-
return false;
|
124 |
-
}
|
125 |
-
|
126 |
-
/**
|
127 |
-
* Strip out unecessary metadata for passing to javascript
|
128 |
-
*
|
129 |
-
* @param array $font Font metadata, such as array( 'key', 'import_family', 'font_family', 'font_name' )
|
130 |
-
* @return array Same array, stripped of extra keys
|
131 |
-
*/
|
132 |
-
public function get_option_values() {
|
133 |
-
if ( !empty( $this->option_values ) ) { return $this->option_values; }
|
134 |
-
|
135 |
-
foreach ( $this->get_fonts() as $font ) {
|
136 |
-
$this->option_values[ 'fonts' ][] = $font->get_option_values();
|
137 |
-
}
|
138 |
-
|
139 |
-
$this->option_values[ 'import_template' ] = self::import_template;
|
140 |
-
$this->option_values[ 'admin_ajax' ] = admin_url( 'admin-ajax.php' );
|
141 |
-
|
142 |
-
return $this->option_values;
|
143 |
-
}
|
144 |
-
|
145 |
-
/**
|
146 |
-
* Connect to the remote Google API. Fall back to get_api_fallback on failure.
|
147 |
-
*/
|
148 |
-
public function remote_get_google_api() {
|
149 |
-
// API key must be set with this filter
|
150 |
-
$api_key = apply_filters( 'styles_google_font_api', false );
|
151 |
-
|
152 |
-
// Bail if no API key is set
|
153 |
-
if ( false === $api_key ) { return $this->get_api_fallback(); }
|
154 |
-
|
155 |
-
// Construct request
|
156 |
-
$url = add_query_arg( 'sort', apply_filters( 'styles_google_font_sort', 'popularity' ), self::font_api_url );
|
157 |
-
$url = add_query_arg( 'key', $api_key, $url );
|
158 |
-
$response = wp_remote_get( $url );
|
159 |
-
|
160 |
-
// If response is an error, use the fallback file
|
161 |
-
if ( is_a( $response, 'WP_Error') ) { return $this->get_api_fallback(); }
|
162 |
-
|
163 |
-
return json_decode( $response['body'] );
|
164 |
-
}
|
165 |
-
|
166 |
-
/**
|
167 |
-
* If the we don't have a Google API key, or the request fails,
|
168 |
-
* use the contents of this file instead.
|
169 |
-
*
|
170 |
-
* @todo Rework this and set_api_fallback to use transients and write to disk using WP_Filesystem so we don't have two caching mechanisms going on at once.
|
171 |
-
*/
|
172 |
-
public function get_api_fallback() {
|
173 |
-
$this->fonts = json_decode( file_get_contents( $this->api_fallback_file ) );
|
174 |
-
return $this->fonts;
|
175 |
-
}
|
176 |
-
|
177 |
-
/**
|
178 |
-
* Save Google Fonts API response to file for cases where we
|
179 |
-
* don't have an API key or the API request fails
|
180 |
-
*
|
181 |
-
* @todo Write with WP_Filesystem instead of file_put_contents
|
182 |
-
*/
|
183 |
-
public function set_api_fallback() {
|
184 |
-
if ( !empty( $this->font_data ) && is_writable( $this->api_fallback_file ) ) {
|
185 |
-
file_put_contents( $this->api_fallback_file, json_encode( $this->font_data ) );
|
186 |
-
}
|
187 |
-
}
|
188 |
-
|
189 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class SFM_Group_Google extends SFM_Group {
|
4 |
+
|
5 |
+
const font_api_url = 'https://www.googleapis.com/webfonts/v1/webfonts';
|
6 |
+
const import_template = "@import url(//fonts.googleapis.com/css?family=@import_family@);/r";
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @example Override with <code>add_filter( 'styles_google_fonts_cache_interval', function(){ return 60*60*24*1; } );</code>
|
10 |
+
* @var int Seconds before cache expires. Defaults to 15 days.
|
11 |
+
*/
|
12 |
+
var $cache_interval;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @var stdClass Response from Google API listing all fonts
|
16 |
+
*/
|
17 |
+
protected $font_data;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var array Array of SFM_Single_Google instances instantiated from $font_data
|
21 |
+
*/
|
22 |
+
protected $fonts;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var string CSS for display of font previews in the menu.
|
26 |
+
*/
|
27 |
+
protected $menu_css;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Values to pass to javascript
|
31 |
+
*/
|
32 |
+
protected $option_values;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @var string path to JSON backup of Google API response. In case API fails or is unavailable.
|
36 |
+
*/
|
37 |
+
protected $api_fallback_file;
|
38 |
+
|
39 |
+
public function __construct() {
|
40 |
+
$this->cache_interval = apply_filters( 'styles_google_fonts_cache_interval', 60*60*24*15 ); // 15 days
|
41 |
+
$this->api_fallback_file = dirname( dirname( __FILE__ ) ) . '/js/google-fonts-api-fallback.json';
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Fires when accessing $this->font_data from outside the class.
|
46 |
+
*/
|
47 |
+
public function get_font_data() {
|
48 |
+
// If we already processed fonts, return them.
|
49 |
+
if ( !empty( $this->font_data ) ) {
|
50 |
+
return $this->font_data;
|
51 |
+
}
|
52 |
+
|
53 |
+
// If fonts are cached in the transient, return them.
|
54 |
+
$this->font_data = get_transient( 'styles_google_fonts' );
|
55 |
+
if ( false !== $this->font_data ) {
|
56 |
+
return $this->font_data;
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* If no cache, try connecting to Google API
|
61 |
+
* Requires API key be set:
|
62 |
+
*
|
63 |
+
* @example
|
64 |
+
* add_filter( 'styles_google_font_api', create_function('', "return 'XXXXXXXX';" ) );
|
65 |
+
*/
|
66 |
+
$this->font_data = $this->remote_get_google_api();
|
67 |
+
|
68 |
+
// If Google API failed, use the fallback file.
|
69 |
+
if ( !is_object( $this->font_data ) || !is_array( $this->font_data->items ) ) {
|
70 |
+
$this->font_data = $this->get_api_fallback();
|
71 |
+
return $this->font_data;
|
72 |
+
}
|
73 |
+
|
74 |
+
// API returned some good data. Cache it to the transient
|
75 |
+
// and update the fallback file.
|
76 |
+
set_transient( 'styles_google_font_data', $this->font_data, $this->cache_interval );
|
77 |
+
$this->set_api_fallback();
|
78 |
+
|
79 |
+
return $this->font_data;
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Fires when accessing $this->fonts from outside the class.
|
84 |
+
*/
|
85 |
+
public function get_fonts() {
|
86 |
+
if ( !empty( $this->fonts ) ) { return $this->fonts; }
|
87 |
+
|
88 |
+
$fonts = array();
|
89 |
+
|
90 |
+
foreach ( (array) $this->get_font_data()->items as $font ){
|
91 |
+
// Exclude non-latin fonts
|
92 |
+
if ( !in_array('latin', $font->subsets ) ) { continue; }
|
93 |
+
|
94 |
+
$fonts[] = new SFM_Single_Google( array(
|
95 |
+
'family' => $font->family,
|
96 |
+
'name' => $font->family,
|
97 |
+
'variants' => $font->variants,
|
98 |
+
'files' => $font->files,
|
99 |
+
) );
|
100 |
+
|
101 |
+
}
|
102 |
+
|
103 |
+
$this->fonts = $fonts;
|
104 |
+
|
105 |
+
return $this->fonts;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Get individual font by name
|
110 |
+
*
|
111 |
+
* @return SFM_Single_Google
|
112 |
+
*/
|
113 |
+
public function get_font_by_name( $name ) {
|
114 |
+
if ( empty( $name ) ) {
|
115 |
+
wp_die( 'Please specify a font family to preview.');
|
116 |
+
}
|
117 |
+
|
118 |
+
foreach ( $this->get_fonts() as $font ) {
|
119 |
+
if ( $name == $font->family ) {
|
120 |
+
return $font;
|
121 |
+
}
|
122 |
+
}
|
123 |
+
return false;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Strip out unecessary metadata for passing to javascript
|
128 |
+
*
|
129 |
+
* @param array $font Font metadata, such as array( 'key', 'import_family', 'font_family', 'font_name' )
|
130 |
+
* @return array Same array, stripped of extra keys
|
131 |
+
*/
|
132 |
+
public function get_option_values() {
|
133 |
+
if ( !empty( $this->option_values ) ) { return $this->option_values; }
|
134 |
+
|
135 |
+
foreach ( $this->get_fonts() as $font ) {
|
136 |
+
$this->option_values[ 'fonts' ][] = $font->get_option_values();
|
137 |
+
}
|
138 |
+
|
139 |
+
$this->option_values[ 'import_template' ] = self::import_template;
|
140 |
+
$this->option_values[ 'admin_ajax' ] = admin_url( 'admin-ajax.php' );
|
141 |
+
|
142 |
+
return $this->option_values;
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Connect to the remote Google API. Fall back to get_api_fallback on failure.
|
147 |
+
*/
|
148 |
+
public function remote_get_google_api() {
|
149 |
+
// API key must be set with this filter
|
150 |
+
$api_key = apply_filters( 'styles_google_font_api', false );
|
151 |
+
|
152 |
+
// Bail if no API key is set
|
153 |
+
if ( false === $api_key ) { return $this->get_api_fallback(); }
|
154 |
+
|
155 |
+
// Construct request
|
156 |
+
$url = add_query_arg( 'sort', apply_filters( 'styles_google_font_sort', 'popularity' ), self::font_api_url );
|
157 |
+
$url = add_query_arg( 'key', $api_key, $url );
|
158 |
+
$response = wp_remote_get( $url );
|
159 |
+
|
160 |
+
// If response is an error, use the fallback file
|
161 |
+
if ( is_a( $response, 'WP_Error') ) { return $this->get_api_fallback(); }
|
162 |
+
|
163 |
+
return json_decode( $response['body'] );
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* If the we don't have a Google API key, or the request fails,
|
168 |
+
* use the contents of this file instead.
|
169 |
+
*
|
170 |
+
* @todo Rework this and set_api_fallback to use transients and write to disk using WP_Filesystem so we don't have two caching mechanisms going on at once.
|
171 |
+
*/
|
172 |
+
public function get_api_fallback() {
|
173 |
+
$this->fonts = json_decode( file_get_contents( $this->api_fallback_file ) );
|
174 |
+
return $this->fonts;
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Save Google Fonts API response to file for cases where we
|
179 |
+
* don't have an API key or the API request fails
|
180 |
+
*
|
181 |
+
* @todo Write with WP_Filesystem instead of file_put_contents
|
182 |
+
*/
|
183 |
+
public function set_api_fallback() {
|
184 |
+
if ( !empty( $this->font_data ) && is_writable( $this->api_fallback_file ) ) {
|
185 |
+
file_put_contents( $this->api_fallback_file, json_encode( $this->font_data ) );
|
186 |
+
}
|
187 |
+
}
|
188 |
+
|
189 |
}
|
classes/styles-font-menu/classes/sfm-group-standard.php
CHANGED
@@ -1,57 +1,57 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class SFM_Group_Standard extends SFM_Group {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var array Font name (key) => font-family stack (value)
|
7 |
-
*/
|
8 |
-
protected $font_data = array( 'Arial' => 'Arial, Helvetica, sans-serif', 'Bookman' => 'Bookman, Palatino, Georgia, serif', 'Century Gothic' => '\'Century Gothic\', Helvetica, Arial, sans-serif', 'Comic Sans MS' => '\'Comic Sans MS\', Arial, sans-serif', 'Courier' => 'Courier, monospace', 'Garamond' => 'Garamond, Palatino, Georgia, serif', 'Georgia' => 'Georgia, Times, serif', 'Helvetica' => 'Helvetica, Arial, sans-serif', 'Lucida Grande' => '\'Lucida Grande\',\'Lucida Sans Unicode\',Tahoma,Verdana,sans-serif', 'Palatino' => 'Palatino, Georgia, serif', 'Tahoma' => 'Tahoma, Verdana, Helvetica, sans-serif', 'Times' => 'Times, Georgia, serif', 'Trebuchet MS' => '\'Trebuchet MS\', Tahoma, Helvetica, sans-serif', 'Verdana' => 'Verdana, Tahoma, sans-serif', );
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var string|bool If @imports are needed, this holds the template. Else, false.
|
12 |
-
*/
|
13 |
-
protected $import_template = false;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var array Array of Styles_Font objects.
|
17 |
-
*/
|
18 |
-
protected $fonts;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Values to pass to javascript
|
22 |
-
*/
|
23 |
-
protected $option_values;
|
24 |
-
|
25 |
-
/**
|
26 |
-
* Fires when accessing $this->fonts from outside the class.
|
27 |
-
*/
|
28 |
-
public function get_fonts() {
|
29 |
-
if ( !empty( $this->fonts ) ) { return $this->fonts; }
|
30 |
-
|
31 |
-
foreach ( (array) $this->font_data as $name => $family ){
|
32 |
-
$this->fonts[] = new SFM_Single_Standard( array(
|
33 |
-
'family' => $family,
|
34 |
-
'name' => $name,
|
35 |
-
) );
|
36 |
-
}
|
37 |
-
|
38 |
-
return $this->fonts;
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Strip out unecessary metadata for passing to javascript
|
43 |
-
*
|
44 |
-
* @param array $font Font metadata, such as array( 'key', 'import_family', 'font_family', 'font_name' )
|
45 |
-
* @return array Same array, stripped of extra keys
|
46 |
-
*/
|
47 |
-
public function get_option_values() {
|
48 |
-
if ( !empty( $this->option_values ) ) { return $this->option_values; }
|
49 |
-
|
50 |
-
foreach ( $this->get_fonts() as $font ) {
|
51 |
-
$this->option_values[ 'fonts' ][] = $font->get_option_values();
|
52 |
-
}
|
53 |
-
|
54 |
-
return $this->option_values;
|
55 |
-
}
|
56 |
-
|
57 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class SFM_Group_Standard extends SFM_Group {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var array Font name (key) => font-family stack (value)
|
7 |
+
*/
|
8 |
+
protected $font_data = array( 'Arial' => 'Arial, Helvetica, sans-serif', 'Bookman' => 'Bookman, Palatino, Georgia, serif', 'Century Gothic' => '\'Century Gothic\', Helvetica, Arial, sans-serif', 'Comic Sans MS' => '\'Comic Sans MS\', Arial, sans-serif', 'Courier' => 'Courier, monospace', 'Garamond' => 'Garamond, Palatino, Georgia, serif', 'Georgia' => 'Georgia, Times, serif', 'Helvetica' => 'Helvetica, Arial, sans-serif', 'Lucida Grande' => '\'Lucida Grande\',\'Lucida Sans Unicode\',Tahoma,Verdana,sans-serif', 'Palatino' => 'Palatino, Georgia, serif', 'Tahoma' => 'Tahoma, Verdana, Helvetica, sans-serif', 'Times' => 'Times, Georgia, serif', 'Trebuchet MS' => '\'Trebuchet MS\', Tahoma, Helvetica, sans-serif', 'Verdana' => 'Verdana, Tahoma, sans-serif', );
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var string|bool If @imports are needed, this holds the template. Else, false.
|
12 |
+
*/
|
13 |
+
protected $import_template = false;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var array Array of Styles_Font objects.
|
17 |
+
*/
|
18 |
+
protected $fonts;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Values to pass to javascript
|
22 |
+
*/
|
23 |
+
protected $option_values;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Fires when accessing $this->fonts from outside the class.
|
27 |
+
*/
|
28 |
+
public function get_fonts() {
|
29 |
+
if ( !empty( $this->fonts ) ) { return $this->fonts; }
|
30 |
+
|
31 |
+
foreach ( (array) $this->font_data as $name => $family ){
|
32 |
+
$this->fonts[] = new SFM_Single_Standard( array(
|
33 |
+
'family' => $family,
|
34 |
+
'name' => $name,
|
35 |
+
) );
|
36 |
+
}
|
37 |
+
|
38 |
+
return $this->fonts;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Strip out unecessary metadata for passing to javascript
|
43 |
+
*
|
44 |
+
* @param array $font Font metadata, such as array( 'key', 'import_family', 'font_family', 'font_name' )
|
45 |
+
* @return array Same array, stripped of extra keys
|
46 |
+
*/
|
47 |
+
public function get_option_values() {
|
48 |
+
if ( !empty( $this->option_values ) ) { return $this->option_values; }
|
49 |
+
|
50 |
+
foreach ( $this->get_fonts() as $font ) {
|
51 |
+
$this->option_values[ 'fonts' ][] = $font->get_option_values();
|
52 |
+
}
|
53 |
+
|
54 |
+
return $this->option_values;
|
55 |
+
}
|
56 |
+
|
57 |
}
|
classes/styles-font-menu/classes/sfm-group.php
CHANGED
@@ -1,39 +1,39 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
abstract class SFM_Group {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* If client tries to access variables directly, pass to get() method
|
7 |
-
*/
|
8 |
-
public function __get( $target ) {
|
9 |
-
return $this->get( $target );
|
10 |
-
}
|
11 |
-
|
12 |
-
/**
|
13 |
-
* If a get_XXX method exists for a variable, use it.
|
14 |
-
* Otherwise, return the variable value
|
15 |
-
*/
|
16 |
-
public function get( $target = 'fonts' ) {
|
17 |
-
$method = 'get_' . $target;
|
18 |
-
if ( method_exists( $this, $method ) ) {
|
19 |
-
return $this->$method();
|
20 |
-
}else if ( isset( $this->$target ) ){
|
21 |
-
return $this->$target;
|
22 |
-
}else {
|
23 |
-
return false;
|
24 |
-
}
|
25 |
-
}
|
26 |
-
|
27 |
-
public function get_menu_css() {
|
28 |
-
if ( !empty( $this->menu_css ) ) {
|
29 |
-
return $this->menu_css;
|
30 |
-
}
|
31 |
-
|
32 |
-
foreach( $this->get_fonts() as $font ) {
|
33 |
-
$this->menu_css .= $font->get_menu_css();
|
34 |
-
}
|
35 |
-
|
36 |
-
return $this->menu_css;
|
37 |
-
}
|
38 |
-
|
39 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
abstract class SFM_Group {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* If client tries to access variables directly, pass to get() method
|
7 |
+
*/
|
8 |
+
public function __get( $target ) {
|
9 |
+
return $this->get( $target );
|
10 |
+
}
|
11 |
+
|
12 |
+
/**
|
13 |
+
* If a get_XXX method exists for a variable, use it.
|
14 |
+
* Otherwise, return the variable value
|
15 |
+
*/
|
16 |
+
public function get( $target = 'fonts' ) {
|
17 |
+
$method = 'get_' . $target;
|
18 |
+
if ( method_exists( $this, $method ) ) {
|
19 |
+
return $this->$method();
|
20 |
+
}else if ( isset( $this->$target ) ){
|
21 |
+
return $this->$target;
|
22 |
+
}else {
|
23 |
+
return false;
|
24 |
+
}
|
25 |
+
}
|
26 |
+
|
27 |
+
public function get_menu_css() {
|
28 |
+
if ( !empty( $this->menu_css ) ) {
|
29 |
+
return $this->menu_css;
|
30 |
+
}
|
31 |
+
|
32 |
+
foreach( $this->get_fonts() as $font ) {
|
33 |
+
$this->menu_css .= $font->get_menu_css();
|
34 |
+
}
|
35 |
+
|
36 |
+
return $this->menu_css;
|
37 |
+
}
|
38 |
+
|
39 |
}
|
classes/styles-font-menu/classes/sfm-image-preview.php
CHANGED
@@ -1,146 +1,146 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class SFM_Image_Preview {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var string $_GET key that triggers this class to run
|
7 |
-
*/
|
8 |
-
protected $action_key = 'styles-font-preview';
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var array Display attributes for the preview image and font
|
12 |
-
*/
|
13 |
-
var $preview_attributes = array(
|
14 |
-
'font_size' => 28,
|
15 |
-
'left_margin' => 3,
|
16 |
-
'width' => 400,
|
17 |
-
'height' => 64,
|
18 |
-
'background_color' => array( 255, 255, 255 ),
|
19 |
-
'font_color' => array( 0, 0, 0 ),
|
20 |
-
);
|
21 |
-
|
22 |
-
public function __construct() {
|
23 |
-
add_action( 'wp_ajax_styles-font-preview', array( $this, 'wp_ajax_styles_font_preview' ) );
|
24 |
-
}
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Load Google font specified in $_GET request.
|
28 |
-
*
|
29 |
-
* @param string $_GET['font-family'] Required. Name of the font to render
|
30 |
-
* @param string $_GET['variant'] Optional. Name of the variant to render
|
31 |
-
* @return null Output URL to image as string
|
32 |
-
*/
|
33 |
-
public function wp_ajax_styles_font_preview() {
|
34 |
-
$plugin = SFM_Plugin::get_instance();
|
35 |
-
$font_family = ( isset( $_GET[ 'font-family' ] ) ) ? $_GET[ 'font-family' ] : false;
|
36 |
-
|
37 |
-
// Load font family from Google Fonts
|
38 |
-
$this->font = $plugin->google_fonts->get_font_by_name( $font_family );
|
39 |
-
|
40 |
-
if ( !$this->font ) {
|
41 |
-
wp_die( 'Font not found: ' . $this->font_family );
|
42 |
-
}
|
43 |
-
|
44 |
-
// Output PNG URL
|
45 |
-
if ( !$this->font->get_png_url() ) {
|
46 |
-
$this->generate_image();
|
47 |
-
}
|
48 |
-
|
49 |
-
echo $this->font->get_png_url();
|
50 |
-
exit;
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Create PNG of font name written with font TTF.
|
55 |
-
*/
|
56 |
-
public function generate_image() {
|
57 |
-
$width = $height = $font_size = $left_margin = $background_color = $font_color = false;
|
58 |
-
extract( $this->preview_attributes, EXTR_IF_EXISTS );
|
59 |
-
|
60 |
-
// Text Mask
|
61 |
-
$mask = imageCreate($width, $height);
|
62 |
-
|
63 |
-
$background = imageColorAllocate($mask, $background_color[0], $background_color[1], $background_color[2]);
|
64 |
-
$foreground = imageColorAllocate($mask, $font_color[0], $font_color[1], $font_color[2]);
|
65 |
-
|
66 |
-
$ttf_path = $this->font->maybe_get_remote_ttf();
|
67 |
-
if ( !file_exists( $ttf_path ) ) {
|
68 |
-
wp_die( 'Could not load $ttf_path: ' . $ttf_path );
|
69 |
-
}
|
70 |
-
|
71 |
-
// Text
|
72 |
-
$y = $this->get_centered_y_coordinate( $font_size, $ttf_path, $this->font->family );
|
73 |
-
imagettftext($mask, $font_size, 0, $left_margin, $y, $foreground, $ttf_path, $this->font->family );
|
74 |
-
|
75 |
-
// White fill
|
76 |
-
$white = imageCreate($width, $height);
|
77 |
-
$background = imageColorAllocate($white, $background_color[0], $background_color[1], $background_color[2]);
|
78 |
-
|
79 |
-
// Image
|
80 |
-
$image = imagecreatetruecolor($width, $height);
|
81 |
-
imagesavealpha( $image, true );
|
82 |
-
imagefill( $image, 0, 0, imagecolorallocatealpha( $image, 0, 0, 0, 127 ) );
|
83 |
-
|
84 |
-
// Apply Mask to Image
|
85 |
-
for( $x = 0; $x < $width; $x++ ) {
|
86 |
-
for( $y = 0; $y < $height; $y++ ) {
|
87 |
-
$alpha = imagecolorsforindex( $mask, imagecolorat( $mask, $x, $y ) );
|
88 |
-
$alpha = 127 - floor( $alpha[ 'red' ] / 2 );
|
89 |
-
$color = imagecolorsforindex( $white, imagecolorat( $white, $x, $y ) );
|
90 |
-
imagesetpixel( $image, $x, $y, imagecolorallocatealpha( $image, $color[ 'red' ], $color[ 'green' ], $color[ 'blue' ], $alpha ) );
|
91 |
-
}
|
92 |
-
}
|
93 |
-
|
94 |
-
ob_start();
|
95 |
-
imagePNG($image);
|
96 |
-
$image = ob_get_clean();
|
97 |
-
|
98 |
-
$this->save_image( $image );
|
99 |
-
|
100 |
-
// header("Content-type: image/png");
|
101 |
-
// echo $image;
|
102 |
-
}
|
103 |
-
|
104 |
-
/**
|
105 |
-
* Calculate y-coordinate for centering text vertically.
|
106 |
-
*
|
107 |
-
* @link http://stackoverflow.com/a/15001168
|
108 |
-
* @return int y-coordinate
|
109 |
-
*/
|
110 |
-
public function get_centered_y_coordinate( $fontsize, $font, $text ) {
|
111 |
-
$dims = imagettfbbox($fontsize, 0, $font, $text);
|
112 |
-
|
113 |
-
$ascent = abs($dims[7]);
|
114 |
-
$descent = abs($dims[1]);
|
115 |
-
|
116 |
-
// $width = abs( $dims[0] ) + abs( $dims[2] );
|
117 |
-
|
118 |
-
$height = $ascent + $descent;
|
119 |
-
$image_height = $this->preview_attributes['height'];
|
120 |
-
|
121 |
-
$y = ( ( $image_height/2 ) - ( $height/2 ) ) + $ascent;
|
122 |
-
|
123 |
-
return $y;
|
124 |
-
}
|
125 |
-
|
126 |
-
/**
|
127 |
-
* Save preview image file.
|
128 |
-
*/
|
129 |
-
public function save_image( $image ) {
|
130 |
-
if ( !function_exists('WP_Filesystem')) { require ABSPATH . 'wp-admin/includes/file.php'; }
|
131 |
-
global $wp_filesystem; WP_Filesystem();
|
132 |
-
|
133 |
-
$dir = dirname( $this->font->get_png_cache_path() );
|
134 |
-
|
135 |
-
if ( !is_dir( $dir ) && !wp_mkdir_p( $dir ) ) {
|
136 |
-
wp_die( "Please check permissions. Could not create directory $dir" );
|
137 |
-
}
|
138 |
-
|
139 |
-
$image_file = $wp_filesystem->put_contents( $this->font->get_png_cache_path(), $image, FS_CHMOD_FILE ); // predefined mode settings for WP files
|
140 |
-
|
141 |
-
if ( !$image_file ) {
|
142 |
-
wp_die( "Please check permissions. Could not write image to $dir" );
|
143 |
-
}
|
144 |
-
}
|
145 |
-
|
146 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class SFM_Image_Preview {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var string $_GET key that triggers this class to run
|
7 |
+
*/
|
8 |
+
protected $action_key = 'styles-font-preview';
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var array Display attributes for the preview image and font
|
12 |
+
*/
|
13 |
+
var $preview_attributes = array(
|
14 |
+
'font_size' => 28,
|
15 |
+
'left_margin' => 3,
|
16 |
+
'width' => 400,
|
17 |
+
'height' => 64,
|
18 |
+
'background_color' => array( 255, 255, 255 ),
|
19 |
+
'font_color' => array( 0, 0, 0 ),
|
20 |
+
);
|
21 |
+
|
22 |
+
public function __construct() {
|
23 |
+
add_action( 'wp_ajax_styles-font-preview', array( $this, 'wp_ajax_styles_font_preview' ) );
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Load Google font specified in $_GET request.
|
28 |
+
*
|
29 |
+
* @param string $_GET['font-family'] Required. Name of the font to render
|
30 |
+
* @param string $_GET['variant'] Optional. Name of the variant to render
|
31 |
+
* @return null Output URL to image as string
|
32 |
+
*/
|
33 |
+
public function wp_ajax_styles_font_preview() {
|
34 |
+
$plugin = SFM_Plugin::get_instance();
|
35 |
+
$font_family = ( isset( $_GET[ 'font-family' ] ) ) ? $_GET[ 'font-family' ] : false;
|
36 |
+
|
37 |
+
// Load font family from Google Fonts
|
38 |
+
$this->font = $plugin->google_fonts->get_font_by_name( $font_family );
|
39 |
+
|
40 |
+
if ( !$this->font ) {
|
41 |
+
wp_die( 'Font not found: ' . $this->font_family );
|
42 |
+
}
|
43 |
+
|
44 |
+
// Output PNG URL
|
45 |
+
if ( !$this->font->get_png_url() ) {
|
46 |
+
$this->generate_image();
|
47 |
+
}
|
48 |
+
|
49 |
+
echo $this->font->get_png_url();
|
50 |
+
exit;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Create PNG of font name written with font TTF.
|
55 |
+
*/
|
56 |
+
public function generate_image() {
|
57 |
+
$width = $height = $font_size = $left_margin = $background_color = $font_color = false;
|
58 |
+
extract( $this->preview_attributes, EXTR_IF_EXISTS );
|
59 |
+
|
60 |
+
// Text Mask
|
61 |
+
$mask = imageCreate($width, $height);
|
62 |
+
|
63 |
+
$background = imageColorAllocate($mask, $background_color[0], $background_color[1], $background_color[2]);
|
64 |
+
$foreground = imageColorAllocate($mask, $font_color[0], $font_color[1], $font_color[2]);
|
65 |
+
|
66 |
+
$ttf_path = $this->font->maybe_get_remote_ttf();
|
67 |
+
if ( !file_exists( $ttf_path ) ) {
|
68 |
+
wp_die( 'Could not load $ttf_path: ' . $ttf_path );
|
69 |
+
}
|
70 |
+
|
71 |
+
// Text
|
72 |
+
$y = $this->get_centered_y_coordinate( $font_size, $ttf_path, $this->font->family );
|
73 |
+
imagettftext($mask, $font_size, 0, $left_margin, $y, $foreground, $ttf_path, $this->font->family );
|
74 |
+
|
75 |
+
// White fill
|
76 |
+
$white = imageCreate($width, $height);
|
77 |
+
$background = imageColorAllocate($white, $background_color[0], $background_color[1], $background_color[2]);
|
78 |
+
|
79 |
+
// Image
|
80 |
+
$image = imagecreatetruecolor($width, $height);
|
81 |
+
imagesavealpha( $image, true );
|
82 |
+
imagefill( $image, 0, 0, imagecolorallocatealpha( $image, 0, 0, 0, 127 ) );
|
83 |
+
|
84 |
+
// Apply Mask to Image
|
85 |
+
for( $x = 0; $x < $width; $x++ ) {
|
86 |
+
for( $y = 0; $y < $height; $y++ ) {
|
87 |
+
$alpha = imagecolorsforindex( $mask, imagecolorat( $mask, $x, $y ) );
|
88 |
+
$alpha = 127 - floor( $alpha[ 'red' ] / 2 );
|
89 |
+
$color = imagecolorsforindex( $white, imagecolorat( $white, $x, $y ) );
|
90 |
+
imagesetpixel( $image, $x, $y, imagecolorallocatealpha( $image, $color[ 'red' ], $color[ 'green' ], $color[ 'blue' ], $alpha ) );
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
ob_start();
|
95 |
+
imagePNG($image);
|
96 |
+
$image = ob_get_clean();
|
97 |
+
|
98 |
+
$this->save_image( $image );
|
99 |
+
|
100 |
+
// header("Content-type: image/png");
|
101 |
+
// echo $image;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Calculate y-coordinate for centering text vertically.
|
106 |
+
*
|
107 |
+
* @link http://stackoverflow.com/a/15001168
|
108 |
+
* @return int y-coordinate
|
109 |
+
*/
|
110 |
+
public function get_centered_y_coordinate( $fontsize, $font, $text ) {
|
111 |
+
$dims = imagettfbbox($fontsize, 0, $font, $text);
|
112 |
+
|
113 |
+
$ascent = abs($dims[7]);
|
114 |
+
$descent = abs($dims[1]);
|
115 |
+
|
116 |
+
// $width = abs( $dims[0] ) + abs( $dims[2] );
|
117 |
+
|
118 |
+
$height = $ascent + $descent;
|
119 |
+
$image_height = $this->preview_attributes['height'];
|
120 |
+
|
121 |
+
$y = ( ( $image_height/2 ) - ( $height/2 ) ) + $ascent;
|
122 |
+
|
123 |
+
return $y;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Save preview image file.
|
128 |
+
*/
|
129 |
+
public function save_image( $image ) {
|
130 |
+
if ( !function_exists('WP_Filesystem')) { require ABSPATH . 'wp-admin/includes/file.php'; }
|
131 |
+
global $wp_filesystem; WP_Filesystem();
|
132 |
+
|
133 |
+
$dir = dirname( $this->font->get_png_cache_path() );
|
134 |
+
|
135 |
+
if ( !is_dir( $dir ) && !wp_mkdir_p( $dir ) ) {
|
136 |
+
wp_die( "Please check permissions. Could not create directory $dir" );
|
137 |
+
}
|
138 |
+
|
139 |
+
$image_file = $wp_filesystem->put_contents( $this->font->get_png_cache_path(), $image, FS_CHMOD_FILE ); // predefined mode settings for WP files
|
140 |
+
|
141 |
+
if ( !$image_file ) {
|
142 |
+
wp_die( "Please check permissions. Could not write image to $dir" );
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
}
|
classes/styles-font-menu/classes/sfm-plugin.php
CHANGED
@@ -1,173 +1,173 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
require_once dirname(__FILE__) . '/sfm-admin.php';
|
4 |
-
require_once dirname(__FILE__) . '/sfm-group.php';
|
5 |
-
require_once dirname(__FILE__) . '/sfm-group-standard.php';
|
6 |
-
require_once dirname(__FILE__) . '/sfm-group-google.php';
|
7 |
-
require_once dirname(__FILE__) . '/sfm-single-standard.php';
|
8 |
-
require_once dirname(__FILE__) . '/sfm-single-google.php';
|
9 |
-
require_once dirname(__FILE__) . '/sfm-image-preview.php';
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Controller class
|
13 |
-
* Holds instances of models in vars
|
14 |
-
* Loads views from views/ directory
|
15 |
-
*
|
16 |
-
* Follows the Singleton pattern. @see http://jumping-duck.com/tutorial/wordpress-plugin-structure/
|
17 |
-
* @example Access plugin instance with $font_dropdown = SFM_Plugin::get_instance();
|
18 |
-
*/
|
19 |
-
class SFM_Plugin {
|
20 |
-
|
21 |
-
/**
|
22 |
-
* @var string The plugin version.
|
23 |
-
*/
|
24 |
-
var $version = '1.0.1';
|
25 |
-
|
26 |
-
/**
|
27 |
-
* @var Styles_Font_Menu Instance of the class.
|
28 |
-
*/
|
29 |
-
protected static $instance = false;
|
30 |
-
|
31 |
-
/**
|
32 |
-
* @var string Class to apply to menu element and prefix to selectors.
|
33 |
-
*/
|
34 |
-
public $menu_class = 'sfm';
|
35 |
-
|
36 |
-
/**
|
37 |
-
* @var SFM_Admin Methods for WordPress admin user interface.
|
38 |
-
*/
|
39 |
-
var $admin;
|
40 |
-
|
41 |
-
/**
|
42 |
-
* @var SFM_Group_Standard Web standard font families and CSS font stacks.
|
43 |
-
*/
|
44 |
-
var $standard_fonts;
|
45 |
-
|
46 |
-
/**
|
47 |
-
* @var SFM_Group_Google Connects to Google Font API.
|
48 |
-
*/
|
49 |
-
var $google_fonts;
|
50 |
-
|
51 |
-
/**
|
52 |
-
* @var SFM_Image_Preview Generate image preview of a font.
|
53 |
-
*/
|
54 |
-
var $image_preview;
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Set with site_url() because we might not be running as a plugin.
|
58 |
-
*
|
59 |
-
* @var string URL for the styles-font-menu directory.
|
60 |
-
*/
|
61 |
-
var $plugin_url;
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Set with dirname(__FILE__) because we might not be running as a plugin.
|
65 |
-
*
|
66 |
-
* @var string Path for the styles-font-menu directory.
|
67 |
-
*/
|
68 |
-
var $plugin_directory;
|
69 |
-
|
70 |
-
/**
|
71 |
-
* Intentionally inaccurate if we're running as a plugin.
|
72 |
-
*
|
73 |
-
* @var string Plugin basename, only if we're running as a plugin.
|
74 |
-
*/
|
75 |
-
var $plugin_basename;
|
76 |
-
|
77 |
-
/**
|
78 |
-
* print_scripts() runs as late as possible to avoid processing Google Fonts.
|
79 |
-
* This prevents running multiple times.
|
80 |
-
*
|
81 |
-
* @var bool Whether we have already registered scripts or not.
|
82 |
-
*/
|
83 |
-
var $scripts_printed = false;
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Don't use this. Use ::get_instance() instead.
|
87 |
-
*/
|
88 |
-
public function __construct() {
|
89 |
-
if ( !self::$instance ) {
|
90 |
-
$message = '<code>' . __CLASS__ . '</code> is a singleton.<br/> Please get an instantiate it with <code>' . __CLASS__ . '::get_instance();</code>';
|
91 |
-
wp_die( $message );
|
92 |
-
}
|
93 |
-
}
|
94 |
-
|
95 |
-
public static function get_instance() {
|
96 |
-
if ( !is_a( self::$instance, __CLASS__ ) ) {
|
97 |
-
self::$instance = true;
|
98 |
-
self::$instance = new self();
|
99 |
-
self::$instance->init();
|
100 |
-
}
|
101 |
-
return self::$instance;
|
102 |
-
}
|
103 |
-
|
104 |
-
/**
|
105 |
-
* Initial setup. Called by get_instance.
|
106 |
-
*/
|
107 |
-
protected function init() {
|
108 |
-
// Fix for IIS paths
|
109 |
-
$normalized_abspath = str_replace(array('/', '\\'), '/', ABSPATH );
|
110 |
-
|
111 |
-
$this->plugin_directory = str_replace(array('/', '\\'), '/', dirname( dirname( __FILE__ ) ) );
|
112 |
-
$this->plugin_url = site_url( str_replace( $normalized_abspath, '', $this->plugin_directory ) );
|
113 |
-
$this->plugin_basename = plugin_basename( $this->plugin_directory . '/plugin.php' );
|
114 |
-
|
115 |
-
$this->admin = new SFM_Admin( $this );
|
116 |
-
$this->google_fonts = new SFM_Group_Google();
|
117 |
-
$this->standard_fonts = new SFM_Group_Standard();
|
118 |
-
$this->image_preview = new SFM_Image_Preview();
|
119 |
-
|
120 |
-
/**
|
121 |
-
* Output dropdown menu anywhere styles_font_menu action is called.
|
122 |
-
* @example <code>do_action( 'styles_font_menu' );</code>
|
123 |
-
*/
|
124 |
-
add_action( 'styles_font_menu', array( $this, 'get_view_menu' ), 10, 2 );
|
125 |
-
}
|
126 |
-
|
127 |
-
public function print_scripts() {
|
128 |
-
if ( $this->scripts_printed ) { return false; }
|
129 |
-
|
130 |
-
wp_register_script( 'styles-chosen', $this->plugin_url . '/js/chosen/chosen.jquery.min.js', array( 'jquery' ), $this->version );
|
131 |
-
wp_register_script( 'styles-font-menu', $this->plugin_url . '/js/styles-font-menu.js', array( 'jquery', 'styles-chosen' ), $this->version );
|
132 |
-
wp_register_style( 'styles-chosen', $this->plugin_url . '/js/chosen/chosen.css', array(), $this->version );
|
133 |
-
wp_register_style( 'styles-font-menu', $this->plugin_url . '/css/styles-font-menu.css', array(), $this->version );
|
134 |
-
// wp_register_style( 'styles-chosen', $this->plugin_url . '/js/chosen/chosen.min.css', array(), $this->version );
|
135 |
-
|
136 |
-
// Pass Google Font Families to javascript
|
137 |
-
// This saves on bandwidth by outputing them once,
|
138 |
-
// then appending them to all <select> elements client-side
|
139 |
-
wp_localize_script( 'styles-font-menu', 'styles_standard_fonts', $this->standard_fonts->option_values );
|
140 |
-
wp_localize_script( 'styles-font-menu', 'styles_google_options', $this->google_fonts->option_values );
|
141 |
-
|
142 |
-
// Output scripts and dependencies
|
143 |
-
// Tracks whether dependencies have already been output
|
144 |
-
wp_print_scripts( array( 'styles-font-menu' ) );
|
145 |
-
wp_print_styles( array( 'styles-chosen' ) );
|
146 |
-
wp_print_styles( array( 'styles-font-menu' ) );
|
147 |
-
|
148 |
-
// Generated scripts for font previews
|
149 |
-
echo '<style>' . $this->standard_fonts->get_menu_css() . '</style>';
|
150 |
-
|
151 |
-
$this->scripts_printed = true;
|
152 |
-
}
|
153 |
-
|
154 |
-
/**
|
155 |
-
* Display views/menu.php
|
156 |
-
*/
|
157 |
-
public function get_view_menu( $attributes = '', $value = false ) {
|
158 |
-
$args = compact( 'attributes', 'value' );
|
159 |
-
$this->get_view( 'menu', $args );
|
160 |
-
}
|
161 |
-
|
162 |
-
/**
|
163 |
-
* Display any view from the views/ directory.
|
164 |
-
* Allows views to have access to $this
|
165 |
-
*/
|
166 |
-
public function get_view( $file = 'menu', $args = array() ) {
|
167 |
-
extract( $args );
|
168 |
-
$file = dirname( dirname( __FILE__ ) ) . "/views/$file.php";
|
169 |
-
if ( file_exists( $file ) ) {
|
170 |
-
include $file;
|
171 |
-
}
|
172 |
-
}
|
173 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require_once dirname(__FILE__) . '/sfm-admin.php';
|
4 |
+
require_once dirname(__FILE__) . '/sfm-group.php';
|
5 |
+
require_once dirname(__FILE__) . '/sfm-group-standard.php';
|
6 |
+
require_once dirname(__FILE__) . '/sfm-group-google.php';
|
7 |
+
require_once dirname(__FILE__) . '/sfm-single-standard.php';
|
8 |
+
require_once dirname(__FILE__) . '/sfm-single-google.php';
|
9 |
+
require_once dirname(__FILE__) . '/sfm-image-preview.php';
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Controller class
|
13 |
+
* Holds instances of models in vars
|
14 |
+
* Loads views from views/ directory
|
15 |
+
*
|
16 |
+
* Follows the Singleton pattern. @see http://jumping-duck.com/tutorial/wordpress-plugin-structure/
|
17 |
+
* @example Access plugin instance with $font_dropdown = SFM_Plugin::get_instance();
|
18 |
+
*/
|
19 |
+
class SFM_Plugin {
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var string The plugin version.
|
23 |
+
*/
|
24 |
+
var $version = '1.0.1';
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @var Styles_Font_Menu Instance of the class.
|
28 |
+
*/
|
29 |
+
protected static $instance = false;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @var string Class to apply to menu element and prefix to selectors.
|
33 |
+
*/
|
34 |
+
public $menu_class = 'sfm';
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var SFM_Admin Methods for WordPress admin user interface.
|
38 |
+
*/
|
39 |
+
var $admin;
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @var SFM_Group_Standard Web standard font families and CSS font stacks.
|
43 |
+
*/
|
44 |
+
var $standard_fonts;
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @var SFM_Group_Google Connects to Google Font API.
|
48 |
+
*/
|
49 |
+
var $google_fonts;
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @var SFM_Image_Preview Generate image preview of a font.
|
53 |
+
*/
|
54 |
+
var $image_preview;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Set with site_url() because we might not be running as a plugin.
|
58 |
+
*
|
59 |
+
* @var string URL for the styles-font-menu directory.
|
60 |
+
*/
|
61 |
+
var $plugin_url;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Set with dirname(__FILE__) because we might not be running as a plugin.
|
65 |
+
*
|
66 |
+
* @var string Path for the styles-font-menu directory.
|
67 |
+
*/
|
68 |
+
var $plugin_directory;
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Intentionally inaccurate if we're running as a plugin.
|
72 |
+
*
|
73 |
+
* @var string Plugin basename, only if we're running as a plugin.
|
74 |
+
*/
|
75 |
+
var $plugin_basename;
|
76 |
+
|
77 |
+
/**
|
78 |
+
* print_scripts() runs as late as possible to avoid processing Google Fonts.
|
79 |
+
* This prevents running multiple times.
|
80 |
+
*
|
81 |
+
* @var bool Whether we have already registered scripts or not.
|
82 |
+
*/
|
83 |
+
var $scripts_printed = false;
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Don't use this. Use ::get_instance() instead.
|
87 |
+
*/
|
88 |
+
public function __construct() {
|
89 |
+
if ( !self::$instance ) {
|
90 |
+
$message = '<code>' . __CLASS__ . '</code> is a singleton.<br/> Please get an instantiate it with <code>' . __CLASS__ . '::get_instance();</code>';
|
91 |
+
wp_die( $message );
|
92 |
+
}
|
93 |
+
}
|
94 |
+
|
95 |
+
public static function get_instance() {
|
96 |
+
if ( !is_a( self::$instance, __CLASS__ ) ) {
|
97 |
+
self::$instance = true;
|
98 |
+
self::$instance = new self();
|
99 |
+
self::$instance->init();
|
100 |
+
}
|
101 |
+
return self::$instance;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Initial setup. Called by get_instance.
|
106 |
+
*/
|
107 |
+
protected function init() {
|
108 |
+
// Fix for IIS paths
|
109 |
+
$normalized_abspath = str_replace(array('/', '\\'), '/', ABSPATH );
|
110 |
+
|
111 |
+
$this->plugin_directory = str_replace(array('/', '\\'), '/', dirname( dirname( __FILE__ ) ) );
|
112 |
+
$this->plugin_url = site_url( str_replace( $normalized_abspath, '', $this->plugin_directory ) );
|
113 |
+
$this->plugin_basename = plugin_basename( $this->plugin_directory . '/plugin.php' );
|
114 |
+
|
115 |
+
$this->admin = new SFM_Admin( $this );
|
116 |
+
$this->google_fonts = new SFM_Group_Google();
|
117 |
+
$this->standard_fonts = new SFM_Group_Standard();
|
118 |
+
$this->image_preview = new SFM_Image_Preview();
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Output dropdown menu anywhere styles_font_menu action is called.
|
122 |
+
* @example <code>do_action( 'styles_font_menu' );</code>
|
123 |
+
*/
|
124 |
+
add_action( 'styles_font_menu', array( $this, 'get_view_menu' ), 10, 2 );
|
125 |
+
}
|
126 |
+
|
127 |
+
public function print_scripts() {
|
128 |
+
if ( $this->scripts_printed ) { return false; }
|
129 |
+
|
130 |
+
wp_register_script( 'styles-chosen', $this->plugin_url . '/js/chosen/chosen.jquery.min.js', array( 'jquery' ), $this->version );
|
131 |
+
wp_register_script( 'styles-font-menu', $this->plugin_url . '/js/styles-font-menu.js', array( 'jquery', 'styles-chosen' ), $this->version );
|
132 |
+
wp_register_style( 'styles-chosen', $this->plugin_url . '/js/chosen/chosen.css', array(), $this->version );
|
133 |
+
wp_register_style( 'styles-font-menu', $this->plugin_url . '/css/styles-font-menu.css', array(), $this->version );
|
134 |
+
// wp_register_style( 'styles-chosen', $this->plugin_url . '/js/chosen/chosen.min.css', array(), $this->version );
|
135 |
+
|
136 |
+
// Pass Google Font Families to javascript
|
137 |
+
// This saves on bandwidth by outputing them once,
|
138 |
+
// then appending them to all <select> elements client-side
|
139 |
+
wp_localize_script( 'styles-font-menu', 'styles_standard_fonts', $this->standard_fonts->option_values );
|
140 |
+
wp_localize_script( 'styles-font-menu', 'styles_google_options', $this->google_fonts->option_values );
|
141 |
+
|
142 |
+
// Output scripts and dependencies
|
143 |
+
// Tracks whether dependencies have already been output
|
144 |
+
wp_print_scripts( array( 'styles-font-menu' ) );
|
145 |
+
wp_print_styles( array( 'styles-chosen' ) );
|
146 |
+
wp_print_styles( array( 'styles-font-menu' ) );
|
147 |
+
|
148 |
+
// Generated scripts for font previews
|
149 |
+
echo '<style>' . $this->standard_fonts->get_menu_css() . '</style>';
|
150 |
+
|
151 |
+
$this->scripts_printed = true;
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Display views/menu.php
|
156 |
+
*/
|
157 |
+
public function get_view_menu( $attributes = '', $value = false ) {
|
158 |
+
$args = compact( 'attributes', 'value' );
|
159 |
+
$this->get_view( 'menu', $args );
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Display any view from the views/ directory.
|
164 |
+
* Allows views to have access to $this
|
165 |
+
*/
|
166 |
+
public function get_view( $file = 'menu', $args = array() ) {
|
167 |
+
extract( $args );
|
168 |
+
$file = dirname( dirname( __FILE__ ) ) . "/views/$file.php";
|
169 |
+
if ( file_exists( $file ) ) {
|
170 |
+
include $file;
|
171 |
+
}
|
172 |
+
}
|
173 |
}
|
classes/styles-font-menu/classes/sfm-single-google.php
CHANGED
@@ -1,262 +1,262 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class SFM_Single_Google extends SFM_Single_Standard {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var array Variant names
|
7 |
-
*/
|
8 |
-
protected $variants;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var array Info on active variant, for image previews
|
12 |
-
*/
|
13 |
-
protected $variant;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var array URLs to TTF files with variants as array keys.
|
17 |
-
*/
|
18 |
-
protected $files;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Path and URL to the plugin directory and uploads directory
|
22 |
-
*/
|
23 |
-
protected $file_paths;
|
24 |
-
|
25 |
-
/**
|
26 |
-
* @string Variation of name for insertion into @import CSS string.
|
27 |
-
*/
|
28 |
-
protected $import_family;
|
29 |
-
|
30 |
-
protected $png_url;
|
31 |
-
|
32 |
-
/**
|
33 |
-
* Values for this font that should go into JSON encoded <option> values
|
34 |
-
*/
|
35 |
-
protected $option_value_whitelist = array( 'family', 'name', 'import_family', 'classname', 'png_url' );
|
36 |
-
|
37 |
-
/**
|
38 |
-
* @var array Options to pass to javascript
|
39 |
-
*/
|
40 |
-
protected $options;
|
41 |
-
|
42 |
-
public function __construct( $args = array() ) {
|
43 |
-
parent::__construct( $args );
|
44 |
-
|
45 |
-
$this->variants = $args['variants'];
|
46 |
-
$this->files = $args['files'];
|
47 |
-
$this->import_family = $this->get_import_family();
|
48 |
-
}
|
49 |
-
|
50 |
-
public function get_import_family() {
|
51 |
-
return str_replace( ' ', '+', $this->family ) . ':' . implode( ',', $this->variants );
|
52 |
-
}
|
53 |
-
|
54 |
-
/**
|
55 |
-
* This function can lead to get_remote_ttf
|
56 |
-
* For that reason, it shouldn't be called on init
|
57 |
-
* Right now, it's only called in an AJAX request for a font preview
|
58 |
-
*/
|
59 |
-
public function get_variant( $variant_request = false ) {
|
60 |
-
if ( isset( $this->variant ) ) {
|
61 |
-
return $this->variant;
|
62 |
-
}
|
63 |
-
|
64 |
-
if ( empty( $variant_request ) && isset( $_GET['variant'] ) ) {
|
65 |
-
$variant_request = $_GET['variant'];
|
66 |
-
}
|
67 |
-
|
68 |
-
if ( empty( $variant_request ) ) {
|
69 |
-
// No variant requested. Give default.
|
70 |
-
if ( in_array( 'regular', (array) $this->variants ) ) {
|
71 |
-
$variant_name = 'regular';
|
72 |
-
}else {
|
73 |
-
$variant_name = $this->variants[0];
|
74 |
-
}
|
75 |
-
}else if ( in_array( $variant_request, (array) $this->variants ) ) {
|
76 |
-
// Variant requested and found
|
77 |
-
$variant_name = $variant;
|
78 |
-
}
|
79 |
-
|
80 |
-
if ( !$variant_name ) {
|
81 |
-
// Requested a variant, but none found
|
82 |
-
$variants = implode( '</li><li>', array_keys( (array) $this->variants ) );
|
83 |
-
wp_die( 'Variant not found. Variants: <ul><li>' . $variants . '</li></ul>' );
|
84 |
-
}
|
85 |
-
|
86 |
-
// Variant meta
|
87 |
-
$this->variant = array();
|
88 |
-
$this->variant['name'] = $variant_name;
|
89 |
-
$this->variant['filename'] = $this->get_nicename() . '-' . $variant_name;
|
90 |
-
$this->variant['png_path'] = $this->get_png_path();
|
91 |
-
$this->variant['png_url'] = $this->get_png_url();
|
92 |
-
$this->variant['ttf_path'] = $this->get_ttf_path();
|
93 |
-
$this->variant['ttf_url'] = $this->get_ttf_url();
|
94 |
-
|
95 |
-
return $this->variant;
|
96 |
-
}
|
97 |
-
|
98 |
-
public function get_file_paths() {
|
99 |
-
if ( isset( $this->file_paths ) ) {
|
100 |
-
return $this->file_paths;
|
101 |
-
}
|
102 |
-
|
103 |
-
$plugin = SFM_Plugin::get_instance();
|
104 |
-
|
105 |
-
$uploads = wp_upload_dir();
|
106 |
-
$fonts_dir = '/styles-fonts';
|
107 |
-
|
108 |
-
$this->file_paths = array(
|
109 |
-
'plugin' => array(
|
110 |
-
'path' => $plugin->plugin_directory . $fonts_dir,
|
111 |
-
'url' => $plugin->plugin_url . $fonts_dir,
|
112 |
-
),
|
113 |
-
'uploads' => array(
|
114 |
-
'path' => $uploads['basedir'] . $fonts_dir,
|
115 |
-
'url' => $uploads['baseurl'] . $fonts_dir,
|
116 |
-
),
|
117 |
-
);
|
118 |
-
return $this->file_paths;
|
119 |
-
}
|
120 |
-
|
121 |
-
/**
|
122 |
-
* @return string Path or URL to file if it exists in paths listed in get_file_paths()
|
123 |
-
*/
|
124 |
-
public function get_file( $path_or_url = 'path', $ext = 'png', $return_cache_path = false ) {
|
125 |
-
$variant = $this->get_variant();
|
126 |
-
|
127 |
-
$target = "/$ext/" . $variant['filename'] . ".$ext";
|
128 |
-
$locations = $this->get_file_paths();
|
129 |
-
|
130 |
-
foreach ( $locations as $location ) {
|
131 |
-
$path = $location[ 'path' ] . $target;
|
132 |
-
$url = $location[ 'url' ] . $target;
|
133 |
-
|
134 |
-
if ( file_exists( $path ) ) {
|
135 |
-
if ( 'path' == $path_or_url ) {
|
136 |
-
return $path;
|
137 |
-
}else {
|
138 |
-
return $url;
|
139 |
-
}
|
140 |
-
}
|
141 |
-
}
|
142 |
-
|
143 |
-
if ( $return_cache_path ) {
|
144 |
-
return $locations['uploads']['path'] . $target;
|
145 |
-
}
|
146 |
-
|
147 |
-
return false;
|
148 |
-
}
|
149 |
-
|
150 |
-
/**
|
151 |
-
* @return string URL of image preview PNG for the active variant
|
152 |
-
*/
|
153 |
-
public function get_png_url() {
|
154 |
-
return $this->get_file( 'url', 'png' );
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* @return string path of image preview PNG for the active variant
|
159 |
-
*/
|
160 |
-
public function get_png_path() {
|
161 |
-
return $this->get_file( 'path', 'png');
|
162 |
-
}
|
163 |
-
|
164 |
-
public function get_png_cache_path() {
|
165 |
-
return $this->get_file( 'path', 'png', true );
|
166 |
-
}
|
167 |
-
|
168 |
-
/**
|
169 |
-
* @return string path of TTF for the active variant
|
170 |
-
*/
|
171 |
-
public function get_ttf_path() {
|
172 |
-
return $this->get_file( 'path', 'ttf' );
|
173 |
-
}
|
174 |
-
|
175 |
-
public function get_ttf_cache_path() {
|
176 |
-
return $this->get_file( 'path', 'ttf', true );
|
177 |
-
}
|
178 |
-
|
179 |
-
/**
|
180 |
-
* @return string Remote (google) URL of TTF for the active variant
|
181 |
-
*/
|
182 |
-
public function get_ttf_url() {
|
183 |
-
$variant = $this->get_variant();
|
184 |
-
$variant_name = $variant['name'];
|
185 |
-
|
186 |
-
return $this->files->{$variant_name};
|
187 |
-
}
|
188 |
-
|
189 |
-
/**
|
190 |
-
* @return string sanatized font family name for use in file names.
|
191 |
-
*/
|
192 |
-
public function get_nicename() {
|
193 |
-
if ( isset( $this->nicename ) ) {
|
194 |
-
return $this->nicename;
|
195 |
-
}
|
196 |
-
$this->nicename = strtolower( preg_replace( '/[^a-zA-Z0-9]/', '', $this->family ) );
|
197 |
-
return $this->nicename;
|
198 |
-
}
|
199 |
-
|
200 |
-
/**
|
201 |
-
* @return string path to the cached or downloaded TTF file
|
202 |
-
*/
|
203 |
-
public function maybe_get_remote_ttf() {
|
204 |
-
$ttf_path = $this->get_ttf_path();
|
205 |
-
|
206 |
-
if ( file_exists( $ttf_path ) ) {
|
207 |
-
return $ttf_path;
|
208 |
-
}else {
|
209 |
-
return $this->get_remote_ttf();
|
210 |
-
}
|
211 |
-
}
|
212 |
-
|
213 |
-
/**
|
214 |
-
* @return string path to the cached TTF file received from remote request.
|
215 |
-
*/
|
216 |
-
public function get_remote_ttf() {
|
217 |
-
// Load filesystem
|
218 |
-
if ( !function_exists('WP_Filesystem')) { require ABSPATH . 'wp-admin/includes/file.php'; }
|
219 |
-
global $wp_filesystem;
|
220 |
-
WP_Filesystem();
|
221 |
-
|
222 |
-
// Create cache directory
|
223 |
-
$dir = dirname( $this->get_ttf_path() );
|
224 |
-
if ( !is_dir( $dir ) && !wp_mkdir_p( $dir ) ) {
|
225 |
-
wp_die( "Please check permissions. Could not create directory $dir" );
|
226 |
-
}
|
227 |
-
|
228 |
-
// Cache remote TTF to filesystem
|
229 |
-
$ttf_file_path = $wp_filesystem->put_contents(
|
230 |
-
$this->get_ttf_cache_path(),
|
231 |
-
$this->get_remote_ttf_contents(),
|
232 |
-
FS_CHMOD_FILE // predefined mode settings for WP files
|
233 |
-
);
|
234 |
-
|
235 |
-
// Check file saved
|
236 |
-
if ( !$ttf_file_path ) {
|
237 |
-
wp_die( "Please check permissions. Could not write font to $dir" );
|
238 |
-
}
|
239 |
-
|
240 |
-
return $this->get_ttf_path();
|
241 |
-
}
|
242 |
-
|
243 |
-
/**
|
244 |
-
* @return binary The active variant's TTF file contents
|
245 |
-
*/
|
246 |
-
public function get_remote_ttf_contents() {
|
247 |
-
$ttf_url = $this->get_ttf_url();
|
248 |
-
|
249 |
-
if ( empty( $ttf_url ) ) {
|
250 |
-
wp_die( 'Font URL not set.' );
|
251 |
-
}
|
252 |
-
|
253 |
-
$response = wp_remote_get( $ttf_url );
|
254 |
-
|
255 |
-
if ( is_a( $response, 'WP_Error') ) {
|
256 |
-
wp_die( "Attempt to get remote font returned an error.<br/>$ttf_url" );
|
257 |
-
}
|
258 |
-
|
259 |
-
return $response['body'];
|
260 |
-
}
|
261 |
-
|
262 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class SFM_Single_Google extends SFM_Single_Standard {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var array Variant names
|
7 |
+
*/
|
8 |
+
protected $variants;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var array Info on active variant, for image previews
|
12 |
+
*/
|
13 |
+
protected $variant;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var array URLs to TTF files with variants as array keys.
|
17 |
+
*/
|
18 |
+
protected $files;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Path and URL to the plugin directory and uploads directory
|
22 |
+
*/
|
23 |
+
protected $file_paths;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @string Variation of name for insertion into @import CSS string.
|
27 |
+
*/
|
28 |
+
protected $import_family;
|
29 |
+
|
30 |
+
protected $png_url;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Values for this font that should go into JSON encoded <option> values
|
34 |
+
*/
|
35 |
+
protected $option_value_whitelist = array( 'family', 'name', 'import_family', 'classname', 'png_url' );
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var array Options to pass to javascript
|
39 |
+
*/
|
40 |
+
protected $options;
|
41 |
+
|
42 |
+
public function __construct( $args = array() ) {
|
43 |
+
parent::__construct( $args );
|
44 |
+
|
45 |
+
$this->variants = $args['variants'];
|
46 |
+
$this->files = $args['files'];
|
47 |
+
$this->import_family = $this->get_import_family();
|
48 |
+
}
|
49 |
+
|
50 |
+
public function get_import_family() {
|
51 |
+
return str_replace( ' ', '+', $this->family ) . ':' . implode( ',', $this->variants );
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* This function can lead to get_remote_ttf
|
56 |
+
* For that reason, it shouldn't be called on init
|
57 |
+
* Right now, it's only called in an AJAX request for a font preview
|
58 |
+
*/
|
59 |
+
public function get_variant( $variant_request = false ) {
|
60 |
+
if ( isset( $this->variant ) ) {
|
61 |
+
return $this->variant;
|
62 |
+
}
|
63 |
+
|
64 |
+
if ( empty( $variant_request ) && isset( $_GET['variant'] ) ) {
|
65 |
+
$variant_request = $_GET['variant'];
|
66 |
+
}
|
67 |
+
|
68 |
+
if ( empty( $variant_request ) ) {
|
69 |
+
// No variant requested. Give default.
|
70 |
+
if ( in_array( 'regular', (array) $this->variants ) ) {
|
71 |
+
$variant_name = 'regular';
|
72 |
+
}else {
|
73 |
+
$variant_name = $this->variants[0];
|
74 |
+
}
|
75 |
+
}else if ( in_array( $variant_request, (array) $this->variants ) ) {
|
76 |
+
// Variant requested and found
|
77 |
+
$variant_name = $variant;
|
78 |
+
}
|
79 |
+
|
80 |
+
if ( !$variant_name ) {
|
81 |
+
// Requested a variant, but none found
|
82 |
+
$variants = implode( '</li><li>', array_keys( (array) $this->variants ) );
|
83 |
+
wp_die( 'Variant not found. Variants: <ul><li>' . $variants . '</li></ul>' );
|
84 |
+
}
|
85 |
+
|
86 |
+
// Variant meta
|
87 |
+
$this->variant = array();
|
88 |
+
$this->variant['name'] = $variant_name;
|
89 |
+
$this->variant['filename'] = $this->get_nicename() . '-' . $variant_name;
|
90 |
+
$this->variant['png_path'] = $this->get_png_path();
|
91 |
+
$this->variant['png_url'] = $this->get_png_url();
|
92 |
+
$this->variant['ttf_path'] = $this->get_ttf_path();
|
93 |
+
$this->variant['ttf_url'] = $this->get_ttf_url();
|
94 |
+
|
95 |
+
return $this->variant;
|
96 |
+
}
|
97 |
+
|
98 |
+
public function get_file_paths() {
|
99 |
+
if ( isset( $this->file_paths ) ) {
|
100 |
+
return $this->file_paths;
|
101 |
+
}
|
102 |
+
|
103 |
+
$plugin = SFM_Plugin::get_instance();
|
104 |
+
|
105 |
+
$uploads = wp_upload_dir();
|
106 |
+
$fonts_dir = '/styles-fonts';
|
107 |
+
|
108 |
+
$this->file_paths = array(
|
109 |
+
'plugin' => array(
|
110 |
+
'path' => $plugin->plugin_directory . $fonts_dir,
|
111 |
+
'url' => $plugin->plugin_url . $fonts_dir,
|
112 |
+
),
|
113 |
+
'uploads' => array(
|
114 |
+
'path' => $uploads['basedir'] . $fonts_dir,
|
115 |
+
'url' => $uploads['baseurl'] . $fonts_dir,
|
116 |
+
),
|
117 |
+
);
|
118 |
+
return $this->file_paths;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* @return string Path or URL to file if it exists in paths listed in get_file_paths()
|
123 |
+
*/
|
124 |
+
public function get_file( $path_or_url = 'path', $ext = 'png', $return_cache_path = false ) {
|
125 |
+
$variant = $this->get_variant();
|
126 |
+
|
127 |
+
$target = "/$ext/" . $variant['filename'] . ".$ext";
|
128 |
+
$locations = $this->get_file_paths();
|
129 |
+
|
130 |
+
foreach ( $locations as $location ) {
|
131 |
+
$path = $location[ 'path' ] . $target;
|
132 |
+
$url = $location[ 'url' ] . $target;
|
133 |
+
|
134 |
+
if ( file_exists( $path ) ) {
|
135 |
+
if ( 'path' == $path_or_url ) {
|
136 |
+
return $path;
|
137 |
+
}else {
|
138 |
+
return $url;
|
139 |
+
}
|
140 |
+
}
|
141 |
+
}
|
142 |
+
|
143 |
+
if ( $return_cache_path ) {
|
144 |
+
return $locations['uploads']['path'] . $target;
|
145 |
+
}
|
146 |
+
|
147 |
+
return false;
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* @return string URL of image preview PNG for the active variant
|
152 |
+
*/
|
153 |
+
public function get_png_url() {
|
154 |
+
return $this->get_file( 'url', 'png' );
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* @return string path of image preview PNG for the active variant
|
159 |
+
*/
|
160 |
+
public function get_png_path() {
|
161 |
+
return $this->get_file( 'path', 'png');
|
162 |
+
}
|
163 |
+
|
164 |
+
public function get_png_cache_path() {
|
165 |
+
return $this->get_file( 'path', 'png', true );
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* @return string path of TTF for the active variant
|
170 |
+
*/
|
171 |
+
public function get_ttf_path() {
|
172 |
+
return $this->get_file( 'path', 'ttf' );
|
173 |
+
}
|
174 |
+
|
175 |
+
public function get_ttf_cache_path() {
|
176 |
+
return $this->get_file( 'path', 'ttf', true );
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* @return string Remote (google) URL of TTF for the active variant
|
181 |
+
*/
|
182 |
+
public function get_ttf_url() {
|
183 |
+
$variant = $this->get_variant();
|
184 |
+
$variant_name = $variant['name'];
|
185 |
+
|
186 |
+
return $this->files->{$variant_name};
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* @return string sanatized font family name for use in file names.
|
191 |
+
*/
|
192 |
+
public function get_nicename() {
|
193 |
+
if ( isset( $this->nicename ) ) {
|
194 |
+
return $this->nicename;
|
195 |
+
}
|
196 |
+
$this->nicename = strtolower( preg_replace( '/[^a-zA-Z0-9]/', '', $this->family ) );
|
197 |
+
return $this->nicename;
|
198 |
+
}
|
199 |
+
|
200 |
+
/**
|
201 |
+
* @return string path to the cached or downloaded TTF file
|
202 |
+
*/
|
203 |
+
public function maybe_get_remote_ttf() {
|
204 |
+
$ttf_path = $this->get_ttf_path();
|
205 |
+
|
206 |
+
if ( file_exists( $ttf_path ) ) {
|
207 |
+
return $ttf_path;
|
208 |
+
}else {
|
209 |
+
return $this->get_remote_ttf();
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* @return string path to the cached TTF file received from remote request.
|
215 |
+
*/
|
216 |
+
public function get_remote_ttf() {
|
217 |
+
// Load filesystem
|
218 |
+
if ( !function_exists('WP_Filesystem')) { require ABSPATH . 'wp-admin/includes/file.php'; }
|
219 |
+
global $wp_filesystem;
|
220 |
+
WP_Filesystem();
|
221 |
+
|
222 |
+
// Create cache directory
|
223 |
+
$dir = dirname( $this->get_ttf_path() );
|
224 |
+
if ( !is_dir( $dir ) && !wp_mkdir_p( $dir ) ) {
|
225 |
+
wp_die( "Please check permissions. Could not create directory $dir" );
|
226 |
+
}
|
227 |
+
|
228 |
+
// Cache remote TTF to filesystem
|
229 |
+
$ttf_file_path = $wp_filesystem->put_contents(
|
230 |
+
$this->get_ttf_cache_path(),
|
231 |
+
$this->get_remote_ttf_contents(),
|
232 |
+
FS_CHMOD_FILE // predefined mode settings for WP files
|
233 |
+
);
|
234 |
+
|
235 |
+
// Check file saved
|
236 |
+
if ( !$ttf_file_path ) {
|
237 |
+
wp_die( "Please check permissions. Could not write font to $dir" );
|
238 |
+
}
|
239 |
+
|
240 |
+
return $this->get_ttf_path();
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* @return binary The active variant's TTF file contents
|
245 |
+
*/
|
246 |
+
public function get_remote_ttf_contents() {
|
247 |
+
$ttf_url = $this->get_ttf_url();
|
248 |
+
|
249 |
+
if ( empty( $ttf_url ) ) {
|
250 |
+
wp_die( 'Font URL not set.' );
|
251 |
+
}
|
252 |
+
|
253 |
+
$response = wp_remote_get( $ttf_url );
|
254 |
+
|
255 |
+
if ( is_a( $response, 'WP_Error') ) {
|
256 |
+
wp_die( "Attempt to get remote font returned an error.<br/>$ttf_url" );
|
257 |
+
}
|
258 |
+
|
259 |
+
return $response['body'];
|
260 |
+
}
|
261 |
+
|
262 |
}
|
classes/styles-font-menu/classes/sfm-single-standard.php
CHANGED
@@ -1,115 +1,115 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class SFM_Single_Standard {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* @var string Name of the font
|
7 |
-
*/
|
8 |
-
protected $name;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Font family stack for output as CSS value
|
12 |
-
*/
|
13 |
-
protected $family;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* CSS class for output in Menu stylesheet
|
17 |
-
*/
|
18 |
-
protected $classname;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* Values for this font that should go into JSON encoded <option> values
|
22 |
-
*/
|
23 |
-
protected $option_value_whitelist = array( 'family', 'name', 'classname' );
|
24 |
-
|
25 |
-
public function __construct( $args ) {
|
26 |
-
$this->name = $args['name'];
|
27 |
-
$this->family = $args['family'];
|
28 |
-
$this->classname = $this->get_classname();
|
29 |
-
}
|
30 |
-
|
31 |
-
/**
|
32 |
-
* When we echo this class, output encoded JSON values
|
33 |
-
*
|
34 |
-
* @return string JSON string of values
|
35 |
-
*/
|
36 |
-
public function __tostring() {
|
37 |
-
return json_encode( $this->get_option_values() );
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* If client tries to access variables directly, pass to get() method
|
42 |
-
*/
|
43 |
-
public function __get( $target ) {
|
44 |
-
return $this->get( $target );
|
45 |
-
}
|
46 |
-
|
47 |
-
/**
|
48 |
-
* If a get_XXX method exists for a variable, use it.
|
49 |
-
* Otherwise, return the variable value
|
50 |
-
*/
|
51 |
-
public function get( $target = 'fonts' ) {
|
52 |
-
$method = 'get_' . $target;
|
53 |
-
if ( method_exists( $this, $method ) ) {
|
54 |
-
return $this->$method();
|
55 |
-
}else if ( isset( $this->$target ) ){
|
56 |
-
return $this->$target;
|
57 |
-
}else {
|
58 |
-
return false;
|
59 |
-
}
|
60 |
-
}
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Similar to WordPress sanatize_key.
|
64 |
-
*
|
65 |
-
* @param string $key Name of a font.
|
66 |
-
* @return string Lowercase alphanumeric name of font without spaces.
|
67 |
-
*/
|
68 |
-
public function sanatize_key( $key ) {
|
69 |
-
return strtolower( preg_replace( '/[^a-zA-Z0-9]/', '', $key ) );
|
70 |
-
}
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Strip out unecessary metadata <select> option values
|
74 |
-
*
|
75 |
-
* @param array $font Font metadata, such as array( 'key', 'import_family', 'font_family', 'font_name' )
|
76 |
-
* @return array Same array, stripped of extra keys
|
77 |
-
*/
|
78 |
-
public function get_option_values() {
|
79 |
-
$option_values = array();
|
80 |
-
|
81 |
-
foreach ( $this->option_value_whitelist as $key ) {
|
82 |
-
$value = $this->get( $key );
|
83 |
-
if ( !empty( $value ) ) {
|
84 |
-
$option_values[ $key ] = esc_attr( $value );
|
85 |
-
}
|
86 |
-
}
|
87 |
-
|
88 |
-
return $option_values;
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Get CSS class for output in stylesheet
|
93 |
-
*
|
94 |
-
* @return string CSS selector
|
95 |
-
*/
|
96 |
-
public function get_classname() {
|
97 |
-
if ( !empty( $this->classname ) ) {
|
98 |
-
return $this->classname;
|
99 |
-
}
|
100 |
-
$this->classname = $this->sanatize_key( $this->name );
|
101 |
-
|
102 |
-
return $this->classname;
|
103 |
-
}
|
104 |
-
|
105 |
-
public function get_selector(){
|
106 |
-
$plugin = SFM_Plugin::get_instance();
|
107 |
-
|
108 |
-
return '.' . $plugin->menu_class . ' .' . $this->get_classname();
|
109 |
-
}
|
110 |
-
|
111 |
-
public function get_menu_css() {
|
112 |
-
return $this->get_selector() . "{font-family:{$this->family}}" . PHP_EOL;
|
113 |
-
}
|
114 |
-
|
115 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class SFM_Single_Standard {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var string Name of the font
|
7 |
+
*/
|
8 |
+
protected $name;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Font family stack for output as CSS value
|
12 |
+
*/
|
13 |
+
protected $family;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* CSS class for output in Menu stylesheet
|
17 |
+
*/
|
18 |
+
protected $classname;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Values for this font that should go into JSON encoded <option> values
|
22 |
+
*/
|
23 |
+
protected $option_value_whitelist = array( 'family', 'name', 'classname' );
|
24 |
+
|
25 |
+
public function __construct( $args ) {
|
26 |
+
$this->name = $args['name'];
|
27 |
+
$this->family = $args['family'];
|
28 |
+
$this->classname = $this->get_classname();
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* When we echo this class, output encoded JSON values
|
33 |
+
*
|
34 |
+
* @return string JSON string of values
|
35 |
+
*/
|
36 |
+
public function __tostring() {
|
37 |
+
return json_encode( $this->get_option_values() );
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* If client tries to access variables directly, pass to get() method
|
42 |
+
*/
|
43 |
+
public function __get( $target ) {
|
44 |
+
return $this->get( $target );
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* If a get_XXX method exists for a variable, use it.
|
49 |
+
* Otherwise, return the variable value
|
50 |
+
*/
|
51 |
+
public function get( $target = 'fonts' ) {
|
52 |
+
$method = 'get_' . $target;
|
53 |
+
if ( method_exists( $this, $method ) ) {
|
54 |
+
return $this->$method();
|
55 |
+
}else if ( isset( $this->$target ) ){
|
56 |
+
return $this->$target;
|
57 |
+
}else {
|
58 |
+
return false;
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Similar to WordPress sanatize_key.
|
64 |
+
*
|
65 |
+
* @param string $key Name of a font.
|
66 |
+
* @return string Lowercase alphanumeric name of font without spaces.
|
67 |
+
*/
|
68 |
+
public function sanatize_key( $key ) {
|
69 |
+
return strtolower( preg_replace( '/[^a-zA-Z0-9]/', '', $key ) );
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Strip out unecessary metadata <select> option values
|
74 |
+
*
|
75 |
+
* @param array $font Font metadata, such as array( 'key', 'import_family', 'font_family', 'font_name' )
|
76 |
+
* @return array Same array, stripped of extra keys
|
77 |
+
*/
|
78 |
+
public function get_option_values() {
|
79 |
+
$option_values = array();
|
80 |
+
|
81 |
+
foreach ( $this->option_value_whitelist as $key ) {
|
82 |
+
$value = $this->get( $key );
|
83 |
+
if ( !empty( $value ) ) {
|
84 |
+
$option_values[ $key ] = esc_attr( $value );
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
return $option_values;
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Get CSS class for output in stylesheet
|
93 |
+
*
|
94 |
+
* @return string CSS selector
|
95 |
+
*/
|
96 |
+
public function get_classname() {
|
97 |
+
if ( !empty( $this->classname ) ) {
|
98 |
+
return $this->classname;
|
99 |
+
}
|
100 |
+
$this->classname = $this->sanatize_key( $this->name );
|
101 |
+
|
102 |
+
return $this->classname;
|
103 |
+
}
|
104 |
+
|
105 |
+
public function get_selector(){
|
106 |
+
$plugin = SFM_Plugin::get_instance();
|
107 |
+
|
108 |
+
return '.' . $plugin->menu_class . ' .' . $this->get_classname();
|
109 |
+
}
|
110 |
+
|
111 |
+
public function get_menu_css() {
|
112 |
+
return $this->get_selector() . "{font-family:{$this->family}}" . PHP_EOL;
|
113 |
+
}
|
114 |
+
|
115 |
}
|
classes/styles-font-menu/css/styles-font-menu.css
CHANGED
@@ -1,46 +1,46 @@
|
|
1 |
-
/* Admin Readme */
|
2 |
-
#styles-font-menu-readme > ul {
|
3 |
-
list-style-type: disc;
|
4 |
-
margin-left: 30px;
|
5 |
-
}
|
6 |
-
|
7 |
-
/* Menu height */
|
8 |
-
.sfm .chosen-results {
|
9 |
-
max-height: 400px !important;
|
10 |
-
}
|
11 |
-
|
12 |
-
/* Standard Font */
|
13 |
-
.sfm .sf {
|
14 |
-
font-size: 36px;
|
15 |
-
height:52px;
|
16 |
-
line-height: 52px !important;
|
17 |
-
white-space: nowrap;
|
18 |
-
}
|
19 |
-
.sfm .sf:hover {
|
20 |
-
color: #21759B;
|
21 |
-
}
|
22 |
-
|
23 |
-
/* Google Font */
|
24 |
-
.sfm .gf {
|
25 |
-
height:64px;
|
26 |
-
text-indent: -9999px;
|
27 |
-
overflow:hidden;
|
28 |
-
background-repeat: no-repeat;
|
29 |
-
}
|
30 |
-
|
31 |
-
img.sfm-preview {
|
32 |
-
margin: 0;
|
33 |
-
padding:0;
|
34 |
-
border: 0;
|
35 |
-
}
|
36 |
-
|
37 |
-
.sfm-preview, .sfm .gf {
|
38 |
-
background-color: #000;
|
39 |
-
}
|
40 |
-
|
41 |
-
.sfm-preview:hover, .sfm .gf:hover {
|
42 |
-
background-color: #21759B;
|
43 |
-
}
|
44 |
-
.sfm .chosen-results li {
|
45 |
-
padding:0 !important;
|
46 |
}
|
1 |
+
/* Admin Readme */
|
2 |
+
#styles-font-menu-readme > ul {
|
3 |
+
list-style-type: disc;
|
4 |
+
margin-left: 30px;
|
5 |
+
}
|
6 |
+
|
7 |
+
/* Menu height */
|
8 |
+
.sfm .chosen-results {
|
9 |
+
max-height: 400px !important;
|
10 |
+
}
|
11 |
+
|
12 |
+
/* Standard Font */
|
13 |
+
.sfm .sf {
|
14 |
+
font-size: 36px;
|
15 |
+
height:52px;
|
16 |
+
line-height: 52px !important;
|
17 |
+
white-space: nowrap;
|
18 |
+
}
|
19 |
+
.sfm .sf:hover {
|
20 |
+
color: #21759B;
|
21 |
+
}
|
22 |
+
|
23 |
+
/* Google Font */
|
24 |
+
.sfm .gf {
|
25 |
+
height:64px;
|
26 |
+
text-indent: -9999px;
|
27 |
+
overflow:hidden;
|
28 |
+
background-repeat: no-repeat;
|
29 |
+
}
|
30 |
+
|
31 |
+
img.sfm-preview {
|
32 |
+
margin: 0;
|
33 |
+
padding:0;
|
34 |
+
border: 0;
|
35 |
+
}
|
36 |
+
|
37 |
+
.sfm-preview, .sfm .gf {
|
38 |
+
background-color: #000;
|
39 |
+
}
|
40 |
+
|
41 |
+
.sfm-preview:hover, .sfm .gf:hover {
|
42 |
+
background-color: #21759B;
|
43 |
+
}
|
44 |
+
.sfm .chosen-results li {
|
45 |
+
padding:0 !important;
|
46 |
}
|
classes/styles-font-menu/js/chosen/chosen.css
CHANGED
@@ -1,430 +1,430 @@
|
|
1 |
-
/* @group Base */
|
2 |
-
.chosen-container {
|
3 |
-
position: relative;
|
4 |
-
display: inline-block;
|
5 |
-
vertical-align: middle;
|
6 |
-
font-size: 13px;
|
7 |
-
zoom: 1;
|
8 |
-
*display: inline;
|
9 |
-
-webkit-user-select: none;
|
10 |
-
-moz-user-select: none;
|
11 |
-
user-select: none;
|
12 |
-
}
|
13 |
-
.chosen-container .chosen-drop {
|
14 |
-
position: absolute;
|
15 |
-
top: 100%;
|
16 |
-
left: -9999px;
|
17 |
-
z-index: 1010;
|
18 |
-
-webkit-box-sizing: border-box;
|
19 |
-
-moz-box-sizing: border-box;
|
20 |
-
box-sizing: border-box;
|
21 |
-
width: 100%;
|
22 |
-
border: 1px solid #aaa;
|
23 |
-
border-top: 0;
|
24 |
-
background: #fff;
|
25 |
-
box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
|
26 |
-
}
|
27 |
-
.chosen-container.chosen-with-drop .chosen-drop {
|
28 |
-
left: 0;
|
29 |
-
}
|
30 |
-
.chosen-container a {
|
31 |
-
cursor: pointer;
|
32 |
-
}
|
33 |
-
|
34 |
-
/* @end */
|
35 |
-
/* @group Single Chosen */
|
36 |
-
.chosen-container-single .chosen-single {
|
37 |
-
position: relative;
|
38 |
-
display: block;
|
39 |
-
overflow: hidden;
|
40 |
-
padding: 0 0 0 8px;
|
41 |
-
height: 23px;
|
42 |
-
border: 1px solid #aaa;
|
43 |
-
border-radius: 5px;
|
44 |
-
background-color: #fff;
|
45 |
-
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
|
46 |
-
background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
|
47 |
-
background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
|
48 |
-
background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
|
49 |
-
background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
|
50 |
-
background-clip: padding-box;
|
51 |
-
box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
|
52 |
-
color: #444;
|
53 |
-
text-decoration: none;
|
54 |
-
white-space: nowrap;
|
55 |
-
line-height: 24px;
|
56 |
-
}
|
57 |
-
.chosen-container-single .chosen-default {
|
58 |
-
color: #999;
|
59 |
-
}
|
60 |
-
.chosen-container-single .chosen-single span {
|
61 |
-
display: block;
|
62 |
-
overflow: hidden;
|
63 |
-
margin-right: 26px;
|
64 |
-
text-overflow: ellipsis;
|
65 |
-
white-space: nowrap;
|
66 |
-
}
|
67 |
-
.chosen-container-single .chosen-single-with-deselect span {
|
68 |
-
margin-right: 38px;
|
69 |
-
}
|
70 |
-
.chosen-container-single .chosen-single abbr {
|
71 |
-
position: absolute;
|
72 |
-
top: 6px;
|
73 |
-
right: 26px;
|
74 |
-
display: block;
|
75 |
-
width: 12px;
|
76 |
-
height: 12px;
|
77 |
-
background: url('chosen-sprite.png') -42px 1px no-repeat;
|
78 |
-
font-size: 1px;
|
79 |
-
}
|
80 |
-
.chosen-container-single .chosen-single abbr:hover {
|
81 |
-
background-position: -42px -10px;
|
82 |
-
}
|
83 |
-
.chosen-container-single.chosen-disabled .chosen-single abbr:hover {
|
84 |
-
background-position: -42px -10px;
|
85 |
-
}
|
86 |
-
.chosen-container-single .chosen-single div {
|
87 |
-
position: absolute;
|
88 |
-
top: 0;
|
89 |
-
right: 0;
|
90 |
-
display: block;
|
91 |
-
width: 18px;
|
92 |
-
height: 100%;
|
93 |
-
}
|
94 |
-
.chosen-container-single .chosen-single div b {
|
95 |
-
display: block;
|
96 |
-
width: 100%;
|
97 |
-
height: 100%;
|
98 |
-
background: url('chosen-sprite.png') no-repeat 0px 2px;
|
99 |
-
}
|
100 |
-
.chosen-container-single .chosen-search {
|
101 |
-
position: relative;
|
102 |
-
z-index: 1010;
|
103 |
-
margin: 0;
|
104 |
-
padding: 3px 4px;
|
105 |
-
white-space: nowrap;
|
106 |
-
}
|
107 |
-
.chosen-container-single .chosen-search input[type="text"] {
|
108 |
-
-webkit-box-sizing: border-box;
|
109 |
-
-moz-box-sizing: border-box;
|
110 |
-
box-sizing: border-box;
|
111 |
-
margin: 1px 0;
|
112 |
-
padding: 4px 20px 4px 5px;
|
113 |
-
width: 100%;
|
114 |
-
height: auto;
|
115 |
-
outline: 0;
|
116 |
-
border: 1px solid #aaa;
|
117 |
-
background: white url('chosen-sprite.png') no-repeat 100% -20px;
|
118 |
-
background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
|
119 |
-
background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
120 |
-
background: url('chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
121 |
-
background: url('chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
122 |
-
background: url('chosen-sprite.png') no-repeat 100% -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
|
123 |
-
font-size: 1em;
|
124 |
-
font-family: sans-serif;
|
125 |
-
line-height: normal;
|
126 |
-
border-radius: 0;
|
127 |
-
}
|
128 |
-
.chosen-container-single .chosen-drop {
|
129 |
-
margin-top: -1px;
|
130 |
-
border-radius: 0 0 4px 4px;
|
131 |
-
background-clip: padding-box;
|
132 |
-
}
|
133 |
-
.chosen-container-single.chosen-container-single-nosearch .chosen-search {
|
134 |
-
position: absolute;
|
135 |
-
left: -9999px;
|
136 |
-
}
|
137 |
-
|
138 |
-
/* @end */
|
139 |
-
/* @group Results */
|
140 |
-
.chosen-container .chosen-results {
|
141 |
-
position: relative;
|
142 |
-
overflow-x: hidden;
|
143 |
-
overflow-y: auto;
|
144 |
-
margin: 0 4px 4px 0;
|
145 |
-
padding: 0 0 0 4px;
|
146 |
-
max-height: 240px;
|
147 |
-
-webkit-overflow-scrolling: touch;
|
148 |
-
}
|
149 |
-
.chosen-container .chosen-results li {
|
150 |
-
display: none;
|
151 |
-
margin: 0;
|
152 |
-
padding: 5px 6px;
|
153 |
-
list-style: none;
|
154 |
-
line-height: 15px;
|
155 |
-
}
|
156 |
-
.chosen-container .chosen-results li.active-result {
|
157 |
-
display: list-item;
|
158 |
-
cursor: pointer;
|
159 |
-
}
|
160 |
-
.chosen-container .chosen-results li.disabled-result {
|
161 |
-
display: list-item;
|
162 |
-
color: #ccc;
|
163 |
-
cursor: default;
|
164 |
-
}
|
165 |
-
.chosen-container .chosen-results li.highlighted {
|
166 |
-
/*background-color: #3875d7;
|
167 |
-
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
|
168 |
-
background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
|
169 |
-
background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
|
170 |
-
background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
|
171 |
-
background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
|
172 |
-
color: #fff;*/
|
173 |
-
}
|
174 |
-
.chosen-container .chosen-results li.no-results {
|
175 |
-
display: list-item;
|
176 |
-
background: #f4f4f4;
|
177 |
-
}
|
178 |
-
.chosen-container .chosen-results li.group-result {
|
179 |
-
display: list-item;
|
180 |
-
font-weight: bold;
|
181 |
-
cursor: default;
|
182 |
-
}
|
183 |
-
.chosen-container .chosen-results li.group-option {
|
184 |
-
padding-left: 15px;
|
185 |
-
}
|
186 |
-
.chosen-container .chosen-results li em {
|
187 |
-
font-style: normal;
|
188 |
-
text-decoration: underline;
|
189 |
-
}
|
190 |
-
|
191 |
-
/* @end */
|
192 |
-
/* @group Multi Chosen */
|
193 |
-
.chosen-container-multi .chosen-choices {
|
194 |
-
position: relative;
|
195 |
-
overflow: hidden;
|
196 |
-
-webkit-box-sizing: border-box;
|
197 |
-
-moz-box-sizing: border-box;
|
198 |
-
box-sizing: border-box;
|
199 |
-
margin: 0;
|
200 |
-
padding: 0;
|
201 |
-
width: 100%;
|
202 |
-
height: auto !important;
|
203 |
-
height: 1%;
|
204 |
-
border: 1px solid #aaa;
|
205 |
-
background-color: #fff;
|
206 |
-
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
|
207 |
-
background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
208 |
-
background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
209 |
-
background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
210 |
-
background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
|
211 |
-
cursor: text;
|
212 |
-
}
|
213 |
-
.chosen-container-multi .chosen-choices li {
|
214 |
-
float: left;
|
215 |
-
list-style: none;
|
216 |
-
}
|
217 |
-
.chosen-container-multi .chosen-choices li.search-field {
|
218 |
-
margin: 0;
|
219 |
-
padding: 0;
|
220 |
-
white-space: nowrap;
|
221 |
-
}
|
222 |
-
.chosen-container-multi .chosen-choices li.search-field input[type="text"] {
|
223 |
-
margin: 1px 0;
|
224 |
-
padding: 5px;
|
225 |
-
height: 15px;
|
226 |
-
outline: 0;
|
227 |
-
border: 0 !important;
|
228 |
-
background: transparent !important;
|
229 |
-
box-shadow: none;
|
230 |
-
color: #666;
|
231 |
-
font-size: 100%;
|
232 |
-
font-family: sans-serif;
|
233 |
-
line-height: normal;
|
234 |
-
border-radius: 0;
|
235 |
-
}
|
236 |
-
.chosen-container-multi .chosen-choices li.search-field .default {
|
237 |
-
color: #999;
|
238 |
-
}
|
239 |
-
.chosen-container-multi .chosen-choices li.search-choice {
|
240 |
-
position: relative;
|
241 |
-
margin: 3px 0 3px 5px;
|
242 |
-
padding: 3px 20px 3px 5px;
|
243 |
-
border: 1px solid #aaa;
|
244 |
-
border-radius: 3px;
|
245 |
-
/*background-color: #e4e4e4;
|
246 |
-
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
|
247 |
-
background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
248 |
-
background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
249 |
-
background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
250 |
-
background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);*/
|
251 |
-
background-clip: padding-box;
|
252 |
-
box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
|
253 |
-
color: #333;
|
254 |
-
line-height: 13px;
|
255 |
-
cursor: default;
|
256 |
-
}
|
257 |
-
.chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
|
258 |
-
position: absolute;
|
259 |
-
top: 4px;
|
260 |
-
right: 3px;
|
261 |
-
display: block;
|
262 |
-
width: 12px;
|
263 |
-
height: 12px;
|
264 |
-
background: url('chosen-sprite.png') -42px 1px no-repeat;
|
265 |
-
font-size: 1px;
|
266 |
-
}
|
267 |
-
.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
|
268 |
-
background-position: -42px -10px;
|
269 |
-
}
|
270 |
-
.chosen-container-multi .chosen-choices li.search-choice-disabled {
|
271 |
-
padding-right: 5px;
|
272 |
-
border: 1px solid #ccc;
|
273 |
-
background-color: #e4e4e4;
|
274 |
-
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
|
275 |
-
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
276 |
-
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
277 |
-
background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
278 |
-
background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
279 |
-
color: #666;
|
280 |
-
}
|
281 |
-
.chosen-container-multi .chosen-choices li.search-choice-focus {
|
282 |
-
background: #d4d4d4;
|
283 |
-
}
|
284 |
-
.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
|
285 |
-
background-position: -42px -10px;
|
286 |
-
}
|
287 |
-
.chosen-container-multi .chosen-results {
|
288 |
-
margin: 0;
|
289 |
-
padding: 0;
|
290 |
-
}
|
291 |
-
.chosen-container-multi .chosen-drop .result-selected {
|
292 |
-
display: list-item;
|
293 |
-
color: #ccc;
|
294 |
-
cursor: default;
|
295 |
-
}
|
296 |
-
|
297 |
-
/* @end */
|
298 |
-
/* @group Active */
|
299 |
-
.chosen-container-active .chosen-single {
|
300 |
-
border: 1px solid #5897fb;
|
301 |
-
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
|
302 |
-
}
|
303 |
-
.chosen-container-active.chosen-with-drop .chosen-single {
|
304 |
-
border: 1px solid #aaa;
|
305 |
-
-moz-border-radius-bottomright: 0;
|
306 |
-
border-bottom-right-radius: 0;
|
307 |
-
-moz-border-radius-bottomleft: 0;
|
308 |
-
border-bottom-left-radius: 0;
|
309 |
-
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
|
310 |
-
background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
|
311 |
-
background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
|
312 |
-
background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
|
313 |
-
background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
|
314 |
-
box-shadow: 0 1px 0 #fff inset;
|
315 |
-
}
|
316 |
-
.chosen-container-active.chosen-with-drop .chosen-single div {
|
317 |
-
border-left: none;
|
318 |
-
background: transparent;
|
319 |
-
}
|
320 |
-
.chosen-container-active.chosen-with-drop .chosen-single div b {
|
321 |
-
background-position: -18px 2px;
|
322 |
-
}
|
323 |
-
.chosen-container-active .chosen-choices {
|
324 |
-
border: 1px solid #5897fb;
|
325 |
-
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
|
326 |
-
}
|
327 |
-
.chosen-container-active .chosen-choices li.search-field input[type="text"] {
|
328 |
-
color: #111 !important;
|
329 |
-
}
|
330 |
-
|
331 |
-
/* @end */
|
332 |
-
/* @group Disabled Support */
|
333 |
-
.chosen-disabled {
|
334 |
-
opacity: 0.5 !important;
|
335 |
-
cursor: default;
|
336 |
-
}
|
337 |
-
.chosen-disabled .chosen-single {
|
338 |
-
cursor: default;
|
339 |
-
}
|
340 |
-
.chosen-disabled .chosen-choices .search-choice .search-choice-close {
|
341 |
-
cursor: default;
|
342 |
-
}
|
343 |
-
|
344 |
-
/* @end */
|
345 |
-
/* @group Right to Left */
|
346 |
-
.chosen-rtl {
|
347 |
-
text-align: right;
|
348 |
-
}
|
349 |
-
.chosen-rtl .chosen-single {
|
350 |
-
overflow: visible;
|
351 |
-
padding: 0 8px 0 0;
|
352 |
-
}
|
353 |
-
.chosen-rtl .chosen-single span {
|
354 |
-
margin-right: 0;
|
355 |
-
margin-left: 26px;
|
356 |
-
direction: rtl;
|
357 |
-
}
|
358 |
-
.chosen-rtl .chosen-single-with-deselect span {
|
359 |
-
margin-left: 38px;
|
360 |
-
}
|
361 |
-
.chosen-rtl .chosen-single div {
|
362 |
-
right: auto;
|
363 |
-
left: 3px;
|
364 |
-
}
|
365 |
-
.chosen-rtl .chosen-single abbr {
|
366 |
-
right: auto;
|
367 |
-
left: 26px;
|
368 |
-
}
|
369 |
-
.chosen-rtl .chosen-choices li {
|
370 |
-
float: right;
|
371 |
-
}
|
372 |
-
.chosen-rtl .chosen-choices li.search-field input[type="text"] {
|
373 |
-
direction: rtl;
|
374 |
-
}
|
375 |
-
.chosen-rtl .chosen-choices li.search-choice {
|
376 |
-
margin: 3px 5px 3px 0;
|
377 |
-
padding: 3px 5px 3px 19px;
|
378 |
-
}
|
379 |
-
.chosen-rtl .chosen-choices li.search-choice .search-choice-close {
|
380 |
-
right: auto;
|
381 |
-
left: 4px;
|
382 |
-
}
|
383 |
-
.chosen-rtl.chosen-container-single-nosearch .chosen-search,
|
384 |
-
.chosen-rtl .chosen-drop {
|
385 |
-
left: 9999px;
|
386 |
-
}
|
387 |
-
.chosen-rtl.chosen-container-single .chosen-results {
|
388 |
-
margin: 0 0 4px 4px;
|
389 |
-
padding: 0 4px 0 0;
|
390 |
-
}
|
391 |
-
.chosen-rtl .chosen-results li.group-option {
|
392 |
-
padding-right: 15px;
|
393 |
-
padding-left: 0;
|
394 |
-
}
|
395 |
-
.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
|
396 |
-
border-right: none;
|
397 |
-
}
|
398 |
-
.chosen-rtl .chosen-search input[type="text"] {
|
399 |
-
padding: 4px 5px 4px 20px;
|
400 |
-
background: white url('chosen-sprite.png') no-repeat -30px -20px;
|
401 |
-
background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
|
402 |
-
background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
403 |
-
background: url('chosen-sprite.png') no-repeat -30px -20px, -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
404 |
-
background: url('chosen-sprite.png') no-repeat -30px -20px, -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
405 |
-
background: url('chosen-sprite.png') no-repeat -30px -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
|
406 |
-
direction: rtl;
|
407 |
-
}
|
408 |
-
.chosen-rtl.chosen-container-single .chosen-single div b {
|
409 |
-
background-position: 6px 2px;
|
410 |
-
}
|
411 |
-
.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
|
412 |
-
background-position: -12px 2px;
|
413 |
-
}
|
414 |
-
|
415 |
-
/* @end */
|
416 |
-
/* @group Retina compatibility */
|
417 |
-
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
|
418 |
-
.chosen-rtl .chosen-search input[type="text"],
|
419 |
-
.chosen-container-single .chosen-single abbr,
|
420 |
-
.chosen-container-single .chosen-single div b,
|
421 |
-
.chosen-container-single .chosen-search input[type="text"],
|
422 |
-
.chosen-container-multi .chosen-choices .search-choice .search-choice-close,
|
423 |
-
.chosen-container .chosen-results-scroll-down span,
|
424 |
-
.chosen-container .chosen-results-scroll-up span {
|
425 |
-
background-image: url('chosen-sprite@2x.png') !important;
|
426 |
-
background-size: 52px 37px !important;
|
427 |
-
background-repeat: no-repeat !important;
|
428 |
-
}
|
429 |
-
}
|
430 |
-
/* @end */
|
1 |
+
/* @group Base */
|
2 |
+
.chosen-container {
|
3 |
+
position: relative;
|
4 |
+
display: inline-block;
|
5 |
+
vertical-align: middle;
|
6 |
+
font-size: 13px;
|
7 |
+
zoom: 1;
|
8 |
+
*display: inline;
|
9 |
+
-webkit-user-select: none;
|
10 |
+
-moz-user-select: none;
|
11 |
+
user-select: none;
|
12 |
+
}
|
13 |
+
.chosen-container .chosen-drop {
|
14 |
+
position: absolute;
|
15 |
+
top: 100%;
|
16 |
+
left: -9999px;
|
17 |
+
z-index: 1010;
|
18 |
+
-webkit-box-sizing: border-box;
|
19 |
+
-moz-box-sizing: border-box;
|
20 |
+
box-sizing: border-box;
|
21 |
+
width: 100%;
|
22 |
+
border: 1px solid #aaa;
|
23 |
+
border-top: 0;
|
24 |
+
background: #fff;
|
25 |
+
box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
|
26 |
+
}
|
27 |
+
.chosen-container.chosen-with-drop .chosen-drop {
|
28 |
+
left: 0;
|
29 |
+
}
|
30 |
+
.chosen-container a {
|
31 |
+
cursor: pointer;
|
32 |
+
}
|
33 |
+
|
34 |
+
/* @end */
|
35 |
+
/* @group Single Chosen */
|
36 |
+
.chosen-container-single .chosen-single {
|
37 |
+
position: relative;
|
38 |
+
display: block;
|
39 |
+
overflow: hidden;
|
40 |
+
padding: 0 0 0 8px;
|
41 |
+
height: 23px;
|
42 |
+
border: 1px solid #aaa;
|
43 |
+
border-radius: 5px;
|
44 |
+
background-color: #fff;
|
45 |
+
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
|
46 |
+
background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
|
47 |
+
background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
|
48 |
+
background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
|
49 |
+
background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
|
50 |
+
background-clip: padding-box;
|
51 |
+
box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
|
52 |
+
color: #444;
|
53 |
+
text-decoration: none;
|
54 |
+
white-space: nowrap;
|
55 |
+
line-height: 24px;
|
56 |
+
}
|
57 |
+
.chosen-container-single .chosen-default {
|
58 |
+
color: #999;
|
59 |
+
}
|
60 |
+
.chosen-container-single .chosen-single span {
|
61 |
+
display: block;
|
62 |
+
overflow: hidden;
|
63 |
+
margin-right: 26px;
|
64 |
+
text-overflow: ellipsis;
|
65 |
+
white-space: nowrap;
|
66 |
+
}
|
67 |
+
.chosen-container-single .chosen-single-with-deselect span {
|
68 |
+
margin-right: 38px;
|
69 |
+
}
|
70 |
+
.chosen-container-single .chosen-single abbr {
|
71 |
+
position: absolute;
|
72 |
+
top: 6px;
|
73 |
+
right: 26px;
|
74 |
+
display: block;
|
75 |
+
width: 12px;
|
76 |
+
height: 12px;
|
77 |
+
background: url('chosen-sprite.png') -42px 1px no-repeat;
|
78 |
+
font-size: 1px;
|
79 |
+
}
|
80 |
+
.chosen-container-single .chosen-single abbr:hover {
|
81 |
+
background-position: -42px -10px;
|
82 |
+
}
|
83 |
+
.chosen-container-single.chosen-disabled .chosen-single abbr:hover {
|
84 |
+
background-position: -42px -10px;
|
85 |
+
}
|
86 |
+
.chosen-container-single .chosen-single div {
|
87 |
+
position: absolute;
|
88 |
+
top: 0;
|
89 |
+
right: 0;
|
90 |
+
display: block;
|
91 |
+
width: 18px;
|
92 |
+
height: 100%;
|
93 |
+
}
|
94 |
+
.chosen-container-single .chosen-single div b {
|
95 |
+
display: block;
|
96 |
+
width: 100%;
|
97 |
+
height: 100%;
|
98 |
+
background: url('chosen-sprite.png') no-repeat 0px 2px;
|
99 |
+
}
|
100 |
+
.chosen-container-single .chosen-search {
|
101 |
+
position: relative;
|
102 |
+
z-index: 1010;
|
103 |
+
margin: 0;
|
104 |
+
padding: 3px 4px;
|
105 |
+
white-space: nowrap;
|
106 |
+
}
|
107 |
+
.chosen-container-single .chosen-search input[type="text"] {
|
108 |
+
-webkit-box-sizing: border-box;
|
109 |
+
-moz-box-sizing: border-box;
|
110 |
+
box-sizing: border-box;
|
111 |
+
margin: 1px 0;
|
112 |
+
padding: 4px 20px 4px 5px;
|
113 |
+
width: 100%;
|
114 |
+
height: auto;
|
115 |
+
outline: 0;
|
116 |
+
border: 1px solid #aaa;
|
117 |
+
background: white url('chosen-sprite.png') no-repeat 100% -20px;
|
118 |
+
background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
|
119 |
+
background: url('chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
120 |
+
background: url('chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
121 |
+
background: url('chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
122 |
+
background: url('chosen-sprite.png') no-repeat 100% -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
|
123 |
+
font-size: 1em;
|
124 |
+
font-family: sans-serif;
|
125 |
+
line-height: normal;
|
126 |
+
border-radius: 0;
|
127 |
+
}
|
128 |
+
.chosen-container-single .chosen-drop {
|
129 |
+
margin-top: -1px;
|
130 |
+
border-radius: 0 0 4px 4px;
|
131 |
+
background-clip: padding-box;
|
132 |
+
}
|
133 |
+
.chosen-container-single.chosen-container-single-nosearch .chosen-search {
|
134 |
+
position: absolute;
|
135 |
+
left: -9999px;
|
136 |
+
}
|
137 |
+
|
138 |
+
/* @end */
|
139 |
+
/* @group Results */
|
140 |
+
.chosen-container .chosen-results {
|
141 |
+
position: relative;
|
142 |
+
overflow-x: hidden;
|
143 |
+
overflow-y: auto;
|
144 |
+
margin: 0 4px 4px 0;
|
145 |
+
padding: 0 0 0 4px;
|
146 |
+
max-height: 240px;
|
147 |
+
-webkit-overflow-scrolling: touch;
|
148 |
+
}
|
149 |
+
.chosen-container .chosen-results li {
|
150 |
+
display: none;
|
151 |
+
margin: 0;
|
152 |
+
padding: 5px 6px;
|
153 |
+
list-style: none;
|
154 |
+
line-height: 15px;
|
155 |
+
}
|
156 |
+
.chosen-container .chosen-results li.active-result {
|
157 |
+
display: list-item;
|
158 |
+
cursor: pointer;
|
159 |
+
}
|
160 |
+
.chosen-container .chosen-results li.disabled-result {
|
161 |
+
display: list-item;
|
162 |
+
color: #ccc;
|
163 |
+
cursor: default;
|
164 |
+
}
|
165 |
+
.chosen-container .chosen-results li.highlighted {
|
166 |
+
/*background-color: #3875d7;
|
167 |
+
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
|
168 |
+
background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
|
169 |
+
background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
|
170 |
+
background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
|
171 |
+
background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
|
172 |
+
color: #fff;*/
|
173 |
+
}
|
174 |
+
.chosen-container .chosen-results li.no-results {
|
175 |
+
display: list-item;
|
176 |
+
background: #f4f4f4;
|
177 |
+
}
|
178 |
+
.chosen-container .chosen-results li.group-result {
|
179 |
+
display: list-item;
|
180 |
+
font-weight: bold;
|
181 |
+
cursor: default;
|
182 |
+
}
|
183 |
+
.chosen-container .chosen-results li.group-option {
|
184 |
+
padding-left: 15px;
|
185 |
+
}
|
186 |
+
.chosen-container .chosen-results li em {
|
187 |
+
font-style: normal;
|
188 |
+
text-decoration: underline;
|
189 |
+
}
|
190 |
+
|
191 |
+
/* @end */
|
192 |
+
/* @group Multi Chosen */
|
193 |
+
.chosen-container-multi .chosen-choices {
|
194 |
+
position: relative;
|
195 |
+
overflow: hidden;
|
196 |
+
-webkit-box-sizing: border-box;
|
197 |
+
-moz-box-sizing: border-box;
|
198 |
+
box-sizing: border-box;
|
199 |
+
margin: 0;
|
200 |
+
padding: 0;
|
201 |
+
width: 100%;
|
202 |
+
height: auto !important;
|
203 |
+
height: 1%;
|
204 |
+
border: 1px solid #aaa;
|
205 |
+
background-color: #fff;
|
206 |
+
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
|
207 |
+
background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
208 |
+
background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
209 |
+
background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
210 |
+
background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
|
211 |
+
cursor: text;
|
212 |
+
}
|
213 |
+
.chosen-container-multi .chosen-choices li {
|
214 |
+
float: left;
|
215 |
+
list-style: none;
|
216 |
+
}
|
217 |
+
.chosen-container-multi .chosen-choices li.search-field {
|
218 |
+
margin: 0;
|
219 |
+
padding: 0;
|
220 |
+
white-space: nowrap;
|
221 |
+
}
|
222 |
+
.chosen-container-multi .chosen-choices li.search-field input[type="text"] {
|
223 |
+
margin: 1px 0;
|
224 |
+
padding: 5px;
|
225 |
+
height: 15px;
|
226 |
+
outline: 0;
|
227 |
+
border: 0 !important;
|
228 |
+
background: transparent !important;
|
229 |
+
box-shadow: none;
|
230 |
+
color: #666;
|
231 |
+
font-size: 100%;
|
232 |
+
font-family: sans-serif;
|
233 |
+
line-height: normal;
|
234 |
+
border-radius: 0;
|
235 |
+
}
|
236 |
+
.chosen-container-multi .chosen-choices li.search-field .default {
|
237 |
+
color: #999;
|
238 |
+
}
|
239 |
+
.chosen-container-multi .chosen-choices li.search-choice {
|
240 |
+
position: relative;
|
241 |
+
margin: 3px 0 3px 5px;
|
242 |
+
padding: 3px 20px 3px 5px;
|
243 |
+
border: 1px solid #aaa;
|
244 |
+
border-radius: 3px;
|
245 |
+
/*background-color: #e4e4e4;
|
246 |
+
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
|
247 |
+
background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
248 |
+
background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
249 |
+
background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
250 |
+
background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);*/
|
251 |
+
background-clip: padding-box;
|
252 |
+
box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
|
253 |
+
color: #333;
|
254 |
+
line-height: 13px;
|
255 |
+
cursor: default;
|
256 |
+
}
|
257 |
+
.chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
|
258 |
+
position: absolute;
|
259 |
+
top: 4px;
|
260 |
+
right: 3px;
|
261 |
+
display: block;
|
262 |
+
width: 12px;
|
263 |
+
height: 12px;
|
264 |
+
background: url('chosen-sprite.png') -42px 1px no-repeat;
|
265 |
+
font-size: 1px;
|
266 |
+
}
|
267 |
+
.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
|
268 |
+
background-position: -42px -10px;
|
269 |
+
}
|
270 |
+
.chosen-container-multi .chosen-choices li.search-choice-disabled {
|
271 |
+
padding-right: 5px;
|
272 |
+
border: 1px solid #ccc;
|
273 |
+
background-color: #e4e4e4;
|
274 |
+
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
|
275 |
+
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
276 |
+
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
277 |
+
background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
278 |
+
background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
|
279 |
+
color: #666;
|
280 |
+
}
|
281 |
+
.chosen-container-multi .chosen-choices li.search-choice-focus {
|
282 |
+
background: #d4d4d4;
|
283 |
+
}
|
284 |
+
.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
|
285 |
+
background-position: -42px -10px;
|
286 |
+
}
|
287 |
+
.chosen-container-multi .chosen-results {
|
288 |
+
margin: 0;
|
289 |
+
padding: 0;
|
290 |
+
}
|
291 |
+
.chosen-container-multi .chosen-drop .result-selected {
|
292 |
+
display: list-item;
|
293 |
+
color: #ccc;
|
294 |
+
cursor: default;
|
295 |
+
}
|
296 |
+
|
297 |
+
/* @end */
|
298 |
+
/* @group Active */
|
299 |
+
.chosen-container-active .chosen-single {
|
300 |
+
border: 1px solid #5897fb;
|
301 |
+
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
|
302 |
+
}
|
303 |
+
.chosen-container-active.chosen-with-drop .chosen-single {
|
304 |
+
border: 1px solid #aaa;
|
305 |
+
-moz-border-radius-bottomright: 0;
|
306 |
+
border-bottom-right-radius: 0;
|
307 |
+
-moz-border-radius-bottomleft: 0;
|
308 |
+
border-bottom-left-radius: 0;
|
309 |
+
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
|
310 |
+
background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
|
311 |
+
background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
|
312 |
+
background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
|
313 |
+
background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
|
314 |
+
box-shadow: 0 1px 0 #fff inset;
|
315 |
+
}
|
316 |
+
.chosen-container-active.chosen-with-drop .chosen-single div {
|
317 |
+
border-left: none;
|
318 |
+
background: transparent;
|
319 |
+
}
|
320 |
+
.chosen-container-active.chosen-with-drop .chosen-single div b {
|
321 |
+
background-position: -18px 2px;
|
322 |
+
}
|
323 |
+
.chosen-container-active .chosen-choices {
|
324 |
+
border: 1px solid #5897fb;
|
325 |
+
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
|
326 |
+
}
|
327 |
+
.chosen-container-active .chosen-choices li.search-field input[type="text"] {
|
328 |
+
color: #111 !important;
|
329 |
+
}
|
330 |
+
|
331 |
+
/* @end */
|
332 |
+
/* @group Disabled Support */
|
333 |
+
.chosen-disabled {
|
334 |
+
opacity: 0.5 !important;
|
335 |
+
cursor: default;
|
336 |
+
}
|
337 |
+
.chosen-disabled .chosen-single {
|
338 |
+
cursor: default;
|
339 |
+
}
|
340 |
+
.chosen-disabled .chosen-choices .search-choice .search-choice-close {
|
341 |
+
cursor: default;
|
342 |
+
}
|
343 |
+
|
344 |
+
/* @end */
|
345 |
+
/* @group Right to Left */
|
346 |
+
.chosen-rtl {
|
347 |
+
text-align: right;
|
348 |
+
}
|
349 |
+
.chosen-rtl .chosen-single {
|
350 |
+
overflow: visible;
|
351 |
+
padding: 0 8px 0 0;
|
352 |
+
}
|
353 |
+
.chosen-rtl .chosen-single span {
|
354 |
+
margin-right: 0;
|
355 |
+
margin-left: 26px;
|
356 |
+
direction: rtl;
|
357 |
+
}
|
358 |
+
.chosen-rtl .chosen-single-with-deselect span {
|
359 |
+
margin-left: 38px;
|
360 |
+
}
|
361 |
+
.chosen-rtl .chosen-single div {
|
362 |
+
right: auto;
|
363 |
+
left: 3px;
|
364 |
+
}
|
365 |
+
.chosen-rtl .chosen-single abbr {
|
366 |
+
right: auto;
|
367 |
+
left: 26px;
|
368 |
+
}
|
369 |
+
.chosen-rtl .chosen-choices li {
|
370 |
+
float: right;
|
371 |
+
}
|
372 |
+
.chosen-rtl .chosen-choices li.search-field input[type="text"] {
|
373 |
+
direction: rtl;
|
374 |
+
}
|
375 |
+
.chosen-rtl .chosen-choices li.search-choice {
|
376 |
+
margin: 3px 5px 3px 0;
|
377 |
+
padding: 3px 5px 3px 19px;
|
378 |
+
}
|
379 |
+
.chosen-rtl .chosen-choices li.search-choice .search-choice-close {
|
380 |
+
right: auto;
|
381 |
+
left: 4px;
|
382 |
+
}
|
383 |
+
.chosen-rtl.chosen-container-single-nosearch .chosen-search,
|
384 |
+
.chosen-rtl .chosen-drop {
|
385 |
+
left: 9999px;
|
386 |
+
}
|
387 |
+
.chosen-rtl.chosen-container-single .chosen-results {
|
388 |
+
margin: 0 0 4px 4px;
|
389 |
+
padding: 0 4px 0 0;
|
390 |
+
}
|
391 |
+
.chosen-rtl .chosen-results li.group-option {
|
392 |
+
padding-right: 15px;
|
393 |
+
padding-left: 0;
|
394 |
+
}
|
395 |
+
.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
|
396 |
+
border-right: none;
|
397 |
+
}
|
398 |
+
.chosen-rtl .chosen-search input[type="text"] {
|
399 |
+
padding: 4px 5px 4px 20px;
|
400 |
+
background: white url('chosen-sprite.png') no-repeat -30px -20px;
|
401 |
+
background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
|
402 |
+
background: url('chosen-sprite.png') no-repeat -30px -20px, -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
403 |
+
background: url('chosen-sprite.png') no-repeat -30px -20px, -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
404 |
+
background: url('chosen-sprite.png') no-repeat -30px -20px, -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
|
405 |
+
background: url('chosen-sprite.png') no-repeat -30px -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
|
406 |
+
direction: rtl;
|
407 |
+
}
|
408 |
+
.chosen-rtl.chosen-container-single .chosen-single div b {
|
409 |
+
background-position: 6px 2px;
|
410 |
+
}
|
411 |
+
.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
|
412 |
+
background-position: -12px 2px;
|
413 |
+
}
|
414 |
+
|
415 |
+
/* @end */
|
416 |
+
/* @group Retina compatibility */
|
417 |
+
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
|
418 |
+
.chosen-rtl .chosen-search input[type="text"],
|
419 |
+
.chosen-container-single .chosen-single abbr,
|
420 |
+
.chosen-container-single .chosen-single div b,
|
421 |
+
.chosen-container-single .chosen-search input[type="text"],
|
422 |
+
.chosen-container-multi .chosen-choices .search-choice .search-choice-close,
|
423 |
+
.chosen-container .chosen-results-scroll-down span,
|
424 |
+
.chosen-container .chosen-results-scroll-up span {
|
425 |
+
background-image: url('chosen-sprite@2x.png') !important;
|
426 |
+
background-size: 52px 37px !important;
|
427 |
+
background-repeat: no-repeat !important;
|
428 |
+
}
|
429 |
+
}
|
430 |
+
/* @end */
|
classes/styles-font-menu/js/chosen/chosen.jquery.js
CHANGED
@@ -1,1166 +1,1166 @@
|
|
1 |
-
// Chosen, a Select Box Enhancer for jQuery and Prototype
|
2 |
-
// by Patrick Filler for Harvest, http://getharvest.com
|
3 |
-
//
|
4 |
-
// Version 1.0.0
|
5 |
-
// Full source at https://github.com/harvesthq/chosen
|
6 |
-
// Copyright (c) 2011 Harvest http://getharvest.com
|
7 |
-
|
8 |
-
// MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
|
9 |
-
// This file is generated by `grunt build`, do not edit it by hand.
|
10 |
-
(function() {
|
11 |
-
var $, AbstractChosen, Chosen, SelectParser, _ref,
|
12 |
-
__hasProp = {}.hasOwnProperty,
|
13 |
-
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
14 |
-
|
15 |
-
SelectParser = (function() {
|
16 |
-
function SelectParser() {
|
17 |
-
this.options_index = 0;
|
18 |
-
this.parsed = [];
|
19 |
-
}
|
20 |
-
|
21 |
-
SelectParser.prototype.add_node = function(child) {
|
22 |
-
if (child.nodeName.toUpperCase() === "OPTGROUP") {
|
23 |
-
return this.add_group(child);
|
24 |
-
} else {
|
25 |
-
return this.add_option(child);
|
26 |
-
}
|
27 |
-
};
|
28 |
-
|
29 |
-
SelectParser.prototype.add_group = function(group) {
|
30 |
-
var group_position, option, _i, _len, _ref, _results;
|
31 |
-
|
32 |
-
group_position = this.parsed.length;
|
33 |
-
this.parsed.push({
|
34 |
-
array_index: group_position,
|
35 |
-
group: true,
|
36 |
-
label: this.escapeExpression(group.label),
|
37 |
-
children: 0,
|
38 |
-
disabled: group.disabled
|
39 |
-
});
|
40 |
-
_ref = group.childNodes;
|
41 |
-
_results = [];
|
42 |
-
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
43 |
-
option = _ref[_i];
|
44 |
-
_results.push(this.add_option(option, group_position, group.disabled));
|
45 |
-
}
|
46 |
-
return _results;
|
47 |
-
};
|
48 |
-
|
49 |
-
SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
|
50 |
-
if (option.nodeName.toUpperCase() === "OPTION") {
|
51 |
-
if (option.text !== "") {
|
52 |
-
if (group_position != null) {
|
53 |
-
this.parsed[group_position].children += 1;
|
54 |
-
}
|
55 |
-
this.parsed.push({
|
56 |
-
array_index: this.parsed.length,
|
57 |
-
options_index: this.options_index,
|
58 |
-
value: option.value,
|
59 |
-
text: option.text,
|
60 |
-
html: option.innerHTML,
|
61 |
-
selected: option.selected,
|
62 |
-
disabled: group_disabled === true ? group_disabled : option.disabled,
|
63 |
-
group_array_index: group_position,
|
64 |
-
classes: option.className,
|
65 |
-
style: option.style.cssText
|
66 |
-
});
|
67 |
-
} else {
|
68 |
-
this.parsed.push({
|
69 |
-
array_index: this.parsed.length,
|
70 |
-
options_index: this.options_index,
|
71 |
-
empty: true
|
72 |
-
});
|
73 |
-
}
|
74 |
-
return this.options_index += 1;
|
75 |
-
}
|
76 |
-
};
|
77 |
-
|
78 |
-
SelectParser.prototype.escapeExpression = function(text) {
|
79 |
-
var map, unsafe_chars;
|
80 |
-
|
81 |
-
if ((text == null) || text === false) {
|
82 |
-
return "";
|
83 |
-
}
|
84 |
-
if (!/[\&\<\>\"\'\`]/.test(text)) {
|
85 |
-
return text;
|
86 |
-
}
|
87 |
-
map = {
|
88 |
-
"<": "<",
|
89 |
-
">": ">",
|
90 |
-
'"': """,
|
91 |
-
"'": "'",
|
92 |
-
"`": "`"
|
93 |
-
};
|
94 |
-
unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
|
95 |
-
return text.replace(unsafe_chars, function(chr) {
|
96 |
-
return map[chr] || "&";
|
97 |
-
});
|
98 |
-
};
|
99 |
-
|
100 |
-
return SelectParser;
|
101 |
-
|
102 |
-
})();
|
103 |
-
|
104 |
-
SelectParser.select_to_array = function(select) {
|
105 |
-
var child, parser, _i, _len, _ref;
|
106 |
-
|
107 |
-
parser = new SelectParser();
|
108 |
-
_ref = select.childNodes;
|
109 |
-
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
110 |
-
child = _ref[_i];
|
111 |
-
parser.add_node(child);
|
112 |
-
}
|
113 |
-
return parser.parsed;
|
114 |
-
};
|
115 |
-
|
116 |
-
AbstractChosen = (function() {
|
117 |
-
function AbstractChosen(form_field, options) {
|
118 |
-
this.form_field = form_field;
|
119 |
-
this.options = options != null ? options : {};
|
120 |
-
if (!AbstractChosen.browser_is_supported()) {
|
121 |
-
return;
|
122 |
-
}
|
123 |
-
this.is_multiple = this.form_field.multiple;
|
124 |
-
this.set_default_text();
|
125 |
-
this.set_default_values();
|
126 |
-
this.setup();
|
127 |
-
this.set_up_html();
|
128 |
-
this.register_observers();
|
129 |
-
}
|
130 |
-
|
131 |
-
AbstractChosen.prototype.set_default_values = function() {
|
132 |
-
var _this = this;
|
133 |
-
|
134 |
-
this.click_test_action = function(evt) {
|
135 |
-
return _this.test_active_click(evt);
|
136 |
-
};
|
137 |
-
this.activate_action = function(evt) {
|
138 |
-
return _this.activate_field(evt);
|
139 |
-
};
|
140 |
-
this.active_field = false;
|
141 |
-
this.mouse_on_container = false;
|
142 |
-
this.results_showing = false;
|
143 |
-
this.result_highlighted = null;
|
144 |
-
this.result_single_selected = null;
|
145 |
-
this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
|
146 |
-
this.disable_search_threshold = this.options.disable_search_threshold || 0;
|
147 |
-
this.disable_search = this.options.disable_search || false;
|
148 |
-
this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
|
149 |
-
this.group_search = this.options.group_search != null ? this.options.group_search : true;
|
150 |
-
this.search_contains = this.options.search_contains || false;
|
151 |
-
this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
|
152 |
-
this.max_selected_options = this.options.max_selected_options || Infinity;
|
153 |
-
this.inherit_select_classes = this.options.inherit_select_classes || false;
|
154 |
-
this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
|
155 |
-
return this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
|
156 |
-
};
|
157 |
-
|
158 |
-
AbstractChosen.prototype.set_default_text = function() {
|
159 |
-
if (this.form_field.getAttribute("data-placeholder")) {
|
160 |
-
this.default_text = this.form_field.getAttribute("data-placeholder");
|
161 |
-
} else if (this.is_multiple) {
|
162 |
-
this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
|
163 |
-
} else {
|
164 |
-
this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
|
165 |
-
}
|
166 |
-
return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
|
167 |
-
};
|
168 |
-
|
169 |
-
AbstractChosen.prototype.mouse_enter = function() {
|
170 |
-
return this.mouse_on_container = true;
|
171 |
-
};
|
172 |
-
|
173 |
-
AbstractChosen.prototype.mouse_leave = function() {
|
174 |
-
return this.mouse_on_container = false;
|
175 |
-
};
|
176 |
-
|
177 |
-
AbstractChosen.prototype.input_focus = function(evt) {
|
178 |
-
var _this = this;
|
179 |
-
|
180 |
-
if (this.is_multiple) {
|
181 |
-
if (!this.active_field) {
|
182 |
-
return setTimeout((function() {
|
183 |
-
return _this.container_mousedown();
|
184 |
-
}), 50);
|
185 |
-
}
|
186 |
-
} else {
|
187 |
-
if (!this.active_field) {
|
188 |
-
return this.activate_field();
|
189 |
-
}
|
190 |
-
}
|
191 |
-
};
|
192 |
-
|
193 |
-
AbstractChosen.prototype.input_blur = function(evt) {
|
194 |
-
var _this = this;
|
195 |
-
|
196 |
-
if (!this.mouse_on_container) {
|
197 |
-
this.active_field = false;
|
198 |
-
return setTimeout((function() {
|
199 |
-
return _this.blur_test();
|
200 |
-
}), 100);
|
201 |
-
}
|
202 |
-
};
|
203 |
-
|
204 |
-
AbstractChosen.prototype.results_option_build = function(options) {
|
205 |
-
var content, data, _i, _len, _ref;
|
206 |
-
|
207 |
-
content = '';
|
208 |
-
_ref = this.results_data;
|
209 |
-
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
210 |
-
data = _ref[_i];
|
211 |
-
if (data.group) {
|
212 |
-
content += this.result_add_group(data);
|
213 |
-
} else {
|
214 |
-
content += this.result_add_option(data);
|
215 |
-
}
|
216 |
-
if (options != null ? options.first : void 0) {
|
217 |
-
if (data.selected && this.is_multiple) {
|
218 |
-
this.choice_build(data);
|
219 |
-
} else if (data.selected && !this.is_multiple) {
|
220 |
-
this.single_set_selected_text(data.text);
|
221 |
-
}
|
222 |
-
}
|
223 |
-
}
|
224 |
-
return content;
|
225 |
-
};
|
226 |
-
|
227 |
-
AbstractChosen.prototype.result_add_option = function(option) {
|
228 |
-
var classes, style;
|
229 |
-
|
230 |
-
if (!option.search_match) {
|
231 |
-
return '';
|
232 |
-
}
|
233 |
-
if (!this.include_option_in_results(option)) {
|
234 |
-
return '';
|
235 |
-
}
|
236 |
-
classes = [];
|
237 |
-
if (!option.disabled && !(option.selected && this.is_multiple)) {
|
238 |
-
classes.push("active-result");
|
239 |
-
}
|
240 |
-
if (option.disabled && !(option.selected && this.is_multiple)) {
|
241 |
-
classes.push("disabled-result");
|
242 |
-
}
|
243 |
-
if (option.selected) {
|
244 |
-
classes.push("result-selected");
|
245 |
-
}
|
246 |
-
if (option.group_array_index != null) {
|
247 |
-
classes.push("group-option");
|
248 |
-
}
|
249 |
-
if (option.classes !== "") {
|
250 |
-
classes.push(option.classes);
|
251 |
-
}
|
252 |
-
style = option.style.cssText !== "" ? " style=\"" + option.style + "\"" : "";
|
253 |
-
return "<li class=\"" + (classes.join(' ')) + "\"" + style + " data-option-array-index=\"" + option.array_index + "\">" + option.search_text + "</li>";
|
254 |
-
};
|
255 |
-
|
256 |
-
AbstractChosen.prototype.result_add_group = function(group) {
|
257 |
-
if (!(group.search_match || group.group_match)) {
|
258 |
-
return '';
|
259 |
-
}
|
260 |
-
if (!(group.active_options > 0)) {
|
261 |
-
return '';
|
262 |
-
}
|
263 |
-
return "<li class=\"group-result\">" + group.search_text + "</li>";
|
264 |
-
};
|
265 |
-
|
266 |
-
AbstractChosen.prototype.results_update_field = function() {
|
267 |
-
this.set_default_text();
|
268 |
-
if (!this.is_multiple) {
|
269 |
-
this.results_reset_cleanup();
|
270 |
-
}
|
271 |
-
this.result_clear_highlight();
|
272 |
-
this.result_single_selected = null;
|
273 |
-
this.results_build();
|
274 |
-
if (this.results_showing) {
|
275 |
-
return this.winnow_results();
|
276 |
-
}
|
277 |
-
};
|
278 |
-
|
279 |
-
AbstractChosen.prototype.results_toggle = function() {
|
280 |
-
if (this.results_showing) {
|
281 |
-
return this.results_hide();
|
282 |
-
} else {
|
283 |
-
return this.results_show();
|
284 |
-
}
|
285 |
-
};
|
286 |
-
|
287 |
-
AbstractChosen.prototype.results_search = function(evt) {
|
288 |
-
if (this.results_showing) {
|
289 |
-
return this.winnow_results();
|
290 |
-
} else {
|
291 |
-
return this.results_show();
|
292 |
-
}
|
293 |
-
};
|
294 |
-
|
295 |
-
AbstractChosen.prototype.winnow_results = function() {
|
296 |
-
var escapedSearchText, option, regex, regexAnchor, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
|
297 |
-
|
298 |
-
this.no_results_clear();
|
299 |
-
results = 0;
|
300 |
-
searchText = this.get_search_text();
|
301 |
-
escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
302 |
-
regexAnchor = this.search_contains ? "" : "^";
|
303 |
-
regex = new RegExp(regexAnchor + escapedSearchText, 'i');
|
304 |
-
zregex = new RegExp(escapedSearchText, 'i');
|
305 |
-
_ref = this.results_data;
|
306 |
-
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
307 |
-
option = _ref[_i];
|
308 |
-
option.search_match = false;
|
309 |
-
results_group = null;
|
310 |
-
if (this.include_option_in_results(option)) {
|
311 |
-
if (option.group) {
|
312 |
-
option.group_match = false;
|
313 |
-
option.active_options = 0;
|
314 |
-
}
|
315 |
-
if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
|
316 |
-
results_group = this.results_data[option.group_array_index];
|
317 |
-
if (results_group.active_options === 0 && results_group.search_match) {
|
318 |
-
results += 1;
|
319 |
-
}
|
320 |
-
results_group.active_options += 1;
|
321 |
-
}
|
322 |
-
if (!(option.group && !this.group_search)) {
|
323 |
-
option.search_text = option.group ? option.label : option.html;
|
324 |
-
option.search_match = this.search_string_match(option.search_text, regex);
|
325 |
-
if (option.search_match && !option.group) {
|
326 |
-
results += 1;
|
327 |
-
}
|
328 |
-
if (option.search_match) {
|
329 |
-
if (searchText.length) {
|
330 |
-
startpos = option.search_text.search(zregex);
|
331 |
-
text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
|
332 |
-
option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
|
333 |
-
}
|
334 |
-
if (results_group != null) {
|
335 |
-
results_group.group_match = true;
|
336 |
-
}
|
337 |
-
} else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
|
338 |
-
option.search_match = true;
|
339 |
-
}
|
340 |
-
}
|
341 |
-
}
|
342 |
-
}
|
343 |
-
this.result_clear_highlight();
|
344 |
-
if (results < 1 && searchText.length) {
|
345 |
-
this.update_results_content("");
|
346 |
-
return this.no_results(searchText);
|
347 |
-
} else {
|
348 |
-
this.update_results_content(this.results_option_build());
|
349 |
-
return this.winnow_results_set_highlight();
|
350 |
-
}
|
351 |
-
};
|
352 |
-
|
353 |
-
AbstractChosen.prototype.search_string_match = function(search_string, regex) {
|
354 |
-
var part, parts, _i, _len;
|
355 |
-
|
356 |
-
if (regex.test(search_string)) {
|
357 |
-
return true;
|
358 |
-
} else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
|
359 |
-
parts = search_string.replace(/\[|\]/g, "").split(" ");
|
360 |
-
if (parts.length) {
|
361 |
-
for (_i = 0, _len = parts.length; _i < _len; _i++) {
|
362 |
-
part = parts[_i];
|
363 |
-
if (regex.test(part)) {
|
364 |
-
return true;
|
365 |
-
}
|
366 |
-
}
|
367 |
-
}
|
368 |
-
}
|
369 |
-
};
|
370 |
-
|
371 |
-
AbstractChosen.prototype.choices_count = function() {
|
372 |
-
var option, _i, _len, _ref;
|
373 |
-
|
374 |
-
if (this.selected_option_count != null) {
|
375 |
-
return this.selected_option_count;
|
376 |
-
}
|
377 |
-
this.selected_option_count = 0;
|
378 |
-
_ref = this.form_field.options;
|
379 |
-
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
380 |
-
option = _ref[_i];
|
381 |
-
if (option.selected) {
|
382 |
-
this.selected_option_count += 1;
|
383 |
-
}
|
384 |
-
}
|
385 |
-
return this.selected_option_count;
|
386 |
-
};
|
387 |
-
|
388 |
-
AbstractChosen.prototype.choices_click = function(evt) {
|
389 |
-
evt.preventDefault();
|
390 |
-
if (!(this.results_showing || this.is_disabled)) {
|
391 |
-
return this.results_show();
|
392 |
-
}
|
393 |
-
};
|
394 |
-
|
395 |
-
AbstractChosen.prototype.keyup_checker = function(evt) {
|
396 |
-
var stroke, _ref;
|
397 |
-
|
398 |
-
stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
|
399 |
-
this.search_field_scale();
|
400 |
-
switch (stroke) {
|
401 |
-
case 8:
|
402 |
-
if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
|
403 |
-
return this.keydown_backstroke();
|
404 |
-
} else if (!this.pending_backstroke) {
|
405 |
-
this.result_clear_highlight();
|
406 |
-
return this.results_search();
|
407 |
-
}
|
408 |
-
break;
|
409 |
-
case 13:
|
410 |
-
evt.preventDefault();
|
411 |
-
if (this.results_showing) {
|
412 |
-
return this.result_select(evt);
|
413 |
-
}
|
414 |
-
break;
|
415 |
-
case 27:
|
416 |
-
if (this.results_showing) {
|
417 |
-
this.results_hide();
|
418 |
-
}
|
419 |
-
return true;
|
420 |
-
case 9:
|
421 |
-
case 38:
|
422 |
-
case 40:
|
423 |
-
case 16:
|
424 |
-
case 91:
|
425 |
-
case 17:
|
426 |
-
break;
|
427 |
-
default:
|
428 |
-
return this.results_search();
|
429 |
-
}
|
430 |
-
};
|
431 |
-
|
432 |
-
AbstractChosen.prototype.container_width = function() {
|
433 |
-
if (this.options.width != null) {
|
434 |
-
return this.options.width;
|
435 |
-
} else {
|
436 |
-
return "" + this.form_field.offsetWidth + "px";
|
437 |
-
}
|
438 |
-
};
|
439 |
-
|
440 |
-
AbstractChosen.prototype.include_option_in_results = function(option) {
|
441 |
-
if (this.is_multiple && (!this.display_selected_options && option.selected)) {
|
442 |
-
return false;
|
443 |
-
}
|
444 |
-
if (!this.display_disabled_options && option.disabled) {
|
445 |
-
return false;
|
446 |
-
}
|
447 |
-
if (option.empty) {
|
448 |
-
return false;
|
449 |
-
}
|
450 |
-
return true;
|
451 |
-
};
|
452 |
-
|
453 |
-
AbstractChosen.browser_is_supported = function() {
|
454 |
-
if (window.navigator.appName === "Microsoft Internet Explorer") {
|
455 |
-
return document.documentMode >= 8;
|
456 |
-
}
|
457 |
-
if (/iP(od|hone)/i.test(window.navigator.userAgent)) {
|
458 |
-
return false;
|
459 |
-
}
|
460 |
-
if (/Android/i.test(window.navigator.userAgent)) {
|
461 |
-
if (/Mobile/i.test(window.navigator.userAgent)) {
|
462 |
-
return false;
|
463 |
-
}
|
464 |
-
}
|
465 |
-
return true;
|
466 |
-
};
|
467 |
-
|
468 |
-
AbstractChosen.default_multiple_text = "Select Some Options";
|
469 |
-
|
470 |
-
AbstractChosen.default_single_text = "Select an Option";
|
471 |
-
|
472 |
-
AbstractChosen.default_no_result_text = "No results match";
|
473 |
-
|
474 |
-
return AbstractChosen;
|
475 |
-
|
476 |
-
})();
|
477 |
-
|
478 |
-
$ = jQuery;
|
479 |
-
|
480 |
-
$.fn.extend({
|
481 |
-
chosen: function(options) {
|
482 |
-
if (!AbstractChosen.browser_is_supported()) {
|
483 |
-
return this;
|
484 |
-
}
|
485 |
-
return this.each(function(input_field) {
|
486 |
-
var $this, chosen;
|
487 |
-
|
488 |
-
$this = $(this);
|
489 |
-
chosen = $this.data('chosen');
|
490 |
-
if (options === 'destroy' && chosen) {
|
491 |
-
chosen.destroy();
|
492 |
-
} else if (!chosen) {
|
493 |
-
$this.data('chosen', new Chosen(this, options));
|
494 |
-
}
|
495 |
-
});
|
496 |
-
}
|
497 |
-
});
|
498 |
-
|
499 |
-
Chosen = (function(_super) {
|
500 |
-
__extends(Chosen, _super);
|
501 |
-
|
502 |
-
function Chosen() {
|
503 |
-
_ref = Chosen.__super__.constructor.apply(this, arguments);
|
504 |
-
return _ref;
|
505 |
-
}
|
506 |
-
|
507 |
-
Chosen.prototype.setup = function() {
|
508 |
-
this.form_field_jq = $(this.form_field);
|
509 |
-
this.current_selectedIndex = this.form_field.selectedIndex;
|
510 |
-
return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl");
|
511 |
-
};
|
512 |
-
|
513 |
-
Chosen.prototype.set_up_html = function() {
|
514 |
-
var container_classes, container_props;
|
515 |
-
|
516 |
-
container_classes = ["chosen-container"];
|
517 |
-
container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
|
518 |
-
if (this.inherit_select_classes && this.form_field.className) {
|
519 |
-
container_classes.push(this.form_field.className);
|
520 |
-
}
|
521 |
-
if (this.is_rtl) {
|
522 |
-
container_classes.push("chosen-rtl");
|
523 |
-
}
|
524 |
-
container_props = {
|
525 |
-
'class': container_classes.join(' '),
|
526 |
-
'style': "width: " + (this.container_width()) + ";",
|
527 |
-
'title': this.form_field.title
|
528 |
-
};
|
529 |
-
if (this.form_field.id.length) {
|
530 |
-
container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
|
531 |
-
}
|
532 |
-
this.container = $("<div />", container_props);
|
533 |
-
if (this.is_multiple) {
|
534 |
-
this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>');
|
535 |
-
} else {
|
536 |
-
this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>');
|
537 |
-
}
|
538 |
-
this.form_field_jq.hide().after(this.container);
|
539 |
-
this.dropdown = this.container.find('div.chosen-drop').first();
|
540 |
-
this.search_field = this.container.find('input').first();
|
541 |
-
this.search_results = this.container.find('ul.chosen-results').first();
|
542 |
-
this.search_field_scale();
|
543 |
-
this.search_no_results = this.container.find('li.no-results').first();
|
544 |
-
if (this.is_multiple) {
|
545 |
-
this.search_choices = this.container.find('ul.chosen-choices').first();
|
546 |
-
this.search_container = this.container.find('li.search-field').first();
|
547 |
-
} else {
|
548 |
-
this.search_container = this.container.find('div.chosen-search').first();
|
549 |
-
this.selected_item = this.container.find('.chosen-single').first();
|
550 |
-
}
|
551 |
-
this.results_build();
|
552 |
-
this.set_tab_index();
|
553 |
-
this.set_label_behavior();
|
554 |
-
return this.form_field_jq.trigger("chosen:ready", {
|
555 |
-
chosen: this
|
556 |
-
});
|
557 |
-
};
|
558 |
-
|
559 |
-
Chosen.prototype.register_observers = function() {
|
560 |
-
var _this = this;
|
561 |
-
|
562 |
-
this.container.bind('mousedown.chosen', function(evt) {
|
563 |
-
_this.container_mousedown(evt);
|
564 |
-
});
|
565 |
-
this.container.bind('mouseup.chosen', function(evt) {
|
566 |
-
_this.container_mouseup(evt);
|
567 |
-
});
|
568 |
-
this.container.bind('mouseenter.chosen', function(evt) {
|
569 |
-
_this.mouse_enter(evt);
|
570 |
-
});
|
571 |
-
this.container.bind('mouseleave.chosen', function(evt) {
|
572 |
-
_this.mouse_leave(evt);
|
573 |
-
});
|
574 |
-
this.search_results.bind('mouseup.chosen', function(evt) {
|
575 |
-
_this.search_results_mouseup(evt);
|
576 |
-
});
|
577 |
-
this.search_results.bind('mouseover.chosen', function(evt) {
|
578 |
-
_this.search_results_mouseover(evt);
|
579 |
-
});
|
580 |
-
this.search_results.bind('mouseout.chosen', function(evt) {
|
581 |
-
_this.search_results_mouseout(evt);
|
582 |
-
});
|
583 |
-
this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
|
584 |
-
_this.search_results_mousewheel(evt);
|
585 |
-
});
|
586 |
-
this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
|
587 |
-
_this.results_update_field(evt);
|
588 |
-
});
|
589 |
-
this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
|
590 |
-
_this.activate_field(evt);
|
591 |
-
});
|
592 |
-
this.form_field_jq.bind("chosen:open.chosen", function(evt) {
|
593 |
-
_this.container_mousedown(evt);
|
594 |
-
});
|
595 |
-
this.search_field.bind('blur.chosen', function(evt) {
|
596 |
-
_this.input_blur(evt);
|
597 |
-
});
|
598 |
-
this.search_field.bind('keyup.chosen', function(evt) {
|
599 |
-
_this.keyup_checker(evt);
|
600 |
-
});
|
601 |
-
this.search_field.bind('keydown.chosen', function(evt) {
|
602 |
-
_this.keydown_checker(evt);
|
603 |
-
});
|
604 |
-
this.search_field.bind('focus.chosen', function(evt) {
|
605 |
-
_this.input_focus(evt);
|
606 |
-
});
|
607 |
-
if (this.is_multiple) {
|
608 |
-
return this.search_choices.bind('click.chosen', function(evt) {
|
609 |
-
_this.choices_click(evt);
|
610 |
-
});
|
611 |
-
} else {
|
612 |
-
return this.container.bind('click.chosen', function(evt) {
|
613 |
-
evt.preventDefault();
|
614 |
-
});
|
615 |
-
}
|
616 |
-
};
|
617 |
-
|
618 |
-
Chosen.prototype.destroy = function() {
|
619 |
-
$(document).unbind("click.chosen", this.click_test_action);
|
620 |
-
if (this.search_field[0].tabIndex) {
|
621 |
-
this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
|
622 |
-
}
|
623 |
-
this.container.remove();
|
624 |
-
this.form_field_jq.removeData('chosen');
|
625 |
-
return this.form_field_jq.show();
|
626 |
-
};
|
627 |
-
|
628 |
-
Chosen.prototype.search_field_disabled = function() {
|
629 |
-
this.is_disabled = this.form_field_jq[0].disabled;
|
630 |
-
if (this.is_disabled) {
|
631 |
-
this.container.addClass('chosen-disabled');
|
632 |
-
this.search_field[0].disabled = true;
|
633 |
-
if (!this.is_multiple) {
|
634 |
-
this.selected_item.unbind("focus.chosen", this.activate_action);
|
635 |
-
}
|
636 |
-
return this.close_field();
|
637 |
-
} else {
|
638 |
-
this.container.removeClass('chosen-disabled');
|
639 |
-
this.search_field[0].disabled = false;
|
640 |
-
if (!this.is_multiple) {
|
641 |
-
return this.selected_item.bind("focus.chosen", this.activate_action);
|
642 |
-
}
|
643 |
-
}
|
644 |
-
};
|
645 |
-
|
646 |
-
Chosen.prototype.container_mousedown = function(evt) {
|
647 |
-
if (!this.is_disabled) {
|
648 |
-
if (evt && evt.type === "mousedown" && !this.results_showing) {
|
649 |
-
evt.preventDefault();
|
650 |
-
}
|
651 |
-
if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
|
652 |
-
if (!this.active_field) {
|
653 |
-
if (this.is_multiple) {
|
654 |
-
this.search_field.val("");
|
655 |
-
}
|
656 |
-
$(document).bind('click.chosen', this.click_test_action);
|
657 |
-
this.results_show();
|
658 |
-
} else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
|
659 |
-
evt.preventDefault();
|
660 |
-
this.results_toggle();
|
661 |
-
}
|
662 |
-
return this.activate_field();
|
663 |
-
}
|
664 |
-
}
|
665 |
-
};
|
666 |
-
|
667 |
-
Chosen.prototype.container_mouseup = function(evt) {
|
668 |
-
if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
|
669 |
-
return this.results_reset(evt);
|
670 |
-
}
|
671 |
-
};
|
672 |
-
|
673 |
-
Chosen.prototype.search_results_mousewheel = function(evt) {
|
674 |
-
var delta, _ref1, _ref2;
|
675 |
-
|
676 |
-
delta = -((_ref1 = evt.originalEvent) != null ? _ref1.wheelDelta : void 0) || ((_ref2 = evt.originialEvent) != null ? _ref2.detail : void 0);
|
677 |
-
if (delta != null) {
|
678 |
-
evt.preventDefault();
|
679 |
-
if (evt.type === 'DOMMouseScroll') {
|
680 |
-
delta = delta * 40;
|
681 |
-
}
|
682 |
-
return this.search_results.scrollTop(delta + this.search_results.scrollTop());
|
683 |
-
}
|
684 |
-
};
|
685 |
-
|
686 |
-
Chosen.prototype.blur_test = function(evt) {
|
687 |
-
if (!this.active_field && this.container.hasClass("chosen-container-active")) {
|
688 |
-
return this.close_field();
|
689 |
-
}
|
690 |
-
};
|
691 |
-
|
692 |
-
Chosen.prototype.close_field = function() {
|
693 |
-
$(document).unbind("click.chosen", this.click_test_action);
|
694 |
-
this.active_field = false;
|
695 |
-
this.results_hide();
|
696 |
-
this.container.removeClass("chosen-container-active");
|
697 |
-
this.clear_backstroke();
|
698 |
-
this.show_search_field_default();
|
699 |
-
return this.search_field_scale();
|
700 |
-
};
|
701 |
-
|
702 |
-
Chosen.prototype.activate_field = function() {
|
703 |
-
this.container.addClass("chosen-container-active");
|
704 |
-
this.active_field = true;
|
705 |
-
this.search_field.val(this.search_field.val());
|
706 |
-
return this.search_field.focus();
|
707 |
-
};
|
708 |
-
|
709 |
-
Chosen.prototype.test_active_click = function(evt) {
|
710 |
-
if (this.container.is($(evt.target).closest('.chosen-container'))) {
|
711 |
-
return this.active_field = true;
|
712 |
-
} else {
|
713 |
-
return this.close_field();
|
714 |
-
}
|
715 |
-
};
|
716 |
-
|
717 |
-
Chosen.prototype.results_build = function() {
|
718 |
-
this.parsing = true;
|
719 |
-
this.selected_option_count = null;
|
720 |
-
this.results_data = SelectParser.select_to_array(this.form_field);
|
721 |
-
if (this.is_multiple) {
|
722 |
-
this.search_choices.find("li.search-choice").remove();
|
723 |
-
} else if (!this.is_multiple) {
|
724 |
-
this.single_set_selected_text();
|
725 |
-
if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
|
726 |
-
this.search_field[0].readOnly = true;
|
727 |
-
this.container.addClass("chosen-container-single-nosearch");
|
728 |
-
} else {
|
729 |
-
this.search_field[0].readOnly = false;
|
730 |
-
this.container.removeClass("chosen-container-single-nosearch");
|
731 |
-
}
|
732 |
-
}
|
733 |
-
this.update_results_content(this.results_option_build({
|
734 |
-
first: true
|
735 |
-
}));
|
736 |
-
this.search_field_disabled();
|
737 |
-
this.show_search_field_default();
|
738 |
-
this.search_field_scale();
|
739 |
-
return this.parsing = false;
|
740 |
-
};
|
741 |
-
|
742 |
-
Chosen.prototype.result_do_highlight = function(el) {
|
743 |
-
var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
|
744 |
-
|
745 |
-
if (el.length) {
|
746 |
-
this.result_clear_highlight();
|
747 |
-
this.result_highlight = el;
|
748 |
-
this.result_highlight.addClass("highlighted");
|
749 |
-
maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
|
750 |
-
visible_top = this.search_results.scrollTop();
|
751 |
-
visible_bottom = maxHeight + visible_top;
|
752 |
-
high_top = this.result_highlight.position().top + this.search_results.scrollTop();
|
753 |
-
high_bottom = high_top + this.result_highlight.outerHeight();
|
754 |
-
if (high_bottom >= visible_bottom) {
|
755 |
-
return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
|
756 |
-
} else if (high_top < visible_top) {
|
757 |
-
return this.search_results.scrollTop(high_top);
|
758 |
-
}
|
759 |
-
}
|
760 |
-
};
|
761 |
-
|
762 |
-
Chosen.prototype.result_clear_highlight = function() {
|
763 |
-
if (this.result_highlight) {
|
764 |
-
this.result_highlight.removeClass("highlighted");
|
765 |
-
}
|
766 |
-
return this.result_highlight = null;
|
767 |
-
};
|
768 |
-
|
769 |
-
Chosen.prototype.results_show = function() {
|
770 |
-
if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
|
771 |
-
this.form_field_jq.trigger("chosen:maxselected", {
|
772 |
-
chosen: this
|
773 |
-
});
|
774 |
-
return false;
|
775 |
-
}
|
776 |
-
this.container.addClass("chosen-with-drop");
|
777 |
-
this.form_field_jq.trigger("chosen:showing_dropdown", {
|
778 |
-
chosen: this
|
779 |
-
});
|
780 |
-
this.results_showing = true;
|
781 |
-
this.search_field.focus();
|
782 |
-
this.search_field.val(this.search_field.val());
|
783 |
-
return this.winnow_results();
|
784 |
-
};
|
785 |
-
|
786 |
-
Chosen.prototype.update_results_content = function(content) {
|
787 |
-
return this.search_results.html(content);
|
788 |
-
};
|
789 |
-
|
790 |
-
Chosen.prototype.results_hide = function() {
|
791 |
-
if (this.results_showing) {
|
792 |
-
this.result_clear_highlight();
|
793 |
-
this.container.removeClass("chosen-with-drop");
|
794 |
-
this.form_field_jq.trigger("chosen:hiding_dropdown", {
|
795 |
-
chosen: this
|
796 |
-
});
|
797 |
-
}
|
798 |
-
return this.results_showing = false;
|
799 |
-
};
|
800 |
-
|
801 |
-
Chosen.prototype.set_tab_index = function(el) {
|
802 |
-
var ti;
|
803 |
-
|
804 |
-
if (this.form_field.tabIndex) {
|
805 |
-
ti = this.form_field.tabIndex;
|
806 |
-
this.form_field.tabIndex = -1;
|
807 |
-
return this.search_field[0].tabIndex = ti;
|
808 |
-
}
|
809 |
-
};
|
810 |
-
|
811 |
-
Chosen.prototype.set_label_behavior = function() {
|
812 |
-
var _this = this;
|
813 |
-
|
814 |
-
this.form_field_label = this.form_field_jq.parents("label");
|
815 |
-
if (!this.form_field_label.length && this.form_field.id.length) {
|
816 |
-
this.form_field_label = $("label[for='" + this.form_field.id + "']");
|
817 |
-
}
|
818 |
-
if (this.form_field_label.length > 0) {
|
819 |
-
return this.form_field_label.bind('click.chosen', function(evt) {
|
820 |
-
if (_this.is_multiple) {
|
821 |
-
return _this.container_mousedown(evt);
|
822 |
-
} else {
|
823 |
-
return _this.activate_field();
|
824 |
-
}
|
825 |
-
});
|
826 |
-
}
|
827 |
-
};
|
828 |
-
|
829 |
-
Chosen.prototype.show_search_field_default = function() {
|
830 |
-
if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
|
831 |
-
this.search_field.val(this.default_text);
|
832 |
-
return this.search_field.addClass("default");
|
833 |
-
} else {
|
834 |
-
this.search_field.val("");
|
835 |
-
return this.search_field.removeClass("default");
|
836 |
-
}
|
837 |
-
};
|
838 |
-
|
839 |
-
Chosen.prototype.search_results_mouseup = function(evt) {
|
840 |
-
var target;
|
841 |
-
|
842 |
-
target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
|
843 |
-
if (target.length) {
|
844 |
-
this.result_highlight = target;
|
845 |
-
this.result_select(evt);
|
846 |
-
return this.search_field.focus();
|
847 |
-
}
|
848 |
-
};
|
849 |
-
|
850 |
-
Chosen.prototype.search_results_mouseover = function(evt) {
|
851 |
-
var target;
|
852 |
-
|
853 |
-
target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
|
854 |
-
if (target) {
|
855 |
-
return this.result_do_highlight(target);
|
856 |
-
}
|
857 |
-
};
|
858 |
-
|
859 |
-
Chosen.prototype.search_results_mouseout = function(evt) {
|
860 |
-
if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
|
861 |
-
return this.result_clear_highlight();
|
862 |
-
}
|
863 |
-
};
|
864 |
-
|
865 |
-
Chosen.prototype.choice_build = function(item) {
|
866 |
-
var choice, close_link,
|
867 |
-
_this = this;
|
868 |
-
|
869 |
-
choice = $('<li />', {
|
870 |
-
"class": "search-choice"
|
871 |
-
}).html("<span>" + item.html + "</span>");
|
872 |
-
if (item.disabled) {
|
873 |
-
choice.addClass('search-choice-disabled');
|
874 |
-
} else {
|
875 |
-
close_link = $('<a />', {
|
876 |
-
"class": 'search-choice-close',
|
877 |
-
'data-option-array-index': item.array_index
|
878 |
-
});
|
879 |
-
close_link.bind('click.chosen', function(evt) {
|
880 |
-
return _this.choice_destroy_link_click(evt);
|
881 |
-
});
|
882 |
-
choice.append(close_link);
|
883 |
-
}
|
884 |
-
return this.search_container.before(choice);
|
885 |
-
};
|
886 |
-
|
887 |
-
Chosen.prototype.choice_destroy_link_click = function(evt) {
|
888 |
-
evt.preventDefault();
|
889 |
-
evt.stopPropagation();
|
890 |
-
if (!this.is_disabled) {
|
891 |
-
return this.choice_destroy($(evt.target));
|
892 |
-
}
|
893 |
-
};
|
894 |
-
|
895 |
-
Chosen.prototype.choice_destroy = function(link) {
|
896 |
-
if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
|
897 |
-
this.show_search_field_default();
|
898 |
-
if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
|
899 |
-
this.results_hide();
|
900 |
-
}
|
901 |
-
link.parents('li').first().remove();
|
902 |
-
return this.search_field_scale();
|
903 |
-
}
|
904 |
-
};
|
905 |
-
|
906 |
-
Chosen.prototype.results_reset = function() {
|
907 |
-
this.form_field.options[0].selected = true;
|
908 |
-
this.selected_option_count = null;
|
909 |
-
this.single_set_selected_text();
|
910 |
-
this.show_search_field_default();
|
911 |
-
this.results_reset_cleanup();
|
912 |
-
this.form_field_jq.trigger("change");
|
913 |
-
if (this.active_field) {
|
914 |
-
return this.results_hide();
|
915 |
-
}
|
916 |
-
};
|
917 |
-
|
918 |
-
Chosen.prototype.results_reset_cleanup = function() {
|
919 |
-
this.current_selectedIndex = this.form_field.selectedIndex;
|
920 |
-
return this.selected_item.find("abbr").remove();
|
921 |
-
};
|
922 |
-
|
923 |
-
Chosen.prototype.result_select = function(evt) {
|
924 |
-
var high, item, selected_index;
|
925 |
-
|
926 |
-
if (this.result_highlight) {
|
927 |
-
high = this.result_highlight;
|
928 |
-
this.result_clear_highlight();
|
929 |
-
if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
|
930 |
-
this.form_field_jq.trigger("chosen:maxselected", {
|
931 |
-
chosen: this
|
932 |
-
});
|
933 |
-
return false;
|
934 |
-
}
|
935 |
-
if (this.is_multiple) {
|
936 |
-
high.removeClass("active-result");
|
937 |
-
} else {
|
938 |
-
if (this.result_single_selected) {
|
939 |
-
this.result_single_selected.removeClass("result-selected");
|
940 |
-
selected_index = this.result_single_selected[0].getAttribute('data-option-array-index');
|
941 |
-
this.results_data[selected_index].selected = false;
|
942 |
-
}
|
943 |
-
this.result_single_selected = high;
|
944 |
-
}
|
945 |
-
high.addClass("result-selected");
|
946 |
-
item = this.results_data[high[0].getAttribute("data-option-array-index")];
|
947 |
-
item.selected = true;
|
948 |
-
this.form_field.options[item.options_index].selected = true;
|
949 |
-
this.selected_option_count = null;
|
950 |
-
if (this.is_multiple) {
|
951 |
-
this.choice_build(item);
|
952 |
-
} else {
|
953 |
-
this.single_set_selected_text(item.text);
|
954 |
-
}
|
955 |
-
if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
|
956 |
-
this.results_hide();
|
957 |
-
}
|
958 |
-
this.search_field.val("");
|
959 |
-
if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
|
960 |
-
this.form_field_jq.trigger("change", {
|
961 |
-
'selected': this.form_field.options[item.options_index].value
|
962 |
-
});
|
963 |
-
}
|
964 |
-
this.current_selectedIndex = this.form_field.selectedIndex;
|
965 |
-
return this.search_field_scale();
|
966 |
-
}
|
967 |
-
};
|
968 |
-
|
969 |
-
Chosen.prototype.single_set_selected_text = function(text) {
|
970 |
-
if (text == null) {
|
971 |
-
text = this.default_text;
|
972 |
-
}
|
973 |
-
if (text === this.default_text) {
|
974 |
-
this.selected_item.addClass("chosen-default");
|
975 |
-
} else {
|
976 |
-
this.single_deselect_control_build();
|
977 |
-
this.selected_item.removeClass("chosen-default");
|
978 |
-
}
|
979 |
-
return this.selected_item.find("span").text(text);
|
980 |
-
};
|
981 |
-
|
982 |
-
Chosen.prototype.result_deselect = function(pos) {
|
983 |
-
var result_data;
|
984 |
-
|
985 |
-
result_data = this.results_data[pos];
|
986 |
-
if (!this.form_field.options[result_data.options_index].disabled) {
|
987 |
-
result_data.selected = false;
|
988 |
-
this.form_field.options[result_data.options_index].selected = false;
|
989 |
-
this.selected_option_count = null;
|
990 |
-
this.result_clear_highlight();
|
991 |
-
if (this.results_showing) {
|
992 |
-
this.winnow_results();
|
993 |
-
}
|
994 |
-
this.form_field_jq.trigger("change", {
|
995 |
-
deselected: this.form_field.options[result_data.options_index].value
|
996 |
-
});
|
997 |
-
this.search_field_scale();
|
998 |
-
return true;
|
999 |
-
} else {
|
1000 |
-
return false;
|
1001 |
-
}
|
1002 |
-
};
|
1003 |
-
|
1004 |
-
Chosen.prototype.single_deselect_control_build = function() {
|
1005 |
-
if (!this.allow_single_deselect) {
|
1006 |
-
return;
|
1007 |
-
}
|
1008 |
-
if (!this.selected_item.find("abbr").length) {
|
1009 |
-
this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
|
1010 |
-
}
|
1011 |
-
return this.selected_item.addClass("chosen-single-with-deselect");
|
1012 |
-
};
|
1013 |
-
|
1014 |
-
Chosen.prototype.get_search_text = function() {
|
1015 |
-
if (this.search_field.val() === this.default_text) {
|
1016 |
-
return "";
|
1017 |
-
} else {
|
1018 |
-
return $('<div/>').text($.trim(this.search_field.val())).html();
|
1019 |
-
}
|
1020 |
-
};
|
1021 |
-
|
1022 |
-
Chosen.prototype.winnow_results_set_highlight = function() {
|
1023 |
-
var do_high, selected_results;
|
1024 |
-
|
1025 |
-
selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
|
1026 |
-
do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
|
1027 |
-
if (do_high != null) {
|
1028 |
-
return this.result_do_highlight(do_high);
|
1029 |
-
}
|
1030 |
-
};
|
1031 |
-
|
1032 |
-
Chosen.prototype.no_results = function(terms) {
|
1033 |
-
var no_results_html;
|
1034 |
-
|
1035 |
-
no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
|
1036 |
-
no_results_html.find("span").first().html(terms);
|
1037 |
-
return this.search_results.append(no_results_html);
|
1038 |
-
};
|
1039 |
-
|
1040 |
-
Chosen.prototype.no_results_clear = function() {
|
1041 |
-
return this.search_results.find(".no-results").remove();
|
1042 |
-
};
|
1043 |
-
|
1044 |
-
Chosen.prototype.keydown_arrow = function() {
|
1045 |
-
var next_sib;
|
1046 |
-
|
1047 |
-
if (this.results_showing && this.result_highlight) {
|
1048 |
-
next_sib = this.result_highlight.nextAll("li.active-result").first();
|
1049 |
-
if (next_sib) {
|
1050 |
-
return this.result_do_highlight(next_sib);
|
1051 |
-
}
|
1052 |
-
} else {
|
1053 |
-
return this.results_show();
|
1054 |
-
}
|
1055 |
-
};
|
1056 |
-
|
1057 |
-
Chosen.prototype.keyup_arrow = function() {
|
1058 |
-
var prev_sibs;
|
1059 |
-
|
1060 |
-
if (!this.results_showing && !this.is_multiple) {
|
1061 |
-
return this.results_show();
|
1062 |
-
} else if (this.result_highlight) {
|
1063 |
-
prev_sibs = this.result_highlight.prevAll("li.active-result");
|
1064 |
-
if (prev_sibs.length) {
|
1065 |
-
return this.result_do_highlight(prev_sibs.first());
|
1066 |
-
} else {
|
1067 |
-
if (this.choices_count() > 0) {
|
1068 |
-
this.results_hide();
|
1069 |
-
}
|
1070 |
-
return this.result_clear_highlight();
|
1071 |
-
}
|
1072 |
-
}
|
1073 |
-
};
|
1074 |
-
|
1075 |
-
Chosen.prototype.keydown_backstroke = function() {
|
1076 |
-
var next_available_destroy;
|
1077 |
-
|
1078 |
-
if (this.pending_backstroke) {
|
1079 |
-
this.choice_destroy(this.pending_backstroke.find("a").first());
|
1080 |
-
return this.clear_backstroke();
|
1081 |
-
} else {
|
1082 |
-
next_available_destroy = this.search_container.siblings("li.search-choice").last();
|
1083 |
-
if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
|
1084 |
-
this.pending_backstroke = next_available_destroy;
|
1085 |
-
if (this.single_backstroke_delete) {
|
1086 |
-
return this.keydown_backstroke();
|
1087 |
-
} else {
|
1088 |
-
return this.pending_backstroke.addClass("search-choice-focus");
|
1089 |
-
}
|
1090 |
-
}
|
1091 |
-
}
|
1092 |
-
};
|
1093 |
-
|
1094 |
-
Chosen.prototype.clear_backstroke = function() {
|
1095 |
-
if (this.pending_backstroke) {
|
1096 |
-
this.pending_backstroke.removeClass("search-choice-focus");
|
1097 |
-
}
|
1098 |
-
return this.pending_backstroke = null;
|
1099 |
-
};
|
1100 |
-
|
1101 |
-
Chosen.prototype.keydown_checker = function(evt) {
|
1102 |
-
var stroke, _ref1;
|
1103 |
-
|
1104 |
-
stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
|
1105 |
-
this.search_field_scale();
|
1106 |
-
if (stroke !== 8 && this.pending_backstroke) {
|
1107 |
-
this.clear_backstroke();
|
1108 |
-
}
|
1109 |
-
switch (stroke) {
|
1110 |
-
case 8:
|
1111 |
-
this.backstroke_length = this.search_field.val().length;
|
1112 |
-
break;
|
1113 |
-
case 9:
|
1114 |
-
if (this.results_showing && !this.is_multiple) {
|
1115 |
-
this.result_select(evt);
|
1116 |
-
}
|
1117 |
-
this.mouse_on_container = false;
|
1118 |
-
break;
|
1119 |
-
case 13:
|
1120 |
-
evt.preventDefault();
|
1121 |
-
break;
|
1122 |
-
case 38:
|
1123 |
-
evt.preventDefault();
|
1124 |
-
this.keyup_arrow();
|
1125 |
-
break;
|
1126 |
-
case 40:
|
1127 |
-
evt.preventDefault();
|
1128 |
-
this.keydown_arrow();
|
1129 |
-
break;
|
1130 |
-
}
|
1131 |
-
};
|
1132 |
-
|
1133 |
-
Chosen.prototype.search_field_scale = function() {
|
1134 |
-
var div, f_width, h, style, style_block, styles, w, _i, _len;
|
1135 |
-
|
1136 |
-
if (this.is_multiple) {
|
1137 |
-
h = 0;
|
1138 |
-
w = 0;
|
1139 |
-
style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
|
1140 |
-
styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
|
1141 |
-
for (_i = 0, _len = styles.length; _i < _len; _i++) {
|
1142 |
-
style = styles[_i];
|
1143 |
-
style_block += style + ":" + this.search_field.css(style) + ";";
|
1144 |
-
}
|
1145 |
-
div = $('<div />', {
|
1146 |
-
'style': style_block
|
1147 |
-
});
|
1148 |
-
div.text(this.search_field.val());
|
1149 |
-
$('body').append(div);
|
1150 |
-
w = div.width() + 25;
|
1151 |
-
div.remove();
|
1152 |
-
f_width = this.container.outerWidth();
|
1153 |
-
if (w > f_width - 10) {
|
1154 |
-
w = f_width - 10;
|
1155 |
-
}
|
1156 |
-
return this.search_field.css({
|
1157 |
-
'width': w + 'px'
|
1158 |
-
});
|
1159 |
-
}
|
1160 |
-
};
|
1161 |
-
|
1162 |
-
return Chosen;
|
1163 |
-
|
1164 |
-
})(AbstractChosen);
|
1165 |
-
|
1166 |
-
}).call(this);
|
1 |
+
// Chosen, a Select Box Enhancer for jQuery and Prototype
|
2 |
+
// by Patrick Filler for Harvest, http://getharvest.com
|
3 |
+
//
|
4 |
+
// Version 1.0.0
|
5 |
+
// Full source at https://github.com/harvesthq/chosen
|
6 |
+
// Copyright (c) 2011 Harvest http://getharvest.com
|
7 |
+
|
8 |
+
// MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
|
9 |
+
// This file is generated by `grunt build`, do not edit it by hand.
|
10 |
+
(function() {
|
11 |
+
var $, AbstractChosen, Chosen, SelectParser, _ref,
|
12 |
+
__hasProp = {}.hasOwnProperty,
|
13 |
+
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
14 |
+
|
15 |
+
SelectParser = (function() {
|
16 |
+
function SelectParser() {
|
17 |
+
this.options_index = 0;
|
18 |
+
this.parsed = [];
|
19 |
+
}
|
20 |
+
|
21 |
+
SelectParser.prototype.add_node = function(child) {
|
22 |
+
if (child.nodeName.toUpperCase() === "OPTGROUP") {
|
23 |
+
return this.add_group(child);
|
24 |
+
} else {
|
25 |
+
return this.add_option(child);
|
26 |
+
}
|
27 |
+
};
|
28 |
+
|
29 |
+
SelectParser.prototype.add_group = function(group) {
|
30 |
+
var group_position, option, _i, _len, _ref, _results;
|
31 |
+
|
32 |
+
group_position = this.parsed.length;
|
33 |
+
this.parsed.push({
|
34 |
+
array_index: group_position,
|
35 |
+
group: true,
|
36 |
+
label: this.escapeExpression(group.label),
|
37 |
+
children: 0,
|
38 |
+
disabled: group.disabled
|
39 |
+
});
|
40 |
+
_ref = group.childNodes;
|
41 |
+
_results = [];
|
42 |
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
43 |
+
option = _ref[_i];
|
44 |
+
_results.push(this.add_option(option, group_position, group.disabled));
|
45 |
+
}
|
46 |
+
return _results;
|
47 |
+
};
|
48 |
+
|
49 |
+
SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
|
50 |
+
if (option.nodeName.toUpperCase() === "OPTION") {
|
51 |
+
if (option.text !== "") {
|
52 |
+
if (group_position != null) {
|
53 |
+
this.parsed[group_position].children += 1;
|
54 |
+
}
|
55 |
+
this.parsed.push({
|
56 |
+
array_index: this.parsed.length,
|
57 |
+
options_index: this.options_index,
|
58 |
+
value: option.value,
|
59 |
+
text: option.text,
|
60 |
+
html: option.innerHTML,
|
61 |
+
selected: option.selected,
|
62 |
+
disabled: group_disabled === true ? group_disabled : option.disabled,
|
63 |
+
group_array_index: group_position,
|
64 |
+
classes: option.className,
|
65 |
+
style: option.style.cssText
|
66 |
+
});
|
67 |
+
} else {
|
68 |
+
this.parsed.push({
|
69 |
+
array_index: this.parsed.length,
|
70 |
+
options_index: this.options_index,
|
71 |
+
empty: true
|
72 |
+
});
|
73 |
+
}
|
74 |
+
return this.options_index += 1;
|
75 |
+
}
|
76 |
+
};
|
77 |
+
|
78 |
+
SelectParser.prototype.escapeExpression = function(text) {
|
79 |
+
var map, unsafe_chars;
|
80 |
+
|
81 |
+
if ((text == null) || text === false) {
|
82 |
+
return "";
|
83 |
+
}
|
84 |
+
if (!/[\&\<\>\"\'\`]/.test(text)) {
|
85 |
+
return text;
|
86 |
+
}
|
87 |
+
map = {
|
88 |
+
"<": "<",
|
89 |
+
">": ">",
|
90 |
+
'"': """,
|
91 |
+
"'": "'",
|
92 |
+
"`": "`"
|
93 |
+
};
|
94 |
+
unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
|
95 |
+
return text.replace(unsafe_chars, function(chr) {
|
96 |
+
return map[chr] || "&";
|
97 |
+
});
|
98 |
+
};
|
99 |
+
|
100 |
+
return SelectParser;
|
101 |
+
|
102 |
+
})();
|
103 |
+
|
104 |
+
SelectParser.select_to_array = function(select) {
|
105 |
+
var child, parser, _i, _len, _ref;
|
106 |
+
|
107 |
+
parser = new SelectParser();
|
108 |
+
_ref = select.childNodes;
|
109 |
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
110 |
+
child = _ref[_i];
|
111 |
+
parser.add_node(child);
|
112 |
+
}
|
113 |
+
return parser.parsed;
|
114 |
+
};
|
115 |
+
|
116 |
+
AbstractChosen = (function() {
|
117 |
+
function AbstractChosen(form_field, options) {
|
118 |
+
this.form_field = form_field;
|
119 |
+
this.options = options != null ? options : {};
|
120 |
+
if (!AbstractChosen.browser_is_supported()) {
|
121 |
+
return;
|
122 |
+
}
|
123 |
+
this.is_multiple = this.form_field.multiple;
|
124 |
+
this.set_default_text();
|
125 |
+
this.set_default_values();
|
126 |
+
this.setup();
|
127 |
+
this.set_up_html();
|
128 |
+
this.register_observers();
|
129 |
+
}
|
130 |
+
|
131 |
+
AbstractChosen.prototype.set_default_values = function() {
|
132 |
+
var _this = this;
|
133 |
+
|
134 |
+
this.click_test_action = function(evt) {
|
135 |
+
return _this.test_active_click(evt);
|
136 |
+
};
|
137 |
+
this.activate_action = function(evt) {
|
138 |
+
return _this.activate_field(evt);
|
139 |
+
};
|
140 |
+
this.active_field = false;
|
141 |
+
this.mouse_on_container = false;
|
142 |
+
this.results_showing = false;
|
143 |
+
this.result_highlighted = null;
|
144 |
+
this.result_single_selected = null;
|
145 |
+
this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
|
146 |
+
this.disable_search_threshold = this.options.disable_search_threshold || 0;
|
147 |
+
this.disable_search = this.options.disable_search || false;
|
148 |
+
this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
|
149 |
+
this.group_search = this.options.group_search != null ? this.options.group_search : true;
|
150 |
+
this.search_contains = this.options.search_contains || false;
|
151 |
+
this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
|
152 |
+
this.max_selected_options = this.options.max_selected_options || Infinity;
|
153 |
+
this.inherit_select_classes = this.options.inherit_select_classes || false;
|
154 |
+
this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
|
155 |
+
return this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
|
156 |
+
};
|
157 |
+
|
158 |
+
AbstractChosen.prototype.set_default_text = function() {
|
159 |
+
if (this.form_field.getAttribute("data-placeholder")) {
|
160 |
+
this.default_text = this.form_field.getAttribute("data-placeholder");
|
161 |
+
} else if (this.is_multiple) {
|
162 |
+
this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
|
163 |
+
} else {
|
164 |
+
this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
|
165 |
+
}
|
166 |
+
return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
|
167 |
+
};
|
168 |
+
|
169 |
+
AbstractChosen.prototype.mouse_enter = function() {
|
170 |
+
return this.mouse_on_container = true;
|
171 |
+
};
|
172 |
+
|
173 |
+
AbstractChosen.prototype.mouse_leave = function() {
|
174 |
+
return this.mouse_on_container = false;
|
175 |
+
};
|
176 |
+
|
177 |
+
AbstractChosen.prototype.input_focus = function(evt) {
|
178 |
+
var _this = this;
|
179 |
+
|
180 |
+
if (this.is_multiple) {
|
181 |
+
if (!this.active_field) {
|
182 |
+
return setTimeout((function() {
|
183 |
+
return _this.container_mousedown();
|
184 |
+
}), 50);
|
185 |
+
}
|
186 |
+
} else {
|
187 |
+
if (!this.active_field) {
|
188 |
+
return this.activate_field();
|
189 |
+
}
|
190 |
+
}
|
191 |
+
};
|
192 |
+
|
193 |
+
AbstractChosen.prototype.input_blur = function(evt) {
|
194 |
+
var _this = this;
|
195 |
+
|
196 |
+
if (!this.mouse_on_container) {
|
197 |
+
this.active_field = false;
|
198 |
+
return setTimeout((function() {
|
199 |
+
return _this.blur_test();
|
200 |
+
}), 100);
|
201 |
+
}
|
202 |
+
};
|
203 |
+
|
204 |
+
AbstractChosen.prototype.results_option_build = function(options) {
|
205 |
+
var content, data, _i, _len, _ref;
|
206 |
+
|
207 |
+
content = '';
|
208 |
+
_ref = this.results_data;
|
209 |
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
210 |
+
data = _ref[_i];
|
211 |
+
if (data.group) {
|
212 |
+
content += this.result_add_group(data);
|
213 |
+
} else {
|
214 |
+
content += this.result_add_option(data);
|
215 |
+
}
|
216 |
+
if (options != null ? options.first : void 0) {
|
217 |
+
if (data.selected && this.is_multiple) {
|
218 |
+
this.choice_build(data);
|
219 |
+
} else if (data.selected && !this.is_multiple) {
|
220 |
+
this.single_set_selected_text(data.text);
|
221 |
+
}
|
222 |
+
}
|
223 |
+
}
|
224 |
+
return content;
|
225 |
+
};
|
226 |
+
|
227 |
+
AbstractChosen.prototype.result_add_option = function(option) {
|
228 |
+
var classes, style;
|
229 |
+
|
230 |
+
if (!option.search_match) {
|
231 |
+
return '';
|
232 |
+
}
|
233 |
+
if (!this.include_option_in_results(option)) {
|
234 |
+
return '';
|
235 |
+
}
|
236 |
+
classes = [];
|
237 |
+
if (!option.disabled && !(option.selected && this.is_multiple)) {
|
238 |
+
classes.push("active-result");
|
239 |
+
}
|
240 |
+
if (option.disabled && !(option.selected && this.is_multiple)) {
|
241 |
+
classes.push("disabled-result");
|
242 |
+
}
|
243 |
+
if (option.selected) {
|
244 |
+
classes.push("result-selected");
|
245 |
+
}
|
246 |
+
if (option.group_array_index != null) {
|
247 |
+
classes.push("group-option");
|
248 |
+
}
|
249 |
+
if (option.classes !== "") {
|
250 |
+
classes.push(option.classes);
|
251 |
+
}
|
252 |
+
style = option.style.cssText !== "" ? " style=\"" + option.style + "\"" : "";
|
253 |
+
return "<li class=\"" + (classes.join(' ')) + "\"" + style + " data-option-array-index=\"" + option.array_index + "\">" + option.search_text + "</li>";
|
254 |
+
};
|
255 |
+
|
256 |
+
AbstractChosen.prototype.result_add_group = function(group) {
|
257 |
+
if (!(group.search_match || group.group_match)) {
|
258 |
+
return '';
|
259 |
+
}
|
260 |
+
if (!(group.active_options > 0)) {
|
261 |
+
return '';
|
262 |
+
}
|
263 |
+
return "<li class=\"group-result\">" + group.search_text + "</li>";
|
264 |
+
};
|
265 |
+
|
266 |
+
AbstractChosen.prototype.results_update_field = function() {
|
267 |
+
this.set_default_text();
|
268 |
+
if (!this.is_multiple) {
|
269 |
+
this.results_reset_cleanup();
|
270 |
+
}
|
271 |
+
this.result_clear_highlight();
|
272 |
+
this.result_single_selected = null;
|
273 |
+
this.results_build();
|
274 |
+
if (this.results_showing) {
|
275 |
+
return this.winnow_results();
|
276 |
+
}
|
277 |
+
};
|
278 |
+
|
279 |
+
AbstractChosen.prototype.results_toggle = function() {
|
280 |
+
if (this.results_showing) {
|
281 |
+
return this.results_hide();
|
282 |
+
} else {
|
283 |
+
return this.results_show();
|
284 |
+
}
|
285 |
+
};
|
286 |
+
|
287 |
+
AbstractChosen.prototype.results_search = function(evt) {
|
288 |
+
if (this.results_showing) {
|
289 |
+
return this.winnow_results();
|
290 |
+
} else {
|
291 |
+
return this.results_show();
|
292 |
+
}
|
293 |
+
};
|
294 |
+
|
295 |
+
AbstractChosen.prototype.winnow_results = function() {
|
296 |
+
var escapedSearchText, option, regex, regexAnchor, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
|
297 |
+
|
298 |
+
this.no_results_clear();
|
299 |
+
results = 0;
|
300 |
+
searchText = this.get_search_text();
|
301 |
+
escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
302 |
+
regexAnchor = this.search_contains ? "" : "^";
|
303 |
+
regex = new RegExp(regexAnchor + escapedSearchText, 'i');
|
304 |
+
zregex = new RegExp(escapedSearchText, 'i');
|
305 |
+
_ref = this.results_data;
|
306 |
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
307 |
+
option = _ref[_i];
|
308 |
+
option.search_match = false;
|
309 |
+
results_group = null;
|
310 |
+
if (this.include_option_in_results(option)) {
|
311 |
+
if (option.group) {
|
312 |
+
option.group_match = false;
|
313 |
+
option.active_options = 0;
|
314 |
+
}
|
315 |
+
if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
|
316 |
+
results_group = this.results_data[option.group_array_index];
|
317 |
+
if (results_group.active_options === 0 && results_group.search_match) {
|
318 |
+
results += 1;
|
319 |
+
}
|
320 |
+
results_group.active_options += 1;
|
321 |
+
}
|
322 |
+
if (!(option.group && !this.group_search)) {
|
323 |
+
option.search_text = option.group ? option.label : option.html;
|
324 |
+
option.search_match = this.search_string_match(option.search_text, regex);
|
325 |
+
if (option.search_match && !option.group) {
|
326 |
+
results += 1;
|
327 |
+
}
|
328 |
+
if (option.search_match) {
|
329 |
+
if (searchText.length) {
|
330 |
+
startpos = option.search_text.search(zregex);
|
331 |
+
text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
|
332 |
+
option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
|
333 |
+
}
|
334 |
+
if (results_group != null) {
|
335 |
+
results_group.group_match = true;
|
336 |
+
}
|
337 |
+
} else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
|
338 |
+
option.search_match = true;
|
339 |
+
}
|
340 |
+
}
|
341 |
+
}
|
342 |
+
}
|
343 |
+
this.result_clear_highlight();
|
344 |
+
if (results < 1 && searchText.length) {
|
345 |
+
this.update_results_content("");
|
346 |
+
return this.no_results(searchText);
|
347 |
+
} else {
|
348 |
+
this.update_results_content(this.results_option_build());
|
349 |
+
return this.winnow_results_set_highlight();
|
350 |
+
}
|
351 |
+
};
|
352 |
+
|
353 |
+
AbstractChosen.prototype.search_string_match = function(search_string, regex) {
|
354 |
+
var part, parts, _i, _len;
|
355 |
+
|
356 |
+
if (regex.test(search_string)) {
|
357 |
+
return true;
|
358 |
+
} else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
|
359 |
+
parts = search_string.replace(/\[|\]/g, "").split(" ");
|
360 |
+
if (parts.length) {
|
361 |
+
for (_i = 0, _len = parts.length; _i < _len; _i++) {
|
362 |
+
part = parts[_i];
|
363 |
+
if (regex.test(part)) {
|
364 |
+
return true;
|
365 |
+
}
|
366 |
+
}
|
367 |
+
}
|
368 |
+
}
|
369 |
+
};
|
370 |
+
|
371 |
+
AbstractChosen.prototype.choices_count = function() {
|
372 |
+
var option, _i, _len, _ref;
|
373 |
+
|
374 |
+
if (this.selected_option_count != null) {
|
375 |
+
return this.selected_option_count;
|
376 |
+
}
|
377 |
+
this.selected_option_count = 0;
|
378 |
+
_ref = this.form_field.options;
|
379 |
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
380 |
+
option = _ref[_i];
|
381 |
+
if (option.selected) {
|
382 |
+
this.selected_option_count += 1;
|
383 |
+
}
|
384 |
+
}
|
385 |
+
return this.selected_option_count;
|
386 |
+
};
|
387 |
+
|
388 |
+
AbstractChosen.prototype.choices_click = function(evt) {
|
389 |
+
evt.preventDefault();
|
390 |
+
if (!(this.results_showing || this.is_disabled)) {
|
391 |
+
return this.results_show();
|
392 |
+
}
|
393 |
+
};
|
394 |
+
|
395 |
+
AbstractChosen.prototype.keyup_checker = function(evt) {
|
396 |
+
var stroke, _ref;
|
397 |
+
|
398 |
+
stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
|
399 |
+
this.search_field_scale();
|
400 |
+
switch (stroke) {
|
401 |
+
case 8:
|
402 |
+
if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
|
403 |
+
return this.keydown_backstroke();
|
404 |
+
} else if (!this.pending_backstroke) {
|
405 |
+
this.result_clear_highlight();
|
406 |
+
return this.results_search();
|
407 |
+
}
|
408 |
+
break;
|
409 |
+
case 13:
|
410 |
+
evt.preventDefault();
|
411 |
+
if (this.results_showing) {
|
412 |
+
return this.result_select(evt);
|
413 |
+
}
|
414 |
+
break;
|
415 |
+
case 27:
|
416 |
+
if (this.results_showing) {
|
417 |
+
this.results_hide();
|
418 |
+
}
|
419 |
+
return true;
|
420 |
+
case 9:
|
421 |
+
case 38:
|
422 |
+
case 40:
|
423 |
+
case 16:
|
424 |
+
case 91:
|
425 |
+
case 17:
|
426 |
+
break;
|
427 |
+
default:
|
428 |
+
return this.results_search();
|
429 |
+
}
|
430 |
+
};
|
431 |
+
|
432 |
+
AbstractChosen.prototype.container_width = function() {
|
433 |
+
if (this.options.width != null) {
|
434 |
+
return this.options.width;
|
435 |
+
} else {
|
436 |
+
return "" + this.form_field.offsetWidth + "px";
|
437 |
+
}
|
438 |
+
};
|
439 |
+
|
440 |
+
AbstractChosen.prototype.include_option_in_results = function(option) {
|
441 |
+
if (this.is_multiple && (!this.display_selected_options && option.selected)) {
|
442 |
+
return false;
|
443 |
+
}
|
444 |
+
if (!this.display_disabled_options && option.disabled) {
|
445 |
+
return false;
|
446 |
+
}
|
447 |
+
if (option.empty) {
|
448 |
+
return false;
|
449 |
+
}
|
450 |
+
return true;
|
451 |
+
};
|
452 |
+
|
453 |
+
AbstractChosen.browser_is_supported = function() {
|
454 |
+
if (window.navigator.appName === "Microsoft Internet Explorer") {
|
455 |
+
return document.documentMode >= 8;
|
456 |
+
}
|
457 |
+
if (/iP(od|hone)/i.test(window.navigator.userAgent)) {
|
458 |
+
return false;
|
459 |
+
}
|
460 |
+
if (/Android/i.test(window.navigator.userAgent)) {
|
461 |
+
if (/Mobile/i.test(window.navigator.userAgent)) {
|
462 |
+
return false;
|
463 |
+
}
|
464 |
+
}
|
465 |
+
return true;
|
466 |
+
};
|
467 |
+
|
468 |
+
AbstractChosen.default_multiple_text = "Select Some Options";
|
469 |
+
|
470 |
+
AbstractChosen.default_single_text = "Select an Option";
|
471 |
+
|
472 |
+
AbstractChosen.default_no_result_text = "No results match";
|
473 |
+
|
474 |
+
return AbstractChosen;
|
475 |
+
|
476 |
+
})();
|
477 |
+
|
478 |
+
$ = jQuery;
|
479 |
+
|
480 |
+
$.fn.extend({
|
481 |
+
chosen: function(options) {
|
482 |
+
if (!AbstractChosen.browser_is_supported()) {
|
483 |
+
return this;
|
484 |
+
}
|
485 |
+
return this.each(function(input_field) {
|
486 |
+
var $this, chosen;
|
487 |
+
|
488 |
+
$this = $(this);
|
489 |
+
chosen = $this.data('chosen');
|
490 |
+
if (options === 'destroy' && chosen) {
|
491 |
+
chosen.destroy();
|
492 |
+
} else if (!chosen) {
|
493 |
+
$this.data('chosen', new Chosen(this, options));
|
494 |
+
}
|
495 |
+
});
|
496 |
+
}
|
497 |
+
});
|
498 |
+
|
499 |
+
Chosen = (function(_super) {
|
500 |
+
__extends(Chosen, _super);
|
501 |
+
|
502 |
+
function Chosen() {
|
503 |
+
_ref = Chosen.__super__.constructor.apply(this, arguments);
|
504 |
+
return _ref;
|
505 |
+
}
|
506 |
+
|
507 |
+
Chosen.prototype.setup = function() {
|
508 |
+
this.form_field_jq = $(this.form_field);
|
509 |
+
this.current_selectedIndex = this.form_field.selectedIndex;
|
510 |
+
return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl");
|
511 |
+
};
|
512 |
+
|
513 |
+
Chosen.prototype.set_up_html = function() {
|
514 |
+
var container_classes, container_props;
|
515 |
+
|
516 |
+
container_classes = ["chosen-container"];
|
517 |
+
container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
|
518 |
+
if (this.inherit_select_classes && this.form_field.className) {
|
519 |
+
container_classes.push(this.form_field.className);
|
520 |
+
}
|
521 |
+
if (this.is_rtl) {
|
522 |
+
container_classes.push("chosen-rtl");
|
523 |
+
}
|
524 |
+
container_props = {
|
525 |
+
'class': container_classes.join(' '),
|
526 |
+
'style': "width: " + (this.container_width()) + ";",
|
527 |
+
'title': this.form_field.title
|
528 |
+
};
|
529 |
+
if (this.form_field.id.length) {
|
530 |
+
container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
|
531 |
+
}
|
532 |
+
this.container = $("<div />", container_props);
|
533 |
+
if (this.is_multiple) {
|
534 |
+
this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>');
|
535 |
+
} else {
|
536 |
+
this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>');
|
537 |
+
}
|
538 |
+
this.form_field_jq.hide().after(this.container);
|
539 |
+
this.dropdown = this.container.find('div.chosen-drop').first();
|
540 |
+
this.search_field = this.container.find('input').first();
|
541 |
+
this.search_results = this.container.find('ul.chosen-results').first();
|
542 |
+
this.search_field_scale();
|
543 |
+
this.search_no_results = this.container.find('li.no-results').first();
|
544 |
+
if (this.is_multiple) {
|
545 |
+
this.search_choices = this.container.find('ul.chosen-choices').first();
|
546 |
+
this.search_container = this.container.find('li.search-field').first();
|
547 |
+
} else {
|
548 |
+
this.search_container = this.container.find('div.chosen-search').first();
|
549 |
+
this.selected_item = this.container.find('.chosen-single').first();
|
550 |
+
}
|
551 |
+
this.results_build();
|
552 |
+
this.set_tab_index();
|
553 |
+
this.set_label_behavior();
|
554 |
+
return this.form_field_jq.trigger("chosen:ready", {
|
555 |
+
chosen: this
|
556 |
+
});
|
557 |
+
};
|
558 |
+
|
559 |
+
Chosen.prototype.register_observers = function() {
|
560 |
+
var _this = this;
|
561 |
+
|
562 |
+
this.container.bind('mousedown.chosen', function(evt) {
|
563 |
+
_this.container_mousedown(evt);
|
564 |
+
});
|
565 |
+
this.container.bind('mouseup.chosen', function(evt) {
|
566 |
+
_this.container_mouseup(evt);
|
567 |
+
});
|
568 |
+
this.container.bind('mouseenter.chosen', function(evt) {
|
569 |
+
_this.mouse_enter(evt);
|
570 |
+
});
|
571 |
+
this.container.bind('mouseleave.chosen', function(evt) {
|
572 |
+
_this.mouse_leave(evt);
|
573 |
+
});
|
574 |
+
this.search_results.bind('mouseup.chosen', function(evt) {
|
575 |
+
_this.search_results_mouseup(evt);
|
576 |
+
});
|
577 |
+
this.search_results.bind('mouseover.chosen', function(evt) {
|
578 |
+
_this.search_results_mouseover(evt);
|
579 |
+
});
|
580 |
+
this.search_results.bind('mouseout.chosen', function(evt) {
|
581 |
+
_this.search_results_mouseout(evt);
|
582 |
+
});
|
583 |
+
this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
|
584 |
+
_this.search_results_mousewheel(evt);
|
585 |
+
});
|
586 |
+
this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
|
587 |
+
_this.results_update_field(evt);
|
588 |
+
});
|
589 |
+
this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
|
590 |
+
_this.activate_field(evt);
|
591 |
+
});
|
592 |
+
this.form_field_jq.bind("chosen:open.chosen", function(evt) {
|
593 |
+
_this.container_mousedown(evt);
|
594 |
+
});
|
595 |
+
this.search_field.bind('blur.chosen', function(evt) {
|
596 |
+
_this.input_blur(evt);
|
597 |
+
});
|
598 |
+
this.search_field.bind('keyup.chosen', function(evt) {
|
599 |
+
_this.keyup_checker(evt);
|
600 |
+
});
|
601 |
+
this.search_field.bind('keydown.chosen', function(evt) {
|
602 |
+
_this.keydown_checker(evt);
|
603 |
+
});
|
604 |
+
this.search_field.bind('focus.chosen', function(evt) {
|
605 |
+
_this.input_focus(evt);
|
606 |
+
});
|
607 |
+
if (this.is_multiple) {
|
608 |
+
return this.search_choices.bind('click.chosen', function(evt) {
|
609 |
+
_this.choices_click(evt);
|
610 |
+
});
|
611 |
+
} else {
|
612 |
+
return this.container.bind('click.chosen', function(evt) {
|
613 |
+
evt.preventDefault();
|
614 |
+
});
|
615 |
+
}
|
616 |
+
};
|
617 |
+
|
618 |
+
Chosen.prototype.destroy = function() {
|
619 |
+
$(document).unbind("click.chosen", this.click_test_action);
|
620 |
+
if (this.search_field[0].tabIndex) {
|
621 |
+
this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
|
622 |
+
}
|
623 |
+
this.container.remove();
|
624 |
+
this.form_field_jq.removeData('chosen');
|
625 |
+
return this.form_field_jq.show();
|
626 |
+
};
|
627 |
+
|
628 |
+
Chosen.prototype.search_field_disabled = function() {
|
629 |
+
this.is_disabled = this.form_field_jq[0].disabled;
|
630 |
+
if (this.is_disabled) {
|
631 |
+
this.container.addClass('chosen-disabled');
|
632 |
+
this.search_field[0].disabled = true;
|
633 |
+
if (!this.is_multiple) {
|
634 |
+
this.selected_item.unbind("focus.chosen", this.activate_action);
|
635 |
+
}
|
636 |
+
return this.close_field();
|
637 |
+
} else {
|
638 |
+
this.container.removeClass('chosen-disabled');
|
639 |
+
this.search_field[0].disabled = false;
|
640 |
+
if (!this.is_multiple) {
|
641 |
+
return this.selected_item.bind("focus.chosen", this.activate_action);
|
642 |
+
}
|
643 |
+
}
|
644 |
+
};
|
645 |
+
|
646 |
+
Chosen.prototype.container_mousedown = function(evt) {
|
647 |
+
if (!this.is_disabled) {
|
648 |
+
if (evt && evt.type === "mousedown" && !this.results_showing) {
|
649 |
+
evt.preventDefault();
|
650 |
+
}
|
651 |
+
if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
|
652 |
+
if (!this.active_field) {
|
653 |
+
if (this.is_multiple) {
|
654 |
+
this.search_field.val("");
|
655 |
+
}
|
656 |
+
$(document).bind('click.chosen', this.click_test_action);
|
657 |
+
this.results_show();
|
658 |
+
} else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
|
659 |
+
evt.preventDefault();
|
660 |
+
this.results_toggle();
|
661 |
+
}
|
662 |
+
return this.activate_field();
|
663 |
+
}
|
664 |
+
}
|
665 |
+
};
|
666 |
+
|
667 |
+
Chosen.prototype.container_mouseup = function(evt) {
|
668 |
+
if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
|
669 |
+
return this.results_reset(evt);
|
670 |
+
}
|
671 |
+
};
|
672 |
+
|
673 |
+
Chosen.prototype.search_results_mousewheel = function(evt) {
|
674 |
+
var delta, _ref1, _ref2;
|
675 |
+
|
676 |
+
delta = -((_ref1 = evt.originalEvent) != null ? _ref1.wheelDelta : void 0) || ((_ref2 = evt.originialEvent) != null ? _ref2.detail : void 0);
|
677 |
+
if (delta != null) {
|
678 |
+
evt.preventDefault();
|
679 |
+
if (evt.type === 'DOMMouseScroll') {
|
680 |
+
delta = delta * 40;
|
681 |
+
}
|
682 |
+
return this.search_results.scrollTop(delta + this.search_results.scrollTop());
|
683 |
+
}
|
684 |
+
};
|
685 |
+
|
686 |
+
Chosen.prototype.blur_test = function(evt) {
|
687 |
+
if (!this.active_field && this.container.hasClass("chosen-container-active")) {
|
688 |
+
return this.close_field();
|
689 |
+
}
|
690 |
+
};
|
691 |
+
|
692 |
+
Chosen.prototype.close_field = function() {
|
693 |
+
$(document).unbind("click.chosen", this.click_test_action);
|
694 |
+
this.active_field = false;
|
695 |
+
this.results_hide();
|
696 |
+
this.container.removeClass("chosen-container-active");
|
697 |
+
this.clear_backstroke();
|
698 |
+
this.show_search_field_default();
|
699 |
+
return this.search_field_scale();
|
700 |
+
};
|
701 |
+
|
702 |
+
Chosen.prototype.activate_field = function() {
|
703 |
+
this.container.addClass("chosen-container-active");
|
704 |
+
this.active_field = true;
|
705 |
+
this.search_field.val(this.search_field.val());
|
706 |
+
return this.search_field.focus();
|
707 |
+
};
|
708 |
+
|
709 |
+
Chosen.prototype.test_active_click = function(evt) {
|
710 |
+
if (this.container.is($(evt.target).closest('.chosen-container'))) {
|
711 |
+
return this.active_field = true;
|
712 |
+
} else {
|
713 |
+
return this.close_field();
|
714 |
+
}
|
715 |
+
};
|
716 |
+
|
717 |
+
Chosen.prototype.results_build = function() {
|
718 |
+
this.parsing = true;
|
719 |
+
this.selected_option_count = null;
|
720 |
+
this.results_data = SelectParser.select_to_array(this.form_field);
|
721 |
+
if (this.is_multiple) {
|
722 |
+
this.search_choices.find("li.search-choice").remove();
|
723 |
+
} else if (!this.is_multiple) {
|
724 |
+
this.single_set_selected_text();
|
725 |
+
if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
|
726 |
+
this.search_field[0].readOnly = true;
|
727 |
+
this.container.addClass("chosen-container-single-nosearch");
|
728 |
+
} else {
|
729 |
+
this.search_field[0].readOnly = false;
|
730 |
+
this.container.removeClass("chosen-container-single-nosearch");
|
731 |
+
}
|
732 |
+
}
|
733 |
+
this.update_results_content(this.results_option_build({
|
734 |
+
first: true
|
735 |
+
}));
|
736 |
+
this.search_field_disabled();
|
737 |
+
this.show_search_field_default();
|
738 |
+
this.search_field_scale();
|
739 |
+
return this.parsing = false;
|
740 |
+
};
|
741 |
+
|
742 |
+
Chosen.prototype.result_do_highlight = function(el) {
|
743 |
+
var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
|
744 |
+
|
745 |
+
if (el.length) {
|
746 |
+
this.result_clear_highlight();
|
747 |
+
this.result_highlight = el;
|
748 |
+
this.result_highlight.addClass("highlighted");
|
749 |
+
maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
|
750 |
+
visible_top = this.search_results.scrollTop();
|
751 |
+
visible_bottom = maxHeight + visible_top;
|
752 |
+
high_top = this.result_highlight.position().top + this.search_results.scrollTop();
|
753 |
+
high_bottom = high_top + this.result_highlight.outerHeight();
|
754 |
+
if (high_bottom >= visible_bottom) {
|
755 |
+
return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
|
756 |
+
} else if (high_top < visible_top) {
|
757 |
+
return this.search_results.scrollTop(high_top);
|
758 |
+
}
|
759 |
+
}
|
760 |
+
};
|
761 |
+
|
762 |
+
Chosen.prototype.result_clear_highlight = function() {
|
763 |
+
if (this.result_highlight) {
|
764 |
+
this.result_highlight.removeClass("highlighted");
|
765 |
+
}
|
766 |
+
return this.result_highlight = null;
|
767 |
+
};
|
768 |
+
|
769 |
+
Chosen.prototype.results_show = function() {
|
770 |
+
if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
|
771 |
+
this.form_field_jq.trigger("chosen:maxselected", {
|
772 |
+
chosen: this
|
773 |
+
});
|
774 |
+
return false;
|
775 |
+
}
|
776 |
+
this.container.addClass("chosen-with-drop");
|
777 |
+
this.form_field_jq.trigger("chosen:showing_dropdown", {
|
778 |
+
chosen: this
|
779 |
+
});
|
780 |
+
this.results_showing = true;
|
781 |
+
this.search_field.focus();
|
782 |
+
this.search_field.val(this.search_field.val());
|
783 |
+
return this.winnow_results();
|
784 |
+
};
|
785 |
+
|
786 |
+
Chosen.prototype.update_results_content = function(content) {
|
787 |
+
return this.search_results.html(content);
|
788 |
+
};
|
789 |
+
|
790 |
+
Chosen.prototype.results_hide = function() {
|
791 |
+
if (this.results_showing) {
|
792 |
+
this.result_clear_highlight();
|
793 |
+
this.container.removeClass("chosen-with-drop");
|
794 |
+
this.form_field_jq.trigger("chosen:hiding_dropdown", {
|
795 |
+
chosen: this
|
796 |
+
});
|
797 |
+
}
|
798 |
+
return this.results_showing = false;
|
799 |
+
};
|
800 |
+
|
801 |
+
Chosen.prototype.set_tab_index = function(el) {
|
802 |
+
var ti;
|
803 |
+
|
804 |
+
if (this.form_field.tabIndex) {
|
805 |
+
ti = this.form_field.tabIndex;
|
806 |
+
this.form_field.tabIndex = -1;
|
807 |
+
return this.search_field[0].tabIndex = ti;
|
808 |
+
}
|
809 |
+
};
|
810 |
+
|
811 |
+
Chosen.prototype.set_label_behavior = function() {
|
812 |
+
var _this = this;
|
813 |
+
|
814 |
+
this.form_field_label = this.form_field_jq.parents("label");
|
815 |
+
if (!this.form_field_label.length && this.form_field.id.length) {
|
816 |
+
this.form_field_label = $("label[for='" + this.form_field.id + "']");
|
817 |
+
}
|
818 |
+
if (this.form_field_label.length > 0) {
|
819 |
+
return this.form_field_label.bind('click.chosen', function(evt) {
|
820 |
+
if (_this.is_multiple) {
|
821 |
+
return _this.container_mousedown(evt);
|
822 |
+
} else {
|
823 |
+
return _this.activate_field();
|
824 |
+
}
|
825 |
+
});
|
826 |
+
}
|
827 |
+
};
|
828 |
+
|
829 |
+
Chosen.prototype.show_search_field_default = function() {
|
830 |
+
if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
|
831 |
+
this.search_field.val(this.default_text);
|
832 |
+
return this.search_field.addClass("default");
|
833 |
+
} else {
|
834 |
+
this.search_field.val("");
|
835 |
+
return this.search_field.removeClass("default");
|
836 |
+
}
|
837 |
+
};
|
838 |
+
|
839 |
+
Chosen.prototype.search_results_mouseup = function(evt) {
|
840 |
+
var target;
|
841 |
+
|
842 |
+
target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
|
843 |
+
if (target.length) {
|
844 |
+
this.result_highlight = target;
|
845 |
+
this.result_select(evt);
|
846 |
+
return this.search_field.focus();
|
847 |
+
}
|
848 |
+
};
|
849 |
+
|
850 |
+
Chosen.prototype.search_results_mouseover = function(evt) {
|
851 |
+
var target;
|
852 |
+
|
853 |
+
target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
|
854 |
+
if (target) {
|
855 |
+
return this.result_do_highlight(target);
|
856 |
+
}
|
857 |
+
};
|
858 |
+
|
859 |
+
Chosen.prototype.search_results_mouseout = function(evt) {
|
860 |
+
if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
|
861 |
+
return this.result_clear_highlight();
|
862 |
+
}
|
863 |
+
};
|
864 |
+
|
865 |
+
Chosen.prototype.choice_build = function(item) {
|
866 |
+
var choice, close_link,
|
867 |
+
_this = this;
|
868 |
+
|
869 |
+
choice = $('<li />', {
|
870 |
+
"class": "search-choice"
|
871 |
+
}).html("<span>" + item.html + "</span>");
|
872 |
+
if (item.disabled) {
|
873 |
+
choice.addClass('search-choice-disabled');
|
874 |
+
} else {
|
875 |
+
close_link = $('<a />', {
|
876 |
+
"class": 'search-choice-close',
|
877 |
+
'data-option-array-index': item.array_index
|
878 |
+
});
|
879 |
+
close_link.bind('click.chosen', function(evt) {
|
880 |
+
return _this.choice_destroy_link_click(evt);
|
881 |
+
});
|
882 |
+
choice.append(close_link);
|
883 |
+
}
|
884 |
+
return this.search_container.before(choice);
|
885 |
+
};
|
886 |
+
|
887 |
+
Chosen.prototype.choice_destroy_link_click = function(evt) {
|
888 |
+
evt.preventDefault();
|
889 |
+
evt.stopPropagation();
|
890 |
+
if (!this.is_disabled) {
|
891 |
+
return this.choice_destroy($(evt.target));
|
892 |
+
}
|
893 |
+
};
|
894 |
+
|
895 |
+
Chosen.prototype.choice_destroy = function(link) {
|
896 |
+
if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
|
897 |
+
this.show_search_field_default();
|
898 |
+
if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
|
899 |
+
this.results_hide();
|
900 |
+
}
|
901 |
+
link.parents('li').first().remove();
|
902 |
+
return this.search_field_scale();
|
903 |
+
}
|
904 |
+
};
|
905 |
+
|
906 |
+
Chosen.prototype.results_reset = function() {
|
907 |
+
this.form_field.options[0].selected = true;
|
908 |
+
this.selected_option_count = null;
|
909 |
+
this.single_set_selected_text();
|
910 |
+
this.show_search_field_default();
|
911 |
+
this.results_reset_cleanup();
|
912 |
+
this.form_field_jq.trigger("change");
|
913 |
+
if (this.active_field) {
|
914 |
+
return this.results_hide();
|
915 |
+
}
|
916 |
+
};
|
917 |
+
|
918 |
+
Chosen.prototype.results_reset_cleanup = function() {
|
919 |
+
this.current_selectedIndex = this.form_field.selectedIndex;
|
920 |
+
return this.selected_item.find("abbr").remove();
|
921 |
+
};
|
922 |
+
|
923 |
+
Chosen.prototype.result_select = function(evt) {
|
924 |
+
var high, item, selected_index;
|
925 |
+
|
926 |
+
if (this.result_highlight) {
|
927 |
+
high = this.result_highlight;
|
928 |
+
this.result_clear_highlight();
|
929 |
+
if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
|
930 |
+
this.form_field_jq.trigger("chosen:maxselected", {
|
931 |
+
chosen: this
|
932 |
+
});
|
933 |
+
return false;
|
934 |
+
}
|
935 |
+
if (this.is_multiple) {
|
936 |
+
high.removeClass("active-result");
|
937 |
+
} else {
|
938 |
+
if (this.result_single_selected) {
|
939 |
+
this.result_single_selected.removeClass("result-selected");
|
940 |
+
selected_index = this.result_single_selected[0].getAttribute('data-option-array-index');
|
941 |
+
this.results_data[selected_index].selected = false;
|
942 |
+
}
|
943 |
+
this.result_single_selected = high;
|
944 |
+
}
|
945 |
+
high.addClass("result-selected");
|
946 |
+
item = this.results_data[high[0].getAttribute("data-option-array-index")];
|
947 |
+
item.selected = true;
|
948 |
+
this.form_field.options[item.options_index].selected = true;
|
949 |
+
this.selected_option_count = null;
|
950 |
+
if (this.is_multiple) {
|
951 |
+
this.choice_build(item);
|
952 |
+
} else {
|
953 |
+
this.single_set_selected_text(item.text);
|
954 |
+
}
|
955 |
+
if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
|
956 |
+
this.results_hide();
|
957 |
+
}
|
958 |
+
this.search_field.val("");
|
959 |
+
if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
|
960 |
+
this.form_field_jq.trigger("change", {
|
961 |
+
'selected': this.form_field.options[item.options_index].value
|
962 |
+
});
|
963 |
+
}
|
964 |
+
this.current_selectedIndex = this.form_field.selectedIndex;
|
965 |
+
return this.search_field_scale();
|
966 |
+
}
|
967 |
+
};
|
968 |
+
|
969 |
+
Chosen.prototype.single_set_selected_text = function(text) {
|
970 |
+
if (text == null) {
|
971 |
+
text = this.default_text;
|
972 |
+
}
|
973 |
+
if (text === this.default_text) {
|
974 |
+
this.selected_item.addClass("chosen-default");
|
975 |
+
} else {
|
976 |
+
this.single_deselect_control_build();
|
977 |
+
this.selected_item.removeClass("chosen-default");
|
978 |
+
}
|
979 |
+
return this.selected_item.find("span").text(text);
|
980 |
+
};
|
981 |
+
|
982 |
+
Chosen.prototype.result_deselect = function(pos) {
|
983 |
+
var result_data;
|
984 |
+
|
985 |
+
result_data = this.results_data[pos];
|
986 |
+
if (!this.form_field.options[result_data.options_index].disabled) {
|
987 |
+
result_data.selected = false;
|
988 |
+
this.form_field.options[result_data.options_index].selected = false;
|
989 |
+
this.selected_option_count = null;
|
990 |
+
this.result_clear_highlight();
|
991 |
+
if (this.results_showing) {
|
992 |
+
this.winnow_results();
|
993 |
+
}
|
994 |
+
this.form_field_jq.trigger("change", {
|
995 |
+
deselected: this.form_field.options[result_data.options_index].value
|
996 |
+
});
|
997 |
+
this.search_field_scale();
|
998 |
+
return true;
|
999 |
+
} else {
|
1000 |
+
return false;
|
1001 |
+
}
|
1002 |
+
};
|
1003 |
+
|
1004 |
+
Chosen.prototype.single_deselect_control_build = function() {
|
1005 |
+
if (!this.allow_single_deselect) {
|
1006 |
+
return;
|
1007 |
+
}
|
1008 |
+
if (!this.selected_item.find("abbr").length) {
|
1009 |
+
this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
|
1010 |
+
}
|
1011 |
+
return this.selected_item.addClass("chosen-single-with-deselect");
|
1012 |
+
};
|
1013 |
+
|
1014 |
+
Chosen.prototype.get_search_text = function() {
|
1015 |
+
if (this.search_field.val() === this.default_text) {
|
1016 |
+
return "";
|
1017 |
+
} else {
|
1018 |
+
return $('<div/>').text($.trim(this.search_field.val())).html();
|
1019 |
+
}
|
1020 |
+
};
|
1021 |
+
|
1022 |
+
Chosen.prototype.winnow_results_set_highlight = function() {
|
1023 |
+
var do_high, selected_results;
|
1024 |
+
|
1025 |
+
selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
|
1026 |
+
do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
|
1027 |
+
if (do_high != null) {
|
1028 |
+
return this.result_do_highlight(do_high);
|
1029 |
+
}
|
1030 |
+
};
|
1031 |
+
|
1032 |
+
Chosen.prototype.no_results = function(terms) {
|
1033 |
+
var no_results_html;
|
1034 |
+
|
1035 |
+
no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
|
1036 |
+
no_results_html.find("span").first().html(terms);
|
1037 |
+
return this.search_results.append(no_results_html);
|
1038 |
+
};
|
1039 |
+
|
1040 |
+
Chosen.prototype.no_results_clear = function() {
|
1041 |
+
return this.search_results.find(".no-results").remove();
|
1042 |
+
};
|
1043 |
+
|
1044 |
+
Chosen.prototype.keydown_arrow = function() {
|
1045 |
+
var next_sib;
|
1046 |
+
|
1047 |
+
if (this.results_showing && this.result_highlight) {
|
1048 |
+
next_sib = this.result_highlight.nextAll("li.active-result").first();
|
1049 |
+
if (next_sib) {
|
1050 |
+
return this.result_do_highlight(next_sib);
|
1051 |
+
}
|
1052 |
+
} else {
|
1053 |
+
return this.results_show();
|
1054 |
+
}
|
1055 |
+
};
|
1056 |
+
|
1057 |
+
Chosen.prototype.keyup_arrow = function() {
|
1058 |
+
var prev_sibs;
|
1059 |
+
|
1060 |
+
if (!this.results_showing && !this.is_multiple) {
|
1061 |
+
return this.results_show();
|
1062 |
+
} else if (this.result_highlight) {
|
1063 |
+
prev_sibs = this.result_highlight.prevAll("li.active-result");
|
1064 |
+
if (prev_sibs.length) {
|
1065 |
+
return this.result_do_highlight(prev_sibs.first());
|
1066 |
+
} else {
|
1067 |
+
if (this.choices_count() > 0) {
|
1068 |
+
this.results_hide();
|
1069 |
+
}
|
1070 |
+
return this.result_clear_highlight();
|
1071 |
+
}
|
1072 |
+
}
|
1073 |
+
};
|
1074 |
+
|
1075 |
+
Chosen.prototype.keydown_backstroke = function() {
|
1076 |
+
var next_available_destroy;
|
1077 |
+
|
1078 |
+
if (this.pending_backstroke) {
|
1079 |
+
this.choice_destroy(this.pending_backstroke.find("a").first());
|
1080 |
+
return this.clear_backstroke();
|
1081 |
+
} else {
|
1082 |
+
next_available_destroy = this.search_container.siblings("li.search-choice").last();
|
1083 |
+
if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
|
1084 |
+
this.pending_backstroke = next_available_destroy;
|
1085 |
+
if (this.single_backstroke_delete) {
|
1086 |
+
return this.keydown_backstroke();
|
1087 |
+
} else {
|
1088 |
+
return this.pending_backstroke.addClass("search-choice-focus");
|
1089 |
+
}
|
1090 |
+
}
|
1091 |
+
}
|
1092 |
+
};
|
1093 |
+
|
1094 |
+
Chosen.prototype.clear_backstroke = function() {
|
1095 |
+
if (this.pending_backstroke) {
|
1096 |
+
this.pending_backstroke.removeClass("search-choice-focus");
|
1097 |
+
}
|
1098 |
+
return this.pending_backstroke = null;
|
1099 |
+
};
|
1100 |
+
|
1101 |
+
Chosen.prototype.keydown_checker = function(evt) {
|
1102 |
+
var stroke, _ref1;
|
1103 |
+
|
1104 |
+
stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
|
1105 |
+
this.search_field_scale();
|
1106 |
+
if (stroke !== 8 && this.pending_backstroke) {
|
1107 |
+
this.clear_backstroke();
|
1108 |
+
}
|
1109 |
+
switch (stroke) {
|
1110 |
+
case 8:
|
1111 |
+
this.backstroke_length = this.search_field.val().length;
|
1112 |
+
break;
|
1113 |
+
case 9:
|
1114 |
+
if (this.results_showing && !this.is_multiple) {
|
1115 |
+
this.result_select(evt);
|
1116 |
+
}
|
1117 |
+
this.mouse_on_container = false;
|
1118 |
+
break;
|
1119 |
+
case 13:
|
1120 |
+
evt.preventDefault();
|
1121 |
+
break;
|
1122 |
+
case 38:
|
1123 |
+
evt.preventDefault();
|
1124 |
+
this.keyup_arrow();
|
1125 |
+
break;
|
1126 |
+
case 40:
|
1127 |
+
evt.preventDefault();
|
1128 |
+
this.keydown_arrow();
|
1129 |
+
break;
|
1130 |
+
}
|
1131 |
+
};
|
1132 |
+
|
1133 |
+
Chosen.prototype.search_field_scale = function() {
|
1134 |
+
var div, f_width, h, style, style_block, styles, w, _i, _len;
|
1135 |
+
|
1136 |
+
if (this.is_multiple) {
|
1137 |
+
h = 0;
|
1138 |
+
w = 0;
|
1139 |
+
style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
|
1140 |
+
styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
|
1141 |
+
for (_i = 0, _len = styles.length; _i < _len; _i++) {
|
1142 |
+
style = styles[_i];
|
1143 |
+
style_block += style + ":" + this.search_field.css(style) + ";";
|
1144 |
+
}
|
1145 |
+
div = $('<div />', {
|
1146 |
+
'style': style_block
|
1147 |
+
});
|
1148 |
+
div.text(this.search_field.val());
|
1149 |
+
$('body').append(div);
|
1150 |
+
w = div.width() + 25;
|
1151 |
+
div.remove();
|
1152 |
+
f_width = this.container.outerWidth();
|
1153 |
+
if (w > f_width - 10) {
|
1154 |
+
w = f_width - 10;
|
1155 |
+
}
|
1156 |
+
return this.search_field.css({
|
1157 |
+
'width': w + 'px'
|
1158 |
+
});
|
1159 |
+
}
|
1160 |
+
};
|
1161 |
+
|
1162 |
+
return Chosen;
|
1163 |
+
|
1164 |
+
})(AbstractChosen);
|
1165 |
+
|
1166 |
+
}).call(this);
|
classes/styles-font-menu/js/chosen/chosen.jquery.min.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
/* Chosen v1.0.0 | (c) 2011-2013 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
|
2 |
!function(){var a,AbstractChosen,Chosen,SelectParser,b,c={}.hasOwnProperty,d=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),children:0,disabled:a.disabled}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"<",">":">",'"':""","'":"'","`":"`"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.result_single_selected=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(c.text));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=""!==a.style.cssText?' style="'+a.style+'"':"",'<li class="'+b.join(" ")+'"'+c+' data-option-array-index="'+a.array_index+'">'+a.search_text+"</li>"):"":""},AbstractChosen.prototype.result_add_group=function(a){return a.search_match||a.group_match?a.active_options>0?'<li class="group-result">'+a.search_text+"</li>":"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.result_single_selected=null,this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m;for(this.no_results_clear(),e=0,g=this.get_search_text(),a=g.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),d=this.search_contains?"":"^",c=new RegExp(d+a,"i"),j=new RegExp(a,"i"),m=this.results_data,k=0,l=m.length;l>k;k++)b=m[k],b.search_match=!1,f=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(f=this.results_data[b.group_array_index],0===f.active_options&&f.search_match&&(e+=1),f.active_options+=1),(!b.group||this.group_search)&&(b.search_text=b.group?b.label:b.html,b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(e+=1),b.search_match?(g.length&&(h=b.search_text.search(j),i=b.search_text.substr(0,h+g.length)+"</em>"+b.search_text.substr(h+g.length),b.search_text=i.substr(0,h)+"<em>"+i.substr(h)),null!=f&&(f.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>e&&g.length?(this.update_results_content(""),this.no_results(g)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),a=jQuery,a.fn.extend({chosen:function(b){return AbstractChosen.browser_is_supported()?this.each(function(){var c,d;c=a(this),d=c.data("chosen"),"destroy"===b&&d?d.destroy():d||c.data("chosen",new Chosen(this,b))}):this}}),Chosen=function(c){function Chosen(){return b=Chosen.__super__.constructor.apply(this,arguments)}return d(Chosen,c),Chosen.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},Chosen.prototype.set_up_html=function(){var b,c;return b=["chosen-container"],b.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&b.push(this.form_field.className),this.is_rtl&&b.push("chosen-rtl"),c={"class":b.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(c.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=a("<div />",c),this.is_multiple?this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="'+this.default_text+'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>'):this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>'+this.default_text+'</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>'),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.results_build(),this.set_tab_index(),this.set_label_behavior(),this.form_field_jq.trigger("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.bind("mousedown.chosen",function(b){a.container_mousedown(b)}),this.container.bind("mouseup.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mouseenter.chosen",function(b){a.mouse_enter(b)}),this.container.bind("mouseleave.chosen",function(b){a.mouse_leave(b)}),this.search_results.bind("mouseup.chosen",function(b){a.search_results_mouseup(b)}),this.search_results.bind("mouseover.chosen",function(b){a.search_results_mouseover(b)}),this.search_results.bind("mouseout.chosen",function(b){a.search_results_mouseout(b)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(b){a.search_results_mousewheel(b)}),this.form_field_jq.bind("chosen:updated.chosen",function(b){a.results_update_field(b)}),this.form_field_jq.bind("chosen:activate.chosen",function(b){a.activate_field(b)}),this.form_field_jq.bind("chosen:open.chosen",function(b){a.container_mousedown(b)}),this.search_field.bind("blur.chosen",function(b){a.input_blur(b)}),this.search_field.bind("keyup.chosen",function(b){a.keyup_checker(b)}),this.search_field.bind("keydown.chosen",function(b){a.keydown_checker(b)}),this.search_field.bind("focus.chosen",function(b){a.input_focus(b)}),this.is_multiple?this.search_choices.bind("click.chosen",function(b){a.choices_click(b)}):this.container.bind("click.chosen",function(a){a.preventDefault()})},Chosen.prototype.destroy=function(){return a(document).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},Chosen.prototype.container_mousedown=function(b){return this.is_disabled||(b&&"mousedown"===b.type&&!this.results_showing&&b.preventDefault(),null!=b&&a(b.target).hasClass("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!b||a(b.target)[0]!==this.selected_item[0]&&!a(b.target).parents("a.chosen-single").length||(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(document).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b,c,d;return b=-(null!=(c=a.originalEvent)?c.wheelDelta:void 0)||(null!=(d=a.originialEvent)?d.detail:void 0),null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop(b+this.search_results.scrollTop())):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClass("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return a(document).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},Chosen.prototype.test_active_click=function(b){return this.container.is(a(b.target).closest(".chosen-container"))?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){if(this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight(),b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(f>c)return this.search_results.scrollTop(c)}},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.container.addClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:showing_dropdown",{chosen:this}),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results())},Chosen.prototype.update_results_content=function(a){return this.search_results.html(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var b=this;return this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=a("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0?this.form_field_label.bind("click.chosen",function(a){return b.is_multiple?b.container_mousedown(a):b.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},Chosen.prototype.search_results_mouseup=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c.length?(this.result_highlight=c,this.result_select(b),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c?this.result_do_highlight(c):void 0},Chosen.prototype.search_results_mouseout=function(b){return a(b.target).hasClass("active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(b){var c,d,e=this;return c=a("<li />",{"class":"search-choice"}).html("<span>"+b.html+"</span>"),b.disabled?c.addClass("search-choice-disabled"):(d=a("<a />",{"class":"search-choice-close","data-option-array-index":b.array_index}),d.bind("click.chosen",function(a){return e.choice_destroy_link_click(a)}),c.append(d)),this.search_container.before(c)},Chosen.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),b.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a(b.target))},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a[0].getAttribute("data-option-array-index"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),a.parents("li").first().remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.form_field.options[0].selected=!0,this.selected_option_count=null,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},Chosen.prototype.result_select=function(a){var b,c,d;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClass("active-result"):(this.result_single_selected&&(this.result_single_selected.removeClass("result-selected"),d=this.result_single_selected[0].getAttribute("data-option-array-index"),this.results_data[d].selected=!1),this.result_single_selected=b),b.addClass("result-selected"),c=this.results_data[b[0].getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(c.text),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[c.options_index].value}),this.current_selectedIndex=this.form_field.selectedIndex,this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.selected_item.find("span").text(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[b.options_index].value}),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.find("abbr").length||this.selected_item.find("span").first().after('<abbr class="search-choice-close"></abbr>'),this.selected_item.addClass("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return this.search_field.val()===this.default_text?"":a("<div/>").text(a.trim(this.search_field.val())).html()},Chosen.prototype.winnow_results_set_highlight=function(){var a,b;return b=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),a=b.length?b.first():this.search_results.find(".active-result").first(),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(b){var c;return c=a('<li class="no-results">'+this.results_none_found+' "<span></span>"</li>'),c.find("span").first().html(b),this.search_results.append(c)},Chosen.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a;return this.results_showing||this.is_multiple?this.result_highlight?(a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(a=this.search_container.siblings("li.search-choice").last(),a.length&&!a.hasClass("search-choice-disabled")?(this.pending_backstroke=a,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){for(d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],i=0,j=g.length;j>i;i++)e=g[i],f+=e+":"+this.search_field.css(e)+";";return b=a("<div />",{style:f}),b.text(this.search_field.val()),a("body").append(b),h=b.width()+25,b.remove(),c=this.container.outerWidth(),h>c-10&&(h=c-10),this.search_field.css({width:h+"px"})}},Chosen}(AbstractChosen)}.call(this);
|
1 |
+
/* Chosen v1.0.0 | (c) 2011-2013 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
|
2 |
!function(){var a,AbstractChosen,Chosen,SelectParser,b,c={}.hasOwnProperty,d=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),children:0,disabled:a.disabled}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"<",">":">",'"':""","'":"'","`":"`"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.result_single_selected=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(c.text));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=""!==a.style.cssText?' style="'+a.style+'"':"",'<li class="'+b.join(" ")+'"'+c+' data-option-array-index="'+a.array_index+'">'+a.search_text+"</li>"):"":""},AbstractChosen.prototype.result_add_group=function(a){return a.search_match||a.group_match?a.active_options>0?'<li class="group-result">'+a.search_text+"</li>":"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.result_single_selected=null,this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m;for(this.no_results_clear(),e=0,g=this.get_search_text(),a=g.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),d=this.search_contains?"":"^",c=new RegExp(d+a,"i"),j=new RegExp(a,"i"),m=this.results_data,k=0,l=m.length;l>k;k++)b=m[k],b.search_match=!1,f=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(f=this.results_data[b.group_array_index],0===f.active_options&&f.search_match&&(e+=1),f.active_options+=1),(!b.group||this.group_search)&&(b.search_text=b.group?b.label:b.html,b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(e+=1),b.search_match?(g.length&&(h=b.search_text.search(j),i=b.search_text.substr(0,h+g.length)+"</em>"+b.search_text.substr(h+g.length),b.search_text=i.substr(0,h)+"<em>"+i.substr(h)),null!=f&&(f.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>e&&g.length?(this.update_results_content(""),this.no_results(g)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),a=jQuery,a.fn.extend({chosen:function(b){return AbstractChosen.browser_is_supported()?this.each(function(){var c,d;c=a(this),d=c.data("chosen"),"destroy"===b&&d?d.destroy():d||c.data("chosen",new Chosen(this,b))}):this}}),Chosen=function(c){function Chosen(){return b=Chosen.__super__.constructor.apply(this,arguments)}return d(Chosen,c),Chosen.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},Chosen.prototype.set_up_html=function(){var b,c;return b=["chosen-container"],b.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&b.push(this.form_field.className),this.is_rtl&&b.push("chosen-rtl"),c={"class":b.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(c.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=a("<div />",c),this.is_multiple?this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="'+this.default_text+'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>'):this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>'+this.default_text+'</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>'),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.results_build(),this.set_tab_index(),this.set_label_behavior(),this.form_field_jq.trigger("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.bind("mousedown.chosen",function(b){a.container_mousedown(b)}),this.container.bind("mouseup.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mouseenter.chosen",function(b){a.mouse_enter(b)}),this.container.bind("mouseleave.chosen",function(b){a.mouse_leave(b)}),this.search_results.bind("mouseup.chosen",function(b){a.search_results_mouseup(b)}),this.search_results.bind("mouseover.chosen",function(b){a.search_results_mouseover(b)}),this.search_results.bind("mouseout.chosen",function(b){a.search_results_mouseout(b)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(b){a.search_results_mousewheel(b)}),this.form_field_jq.bind("chosen:updated.chosen",function(b){a.results_update_field(b)}),this.form_field_jq.bind("chosen:activate.chosen",function(b){a.activate_field(b)}),this.form_field_jq.bind("chosen:open.chosen",function(b){a.container_mousedown(b)}),this.search_field.bind("blur.chosen",function(b){a.input_blur(b)}),this.search_field.bind("keyup.chosen",function(b){a.keyup_checker(b)}),this.search_field.bind("keydown.chosen",function(b){a.keydown_checker(b)}),this.search_field.bind("focus.chosen",function(b){a.input_focus(b)}),this.is_multiple?this.search_choices.bind("click.chosen",function(b){a.choices_click(b)}):this.container.bind("click.chosen",function(a){a.preventDefault()})},Chosen.prototype.destroy=function(){return a(document).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},Chosen.prototype.container_mousedown=function(b){return this.is_disabled||(b&&"mousedown"===b.type&&!this.results_showing&&b.preventDefault(),null!=b&&a(b.target).hasClass("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!b||a(b.target)[0]!==this.selected_item[0]&&!a(b.target).parents("a.chosen-single").length||(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(document).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b,c,d;return b=-(null!=(c=a.originalEvent)?c.wheelDelta:void 0)||(null!=(d=a.originialEvent)?d.detail:void 0),null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop(b+this.search_results.scrollTop())):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClass("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return a(document).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},Chosen.prototype.test_active_click=function(b){return this.container.is(a(b.target).closest(".chosen-container"))?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){if(this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight(),b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(f>c)return this.search_results.scrollTop(c)}},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.container.addClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:showing_dropdown",{chosen:this}),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results())},Chosen.prototype.update_results_content=function(a){return this.search_results.html(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var b=this;return this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=a("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0?this.form_field_label.bind("click.chosen",function(a){return b.is_multiple?b.container_mousedown(a):b.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},Chosen.prototype.search_results_mouseup=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c.length?(this.result_highlight=c,this.result_select(b),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c?this.result_do_highlight(c):void 0},Chosen.prototype.search_results_mouseout=function(b){return a(b.target).hasClass("active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(b){var c,d,e=this;return c=a("<li />",{"class":"search-choice"}).html("<span>"+b.html+"</span>"),b.disabled?c.addClass("search-choice-disabled"):(d=a("<a />",{"class":"search-choice-close","data-option-array-index":b.array_index}),d.bind("click.chosen",function(a){return e.choice_destroy_link_click(a)}),c.append(d)),this.search_container.before(c)},Chosen.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),b.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a(b.target))},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a[0].getAttribute("data-option-array-index"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),a.parents("li").first().remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.form_field.options[0].selected=!0,this.selected_option_count=null,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},Chosen.prototype.result_select=function(a){var b,c,d;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClass("active-result"):(this.result_single_selected&&(this.result_single_selected.removeClass("result-selected"),d=this.result_single_selected[0].getAttribute("data-option-array-index"),this.results_data[d].selected=!1),this.result_single_selected=b),b.addClass("result-selected"),c=this.results_data[b[0].getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(c.text),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[c.options_index].value}),this.current_selectedIndex=this.form_field.selectedIndex,this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.selected_item.find("span").text(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[b.options_index].value}),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.find("abbr").length||this.selected_item.find("span").first().after('<abbr class="search-choice-close"></abbr>'),this.selected_item.addClass("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return this.search_field.val()===this.default_text?"":a("<div/>").text(a.trim(this.search_field.val())).html()},Chosen.prototype.winnow_results_set_highlight=function(){var a,b;return b=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),a=b.length?b.first():this.search_results.find(".active-result").first(),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(b){var c;return c=a('<li class="no-results">'+this.results_none_found+' "<span></span>"</li>'),c.find("span").first().html(b),this.search_results.append(c)},Chosen.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a;return this.results_showing||this.is_multiple?this.result_highlight?(a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(a=this.search_container.siblings("li.search-choice").last(),a.length&&!a.hasClass("search-choice-disabled")?(this.pending_backstroke=a,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){for(d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],i=0,j=g.length;j>i;i++)e=g[i],f+=e+":"+this.search_field.css(e)+";";return b=a("<div />",{style:f}),b.text(this.search_field.val()),a("body").append(b),h=b.width()+25,b.remove(),c=this.container.outerWidth(),h>c-10&&(h=c-10),this.search_field.css({width:h+"px"})}},Chosen}(AbstractChosen)}.call(this);
|
classes/styles-font-menu/js/chosen/chosen.min.css
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
-
/* Chosen v1.0.0 | (c) 2011-2013 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
|
2 |
-
|
3 |
.chosen-container{position:relative;display:inline-block;vertical-align:middle;font-size:13px;zoom:1;*display:inline;-webkit-user-select:none;-moz-user-select:none;user-select:none}.chosen-container .chosen-drop{position:absolute;top:100%;left:-9999px;z-index:1010;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:100%;border:1px solid #aaa;border-top:0;background:#fff;box-shadow:0 4px 5px rgba(0,0,0,.15)}.chosen-container.chosen-with-drop .chosen-drop{left:0}.chosen-container a{cursor:pointer}.chosen-container-single .chosen-single{position:relative;display:block;overflow:hidden;padding:0 0 0 8px;height:23px;border:1px solid #aaa;border-radius:5px;background-color:#fff;background:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#fff),color-stop(50%,#f6f6f6),color-stop(52%,#eee),color-stop(100%,#f4f4f4));background:-webkit-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-moz-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-o-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background-clip:padding-box;box-shadow:0 0 3px #fff inset,0 1px 1px rgba(0,0,0,.1);color:#444;text-decoration:none;white-space:nowrap;line-height:24px}.chosen-container-single .chosen-default{color:#999}.chosen-container-single .chosen-single span{display:block;overflow:hidden;margin-right:26px;text-overflow:ellipsis;white-space:nowrap}.chosen-container-single .chosen-single-with-deselect span{margin-right:38px}.chosen-container-single .chosen-single abbr{position:absolute;top:6px;right:26px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-single .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single.chosen-disabled .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single .chosen-single div{position:absolute;top:0;right:0;display:block;width:18px;height:100%}.chosen-container-single .chosen-single div b{display:block;width:100%;height:100%;background:url(chosen-sprite.png) no-repeat 0 2px}.chosen-container-single .chosen-search{position:relative;z-index:1010;margin:0;padding:3px 4px;white-space:nowrap}.chosen-container-single .chosen-search input[type=text]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:1px 0;padding:4px 20px 4px 5px;width:100%;height:auto;outline:0;border:1px solid #aaa;background:#fff url(chosen-sprite.png) no-repeat 100% -20px;background:url(chosen-sprite.png) no-repeat 100% -20px,-webkit-gradient(linear,50% 0,50% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background:url(chosen-sprite.png) no-repeat 100% -20px,-webkit-linear-gradient(#eee 1%,#fff 15%);background:url(chosen-sprite.png) no-repeat 100% -20px,-moz-linear-gradient(#eee 1%,#fff 15%);background:url(chosen-sprite.png) no-repeat 100% -20px,-o-linear-gradient(#eee 1%,#fff 15%);background:url(chosen-sprite.png) no-repeat 100% -20px,linear-gradient(#eee 1%,#fff 15%);font-size:1em;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-single .chosen-drop{margin-top:-1px;border-radius:0 0 4px 4px;background-clip:padding-box}.chosen-container-single.chosen-container-single-nosearch .chosen-search{position:absolute;left:-9999px}.chosen-container .chosen-results{position:relative;overflow-x:hidden;overflow-y:auto;margin:0 4px 4px 0;padding:0 0 0 4px;max-height:240px;-webkit-overflow-scrolling:touch}.chosen-container .chosen-results li{display:none;margin:0;padding:5px 6px;list-style:none;line-height:15px}.chosen-container .chosen-results li.active-result{display:list-item;cursor:pointer}.chosen-container .chosen-results li.disabled-result{display:list-item;color:#ccc;cursor:default}.chosen-container .chosen-results li.highlighted{background-color:#3875d7;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#3875d7),color-stop(90%,#2a62bc));background-image:-webkit-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-moz-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-o-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:linear-gradient(#3875d7 20%,#2a62bc 90%);color:#fff}.chosen-container .chosen-results li.no-results{display:list-item;background:#f4f4f4}.chosen-container .chosen-results li.group-result{display:list-item;font-weight:700;cursor:default}.chosen-container .chosen-results li.group-option{padding-left:15px}.chosen-container .chosen-results li em{font-style:normal;text-decoration:underline}.chosen-container-multi .chosen-choices{position:relative;overflow:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;width:100%;height:auto!important;height:1%;border:1px solid #aaa;background-color:#fff;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background-image:-webkit-linear-gradient(#eee 1%,#fff 15%);background-image:-moz-linear-gradient(#eee 1%,#fff 15%);background-image:-o-linear-gradient(#eee 1%,#fff 15%);background-image:linear-gradient(#eee 1%,#fff 15%);cursor:text}.chosen-container-multi .chosen-choices li{float:left;list-style:none}.chosen-container-multi .chosen-choices li.search-field{margin:0;padding:0;white-space:nowrap}.chosen-container-multi .chosen-choices li.search-field input[type=text]{margin:1px 0;padding:5px;height:15px;outline:0;border:0!important;background:transparent!important;box-shadow:none;color:#666;font-size:100%;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-multi .chosen-choices li.search-field .default{color:#999}.chosen-container-multi .chosen-choices li.search-choice{position:relative;margin:3px 0 3px 5px;padding:3px 20px 3px 5px;border:1px solid #aaa;border-radius:3px;background-color:#e4e4e4;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-clip:padding-box;box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);color:#333;line-height:13px;cursor:default}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close{position:absolute;top:4px;right:3px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover{background-position:-42px -10px}.chosen-container-multi .chosen-choices li.search-choice-disabled{padding-right:5px;border:1px solid #ccc;background-color:#e4e4e4;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);color:#666}.chosen-container-multi .chosen-choices li.search-choice-focus{background:#d4d4d4}.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close{background-position:-42px -10px}.chosen-container-multi .chosen-results{margin:0;padding:0}.chosen-container-multi .chosen-drop .result-selected{display:list-item;color:#ccc;cursor:default}.chosen-container-active .chosen-single{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active.chosen-with-drop .chosen-single{border:1px solid #aaa;-moz-border-radius-bottomright:0;border-bottom-right-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#eee),color-stop(80%,#fff));background-image:-webkit-linear-gradient(#eee 20%,#fff 80%);background-image:-moz-linear-gradient(#eee 20%,#fff 80%);background-image:-o-linear-gradient(#eee 20%,#fff 80%);background-image:linear-gradient(#eee 20%,#fff 80%);box-shadow:0 1px 0 #fff inset}.chosen-container-active.chosen-with-drop .chosen-single div{border-left:0;background:transparent}.chosen-container-active.chosen-with-drop .chosen-single div b{background-position:-18px 2px}.chosen-container-active .chosen-choices{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active .chosen-choices li.search-field input[type=text]{color:#111!important}.chosen-disabled{opacity:.5!important;cursor:default}.chosen-disabled .chosen-single{cursor:default}.chosen-disabled .chosen-choices .search-choice .search-choice-close{cursor:default}.chosen-rtl{text-align:right}.chosen-rtl .chosen-single{overflow:visible;padding:0 8px 0 0}.chosen-rtl .chosen-single span{margin-right:0;margin-left:26px;direction:rtl}.chosen-rtl .chosen-single-with-deselect span{margin-left:38px}.chosen-rtl .chosen-single div{right:auto;left:3px}.chosen-rtl .chosen-single abbr{right:auto;left:26px}.chosen-rtl .chosen-choices li{float:right}.chosen-rtl .chosen-choices li.search-field input[type=text]{direction:rtl}.chosen-rtl .chosen-choices li.search-choice{margin:3px 5px 3px 0;padding:3px 5px 3px 19px}.chosen-rtl .chosen-choices li.search-choice .search-choice-close{right:auto;left:4px}.chosen-rtl.chosen-container-single-nosearch .chosen-search,.chosen-rtl .chosen-drop{left:9999px}.chosen-rtl.chosen-container-single .chosen-results{margin:0 0 4px 4px;padding:0 4px 0 0}.chosen-rtl .chosen-results li.group-option{padding-right:15px;padding-left:0}.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div{border-right:0}.chosen-rtl .chosen-search input[type=text]{padding:4px 5px 4px 20px;background:#fff url(chosen-sprite.png) no-repeat -30px -20px;background:url(chosen-sprite.png) no-repeat -30px -20px,-webkit-gradient(linear,50% 0,50% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background:url(chosen-sprite.png) no-repeat -30px -20px,-webkit-linear-gradient(#eee 1%,#fff 15%);background:url(chosen-sprite.png) no-repeat -30px -20px,-moz-linear-gradient(#eee 1%,#fff 15%);background:url(chosen-sprite.png) no-repeat -30px -20px,-o-linear-gradient(#eee 1%,#fff 15%);background:url(chosen-sprite.png) no-repeat -30px -20px,linear-gradient(#eee 1%,#fff 15%);direction:rtl}.chosen-rtl.chosen-container-single .chosen-single div b{background-position:6px 2px}.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b{background-position:-12px 2px}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-resolution:144dpi){.chosen-rtl .chosen-search input[type=text],.chosen-container-single .chosen-single abbr,.chosen-container-single .chosen-single div b,.chosen-container-single .chosen-search input[type=text],.chosen-container-multi .chosen-choices .search-choice .search-choice-close,.chosen-container .chosen-results-scroll-down span,.chosen-container .chosen-results-scroll-up span{background-image:url(chosen-sprite@2x.png)!important;background-size:52px 37px!important;background-repeat:no-repeat!important}}
|
1 |
+
/* Chosen v1.0.0 | (c) 2011-2013 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
|
2 |
+
|
3 |
.chosen-container{position:relative;display:inline-block;vertical-align:middle;font-size:13px;zoom:1;*display:inline;-webkit-user-select:none;-moz-user-select:none;user-select:none}.chosen-container .chosen-drop{position:absolute;top:100%;left:-9999px;z-index:1010;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:100%;border:1px solid #aaa;border-top:0;background:#fff;box-shadow:0 4px 5px rgba(0,0,0,.15)}.chosen-container.chosen-with-drop .chosen-drop{left:0}.chosen-container a{cursor:pointer}.chosen-container-single .chosen-single{position:relative;display:block;overflow:hidden;padding:0 0 0 8px;height:23px;border:1px solid #aaa;border-radius:5px;background-color:#fff;background:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#fff),color-stop(50%,#f6f6f6),color-stop(52%,#eee),color-stop(100%,#f4f4f4));background:-webkit-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-moz-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-o-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background-clip:padding-box;box-shadow:0 0 3px #fff inset,0 1px 1px rgba(0,0,0,.1);color:#444;text-decoration:none;white-space:nowrap;line-height:24px}.chosen-container-single .chosen-default{color:#999}.chosen-container-single .chosen-single span{display:block;overflow:hidden;margin-right:26px;text-overflow:ellipsis;white-space:nowrap}.chosen-container-single .chosen-single-with-deselect span{margin-right:38px}.chosen-container-single .chosen-single abbr{position:absolute;top:6px;right:26px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-single .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single.chosen-disabled .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single .chosen-single div{position:absolute;top:0;right:0;display:block;width:18px;height:100%}.chosen-container-single .chosen-single div b{display:block;width:100%;height:100%;background:url(chosen-sprite.png) no-repeat 0 2px}.chosen-container-single .chosen-search{position:relative;z-index:1010;margin:0;padding:3px 4px;white-space:nowrap}.chosen-container-single .chosen-search input[type=text]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:1px 0;padding:4px 20px 4px 5px;width:100%;height:auto;outline:0;border:1px solid #aaa;background:#fff url(chosen-sprite.png) no-repeat 100% -20px;background:url(chosen-sprite.png) no-repeat 100% -20px,-webkit-gradient(linear,50% 0,50% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background:url(chosen-sprite.png) no-repeat 100% -20px,-webkit-linear-gradient(#eee 1%,#fff 15%);background:url(chosen-sprite.png) no-repeat 100% -20px,-moz-linear-gradient(#eee 1%,#fff 15%);background:url(chosen-sprite.png) no-repeat 100% -20px,-o-linear-gradient(#eee 1%,#fff 15%);background:url(chosen-sprite.png) no-repeat 100% -20px,linear-gradient(#eee 1%,#fff 15%);font-size:1em;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-single .chosen-drop{margin-top:-1px;border-radius:0 0 4px 4px;background-clip:padding-box}.chosen-container-single.chosen-container-single-nosearch .chosen-search{position:absolute;left:-9999px}.chosen-container .chosen-results{position:relative;overflow-x:hidden;overflow-y:auto;margin:0 4px 4px 0;padding:0 0 0 4px;max-height:240px;-webkit-overflow-scrolling:touch}.chosen-container .chosen-results li{display:none;margin:0;padding:5px 6px;list-style:none;line-height:15px}.chosen-container .chosen-results li.active-result{display:list-item;cursor:pointer}.chosen-container .chosen-results li.disabled-result{display:list-item;color:#ccc;cursor:default}.chosen-container .chosen-results li.highlighted{background-color:#3875d7;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#3875d7),color-stop(90%,#2a62bc));background-image:-webkit-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-moz-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-o-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:linear-gradient(#3875d7 20%,#2a62bc 90%);color:#fff}.chosen-container .chosen-results li.no-results{display:list-item;background:#f4f4f4}.chosen-container .chosen-results li.group-result{display:list-item;font-weight:700;cursor:default}.chosen-container .chosen-results li.group-option{padding-left:15px}.chosen-container .chosen-results li em{font-style:normal;text-decoration:underline}.chosen-container-multi .chosen-choices{position:relative;overflow:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;width:100%;height:auto!important;height:1%;border:1px solid #aaa;background-color:#fff;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background-image:-webkit-linear-gradient(#eee 1%,#fff 15%);background-image:-moz-linear-gradient(#eee 1%,#fff 15%);background-image:-o-linear-gradient(#eee 1%,#fff 15%);background-image:linear-gradient(#eee 1%,#fff 15%);cursor:text}.chosen-container-multi .chosen-choices li{float:left;list-style:none}.chosen-container-multi .chosen-choices li.search-field{margin:0;padding:0;white-space:nowrap}.chosen-container-multi .chosen-choices li.search-field input[type=text]{margin:1px 0;padding:5px;height:15px;outline:0;border:0!important;background:transparent!important;box-shadow:none;color:#666;font-size:100%;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-multi .chosen-choices li.search-field .default{color:#999}.chosen-container-multi .chosen-choices li.search-choice{position:relative;margin:3px 0 3px 5px;padding:3px 20px 3px 5px;border:1px solid #aaa;border-radius:3px;background-color:#e4e4e4;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-clip:padding-box;box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);color:#333;line-height:13px;cursor:default}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close{position:absolute;top:4px;right:3px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover{background-position:-42px -10px}.chosen-container-multi .chosen-choices li.search-choice-disabled{padding-right:5px;border:1px solid #ccc;background-color:#e4e4e4;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);color:#666}.chosen-container-multi .chosen-choices li.search-choice-focus{background:#d4d4d4}.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close{background-position:-42px -10px}.chosen-container-multi .chosen-results{margin:0;padding:0}.chosen-container-multi .chosen-drop .result-selected{display:list-item;color:#ccc;cursor:default}.chosen-container-active .chosen-single{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active.chosen-with-drop .chosen-single{border:1px solid #aaa;-moz-border-radius-bottomright:0;border-bottom-right-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#eee),color-stop(80%,#fff));background-image:-webkit-linear-gradient(#eee 20%,#fff 80%);background-image:-moz-linear-gradient(#eee 20%,#fff 80%);background-image:-o-linear-gradient(#eee 20%,#fff 80%);background-image:linear-gradient(#eee 20%,#fff 80%);box-shadow:0 1px 0 #fff inset}.chosen-container-active.chosen-with-drop .chosen-single div{border-left:0;background:transparent}.chosen-container-active.chosen-with-drop .chosen-single div b{background-position:-18px 2px}.chosen-container-active .chosen-choices{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active .chosen-choices li.search-field input[type=text]{color:#111!important}.chosen-disabled{opacity:.5!important;cursor:default}.chosen-disabled .chosen-single{cursor:default}.chosen-disabled .chosen-choices .search-choice .search-choice-close{cursor:default}.chosen-rtl{text-align:right}.chosen-rtl .chosen-single{overflow:visible;padding:0 8px 0 0}.chosen-rtl .chosen-single span{margin-right:0;margin-left:26px;direction:rtl}.chosen-rtl .chosen-single-with-deselect span{margin-left:38px}.chosen-rtl .chosen-single div{right:auto;left:3px}.chosen-rtl .chosen-single abbr{right:auto;left:26px}.chosen-rtl .chosen-choices li{float:right}.chosen-rtl .chosen-choices li.search-field input[type=text]{direction:rtl}.chosen-rtl .chosen-choices li.search-choice{margin:3px 5px 3px 0;padding:3px 5px 3px 19px}.chosen-rtl .chosen-choices li.search-choice .search-choice-close{right:auto;left:4px}.chosen-rtl.chosen-container-single-nosearch .chosen-search,.chosen-rtl .chosen-drop{left:9999px}.chosen-rtl.chosen-container-single .chosen-results{margin:0 0 4px 4px;padding:0 4px 0 0}.chosen-rtl .chosen-results li.group-option{padding-right:15px;padding-left:0}.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div{border-right:0}.chosen-rtl .chosen-search input[type=text]{padding:4px 5px 4px 20px;background:#fff url(chosen-sprite.png) no-repeat -30px -20px;background:url(chosen-sprite.png) no-repeat -30px -20px,-webkit-gradient(linear,50% 0,50% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background:url(chosen-sprite.png) no-repeat -30px -20px,-webkit-linear-gradient(#eee 1%,#fff 15%);background:url(chosen-sprite.png) no-repeat -30px -20px,-moz-linear-gradient(#eee 1%,#fff 15%);background:url(chosen-sprite.png) no-repeat -30px -20px,-o-linear-gradient(#eee 1%,#fff 15%);background:url(chosen-sprite.png) no-repeat -30px -20px,linear-gradient(#eee 1%,#fff 15%);direction:rtl}.chosen-rtl.chosen-container-single .chosen-single div b{background-position:6px 2px}.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b{background-position:-12px 2px}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-resolution:144dpi){.chosen-rtl .chosen-search input[type=text],.chosen-container-single .chosen-single abbr,.chosen-container-single .chosen-single div b,.chosen-container-single .chosen-search input[type=text],.chosen-container-multi .chosen-choices .search-choice .search-choice-close,.chosen-container .chosen-results-scroll-down span,.chosen-container .chosen-results-scroll-up span{background-image:url(chosen-sprite@2x.png)!important;background-size:52px 37px!important;background-repeat:no-repeat!important}}
|
classes/styles-font-menu/js/google-fonts-api-fallback.json
CHANGED
@@ -1 +1 @@
|
|
1 |
-
{"kind":"webfonts#webfontList","items":[{"kind":"webfonts#webfont","family":"Open Sans","variants":["300","300italic","regular","italic","600","600italic","700","700italic","800","800italic"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","vietnamese","latin"],"version":"v6","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensans\/v6\/DXI1ORHCpsQm3Vp6mXoaTS3USBnSvpkopQaUR-2r7iU.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensans\/v6\/PRmiXeptR36kaC0GEAetxi9-WlPSxbfiI49GsXo3q0g.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensans\/v6\/IgZJs4-7SA1XX_edsoXWog.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensans\/v6\/O4NhV7_qs9r9seTo7fnsVKCWcynf_cDxXwCLxiixG1c.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensans\/v6\/MTP_ySUJH_bn48VBG8sNSi3USBnSvpkopQaUR-2r7iU.ttf","600italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensans\/v6\/PRmiXeptR36kaC0GEAetxpZ7xm-Bj30Bj2KNdXDzSZg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensans\/v6\/k3k702ZOKiLJc3WVjuplzC3USBnSvpkopQaUR-2r7iU.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensans\/v6\/PRmiXeptR36kaC0GEAetxne1Pd76Vl7zRpE7NLJQ7XU.ttf","800":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensans\/v6\/EInbV5DfGHOiMmvb1Xr-hi3USBnSvpkopQaUR-2r7iU.ttf","800italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensans\/v6\/PRmiXeptR36kaC0GEAetxg89PwPrYLaRFJ-HNCU9NbA.ttf"}},{"kind":"webfonts#webfont","family":"Roboto","variants":["100","100italic","300","300italic","regular","italic","500","500italic","700","700italic","900","900italic"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","vietnamese","latin"],"version":"v9","lastModified":"2013-07-31","files":{"100":"http:\/\/themes.googleusercontent.com\/static\/fonts\/roboto\/v9\/7MygqTe2zs9YkP0adA9QQQ.ttf","100italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/roboto\/v9\/T1xnudodhcgwXCmZQ490TPesZW2xOQ-xsNqO47m55DA.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/roboto\/v9\/dtpHsbgPEm2lVWciJZ0P-A.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/roboto\/v9\/iE8HhaRzdhPxC93dOdA056CWcynf_cDxXwCLxiixG1c.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/roboto\/v9\/W5F8_SL0XFawnjxHGsZjJA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/roboto\/v9\/hcKoSgxdnKlbH5dlTwKbow.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/roboto\/v9\/Uxzkqj-MIMWle-XP2pDNAA.ttf","500italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/roboto\/v9\/daIfzbEw-lbjMyv4rMUUTqCWcynf_cDxXwCLxiixG1c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/roboto\/v9\/bdHGHleUa-ndQCOrdpfxfw.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/roboto\/v9\/owYYXKukxFDFjr0ZO8NXh6CWcynf_cDxXwCLxiixG1c.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/roboto\/v9\/H1vB34nOKWXqzKotq25pcg.ttf","900italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/roboto\/v9\/b9PWBSMHrT2zM5FgUdtu0aCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Oswald","variants":["300","regular","700"],"subsets":["latin-ext","latin"],"version":"v7","lastModified":"2012-10-03","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oswald\/v7\/y3tZpCdiRD4oNRRYFcAR5Q.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oswald\/v7\/uLEd2g2vJglLPfsBF91DCg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oswald\/v7\/7wj8ldV_5Ti37rHa0m1DDw.ttf"}},{"kind":"webfonts#webfont","family":"Droid Sans","variants":["regular","700"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/droidsans\/v3\/rS9BT6-asrfjpkcV3DXf__esZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/droidsans\/v3\/EFpQQyG9GqCrobXxL-KRMQJKKGfqHaYFsRG-T3ceEVo.ttf"}},{"kind":"webfonts#webfont","family":"Lato","variants":["100","100italic","300","300italic","regular","italic","700","700italic","900","900italic"],"subsets":["latin"],"version":"v6","lastModified":"2012-07-25","files":{"100":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lato\/v6\/Upp-ka9rLQmHYCsFgwL-eg.ttf","100italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lato\/v6\/zLegi10uS_9-fnUDISl0KA.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lato\/v6\/Ja02qOppOVq9jeRjWekbHg.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lato\/v6\/dVebFcn7EV7wAKwgYestUg.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lato\/v6\/h7rISIcQapZBpei-sXwIwg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lato\/v6\/P_dJOFJylV3A870UIOtr0w.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lato\/v6\/iX_QxBBZLhNj5JHlTzHQzg.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lato\/v6\/WFcZakHrrCKeUJxHA4T_gw.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lato\/v6\/8TPEV6NbYWZlNsXjbYVv7w.ttf","900italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lato\/v6\/draWperrI7n2xi35Cl08fA.ttf"}},{"kind":"webfonts#webfont","family":"Open Sans Condensed","variants":["300","300italic","700"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","vietnamese","latin"],"version":"v6","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensanscondensed\/v6\/gk5FxslNkTTHtojXrkp-xEMwSSh38KQVJx4ABtsZTnA.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensanscondensed\/v6\/jIXlqT1WKafUSwj6s9AzV4_LkTZ_uhAwfmGJ084hlvM.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/opensanscondensed\/v6\/gk5FxslNkTTHtojXrkp-xBEM87DM3yorPOrvA-vB930.ttf"}},{"kind":"webfonts#webfont","family":"PT Sans","variants":["regular","italic","700","700italic"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v5","lastModified":"2013-05-29","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptsans\/v5\/UFoEz2uiuMypUGZL1NKoeg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptsans\/v5\/yls9EYWOd496wiu7qzfgNg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptsans\/v5\/F51BEgHuR0tYHxF0bD4vwvesZW2xOQ-xsNqO47m55DA.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptsans\/v5\/lILlYDvubYemzYzN7GbLkC3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Droid Serif","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/droidserif\/v3\/DgAtPy6rIVa2Zx3Xh9KaNaCWcynf_cDxXwCLxiixG1c.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/droidserif\/v3\/cj2hUnSRBhwmSPr9kS5890eOrDcLawS7-ssYqLr2Xp4.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/droidserif\/v3\/QQt14e8dY39u-eYBZmppwXe1Pd76Vl7zRpE7NLJQ7XU.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/droidserif\/v3\/c92rD_x0V1LslSFt3-QEps_zJjSACmk0BRPxQqhnNLU.ttf"}},{"kind":"webfonts#webfont","family":"Roboto Condensed","variants":["300","300italic","regular","italic","700","700italic"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","vietnamese","latin"],"version":"v8","lastModified":"2013-07-31","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/robotocondensed\/v8\/b9QBgL0iMZfDSpmcXcE8nJRhFVcex_hajThhFkHyhYk.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/robotocondensed\/v8\/mg0cGfGRUERshzBlvqxeAPYa9bgCHecWXGgisnodcS0.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/robotocondensed\/v8\/Zd2E9abXLFGSr9G3YK2MsKDbm6fPDOZJsR8PmdG62gY.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/robotocondensed\/v8\/BP5K8ZAJv9qEbmuFp8RpJY_eiqgTfYGaH0bJiUDZ5GA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/robotocondensed\/v8\/b9QBgL0iMZfDSpmcXcE8nPOYkGiSOYDq_T7HbIOV1hA.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/robotocondensed\/v8\/mg0cGfGRUERshzBlvqxeAE2zk2RGRC3SlyyLLQfjS_8.ttf"}},{"kind":"webfonts#webfont","family":"Source Sans Pro","variants":["200","200italic","300","300italic","regular","italic","600","600italic","700","700italic","900","900italic"],"subsets":["latin-ext","vietnamese","latin"],"version":"v6","lastModified":"2013-09-26","files":{"200":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcesanspro\/v6\/toadOcfmlt9b38dHJxOBGKXvKVW_haheDNrHjziJZVk.ttf","200italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcesanspro\/v6\/fpTVHK8qsXbIeTHTrnQH6OptKU7UIBg2hLM7eMTU8bI.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcesanspro\/v6\/toadOcfmlt9b38dHJxOBGFP7R5lD_au4SZC6Ks_vyWs.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcesanspro\/v6\/fpTVHK8qsXbIeTHTrnQH6DUpNKoQAsDux-Todp8f29w.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcesanspro\/v6\/ODelI1aHBYDBqgeIAH2zlNRl0pGnog23EMYRrBmUzJQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcesanspro\/v6\/M2Jd71oPJhLKp0zdtTvoMwRX4TIfMQQEXLu74GftruE.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcesanspro\/v6\/toadOcfmlt9b38dHJxOBGOiMeWyi5E_-XkTgB5psiDg.ttf","600italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcesanspro\/v6\/fpTVHK8qsXbIeTHTrnQH6Pp6lGoTTgjlW0sC4r900Co.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcesanspro\/v6\/toadOcfmlt9b38dHJxOBGPgXsetDviZcdR5OzC1KPcw.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcesanspro\/v6\/fpTVHK8qsXbIeTHTrnQH6LVT4locI09aamSzFGQlDMY.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcesanspro\/v6\/toadOcfmlt9b38dHJxOBGBA_awHl7mXRjE_LQVochcU.ttf","900italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcesanspro\/v6\/fpTVHK8qsXbIeTHTrnQH6A0NcF6HPGWR298uWIdxWv0.ttf"}},{"kind":"webfonts#webfont","family":"Ubuntu","variants":["300","300italic","regular","italic","500","500italic","700","700italic"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","latin"],"version":"v4","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntu\/v4\/7-wH0j2QCTHKgp7vLh9-sQ.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntu\/v4\/j-TYDdXcC_eQzhhp386SjaCWcynf_cDxXwCLxiixG1c.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntu\/v4\/lhhB5ZCwEkBRbHMSnYuKyA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntu\/v4\/b9hP8wd30SygxZjGGk4DCQ.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntu\/v4\/bMbHEMwSUmkzcK2x_74QbA.ttf","500italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntu\/v4\/NWdMogIO7U6AtEM4dDdf_aCWcynf_cDxXwCLxiixG1c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntu\/v4\/B7BtHjNYwAp3HgLNagENOQ.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntu\/v4\/pqisLQoeO9YTDCNnlQ9bf6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"PT Sans Narrow","variants":["regular","700"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v4","lastModified":"2013-05-29","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptsansnarrow\/v4\/UyYrYy3ltEffJV9QueSi4ZTvAuddT2xDMbdz0mdLyZY.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptsansnarrow\/v4\/Q_pTky3Sc3ubRibGToTAYsLtdzs3iyjn_YuT226ZsLU.ttf"}},{"kind":"webfonts#webfont","family":"Oxygen","variants":["300","regular","700"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-10-31","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oxygen\/v2\/lZ31r0bR1Bzt_DfGZu1S8A.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oxygen\/v2\/uhoyAE7XlQL22abzQieHjw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oxygen\/v2\/yLqkmDwuNtt5pSqsJmhyrg.ttf"}},{"kind":"webfonts#webfont","family":"Raleway","variants":["100","200","300","regular","500","600","700","800","900"],"subsets":["latin"],"version":"v6","lastModified":"2012-09-14","files":{"100":"http:\/\/themes.googleusercontent.com\/static\/fonts\/raleway\/v6\/UDfD6oxBaBnmFJwQ7XAFNw.ttf","200":"http:\/\/themes.googleusercontent.com\/static\/fonts\/raleway\/v6\/LAQwev4hdCtYkOYX4Oc7nPesZW2xOQ-xsNqO47m55DA.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/raleway\/v6\/2VvSZU2kb4DZwFfRM4fLQPesZW2xOQ-xsNqO47m55DA.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/raleway\/v6\/_dCzxpXzIS3sL-gdJWAP8A.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/raleway\/v6\/348gn6PEmbLDWlHbbV15d_esZW2xOQ-xsNqO47m55DA.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/raleway\/v6\/M7no6oPkwKYJkedjB1wqEvesZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/raleway\/v6\/VGEV9-DrblisWOWLbK-1XPesZW2xOQ-xsNqO47m55DA.ttf","800":"http:\/\/themes.googleusercontent.com\/static\/fonts\/raleway\/v6\/mMh0JrsYMXcLO69jgJwpUvesZW2xOQ-xsNqO47m55DA.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/raleway\/v6\/ajQQGcDBLcyLpaUfD76UuPesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Yanone Kaffeesatz","variants":["200","300","regular","700"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-07-25","files":{"200":"http:\/\/themes.googleusercontent.com\/static\/fonts\/yanonekaffeesatz\/v4\/We_iSDqttE3etzfdfhuPRbq92v6XxU4pSv06GI0NsGc.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/yanonekaffeesatz\/v4\/We_iSDqttE3etzfdfhuPRZlIwXPiNoNT_wxzJ2t3mTE.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/yanonekaffeesatz\/v4\/YDAoLskQQ5MOAgvHUQCcLdXn3cHbFGWU4T2HrSN6JF4.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/yanonekaffeesatz\/v4\/We_iSDqttE3etzfdfhuPRf2R4S6PlKaGXWPfWpHpcl0.ttf"}},{"kind":"webfonts#webfont","family":"Lora","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lora\/v5\/aXJ7KVIGcejEy1abawZazg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lora\/v5\/AN2EZaj2tFRpyveuNn9BOg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lora\/v5\/enKND5SfzQKkggBA_VnT1A.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lora\/v5\/ivs9j3kYU65pR9QD9YFdzQ.ttf"}},{"kind":"webfonts#webfont","family":"Lobster","variants":["regular"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lobster\/v5\/9LpJGtNuM1D8FAZ2BkJH2Q.ttf"}},{"kind":"webfonts#webfont","family":"Arvo","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arvo\/v5\/vvWPwz-PlZEwjOOIKqoZzA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arvo\/v5\/id5a4BCjbenl5Gkqonw_Rw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arvo\/v5\/OB3FDST7U38u3OjPK_vvRQ.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arvo\/v5\/Hvl2MuWoXLaCy2v6MD4Yvw.ttf"}},{"kind":"webfonts#webfont","family":"Montserrat","variants":["regular","700"],"subsets":["latin"],"version":"v3","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/montserrat\/v3\/Kqy6-utIpx_30Xzecmeo8_esZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/montserrat\/v3\/IQHow_FEYlDC4Gzy_m8fcgJKKGfqHaYFsRG-T3ceEVo.ttf"}},{"kind":"webfonts#webfont","family":"Bitter","variants":["regular","italic","700"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bitter\/v4\/w_BNdJvVZDRmqy5aSfB2kQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bitter\/v4\/TC0FZEVzXQIGgzmRfKPZbA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bitter\/v4\/4dUtr_4BvHuoRU35suyOAg.ttf"}},{"kind":"webfonts#webfont","family":"Francois One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v6","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/francoisone\/v6\/bYbkq2nU2TSx4SwFbz5sCC3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Arimo","variants":["regular","italic","700","700italic"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","vietnamese","latin"],"version":"v5","lastModified":"2013-07-31","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arimo\/v5\/Gpeo80g-5ji2CcyXWnzh7g.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arimo\/v5\/_OdGbnX2-qQ96C4OjhyuPw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arimo\/v5\/ZItXugREyvV9LnbY_gxAmw.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arimo\/v5\/__nOLWqmeXdhfr0g7GaFePesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Noto Sans","variants":["regular","italic","700","700italic"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","vietnamese","latin"],"version":"v1","lastModified":"2013-11-21","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/notosans\/v1\/0Ue9FiUJwVhi4NGfHJS5uA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/notosans\/v1\/dLcNKMgJ1H5RVoZFraDz0qCWcynf_cDxXwCLxiixG1c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/notosans\/v1\/PIbvSEyHEdL91QLOQRnZ1y3USBnSvpkopQaUR-2r7iU.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/notosans\/v1\/9Z3uUWMRR7crzm1TjRicDne1Pd76Vl7zRpE7NLJQ7XU.ttf"}},{"kind":"webfonts#webfont","family":"Merriweather","variants":["300","300italic","regular","italic","700","700italic","900","900italic"],"subsets":["latin-ext","latin"],"version":"v5","lastModified":"2013-05-22","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweather\/v5\/ZvcMqxEwPfh2qDWBPxn6nqcQoVhARpoaILP7amxE_8g.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweather\/v5\/EYh7Vl4ywhowqULgRdYwICna0FLWfcB-J_SAYmcAXaI.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweather\/v5\/RFda8w1V0eDZheqfcyQ4EC3USBnSvpkopQaUR-2r7iU.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweather\/v5\/So5lHxHT37p2SS4-t60SlPMZXuCXbOrAvx5R0IT5Oyo.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweather\/v5\/ZvcMqxEwPfh2qDWBPxn6nkD2ttfZwueP-QU272T9-k4.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweather\/v5\/EYh7Vl4ywhowqULgRdYwIPAs9-1nE9qOqhChW0m4nDE.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweather\/v5\/ZvcMqxEwPfh2qDWBPxn6nqObDOjC3UL77puoeHsE3fw.ttf","900italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweather\/v5\/EYh7Vl4ywhowqULgRdYwIBd0_s6jQr9r5s5OZYvtzBY.ttf"}},{"kind":"webfonts#webfont","family":"PT Serif","variants":["regular","italic","700","700italic"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v5","lastModified":"2013-05-29","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptserif\/v5\/sAo427rn3-QL9sWCbMZXhA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptserif\/v5\/9khWhKzhpkH0OkNnBKS3n_esZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptserif\/v5\/kyZw18tqQ5if-_wpmxxOeKCWcynf_cDxXwCLxiixG1c.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptserif\/v5\/Foydq9xJp--nfYIx2TBz9QJKKGfqHaYFsRG-T3ceEVo.ttf"}},{"kind":"webfonts#webfont","family":"Rokkitt","variants":["regular","700"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rokkitt\/v5\/GMA7Z_ToF8uSvpZAgnp_VQ.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rokkitt\/v5\/gxlo-sr3rPmvgSixYog_ofesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Cabin","variants":["regular","italic","500","500italic","600","600italic","700","700italic"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabin\/v4\/XeuAFYo2xAPHxZGBbQtHhA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabin\/v4\/0tJ9k3DI5xC4GBgs1E_Jxw.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabin\/v4\/HgsCQ-k3_Z_uQ86aFolNBg.ttf","500italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabin\/v4\/50sjhrGE0njyO-7mGDhGP_esZW2xOQ-xsNqO47m55DA.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabin\/v4\/eUDAvKhBtmTCkeVBsFk34A.ttf","600italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabin\/v4\/sFQpQDBd3G2om0Nl5dD2CvesZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabin\/v4\/4EKhProuY1hq_WCAomq9Dg.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabin\/v4\/K83QKi8MOKLEqj6bgZ7LrfesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Dosis","variants":["200","300","regular","500","600","700","800"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"200":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dosis\/v1\/ztftab0r6hcd7AeurUGrSQ.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dosis\/v1\/awIB6L0h5mb0plIKorXmuA.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dosis\/v1\/rJRlixu-w0JZ1MyhJpao_Q.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dosis\/v1\/ruEXDOFMxDPGnjCBKRqdAQ.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dosis\/v1\/KNAswRNwm3tfONddYyidxg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dosis\/v1\/AEEAj0ONidK8NQQMBBlSig.ttf","800":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dosis\/v1\/nlrKd8E69vvUU39XGsvR7Q.ttf"}},{"kind":"webfonts#webfont","family":"Nunito","variants":["300","regular","700"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/nunito\/v4\/zXQvrWBJqUooM7Xv98MrQw.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/nunito\/v4\/ySZTeT3IuzJj0GK6uGpbBg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/nunito\/v4\/aEdlqgMuYbpe4U3TnqOQMA.ttf"}},{"kind":"webfonts#webfont","family":"Titillium Web","variants":["200","200italic","300","300italic","regular","italic","600","600italic","700","700italic","900"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-10-03","files":{"200":"http:\/\/themes.googleusercontent.com\/static\/fonts\/titilliumweb\/v1\/anMUvcNT0H1YN4FII8wprzOdCrLccoxq42eaxM802O0.ttf","200italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/titilliumweb\/v1\/RZunN20OBmkvrU7sA4GPPj4N98U-66ThNJvtgddRfBE.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/titilliumweb\/v1\/anMUvcNT0H1YN4FII8wpr9ZAkYT8DuUZELiKLwMGWAo.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/titilliumweb\/v1\/RZunN20OBmkvrU7sA4GPPrfzCkqg7ORZlRf2cc4mXu8.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/titilliumweb\/v1\/7XUFZ5tgS-tD6QamInJTcTyagQBwYgYywpS70xNq8SQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/titilliumweb\/v1\/r9OmwyQxrgzUAhaLET_KO-ixohbIP6lHkU-1Mgq95cY.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/titilliumweb\/v1\/anMUvcNT0H1YN4FII8wpr28K9dEd5Ue-HTQrlA7E2xQ.ttf","600italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/titilliumweb\/v1\/RZunN20OBmkvrU7sA4GPPgOhzTSndyK8UWja2yJjKLc.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/titilliumweb\/v1\/anMUvcNT0H1YN4FII8wpr2-6tpSbB9YhmWtmd1_gi_U.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/titilliumweb\/v1\/RZunN20OBmkvrU7sA4GPPio3LEw-4MM8Ao2j9wPOfpw.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/titilliumweb\/v1\/anMUvcNT0H1YN4FII8wpr7L0GmZLri-m-nfoo0Vul4Y.ttf"}},{"kind":"webfonts#webfont","family":"Play","variants":["regular","700"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/play\/v3\/GWvfObW8LhtsOX333MCpBg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/play\/v3\/crPhg6I0alLI-MpB3vW-zw.ttf"}},{"kind":"webfonts#webfont","family":"Libre Baskerville","variants":["regular","italic","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-12-06","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/librebaskerville\/v1\/pR0sBQVcY0JZc_ciXjFsKyyZRYCSvpCzQKuMWnP5NDY.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/librebaskerville\/v1\/QHIOz1iKF3bIEzRdDFaf5QnhapNS5Oi8FPrBRDLbsW4.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/librebaskerville\/v1\/kH7K4InNTm7mmOXXjrA5v-xuswJKUVpBRfYFpz0W3Iw.ttf"}},{"kind":"webfonts#webfont","family":"Abel","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/abel\/v3\/RpUKfqNxoyNe_ka23bzQ2A.ttf"}},{"kind":"webfonts#webfont","family":"Cuprum","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","cyrillic","latin"],"version":"v4","lastModified":"2012-08-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cuprum\/v4\/JgXs0F_UiaEdAS74msmFNg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cuprum\/v4\/cLEz0KV6OxInnktSzpk58g.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cuprum\/v4\/6tl3_FkDeXSD72oEHuJh4w.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cuprum\/v4\/bnkXaBfoYvaJ75axRPSwVKCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Roboto Slab","variants":["100","300","regular","700"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","vietnamese","latin"],"version":"v2","lastModified":"2013-07-31","files":{"100":"http:\/\/themes.googleusercontent.com\/static\/fonts\/robotoslab\/v2\/MEz38VLIFL-t46JUtkIEgIAWxXGWZ3yJw6KhWS7MxOk.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/robotoslab\/v2\/dazS1PrQQuCxC3iOAJFEJS9-WlPSxbfiI49GsXo3q0g.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/robotoslab\/v2\/3__ulTNA7unv0UtplybPiqCWcynf_cDxXwCLxiixG1c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/robotoslab\/v2\/dazS1PrQQuCxC3iOAJFEJXe1Pd76Vl7zRpE7NLJQ7XU.ttf"}},{"kind":"webfonts#webfont","family":"Ubuntu Condensed","variants":["regular"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntucondensed\/v3\/DBCt-NXN57MTAFjitYxdrKDbm6fPDOZJsR8PmdG62gY.ttf"}},{"kind":"webfonts#webfont","family":"Fjalla One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2013-11-21","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fjallaone\/v1\/3b7vWCfOZsU53vMa8LWsf_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Shadows Into Light","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/shadowsintolight\/v3\/clhLqOv7MXn459PTh0gXYAW_5bEze-iLRNvGrRpJsfM.ttf"}},{"kind":"webfonts#webfont","family":"Anton","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/anton\/v3\/XIbCenm-W0IRHWYIh7CGUQ.ttf"}},{"kind":"webfonts#webfont","family":"Maven Pro","variants":["regular","500","700","900"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mavenpro\/v4\/sqPJIFG4gqsjl-0q_46Gbw.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mavenpro\/v4\/SQVfzoJBbj9t3aVcmbspRi3USBnSvpkopQaUR-2r7iU.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mavenpro\/v4\/uDssvmXgp7Nj3i336k_dSi3USBnSvpkopQaUR-2r7iU.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mavenpro\/v4\/-91TwiFzqeL1F7Kh91APwS3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Electrolize","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/electrolize\/v2\/yFVu5iokC-nt4B1Cyfxb9aCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Signika","variants":["300","regular","600","700"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/signika\/v3\/0wDPonOzsYeEo-1KO78w4fesZW2xOQ-xsNqO47m55DA.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/signika\/v3\/WvDswbww0oAtvBg2l1L-9w.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/signika\/v3\/lQMOF6NUN2ooR7WvB7tADvesZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/signika\/v3\/lEcnfPBICWJPv5BbVNnFJPesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Merriweather Sans","variants":["300","300italic","regular","italic","700","700italic","800","800italic"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2013-06-12","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweathersans\/v2\/6LmGj5dOJopQKEkt88Gowan5N8K-_DP0e9e_v51obXQ.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweathersans\/v2\/nAqt4hiqwq3tzCecpgPmVdytE4nGXk2hYD5nJ740tBw.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweathersans\/v2\/AKu1CjQ4qnV8MUltkAX3sOAj_ty82iuwwDTNEYXGiyQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweathersans\/v2\/3Mz4hOHzs2npRMG3B1ascZ32VBCoA_HLsn85tSWZmdo.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweathersans\/v2\/6LmGj5dOJopQKEkt88GowbqxG25nQNOioCZSK4sU-CA.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweathersans\/v2\/nAqt4hiqwq3tzCecpgPmVbuqAJxizi8Dk_SK5et7kMg.ttf","800":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweathersans\/v2\/6LmGj5dOJopQKEkt88GowYufzO2zUYSj5LqoJ3UGkco.ttf","800italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merriweathersans\/v2\/nAqt4hiqwq3tzCecpgPmVdDmPrYMy3aZO4LmnZsxTQw.ttf"}},{"kind":"webfonts#webfont","family":"Inconsolata","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v6","lastModified":"2012-09-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/inconsolata\/v6\/7bMKuoy6Nh0ft0SHnIGMuaCWcynf_cDxXwCLxiixG1c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/inconsolata\/v6\/AIed271kqQlcIRSOnQH0yXe1Pd76Vl7zRpE7NLJQ7XU.ttf"}},{"kind":"webfonts#webfont","family":"Vollkorn","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/vollkorn\/v3\/IiexqYAeh8uII223thYx3w.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/vollkorn\/v3\/UuIzosgR1ovBhJFdwVp3fvesZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/vollkorn\/v3\/gOwQjJVGXlDOONC12hVoBqCWcynf_cDxXwCLxiixG1c.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/vollkorn\/v3\/KNiAlx6phRqXCwnZZG51JAJKKGfqHaYFsRG-T3ceEVo.ttf"}},{"kind":"webfonts#webfont","family":"Josefin Sans","variants":["100","100italic","300","300italic","regular","italic","600","600italic","700","700italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"100":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinsans\/v3\/q9w3H4aeBxj0hZ8Osfi3d8SVQ0giZ-l_NELu3lgGyYw.ttf","100italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinsans\/v3\/s7-P1gqRNRNn-YWdOYnAOXXcj1rQwlNLIS625o-SrL0.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinsans\/v3\/C6HYlRF50SGJq1XyXj04z6cQoVhARpoaILP7amxE_8g.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinsans\/v3\/ppse0J9fKSaoxCIIJb33Gyna0FLWfcB-J_SAYmcAXaI.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinsans\/v3\/xgzbb53t8j-Mo-vYa23n5i3USBnSvpkopQaUR-2r7iU.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinsans\/v3\/q9w3H4aeBxj0hZ8Osfi3d_MZXuCXbOrAvx5R0IT5Oyo.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinsans\/v3\/C6HYlRF50SGJq1XyXj04z2v8CylhIUtwUiYO7Z2wXbE.ttf","600italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinsans\/v3\/ppse0J9fKSaoxCIIJb33G4R-5-urNOGAobhAyctHvW8.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinsans\/v3\/C6HYlRF50SGJq1XyXj04z0D2ttfZwueP-QU272T9-k4.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinsans\/v3\/ppse0J9fKSaoxCIIJb33G_As9-1nE9qOqhChW0m4nDE.ttf"}},{"kind":"webfonts#webfont","family":"Archivo Narrow","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-12-17","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/archivonarrow\/v2\/DsLzC9scoPnrGiwYYMQXppTvAuddT2xDMbdz0mdLyZY.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/archivonarrow\/v2\/vqsrtPCpTU3tJlKfuXP5zUpmlyBQEFfdE6dERLXdQGQ.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/archivonarrow\/v2\/M__Wu4PAmHf4YZvQM8tWsMLtdzs3iyjn_YuT226ZsLU.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/archivonarrow\/v2\/wG6O733y5zHl4EKCOh8rSTg5KB8MNJ4uPAETq9naQO8.ttf"}},{"kind":"webfonts#webfont","family":"Crafty Girls","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/craftygirls\/v2\/0Sv8UWFFdhQmesHL32H8oy3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Asap","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/asap\/v1\/2lf-1MDR8tsTpEtvJmr2hA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/asap\/v1\/mwxNHf8QS8gNWCAMwkJNIg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/asap\/v1\/o5RUA7SsJ80M8oDFBnrDbg.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/asap\/v1\/_rZz9y2oXc09jT5T6BexLQ.ttf"}},{"kind":"webfonts#webfont","family":"Questrial","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/questrial\/v3\/MoHHaw_WwNs_hd9ob1zTVw.ttf"}},{"kind":"webfonts#webfont","family":"Armata","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/armata\/v3\/1H8FwGgIRrbYtxSfXhOHlQ.ttf"}},{"kind":"webfonts#webfont","family":"Alegreya","variants":["regular","italic","700","700italic","900","900italic"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-08-08","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alegreya\/v4\/62J3atXd6bvMU4qO_ca-eA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alegreya\/v4\/cbshnQGxwmlHBjUil7DaIfesZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alegreya\/v4\/5oZtdI5-wQwgAFrd9erCsaCWcynf_cDxXwCLxiixG1c.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alegreya\/v4\/IWi8e5bpnqhMRsZKTcTUWgJKKGfqHaYFsRG-T3ceEVo.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alegreya\/v4\/oQeMxX-vxGImzDgX6nxA7KCWcynf_cDxXwCLxiixG1c.ttf","900italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alegreya\/v4\/-L71QLH_XqgYWaI1GbOVhp0EAVxt0G0biEntp43Qt6E.ttf"}},{"kind":"webfonts#webfont","family":"Playfair Display","variants":["regular","italic","700","700italic","900","900italic"],"subsets":["latin-ext","cyrillic","latin"],"version":"v7","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playfairdisplay\/v7\/2NBgzUtEeyB-Xtpr9bm1CV6uyC_qD11hrFQ6EGgTJWI.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playfairdisplay\/v7\/9MkijrV-dEJ0-_NWV7E6NzMsbnvDNEBX25F5HWk9AhI.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playfairdisplay\/v7\/UC3ZEjagJi85gF9qFaBgICsv6SrURqJprbhH_C1Mw8w.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playfairdisplay\/v7\/n7G4PqJvFP2Kubl0VBLDECsYW3XoOVcYyYdp9NzzS9E.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playfairdisplay\/v7\/UC3ZEjagJi85gF9qFaBgIKqwMe2wjvZrAR44M0BJZ48.ttf","900italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playfairdisplay\/v7\/n7G4PqJvFP2Kubl0VBLDEC0JfJ4xmm7j1kL6D7mPxrA.ttf"}},{"kind":"webfonts#webfont","family":"Istok Web","variants":["regular","italic","700","700italic"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/istokweb\/v5\/RYLSjEXQ0nNtLLc4n7--dQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/istokweb\/v5\/kvcT2SlTjmGbC3YlZxmrl6CWcynf_cDxXwCLxiixG1c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/istokweb\/v5\/2koEo4AKFSvK4B52O_Mwai3USBnSvpkopQaUR-2r7iU.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/istokweb\/v5\/ycQ3g52ELrh3o_HYCNNUw3e1Pd76Vl7zRpE7NLJQ7XU.ttf"}},{"kind":"webfonts#webfont","family":"Pacifico","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/pacifico\/v4\/GIrpeRY1r5CzbfL8r182lw.ttf"}},{"kind":"webfonts#webfont","family":"Dancing Script","variants":["regular","700"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dancingscript\/v3\/DK0eTGXiZjN6yA8zAEyM2RnpV0hQCek3EmWnCPrvGRM.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dancingscript\/v3\/KGBfwabt0ZRLA5W1ywjowb_dAmXiKjTPGCuO6G2MbfA.ttf"}},{"kind":"webfonts#webfont","family":"Muli","variants":["300","300italic","regular","italic"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/muli\/v4\/VJw4F3ZHRAZ7Hmg3nQu5YQ.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/muli\/v4\/s-NKMCru8HiyjEt0ZDoBoA.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/muli\/v4\/KJiP6KznxbALQgfJcDdPAw.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/muli\/v4\/Cg0K_IWANs9xkNoxV7H1_w.ttf"}},{"kind":"webfonts#webfont","family":"Coming Soon","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/comingsoon\/v3\/Yz2z3IAe2HSQAOWsSG8COKCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"PT Sans Caption","variants":["regular","700"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v6","lastModified":"2013-05-29","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptsanscaption\/v6\/OXYTDOzBcXU8MTNBvBHeSW8by34Z3mUMtM-o4y-SHCY.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptsanscaption\/v6\/Q-gJrFokeE7JydPpxASt25tc0eyfI4QDEsobEEpk_hA.ttf"}},{"kind":"webfonts#webfont","family":"Exo","variants":["100","100italic","200","200italic","300","300italic","regular","italic","500","500italic","600","600italic","700","700italic","800","800italic","900","900italic"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"100":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/RI7A9uwjRmPbVp0n8e-Jvg.ttf","100italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/qtGyZZlWb2EEvby3ZPosxw.ttf","200":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/F8OfC_swrRRxpFt-tlXZQg.ttf","200italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/fr4HBfXHYiIngW2_bhlgRw.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/SBrN7TKUqgGUvfxqHqsnNw.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/3gmiLjBegIfcDLISjTGA1g.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/eUEzTFueNXRVhbt4PEB8kQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/cfgolWisMSURhpQeVHl_NA.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/jCg6DmGGXt_OVyp5ofQHPw.ttf","500italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/lo5eTdCNJZQVN08p8RnzAQ.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/q_SG5kXUmOcIvFpgtdZnlw.ttf","600italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/0cExa8K_pxS2lTuMr68XUA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/3_jwsL4v9uHjl5Q37G57mw.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/0me55yJIxd5vyQ9bF7SsiA.ttf","800":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/yLPuxBuV0lzqibRJyooOJg.ttf","800italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/n3LejeKVj_8gtZq5fIgNYw.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/97d0nd6Yv4-SA_X92xAuZA.ttf","900italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/exo\/v1\/JHTkQVhzyLtkY13Ye95TJQ.ttf"}},{"kind":"webfonts#webfont","family":"Indie Flower","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/indieflower\/v4\/10JVD_humAd5zP2yrFqw6i3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Quicksand","variants":["300","regular","700"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quicksand\/v2\/qhfoJiLu10kFjChCCTvGlC3USBnSvpkopQaUR-2r7iU.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quicksand\/v2\/Ngv3fIJjKB7sD-bTUGIFCA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quicksand\/v2\/32nyIRHyCu6iqEka_hbKsi3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Changa One","variants":["regular","italic"],"subsets":["latin"],"version":"v6","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/changaone\/v6\/dr4qjce4W3kxFrZRkVD87fesZW2xOQ-xsNqO47m55DA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/changaone\/v6\/wJVQlUs1lAZel-WdTo2U9y3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Economica","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/economica\/v1\/G4rJRujzZbq9Nxngu9l3hg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/economica\/v1\/p5O9AVeUqx_n35xQRinNYaCWcynf_cDxXwCLxiixG1c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/economica\/v1\/UK4l2VEpwjv3gdcwbwXE9C3USBnSvpkopQaUR-2r7iU.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/economica\/v1\/ac5dlUsedQ03RqGOeay-3Xe1Pd76Vl7zRpE7NLJQ7XU.ttf"}},{"kind":"webfonts#webfont","family":"Kreon","variants":["300","regular","700"],"subsets":["latin"],"version":"v6","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kreon\/v6\/HKtJRiq5C2zbq5N1IX32sA.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kreon\/v6\/zA_IZt0u0S3cvHJu-n1oEg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kreon\/v6\/jh0dSmaPodjxISiblIUTkw.ttf"}},{"kind":"webfonts#webfont","family":"Special Elite","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/specialelite\/v3\/9-wW4zu3WNoD5Fjka35Jm4jjx0o0jr6fNXxPgYh_a8Q.ttf"}},{"kind":"webfonts#webfont","family":"Cabin Condensed","variants":["regular","500","600","700"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabincondensed\/v4\/B0txb0blf2N29WdYPJjMSiQPsWWoiv__AzYJ9Zzn9II.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabincondensed\/v4\/Ez4zJbsGr2BgXcNUWBVgEARL_-ABKXdjsJSPT0lc2Bk.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabincondensed\/v4\/Ez4zJbsGr2BgXcNUWBVgELS5sSASxc8z4EQTQj7DCAI.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabincondensed\/v4\/Ez4zJbsGr2BgXcNUWBVgEMAWgzcA047xWLixhLCofl8.ttf"}},{"kind":"webfonts#webfont","family":"News Cycle","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v9","lastModified":"2012-08-16","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/newscycle\/v9\/xyMAr8VfiUzIOvS1abHJO_esZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/newscycle\/v9\/G28Ny31cr5orMqEQy6ljtwJKKGfqHaYFsRG-T3ceEVo.ttf"}},{"kind":"webfonts#webfont","family":"Nobile","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/nobile\/v4\/lC_lPi1ddtN38iXTCRh6ow.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/nobile\/v4\/vGmrpKzWQQSrb-PR6FWBIA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/nobile\/v4\/9p6M-Yrg_r_QPmSD1skrOg.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/nobile\/v4\/oQ1eYPaXV638N03KvsNvyKCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Squada One","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/squadaone\/v2\/3tzGuaJdD65cZVgfQzN8uvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Tangerine","variants":["regular","700"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tangerine\/v3\/DTPeM3IROhnkz7aYG2a9sA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tangerine\/v3\/UkFsr-RwJB_d2l9fIWsx3i3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Philosopher","variants":["regular","italic","700","700italic"],"subsets":["cyrillic","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/philosopher\/v4\/oZLTrB9jmJsyV0u_T0TKEaCWcynf_cDxXwCLxiixG1c.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/philosopher\/v4\/_9Hnc_gz9k7Qq6uKaeHKmUeOrDcLawS7-ssYqLr2Xp4.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/philosopher\/v4\/napvkewXG9Gqby5vwGHICHe1Pd76Vl7zRpE7NLJQ7XU.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/philosopher\/v4\/PuKlryTcvTj7-qZWfLCFIM_zJjSACmk0BRPxQqhnNLU.ttf"}},{"kind":"webfonts#webfont","family":"Cantarell","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cantarell\/v3\/p5ydP_uWQ5lsFzcP_XVMEw.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cantarell\/v3\/DTCLtOSqP-7dgM-V_xKUjqCWcynf_cDxXwCLxiixG1c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cantarell\/v3\/Yir4ZDsCn4g1kWopdg-ehC3USBnSvpkopQaUR-2r7iU.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cantarell\/v3\/weehrwMeZBXb0QyrWnRwFXe1Pd76Vl7zRpE7NLJQ7XU.ttf"}},{"kind":"webfonts#webfont","family":"Noto Serif","variants":["regular","italic","700","700italic"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","vietnamese","latin"],"version":"v1","lastModified":"2013-11-21","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/notoserif\/v1\/zW6mc7bC1CWw8dH0yxY8JfesZW2xOQ-xsNqO47m55DA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/notoserif\/v1\/HQXBIwLHsOJCNEQeX9kNzy3USBnSvpkopQaUR-2r7iU.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/notoserif\/v1\/lJAvZoKA5NttpPc9yc6lPQJKKGfqHaYFsRG-T3ceEVo.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/notoserif\/v1\/Wreg0Be4tcFGM2t6VWytvED2ttfZwueP-QU272T9-k4.ttf"}},{"kind":"webfonts#webfont","family":"Comfortaa","variants":["300","regular","700"],"subsets":["cyrillic-ext","latin-ext","cyrillic","greek","latin"],"version":"v4","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/comfortaa\/v4\/r_tUZNl0G8xCoOmp_JkSCi3USBnSvpkopQaUR-2r7iU.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/comfortaa\/v4\/lZx6C1VViPgSOhCBUP7hXA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/comfortaa\/v4\/fND5XPYKrF2tQDwwfWZJIy3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Chewy","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/chewy\/v4\/hcDN5cvQdIu6Bx4mg_TSyw.ttf"}},{"kind":"webfonts#webfont","family":"Luckiest Guy","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/luckiestguy\/v3\/5718gH8nDy3hFVihOpkY5C3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Bree Serif","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/breeserif\/v2\/5h9crBVIrvZqgf34FHcnEfesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Playball","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playball\/v3\/3hOFiQm_EUzycTpcN9uz4w.ttf"}},{"kind":"webfonts#webfont","family":"Gudea","variants":["regular","italic","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gudea\/v1\/S-4QqBlkMPiiA3jNeCR5yw.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gudea\/v1\/7mNgsGw_vfS-uUgRVXNDSw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gudea\/v1\/lsip4aiWhJ9bx172Y9FN_w.ttf"}},{"kind":"webfonts#webfont","family":"Ropa Sans","variants":["regular","italic"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ropasans\/v2\/Gba7ZzVBuhg6nX_AoSwlkQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ropasans\/v2\/V1zbhZQscNrh63dy5Jk2nqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Signika Negative","variants":["300","regular","600","700"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/signikanegative\/v2\/q5TOjIw4CenPw6C-TW06FjYFXpUPtCmIEFDvjUnLLaI.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/signikanegative\/v2\/Z-Q1hzbY8uAo3TpTyPFMXVM1lnCWMnren5_v6047e5A.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/signikanegative\/v2\/q5TOjIw4CenPw6C-TW06FrKLaDJM01OezSVA2R_O3qI.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/signikanegative\/v2\/q5TOjIw4CenPw6C-TW06FpYzPxtVvobH1w3hEppR8WI.ttf"}},{"kind":"webfonts#webfont","family":"Patua One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-08-08","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/patuaone\/v3\/njZwotTYjswR4qdhsW-kJw.ttf"}},{"kind":"webfonts#webfont","family":"Pontano Sans","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/pontanosans\/v1\/gTHiwyxi6S7iiHpqAoiE3C3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Fredoka One","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fredokaone\/v1\/QKfwXi-z-KtJAlnO2ethYqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Marvel","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/marvel\/v3\/Fg1dO8tWVb-MlyqhsbXEkg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/marvel\/v3\/HzyjFB-oR5usrc7Lxz9g8w.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/marvel\/v3\/WrHDBL1RupWGo2UcdgxB3Q.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/marvel\/v3\/Gzf5NT09Y6xskdQRj2kz1qCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Varela Round","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/varelaround\/v3\/APH4jr0uSos5wiut5cpjri3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Monda","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-12-06","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/monda\/v1\/qFMHZ9zvR6B_gnoIgosPrw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/monda\/v1\/EVOzZUyc_j1w2GuTgTAW1g.ttf"}},{"kind":"webfonts#webfont","family":"Noticia Text","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","vietnamese","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/noticiatext\/v3\/wdyV6x3eKpdeUPQ7BJ5uUC3USBnSvpkopQaUR-2r7iU.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/noticiatext\/v3\/dAuxVpkYE_Q_IwIm6elsKPMZXuCXbOrAvx5R0IT5Oyo.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/noticiatext\/v3\/pEko-RqEtp45bE2P80AAKUD2ttfZwueP-QU272T9-k4.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/noticiatext\/v3\/-rQ7V8ARjf28_b7kRa0JuvAs9-1nE9qOqhChW0m4nDE.ttf"}},{"kind":"webfonts#webfont","family":"Karla","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/karla\/v2\/78UgGRwJFkhqaoFimqoKpQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/karla\/v2\/51UBKly9RQOnOkj95ZwEFw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/karla\/v2\/JS501sZLxZ4zraLQdncOUA.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/karla\/v2\/3YDyi09gQjCRh-5-SVhTTvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Black Ops One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/blackopsone\/v4\/2XW-DmDsGbDLE372KrMW1Yjjx0o0jr6fNXxPgYh_a8Q.ttf"}},{"kind":"webfonts#webfont","family":"Righteous","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/righteous\/v2\/0nRRWM_gCGCt2S-BCfN8WQ.ttf"}},{"kind":"webfonts#webfont","family":"Voltaire","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/voltaire\/v3\/WvqBzaGEBbRV-hrahwO2cA.ttf"}},{"kind":"webfonts#webfont","family":"Permanent Marker","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/permanentmarker\/v2\/9vYsg5VgPHKK8SXYbf3sMol14xj5tdg9OHF8w4E7StQ.ttf"}},{"kind":"webfonts#webfont","family":"Josefin Slab","variants":["100","100italic","300","300italic","regular","italic","600","600italic","700","700italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"100":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinslab\/v3\/etsUjZYO8lTLU85lDhZwUsSVQ0giZ-l_NELu3lgGyYw.ttf","100italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinslab\/v3\/8BjDChqLgBF3RJKfwHIYh3Xcj1rQwlNLIS625o-SrL0.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinslab\/v3\/NbE6ykYuM2IyEwxQxOIi2KcQoVhARpoaILP7amxE_8g.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinslab\/v3\/af9sBoKGPbGO0r21xJulyyna0FLWfcB-J_SAYmcAXaI.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinslab\/v3\/46aYWdgz-1oFX11flmyEfS3USBnSvpkopQaUR-2r7iU.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinslab\/v3\/etsUjZYO8lTLU85lDhZwUvMZXuCXbOrAvx5R0IT5Oyo.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinslab\/v3\/NbE6ykYuM2IyEwxQxOIi2Gv8CylhIUtwUiYO7Z2wXbE.ttf","600italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinslab\/v3\/af9sBoKGPbGO0r21xJuly4R-5-urNOGAobhAyctHvW8.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinslab\/v3\/NbE6ykYuM2IyEwxQxOIi2ED2ttfZwueP-QU272T9-k4.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/josefinslab\/v3\/af9sBoKGPbGO0r21xJuly_As9-1nE9qOqhChW0m4nDE.ttf"}},{"kind":"webfonts#webfont","family":"Crimson Text","variants":["regular","italic","600","600italic","700","700italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/crimsontext\/v3\/3IFMwfRa07i-auYR-B-zNS3USBnSvpkopQaUR-2r7iU.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/crimsontext\/v3\/a5QZnvmn5amyNI-t2BMkWPMZXuCXbOrAvx5R0IT5Oyo.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/crimsontext\/v3\/rEy5tGc5HdXy56Xvd4f3I2v8CylhIUtwUiYO7Z2wXbE.ttf","600italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/crimsontext\/v3\/4j4TR-EfnvCt43InYpUNDIR-5-urNOGAobhAyctHvW8.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/crimsontext\/v3\/rEy5tGc5HdXy56Xvd4f3I0D2ttfZwueP-QU272T9-k4.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/crimsontext\/v3\/4j4TR-EfnvCt43InYpUNDPAs9-1nE9qOqhChW0m4nDE.ttf"}},{"kind":"webfonts#webfont","family":"Lobster Two","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lobstertwo\/v4\/xb9aY4w9ceh8JRzobID1naCWcynf_cDxXwCLxiixG1c.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lobstertwo\/v4\/Ul_16MSbfayQv1I4QhLEoEeOrDcLawS7-ssYqLr2Xp4.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lobstertwo\/v4\/bmdxOflBqMqjEC0-kGsIiHe1Pd76Vl7zRpE7NLJQ7XU.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lobstertwo\/v4\/LEkN2_no_6kFvRfiBZ8xpM_zJjSACmk0BRPxQqhnNLU.ttf"}},{"kind":"webfonts#webfont","family":"Amatic SC","variants":["regular","700"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/amaticsc\/v3\/MldbRWLFytvqxU1y81xSVg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/amaticsc\/v3\/IDnkRTPGcrSVo50UyYNK7y3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Quattrocento Sans","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quattrocentosans\/v5\/efd6FGWWGX5Z3ztwLBrG9eAj_ty82iuwwDTNEYXGiyQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quattrocentosans\/v5\/8PXYbvM__bjl0rBnKiByg532VBCoA_HLsn85tSWZmdo.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quattrocentosans\/v5\/tXSgPxDl7Lk8Zr_5qX8FIbqxG25nQNOioCZSK4sU-CA.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quattrocentosans\/v5\/8N1PdXpbG6RtFvTjl-5E7buqAJxizi8Dk_SK5et7kMg.ttf"}},{"kind":"webfonts#webfont","family":"Cantata One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cantataone\/v2\/-a5FDvnBqaBMDaGgZYnEfqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Satisfy","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/satisfy\/v3\/PRlyepkd-JCGHiN8e9WV2w.ttf"}},{"kind":"webfonts#webfont","family":"Poiret One","variants":["regular"],"subsets":["latin-ext","cyrillic","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/poiretone\/v1\/dWcYed048E5gHGDIt8i1CPesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Calligraffitti","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/calligraffitti\/v4\/vLVN2Y-z65rVu1R7lWdvyDXz_orj3gX0_NzfmYulrko.ttf"}},{"kind":"webfonts#webfont","family":"Crete Round","variants":["regular","italic"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/creteround\/v2\/B8EwN421qqOCCT8vOH4wJ6CWcynf_cDxXwCLxiixG1c.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/creteround\/v2\/5xAt7XK2vkUdjhGtt98unUeOrDcLawS7-ssYqLr2Xp4.ttf"}},{"kind":"webfonts#webfont","family":"Rock Salt","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rocksalt\/v3\/Zy7JF9h9WbhD9V3SFMQ1UQ.ttf"}},{"kind":"webfonts#webfont","family":"Passion One","variants":["regular","700","900"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/passionone\/v3\/1UIK1tg3bKJ4J3o35M4heqCWcynf_cDxXwCLxiixG1c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/passionone\/v3\/feOcYDy2R-f3Ysy72PYJ2ne1Pd76Vl7zRpE7NLJQ7XU.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/passionone\/v3\/feOcYDy2R-f3Ysy72PYJ2ienaqEuufTBk9XMKnKmgDA.ttf"}},{"kind":"webfonts#webfont","family":"Telex","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/telex\/v1\/24-3xP9ywYeHOcFU3iGk8A.ttf"}},{"kind":"webfonts#webfont","family":"Droid Sans Mono","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/droidsansmono\/v4\/ns-m2xQYezAtqh7ai59hJcwD6PD0c3_abh9zHKQtbGU.ttf"}},{"kind":"webfonts#webfont","family":"Shadows Into Light Two","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/shadowsintolighttwo\/v1\/gDxHeefcXIo-lOuZFCn2xVQrZk-Pga5KeEE_oZjkQjQ.ttf"}},{"kind":"webfonts#webfont","family":"EB Garamond","variants":["regular"],"subsets":["cyrillic-ext","latin-ext","cyrillic","vietnamese","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ebgaramond\/v4\/CDR0kuiFK7I1OZ2hSdR7G6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Pathway Gothic One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2013-06-12","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/pathwaygothicone\/v1\/Lqv9ztoTUV8Q0FmQZzPqaA6A6xIYD7vYcYDop1i-K-c.ttf"}},{"kind":"webfonts#webfont","family":"Tinos","variants":["regular","italic","700","700italic"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","vietnamese","latin"],"version":"v5","lastModified":"2013-07-31","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tinos\/v5\/EqpUbkVmutfwZ0PjpoGwCg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tinos\/v5\/slfyzlasCr9vTsaP4lUh9A.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tinos\/v5\/vHXfhX8jZuQruowfon93yQ.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tinos\/v5\/M6kfzvDMM0CdxdraoFpG6vesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Old Standard TT","variants":["regular","italic","700"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oldstandardtt\/v4\/n6RTCDcIPWSE8UNBa4k-DLcB5jyhm1VsHs65c3QNDr0.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oldstandardtt\/v4\/QQT_AUSp4AV4dpJfIN7U5PWrQzeMtsHf8QsWQ2cZg3c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oldstandardtt\/v4\/5Ywdce7XEbTSbxs__4X1_HJqbZqK7TdZ58X80Q_Lw8Y.ttf"}},{"kind":"webfonts#webfont","family":"Waiting for the Sunrise","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/waitingforthesunrise\/v4\/eNfH7kLpF1PZWpsetF-ha9TChrNgrDiT3Zy6yGf3FnM.ttf"}},{"kind":"webfonts#webfont","family":"Quattrocento","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quattrocento\/v4\/WZDISdyil4HsmirlOdBRFC3USBnSvpkopQaUR-2r7iU.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quattrocento\/v4\/Uvi-cRwyvqFpl9j3oT2mqkD2ttfZwueP-QU272T9-k4.ttf"}},{"kind":"webfonts#webfont","family":"BenchNine","variants":["300","regular","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-10-03","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/benchnine\/v1\/ah9xtUy9wLQ3qnWa2p-piS3USBnSvpkopQaUR-2r7iU.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/benchnine\/v1\/h3OAlYqU3aOeNkuXgH2Q2w.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/benchnine\/v1\/qZpi6ZVZg3L2RL_xoBLxWS3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Unkempt","variants":["regular","700"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/unkempt\/v4\/NLLBeNSspr0RGs71R5LHWA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/unkempt\/v4\/V7H-GCl9bgwGwqFqTTgDHvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Gentium Book Basic","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gentiumbookbasic\/v3\/IRFxB2matTxrjZt6a3FUnrWDjKAyldGEr6eEi2MBNeY.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gentiumbookbasic\/v3\/qHqW2lwKO8-uTfIkh8FsUfXfjMwrYnmPVsQth2IcAPY.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gentiumbookbasic\/v3\/T2vUYmWzlqUtgLYdlemGnaWESMHIjnSjm9UUxYtEOko.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gentiumbookbasic\/v3\/632u7TMIoFDWQYUaHFUp5PA2A9KyRZEkn4TZVuhsWRM.ttf"}},{"kind":"webfonts#webfont","family":"Molengo","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/molengo\/v4\/jcjgeGuzv83I55AzOTpXNQ.ttf"}},{"kind":"webfonts#webfont","family":"Handlee","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/handlee\/v2\/6OfkXkyC0E5NZN80ED8u3A.ttf"}},{"kind":"webfonts#webfont","family":"Marck Script","variants":["regular"],"subsets":["latin-ext","cyrillic","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/marckscript\/v4\/O_D1NAZVOFOobLbVtW3bci3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Cherry Cream Soda","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cherrycreamsoda\/v3\/OrD-AUnFcZeeKa6F_c0_WxOiHiuAPYA9ry3O1RG2XIU.ttf"}},{"kind":"webfonts#webfont","family":"Varela","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/varela\/v4\/ON7qs0cKUUixhhDFXlZUjw.ttf"}},{"kind":"webfonts#webfont","family":"Pinyon Script","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/pinyonscript\/v3\/TzghnhfCn7TuE73f-CBQ0CeUSrabuTpOsMEiRLtKwk0.ttf"}},{"kind":"webfonts#webfont","family":"Architects Daughter","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/architectsdaughter\/v3\/RXTgOOQ9AAtaVOHxx0IUBMCy0EhZjHzu-y0e6uLf4Fg.ttf"}},{"kind":"webfonts#webfont","family":"Chivo","variants":["regular","italic","900","900italic"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/chivo\/v4\/L88PEuzS9eRfHRZhAPhZyw.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/chivo\/v4\/Oe3-Q-a2kBzPnhHck_baMg.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/chivo\/v4\/JAdkiWd46QCW4vOsj3dzTA.ttf","900italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/chivo\/v4\/LoszYnE86q2wJEOjCigBQ_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Allerta","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/allerta\/v4\/s9FOEuiJFTNbMe06ifzV8g.ttf"}},{"kind":"webfonts#webfont","family":"Patrick Hand","variants":["regular"],"subsets":["latin-ext","vietnamese","latin"],"version":"v7","lastModified":"2013-02-27","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/patrickhand\/v7\/9BG3JJgt_HlF3NpEUehL0C3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Orbitron","variants":["regular","500","700","900"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/orbitron\/v3\/DY8swouAZjR3RaUPRf0HDQ.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/orbitron\/v3\/p-y_ffzMdo5JN_7ia0vYEqCWcynf_cDxXwCLxiixG1c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/orbitron\/v3\/PS9_6SLkY1Y6OgPO3APr6qCWcynf_cDxXwCLxiixG1c.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/orbitron\/v3\/2I3-8i9hT294TE_pyjy9SaCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Bevan","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-08-08","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bevan\/v4\/Rtg3zDsCeQiaJ_Qno22OJA.ttf"}},{"kind":"webfonts#webfont","family":"Amaranth","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/amaranth\/v3\/7VcBog22JBHsHXHdnnycTA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/amaranth\/v3\/UrJlRY9LcVERJSvggsdBqPesZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/amaranth\/v3\/j5OFHqadfxyLnQRxFeox6qCWcynf_cDxXwCLxiixG1c.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/amaranth\/v3\/BHyuYFj9nqLFNvOvGh0xTwJKKGfqHaYFsRG-T3ceEVo.ttf"}},{"kind":"webfonts#webfont","family":"Reenie Beanie","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/reeniebeanie\/v3\/ljpKc6CdXusL1cnGUSamX4jjx0o0jr6fNXxPgYh_a8Q.ttf"}},{"kind":"webfonts#webfont","family":"Archivo Black","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/archivoblack\/v1\/WoAoVT7K3k7hHfxKbvB6B51XQG8isOYYJhPIYAyrESQ.ttf"}},{"kind":"webfonts#webfont","family":"Doppio One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/doppioone\/v1\/WHZ3HJQotpk_4aSMNBo_t_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Jockey One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/jockeyone\/v3\/cAucnOZLvFo07w2AbufBCfesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Coda","variants":["regular","800"],"subsets":["latin"],"version":"v7","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/coda\/v7\/yHDvulhg-P-p2KRgRrnUYw.ttf","800":"http:\/\/themes.googleusercontent.com\/static\/fonts\/coda\/v7\/6ZIw0sbALY0KTMWllZB3hQ.ttf"}},{"kind":"webfonts#webfont","family":"Actor","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/actor\/v3\/ugMf40CrRK6Jf6Yz_xNSmQ.ttf"}},{"kind":"webfonts#webfont","family":"Gloria Hallelujah","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gloriahallelujah\/v4\/CA1k7SlXcY5kvI81M_R28Q3RdPdyebSUyJECJouPsvA.ttf"}},{"kind":"webfonts#webfont","family":"Carme","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/carme\/v4\/08E0NP1eRBEyFRUadmMfgA.ttf"}},{"kind":"webfonts#webfont","family":"Leckerli One","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-08-08","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/leckerlione\/v4\/S2Y_iLrItTu8kIJTkS7DrC3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Sanchez","variants":["regular","italic"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sanchez\/v1\/BEL8ao-E2LJ5eHPLB2UAiw.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sanchez\/v1\/iSrhkWLexUZzDeNxNEHtzA.ttf"}},{"kind":"webfonts#webfont","family":"Syncopate","variants":["regular","700"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/syncopate\/v3\/RQVwO52fAH6MI764EcaYtw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/syncopate\/v3\/S5z8ixiOoC4WJ1im6jAlYC3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Didact Gothic","variants":["regular"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/didactgothic\/v4\/v8_72sD3DYMKyM0dn3LtWotBLojGU5Qdl8-5NL4v70w.ttf"}},{"kind":"webfonts#webfont","family":"Neucha","variants":["regular"],"subsets":["cyrillic","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/neucha\/v4\/bijdhB-TzQdtpl0ykhGh4Q.ttf"}},{"kind":"webfonts#webfont","family":"Source Code Pro","variants":["200","300","regular","500","600","700","900"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2013-01-23","files":{"200":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcecodepro\/v3\/leqv3v-yTsJNC7nFznSMqaXvKVW_haheDNrHjziJZVk.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcecodepro\/v3\/leqv3v-yTsJNC7nFznSMqVP7R5lD_au4SZC6Ks_vyWs.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcecodepro\/v3\/mrl8jkM18OlOQN8JLgasD9Rl0pGnog23EMYRrBmUzJQ.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcecodepro\/v3\/leqv3v-yTsJNC7nFznSMqX63uKwMO11Of4rJWV582wg.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcecodepro\/v3\/leqv3v-yTsJNC7nFznSMqeiMeWyi5E_-XkTgB5psiDg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcecodepro\/v3\/leqv3v-yTsJNC7nFznSMqfgXsetDviZcdR5OzC1KPcw.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sourcecodepro\/v3\/leqv3v-yTsJNC7nFznSMqRA_awHl7mXRjE_LQVochcU.ttf"}},{"kind":"webfonts#webfont","family":"Kameron","variants":["regular","700"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kameron\/v4\/9r8HYhqDSwcq9WMjupL82A.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kameron\/v4\/rabVVbzlflqvmXJUFlKnu_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Lusitana","variants":["regular","700"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lusitana\/v1\/l1h9VDomkwbdzbPdmLcUIw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lusitana\/v1\/GWtZyUsONxgkdl3Mc1P7FKCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Share","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-10-31","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/share\/v1\/1ytD7zSb_-g9I2GG67vmVw.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/share\/v1\/a9YGdQWFRlNJ0zClJVaY3Q.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/share\/v1\/XrU8e7a1YKurguyY2azk1Q.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/share\/v1\/A992-bLVYwAflKu6iaznufesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Copse","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/copse\/v3\/wikLrtPGjZDvZ5w2i5HLWg.ttf"}},{"kind":"webfonts#webfont","family":"Covered By Your Grace","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/coveredbyyourgrace\/v3\/6ozZp4BPlrbDRWPe3EBGA6CVUMdvnk-GcAiZQrX9Gek.ttf"}},{"kind":"webfonts#webfont","family":"Trocchi","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/trocchi\/v1\/uldNPaKrUGVeGCVsmacLwA.ttf"}},{"kind":"webfonts#webfont","family":"Walter Turncoat","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/walterturncoat\/v3\/sG9su5g4GXy1KP73cU3hvQplL2YwNeota48DxFlGDUo.ttf"}},{"kind":"webfonts#webfont","family":"Cardo","variants":["regular","italic","700"],"subsets":["latin-ext","greek-ext","greek","latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cardo\/v5\/jbkF2_R0FKUEZTq5dwSknQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cardo\/v5\/pcv4Np9tUkq0YREYUcEEJQ.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cardo\/v5\/lQN30weILimrKvp8rZhF1w.ttf"}},{"kind":"webfonts#webfont","family":"Goudy Bookletter 1911","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/goudybookletter1911\/v3\/l5lwlGTN3pEY5Bf-rQEuIIjNDsyURsIKu4GSfvSE4mA.ttf"}},{"kind":"webfonts#webfont","family":"Paytone One","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/paytoneone\/v5\/3WCxC7JAJjQHQVoIE0ZwvqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Antic Slab","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/anticslab\/v1\/PSbJCTKkAS7skPdkd7AKEvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Nothing You Could Do","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/nothingyoucoulddo\/v3\/jpk1K3jbJoyoK0XKaSyQAf-TpkXjXYGWiJZAEtBRjPU.ttf"}},{"kind":"webfonts#webfont","family":"Rancho","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rancho\/v3\/ekp3-4QykC4--6KaslRgHA.ttf"}},{"kind":"webfonts#webfont","family":"Just Me Again Down Here","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v5","lastModified":"2013-05-22","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/justmeagaindownhere\/v5\/sN06iTc9ITubLTgXoG-kc3M9eVLpVTSK6TqZTIgBrWQ.ttf"}},{"kind":"webfonts#webfont","family":"Oleo Script","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oleoscript\/v2\/21stZcmPyzbQVXtmGegyqKCWcynf_cDxXwCLxiixG1c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oleoscript\/v2\/hudNQFKFl98JdNnlo363fne1Pd76Vl7zRpE7NLJQ7XU.ttf"}},{"kind":"webfonts#webfont","family":"PT Serif Caption","variants":["regular","italic"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v5","lastModified":"2013-05-29","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptserifcaption\/v5\/7xkFOeTxxO1GMC1suOUYWVsRioCqs5fohhaYel24W3k.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptserifcaption\/v5\/0kfPsmrmTSgiec7u_Wa0DB1mqvzPHelJwRcF_s_EUM0.ttf"}},{"kind":"webfonts#webfont","family":"Kotta One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kottaone\/v1\/AB2Q7hVw6niJYDgLvFXu5w.ttf"}},{"kind":"webfonts#webfont","family":"Loved by the King","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lovedbytheking\/v3\/wg03xD4cWigj4YDufLBSr8io2AFEwwMpu7y5KyiyAJc.ttf"}},{"kind":"webfonts#webfont","family":"Nixie One","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-08-01","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/nixieone\/v4\/h6kQfmzm0Shdnp3eswRaqQ.ttf"}},{"kind":"webfonts#webfont","family":"Happy Monkey","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/happymonkey\/v2\/c2o0ps8nkBmaOYctqBq1rS3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Schoolbell","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/schoolbell\/v3\/95-3djEuubb3cJx-6E7j4vesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Overlock","variants":["regular","italic","700","700italic","900","900italic"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/overlock\/v2\/Z8oYsGi88-E1cUB8YBFMAg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/overlock\/v2\/rq6EacukHROOBrFrK_zF6_esZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/overlock\/v2\/Fexr8SqXM8Bm_gEVUA7AKaCWcynf_cDxXwCLxiixG1c.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/overlock\/v2\/wFWnYgeXKYBks6gEUwYnfAJKKGfqHaYFsRG-T3ceEVo.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/overlock\/v2\/YPJCVTT8ZbG3899l_-KIGqCWcynf_cDxXwCLxiixG1c.ttf","900italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/overlock\/v2\/iOZhxT2zlg7W5ij_lb-oDp0EAVxt0G0biEntp43Qt6E.ttf"}},{"kind":"webfonts#webfont","family":"Just Another Hand","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/justanotherhand\/v4\/fKV8XYuRNNagXr38eqbRf99BnJIEGrvoojniP57E51c.ttf"}},{"kind":"webfonts#webfont","family":"Enriqueta","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/enriqueta\/v2\/_p90TrIwR1SC-vDKtmrv6A.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/enriqueta\/v2\/I27Pb-wEGH2ajLYP0QrtSC3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Sorts Mill Goudy","variants":["regular","italic"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sortsmillgoudy\/v3\/JzRrPKdwEnE8F1TDmDLMUlIL2Qjg-Xlsg_fhGbe2P5U.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sortsmillgoudy\/v3\/UUu1lKiy4hRmBWk599VL1TYNkCNSzLyoucKmbTguvr0.ttf"}},{"kind":"webfonts#webfont","family":"Viga","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/viga\/v2\/uD87gDbhS7frHLX4uL6agg.ttf"}},{"kind":"webfonts#webfont","family":"Kaushan Script","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kaushanscript\/v1\/qx1LSqts-NtiKcLw4N03IBnpV0hQCek3EmWnCPrvGRM.ttf"}},{"kind":"webfonts#webfont","family":"Scada","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","cyrillic","latin"],"version":"v1","lastModified":"2012-09-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/scada\/v1\/iZNC3ZEYwe3je6H-28d5Ug.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/scada\/v1\/PCGyLT1qNawkOUQ3uHFhBw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/scada\/v1\/t6XNWdMdVWUz93EuRVmifQ.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/scada\/v1\/kLrBIf7V4mDMwcd_Yw7-D_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Berkshire Swash","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/berkshireswash\/v1\/4RZJjVRPjYnC2939hKCAimKfbtsIjCZP_edQljX9gR0.ttf"}},{"kind":"webfonts#webfont","family":"Bangers","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bangers\/v4\/WAffdge5w99Xif-DLeqmcA.ttf"}},{"kind":"webfonts#webfont","family":"Marmelad","variants":["regular"],"subsets":["latin-ext","cyrillic","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/marmelad\/v3\/jI0_FBlSOIRLL0ePWOhOwQ.ttf"}},{"kind":"webfonts#webfont","family":"Vidaloka","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/vidaloka\/v5\/C6Nul0ogKUWkx356rrt9RA.ttf"}},{"kind":"webfonts#webfont","family":"Russo One","variants":["regular"],"subsets":["latin-ext","cyrillic","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/russoone\/v1\/zfwxZ--UhUc7FVfgT21PRQ.ttf"}},{"kind":"webfonts#webfont","family":"Neuton","variants":["200","300","regular","italic","700","800"],"subsets":["latin-ext","latin"],"version":"v5","lastModified":"2012-07-25","files":{"200":"http:\/\/themes.googleusercontent.com\/static\/fonts\/neuton\/v5\/DA3Mkew3XqSkPpi1f4tJow.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/neuton\/v5\/xrc_aZ2hx-gdeV0mlY8Vww.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/neuton\/v5\/9R-MGIOQUdjAVeB6nE6PcQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/neuton\/v5\/uVMT3JOB5BNFi3lgPp6kEg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/neuton\/v5\/gnWpkWY7DirkKiovncYrfg.ttf","800":"http:\/\/themes.googleusercontent.com\/static\/fonts\/neuton\/v5\/XPzBQV4lY6enLxQG9cF1jw.ttf"}},{"kind":"webfonts#webfont","family":"Rambla","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rambla\/v1\/YaTmpvm5gFg_ShJKTQmdzg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rambla\/v1\/mhUgsKmp0qw3uATdDDAuwA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rambla\/v1\/C5VZH8BxQKmnBuoC00UPpw.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rambla\/v1\/ziMzUZya6QahrKONSI1TzqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Allan","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/allan\/v4\/T3lemhgZmLQkQI2Qc2bQHA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/allan\/v4\/zSxQiwo7wgnr7KkMXhSiag.ttf"}},{"kind":"webfonts#webfont","family":"Rochester","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rochester\/v3\/bnj8tmQBiOkdji_G_yvypg.ttf"}},{"kind":"webfonts#webfont","family":"Homemade Apple","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/homemadeapple\/v3\/yg3UMEsefgZ8IHz_ryz86BiPOmFWYV1WlrJkRafc4c0.ttf"}},{"kind":"webfonts#webfont","family":"Domine","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-12-06","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/domine\/v1\/wfVIgamVFjMNQAEWurCiHA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/domine\/v1\/phBcG1ZbQFxUIt18hPVxnw.ttf"}},{"kind":"webfonts#webfont","family":"Julius Sans One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-10-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/juliussansone\/v1\/iU65JP9acQHPDLkdalCF7jjVlsJB_M_Q_LtZxsoxvlw.ttf"}},{"kind":"webfonts#webfont","family":"Rosario","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v7","lastModified":"2013-05-22","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rosario\/v7\/bL-cEh8dXtDupB2WccA2LA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rosario\/v7\/pkflNy18HEuVVx4EOjeb_Q.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rosario\/v7\/nrS6PJvDWN42RP4TFWccd_esZW2xOQ-xsNqO47m55DA.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rosario\/v7\/EOgFX2Va5VGrkhn_eDpIRS3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Damion","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/damion\/v3\/13XtECwKxhD_VrOqXL4SiA.ttf"}},{"kind":"webfonts#webfont","family":"Hammersmith One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/hammersmithone\/v4\/FWNn6ITYqL6or7ZTmBxRhjjVlsJB_M_Q_LtZxsoxvlw.ttf"}},{"kind":"webfonts#webfont","family":"Jura","variants":["300","regular","500","600"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","latin"],"version":"v4","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/jura\/v4\/Rqx_xy1UnN0C7wD3FUSyPQ.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/jura\/v4\/YAWMwF3sN0KCbynMq-Yr_Q.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/jura\/v4\/16xhfjHCiaLj3tsqqgmtGg.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/jura\/v4\/iwseduOwJSdY8wQ1Y6CJdA.ttf"}},{"kind":"webfonts#webfont","family":"Convergence","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/convergence\/v2\/eykrGz1NN_YpQmkAZjW-qKCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Great Vibes","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/greatvibes\/v1\/4Mi5RG_9LjQYrTU55GN_L6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Glegoo","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/glegoo\/v1\/2tf-h3n2A_SNYXEO0C8bKw.ttf"}},{"kind":"webfonts#webfont","family":"Spirax","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/spirax\/v2\/IOKqhk-Ccl7y31yDsePPkw.ttf"}},{"kind":"webfonts#webfont","family":"Coustard","variants":["regular","900"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/coustard\/v3\/iO2Rs5PmqAEAXoU3SkMVBg.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/coustard\/v3\/W02OCWO6OfMUHz6aVyegQ6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Ubuntu Mono","variants":["regular","italic","700","700italic"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntumono\/v3\/EgeuS9OtEmA0y_JRo03MQaCWcynf_cDxXwCLxiixG1c.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntumono\/v3\/KAKuHXAHZOeECOWAHsRKA0eOrDcLawS7-ssYqLr2Xp4.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntumono\/v3\/ceqTZGKHipo8pJj4molytne1Pd76Vl7zRpE7NLJQ7XU.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ubuntumono\/v3\/n_d8tv_JOIiYyMXR4eaV9c_zJjSACmk0BRPxQqhnNLU.ttf"}},{"kind":"webfonts#webfont","family":"Alfa Slab One","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alfaslabone\/v2\/Qx6FPcitRwTC_k88tLPc-Yjjx0o0jr6fNXxPgYh_a8Q.ttf"}},{"kind":"webfonts#webfont","family":"Metrophobic","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/metrophobic\/v3\/SaglWZWCrrv_D17u1i4v_aCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"The Girl Next Door","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/thegirlnextdoor\/v4\/cWRA4JVGeEcHGcPl5hmX7kzo0nFFoM60ux_D9BUymX4.ttf"}},{"kind":"webfonts#webfont","family":"Bad Script","variants":["regular"],"subsets":["cyrillic","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/badscript\/v2\/cRyUs0nJ2eMQFHwBsZNRXfesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Andika","variants":["regular"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/andika\/v3\/oe-ag1G0lcqZ3IXfeEgaGg.ttf"}},{"kind":"webfonts#webfont","family":"Aldrich","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/aldrich\/v3\/kMMW1S56gFx7RP_mW1g-Eg.ttf"}},{"kind":"webfonts#webfont","family":"Sansita One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sansitaone\/v3\/xWqf68oB50JXqGIRR0h2hqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Allerta Stencil","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/allertastencil\/v4\/CdSZfRtHbQrBohqmzSdDYFf2eT4jUldwg_9fgfY_tHc.ttf"}},{"kind":"webfonts#webfont","family":"Radley","variants":["regular","italic"],"subsets":["latin-ext","latin"],"version":"v6","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/radley\/v6\/FgE9di09a-mXGzAIyI6Q9Q.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/radley\/v6\/Z_JcACuPAOO2f9kzQcGRug.ttf"}},{"kind":"webfonts#webfont","family":"Cinzel","variants":["regular","700","900"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cinzel\/v1\/GF7dy_Nc-a6EaHYSyGd-EA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cinzel\/v1\/nYcFQ6_3pf_6YDrOFjBR8Q.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cinzel\/v1\/FTBj72ozM2cEOSxiVsRb3A.ttf"}},{"kind":"webfonts#webfont","family":"ABeeZee","variants":["regular","italic"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-31","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/abeezee\/v1\/mE5BOuZKGln_Ex0uYKpIaw.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/abeezee\/v1\/kpplLynmYgP0YtlJA3atRw.ttf"}},{"kind":"webfonts#webfont","family":"Judson","variants":["regular","italic","700"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/judson\/v4\/znM1AAs0eytUaJzf1CrYZQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/judson\/v4\/GVqQW9P52ygW-ySq-CLwAA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/judson\/v4\/he4a2LwiPJc7r8x0oKCKiA.ttf"}},{"kind":"webfonts#webfont","family":"Arbutus Slab","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arbutusslab\/v1\/6k3Yp6iS9l4jRIpynA8qMy3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Gentium Basic","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gentiumbasic\/v4\/KCktj43blvLkhOTolFn-MYtBLojGU5Qdl8-5NL4v70w.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gentiumbasic\/v4\/qoFz4NSMaYC2UmsMAG3lyTj3mvXnCeAk09uTtmkJGRc.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gentiumbasic\/v4\/2qL6yulgGf0wwgOp-UqGyLNuTeOOLg3nUymsEEGmdO0.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gentiumbasic\/v4\/8N9-c_aQDJ8LbI1NGVMrwtswO1vWwP9exiF8s0wqW10.ttf"}},{"kind":"webfonts#webfont","family":"Petit Formal Script","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/petitformalscript\/v1\/OEZwr2-ovBsq2n3ACCKoEvVPl2Gjtxj0D6F7QLy1VQc.ttf"}},{"kind":"webfonts#webfont","family":"Michroma","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/michroma\/v4\/0c2XrW81_QsiKV8T9thumA.ttf"}},{"kind":"webfonts#webfont","family":"Orienta","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/orienta\/v1\/_NKSk93mMs0xsqtfjCsB3Q.ttf"}},{"kind":"webfonts#webfont","family":"Fontdiner Swanky","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fontdinerswanky\/v3\/8_GxIO5ixMtn5P6COsF3TlBjMPLzPAFJwRBn-s1U7kA.ttf"}},{"kind":"webfonts#webfont","family":"Volkhov","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/volkhov\/v5\/MDIZAofe1T_J3un5Kgo8zg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/volkhov\/v5\/1rTjmztKEpbkKH06JwF8Yw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/volkhov\/v5\/L8PbKS-kEoLHm7nP--NCzPesZW2xOQ-xsNqO47m55DA.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/volkhov\/v5\/W6oG0QDDjCgj0gmsHE520C3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Gochi Hand","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gochihand\/v4\/KT1-WxgHsittJ34_20IfAPesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Love Ya Like A Sister","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/loveyalikeasister\/v4\/LzkxWS-af0Br2Sk_YgSJY-ad1xEP8DQfgfY8MH9aBUg.ttf"}},{"kind":"webfonts#webfont","family":"Puritan","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/puritan\/v4\/wv_RtgVBSCn-or2MC0n4Kg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/puritan\/v4\/BqZX8Tp200LeMv1KlzXgLQ.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/puritan\/v4\/pJS2SdwI0SCiVnO0iQSFT_esZW2xOQ-xsNqO47m55DA.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/puritan\/v4\/rFG3XkMJL75nUNZwCEIJqC3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Six Caps","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sixcaps\/v4\/_XeDnO0HOV8Er9u97If1tQ.ttf"}},{"kind":"webfonts#webfont","family":"Courgette","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/courgette\/v1\/2YO0EYtyE9HUPLZprahpZA.ttf"}},{"kind":"webfonts#webfont","family":"Inder","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2013-11-21","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/inder\/v2\/C38TwecLTfKxIHDc_Adcrw.ttf"}},{"kind":"webfonts#webfont","family":"Sintony","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2013-02-27","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sintony\/v1\/IDhCijoIMev2L6Lg5QsduQ.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sintony\/v1\/zVXQB1wqJn6PE4dWXoYpvPesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Shanti","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/shanti\/v4\/lc4nG_JG6Q-2FQSOMMhb_w.ttf"}},{"kind":"webfonts#webfont","family":"Sancreek","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sancreek\/v4\/8ZacBMraWMvHly4IJI3esw.ttf"}},{"kind":"webfonts#webfont","family":"Kristi","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kristi\/v4\/aRsgBQrkQkMlu4UPSnJyOQ.ttf"}},{"kind":"webfonts#webfont","family":"Anonymous Pro","variants":["regular","italic","700","700italic"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/anonymouspro\/v3\/Zhfjj_gat3waL4JSju74E-V_5zh5b-_HiooIRUBwn1A.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/anonymouspro\/v3\/q0u6LFHwttnT_69euiDbWKwIsuKDCXG0NQm7BvAgx-c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/anonymouspro\/v3\/WDf5lZYgdmmKhO8E1AQud--Cz_5MeePnXDAcLNWyBME.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/anonymouspro\/v3\/_fVr_XGln-cetWSUc-JpfA1LL9bfs7wyIp6F8OC9RxA.ttf"}},{"kind":"webfonts#webfont","family":"Advent Pro","variants":["100","200","300","regular","500","600","700"],"subsets":["latin-ext","greek","latin"],"version":"v1","lastModified":"2012-07-25","files":{"100":"http:\/\/themes.googleusercontent.com\/static\/fonts\/adventpro\/v1\/87-JOpSUecTG50PBYK4ysi3USBnSvpkopQaUR-2r7iU.ttf","200":"http:\/\/themes.googleusercontent.com\/static\/fonts\/adventpro\/v1\/URTSSjIp0Wr-GrjxFdFWnGeudeTO44zf-ht3k-KNzwg.ttf","300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/adventpro\/v1\/sJaBfJYSFgoB80OL1_66m0eOrDcLawS7-ssYqLr2Xp4.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/adventpro\/v1\/1NxMBeKVcNNH2H46AUR3wfesZW2xOQ-xsNqO47m55DA.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/adventpro\/v1\/7kBth2-rT8tP40RmMMXMLJp-63r6doWhTEbsfBIRJ7A.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/adventpro\/v1\/3Jo-2maCzv2QLzQBzaKHV_pTEJqju4Hz1txDWij77d4.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/adventpro\/v1\/M4I6QiICt-ey_wZTpR2gKwJKKGfqHaYFsRG-T3ceEVo.ttf"}},{"kind":"webfonts#webfont","family":"Limelight","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/limelight\/v4\/5dTfN6igsXjLjOy8QQShcg.ttf"}},{"kind":"webfonts#webfont","family":"Merienda One","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/meriendaone\/v4\/bCA-uDdUx6nTO8SjzCLXvS3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Crushed","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/crushed\/v3\/aHwSejs3Kt0Lg95u7j32jA.ttf"}},{"kind":"webfonts#webfont","family":"Days One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/daysone\/v3\/kzwZjNhc1iabMsrc_hKBIA.ttf"}},{"kind":"webfonts#webfont","family":"Magra","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/magra\/v1\/hoZ13bwCXBxuGZqAudgc5A.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/magra\/v1\/6fOM5sq5cIn8D0RjX8Lztw.ttf"}},{"kind":"webfonts#webfont","family":"Carrois Gothic","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/carroisgothic\/v1\/GCgb7bssGpwp7V5ynxmWy2x3d0cwUleGuRTmCYfCUaM.ttf"}},{"kind":"webfonts#webfont","family":"IM Fell English","variants":["regular","italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfellenglish\/v3\/xwIisCqGFi8pff-oa9uSVHGNmx1fDm-u2eBJHQkdrmk.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfellenglish\/v3\/Z3cnIAI_L3XTRfz4JuZKbuewladMPCWTthtMv9cPS-c.ttf"}},{"kind":"webfonts#webfont","family":"Racing Sans One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-08-16","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/racingsansone\/v1\/1r3DpWaCiT7y3PD4KgkNyDjVlsJB_M_Q_LtZxsoxvlw.ttf"}},{"kind":"webfonts#webfont","family":"Cabin Sketch","variants":["regular","700"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabinsketch\/v5\/d9fijO34zQajqQvl3YHRCS3USBnSvpkopQaUR-2r7iU.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cabinsketch\/v5\/ki3SSN5HMOO0-IOLOj069ED2ttfZwueP-QU272T9-k4.ttf"}},{"kind":"webfonts#webfont","family":"Arapey","variants":["regular","italic"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arapey\/v2\/dqu823lrSYn8T2gApTdslA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arapey\/v2\/pY-Xi5JNBpaWxy2tZhEm5A.ttf"}},{"kind":"webfonts#webfont","family":"Prata","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/prata\/v3\/3gmx8r842loRRm9iQkCDGg.ttf"}},{"kind":"webfonts#webfont","family":"Boogaloo","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/boogaloo\/v3\/4Wu1tvFMoB80fSu8qLgQfQ.ttf"}},{"kind":"webfonts#webfont","family":"Ovo","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ovo\/v4\/mFg27dimu3s9t09qjCwB1g.ttf"}},{"kind":"webfonts#webfont","family":"Pompiere","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/pompiere\/v3\/o_va2p9CD5JfmFohAkGZIA.ttf"}},{"kind":"webfonts#webfont","family":"Cookie","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cookie\/v4\/HxeUC62y_YdDbiFlze357A.ttf"}},{"kind":"webfonts#webfont","family":"Cutive","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cutive\/v4\/G2bW-ImyOCwKxBkLyz39YQ.ttf"}},{"kind":"webfonts#webfont","family":"Slackey","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/slackey\/v3\/evRIMNhGVCRJvCPv4kteeA.ttf"}},{"kind":"webfonts#webfont","family":"Mako","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mako\/v4\/z5zSLmfPlv1uTVAdmJBLXg.ttf"}},{"kind":"webfonts#webfont","family":"Abril Fatface","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/abrilfatface\/v5\/X1g_KwGeBV3ajZIXQ9VnDojjx0o0jr6fNXxPgYh_a8Q.ttf"}},{"kind":"webfonts#webfont","family":"Alike","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alike\/v4\/Ho8YpRKNk_202fwDiGNIyw.ttf"}},{"kind":"webfonts#webfont","family":"Lekton","variants":["regular","italic","700"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lekton\/v4\/r483JYmxf5PjIm4jVAm8Yg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lekton\/v4\/_UbDIPBA1wDqSbhp-OED7A.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lekton\/v4\/WZw-uL8WTkx3SBVfTlevXQ.ttf"}},{"kind":"webfonts#webfont","family":"Average Sans","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averagesans\/v1\/dnU3R-5A_43y5bIyLztPsS3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Fredericka the Great","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/frederickathegreat\/v2\/7Es8Lxoku-e5eOZWpxw18nrnet6gXN1McwdQxS1dVrI.ttf"}},{"kind":"webfonts#webfont","family":"Fenix","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fenix\/v1\/Ak8wR3VSlAN7VN_eMeJj7Q.ttf"}},{"kind":"webfonts#webfont","family":"Gruppo","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gruppo\/v4\/pS_JM0cK_piBZve-lfUq9w.ttf"}},{"kind":"webfonts#webfont","family":"Montserrat Alternates","variants":["regular","700"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/montserratalternates\/v1\/z2n1Sjxk9souK3HCtdHuklPuEVRGaG9GCQnmM16YWq0.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/montserratalternates\/v1\/YENqOGAVzwIHjYNjmKuAZpeqBKvsAhm-s2I4RVSXFfc.ttf"}},{"kind":"webfonts#webfont","family":"Englebert","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/englebert\/v1\/sll38iOvOuarDTYBchlP3Q.ttf"}},{"kind":"webfonts#webfont","family":"Give You Glory","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/giveyouglory\/v3\/DFEWZFgGmfseyIdGRJAxuBwwkpSPZdvjnMtysdqprfI.ttf"}},{"kind":"webfonts#webfont","family":"Homenaje","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/homenaje\/v2\/v0YBU0iBRrGdVjDNQILxtA.ttf"}},{"kind":"webfonts#webfont","family":"Parisienne","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/parisienne\/v1\/TW74B5QISJNx9moxGlmJfvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Alex Brush","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alexbrush\/v3\/ooh3KJFbKJSUoIRWfiu8o_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Fugaz One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fugazone\/v3\/5tteVDCwxsr8-5RuSiRWOw.ttf"}},{"kind":"webfonts#webfont","family":"Caudex","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","greek-ext","greek","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/caudex\/v3\/PWEexiHLDmQbn2b1OPZWfg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/caudex\/v3\/XjMZF6XCisvV3qapD4oJdw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/caudex\/v3\/PetCI4GyQ5Q3LiOzUu_mMg.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/caudex\/v3\/yT8YeHLjaJvQXlUEYOA8gqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Contrail One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/contrailone\/v3\/b41KxjgiyqX-hkggANDU6C3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Kranky","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kranky\/v3\/C8dxxTS99-fZ84vWk8SDrg.ttf"}},{"kind":"webfonts#webfont","family":"Yellowtail","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/yellowtail\/v3\/HLrU6lhCTjXfLZ7X60LcB_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Brawler","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/brawler\/v3\/3gfSw6imxQnQxweVITqUrg.ttf"}},{"kind":"webfonts#webfont","family":"Headland One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/headlandone\/v1\/iGmBeOvQGfq9DSbjJ8jDVy3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Mountains of Christmas","variants":["regular","700"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mountainsofchristmas\/v5\/dVGBFPwd6G44IWDbQtPew2Auds3jz1Fxb61CgfaGDr4.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mountainsofchristmas\/v5\/PymufKtHszoLrY0uiAYKNM9cPTbSBTrQyTa5TWAe3vE.ttf"}},{"kind":"webfonts#webfont","family":"Ultra","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ultra\/v4\/OW8uXkOstRADuhEmGOFQLA.ttf"}},{"kind":"webfonts#webfont","family":"Alegreya SC","variants":["regular","italic","700","700italic","900","900italic"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alegreyasc\/v3\/3ozeFnTbygMK6PfHh8B-iqCWcynf_cDxXwCLxiixG1c.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alegreyasc\/v3\/GOqmv3FLsJ2r6ZALMZVBmkeOrDcLawS7-ssYqLr2Xp4.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alegreyasc\/v3\/M9OIREoxDkvynwTpBAYUq3e1Pd76Vl7zRpE7NLJQ7XU.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alegreyasc\/v3\/5PCoU7IUfCicpKBJtBmP6c_zJjSACmk0BRPxQqhnNLU.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alegreyasc\/v3\/M9OIREoxDkvynwTpBAYUqyenaqEuufTBk9XMKnKmgDA.ttf","900italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alegreyasc\/v3\/5PCoU7IUfCicpKBJtBmP6U_yTOUGsoC54csJe1b-IRw.ttf"}},{"kind":"webfonts#webfont","family":"Oleo Script Swash Caps","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oleoscriptswashcaps\/v1\/vdWhGqsBUAP-FF3NOYTe4iMF4kXAPemmyaDpMXQ31P0.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oleoscriptswashcaps\/v1\/HMO3ftxA9AU5floml9c755reFYaXZ4zuJXJ8fr8OO1g.ttf"}},{"kind":"webfonts#webfont","family":"Sunshiney","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sunshiney\/v3\/kaWOb4pGbwNijM7CkxK1sQ.ttf"}},{"kind":"webfonts#webfont","family":"Cantora One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cantoraone\/v2\/oI-DS62RbHI8ZREjp73ehqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Rationale","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rationale\/v4\/7M2eN-di0NGLQse7HzJRfg.ttf"}},{"kind":"webfonts#webfont","family":"Quantico","variants":["regular","italic","700","700italic"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quantico\/v2\/pwSnP8Xpaix2rIz99HrSlQ.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quantico\/v2\/KQhDd2OsZi6HiITUeFQ2U_esZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quantico\/v2\/OVZZzjcZ3Hkq2ojVcUtDjaCWcynf_cDxXwCLxiixG1c.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quantico\/v2\/HeCYRcZbdRso3ZUu01ELbQJKKGfqHaYFsRG-T3ceEVo.ttf"}},{"kind":"webfonts#webfont","family":"Port Lligat Slab","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/portlligatslab\/v2\/CUEdhRk7oC7up0p6t0g4PxLSPACXvawUYCBEnHsOe30.ttf"}},{"kind":"webfonts#webfont","family":"Tenor Sans","variants":["regular"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tenorsans\/v4\/dUBulmjNJJInvK5vL7O9yfesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Carter One","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/carterone\/v5\/5X_LFvdbcB7OBG7hBgZ7fPesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Coda Caption","variants":["800"],"subsets":["latin"],"version":"v5","lastModified":"2012-08-01","files":{"800":"http:\/\/themes.googleusercontent.com\/static\/fonts\/codacaption\/v5\/YDl6urZh-DUFhiMBTgAnz_qsay_1ZmRGmC8pVRdIfAg.ttf"}},{"kind":"webfonts#webfont","family":"Bentham","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bentham\/v3\/5-Mo8Fe7yg5tzV0GlQIuzQ.ttf"}},{"kind":"webfonts#webfont","family":"Cousine","variants":["regular","italic","700","700italic"],"subsets":["cyrillic-ext","latin-ext","greek-ext","cyrillic","greek","vietnamese","latin"],"version":"v6","lastModified":"2013-08-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cousine\/v6\/GYX4bPXObJNJo63QJEUnLg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cousine\/v6\/1WtIuajLoo8vjVwsrZ3eOg.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cousine\/v6\/FXEOnNUcCzhdtoBxiq-lovesZW2xOQ-xsNqO47m55DA.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cousine\/v6\/y_AZ5Sz-FwL1lux2xLSTZS3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Kavoon","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2013-01-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kavoon\/v1\/382m-6baKXqJFQjEgobt6Q.ttf"}},{"kind":"webfonts#webfont","family":"Alice","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alice\/v4\/wZTAfivekBqIg-rk63nFvQ.ttf"}},{"kind":"webfonts#webfont","family":"Ruda","variants":["regular","700","900"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ruda\/v4\/jPEIPB7DM2DNK_uBGv2HGw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ruda\/v4\/JABOu1SYOHcGXVejUq4w6g.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ruda\/v4\/Uzusv-enCjoIrznlJJaBRw.ttf"}},{"kind":"webfonts#webfont","family":"Short Stack","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/shortstack\/v3\/v4dXPI0Rm8XN9gk4SDdqlqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Wire One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/wireone\/v3\/sRLhaQOQpWnvXwIx0CycQw.ttf"}},{"kind":"webfonts#webfont","family":"Salsa","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/salsa\/v3\/BnpUCBmYdvggScEPs5JbpA.ttf"}},{"kind":"webfonts#webfont","family":"Sofia","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sofia\/v2\/Imnvx0Ag9r6iDBFUY5_RaQ.ttf"}},{"kind":"webfonts#webfont","family":"Poly","variants":["regular","italic"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/poly\/v4\/bcMAuiacS2qkd54BcwW6_Q.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/poly\/v4\/Zkx-eIlZSjKUrPGYhV5PeA.ttf"}},{"kind":"webfonts#webfont","family":"Wendy One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-12-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/wendyone\/v1\/R8CJT2oDXdMk_ZtuHTxoxw.ttf"}},{"kind":"webfonts#webfont","family":"Merienda","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merienda\/v1\/MYY6Og1qZlOQtPW2G95Y3A.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/merienda\/v1\/GlwcvRLlgiVE2MBFQ4r0sKCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Adamina","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/adamina\/v4\/RUQfOodOMiVVYqFZcSlT9w.ttf"}},{"kind":"webfonts#webfont","family":"Spinnaker","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/spinnaker\/v5\/MQdIXivKITpjROUdiN6Jgg.ttf"}},{"kind":"webfonts#webfont","family":"Delius","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/delius\/v3\/TQA163qafki2-gV-B6F_ag.ttf"}},{"kind":"webfonts#webfont","family":"Metamorphous","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/metamorphous\/v3\/wGqUKXRinIYggz-BTRU9ei3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Lemon","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lemon\/v2\/wed1nNu4LNSu-3RoRVUhUw.ttf"}},{"kind":"webfonts#webfont","family":"Fauna One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2013-06-12","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/faunaone\/v1\/8kL-wpAPofcAMELI_5NRnQ.ttf"}},{"kind":"webfonts#webfont","family":"Belleza","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/belleza\/v1\/wchA3BWJlVqvIcSeNZyXew.ttf"}},{"kind":"webfonts#webfont","family":"Buenard","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/buenard\/v3\/NSpMPGKAUgrLrlstYVvIXQ.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/buenard\/v3\/yUlGE115dGr7O9w9FlP3UvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Tauri","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2013-02-27","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tauri\/v1\/XIWeYJDXNqiVNej0zEqtGg.ttf"}},{"kind":"webfonts#webfont","family":"La Belle Aurore","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/labelleaurore\/v3\/Irdbc4ASuUoWDjd_Wc3md123K2iuuhwZgaKapkyRTY8.ttf"}},{"kind":"webfonts#webfont","family":"IM Fell DW Pica","variants":["regular","italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfelldwpica\/v3\/W81bfaWiUicLSPbJhW-ATsA5qm663gJGVdtpamafG5A.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfelldwpica\/v3\/alQJ8SK5aSOZVaelYoyT4PL2asmh5DlYQYCosKo6yQs.ttf"}},{"kind":"webfonts#webfont","family":"Sacramento","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sacramento\/v1\/_kv-qycSHMNdhjiv0Kj7BvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Mouse Memoirs","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mousememoirs\/v1\/NBFaaJFux_j0AQbAsW3QeH8f0n03UdmQgF_CLvNR2vg.ttf"}},{"kind":"webfonts#webfont","family":"Anaheim","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/anaheim\/v1\/t-z8aXHMpgI2gjN_rIflKA.ttf"}},{"kind":"webfonts#webfont","family":"Cedarville Cursive","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cedarvillecursive\/v3\/cuCe6HrkcqrWTWTUE7dw-41zwq9-z_Lf44CzRAA0d0Y.ttf"}},{"kind":"webfonts#webfont","family":"Sue Ellen Francisco","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sueellenfrancisco\/v4\/TwHX4vSxMUnJUdEz1JIgrhzazJzPVbGl8jnf1tisRz4.ttf"}},{"kind":"webfonts#webfont","family":"Podkova","variants":["regular","700"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/podkova\/v5\/eylljyGVfB8ZUQjYY3WZRQ.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/podkova\/v5\/SqW4aa8m_KVrOgYSydQ33vesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Chau Philomene One","variants":["regular","italic"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/chauphilomeneone\/v1\/KKc5egCL-a2fFVoOA2x6tBFi5dxgSTdxqnMJgWkBJcg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/chauphilomeneone\/v1\/eJj1PY_iN4KiIuyOvtMHJP6uyLkxyiC4WcYA74sfquE.ttf"}},{"kind":"webfonts#webfont","family":"UnifrakturMaguntia","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/unifrakturmaguntia\/v4\/7KWy3ymCVR_xfAvvcIXm3-kdNg30GQauG_DE-tMYtWk.ttf"}},{"kind":"webfonts#webfont","family":"Audiowide","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/audiowide\/v1\/yGcwRZB6VmoYhPUYT-mEow.ttf"}},{"kind":"webfonts#webfont","family":"Nova Round","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/novaround\/v5\/7-cK3Ari_8XYYFgVMxVhDvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Lilita One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lilitaone\/v1\/vTxJQjbNV6BCBHx8sGDCVvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Acme","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/acme\/v2\/-J6XNtAHPZBEbsifCdBt-g.ttf"}},{"kind":"webfonts#webfont","family":"Delius Swash Caps","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/deliusswashcaps\/v5\/uXyrEUnoWApxIOICunRq7yIrxb5zDVgU2N3VzXm7zq4.ttf"}},{"kind":"webfonts#webfont","family":"Grand Hotel","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-12-06","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/grandhotel\/v1\/C_A8HiFZjXPpnMt38XnK7qCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Strait","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-31","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/strait\/v1\/m4W73ViNmProETY2ybc-Bg.ttf"}},{"kind":"webfonts#webfont","family":"Annie Use Your Telescope","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/annieuseyourtelescope\/v3\/2cuiO5VmaR09C8SLGEQjGqbp7mtG8sPlcZvOaO8HBak.ttf"}},{"kind":"webfonts#webfont","family":"Snippet","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-08-08","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/snippet\/v3\/eUcYMLq2GtHZovLlQH_9kA.ttf"}},{"kind":"webfonts#webfont","family":"Corben","variants":["regular","700"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/corben\/v5\/tTysMZkt-j8Y5yhkgsoajQ.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/corben\/v5\/lirJaFSQWdGQuV--fksg5g.ttf"}},{"kind":"webfonts#webfont","family":"Forum","variants":["regular"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/forum\/v4\/MZUpsq1VfLrqv8eSDcbrrQ.ttf"}},{"kind":"webfonts#webfont","family":"Federo","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/federo\/v5\/JPhe1S2tujeyaR79gXBLeQ.ttf"}},{"kind":"webfonts#webfont","family":"Geo","variants":["regular","italic"],"subsets":["latin"],"version":"v5","lastModified":"2012-10-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/geo\/v5\/mJuJYk5Pww84B4uHAQ1XaA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/geo\/v5\/8_r1wToF7nPdDuX1qxel6Q.ttf"}},{"kind":"webfonts#webfont","family":"Marcellus SC","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/marcellussc\/v1\/_jugwxhkkynrvsfrxVx8gS3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Basic","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/basic\/v2\/hNII2mS5Dxw5C0u_m3mXgA.ttf"}},{"kind":"webfonts#webfont","family":"Montez","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/montez\/v3\/kx58rLOWQQLGFM4pDHv5Ng.ttf"}},{"kind":"webfonts#webfont","family":"Aclonica","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/aclonica\/v3\/M6pHZMPwK3DiBSlo3jwAKQ.ttf"}},{"kind":"webfonts#webfont","family":"Bowlby One SC","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bowlbyonesc\/v5\/8ZkeXftTuzKBtmxOYXoRedDkZCMxWJecxjvKm2f8MJw.ttf"}},{"kind":"webfonts#webfont","family":"Maiden Orange","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/maidenorange\/v3\/ZhKIA2SPisEwdhW7g0RUWojjx0o0jr6fNXxPgYh_a8Q.ttf"}},{"kind":"webfonts#webfont","family":"Stardos Stencil","variants":["regular","700"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/stardosstencil\/v3\/ygEOyTW9a6u4fi4OXEZeTFf2eT4jUldwg_9fgfY_tHc.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/stardosstencil\/v3\/h4ExtgvoXhPtv9Ieqd-XC81wDCbBgmIo8UyjIhmkeSM.ttf"}},{"kind":"webfonts#webfont","family":"Tulpen One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tulpenone\/v3\/lwcTfVIEVxpZLZlWzR5baPesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Quando","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quando\/v1\/03nDiEZuO2-h3xvtG6UmHg.ttf"}},{"kind":"webfonts#webfont","family":"Andada","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/andada\/v4\/rSFaDqNNQBRw3y19MB5Y4w.ttf"}},{"kind":"webfonts#webfont","family":"Tienne","variants":["regular","700","900"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tienne\/v5\/-IIfDl701C0z7-fy2kmGvA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tienne\/v5\/JvoCDOlyOSEyYGRwCyfs3g.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tienne\/v5\/FBano5T521OWexj2iRYLMw.ttf"}},{"kind":"webfonts#webfont","family":"Yesteryear","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/yesteryear\/v2\/dv09hP_ZrdjVOfZQXKXuZvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Allura","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/allura\/v1\/4hcqgZanyuJ2gMYWffIR6A.ttf"}},{"kind":"webfonts#webfont","family":"Antic","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/antic\/v4\/hEa8XCNM7tXGzD0Uk0AipA.ttf"}},{"kind":"webfonts#webfont","family":"Dawning of a New Day","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dawningofanewday\/v4\/JiDsRhiKZt8uz3NJ5xA06gXLnohmOYWQZqo_sW8GLTk.ttf"}},{"kind":"webfonts#webfont","family":"Playfair Display SC","variants":["regular","italic","700","700italic","900","900italic"],"subsets":["latin-ext","cyrillic","latin"],"version":"v1","lastModified":"2012-10-31","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playfairdisplaysc\/v1\/G0-tvBxd4eQRdwFKB8dRkcpjYTDWIvcAwAccqeW9uNM.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playfairdisplaysc\/v1\/myuYiFR-4NTrUT4w6TKls2klJsJYggW8rlNoTOTuau0.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playfairdisplaysc\/v1\/5ggqGkvWJU_TtW2W8cEubA-Amcyomnuy4WsCiPxGHjw.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playfairdisplaysc\/v1\/6X0OQrQhEEnPo56RalREX4krgPi80XvBcbTwmz-rgmU.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playfairdisplaysc\/v1\/5ggqGkvWJU_TtW2W8cEubKXL3C32k275YmX_AcBPZ7w.ttf","900italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/playfairdisplaysc\/v1\/6X0OQrQhEEnPo56RalREX8Zag2q3ssKz8uH1RU4a9gs.ttf"}},{"kind":"webfonts#webfont","family":"Expletus Sans","variants":["regular","italic","500","500italic","600","600italic","700","700italic"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/expletussans\/v4\/gegTSDBDs5le3g6uxU1ZsX8f0n03UdmQgF_CLvNR2vg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/expletussans\/v4\/Y-erXmY0b6DU_i2Qu0hTJj4G9C9ttb0Oz5Cvf0qOitE.ttf","500":"http:\/\/themes.googleusercontent.com\/static\/fonts\/expletussans\/v4\/cl6rhMY77Ilk8lB_uYRRwAqQmZ7VjhwksfpNVG0pqGc.ttf","500italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/expletussans\/v4\/sRBNtc46w65uJE451UYmW87DCVO6wo6i5LKIyZDzK40.ttf","600":"http:\/\/themes.googleusercontent.com\/static\/fonts\/expletussans\/v4\/cl6rhMY77Ilk8lB_uYRRwCvj1tU7IJMS3CS9kCx2B3U.ttf","600italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/expletussans\/v4\/sRBNtc46w65uJE451UYmW8yKH23ZS6zCKOFHG0e_4JE.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/expletussans\/v4\/cl6rhMY77Ilk8lB_uYRRwFCbmAUID8LN-q3pJpOk3Ys.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/expletussans\/v4\/sRBNtc46w65uJE451UYmW5F66r9C4AnxxlBlGd7xY4g.ttf"}},{"kind":"webfonts#webfont","family":"Lustria","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lustria\/v1\/gXAk0s4ai0X-TAOhYzZd1w.ttf"}},{"kind":"webfonts#webfont","family":"Numans","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/numans\/v3\/g5snI2p6OEjjTNmTHyBdiQ.ttf"}},{"kind":"webfonts#webfont","family":"Redressed","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/redressed\/v3\/3aZ5sTBppH3oSm5SabegtA.ttf"}},{"kind":"webfonts#webfont","family":"Over the Rainbow","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/overtherainbow\/v4\/6gp-gkpI2kie2dHQQLM2jQBdxkZd83xOSx-PAQ2QmiI.ttf"}},{"kind":"webfonts#webfont","family":"Baumans","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/baumans\/v2\/o0bFdPW1H5kd5saqqOcoVg.ttf"}},{"kind":"webfonts#webfont","family":"Kelly Slab","variants":["regular"],"subsets":["latin-ext","cyrillic","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kellyslab\/v3\/F_2oS1e9XdYx1MAi8XEVefesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Norican","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/norican\/v1\/SHnSqhYAWG5sZTWcPzEHig.ttf"}},{"kind":"webfonts#webfont","family":"Iceland","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/iceland\/v2\/kq3uTMGgvzWGNi39B_WxGA.ttf"}},{"kind":"webfonts#webfont","family":"Skranji","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/skranji\/v1\/jnOLPS0iZmDL7dfWnW3nIw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/skranji\/v1\/Lcrhg-fviVkxiEgoadsI1vesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Niconne","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/niconne\/v3\/ZA-mFw2QNXodx5y7kfELBg.ttf"}},{"kind":"webfonts#webfont","family":"Cinzel Decorative","variants":["regular","700","900"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cinzeldecorative\/v1\/fmgK7oaJJIXAkhd9798yQgT5USbJx2F82lQbogPy2bY.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cinzeldecorative\/v1\/pXhIVnhFtL_B9Vb1wq2F95-YYVDmZkJErg0zgx9XuZI.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cinzeldecorative\/v1\/pXhIVnhFtL_B9Vb1wq2F97Khqbv0zQZa0g-9HOXAalU.ttf"}},{"kind":"webfonts#webfont","family":"Vibur","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/vibur\/v4\/xB9aKsUbJo68XP0bAg2iLw.ttf"}},{"kind":"webfonts#webfont","family":"Cherry Swash","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-10-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cherryswash\/v1\/HqOk7C7J1TZ5i3L-ejF0vi3USBnSvpkopQaUR-2r7iU.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cherryswash\/v1\/-CfyMyQqfucZPQNB0nvYyED2ttfZwueP-QU272T9-k4.ttf"}},{"kind":"webfonts#webfont","family":"Delius Unicase","variants":["regular","700"],"subsets":["latin"],"version":"v6","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/deliusunicase\/v6\/b2sKujV3Q48RV2PQ0k1vqu6rPKfVZo7L2bERcf0BDns.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/deliusunicase\/v6\/7FTMTITcb4dxUp99FAdTqNy5weKXdcrx-wE0cgECMq8.ttf"}},{"kind":"webfonts#webfont","family":"Dorsa","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dorsa\/v4\/wCc3cUe6XrmG2LQE6GlIrw.ttf"}},{"kind":"webfonts#webfont","family":"Clicker Script","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/clickerscript\/v1\/Zupmk8XwADjufGxWB9KThBnpV0hQCek3EmWnCPrvGRM.ttf"}},{"kind":"webfonts#webfont","family":"Nova Square","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/novasquare\/v5\/BcBzXoaDzYX78rquGXVuSqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Oranienbaum","variants":["regular"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v1","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oranienbaum\/v1\/M98jYwCSn0PaFhXXgviCoaCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Quintessential","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/quintessential\/v1\/mmk6ioesnTrEky_Zb92E5s02lXbtMOtZWfuxKeMZO8Q.ttf"}},{"kind":"webfonts#webfont","family":"Simonetta","variants":["regular","italic","900","900italic"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/simonetta\/v2\/fN8puNuahBo4EYMQgp12Yg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/simonetta\/v2\/ynxQ3FqfF_Nziwy3T9ZwL6CWcynf_cDxXwCLxiixG1c.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/simonetta\/v2\/22EwvvJ2r1VwVCxit5LcVi3USBnSvpkopQaUR-2r7iU.ttf","900italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/simonetta\/v2\/WUXOpCgBZaRPrWtMCpeKoienaqEuufTBk9XMKnKmgDA.ttf"}},{"kind":"webfonts#webfont","family":"Krona One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kronaone\/v1\/zcQj4ljqTo166AdourlF9w.ttf"}},{"kind":"webfonts#webfont","family":"Denk One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2013-11-21","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/denkone\/v1\/TdXOeA4eA_hEx4W8Sh9wPw.ttf"}},{"kind":"webfonts#webfont","family":"Megrim","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/megrim\/v4\/e-9jVUC9lv1zxaFQARuftw.ttf"}},{"kind":"webfonts#webfont","family":"Junge","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/junge\/v1\/j4IXCXtxrw9qIBheercp3A.ttf"}},{"kind":"webfonts#webfont","family":"IM Fell English SC","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfellenglishsc\/v3\/h3Tn6yWfw4b5qaLD1RWvz5ATixNthKRRR1XVH3rJNiw.ttf"}},{"kind":"webfonts#webfont","family":"PT Mono","variants":["regular"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v1","lastModified":"2013-04-10","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ptmono\/v1\/QUbM8H9yJK5NhpQ0REO6Wg.ttf"}},{"kind":"webfonts#webfont","family":"Prosto One","variants":["regular"],"subsets":["latin-ext","cyrillic","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/prostoone\/v1\/bsqnAElAqk9kX7eABTRFJPesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"IM Fell DW Pica SC","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfelldwpicasc\/v3\/xBKKJV4z2KsrtQnmjGO17JZ9RBdEL0H9o5qzT1Rtof4.ttf"}},{"kind":"webfonts#webfont","family":"Hanuman","variants":["regular","700"],"subsets":["khmer"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/hanuman\/v5\/hRhwOGGmElJSl6KSPvEnOQ.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/hanuman\/v5\/lzzXZ2l84x88giDrbfq76vesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Capriola","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/capriola\/v1\/JxXPlkdzWwF9Cwelbvi9jA.ttf"}},{"kind":"webfonts#webfont","family":"Mr Dafoe","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mrdafoe\/v2\/s32Q1S6ZkT7EaX53mUirvQ.ttf"}},{"kind":"webfonts#webfont","family":"Sigmar One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-08-08","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sigmarone\/v3\/oh_5NxD5JBZksdo2EntKefesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Imprima","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imprima\/v1\/eRjquWLjwLGnTEhLH7u3kA.ttf"}},{"kind":"webfonts#webfont","family":"Nova Mono","variants":["regular"],"subsets":["greek","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/novamono\/v4\/6-SChr5ZIaaasJFBkgrLNw.ttf"}},{"kind":"webfonts#webfont","family":"Buda","variants":["300"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/buda\/v3\/hLtAmNUmEMJH2yx7NGUjnA.ttf"}},{"kind":"webfonts#webfont","family":"Chelsea Market","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/chelseamarket\/v1\/qSdzwh2A4BbNemy78sJLfAAI1i8fIftCBXsBF2v9UMI.ttf"}},{"kind":"webfonts#webfont","family":"GFS Didot","variants":["regular"],"subsets":["greek"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gfsdidot\/v3\/jQKxZy2RU-h9tkPZcRVluA.ttf"}},{"kind":"webfonts#webfont","family":"Codystar","variants":["300","regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/codystar\/v1\/EVaUzfJkcb8Zqx9kzQLXqqCWcynf_cDxXwCLxiixG1c.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/codystar\/v1\/EN-CPFKYowSI7SuR7-0cZA.ttf"}},{"kind":"webfonts#webfont","family":"Londrina Solid","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/londrinasolid\/v1\/yysorIEiYSBb0ylZjg791MR125CwGqh8XBqkBzea0LA.ttf"}},{"kind":"webfonts#webfont","family":"Italianno","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/italianno\/v3\/HsyHnLpKf8uP7aMpDQHZmg.ttf"}},{"kind":"webfonts#webfont","family":"Holtwood One SC","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/holtwoodonesc\/v4\/sToOq3cIxbfnhbEkgYNuBbAgSRh1LpJXlLfl8IbsmHg.ttf"}},{"kind":"webfonts#webfont","family":"Swanky and Moo Moo","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/swankyandmoomoo\/v3\/orVNZ9kDeE3lWp3U3YELu9DVLKqNC3_XMNHhr8S94FU.ttf"}},{"kind":"webfonts#webfont","family":"Medula One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/medulaone\/v3\/AasPgDQak81dsTGQHc5zUPesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Galdeano","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/galdeano\/v3\/ZKFMQI6HxEG1jOT0UGSZUg.ttf"}},{"kind":"webfonts#webfont","family":"Vast Shadow","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/vastshadow\/v3\/io4hqKX3ibiqQQjYfW0-h6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Meddon","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/meddon\/v4\/f8zJO98uu2EtSj9p7ci9RA.ttf"}},{"kind":"webfonts#webfont","family":"MedievalSharp","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/medievalsharp\/v5\/85X_PjV6tftJ0-rX7KYQkOe45sJkivqprK7VkUlzfg0.ttf"}},{"kind":"webfonts#webfont","family":"Unica One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-10-31","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/unicaone\/v1\/KbYKlhWMDpatWViqDkNQgA.ttf"}},{"kind":"webfonts#webfont","family":"IM Fell Great Primer SC","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfellgreatprimersc\/v3\/A313vRj97hMMGFjt6rgSJtRg-ciw1Y27JeXb2Zv4lZQ.ttf"}},{"kind":"webfonts#webfont","family":"Belgrano","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/belgrano\/v3\/iq8DUa2s7g6WRCeMiFrmtQ.ttf"}},{"kind":"webfonts#webfont","family":"IM Fell French Canon","variants":["regular","italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfellfrenchcanon\/v3\/iKB0WL1BagSpNPz3NLMdsJ3V2FNpBrlLSvqUnERhBP8.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfellfrenchcanon\/v3\/owCuNQkLLFW7TBBPJbMnhRa-QL94KdW80H29tcyld2A.ttf"}},{"kind":"webfonts#webfont","family":"Voces","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/voces\/v1\/QoBH6g6yKgNIgvL8A2aE2Q.ttf"}},{"kind":"webfonts#webfont","family":"Finger Paint","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fingerpaint\/v1\/m_ZRbiY-aPb13R3DWPBGXy3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Sonsie One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sonsieone\/v2\/KSP7xT1OSy0q2ob6RQOTWPesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Unna","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/unna\/v5\/UAS0AM7AmbdCNY_80xyAZQ.ttf"}},{"kind":"webfonts#webfont","family":"IM Fell Double Pica","variants":["regular","italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfelldoublepica\/v3\/yN1wY_01BkQnO0LYAhXdUol14jEdVOhEmvtCMCVwYak.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfelldoublepica\/v3\/64odUh2hAw8D9dkFKTlWYq0AWwkgdQfsRHec8TYi4mI.ttf"}},{"kind":"webfonts#webfont","family":"Life Savers","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-12-17","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lifesavers\/v3\/g49cUDk4Y1P0G5NMkMAm7qCWcynf_cDxXwCLxiixG1c.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lifesavers\/v3\/THQKqChyYUm97rNPVFdGGXe1Pd76Vl7zRpE7NLJQ7XU.ttf"}},{"kind":"webfonts#webfont","family":"Mate SC","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/matesc\/v2\/-YkIT2TZoPZF6pawKzDpWw.ttf"}},{"kind":"webfonts#webfont","family":"Wellfleet","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/wellfleet\/v1\/J5tOx72iFRPgHYpbK9J4XQ.ttf"}},{"kind":"webfonts#webfont","family":"Share Tech","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sharetech\/v1\/Dq3DuZ5_0SW3oEfAWFpen_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Knewave","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/knewave\/v2\/KGHM4XWr4iKnBMqzZLkPBg.ttf"}},{"kind":"webfonts#webfont","family":"Press Start 2P","variants":["regular"],"subsets":["latin-ext","cyrillic","greek","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/pressstart2p\/v1\/8Lg6LX8-ntOHUQnvQ0E7o1jfl3W46Sz5gOkEVhcFWF4.ttf"}},{"kind":"webfonts#webfont","family":"Fjord One","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fjordone\/v2\/R_YHK8au2uFPw5tNu5N7zw.ttf"}},{"kind":"webfonts#webfont","family":"Donegal One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-12-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/donegalone\/v1\/6kN4-fDxz7T9s5U61HwfF6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Euphoria Script","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/euphoriascript\/v1\/c4XB4Iijj_NvSsCF4I0O2MxLhO8OSNnfAp53LK1_iRs.ttf"}},{"kind":"webfonts#webfont","family":"Marcellus","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/marcellus\/v1\/UjiLZzumxWC9whJ86UtaYw.ttf"}},{"kind":"webfonts#webfont","family":"Candal","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/candal\/v3\/x44dDW28zK7GR1gGDBmj9g.ttf"}},{"kind":"webfonts#webfont","family":"VT323","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/vt323\/v4\/ITU2YQfM073o1iYK3nSOmQ.ttf"}},{"kind":"webfonts#webfont","family":"Fanwood Text","variants":["regular","italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fanwoodtext\/v3\/hDNDHUlsSb8bgnEmDp4T_i3USBnSvpkopQaUR-2r7iU.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fanwoodtext\/v3\/0J3SBbkMZqBV-3iGxs5E9_MZXuCXbOrAvx5R0IT5Oyo.ttf"}},{"kind":"webfonts#webfont","family":"Amethysta","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/amethysta\/v1\/1jEo9tOFIJDolAUpBnWbnA.ttf"}},{"kind":"webfonts#webfont","family":"Bowlby One","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bowlbyone\/v4\/eKpHjHfjoxM2bX36YNucefesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Monoton","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/monoton\/v3\/aCz8ja_bE4dg-7agSvExdw.ttf"}},{"kind":"webfonts#webfont","family":"Average","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/average\/v1\/aHUibBqdDbVYl5FM48pxyQ.ttf"}},{"kind":"webfonts#webfont","family":"Gilda Display","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gildadisplay\/v1\/8yAVUZLLZ3wb7dSsjix0CADHmap7fRWINAsw8-RaxNg.ttf"}},{"kind":"webfonts#webfont","family":"Oldenburg","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oldenburg\/v1\/dqA_M_uoCVXZbCO-oKBTnQ.ttf"}},{"kind":"webfonts#webfont","family":"Graduate","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/graduate\/v1\/JpAmYLHqcIh9_Ff35HHwiA.ttf"}},{"kind":"webfonts#webfont","family":"Patrick Hand SC","variants":["regular"],"subsets":["latin-ext","vietnamese","latin"],"version":"v1","lastModified":"2013-02-27","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/patrickhandsc\/v1\/OYFWCgfCR-7uHIovjUZXsbAgSRh1LpJXlLfl8IbsmHg.ttf"}},{"kind":"webfonts#webfont","family":"League Script","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/leaguescript\/v4\/wnRFLvfabWK_DauqppD6vSeUSrabuTpOsMEiRLtKwk0.ttf"}},{"kind":"webfonts#webfont","family":"Alef","variants":["regular","700"],"subsets":["latin"],"version":"v1","lastModified":"2013-05-22","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alef\/v1\/ENvZ_P0HBDQxNZYCQO0lUA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alef\/v1\/VDgZJhEwudtOzOFQpZ8MEA.ttf"}},{"kind":"webfonts#webfont","family":"Miltonian Tattoo","variants":["regular"],"subsets":["latin"],"version":"v6","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/miltoniantattoo\/v6\/1oU_8OGYwW46eh02YHydn2uk0YtI6thZkz1Hmh-odwg.ttf"}},{"kind":"webfonts#webfont","family":"Geostar Fill","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/geostarfill\/v3\/Y5ovXPPOHYTfQzK2aM-hui3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Oxygen Mono","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oxygenmono\/v1\/DigTu7k4b7OmM8ubt1Qza6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Ruslan Display","variants":["regular"],"subsets":["cyrillic-ext","latin-ext","cyrillic","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ruslandisplay\/v4\/SREdhlyLNUfU1VssRBfs3rgH88D3l9N4auRNHrNS708.ttf"}},{"kind":"webfonts#webfont","family":"Rammetto One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rammettoone\/v2\/mh0uQ1tV8QgSx9v_KyEYPC3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"IM Fell French Canon SC","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfellfrenchcanonsc\/v3\/kA3bS19-tQbeT_iG32EZmaiyyzHwYrAbmNulTz423iM.ttf"}},{"kind":"webfonts#webfont","family":"IM Fell Great Primer","variants":["regular","italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfellgreatprimer\/v3\/AL8ALGNthei20f9Cu3e93rgeX3ROgtTz44CitKAxzKI.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfellgreatprimer\/v3\/1a-artkXMVg682r7TTxVY1_YG2SFv8Ma7CxRl1S3o7g.ttf"}},{"kind":"webfonts#webfont","family":"Artifika","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/artifika\/v3\/Ekfp4H4QG7D-WsABDOyj8g.ttf"}},{"kind":"webfonts#webfont","family":"Qwigley","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/qwigley\/v3\/aDqxws-KubFID85TZHFouw.ttf"}},{"kind":"webfonts#webfont","family":"Zeyada","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/zeyada\/v3\/hmonmGYYFwqTZQfG2nRswQ.ttf"}},{"kind":"webfonts#webfont","family":"Wallpoet","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/wallpoet\/v4\/hmum4WuBN4A0Z_7367NDIg.ttf"}},{"kind":"webfonts#webfont","family":"Linden Hill","variants":["regular","italic"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lindenhill\/v3\/UgsC0txqd-E1yjvjutwm_KCWcynf_cDxXwCLxiixG1c.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lindenhill\/v3\/OcS3bZcu8vJvIDH8Zic83keOrDcLawS7-ssYqLr2Xp4.ttf"}},{"kind":"webfonts#webfont","family":"Smokum","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/smokum\/v3\/8YP4BuAcy97X8WfdKfxVRw.ttf"}},{"kind":"webfonts#webfont","family":"Mate","variants":["regular","italic"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mate\/v2\/ooFviPcJ6hZP5bAE71Cawg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mate\/v2\/5XwW6_cbisGvCX5qmNiqfA.ttf"}},{"kind":"webfonts#webfont","family":"Petrona","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/petrona\/v2\/nnQwxlP6dhrGovYEFtemTg.ttf"}},{"kind":"webfonts#webfont","family":"Creepster","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/creepster\/v2\/0vdr5kWJ6aJlOg5JvxnXzQ.ttf"}},{"kind":"webfonts#webfont","family":"Della Respira","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dellarespira\/v1\/F4E6Lo_IZ6L9AJCcbqtDVeDcg5akpSnIcsPhLOFv7l8.ttf"}},{"kind":"webfonts#webfont","family":"Trochut","variants":["regular","italic","700"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/trochut\/v1\/6Y65B0x-2JsnYt16OH5omw.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/trochut\/v1\/pczUwr4ZFvC79TgNO5cZng.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/trochut\/v1\/lWqNOv6ISR8ehNzGLFLnJ_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"UnifrakturCook","variants":["700"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/unifrakturcook\/v5\/ASwh69ykD8iaoYijVEU6RrWZkcsCTHKV51zmcUsafQ0.ttf"}},{"kind":"webfonts#webfont","family":"Yeseva One","variants":["regular"],"subsets":["latin-ext","cyrillic","latin"],"version":"v6","lastModified":"2012-09-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/yesevaone\/v6\/eenQQxvpzSA80JmisGcgX_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Julee","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/julee\/v3\/CAib-jsUsSO8SvVRnE9fHA.ttf"}},{"kind":"webfonts#webfont","family":"Poller One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/pollerone\/v3\/dkctmDlTPcZ6boC8662RA_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Montaga","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/montaga\/v1\/PwTwUboiD-M4-mFjZfJs2A.ttf"}},{"kind":"webfonts#webfont","family":"Duru Sans","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/durusans\/v3\/R1xHvAOARPh8_so9_UKw1w.ttf"}},{"kind":"webfonts#webfont","family":"GFS Neohellenic","variants":["regular","italic","700","700italic"],"subsets":["greek"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gfsneohellenic\/v4\/B4xRqbn-tANVqVgamMsSDiayCZa0z7CpFzlkqoCHztc.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gfsneohellenic\/v4\/KnaWrO4awITAqigQIIYXKkCTdomiyJpIzPbEbIES3rU.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gfsneohellenic\/v4\/7HwjPQa7qNiOsnUce2h4448_BwCLZY3eDSV6kppAwI8.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gfsneohellenic\/v4\/FwWjoX6XqT-szJFyqsu_GYFF0fM4h-krcpQk7emtCpE.ttf"}},{"kind":"webfonts#webfont","family":"Bubblegum Sans","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bubblegumsans\/v2\/Y9iTUUNz6lbl6TrvV4iwsytnKWgpfO2iSkLzTz-AABg.ttf"}},{"kind":"webfonts#webfont","family":"Rufina","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rufina\/v1\/s9IFr_fIemiohfZS-ZRDbQ.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rufina\/v1\/D0RUjXFr55y4MVZY2Ww_RA.ttf"}},{"kind":"webfonts#webfont","family":"Sniglet","variants":["regular","800"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2013-09-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sniglet\/v4\/XWhyQLHH4SpCVsHRPRgu9w.ttf","800":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sniglet\/v4\/NLF91nBmcEfkBgcEWbHFa_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Astloch","variants":["regular","700"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/astloch\/v3\/fmbitVmHYLQP7MGPuFgpag.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/astloch\/v3\/aPkhM2tL-tz1jX6aX2rvo_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Montserrat Subrayada","variants":["regular","700"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/montserratsubrayada\/v1\/nzoCWCz0e9c7Mr2Gl8bbgrJymm6ilkk9f0nDA_sC_qk.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/montserratsubrayada\/v1\/wf-IKpsHcfm0C9uaz9IeGJvEcF1LWArDbGWgKZSH9go.ttf"}},{"kind":"webfonts#webfont","family":"Irish Grover","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/irishgrover\/v3\/kUp7uUPooL-KsLGzeVJbBC3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Mr De Haviland","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mrdehaviland\/v2\/fD8y4L6PJ4vqDk7z8Y8e27v4lrhng1lzu7-weKO6cw8.ttf"}},{"kind":"webfonts#webfont","family":"Rouge Script","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rougescript\/v2\/AgXDSqZJmy12qS0ixjs6Vy3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Dynalight","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dynalight\/v2\/-CWsIe8OUDWTIHjSAh41kA.ttf"}},{"kind":"webfonts#webfont","family":"Pirata One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/pirataone\/v1\/WnbD86B4vB2ckYcL7oxuhvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Shojumaru","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/shojumaru\/v1\/WP8cxonzQQVAoI3RJQ2wug.ttf"}},{"kind":"webfonts#webfont","family":"IM Fell Double Pica SC","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/imfelldoublepicasc\/v3\/jkrUtrLFpMw4ZazhfkKsGwc4LoC4OJUqLw9omnT3VOU.ttf"}},{"kind":"webfonts#webfont","family":"Carrois Gothic SC","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/carroisgothicsc\/v1\/bVp4nhwFIXU-r3LqUR8DSJTdPW1ioadGi2uRiKgJVCY.ttf"}},{"kind":"webfonts#webfont","family":"Gravitas One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gravitasone\/v3\/nBHdBv6zVNU8MtP6w9FwTS3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Nova Slim","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/novaslim\/v5\/rPYXC81_VL2EW-4CzBX65g.ttf"}},{"kind":"webfonts#webfont","family":"Prociono","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/prociono\/v3\/43ZYDHWogdFeNBWTl6ksmw.ttf"}},{"kind":"webfonts#webfont","family":"Overlock SC","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/overlocksc\/v2\/8D7HYDsvS_g1GhBnlHzgzaCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Bigshot One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bigshotone\/v3\/wSyZjBNTWDQHnvWE2jt6j6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Nova Script","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/novascript\/v5\/dEvxQDLgx1M1TKY-NmBWYaCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Amarante","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/amarante\/v1\/2dQHjIBWSpydit5zkJZnOw.ttf"}},{"kind":"webfonts#webfont","family":"Kenia","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-08-01","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kenia\/v5\/OLM9-XfITK9PsTLKbGBrwg.ttf"}},{"kind":"webfonts#webfont","family":"Lily Script One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2013-06-12","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lilyscriptone\/v1\/uPWsLVW8uiXqIBnE8ZwGPDjVlsJB_M_Q_LtZxsoxvlw.ttf"}},{"kind":"webfonts#webfont","family":"Monofett","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/monofett\/v3\/C6K5L799Rgxzg2brgOaqAw.ttf"}},{"kind":"webfonts#webfont","family":"Cutive Mono","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-10-31","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cutivemono\/v1\/ncWQtFVKcSs8OW798v30k6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Sail","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sail\/v3\/iuEoG6kt-bePGvtdpL0GUQ.ttf"}},{"kind":"webfonts#webfont","family":"Alike Angular","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/alikeangular\/v3\/OpeCu4xxI3qO1C7CZcJtPT3XH2uEnVI__ynTBvNyki8.ttf"}},{"kind":"webfonts#webfont","family":"Nova Flat","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/novaflat\/v5\/pK7a0CoGzI684qe_XSHBqQ.ttf"}},{"kind":"webfonts#webfont","family":"Bilbo","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bilbo\/v3\/-ty-lPs5H7OIucWbnpFrkA.ttf"}},{"kind":"webfonts#webfont","family":"Smythe","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/smythe\/v4\/yACD1gy_MpbB9Ft42fUvYw.ttf"}},{"kind":"webfonts#webfont","family":"Arizonia","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arizonia\/v3\/yzJqkHZqryZBTM7RKYV9Wg.ttf"}},{"kind":"webfonts#webfont","family":"Trade Winds","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/tradewinds\/v2\/sDOCVgAxw6PEUi2xdMsoDaCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Stint Ultra Condensed","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/stintultracondensed\/v2\/8DqLK6-YSClFZt3u3EgOUYelbRYnLTTQA1Z5cVLnsI4.ttf"}},{"kind":"webfonts#webfont","family":"Ranchers","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ranchers\/v1\/9ya8CZYhqT66VERfjQ7eLA.ttf"}},{"kind":"webfonts#webfont","family":"Lovers Quarrel","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/loversquarrel\/v1\/gipdZ8b7pKb89MzQLAtJHLHLxci2ElvNEmOB303HLk0.ttf"}},{"kind":"webfonts#webfont","family":"Jacques Francois Shadow","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/jacquesfrancoisshadow\/v1\/V14y0H3vq56fY9SV4OL_FASt0D_oLVawA8L8b9iKjbs.ttf"}},{"kind":"webfonts#webfont","family":"Balthazar","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/balthazar\/v2\/WgbaSIs6dJAGXJ0qbz2xlw.ttf"}},{"kind":"webfonts#webfont","family":"Modern Antiqua","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/modernantiqua\/v3\/8qX_tr6Xzy4t9fvZDXPkh6rFJ4O13IHVxZbM6yoslpo.ttf"}},{"kind":"webfonts#webfont","family":"Flamenco","variants":["300","regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/flamenco\/v3\/x9iI5CogvuZVCGoRHwXuo6CWcynf_cDxXwCLxiixG1c.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/flamenco\/v3\/HC0ugfLLgt26I5_BWD1PZA.ttf"}},{"kind":"webfonts#webfont","family":"Molle","variants":["italic"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-26","files":{"italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/molle\/v1\/9XTdCsjPXifLqo5et-YoGA.ttf"}},{"kind":"webfonts#webfont","family":"Bilbo Swash Caps","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bilboswashcaps\/v4\/UB_-crLvhx-PwGKW1oosDmYeFSdnSpRYv5h9gpdlD1g.ttf"}},{"kind":"webfonts#webfont","family":"Gabriela","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2013-03-07","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gabriela\/v1\/B-2ZfbAO3HDrxqV6lR5tdA.ttf"}},{"kind":"webfonts#webfont","family":"Engagement","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/engagement\/v2\/4Uz0Jii7oVPcaFRYmbpU6vesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Text Me One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/textmeone\/v1\/9em_3ckd_P5PQkP4aDyDLqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Port Lligat Sans","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/portlligatsans\/v2\/CUEdhRk7oC7up0p6t0g4P6mASEpx5X0ZpsuJOuvfOGA.ttf"}},{"kind":"webfonts#webfont","family":"Milonga","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-12-06","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/milonga\/v1\/dzNdIUSTGFmy2ahovDRcWg.ttf"}},{"kind":"webfonts#webfont","family":"Nosifer","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/nosifer\/v2\/7eJGoIuHRrtcG00j6CptSA.ttf"}},{"kind":"webfonts#webfont","family":"Goblin One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/goblinone\/v3\/331XtzoXgpVEvNTVcBJ_C_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Nova Oval","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/novaoval\/v5\/VuukVpKP8BwUf8o9W5LYQQ.ttf"}},{"kind":"webfonts#webfont","family":"Condiment","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/condiment\/v1\/CstmdiPpgFSV0FUNL5LrJA.ttf"}},{"kind":"webfonts#webfont","family":"Snowburst One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-12-17","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/snowburstone\/v1\/zSQzKOPukXRux2oTqfYJjIjjx0o0jr6fNXxPgYh_a8Q.ttf"}},{"kind":"webfonts#webfont","family":"Asset","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/asset\/v3\/hfPmqY-JzuR1lULlQf9iTg.ttf"}},{"kind":"webfonts#webfont","family":"Cagliostro","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cagliostro\/v2\/i85oXbtdSatNEzss99bpj_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Kite One","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-31","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/kiteone\/v1\/8ojWmgUc97m0f_i6sTqLoQ.ttf"}},{"kind":"webfonts#webfont","family":"Raleway Dots","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ralewaydots\/v1\/lhLgmWCRcyz-QXo8LCzTfC3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Rosarivo","variants":["regular","italic"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rosarivo\/v1\/EmPiINK0qyqc7KSsNjJamA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rosarivo\/v1\/u3VuWsWQlX1pDqsbz4paNPesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Oregano","variants":["regular","italic"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-08-16","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oregano\/v1\/UiLhqNixVv2EpjRoBG6axA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/oregano\/v1\/_iwqGEht6XsAuEaCbYG64Q.ttf"}},{"kind":"webfonts#webfont","family":"Ledger","variants":["regular"],"subsets":["latin-ext","cyrillic","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ledger\/v1\/G432jp-tahOfWHbCYkI0jw.ttf"}},{"kind":"webfonts#webfont","family":"Geostar","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/geostar\/v3\/A8WQbhQbpYx3GWWaShJ9GA.ttf"}},{"kind":"webfonts#webfont","family":"Lancelot","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/lancelot\/v2\/XMT7T_oo_MQUGAnU2v-sdA.ttf"}},{"kind":"webfonts#webfont","family":"Iceberg","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/iceberg\/v1\/p2XVm4M-N0AOEEOymFKC5w.ttf"}},{"kind":"webfonts#webfont","family":"Ruluko","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ruluko\/v1\/lv4cMwJtrx_dzmlK5SDc1g.ttf"}},{"kind":"webfonts#webfont","family":"Rye","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rye\/v1\/VUrJlpPpSZxspl3w_yNOrQ.ttf"}},{"kind":"webfonts#webfont","family":"Gorditas","variants":["regular","700"],"subsets":["latin"],"version":"v1","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gorditas\/v1\/uMgZhXUyH6qNGF3QsjQT5Q.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gorditas\/v1\/6-XCeknmxaon8AUqVkMnHaCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Fresca","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fresca\/v2\/2q7Qm9sCo1tWvVgSDVWNIw.ttf"}},{"kind":"webfonts#webfont","family":"Passero One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/passeroone\/v5\/Yc-7nH5deCCv9Ed0MMnAQqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Nova Cut","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/novacut\/v5\/6q12jWcBvj0KO2cMRP97tA.ttf"}},{"kind":"webfonts#webfont","family":"Esteban","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/esteban\/v1\/ESyhLgqDDyK5JcFPp2svDw.ttf"}},{"kind":"webfonts#webfont","family":"Elsie Swash Caps","variants":["regular","900"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-12-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/elsieswashcaps\/v1\/9L3hIJMPCf6sxCltnxd6X2YeFSdnSpRYv5h9gpdlD1g.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/elsieswashcaps\/v1\/iZnus9qif0tR5pGaDv5zdKoKBWBozTtxi30NfZDOXXU.ttf"}},{"kind":"webfonts#webfont","family":"Atomic Age","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/atomicage\/v3\/WvBMe4FxANIKpo6Oi0mVJ_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Federant","variants":["regular"],"subsets":["latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/federant\/v4\/tddZFSiGvxICNOGra0i5aA.ttf"}},{"kind":"webfonts#webfont","family":"Miltonian","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/miltonian\/v5\/Z4HrYZyqm0BnNNzcCUfzoQ.ttf"}},{"kind":"webfonts#webfont","family":"Aubrey","variants":["regular"],"subsets":["latin"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/aubrey\/v5\/zo9w8klO8bmOQIMajQ2aTA.ttf"}},{"kind":"webfonts#webfont","family":"Chela One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-10-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/chelaone\/v1\/h5O0dEnpnIq6jQnWxZybrA.ttf"}},{"kind":"webfonts#webfont","family":"Aladin","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/aladin\/v2\/PyuJ5cVHkduO0j5fAMKvAA.ttf"}},{"kind":"webfonts#webfont","family":"Henny Penny","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/hennypenny\/v1\/XRgo3ogXyi3tpsFfjImRF6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Miniver","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/miniver\/v2\/4yTQohOH_cWKRS5laRFhYg.ttf"}},{"kind":"webfonts#webfont","family":"Seaweed Script","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/seaweedscript\/v1\/eorWAPpOvvWrPw5IHwE60BnpV0hQCek3EmWnCPrvGRM.ttf"}},{"kind":"webfonts#webfont","family":"Cambo","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cambo\/v2\/PnwpRuTdkYCf8qk4ajmNRA.ttf"}},{"kind":"webfonts#webfont","family":"Averia Libre","variants":["300","300italic","regular","italic","700","700italic"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averialibre\/v1\/r6hGL8sSLm4dTzOPXgx5XacQoVhARpoaILP7amxE_8g.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averialibre\/v1\/I6wAYuAvOgT7el2ePj2nkina0FLWfcB-J_SAYmcAXaI.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averialibre\/v1\/rYVgHZZQICWnhjguGsBspC3USBnSvpkopQaUR-2r7iU.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averialibre\/v1\/1etzuoNxVHR8F533EkD1WfMZXuCXbOrAvx5R0IT5Oyo.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averialibre\/v1\/r6hGL8sSLm4dTzOPXgx5XUD2ttfZwueP-QU272T9-k4.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averialibre\/v1\/I6wAYuAvOgT7el2ePj2nkvAs9-1nE9qOqhChW0m4nDE.ttf"}},{"kind":"webfonts#webfont","family":"Supermercado One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/supermercadoone\/v3\/kMGPVTNFiFEp1U274uBMb4mm5hmSKNFf3C5YoMa-lrM.ttf"}},{"kind":"webfonts#webfont","family":"Concert One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/concertone\/v4\/N5IWCIGhUNdPZn_efTxKN6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Monsieur La Doulaise","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/monsieurladoulaise\/v2\/IMAdMj6Eq9jZ46CPctFtMKP61oAqTJXlx5ZVOBmcPdM.ttf"}},{"kind":"webfonts#webfont","family":"Stoke","variants":["300","regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-08-08","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/stoke\/v3\/Sell9475FOS8jUqQsfFsUQ.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/stoke\/v3\/A7qJNoqOm2d6o1E6e0yUFg.ttf"}},{"kind":"webfonts#webfont","family":"Paprika","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-31","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/paprika\/v1\/b-VpyoRSieBdB5BPJVF8HQ.ttf"}},{"kind":"webfonts#webfont","family":"Ruthie","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ruthie\/v3\/vJ2LorukHSbWYoEs5juivg.ttf"}},{"kind":"webfonts#webfont","family":"Averia Sans Libre","variants":["300","300italic","regular","italic","700","700italic"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiasanslibre\/v1\/_9-jTfQjaBsWAF_yp5z-V4CP_KG_g80s1KXiBtJHoNc.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiasanslibre\/v1\/o7BEIK-fG3Ykc5Rzteh88YuyGu4JqttndUh4gRKxic0.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiasanslibre\/v1\/yRJpjT39KxACO9F31mj_LqV8_KRn4epKAjTFK1s1fsg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiasanslibre\/v1\/COEzR_NPBSUOl3pFwPbPoCZU2HnUZT1xVKaIrHDioao.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiasanslibre\/v1\/_9-jTfQjaBsWAF_yp5z-V8QwVOrz1y5GihpZmtKLhlI.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiasanslibre\/v1\/o7BEIK-fG3Ykc5Rzteh88bXy1DXgmJcVtKjM5UWamMs.ttf"}},{"kind":"webfonts#webfont","family":"Averia Serif Libre","variants":["300","300italic","regular","italic","700","700italic"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"300":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiaseriflibre\/v2\/yvITAdr5D1nlsdFswJAb8SmC4gFJ2PHmfdVKEd_5S9M.ttf","300italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiaseriflibre\/v2\/YOLFXyye4sZt6AZk1QybCG2okl0bU63CauowU4iApig.ttf","regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiaseriflibre\/v2\/fdtF30xa_Erw0zAzOoG4BZqY66i8AUyI16fGqw0iAew.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiaseriflibre\/v2\/o9qhvK9iT5iDWfyhQUe-6Ru_b0bTq5iipbJ9hhgHJ6U.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiaseriflibre\/v2\/yvITAdr5D1nlsdFswJAb8Q50KV5TaOVolur4zV2iZsg.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiaseriflibre\/v2\/YOLFXyye4sZt6AZk1QybCNxohRXP4tNDqG3X4Hqn21k.ttf"}},{"kind":"webfonts#webfont","family":"Inika","variants":["regular","700"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/inika\/v1\/eZCrULQGaIxkrRoGz_DjhQ.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/inika\/v1\/bl3ZoTyrWsFun2zYbsgJrA.ttf"}},{"kind":"webfonts#webfont","family":"Griffy","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/griffy\/v1\/vWkyYGBSyE5xjnShNtJtzw.ttf"}},{"kind":"webfonts#webfont","family":"Croissant One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/croissantone\/v1\/mPjsOObnC77fp1cvZlOfIYjjx0o0jr6fNXxPgYh_a8Q.ttf"}},{"kind":"webfonts#webfont","family":"Titan One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/titanone\/v1\/FbvpRvzfV_oipS0De3iAZg.ttf"}},{"kind":"webfonts#webfont","family":"McLaren","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-08-16","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mclaren\/v1\/OprvTGxaiINBKW_1_U0eoQ.ttf"}},{"kind":"webfonts#webfont","family":"Italiana","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/italiana\/v1\/dt95fkCSTOF-c6QNjwSycA.ttf"}},{"kind":"webfonts#webfont","family":"Aguafina Script","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/aguafinascript\/v2\/65g7cgMtMGnNlNyq_Z6CvMxLhO8OSNnfAp53LK1_iRs.ttf"}},{"kind":"webfonts#webfont","family":"Mrs Sheppards","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mrssheppards\/v2\/2WFsWMV3VUeCz6UVH7UjCn8f0n03UdmQgF_CLvNR2vg.ttf"}},{"kind":"webfonts#webfont","family":"Habibi","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/habibi\/v2\/YYyqXF6pWpL7kmKgS_2iUA.ttf"}},{"kind":"webfonts#webfont","family":"Jacques Francois","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/jacquesfrancois\/v1\/_-0XWPQIW6tOzTHg4KaJ_M13D_4KM32Q4UmTSjpuNGQ.ttf"}},{"kind":"webfonts#webfont","family":"Spicy Rice","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/spicyrice\/v2\/WGCtz7cLoggXARPi9OGD6_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Bigelow Rules","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bigelowrules\/v1\/FEJCPLwo07FS-6SK6Al50X8f0n03UdmQgF_CLvNR2vg.ttf"}},{"kind":"webfonts#webfont","family":"Share Tech Mono","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sharetechmono\/v1\/RQxK-3RA0Lnf3gnnnNrAscwD6PD0c3_abh9zHKQtbGU.ttf"}},{"kind":"webfonts#webfont","family":"Khmer","variants":["regular"],"subsets":["khmer"],"version":"v6","lastModified":"2013-06-12","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/khmer\/v6\/vWaBJIbaQuBNz02ALIKJ3A.ttf"}},{"kind":"webfonts#webfont","family":"Caesar Dressing","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/caesardressing\/v2\/2T_WzBgE2Xz3FsyJMq34T9gR43u4FvCuJwIfF5Zxl6Y.ttf"}},{"kind":"webfonts#webfont","family":"Mystery Quest","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mysteryquest\/v1\/467jJvg0c7HgucvBB9PLDyeUSrabuTpOsMEiRLtKwk0.ttf"}},{"kind":"webfonts#webfont","family":"Gafata","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2013-03-07","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/gafata\/v2\/aTFqlki_3Dc3geo-FxHTvQ.ttf"}},{"kind":"webfonts#webfont","family":"Keania One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/keaniaone\/v1\/PACrDKZWngXzgo-ucl6buvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Trykker","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/trykker\/v2\/YiVrVJpBFN7I1l_CWk6yYQ.ttf"}},{"kind":"webfonts#webfont","family":"Risque","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/risque\/v1\/92RnElGnl8yHP97-KV3Fyg.ttf"}},{"kind":"webfonts#webfont","family":"Chango","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/chango\/v2\/3W3AeMMtRTH08t5qLOjBmg.ttf"}},{"kind":"webfonts#webfont","family":"Rum Raisin","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rumraisin\/v1\/kDiL-ntDOEq26B7kYM7cx_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Battambang","variants":["regular","700"],"subsets":["khmer"],"version":"v6","lastModified":"2013-06-12","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/battambang\/v6\/MzrUfQLefYum5vVGM3EZVPesZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/battambang\/v6\/dezbRtMzfzAA99DmrCYRMgJKKGfqHaYFsRG-T3ceEVo.ttf"}},{"kind":"webfonts#webfont","family":"Devonshire","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/devonshire\/v2\/I3ct_2t12SYizP8ZC-KFi_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Fondamento","variants":["regular","italic"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fondamento\/v2\/6LWXcjT1B7bnWluAOSNfMPesZW2xOQ-xsNqO47m55DA.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fondamento\/v2\/y6TmwhSbZ8rYq7OTFyo7OS3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Suwannaphum","variants":["regular"],"subsets":["khmer"],"version":"v6","lastModified":"2013-06-12","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/suwannaphum\/v6\/1jIPOyXied3T79GCnSlCN6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Joti One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/jotione\/v1\/P3r_Th0ESHJdzunsvWgUfQ.ttf"}},{"kind":"webfonts#webfont","family":"Sarina","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sarina\/v2\/XYtRfaSknHIU3NHdfTdXoQ.ttf"}},{"kind":"webfonts#webfont","family":"Autour One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/autourone\/v1\/2xmQBcg7FN72jaQRFZPIDvesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Londrina Shadow","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/londrinashadow\/v1\/dNYuzPS_7eYgXFJBzMoKdbw6Z3rVA5KDSi7aQxS92Nk.ttf"}},{"kind":"webfonts#webfont","family":"Glass Antiqua","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/glassantiqua\/v1\/0yLrXKplgdUDIMz5TnCHNODcg5akpSnIcsPhLOFv7l8.ttf"}},{"kind":"webfonts#webfont","family":"Antic Didone","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/anticdidone\/v1\/r3nJcTDuOluOL6LGDV1vRy3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Stint Ultra Expanded","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/stintultraexpanded\/v1\/FeigX-wDDgHMCKuhekhedQ7dxr0N5HY0cZKknTIL6n4.ttf"}},{"kind":"webfonts#webfont","family":"Princess Sofia","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/princesssofia\/v1\/8g5l8r9BM0t1QsXLTajDe-wjmA7ie-lFcByzHGRhCIg.ttf"}},{"kind":"webfonts#webfont","family":"Emilys Candy","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/emilyscandy\/v1\/PofLVm6v1SwZGOzC8s-I3S3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Asul","variants":["regular","700"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/asul\/v2\/9qpsNR_OOwyOYyo2N0IbBw.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/asul\/v2\/uO8uNmxaq87-DdPmkEg5Gg.ttf"}},{"kind":"webfonts#webfont","family":"Eagle Lake","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/eaglelake\/v1\/ZKlYin7caemhx9eSg6RvPfesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Piedra","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/piedra\/v2\/owf-AvEEyAj9LJ2tVZ_3Mw.ttf"}},{"kind":"webfonts#webfont","family":"Mrs Saint Delafield","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mrssaintdelafield\/v1\/vuWagfFT7bj9lFtZOFBwmjHMBelqWf3tJeGyts2SmKU.ttf"}},{"kind":"webfonts#webfont","family":"Stalemate","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/stalemate\/v1\/wQLCnG0qB6mOu2Wit2dt_w.ttf"}},{"kind":"webfonts#webfont","family":"Original Surfer","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/originalsurfer\/v2\/gdHw6HpSIN4D6Xt7pi1-qIkEz33TDwAZczo_6fY7eg0.ttf"}},{"kind":"webfonts#webfont","family":"Germania One","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/germaniaone\/v1\/3_6AyUql_-FbDi1e68jHdC3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Purple Purse","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/purplepurse\/v1\/Q5heFUrdmei9axbMITxxxS3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Chicle","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/chicle\/v2\/xg4q57Ut9ZmyFwLp51JLgg.ttf"}},{"kind":"webfonts#webfont","family":"Sevillana","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sevillana\/v1\/6m1Nh35oP7YEt00U80Smiw.ttf"}},{"kind":"webfonts#webfont","family":"Offside","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-31","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/offside\/v1\/v0C913SB8wqQUvcu1faUqw.ttf"}},{"kind":"webfonts#webfont","family":"Londrina Sketch","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/londrinasketch\/v1\/p7Ai06aT1Ycp_D2fyE3z69d6z_uhFGnpCOifUY1fJQo.ttf"}},{"kind":"webfonts#webfont","family":"Nokora","variants":["regular","700"],"subsets":["khmer"],"version":"v6","lastModified":"2012-10-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/nokora\/v6\/dRyz1JfnyKPNaRcBNX9F9A.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/nokora\/v6\/QMqqa4QEOhQpiig3cAPmbQ.ttf"}},{"kind":"webfonts#webfont","family":"Meie Script","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-08-23","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/meiescript\/v1\/oTIWE5MmPye-rCyVp_6KEqCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Sofadi One","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-03","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sofadione\/v1\/nirf4G12IcJ6KI8Eoj119fesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Ribeye","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ribeye\/v2\/e5w3VE8HnWBln4Ll6lUj3Q.ttf"}},{"kind":"webfonts#webfont","family":"Almendra","variants":["regular","italic","700","700italic"],"subsets":["latin-ext","latin"],"version":"v5","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/almendra\/v5\/PDpbB-ZF7deXAAEYPkQOeg.ttf","italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/almendra\/v5\/CNWLyiDucqVKVgr4EMidi_esZW2xOQ-xsNqO47m55DA.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/almendra\/v5\/ZpLdQMj7Q2AFio4nNO6A76CWcynf_cDxXwCLxiixG1c.ttf","700italic":"http:\/\/themes.googleusercontent.com\/static\/fonts\/almendra\/v5\/-tXHKMcnn6FqrhJV3l1e3QJKKGfqHaYFsRG-T3ceEVo.ttf"}},{"kind":"webfonts#webfont","family":"Sirin Stencil","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/sirinstencil\/v1\/pRpLdo0SawzO7MoBpvowsImg74kgS1F7KeR8rWhYwkU.ttf"}},{"kind":"webfonts#webfont","family":"Butterfly Kids","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/butterflykids\/v1\/J4NTF5M25htqeTffYImtlUZaDk62iwTBnbnvwSjZciA.ttf"}},{"kind":"webfonts#webfont","family":"Arbutus","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/arbutus\/v2\/Go_hurxoUsn5MnqNVQgodQ.ttf"}},{"kind":"webfonts#webfont","family":"Bubbler One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bubblerone\/v1\/e8S0qevkZAFaBybtt_SU4qCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Galindo","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-08-16","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/galindo\/v1\/2lafAS_ZEfB33OJryhXDUg.ttf"}},{"kind":"webfonts#webfont","family":"Ribeye Marrow","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ribeyemarrow\/v3\/q7cBSA-4ErAXBCDFPrhlY0cTNmV93fYG7UKgsLQNQWs.ttf"}},{"kind":"webfonts#webfont","family":"Fascinate","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fascinate\/v2\/ZE0637WWkBPKt1AmFaqD3Q.ttf"}},{"kind":"webfonts#webfont","family":"Odor Mean Chey","variants":["regular"],"subsets":["khmer"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/odormeanchey\/v5\/GK3E7EjPoBkeZhYshGFo0eVKG8sq4NyGgdteJLvqLDs.ttf"}},{"kind":"webfonts#webfont","family":"Jolly Lodger","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/jollylodger\/v1\/RX8HnkBgaEKQSHQyP9itiS3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Emblema One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/emblemaone\/v2\/7IlBUjBWPIiw7cr_O2IfSaCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Content","variants":["regular","700"],"subsets":["khmer"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/content\/v5\/l8qaLjygvOkDEU2G6-cjfQ.ttf","700":"http:\/\/themes.googleusercontent.com\/static\/fonts\/content\/v5\/7PivP8Zvs2qn6F6aNbSQe_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Eater","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/eater\/v2\/gm6f3OmYEdbs3lPQtUfBkA.ttf"}},{"kind":"webfonts#webfont","family":"Bokor","variants":["regular"],"subsets":["khmer"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bokor\/v5\/uAKdo0A85WW23Gs6mcbw7A.ttf"}},{"kind":"webfonts#webfont","family":"Averia Gruesa Libre","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/averiagruesalibre\/v1\/10vbZTOoN6T8D-nvDzwRFyXcKHuZXlCN8VkWHpkUzKM.ttf"}},{"kind":"webfonts#webfont","family":"Felipa","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/felipa\/v1\/SeyfyFZY7abAQXGrOIYnYg.ttf"}},{"kind":"webfonts#webfont","family":"Frijole","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/frijole\/v2\/L2MfZse-2gCascuD-nLhWg.ttf"}},{"kind":"webfonts#webfont","family":"Revalia","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/revalia\/v1\/1TKw66fF5_poiL0Ktgo4_A.ttf"}},{"kind":"webfonts#webfont","family":"Ewert","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ewert\/v1\/Em8hrzuzSbfHcTVqMjbAQg.ttf"}},{"kind":"webfonts#webfont","family":"Freehand","variants":["regular"],"subsets":["khmer"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/freehand\/v5\/uEBQxvA0lnn_BrD6krlxMw.ttf"}},{"kind":"webfonts#webfont","family":"Peralta","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-08-08","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/peralta\/v1\/cTJX5KEuc0GKRU9NXSm-8Q.ttf"}},{"kind":"webfonts#webfont","family":"Flavors","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/flavors\/v2\/SPJi5QclATvon8ExcKGRvQ.ttf"}},{"kind":"webfonts#webfont","family":"Macondo Swash Caps","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/macondoswashcaps\/v1\/SsSR706z-MlvEH7_LS6JAPkkgYRHs6GSG949m-K6x2k.ttf"}},{"kind":"webfonts#webfont","family":"Dr Sugiyama","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/drsugiyama\/v2\/S5Yx3MIckgoyHhhS4C9Tv6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Akronim","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/akronim\/v1\/qA0L2CSArk3tuOWE1AR1DA.ttf"}},{"kind":"webfonts#webfont","family":"Combo","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/combo\/v1\/Nab98KjR3JZSSPGtzLyXNw.ttf"}},{"kind":"webfonts#webfont","family":"Elsie","variants":["regular","900"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-12-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/elsie\/v1\/gwspePauE45BJu6Ok1QrfQ.ttf","900":"http:\/\/themes.googleusercontent.com\/static\/fonts\/elsie\/v1\/1t-9f0N2NFYwAgN7oaISqg.ttf"}},{"kind":"webfonts#webfont","family":"Angkor","variants":["regular"],"subsets":["khmer"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/angkor\/v5\/DLpLgIS-8F10ecwKqCm95Q.ttf"}},{"kind":"webfonts#webfont","family":"New Rocker","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-12-06","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/newrocker\/v1\/EFUWzHJedEkpW399zYOHofesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Marko One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/markoone\/v3\/hpP7j861sOAco43iDc4n4w.ttf"}},{"kind":"webfonts#webfont","family":"Romanesco","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/romanesco\/v2\/2udIjUrpK_CPzYSxRVzD4Q.ttf"}},{"kind":"webfonts#webfont","family":"Preahvihear","variants":["regular"],"subsets":["khmer"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/preahvihear\/v5\/82tDI-xTc53CxxOzEG4hDaCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Margarine","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/margarine\/v1\/DJnJwIrcO_cGkjSzY3MERw.ttf"}},{"kind":"webfonts#webfont","family":"Herr Von Muellerhoff","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/herrvonmuellerhoff\/v3\/mmy24EUmk4tjm4gAEjUd7NLGIYrUsBdh-JWHYgiDiMU.ttf"}},{"kind":"webfonts#webfont","family":"Mr Bedfort","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/mrbedfort\/v2\/81bGgHTRikLs_puEGshl7_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Miss Fajardose","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v3","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/missfajardose\/v3\/WcXjlQPKn6nBfr8LY3ktNu6rPKfVZo7L2bERcf0BDns.ttf"}},{"kind":"webfonts#webfont","family":"Ruge Boogie","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/rugeboogie\/v4\/U-TTmltL8aENLVIqYbI5QaCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Freckle Face","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-11-28","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/freckleface\/v1\/7-B8j9BPJgazdHIGqPNv8y3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Seymour One","variants":["regular"],"subsets":["latin-ext","cyrillic","latin"],"version":"v1","lastModified":"2012-10-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/seymourone\/v1\/HrdG2AEG_870Xb7xBVv6C6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Londrina Outline","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/londrinaoutline\/v2\/lls08GOa1eT74p072l1AWJmp8DTZ6iHear7UV05iykg.ttf"}},{"kind":"webfonts#webfont","family":"Dangrek","variants":["regular"],"subsets":["khmer"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/dangrek\/v5\/LOaFhBT-EHNxZjV8DAW_ew.ttf"}},{"kind":"webfonts#webfont","family":"Uncial Antiqua","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/uncialantiqua\/v1\/F-leefDiFwQXsyd6eaSllqrFJ4O13IHVxZbM6yoslpo.ttf"}},{"kind":"webfonts#webfont","family":"Koulen","variants":["regular"],"subsets":["khmer"],"version":"v6","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/koulen\/v6\/AAYOK8RSRO7FTskTzFuzNw.ttf"}},{"kind":"webfonts#webfont","family":"Diplomata","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-09-14","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/diplomata\/v1\/u-ByBiKgN6rTMA36H3kcKg.ttf"}},{"kind":"webfonts#webfont","family":"Taprom","variants":["regular"],"subsets":["khmer"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/taprom\/v5\/-KByU3BaUsyIvQs79qFObg.ttf"}},{"kind":"webfonts#webfont","family":"Moul","variants":["regular"],"subsets":["khmer"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/moul\/v5\/Kb0ALQnfyXawP1a_P_gpTQ.ttf"}},{"kind":"webfonts#webfont","family":"Underdog","variants":["regular"],"subsets":["latin-ext","cyrillic","latin"],"version":"v1","lastModified":"2012-09-26","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/underdog\/v1\/gBv9yjez_-5PnTprHWq0ig.ttf"}},{"kind":"webfonts#webfont","family":"Jim Nightshade","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v1","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/jimnightshade\/v1\/_n43lYHXVWNgXegdYRIK9CF1W_bo0EdycfH0kHciIic.ttf"}},{"kind":"webfonts#webfont","family":"Faster One","variants":["regular"],"subsets":["latin"],"version":"v1","lastModified":"2012-10-31","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fasterone\/v1\/YxTOW2sf56uxD1T7byP5K_esZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Metal Mania","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2012-08-16","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/metalmania\/v2\/isriV_rAUgj6bPWPN6l9QKCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Macondo","variants":["regular"],"subsets":["latin"],"version":"v2","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/macondo\/v2\/G6yPNUscRPQ8ufBXs_8yRQ.ttf"}},{"kind":"webfonts#webfont","family":"Butcherman","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/butcherman\/v4\/bxiJmD567sPBVpJsT0XR0vesZW2xOQ-xsNqO47m55DA.ttf"}},{"kind":"webfonts#webfont","family":"Almendra SC","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/almendrasc\/v3\/IuiLd8Fm9I6raSalxMoWeaCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Bayon","variants":["regular"],"subsets":["khmer"],"version":"v5","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bayon\/v5\/yTubusjTnpNRZwA4_50iVw.ttf"}},{"kind":"webfonts#webfont","family":"Stalinist One","variants":["regular"],"subsets":["latin-ext","cyrillic","latin"],"version":"v2","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/stalinistone\/v2\/ltOD4Zj3WJDXYjAIR-9vZojjx0o0jr6fNXxPgYh_a8Q.ttf"}},{"kind":"webfonts#webfont","family":"Ceviche One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2012-07-25","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/cevicheone\/v3\/WOaXIMBD4VYMy39MsobJhKCWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Bonbon","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/bonbon\/v3\/IW3u1yzG1knyW5oz0s9_6Q.ttf"}},{"kind":"webfonts#webfont","family":"Plaster","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v4","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/plaster\/v4\/O4QG9Z5116CXyfJdR9zxLw.ttf"}},{"kind":"webfonts#webfont","family":"Vampiro One","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/vampiroone\/v2\/OVDs4gY4WpS5u3Qd1gXRW6CWcynf_cDxXwCLxiixG1c.ttf"}},{"kind":"webfonts#webfont","family":"Fruktur","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fruktur\/v2\/PnQvfEi1LssAvhJsCwH__w.ttf"}},{"kind":"webfonts#webfont","family":"Moulpali","variants":["regular"],"subsets":["khmer"],"version":"v6","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/moulpali\/v6\/diD74BprGhmVkJoerKmrKA.ttf"}},{"kind":"webfonts#webfont","family":"Almendra Display","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/almendradisplay\/v2\/2Zuu97WJ_ez-87yz5Ai8fF6uyC_qD11hrFQ6EGgTJWI.ttf"}},{"kind":"webfonts#webfont","family":"Erica One","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2013-11-21","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/ericaone\/v3\/cIBnH2VAqQMIGYAcE4ufvQ.ttf"}},{"kind":"webfonts#webfont","family":"Diplomata SC","variants":["regular"],"subsets":["latin-ext","latin"],"version":"v2","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/diplomatasc\/v2\/JdVwAwfE1a_pahXjk5qpNi3USBnSvpkopQaUR-2r7iU.ttf"}},{"kind":"webfonts#webfont","family":"Fascinate Inline","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2013-11-19","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/fascinateinline\/v3\/lRguYfMfWArflkm5aOQ5QJmp8DTZ6iHear7UV05iykg.ttf"}},{"kind":"webfonts#webfont","family":"Metal","variants":["regular"],"subsets":["khmer"],"version":"v6","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleusercontent.com\/static\/fonts\/metal\/v6\/zA3UOP13ooQcxjv04BZX5g.ttf"}},{"kind":"webfonts#webfont","family":"Unlock","variants":["regular"],"subsets":["latin"],"version":"v3","lastModified":"2013-12-02","files":{"regular":"http:\/\/themes.googleus
|
|