Skip to content
This repository has been archived by the owner on Apr 1, 2019. It is now read-only.

Commit

Permalink
Renamed Rect + type coercion (closes #50, #51)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoscaceres committed Aug 28, 2015
1 parent 550b7c2 commit 026c40d
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 82 deletions.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
<script type="text/javascript;version=1.8" src="locale/newTab.js"></script>
<script type="text/javascript;version=1.8" src="js/lib/async.js"></script>
<script type="text/javascript;version=1.8" src="js/customize.js"></script>
<script type="text/javascript;version=1.8" src="js/rect.js"></script>
<script type="text/javascript;version=1.8" src="js/rectangle.js"></script>
<script type="text/javascript;version=1.8" src="js/dropTargetShim.js"></script>
<script type="text/javascript;version=1.8" src="js/dropPreview.js"></script>
<script type="text/javascript;version=1.8" src="js/drop.js"></script>
Expand Down
76 changes: 0 additions & 76 deletions js/rect.js

This file was deleted.

71 changes: 71 additions & 0 deletions js/rectangle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/

"use strict";

(function(exports) {
function Rectangle(x, y, w, h) {
this.setRect(x, y, w, h);
}

Rectangle.prototype = {
get width() {
return this.right - this.left;
},
get height() {
return this.bottom - this.top;
},
set width(v) {
this.right = this.left + coerceToNumber(v);
},
set height(v) {
this.bottom = this.top + coerceToNumber(v);
},
get isEmpty() {
return this.left >= this.right || this.top >= this.bottom;
},

clone() {
return new Rectangle(this.left, this.top, this.width, this.height);
},

intersect(other) {
return this.clone().restrictTo(other);
},

setRect(x, y, w, h) {
this.left = coerceToNumber(x);
this.top = coerceToNumber(y);
this.right = this.left + coerceToNumber(w);
this.bottom = this.top + coerceToNumber(h);
return this;
},

// Restrict area of this rectangle to the intersection of both rectangles.
restrictTo(other) {
if (this.isEmpty || other.isEmpty) {
return this.setRect(0, 0, 0, 0);
}

const x1 = Math.max(this.left, other.left);
const x2 = Math.min(this.right, other.right);
const y1 = Math.max(this.top, other.top);
const y2 = Math.min(this.bottom, other.bottom);

// If width or height is 0, the intersection was empty.
return this.setRect(x1, y1, Math.max(0, x2 - x1), Math.max(0, y2 - y1));
},
};

function coerceToNumber(v) {
var num = Number.parseInt(v, 10);
if (Number.isNaN(num)) {
throw new TypeError("Expected number.");
}
return num;
}
exports.Rectangle = Rectangle;
}(window));

6 changes: 3 additions & 3 deletions js/transformations.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/*globals gGrid, gDrag, Rect*/
/*globals gGrid, gDrag, Rectangle*/

"use strict";
(function(exports) {
Expand Down Expand Up @@ -36,7 +36,7 @@
* Gets a DOM node's position.
*
* @param {Node} aNode The DOM node.
* @return {Rect} A Rect instance with the position.
* @return {Rectangle} A Rect instance with the position.
*/
getNodePosition(aNode) {
let {
Expand All @@ -46,7 +46,7 @@
let {
left, top, width, height
} = aNode.getBoundingClientRect();
return new Rect(left + scrollX, top + scrollY, width, height);
return new Rectangle(left + scrollX, top + scrollY, width, height);
},

/**
Expand Down
3 changes: 2 additions & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ module.exports = function(config) {
exclude: [
"**/*.swp",
"*.swp",
".DS_Store"
".DS_Store",
"test/rectangle.js",
],

// preprocess matching files before serving them to the browser
Expand Down
2 changes: 1 addition & 1 deletion sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ self.addEventListener("install", (ev) => {
"js/grid.js",
"js/newTab.js",
"js/page.js",
"js/rect.js",
"js/rectangle.js",
"js/sites.js",
"js/transformations.js",
"js/undo.js",
Expand Down
141 changes: 141 additions & 0 deletions test/rectangle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/*global assert, expect*/
"use strict";

describe("Rect class", () => {

describe("Exposed correctly", () => {
it("should be present on window object", () => {
assert.equal(!!(window.Rectangle), true);
});
it("should be a function.", () => {
assert.equal(typeof window.Rectangle === "function", true);
});
it("should be constructible.", () => {
var rect = new window.Rectangle(0, 0, 0, 0);
expect(rect).to.be.an.instanceof(window.Rectangle);
});
});

describe("Creating a rectangle", () => {
it("should throw when constructor arguments result in NaN.", () => {
var builder = function() {
new window.Rectangle(...arguments);
};
expect(() => {
builder();
}).to.throw(TypeError);
expect(() => {
builder("one");
}).to.throw(TypeError);
expect(() => {
builder(1, "two", 3, 4);
}).to.throw(TypeError);
expect(() => {
builder(1, 2, "three", 4);
}).to.throw(TypeError);
expect(() => {
builder(1, 2, 3, "four");
}).to.throw(TypeError);
});
it("should have attributes whose types are numbers.", () => {
var rect = new window.Rectangle(1, 1, 10, 10);
assert.typeOf(rect.left, "number");
assert.typeOf(rect.top, "number");
assert.typeOf(rect.bottom, "number");
assert.typeOf(rect.right, "number");
});
it("should have its properties set correctly.", () => {
var rect = new window.Rectangle(5, 10, 10, 20);
expect(rect.left).to.equal(5);
expect(rect.top).to.equal(10);
expect(rect.right).to.equal(15);
expect(rect.bottom).to.equal(30);
});
it("should parse strings correctly.", () => {
var rect = new window.Rectangle(" 5 ", " \n 10 \t\t", "10", "\t20");
expect(rect.left).to.equal(5);
expect(rect.left).to.be.a("number");
expect(rect.top).to.equal(10);
expect(rect.top).to.be.a("number");
expect(rect.right).to.equal(15);
expect(rect.right).to.be.a("number");
expect(rect.bottom).to.equal(30);
expect(rect.bottom).to.be.a("number");
});
});

describe("Cloning", () => {
var rect = new window.Rectangle(0, 0, 10, 10);
var clone = rect.clone();
it("should result in different objects.", () => {
expect(clone).to.not.be(rect);
});
it("should have the same property values", () => {
expect(clone).to.have.property("width", rect.width);
expect(clone).to.have.property("height", rect.height);
expect(clone).to.have.property("top", rect.top);
expect(clone).to.have.property("bottom", rect.bottom);
expect(clone).to.have.property("left", rect.left);
expect(clone).to.have.property("right", rect.right);
});
});

describe("Intersect and restrict", ()=> {
it("should result in an empty rectangle after intersection.", ()=> {
var emptyA = new window.Rectangle(0, 0, 0, 0);
var b = new window.Rectangle(0, 0, 10, 10);
expect(b.isEmpty).to.be(false);
b.intersect(emptyA);
expect(b.isEmpty).to.be(true);
});
it("it should restrict a to b", ()=> {
var a = new window.Rectangle(0, 0, 100, 100);
var b = new window.Rectangle(10, 10, 50, 50);
a.restrictTo(b);
expect(a).to.have.property("left", 10);
expect(a).to.have.property("top", 10);
expect(a).to.have.property("right", 60);
expect(a).to.have.property("bottom", 60);
});
});

describe("Getters and setters", () => {
var rect = new window.Rectangle(0, 0, 10, 20);
it("should return the width.", () => {
expect(rect.width).to.equal(10);
});
it("should return the height.", () => {
expect(rect.height).to.equal(20);
});
it("should throw if setting the width to a NaN.", () => {
expect(() => {
rect.width = "not a number";
}).to.throw(TypeError);
});
it("should throw if setting the height to a NaN.", () => {
expect(() => {
rect.height = "not a number";
}).to.throw(TypeError);
});
it("should set the width.", () => {
rect.width = 32;
expect(rect.width).to.equal(32);
});
it("should set the height.", () => {
rect.height = 32;
expect(rect.height).to.equal(32);
});
it("should not be empty.", () => {
assert.equal(rect.isEmpty, false);
});
it("should become empty.", () => {
rect.setRect(0, 0, 0, 0);
assert.equal(rect.isEmpty, true);
rect.setRect(0, 0, -10, -10);
assert.equal(rect.isEmpty, true);
});
});
});

0 comments on commit 026c40d

Please sign in to comment.