Skip to content

Commit

Permalink
supporting CSStyleDeclaration style (#138)
Browse files Browse the repository at this point in the history
  • Loading branch information
gliechtenstein authored Jul 5, 2017
1 parent 24b77e8 commit d2a2588
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 4 deletions.
7 changes: 7 additions & 0 deletions cell.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,9 @@
// "_" variables don't directly alter the phenotype, so do nothing
} else if (key === 'value') {
$node[key] = val;
} else if (key === 'style' && typeof val === 'object') {
var CSSStyleDeclaration = Object.getOwnPropertyDescriptor($root.HTMLElement.prototype, key).get.call($node);
for (var attr in val) { CSSStyleDeclaration[attr] = val[attr]; }
} else if (typeof val === 'number' || typeof val === 'string' || typeof val === 'boolean') {
if ($node.setAttribute) $node.setAttribute(key, val);
} else if (typeof val === 'function') {
Expand Down Expand Up @@ -345,6 +348,8 @@
if (key === 'value') {
// The "value" attribute needs a special treatment.
return Object.getOwnPropertyDescriptor(Object.getPrototypeOf($node), key).get.call($node);
} else if (key === 'style') {
return Object.getOwnPropertyDescriptor($root.HTMLElement.prototype, key).get.call($node);
} else if (key in $node.Genotype) {
// Otherwise utilize Genotype
return $node.Genotype[key];
Expand Down Expand Up @@ -376,6 +381,8 @@
if (key[0] !== '$' && key[0] !== '_') {
if (key === 'value') {
return Object.getOwnPropertyDescriptor(Object.getPrototypeOf($node), key).set.call($node, val);
} else if (key === 'style' && typeof val === 'object') {
Object.getOwnPropertyDescriptor($root.HTMLElement.prototype, key).set.call($node, val);
} else if (typeof val === 'number' || typeof val === 'string' || typeof val === 'boolean') {
$node.setAttribute(key, val);
} else if (typeof val === 'function') {
Expand Down
49 changes: 46 additions & 3 deletions test/Nucleus.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,9 @@ describe("Nucleus", function() {
spy.Genotype.update.reset();
$div.class = "red";

var getOwnPropertySpy = sinon.spy(Object, "getOwnPropertyDescriptor")
getOwnPropertySpy.reset();
spy.O.getOwnPropertyDescriptor.reset();
var d = $div.class;
compare(getOwnPropertySpy.callCount, 0);
compare(spy.O.getOwnPropertyDescriptor.callCount, 0);
})
it("properties that already exist on the DOM", function() {
// For example, "tagName", "nodeType", etc. already exist on the element natively, and users nomrally don't set these manually. But sometimes we need to access these
Expand All @@ -100,6 +99,50 @@ describe("Nucleus", function() {
compare(spy.Nucleus.bind.callCount, 0);
compare(name.toLowerCase(), "div")
})
describe("special properties", function() {
it("style", function() {
spy.Nucleus.bind.reset();
spy.Genotype.update.reset();
var style = $div.style;

compare(spy.Genotype.update.callCount, 0);

// the getter returns a CSSStyleDeclaration object
compare(Object.getPrototypeOf(style).constructor.name, "CSSStyleDeclaration");

// node setup
$div.Genotype = {
style: "background-color: red;"
}
Nucleus.build($div)

spy.O.getOwnPropertyDescriptor.reset();

// getter is called, and the key is 'style'
// so Object.getOwnPropertyDescriptor is called
style = $div.style;
compare(spy.O.getOwnPropertyDescriptor.callCount, 1);
// the getter returns a CSSStyleDeclaration object
compare(Object.getPrototypeOf(style).constructor.name, "CSSStyleDeclaration");

// string type style setter
spy.Genotype.update.reset();
spy.O.getOwnPropertyDescriptor.reset();
$div.style = "background-color: blue;";
// since the setter is called and it's not an object type style,
// it will trigger setAttribute and not Object.getOwnPropertyDescriptor
compare(spy.O.getOwnPropertyDescriptor.callCount, 0);

// object type style setter
spy.O.getOwnPropertyDescriptor.reset();
$div.style = {
backgroundColor: "blue"
}
// triggers setter, which triggers getter, both of which calls Object.getOwnPropertyDescriptor => 2
compare(spy.O.getOwnPropertyDescriptor.callCount, 2);

});
});
})
})
describe("set", function() {
Expand Down
57 changes: 57 additions & 0 deletions test/Phenotype.js
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,64 @@ describe("Phenotype", function() {
describe("[_] User defined variables", function() {
})
describe("[ ] dom attributes", function() {
describe("object", function() {
it("style", function() {
const $parent = document.createElement("div");
const $node = document.createElement("div")
$node.Genotype = {}
$node.Meta = {}
$parent.appendChild($node)

// normally it's set directly on the DOM as an attribute
var styleAttr = $node.getAttribute("style");
compare(styleAttr, null);

var styleProp = $node.style;
compare(Object.getPrototypeOf(styleProp).constructor.name, "CSSStyleDeclaration");

Phenotype.set($node, "style", {
backgroundColor: "red",
fontFamily: "Courier"
})

styleAttr = $node.getAttribute("style");
styleProp = $node.style;

compare(styleAttr, "background-color: red; font-family: Courier;")
compare(styleProp.backgroundColor, "red");
compare(styleProp.fontFamily, "Courier");

compare(Object.getPrototypeOf(styleProp).constructor.name, "CSSStyleDeclaration");

});
});
describe("string", function() {
it("style", function() {
const $parent = document.createElement("div");
const $node = document.createElement("div")
$node.Genotype = {}
$node.Meta = {}
$parent.appendChild($node)

// normally it's set directly on the DOM as an attribute
var styleAttr = $node.getAttribute("style");
compare(styleAttr, null);

var styleProp = $node.style;
compare(Object.getPrototypeOf(styleProp).constructor.name, "CSSStyleDeclaration");

Phenotype.set($node, "style", "background-color: red;")

styleAttr = $node.getAttribute("style");
styleProp = $node.style;

compare(styleAttr, "background-color: red;")
// even if we initially set the style as string,
// we should be able to access it as an object property
compare(styleProp.backgroundColor, "red");
compare(Object.getPrototypeOf(styleProp).constructor.name, "CSSStyleDeclaration");

});
it("class", function() {
const $parent = document.createElement("div");
const $node = document.createElement("div")
Expand Down
3 changes: 2 additions & 1 deletion test/spy.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ module.exports = {
update: sinon.spy(Genotype, "update")
},
O: {
defineProperty: sinon.spy(Object, "defineProperty")
defineProperty: sinon.spy(Object, "defineProperty"),
getOwnPropertyDescriptor: sinon.spy(Object, "getOwnPropertyDescriptor")
},
Gene: {
freeze: sinon.spy(Gene, "freeze")
Expand Down

0 comments on commit d2a2588

Please sign in to comment.