Skip to content

Commit

Permalink
Refactor namespace code.
Browse files Browse the repository at this point in the history
  • Loading branch information
reason-bv committed Sep 3, 2015
1 parent 6931997 commit 99cd523
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 27 deletions.
19 changes: 4 additions & 15 deletions lib/browser/application.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
/* global APP_NAMESPACE */
'use strict';

/**
* A module for registering an application. It creates a property
* on global.NS using the application name, and exposes a render
* method on an object there.
* A module for registering an application. It creates a property on global.NS
* using the application name, and exposes a render method on an object there.
*/
'use strict';

var NS = require('./namespace');

module.exports = function (name, config) {
if (NS.hasOwnProperty(name)) {
throw new Error(
'Cannot register ' + name +
' because a property with that name already exists' +
' on window.' + APP_NAMESPACE);
}

NS[name] = new Application(config);
NS.registerProperty(name, new Application(config));
return NS[name];
};


function Application (config) {
this.config = config;
this._renderQueue = [];
Expand Down
7 changes: 2 additions & 5 deletions lib/browser/kernel.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
/* global APP_NAMESPACE */
'use strict';

/**
* Entry point for scout files. This module sets up the namespace, requires
* all application modules, and finally exports the namespace on the global
* object.
* all application modules, and finally exports the namespace.
*
* @module
*/

var NS = require('./namespace');
var global = require('./global');

// begin application module require blocks
/* APP_MODULES */
// end application module require blocks

module.exports = global[APP_NAMESPACE] = NS;
module.exports = NS;
14 changes: 7 additions & 7 deletions lib/browser/namespace.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* global APP_NAMESPACE */

/**
* Define the shared namespace; if there is already an object on
* window at the namespace property, use it.
* Define the namespace name with a flag (APP_NAMESPACE) that will be replaced
* with a string in the webpack build.
*
* APP_NAMESPACE will be replaced with the value passed to webpack
* options.namespace or the default namespace name.
*/
'use strict';

var global = require('./global');
var NS = typeof global[APP_NAMESPACE] === 'object' ?
global[APP_NAMESPACE] : {};
var namespacer = require('./namespacer');

module.exports = NS;
module.exports = namespacer.namespace(APP_NAMESPACE);
83 changes: 83 additions & 0 deletions lib/browser/namespacer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
'use strict';

/**
* A namespace generator.
*
* @module
*/

var global = require('./global');

/**
* A namespace.
*
* @class
*/
function Namespace (name) {
this.name = name;
}

/**
* Register a property in the namespace, such as an application instance.
*
* Attempting to register the same property twice is almost always an error, and
* thus results in a thrown exception.
*
* @param {String} name The property name.
* @param {Mixed} value The property value.
*/
Namespace.prototype.registerProperty = function (name, value) {
if (this.hasOwnProperty(name)) {
throw new Error(
'Cannot register ' + name +
' because a property with that name already exists on window.' +
this.name
);
}

this[name] = value;
return this;
};

module.exports = {
/**
* Obtain a namespace object, creating one if necessary.
*
* The namespace will be assigned to the global (window) object as a property
* with the provided name.
*
* @param {String} name The namespace name.
* @return {Mixed} The namespace.
*/
namespace: function (name) {
// There is no value yet assigned for this namespace.
if (global[name] === undefined) {
global[name] = new Namespace(name);
}
// A namespace object already exists, which may or may not be a Namespace
// instance.
else if (typeof global[name] === 'object') {
// If we have an existing object literal then give it the necessary
// decorations and functions that a Namespace instance would have.
//
// Other code may have a reference to the object, so we can't do anything
// more drastic such as replacing it.
if (!(global[name] instanceof Namespace)) {
Namespace.call(global[name], name);
for (var prop in Namespace.prototype) {
global[name][prop] = Namespace.prototype[prop];
}
}
}
// Otherwise other code is using this global name for another purpose, so
// throw.
else {
throw new Error(
'Namespace ' + name + ' cannot be created.' +
' A non-object variable is already assigned to window.' + name
);
}

return global[name];
}
};

0 comments on commit 99cd523

Please sign in to comment.