Skip to content

Instantly share code, notes, and snippets.

@domenic
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save domenic/8f96ca2eccff5df951ef to your computer and use it in GitHub Desktop.
Save domenic/8f96ca2eccff5df951ef to your computer and use it in GitHub Desktop.
One way of doing DOMRect + DOMQuadBounds

DOMRectUtils

[NoInterfaceObject]
interface DOMRectUtils {
  readonly attribute unrestricted double top;
  readonly attribute unrestricted double right;
  readonly attribute unrestricted double bottom;
  readonly attribute unrestricted double left;
}

NOTE: The DOMRectUtils interface is not meant to be inherited from directly, but instead used with the implements keyword.

The top getter must return min(this.y, this.y + this.height).

The right getter must return max(this.x, this.x + this.width).

The bottom getter must return max(this.y, this.y + this.height).

The left getter must return min(this.x, this.x + this.width).

DOMRect

[Constructor(unrestricted optional double x = 0, unrestricted optional double y = 0,
             unrestricted optional double width = 0, unrestricted optional double height = 0)]
interface DOMRect implements DOMRectUtils {
    attribute unrestricted double x;
    attribute unrestricted double y;
    attribute unrestricted double width;
    attribute unrestricted double height;
};

DOMRect instances have four internal slots, [[x]], [[y]], [[width]], and [[height]].

The DOMRect(x, y, width, height) constructor must:

  1. Set the [[x]] internal slot of this to x.
  2. Set the [[y]] internal slot of this to y.
  3. Set the [[width]] internal slot of this to width.
  4. Set the [[height]] internal slot of this to height.

The x, y, width, and height accessors must reflect the [[x]], [[y]], [[width]], and [[height]] internal slots, respectively.

DOMQuadBounds

[Constructor(DOMQuadInit quad)]
interface DOMQuadBounds implements DOMRectUtils {
    readonly attribute unrestricted double x;
    readonly attribute unrestricted double y;
    readonly attribute unrestricted double width;
    readonly attribute unrestricted double height;
};

DOMQuadBounds instances have one internal slot, [[quad]].

The DOMQuadBounds(quad) constructor must set the [[quad]] internal slot of this to quad.

In the following algorithms, let q be the value of the [[quad]] internal slot of this. Then:

The x getter must return the minimum of q.p1.x, q.p2.x, q.p3.x, and q.p4.x.

The y getter must return the minimum of q.p1.y, q.p2.y, q.p3.y, and q.p4.y.

The width getter must return (the maximum of q.p1.x, q.p2.x, q.p3.x, and q.p4.x) minus this.x.

The height getter must return (the maximum of q.p1.y, q.p2.y, q.p3.y, and q.p4.y) minus this.y.

var min = Math.min;
var max = Math.max;
var mixin = Object.mixin; // ES7; essentially a loop that copies property descriptors
var internalSlots = new WeakMap();
var DOMRectUtils = {
get top() {
return min(this.y, this.y + this.height);
},
get right() {
return max(this.x, this.x + this.width);
},
get bottom() {
return max(this.y, this.y + this.height);
},
get left() {
return min(this.x, this.x + this.width);
}
};
class DOMRect {
constructor(x = 0, y = 0, width = 0, height = 0) {
x = +x;
y = +y;
width = +width;
height = +height;
internalSlots.set(this, { x, y, width, height });
}
get x() {
return internalSlots.get(this).x;
}
set x(value) {
internalSlots.get(this).x = +value;
}
get y() {
return internalSlots.get(this).y;
}
set y(value) {
internalSlots.get(this).y = +value;
}
get width() {
return internalSlots.get(this).width;
}
set width(value) {
internalSlots.get(this).width = +value;
}
get height() {
return internalSlots.get(this).height;
}
set height(value) {
internalSlots.get(this).height = +value;
}
}
mixin(DOMRect.prototype, DOMRectUtils);
class DOMQuadBounds {
constructor(quad) {
// Could add a type check here that quad is a DOMQuad, but that is kind of un-JSey
// (e.g. it prevents people passing in { p1, p2, p3, p4 } of their own, for no real reason).
// Better to use a DOMQuadInit type.
// This does entail some checks, which I omit in this code.
internalSlots.set(this, { quad })
}
get x() {
var q = internalSlots.get(this).quad;
return min(q.p1.x, q.p2.x, q.p3.x, q.p4.x);
}
get y() {
var q = internalSlots.get(this).quad;
return min(q.p1.y, q.p2.y, q.p3.y, q.p4.y);
}
get width() {
var q = internalSlots.get(this).quad;
return max(q.p1.x, q.p2.x, q.p3.x, q.p4.x) - this.x;
}
get height() {
var q = internalSlots.get(this).quad;
return max(q.p1.y, q.p2.y, q.p3.y, q.p4.y) - this.y;
}
}
mixin(DOMQuadBounds.prototype, DOMRectUtils);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment