Created
March 21, 2017 17:02
-
-
Save mjgpy3/ad25697e65120ce9f21aa7cd3ecd4409 to your computer and use it in GitHub Desktop.
Perhaps a CSS Monoid
This file contains hidden or 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
function Unstyled() { | |
this.append = function (other) { | |
return other; | |
}; | |
this.empty = function () { | |
return new Unstyled(); | |
}; | |
this.$addLesserStyle = function (style, value) { | |
return new SingleStyle(style, value); | |
}; | |
this.toString = function () { | |
return "{\n}"; | |
}; | |
} | |
function SingleStyle(style, value) { | |
this.append = function (other) { | |
return other.$addLesserStyle(style, value); | |
}; | |
this.empty = function () { | |
return new Unstyled(); | |
}; | |
this.$addLesserStyle = function (newStyle, newValue) { | |
if (newStyle === style) { | |
return new SingleStyle(style, value); | |
} else { | |
return new MultiStyle({ | |
[style]: value, | |
[newStyle]: newValue | |
}); | |
} | |
}; | |
this.toString = function () { | |
return "{\n " + style + ": " + value + ";\n}"; | |
}; | |
} | |
function MultiStyle(styleDefs) { | |
this.append = function (other) { | |
var result = other; | |
for (var style in styleDefs) { | |
result = result.$addLesserStyle(style, styleDefs[style]); | |
} | |
return result; | |
}; | |
this.empty = function () { | |
return new Unstyled(); | |
}; | |
this.$addLesserStyle = function (newStyle, newValue) { | |
var result = { [newStyle]: newValue }; | |
for (var style in styleDefs) { | |
result[style] = styleDefs[style]; | |
} | |
return new MultiStyle(result); | |
}; | |
this.toString = function () { | |
var result = ''; | |
for (var style in styleDefs) { | |
result += ' ' + style + ': ' + styleDefs[style] + ';\n'; | |
} | |
return "{\n" + result + "}"; | |
}; | |
} | |
function unstyled() { | |
return new Unstyled(); | |
} | |
function style(name, value) { | |
return new SingleStyle(name, value); | |
} | |
function styles(obj) { | |
var keys = Object.keys(obj); | |
switch (keys.length) { | |
case 0: | |
return unstyled(); | |
case 1: | |
return style(keys[0], obj[keys[0]]); | |
default: | |
return new MultiStyle(obj); | |
} | |
} | |
function concat(styles) { | |
return styles.reduce( | |
function (acc, current) { return acc.append(current); }, | |
unstyled() | |
); | |
} | |
function color(value) { | |
return new SingleStyle('color', value); | |
} | |
function backgroundColor(value) { | |
return new SingleStyle('background-color', value); | |
} | |
console.log(new Unstyled().toString()); | |
console.log(new SingleStyle('color', 'red').toString()); | |
console.log(color('red').append(color('yellow')).append(backgroundColor('black')).toString()); | |
var blackOnYellow = color('black').append(backgroundColor('yellow')); | |
console.log( | |
blackOnYellow.toString() | |
); | |
console.log( | |
styles({}) | |
); | |
console.log( | |
styles({ color: 'red' }) | |
); | |
console.log( | |
styles({ color: 'red', 'background-color': 'green' }) | |
.append( | |
styles({ color: 'blue', 'background-color': 'pink' })).toString() | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment