sproutcore 1.6.0.beta.1 → 1.6.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ *SproutCore 1.6.0.beta.2 (May 10, 2011)*
2
+
3
+ * Framework updates
4
+ * Less noisy packager task
5
+
6
+
1
7
  *SproutCore 1.6.0.beta.1 (May 8, 2011)*
2
8
 
3
9
  * Better dependencies for Windows
@@ -6,6 +12,7 @@
6
12
  * Uses newer version of Thin
7
13
  * Uses newer version of YUI Compressor
8
14
 
15
+
9
16
  *SproutCore 1.5.0 (April 19, 2011)*
10
17
 
11
18
  * Fixed description for init, docs and gen tasks
@@ -18,6 +25,7 @@
18
25
 
19
26
  * Fixed a compatibility issue with Windows environments
20
27
 
28
+
21
29
  *SproutCore 1.5.0.rc.1 (April 1, 2011)*
22
30
 
23
31
  * Made it possible to share index.html across multiple languages vs. duplicating it for each.
data/Rakefile CHANGED
@@ -56,5 +56,7 @@ begin
56
56
  t.resource_files = ["vendor", "VERSION.yml"]
57
57
  end
58
58
  rescue LoadError
59
- puts "`gem install packager` for packaging tasks"
59
+ if Rake.application.options.show_tasks
60
+ puts "`gem install packager` for packaging tasks"
61
+ end
60
62
  end
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 1
3
3
  :minor: 6
4
- :patch: 0.beta.1
4
+ :patch: 0.beta.2
@@ -2,6 +2,13 @@
2
2
  CHANGE LOG FOR 1.6
3
3
  ==================
4
4
 
5
+ 1.6.0.beta.2
6
+ ------------
7
+ * Allow native touch scrolling inside an SC.TemplatePane.
8
+ * Add SC.Button template control.
9
+ * Created SC.TextField and SC.Checkbox views to eventually replace the *Support mixins.
10
+
11
+
5
12
  1.6.0.beta.1
6
13
  ------------
7
14
  * Bugfixes to synchronization between SproutCore RecordArray/ManyArray/ChildArray and TemplateCollectionView
@@ -0,0 +1,49 @@
1
+ sc_require('views/template');
2
+
3
+ SC.Button = SC.TemplateView.extend({
4
+ classNames: ['sc-button'],
5
+
6
+ // Setting isActive to true will trigger the classBinding and add
7
+ // 'is-active' to our layer's class names.
8
+ mouseDown: function() {
9
+ this.set('isActive', true);
10
+ this._isMouseDown = YES;
11
+ },
12
+
13
+ mouseExited: function() {
14
+ this.set('isActive', false);
15
+ },
16
+
17
+ mouseEntered: function() {
18
+ if (this._isMouseDown) {
19
+ this.set('isActive', true);
20
+ }
21
+ },
22
+
23
+ // Setting isActive to false will remove 'is-active' from our
24
+ // layer's class names.
25
+ mouseUp: function(event) {
26
+ if (this.get('isActive')) {
27
+ var action = this.get('action'),
28
+ target = this.get('target') || null,
29
+ rootResponder = this.getPath('pane.rootResponder');
30
+
31
+ if (action && rootResponder) {
32
+ rootResponder.sendAction(action, target, this, this.get('pane'), null, this);
33
+ }
34
+
35
+ this.set('isActive', false);
36
+ }
37
+
38
+ this._isMouseDown = NO;
39
+ },
40
+
41
+ touchStart: function(touch) {
42
+ this.mouseDown(touch);
43
+ },
44
+
45
+ touchEnd: function(touch) {
46
+ this.mouseUp(touch);
47
+ }
48
+ });
49
+
@@ -4,9 +4,44 @@
4
4
  // ©2008-2011 Apple Inc. All rights reserved.
5
5
  // License: Licensed under MIT license (see license.js)
6
6
  // ==========================================================================
7
+
8
+ sc_require('views/template');
9
+
7
10
  /** @class */
8
11
 
9
- SC.CheckboxSupport = /** @scope SC.CheckboxSupport.prototype */{
12
+ SC.Checkbox = SC.TemplateView.extend(
13
+ /** @scope SC.Checkbox.prototype */ {
14
+
15
+ title: null,
16
+ value: null,
17
+
18
+ classNames: ['sc-checkbox'],
19
+ template: SC.Handlebars.compile('<label><input type="checkbox">{{title}}</label>'),
20
+
21
+ didCreateLayer: function() {
22
+ var self = this;
23
+
24
+ this.$('input').bind('change', function() {
25
+ self.domValueDidChange(this);
26
+ });
27
+ },
28
+
29
+ domValueDidChange: function(node) {
30
+ this.set('value', !!$(node).attr('checked'));
31
+ },
32
+
33
+ value: function(key, value) {
34
+ if (value !== undefined) {
35
+ this.$('input').attr('checked', value);
36
+ } else {
37
+ value = this.$('input').attr('checked');
38
+ }
39
+
40
+ return value;
41
+ }.property()
42
+ });
43
+
44
+ SC.CheckboxSupport = /** @scope SC.CheckboxSupport */{
10
45
  didCreateLayer: function() {
11
46
  this.$('input').change(jQuery.proxy(function() {
12
47
  SC.RunLoop.begin();
@@ -4,11 +4,109 @@
4
4
  // ©2008-2011 Apple Inc. All rights reserved.
5
5
  // License: Licensed under MIT license (see license.js)
6
6
  // ==========================================================================
7
- /** @class
8
7
 
9
- */
10
- SC.TextFieldSupport = /** @scope SC.TextFieldSupport.prototype */{
11
-
8
+ sc_require('views/template');
9
+
10
+ /** @class */
11
+
12
+ SC.TextField = SC.TemplateView.extend(
13
+ /** @scope SC.TextField.prototype */ {
14
+
15
+ classNames: ['sc-text-field'],
16
+
17
+ // we can't use bindAttr because of a race condition:
18
+ //
19
+ // when `value` is set, the bindAttr observer immediately calls
20
+ // `get` in order to persist it to the DOM, but because we made
21
+ // the `value` property idempotent, when it gets called by
22
+ // bindAttr, it fetches the not-yet-updated value from the DOM
23
+ // and returns it.
24
+ //
25
+ // In short, because we need to be able to catch changes to the
26
+ // DOM made directly, we cannot also rely on bindAttr to update
27
+ // the property: a chicken-and-egg problem.
28
+ template: SC.Handlebars.compile('<input type="text">'),
29
+
30
+ didCreateLayer: function() {
31
+ var self = this;
32
+
33
+ var input = this.$('input');
34
+ input.val(this._value);
35
+
36
+ SC.Event.add(input, 'focus', this, this.focusIn);
37
+ SC.Event.add(input, 'blur', this, this.focusOut);
38
+
39
+ this.$('input').bind('change', function() {
40
+ self.domValueDidChange(SC.$(this));
41
+ });
42
+ },
43
+
44
+ /**
45
+ The problem this property is trying to solve is twofold:
46
+
47
+ 1. Make it possible to set the value of a text field that has
48
+ not yet been inserted into the DOM
49
+ 2. Make sure that `value` properly reflects changes made directly
50
+ to the element's `value` property.
51
+
52
+ In order to achieve (2), we need to make the property volatile,
53
+ so that SproutCore will call the getter no matter what if get()
54
+ is called.
55
+
56
+ In order to achieve (1), we need to store a local cache of the
57
+ value, so that SproutCore can set the proper value as soon as
58
+ the underlying DOM element is created.
59
+ */
60
+ value: function(key, value) {
61
+ var input = this.$('input');
62
+
63
+ if (value !== undefined) {
64
+ this._value = value;
65
+ input.val(value);
66
+ } else if (input.length) {
67
+ if(window.billy) { debugger; }
68
+ this._value = value = input.val();
69
+ } else {
70
+ if(window.billy) { debugger; }
71
+ value = this._value;
72
+ }
73
+
74
+ return value;
75
+ }.property().idempotent(),
76
+
77
+ domValueDidChange: function(jquery) {
78
+ this.set('value', jquery.val());
79
+ },
80
+
81
+ focusIn: function(event) {
82
+ this.becomeFirstResponder();
83
+ this.tryToPerform('focus', event);
84
+ },
85
+
86
+ focusOut: function(event) {
87
+ this.resignFirstResponder();
88
+ this.tryToPerform('blur', event);
89
+ },
90
+
91
+ willLoseFirstResponder: function() {
92
+ this.notifyPropertyChange('value');
93
+ },
94
+
95
+ keyUp: function(evt) {
96
+ this.domValueDidChange(this.$('input'));
97
+
98
+ if (evt.keyCode === 13) {
99
+ return this.insertNewline(evt);
100
+ } else if (evt.keyCode === 27) {
101
+ return this.cancel(evt);
102
+ }
103
+
104
+ return true;
105
+ }
106
+ });
107
+
108
+ SC.TextFieldSupport = /** @scope SC.TextFieldSupport */{
109
+
12
110
  /** @private
13
111
  Used internally to store value because the layer may not exist
14
112
  */
@@ -16,7 +16,19 @@
16
16
  })
17
17
  }
18
18
  */
19
- SC.TemplatePane = SC.Object.extend({});
19
+ SC.TemplatePane = SC.Object.extend({
20
+ touchStart: function(touch) {
21
+ touch.allowDefault();
22
+ },
23
+
24
+ touchesDragged: function(evt, touches) {
25
+ evt.allowDefault();
26
+ },
27
+
28
+ touchEnd: function(touch) {
29
+ touch.allowDefault();
30
+ }
31
+ });
20
32
 
21
33
  SC.mixin(SC.TemplatePane, {
22
34
  append: function(attrs) {
@@ -0,0 +1,78 @@
1
+ var button;
2
+
3
+ module("SC.Button", {
4
+ setup: function() {
5
+ button = SC.Button.create();
6
+
7
+ pane = SC.MainPane.create({
8
+ childViews: [button]
9
+ });
10
+ pane.append();
11
+ },
12
+
13
+ teardown: function() {
14
+ pane.remove();
15
+ }
16
+ });
17
+
18
+ function synthesizeEvent(type, view) {
19
+ var event = new SC.Event({
20
+ type: type,
21
+ target: view.get('layer')
22
+ });
23
+ SC.RootResponder.responder[type](event);
24
+ }
25
+
26
+ test("should trigger an action when clicked", function() {
27
+ var wasClicked = false;
28
+
29
+ var actionObject = SC.Object.create({
30
+ myAction: function() {
31
+ wasClicked = true;
32
+ }
33
+ });
34
+
35
+ button.target = actionObject;
36
+ button.action = 'myAction';
37
+
38
+ synthesizeEvent('mousedown', button);
39
+ synthesizeEvent('mouseup', button);
40
+
41
+ ok(wasClicked);
42
+ });
43
+
44
+ test("should not trigger action if mouse leaves area before mouseup", function() {
45
+ var wasClicked = false;
46
+
47
+ var actionObject = SC.Object.create({
48
+ myAction: function() {
49
+ wasClicked = true;
50
+ }
51
+ });
52
+
53
+ var otherButton = SC.Button.create();
54
+ pane.appendChild(otherButton);
55
+
56
+ button.target = actionObject;
57
+ button.action = 'myAction';
58
+
59
+ synthesizeEvent('mousedown', button);
60
+ synthesizeEvent('mousemove', button);
61
+ ok(button.get('isActive'), "becomes active when hovered");
62
+ synthesizeEvent('mousemove', otherButton);
63
+ ok(!button.get('isActive'), "loses active state if mouse exits");
64
+ synthesizeEvent('mouseup', button);
65
+
66
+ ok(!wasClicked);
67
+
68
+ wasClicked = false;
69
+
70
+ synthesizeEvent('mousedown', button);
71
+ synthesizeEvent('mousemove', button);
72
+ synthesizeEvent('mousemove', otherButton);
73
+ synthesizeEvent('mousemove', button);
74
+ synthesizeEvent('mouseup', button);
75
+
76
+ ok(wasClicked);
77
+ });
78
+
@@ -34,5 +34,31 @@
34
34
  checkboxView.set('value', true);
35
35
  ok(checkboxView.$('input').attr("checked"), "sets value of DOM to value property");
36
36
  });
37
+
38
+ module("SC.Checkbox", {
39
+ setup: function() {
40
+ checkboxView = SC.Checkbox.create({});
41
+
42
+ pane = SC.MainPane.create({
43
+ childViews: [checkboxView]
44
+ });
45
+ pane.append();
46
+ },
47
+
48
+ teardown: function() {
49
+ pane.remove();
50
+ }
51
+ });
52
+
53
+ test("value property mirrors input value", function() {
54
+ checkboxView.$('input').attr('checked', true);
55
+
56
+ equals(checkboxView.get('value'), true, "gets value property from DOM");
57
+
58
+ checkboxView.$('input').attr('checked', false);
59
+
60
+ checkboxView.set('value', true);
61
+ ok(checkboxView.$('input').attr("checked"), "sets value of DOM to value property");
62
+ });
37
63
  })();
38
64
 
@@ -100,4 +100,94 @@
100
100
  equals(cancelCalled, 1, "calls cancel after pressing escape key");
101
101
 
102
102
  });
103
+
104
+ module("SC.TextField", {
105
+ setup: function() {
106
+ TestObject = window.TestObject = SC.Object.create({
107
+ value: null
108
+ });
109
+
110
+ textFieldView = SC.TextField.create();
111
+
112
+ pane = SC.MainPane.create({
113
+ childViews: [textFieldView]
114
+ });
115
+ pane.append();
116
+ },
117
+
118
+ teardown: function() {
119
+ pane.remove();
120
+ TestObject = window.TestObject = textFieldView = pane = null;
121
+ }
122
+ });
123
+
124
+ test("value property mirrors input value", function() {
125
+ textFieldView.$('input').val('foo bar');
126
+
127
+ equals(textFieldView.get('value'), 'foo bar', "gets value property from DOM");
128
+
129
+ textFieldView.set('value', "afterlife");
130
+ equals(textFieldView.$('input').val(), "afterlife", "sets value of DOM to value property");
131
+ });
132
+
133
+ test("value binding works properly for inputs that haven't been created", function() {
134
+ var view = SC.TextField.create({
135
+ valueBinding: 'TestObject.value'
136
+ });
137
+
138
+ equals(view.get('value'), null, "precond - default value is null");
139
+ equals(view.$('input').length, 0, "precond - view doesn't have its layer created yet, thus no input element");
140
+
141
+ SC.run(function() { TestObject.set('value', 'ohai'); });
142
+
143
+ equals(view.get('value'), 'ohai', "value property was properly updated");
144
+
145
+ SC.run(function() { pane.appendChild(view); });
146
+
147
+ equals(view.get('value'), 'ohai', "value property remains the same once the view has been appended");
148
+ equals(view.$('input').val(), 'ohai', "value is reflected in the input element once it is created");
149
+ });
150
+
151
+ test("listens for focus and blur events", function() {
152
+ var focusCalled = 0;
153
+ var blurCalled = 0;
154
+
155
+ textFieldView.focus = function() {
156
+ focusCalled++;
157
+ };
158
+ textFieldView.blur = function() {
159
+ blurCalled++;
160
+ };
161
+
162
+ equals(focusCalled+blurCalled, 0, "precond - no callbacks called yet");
163
+
164
+ textFieldView.$('input').focus();
165
+ equals(focusCalled, 1, "focus called after field receives focus");
166
+
167
+ textFieldView.$('input').blur();
168
+ equals(blurCalled, 1, "blur alled after field blurs");
169
+ });
170
+
171
+ test("calls correct method for key events", function() {
172
+ var insertNewlineCalled = 0;
173
+ var cancelCalled = 0;
174
+
175
+ textFieldView.insertNewline = function() {
176
+ insertNewlineCalled++;
177
+ return YES;
178
+ };
179
+ textFieldView.cancel = function() {
180
+ cancelCalled++;
181
+ return YES;
182
+ };
183
+
184
+ textFieldView.$('input').focus();
185
+ equals(insertNewlineCalled+cancelCalled, 0, "precond - no callbacks called yet");
186
+
187
+ SC.RootResponder.responder.keyup(new SC.Event({ type: 'keyup', keyCode: 13 }));
188
+ equals(insertNewlineCalled, 1, "calls insertNewline after hitting return");
189
+
190
+ SC.RootResponder.responder.keyup(new SC.Event({ type: 'keyup', keyCode: 27 }));
191
+ equals(cancelCalled, 1, "calls cancel after pressing escape key");
192
+ });
103
193
  })();
@@ -3,6 +3,7 @@ sc_require("ext/handlebars/bind");
3
3
  sc_require("ext/handlebars/collection");
4
4
  sc_require("ext/handlebars/localization");
5
5
  sc_require("ext/handlebars/view");
6
+ sc_require("views/view");
6
7
 
7
8
  // Global hash of shared templates. This will automatically be populated
8
9
  // by the build tools so that you can store your Handlebars templates in
@@ -1,3 +1,4 @@
1
+ sc_require('mixins/delegate_support');
1
2
 
2
3
  /** @class */
3
4
  SC.CoreView = SC.Responder.extend(SC.DelegateSupport);
@@ -36,7 +36,7 @@ if (typeof console === 'undefined') {
36
36
  // rest of the methods go into the mixin defined below.
37
37
 
38
38
  /**
39
- @version 1.6.0.beta.1
39
+ @version 1.6.0.beta.2
40
40
  @namespace
41
41
 
42
42
  All SproutCore methods and functions are defined
@@ -57,7 +57,7 @@ if (typeof console === 'undefined') {
57
57
  window.SC = window.SC || {} ;
58
58
  window.SproutCore = window.SproutCore || SC ;
59
59
 
60
- SC.VERSION = '1.6.0.beta.1';
60
+ SC.VERSION = '1.6.0.beta.2';
61
61
 
62
62
  /**
63
63
  @private
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: sproutcore
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 6
5
- version: 1.6.0.beta.1
5
+ version: 1.6.0.beta.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Strobe, Inc., Apple Inc. and contributors
@@ -10,7 +10,8 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-05-08 00:00:00 Z
13
+ date: 2011-05-10 00:00:00 -07:00
14
+ default_executable:
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
17
  name: rack
@@ -958,6 +959,7 @@ files:
958
959
  - lib/frameworks/sproutcore/frameworks/core_foundation/controllers/array.js
959
960
  - lib/frameworks/sproutcore/frameworks/core_foundation/controllers/controller.js
960
961
  - lib/frameworks/sproutcore/frameworks/core_foundation/controllers/object.js
962
+ - lib/frameworks/sproutcore/frameworks/core_foundation/controls/button.js
961
963
  - lib/frameworks/sproutcore/frameworks/core_foundation/core.js
962
964
  - lib/frameworks/sproutcore/frameworks/core_foundation/ext/function.js
963
965
  - lib/frameworks/sproutcore/frameworks/core_foundation/ext/handlebars/bind.js
@@ -1016,6 +1018,7 @@ files:
1016
1018
  - lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/object/multiple_case.js
1017
1019
  - lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/object/single_case.js
1018
1020
  - lib/frameworks/sproutcore/frameworks/core_foundation/tests/controllers/object/single_enumerable_case.js
1021
+ - lib/frameworks/sproutcore/frameworks/core_foundation/tests/controls/button.js
1019
1022
  - lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/responder_context.js
1020
1023
  - lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/string.js
1021
1024
  - lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/template_helpers/checkbox_support.js
@@ -2296,6 +2299,7 @@ files:
2296
2299
  - lib/frameworks/sproutcore/themes/legacy_theme/Source/icons/48/19.png
2297
2300
  - lib/frameworks/sproutcore/themes/legacy_theme/Source/icons/48/2.png
2298
2301
  - lib/frameworks/sproutcore/themes/legacy_theme/theme.js
2302
+ has_rdoc: true
2299
2303
  homepage: http://www.sproutcore.com
2300
2304
  licenses: []
2301
2305
 
@@ -2321,7 +2325,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
2321
2325
  requirements: []
2322
2326
 
2323
2327
  rubyforge_project: sproutcore
2324
- rubygems_version: 1.7.2
2328
+ rubygems_version: 1.5.2
2325
2329
  signing_key:
2326
2330
  specification_version: 3
2327
2331
  summary: SproutCore is a platform for building native look-and-feel applications on the web