html5-starter 0.1.3b

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/LICENSE +3 -0
  2. data/README.md +135 -0
  3. data/VERSION +1 -0
  4. data/lib/app/helpers/html5_boilerplate_helper.rb +47 -0
  5. data/lib/html5-boilerplate.rb +6 -0
  6. data/stylesheets/_html5-boilerplate.scss +15 -0
  7. data/stylesheets/html5-boilerplate/_fonts.scss +36 -0
  8. data/stylesheets/html5-boilerplate/_handheld.scss +8 -0
  9. data/stylesheets/html5-boilerplate/_helpers.scss +25 -0
  10. data/stylesheets/html5-boilerplate/_print.scss +20 -0
  11. data/stylesheets/html5-boilerplate/_reset.scss +50 -0
  12. data/stylesheets/html5-boilerplate/_styles.scss +100 -0
  13. data/templates/project/_flashes.html.haml +4 -0
  14. data/templates/project/_footer.html.haml +2 -0
  15. data/templates/project/_head.html.haml +32 -0
  16. data/templates/project/_header.html.haml +1 -0
  17. data/templates/project/_javascripts.html.haml +38 -0
  18. data/templates/project/_stylesheets.html.haml +8 -0
  19. data/templates/project/application.html.haml +15 -0
  20. data/templates/project/files/404.html +22 -0
  21. data/templates/project/files/apple-touch-icon.png +0 -0
  22. data/templates/project/files/build/build.xml +636 -0
  23. data/templates/project/files/build/buildinfo.properties +5 -0
  24. data/templates/project/files/build/config/build.properties +3 -0
  25. data/templates/project/files/build/config/default.properties +79 -0
  26. data/templates/project/files/build/config/project.properties +49 -0
  27. data/templates/project/files/build/createproject.sh +73 -0
  28. data/templates/project/files/build/tools/ant-contrib-1.0b3.jar +0 -0
  29. data/templates/project/files/build/tools/css-compressor/CSSCompression.php +465 -0
  30. data/templates/project/files/build/tools/css-compressor/changelog.txt +22 -0
  31. data/templates/project/files/build/tools/css-compressor/cli.php +101 -0
  32. data/templates/project/files/build/tools/css-compressor/helpers/hex2short-colors.json +39 -0
  33. data/templates/project/files/build/tools/css-compressor/helpers/hex2short-safe.json +16 -0
  34. data/templates/project/files/build/tools/css-compressor/helpers/long2hex-colors.json +127 -0
  35. data/templates/project/files/build/tools/css-compressor/lib/Cleanup.php +218 -0
  36. data/templates/project/files/build/tools/css-compressor/lib/Color.php +199 -0
  37. data/templates/project/files/build/tools/css-compressor/lib/Combine.php +191 -0
  38. data/templates/project/files/build/tools/css-compressor/lib/Combine/Aural.php +109 -0
  39. data/templates/project/files/build/tools/css-compressor/lib/Combine/Background.php +107 -0
  40. data/templates/project/files/build/tools/css-compressor/lib/Combine/Border.php +98 -0
  41. data/templates/project/files/build/tools/css-compressor/lib/Combine/BorderOutline.php +109 -0
  42. data/templates/project/files/build/tools/css-compressor/lib/Combine/BorderRadius.php +262 -0
  43. data/templates/project/files/build/tools/css-compressor/lib/Combine/Font.php +125 -0
  44. data/templates/project/files/build/tools/css-compressor/lib/Combine/List.php +104 -0
  45. data/templates/project/files/build/tools/css-compressor/lib/Combine/MarginPadding.php +190 -0
  46. data/templates/project/files/build/tools/css-compressor/lib/Compress.php +212 -0
  47. data/templates/project/files/build/tools/css-compressor/lib/Control.php +236 -0
  48. data/templates/project/files/build/tools/css-compressor/lib/Exception.php +32 -0
  49. data/templates/project/files/build/tools/css-compressor/lib/Format.php +187 -0
  50. data/templates/project/files/build/tools/css-compressor/lib/Individuals.php +307 -0
  51. data/templates/project/files/build/tools/css-compressor/lib/Numeric.php +103 -0
  52. data/templates/project/files/build/tools/css-compressor/lib/Option.php +133 -0
  53. data/templates/project/files/build/tools/css-compressor/lib/Organize.php +149 -0
  54. data/templates/project/files/build/tools/css-compressor/lib/Selectors.php +245 -0
  55. data/templates/project/files/build/tools/css-compressor/lib/Setup.php +292 -0
  56. data/templates/project/files/build/tools/css-compressor/lib/Trim.php +213 -0
  57. data/templates/project/files/build/tools/css-compressor/license.txt +21 -0
  58. data/templates/project/files/build/tools/htmlcompressor-0.9.8.jar +0 -0
  59. data/templates/project/files/build/tools/jpegtran.exe +0 -0
  60. data/templates/project/files/build/tools/optipng-0.6.4-exe/LICENSE.txt +21 -0
  61. data/templates/project/files/build/tools/optipng-0.6.4-exe/optipng.exe +0 -0
  62. data/templates/project/files/build/tools/yuicompressor-2.4.2.jar +0 -0
  63. data/templates/project/files/crossdomain.xml +25 -0
  64. data/templates/project/files/favicon.ico +0 -0
  65. data/templates/project/files/gitignore.txt +32 -0
  66. data/templates/project/files/gitignore_placeholder.txt +2 -0
  67. data/templates/project/files/google.yml +22 -0
  68. data/templates/project/files/htaccess +415 -0
  69. data/templates/project/files/humans.txt +43 -0
  70. data/templates/project/files/lighttpd.conf +149 -0
  71. data/templates/project/files/mime.types +80 -0
  72. data/templates/project/files/nginx.conf +108 -0
  73. data/templates/project/files/robots.txt +5 -0
  74. data/templates/project/files/web.config +207 -0
  75. data/templates/project/handheld.scss +8 -0
  76. data/templates/project/index.html +81 -0
  77. data/templates/project/javascripts/libs/dd_belatedpng.js +13 -0
  78. data/templates/project/javascripts/libs/jquery-1.4.4.js +7179 -0
  79. data/templates/project/javascripts/libs/jquery-1.4.4.min.js +167 -0
  80. data/templates/project/javascripts/libs/modernizr-1.6.min.js +30 -0
  81. data/templates/project/javascripts/plugins.js +13 -0
  82. data/templates/project/javascripts/rails.js +156 -0
  83. data/templates/project/javascripts/script.js +26 -0
  84. data/templates/project/manifest.rb +101 -0
  85. data/templates/project/partials/_base.scss +23 -0
  86. data/templates/project/style.scss +70 -0
  87. 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
+ ?>