Created
December 20, 2016 06:08
-
-
Save pyramation/3bafcff80a4fc41b04af8834a2a0d794 to your computer and use it in GitHub Desktop.
serialize and deserialize CSSOM StyleSheet objects to JSON and back
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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