package/lib/clone.js000644 0000003603 3560116604 011466 0ustar00000000 000000 //.CommonJS var CSSOM = { CSSStyleSheet: require("./CSSStyleSheet").CSSStyleSheet, CSSStyleRule: require("./CSSStyleRule").CSSStyleRule, CSSMediaRule: require("./CSSMediaRule").CSSMediaRule, CSSSupportsRule: require("./CSSSupportsRule").CSSSupportsRule, CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration, CSSKeyframeRule: require('./CSSKeyframeRule').CSSKeyframeRule, CSSKeyframesRule: require('./CSSKeyframesRule').CSSKeyframesRule }; ///CommonJS /** * Produces a deep copy of stylesheet — the instance variables of stylesheet are copied recursively. * @param {CSSStyleSheet|CSSOM.CSSStyleSheet} stylesheet * @nosideeffects * @return {CSSOM.CSSStyleSheet} */ CSSOM.clone = function clone(stylesheet) { var cloned = new CSSOM.CSSStyleSheet(); var rules = stylesheet.cssRules; if (!rules) { return cloned; } for (var i = 0, rulesLength = rules.length; i < rulesLength; i++) { var rule = rules[i]; var ruleClone = cloned.cssRules[i] = new rule.constructor(); var style = rule.style; if (style) { var styleClone = ruleClone.style = new CSSOM.CSSStyleDeclaration(); for (var j = 0, styleLength = style.length; j < styleLength; j++) { var name = styleClone[j] = style[j]; styleClone[name] = style[name]; styleClone._importants[name] = style.getPropertyPriority(name); } styleClone.length = style.length; } if (rule.hasOwnProperty('keyText')) { ruleClone.keyText = rule.keyText; } if (rule.hasOwnProperty('selectorText')) { ruleClone.selectorText = rule.selectorText; } if (rule.hasOwnProperty('mediaText')) { ruleClone.mediaText = rule.mediaText; } if (rule.hasOwnProperty('conditionText')) { ruleClone.conditionText = rule.conditionText; } if (rule.hasOwnProperty('cssRules')) { ruleClone.cssRules = clone(rule).cssRules; } } return cloned; }; //.CommonJS exports.clone = CSSOM.clone; ///CommonJS package/lib/CSSDocumentRule.js000644 0000002146 3560116604 013346 0ustar00000000 000000 //.CommonJS var CSSOM = { CSSRule: require("./CSSRule").CSSRule, MatcherList: require("./MatcherList").MatcherList }; ///CommonJS /** * @constructor * @see https://developer.mozilla.org/en/CSS/@-moz-document */ CSSOM.CSSDocumentRule = function CSSDocumentRule() { CSSOM.CSSRule.call(this); this.matcher = new CSSOM.MatcherList(); this.cssRules = []; }; CSSOM.CSSDocumentRule.prototype = new CSSOM.CSSRule(); CSSOM.CSSDocumentRule.prototype.constructor = CSSOM.CSSDocumentRule; CSSOM.CSSDocumentRule.prototype.type = 10; //FIXME //CSSOM.CSSDocumentRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule; //CSSOM.CSSDocumentRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule; Object.defineProperty(CSSOM.CSSDocumentRule.prototype, "cssText", { get: function() { var cssTexts = []; for (var i=0, length=this.cssRules.length; i < length; i++) { cssTexts.push(this.cssRules[i].cssText); } return "@-moz-document " + this.matcher.matcherText + " {" + cssTexts.join("") + "}"; } }); //.CommonJS exports.CSSDocumentRule = CSSOM.CSSDocumentRule; ///CommonJS package/lib/CSSFontFaceRule.js000644 0000002051 3560116604 013250 0ustar00000000 000000 //.CommonJS var CSSOM = { CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration, CSSRule: require("./CSSRule").CSSRule }; ///CommonJS /** * @constructor * @see http://dev.w3.org/csswg/cssom/#css-font-face-rule */ CSSOM.CSSFontFaceRule = function CSSFontFaceRule() { CSSOM.CSSRule.call(this); this.style = new CSSOM.CSSStyleDeclaration(); this.style.parentRule = this; }; CSSOM.CSSFontFaceRule.prototype = new CSSOM.CSSRule(); CSSOM.CSSFontFaceRule.prototype.constructor = CSSOM.CSSFontFaceRule; CSSOM.CSSFontFaceRule.prototype.type = 5; //FIXME //CSSOM.CSSFontFaceRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule; //CSSOM.CSSFontFaceRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule; // http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSFontFaceRule.cpp Object.defineProperty(CSSOM.CSSFontFaceRule.prototype, "cssText", { get: function() { return "@font-face {" + this.style.cssText + "}"; } }); //.CommonJS exports.CSSFontFaceRule = CSSOM.CSSFontFaceRule; ///CommonJS package/lib/CSSHostRule.js000644 0000001621 3560116604 012502 0ustar00000000 000000 //.CommonJS var CSSOM = { CSSRule: require("./CSSRule").CSSRule }; ///CommonJS /** * @constructor * @see http://www.w3.org/TR/shadow-dom/#host-at-rule */ CSSOM.CSSHostRule = function CSSHostRule() { CSSOM.CSSRule.call(this); this.cssRules = []; }; CSSOM.CSSHostRule.prototype = new CSSOM.CSSRule(); CSSOM.CSSHostRule.prototype.constructor = CSSOM.CSSHostRule; CSSOM.CSSHostRule.prototype.type = 1001; //FIXME //CSSOM.CSSHostRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule; //CSSOM.CSSHostRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule; Object.defineProperty(CSSOM.CSSHostRule.prototype, "cssText", { get: function() { var cssTexts = []; for (var i=0, length=this.cssRules.length; i < length; i++) { cssTexts.push(this.cssRules[i].cssText); } return "@host {" + cssTexts.join("") + "}"; } }); //.CommonJS exports.CSSHostRule = CSSOM.CSSHostRule; ///CommonJS package/lib/CSSImportRule.js000644 0000006371 3560116604 013046 0ustar00000000 000000 //.CommonJS var CSSOM = { CSSRule: require("./CSSRule").CSSRule, CSSStyleSheet: require("./CSSStyleSheet").CSSStyleSheet, MediaList: require("./MediaList").MediaList }; ///CommonJS /** * @constructor * @see http://dev.w3.org/csswg/cssom/#cssimportrule * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSImportRule */ CSSOM.CSSImportRule = function CSSImportRule() { CSSOM.CSSRule.call(this); this.href = ""; this.media = new CSSOM.MediaList(); this.styleSheet = new CSSOM.CSSStyleSheet(); }; CSSOM.CSSImportRule.prototype = new CSSOM.CSSRule(); CSSOM.CSSImportRule.prototype.constructor = CSSOM.CSSImportRule; CSSOM.CSSImportRule.prototype.type = 3; Object.defineProperty(CSSOM.CSSImportRule.prototype, "cssText", { get: function() { var mediaText = this.media.mediaText; return "@import url(" + this.href + ")" + (mediaText ? " " + mediaText : "") + ";"; }, set: function(cssText) { var i = 0; /** * @import url(partial.css) screen, handheld; * || | * after-import media * | * url */ var state = ''; var buffer = ''; var index; for (var character; (character = cssText.charAt(i)); i++) { switch (character) { case ' ': case '\t': case '\r': case '\n': case '\f': if (state === 'after-import') { state = 'url'; } else { buffer += character; } break; case '@': if (!state && cssText.indexOf('@import', i) === i) { state = 'after-import'; i += 'import'.length; buffer = ''; } break; case 'u': if (state === 'url' && cssText.indexOf('url(', i) === i) { index = cssText.indexOf(')', i + 1); if (index === -1) { throw i + ': ")" not found'; } i += 'url('.length; var url = cssText.slice(i, index); if (url[0] === url[url.length - 1]) { if (url[0] === '"' || url[0] === "'") { url = url.slice(1, -1); } } this.href = url; i = index; state = 'media'; } break; case '"': if (state === 'url') { index = cssText.indexOf('"', i + 1); if (!index) { throw i + ": '\"' not found"; } this.href = cssText.slice(i + 1, index); i = index; state = 'media'; } break; case "'": if (state === 'url') { index = cssText.indexOf("'", i + 1); if (!index) { throw i + ': "\'" not found'; } this.href = cssText.slice(i + 1, index); i = index; state = 'media'; } break; case ';': if (state === 'media') { if (buffer) { this.media.mediaText = buffer.trim(); } } break; default: if (state === 'media') { buffer += character; } break; } } } }); //.CommonJS exports.CSSImportRule = CSSOM.CSSImportRule; ///CommonJS package/lib/CSSKeyframeRule.js000644 0000002113 3560116604 013325 0ustar00000000 000000 //.CommonJS var CSSOM = { CSSRule: require("./CSSRule").CSSRule, CSSStyleDeclaration: require('./CSSStyleDeclaration').CSSStyleDeclaration }; ///CommonJS /** * @constructor * @see http://www.w3.org/TR/css3-animations/#DOM-CSSKeyframeRule */ CSSOM.CSSKeyframeRule = function CSSKeyframeRule() { CSSOM.CSSRule.call(this); this.keyText = ''; this.style = new CSSOM.CSSStyleDeclaration(); this.style.parentRule = this; }; CSSOM.CSSKeyframeRule.prototype = new CSSOM.CSSRule(); CSSOM.CSSKeyframeRule.prototype.constructor = CSSOM.CSSKeyframeRule; CSSOM.CSSKeyframeRule.prototype.type = 8; //FIXME //CSSOM.CSSKeyframeRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule; //CSSOM.CSSKeyframeRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule; // http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSKeyframeRule.cpp Object.defineProperty(CSSOM.CSSKeyframeRule.prototype, "cssText", { get: function() { return this.keyText + " {" + this.style.cssText + "} "; } }); //.CommonJS exports.CSSKeyframeRule = CSSOM.CSSKeyframeRule; ///CommonJS package/lib/CSSKeyframesRule.js000644 0000002231 3560116604 013511 0ustar00000000 000000 //.CommonJS var CSSOM = { CSSRule: require("./CSSRule").CSSRule }; ///CommonJS /** * @constructor * @see http://www.w3.org/TR/css3-animations/#DOM-CSSKeyframesRule */ CSSOM.CSSKeyframesRule = function CSSKeyframesRule() { CSSOM.CSSRule.call(this); this.name = ''; this.cssRules = []; }; CSSOM.CSSKeyframesRule.prototype = new CSSOM.CSSRule(); CSSOM.CSSKeyframesRule.prototype.constructor = CSSOM.CSSKeyframesRule; CSSOM.CSSKeyframesRule.prototype.type = 7; //FIXME //CSSOM.CSSKeyframesRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule; //CSSOM.CSSKeyframesRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule; // http://www.opensource.apple.com/source/WebCore/WebCore-955.66.1/css/WebKitCSSKeyframesRule.cpp Object.defineProperty(CSSOM.CSSKeyframesRule.prototype, "cssText", { get: function() { var cssTexts = []; for (var i=0, length=this.cssRules.length; i < length; i++) { cssTexts.push(" " + this.cssRules[i].cssText); } return "@" + (this._vendorPrefix || '') + "keyframes " + this.name + " { \n" + cssTexts.join("\n") + "\n}"; } }); //.CommonJS exports.CSSKeyframesRule = CSSOM.CSSKeyframesRule; ///CommonJS package/lib/CSSMediaRule.js000644 0000002260 3560116604 012604 0ustar00000000 000000 //.CommonJS var CSSOM = { CSSRule: require("./CSSRule").CSSRule, MediaList: require("./MediaList").MediaList }; ///CommonJS /** * @constructor * @see http://dev.w3.org/csswg/cssom/#cssmediarule * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSMediaRule */ CSSOM.CSSMediaRule = function CSSMediaRule() { CSSOM.CSSRule.call(this); this.media = new CSSOM.MediaList(); this.cssRules = []; }; CSSOM.CSSMediaRule.prototype = new CSSOM.CSSRule(); CSSOM.CSSMediaRule.prototype.constructor = CSSOM.CSSMediaRule; CSSOM.CSSMediaRule.prototype.type = 4; //FIXME //CSSOM.CSSMediaRule.prototype.insertRule = CSSStyleSheet.prototype.insertRule; //CSSOM.CSSMediaRule.prototype.deleteRule = CSSStyleSheet.prototype.deleteRule; // http://opensource.apple.com/source/WebCore/WebCore-658.28/css/CSSMediaRule.cpp Object.defineProperty(CSSOM.CSSMediaRule.prototype, "cssText", { get: function() { var cssTexts = []; for (var i=0, length=this.cssRules.length; i < length; i++) { cssTexts.push(this.cssRules[i].cssText); } return "@media " + this.media.mediaText + " {" + cssTexts.join("") + "}"; } }); //.CommonJS exports.CSSMediaRule = CSSOM.CSSMediaRule; ///CommonJS package/lib/CSSOM.js000644 0000000022 3560116604 011242 0ustar00000000 000000 var CSSOM = {}; package/lib/CSSRule.js000644 0000002034 3560116604 011643 0ustar00000000 000000 //.CommonJS var CSSOM = {}; ///CommonJS /** * @constructor * @see http://dev.w3.org/csswg/cssom/#the-cssrule-interface * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSRule */ CSSOM.CSSRule = function CSSRule() { this.parentRule = null; this.parentStyleSheet = null; }; CSSOM.CSSRule.UNKNOWN_RULE = 0; // obsolete CSSOM.CSSRule.STYLE_RULE = 1; CSSOM.CSSRule.CHARSET_RULE = 2; // obsolete CSSOM.CSSRule.IMPORT_RULE = 3; CSSOM.CSSRule.MEDIA_RULE = 4; CSSOM.CSSRule.FONT_FACE_RULE = 5; CSSOM.CSSRule.PAGE_RULE = 6; CSSOM.CSSRule.KEYFRAMES_RULE = 7; CSSOM.CSSRule.KEYFRAME_RULE = 8; CSSOM.CSSRule.MARGIN_RULE = 9; CSSOM.CSSRule.NAMESPACE_RULE = 10; CSSOM.CSSRule.COUNTER_STYLE_RULE = 11; CSSOM.CSSRule.SUPPORTS_RULE = 12; CSSOM.CSSRule.DOCUMENT_RULE = 13; CSSOM.CSSRule.FONT_FEATURE_VALUES_RULE = 14; CSSOM.CSSRule.VIEWPORT_RULE = 15; CSSOM.CSSRule.REGION_STYLE_RULE = 16; CSSOM.CSSRule.prototype = { constructor: CSSOM.CSSRule //FIXME }; //.CommonJS exports.CSSRule = CSSOM.CSSRule; ///CommonJS package/lib/CSSStyleDeclaration.js000644 0000007006 3560116604 014206 0ustar00000000 000000 //.CommonJS var CSSOM = {}; ///CommonJS /** * @constructor * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration */ CSSOM.CSSStyleDeclaration = function CSSStyleDeclaration(){ this.length = 0; this.parentRule = null; // NON-STANDARD this._importants = {}; }; CSSOM.CSSStyleDeclaration.prototype = { constructor: CSSOM.CSSStyleDeclaration, /** * * @param {string} name * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-getPropertyValue * @return {string} the value of the property if it has been explicitly set for this declaration block. * Returns the empty string if the property has not been set. */ getPropertyValue: function(name) { return this[name] || ""; }, /** * * @param {string} name * @param {string} value * @param {string} [priority=null] "important" or null * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-setProperty */ setProperty: function(name, value, priority) { if (this[name]) { // Property already exist. Overwrite it. var index = Array.prototype.indexOf.call(this, name); if (index < 0) { this[this.length] = name; this.length++; } } else { // New property. this[this.length] = name; this.length++; } this[name] = value + ""; this._importants[name] = priority; }, /** * * @param {string} name * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration-removeProperty * @return {string} the value of the property if it has been explicitly set for this declaration block. * Returns the empty string if the property has not been set or the property name does not correspond to a known CSS property. */ removeProperty: function(name) { if (!(name in this)) { return ""; } var index = Array.prototype.indexOf.call(this, name); if (index < 0) { return ""; } var prevValue = this[name]; this[name] = ""; // That's what WebKit and Opera do Array.prototype.splice.call(this, index, 1); // That's what Firefox does //this[index] = "" return prevValue; }, getPropertyCSSValue: function() { //FIXME }, /** * * @param {String} name */ getPropertyPriority: function(name) { return this._importants[name] || ""; }, /** * element.style.overflow = "auto" * element.style.getPropertyShorthand("overflow-x") * -> "overflow" */ getPropertyShorthand: function() { //FIXME }, isPropertyImplicit: function() { //FIXME }, // Doesn't work in IE < 9 get cssText(){ var properties = []; for (var i=0, length=this.length; i < length; ++i) { var name = this[i]; var value = this.getPropertyValue(name); var priority = this.getPropertyPriority(name); if (priority) { priority = " !" + priority; } properties[i] = name + ": " + value + priority + ";"; } return properties.join(" "); }, set cssText(text){ var i, name; for (i = this.length; i--;) { name = this[i]; this[name] = ""; } Array.prototype.splice.call(this, 0, this.length); this._importants = {}; var dummyRule = CSSOM.parse('#bogus{' + text + '}').cssRules[0].style; var length = dummyRule.length; for (i = 0; i < length; ++i) { name = dummyRule[i]; this.setProperty(dummyRule[i], dummyRule.getPropertyValue(name), dummyRule.getPropertyPriority(name)); } } }; //.CommonJS exports.CSSStyleDeclaration = CSSOM.CSSStyleDeclaration; CSSOM.parse = require('./parse').parse; // Cannot be included sooner due to the mutual dependency between parse.js and CSSStyleDeclaration.js ///CommonJS package/lib/CSSStyleRule.js000644 0000007041 3560116604 012667 0ustar00000000 000000 //.CommonJS var CSSOM = { CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration, CSSRule: require("./CSSRule").CSSRule }; ///CommonJS /** * @constructor * @see http://dev.w3.org/csswg/cssom/#cssstylerule * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleRule */ CSSOM.CSSStyleRule = function CSSStyleRule() { CSSOM.CSSRule.call(this); this.selectorText = ""; this.style = new CSSOM.CSSStyleDeclaration(); this.style.parentRule = this; }; CSSOM.CSSStyleRule.prototype = new CSSOM.CSSRule(); CSSOM.CSSStyleRule.prototype.constructor = CSSOM.CSSStyleRule; CSSOM.CSSStyleRule.prototype.type = 1; Object.defineProperty(CSSOM.CSSStyleRule.prototype, "cssText", { get: function() { var text; if (this.selectorText) { text = this.selectorText + " {" + this.style.cssText + "}"; } else { text = ""; } return text; }, set: function(cssText) { var rule = CSSOM.CSSStyleRule.parse(cssText); this.style = rule.style; this.selectorText = rule.selectorText; } }); /** * NON-STANDARD * lightweight version of parse.js. * @param {string} ruleText * @return CSSStyleRule */ CSSOM.CSSStyleRule.parse = function(ruleText) { var i = 0; var state = "selector"; var index; var j = i; var buffer = ""; var SIGNIFICANT_WHITESPACE = { "selector": true, "value": true }; var styleRule = new CSSOM.CSSStyleRule(); var name, priority=""; for (var character; (character = ruleText.charAt(i)); i++) { switch (character) { case " ": case "\t": case "\r": case "\n": case "\f": if (SIGNIFICANT_WHITESPACE[state]) { // Squash 2 or more white-spaces in the row into 1 switch (ruleText.charAt(i - 1)) { case " ": case "\t": case "\r": case "\n": case "\f": break; default: buffer += " "; break; } } break; // String case '"': j = i + 1; index = ruleText.indexOf('"', j) + 1; if (!index) { throw '" is missing'; } buffer += ruleText.slice(i, index); i = index - 1; break; case "'": j = i + 1; index = ruleText.indexOf("'", j) + 1; if (!index) { throw "' is missing"; } buffer += ruleText.slice(i, index); i = index - 1; break; // Comment case "/": if (ruleText.charAt(i + 1) === "*") { i += 2; index = ruleText.indexOf("*/", i); if (index === -1) { throw new SyntaxError("Missing */"); } else { i = index + 1; } } else { buffer += character; } break; case "{": if (state === "selector") { styleRule.selectorText = buffer.trim(); buffer = ""; state = "name"; } break; case ":": if (state === "name") { name = buffer.trim(); buffer = ""; state = "value"; } else { buffer += character; } break; case "!": if (state === "value" && ruleText.indexOf("!important", i) === i) { priority = "important"; i += "important".length; } else { buffer += character; } break; case ";": if (state === "value") { styleRule.style.setProperty(name, buffer.trim(), priority); priority = ""; buffer = ""; state = "name"; } else { buffer += character; } break; case "}": if (state === "value") { styleRule.style.setProperty(name, buffer.trim(), priority); priority = ""; buffer = ""; } else if (state === "name") { break; } else { buffer += character; } state = "selector"; break; default: buffer += character; break; } } return styleRule; }; //.CommonJS exports.CSSStyleRule = CSSOM.CSSStyleRule; ///CommonJS package/lib/CSSStyleSheet.js000644 0000004566 3560116604 013041 0ustar00000000 000000 //.CommonJS var CSSOM = { StyleSheet: require("./StyleSheet").StyleSheet, CSSStyleRule: require("./CSSStyleRule").CSSStyleRule }; ///CommonJS /** * @constructor * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleSheet */ CSSOM.CSSStyleSheet = function CSSStyleSheet() { CSSOM.StyleSheet.call(this); this.cssRules = []; }; CSSOM.CSSStyleSheet.prototype = new CSSOM.StyleSheet(); CSSOM.CSSStyleSheet.prototype.constructor = CSSOM.CSSStyleSheet; /** * Used to insert a new rule into the style sheet. The new rule now becomes part of the cascade. * * sheet = new Sheet("body {margin: 0}") * sheet.toString() * -> "body{margin:0;}" * sheet.insertRule("img {border: none}", 0) * -> 0 * sheet.toString() * -> "img{border:none;}body{margin:0;}" * * @param {string} rule * @param {number} index * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleSheet-insertRule * @return {number} The index within the style sheet's rule collection of the newly inserted rule. */ CSSOM.CSSStyleSheet.prototype.insertRule = function(rule, index) { if (index < 0 || index > this.cssRules.length) { throw new RangeError("INDEX_SIZE_ERR"); } var cssRule = CSSOM.parse(rule).cssRules[0]; cssRule.parentStyleSheet = this; this.cssRules.splice(index, 0, cssRule); return index; }; /** * Used to delete a rule from the style sheet. * * sheet = new Sheet("img{border:none} body{margin:0}") * sheet.toString() * -> "img{border:none;}body{margin:0;}" * sheet.deleteRule(0) * sheet.toString() * -> "body{margin:0;}" * * @param {number} index within the style sheet's rule list of the rule to remove. * @see http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleSheet-deleteRule */ CSSOM.CSSStyleSheet.prototype.deleteRule = function(index) { if (index < 0 || index >= this.cssRules.length) { throw new RangeError("INDEX_SIZE_ERR"); } this.cssRules.splice(index, 1); }; /** * NON-STANDARD * @return {string} serialize stylesheet */ CSSOM.CSSStyleSheet.prototype.toString = function() { var result = ""; var rules = this.cssRules; for (var i=0; i 1000 ? '1000px' : 'auto'); * } */ CSSOM.CSSValueExpression.prototype.parse = function() { var token = this._token, idx = this._idx; var character = '', expression = '', error = '', info, paren = []; for (; ; ++idx) { character = token.charAt(idx); // end of token if (character === '') { error = 'css expression error: unfinished expression!'; break; } switch(character) { case '(': paren.push(character); expression += character; break; case ')': paren.pop(character); expression += character; break; case '/': if ((info = this._parseJSComment(token, idx))) { // comment? if (info.error) { error = 'css expression error: unfinished comment in expression!'; } else { idx = info.idx; // ignore the comment } } else if ((info = this._parseJSRexExp(token, idx))) { // regexp idx = info.idx; expression += info.text; } else { // other expression += character; } break; case "'": case '"': info = this._parseJSString(token, idx, character); if (info) { // string idx = info.idx; expression += info.text; } else { expression += character; } break; default: expression += character; break; } if (error) { break; } // end of expression if (paren.length === 0) { break; } } var ret; if (error) { ret = { error: error }; } else { ret = { idx: idx, expression: expression }; } return ret; }; /** * * @return {Object|false} * - idx: * - text: * or * - error: * or * false * */ CSSOM.CSSValueExpression.prototype._parseJSComment = function(token, idx) { var nextChar = token.charAt(idx + 1), text; if (nextChar === '/' || nextChar === '*') { var startIdx = idx, endIdx, commentEndChar; if (nextChar === '/') { // line comment commentEndChar = '\n'; } else if (nextChar === '*') { // block comment commentEndChar = '*/'; } endIdx = token.indexOf(commentEndChar, startIdx + 1 + 1); if (endIdx !== -1) { endIdx = endIdx + commentEndChar.length - 1; text = token.substring(idx, endIdx + 1); return { idx: endIdx, text: text }; } else { var error = 'css expression error: unfinished comment in expression!'; return { error: error }; } } else { return false; } }; /** * * @return {Object|false} * - idx: * - text: * or * false * */ CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep) { var endIdx = this._findMatchedIdx(token, idx, sep), text; if (endIdx === -1) { return false; } else { text = token.substring(idx, endIdx + sep.length); return { idx: endIdx, text: text }; } }; /** * parse regexp in css expression * * @return {Object|false} * - idx: * - regExp: * or * false */ /* all legal RegExp /a/ (/a/) [/a/] [12, /a/] !/a/ +/a/ -/a/ * /a/ / /a/ %/a/ ===/a/ !==/a/ ==/a/ !=/a/ >/a/ >=/a/ >/a/ >>>/a/ &&/a/ ||/a/ ?/a/ =/a/ ,/a/ delete /a/ in /a/ instanceof /a/ new /a/ typeof /a/ void /a/ */ CSSOM.CSSValueExpression.prototype._parseJSRexExp = function(token, idx) { var before = token.substring(0, idx).replace(/\s+$/, ""), legalRegx = [ /^$/, /\($/, /\[$/, /\!$/, /\+$/, /\-$/, /\*$/, /\/\s+/, /\%$/, /\=$/, /\>$/, /<$/, /\&$/, /\|$/, /\^$/, /\~$/, /\?$/, /\,$/, /delete$/, /in$/, /instanceof$/, /new$/, /typeof$/, /void$/ ]; var isLegal = legalRegx.some(function(reg) { return reg.test(before); }); if (!isLegal) { return false; } else { var sep = '/'; // same logic as string return this._parseJSString(token, idx, sep); } }; /** * * find next sep(same line) index in `token` * * @return {Number} * */ CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep) { var startIdx = idx, endIdx; var NOT_FOUND = -1; while(true) { endIdx = token.indexOf(sep, startIdx + 1); if (endIdx === -1) { // not found endIdx = NOT_FOUND; break; } else { var text = token.substring(idx + 1, endIdx), matched = text.match(/\\+$/); if (!matched || matched[0] % 2 === 0) { // not escaped break; } else { startIdx = endIdx; } } } // boundary must be in the same line(js sting or regexp) var nextNewLineIdx = token.indexOf('\n', idx + 1); if (nextNewLineIdx < endIdx) { endIdx = NOT_FOUND; } return endIdx; }; //.CommonJS exports.CSSValueExpression = CSSOM.CSSValueExpression; ///CommonJS package/lib/index.js000644 0000002277 3560116604 011503 0ustar00000000 000000 'use strict'; exports.CSSStyleDeclaration = require('./CSSStyleDeclaration').CSSStyleDeclaration; exports.CSSRule = require('./CSSRule').CSSRule; exports.CSSStyleRule = require('./CSSStyleRule').CSSStyleRule; exports.MediaList = require('./MediaList').MediaList; exports.CSSMediaRule = require('./CSSMediaRule').CSSMediaRule; exports.CSSSupportsRule = require('./CSSSupportsRule').CSSSupportsRule; exports.CSSImportRule = require('./CSSImportRule').CSSImportRule; exports.CSSFontFaceRule = require('./CSSFontFaceRule').CSSFontFaceRule; exports.CSSHostRule = require('./CSSHostRule').CSSHostRule; exports.StyleSheet = require('./StyleSheet').StyleSheet; exports.CSSStyleSheet = require('./CSSStyleSheet').CSSStyleSheet; exports.CSSKeyframesRule = require('./CSSKeyframesRule').CSSKeyframesRule; exports.CSSKeyframeRule = require('./CSSKeyframeRule').CSSKeyframeRule; exports.MatcherList = require('./MatcherList').MatcherList; exports.CSSDocumentRule = require('./CSSDocumentRule').CSSDocumentRule; exports.CSSValue = require('./CSSValue').CSSValue; exports.CSSValueExpression = require('./CSSValueExpression').CSSValueExpression; exports.parse = require('./parse').parse; exports.clone = require('./clone').clone; package/lib/MatcherList.js000644 0000002474 3560116604 012612 0ustar00000000 000000 //.CommonJS var CSSOM = {}; ///CommonJS /** * @constructor * @see https://developer.mozilla.org/en/CSS/@-moz-document */ CSSOM.MatcherList = function MatcherList(){ this.length = 0; }; CSSOM.MatcherList.prototype = { constructor: CSSOM.MatcherList, /** * @return {string} */ get matcherText() { return Array.prototype.join.call(this, ", "); }, /** * @param {string} value */ set matcherText(value) { // just a temporary solution, actually it may be wrong by just split the value with ',', because a url can include ','. var values = value.split(","); var length = this.length = values.length; for (var i=0; i 0; while (ancestorRules.length > 0) { parentRule = ancestorRules.pop(); if ( parentRule.constructor.name === "CSSMediaRule" || parentRule.constructor.name === "CSSSupportsRule" ) { prevScope = currentScope; currentScope = parentRule; currentScope.cssRules.push(prevScope); break; } if (ancestorRules.length === 0) { hasAncestors = false; } } if (!hasAncestors) { currentScope.__ends = i + 1; styleSheet.cssRules.push(currentScope); currentScope = styleSheet; parentRule = null; } buffer = ""; state = "before-selector"; break; } break; default: switch (state) { case "before-selector": state = "selector"; styleRule = new CSSOM.CSSStyleRule(); styleRule.__starts = i; break; case "before-name": state = "name"; break; case "before-value": state = "value"; break; case "importRule-begin": state = "importRule"; break; } buffer += character; break; } } return styleSheet; }; //.CommonJS exports.parse = CSSOM.parse; // The following modules cannot be included sooner due to the mutual dependency with parse.js CSSOM.CSSStyleSheet = require("./CSSStyleSheet").CSSStyleSheet; CSSOM.CSSStyleRule = require("./CSSStyleRule").CSSStyleRule; CSSOM.CSSImportRule = require("./CSSImportRule").CSSImportRule; CSSOM.CSSMediaRule = require("./CSSMediaRule").CSSMediaRule; CSSOM.CSSSupportsRule = require("./CSSSupportsRule").CSSSupportsRule; CSSOM.CSSFontFaceRule = require("./CSSFontFaceRule").CSSFontFaceRule; CSSOM.CSSHostRule = require("./CSSHostRule").CSSHostRule; CSSOM.CSSStyleDeclaration = require('./CSSStyleDeclaration').CSSStyleDeclaration; CSSOM.CSSKeyframeRule = require('./CSSKeyframeRule').CSSKeyframeRule; CSSOM.CSSKeyframesRule = require('./CSSKeyframesRule').CSSKeyframesRule; CSSOM.CSSValueExpression = require('./CSSValueExpression').CSSValueExpression; CSSOM.CSSDocumentRule = require('./CSSDocumentRule').CSSDocumentRule; ///CommonJS package/lib/StyleSheet.js000644 0000000420 3560116604 012451 0ustar00000000 000000 //.CommonJS var CSSOM = {}; ///CommonJS /** * @constructor * @see http://dev.w3.org/csswg/cssom/#the-stylesheet-interface */ CSSOM.StyleSheet = function StyleSheet() { this.parentStyleSheet = null; }; //.CommonJS exports.StyleSheet = CSSOM.StyleSheet; ///CommonJS package/package.json000644 0000000521 3560116604 011544 0ustar00000000 000000 { "name": "cssom", "description": "CSS Object Model implementation and CSS parser", "keywords": [ "CSS", "CSSOM", "parser", "styleSheet" ], "version": "0.4.4", "author": "Nikita Vasilyev ", "repository": "NV/CSSOM", "files": [ "lib/" ], "main": "./lib/index.js", "license": "MIT" } package/README.mdown000644 0000004013 3560116604 011261 0ustar00000000 000000 # CSSOM CSSOM.js is a CSS parser written in pure JavaScript. It is also a partial implementation of [CSS Object Model](http://dev.w3.org/csswg/cssom/). CSSOM.parse("body {color: black}") -> { cssRules: [ { selectorText: "body", style: { 0: "color", color: "black", length: 1 } } ] } ## [Parser demo](http://nv.github.com/CSSOM/docs/parse.html) Works well in Google Chrome 6+, Safari 5+, Firefox 3.6+, Opera 10.63+. Doesn't work in IE < 9 because of unsupported getters/setters. To use CSSOM.js in the browser you might want to build a one-file version that exposes a single `CSSOM` global variable: ➤ git clone https://github.com/NV/CSSOM.git ➤ cd CSSOM ➤ node build.js build/CSSOM.js is done To use it with Node.js or any other CommonJS loader: ➤ npm install cssom ## Don’t use it if... You parse CSS to mungle, minify or reformat code like this: ```css div { background: gray; background: linear-gradient(to bottom, white 0%, black 100%); } ``` This pattern is often used to give browsers that don’t understand linear gradients a fallback solution (e.g. gray color in the example). In CSSOM, `background: gray` [gets overwritten](http://nv.github.io/CSSOM/docs/parse.html#css=div%20%7B%0A%20%20%20%20%20%20background%3A%20gray%3B%0A%20%20%20%20background%3A%20linear-gradient(to%20bottom%2C%20white%200%25%2C%20black%20100%25)%3B%0A%7D). It doesn't get preserved. If you do CSS mungling, minification, image inlining, and such, CSSOM.js is no good for you, considere using one of the following: * [postcss](https://github.com/postcss/postcss) * [reworkcss/css](https://github.com/reworkcss/css) * [csso](https://github.com/css/csso) * [mensch](https://github.com/brettstimmerman/mensch) ## [Tests](http://nv.github.com/CSSOM/spec/) To run tests locally: ➤ git submodule init ➤ git submodule update ## [Who uses CSSOM.js](https://github.com/NV/CSSOM/wiki/Who-uses-CSSOM.js) package/LICENSE.txt000644 0000002036 3560116604 011104 0ustar00000000 000000 Copyright (c) Nikita Vasilyev Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.