sproutcore 1.5.0.pre.4.1 → 1.5.0.pre.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. data/CHANGELOG +7 -0
  2. data/VERSION.yml +1 -1
  3. data/lib/buildtasks/manifest.rake +4 -3
  4. data/lib/frameworks/sproutcore/Buildfile +1 -2
  5. data/lib/frameworks/sproutcore/CHANGELOG.md +8 -3
  6. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/app-selector.css +19 -23
  7. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/button.css +139 -135
  8. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/dock.css +5 -0
  9. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/general.css +0 -1
  10. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/menu.css +10 -13
  11. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/modal.css +9 -8
  12. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/picker.css +19 -12
  13. data/lib/frameworks/sproutcore/apps/greenhouse/models/design.js +2 -2
  14. data/lib/frameworks/sproutcore/apps/greenhouse/states/modals.js +1 -1
  15. data/lib/frameworks/sproutcore/apps/greenhouse/theme.js +2 -2
  16. data/lib/frameworks/sproutcore/apps/greenhouse/views/plist_item.js +3 -1
  17. data/lib/frameworks/sproutcore/frameworks/animation/core.js +1 -1
  18. data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +31 -20
  19. data/lib/frameworks/sproutcore/frameworks/bootstrap/tests/system/browser.js +15 -9
  20. data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/responder_context.js +5 -5
  21. data/lib/frameworks/sproutcore/frameworks/core_foundation/panes/pane.js +1 -1
  22. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/browser.js +23 -45
  23. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/device.js +1 -1
  24. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +60 -5
  25. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/ready.js +1 -1
  26. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/render_context.js +2 -2
  27. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +4 -4
  28. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/ready/done.js +32 -0
  29. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/utils/offset.js +5 -2
  30. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/append_remove.js +8 -3
  31. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/pane/layout.js +4 -4
  32. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/collection.js +51 -5
  33. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/core.js +18 -0
  34. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/template_view/handlebars.js +261 -0
  35. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/animation.js +55 -0
  36. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/clippingFrame.js +2 -19
  37. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/convertFrames.js +3 -1
  38. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/insertBefore.js +17 -0
  39. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/layoutStyle.js +96 -1
  40. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/prepareContext.js +15 -0
  41. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/updateLayerLocation.js +19 -0
  42. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/template/collection.js +8 -1
  43. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +179 -4
  44. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +8 -14
  45. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/cursor.js +7 -0
  46. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/enabled.js +4 -4
  47. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +51 -114
  48. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +84 -36
  49. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +4 -67
  50. data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +244 -1
  51. data/lib/frameworks/sproutcore/frameworks/datastore/models/child_attribute.js +1 -1
  52. data/lib/frameworks/sproutcore/frameworks/datastore/models/children_attribute.js +1 -1
  53. data/lib/frameworks/sproutcore/frameworks/datastore/models/record_attribute.js +7 -1
  54. data/lib/frameworks/sproutcore/frameworks/datastore/system/child_array.js +1 -1
  55. data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +2 -2
  56. data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/record/normalize.js +23 -1
  57. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChanges.js +4 -2
  58. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChangesFromNestedStore.js +4 -0
  59. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/discardChanges.js +4 -1
  60. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/record_type_is.js +4 -0
  61. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/registered_comparisons.js +4 -0
  62. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/query/registered_query_extensions.js +4 -0
  63. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/commitChangesFromNestedStore.js +4 -0
  64. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/createRecord.js +5 -1
  65. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/destroyRecord.js +5 -1
  66. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/loadRecord.js +64 -0
  67. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/recordDidChange.js +38 -35
  68. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/store/unloadRecords.js +4 -0
  69. data/lib/frameworks/sproutcore/frameworks/datetime/system/datetime.js +7 -4
  70. data/lib/frameworks/sproutcore/frameworks/datetime/tests/system/datetime.js +2 -2
  71. data/lib/frameworks/sproutcore/frameworks/debug/core.js +1 -1
  72. data/lib/frameworks/sproutcore/frameworks/debug/invoke_once_last_debugging.js +5 -5
  73. data/lib/frameworks/sproutcore/frameworks/designer/coders/object.js +1 -1
  74. data/lib/frameworks/sproutcore/frameworks/designer/designers/view_designer.js +11 -3
  75. data/lib/frameworks/sproutcore/frameworks/designer/ext/binding.js +33 -0
  76. data/lib/frameworks/sproutcore/frameworks/designer/ext/object.js +1 -1
  77. data/lib/frameworks/sproutcore/frameworks/designer/ext/page.js +5 -33
  78. data/lib/frameworks/sproutcore/frameworks/designer/ext/view.js +0 -27
  79. data/lib/frameworks/sproutcore/frameworks/designer/tests/coders/page.js +54 -0
  80. data/lib/frameworks/sproutcore/frameworks/designer/tests/designers/view_designer.js +47 -0
  81. data/lib/frameworks/sproutcore/frameworks/designer/views/drawing.js +4 -4
  82. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/border.js +19 -6
  83. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/collection_view_delegate.js +1 -1
  84. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/navigation_builder.js +1 -1
  85. data/lib/frameworks/sproutcore/frameworks/desktop/mixins/scrollable.js +1 -1
  86. data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +133 -39
  87. data/lib/frameworks/sproutcore/frameworks/desktop/system/drag.js +3 -3
  88. data/lib/frameworks/sproutcore/frameworks/desktop/tests/mixins/border.js +6 -5
  89. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/picker/ui.js +8 -2
  90. data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/select_button/ui.js +10 -2
  91. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/button/ui.js +8 -2
  92. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/checkbox/ui.js +10 -2
  93. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/collection/ui_diagram.js +15 -9
  94. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/progress/ui.js +8 -2
  95. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/radio/ui.js +8 -2
  96. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +10 -2
  97. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select/ui.js +10 -2
  98. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/methods.js +31 -0
  99. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select_field/ui.js +10 -3
  100. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/separator.js +10 -3
  101. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/split/ui.js +10 -3
  102. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/stacked/ui_comments.js +15 -8
  103. data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/tab/ui.js +10 -3
  104. data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +1 -1
  105. data/lib/frameworks/sproutcore/frameworks/desktop/views/file.js +1 -1
  106. data/lib/frameworks/sproutcore/frameworks/desktop/views/list_item.js +1 -7
  107. data/lib/frameworks/sproutcore/frameworks/desktop/views/select_field.js +10 -0
  108. data/lib/frameworks/sproutcore/frameworks/desktop/views/toolbar.js +3 -3
  109. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/collection_content.js +2 -2
  110. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inline_text_field.js +17 -5
  111. data/lib/frameworks/sproutcore/frameworks/foundation/mixins/inner_frame.js +60 -27
  112. data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/canvas_image.js +1 -1
  113. data/lib/frameworks/sproutcore/frameworks/foundation/system/benchmark.js +4 -4
  114. data/lib/frameworks/sproutcore/frameworks/foundation/system/cookie.js +29 -18
  115. data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +18 -18
  116. data/lib/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +5 -5
  117. data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/misc.js +62 -1
  118. data/lib/frameworks/sproutcore/frameworks/foundation/tests/integration/creating_views.js +8 -3
  119. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/button/ui.js +4 -3
  120. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/editable/ui.js +5 -3
  121. data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/inline_text_field/ui.js +5 -3
  122. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/cookie.js +20 -4
  123. data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/utils/pointInElement.js +235 -0
  124. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/ui.js +5 -0
  125. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/image/ui.js +0 -2
  126. data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/label/ui.js +8 -3
  127. data/lib/frameworks/sproutcore/frameworks/foundation/views/container.js +2 -2
  128. data/lib/frameworks/sproutcore/frameworks/foundation/views/image.js +19 -11
  129. data/lib/frameworks/sproutcore/frameworks/foundation/views/label.js +6 -13
  130. data/lib/frameworks/sproutcore/frameworks/handlebars/extensions.js +23 -117
  131. data/lib/frameworks/sproutcore/frameworks/handlebars/extensions/bind.js +136 -0
  132. data/lib/frameworks/sproutcore/frameworks/handlebars/extensions/collection.js +75 -0
  133. data/lib/frameworks/sproutcore/frameworks/handlebars/extensions/localization.js +5 -0
  134. data/lib/frameworks/sproutcore/frameworks/handlebars/extensions/view.js +115 -0
  135. data/lib/frameworks/sproutcore/frameworks/handlebars/handlebars.js +143 -80
  136. data/lib/frameworks/sproutcore/frameworks/jquery/jquery-buffer.js +1 -1
  137. data/lib/frameworks/sproutcore/frameworks/media/views/audio.js +4 -4
  138. data/lib/frameworks/sproutcore/frameworks/media/views/video.js +5 -5
  139. data/lib/frameworks/sproutcore/frameworks/runtime/debug/test_suites/array.js +14 -0
  140. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/enumerable.js +1 -1
  141. data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +13 -13
  142. data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +4 -4
  143. data/lib/frameworks/sproutcore/frameworks/runtime/system/run_loop.js +3 -3
  144. data/lib/frameworks/sproutcore/frameworks/runtime/tests/mixins/array.js +1 -1
  145. data/lib/frameworks/sproutcore/frameworks/testing/system/plan.js +25 -17
  146. data/lib/frameworks/sproutcore/themes/ace/designs/psds/panel/pointers.psd +0 -0
  147. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/18px/button.css +18 -12
  148. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/24px/button.css +30 -16
  149. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/30px/button.css +27 -15
  150. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/44px/button.css +5 -0
  151. data/lib/frameworks/sproutcore/themes/ace/resources/button/ace/button.css +8 -0
  152. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/24px/button.css +25 -16
  153. data/lib/frameworks/sproutcore/themes/ace/resources/button/dark/30px/button.css +21 -15
  154. data/lib/frameworks/sproutcore/themes/ace/resources/imagebutton/ace/imagebutton.css +11 -0
  155. data/lib/frameworks/sproutcore/themes/ace/resources/picker/ace/panel.png +0 -0
  156. data/lib/frameworks/sproutcore/themes/ace/resources/picker/ace/picker.css +41 -0
  157. data/lib/frameworks/sproutcore/themes/ace/resources/picker/ace/pointers.png +0 -0
  158. data/lib/sproutcore.rb +2 -0
  159. data/lib/sproutcore/buildfile.rb +17 -17
  160. data/lib/sproutcore/buildfile/task.rb +4 -12
  161. data/lib/sproutcore/buildfile/task_manager.rb +13 -4
  162. data/lib/sproutcore/models/manifest.rb +3 -3
  163. data/lib/sproutcore/models/target.rb +1 -1
  164. data/spec/fixtures/real_world/Buildfile +1 -1
  165. data/vendor/chance/lib/chance/imagers/data_url.rb +38 -19
  166. data/vendor/chance/lib/chance/instance.rb +4 -7
  167. data/vendor/chance/lib/chance/slicing.rb +6 -10
  168. metadata +18 -5
  169. data/lib/frameworks/sproutcore/apps/greenhouse/english.lproj/css/tabbed.css +0 -68
  170. data/lib/frameworks/sproutcore/frameworks/designer/coders/localization.js +0 -19
  171. data/lib/sproutcore/buildfile/cloneable.rb +0 -34
@@ -0,0 +1,75 @@
1
+ sc_require('extensions');
2
+
3
+ Handlebars.registerHelper('collection', function(path, fn, inverse) {
4
+ var data = fn.data;
5
+ var collectionClass;
6
+
7
+ if(!data) {
8
+ data = fn;
9
+ fn = null;
10
+ }
11
+
12
+ if(typeof path === "string") {
13
+ collectionClass = SC.objectForPropertyPath(path) || SC.TemplateCollectionView;
14
+ } else {
15
+ collectionClass = path;
16
+ }
17
+
18
+ var hash = fn.hash, itemHash = {}, match;
19
+
20
+ for (var prop in hash) {
21
+ if (fn.hash.hasOwnProperty(prop)) {
22
+ match = prop.match(/^item(.)(.*)$/);
23
+
24
+ if(match) {
25
+ itemHash[match[1].toLowerCase() + match[2]] = hash[prop];
26
+ delete hash[prop];
27
+ }
28
+ }
29
+ }
30
+
31
+ if(fn) {
32
+ var collectionObject = collectionClass;
33
+
34
+ if(collectionObject.isClass) {
35
+ collectionObject = collectionObject.prototype;
36
+ }
37
+
38
+ collectionObject.itemViewTemplate = fn;
39
+ collectionObject.inverseTemplate = inverse;
40
+ collectionObject.itemViewOptions = itemHash;
41
+ }
42
+
43
+ var noop = function() { return ""; };
44
+
45
+ noop.data = fn.data;
46
+ noop.hash = fn.hash;
47
+ noop.fn = noop;
48
+
49
+ return Handlebars.helpers.view.call(this, collectionClass, noop);
50
+ });
51
+
52
+ Handlebars.registerHelper('bindCollection', function(path, bindingString, fn) {
53
+ var data = fn.data;
54
+ var inverse = fn.data;
55
+ var collectionClass = SC.objectForPropertyPath(path) || SC.TemplateCollectionView;
56
+ var binding = SC.Binding.from(bindingString, this);
57
+
58
+ if(!data) {
59
+ data = fn;
60
+ fn = null;
61
+ }
62
+
63
+ if(fn) {
64
+ // attach the function to the original class so it can be used recursively
65
+ collectionClass.prototype.itemViewTemplate = fn;
66
+ }
67
+
68
+ if(collectionClass.isClass) {
69
+ collectionClass = collectionClass.extend({ contentBinding: binding });
70
+ } else {
71
+ collectionClass.bindings.push( binding.to('content', collectionClass) );
72
+ }
73
+
74
+ return Handlebars.helpers.collection.call(this, collectionClass, fn);
75
+ });
@@ -0,0 +1,5 @@
1
+ sc_require('extensions');
2
+
3
+ Handlebars.registerHelper('loc', function(property) {
4
+ return property.loc();
5
+ });
@@ -0,0 +1,115 @@
1
+ sc_require('extensions');
2
+
3
+ SC.Handlebars.ViewHelper = SC.Object.create({
4
+ helper: function(thisContext, path, options) {
5
+ var inverse = options.inverse;
6
+ var data = options.data;
7
+ var view = data.view;
8
+ var fn = options.fn;
9
+
10
+ var newView;
11
+ if (path.isClass || path.isObject) {
12
+ newView = path;
13
+ if (!newView) {
14
+ throw "Null or undefined object was passed to the #view helper. Did you mean to pass a property path string?";
15
+ }
16
+ } else {
17
+ // Path is relative, look it up with this view as the root
18
+ if (path.charAt(0) === '.') {
19
+ newView = SC.objectForPropertyPath(path.slice(1), view);
20
+ } else {
21
+ // Path is absolute, look up path on global (window) object
22
+ newView = SC.objectForPropertyPath(path);
23
+ }
24
+ if (!newView) { throw "Unable to find view at path '" + path + "'"; }
25
+ }
26
+
27
+ var currentView = data.view;
28
+
29
+ var childViews = currentView.get('childViews');
30
+ var childView = currentView.createChildView(newView);
31
+
32
+ // Set the template of the view to the passed block if we got one
33
+ if (fn) { childView.template = fn; }
34
+
35
+
36
+ childViews.pushObject(childView);
37
+
38
+ var context = SC.RenderContext(childView.get('tagName'));
39
+
40
+ // Add id and class names passed to view helper
41
+ this.applyAttributes(options.hash, childView, context);
42
+
43
+ childView.applyAttributesToContext(context);
44
+
45
+
46
+ // tomdale wants to make SproutCore slow
47
+ childView.render(context, YES);
48
+
49
+ return new Handlebars.SafeString(context.join());
50
+ },
51
+
52
+ applyAttributes: function(options, childView, context) {
53
+ var id = options.id;
54
+ var classNames = options['class'];
55
+
56
+ if (classNames) {
57
+ context.addClass(classNames.split(' '));
58
+ }
59
+
60
+ if (id) {
61
+ childView.set('layerId', id);
62
+ context.id(id);
63
+ }
64
+
65
+ var classBindings = options.classBinding;
66
+ if (classBindings) {
67
+ this.addClassBindings(classBindings, childView, context);
68
+ }
69
+ },
70
+
71
+ addClassBindings: function(classBindings, view, context) {
72
+ var classObservers = view._classObservers;
73
+
74
+ // Teardown any existing observers on the view.
75
+ if (classObservers) {
76
+ for (var prop in classObservers) {
77
+ if (classObservers.hasOwnProperty(prop)) {
78
+ view.removeObserver(prop, classObservers[prop]);
79
+ }
80
+ }
81
+ }
82
+
83
+ classObservers = view._classObservers = {};
84
+
85
+ // For each property passed, loop through and setup
86
+ // an observer.
87
+ classBindings.split(' ').forEach(function(property) {
88
+ // Normalize property path to be suitable for use
89
+ // as a class name. For exaple, content.foo.barBaz
90
+ // becomes bar-baz.
91
+
92
+ var dasherizedProperty = property.split('.').get('lastObject');
93
+ dasherizedProperty = dasherizedProperty.dasherize();
94
+
95
+ // Set up an observer on the view. If the bound property
96
+ // changes, toggle the class name
97
+ var observer = classObservers[property] = function() {
98
+ var shouldDisplay = view.getPath(property);
99
+ var elem = view.$();
100
+
101
+ elem.toggleClass(dasherizedProperty, shouldDisplay);
102
+ };
103
+
104
+ view.addObserver(property, observer);
105
+
106
+ // Add the class name to the view
107
+ context.setClass(dasherizedProperty, view.getPath(property));
108
+ });
109
+ }
110
+ });
111
+
112
+
113
+ Handlebars.registerHelper('view', function(path, options) {
114
+ return SC.Handlebars.ViewHelper.helper(this, path, options);
115
+ });
@@ -3,9 +3,9 @@
3
3
  var handlebars = (function(){
4
4
  var parser = {trace: function trace() { },
5
5
  yy: {},
6
- symbols_: {"error":2,"root":3,"program":4,"EOF":5,"statements":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"params":25,"param":26,"STRING":27,"pathSegments":28,"SEP":29,"ID":30,"$accept":0,"$end":1},
7
- terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",27:"STRING",29:"SEP",30:"ID"},
8
- productions_: [0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,2],[17,1],[25,2],[25,1],[26,1],[26,1],[21,1],[28,3],[28,1]],
6
+ symbols_: {"error":2,"root":3,"program":4,"EOF":5,"statements":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"params":25,"hash":26,"param":27,"STRING":28,"hashSegments":29,"hashSegment":30,"ID":31,"EQUALS":32,"pathSegments":33,"SEP":34,"$accept":0,"$end":1},
7
+ terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",28:"STRING",31:"ID",32:"EQUALS",34:"SEP"},
8
+ productions_: [0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,3],[17,2],[17,2],[17,1],[25,2],[25,1],[27,1],[27,1],[26,1],[29,2],[29,1],[30,3],[30,3],[21,1],[33,3],[33,1]],
9
9
  performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
10
10
 
11
11
  var $0 = $$.length - 1;
@@ -34,15 +34,15 @@ case 11: this.$ = new yy.ContentNode($$[$0])
34
34
  break;
35
35
  case 12: this.$ = new yy.CommentNode($$[$0])
36
36
  break;
37
- case 13: this.$ = new yy.MustacheNode($$[$0-1])
37
+ case 13: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
38
38
  break;
39
- case 14: this.$ = new yy.MustacheNode($$[$0-1])
39
+ case 14: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
40
40
  break;
41
41
  case 15: this.$ = $$[$0-1]
42
42
  break;
43
- case 16: this.$ = new yy.MustacheNode($$[$0-1])
43
+ case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1])
44
44
  break;
45
- case 17: this.$ = new yy.MustacheNode($$[$0-1], true)
45
+ case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true)
46
46
  break;
47
47
  case 18: this.$ = new yy.PartialNode($$[$0-1])
48
48
  break;
@@ -50,28 +50,42 @@ case 19: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1])
50
50
  break;
51
51
  case 20:
52
52
  break;
53
- case 21: this.$ = [$$[$0-1]].concat($$[$0])
53
+ case 21: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]]
54
54
  break;
55
- case 22: this.$ = [$$[$0]]
55
+ case 22: this.$ = [[$$[$0-1]].concat($$[$0]), null]
56
56
  break;
57
- case 23: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
57
+ case 23: this.$ = [[$$[$0-1]], $$[$0]]
58
58
  break;
59
- case 24: this.$ = [$$[$0]]
59
+ case 24: this.$ = [[$$[$0]], null]
60
60
  break;
61
- case 25: this.$ = $$[$0]
61
+ case 25: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
62
62
  break;
63
- case 26: this.$ = new yy.StringNode($$[$0])
63
+ case 26: this.$ = [$$[$0]]
64
64
  break;
65
- case 27: this.$ = new yy.IdNode($$[$0])
65
+ case 27: this.$ = $$[$0]
66
66
  break;
67
- case 28: $$[$0-2].push($$[$0]); this.$ = $$[$0-2];
67
+ case 28: this.$ = new yy.StringNode($$[$0])
68
68
  break;
69
- case 29: this.$ = [$$[$0]]
69
+ case 29: this.$ = new yy.HashNode($$[$0])
70
+ break;
71
+ case 30: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]
72
+ break;
73
+ case 31: this.$ = [$$[$0]]
74
+ break;
75
+ case 32: this.$ = [$$[$0-2], $$[$0]]
76
+ break;
77
+ case 33: this.$ = [$$[$0-2], new yy.StringNode($$[$0])]
78
+ break;
79
+ case 34: this.$ = new yy.IdNode($$[$0])
80
+ break;
81
+ case 35: $$[$0-2].push($$[$0]); this.$ = $$[$0-2];
82
+ break;
83
+ case 36: this.$ = [$$[$0]]
70
84
  break;
71
85
  }
72
86
  },
73
- table: [{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,28:24,30:[1,25]},{17:26,21:23,28:24,30:[1,25]},{17:27,21:23,28:24,30:[1,25]},{17:28,21:23,28:24,30:[1,25]},{21:29,28:24,30:[1,25]},{1:[2,1]},{6:30,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,31],21:23,28:24,30:[1,25]},{10:32,20:[1,33]},{10:34,20:[1,33]},{18:[1,35]},{18:[2,22],21:38,25:36,26:37,27:[1,39],28:24,30:[1,25]},{18:[2,27],27:[2,27],29:[1,40],30:[2,27]},{18:[2,29],27:[2,29],29:[2,29],30:[2,29]},{18:[1,41]},{18:[1,42]},{18:[1,43]},{18:[1,44],21:45,28:24,30:[1,25]},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:46,28:24,30:[1,25]},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,21],21:38,26:47,27:[1,39],28:24,30:[1,25]},{18:[2,24],27:[2,24],30:[2,24]},{18:[2,25],27:[2,25],30:[2,25]},{18:[2,26],27:[2,26],30:[2,26]},{30:[1,48]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,49]},{18:[1,50]},{18:[2,23],27:[2,23],30:[2,23]},{18:[2,28],27:[2,28],29:[2,28],30:[2,28]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]}],
74
- defaultActions: {16:[2,1]},
87
+ table: [{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,31:[1,25],33:24},{17:26,21:23,31:[1,25],33:24},{17:27,21:23,31:[1,25],33:24},{17:28,21:23,31:[1,25],33:24},{21:29,31:[1,25],33:24},{1:[2,1]},{6:30,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,31],21:23,31:[1,25],33:24},{10:32,20:[1,33]},{10:34,20:[1,33]},{18:[1,35]},{18:[2,24],21:40,25:36,26:37,27:38,28:[1,41],29:39,30:42,31:[1,43],33:24},{18:[2,34],28:[2,34],31:[2,34],34:[1,44]},{18:[2,36],28:[2,36],31:[2,36],34:[2,36]},{18:[1,45]},{18:[1,46]},{18:[1,47]},{18:[1,48],21:49,31:[1,25],33:24},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:50,31:[1,25],33:24},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,22],21:40,26:51,27:52,28:[1,41],29:39,30:42,31:[1,43],33:24},{18:[2,23]},{18:[2,26],28:[2,26],31:[2,26]},{18:[2,29],30:53,31:[1,54]},{18:[2,27],28:[2,27],31:[2,27]},{18:[2,28],28:[2,28],31:[2,28]},{18:[2,31],31:[2,31]},{18:[2,36],28:[2,36],31:[2,36],32:[1,55],34:[2,36]},{31:[1,56]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,57]},{18:[1,58]},{18:[2,21]},{18:[2,25],28:[2,25],31:[2,25]},{18:[2,30],31:[2,30]},{32:[1,55]},{21:59,28:[1,60],31:[1,25],33:24},{18:[2,35],28:[2,35],31:[2,35],34:[2,35]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{18:[2,32],31:[2,32]},{18:[2,33],31:[2,33]}],
88
+ defaultActions: {16:[2,1],37:[2,23],51:[2,21]},
75
89
  parseError: function parseError(str, hash) {
76
90
  throw new Error(str);
77
91
  },
@@ -225,7 +239,7 @@ parse: function parse(input) {
225
239
  first_line: lstack[lstack.length-(len||1)].first_line,
226
240
  last_line: lstack[lstack.length-1].last_line,
227
241
  first_column: lstack[lstack.length-(len||1)].first_column,
228
- last_column: lstack[lstack.length-1].last_column,
242
+ last_column: lstack[lstack.length-1].last_column
229
243
  };
230
244
  r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
231
245
 
@@ -394,31 +408,39 @@ case 9: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.begin("INITIAL"); r
394
408
  break;
395
409
  case 10: return 22;
396
410
  break;
397
- case 11: return 29;
411
+ case 11: return 32;
412
+ break;
413
+ case 12: return 31;
414
+ break;
415
+ case 13: return 31;
398
416
  break;
399
- case 12: /*ignore whitespace*/
417
+ case 14: return 34;
400
418
  break;
401
- case 13: this.begin("INITIAL"); return 18;
419
+ case 15: /*ignore whitespace*/
402
420
  break;
403
- case 14: this.begin("INITIAL"); return 18;
421
+ case 16: this.begin("INITIAL"); return 18;
404
422
  break;
405
- case 15: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 27;
423
+ case 17: this.begin("INITIAL"); return 18;
406
424
  break;
407
- case 16: return 30;
425
+ case 18: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 28;
408
426
  break;
409
- case 17: return 'INVALID';
427
+ case 19: return 31;
410
428
  break;
411
- case 18: return 5;
429
+ case 20: return 'INVALID';
430
+ break;
431
+ case 21: return 5;
412
432
  break;
413
433
  }
414
434
  };
415
- lexer.rules = [/^[^\x00]*?(?=(\{\{))/,/^[^\x00]+/,/^\{\{>/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{!.*?\}\}/,/^\{\{/,/^\//,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^[a-zA-Z0-9_.]+(?=[} /])/,/^./,/^$/];
416
- lexer.conditions = {"mu":{"rules":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],"inclusive":false},"INITIAL":{"rules":[0,1,18],"inclusive":true}};return lexer;})()
435
+ lexer.rules = [/^[^\x00]*?(?=(\{\{))/,/^[^\x00]+/,/^\{\{>/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{!.*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^[a-zA-Z0-9_]+(?=[=} /.])/,/^./,/^$/];
436
+ lexer.conditions = {"mu":{"rules":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21],"inclusive":false},"INITIAL":{"rules":[0,1,21],"inclusive":true}};return lexer;})()
417
437
  parser.lexer = lexer;
418
438
  return parser;
419
439
  })();
420
440
  // lib/handlebars/base.js
421
- window.Handlebars = {};
441
+
442
+ // Support for node.js and Spade
443
+ var Handlebars = (typeof exports !== 'undefined') ? exports : {};
422
444
 
423
445
  Handlebars.Parser = handlebars;
424
446
 
@@ -538,10 +560,11 @@ Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
538
560
  if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
539
561
  };
540
562
 
541
- Handlebars.AST.MustacheNode = function(params, unescaped) {
563
+ Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
542
564
  this.type = "mustache";
543
565
  this.id = params[0];
544
566
  this.params = params.slice(1);
567
+ this.hash = hash;
545
568
  this.escaped = !unescaped;
546
569
  };
547
570
 
@@ -579,6 +602,11 @@ Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
579
602
  this.string = string;
580
603
  };
581
604
 
605
+ Handlebars.AST.HashNode = function(pairs) {
606
+ this.type = "hash";
607
+ this.pairs = pairs;
608
+ };
609
+
582
610
  Handlebars.AST.IdNode = function(parts) {
583
611
  this.type = "ID";
584
612
  this.original = parts.join("/");
@@ -691,7 +719,8 @@ Handlebars.JavaScriptCompiler = function() {};
691
719
  invokeProgram: 11,
692
720
  invokePartial: 12,
693
721
  push: 13,
694
- invokeInverse: 14
722
+ invokeInverse: 14,
723
+ assignToHash: 15
695
724
  };
696
725
 
697
726
  Compiler.MULTI_PARAM_OPCODES = {
@@ -706,7 +735,8 @@ Handlebars.JavaScriptCompiler = function() {};
706
735
  invokeProgram: 2,
707
736
  invokePartial: 1,
708
737
  push: 1,
709
- invokeInverse: 1
738
+ invokeInverse: 1,
739
+ assignToHash: 1
710
740
  };
711
741
 
712
742
  Compiler.DISASSEMBLE_MAP = {};
@@ -805,20 +835,14 @@ Handlebars.JavaScriptCompiler = function() {};
805
835
 
806
836
  block: function(block) {
807
837
  var mustache = block.mustache;
808
- var params = mustache.params, depth, child, inverse, inverseGuid;
838
+ var depth, child, inverse, inverseGuid;
809
839
 
810
- this.pushParams(params);
811
-
812
- // ID lookup is now on the stack
813
- this.ID(mustache.id);
840
+ var params = this.setupStackForMustache(mustache);
814
841
 
815
842
  var programGuid = this.compileProgram(block.program);
816
843
 
817
844
  if(block.program.inverse) {
818
845
  inverseGuid = this.compileProgram(block.program.inverse);
819
- }
820
-
821
- if(block.program.inverse) {
822
846
  this.declare('inverse', inverseGuid);
823
847
  }
824
848
 
@@ -835,6 +859,20 @@ Handlebars.JavaScriptCompiler = function() {};
835
859
  this.opcode('append');
836
860
  },
837
861
 
862
+ hash: function(hash) {
863
+ var pairs = hash.pairs, pair, val;
864
+
865
+ this.opcode('push', '{}');
866
+
867
+ for(var i=0, l=pairs.length; i<l; i++) {
868
+ pair = pairs[i];
869
+ val = pair[1];
870
+
871
+ this.accept(val);
872
+ this.opcode('assignToHash', pair[0]);
873
+ }
874
+ },
875
+
838
876
  partial: function(partial) {
839
877
  var id = partial.id;
840
878
  this.usePartial = true;
@@ -854,10 +892,7 @@ Handlebars.JavaScriptCompiler = function() {};
854
892
  },
855
893
 
856
894
  mustache: function(mustache) {
857
- var params = mustache.params;
858
-
859
- this.pushParams(params);
860
- this.ID(mustache.id);
895
+ var params = this.setupStackForMustache(mustache);
861
896
 
862
897
  this.opcode('invokeMustache', params.length, mustache.id.original);
863
898
 
@@ -886,6 +921,7 @@ Handlebars.JavaScriptCompiler = function() {};
886
921
 
887
922
  comment: function() {},
888
923
 
924
+ // HELPERS
889
925
  pushParams: function(params) {
890
926
  var i = params.length, param;
891
927
 
@@ -914,6 +950,22 @@ Handlebars.JavaScriptCompiler = function() {};
914
950
  this.depths[depth] = true;
915
951
  this.depths.list.push(depth);
916
952
  }
953
+ },
954
+
955
+ setupStackForMustache: function(mustache) {
956
+ var params = mustache.params;
957
+
958
+ this.pushParams(params);
959
+
960
+ if(mustache.hash) {
961
+ this.hash(mustache.hash);
962
+ } else {
963
+ this.opcode('push', '{}');
964
+ }
965
+
966
+ this.ID(mustache.id);
967
+
968
+ return params;
917
969
  }
918
970
  };
919
971
 
@@ -1134,58 +1186,62 @@ Handlebars.JavaScriptCompiler = function() {};
1134
1186
  },
1135
1187
 
1136
1188
  invokeMustache: function(paramSize, original) {
1137
- var params = ["context"], fn, slot;
1138
-
1139
- fn = this.popStack();
1140
-
1141
- for(var i=0; i<paramSize; i++) {
1142
- params.push(this.popStack());
1143
- }
1144
-
1145
- if(this.data) { params.push("data"); }
1146
-
1147
- var paramString = params.join(", ");
1148
- var helperMissing = ["context"].concat(this.quotedString(original)).concat(params.slice(1));
1149
-
1150
- slot = this.nextStack();
1151
-
1152
- if(paramSize === 0) {
1153
- // TODO: This case is not listed in the mustache spec. Is it important?
1154
- this.source.push("if(typeof " + fn + " === 'function') { " + slot + " = " + fn + ".call(" + paramString + "); }");
1155
- } else {
1156
- this.source.push("if(typeof " + fn + " === 'function') { " + slot + " = " + fn + ".call(" + paramString + "); } else { " + slot + " = helpers.helperMissing.call(" + helperMissing + ") }");
1157
- }
1189
+ this.populateParams(paramSize, this.quotedString(original), "{}", null, function(nextStack, helperMissingString, id) {
1190
+ this.source.push("else if(" + id + "=== undefined) { " + nextStack + " = helpers.helperMissing.call(" + helperMissingString + "); }");
1191
+ this.source.push("else { " + nextStack + " = " + id + "; }");
1192
+ });
1158
1193
  },
1159
1194
 
1160
1195
  invokeProgram: function(guid, paramSize) {
1161
1196
  var inverse = this.programExpression(this.inverse);
1197
+ var mainProgram = this.programExpression(guid);
1162
1198
 
1163
- var fn = this.popStack();
1164
- var id = fn;
1199
+ this.populateParams(paramSize, null, mainProgram, inverse, function(nextStack, helperMissingString, id) {
1200
+ this.source.push("else { " + nextStack + " = helpers.blockHelperMissing.call(" + helperMissingString + "); }");
1201
+ });
1202
+ },
1165
1203
 
1166
- var params = ["context"];
1167
- var blockMissingParams = ["context", id];
1204
+ populateParams: function(paramSize, helperId, program, inverse, fn) {
1205
+ var id = this.popStack(), nextStack;
1206
+ var params = [];
1207
+
1208
+ var hash = this.popStack();
1168
1209
 
1169
1210
  for(var i=0; i<paramSize; i++) {
1170
1211
  var param = this.popStack();
1171
1212
  params.push(param);
1172
- blockMissingParams.push(param);
1173
1213
  }
1174
1214
 
1175
- var mainProgram = this.programExpression(guid);
1215
+ this.register('tmp1', program);
1216
+ this.source.push('tmp1.hash = ' + hash + ';');
1176
1217
 
1177
- params.push(mainProgram, inverse);
1178
- blockMissingParams.push(mainProgram, inverse);
1218
+ if(inverse) {
1219
+ this.source.push('tmp1.fn = tmp1;');
1220
+ this.source.push('tmp1.inverse = ' + inverse + ';');
1221
+ }
1179
1222
 
1180
1223
  if(this.data) {
1181
- params.push("data");
1182
- blockMissingParams.push("data");
1224
+ this.source.push('tmp1.data = data;');
1183
1225
  }
1184
1226
 
1185
- var nextStack = this.nextStack();
1227
+ params.push('tmp1');
1186
1228
 
1187
- this.source.push("if(typeof " + id + " === 'function') { " + nextStack + " = " + id + ".call(" + params.join(", ") + "); }");
1188
- this.source.push("else { " + nextStack + " = helpers.blockHelperMissing.call(" + blockMissingParams.join(", ") + "); }");
1229
+ // TODO: This is legacy behavior. Deprecate and remove.
1230
+ if(inverse) {
1231
+ params.push(inverse);
1232
+ }
1233
+
1234
+ this.populateCall(params, id, helperId || id, fn);
1235
+ },
1236
+
1237
+ populateCall: function(params, id, helperId, fn) {
1238
+ var paramString = ["context"].concat(params).join(", ");
1239
+ var helperMissingString = ["context"].concat(helperId).concat(params).join(", ");
1240
+
1241
+ nextStack = this.nextStack();
1242
+
1243
+ this.source.push("if(typeof " + id + " === 'function') { " + nextStack + " = " + id + ".call(" + paramString + "); }");
1244
+ fn.call(this, nextStack, helperMissingString, id);
1189
1245
  },
1190
1246
 
1191
1247
  invokeInverse: function(guid) {
@@ -1199,6 +1255,13 @@ Handlebars.JavaScriptCompiler = function() {};
1199
1255
  this.pushStack("this.invokePartial(" + this.nameLookup('partials', context, 'partial') + ", '" + context + "', " + this.popStack() + ", helpers, partials);");
1200
1256
  },
1201
1257
 
1258
+ assignToHash: function(key) {
1259
+ var value = this.popStack();
1260
+ var hash = this.topStack();
1261
+
1262
+ this.source.push(hash + "['" + key + "'] = " + value + ";");
1263
+ },
1264
+
1202
1265
  // HELPERS
1203
1266
 
1204
1267
  compiler: JavaScriptCompiler,
@@ -1335,4 +1398,4 @@ Handlebars.VM = {
1335
1398
  }
1336
1399
  };
1337
1400
 
1338
- Handlebars.compile = Handlebars.VM.compile;;
1401
+ Handlebars.compile = Handlebars.VM.compile;