html5-starter 0.1.3b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ ?>