From 5b67a82b72aeeab6ba0460a8885135f4275e3fcc Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Mon, 10 Aug 2015 21:57:53 -0600 Subject: [PATCH] Upgrading to CommonJS modules! Goodbye globals! --- js/app.js | 25 +++++++++++++------------ js/controller.js | 5 +---- js/helpers.js | 38 +++++++++++++++++++++++--------------- js/model.js | 5 +---- js/store.js | 5 +---- js/template.js | 6 ++---- js/view.js | 14 ++++++++------ test/ControllerSpec.js | 4 ++-- 8 files changed, 51 insertions(+), 51 deletions(-) diff --git a/js/app.js b/js/app.js index 7c61725..311a04e 100755 --- a/js/app.js +++ b/js/app.js @@ -1,24 +1,25 @@ -/*global app, $on */ 'use strict'; require('todomvc-common/base.css'); require('todomvc-app-css/index.css'); -require('./view'); -require('./helpers'); -require('./controller'); -require('./model'); -require('./store'); -require('./template'); +var View = require('./view'); +var helpers = require('./helpers'); +var Controller = require('./controller'); +var Model = require('./model'); +var Store = require('./store'); +var Template = require('./template'); + +var $on = helpers.$on; /** * Sets up a brand new Todo list. * * @param {string} name The name of your new to do list. */ function Todo(name) { - this.storage = new app.Store(name); - this.model = new app.Model(this.storage); - this.template = new app.Template(); - this.view = new app.View(this.template); - this.controller = new app.Controller(this.model, this.view); + this.storage = new Store(name); + this.model = new Model(this.storage); + this.template = new Template(); + this.view = new View(this.template); + this.controller = new Controller(this.model, this.view); } var todo; diff --git a/js/controller.js b/js/controller.js index e1cb5dd..4f5e9a7 100755 --- a/js/controller.js +++ b/js/controller.js @@ -1,4 +1,5 @@ 'use strict'; +module.exports = Controller; /** * Takes a model and view and acts as the controller between them * @@ -259,7 +260,3 @@ Controller.prototype._updateFilterState = function (currentPage) { this.view.render('setFilter', currentPage); }; - -// Export to window -window.app = window.app || {}; -window.app.Controller = Controller; diff --git a/js/helpers.js b/js/helpers.js index 4cccd98..48b3fa2 100755 --- a/js/helpers.js +++ b/js/helpers.js @@ -1,24 +1,32 @@ /*global NodeList */ 'use strict'; -// Get element(s) by CSS selector: -window.qs = function (selector, scope) { - return (scope || document).querySelector(selector); -}; -window.qsa = function (selector, scope) { - return (scope || document).querySelectorAll(selector); +module.exports = { + qs: qs, + qsa: qsa, + $on: $on, + $delegate: $delegate, + $parent: $parent }; +// Get element(s) by CSS selector: +function qs(selector, scope) { + return (scope || document).querySelector(selector); +} +function qsa(selector, scope) { + return (scope || document).querySelectorAll(selector); +} + // addEventListener wrapper: -window.$on = function (target, type, callback, useCapture) { +function $on(target, type, callback, useCapture) { target.addEventListener(type, callback, !!useCapture); -}; +} // Attach a handler to event for all elements that match the selector, // now or in the future, based on a root element -window.$delegate = function (target, selector, type, handler) { +function $delegate(target, selector, type, handler) { function dispatchEvent(event) { var targetElement = event.target; - var potentialElements = window.qsa(selector, target); + var potentialElements = qsa(selector, target); var hasMatch = Array.prototype.indexOf.call(potentialElements, targetElement) >= 0; if (hasMatch) { @@ -29,20 +37,20 @@ window.$delegate = function (target, selector, type, handler) { // https://developer.mozilla.org/en-US/docs/Web/Events/blur var useCapture = type === 'blur' || type === 'focus'; - window.$on(target, type, dispatchEvent, useCapture); -}; + $on(target, type, dispatchEvent, useCapture); +} // Find the element's parent with the given tag name: // $parent(qs('a'), 'div'); -window.$parent = function (element, tagName) { +function $parent(element, tagName) { if (!element.parentNode) { return; } if (element.parentNode.tagName.toLowerCase() === tagName.toLowerCase()) { return element.parentNode; } - return window.$parent(element.parentNode, tagName); -}; + return $parent(element.parentNode, tagName); +} // Allow for looping on nodes by chaining: // qsa('.foo').forEach(function () {}) diff --git a/js/model.js b/js/model.js index 7f63113..d6049ca 100755 --- a/js/model.js +++ b/js/model.js @@ -1,4 +1,5 @@ 'use strict'; +module.exports = Model; /** * Creates a new Model instance and hooks up the storage. * @@ -113,7 +114,3 @@ Model.prototype.getCount = function (callback) { callback(todos); }); }; - -// Export to window -window.app = window.app || {}; -window.app.Model = Model; diff --git a/js/store.js b/js/store.js index 384ae84..5ef1eaf 100755 --- a/js/store.js +++ b/js/store.js @@ -1,5 +1,6 @@ /*jshint eqeqeq:false */ 'use strict'; +module.exports = Store; /** * Creates a new client side storage object and will create an empty * collection if no collection already exists. @@ -134,7 +135,3 @@ Store.prototype.drop = function (callback) { localStorage[this._dbName] = JSON.stringify({todos: []}); callback.call(this, JSON.parse(localStorage[this._dbName]).todos); }; - -// Export to window -window.app = window.app || {}; -window.app.Store = Store; diff --git a/js/template.js b/js/template.js index d9349bf..b6d1ca7 100755 --- a/js/template.js +++ b/js/template.js @@ -1,6 +1,8 @@ /*jshint laxbreak:true */ 'use strict'; +module.exports = Template; + var htmlEscapes = { '&': '&', '<': '<', @@ -106,7 +108,3 @@ Template.prototype.clearCompletedButton = function (completedTodos) { return ''; } }; - -// Export to window -window.app = window.app || {}; -window.app.Template = Template; diff --git a/js/view.js b/js/view.js index 3c3907e..0ce9ac5 100755 --- a/js/view.js +++ b/js/view.js @@ -1,6 +1,12 @@ -/*global qs, qsa, $on, $parent, $delegate */ 'use strict'; -require('./helpers'); +var helpers = require('./helpers'); +var qs = helpers.qs; +var qsa = helpers.qsa; +var $on = helpers.$on; +var $parent = helpers.$parent; +var $delegate = helpers.$delegate; + +module.exports = View; /** * View that abstracts away the browser's DOM completely. * It has two simple entry points: @@ -210,7 +216,3 @@ View.prototype.bind = function (event, handler) { that._bindItemEditCancel(handler); } }; - -// Export to window -window.app = window.app || {}; -window.app.View = View; diff --git a/test/ControllerSpec.js b/test/ControllerSpec.js index 3a953b8..fb654e6 100755 --- a/test/ControllerSpec.js +++ b/test/ControllerSpec.js @@ -1,5 +1,5 @@ /*global app, jasmine, describe, it, beforeEach, expect */ -require('../js/controller'); +var Controller = require('../js/controller'); describe('controller', function () { 'use strict'; @@ -56,7 +56,7 @@ describe('controller', function () { beforeEach(function () { model = jasmine.createSpyObj('model', ['read', 'getCount', 'remove', 'create', 'update']); view = createViewStub(); - subject = new app.Controller(model, view); + subject = new Controller(model, view); }); it('should show entries on start-up', function () {