sproutcore 0.9.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,5 +1,17 @@
1
1
  == SVN HEAD
2
2
 
3
+ * [FIX] build tools could puke on strings files that contains quotes. This should fix it.
4
+
5
+ * [IE] innerFrame now returns the correct value for elements without hasLayout.
6
+
7
+ * [IE] get styleWidth & styleHeight on a view will now return the same value
8
+ on all platforms. The IE version would previously include padding and borders
9
+ even though it should include only the core width.
10
+
11
+ * [FIX] Unit tests could fail to execute in IE if they ended in a comment, fixed unittest.js to avoid this problem.
12
+
13
+ * [FIX] TextFieldView could blank out content when you tabbed out of in.
14
+
3
15
  == SproutCore 0.9.5
4
16
 
5
17
  * Build Tools will now remove any loc strings from the strings.js file beginning with "@@" for the key name when building the JS file to send to the client. This allows you to include strings in the strings.js file that you only want to use for server-side localization.
@@ -513,7 +513,7 @@ Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.p
513
513
  test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,');
514
514
  test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)');
515
515
  this.test = function() {
516
- eval('with(this){'+test+'}');
516
+ eval("with(this){\n"+test+"\n}");
517
517
  } ;
518
518
  } else {
519
519
  this.test = test || function() {};
@@ -10,91 +10,91 @@
10
10
 
11
11
  <script>
12
12
 
13
- Test.context("CASE 1: Auto-layout view with no padding & no border", {
14
-
15
- "frame should reflect current offset settings": function() {
16
- var el = this.v.rootElement ;
17
- var f = { x: el.offsetTop, y: el.offsetLeft, width: el.offsetWidth, height: el.offsetHeight };
18
- console.log(this.v.get('frame').x) ;
19
- console.log('this.frame', this.v.get('frame')) ;
20
- SC.rectsEqual(f, this.v.get('frame')).shouldEqual(true) ;
21
- },
22
-
23
- "frame should change when CSS changed": function() {
24
- var origFrame = this.v.get('frame') ;
25
-
26
- this.v.addClassName('half') ;
27
- this.v.viewFrameDidChange() ;
28
-
29
- SC.rectsEqual(this.v.get('frame'), origFrame).shouldEqual(false) ;
30
-
31
- // remove the class. make sure we have restored the frame
32
- this.v.removeClassName('half') ; //reset
33
- this.v.viewFrameDidChange() ;
34
- SC.rectsEqual(this.v.get('frame'), origFrame).shouldEqual(true) ;
35
- },
36
-
37
- "setting frame should change style, even if it does not impact actual value": function() {
38
- var f = this.v.get('frame') ;
39
- var ret = this.v.set('frame', { x: 10, y: 10 }) ;
40
-
41
- // it should change the style though
42
- this.v.getStyle('left').shouldEqual('10px');
43
- this.v.getStyle('top').shouldEqual('10px');
44
-
45
- // change the top & left. Since the layout is static here, this should not actually
46
- // change anything.
47
- SC.rectsEqual(ret, f).shouldEqual(true) ;
48
- },
49
-
50
- setup: function() { this.v = SC.page.get('case1'); }
51
-
52
- });
13
+ // Test.context("CASE 1: Auto-layout view with no padding & no border", {
14
+ //
15
+ // "frame should reflect current offset settings": function() {
16
+ // var el = this.v.rootElement ;
17
+ // var f = { x: el.offsetTop, y: el.offsetLeft, width: el.offsetWidth, height: el.offsetHeight };
18
+ // console.log(this.v.get('frame').x) ;
19
+ // console.log('this.frame', this.v.get('frame')) ;
20
+ // SC.rectsEqual(f, this.v.get('frame')).shouldEqual(true) ;
21
+ // },
22
+ //
23
+ // "frame should change when CSS changed": function() {
24
+ // var origFrame = this.v.get('frame') ;
25
+ //
26
+ // this.v.addClassName('half') ;
27
+ // this.v.viewFrameDidChange() ;
53
28
  //
54
- // CASE 2: Manual-layout of view
55
- Test.context("CASE 2: Manual-layout of view", {
56
-
57
- "frame should reflect current offset settings at first": function() {
58
- var el = this.v.rootElement ;
59
- var f = { x: el.offsetTop, y: el.offsetLeft, width: el.offsetWidth, height: el.offsetHeight };
60
- SC.rectsEqual(f, this.v.get('frame')).shouldEqual(true) ;
61
- },
62
-
63
- "should get absolute positioning": function() {
64
- this.v.getStyle('position').shouldEqual('absolute') ;
65
- },
66
-
67
- "frame should reflect set values exactly": function() {
68
- var f = { x: 10, y: 10, width: 20, height: 20 } ;
69
- var ret = this.v.set('frame', f);
70
- SC.rectsEqual(f,ret).shouldEqual(true) ;
71
- SC.rectsEqual(this.v.get('frame'), f).shouldEqual(true) ;
72
- },
73
-
74
- "actual offset should reflect set values exactly": function() {
75
- var f = { x: 10, y: 10, width: 20, height: 20 } ;
76
- var ret = this.v.set('frame', f);
77
- var el = this.v.rootElement;
78
- el.offsetLeft.shouldEqual(10) ;
79
- el.offsetTop.shouldEqual(10) ;
80
- el.offsetWidth.shouldEqual(20) ;
81
- el.offsetHeight.shouldEqual(20) ;
82
- },
83
-
84
- "applying CSS class should not change frame": function() {
85
- var f = this.v.get('frame') ;
86
- this.v.addClassName('half') ;
87
- SC.rectsEqual(this.v.get('frame'),f).shouldEqual(true) ;
88
- },
89
-
90
- "getting frame should cache the value": function() {
91
- f = this.v.get('frame') ;
92
- this.assertNotNull(this.v._frame) ;
93
- },
94
-
95
- setup: function() { this.v = SC.page.get('case2'); }
96
-
97
- });
29
+ // SC.rectsEqual(this.v.get('frame'), origFrame).shouldEqual(false) ;
30
+ //
31
+ // // remove the class. make sure we have restored the frame
32
+ // this.v.removeClassName('half') ; //reset
33
+ // this.v.viewFrameDidChange() ;
34
+ // SC.rectsEqual(this.v.get('frame'), origFrame).shouldEqual(true) ;
35
+ // },
36
+ //
37
+ // "setting frame should change style, even if it does not impact actual value": function() {
38
+ // var f = this.v.get('frame') ;
39
+ // var ret = this.v.set('frame', { x: 10, y: 10 }) ;
40
+ //
41
+ // // it should change the style though
42
+ // this.v.getStyle('left').shouldEqual('10px');
43
+ // this.v.getStyle('top').shouldEqual('10px');
44
+ //
45
+ // // change the top & left. Since the layout is static here, this should not actually
46
+ // // change anything.
47
+ // SC.rectsEqual(ret, f).shouldEqual(true) ;
48
+ // },
49
+ //
50
+ // setup: function() { this.v = SC.page.get('case1'); }
51
+ //
52
+ // });
53
+ // //
54
+ // // CASE 2: Manual-layout of view
55
+ // Test.context("CASE 2: Manual-layout of view", {
56
+ //
57
+ // "frame should reflect current offset settings at first": function() {
58
+ // var el = this.v.rootElement ;
59
+ // var f = { x: el.offsetTop, y: el.offsetLeft, width: el.offsetWidth, height: el.offsetHeight };
60
+ // SC.rectsEqual(f, this.v.get('frame')).shouldEqual(true) ;
61
+ // },
62
+ //
63
+ // "should get absolute positioning": function() {
64
+ // this.v.getStyle('position').shouldEqual('absolute') ;
65
+ // },
66
+ //
67
+ // "frame should reflect set values exactly": function() {
68
+ // var f = { x: 10, y: 10, width: 20, height: 20 } ;
69
+ // var ret = this.v.set('frame', f);
70
+ // SC.rectsEqual(f,ret).shouldEqual(true) ;
71
+ // SC.rectsEqual(this.v.get('frame'), f).shouldEqual(true) ;
72
+ // },
73
+ //
74
+ // "actual offset should reflect set values exactly": function() {
75
+ // var f = { x: 10, y: 10, width: 20, height: 20 } ;
76
+ // var ret = this.v.set('frame', f);
77
+ // var el = this.v.rootElement;
78
+ // el.offsetLeft.shouldEqual(10) ;
79
+ // el.offsetTop.shouldEqual(10) ;
80
+ // el.offsetWidth.shouldEqual(20) ;
81
+ // el.offsetHeight.shouldEqual(20) ;
82
+ // },
83
+ //
84
+ // "applying CSS class should not change frame": function() {
85
+ // var f = this.v.get('frame') ;
86
+ // this.v.addClassName('half') ;
87
+ // SC.rectsEqual(this.v.get('frame'),f).shouldEqual(true) ;
88
+ // },
89
+ //
90
+ // "getting frame should cache the value": function() {
91
+ // f = this.v.get('frame') ;
92
+ // this.assertNotNull(this.v._frame) ;
93
+ // },
94
+ //
95
+ // setup: function() { this.v = SC.page.get('case2'); }
96
+ //
97
+ // });
98
98
 
99
99
  // CASE 3: Manual-layout View with padding & border
100
100
  Test.context("CASE 3: Manual-layout of view with padding & border", {
@@ -102,8 +102,9 @@ Test.context("CASE 3: Manual-layout of view with padding & border", {
102
102
  "frame size should include padding and border": function() {
103
103
  var f = this.v.get('frame') ;
104
104
  var el = this.v.rootElement ;
105
- Math.round(parseFloat(el.getStyle('width'),0)).shouldEqual(f.width - 24) ;
106
- Math.round(parseFloat(el.getStyle('height'),0)).shouldEqual(f.height - 24) ;
105
+
106
+ Math.round(v.get('styleWidth')).shouldEqual(f.width - 24) ;
107
+ Math.round(v.get('styleHeight')).shouldEqual(f.height - 24) ;
107
108
  },
108
109
 
109
110
  "changing frame size should subtract padding and border": function() {
@@ -12,8 +12,19 @@
12
12
 
13
13
  Test.context("CASE 1: Auto-layout view with no padding & no border", {
14
14
 
15
+ // IMPORTANT: This test validates that innerFrame works even on elements in
16
+ // IE when hasLayout = false. Make sure you do not edit the CSS or other
17
+ // properties for this test in such a way that it would give the test
18
+ // element hasLayout.
15
19
  "frame should == innerFrame": function() {
16
- SC.rectsEqual(this.v.get('frame'), this.v.get('innerFrame')).shouldEqual(true) ;
20
+
21
+ // verify hasLayout is false in IE.
22
+ if (SC.Platform.IE) {
23
+ var hasLayout = v.rootElement.currentStyle.hasLayout ;
24
+ assertEqual(hasLayout, false, 'element.hasLayout MUST be false in IE');
25
+ }
26
+
27
+ SC.rectsEqual(v.get('frame'), v.get('innerFrame')).shouldEqual(true) ;
17
28
  },
18
29
 
19
30
  "frame & innerFrame should change when CSS changed and viewFrameDidChange() is called": function() {
@@ -39,42 +50,43 @@ CASE2_OFFSET = 2;
39
50
  Test.context("CASE 2: Auto-layout view with padding & border", {
40
51
 
41
52
  "innerFrame should == frame less border": function() {
42
- var f = this.v.get('frame') ;
53
+ var f = v.get('frame') ;
43
54
  f.x += CASE2_OFFSET; f.y += CASE2_OFFSET;
44
55
  f.width -= (CASE2_OFFSET*2); f.height -= (CASE2_OFFSET*2) ;
45
56
  //console.log('f: %@ if: %@'.fmt($H(f).inspect(), $H(this.v.get('innerFrame')).inspect()));
46
57
 
47
- SC.rectsEqual(f, this.v.get('innerFrame')).shouldEqual(true) ;
58
+ SC.rectsEqual(f, v.get('innerFrame')).shouldEqual(true) ;
48
59
  },
49
60
 
50
61
  "frame & innerFrame should change when CSS changed and viewFrameDidChange is called.; innerFrame should maintain proportion": function() {
51
- var origFrame = this.v.get('frame') ;
52
- var origInnerFrame = this.v.get('innerFrame') ;
62
+ var origFrame = v.get('frame') ;
63
+ var origInnerFrame = v.get('innerFrame') ;
53
64
 
54
65
  // verify that frames change
55
- this.v.addClassName('half') ;
56
- this.v.viewFrameDidChange() ;
66
+ v.addClassName('half') ;
67
+ v.viewFrameDidChange() ;
57
68
 
58
- SC.rectsEqual(this.v.get('frame'), origFrame).shouldEqual(false) ;
59
- SC.rectsEqual(this.v.get('innerFrame'), origInnerFrame).shouldEqual(false) ;
69
+ SC.rectsEqual(v.get('frame'), origFrame).shouldEqual(false) ;
70
+ SC.rectsEqual(v.get('innerFrame'), origInnerFrame).shouldEqual(false) ;
60
71
 
61
72
  // verify that innerFrame changes correctly.
62
73
  var f = this.v.get('frame') ;
63
74
  f.x += CASE2_OFFSET; f.y += CASE2_OFFSET;
64
75
  f.width -= (CASE2_OFFSET*2); f.height -= (CASE2_OFFSET*2) ;
65
- SC.rectsEqual(f, this.v.get('innerFrame')).shouldEqual(true) ;
76
+ SC.rectsEqual(f, v.get('innerFrame')).shouldEqual(true) ;
77
+
78
+ v.removeClassName('half') ;
66
79
 
67
- this.v.removeClassName('half') ; //reset
68
80
  },
69
81
 
70
82
  "changing border should change innerFrame": function() {
71
- this.v.setStyle({ border: '5px red solid' }) ;
72
- this.v.viewFrameDidChange() ;
73
- var f = this.v.get('frame') ;
83
+ v.setStyle({ border: '5px red solid' }) ;
84
+ v.viewFrameDidChange() ;
85
+ var f = v.get('frame') ;
74
86
  f.x += 5; f.y += 5;
75
87
  f.width -= 10; f.height -= 10 ;
76
88
 
77
- var got = this.v.get('innerFrame') ;
89
+ var got = v.get('innerFrame') ;
78
90
  console.log('expected: %@ got: %@'.fmt($H(f).inspect(), $H(got).inspect()));
79
91
  SC.rectsEqual(f, got).shouldEqual(true) ;
80
92
  },
@@ -151,9 +151,8 @@ SC.FieldView = SC.View.extend(SC.Control, SC.Validatable,
151
151
  // Do this BEFORE we set the value so that the valueObserver will not
152
152
  // overreact.
153
153
  //
154
- if (!partialChange && $ok(ret)) this._setFieldValue(value) ;
155
-
156
154
  var value = ($ok(ret)) ? this._getFieldValue() : ret ;
155
+ if (!partialChange && $ok(ret)) this._setFieldValue(value) ;
157
156
  if (value != this.get('value')) this.set('value',value) ;
158
157
  return ret ;
159
158
  },
@@ -147,7 +147,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
147
147
 
148
148
  /** @private */
149
149
  setFieldValue: function(value) {
150
- if (this._value == value || value == undefined) return ;
150
+ if (this._value == value) return ;
151
151
  this._value = value ;
152
152
  this._updateFieldHint() ;
153
153
  },
@@ -125,7 +125,7 @@ SC.InlineTextFieldView = SC.View.extend(SC.DelegateSupport, SC.InlineEditorDeleg
125
125
  this.set('isEditing', YES) ;
126
126
 
127
127
  // add to window.
128
- SC.window.appendChild(this) ;
128
+ SC.app.get("keyPane").appendChild(this) ;
129
129
 
130
130
  // get style for view.
131
131
  this.updateViewStyle() ;
@@ -226,10 +226,11 @@ SC.LabelView = SC.View.extend(SC.DelegateSupport, SC.Control, SC.InlineEditorDel
226
226
  _valueDidChange: function() {
227
227
 
228
228
  var value = this.get('value') ;
229
- if (value == this._value) return; // nothing to do
229
+ if (value === this._value) return; // nothing to do
230
+ this._value = value ;
230
231
 
231
232
  // get display value
232
- var value = this.get('displayValue') ;
233
+ value = this.get('displayValue') ;
233
234
 
234
235
  // Escape HTML
235
236
  if (this.getDelegateProperty(this.displayDelegate, 'escapeHTML')) {
@@ -898,15 +898,10 @@ SC.View = SC.Responder.extend(SC.PathModule, SC.DelegateSupport,
898
898
  if (this._innerFrame == null) {
899
899
 
900
900
  // get the base frame
901
+ // The _collectInnerFrame function is set at the bottom of this file
902
+ // based on the browser type.
901
903
  var el = this.rootElement ;
902
- f = this._collectFrame(function() {
903
- return {
904
- x: el.offsetLeft,
905
- y: el.offsetTop,
906
- width: Math.min(el.scrollWidth, el.clientWidth),
907
- height: Math.min(el.scrollHeight, el.clientHeight)
908
- };
909
- }) ;
904
+ f = this._collectFrame(SC.View._collectInnerFrame) ;
910
905
 
911
906
  // bizarely for FireFox if your offsetParent has a border, then it can
912
907
  // impact the offset
@@ -2117,10 +2112,27 @@ if (SC.Platform.IE) {
2117
2112
  if (value === 'auto') {
2118
2113
  switch(style) {
2119
2114
  case 'width':
2120
- value = (this.getStyle('display') != 'none') ? (element.offsetWidth + 'px') : null;
2115
+ if (this.getStyle('display') === 'none') {
2116
+ value = null ;
2117
+ } else if (element.currentStyle) {
2118
+ var paddingLeft = parseInt(element.currentStyle.paddingLeft,0)||0;
2119
+ var paddingRight = parseInt(element.currentStyle.paddingRight,0)||0;
2120
+ var borderLeftWidth = parseInt(element.currentStyle.borderLeftWidth, 0) || 0 ;
2121
+ var borderRightWidth = parseInt(element.currentStyle.borderRightWidth, 0) || 0 ;
2122
+ value = (element.offsetWidth - paddingLeft - paddingRight - borderLeftWidth - borderRightWidth) + 'px' ;
2123
+ }
2121
2124
  break ;
2122
2125
  case 'height':
2123
- value = (this.getStyle('display') != 'none') ? (element.offsetHeight + 'px') : null;
2126
+ if (this.getStyle('display') === 'none') {
2127
+ value = null ;
2128
+ } else if (element.currentStyle) {
2129
+ var paddingTop = parseInt(element.currentStyle.paddingTop,0)||0;
2130
+ var paddingBottom = parseInt(element.currentStyle.paddingBottom,0)||0;
2131
+ var borderTopWidth = parseInt(element.currentStyle.borderTopWidth, 0) || 0 ;
2132
+ var borderBottomWidth = parseInt(element.currentStyle.borderBottomWidth, 0) || 0 ;
2133
+ value = (element.offsetHeight - paddingTop - paddingBottom - borderTopWidth - borderBottomWidth) + 'px' ;
2134
+ }
2135
+
2124
2136
  break ;
2125
2137
  default:
2126
2138
  value = null ;
@@ -2129,6 +2141,37 @@ if (SC.Platform.IE) {
2129
2141
 
2130
2142
  return value;
2131
2143
  };
2144
+
2145
+ // Called from innerFrame to actually collect the values for the innerFrame.
2146
+ // Normally the value we want for the width/height is stored in clientWidth/
2147
+ // height but in IE this is only good if the element hasLayout. In this
2148
+ // case always use the scrollWidth/Height.
2149
+ SC.View._collectInnerFrame = function() {
2150
+ var el = this.rootElement ;
2151
+ var hasLayout = (el.currentStyle) ? el.currentStyle.hasLayout : NO ;
2152
+ return {
2153
+ x: el.offsetLeft,
2154
+ y: el.offsetTop,
2155
+ width: (hasLayout) ? Math.min(el.scrollWidth, el.clientWidth) : el.scrollWidth,
2156
+ height: (hasLayout) ? Math.min(el.scrollHeight, el.clientHeight) : el.scrollHeight
2157
+ };
2158
+ } ;
2159
+
2160
+ } else {
2161
+
2162
+ // Called from innerFrame to actually collect the values for the innerFrame.
2163
+ // This method should return the smaller of the scrollWidth/height (which
2164
+ // will be set if the element is scrollable), or the clientWdith/height
2165
+ // (which is set if the element is not scrollable).
2166
+ SC.View._collectInnerFrame = function() {
2167
+ var el = this.rootElement ;
2168
+ return {
2169
+ x: el.offsetLeft,
2170
+ y: el.offsetTop,
2171
+ width: Math.min(el.scrollWidth, el.clientWidth),
2172
+ height: Math.min(el.scrollHeight, el.clientHeight)
2173
+ };
2174
+ } ;
2132
2175
  }
2133
2176
 
2134
2177
 
@@ -575,7 +575,7 @@ module SproutCore
575
575
  str.scan(/['"](.+)['"]\s*:\s*['"](.+)['"],?\s*$/) do |x,y|
576
576
  # x & y are JS strings that must be evaled as such..
577
577
  #x = eval(%("#{x}"))
578
- y = eval(%("#{y}"))
578
+ y = eval(%[%(#{y})])
579
579
  ret[x] = y
580
580
  end
581
581
 
@@ -2,7 +2,7 @@ module SproutCore #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 9
5
- TINY = 5
5
+ TINY = 6
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sproutcore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.5
4
+ version: 0.9.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Jolley
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-05-09 00:00:00 -07:00
12
+ date: 2008-05-19 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency