Gathering detailed insights and metrics for parserlib
Gathering detailed insights and metrics for parserlib
Gathering detailed insights and metrics for parserlib
Gathering detailed insights and metrics for parserlib
npm install parserlib
95.9
Supply Chain
100
Quality
81.4
Maintenance
100
Vulnerability
100
License
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
287 Stars
564 Commits
82 Forks
27 Watching
2 Branches
51 Contributors
Updated on 02 Aug 2024
JavaScript (98.94%)
HTML (1.06%)
Cumulative downloads
Total Downloads
Last day
-4.7%
15,734
Compared to previous day
Last week
0.4%
83,973
Compared to previous week
Last month
5.4%
334,827
Compared to previous month
Last year
-6.9%
3,479,338
Compared to previous year
The ParserLib CSS parser is a CSS3 SAX-inspired parser written in JavaScript. It handles standard CSS syntax as well as validation (checking of property names and values) although it is not guaranteed to thoroughly validate all possible CSS properties.
The CSS parser is built for a number of different JavaScript
environments. The most recently released version of the parser
can be found in the dist
directory when you check out the
repository; run npm run build
to regenerate them from the
latest sources.
You can use the CSS parser in a Node.js
script via the standard
npm
package manager as the parserlib
package (npm install parserlib
):
1var parserlib = require("parserlib"); 2 3var parser = new parserlib.css.Parser();
Alternatively, you can copy a single file version of the parser from
dist/node-parserlib.js
to your own project, and use it as follows:
1var parserlib = require("./node-parserlib");
To use the CSS parser in a Rhino script, copy the file
dist/parserlib.js
to your project and then include it at the beginning:
1load("parserlib.js");
To use the CSS parser on an HTML page, you can either include the entire library on your page:
1<script src="parserlib.js"></script>
Or include it as its component parts, the ParserLib core and the CSS parser:
1<script src="parserlib-core.js"></script> 2<script src="parserlib-css.js"></script>
Note that parsing large JavaScript files may cause the browser to
become unresponsive. All three of these files are located in the
dist
directory.
You can create a new instance of the parser by using the following code:
1var parser = new parserlib.css.Parser();
The constructor accepts an options object that specifies additional features the parser should use. The available options are:
starHack
- set to true to treat properties with a leading asterisk as if
the asterisk wasn't there. Default is false
.underscoreHack
- set to true to treat properties with a leading underscore
as if the underscore wasn't there. Default is false
.ieFilters
- set to true to accept IE < 8 style filter
properties.
Default is false
.strict
- set to true to disable error recovery and stop on the first
syntax error. Default is false
.Here's an example with some options set:
1var parser = new parserlib.css.Parser({ starHack: true, underscoreHack: true });
You can then parse a string of CSS code by passing into the parse()
method:
1parser.parse(someCSSText);
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.
Note: The parseStyleSheet()
method is provided for compatibility with
SAC-based APIs but does the exact same thing as parse()
.
The CSS parser defines several types that inherit from parserlib.util.SyntaxUnit
.
These types are designed to give you easy access to all relevant parts of the CSS syntax.
The parserlib.css.MediaFeature
type represents a specific media feature in a
media query, such as (orientation: portrait)
or (color)
. Essentially, this
type of object represents anything enclosed in parentheses in a media query.
Object of this type have the following properties:
name
- the name of the media feature such as "orientation"value
- the value of the media feature (may be null
)The parserlib.css.MediaQuery
type represents all parts of a media query.
Each instance has the following properties:
modifier
- either "not" or "only"mediaType
- the actual media type such as "print"features
- an array of parserlib.css.MediaFeature
objectsFor example, consider the following media query:
1only screen and (max-device-width: 768px) and (orientation: portrait)
A corresponding object would have the following values:
modifier
= "only"mediaType
= "screen"features
= array of (name
="max-device-width", value
="768px") and (name
="orientation", value
="portrait")The parserlib.css.PropertyName
type represents a property name. Each instance has the following properties:
hack
- if star or underscore hacks are allowed, either *
or _
if present (null
if not present or hacks are not allowed)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
.
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:
parts
- array of PropertyValuePart
objectsThe parts
array always has at least one item.
The parserlib.css.PropertyValuePart
type represents an individual part of a
property value. Each instance has the following properties:
type
- the type of value part ("unknown", "dimension", "percentage", "integer", "number", "color", "uri", "string", "identifier" or "operator")A part is considered any atomic piece of a property value not including white space. Consider the following:
1font: 1em/1.5em "Times New Roman", Times, serif;
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).
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:
1li.selected > a:hover
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.
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()
.
Each instance of parserlib.css.Combinator
has an additional type
property that indicates
the type of combinator: "descendant", "child", "sibling", or "adjacent-sibling".
The CSS parser fires events as it parses text. The events correspond to important parts of the parsing algorithm and are designed to provide developers with all of the information necessary to create lint checkers, ASTs, and other data structures.
For many events, the event
object contains additional information. This additional
information is most frequently in the form of a parserlib.util.SyntaxUnit
object,
which has three properties:
text
- the string valueline
- the line on which this token appearedcol
- the column within the line at which this token appearedThe toString()
method for these objects is overridden to be the same value as text
,
so that you can treat the object as a string for comparison and concatenation purposes.
You should assign your event handlers before calling the parse()
method.
startstylesheet
and endstylesheet
eventsThe 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:
1parser.addListener("startstylesheet", function() { 2 console.log("Starting to parse stylesheet"); 3}); 4 5parser.addListener("endstylesheet", function() { 6 console.log("Finished parsing stylesheet"); 7});
charset
eventThe charset
event fires when the @charset
directive is found in a stylesheet.
Since @charset
is required to appear first in a stylesheet, 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 stylesheet. Example:
1parser.addListener("charset", function(event) { 2 console.log("Character set is " + event.charset); 3});
namespace
eventThe namespace
event fires when the @namespace
directive is found in a stylesheet.
The namespace
event provides an event
object with two properties: prefix
,
which is the namespace prefix, and uri
, which is the namespace URI. Example:
1parser.addListener("namespace", function(event) { 2 console.log("Namespace with prefix=" + event.prefix + " and URI=" + event.uri); 3});
import
eventThe import
event fires when the @import
directive is found in a stylesheet.
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:
1parser.addListener("import", function(event) { 2 console.log("Importing " + event.uri + " for media types [" + event.media + "]"); 3});
startfontface
and endfontface
eventsThe 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:
1parser.addListener("startfontface", function(event) { 2 console.log("Starting font face"); 3}); 4 5parser.addListener("endfontface", function(event) { 6 console.log("Ending font face"); 7});
startpage
and endpage
eventsThe 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:
1parser.addListener("startpage", function(event) { 2 console.log("Starting page with ID=" + event.id + " and pseudo=" + event.pseudo); 3}); 4 5parser.addListener("endpage", function(event) { 6 console.log("Ending page with ID=" + event.id + " and pseudo=" + event.pseudo); 7});
startpagemargin
and endpagemargin
eventsThe 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:
1parser.addListener("startpagemargin", function(event) { 2 console.log("Starting page margin " + event.margin); 3}); 4 5parser.addListener("endpagemargin", function(event) { 6 console.log("Ending page margin " + event.margin); 7});
startmedia
and endmedia
eventsThe 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:
1parser.addListener("startpagemargin", function(event) { 2 console.log("Starting page margin " + event.margin); 3}); 4 5parser.addListener("endpagemargin", function(event) { 6 console.log("Ending page margin " + event.margin); 7});
startkeyframes
and endkeyframes
eventsThe 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:
1parser.addListener("startkeyframes", function(event) { 2 console.log("Starting animation definition " + event.name); 3}); 4 5parser.addListener("endkeyframes", function(event) { 6 console.log("Ending animation definition " + event.name); 7});
startrule
and endrule
eventsThe 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:
1parser.addListener("startrule", function(event) { 2 console.log("Starting rule with " + event.selectors.length + " selector(s)"); 3 4 for (var i = 0, len = event.selectors.length; i < len; i++) { 5 var selector = event.selectors[i]; 6 7 console.log(" Selector #1 (" + selector.line + "," + selector.col + ")"); 8 9 for (var j = 0, count=selector.parts.length; j < count; j++) { 10 console.log(" Unit #" + (j + 1)); 11 12 if (selector.parts[j] instanceof parserlib.css.SelectorPart) { 13 console.log(" Element name: " + selector.parts[j].elementName); 14 15 for (var k = 0; k < selector.parts[j].modifiers.length; k++) { 16 console.log(" Modifier: " + selector.parts[j].modifiers[k]); 17 } 18 } else { 19 console.log(" Combinator: " + selector.parts[j]); 20 } 21 } 22 } 23}); 24 25parser.addListener("endrule", function(event) { 26 console.log("Ending rule with selectors [" + event.selectors + "]"); 27});
property
eventThe 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 four 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
),
important
, which is a Boolean value indicating if the property is flagged
with !important
, and invalid
which is a Boolean value indicating
whether the property value failed validation. Example:
1parser.addListener("property", function(event) { 2 console.log("Property '" + event.property + "' has a value of '" + event.value + "' and " + (event.important ? "is" : "isn't") + " important. (" + event.property.line + "," + event.property.col + ")"); 3});
error
eventThe 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:
1parser.addListener("error", function(event) { 2 console.log("Parse error: " + event.message + " (" + event.line + "," + event.col + ")", "error"); 3});
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:
1a:hover { 2 color: red; 3 font:: Helvetica; /* dropped! */ 4 text-decoration: underline; 5}
1a:hover, foo ... bar { 2 color: red; 3 font: Helvetica; 4 text-decoration: underline; 5}
@ 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.
Unknown @ Rules - any @ rules that isn't recognized is automatically skipped, meaning the entire block after it is not parsed.
You can run the tests via npm test
from the repository's root. You
may need to run npm install
first to install the necessary dependencies.
No vulnerabilities found.
Reason
all changesets reviewed
Reason
no binaries found in the repo
Reason
0 existing vulnerabilities detected
Reason
license file detected
Details
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More