html5-starter 0.1.3b
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +3 -0
- data/README.md +135 -0
- data/VERSION +1 -0
- data/lib/app/helpers/html5_boilerplate_helper.rb +47 -0
- data/lib/html5-boilerplate.rb +6 -0
- data/stylesheets/_html5-boilerplate.scss +15 -0
- data/stylesheets/html5-boilerplate/_fonts.scss +36 -0
- data/stylesheets/html5-boilerplate/_handheld.scss +8 -0
- data/stylesheets/html5-boilerplate/_helpers.scss +25 -0
- data/stylesheets/html5-boilerplate/_print.scss +20 -0
- data/stylesheets/html5-boilerplate/_reset.scss +50 -0
- data/stylesheets/html5-boilerplate/_styles.scss +100 -0
- data/templates/project/_flashes.html.haml +4 -0
- data/templates/project/_footer.html.haml +2 -0
- data/templates/project/_head.html.haml +32 -0
- data/templates/project/_header.html.haml +1 -0
- data/templates/project/_javascripts.html.haml +38 -0
- data/templates/project/_stylesheets.html.haml +8 -0
- data/templates/project/application.html.haml +15 -0
- data/templates/project/files/404.html +22 -0
- data/templates/project/files/apple-touch-icon.png +0 -0
- data/templates/project/files/build/build.xml +636 -0
- data/templates/project/files/build/buildinfo.properties +5 -0
- data/templates/project/files/build/config/build.properties +3 -0
- data/templates/project/files/build/config/default.properties +79 -0
- data/templates/project/files/build/config/project.properties +49 -0
- data/templates/project/files/build/createproject.sh +73 -0
- data/templates/project/files/build/tools/ant-contrib-1.0b3.jar +0 -0
- data/templates/project/files/build/tools/css-compressor/CSSCompression.php +465 -0
- data/templates/project/files/build/tools/css-compressor/changelog.txt +22 -0
- data/templates/project/files/build/tools/css-compressor/cli.php +101 -0
- data/templates/project/files/build/tools/css-compressor/helpers/hex2short-colors.json +39 -0
- data/templates/project/files/build/tools/css-compressor/helpers/hex2short-safe.json +16 -0
- data/templates/project/files/build/tools/css-compressor/helpers/long2hex-colors.json +127 -0
- data/templates/project/files/build/tools/css-compressor/lib/Cleanup.php +218 -0
- data/templates/project/files/build/tools/css-compressor/lib/Color.php +199 -0
- data/templates/project/files/build/tools/css-compressor/lib/Combine.php +191 -0
- data/templates/project/files/build/tools/css-compressor/lib/Combine/Aural.php +109 -0
- data/templates/project/files/build/tools/css-compressor/lib/Combine/Background.php +107 -0
- data/templates/project/files/build/tools/css-compressor/lib/Combine/Border.php +98 -0
- data/templates/project/files/build/tools/css-compressor/lib/Combine/BorderOutline.php +109 -0
- data/templates/project/files/build/tools/css-compressor/lib/Combine/BorderRadius.php +262 -0
- data/templates/project/files/build/tools/css-compressor/lib/Combine/Font.php +125 -0
- data/templates/project/files/build/tools/css-compressor/lib/Combine/List.php +104 -0
- data/templates/project/files/build/tools/css-compressor/lib/Combine/MarginPadding.php +190 -0
- data/templates/project/files/build/tools/css-compressor/lib/Compress.php +212 -0
- data/templates/project/files/build/tools/css-compressor/lib/Control.php +236 -0
- data/templates/project/files/build/tools/css-compressor/lib/Exception.php +32 -0
- data/templates/project/files/build/tools/css-compressor/lib/Format.php +187 -0
- data/templates/project/files/build/tools/css-compressor/lib/Individuals.php +307 -0
- data/templates/project/files/build/tools/css-compressor/lib/Numeric.php +103 -0
- data/templates/project/files/build/tools/css-compressor/lib/Option.php +133 -0
- data/templates/project/files/build/tools/css-compressor/lib/Organize.php +149 -0
- data/templates/project/files/build/tools/css-compressor/lib/Selectors.php +245 -0
- data/templates/project/files/build/tools/css-compressor/lib/Setup.php +292 -0
- data/templates/project/files/build/tools/css-compressor/lib/Trim.php +213 -0
- data/templates/project/files/build/tools/css-compressor/license.txt +21 -0
- data/templates/project/files/build/tools/htmlcompressor-0.9.8.jar +0 -0
- data/templates/project/files/build/tools/jpegtran.exe +0 -0
- data/templates/project/files/build/tools/optipng-0.6.4-exe/LICENSE.txt +21 -0
- data/templates/project/files/build/tools/optipng-0.6.4-exe/optipng.exe +0 -0
- data/templates/project/files/build/tools/yuicompressor-2.4.2.jar +0 -0
- data/templates/project/files/crossdomain.xml +25 -0
- data/templates/project/files/favicon.ico +0 -0
- data/templates/project/files/gitignore.txt +32 -0
- data/templates/project/files/gitignore_placeholder.txt +2 -0
- data/templates/project/files/google.yml +22 -0
- data/templates/project/files/htaccess +415 -0
- data/templates/project/files/humans.txt +43 -0
- data/templates/project/files/lighttpd.conf +149 -0
- data/templates/project/files/mime.types +80 -0
- data/templates/project/files/nginx.conf +108 -0
- data/templates/project/files/robots.txt +5 -0
- data/templates/project/files/web.config +207 -0
- data/templates/project/handheld.scss +8 -0
- data/templates/project/index.html +81 -0
- data/templates/project/javascripts/libs/dd_belatedpng.js +13 -0
- data/templates/project/javascripts/libs/jquery-1.4.4.js +7179 -0
- data/templates/project/javascripts/libs/jquery-1.4.4.min.js +167 -0
- data/templates/project/javascripts/libs/modernizr-1.6.min.js +30 -0
- data/templates/project/javascripts/plugins.js +13 -0
- data/templates/project/javascripts/rails.js +156 -0
- data/templates/project/javascripts/script.js +26 -0
- data/templates/project/manifest.rb +101 -0
- data/templates/project/partials/_base.scss +23 -0
- data/templates/project/style.scss +70 -0
- metadata +171 -0
@@ -0,0 +1,149 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* CSS Compressor [VERSION]
|
4
|
+
* [DATE]
|
5
|
+
* Corey Hart @ http://www.codenothing.com
|
6
|
+
*/
|
7
|
+
|
8
|
+
Class CSSCompression_Organize
|
9
|
+
{
|
10
|
+
/**
|
11
|
+
* Organize Patterns
|
12
|
+
*
|
13
|
+
* @class Control: Compression Controller
|
14
|
+
* @param (array) options: Reference to options
|
15
|
+
* @param (regex) rsemicolon: Checks for semicolon without an escape '\' character before it
|
16
|
+
* @param (regex) rlastsemi: Checks for semicolon at the end of the string
|
17
|
+
*/
|
18
|
+
private $Control;
|
19
|
+
private $options = array();
|
20
|
+
private $rsemicolon = "/(?<!\\\);/";
|
21
|
+
private $rlastsemi = "/(?<!\\\);$/";
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Stash a reference to the controller on each instantiation
|
25
|
+
*
|
26
|
+
* @param (class) control: CSSCompression Controller
|
27
|
+
*/
|
28
|
+
public function __construct( CSSCompression_Control $control ) {
|
29
|
+
$this->Control = $control;
|
30
|
+
$this->options = &$control->Option->options;
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Look to see if we can combine selectors to reduce the number
|
35
|
+
* of definitions.
|
36
|
+
*
|
37
|
+
* @param (array) selectors: Array of selectors, map directly to details
|
38
|
+
* @param (array) details: Array of rule sets, map directly to selectors
|
39
|
+
*/
|
40
|
+
public function organize( &$selectors = array(), &$details = array() ) {
|
41
|
+
// Combining defns based on similar selectors
|
42
|
+
list ( $selectors, $details ) = $this->reduceSelectors( $selectors, $details );
|
43
|
+
|
44
|
+
// Combining defns based on similar details
|
45
|
+
list ( $selectors, $details ) = $this->reduceDetails( $selectors, $details );
|
46
|
+
|
47
|
+
// Return in package form
|
48
|
+
return array( $selectors, $details );
|
49
|
+
}
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Combines multiply defined selectors by merging the rule sets,
|
53
|
+
* latter declarations overide declaratins at top of file
|
54
|
+
*
|
55
|
+
* @param (array) selectors: Array of selectors broken down by setup
|
56
|
+
* @param (array) details: Array of rule sets broken down by setup
|
57
|
+
*/
|
58
|
+
private function reduceSelectors( $selectors, $details ) {
|
59
|
+
$keys = array_keys( $selectors );
|
60
|
+
$max = array_pop( $keys ) + 1;
|
61
|
+
|
62
|
+
for ( $i = 0; $i < $max; $i++ ) {
|
63
|
+
if ( ! isset( $selectors[ $i ] ) ) {
|
64
|
+
continue;
|
65
|
+
}
|
66
|
+
|
67
|
+
for ( $k = $i + 1; $k < $max; $k++ ) {
|
68
|
+
if ( ! isset( $selectors[ $k ] ) ) {
|
69
|
+
continue;
|
70
|
+
}
|
71
|
+
|
72
|
+
if ( $selectors[ $i ] == $selectors[ $k ] ) {
|
73
|
+
// Prevent noticies
|
74
|
+
if ( ! isset( $details[ $i ] ) ) {
|
75
|
+
$details[ $i ] = '';
|
76
|
+
}
|
77
|
+
if ( ! isset( $details[ $k ] ) ) {
|
78
|
+
$details[ $k ] = '';
|
79
|
+
}
|
80
|
+
|
81
|
+
// We kill the last semicolon before organization, so account for that.
|
82
|
+
if ( $details[ $i ] != '' && $details[ $k ] != '' && ! preg_match( $this->rlastsemi, $details[ $i ] ) ) {
|
83
|
+
$details[ $i ] .= ';' . $details[ $k ];
|
84
|
+
}
|
85
|
+
else {
|
86
|
+
$details[ $i ] .= $details[ $k ];
|
87
|
+
}
|
88
|
+
|
89
|
+
// Remove the second part
|
90
|
+
unset( $selectors[ $k ], $details[ $k ] );
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
return array( $selectors, $details );
|
96
|
+
}
|
97
|
+
|
98
|
+
/**
|
99
|
+
* Combines multiply defined rule sets by merging the selectors
|
100
|
+
* in comma seperated format
|
101
|
+
*
|
102
|
+
* @param (array) selectors: Array of selectors broken down by setup
|
103
|
+
* @param (array) details: Array of rule sets broken down by setup
|
104
|
+
*/
|
105
|
+
private function reduceDetails( $selectors, $details ) {
|
106
|
+
$keys = array_keys( $selectors );
|
107
|
+
$max = array_pop( $keys ) + 1;
|
108
|
+
for ( $i = 0; $i < $max; $i++ ) {
|
109
|
+
if ( ! isset( $selectors[ $i ] ) ) {
|
110
|
+
continue;
|
111
|
+
}
|
112
|
+
|
113
|
+
$arr = preg_split( $this->rsemicolon, isset( $details[ $i ] ) ? $details[ $i ] : '' );
|
114
|
+
for ( $k = $i + 1; $k < $max; $k++ ) {
|
115
|
+
if ( ! isset( $selectors[ $k ] ) ) {
|
116
|
+
continue;
|
117
|
+
}
|
118
|
+
|
119
|
+
$match = preg_split( $this->rsemicolon, isset( $details[ $k ] ) ? $details[ $k ] : '' );
|
120
|
+
$x = array_diff( $arr, $match );
|
121
|
+
$y = array_diff( $match, $arr );
|
122
|
+
|
123
|
+
if ( count( $x ) < 1 && count( $y ) < 1 ) {
|
124
|
+
$selectors[ $i ] .= ',' . $selectors[ $k ];
|
125
|
+
unset( $details[ $k ], $selectors[ $k ] );
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
return array( $selectors, $details );
|
131
|
+
}
|
132
|
+
|
133
|
+
/**
|
134
|
+
* Access to private methods for testing
|
135
|
+
*
|
136
|
+
* @param (string) method: Method to be called
|
137
|
+
* @param (array) args: Array of paramters to be passed in
|
138
|
+
*/
|
139
|
+
public function access( $method, $args ) {
|
140
|
+
if ( method_exists( $this, $method ) ) {
|
141
|
+
return call_user_func_array( array( $this, $method ), $args );
|
142
|
+
}
|
143
|
+
else {
|
144
|
+
throw new CSSCompression_Exception( "Unknown method in Organize Class - " . $method );
|
145
|
+
}
|
146
|
+
}
|
147
|
+
};
|
148
|
+
|
149
|
+
?>
|
@@ -0,0 +1,245 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* CSS Compressor [VERSION]
|
4
|
+
* [DATE]
|
5
|
+
* Corey Hart @ http://www.codenothing.com
|
6
|
+
*/
|
7
|
+
|
8
|
+
Class CSSCompression_Selectors
|
9
|
+
{
|
10
|
+
/**
|
11
|
+
* Selector patterns
|
12
|
+
*
|
13
|
+
* @class Control: Compression Controller
|
14
|
+
* @param (string) token: Copy of the injection token
|
15
|
+
* @param (regex) ridattr: ID Attribute matcher (combined with token)
|
16
|
+
* @param (regex) rclassattr: class Attribute matcher (combined with token)
|
17
|
+
* @param (array) options: Reference to options
|
18
|
+
* @param (regex) rmark: Stop points during selector parsing
|
19
|
+
* @param (regex) ridclassend: End of a id/class string
|
20
|
+
* @param (regex) rescapedspace: for replacement in class attributes
|
21
|
+
* @param (regex) rquote: Checks for the next quote character
|
22
|
+
* @param (regex) rcomma: looks for an unescaped comma character
|
23
|
+
* @param (regex) rspace: looks for an unescaped space character
|
24
|
+
* @param (regex) rid: looks for an unescaped hash character
|
25
|
+
* @param (regex) rpseudo: Add space after first-letter|line pseudo selector
|
26
|
+
* --- when it occurs before comma or rule set
|
27
|
+
*/
|
28
|
+
private $Control;
|
29
|
+
private $token = '';
|
30
|
+
private $ridattr = "";
|
31
|
+
private $rclassattr = "";
|
32
|
+
private $options = array();
|
33
|
+
private $rmark = "/(?<!\\\)(#|\.|=)/";
|
34
|
+
private $ridclassend = "/(?<!\\\)[:#>~\[\+\*\. ]/";
|
35
|
+
private $rquote = "/(?<!\\\)(\"|')?\]/";
|
36
|
+
private $rescapedspace = "/\\\ /";
|
37
|
+
private $rcomma = "/(?<!\\\),/";
|
38
|
+
private $rspace = "/(?<!\\\)\s/";
|
39
|
+
private $rid = "/(?<!\\\)#/";
|
40
|
+
private $rpseudo = "/:first-(letter|line)(,|$)/i";
|
41
|
+
|
42
|
+
/**
|
43
|
+
* Stash a reference to the controller on each instantiation
|
44
|
+
*
|
45
|
+
* @param (class) control: CSSCompression Controller
|
46
|
+
*/
|
47
|
+
public function __construct( CSSCompression_Control $control ) {
|
48
|
+
$this->Control = $control;
|
49
|
+
$this->token = CSSCompression::TOKEN;
|
50
|
+
$this->ridattr = "/\[id=$this->token(.*?)$this->token\]/";
|
51
|
+
$this->rclassattr = "/\[class=$this->token(.*?)$this->token\]/";
|
52
|
+
$this->options = &$control->Option->options;
|
53
|
+
}
|
54
|
+
|
55
|
+
/**
|
56
|
+
* Selector specific optimizations
|
57
|
+
*
|
58
|
+
* @param (array) selectors: Array of selectors
|
59
|
+
*/
|
60
|
+
public function selectors( &$selectors = array() ) {
|
61
|
+
foreach ( $selectors as &$selector ) {
|
62
|
+
// Auto ignore sections
|
63
|
+
if ( strpos( $selector, $this->token ) === 0 ) {
|
64
|
+
continue;
|
65
|
+
}
|
66
|
+
|
67
|
+
// Smart casing and token injection
|
68
|
+
$selector = $this->parse( $selector );
|
69
|
+
|
70
|
+
// Converting attr to shorthanded selectors
|
71
|
+
if ( $this->options['attr2selector'] ) {
|
72
|
+
// Use id hash instead of id attr
|
73
|
+
$selector = $this->idAttribute( $selector );
|
74
|
+
|
75
|
+
// Use class notation instead of class attr
|
76
|
+
$selector = $this->classAttribute( $selector );
|
77
|
+
}
|
78
|
+
|
79
|
+
// Remove everything before final id in a selector
|
80
|
+
if ( $this->options['strict-id'] ) {
|
81
|
+
$selector = $this->strictid( $selector );
|
82
|
+
}
|
83
|
+
|
84
|
+
// Get rid of possible repeated selectors
|
85
|
+
$selector = $this->repeats( $selector );
|
86
|
+
|
87
|
+
// Add space after pseudo selectors (so ie6 doesn't complain)
|
88
|
+
if ( $this->options['pseudo-space'] ) {
|
89
|
+
$selector = $this->pseudoSpace( $selector );
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
return $selectors;
|
94
|
+
}
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Converts selectors like BODY => body, DIV => div
|
98
|
+
* and injects tokens wrappers for attribute values
|
99
|
+
*
|
100
|
+
* @param (string) selector: CSS Selector
|
101
|
+
*/
|
102
|
+
private function parse( $selector ) {
|
103
|
+
$clean = '';
|
104
|
+
$substr = '';
|
105
|
+
$pos = 0;
|
106
|
+
|
107
|
+
while ( preg_match( $this->rmark, $selector, $match, PREG_OFFSET_CAPTURE, $pos ) ) {
|
108
|
+
$substr = substr( $selector, $pos, $match[ 0 ][ 1 ] + 1 - $pos );
|
109
|
+
$clean .= $this->options['lowercase-selectors'] ? strtolower( $substr ) : $substr;
|
110
|
+
$pos = $match[ 0 ][ 1 ] + strlen( $match[ 1 ][ 0 ] );
|
111
|
+
|
112
|
+
// Class or id match
|
113
|
+
if ( $match[ 1 ][ 0 ] == '#' || $match[ 1 ][ 0 ] == '.' ) {
|
114
|
+
if ( preg_match( $this->ridclassend, $selector, $m, PREG_OFFSET_CAPTURE, $pos ) ) {
|
115
|
+
$clean .= substr( $selector, $pos, $m[ 0 ][ 1 ] - $pos );
|
116
|
+
$pos = $m[ 0 ][ 1 ];
|
117
|
+
}
|
118
|
+
else {
|
119
|
+
$clean .= substr( $selector, $pos );
|
120
|
+
$pos = strlen( $selector );
|
121
|
+
break;
|
122
|
+
}
|
123
|
+
}
|
124
|
+
// Start of a string
|
125
|
+
else if ( preg_match( $this->rquote, $selector, $m, PREG_OFFSET_CAPTURE, $pos ) ) {
|
126
|
+
if ( $selector[ $pos ] == "\"" || $selector[ $pos ] == "'" ) {
|
127
|
+
$pos++;
|
128
|
+
}
|
129
|
+
$clean .= $this->token . substr( $selector, $pos, $m[ 0 ][ 1 ] - $pos ) . $this->token . ']';
|
130
|
+
$pos = $m[ 0 ][ 1 ] + strlen( $m[ 0 ][ 0 ] );
|
131
|
+
}
|
132
|
+
// No break points left
|
133
|
+
else {
|
134
|
+
$clean .= substr( $selector, $pos );
|
135
|
+
$pos = strlen( $selector );
|
136
|
+
break;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
return $clean . ( $this->options['lowercase-selectors'] ? strtolower( substr( $selector, $pos ) ) : substr( $selector, $pos ) );
|
141
|
+
}
|
142
|
+
|
143
|
+
/**
|
144
|
+
* Convert [id=blah] attribute selectors into id form selector (#blah)
|
145
|
+
*
|
146
|
+
* @param (string) selector: CSS Selector
|
147
|
+
*/
|
148
|
+
private function idAttribute( $selector ) {
|
149
|
+
$pos = 0;
|
150
|
+
while ( preg_match( $this->ridattr, $selector, $match, PREG_OFFSET_CAPTURE, $pos ) ) {
|
151
|
+
// Don't convert if space found (not valid hash selector)
|
152
|
+
if ( strpos( $match[ 1 ][ 0 ], ' ' ) !== false ) {
|
153
|
+
$pos = $match[ 0 ][ 1 ] + strlen( $match[ 0 ][ 0 ] );
|
154
|
+
continue;
|
155
|
+
}
|
156
|
+
|
157
|
+
$selector = substr_replace( $selector, '#' . $match[ 1 ][ 0 ], $match[ 0 ][ 1 ], strlen( $match[ 0 ][ 0 ] ) );
|
158
|
+
$pos = $match[ 0 ][ 1 ] + strlen( $match[ 1 ][ 0 ] ) + 1;
|
159
|
+
}
|
160
|
+
|
161
|
+
return $selector;
|
162
|
+
}
|
163
|
+
|
164
|
+
/**
|
165
|
+
* Convert [class=blah] attribute selectors into class form selector (.blah)
|
166
|
+
*
|
167
|
+
* @param (string) selector: CSS Selector
|
168
|
+
*/
|
169
|
+
private function classAttribute( $selector ) {
|
170
|
+
$pos = 0;
|
171
|
+
while ( preg_match( $this->rclassattr, $selector, $match, PREG_OFFSET_CAPTURE, $pos ) ) {
|
172
|
+
// Don't convert if prescense of dot separator found
|
173
|
+
if ( strpos( $match[ 1 ][ 0 ], '.' ) !== false ) {
|
174
|
+
$pos = $match[ 0 ][ 1 ] + strlen( $match[ 0 ][ 0 ] );
|
175
|
+
continue;
|
176
|
+
}
|
177
|
+
|
178
|
+
$replace = '.' . preg_replace( $this->rescapedspace, ".", $match[ 1 ][ 0 ] );
|
179
|
+
$selector = substr_replace( $selector, $replace, $match[ 0 ][ 1 ], strlen( $match[ 0 ][ 0 ] ) );
|
180
|
+
$pos = $match[ 0 ][ 1 ] + strlen( $match[ 1 ][ 0 ] ) + 1;
|
181
|
+
}
|
182
|
+
|
183
|
+
return $selector;
|
184
|
+
}
|
185
|
+
|
186
|
+
/**
|
187
|
+
* Promotes nested id's to the front of the selector
|
188
|
+
*
|
189
|
+
* @param (string) selector: CSS Selector
|
190
|
+
*/
|
191
|
+
private function strictid( $selector ) {
|
192
|
+
$parts = preg_split( $this->rcomma, $selector );
|
193
|
+
foreach ( $parts as &$s ) {
|
194
|
+
if ( preg_match( $this->rid, $s ) ) {
|
195
|
+
$p = preg_split( $this->rid, $s );
|
196
|
+
$s = '#' . array_pop( $p );
|
197
|
+
}
|
198
|
+
}
|
199
|
+
|
200
|
+
return implode( ',', $parts );
|
201
|
+
}
|
202
|
+
|
203
|
+
/**
|
204
|
+
* Removes repeated selectors that have been comma separated
|
205
|
+
*
|
206
|
+
* @param (string) selector: CSS Selector
|
207
|
+
*/
|
208
|
+
private function repeats( $selector ) {
|
209
|
+
$parts = preg_split( $this->rcomma, $selector );
|
210
|
+
$parts = array_flip( $parts );
|
211
|
+
$parts = array_flip( $parts );
|
212
|
+
return implode( ',', $parts );
|
213
|
+
}
|
214
|
+
|
215
|
+
/**
|
216
|
+
* Adds space after pseudo selector for ie6 like a:first-child{ => a:first-child {
|
217
|
+
*
|
218
|
+
* @param (string) selector: CSS Selector
|
219
|
+
*/
|
220
|
+
private function pseudoSpace( $selector ) {
|
221
|
+
return preg_replace( $this->rpseudo, ":first-$1 $2", $selector );
|
222
|
+
}
|
223
|
+
|
224
|
+
/**
|
225
|
+
* Access to private methods for testing
|
226
|
+
*
|
227
|
+
* @param (string) method: Method to be called
|
228
|
+
* @param (array) args: Array of paramters to be passed in
|
229
|
+
*/
|
230
|
+
public function access( $method, $args ) {
|
231
|
+
if ( method_exists( $this, $method ) ) {
|
232
|
+
if ( $method == 'selectors' ) {
|
233
|
+
return $this->selectors( $args[ 0 ] );
|
234
|
+
}
|
235
|
+
else {
|
236
|
+
return call_user_func_array( array( $this, $method ), $args );
|
237
|
+
}
|
238
|
+
}
|
239
|
+
else {
|
240
|
+
throw new CSSCompression_Exception( "Unknown method in Selectors Class - " . $method );
|
241
|
+
}
|
242
|
+
}
|
243
|
+
};
|
244
|
+
|
245
|
+
?>
|
@@ -0,0 +1,292 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* CSS Compressor [VERSION]
|
4
|
+
* [DATE]
|
5
|
+
* Corey Hart @ http://www.codenothing.com
|
6
|
+
*/
|
7
|
+
|
8
|
+
Class CSSCompression_Setup
|
9
|
+
{
|
10
|
+
/**
|
11
|
+
* Trim Patterns
|
12
|
+
*
|
13
|
+
* @class Control: Compression Controller
|
14
|
+
* @class Individuals: Individuals Instance
|
15
|
+
* @instance instance: CSSCompression Instance
|
16
|
+
* @param (string) token: Copy of the injection token
|
17
|
+
* @param (array) options: Reference to options
|
18
|
+
* @param (array) stats: Reference to stats
|
19
|
+
* @param (regex) rsemicolon: Checks for semicolon without an escape '\' character before it
|
20
|
+
* @param (regex) rcolon: Checks for colon without an escape '\' character before it
|
21
|
+
* @param (regex) rbang: Checks for '!' without an escape '\' character before it
|
22
|
+
* @param (regex) rspacebank: Checks for an unescaped space before a bang character
|
23
|
+
* @param (regex) rliner: Matching known 1-line intros
|
24
|
+
* @param (regex) rnested: Matching known subsection handlers
|
25
|
+
* @param (regex) rurl: url wrapper matching
|
26
|
+
* @param (regex) rsinglequote: Checks for unescaped escaped single quote (mouthfull)
|
27
|
+
* @param (array) rsetup: Expanding stylesheet for semi-tokenizing
|
28
|
+
*/
|
29
|
+
private $Control;
|
30
|
+
private $Individuals;
|
31
|
+
private $instance;
|
32
|
+
private $token = '';
|
33
|
+
private $options = array();
|
34
|
+
private $stats = array();
|
35
|
+
private $rsemicolon = "/(?<!\\\);/";
|
36
|
+
private $rcolon = "/(?<!\\\):/";
|
37
|
+
private $rbang = "/(?<!\\\)\!/";
|
38
|
+
private $rspacebang = "/(?<!\\\)\s\!/";
|
39
|
+
private $rliner = "/^@(import|charset|namespace)/i";
|
40
|
+
private $rmedia = "/^@media/i";
|
41
|
+
private $rurl = "/url\((.*?)\)/";
|
42
|
+
private $rsinglequote = "/(?<!\\\)\\\'/";
|
43
|
+
private $rsetup = array(
|
44
|
+
'patterns' => array(
|
45
|
+
"/(?<!\\\){/",
|
46
|
+
"/(?<!\\\)}/",
|
47
|
+
"/(?<!\\\)@/",
|
48
|
+
"/(@(charset|import)[^;]*(?<!\\\);)/",
|
49
|
+
),
|
50
|
+
'replacements' => array(
|
51
|
+
"\n{\n",
|
52
|
+
"\n}\n",
|
53
|
+
"\n@",
|
54
|
+
"$1\n",
|
55
|
+
),
|
56
|
+
);
|
57
|
+
|
58
|
+
/**
|
59
|
+
* Stash a reference to the controller on each instantiation
|
60
|
+
*
|
61
|
+
* @param (class) control: CSSCompression Controller
|
62
|
+
*/
|
63
|
+
public function __construct( CSSCompression_Control $control ) {
|
64
|
+
$this->Control = $control;
|
65
|
+
$this->Individuals = $control->Individuals;
|
66
|
+
$this->token = CSSCompression::TOKEN;
|
67
|
+
$this->options = &$control->Option->options;
|
68
|
+
$this->stats = &$control->stats;
|
69
|
+
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
* Setup selector and details arrays for compression methods
|
73
|
+
*
|
74
|
+
* @param (string) css: Trimed stylesheet
|
75
|
+
*/
|
76
|
+
public function setup( $css ) {
|
77
|
+
// Seperate the element from the elements details
|
78
|
+
$css = explode( "\n", preg_replace( $this->rsetup['patterns'], $this->rsetup['replacements'], $css ) );
|
79
|
+
$newline = $this->options['readability'] > CSSCompression::READ_NONE ? "\n" : '';
|
80
|
+
$setup = array(
|
81
|
+
'selectors' => array(),
|
82
|
+
'details' => array(),
|
83
|
+
'unknown' => array(),
|
84
|
+
'introliner' => '',
|
85
|
+
'namespace' => '',
|
86
|
+
'import' => '',
|
87
|
+
'charset' => '',
|
88
|
+
);
|
89
|
+
|
90
|
+
while ( count( $css ) ) {
|
91
|
+
$row = trim( array_shift( $css ) );
|
92
|
+
|
93
|
+
if ( $row == '' ) {
|
94
|
+
continue;
|
95
|
+
}
|
96
|
+
// Single block At-Rule set
|
97
|
+
else if ( $row[ 0 ] == '@' && $css[ 0 ] == '{' && trim( $css[ 1 ] ) != '' && $css[ 2 ] == '}' ) {
|
98
|
+
// Stash selector
|
99
|
+
array_push( $setup['selectors'], $row );
|
100
|
+
|
101
|
+
// Stash details (after the opening brace)
|
102
|
+
array_push( $setup['details'], $this->details( trim( $css[ 1 ] ) ) );
|
103
|
+
|
104
|
+
// drop the details from the stack
|
105
|
+
$css = array_slice( $css, 3 );
|
106
|
+
}
|
107
|
+
// Single line At-Rules (import/charset/namespace)
|
108
|
+
else if ( preg_match( $this->rliner, $row, $match ) ) {
|
109
|
+
$setup[ $match[ 1 ] ] .= $this->liner( $row ) . $newline;
|
110
|
+
}
|
111
|
+
// Nested At-Rule declaration blocks
|
112
|
+
else if ( $row[ 0 ] == '@' && $css[ 0 ] == '{' ) {
|
113
|
+
// Stash atrule as selector
|
114
|
+
array_push( $setup['selectors'], $this->token . $row );
|
115
|
+
|
116
|
+
// Stash details (after the opening brace)
|
117
|
+
array_push( $setup['details'], $this->nested( $css, preg_match( $this->rmedia, $row ) ) . $newline );
|
118
|
+
}
|
119
|
+
// Unknown single line At-Rules
|
120
|
+
else if ( $row[ 0 ] == '@' && substr( $row, -1 ) == ';' ) {
|
121
|
+
$setup[ 'introliner' ] .= $row . $newline;
|
122
|
+
}
|
123
|
+
// Declaration Block
|
124
|
+
else if ( count( $css ) >= 3 && $css[ 0 ] == '{' && $css[ 2 ] == '}' ) {
|
125
|
+
// Stash selector
|
126
|
+
array_push( $setup['selectors'], $row );
|
127
|
+
|
128
|
+
// Stash details (after the opening brace)
|
129
|
+
array_push( $setup['details'], $this->details( trim( $css[ 1 ] ) ) );
|
130
|
+
|
131
|
+
// drop the details from the stack
|
132
|
+
$css = array_slice( $css, 3 );
|
133
|
+
}
|
134
|
+
// Last catch, store unknown artifacts as selectors with a token
|
135
|
+
// and give it an empty rule set
|
136
|
+
else {
|
137
|
+
// Still add to unknown stack, for notification
|
138
|
+
array_push( $setup['unknown'], $row );
|
139
|
+
|
140
|
+
// Stash unknown artifacts as selectors with a token
|
141
|
+
array_push( $setup['selectors'], $this->token . $row );
|
142
|
+
|
143
|
+
// Give it an empty rule set
|
144
|
+
array_push( $setup['details'], '' );
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
return $setup;
|
149
|
+
}
|
150
|
+
|
151
|
+
/**
|
152
|
+
* Run nested elements through a separate instance of compression
|
153
|
+
*
|
154
|
+
* @param (array) css: Reference to the original css array
|
155
|
+
* @param (bool) organize: Whether or not to organize the subsection (only true for media sections)
|
156
|
+
*/
|
157
|
+
private function nested( &$css = array(), $organize = false ) {
|
158
|
+
$options = $this->options;
|
159
|
+
$left = 0;
|
160
|
+
$right = 0;
|
161
|
+
$row = '';
|
162
|
+
$independent = '';
|
163
|
+
$content = '';
|
164
|
+
$spacing = '';
|
165
|
+
$newline = $this->options['readability'] > CSSCompression::READ_NONE ? "\n" : '';
|
166
|
+
|
167
|
+
// Find the end of the nested section
|
168
|
+
while ( count( $css ) && ( $left < 1 || $left > $right ) ) {
|
169
|
+
$row = trim( array_shift( $css ) );
|
170
|
+
|
171
|
+
if ( $row == '' ) {
|
172
|
+
continue;
|
173
|
+
}
|
174
|
+
else if ( $row == '{' ) {
|
175
|
+
$left++;
|
176
|
+
}
|
177
|
+
else if ( $row == '}' ) {
|
178
|
+
$right++;
|
179
|
+
}
|
180
|
+
else if ( count( $css ) && substr( $row, 0, 1 ) != '@' && substr( $css[ 0 ], 0, 1 ) == '@' && substr( $row, -1 ) == ';' ) {
|
181
|
+
$independent .= $row;
|
182
|
+
continue;
|
183
|
+
}
|
184
|
+
|
185
|
+
$content .= $row;
|
186
|
+
}
|
187
|
+
|
188
|
+
// Ensure copy of instance exists
|
189
|
+
if ( ! $this->instance ) {
|
190
|
+
$this->instance = new CSSCompression();
|
191
|
+
}
|
192
|
+
|
193
|
+
// Fresh start
|
194
|
+
$this->instance->reset();
|
195
|
+
|
196
|
+
// Compress the nested section independently after removing the wrapping braces
|
197
|
+
// Also make sure to only organize media sections
|
198
|
+
if ( $options['organize'] == true && $organize == false ) {
|
199
|
+
$options['organize'] = false;
|
200
|
+
}
|
201
|
+
// Independent sections should be prepended to the next compressed section
|
202
|
+
$content = ( $independent == '' ? '' : $independent . $newline )
|
203
|
+
. $this->instance->compress( substr( $content, 1, -1 ), $options );
|
204
|
+
|
205
|
+
// Formatting for anything higher then 0 readability
|
206
|
+
if ( $newline == "\n" ) {
|
207
|
+
$content = "\n\t" . str_replace( "\n", "\n\t", $content ) . "\n";
|
208
|
+
$spacing = $this->options['readability'] > CSSCompression::READ_MIN ? ' ' : '';
|
209
|
+
}
|
210
|
+
|
211
|
+
// Stash the compressed nested script
|
212
|
+
return "$spacing{" . $content . "}$newline";
|
213
|
+
}
|
214
|
+
|
215
|
+
/**
|
216
|
+
* Converts import/namespace urls into strings
|
217
|
+
*
|
218
|
+
* @param (string) row: At-rule
|
219
|
+
*/
|
220
|
+
private function liner( $row ) {
|
221
|
+
$pos = 0;
|
222
|
+
while ( preg_match( $this->rurl, $row, $match, PREG_OFFSET_CAPTURE, $pos ) ) {
|
223
|
+
$quote = preg_match( $this->rsinglequote, $match[ 1 ][ 0 ] ) ? '"' : "'";
|
224
|
+
$replace = $quote . $match[ 1 ][ 0 ] . $quote;
|
225
|
+
$row = substr_replace( $row, $replace, $match[ 0 ][ 1 ], strlen( $match[ 0 ][ 0 ] ) );
|
226
|
+
$pos = $match[ 0 ][ 1 ] + strlen( $replace );
|
227
|
+
}
|
228
|
+
|
229
|
+
return $row;
|
230
|
+
}
|
231
|
+
|
232
|
+
/**
|
233
|
+
* Run individual compression techniques on each property of a selector
|
234
|
+
*
|
235
|
+
* @param (string) row: Selector properties
|
236
|
+
*/
|
237
|
+
private function details( $row ) {
|
238
|
+
$row = preg_split( $this->rsemicolon, $row );
|
239
|
+
$parts = array();
|
240
|
+
$details = '';
|
241
|
+
|
242
|
+
foreach ( $row as $line ) {
|
243
|
+
// Set loopers
|
244
|
+
$parts = preg_split( $this->rcolon, $line, 2 );
|
245
|
+
$prop = '';
|
246
|
+
$value = '';
|
247
|
+
|
248
|
+
// Property
|
249
|
+
if ( isset( $parts[ 0 ] ) && ( $parts[ 0 ] = trim( $parts[ 0 ] ) ) != '' ) {
|
250
|
+
$prop = $parts[ 0 ];
|
251
|
+
}
|
252
|
+
|
253
|
+
// Value
|
254
|
+
if ( isset( $parts[ 1 ] ) && ( $parts[ 1 ] = trim( $parts[ 1 ] ) ) != '' ) {
|
255
|
+
$value = preg_replace( $this->rbang, ' !', $parts[ 1 ] );
|
256
|
+
}
|
257
|
+
|
258
|
+
// Fail safe, remove unspecified property/values
|
259
|
+
if ( $prop == '' || $value == '' ) {
|
260
|
+
continue;
|
261
|
+
}
|
262
|
+
|
263
|
+
// Run the tag/element through each compression
|
264
|
+
list ( $prop, $value ) = $this->Individuals->individuals( $prop, $value );
|
265
|
+
|
266
|
+
// Add counter to before stats
|
267
|
+
$this->stats['before']['props']++;
|
268
|
+
|
269
|
+
// Store the compressed element
|
270
|
+
$details .= "$prop:" . preg_replace( $this->rspacebang, '!', $value ) . ";";
|
271
|
+
}
|
272
|
+
|
273
|
+
return $details;
|
274
|
+
}
|
275
|
+
|
276
|
+
/**
|
277
|
+
* Access to private methods for testing
|
278
|
+
*
|
279
|
+
* @param (string) method: Method to be called
|
280
|
+
* @param (array) args: Array of paramters to be passed in
|
281
|
+
*/
|
282
|
+
public function access( $method, $args ) {
|
283
|
+
if ( method_exists( $this, $method ) ) {
|
284
|
+
return call_user_func_array( array( $this, $method ), $args );
|
285
|
+
}
|
286
|
+
else {
|
287
|
+
throw new CSSCompression_Exception( "Unknown method in Setup Class - " . $method );
|
288
|
+
}
|
289
|
+
}
|
290
|
+
};
|
291
|
+
|
292
|
+
?>
|