Created
October 17, 2011 09:00
-
-
Save pixelhandler/1292234 to your computer and use it in GitHub Desktop.
Module Constructor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8" /> | |
<title>QUnit Test Suite</title> | |
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-git.css" type="text/css" media="screen"> | |
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script> | |
<script type="text/javascript" src="http://code.jquery.com/qunit/qunit-git.js"></script> | |
</head> | |
<body> | |
<h1 id="qunit-header">QUnit Test Suite</h1> | |
<h2 id="qunit-banner"></h2> | |
<div id="qunit-testrunner-toolbar"></div> | |
<h2 id="qunit-userAgent"></h2> | |
<ol id="qunit-tests"></ol> | |
<div id="qunit-fixture">test markup</div> | |
<script type="text/javascript" src="module.js"></script> | |
<script type="text/javascript" src="test.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// module.js | |
// namespace PXHLR | |
if (!window.PXHLR) { var PXHLR = {}; } | |
if (typeof Object.create !== 'function') { // ECMA 5 supports Object.create | |
Object.create = function(o) { | |
function F() {} | |
F.prototype = o; | |
return new F(); | |
}; | |
} | |
if ( typeof Object.getPrototypeOf !== "function" ) { | |
if ( typeof "test".__proto__ === "object" ) { | |
Object.getPrototypeOf = function(object){ | |
return object.__proto__; | |
}; | |
} else { | |
Object.getPrototypeOf = function(object){ | |
// May break if the constructor has been tampered with | |
return object.constructor.prototype; | |
}; | |
} | |
} | |
/** | |
* Module | |
* @constructor | |
* @param o {Object} | |
* @return o {Object} this module | |
*/ | |
PXHLR.Module = function(defaults) { | |
if (typeof defaults === 'undefined' && typeof this.defaults === 'undefined') { | |
defaults = PXHLR.Module.prototype.defaults; | |
} else { | |
defaults = defaults || this.defaults; | |
} | |
// extend defaults property with object arg o | |
defaults = $.extend({}, defaults); | |
defaults.context = $(defaults.context); | |
if (defaults.context.length < 1) { | |
// no need to setup behavior | |
return false; | |
} else { | |
// ok ready to setup module objects | |
if (!window.debugMode) { | |
PXHLR.Module.prototype.setupDebugMode(); | |
} | |
return $.extend(this, { | |
"defaults" : defaults, | |
_parent : PXHLR.Module.prototype | |
}); | |
} | |
}; | |
/** | |
* Setup the default object with properties for : | |
* "context" {String} selector as the intended context | |
*/ | |
PXHLR.Module.prototype.defaults = { | |
context : 'body' | |
}; | |
/** | |
* @method to create submodules / subclasses | |
* @param o {Object} literal object with properties/methods as subclass | |
*/ | |
PXHLR.Module.prototype.extend = function (subclass) { | |
var mod = Object.create(this); | |
mod = $.extend(mod, subclass); | |
return mod; | |
}; | |
/** | |
* @method setupDebugMode {Function} to setup debug mode | |
*/ | |
PXHLR.Module.prototype.setupDebugMode = function () { | |
if (typeof window.debugMode === "undefined") { | |
window.debugMode = document.location.hash.match(/debug/) && (typeof console !== "undefined" && console !== null); | |
window.debugMsgs = []; | |
} | |
}; | |
/** | |
* @method debug {Function} for logging | |
*/ | |
PXHLR.Module.prototype.debug = function (msg) { | |
if (window.debugMode) { | |
window.debugMsgs.push(msg); | |
console.log(msg); | |
} | |
}; | |
/** | |
* @method init | |
* @param o {Object} options for module initialization | |
*/ | |
PXHLR.Module.prototype.init = function () { | |
var that = this; | |
that._parent = (function () { | |
var _proto = Object.getPrototypeOf(that); | |
return (_proto !== that._parent) ? _proto : that.constructor.prototype; | |
}()); | |
that.debug("init Module"); | |
// initiate the sequence of methods for beforeBinding, onBinding, afterBinding | |
that.beforeBinding(that, function () { | |
that.onBinding(that, function () { | |
that.afterBinding(that); | |
}); | |
}); | |
}; | |
/** | |
* Module before binding phase | |
* @param that {Object} this context as that | |
*/ | |
PXHLR.Module.prototype.beforeBinding = function (that, callback) { | |
that.debug("Module beforeBinding"); | |
if (callback && typeof callback.constructor === 'function') { | |
callback(); | |
} else { | |
that.onBinding(that); | |
} | |
}; | |
/** | |
* Module on binding phase e.g. setup event listeners | |
* @param that {Object} this context as that | |
*/ | |
PXHLR.Module.prototype.onBinding = function (that, callback) { | |
that.debug("Module onBinding"); | |
if (callback && typeof callback.constructor === 'function') { | |
callback(); | |
} else { | |
that.afterBinding(that); | |
} | |
}; | |
/** | |
* Module after binding phase for handling state of first view | |
* @param that {Object} this context as that | |
*/ | |
PXHLR.Module.prototype.afterBinding = function (that) { | |
that.debug("Module afterBinding"); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// test.js | |
/*jslint browser: true, | |
eqeqeq: true, | |
immed: false, | |
newcap: true, | |
nomen: false, | |
onevar: true, | |
plusplus: false, | |
undef: false, | |
white: false */ | |
/*jshint browser: true, | |
eqeqeq: true, | |
immed: false, | |
newcap: true, | |
nomen: false, | |
onevar: true, | |
plusplus: false, | |
undef: false, | |
white: false */ | |
/*global window, jQuery, $, QUnit, PXHLR */ | |
/* namespace */ | |
module('namespace check'); | |
test('Is PXHLR a global variable?', function(){ | |
expect(1); | |
ok( window.PXHLR, 'PXHLR namespace is present'); | |
}); | |
// /* | |
module('Setup modules and subclasses', { | |
setup: function() { | |
PXHLR.modules = new PXHLR.Module(); | |
PXHLR.modules.init(); | |
PXHLR.modules.defaults = { context : "#qunit-fixture" }; | |
// extend module object | |
PXHLR.modules.subclass = PXHLR.modules.extend({ | |
beforeBinding : function (subclassObj) { | |
this.debug("subclass beforeBinding"); | |
this._parent.beforeBinding(subclassObj); | |
}, | |
onBinding : function (subclassObj) { | |
this.debug("subclass onBinding"); | |
this._parent.onBinding(subclassObj); | |
}, | |
afterBinding : function (subclassObj) { | |
this.debug("subclass afterBinding"); | |
this._parent.afterBinding(subclassObj); | |
} | |
}); | |
PXHLR.modules.subclass.init(); | |
}, | |
teardown: function() { | |
delete PXHLR.modules; | |
} | |
}); | |
test('Module should create new instances', function (){ | |
expect(4); | |
ok(PXHLR.modules, "PXHLR.modules is defined"); | |
deepEqual(PXHLR.Module.prototype, Object.getPrototypeOf(PXHLR.modules), "subclass has modules as its prototype"); | |
ok(PXHLR.modules.subclass, "PXHLR.modules.subclass is defined"); | |
deepEqual(PXHLR.modules, Object.getPrototypeOf(PXHLR.modules.subclass), "subclass has modules as its prototype"); | |
}); | |
test('Setup a couple more module subclasses', function (){ | |
expect(6); | |
// instantiate base module object | |
PXHLR.modules.subclass.childclass = PXHLR.modules.subclass.extend({ | |
beforeBinding : function () { | |
this.debug("childclass beforeBinding"); | |
this._parent.onBinding(this); | |
}, | |
afterBinding : function () { | |
this.debug("childclass afterBinding"); | |
this.childclassHandler("childclass beforeBinding"); | |
this._parent.afterBinding(this); | |
}, | |
childclassHandler : function (who) { | |
this.debug("childclass method childclassHandler called from " + who); | |
} | |
}); | |
PXHLR.modules.subclass.childclass.init(); | |
ok(PXHLR.modules.subclass.childclass, "PXHLR.modules.subclass.childclass is defined"); | |
ok(PXHLR.modules.subclass.childclass instanceof PXHLR.Module, "New instance"); | |
deepEqual(PXHLR.modules.subclass, Object.getPrototypeOf(PXHLR.modules.subclass.childclass), "childclass has subclass as its prototype"); | |
PXHLR.modules.subclass.childclass.grandBaby = PXHLR.modules.subclass.childclass.extend({ | |
init : function () { | |
this.debug("grandBaby - init"); | |
this.grandBabyHandler('grandBaby.init'); | |
}, | |
beforeBinding : function () { | |
this.debug("grandBaby - beforeBinding"); | |
this.grandBabyHandler("grandBaby - beforeBinding"); | |
this._parent.beforeBinding(this); | |
}, | |
grandBabyHandler : function (who) { | |
this.debug("grandBaby method grandBabyHandler called from " + who); | |
this.childclassHandler('grandBabyHandler'); | |
} | |
}); | |
PXHLR.modules.subclass.childclass.grandBaby.init(); | |
ok(PXHLR.modules.subclass.childclass.grandBaby, "PXHLR.modules.subclass.childclass.grandBaby is defined"); | |
ok(PXHLR.modules.subclass.childclass.grandBaby instanceof PXHLR.Module, "New instance"); | |
deepEqual(PXHLR.modules.subclass.childclass, Object.getPrototypeOf(PXHLR.modules.subclass.childclass.grandBaby), "grandBaby has childclass as its prototype"); | |
}); | |
// */ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Module pattern with extend method for submodule inheritance of module prototype. Inspired by http://www.terrifically.org/ module code organization uses methods for sub-routines : init, beforeBinding, onBinding, afterBinding
To log use #debug in the url when you run the index.html (QUnit) test file.