Skip to content

Instantly share code, notes, and snippets.

@pyramation
Created December 20, 2016 06:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pyramation/3bafcff80a4fc41b04af8834a2a0d794 to your computer and use it in GitHub Desktop.
Save pyramation/3bafcff80a4fc41b04af8834a2a0d794 to your computer and use it in GitHub Desktop.
serialize and deserialize CSSOM StyleSheet objects to JSON and back
var CSSOM = require('cssom');
/**
* @param {Object} object
* @return {Object}
*/
function uncircularOwnProperties(object) {
function _uncircular(object, depth, stack) {
var stackLength = stack.push(object);
depth++;
var keys = Object.keys(object);
for (var i = 0, length = keys.length; i < length; i++) {
var key = keys[i];
var value = object[key];
if (value && typeof value === 'object') {
var level = stack.indexOf(value);
if (level !== -1) {
object[key] = buildPath(depth - level - 1);
} else {
_uncircular(value, depth, stack);
stack.length = stackLength;
}
}
}
}
_uncircular(object, 0, []);
return object;
}
/**
* buildPath(2) -> '../..'
* @param {number} level
* @return {string}
*/
function buildPath(level) {
if (level === 0) {
return '.';
} else {
var result = '..';
for (var i = 1; i < level; i++) {
result += '/..';
}
return result;
}
}
/**
* @param {CSSOM.StyleSheet} stylesheet
* @return {JSON}
*/
module.exports.CSSOM2JSON = function (stylesheet) {
function CSSOM2JSON(stylesheet) {
var json = {
parentStyleSheet: null,
cssRules: []
};
var rules = stylesheet.cssRules;
if (!rules) {
return json;
}
for (var i=0, rulesLength=rules.length; i < rulesLength; i++) {
var rule = rules[i];
var ruleJSON = json.cssRules[i] = {
type: rule.type
};
var style = rule.style;
if (style) {
var styleClone = ruleJSON.style = {
length: 0,
parentRule: null,
_importants: {}
};
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')) {
ruleJSON.keyText = rule.keyText;
}
if (rule.hasOwnProperty('selectorText')) {
ruleJSON.selectorText = rule.selectorText;
}
if (rule.hasOwnProperty('mediaText')) {
ruleJSON.mediaText = rule.mediaText;
}
if (rule.hasOwnProperty('cssRules')) {
ruleJSON.cssRules = CSSOM2JSON(rule).cssRules;
}
}
return json;
}
var json = CSSOM2JSON(stylesheet);
return uncircularOwnProperties(json);
};
/**
* @param {JSON} json
* @return {CSSOM.StyleSheet}
*/
module.exports.JSON2CSSOM = function JSON2CSSOM(json) {
var stylesheet = new CSSOM.CSSStyleSheet();
var rules = json.cssRules;
if (!rules) {
return stylesheet;
}
var RULE_TYPES = {
1: CSSOM.CSSStyleRule,
4: CSSOM.CSSMediaRule,
8: CSSOM.CSSKeyframesRule,
9: CSSOM.CSSKeyframeRule
};
for (var i=0, rulesLength=rules.length; i < rulesLength; i++) {
var rule = rules[i];
var ruleClone = stylesheet.cssRules[i] = new RULE_TYPES[rule.type]();
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._importants[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('cssRules')) {
ruleClone.cssRules = JSON2CSSOM(rule).cssRules;
}
}
return stylesheet;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment