You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+40-6Lines changed: 40 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -51,13 +51,17 @@ The constructor accepts an options object that specifies additional features the
51
51
*`strict` - set to true to disable error recovery and stop on the first syntax error. Default is false.
52
52
53
53
Here's an example with some options set:
54
+
54
55
```js
55
56
var parser =newparserlib.css.Parser({ starHack:true, underscoreHack:true });
56
57
```
58
+
57
59
You can then parse a string of CSS code by passing into the `parse()` method:
60
+
58
61
```js
59
62
parser.parse(someCSSText);
60
63
```
64
+
61
65
The `parse()` method throws an error if a non-recoverable syntax error occurs, otherwise it finishes silently. This method does not return a value nor does it build up an abstract syntax tree (AST) for you, it simply parses the CSS text and fires events at important moments along the parse.
62
66
63
67
Note: The `parseStyleSheet()` method is provided for compatibility with SAC-based APIs but does the exact same thing as `parse()`.
@@ -80,9 +84,11 @@ The `parserlib.css.MediaQuery` type represents all parts of a media query. Each
80
84
*`features` - an array of `parserlib.css.MediaFeature` objects
81
85
82
86
For example, consider the following media query:
87
+
83
88
```css
84
89
only screen and (max-device-width: 768px) and (orientation:portrait)
85
90
```
91
+
86
92
A corresponding object would have the following values:
87
93
88
94
*`modifier` = "only"
@@ -93,9 +99,9 @@ A corresponding object would have the following values:
93
99
94
100
The `parserlib.css.PropertyName` type represents a property name. Each instance has the following properties:
95
101
96
-
*`hack` - if star or underscore hacks are allowed, either "*" or "_" if present (`null` if not present or hacks are not allowed)
102
+
*`hack` - if star or underscore hacks are allowed, either `*` or `_` if present (`null` if not present or hacks are not allowed)
97
103
98
-
When star hacks are allowed, the `text` property becomes the actual property name, so `*width` has `hack` equal to "*" and `text` equal to "width". If no hacks are allowed, then `*width` causes a syntax error while `_width` has `hack` equal to `null` and `text` equal to "_width".
104
+
When star hacks are allowed, the `text` property becomes the actual property name, so `*width` has `hack` equal to `*` and `text` equal to "width". If no hacks are allowed, then `*width` causes a syntax error while `_width` has `hack` equal to `null` and `text` equal to "_width".
99
105
100
106
The `parserlib.css.PropertyValue` type represents a property value. Since property values in CSS are complex, this type of object wraps the various parts into a single interface. Each instance has the following properties:
101
107
@@ -108,17 +114,21 @@ The `parserlib.css.PropertyValuePart` type represents an individual part of a pr
108
114
*`type` - the type of value part ("unknown", "dimension", "percentage", "integer", "number", "color", "uri", "string", "identifier" or "operator")
109
115
110
116
A part is considered any atomic piece of a property value not including white space. Consider the following:
117
+
111
118
```css
112
119
font: 1em/1.5em "Times New Roman", Times, serif;
113
120
```
114
-
The `PropertyName` is "font" and the `PropertyValue' represents everything after the colon. The parts are "1em" (dimension), "/" (operator), "1.5em" (dimension), "\"Times New Roman\"" (string), "," (operator), "Times" (identifier), "," (operator), and "serif" (identifier).
121
+
122
+
The `PropertyName` is "font" and the `PropertyValue` represents everything after the colon. The parts are "1em" (dimension), "/" (operator), "1.5em" (dimension), "Times New Roman" (string), "," (operator), "Times" (identifier), "," (operator), and "serif" (identifier).
115
123
116
124
### Selectors
117
125
118
126
The `parserlib.css.Selector` type represents a single selector. Each instance has a `parts` property, which is an array of `parserlib.css.SelectorPart` objects, which represent atomic parts of the selector, and `parserlib.css.Combinator` objects, which represent combinators in the selector. Consider the following selector:
127
+
119
128
```css
120
129
li.selected>a:hover
121
130
```
131
+
122
132
This selector has three parts: `li.selected`, `>`, and `a:hover`. The first part is a `SelectorPart`, the second is a `Combinator`, and the third is a `SelectorPart`. Each `SelectorPart` is made up of an optional element name followed by an ID, class, attribute condition, pseudo class, and/or pseudo element.
123
133
124
134
Each instance of `parserlib.css.SelectorPart` has an `elementName` property, which represents the element name as a `parserlib.css.SelectorSubPart` object or `null` if there isn't one, and a `modifiers` property, which is an array of `parserlib.css.SelectorSubPart` objects. Each `SelectorSubPart` object represents the smallest individual piece of a selector and has a `type` property indicating the type of subpart, "elementName", "class", "attribute", "pseudo", "id", "not". If the `type` is "not", then the `args` property contains an array of `SelectorPart` arguments that were passed to `not()`.
@@ -143,6 +153,7 @@ You should assign your event handlers before calling the `parse()` method.
143
153
### `startstylesheet` and `endstylesheet` events
144
154
145
155
The `startstylesheet` event fires just before parsing of the CSS text begins and the `endstylesheet` event fires just after all of the CSS text has been parsed. There is no additional information provided for these events. Example:
The `charset` event fires when the `@charset` directive is found in a style sheet. Since `@charset` is required to appear first in a style sheet, any other occurances cause a syntax error. The `charset` event provides an `event` object with a property called `charset`, which contains the name of the character set for the style sheet. Example:
170
+
158
171
```js
159
172
parser.addListener("charset", function(event){
160
173
console.log("Character set is "+event.charset);
161
174
});
162
175
```
176
+
163
177
### `namespace` event
164
178
165
179
The `namespace` event fires when the `@namespace` directive is found in a style sheet. The `namespace` event provides an `event` object with two properties: `prefix`, which is the namespace prefix, and `uri`, which is the namespace URI. Example:
180
+
166
181
```js
167
182
parser.addListener("namespace", function(event){
168
183
console.log("Namespace with prefix="+event.prefix+" and URI="+event.uri);
169
184
});
170
185
```
186
+
171
187
### `import` event
172
188
173
189
The `import` event fires when the `@import` directive is found in a style sheet. The `import` event provides an `event` object with two properties: `uri`, which is the URI to import, and `media`, which is an array of media queries for which this URI applies. The `media` array contains zero or more `parserlib.css.MediaQuery` objects. Example:
190
+
174
191
```js
175
192
parser.addListener("import", function(event){
176
193
console.log("Importing "+event.uri+" for media types ["+event.media+"]");
177
194
});
178
195
```
196
+
179
197
### `startfontface` and `endfontface` events
180
198
181
199
The `startfontface` event fires when `@font-face` is encountered and the `endfontface` event fires just after the closing right brace (`}`) is encountered after `@font-face`. There is no additional information available on the `event` object. Example:
The `startpage` event fires when `@page` is encountered and the `endpage` event fires just after the closing right brace (`}`) is encountered after `@page`. The `event` object has two properties: `id`, which is the page ID, and `pseudo`, which is the page pseudo class. Example:
214
+
194
215
```js
195
216
parser.addListener("startpage", function(event){
196
217
console.log("Starting page with ID="+event.id+" and pseudo="+event.pseudo);
console.log("Ending page with ID="+event.id+" and pseudo="+event.pseudo);
201
222
});
202
223
```
224
+
203
225
### `startpagemargin` and `endpagemargin` events
204
226
205
227
The `startpagemargin` event fires when a page margin directive (such as `@top-left`) is encountered and the `endfontface` event fires just after the closing right brace (`}`) is encountered after the page margin. The `event` object has a `margin` property, which contains the actual page margin encountered. Example:
The `startmedia` event fires when `@media` is encountered and the `endmedia` event fires just after the closing right brace (`}`) is encountered after `@media`. The `event` object has one property, `media`, which is an array of `parserlib.css.MediaQuery` objects. Example:
The `startkeyframes` event fires when `@keyframes` (or any vendor prefixed version) is encountered and the `endkeyframes` event fires just after the closing right brace (`}`) is encountered after `@keyframes`. The `event` object has one property, `name`, which is the name of the animation. Example:
The `startrule` event fires just after all selectors on a rule have been parsed and the `endrule` event fires just after the closing right brace (`}`) is encountered for the rule. The `event` object has one additional property, `selectors`, which is an array of `parserlib.css.Selector` objects. Example:
270
+
245
271
```js
246
272
parser.addListener("startrule", function(event){
247
273
console.log("Starting rule with "+event.selectors.length+" selector(s)");
console.log("Ending rule with selectors ["+event.selectors+"]");
272
298
});
273
299
```
300
+
274
301
### `property` event
275
302
276
303
The `property` event fires whenever a CSS property (`name:value`) is encountered, which may be inside of a rule, a media block, a page block, etc. The `event` object has three additional properties: `property`, which is the name of the property as a `parserlib.css.PropertyName` object, `value`, which is an instance of `parserlib.css.PropertyValue`(both types inherit from `parserlib.util.SyntaxUnit`), and `important`, which is a Boolean value indicating if the property is flagged with `!important`. Example:
304
+
277
305
```js
278
306
parser.addListener("property", function(event){
279
307
console.log("Property '"+event.property+"' has a value of '"+event.value+"' and "+ (event.important?"is":"isn't") +" important. ("+event.property.line+","+event.property.col+")");
280
308
});
281
309
```
310
+
282
311
### `error` event
283
312
284
313
The `error` event fires whenever a recoverable error occurs during parsing. When in strict mode, this event does not fire. The `event` object contains three additional properties: `message`, which is the error message, `line`, which is the line on which the error occurred, and `col`, which is the column on that line in which the error occurred. Example:
The CSS parser's goal is to be on-par with error recovery of CSS parsers in browsers. To that end, the following error recovery mechanisms are in place:
294
324
295
325
***Properties** - a syntactically incorrect property definition will be skipped over completely. For instance, the second property below is dropped:
326
+
296
327
```css
297
328
a:hover {
298
329
color: red;
299
330
font:: Helvetica; /*dropped!*/
300
331
text-decoration: underline;
301
332
}
302
333
```
334
+
303
335
***Selectors** - if there's a syntax error in *any* selector, the entire rule is skipped over. For instance, the following rule is completely skipped:
336
+
304
337
```css
305
338
a:hover, foo ... bar {
306
339
color: red;
307
340
font: Helvetica;
308
341
text-decoration: underline;
309
342
}
310
343
```
344
+
311
345
***@ Rules** - there are certain @ rules that are only valid in certain contexts. The parser will skip over `@charset`, `@namespace`, and `@import` if they're found anywhere other than the beginning of the input.
312
346
313
347
***Unknown @ Rules** - any @ rules that isn't recognized is automatically skipped, meaning the entire block after it is not parsed.
0 commit comments