Skip to content

Instantly share code, notes, and snippets.

@domenic
Last active May 12, 2018 08:37
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 domenic/6736258 to your computer and use it in GitHub Desktop.
Save domenic/6736258 to your computer and use it in GitHub Desktop.
DOMRect??
const privates = new WeakMap();
class DOMRect {
constructor(left, top, width, height) {
privates.set(this, {
left: +left,
top: +top,
width: +width,
height: +height
});
}
get left() { return privates.get(this).left; }
get top() { return privates.get(this).top; }
get width() { return privates.get(this).width; }
get height() { return privates.get(this).height; }
get right() { return this.left + this.width; }
get bottom() { return this.top + this.height; }
}
class DOMRectImmutable extends DOMRect {}
// DOES NOT WORK; SEE BELOW
class DOMRectMutable extends DOMRect {
set left(value) { privates.get(this).left = +value; }
set top(value) { privates.get(this).top = +value; }
set width(value) { privates.get(this).width = +value; }
set height(value) { privates.get(this).height = +value; }
}
// THE PROBLEM:
const r = new DOMRectImmutable(1, 2, 3, 4);
Object.getOwnPropertyDescriptor(DOMRectMutable.prototype, 'left').set.call(r, 10);
console.log(r.left); // 10! uh-oh
// Solution: add branding checks
const mutableDomRects = new WeakSet();
function assertIsBranded(obj) {
if (!mutableDomRects.has(obj)) {
throw new TypeError('You can only apply DOMRectMutable2 methods to DOMRectMutable2 instances!');
}
}
class DOMRectMutable2 extends DOMRect {
[Symbol.create]() {
const newDomRect = {};
mutableDomRects.add(newDomRect);
return newDomRect;
}
set left(value) {
assertIsBranded(this);
privates.get(this).left = +value;
}
set top(value) {
assertIsBranded(this);
privates.get(this).top = +value;
}
set width(value) {
assertIsBranded(this);
privates.get(this).width = +value;
}
set height(value) {
assertIsBranded(this);
privates.get(this).height = +value;
}
}
// Now:
Object.getOwnPropertyDescriptor(DOMRectMutable2.prototype, 'left').set.call(r, 10);
// Throws TypeError.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment