Permalink
Browse files

Simplify parameter parsing, defaults and update unit tests

  • Loading branch information...
1 parent c2a5da3 commit f2f87e7a5bc16cdfed9f1686704ad2d3e0f6137d @turnertime committed Feb 27, 2012
Showing with 97 additions and 98 deletions.
  1. +53 −22 tests/virtualist.tests.js
  2. +44 −76 virtualist.js
@@ -1,59 +1,90 @@
-/*global window: false */
+/*global document: false, screen: false, QUnit: false, virtualist: false */
-(function scriptInitKeysTests(qunit, virtualist) {
+(function scriptInitKeysTests(document, screen, qunit, virtualist) {
"use strict";
qunit.module("virtualist");
//-------------------------------------------
- qunit.test("init - parameter validation", 7, function parameterValidationTest() {
+ qunit.test("init - parameter validation", 25, function parameterValidationTest() {
- var container = window.document.getElementById("container");
+ var container = document.getElementById("container"),
+ noop = function noop() { },
+ list;
+
+ // Test error cases.
qunit.raises(
- function init() {
- virtualist.init();
- },
+ function init() { virtualist.init(); },
"settings must be defined",
"empty constructor should fail"
);
qunit.raises(
- function init() {
- virtualist.init({ el: null });
- },
- "settings.el must be defined",
- "null settings.el should fail"
+ function init() { virtualist.init({ el: null }); },
+ "el must be an HTMLElement",
+ "null el should fail"
);
qunit.raises(
function init() {
- virtualist.init({ el: "1", length: null });
+ virtualist.init({ el: container, length: null });
},
- "settings.length must be number",
+ "length must be number",
"null settings.length should fail"
);
qunit.raises(
function init() {
- virtualist.init({ el: "1", length: 1, render: null });
+ virtualist.init({ el: container, length: 1, render: null });
},
- "settings.render must be function",
+ "render must be function",
"null settings.render should fail"
);
qunit.raises(
function init() {
- virtualist.init({ el: "1", length: 1, render: qunit.test, size: null });
+ virtualist.init({ el: container, length: 1, render: noop, size: null });
},
- "settings.size must be number",
+ "size must be number",
"null settings.size should fail"
);
- qunit.ok(virtualist.init({ el: "container", length: 1, render: function (i) { return i; }, size: 1 }));
- qunit.ok(virtualist.init({ el: container, length: 1, render: function (i) { return i; }, size: 1 }));
- container.innerHTML = "";
+ // Test valid cases.
+
+ // defaults and valid values
+ list = virtualist.init({ el: container, length: 1, render: noop, size: 1 });
+ qunit.strictEqual(list.config.bufferSize, 1, "bufferSize should be initialized to 1");
+ qunit.strictEqual(list.config.el, container, "container should be initialized to container");
+ qunit.strictEqual(list.config.explicitSize, screen.availHeight, "container should be initialized to screen.availHeight");
+ qunit.ok(!list.config.isHorizontal, "isHorizontal should be initialized to false");
+ qunit.strictEqual(list.config.length, 1, "length should be initialized to 1");
+ qunit.strictEqual(list.config.maxCanvasSize, 500000, "maxCanvasSize should be initialized to 500000");
+ qunit.strictEqual(list.config.render, noop, "render should be initialized to noop function");
+ qunit.strictEqual(list.config.size, 1, "size should be initialized to 1");
+
+ // negative numbers
+ list = virtualist.init({ bufferSize: -1, explicitSize: -1, el: container, length: -1, maxCanvasSize: -1, render: noop, size: -1 });
+ qunit.strictEqual(list.config.bufferSize, 1, "bufferSize should be initialized to 1");
+ qunit.strictEqual(list.config.explicitSize, 1, "explicitSize should be initialized to 1");
+ qunit.strictEqual(list.config.length, 0, "length should be initialized to 0");
+ qunit.strictEqual(list.config.maxCanvasSize, 1, "maxCanvasSize should be initialized to 1");
+ qunit.strictEqual(list.config.size, 1, "size should be initialized to 1");
+
+ // decimal numbers
+ list = virtualist.init({ bufferSize: 1.2, explicitSize: 1.5, el: container, length: 1.6, maxCanvasSize: 1.8, render: noop, size: 1.3 });
+ qunit.strictEqual(list.config.bufferSize, 2, "bufferSize should be initialized to 2");
+ qunit.strictEqual(list.config.explicitSize, 2, "explicitSize should be initialized to 2");
+ qunit.strictEqual(list.config.length, 2, "length should be initialized to 2");
+ qunit.strictEqual(list.config.maxCanvasSize, 2, "maxCanvasSize should be initialized to 2");
+ qunit.strictEqual(list.config.size, 2, "size should be initialized to 2");
+
+ // isHorizontal
+ list = virtualist.init({ el: container, isHorizontal: true, length: 1, render: noop, size: 1 });
+ qunit.ok(list.config.isHorizontal, "isHorizontal should be initialized to true");
+ qunit.strictEqual(list.config.explicitSize, screen.availWidth, "container should be initialized to screen.availWidth");
+
});
-}(window.QUnit, window.virtualist)); // end of (function () {
+}(document, screen, QUnit, virtualist)); // end of (function () {
View
@@ -1,38 +1,58 @@
-/*global document: false, HTMLElement: false, screen: false, window: false */
+/*global HTMLElement: false, screen: false, window: false */
-window.virtualist = window.virtualist || (function (document, HTMLElement, screen) { // execute immediately on script load (not waiting for DOM), prevent multiple initializations, introduce scope container
+window.virtualist = window.virtualist || (function (HTMLElement, screen) { // execute immediately on script load (not waiting for DOM), prevent multiple initializations, introduce scope container
"use strict";
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Private
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//-------------------------------------------
- function buildItems(config, scrollPos) {
- var i,
- startIndex = Math.min((config.length - config.viewportItems), Math.max(0, Math.floor(scrollPos / config.size))),
- length = startIndex + config.viewportItems,
- result = "",
- pos,
- start = "<div class=\"item\" style=\"position: absolute; ".concat(config.isHorizontal ? "left:" : "top:"),
- mid = "px; ".concat(config.isHorizontal ? "right:" : "bottom:");
- for (i = startIndex; i < length; i += 1) {
- pos = Math.floor(i * config.size);
- result = result.concat(start)
- .concat(pos)
- .concat(mid)
- .concat(pos + config.size)
- .concat("px;\">")
- .concat(config.render(i))
- .concat("</div>");
- }
- return result;
+ function Virtualist(settings) {
+
+ if (!settings) { throw new Error("settings must be defined"); }
+ if (typeof settings.el instanceof HTMLElement) { throw new Error("el must be an HTMLElement"); }
+ if (typeof settings.length !== "number") { throw new Error("length must be a number"); }
+ if (typeof settings.render !== "function") { throw new Error("render must be a function"); }
+ if (typeof settings.size !== "number") { throw new Error("size must be a number"); }
+
+ this.config = {
+
+ // the number of pages in buffer (default: 1)
+ bufferSize: (typeof settings.bufferSize === "number") ? Math.ceil(Math.max(1, settings.bufferSize)) : 1,
+
+ // the HTMLElement with the virtualist instance
+ el: settings.el,
+
+ // the size of the viewport (default: screen.avail[Height|Width]
+ explicitSize: (typeof settings.explicitSize === "number") ? Math.ceil(Math.max(1, settings.explicitSize)) : (settings.isHorizontal ? screen.availWidth : screen.availHeight),
+
+ // specifies whether the list is virtualized horizontally or vertically
+ isHorizontal: !!settings.isHorizontal,
+
+ // the number of items to render
+ length: Math.ceil(Math.max(0, settings.length)),
+
+ // the maximum size (in pixels) of the canvas (default: 500000)
+ maxCanvasSize: (typeof settings.maxCanvasSize === "number") ? Math.ceil(Math.max(1, settings.maxCanvasSize)) : 500000,
+
+ // the function used to render a list item (parameter: index, returns: the html string representation of the rendered item)
+ render: settings.render,
+
+ // the current scroll position
+ scrollPosition: 0,
+
+ // the size (in pixels) of a single list item
+ size: Math.ceil(Math.max(1, settings.size))
+
+ };
+
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Public
+ // Public (TODO) maybe this is not need and make virtualist constructor public.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//-------------------------------------------
@@ -41,61 +61,9 @@ window.virtualist = window.virtualist || (function (document, HTMLElement, scree
//-------------------------------------------
VirtualistManager.prototype.init = function init(settings) {
- var config;
-
- // Parameter validation
-
- if (!settings) { throw new Error("settings must be defined"); }
- if (!settings.el) { throw new Error("settings.el must be defined"); }
- if (typeof settings.length !== "number") { throw new Error("settings.length must be a number"); }
- if (typeof settings.render !== "function") { throw new Error("settings.render must be a function"); }
- if (typeof settings.size !== "number") { throw new Error("settings.size must be a number"); }
-
- config = {
- isHorizontal: !!settings.isHorizontal,
- el: typeof settings.el === "string" ? document.getElementById(settings.el) : settings.el,
- length: settings.length,
- maxSize: Math.floor(settings.length * settings.size),
- size: settings.size,
- render: settings.render,
- viewportSize: settings.isHorizontal ? screen.width : screen.height
- };
- config.viewportItems = Math.floor(config.viewportSize / config.size);
-
- if (!(config.el instanceof HTMLElement)) {
- throw new Error("settings.el must be an HTMLElement or id that matches an element");
- }
-
- // Handle scrolling
-
- config.scrollHandler = (config.isHorizontal)
- ? function horizontalScrollHandler(e) {
- config.viewport.innerHTML = buildItems(config, e.target.scrollLeft);
- }
- : function verticalScrollHandler(e) {
- config.viewport.innerHTML = buildItems(config, e.target.scrollTop);
- };
-
- if (typeof config.el.addEventListener === "function") {
- config.el.addEventListener("scroll", config.scrollHandler, false);
- } else {
- config.el.attachEvent("onscroll", config.scrollHandler);
- }
-
- // render virtualist
-
- config.el.innerHTML = "<div class=\"viewport\" style=\""
- .concat(config.isHorizontal ? "width" : "height")
- .concat(": ")
- .concat(config.maxSize)
- .concat("px;\">")
- .concat(buildItems(config, 0))
- .concat("</div>");
- config.viewport = config.el.firstChild;
-
- return {};
+ return new Virtualist(settings);
};
return new VirtualistManager();
-}(document, HTMLElement, screen)); // end of (function () {
+}(HTMLElement, screen)); // end of (function () {

0 comments on commit f2f87e7

Please sign in to comment.