Skip to content
This repository was archived by the owner on Jun 14, 2018. It is now read-only.

Commit 14f748f

Browse files
committed
Add development files
1 parent 9ebfdff commit 14f748f

5 files changed

+775
-0
lines changed

src/jquery.mvc.controller.js

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
( function( $, undefined ) {
2+
3+
var commandMap = {};
4+
5+
/**
6+
* The controller singleton of the jQuery.mvc manifold.
7+
*
8+
* <p>The controller assumes these responsibilities:</p>
9+
* <ul>
10+
* <li>Maintaining a cache of constructor functions for commands intended to handle
11+
* notifications.</li>
12+
* <li>Registering itself as an observer with the notifier dispatch for each notification
13+
* that it receives a command mapping for.</li>
14+
* <li>Creating and executing instances of the proper command to handle a given
15+
* notification received from jQuery.mvc.notifier.</li>
16+
* </ul>
17+
*/
18+
$.mvc.controller = {
19+
20+
/**
21+
* Checks if a notification has a command registered with the controller.
22+
* @param {String} The notification's name.
23+
* @return {Boolean} Whether a command is currently registered for the given notification.
24+
*/
25+
has: function( notificationName ) {
26+
return commandMap[ notificationName ] !== undefined;
27+
},
28+
29+
/**
30+
* Retrieves the constructor function for the <code>jQuery.mvc.Command</code> that is
31+
* registered for the given notification name.
32+
* @param {String} The notification's name.
33+
* @return {Function} The constructor function.
34+
*/
35+
get: function( name ) {
36+
return $.mvc.controller.has( name ) ? commandMap[ name ] : null;
37+
},
38+
39+
/**
40+
* Registers a constructor function for a <code>jQuery.mvc.Command</code> with the
41+
* controller. Individual instances of the command will be created and executed for
42+
* each matching notification observed.
43+
* @param {String} notificationName The notification for which the command shall
44+
* be executed.
45+
* @param {Function} command The command's constructor function.
46+
* @param {Object} options A hash of options with which instances of the
47+
* registered command will be configured before
48+
* execution.
49+
*/
50+
register: function( notificationName, command, options ) {
51+
var observer;
52+
53+
// Do not allow re-registration. If a command is already registered for the
54+
// notification name, it must be unregistered first.
55+
if ( $.mvc.controller.has( notificationName ) ) {
56+
throw "jQuery.mvc.controller: A command is already registered for notifications named '" + name + "'.";
57+
}
58+
59+
// Construct an observer around a factory method for the command prototype and
60+
// store it in the map. A reference to the controller object is used as the
61+
// observer's context. The context here serves no purpose other than being a
62+
// key used for later removal of the observer.
63+
observer = commandMap[ notificationName] = $.mvc.Observer( function( notification ) {
64+
var instance = new command( options );
65+
instance.execute( notification );
66+
}, $.mvc.controller );
67+
68+
// Register the command's observer.
69+
$.mvc.notifier.register( notificationName, observer );
70+
},
71+
72+
/**
73+
* Removes a command registered for a particular notifcation from the controller.
74+
* @param {String} notificationName The notification for which to remove the command.
75+
*/
76+
remove: function( notificationName ) {
77+
var observer = commandMap[ notificationName ];
78+
if ( observer !== undefined ) {
79+
80+
// Remove the command's observer, using the controller as the context and key.
81+
$.mvc.notifier.remove( notificationName, $.mvc.controller );
82+
83+
// Remove the observer from the map.
84+
delete commandMap[ notificationName ];
85+
}
86+
}
87+
}
88+
89+
/**
90+
* Creates a new jQuery.mvc command prototype with the given name. If the name includes
91+
* a leading namespace (separated from the name by a period), the prototype is stored at
92+
* the location jQuery.mvc.<namespace>.<name> for further use.
93+
* @param {String} name The name of the new command prototype, which may include
94+
* a leading namespace separated by a period.
95+
* @param {Object} base An optional base prototype from which to derive the new command
96+
* prototype. The base command <code>jQuery.mvc.Command</code> will
97+
* be used when this parameter is omitted.
98+
* @param {Object} proto The definition for the new command prototype.
99+
* @return {Function} The constructor function for the new command prototype.
100+
*/
101+
$.mvc.command = function( name, base, proto ) {
102+
103+
if ( typeof proto === "undefined" ) {
104+
proto = base;
105+
base = $.mvc.Command;
106+
}
107+
108+
return $.mvc.module( name, base, proto );
109+
}
110+
111+
/**
112+
* The base command from which all other commands that can be registered
113+
* with the jQuery.mvc manifold's controller should derive.
114+
* @constructor
115+
*/
116+
$.mvc.Command = $.mvc.module("Command", $.mvc.Module, {
117+
118+
/**
119+
* Executes the command whenever the notification it was registered for is observed.
120+
* @param {jQuery.mvc.Notification} notification The observed notification.
121+
*/
122+
execute: function( notification ) { }
123+
});
124+
125+
})( jQuery );

src/jquery.mvc.core.js

+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
( function( $, undefined ) {
2+
3+
// Make sure the jQuery.mvc namespace exists.
4+
$.mvc = $.mvc || {};
5+
6+
/**
7+
* Version indicator for the jQuery.mvc library.
8+
* @type String
9+
*/
10+
$.mvc.version = "1.0.0";
11+
12+
/**
13+
* Creates a new jQuery.mvc module prototype with the given name. If the name includes
14+
* a leading namespace (separated from the name by a dot), the prototype is stored at
15+
* the location jQuery.mvc.<namespace>.<name> for further use.
16+
* @param {String} name The name of the new module prototype, which may include a
17+
* leading dot separated namespace.
18+
* @param {Object} base The base module prototype from which to derive the new
19+
* module prototype.
20+
* @param {Object} proto The definition for the new module prototype.
21+
* @return {Function} The constructor function for the new module prototype.
22+
*/
23+
$.mvc.module = function( name, base, proto ) {
24+
var fullname, namespace, baseObj, namespaceObj;
25+
26+
// Resolve the module's name and namespace.
27+
fullname = name.split( "." );
28+
name = fullname[ 1 ] || fullname[ 0 ];
29+
namespace = fullname[ 0 ] === name ? "" : fullname[ 0 ];
30+
fullname = fullname.join( "-" );
31+
32+
// Create a new, uninitialized instance of the base MVC module and
33+
// deep copy its options onto the instance so they aren't shared
34+
// from the base prototype across multiple instances.
35+
baseObj = new base();
36+
baseObj.options = $.extend( true, {}, baseObj.options );
37+
38+
// Create the namespace for the new MVC module. This may be a temporary
39+
// object when no namespace was specified.
40+
namespaceObj = namespace
41+
? $.mvc[ namespace ] = $.mvc[ namespace ] || {}
42+
: {};
43+
44+
// Create a new constructor function. This has to be a new unique function
45+
// of which the prototype will be extended to create the new MVC module.
46+
namespaceObj[ name ] = function() {
47+
// Allow instantiation without initializing for simple inheritance
48+
if ( arguments.length ) {
49+
this._createModule.apply( this, arguments );
50+
}
51+
};
52+
53+
// Compose the complete prototype for the new MVC module.
54+
namespaceObj[ name ].prototype = $.extend( true, baseObj, {
55+
name : name,
56+
namespace : namespace,
57+
base : base.prototype,
58+
constructor : namespaceObj[ name ]
59+
}, proto );
60+
61+
// Add or replace the internal __super method where necessary.
62+
$.each( namespaceObj[ name ].prototype, function( name, fn ) {
63+
if ( name === "constructor" ) { return true; /* continue */ }
64+
65+
var fnSuper = base.prototype[ name ];
66+
if ( fn !== fnSuper && $.isFunction( fn ) && $.isFunction( fnSuper ) ) {
67+
fn.__super = fnSuper;
68+
}
69+
70+
});
71+
72+
return namespaceObj[ name ];
73+
}
74+
75+
76+
/**
77+
* @constructor
78+
* Creates a new jQuery.mvc module.
79+
* @param {String} name The module's registered name.
80+
* @param {Object} options A hash of options with which the module will
81+
* be configured.
82+
*/
83+
$.mvc.Module = function( name, options ) {
84+
85+
// Allow instantiation without initializing for simple inheritance
86+
if ( arguments.length > 0 ) {
87+
this._createModule.apply( this, arguments );
88+
}
89+
}
90+
91+
$.mvc.Module.prototype = {
92+
/**
93+
* The module's type name.
94+
* @type String
95+
*/
96+
name: "module",
97+
98+
/**
99+
* A hash of option values configuring the module.
100+
* @type Object
101+
*/
102+
options: { },
103+
104+
/**
105+
* Creates a new jQuery.mvc module.
106+
* @param {String} name The module's registered name.
107+
* @param {Object} options A hash of options with which the module will
108+
* be configured.
109+
*/
110+
_createModule: function( name, options ) {
111+
// The instance member reflects the instance name, while the prototype's
112+
// member reflects the type name.
113+
this.name = name;
114+
this.options = $.extend( true, {}, this.options, options );
115+
},
116+
117+
/**
118+
* Calls the 'super' version of the calling method in the module's base module.
119+
* <p>
120+
* The pattern relies on the arguments.callee and arguments.callee.caller properties
121+
* to store a reference on a function to its 'super' function and to obtain a reference
122+
* to the calling function, respectively. The result is a virtual function call that
123+
* will in all situations correctly handle the chain of inheritance -and- is safe for
124+
* use with reentrant callback functions.
125+
* </p>
126+
* <p>
127+
* Correctness comes at the cost of execution speed: the use of arguments.callee and
128+
* arguments.callee.caller is expensive in terms of limiting compiler optimizations.
129+
* It would be a bad idea to make many repeated calls to _super, e.g. , by using it
130+
* inside tight loops. * </p>
131+
* @param {*} ... A variable list of arguments to pass to the super method.
132+
* @return {*} The return value of the super method call.
133+
*/
134+
_super: function( /* ... */ ) {
135+
var caller = arguments.callee.caller;
136+
137+
if ( caller && $.isFunction( caller.__super ) ) {
138+
return caller.__super.apply( this, arguments );
139+
} else {
140+
throw "_super: No super-implementation available for this function."
141+
}
142+
},
143+
144+
/**
145+
* Gets the name of the MVC module's registered instance.
146+
* @returns {String} The instance's name.
147+
*/
148+
getName: function() { return this.name; },
149+
150+
/**
151+
* Broadcasts a notification to the jQuery.mvc manifold.
152+
* @param {String} name The notification's name.
153+
* @param {Object} body The notification's body or data.
154+
*/
155+
_notify: function( name, body ) {
156+
var notification = $.mvc.Notification( name, body );
157+
$.mvc.notifier.notify( notification );
158+
}
159+
}
160+
161+
})( jQuery );

0 commit comments

Comments
 (0)