This repository was archived by the owner on Jan 13, 2022. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathmodule.js
More file actions
138 lines (115 loc) · 3.82 KB
/
Copy pathmodule.js
File metadata and controls
138 lines (115 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
;(function(context) {
'use strict';
// Create a new module.
// Define the namespace and runs the specified callback.
// By default, the last namespace component will be defined as
// as function. You can create a regular object by setting the
// third argument to anything you want.
//
// Module("Todo.Application", function(Application) {
// Application.fn.initialize = function() {};
// });
//
// The module's prototype will be defined as a shortcut called `Module#fn`.
// Any initialization must be performed on the `Module#initialize()` function.
function Module(namespace, callback, object) {
var components = namespace.split(/[.:]+/);
var scope = context;
var component, last;
if (typeof callback !== 'function') {
object = callback;
callback = null;
}
object = object || build();
// Process all components but the last, which will store the
// specified object attribute.
for (var i = 0, count = components.length; i < count; i++) {
last = (i == count - 1);
scope[components[i]] = (last ? object : scope[components[i]] || {});
scope = scope[components[i]];
}
if (callback) {
callback.call(scope, scope, scope.prototype);
}
return scope;
}
// Retrieve a module by its namespace. Return null if not defined.
Module.fetch = function(namespace) {
var components = namespace.split('.');
var scope = context;
for (var i = 0, count = components.length; i < count; i++) {
scope = scope[components[i]];
if (!scope) {
break;
}
}
return scope;
};
// Run the specified module and return the instance.
Module.run = function(namespace, args) {
var module = Module.fetch(namespace);
if (typeof module === 'function') {
return module.apply(null, args || []);
}
};
// Build a new module with the correct attributes and methods.
function build() {
var Constructor, Instance;
Constructor = function() {
// Initialize a new instance, which won't do nothing but
// inheriting the prototype.
var instance = new Instance();
// Apply the initializer on the given instance.
instance.initialize.apply(instance, arguments);
return instance;
};
// Define the function that will be used to
// initialize the instance.
Instance = function() {};
Instance.prototype = Constructor.prototype;
// Save some typing and make an alias to the prototype.
try {
Object.defineProperty(Constructor, 'fn', {
configurable: false,
enumerable: false,
writable: false,
value: Constructor.prototype
});
} catch (error) {
Constructor.fn = Constructor.prototype;
}
// Define a noop initializer.
Constructor.fn.initialize = function() {};
return Constructor;
}
// Sometimes you want to define your own wrapper, with custom initialization.
// In this case, you can use the `Module.wrapper` function.
//
// Module.wrapper("MyApp.Model", function(namespace, callback) {
// Module(namespace, function(Model) {
// $.extend(Model, Validations);
// $.extend(Model, MassAssignment);
//
// Model.fn.initialize = function(attributes) {
// this.assignAttributes(attributes);
// };
// });
// });
//
// MyApp.Model("MyApp.User", function(User) {
// User.validates("name", {presence: true});
// });
//
// var user = MyApp.User();
//
Module.wrapper = function(namespace, initializer) {
return Module(namespace, function(Definition) {
Definition.fn.initialize = function(namespace, callback) {
initializer.apply(Definition, arguments);
};
return Definition;
});
};
// Expose the module function.
context.Module = Module;
})(window);