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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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