extjs-mvc 0.4.0.j → 0.4.0.k

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. data/Rakefile +1 -1
  2. data/VERSION +1 -1
  3. data/lib/extjs-mvc.rb +0 -14
  4. data/lib/extjs-mvc/api.rb +14 -27
  5. data/lib/extjs-mvc/src/App.js +219 -0
  6. data/lib/extjs-mvc/src/MVC.js +260 -0
  7. data/lib/extjs-mvc/src/Presenter.js +52 -0
  8. data/lib/extjs-mvc/src/README.rdoc +69 -0
  9. data/lib/extjs-mvc/src/controller/Controller.js +278 -0
  10. data/lib/extjs-mvc/src/controller/CrudController.js +460 -0
  11. data/lib/extjs-mvc/src/lib/Array.js +26 -0
  12. data/lib/extjs-mvc/src/lib/Booter.js +417 -0
  13. data/lib/extjs-mvc/src/lib/ClassManager.js +191 -0
  14. data/lib/extjs-mvc/src/lib/ControllerClassManager.js +95 -0
  15. data/lib/extjs-mvc/src/lib/Dependencies.js +44 -0
  16. data/lib/extjs-mvc/src/lib/DispatchMatcher.js +98 -0
  17. data/lib/extjs-mvc/src/lib/Dispatcher.js +129 -0
  18. data/lib/extjs-mvc/src/lib/Environment.js +43 -0
  19. data/lib/extjs-mvc/src/lib/Inflector.js +155 -0
  20. data/lib/extjs-mvc/src/lib/ModelClassManager.js +19 -0
  21. data/lib/extjs-mvc/src/lib/Route.js +139 -0
  22. data/lib/extjs-mvc/src/lib/Router.js +282 -0
  23. data/lib/extjs-mvc/src/lib/String.js +94 -0
  24. data/lib/extjs-mvc/src/lib/ViewClassManager.js +229 -0
  25. data/lib/extjs-mvc/src/lib/notes.txt +32 -0
  26. data/lib/extjs-mvc/src/model/AdapterManager.js +30 -0
  27. data/lib/extjs-mvc/src/model/Association.js +26 -0
  28. data/lib/extjs-mvc/src/model/Base.js +63 -0
  29. data/lib/extjs-mvc/src/model/BelongsToAssociation.js +116 -0
  30. data/lib/extjs-mvc/src/model/Cache.js +131 -0
  31. data/lib/extjs-mvc/src/model/HasManyAssociation.js +160 -0
  32. data/lib/extjs-mvc/src/model/Model.js +331 -0
  33. data/lib/extjs-mvc/src/model/UrlBuilder.js +106 -0
  34. data/lib/extjs-mvc/src/model/adapters/AbstractAdapter.js +296 -0
  35. data/lib/extjs-mvc/src/model/adapters/MemoryAdapter.js +103 -0
  36. data/lib/extjs-mvc/src/model/adapters/RESTAdapter.js +345 -0
  37. data/lib/extjs-mvc/src/model/adapters/RESTJSONAdapter.js +68 -0
  38. data/lib/extjs-mvc/src/model/adapters/notes.txt +42 -0
  39. data/lib/extjs-mvc/src/model/associations/Association.js +192 -0
  40. data/lib/extjs-mvc/src/model/associations/notes.txt +87 -0
  41. data/lib/extjs-mvc/src/model/validations/Errors.js +136 -0
  42. data/lib/extjs-mvc/src/model/validations/Plugin.js +139 -0
  43. data/lib/extjs-mvc/src/model/validations/Validations.js +276 -0
  44. data/lib/extjs-mvc/src/notes/Charts.graffle +0 -0
  45. data/lib/extjs-mvc/src/overrides/Ext.Component.js +21 -0
  46. data/lib/extjs-mvc/src/overrides/Ext.extend.js +142 -0
  47. data/lib/extjs-mvc/src/spec/Array.spec.js +15 -0
  48. data/lib/extjs-mvc/src/spec/ExtMVC.spec.js +65 -0
  49. data/lib/extjs-mvc/src/spec/Model.spec.js +370 -0
  50. data/lib/extjs-mvc/src/spec/OS.spec.js +83 -0
  51. data/lib/extjs-mvc/src/spec/Router.spec.js +99 -0
  52. data/lib/extjs-mvc/src/spec/SpecHelper.js +106 -0
  53. data/lib/extjs-mvc/src/spec/String.spec.js +83 -0
  54. data/lib/extjs-mvc/src/spec/model/AbstractAdapter.spec.js +49 -0
  55. data/lib/extjs-mvc/src/spec/model/Associations.spec.js +99 -0
  56. data/lib/extjs-mvc/src/spec/model/Cache.spec.js +5 -0
  57. data/lib/extjs-mvc/src/spec/model/RESTAdapter.spec.js +19 -0
  58. data/lib/extjs-mvc/src/spec/model/ValidationErrors.spec.js +64 -0
  59. data/lib/extjs-mvc/src/spec/model/Validations.spec.js +166 -0
  60. data/lib/extjs-mvc/src/spec/model/ValidationsPlugin.spec.js +108 -0
  61. data/lib/extjs-mvc/src/spec/suite.html +60 -0
  62. data/lib/extjs-mvc/src/specs-old/JSSpec.css +216 -0
  63. data/lib/extjs-mvc/src/specs-old/JSSpec.js +1512 -0
  64. data/lib/extjs-mvc/src/specs-old/all.html +66 -0
  65. data/lib/extjs-mvc/src/specs-old/base.js +14 -0
  66. data/lib/extjs-mvc/src/specs-old/controller.js +17 -0
  67. data/lib/extjs-mvc/src/specs-old/diff_match_patch.js +1 -0
  68. data/lib/extjs-mvc/src/specs-old/model.js +70 -0
  69. data/lib/extjs-mvc/src/specs-old/route.js +38 -0
  70. data/lib/extjs-mvc/src/specs-old/router.js +59 -0
  71. data/lib/extjs-mvc/src/specs-old/string.js +22 -0
  72. data/lib/extjs-mvc/src/testrunner/JSpecFormatter.js +111 -0
  73. data/lib/extjs-mvc/src/testrunner/TestClient.js +181 -0
  74. data/lib/extjs-mvc/src/testrunner/TestGrid.js +351 -0
  75. data/lib/extjs-mvc/src/testrunner/TestRunner.js +110 -0
  76. data/lib/extjs-mvc/src/testrunner/TestViewport.js +94 -0
  77. data/lib/extjs-mvc/src/vendor.yml +30 -0
  78. data/lib/extjs-mvc/src/vendor/ext-3.1.1/vendor.yml +16 -0
  79. data/lib/extjs-mvc/src/view/FormWindow.js +184 -0
  80. data/lib/extjs-mvc/src/view/HasManyEditorGridPanel.js +211 -0
  81. data/lib/extjs-mvc/src/view/scaffold/Edit.js +46 -0
  82. data/lib/extjs-mvc/src/view/scaffold/Index.js +561 -0
  83. data/lib/extjs-mvc/src/view/scaffold/New.js +20 -0
  84. data/lib/extjs-mvc/src/view/scaffold/ScaffoldFormPanel.js +255 -0
  85. data/lib/{vendor.yml → extjs-mvc/vendor.yml} +0 -0
  86. data/test/app/vendor/extjs-mvc/App.js +219 -0
  87. data/test/app/vendor/extjs-mvc/MVC.js +260 -0
  88. data/test/app/vendor/extjs-mvc/Presenter.js +52 -0
  89. data/test/app/vendor/extjs-mvc/README.rdoc +69 -0
  90. data/test/app/vendor/extjs-mvc/controller/Controller.js +278 -0
  91. data/test/app/vendor/extjs-mvc/controller/CrudController.js +460 -0
  92. data/test/app/vendor/extjs-mvc/lib/Array.js +26 -0
  93. data/test/app/vendor/extjs-mvc/lib/Booter.js +417 -0
  94. data/test/app/vendor/extjs-mvc/lib/ClassManager.js +191 -0
  95. data/test/app/vendor/extjs-mvc/lib/ControllerClassManager.js +95 -0
  96. data/test/app/vendor/extjs-mvc/lib/Dependencies.js +44 -0
  97. data/test/app/vendor/extjs-mvc/lib/DispatchMatcher.js +98 -0
  98. data/test/app/vendor/extjs-mvc/lib/Dispatcher.js +129 -0
  99. data/test/app/vendor/extjs-mvc/lib/Environment.js +43 -0
  100. data/test/app/vendor/extjs-mvc/lib/Inflector.js +155 -0
  101. data/test/app/vendor/extjs-mvc/lib/ModelClassManager.js +19 -0
  102. data/test/app/vendor/extjs-mvc/lib/Route.js +139 -0
  103. data/test/app/vendor/extjs-mvc/lib/Router.js +282 -0
  104. data/test/app/vendor/extjs-mvc/lib/String.js +94 -0
  105. data/test/app/vendor/extjs-mvc/lib/ViewClassManager.js +229 -0
  106. data/test/app/vendor/extjs-mvc/lib/notes.txt +32 -0
  107. data/test/app/vendor/extjs-mvc/model/AdapterManager.js +30 -0
  108. data/test/app/vendor/extjs-mvc/model/Association.js +26 -0
  109. data/test/app/vendor/extjs-mvc/model/Base.js +63 -0
  110. data/test/app/vendor/extjs-mvc/model/BelongsToAssociation.js +116 -0
  111. data/test/app/vendor/extjs-mvc/model/Cache.js +131 -0
  112. data/test/app/vendor/extjs-mvc/model/HasManyAssociation.js +160 -0
  113. data/test/app/vendor/extjs-mvc/model/Model.js +331 -0
  114. data/test/app/vendor/extjs-mvc/model/UrlBuilder.js +106 -0
  115. data/test/app/vendor/extjs-mvc/model/adapters/AbstractAdapter.js +296 -0
  116. data/test/app/vendor/extjs-mvc/model/adapters/MemoryAdapter.js +103 -0
  117. data/test/app/vendor/extjs-mvc/model/adapters/RESTAdapter.js +345 -0
  118. data/test/app/vendor/extjs-mvc/model/adapters/RESTJSONAdapter.js +68 -0
  119. data/test/app/vendor/extjs-mvc/model/adapters/notes.txt +42 -0
  120. data/test/app/vendor/extjs-mvc/model/associations/Association.js +192 -0
  121. data/test/app/vendor/extjs-mvc/model/associations/notes.txt +87 -0
  122. data/test/app/vendor/extjs-mvc/model/validations/Errors.js +136 -0
  123. data/test/app/vendor/extjs-mvc/model/validations/Plugin.js +139 -0
  124. data/test/app/vendor/extjs-mvc/model/validations/Validations.js +276 -0
  125. data/test/app/vendor/extjs-mvc/notes/Charts.graffle +0 -0
  126. data/test/app/vendor/extjs-mvc/overrides/Ext.Component.js +21 -0
  127. data/test/app/vendor/extjs-mvc/overrides/Ext.extend.js +142 -0
  128. data/test/app/vendor/extjs-mvc/spec/Array.spec.js +15 -0
  129. data/test/app/vendor/extjs-mvc/spec/ExtMVC.spec.js +65 -0
  130. data/test/app/vendor/extjs-mvc/spec/Model.spec.js +370 -0
  131. data/test/app/vendor/extjs-mvc/spec/OS.spec.js +83 -0
  132. data/test/app/vendor/extjs-mvc/spec/Router.spec.js +99 -0
  133. data/test/app/vendor/extjs-mvc/spec/SpecHelper.js +106 -0
  134. data/test/app/vendor/extjs-mvc/spec/String.spec.js +83 -0
  135. data/test/app/vendor/extjs-mvc/spec/model/AbstractAdapter.spec.js +49 -0
  136. data/test/app/vendor/extjs-mvc/spec/model/Associations.spec.js +99 -0
  137. data/test/app/vendor/extjs-mvc/spec/model/Cache.spec.js +5 -0
  138. data/test/app/vendor/extjs-mvc/spec/model/RESTAdapter.spec.js +19 -0
  139. data/test/app/vendor/extjs-mvc/spec/model/ValidationErrors.spec.js +64 -0
  140. data/test/app/vendor/extjs-mvc/spec/model/Validations.spec.js +166 -0
  141. data/test/app/vendor/extjs-mvc/spec/model/ValidationsPlugin.spec.js +108 -0
  142. data/test/app/vendor/extjs-mvc/spec/suite.html +60 -0
  143. data/test/app/vendor/extjs-mvc/specs-old/JSSpec.css +216 -0
  144. data/test/app/vendor/extjs-mvc/specs-old/JSSpec.js +1512 -0
  145. data/test/app/vendor/extjs-mvc/specs-old/all.html +66 -0
  146. data/test/app/vendor/extjs-mvc/specs-old/base.js +14 -0
  147. data/test/app/vendor/extjs-mvc/specs-old/controller.js +17 -0
  148. data/test/app/vendor/extjs-mvc/specs-old/diff_match_patch.js +1 -0
  149. data/test/app/vendor/extjs-mvc/specs-old/model.js +70 -0
  150. data/test/app/vendor/extjs-mvc/specs-old/route.js +38 -0
  151. data/test/app/vendor/extjs-mvc/specs-old/router.js +59 -0
  152. data/test/app/vendor/extjs-mvc/specs-old/string.js +22 -0
  153. data/test/app/vendor/extjs-mvc/testrunner/JSpecFormatter.js +111 -0
  154. data/test/app/vendor/extjs-mvc/testrunner/TestClient.js +181 -0
  155. data/test/app/vendor/extjs-mvc/testrunner/TestGrid.js +351 -0
  156. data/test/app/vendor/extjs-mvc/testrunner/TestRunner.js +110 -0
  157. data/test/app/vendor/extjs-mvc/testrunner/TestViewport.js +94 -0
  158. data/test/app/vendor/extjs-mvc/vendor.yml +30 -0
  159. data/test/app/vendor/extjs-mvc/vendor/ext-3.1.1/vendor.yml +16 -0
  160. data/test/app/vendor/extjs-mvc/view/FormWindow.js +184 -0
  161. data/test/app/vendor/extjs-mvc/view/HasManyEditorGridPanel.js +211 -0
  162. data/test/app/vendor/extjs-mvc/view/scaffold/Edit.js +46 -0
  163. data/test/app/vendor/extjs-mvc/view/scaffold/Index.js +561 -0
  164. data/test/app/vendor/extjs-mvc/view/scaffold/New.js +20 -0
  165. data/test/app/vendor/extjs-mvc/view/scaffold/ScaffoldFormPanel.js +255 -0
  166. data/test/helper.rb +7 -1
  167. data/test/test_extjs-mvc.rb +46 -0
  168. metadata +167 -7
  169. data/test/test_extjs-mvc-gem.rb +0 -7
@@ -0,0 +1,95 @@
1
+ /**
2
+ * @class ExtMVC.lib.ControllerClassManager
3
+ * @extends ExtMVC.lib.ClassManager
4
+ * Customised class manager for managing Controllers
5
+ */
6
+ ExtMVC.lib.ControllerClassManager = Ext.extend(ExtMVC.lib.ClassManager, {
7
+ constructor: function(config) {
8
+ config = config || {};
9
+
10
+ Ext.applyIf(config, {
11
+ /**
12
+ * @property instances
13
+ * @type Object
14
+ * {name: instance} mapping of any classes which have been instantiated with this manager
15
+ * This is only really used for controllers, where there is only ever one instance at a time
16
+ */
17
+ instances: {},
18
+
19
+ /**
20
+ * @property autoInstantiate
21
+ * @type Boolean
22
+ * If true, the ClassManager will attempt to instantiate controllers immediately after they are defined (defaults to true)
23
+ */
24
+ autoInstantiate: true
25
+ });
26
+
27
+ ExtMVC.lib.ControllerClassManager.superclass.constructor.call(this, config);
28
+
29
+ this.addEvents(
30
+ /**
31
+ * @event class-instantiated
32
+ * Fires when a class in this manager has been instantiated by the manager. This is mostly
33
+ * useful when using autoInstantiate, e.g. for classes for which there should only be one instance
34
+ * @param {String} name The name of the class that was instantiated
35
+ * @param {Object} instance The instance that was just created
36
+ */
37
+ 'class-instantiated'
38
+ );
39
+ },
40
+
41
+ define: function(name) {
42
+ var overrides = this.getRegistered(name);
43
+
44
+ if (overrides == undefined) {
45
+ throw new Ext.Error(String.format("The {0} controller could not be found", name));
46
+ }
47
+
48
+ //set 'application' as the default controller to inherit from
49
+ var superclass = name == "controller" ? Ext.util.Observable : this.getConstructor(overrides.extend || "application");
50
+
51
+ //extend the parent object and register the constructor
52
+ var klass = Ext.extend(superclass, overrides);
53
+ this.constructors[name] = klass;
54
+
55
+ if (this.autoInstantiate === true) this.instantiate(name);
56
+
57
+ this.fireEvent('class-defined', name, klass);
58
+
59
+ return klass;
60
+ },
61
+
62
+ /**
63
+ * Instantiates the given class name, with an optional config object (usually the config is not needed)
64
+ *
65
+ */
66
+ instantiate: function(name, config) {
67
+ //get the controller instance that has already been created
68
+ var instance = this.instances[name];
69
+
70
+ //if the instance isn't defined yet, instantiate it now and cache it
71
+ if (instance == undefined) {
72
+ instance = new (this.getConstructor(name))(config);
73
+ instance.name = name;
74
+ // instance.superclass =
75
+
76
+ this.instances[name] = instance;
77
+
78
+ this.fireEvent('class-instantiated', name, instance);
79
+ }
80
+
81
+ return instance;
82
+ },
83
+
84
+ /**
85
+ * Only really useful for controllers, this returns the canonical instance for a given
86
+ * class name (e.g. getInstance('funds') would return the Funds Controller, instaniating first if required)
87
+ * @param {String} name The name of the class to instantiate
88
+ * @return {Object} The canonical instance of this class
89
+ */
90
+ getInstance: function(name) {
91
+ return this.instances[name] || this.instantiate(name);
92
+ }
93
+ });
94
+
95
+ ExtMVC.registerClassManager('controller', new ExtMVC.lib.ControllerClassManager());
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @class ExtMVC.lib.Dependencies
3
+ * @extends Ext.util.Observable
4
+ * Very simply dependency management class
5
+ */
6
+ ExtMVC.lib.Dependencies = Ext.extend(Ext.util.Observable, {
7
+
8
+ constructor: function() {
9
+
10
+ /**
11
+ * @property dependencies
12
+ * @type Object
13
+ * An object of model creation configurations awaiting definition because their dependency model(s) have not yet
14
+ * been defined. e.g. {'User': [{name: 'SuperUser', config: someConfigObject}, {name: 'AdminUser', config: anotherCfgObj}]}
15
+ * signifies that SuperUser and AdminUser should be defined as soon as User has been defined
16
+ */
17
+ this.dependencies = {};
18
+
19
+ ExtMVC.lib.Dependencies.superclass.constructor.apply(this, arguments);
20
+ },
21
+
22
+ /**
23
+ * Returns an array of any Model subclasses waiting for this model to be defined
24
+ * @param {String} dependencyName The dependency model name to check against
25
+ * @return {Array} An array of items dependent on this item being defined (e.g. [{name: 'MyModel', config: someObject}])
26
+ */
27
+ get: function(dependencyName) {
28
+ return this.dependencies[dependencyName] || [];
29
+ },
30
+
31
+ /**
32
+ * Adds a model definition to the dependencies object if it is waiting for another model to be defined first
33
+ * @param {String} dependencyName The name of another model which must be created before this one
34
+ * @param {String} dependentName The name of the new model to be defined after its dependency
35
+ * @param {Object} config The new model's config object, as sent to ExtMVC.model.define
36
+ */
37
+ add: function(dependencyName, dependentName, config) {
38
+ var arr = this.dependencies[dependencyName] || [];
39
+
40
+ arr.push({name: dependentName, config: config});
41
+
42
+ this.dependencies[dependencyName] = arr;
43
+ }
44
+ });
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @class ExtMVC.lib.DispatchMatcher
3
+ * @extends Object
4
+ * Abstract base class for dispatch matchers. A Dispatch Matcher just takes the arguments that
5
+ * are passed to an ExtMVC.lib.Dispatcher's dispatch method, and returns normalised arguments.
6
+ * This allows the Dispatcher to accept numerous forms, such as:
7
+ * dispatch('controllerName', 'actionName', ['list', 'of', 'arguments'])
8
+ * dispatch({controller: 'controllerName', action: 'actionName', arguments: ['list', 'of', 'arguments']})
9
+ * dispatch("controller/action/123")
10
+ */
11
+ ExtMVC.lib.DispatchMatcher = Ext.extend(Object, {
12
+
13
+ constructor: function(config) {
14
+ Ext.applyIf(this, config || {});
15
+
16
+ ExtMVC.lib.DispatchMatcher.superclass.constructor.apply(this, arguments);
17
+ },
18
+
19
+ matches: function() {
20
+ throw new Ext.Error("DispatchMatcher subclass must implement this method");
21
+ },
22
+
23
+ /**
24
+ * Returns an object like the following:
25
+ * {
26
+ * controller: 'someControllerName',
27
+ * action : 'someActionName',
28
+ * arguments : ['some', 'list', 'of', 'arguments']
29
+ * }
30
+ */
31
+ getDispatchConfig: function() {
32
+ throw new Ext.Error("DispatchMatcher subclass must implement this method");
33
+ }
34
+ });
35
+
36
+ /**
37
+ * @class ExtMVC.lib.DefaultDispatchMatcher
38
+ * @extends ExtMVC.lib.DispatchMatcher
39
+ * Dispatch matcher that accepts arguments in the form (controller, action, [args])
40
+ */
41
+ ExtMVC.lib.DefaultDispatchMatcher = Ext.extend(ExtMVC.lib.DispatchMatcher, {
42
+ name: 'default',
43
+
44
+ /**
45
+ * Returns true if the supplied arguments look like ('controllerName', 'actionName', ['args'])
46
+ */
47
+ matches: function(controller, action, args) {
48
+ return Ext.isString(controller) && Ext.isString(action) && Ext.isArray(args || []);
49
+ },
50
+
51
+ getDispatchConfig: function() {
52
+ return {
53
+ controller: arguments[0],
54
+ action : arguments[1],
55
+ arguments : arguments[2] || []
56
+ };
57
+ }
58
+ });
59
+
60
+ /**
61
+ * @class ExtMVC.lib.ObjectDispatchMatcher
62
+ * @extends ExtMVC.lib.DispatchMatcher
63
+ * Dispatch matcher that accepts arguments in the form ({controller: controller, action: action, arguments: [args]})
64
+ */
65
+ ExtMVC.lib.ObjectDispatchMatcher = Ext.extend(ExtMVC.lib.DispatchMatcher, {
66
+ name: 'object',
67
+
68
+ /**
69
+ * Returns true if the supplied arguments are parseable by this matcher
70
+ * @return {Boolean} true if this matcher matches the supplied arguments
71
+ */
72
+ matches: function() {
73
+ var obj = arguments[0];
74
+
75
+ //set the default action to 'index', if not supplied
76
+ Ext.applyIf(obj, {
77
+ action: 'index'
78
+ });
79
+
80
+ return arguments.length == 1 && obj.controller != undefined && obj.action != undefined;
81
+ },
82
+
83
+ getDispatchConfig: function() {
84
+ return arguments[0];
85
+ }
86
+ });
87
+
88
+
89
+ /**
90
+ * @class ExtMVC.lib.RouterDispatchManager
91
+ * @extends ExtMVC.lib.DispatchMatcher
92
+ * Dispatch matcher that uses a Router to match a given string and split it into suitable arguments
93
+ */
94
+ ExtMVC.lib.RouterDispatchManager = Ext.extend(ExtMVC.lib.DispatchMatcher, {
95
+ name: 'router'
96
+
97
+ //TODO
98
+ });
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @class ExtMVC.lib.Dispatcher
3
+ * @extends Ext.util.MixedCollection
4
+ * Normalises dispatch info received by an application, finds and calls the relevant controller action
5
+ * with any arguments supplied
6
+ */
7
+ ExtMVC.lib.Dispatcher = Ext.extend(Ext.util.MixedCollection, {
8
+
9
+ constructor: function(config) {
10
+ ExtMVC.lib.Dispatcher.superclass.constructor.apply(this, arguments);
11
+
12
+ Ext.apply(this, config || {}, {
13
+ /**
14
+ * @property matchers
15
+ * @type Array
16
+ * All registered Dispatch Matchers
17
+ */
18
+ matchers: [],
19
+
20
+ /**
21
+ * @cfg matcherOrder
22
+ * @type Array
23
+ * An array of strings that correspond to DispatchMatcher names. This defines the order
24
+ * in which dispatch matchers will be called. Override if you wish to inject your own matchers
25
+ * before the default ones. This is empty by default, and pushed to whenever a matcher is registered
26
+ */
27
+ matcherOrder: []
28
+ });
29
+
30
+ this.addEvents(
31
+ /**
32
+ * @event dispatch
33
+ * Fires before the dispatcher dispatches a request. Return false to cancel
34
+ * @param {Array} arguments The arguments receivd by the dispatcher
35
+ * @param {ExtMVC.lib.DispatchMatcher} matcher The DispatchMatcher instance that will be used
36
+ * @param {Object} dispatchConfig An object containing controller, action and arguments properties
37
+ */
38
+ 'dispatch'
39
+ );
40
+
41
+ this.registerDefaultDispatchMatchers();
42
+ },
43
+
44
+ /**
45
+ * Dispatches to a controller action. Takes numerous argument formats, such as:
46
+ <pre>
47
+ <ul>
48
+ <li>dispatch('controllerName', 'actionName', ['list', 'of', 'arguments'])</li>
49
+ <li>dispatch({controller: 'controllerName', action: 'actionName', arguments: ['list', 'of', 'arguments']})</li>
50
+ </ul>
51
+ </pre>
52
+ * These are normalised, the controller found and the action called with the supplied arguments.
53
+ */
54
+ dispatch: function() {
55
+ var matcher = this.getDispatchMatcher.apply(this, arguments),
56
+ config = matcher.getDispatchConfig.apply(matcher, arguments);
57
+
58
+ //fire the 'dispatch' event, and then dispatch if no listeners return false
59
+ if (this.fireEvent('dispatch', arguments, matcher, config) !== false) {
60
+ var controller = ExtMVC.getController(config.controller);
61
+
62
+ if (controller == undefined) {
63
+ throw new Ext.Error(
64
+ String.format("The controller you are trying to dispatch to ({0}) does not exist", config.controller)
65
+ );
66
+ }
67
+
68
+ if (controller[config.action] == undefined) {
69
+ throw new Ext.Error(
70
+ String.format("The action {0} does not exist on the {1} controller", config.action, config.controller)
71
+ );
72
+ }
73
+
74
+ //if controller and action both exist, dispatch now
75
+ return controller[config.action].apply(controller, config.arguments);
76
+ }
77
+ },
78
+
79
+ /**
80
+ * Registers a dispatch matcher for use with this dispatcher.
81
+ * @param {ExtMVC.lib.DispatchMatcher} matcher The matcher to register
82
+ */
83
+ registerDispatchMatcher: function(matcher) {
84
+ this.add(matcher);
85
+
86
+ this.matcherOrder.push(matcher.name);
87
+ },
88
+
89
+ /**
90
+ * Adds the default dispatch matchers. This is called automatically by the constructor
91
+ */
92
+ registerDefaultDispatchMatchers: function() {
93
+ this.registerDispatchMatcher(new ExtMVC.lib.DefaultDispatchMatcher());
94
+ this.registerDispatchMatcher(new ExtMVC.lib.ObjectDispatchMatcher());
95
+ },
96
+
97
+ /**
98
+ * @private
99
+ * Returns a DispatchMatcher object if any matchers match the supplied dispatch format
100
+ */
101
+ getDispatchMatcher: function() {
102
+ var dispatchArgs = arguments,
103
+ dispatchMatcher;
104
+
105
+ Ext.each(this.matcherOrder, function(name) {
106
+ var matcher = this.get(name);
107
+
108
+ if (matcher.matches.apply(matcher, dispatchArgs)) {
109
+ dispatchMatcher = matcher;
110
+
111
+ //stops Ext.each
112
+ return false;
113
+ }
114
+ }, this);
115
+
116
+ if (dispatchMatcher == undefined) {
117
+ throw new Ext.Error("Could not find a suitable Dispatch Matcher for the dispatch arguments provided", dispatchArgs);
118
+ } else {
119
+ return dispatchMatcher;
120
+ }
121
+ },
122
+
123
+ /**
124
+ * @private
125
+ */
126
+ getKey: function(item) {
127
+ return item.name;
128
+ }
129
+ });
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @class ExtMVC.Environment
3
+ * @extends Ext.util.Observable
4
+ * Represents an application in which to load an application. This is used by the
5
+ * environment files inside the public/config and public/config/environments directories
6
+ *
7
+ */
8
+ ExtMVC.Environment = Ext.extend(Ext.util.Observable, {
9
+
10
+ constructor: function(config) {
11
+ config = config || {};
12
+
13
+ Ext.apply(this, config, {
14
+ //TODO: jsdoc these defaults
15
+ pluginsDir : '../vendor/plugins',
16
+ libDir : '../lib',
17
+ configDir : '../config',
18
+ overridesDir: '../config/overrides',
19
+ appDir : '../app',
20
+ vendor : ['mvc'],
21
+ mvcFilename : 'ext-mvc-all-min',
22
+ config : ['app/App', 'config/routes'],
23
+
24
+ /**
25
+ * @property stylesheets
26
+ * @type Array
27
+ * The stylesheets to load for this app (defaults to just ext-all)
28
+ */
29
+ stylesheets: ['ext-all']
30
+ });
31
+
32
+ ExtMVC.Environment.superclass.constructor.apply(this, arguments);
33
+ },
34
+
35
+ /**
36
+ * Updates this environment by applying the updates argument to itself
37
+ * @param {Object} updates Any updated values to apply to the Environment
38
+ * @return {ExtMVC.Environment} The environment object
39
+ */
40
+ update: function(updates) {
41
+ Ext.apply(this, updates);
42
+ }
43
+ });
@@ -0,0 +1,155 @@
1
+ /*
2
+ * Adapted from http://snippets.dzone.com/posts/show/3205
3
+ */
4
+
5
+ ExtMVC.Inflector = {
6
+ /*
7
+ * The order of all these lists has been reversed from the way
8
+ * ActiveSupport had them to keep the correct priority.
9
+ */
10
+ Inflections: {
11
+ plural: [
12
+ [(/(quiz)$/i), "$1zes" ],
13
+ [(/^(ox)$/i), "$1en" ],
14
+ [(/([m|l])ouse$/i), "$1ice" ],
15
+ [(/(matr|vert|ind)ix|ex$/i), "$1ices" ],
16
+ [(/(x|ch|ss|sh)$/i), "$1es" ],
17
+ [(/([^aeiouy]|qu)y$/i), "$1ies" ],
18
+ [(/(hive)$/i), "$1s" ],
19
+ [(/(?:([^f])fe|([lr])f)$/i), "$1$2ves"],
20
+ [(/sis$/i), "ses" ],
21
+ [(/([ti])um$/i), "$1a" ],
22
+ [(/(buffal|tomat)o$/i), "$1oes" ],
23
+ [(/(bu)s$/i), "$1ses" ],
24
+ [(/(alias|status)$/i), "$1es" ],
25
+ [(/(octop|vir)us$/i), "$1i" ],
26
+ [(/(ax|test)is$/i), "$1es" ],
27
+ [(/s$/i), "s" ],
28
+ [(/$/), "s" ]
29
+ ],
30
+ singular: [
31
+ [(/(quiz)zes$/i), "$1" ],
32
+ [(/(matr)ices$/i), "$1ix" ],
33
+ [(/(vert|ind)ices$/i), "$1ex" ],
34
+ [(/^(ox)en/i), "$1" ],
35
+ [(/(alias|status)es$/i), "$1" ],
36
+ [(/(octop|vir)i$/i), "$1us" ],
37
+ [(/(cris|ax|test)es$/i), "$1is" ],
38
+ [(/(shoe)s$/i), "$1" ],
39
+ [(/(o)es$/i), "$1" ],
40
+ [(/(bus)es$/i), "$1" ],
41
+ [(/([m|l])ice$/i), "$1ouse" ],
42
+ [(/(x|ch|ss|sh)es$/i), "$1" ],
43
+ [(/(m)ovies$/i), "$1ovie" ],
44
+ [(/(s)eries$/i), "$1eries"],
45
+ [(/([^aeiouy]|qu)ies$/i), "$1y" ],
46
+ [(/([lr])ves$/i), "$1f" ],
47
+ [(/(tive)s$/i), "$1" ],
48
+ [(/(hive)s$/i), "$1" ],
49
+ [(/([^f])ves$/i), "$1fe" ],
50
+ [(/(^analy)ses$/i), "$1sis" ],
51
+ [(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i), "$1$2sis"],
52
+ [(/([ti])a$/i), "$1um" ],
53
+ [(/(n)ews$/i), "$1ews" ],
54
+ [(/s$/i), "" ]
55
+ ],
56
+ irregular: [
57
+ ['move', 'moves' ],
58
+ ['sex', 'sexes' ],
59
+ ['child', 'children'],
60
+ ['man', 'men' ],
61
+ ['person', 'people' ]
62
+ ],
63
+ uncountable: [
64
+ "sheep",
65
+ "fish",
66
+ "series",
67
+ "species",
68
+ "money",
69
+ "rice",
70
+ "information",
71
+ "equipment"
72
+ ]
73
+ },
74
+
75
+ ordinalize: function(number) {
76
+ if (11 <= parseInt(number, 10) % 100 && parseInt(number, 10) % 100 <= 13) {
77
+ return number + "th";
78
+ } else {
79
+ switch (parseInt(number, 10) % 10) {
80
+ case 1: return number + "st";
81
+ case 2: return number + "nd";
82
+ case 3: return number + "rd";
83
+ default: return number + "th";
84
+ }
85
+ }
86
+ },
87
+
88
+ camelize: function(str) {
89
+ return (str.charAt(0).toUpperCase()+str.slice(1)).replace(/[\-_]+(\S)?/g, function(match, chr) {
90
+ return chr ? chr.toUpperCase() : '';
91
+ });
92
+ },
93
+
94
+ // From http://code.google.com/p/inflection-js/source/browse/trunk/inflection.js
95
+ underscore: function(str) {
96
+ var str_path=str.split('::');
97
+ var upCase=new RegExp('([A-Z])','g');
98
+ var fb=new RegExp('^_');
99
+ for(var i=0;i<str_path.length;i++)
100
+ str_path[i]=str_path[i].replace(upCase,'_$1').replace(fb,'');
101
+ str=str_path.join('/').toLowerCase();
102
+ return str;
103
+ },
104
+
105
+ pluralize: function(word) {
106
+ var unusual = ExtMVC.Inflector.uncountableOrIrregular(word);
107
+ if (unusual) { return unusual; }
108
+
109
+ for (var i = 0; i < ExtMVC.Inflector.Inflections.plural.length; i++) {
110
+ var regex = ExtMVC.Inflector.Inflections.plural[i][0];
111
+ var replace_string = ExtMVC.Inflector.Inflections.plural[i][1];
112
+ if (regex.test(word)) {
113
+ return word.replace(regex, replace_string);
114
+ }
115
+ }
116
+
117
+ //return the word if it is already pluralized
118
+ return word;
119
+ },
120
+
121
+ singularize: function(word) {
122
+ var unusual = ExtMVC.Inflector.uncountableOrIrregular(word);
123
+ if (unusual) { return unusual; }
124
+
125
+ for (var i = 0; i < ExtMVC.Inflector.Inflections.singular.length; i++) {
126
+ var regex = ExtMVC.Inflector.Inflections.singular[i][0];
127
+ var replace_string = ExtMVC.Inflector.Inflections.singular[i][1];
128
+
129
+ if (regex.test(word)) {
130
+ return word.replace(regex, replace_string);
131
+ }
132
+ }
133
+
134
+ //return the word if it is already singularized
135
+ return word;
136
+ },
137
+
138
+ uncountableOrIrregular: function(word) {
139
+ for (var i = 0; i < ExtMVC.Inflector.Inflections.uncountable.length; i++) {
140
+ var uncountable = ExtMVC.Inflector.Inflections.uncountable[i];
141
+ if (word.toLowerCase == uncountable) {
142
+ return uncountable;
143
+ }
144
+ }
145
+ for (var i = 0; i < ExtMVC.Inflector.Inflections.irregular.length; i++) {
146
+ var singular = ExtMVC.Inflector.Inflections.irregular[i][0];
147
+ var plural = ExtMVC.Inflector.Inflections.irregular[i][1];
148
+ if ((word.toLowerCase == singular) || (word == plural)) {
149
+ return plural;
150
+ }
151
+ }
152
+
153
+ return false;
154
+ }
155
+ };