sproutcore 1.8.0 → 1.8.1
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/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')
|