},{}],11:[function(require,module,exports){
module.exports = PropertyValuePart;
var SyntaxUnit = require("../util/SyntaxUnit");
var Colors = require("./Colors");
var Parser = require("./Parser");
var Tokens = require("./Tokens");
* Represents a single part of a CSS property value, meaning that it represents
* just one part of the data between ":" and ";".
* @param {String} text The text representation of the unit.
* @param {int} line The line of text on which the unit resides.
* @param {int} col The column of text on which the unit resides.
* @namespace parserlib.css
* @class PropertyValuePart
* @extends parserlib.util.SyntaxUnit
function PropertyValuePart(text, line, col, optionalHint) {
var hint = optionalHint || {};
SyntaxUnit.call(this, text, line, col, Parser.PROPERTY_VALUE_PART_TYPE);
* Indicates the type of value unit.
//figure out what type of data it is
if (/^([+\-]?[\d\.]+)([a-z]+)$/i.test(text)) { //dimension
switch (this.units.toLowerCase()) {
this.type = "resolution";
} else if (/^([+\-]?[\d\.]+)%$/i.test(text)) { //percentage
this.type = "percentage";
} else if (/^([+\-]?\d+)$/i.test(text)) { //integer
} else if (/^([+\-]?[\d\.]+)$/i.test(text)) { //number
} else if (/^#([a-f0-9]{3,6})/i.test(text)) { //hexcolor
this.red = parseInt(temp.charAt(0)+temp.charAt(0), 16);
this.green = parseInt(temp.charAt(1)+temp.charAt(1), 16);
this.blue = parseInt(temp.charAt(2)+temp.charAt(2), 16);
this.red = parseInt(temp.substring(0, 2), 16);
this.green = parseInt(temp.substring(2, 4), 16);
this.blue = parseInt(temp.substring(4, 6), 16);
} else if (/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(text)) { //rgb() color with absolute numbers
} else if (/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)) { //rgb() color with percentages
this.red = +RegExp.$1 * 255 / 100;
this.green = +RegExp.$2 * 255 / 100;
this.blue = +RegExp.$3 * 255 / 100;
} else if (/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/i.test(text)) { //rgba() color with absolute numbers
} else if (/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)) { //rgba() color with percentages
this.red = +RegExp.$1 * 255 / 100;
this.green = +RegExp.$2 * 255 / 100;
this.blue = +RegExp.$3 * 255 / 100;
} else if (/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)) { //hsl()
this.saturation = +RegExp.$2 / 100;
this.lightness = +RegExp.$3 / 100;
} else if (/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)) { //hsla() color with percentages
this.saturation = +RegExp.$2 / 100;
this.lightness = +RegExp.$3 / 100;
} else if (/^url\(("([^\\"]|\\.)*")\)/i.test(text)) { //URI
// generated by TokenStream.readURI, so always double-quoted.
this.uri = PropertyValuePart.parseString(RegExp.$1);
} else if (/^([^\(]+)\(/i.test(text)) {
} else if (/^"([^\n\r\f\\"]|\\\r\n|\\[^\r0-9a-f]|\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)*"/i.test(text)) { //double-quoted string
this.value = PropertyValuePart.parseString(text);
} else if (/^'([^\n\r\f\\']|\\\r\n|\\[^\r0-9a-f]|\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)*'/i.test(text)) { //single-quoted string
this.value = PropertyValuePart.parseString(text);
} else if (Colors[text.toLowerCase()]) { //named color
temp = Colors[text.toLowerCase()].substring(1);
this.red = parseInt(temp.substring(0, 2), 16);
this.green = parseInt(temp.substring(2, 4), 16);
this.blue = parseInt(temp.substring(4, 6), 16);
} else if (/^[,\/]$/.test(text)) {
} else if (/^-?[a-z_\u00A0-\uFFFF][a-z0-9\-_\u00A0-\uFFFF]*$/i.test(text)) {
this.type = "identifier";
// There can be ambiguity with escape sequences in identifiers, as
// well as with "color" parts which are also "identifiers", so record
// an explicit hint when the token generating this PropertyValuePart
this.wasIdent = Boolean(hint.ident);
PropertyValuePart.prototype = new SyntaxUnit();
PropertyValuePart.prototype.constructor = PropertyValuePart;
* Helper method to parse a CSS string.
PropertyValuePart.parseString = function(str) {
str = str.slice(1, -1); // Strip surrounding single/double quotes
var replacer = function(match, esc) {
if (/^(\n|\r\n|\r|\f)$/.test(esc)) {
var m = /^[0-9a-f]{1,6}/i.exec(esc);
var codePoint = parseInt(m[0], 16);
if (String.fromCodePoint) {
return String.fromCodePoint(codePoint);
// XXX No support for surrogates on old JavaScript engines.
return String.fromCharCode(codePoint);
return str.replace(/\\(\r\n|[^\r0-9a-f]|[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)/ig,
* Helper method to serialize a CSS string.
PropertyValuePart.serializeString = function(value) {
var replacer = function(match, c) {
var cp = String.codePointAt ? String.codePointAt(0) :
// We only escape non-surrogate chars, so using charCodeAt
return "\\" + cp.toString(16) + " ";
return "\"" + value.replace(/["\r\n\f]/g, replacer) + "\"";
* Create a new syntax unit based solely on the given token.
* Convenience method for creating a new syntax unit when
* it represents a single token instead of multiple.
* @param {Object} token The token object to represent.
* @return {parserlib.css.PropertyValuePart} The object representing the token.
PropertyValuePart.fromToken = function(token) {
var part = new PropertyValuePart(token.value, token.startLine, token.startCol, {
// Tokens can have escaped characters that would fool the type
// identification in the PropertyValuePart constructor, so pass
// in a hint if this was an identifier.
ident: token.type === Tokens.IDENT
},{"../util/SyntaxUnit":26,"./Colors":1,"./Parser":6,"./Tokens":18}],12:[function(require,module,exports){
var Pseudos = module.exports = {
Pseudos.isElement = function(pseudo) {
return pseudo.indexOf("::") === 0 || Pseudos[pseudo.toLowerCase()] === Pseudos.ELEMENT;
},{}],13:[function(require,module,exports){
module.exports = Selector;
var SyntaxUnit = require("../util/SyntaxUnit");
var Parser = require("./Parser");
var Specificity = require("./Specificity");
* Represents an entire single selector, including all parts but not
* including multiple selectors (those separated by commas).
* @namespace parserlib.css
* @extends parserlib.util.SyntaxUnit
* @param {Array} parts Array of selectors parts making up this selector.
* @param {int} line The line of text on which the unit resides.
* @param {int} col The column of text on which the unit resides.
function Selector(parts, line, col) {
SyntaxUnit.call(this, parts.join(" "), line, col, Parser.SELECTOR_TYPE);
* The parts that make up the selector.
* The specificity of the selector.
* @type parserlib.css.Specificity
this.specificity = Specificity.calculate(this);
Selector.prototype = new SyntaxUnit();
Selector.prototype.constructor = Selector;
},{"../util/SyntaxUnit":26,"./Parser":6,"./Specificity":16}],14:[function(require,module,exports){
module.exports = SelectorPart;
var SyntaxUnit = require("../util/SyntaxUnit");
var Parser = require("./Parser");
* Represents a single part of a selector string, meaning a single set of
* element name and modifiers. This does not include combinators such as
* @namespace parserlib.css
* @extends parserlib.util.SyntaxUnit
* @param {String} elementName The element name in the selector or null
* if there is no element name.
* @param {Array} modifiers Array of individual modifiers for the element.
* May be empty if there are none.
* @param {String} text The text representation of the unit.
* @param {int} line The line of text on which the unit resides.
* @param {int} col The column of text on which the unit resides.
function SelectorPart(elementName, modifiers, text, line, col) {
SyntaxUnit.call(this, text, line, col, Parser.SELECTOR_PART_TYPE);
* The tag name of the element to which this part
* of the selector affects.
this.elementName = elementName;
* The parts that come after the element name, such as class names, IDs,
* pseudo classes/elements, etc.
this.modifiers = modifiers;
SelectorPart.prototype = new SyntaxUnit();
SelectorPart.prototype.constructor = SelectorPart;
},{"../util/SyntaxUnit":26,"./Parser":6}],15:[function(require,module,exports){
module.exports = SelectorSubPart;
var SyntaxUnit = require("../util/SyntaxUnit");
var Parser = require("./Parser");
* Represents a selector modifier string, meaning a class name, element name,
* element ID, pseudo rule, etc.
* @namespace parserlib.css
* @extends parserlib.util.SyntaxUnit
* @param {String} text The text representation of the unit.
* @param {String} type The type of selector modifier.
* @param {int} line The line of text on which the unit resides.
* @param {int} col The column of text on which the unit resides.
function SelectorSubPart(text, type, line, col) {
SyntaxUnit.call(this, text, line, col, Parser.SELECTOR_SUB_PART_TYPE);
* Some subparts have arguments, this represents them.
SelectorSubPart.prototype = new SyntaxUnit();
SelectorSubPart.prototype.constructor = SelectorSubPart;
},{"../util/SyntaxUnit":26,"./Parser":6}],16:[function(require,module,exports){
module.exports = Specificity;
var Pseudos = require("./Pseudos");
var SelectorPart = require("./SelectorPart");
* Represents a selector's specificity.
* @namespace parserlib.css
* @param {int} a Should be 1 for inline styles, zero for stylesheet styles
* @param {int} b Number of ID selectors
* @param {int} c Number of classes and pseudo classes
* @param {int} d Number of element names and pseudo elements
function Specificity(a, b, c, d) {
Specificity.prototype = {
constructor: Specificity,
* Compare this specificity to another.
* @param {Specificity} other The other specificity to compare to.
* @return {int} -1 if the other specificity is larger, 1 if smaller, 0 if equal.
compare: function(other) {
var comps = ["a", "b", "c", "d"],
for (i=0, len=comps.length; i < len; i++) {
if (this[comps[i]] < other[comps[i]]) {
} else if (this[comps[i]] > other[comps[i]]) {
* Creates a numeric value for the specificity.
* @return {int} The numeric value for the specificity.
return (this.a * 1000) + (this.b * 100) + (this.c * 10) + this.d;
* Returns a string representation for specificity.
* @return {String} The string representation of specificity.
return this.a + "," + this.b + "," + this.c + "," + this.d;
* Calculates the specificity of the given selector.
* @param {parserlib.css.Selector} The selector to calculate specificity for.
* @return {parserlib.css.Specificity} The specificity of the selector.
Specificity.calculate = function(selector) {
function updateValues(part) {
elementName = part.elementName ? part.elementName.text : "",
if (elementName && elementName.charAt(elementName.length-1) !== "*") {