sproutcore 1.9.1 → 1.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION.yml +1 -1
- data/lib/frameworks/sproutcore/CHANGELOG.md +212 -11
- data/lib/frameworks/sproutcore/frameworks/ajax/system/response.js +17 -17
- data/lib/frameworks/sproutcore/frameworks/ajax/tests/system/request.js +103 -86
- data/lib/frameworks/sproutcore/frameworks/bootstrap/system/browser.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/bootstrap/tests/system/browser.js +33 -21
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +3 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +7 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +5 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +7 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/data_sources/data_source.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/system/many_array.js +36 -30
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/many_array/core_methods.js +84 -42
- data/lib/frameworks/sproutcore/frameworks/desktop/{resources/debug → debug/resources}/a_sample_image.jpg +0 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/{resources/debug → debug/resources}/iframe.html +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/protocols/responder.js +68 -68
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/list_item.css +1 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/menu_item_view.css +1 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/slider.css +6 -5
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/methods.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/web/ui.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +45 -36
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/{gestureable.js → gesturable.js} +0 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/render_delegates/label.js +2 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/benchmark.css +1 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/label/ui.js +13 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/views/inline_text_field.js +4 -33
- data/lib/frameworks/sproutcore/frameworks/foundation/views/label.js +31 -17
- data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +59 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
- data/lib/frameworks/sproutcore/themes/ace/resources/master-detail/master-detail.css +4 -0
- data/lib/gen/app/templates/apps/@target_name@/Buildfile +3 -1
- data/lib/gen/app/templates/apps/@target_name@/core.js +3 -3
- data/lib/gen/app/templates/apps/@target_name@/main.js +7 -5
- data/lib/gen/app/templates/apps/@target_name@/resources/main_page.css +20 -0
- data/lib/gen/app/templates/apps/@target_name@/resources/main_page.js +7 -7
- data/lib/gen/controller/templates/controllers/@filename@_controller.js +2 -2
- data/lib/gen/data-source/templates/data_sources/@filename@_data_source.js +21 -21
- data/lib/gen/design/templates/resources/@filename@.css +12 -0
- data/lib/gen/framework/templates/frameworks/@target_name@/core.js +3 -3
- data/lib/gen/framework/templates/frameworks/@target_name@/english.lproj/strings.js +1 -1
- data/lib/gen/language/templates/@filename@/strings.js +1 -1
- data/lib/gen/model/templates/models/@filename@_model.js +1 -1
- data/lib/gen/page/templates/pages/@target_name@/core.js +3 -3
- data/lib/gen/project/templates/@filename@/Buildfile +29 -5
- data/lib/gen/{responder → state}/Buildfile +3 -2
- data/lib/gen/state/README +1 -0
- data/lib/gen/state/USAGE +15 -0
- data/lib/gen/state/templates/states/@filename@_state.js +24 -0
- data/lib/gen/state/templates/tests/states/@filename@_test.js +12 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/Buildfile +3 -1
- data/lib/gen/statechart_app/templates/apps/@target_name@/core.js +3 -3
- data/lib/gen/statechart_app/templates/apps/@target_name@/main.js +3 -10
- data/lib/gen/statechart_app/templates/apps/@target_name@/resources/main_page.css +20 -0
- data/lib/gen/statechart_app/templates/apps/@target_name@/resources/main_page.js +7 -7
- data/lib/gen/statechart_app/templates/apps/@target_name@/statechart.js +3 -3
- data/lib/sproutcore/models/generator.rb +1 -1
- data/spec/lib/models/generator/snake_case_spec.rb +26 -0
- data/sproutcore.gemspec +16 -16
- data/vendor/chance/lib/chance/instance/spriting.rb +32 -30
- metadata +30 -26
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/debug/apple-logo1.jpeg +0 -0
- data/lib/gen/responder/README +0 -1
- data/lib/gen/responder/USAGE +0 -15
- data/lib/gen/responder/templates/states/@filename@_state.js +0 -36
data/VERSION.yml
CHANGED
@@ -7,6 +7,143 @@ Edge
|
|
7
7
|
### CHANGES & FEATURES
|
8
8
|
|
9
9
|
* Improves and adds documentation.
|
10
|
+
* Sets SC.WebView src to '' instead of 'null' or 'undefined' when the value is null or undefined. Removes the "No matching entry in target" message when value of SC.WebView is cleared.
|
11
|
+
* Adds the inline text field to the view's parent rather than its pane. If any view in the chain from pane to the view's parent has a zIndex, the text field won't be visible. By adding it to the parent instead, there's a greater chance that nothing special will need to be done with the text field.
|
12
|
+
* Add a difference method to SC.DateTime. SC.DateTime.prototype.difference(a, b, format).
|
13
|
+
|
14
|
+
This method allows you to very easily compute the number of weeks, days, hours,
|
15
|
+
minutes, or seconds between two dates.
|
16
|
+
* Improved String.fmt handling of missing named arguments.
|
17
|
+
* The SC.Store.reset() method was not clearing out previously constructed
|
18
|
+
RecordArrays, even though the underlying data hash was being cleared.
|
19
|
+
While technically this is valid -> most of the storekeys are set to
|
20
|
+
SC.Record.EMPTY rather than being deleted altogether, which means the
|
21
|
+
storeKey lists inside of the RA's aren't invalidated -> it seems a
|
22
|
+
little strange that a method labeled "reset" does not, in fact, clean up
|
23
|
+
the entire store.
|
24
|
+
|
25
|
+
This patch ensures that the entire store is cleared, and adds a few unit
|
26
|
+
tests that enforce the one-record-array-per-query contract.
|
27
|
+
* Fixes the order of the container and segmented view in the DOM for SC.TabView so that the segmented view should be rendered above the container without having to resort to forced z-index settings.
|
28
|
+
* Adds transition plugin support to SC.ContainerView and introduces five
|
29
|
+
pre-built plugins: SC.ContainerView.PUSH, SC.ContainerView.DISSOLVE,
|
30
|
+
SC.ContainerView.FADE_COLOR, SC.ContainerView.MOVE_IN and SC.ContainerView.REVEAL.
|
31
|
+
* Adds a developer error message if an SC.View is created using an existing layerId. This should prevent some weirdness from occurring.
|
32
|
+
* Refactors SC.View:animate().
|
33
|
+
|
34
|
+
- animate() uses invokeNext() so that the developer never needs to monkey with
|
35
|
+
the run loop in order to call animate(). Animations will only begin after
|
36
|
+
the browser has had a chance to flush any changes to the DOM, thus ensuring
|
37
|
+
that the animation actually occurs. This will make using .animate() much
|
38
|
+
easier whereas previously, developers would revert to invokeLater/invokeLast
|
39
|
+
to try and make sure the DOM style existed before animate would adjust it.
|
40
|
+
- the animate() function can now accept a target argument as well as a method,
|
41
|
+
which conforms to the standard used by many methods in SproutCore.
|
42
|
+
- if no target it given the view itself will be the value of `this` in the
|
43
|
+
callback. Previously, this would be the layoutStyleCalculator, an internal
|
44
|
+
object of SC.View.
|
45
|
+
- the animate() function is thoroughly documented now, including notes on how
|
46
|
+
to hardware accelerate position changes.
|
47
|
+
- uses new additions to SC.platform and SC.browser to make animations forward
|
48
|
+
compatible and fixes animate() on Firefox nightly
|
49
|
+
- hardware accelerated styles no longer remain in the DOM after the animation
|
50
|
+
completes (i.e. sometimes the translate values would stay in the style)
|
51
|
+
- resetAnimation() has been renamed to cancelAnimation(), because reset
|
52
|
+
indicates 'revert', but the default behavior doesn't revert the layout.
|
53
|
+
- added SC.LayoutState enum for use by cancelAnimation().
|
54
|
+
- fixes hasAcceleratedLayer to be dependent on the layout. Previously,
|
55
|
+
adjusting a non-accelerated layout to an accelerate-able layout failed to
|
56
|
+
update the property and hasAcceleratedLayer would be incorrect.
|
57
|
+
- cancelAnimation() can now cancel an animation and adjust the layout to its
|
58
|
+
current value during the transition, to its original value or to the final
|
59
|
+
value which is the default. The current value even works for accelerated
|
60
|
+
transitions that use transforms and return CSSMatrix values while animating.
|
61
|
+
- simplifies the code somewhat and cleans up a lot of loose ends that remained
|
62
|
+
since the original code was largely copy-pasted over from the old animation
|
63
|
+
framework.
|
64
|
+
- removes an observer on the view's layout from within the
|
65
|
+
layoutStyleCalculator and properly chained up the dependencies to remove
|
66
|
+
some manual notification code.
|
67
|
+
- Previously, each SC.View created an SC.LayoutStyleCalculator object that it
|
68
|
+
used in a truly dubious manner. The LayoutStyleCalculator was supposed to be a group of functions that could be shared between all views, but instead each view had to create and modify its own instance of the calculator. The calculator had several internal state variables which meant it could not be shared between views. The calculator also cross-referenced the view itself and was never cleaned up resulting in a memory leak. This update untangles the view from the calculator so that the calculator can be shared between views (not really much reason to even have this separate, but none-the-less…).
|
69
|
+
* Changes the internal classNames of SC.Theme to be an Array rather than a CoreSet. Having it as a Set makes no sense and the amount of property overloading is ridiculous. We have to check for Objects, Arrays, Strings and Sets, which is a waste of code rather than just standardizing on an Array like classNames is on SC.View. Also, this causes problems if developers use the theme's classNames and assume it will be an Array like with SC.View.
|
70
|
+
* Refactors transition and animation testing of SC.platform;
|
71
|
+
adds SC.browser.cssPrefix, SC.browser.domPrefix and SC.browser.classPrefix;
|
72
|
+
adds SC.browser.experimentalNameFor(), SC.browser.experimentalStyleNameFor()
|
73
|
+
and SC.browser. experimentalCSSNameFor() methods;
|
74
|
+
adds SC.UNSUPPORTED constant.
|
75
|
+
|
76
|
+
There were many problems with the animation and transition tests that existed before. There was no forward support so browsers, like the Firefox nightly that have dropped prefixes, would fail to identify as supporting transitions and transforms. Also, animation event listeners were hard coded into RootResponder for webkit only. Also the event names needed to be forward supported as well and because there is no consistency in the event naming, the real transition and animation events may not have been captured on certain browsers.
|
77
|
+
|
78
|
+
Now, SC.platform does quick and precise tests to determine the actual event names allowing the RootResponder to listen only to the properly named events rather than using a shotgun approach with a bunch of different browser prefixes.
|
79
|
+
|
80
|
+
To make the code forward compatible for when prefixes are dropped, SC.browser has three new support functions: experimentalNameFor(), experimentalStyleNameFor(), experimentalCSSNameFor(). These functions return the proper name for experimental names for object classes & properties, DOM properties and CSS attributes, not by guessing, but by testing the standard name and then testing prefixed versions of the name if necessary. This allows developers to avoid writing code like: SC.browser.cssPrefix + "box-shadow black 0 1px 2px", which will fail on browsers that no longer need a prefix and instead use: SC.browser.experimentalCSSNameFor('boxShadow'), which will return either "box-shadow", some browser prefix + "box-shadow" or SC.UNSUPPORTED (allowing you to do something else).
|
81
|
+
* Makes invokeNext trigger the next run of the run loop if none is scheduled.
|
82
|
+
This makes invokeNext the appropriate method to use when needing the DOM to
|
83
|
+
be up-to-date before running code against it.
|
84
|
+
|
85
|
+
Previously, invokeNext functions would not run until the next run loop
|
86
|
+
occurred, which if there were no events or timers, might mean that the code
|
87
|
+
won't run for a long time. While invokeLast lets you put code at the end of
|
88
|
+
the run loop, the DOM will not have yet been updated and invokeLater is risky
|
89
|
+
to use at small intervals, because if the interval is too small, the
|
90
|
+
invokeLater code will run in the current run of the run loop and again the DOM
|
91
|
+
will not have been updated. Instead, invokeNext now ensures that the run loop
|
92
|
+
completes execution and schedules an immediate timeout in order to allow the
|
93
|
+
browser to update the DOM.
|
94
|
+
|
95
|
+
This works with the timer additions to the run loop, so additional run loops
|
96
|
+
only run once even if there is an invokeLater expiring at the same time as the
|
97
|
+
invokeNext timeout triggers a new run loop.
|
98
|
+
* Refactors SC.RenderContext to simplify the API, introduce consistent naming
|
99
|
+
and make it behave appropriately. This should remove the guess work about
|
100
|
+
whether a function is or is not supported by the context and make it easier
|
101
|
+
to remember the names and parameters of each method.
|
102
|
+
|
103
|
+
- There are now 3 similar access methods: attrs(), classes(), styles()
|
104
|
+
- There are now 3 similar add methods: addAttr(), addClass(), addStyle()
|
105
|
+
- There are now 3 similar remove methods: removeAttr(), removeClass(), removeStyle()
|
106
|
+
- There are now 2 similar reset methods: resetClasses(), resetStyles()
|
107
|
+
- Fully backwards compatible.
|
108
|
+
- Duplicate and inconsistent method names have been deprecated: css(), html(),
|
109
|
+
classNames(), resetClassNames(), attr()
|
110
|
+
- Adds several Developer Warnings to aid developers in updating their code
|
111
|
+
(in debug mode only as not to take up space in production).
|
112
|
+
* Added platform detection for the Apache Cordova (formerly phonegap)
|
113
|
+
javascript-to-mobile bridge.
|
114
|
+
* Added gitignore entries for .project and .settings, which are eclipse-specific
|
115
|
+
configuration files.
|
116
|
+
* Updates jQuery framework to 1.8.3 and removes buffered jQuery.
|
117
|
+
* Patches jQuery to prevent security warnings in IE.
|
118
|
+
|
119
|
+
This does NOT patch jQuery to make all calls to .append(), .insert(), etc.
|
120
|
+
pass security validation in IE. Instead it uses execUnsafeLocalFunction to
|
121
|
+
perform jQuery's tests that are based on invalid HTML.
|
122
|
+
* Minor optimizations to Array#filterProperty.
|
123
|
+
* Improves animation support for current and future browsers. The previous
|
124
|
+
platform checks prevented using accelerated layers on non-webkit platforms,
|
125
|
+
plus any browser that dropped the prefixes would indicate that they did not
|
126
|
+
have support for transitions and transforms.
|
127
|
+
* Removes duplicate transitionend event listeners and only listens for the
|
128
|
+
supported platforms event.
|
129
|
+
* Adds 'delay' option to set the transition-delay property
|
130
|
+
* Adds new SproutCore-only date time formatter, %E, to SC.DateTime which returns
|
131
|
+
the elapsed time from or since now. There is an entire set of default values
|
132
|
+
from the number of years ago to right now to a number of years in the future
|
133
|
+
and of course the strings are completely configurable and localizable.
|
134
|
+
|
135
|
+
For example,
|
136
|
+
|
137
|
+
var date = SC.DateTime.create();
|
138
|
+
|
139
|
+
date.toFormattedString("%E"); // "Right now"
|
140
|
+
|
141
|
+
date.advance({ minute: 4 });
|
142
|
+
date.toFormattedString("%E"); // "In 4 minutes"
|
143
|
+
|
144
|
+
date.advance({ day: -7 });
|
145
|
+
date.toFormattedString("%E"); // "About a week ago"
|
146
|
+
|
10
147
|
* Adds SC.appCache and SC.platform.supportsApplicationCache.
|
11
148
|
Working with the application cache is a confusing and time-consuming task.
|
12
149
|
This simple object abstracts out the most important properties for developers
|
@@ -45,6 +182,15 @@ Edge
|
|
45
182
|
|
46
183
|
### DEPRECATIONS & REMOVALS
|
47
184
|
|
185
|
+
* Deprecates SC.platform.cssPrefix and SC.platform.domCSSPrefix in favor of
|
186
|
+
SC.browser.cssPrefix, SC.browser.domPrefix and SC.browser.classPrefix. The css
|
187
|
+
prefix and dom prefix in SC.platform were calculated from the user agent, which
|
188
|
+
duplicated work already being done with more rigor in SC.browser.
|
189
|
+
* The :template_view framework is no longer included by default when requiring
|
190
|
+
:sproutcore. This framework is now partially deprecated, meaning that it
|
191
|
+
won't be officially supported by the core team. But it is not scheduled
|
192
|
+
to be removed in any successive version and therefor anyone using it is
|
193
|
+
welcome to continue doing so.
|
48
194
|
* The default value of SC.SelectView:itemSeparatorKey has been changed from
|
49
195
|
'separator' to 'isSeparator' to match the documentation. If a property
|
50
196
|
'separator' is found on the item, it will still be used and a developer
|
@@ -58,6 +204,28 @@ Edge
|
|
58
204
|
|
59
205
|
### BUG FIXES
|
60
206
|
|
207
|
+
* Fixes a regression with SC.CollectionView that occurred after a previous fix
|
208
|
+
to remove a view DOM leak. SC.CollectionView previously created a view with
|
209
|
+
the same layerId as the view to be replaced before replacing it, which only
|
210
|
+
worked because of some weird logic external to the CollectionView that used to
|
211
|
+
prevent a view from being able to find its layer if it didn't have a
|
212
|
+
parentView (which was also the cause of a leak because the layer might still
|
213
|
+
exist in the DOM). In any case, having two views use the same layerId at the
|
214
|
+
same time is a bad idea.
|
215
|
+
* Fixes duplicate 'input' property in SC.platform.
|
216
|
+
* Fixes bug noticed by updated jQuery. The previous version of
|
217
|
+
SC.RenderContext:addStyle() would replace styles, which was really only due
|
218
|
+
to an undocumented behavior of jQuery, plus it is semantically incorrect for
|
219
|
+
'add' to replace. The refactor of RenderContext makes the functions behave
|
220
|
+
properly.
|
221
|
+
* Fixes SC.View:animate() failing to work on Firefox 16+ and IE10+, since they
|
222
|
+
have dropped prefixes on the properties.
|
223
|
+
* Fixes problem with cleaning up bindings on SC.View. Previously, SC.View would
|
224
|
+
destroy itself first before calling the super destroy method. This would
|
225
|
+
remove the parentView object from all childViews, which meant that when the
|
226
|
+
super destroy method tried to remove bindings and observers, it was unable to
|
227
|
+
resolve any parentView property paths and thus unable to remove any bindings
|
228
|
+
to the view's parentView.
|
61
229
|
* Fixes minor memory leak in SC.Set. The way that SC.Set removes objects is
|
62
230
|
to "untrack" the internal index of the object by shrinking its length, but it
|
63
231
|
never actually removed the object at the last index. The only way that the
|
@@ -78,6 +246,39 @@ Edge
|
|
78
246
|
because the target may have been destroyed and freed, but we are still
|
79
247
|
maintaining an empty tracking hash for it.
|
80
248
|
|
249
|
+
1.9.2 - BUG FIX RELEASE
|
250
|
+
----------
|
251
|
+
|
252
|
+
* Softens the build tools dependency requirements from being ultra-pessimistic (i.e. within a minor version) to being pessimistic (i.e. within a major version).
|
253
|
+
* Fixes 'repeat' slice for @2x version. It was incorrectly appending @2x to the end of the whole path (ex. /resources/images/image-sliced-from.png@2x instead of /resources/images/image-sliced-from@2x.png).
|
254
|
+
* Fixes incorrectly named "responder" generator to "state" generator for generating SC.State subclasses.
|
255
|
+
* Fixes the snake case generator for "sproutcore gen", so that names like 'SCProject' get properly transformed to 'sc_project' and not 's_c_project'.
|
256
|
+
* Added support for background-size property in Buildtools spriting, this is required for spriting to work properly in retina firefox.
|
257
|
+
* Fixes inconsistencies and improper syntax in several templates created with "sproutcore gen".
|
258
|
+
* Fixes missing stylesheet warnings on a clean app generated with "sproutcore gen app" or "sproutcore gen statechart_app" by adding a default stylesheet to the app. Also adds a default stylesheet to a design, when using "sproutcore gen design" (i.e. an SC.Page resource)
|
259
|
+
* Fixes improper binary search used by SC.ManyArray addInverseRecord that resulted in an infinite loop.
|
260
|
+
* Fixes bug that allowed the context menu to appear regardless of overriding contextMenu in a view or setting SC.CONTEXT_MENU_ENABLED or isContextMenuEnabled to false. This makes the context menu event handling behave the same as the key, mouse, etc. event handling.
|
261
|
+
* Fixes actions: deleteForward, deleteBackward, moveLeft, moveRight, selectAll, moveUp and moveDown to be always handled by the TextFieldView element when it has focus.
|
262
|
+
* Fixes SC.TextFieldView to insert a new line when the enter key is pressed on a text area.
|
263
|
+
* Fixes the hint value for SC.LabelView so that it will appear when the label has no value and isEditable is true. Includes unit test.
|
264
|
+
* No longer modifies the underlying items given to an SC.SegmentedView with an
|
265
|
+
overflow menu directly so that we don't invariably dirty the original object.
|
266
|
+
* Fixes regression in IE7 and IE8 which caused XHR requests to fail to notify.
|
267
|
+
Also fixes unit tests to pass in IE7+.
|
268
|
+
* Fixes debug images and test iframe.html being included in builds. These files
|
269
|
+
(one of which is 2.5MB) would get included into every build, because they were
|
270
|
+
at the wrong path. I removed the apple logo which appears unused in the tests
|
271
|
+
and fixed the directory structure and file references so that
|
272
|
+
'a_sample_image.jpg' and 'iframe.html' don't get included in production builds.
|
273
|
+
|
274
|
+
Note: this is especially a problem if you wanted to create an app manifest
|
275
|
+
based on the contents of the built static directory. The client would have to
|
276
|
+
download a 2.5MB debug image that is never used.
|
277
|
+
* Fixes SC.browser unit tests
|
278
|
+
* Fixes determination of touch support in Chrome on Win 8.
|
279
|
+
* Adds missing un-prefixed border-radius rules to the default theme for browsers
|
280
|
+
that have dropped the prefix.
|
281
|
+
|
81
282
|
1.9.1 - BUG FIX RELEASE
|
82
283
|
----------
|
83
284
|
|
@@ -1202,25 +1403,25 @@ more, please see frameworks/experimental/README.md.
|
|
1202
1403
|
* Support for extending classes after they've been created with the
|
1203
1404
|
reopen()/enhance() combo. For more, see: [this
|
1204
1405
|
discussion](http://groups.google.com/group/sproutcore-dev/browse_thread/thread/d65ad54d6fddef5d)
|
1205
|
-
|
1206
|
-
|
1406
|
+
- This change may break existing code if you call sc_super() in your mixins.
|
1407
|
+
If your app throws exceptions after updating, please see [this post](http://groups.google.com/group/sproutcore-dev/browse_thread/thread/cc6a97e6133cb8cc).
|
1207
1408
|
* Added SC.TemplateView and Handlebars. These allow you to specify the content
|
1208
1409
|
of your views using templates.
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1410
|
+
- {{#view}} helper allows you to define child views
|
1411
|
+
- {{#bind}} helper allows you to render a property, and automatically update DOM if that
|
1412
|
+
property ever changes.
|
1413
|
+
- {{#collection}} helpers allows you to render a simple collection of items
|
1414
|
+
using templates
|
1415
|
+
- SC.TextFieldSupport and SC.CheckboxSupport mixins for SC.TemplateViews
|
1416
|
+
that wrap <input> elements.
|
1216
1417
|
* Split SC.View into units of functionality. SC.View remains functionally the
|
1217
1418
|
same, but you can now use SC.CoreView, a light-weight subset of SC.View.
|
1218
1419
|
* SC.ImageView will use a <canvas> tag on platforms that support it, which
|
1219
1420
|
improves performance significantly.
|
1220
1421
|
* SC.SegmentedView now creates an overflow menu if there are too many segments
|
1221
1422
|
to display.
|
1222
|
-
|
1223
|
-
|
1423
|
+
- Class names for SC.SegmentedView have been cleaned up. You may need to
|
1424
|
+
update your CSS if you were theming SC.SegmentedView.
|
1224
1425
|
* You can now observe the contents of enumerables using the special `@each`
|
1225
1426
|
key.
|
1226
1427
|
* Dependent keys can accept property paths. For example, you can say
|
@@ -80,7 +80,7 @@ SC.Response = SC.Object.extend(
|
|
80
80
|
originalRequest: function() {
|
81
81
|
var ret = this.get('request');
|
82
82
|
while (ret.get('source')) { ret = ret.get('source'); }
|
83
|
-
return ret
|
83
|
+
return ret;
|
84
84
|
}.property('request').cacheable(),
|
85
85
|
|
86
86
|
/**
|
@@ -128,7 +128,7 @@ SC.Response = SC.Object.extend(
|
|
128
128
|
@observes request
|
129
129
|
*/
|
130
130
|
isXML: function() {
|
131
|
-
return this.getPath('request.isXML') || NO
|
131
|
+
return this.getPath('request.isXML') || NO;
|
132
132
|
}.property('request').cacheable(),
|
133
133
|
|
134
134
|
/**
|
@@ -324,9 +324,9 @@ SC.Response = SC.Object.extend(
|
|
324
324
|
*/
|
325
325
|
cancel: function() {
|
326
326
|
if (!this.get('isCancelled')) {
|
327
|
-
this.set('isCancelled', YES)
|
328
|
-
this.cancelTransport()
|
329
|
-
SC.Request.manager.transportDidClose(this)
|
327
|
+
this.set('isCancelled', YES);
|
328
|
+
this.cancelTransport();
|
329
|
+
SC.Request.manager.transportDidClose(this);
|
330
330
|
}
|
331
331
|
},
|
332
332
|
|
@@ -349,8 +349,8 @@ SC.Response = SC.Object.extend(
|
|
349
349
|
if (!proceed) { return; }
|
350
350
|
|
351
351
|
// Set our value to an error.
|
352
|
-
var error = SC.$error("HTTP Request timed out", "Request", 0)
|
353
|
-
error.set("errorValue", this)
|
352
|
+
var error = SC.$error("HTTP Request timed out", "Request", 0);
|
353
|
+
error.set("errorValue", this);
|
354
354
|
this.set('isError', YES);
|
355
355
|
this.set('errorObject', error);
|
356
356
|
this.set('status', 0);
|
@@ -411,7 +411,7 @@ SC.Response = SC.Object.extend(
|
|
411
411
|
if (!handled && baseStat !== status) { handled = this._notifyListeners(listeners, baseStat); }
|
412
412
|
if (!handled && status !== 0) { handled = this._notifyListeners(listeners, 0); }
|
413
413
|
|
414
|
-
return this
|
414
|
+
return this;
|
415
415
|
},
|
416
416
|
|
417
417
|
/**
|
@@ -513,7 +513,7 @@ SC.XHRResponse = SC.Response.extend(
|
|
513
513
|
rawRequest = this.createRequest();
|
514
514
|
this.set('rawRequest', rawRequest);
|
515
515
|
|
516
|
-
|
516
|
+
// configure async callback - differs per browser...
|
517
517
|
async = !!request.get('isAsynchronous');
|
518
518
|
|
519
519
|
if (async) {
|
@@ -549,8 +549,8 @@ SC.XHRResponse = SC.Response.extend(
|
|
549
549
|
}
|
550
550
|
|
551
551
|
SC.Event.add(rawRequest, 'loadend', this, this.finishRequest);
|
552
|
-
} else if (window.XMLHttpRequest) {
|
553
|
-
// XMLHttpRequest Level 1
|
552
|
+
} else if (window.XMLHttpRequest && rawRequest.addEventListener) {
|
553
|
+
// XMLHttpRequest Level 1 + support for addEventListener (IE prior to version 9.0 lacks support for addEventListener)
|
554
554
|
SC.Event.add(rawRequest, 'readystatechange', this, this.finishRequest);
|
555
555
|
} else {
|
556
556
|
transport = this;
|
@@ -570,12 +570,12 @@ SC.XHRResponse = SC.Response.extend(
|
|
570
570
|
// headers need to be set *after* the open call.
|
571
571
|
headers = this.getPath('request.headers');
|
572
572
|
for (var headerKey in headers) {
|
573
|
-
rawRequest.setRequestHeader(headerKey, headers[headerKey])
|
573
|
+
rawRequest.setRequestHeader(headerKey, headers[headerKey]);
|
574
574
|
}
|
575
575
|
|
576
576
|
// now send the actual request body - for sync requests browser will
|
577
577
|
// block here
|
578
|
-
rawRequest.send(this.getPath('request.encodedBody'))
|
578
|
+
rawRequest.send(this.getPath('request.encodedBody'));
|
579
579
|
if (!async) { this.finishRequest(); }
|
580
580
|
|
581
581
|
return rawRequest;
|
@@ -643,7 +643,7 @@ SC.XHRResponse = SC.Response.extend(
|
|
643
643
|
}
|
644
644
|
|
645
645
|
error = SC.$error(msg || "HTTP Request failed", "Request", status);
|
646
|
-
error.set("errorValue", this)
|
646
|
+
error.set("errorValue", this);
|
647
647
|
this.set('isError', YES);
|
648
648
|
this.set('errorObject', error);
|
649
649
|
}
|
@@ -654,7 +654,7 @@ SC.XHRResponse = SC.Response.extend(
|
|
654
654
|
|
655
655
|
// Avoid memory leaks
|
656
656
|
if (window.XMLHttpRequestProgressEvent) {
|
657
|
-
//
|
657
|
+
// XMLHttpRequest Level 2
|
658
658
|
|
659
659
|
SC.Event.remove(rawRequest, 'loadend', this, this.finishRequest);
|
660
660
|
|
@@ -679,8 +679,8 @@ SC.XHRResponse = SC.Response.extend(
|
|
679
679
|
}
|
680
680
|
}
|
681
681
|
}
|
682
|
-
} else if (window.XMLHttpRequest) {
|
683
|
-
//
|
682
|
+
} else if (window.XMLHttpRequest && rawRequest.addEventListener) {
|
683
|
+
// XMLHttpRequest Level 1 + support for addEventListener (IE prior to version 9.0 lacks support for addEventListener)
|
684
684
|
SC.Event.remove(rawRequest, 'readystatechange', this, this.finishRequest);
|
685
685
|
} else {
|
686
686
|
rawRequest.onreadystatechange = null;
|
@@ -9,27 +9,27 @@
|
|
9
9
|
// ========================================================================
|
10
10
|
/*globals module, test, ok, isObj, equals, expects */
|
11
11
|
|
12
|
-
var url, request, contents
|
12
|
+
var url, request, contents;
|
13
13
|
|
14
14
|
module("SC.Request", {
|
15
15
|
|
16
16
|
setup: function() {
|
17
17
|
url = sc_static("file_exists.json");
|
18
18
|
request = SC.Request.getUrl(url);
|
19
|
-
contents = null
|
19
|
+
contents = null;
|
20
20
|
},
|
21
21
|
|
22
22
|
teardown: function() {
|
23
|
-
url = request = contents;
|
23
|
+
url = request = contents = null;
|
24
24
|
}
|
25
25
|
|
26
26
|
});
|
27
27
|
|
28
28
|
test("Basic Requirements", function() {
|
29
|
-
ok(SC.Request, "SC.Request is defined")
|
30
|
-
ok("" !== url, "url variable is not empty")
|
31
|
-
ok(request !== null, "request object is not null")
|
32
|
-
ok(contents === null, "contents is null" )
|
29
|
+
ok(SC.Request, "SC.Request is defined");
|
30
|
+
ok("" !== url, "url variable is not empty");
|
31
|
+
ok(request !== null, "request object is not null");
|
32
|
+
ok(contents === null, "contents is null" );
|
33
33
|
});
|
34
34
|
|
35
35
|
test("Default properties are correct for different types of requests.", function() {
|
@@ -40,7 +40,26 @@ test("Default properties are correct for different types of requests.", function
|
|
40
40
|
req1, req2, req3, req4, req5;
|
41
41
|
|
42
42
|
// use this document for creating XML
|
43
|
-
|
43
|
+
if (document.implementation.createDocument) {
|
44
|
+
xmlBody = document.implementation.createDocument(null, null, null);
|
45
|
+
} else if (typeof (ActiveXObject) != "undefined") {
|
46
|
+
// Use ActiveXObject for IE prior to version 9.
|
47
|
+
var progIDs = [
|
48
|
+
"Msxml2.DOMDocument.6.0",
|
49
|
+
"Msxml2.DOMDocument.5.0",
|
50
|
+
"Msxml2.DOMDocument.4.0",
|
51
|
+
"Msxml2.DOMDocument.3.0",
|
52
|
+
"MSXML2.DOMDocument",
|
53
|
+
"MSXML.DOMDocument"
|
54
|
+
];
|
55
|
+
|
56
|
+
for (var i = 0; i < progIDs.length; i++) {
|
57
|
+
try {
|
58
|
+
xmlBody = new ActiveXObject(progIDs[i]);
|
59
|
+
break;
|
60
|
+
} catch(e) {}
|
61
|
+
}
|
62
|
+
}
|
44
63
|
|
45
64
|
// function that creates the XML structure
|
46
65
|
function o() {
|
@@ -120,16 +139,16 @@ test("Test Asynchronous GET Request", function() {
|
|
120
139
|
ok(response !== null, 'request.send() should return a response object');
|
121
140
|
ok(response.get('status')<0, 'response should still not have a return code since this should be async');
|
122
141
|
|
123
|
-
stop()
|
142
|
+
stop(2500); // stops the test runner - wait for response
|
124
143
|
});
|
125
144
|
|
126
145
|
test("Test Synchronous GET Request", function() {
|
127
146
|
request.set("isAsynchronous", NO);
|
128
147
|
var response = request.send();
|
129
148
|
|
130
|
-
ok(response !== null, 'send() should return response')
|
149
|
+
ok(response !== null, 'send() should return response');
|
131
150
|
ok(SC.$ok(response), 'contents should not be an error ');
|
132
|
-
equals(response.get('body'), '{"message": "Yay!"}', 'should match retrieved message')
|
151
|
+
equals(response.get('body'), '{"message": "Yay!"}', 'should match retrieved message');
|
133
152
|
});
|
134
153
|
|
135
154
|
test("Test Asynchronous GET Request, auto-deserializing JSON", function() {
|
@@ -152,7 +171,7 @@ test("Test Asynchronous GET Request, auto-deserializing JSON", function() {
|
|
152
171
|
|
153
172
|
request.send();
|
154
173
|
|
155
|
-
stop()
|
174
|
+
stop(2500); // stops the test runner
|
156
175
|
|
157
176
|
});
|
158
177
|
|
@@ -180,7 +199,7 @@ test("Test auto-deserializing malformed JSON", function() {
|
|
180
199
|
|
181
200
|
request.send();
|
182
201
|
|
183
|
-
stop();
|
202
|
+
stop(2500);
|
184
203
|
});
|
185
204
|
|
186
205
|
test("Test Synchronous GET Request, auto-deserializing JSON", function() {
|
@@ -189,9 +208,9 @@ test("Test Synchronous GET Request, auto-deserializing JSON", function() {
|
|
189
208
|
|
190
209
|
var response = request.send();
|
191
210
|
|
192
|
-
ok(response !== null, 'response should not be null')
|
211
|
+
ok(response !== null, 'response should not be null');
|
193
212
|
ok(SC.ok(response), 'contents should not be an error');
|
194
|
-
same(response.get('body'), {"message": "Yay!"}, 'contents should have message')
|
213
|
+
same(response.get('body'), {"message": "Yay!"}, 'contents should have message');
|
195
214
|
});
|
196
215
|
|
197
216
|
|
@@ -224,11 +243,11 @@ test("Test Multiple Asynchronous GET Request - two immediate, and two in serial"
|
|
224
243
|
SC.Request.getUrl(url).notify(this, observer).send();
|
225
244
|
SC.Request.getUrl(url).notify(this, observer).send();
|
226
245
|
|
227
|
-
stop()
|
246
|
+
stop(2500); // stops the test runner
|
228
247
|
setTimeout( function(){
|
229
248
|
equals(requestCount, 6, "requestCount should be 6");
|
230
249
|
equals(responseCount, 6, "responseCount should be 6");
|
231
|
-
window.start()
|
250
|
+
window.start(); // starts the test runner
|
232
251
|
}, 2000);
|
233
252
|
});
|
234
253
|
|
@@ -244,8 +263,7 @@ test("Timeouts - SC.Request didReceive callback", function() {
|
|
244
263
|
// Sanity check - Should throw an error if we try to set a timeout of 0s.
|
245
264
|
try {
|
246
265
|
SC.Request.getUrl(url).set('timeout', 0).send();
|
247
|
-
}
|
248
|
-
catch (e) {
|
266
|
+
} catch (e) {
|
249
267
|
message = e;
|
250
268
|
}
|
251
269
|
ok(message && message.indexOf("The timeout value must either not be specified or must be greater than 0") !== -1, 'An error should be thrown when the timeout value is 0 ms');
|
@@ -299,7 +317,7 @@ test("Timeouts - SC.Request didReceive callback", function() {
|
|
299
317
|
SC.RunLoop.end();
|
300
318
|
|
301
319
|
// Stop the test runner and wait for a timeout or a response.
|
302
|
-
stop();
|
320
|
+
stop(2500);
|
303
321
|
|
304
322
|
// In case we never receive a timeout, just start unit testing again after
|
305
323
|
// 500ms.
|
@@ -331,7 +349,7 @@ test("Timeouts - Status listener callback", function() {
|
|
331
349
|
timeoutRequest.send();
|
332
350
|
SC.RunLoop.end();
|
333
351
|
|
334
|
-
stop()
|
352
|
+
stop(2500); // stops the test runner
|
335
353
|
|
336
354
|
// in case nothing works
|
337
355
|
checkstop = setTimeout(function() {
|
@@ -364,7 +382,7 @@ test("Test Multiple listeners per single status response", function() {
|
|
364
382
|
ok(response !== null, 'request.send() should return a response object');
|
365
383
|
ok(response.get('status')<0, 'response should still not have a return code since this should be async');
|
366
384
|
|
367
|
-
stop()
|
385
|
+
stop(2500); // stops the test runner - wait for response
|
368
386
|
});
|
369
387
|
|
370
388
|
|
@@ -380,8 +398,6 @@ test("Multiple arguments passed to notify()", function() {
|
|
380
398
|
equals(a, 'a', "Listener called with argument 'a'");
|
381
399
|
equals(b, 'b', "Listener called with argument 'b'");
|
382
400
|
equals(c, 'c', "Listener called with argument 'c'");
|
383
|
-
|
384
|
-
window.start();
|
385
401
|
}, 'a', 'b', 'c');
|
386
402
|
|
387
403
|
request.notify(200, this, function(response, a, b, c) {
|
@@ -394,7 +410,7 @@ test("Multiple arguments passed to notify()", function() {
|
|
394
410
|
|
395
411
|
response = request.send();
|
396
412
|
|
397
|
-
stop()
|
413
|
+
stop(2500); // stops the test runner - wait for response
|
398
414
|
});
|
399
415
|
|
400
416
|
|
@@ -428,10 +444,12 @@ test("Test event listeners on successful request.", function() {
|
|
428
444
|
request.notify(200, this, function(response) {
|
429
445
|
status = response.status;
|
430
446
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
447
|
+
if (window.XMLHttpRequestProgressEvent) {
|
448
|
+
ok(loadstart, "Received a loadstart event.");
|
449
|
+
ok(progress, "Received a progress event.");
|
450
|
+
ok(load, "Received a load event.");
|
451
|
+
ok(loadend, "Received a loadend event.");
|
452
|
+
}
|
435
453
|
ok(!abort, "Did not receive an abort event.");
|
436
454
|
ok(!error, "Did not receive an error event.");
|
437
455
|
ok(!timeout, "Did not receive a timeout event.");
|
@@ -442,59 +460,56 @@ test("Test event listeners on successful request.", function() {
|
|
442
460
|
|
443
461
|
response = request.send();
|
444
462
|
|
445
|
-
stop()
|
463
|
+
stop(2500); // stops the test runner - wait for response
|
446
464
|
});
|
447
465
|
|
448
|
-
|
449
|
-
test("Test event listeners on aborted request.", function() {
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
466
|
+
if (window.XMLHttpRequestProgressEvent) {
|
467
|
+
test("Test event listeners on aborted request.", function() {
|
468
|
+
var abort = false,
|
469
|
+
error = false,
|
470
|
+
load = false,
|
471
|
+
loadend = false,
|
472
|
+
loadstart = false,
|
473
|
+
progress = false,
|
474
|
+
response,
|
475
|
+
status,
|
476
|
+
timeout = false;
|
477
|
+
|
478
|
+
request.notify("loadstart", this, function(evt) {
|
479
|
+
loadstart = true;
|
480
|
+
});
|
481
|
+
|
482
|
+
request.notify("abort", this, function(evt) {
|
483
|
+
abort = true;
|
484
|
+
});
|
485
|
+
|
486
|
+
request.notify("progress", this, function(evt) {
|
487
|
+
progress = true;
|
488
|
+
|
489
|
+
// Cancel it before it completes.
|
490
|
+
response.cancel();
|
491
|
+
});
|
492
|
+
|
493
|
+
request.notify("loadend", this, function(evt) {
|
494
|
+
loadend = true;
|
495
|
+
|
496
|
+
ok(loadstart, "Received a loadstart event.");
|
497
|
+
ok(progress, "Received a progress event.");
|
498
|
+
ok(abort, "Received an abort event.");
|
499
|
+
ok(!load, "Did not receive a load event.");
|
500
|
+
ok(loadend, "Received a loadend event.");
|
501
|
+
ok(!error, "Did not receive an error event.");
|
502
|
+
ok(!timeout, "Did not receive a timeout event.");
|
503
|
+
equals(status, undefined, "Did not receive a status notification.");
|
504
|
+
|
505
|
+
window.start();
|
506
|
+
});
|
507
|
+
|
508
|
+
response = request.send();
|
509
|
+
|
510
|
+
stop(2500); // stops the test runner - wait for response
|
492
511
|
});
|
493
|
-
|
494
|
-
response = request.send();
|
495
|
-
|
496
|
-
stop(); // stops the test runner - wait for response
|
497
|
-
});
|
512
|
+
}
|
498
513
|
|
499
514
|
test("Test upload event listeners on successful request.", function() {
|
500
515
|
var abort = false,
|
@@ -530,10 +545,12 @@ test("Test upload event listeners on successful request.", function() {
|
|
530
545
|
request.notify(200, this, function(response) {
|
531
546
|
status = response.status;
|
532
547
|
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
548
|
+
if (window.XMLHttpRequestProgressEvent) {
|
549
|
+
ok(loadstart, "Received a loadstart event.");
|
550
|
+
ok(progress, "Received a progress event.");
|
551
|
+
ok(load, "Received a load event.");
|
552
|
+
ok(loadend, "Received a loadend event.");
|
553
|
+
}
|
537
554
|
ok(!abort, "Did not receive an abort event.");
|
538
555
|
ok(!error, "Did not receive an error event.");
|
539
556
|
ok(!timeout, "Did not receive a timeout event.");
|
@@ -544,11 +561,11 @@ test("Test upload event listeners on successful request.", function() {
|
|
544
561
|
|
545
562
|
// Make a significant body object.
|
546
563
|
var i;
|
547
|
-
for (i =
|
564
|
+
for (i = 2000; i >= 0; i--) {
|
548
565
|
body['k' + i] = 'v' + i;
|
549
566
|
}
|
550
567
|
|
551
|
-
response = request.send(body);
|
568
|
+
response = request.send(JSON.stringify(body));
|
552
569
|
|
553
|
-
stop()
|
570
|
+
stop(2500); // stops the test runner - wait for response
|
554
571
|
});
|