sproutcore 1.8.0 → 1.8.1
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 +49 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/list_item.css +4 -4
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/modal.css +8 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/resources/panel.css +1 -8
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/integration.js +0 -27
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/methods.js +245 -18
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +23 -4
- data/lib/frameworks/sproutcore/frameworks/desktop/views/static_content.js +5 -7
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/scroll_view/tests/scroll/integration.js +0 -25
- data/lib/frameworks/sproutcore/frameworks/foundation/resources/text_field.css +42 -39
- data/lib/frameworks/sproutcore/frameworks/foundation/system/image_queue.js +5 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/image_queue.js +84 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/methods.js +48 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +288 -184
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
- data/lib/frameworks/sproutcore/lib/index.rhtml +23 -18
- data/lib/frameworks/sproutcore/themes/ace/resources/picker/popover/popover.css +44 -0
- data/lib/sproutcore/rack/proxy.rb +12 -9
- metadata +3 -3
- data/lib/frameworks/sproutcore/themes/ace/resources/pane/pane.css +0 -3
@@ -864,11 +864,30 @@ SC.ScrollView = SC.View.extend({
|
|
864
864
|
|
865
865
|
/** @private */
|
866
866
|
mouseWheel: function(evt) {
|
867
|
-
|
868
|
-
|
867
|
+
var horizontalScrollOffset = this.get('horizontalScrollOffset'),
|
868
|
+
maximumHorizontalScrollOffset = this.get('maximumHorizontalScrollOffset'),
|
869
|
+
maximumVerticalScrollOffset = this.get('maximumVerticalScrollOffset'),
|
870
|
+
shouldScroll = NO,
|
871
|
+
verticalScrollOffset = this.get('verticalScrollOffset');
|
872
|
+
|
873
|
+
// Only attempt to scroll if we are allowed to scroll in the direction and
|
874
|
+
// have room to scroll in the direction. Otherwise, ignore the event so
|
875
|
+
// that an outer ScrollView may capture it.
|
876
|
+
shouldScroll = ((this.get('canScrollHorizontal') &&
|
877
|
+
(evt.wheelDeltaX < 0 && horizontalScrollOffset > 0) ||
|
878
|
+
(evt.wheelDeltaX > 0 && horizontalScrollOffset < maximumHorizontalScrollOffset)) ||
|
879
|
+
(this.get('canScrollVertical') &&
|
880
|
+
(evt.wheelDeltaY < 0 && verticalScrollOffset > 0) ||
|
881
|
+
(evt.wheelDeltaY > 0 && verticalScrollOffset < maximumVerticalScrollOffset)));
|
882
|
+
|
883
|
+
if (shouldScroll) {
|
884
|
+
this._scroll_wheelDeltaX += evt.wheelDeltaX;
|
885
|
+
this._scroll_wheelDeltaY += evt.wheelDeltaY;
|
886
|
+
|
887
|
+
this.invokeLater(this._scroll_mouseWheel, 10);
|
888
|
+
}
|
869
889
|
|
870
|
-
|
871
|
-
return this.get('canScrollHorizontal') || this.get('canScrollVertical') ;
|
890
|
+
return shouldScroll;
|
872
891
|
},
|
873
892
|
|
874
893
|
/** @private */
|
@@ -128,21 +128,19 @@ SC.StaticContentView = SC.View.extend(SC.StaticLayout,
|
|
128
128
|
render: function(context, firstTime) {
|
129
129
|
var content = this.get('content');
|
130
130
|
|
131
|
-
|
132
|
-
context.push(content||'');
|
133
|
-
}
|
131
|
+
context.push(content || '');
|
134
132
|
},
|
135
|
-
|
133
|
+
|
136
134
|
/** @private */
|
137
135
|
touchStart: function(evt){
|
138
136
|
evt.allowDefault();
|
139
137
|
return YES;
|
140
138
|
},
|
141
|
-
|
139
|
+
|
142
140
|
/** @private */
|
143
141
|
touchEnd: function(evt){
|
144
142
|
evt.allowDefault();
|
145
143
|
return YES;
|
146
144
|
}
|
147
|
-
|
148
|
-
});
|
145
|
+
|
146
|
+
});
|
@@ -1,29 +1,5 @@
|
|
1
1
|
module("SC.ScrollView integration");
|
2
2
|
|
3
|
-
test("should work with SC.TemplateView", function() {
|
4
|
-
var pane = SC.MainPane.create({
|
5
|
-
childViews: ['scrollView'],
|
6
|
-
|
7
|
-
scrollView: SC.ScrollView.design({
|
8
|
-
layout: { width: 400, height: 600 },
|
9
|
-
|
10
|
-
contentView: SC.TemplateView.create({
|
11
|
-
template: SC.Handlebars.compile("foo bar baz")
|
12
|
-
})
|
13
|
-
})
|
14
|
-
});
|
15
|
-
|
16
|
-
pane.append();
|
17
|
-
var exceptionThrown = false;
|
18
|
-
try {
|
19
|
-
SC.RunLoop.begin().end();
|
20
|
-
} catch (e) {
|
21
|
-
exceptionThrown = true;
|
22
|
-
}
|
23
|
-
ok(!exceptionThrown, "Does not throw an exception at the end of the run loop.");
|
24
|
-
pane.remove();
|
25
|
-
});
|
26
|
-
|
27
3
|
test("should work with views that have static layout applied", function() {
|
28
4
|
var pane;
|
29
5
|
try {
|
@@ -47,4 +23,3 @@ test("should work with views that have static layout applied", function() {
|
|
47
23
|
if (pane) { pane.remove(); }
|
48
24
|
}
|
49
25
|
});
|
50
|
-
|
@@ -18,67 +18,70 @@
|
|
18
18
|
right: 3px;
|
19
19
|
position: absolute;
|
20
20
|
}
|
21
|
+
|
21
22
|
&.sc-text-field-accessory-view {
|
22
|
-
|
23
|
+
z-index: 2;
|
23
24
|
}
|
24
25
|
input {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
position: absolute;
|
27
|
+
top: 0px;
|
28
|
+
left: 0px;
|
29
|
+
width: 100%;
|
29
30
|
height: 100%;
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
display: block;
|
32
|
+
background: transparent;
|
33
|
+
vertical-align: middle;
|
34
|
+
border: none;
|
35
|
+
outline: none;
|
36
|
+
-webkit-appearance:none;
|
36
37
|
}
|
37
38
|
|
38
39
|
textarea {
|
39
40
|
position: absolute;
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
vertical-align: middle;
|
49
|
-
resize: none;
|
50
|
-
overflow: auto;
|
51
|
-
border: none;
|
41
|
+
height: 100%;
|
42
|
+
width: 100%;
|
43
|
+
display: block;
|
44
|
+
background: transparent;
|
45
|
+
vertical-align: middle;
|
46
|
+
resize: none;
|
47
|
+
overflow: auto;
|
48
|
+
border: none;
|
52
49
|
outline: none;
|
53
50
|
-webkit-appearance:none;
|
54
51
|
}
|
52
|
+
|
53
|
+
&.text-area .padding {
|
54
|
+
bottom: 1px;
|
55
|
+
top: 2px;
|
56
|
+
}
|
55
57
|
|
56
58
|
.sc-hint {
|
57
59
|
z-index: 1;
|
58
60
|
}
|
59
61
|
|
60
62
|
.sc-hint, .hint {
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
63
|
+
position: absolute;
|
64
|
+
top: 3px;
|
65
|
+
left: 1px;
|
66
|
+
right: 1px;
|
67
|
+
bottom: 3px;
|
68
|
+
padding: 0px;
|
69
|
+
color: #aaa ;
|
70
|
+
font-size: 12px;
|
71
|
+
-webkit-font-smoothing: antialiased;
|
69
72
|
}
|
70
73
|
|
71
74
|
&.text-area .sc-hint,
|
72
75
|
&.text-area .hint {
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
76
|
+
top: 0px;
|
77
|
+
left: 1px;
|
78
|
+
right: 1px;
|
79
|
+
bottom: 2px;
|
77
80
|
}
|
78
81
|
|
79
82
|
&.focus .sc-hint,
|
80
83
|
&.not-empty .sc-hint {
|
81
|
-
display: none
|
84
|
+
display: none;
|
82
85
|
}
|
83
86
|
|
84
87
|
&.sc-hint .field{
|
@@ -95,7 +98,7 @@
|
|
95
98
|
}
|
96
99
|
}
|
97
100
|
|
98
|
-
.
|
101
|
+
.firefox &{
|
99
102
|
&.focus {
|
100
103
|
outline-color:-moz-mac-focusring;
|
101
104
|
outline-offset:-5px;
|
@@ -106,7 +109,7 @@
|
|
106
109
|
-moz-appearance: textfield;
|
107
110
|
}
|
108
111
|
textarea.field {
|
109
|
-
|
112
|
+
height: 100%;
|
110
113
|
}
|
111
114
|
}
|
112
115
|
|
@@ -118,7 +121,7 @@
|
|
118
121
|
border:1px inset;
|
119
122
|
}
|
120
123
|
textarea.field {
|
121
|
-
|
124
|
+
height: 100%;
|
122
125
|
}
|
123
126
|
}
|
124
127
|
}
|
@@ -241,6 +241,11 @@ SC.imageQueue = SC.Object.create(/** @scope SC.imageQueue.prototype */ {
|
|
241
241
|
url: url, status: this.IMAGE_WAITING, callbacks: [], retainCount: 0, image: img
|
242
242
|
};
|
243
243
|
img.entry = entry ; // provide a link back to the image
|
244
|
+
} else if (entry && entry.image === null) {
|
245
|
+
// Ensure that if we retrieve an entry that it has an associated Image,
|
246
|
+
// since failed/aborted images will have had their image property nulled.
|
247
|
+
entry.image = new Image();
|
248
|
+
entry.image.entry = entry;
|
244
249
|
}
|
245
250
|
return entry ;
|
246
251
|
},
|
@@ -0,0 +1,84 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Project: SproutCore - JavaScript Application Framework
|
3
|
+
// Copyright: ©2006-2011 Strobe Inc. and contributors.
|
4
|
+
// ©2008-2011 Apple Inc. All rights reserved.
|
5
|
+
// License: Licensed under MIT license (see license.js)
|
6
|
+
// ==========================================================================
|
7
|
+
// ========================================================================
|
8
|
+
// SC.imageQueue Test for queue stalling (https://github.com/sproutcore/sproutcore/pull/716)
|
9
|
+
// ========================================================================
|
10
|
+
/*globals module test ok isObj equals expects */
|
11
|
+
|
12
|
+
module("Image Queue", {
|
13
|
+
setup: function() {
|
14
|
+
this.guardTimeout = 10000;
|
15
|
+
this.firstGoodImageURL = sc_static('images/sproutcore.png');
|
16
|
+
this.secondGoodImageURL = sc_static('images/sproutcore-logo.png');
|
17
|
+
this.badImageURL = "http://www.sproutcore.com/images/foobar.png";
|
18
|
+
}
|
19
|
+
});
|
20
|
+
|
21
|
+
test("Ensure queue is in known state.", function() {
|
22
|
+
SC.imageQueue._images = {};
|
23
|
+
SC.imageQueue._loading = [] ;
|
24
|
+
SC.imageQueue._foregroundQueue = [];
|
25
|
+
SC.imageQueue._backgroundQueue = [];
|
26
|
+
SC.imageQueue.set('isLoading', NO);
|
27
|
+
|
28
|
+
equals(SC.imageQueue.activeRequests, 0, "There should be no active requests");
|
29
|
+
});
|
30
|
+
|
31
|
+
test("Attempt to load a non-existent image.", function() {
|
32
|
+
SC.imageQueue.loadImage(this.badImageURL, {action: function(imageUrl, imageOrError) {
|
33
|
+
// verify request loaded OK
|
34
|
+
ok(SC.typeOf(imageOrError) === "error", "Image retrieval should fail with error.");
|
35
|
+
// resume executing tests
|
36
|
+
start();
|
37
|
+
}}, 'action', NO);
|
38
|
+
|
39
|
+
stop(this.guardTimeout);
|
40
|
+
});
|
41
|
+
|
42
|
+
test("Load a valid image successfully.", function() {
|
43
|
+
SC.imageQueue.loadImage(this.firstGoodImageURL, {action: function(imageUrl, imageOrError) {
|
44
|
+
// verify request loaded OK
|
45
|
+
ok(SC.typeOf(imageOrError) !== "error", "Image should be retrieved successfully.");
|
46
|
+
// resume executing tests
|
47
|
+
start();
|
48
|
+
}}, 'action', NO);
|
49
|
+
|
50
|
+
stop(this.guardTimeout);
|
51
|
+
});
|
52
|
+
|
53
|
+
test("Attempt to reload previous non-existent image.", function() {
|
54
|
+
SC.imageQueue.loadImage(this.badImageURL, {action: function(imageUrl, imageOrError) {
|
55
|
+
// verify request loaded OK
|
56
|
+
ok(SC.typeOf(imageOrError) === "error", "Image retrieval should fail with error.");
|
57
|
+
// resume executing tests
|
58
|
+
start();
|
59
|
+
}}, 'action', NO);
|
60
|
+
|
61
|
+
stop(this.guardTimeout);
|
62
|
+
});
|
63
|
+
|
64
|
+
test("Reload previous valid image (now cached) successfully.", function() {
|
65
|
+
SC.imageQueue.loadImage(this.firstGoodImageURL, {action: function(imageUrl, imageOrError) {
|
66
|
+
// verify request loaded OK
|
67
|
+
ok(SC.typeOf(imageOrError) !== "error", "Image should be retrieved successfully.");
|
68
|
+
// resume executing tests
|
69
|
+
start();
|
70
|
+
}}, 'action', NO);
|
71
|
+
|
72
|
+
stop(this.guardTimeout);
|
73
|
+
});
|
74
|
+
|
75
|
+
test("Load a second non-cached image successfully.", function() {
|
76
|
+
SC.imageQueue.loadImage(this.secondGoodImageURL, {action: function(imageUrl, imageOrError) {
|
77
|
+
// verify request loaded OK
|
78
|
+
ok(SC.typeOf(imageOrError) !== "error", "Image should be retrieved successfully.");
|
79
|
+
// resume executing tests
|
80
|
+
start();
|
81
|
+
}}, 'action', NO);
|
82
|
+
|
83
|
+
stop(this.guardTimeout);
|
84
|
+
});
|
@@ -105,6 +105,54 @@ test("isEnabled=YES isEditable=YES should not add disable or readOnly attribute"
|
|
105
105
|
ok(!view.$input().attr('readOnly'), 'should not have readOnly attribute');
|
106
106
|
});
|
107
107
|
|
108
|
+
test("autoCapitalize=YES should add autocapitalize", function() {
|
109
|
+
SC.RunLoop.begin();
|
110
|
+
view.set('autoCapitalize', YES);
|
111
|
+
view.displayDidChange();
|
112
|
+
SC.RunLoop.end();
|
113
|
+
ok(view.$input().attr('autocapitalize') !== "off", 'should have an autocapitalize attribute');
|
114
|
+
});
|
115
|
+
|
116
|
+
test("autoCapitalize=NO should add autocapitalize='off'", function() {
|
117
|
+
SC.RunLoop.begin();
|
118
|
+
view.set('autoCapitalize', NO);
|
119
|
+
view.displayDidChange();
|
120
|
+
SC.RunLoop.end();
|
121
|
+
ok(view.$input().attr('autocapitalize') === "off", 'should have an autocapitalize attribute set to "off"');
|
122
|
+
});
|
123
|
+
|
124
|
+
test("autoCapitalize=null should not add autocapitalize", function() {
|
125
|
+
SC.RunLoop.begin();
|
126
|
+
view.set('autoCapitalize', null);
|
127
|
+
view.displayDidChange();
|
128
|
+
SC.RunLoop.end();
|
129
|
+
ok(!view.$input().attr('autocapitalize'), 'should not have an autocapitalize attribute set');
|
130
|
+
});
|
131
|
+
|
132
|
+
test("autoCorrect=YES should add autocorrect", function() {
|
133
|
+
SC.RunLoop.begin();
|
134
|
+
view.set('autoCorrect', YES);
|
135
|
+
view.displayDidChange();
|
136
|
+
SC.RunLoop.end();
|
137
|
+
ok(view.$input().attr('autocorrect') !== "off", 'should have an autocorrect attribute');
|
138
|
+
});
|
139
|
+
|
140
|
+
test("autoCorrect=NO should add autocorrect='off'", function() {
|
141
|
+
SC.RunLoop.begin();
|
142
|
+
view.set('autoCorrect', NO);
|
143
|
+
view.displayDidChange();
|
144
|
+
SC.RunLoop.end();
|
145
|
+
ok(view.$input().attr('autocorrect') === "off", 'should have an autocorrect attribute set to "off"');
|
146
|
+
});
|
147
|
+
|
148
|
+
test("autoCorrect=null should not add autocorrect", function() {
|
149
|
+
SC.RunLoop.begin();
|
150
|
+
view.set('autoCorrect', null);
|
151
|
+
view.displayDidChange();
|
152
|
+
SC.RunLoop.end();
|
153
|
+
ok(!view.$input().attr('autocorrect'), 'should not have an autocorrect attribute set');
|
154
|
+
});
|
155
|
+
|
108
156
|
// test("isEnabled=NO should add disabled attr to input", function() {
|
109
157
|
// SC.RunLoop.begin();
|
110
158
|
// view1.set('isEnabled', NO);
|
@@ -19,13 +19,13 @@
|
|
19
19
|
})
|
20
20
|
|
21
21
|
.add("password", SC.TextFieldView, {
|
22
|
-
|
22
|
+
type: "password",
|
23
23
|
value: "I'm so secret"
|
24
24
|
})
|
25
25
|
|
26
26
|
.add("password-hint", SC.TextFieldView, {
|
27
27
|
hint: "Passwerd",
|
28
|
-
|
28
|
+
type: "password",
|
29
29
|
value: "I'm so secret"
|
30
30
|
})
|
31
31
|
|
@@ -19,11 +19,19 @@ sc_require('mixins/editable');
|
|
19
19
|
@extends SC.FieldView
|
20
20
|
@extends SC.Editable
|
21
21
|
@author Charles Jolley
|
22
|
-
*/
|
22
|
+
*/
|
23
23
|
SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
24
|
-
/** @scope SC.TextFieldView.prototype */ {
|
24
|
+
/** @scope SC.TextFieldView.prototype */ {
|
25
25
|
|
26
26
|
classNames: ['sc-text-field-view'],
|
27
|
+
|
28
|
+
/**
|
29
|
+
Walk like a duck.
|
30
|
+
|
31
|
+
@type Boolean
|
32
|
+
@default YES
|
33
|
+
@readOnly
|
34
|
+
*/
|
27
35
|
isTextField: YES,
|
28
36
|
|
29
37
|
// ..........................................................
|
@@ -31,54 +39,64 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
31
39
|
//
|
32
40
|
|
33
41
|
/**
|
34
|
-
When applyImmediately is turned on, every keystroke will set the value
|
42
|
+
When `applyImmediately` is turned on, every keystroke will set the value
|
35
43
|
of the underlying object. Turning it off will only set the value on blur.
|
36
44
|
|
37
45
|
@type String
|
38
46
|
@default YES
|
39
|
-
|
47
|
+
*/
|
40
48
|
applyImmediately: YES,
|
41
49
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
50
|
+
/**
|
51
|
+
Flag indicating whether the editor should automatically commit if you click
|
52
|
+
outside it.
|
53
|
+
|
54
|
+
@type Boolean
|
55
|
+
@default YES
|
56
|
+
*/
|
48
57
|
commitOnBlur: YES,
|
49
58
|
|
50
|
-
/**
|
51
|
-
If YES
|
59
|
+
/** @deprecated
|
60
|
+
If `YES`, the field will hide its text from display.
|
61
|
+
This value is deprecated. Please use `type` instead to `"password"`.
|
52
62
|
|
53
|
-
@property
|
54
63
|
@type Boolean
|
55
|
-
|
64
|
+
@default NO
|
65
|
+
*/
|
56
66
|
isPassword: NO,
|
57
67
|
|
58
68
|
/**
|
59
|
-
If YES then allow multi-line input. This will also change the default
|
69
|
+
If `YES` then allow multi-line input. This will also change the default
|
60
70
|
tag type from "input" to "textarea". Otherwise, pressing return will
|
61
71
|
trigger the default insertion handler.
|
62
72
|
|
63
|
-
@property
|
64
73
|
@type Boolean
|
65
|
-
|
74
|
+
@default NO
|
75
|
+
*/
|
66
76
|
isTextArea: NO,
|
67
77
|
|
78
|
+
/**
|
79
|
+
Whether the text field is currently focused.
|
80
|
+
|
81
|
+
@type Boolean
|
82
|
+
@default NO
|
83
|
+
*/
|
84
|
+
focused: NO,
|
85
|
+
|
68
86
|
/**
|
69
87
|
The hint to display while the field is not active.
|
70
88
|
|
71
|
-
@property
|
72
89
|
@type String
|
73
|
-
|
90
|
+
@default ""
|
91
|
+
*/
|
74
92
|
hint: '',
|
75
93
|
|
76
94
|
/**
|
77
95
|
The hint to display while the field is not active.
|
78
96
|
|
79
|
-
@property
|
80
97
|
@type String
|
81
|
-
|
98
|
+
@default "text"
|
99
|
+
*/
|
82
100
|
type: 'text',
|
83
101
|
|
84
102
|
/**
|
@@ -90,89 +108,107 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
90
108
|
problem when you had an alert on top of a mainPane with textfields.
|
91
109
|
|
92
110
|
Modal panes set this to NO on all textfields that don't belong to itself.
|
93
|
-
@
|
94
|
-
|
95
|
-
|
111
|
+
@type Boolean
|
112
|
+
@default YES
|
113
|
+
*/
|
96
114
|
isBrowserFocusable: YES,
|
97
115
|
|
98
|
-
|
99
|
-
|
116
|
+
/**
|
117
|
+
Whether the browser should automatically correct the input.
|
118
|
+
|
119
|
+
When `autoCorrect` is set to `null`, the browser will use
|
120
|
+
the system defaults.
|
121
|
+
|
122
|
+
@type Boolean
|
123
|
+
@default YES
|
124
|
+
*/
|
125
|
+
autoCorrect: YES,
|
126
|
+
|
127
|
+
/**
|
128
|
+
Whether the browser should automatically capitalize the input.
|
100
129
|
|
130
|
+
When `autoCapitalize` is set to `null`, the browser will use
|
131
|
+
the system defaults.
|
101
132
|
|
102
|
-
|
133
|
+
@type Boolean
|
134
|
+
@default YES
|
135
|
+
*/
|
136
|
+
autoCapitalize: YES,
|
137
|
+
|
138
|
+
/**
|
103
139
|
Localizes the hint if necessary.
|
104
140
|
|
105
|
-
@
|
141
|
+
@field
|
106
142
|
@type String
|
107
|
-
|
108
|
-
formattedHint: function() {
|
143
|
+
*/
|
144
|
+
formattedHint: function () {
|
109
145
|
var hint = this.get('hint');
|
110
146
|
return typeof(hint) === 'string' && this.get('localize') ? SC.String.loc(hint) : hint;
|
111
147
|
}.property('hint', 'localize').cacheable(),
|
112
148
|
|
113
149
|
/**
|
114
|
-
Whether to show the hint while the field has focus.
|
115
|
-
as soon as any character is in the field.
|
150
|
+
Whether to show the hint while the field has focus.
|
151
|
+
If `YES`, it will disappear as soon as any character is in the field.
|
116
152
|
|
117
|
-
@property
|
118
153
|
@type Boolean
|
119
|
-
|
154
|
+
@default YES
|
155
|
+
*/
|
120
156
|
hintOnFocus: YES,
|
121
157
|
|
122
|
-
|
158
|
+
/**
|
123
159
|
Whether the hint should be localized or not.
|
124
160
|
|
125
|
-
@property
|
126
161
|
@type Boolean
|
127
|
-
|
162
|
+
@default YES
|
163
|
+
*/
|
128
164
|
localize: YES,
|
129
165
|
|
130
166
|
/**
|
131
|
-
If YES then the text field is currently editing.
|
167
|
+
If `YES` then the text field is currently editing.
|
132
168
|
|
133
|
-
@property
|
134
169
|
@type Boolean
|
135
|
-
|
170
|
+
@default NO
|
171
|
+
*/
|
136
172
|
isEditing: NO,
|
137
173
|
|
138
174
|
/**
|
139
175
|
If you set this property to false the tab key won't trigger its default
|
140
176
|
behavior (tabbing to the next field).
|
141
177
|
|
142
|
-
@property
|
143
178
|
@type Boolean
|
144
|
-
|
179
|
+
@default YES
|
180
|
+
*/
|
145
181
|
defaultTabbingEnabled: YES,
|
146
182
|
|
147
183
|
/**
|
148
184
|
Enabled context menu for textfields.
|
149
185
|
|
150
|
-
@property
|
151
186
|
@type Boolean
|
152
|
-
|
187
|
+
@default YES
|
188
|
+
*/
|
153
189
|
isContextMenuEnabled: YES,
|
154
190
|
|
155
191
|
/**
|
156
192
|
@deprecated Use #applyImmediately instead.
|
157
193
|
|
158
|
-
If true, every change to the text in the text field updates
|
159
|
-
If false,
|
194
|
+
If true, every change to the text in the text field updates `value`.
|
195
|
+
If false, `value` is only updated when commitEditing() is called (this
|
160
196
|
is called automatically when the text field loses focus), or whenever
|
161
197
|
the return key is pressed while editing the field.
|
162
198
|
|
163
199
|
@type Boolean
|
164
200
|
@default null
|
165
|
-
|
201
|
+
*/
|
166
202
|
continuouslyUpdatesValue: null,
|
167
203
|
|
168
204
|
/**
|
169
205
|
If no, will not allow transform or validation errors (SC.Error objects)
|
170
|
-
to be passed to
|
206
|
+
to be passed to `value`. Upon focus lost, the text field will revert
|
171
207
|
to its previous value.
|
172
208
|
|
173
|
-
@property
|
174
209
|
@type Boolean
|
175
|
-
|
210
|
+
@default YES
|
211
|
+
*/
|
176
212
|
allowsErrorAsValue: YES,
|
177
213
|
|
178
214
|
/**
|
@@ -195,9 +231,9 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
195
231
|
amount of left padding used when the accessory view is visible, make the
|
196
232
|
accessory view wider, with empty space on the right.
|
197
233
|
|
198
|
-
@property
|
199
234
|
@type SC.View
|
200
|
-
|
235
|
+
@default null
|
236
|
+
*/
|
201
237
|
leftAccessoryView: null,
|
202
238
|
|
203
239
|
/**
|
@@ -221,54 +257,82 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
221
257
|
amount of right padding used when the accessory view is visible, make the
|
222
258
|
accessory view wider, with empty space on the left.
|
223
259
|
|
224
|
-
@property
|
225
260
|
@type SC.View
|
226
|
-
|
261
|
+
@default null
|
262
|
+
*/
|
227
263
|
rightAccessoryView: null,
|
228
264
|
|
229
265
|
/**
|
230
266
|
This property will enable disable HTML5 spell checking if available on the
|
231
|
-
browser. As of today Safari 4+, Chrome 3+ and Firefox 3+ support it
|
267
|
+
browser. As of today Safari 4+, Chrome 3+ and Firefox 3+ support it.
|
232
268
|
|
233
|
-
@property
|
234
269
|
@type Boolean
|
235
|
-
|
270
|
+
@default YES
|
271
|
+
*/
|
236
272
|
spellCheckEnabled: YES,
|
237
273
|
|
238
274
|
/**
|
239
275
|
Maximum amount of characters this field will allow.
|
240
276
|
|
241
|
-
@property
|
242
277
|
@type Number
|
243
|
-
|
278
|
+
@default 5096
|
279
|
+
*/
|
244
280
|
maxLength: 5096,
|
245
281
|
|
246
282
|
/**
|
247
283
|
Whether to render a border or not.
|
248
284
|
|
249
|
-
@property
|
250
285
|
@type Boolean
|
251
|
-
|
286
|
+
@default YES
|
287
|
+
*/
|
252
288
|
shouldRenderBorder: YES,
|
253
289
|
|
254
|
-
//
|
290
|
+
// ..........................................................
|
255
291
|
// SUPPORT FOR AUTOMATIC RESIZING
|
256
292
|
//
|
293
|
+
|
294
|
+
/**
|
295
|
+
Text fields support auto resizing.
|
296
|
+
@type Boolean
|
297
|
+
@default YES
|
298
|
+
@see SC.AutoResize#supportsAutoResize
|
299
|
+
*/
|
257
300
|
supportsAutoResize: YES,
|
258
|
-
autoResizeLayer: function() { return this.$input()[0]; }
|
259
|
-
.property('layer').cacheable(),
|
260
301
|
|
261
|
-
|
262
|
-
|
302
|
+
/**
|
303
|
+
The layer to automatically resize.
|
304
|
+
|
305
|
+
@type DOMElement
|
306
|
+
@see SC.AutoResize#autoResizeLayer
|
307
|
+
*/
|
308
|
+
autoResizeLayer: function () {
|
309
|
+
return this.$input()[0];
|
310
|
+
}.property('layer').cacheable(),
|
311
|
+
|
312
|
+
/**
|
313
|
+
The text to be used when automatically resizing the text field.
|
263
314
|
|
315
|
+
@type String
|
316
|
+
@see SC.AutoResize#autoResizeText
|
317
|
+
*/
|
318
|
+
autoResizeText: function () {
|
319
|
+
return this.get('value');
|
320
|
+
}.property('value').cacheable(),
|
321
|
+
|
322
|
+
/**
|
323
|
+
How much padding should be used when automatically resizing.
|
324
|
+
@type Number
|
325
|
+
@default 20
|
326
|
+
@see SC.AutoResize#autoResizePadding
|
327
|
+
*/
|
264
328
|
autoResizePadding: SC.propertyFromRenderDelegate('autoResizePadding', 20),
|
265
329
|
|
266
330
|
/** @private
|
267
|
-
Whether to show hint or not
|
268
|
-
|
331
|
+
Whether to show hint or not.
|
332
|
+
*/
|
269
333
|
_hintON: YES,
|
270
334
|
|
271
|
-
init: function() {
|
335
|
+
init: function () {
|
272
336
|
var val = this.get('value');
|
273
337
|
this._hintON = ((!val || val && val.length===0) && !this.get('hintOnFocus')) ? YES : NO;
|
274
338
|
|
@@ -286,13 +350,13 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
286
350
|
|
287
351
|
/**
|
288
352
|
This property indicates if the value in the text field can be changed.
|
289
|
-
If set to NO
|
353
|
+
If set to `NO`, a `readOnly` attribute will be added to the DOM Element.
|
290
354
|
|
291
|
-
Note if isEnabled is NO this property will have no effect.
|
355
|
+
Note if `isEnabled` is `NO` this property will have no effect.
|
292
356
|
|
293
|
-
@property
|
294
357
|
@type Boolean
|
295
|
-
|
358
|
+
@default YES
|
359
|
+
*/
|
296
360
|
isEditable: YES,
|
297
361
|
|
298
362
|
/**
|
@@ -303,9 +367,10 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
303
367
|
not the case that a previously-returned SC.TextSelection object will
|
304
368
|
simply have its properties mutated.
|
305
369
|
|
306
|
-
@
|
307
|
-
|
308
|
-
|
370
|
+
@field
|
371
|
+
@type SC.TextSelection
|
372
|
+
*/
|
373
|
+
selection: function (key, value) {
|
309
374
|
var element = this.$input()[0],
|
310
375
|
range, start, end;
|
311
376
|
|
@@ -408,16 +473,16 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
408
473
|
|
409
474
|
displayProperties: ['isBrowserFocusable','formattedHint', 'fieldValue', 'isEditing', 'isEditable', 'leftAccessoryView', 'rightAccessoryView', 'isTextArea'],
|
410
475
|
|
411
|
-
createChildViews: function() {
|
476
|
+
createChildViews: function () {
|
412
477
|
sc_super();
|
413
478
|
this.accessoryViewObserver();
|
414
479
|
},
|
415
480
|
|
416
|
-
acceptsFirstResponder: function() {
|
481
|
+
acceptsFirstResponder: function () {
|
417
482
|
return this.get('isEnabled');
|
418
483
|
}.property('isEnabled'),
|
419
484
|
|
420
|
-
accessoryViewObserver: function() {
|
485
|
+
accessoryViewObserver: function () {
|
421
486
|
var classNames,
|
422
487
|
viewProperties = ['leftAccessoryView', 'rightAccessoryView'],
|
423
488
|
len = viewProperties.length , i, viewProperty, previousView,
|
@@ -476,7 +541,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
476
541
|
}
|
477
542
|
}.observes('leftAccessoryView', 'rightAccessoryView'),
|
478
543
|
|
479
|
-
layoutChildViewsIfNeeded: function(isVisible) {
|
544
|
+
layoutChildViewsIfNeeded: function (isVisible) {
|
480
545
|
// For the right accessory view, adjust the positioning such that the view
|
481
546
|
// is right-justified, unless 'right' is specified.
|
482
547
|
if (!isVisible) isVisible = this.get('isVisibleInWindow') ;
|
@@ -499,7 +564,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
499
564
|
sc_super() ;
|
500
565
|
},
|
501
566
|
|
502
|
-
render: function(context, firstTime) {
|
567
|
+
render: function (context, firstTime) {
|
503
568
|
sc_super() ;
|
504
569
|
var v, accessoryViewWidths, leftAdjustment, rightAdjustment;
|
505
570
|
|
@@ -530,16 +595,16 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
530
595
|
If isTextArea is changed (this might happen in inlineeditor constantly)
|
531
596
|
force the field render to render like the firsttime to avoid writing extra
|
532
597
|
code. This can be useful also
|
533
|
-
|
598
|
+
*/
|
534
599
|
_forceRenderFirstTime: NO,
|
535
600
|
|
536
601
|
/** @private */
|
537
|
-
_renderFieldLikeFirstTime: function(){
|
602
|
+
_renderFieldLikeFirstTime: function (){
|
538
603
|
this.set('_forceRenderFirstTime', YES);
|
539
604
|
}.observes('isTextArea'),
|
540
605
|
|
541
606
|
/** @private */
|
542
|
-
_renderField: function(context, firstTime, value, leftAdjustment, rightAdjustment) {
|
607
|
+
_renderField: function (context, firstTime, value, leftAdjustment, rightAdjustment) {
|
543
608
|
// TODO: The cleanest thing might be to create a sub- rendering context
|
544
609
|
// here, but currently SC.RenderContext will render sibling
|
545
610
|
// contexts as parent/child.
|
@@ -567,7 +632,6 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
567
632
|
context.setClass('oldWebKitFieldPadding', isOldSafari);
|
568
633
|
|
569
634
|
|
570
|
-
|
571
635
|
if (firstTime || this._forceRenderFirstTime) {
|
572
636
|
this._forceRenderFirstTime = NO;
|
573
637
|
activeState = isEnabled ? (isEditable ? '' : 'readonly="readonly"') : 'disabled="disabled"' ;
|
@@ -575,39 +639,42 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
575
639
|
|
576
640
|
spellCheckString = this.get('spellCheckEnabled') ? ' spellcheck="true"' : ' spellcheck="false"';
|
577
641
|
|
578
|
-
if(
|
579
|
-
autocorrectString = !autoCorrect ? '
|
580
|
-
autocapitalizeString = !autoCapitalize ? ' autocapitalize="off"' : '';
|
642
|
+
if (autoCorrect != null) {
|
643
|
+
autocorrectString = ' autocorrect=' + (!autoCorrect ? '"off"' : '"true"');
|
581
644
|
}
|
582
645
|
|
583
|
-
if(
|
646
|
+
if (autoCorrect != null) {
|
647
|
+
autocapitalizeString = ' autocapitalize=' + (!autoCapitalize ? '"off"' : '"true"');
|
648
|
+
}
|
649
|
+
|
650
|
+
if (isBrowserFocusable) {
|
584
651
|
browserFocusable = 'tabindex="-1"';
|
585
652
|
}
|
586
653
|
// if hint is on and we don't want it to show on focus, create one
|
587
|
-
if(SC.platform.input.placeholder && !hintOnFocus) {
|
654
|
+
if (SC.platform.input.placeholder && !hintOnFocus) {
|
588
655
|
hintString = ' placeholder="' + hint + '"';
|
589
656
|
}
|
590
657
|
|
591
|
-
if(this.get('shouldRenderBorder')) context.push('<div class="border"></div>');
|
658
|
+
if (this.get('shouldRenderBorder')) context.push('<div class="border"></div>');
|
592
659
|
|
593
660
|
// Render the padding element, with any necessary positioning
|
594
661
|
// adjustments to accommodate accessory views.
|
595
662
|
adjustmentStyle = '' ;
|
596
|
-
if (leftAdjustment
|
663
|
+
if (leftAdjustment || rightAdjustment) {
|
597
664
|
adjustmentStyle = 'style="' ;
|
598
|
-
if (leftAdjustment) adjustmentStyle += 'left:
|
599
|
-
if (rightAdjustment) adjustmentStyle += 'right:
|
665
|
+
if (leftAdjustment) adjustmentStyle += 'left:' + leftAdjustment + ';' ;
|
666
|
+
if (rightAdjustment) adjustmentStyle += 'right:' + rightAdjustment + ';' ;
|
600
667
|
adjustmentStyle += '"' ;
|
601
668
|
}
|
602
669
|
context.push('<div class="padding" '+adjustmentStyle+'>');
|
603
670
|
|
604
671
|
value = this.get('escapeHTML') ? SC.RenderContext.escapeHTML(value) : value;
|
605
|
-
if(this._hintON && !SC.platform.input.placeholder && (!value || (value && value.length===0))) {
|
672
|
+
if (this._hintON && !SC.platform.input.placeholder && (!value || (value && value.length===0))) {
|
606
673
|
value = hint;
|
607
674
|
context.setClass('sc-hint', YES);
|
608
675
|
}
|
609
676
|
|
610
|
-
if(hintOnFocus) {
|
677
|
+
if (hintOnFocus) {
|
611
678
|
var hintStr = '<div aria-hidden="true" class="hint '+
|
612
679
|
(isTextArea ? '':'ellipsis')+'%@">'+ hint + '</div>';
|
613
680
|
context.push(hintStr.fmt(value ? ' sc-hidden': ''));
|
@@ -628,7 +695,13 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
628
695
|
|
629
696
|
// Internet Explorer won't let us change the type attribute later
|
630
697
|
// so we force it to password if needed now, or if the value is not the hint
|
631
|
-
if (this.get('isPassword')) {
|
698
|
+
if (this.get('isPassword')) {
|
699
|
+
// @if (debug)
|
700
|
+
SC.Logger.warn("SC.TextFieldView#isPassword is deprecated. Please set SC.TextFieldView#type to password instead.");
|
701
|
+
// @endif
|
702
|
+
|
703
|
+
type = 'password';
|
704
|
+
}
|
632
705
|
|
633
706
|
context.push('<input aria-label="' + hint + '" class="'+fieldClassNames+'" type="'+ type+
|
634
707
|
'" name="'+ name + '" '+ activeState + ' value="'+ value + '"' +
|
@@ -642,8 +715,14 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
642
715
|
elem = input[0],
|
643
716
|
val = this.get('value');
|
644
717
|
|
645
|
-
if(hintOnFocus) this.$('.hint')[0].innerHTML = hint;
|
646
|
-
else if(!hintOnFocus) elem.placeholder = hint;
|
718
|
+
if (hintOnFocus) this.$('.hint')[0].innerHTML = hint;
|
719
|
+
else if (!hintOnFocus) elem.placeholder = hint;
|
720
|
+
|
721
|
+
// IE8 has problems aligning the input text in the center
|
722
|
+
// This is a workaround for centering it.
|
723
|
+
if (SC.browser.name === SC.BROWSER.ie && SC.browser.version <= 8 && !isTextArea) {
|
724
|
+
input.css('line-height', this.get('frame').height + 'px');
|
725
|
+
}
|
647
726
|
|
648
727
|
if (!val || (val && val.length === 0)) {
|
649
728
|
if (this.get('isPassword')) { elem.type = 'password'; }
|
@@ -664,16 +743,23 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
664
743
|
}
|
665
744
|
}
|
666
745
|
|
667
|
-
if(
|
668
|
-
input.attr('
|
669
|
-
|
746
|
+
if (autoCorrect != null) {
|
747
|
+
input.attr('autoCorrect', !autoCorrect ? 'off' : 'true');
|
748
|
+
} else {
|
749
|
+
input.attr('autoCorrect', null);
|
750
|
+
}
|
751
|
+
|
752
|
+
if (autoCapitalize != null) {
|
753
|
+
input.attr('autoCapitalize', !autoCapitalize ? 'off' : 'true');
|
754
|
+
} else {
|
755
|
+
input.attr('autoCapitalize', null);
|
670
756
|
}
|
671
757
|
|
672
758
|
if (!hintOnFocus && SC.platform.input.placeholder) input.attr('placeholder', hint);
|
673
759
|
|
674
|
-
if(isBrowserFocusable){
|
760
|
+
if (isBrowserFocusable) {
|
675
761
|
input.removeAttr('tabindex');
|
676
|
-
}else{
|
762
|
+
} else {
|
677
763
|
input.attr('tabindex', '-1');
|
678
764
|
}
|
679
765
|
// Enable/disable the actual input/textarea as appropriate.
|
@@ -682,7 +768,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
682
768
|
if (!isEnabled) {
|
683
769
|
element.disabled = 'true' ;
|
684
770
|
element.readOnly = null ;
|
685
|
-
} else if(!isEditable) {
|
771
|
+
} else if (!isEditable) {
|
686
772
|
element.disabled = null ;
|
687
773
|
element.readOnly = 'true' ;
|
688
774
|
} else {
|
@@ -713,7 +799,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
713
799
|
}
|
714
800
|
},
|
715
801
|
|
716
|
-
_getAccessoryViewWidths: function() {
|
802
|
+
_getAccessoryViewWidths: function () {
|
717
803
|
var widths = {},
|
718
804
|
accessoryViewPositions = ['left', 'right'],
|
719
805
|
numberOfAccessoryViewPositions = accessoryViewPositions.length, i,
|
@@ -753,13 +839,13 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
753
839
|
// HANDLE NATIVE CONTROL EVENTS
|
754
840
|
//
|
755
841
|
|
756
|
-
didCreateLayer: function() {
|
842
|
+
didCreateLayer: function () {
|
757
843
|
sc_super();
|
758
|
-
if(!SC.platform.input.placeholder) this.invokeLast(this._setInitialPlaceHolderIE);
|
844
|
+
if (!SC.platform.input.placeholder) this.invokeLast(this._setInitialPlaceHolderIE);
|
759
845
|
// For some strange reason if we add focus/blur events to textarea
|
760
846
|
// inmediately they won't work. However if I add them at the end of the
|
761
847
|
// runLoop it works fine.
|
762
|
-
if(this.get('isTextArea')) {
|
848
|
+
if (this.get('isTextArea')) {
|
763
849
|
this.invokeLast(this._addTextAreaEvents);
|
764
850
|
}
|
765
851
|
else {
|
@@ -776,29 +862,49 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
776
862
|
SC.Event.add(input, 'keypress', this, this._firefox_dispatch_keypress);
|
777
863
|
}
|
778
864
|
}
|
865
|
+
|
866
|
+
if (this.get('hintOnFocus') ||
|
867
|
+
(SC.browser.name === SC.BROWSER.ie && SC.browser.version <= 8 && !this.get('isTextArea'))) {
|
868
|
+
this.invokeLast(this._fixupTextLayout);
|
869
|
+
}
|
779
870
|
},
|
780
871
|
|
781
|
-
/**
|
872
|
+
/** @private
|
873
|
+
Apply proper text layout to sc-hints and inputs.
|
874
|
+
*/
|
875
|
+
_fixupTextLayout: function () {
|
876
|
+
var height = this.get('frame').height;
|
877
|
+
|
878
|
+
if (SC.browser.name === SC.BROWSER.ie && SC.browser.version <= 8 &&
|
879
|
+
!this.get('isTextArea')) {
|
880
|
+
this.$input().css('line-height', height + 'px');
|
881
|
+
}
|
882
|
+
|
883
|
+
if (this.get('hintOnFocus') && !this.get('isTextArea')) {
|
884
|
+
this.$('.hint').css('line-height', this.$('.hint').outerHeight() + 'px');
|
885
|
+
}
|
886
|
+
},
|
887
|
+
|
888
|
+
/** @private
|
782
889
|
Set initial placeholder for IE
|
783
|
-
|
784
|
-
_setInitialPlaceHolderIE: function() {
|
785
|
-
if(!SC.platform.input.placeholder && this._hintON){
|
890
|
+
*/
|
891
|
+
_setInitialPlaceHolderIE: function () {
|
892
|
+
if (!SC.platform.input.placeholder && this._hintON) {
|
786
893
|
var input = this.$input(),
|
787
894
|
currentValue = input.val();
|
788
|
-
if(!currentValue || (currentValue && currentValue.length===0)){
|
895
|
+
if (!currentValue || (currentValue && currentValue.length===0)) {
|
789
896
|
input.val(this.get('formattedHint'));
|
790
897
|
}
|
791
898
|
}
|
792
899
|
},
|
793
900
|
|
794
|
-
/**
|
901
|
+
/** @private
|
795
902
|
Adds all the textarea events. This functions is called by didCreateLayer
|
796
903
|
at different moments depending if it is a textarea or not. Appending
|
797
904
|
events to text areas is not reliable unless the element is already added
|
798
905
|
to the DOM.
|
799
|
-
|
800
|
-
|
801
|
-
_addTextAreaEvents: function() {
|
906
|
+
*/
|
907
|
+
_addTextAreaEvents: function () {
|
802
908
|
var input = this.$input();
|
803
909
|
SC.Event.add(input, 'focus', this, this._textField_fieldDidFocus);
|
804
910
|
SC.Event.add(input, 'blur', this, this._textField_fieldDidBlur);
|
@@ -811,9 +917,8 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
811
917
|
|
812
918
|
/**
|
813
919
|
Removes all the events attached to the textfield
|
814
|
-
|
815
|
-
|
816
|
-
willDestroyLayer: function() {
|
920
|
+
*/
|
921
|
+
willDestroyLayer: function () {
|
817
922
|
sc_super();
|
818
923
|
|
819
924
|
var input = this.$input();
|
@@ -824,14 +929,14 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
824
929
|
},
|
825
930
|
|
826
931
|
/** @private
|
827
|
-
|
932
|
+
This function is called by the event when the textfield gets focus
|
828
933
|
*/
|
829
|
-
_textField_fieldDidFocus: function(evt) {
|
830
|
-
SC.run(function() {
|
934
|
+
_textField_fieldDidFocus: function (evt) {
|
935
|
+
SC.run(function () {
|
831
936
|
this.set('focused',YES);
|
832
937
|
this.fieldDidFocus(evt);
|
833
938
|
var val = this.get('value');
|
834
|
-
if(!SC.platform.input.placeholder && ((!val) || (val && val.length===0))) {
|
939
|
+
if (!SC.platform.input.placeholder && ((!val) || (val && val.length===0))) {
|
835
940
|
this._hintON = NO;
|
836
941
|
}
|
837
942
|
}, this);
|
@@ -839,22 +944,22 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
839
944
|
|
840
945
|
/** @private
|
841
946
|
This function is called by the event when the textfield blurs
|
842
|
-
|
843
|
-
_textField_fieldDidBlur: function(evt) {
|
844
|
-
SC.run(function() {
|
947
|
+
*/
|
948
|
+
_textField_fieldDidBlur: function (evt) {
|
949
|
+
SC.run(function () {
|
845
950
|
this.set('focused',NO);
|
846
951
|
// passing the original event here instead that was potentially set from
|
847
952
|
// loosing the responder on the inline text editor so that we can
|
848
953
|
// use it for the delegate to end editing
|
849
954
|
this.fieldDidBlur(this._origEvent || evt);
|
850
955
|
var val = this.get('value');
|
851
|
-
if(!SC.platform.input.placeholder && !this.get('hintOnFocus') && ((!val) || (val && val.length===0))) {
|
956
|
+
if (!SC.platform.input.placeholder && !this.get('hintOnFocus') && ((!val) || (val && val.length===0))) {
|
852
957
|
this._hintON = YES;
|
853
958
|
}
|
854
959
|
}, this);
|
855
960
|
},
|
856
961
|
|
857
|
-
fieldDidFocus: function(evt) {
|
962
|
+
fieldDidFocus: function (evt) {
|
858
963
|
this.becomeFirstResponder();
|
859
964
|
|
860
965
|
this.beginEditing(evt);
|
@@ -877,10 +982,10 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
877
982
|
}
|
878
983
|
},
|
879
984
|
|
880
|
-
fieldDidBlur: function(evt) {
|
985
|
+
fieldDidBlur: function (evt) {
|
881
986
|
this.resignFirstResponder(evt) ;
|
882
987
|
|
883
|
-
if(this.get('commitOnBlur')) this.commitEditing(evt);
|
988
|
+
if (this.get('commitOnBlur')) this.commitEditing(evt);
|
884
989
|
|
885
990
|
// get the pane we hid intercept pane for (if any)
|
886
991
|
var touchPane = this._didHideInterceptForPane;
|
@@ -891,9 +996,9 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
891
996
|
},
|
892
997
|
|
893
998
|
/** @private */
|
894
|
-
_field_fieldValueDidChange: function(evt) {
|
895
|
-
if(this.get('focused')){
|
896
|
-
SC.run(function() {
|
999
|
+
_field_fieldValueDidChange: function (evt) {
|
1000
|
+
if (this.get('focused')){
|
1001
|
+
SC.run(function () {
|
897
1002
|
this.fieldValueDidChange(NO);
|
898
1003
|
}, this);
|
899
1004
|
}
|
@@ -902,13 +1007,13 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
902
1007
|
|
903
1008
|
/** @private
|
904
1009
|
Make sure to update visibility of hint if it changes
|
905
|
-
|
906
|
-
updateHintOnFocus: function() {
|
1010
|
+
*/
|
1011
|
+
updateHintOnFocus: function () {
|
907
1012
|
// if there is a value in the field, hide the hint
|
908
1013
|
var hintOnFocus = this.get('hintOnFocus');
|
909
|
-
if(!hintOnFocus) return;
|
1014
|
+
if (!hintOnFocus) return;
|
910
1015
|
|
911
|
-
if(this.getFieldValue()) {
|
1016
|
+
if (this.getFieldValue()) {
|
912
1017
|
this.$('.hint').addClass('sc-hidden');
|
913
1018
|
}
|
914
1019
|
else {
|
@@ -918,7 +1023,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
918
1023
|
|
919
1024
|
/** @private
|
920
1025
|
Move magic number out so it can be over-written later in inline editor
|
921
|
-
|
1026
|
+
*/
|
922
1027
|
_topOffsetForFirefoxCursorFix: 3,
|
923
1028
|
|
924
1029
|
/** @private
|
@@ -928,8 +1033,8 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
928
1033
|
document (only for the input element), although it will be bubbled up in
|
929
1034
|
other contexts. Since SproutCore's event dispatching requires the
|
930
1035
|
document to see the event, we'll manually forward the event along.
|
931
|
-
|
932
|
-
_firefox_dispatch_keypress: function(evt) {
|
1036
|
+
*/
|
1037
|
+
_firefox_dispatch_keypress: function (evt) {
|
933
1038
|
var selection = this.get('selection'),
|
934
1039
|
value = this.get('value'),
|
935
1040
|
valueLen = value ? value.length : 0,
|
@@ -944,7 +1049,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
944
1049
|
},
|
945
1050
|
|
946
1051
|
/** @private */
|
947
|
-
_textField_selectionDidChange: function() {
|
1052
|
+
_textField_selectionDidChange: function () {
|
948
1053
|
this.notifyPropertyChange('selection');
|
949
1054
|
},
|
950
1055
|
|
@@ -957,15 +1062,14 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
957
1062
|
/** @private
|
958
1063
|
When we become first responder, focus the text field if needed and
|
959
1064
|
hide the hint text.
|
960
|
-
|
961
|
-
didBecomeKeyResponderFrom: function(keyView) {
|
962
|
-
if(this.get('isVisibleInWindow')) {
|
1065
|
+
*/
|
1066
|
+
didBecomeKeyResponderFrom: function (keyView) {
|
1067
|
+
if (this.get('isVisibleInWindow')) {
|
963
1068
|
var inp = this.$input()[0];
|
964
|
-
try{
|
965
|
-
if(inp) inp.focus();
|
966
|
-
}
|
967
|
-
|
968
|
-
if(!this._txtFieldMouseDown){
|
1069
|
+
try {
|
1070
|
+
if (inp) inp.focus();
|
1071
|
+
} catch(e){}
|
1072
|
+
if (!this._txtFieldMouseDown) {
|
969
1073
|
this.invokeLast(this._selectRootElement) ;
|
970
1074
|
}
|
971
1075
|
}
|
@@ -974,19 +1078,19 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
974
1078
|
/** @private
|
975
1079
|
In IE, you can't modify functions on DOM elements so we need to wrap the
|
976
1080
|
call to select() like this.
|
977
|
-
|
978
|
-
_selectRootElement: function() {
|
1081
|
+
*/
|
1082
|
+
_selectRootElement: function () {
|
979
1083
|
var inputElem = this.$input()[0],
|
980
1084
|
isLion;
|
981
1085
|
// Make sure input element still exists, as a redraw could have remove it
|
982
1086
|
// already.
|
983
|
-
if(inputElem){
|
1087
|
+
if (inputElem) {
|
984
1088
|
// Determine if the OS is OS 10.7 "Lion"
|
985
1089
|
isLion = SC.browser.os === SC.OS.mac &&
|
986
1090
|
SC.browser.compare(SC.browser.osVersion, '10.7') === 0;
|
987
1091
|
|
988
|
-
if(!(SC.browser.name === SC.BROWSER.safari &&
|
989
|
-
|
1092
|
+
if (!(SC.browser.name === SC.BROWSER.safari &&
|
1093
|
+
isLion && SC.buildLocale==='ko-kr')) {
|
990
1094
|
inputElem.select() ;
|
991
1095
|
}
|
992
1096
|
}
|
@@ -996,8 +1100,8 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
996
1100
|
/** @private
|
997
1101
|
When we lose first responder, blur the text field if needed and show
|
998
1102
|
the hint text if needed.
|
999
|
-
|
1000
|
-
didLoseKeyResponderTo: function(keyView) {
|
1103
|
+
*/
|
1104
|
+
didLoseKeyResponderTo: function (keyView) {
|
1001
1105
|
var el = this.$input()[0];
|
1002
1106
|
if (el) el.blur();
|
1003
1107
|
this.invokeLater("scrollToOriginIfNeeded", 100);
|
@@ -1005,8 +1109,8 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
1005
1109
|
|
1006
1110
|
/** @private
|
1007
1111
|
Scrolls to origin if necessary (if the pane's current firstResponder is not a text field).
|
1008
|
-
|
1009
|
-
scrollToOriginIfNeeded: function() {
|
1112
|
+
*/
|
1113
|
+
scrollToOriginIfNeeded: function () {
|
1010
1114
|
var pane = this.get("pane");
|
1011
1115
|
if (!pane) return;
|
1012
1116
|
|
@@ -1019,8 +1123,8 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
1019
1123
|
/**
|
1020
1124
|
Simply allow keyDown & keyUp to pass through to the default web browser
|
1021
1125
|
implementation.
|
1022
|
-
|
1023
|
-
keyDown: function(evt) {
|
1126
|
+
*/
|
1127
|
+
keyDown: function (evt) {
|
1024
1128
|
var which = evt.which,
|
1025
1129
|
keyCode = evt.keyCode,
|
1026
1130
|
maxLengthReached = false,
|
@@ -1042,13 +1146,13 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
1042
1146
|
}
|
1043
1147
|
|
1044
1148
|
// maxlength for textareas
|
1045
|
-
if(!SC.platform.input.maxlength && this.get('isTextArea')){
|
1149
|
+
if (!SC.platform.input.maxlength && this.get('isTextArea')) {
|
1046
1150
|
var val = this.get('value');
|
1047
1151
|
|
1048
1152
|
// This code is nasty. It's thanks gecko .keycode table that has charters like & with the same keycode as up arrow key
|
1049
|
-
if(val && ((!SC.browser.isMozilla && which>47) ||
|
1050
|
-
|
1051
|
-
|
1153
|
+
if (val && ((!SC.browser.isMozilla && which>47) ||
|
1154
|
+
(SC.browser.isMozilla && ((which>32 && which<43) || which>47) && !(keyCode>36 && keyCode<41))) &&
|
1155
|
+
(val.length >= this.get('maxLength'))) {
|
1052
1156
|
maxLengthReached = true;
|
1053
1157
|
}
|
1054
1158
|
}
|
@@ -1065,7 +1169,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
1065
1169
|
// There used to be an invokeLater here instead of setTimeout. What we
|
1066
1170
|
// really need is setTimeout.
|
1067
1171
|
var self = this;
|
1068
|
-
setTimeout(function() {
|
1172
|
+
setTimeout(function () {
|
1069
1173
|
self.fieldValueDidChange();
|
1070
1174
|
}, 10);
|
1071
1175
|
}
|
@@ -1073,7 +1177,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
1073
1177
|
return YES;
|
1074
1178
|
},
|
1075
1179
|
|
1076
|
-
keyUp: function(evt) {
|
1180
|
+
keyUp: function (evt) {
|
1077
1181
|
if (SC.browser.isMozilla &&
|
1078
1182
|
evt.keyCode === SC.Event.KEY_RETURN) { this.fieldValueDidChange(); }
|
1079
1183
|
|
@@ -1086,7 +1190,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
1086
1190
|
return YES;
|
1087
1191
|
},
|
1088
1192
|
|
1089
|
-
mouseDown: function(evt) {
|
1193
|
+
mouseDown: function (evt) {
|
1090
1194
|
var fieldValue = this.get('fieldValue'); // use 'fieldValue' since we want actual text
|
1091
1195
|
this._txtFieldMouseDown=YES;
|
1092
1196
|
this.becomeFirstResponder();
|
@@ -1098,7 +1202,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
1098
1202
|
}
|
1099
1203
|
},
|
1100
1204
|
|
1101
|
-
mouseUp: function(evt) {
|
1205
|
+
mouseUp: function (evt) {
|
1102
1206
|
this._txtFieldMouseDown=NO;
|
1103
1207
|
// The caret/selection could have moved. In some browsers, though, the
|
1104
1208
|
// element's values won't be updated until after this event is finished
|
@@ -1112,37 +1216,37 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
1112
1216
|
return sc_super();
|
1113
1217
|
},
|
1114
1218
|
|
1115
|
-
touchStart: function(evt) {
|
1219
|
+
touchStart: function (evt) {
|
1116
1220
|
return this.mouseDown(evt);
|
1117
1221
|
},
|
1118
1222
|
|
1119
|
-
touchEnd: function(evt) {
|
1223
|
+
touchEnd: function (evt) {
|
1120
1224
|
return this.mouseUp(evt);
|
1121
1225
|
},
|
1122
1226
|
|
1123
1227
|
/**
|
1124
1228
|
Adds mouse wheel support for textareas.
|
1125
|
-
|
1126
|
-
mouseWheel: function(evt) {
|
1127
|
-
if(this.get('isTextArea')) {
|
1229
|
+
*/
|
1230
|
+
mouseWheel: function (evt) {
|
1231
|
+
if (this.get('isTextArea')) {
|
1128
1232
|
evt.allowDefault();
|
1129
1233
|
return YES;
|
1130
1234
|
} else return NO;
|
1131
1235
|
},
|
1132
1236
|
|
1133
|
-
|
1237
|
+
/**
|
1134
1238
|
Allows text selection in IE. We block the IE only event selectStart to
|
1135
1239
|
block text selection in all other views.
|
1136
|
-
|
1137
|
-
selectStart: function(evt) {
|
1240
|
+
*/
|
1241
|
+
selectStart: function (evt) {
|
1138
1242
|
return YES;
|
1139
1243
|
},
|
1140
1244
|
|
1141
1245
|
/** @private
|
1142
1246
|
Overridden from SC.FieldView. Provides correct tag name based on the
|
1143
|
-
|
1247
|
+
`isTextArea` property.
|
1144
1248
|
*/
|
1145
|
-
_inputElementTagName: function() {
|
1249
|
+
_inputElementTagName: function () {
|
1146
1250
|
if (this.get('isTextArea')) {
|
1147
1251
|
return 'textarea';
|
1148
1252
|
} else {
|
@@ -1153,17 +1257,17 @@ SC.TextFieldView = SC.FieldView.extend(SC.StaticLayout, SC.Editable,
|
|
1153
1257
|
/** @private
|
1154
1258
|
This observer makes sure to hide the hint when a value is entered, or
|
1155
1259
|
show it if it becomes empty.
|
1156
|
-
|
1157
|
-
_valueObserver: function() {
|
1260
|
+
*/
|
1261
|
+
_valueObserver: function () {
|
1158
1262
|
var val = this.get('value'), max;
|
1159
|
-
if (val && val.length>0) {
|
1263
|
+
if (val && val.length > 0) {
|
1160
1264
|
this._hintON = NO;
|
1161
1265
|
|
1162
1266
|
max = this.get('maxLength');
|
1163
1267
|
if (!SC.platform.input.maxlength && val.length > max) {
|
1164
1268
|
this.set('value', val.substr(0, max));
|
1165
1269
|
}
|
1166
|
-
} else if(!this.get('hintOnFocus')) {
|
1270
|
+
} else if (!this.get('hintOnFocus')) {
|
1167
1271
|
this._hintON = YES;
|
1168
1272
|
}
|
1169
1273
|
}.observes('value')
|