sproutcore 1.10.1 → 1.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/CHANGELOG +13 -0
- data/VERSION.yml +1 -1
- data/lib/frameworks/sproutcore/CHANGELOG.md +69 -31
- data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/array.js +14 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/controllers/object.js +14 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/event.js +7 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +13 -9
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +57 -23
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/enabled_states_test.js +24 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/enabled.js +63 -13
- data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +3 -3
- data/lib/frameworks/sproutcore/frameworks/datastore/models/single_attribute.js +7 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/system/many_array.js +28 -5
- data/lib/frameworks/sproutcore/frameworks/datastore/system/query.js +15 -0
- data/lib/frameworks/sproutcore/frameworks/datastore/system/record_array.js +30 -3
- data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +23 -1
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/many_attribute.js +135 -89
- data/lib/frameworks/sproutcore/frameworks/datastore/tests/models/single_attribute.js +12 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/panes/picker.js +18 -6
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/panes/picker/ui.js +58 -20
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/date_field/methods.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select/methods.js +15 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/popup_button.js +10 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/views/select.js +24 -23
- data/lib/frameworks/sproutcore/frameworks/desktop/views/split.js +4 -0
- data/lib/frameworks/sproutcore/frameworks/experimental/frameworks/select_view/views/popup_button.js +10 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/delegates/inline_text_field.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/auto_mixin.js +33 -16
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/content_value_support.js +14 -6
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/control.js +23 -18
- data/lib/frameworks/sproutcore/frameworks/foundation/system/user_defaults.js +4 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/delegates/inline_text_field/inline_text_field.js +1 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/auto_mixin_tests.js +78 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/auto_resize_test.js +45 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/mixins/content_value_support/content.js +112 -58
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/system/image_queue.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/container/transition_test.js +141 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/methods.js +27 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/views/text_field/ui.js +631 -593
- data/lib/frameworks/sproutcore/frameworks/foundation/transitions/swap_fade_color_transition.js +5 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/transitions/swap_move_in_transition.js +5 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/transitions/swap_reveal_transition.js +68 -1
- data/lib/frameworks/sproutcore/frameworks/foundation/views/container.js +128 -49
- data/lib/frameworks/sproutcore/frameworks/foundation/views/field.js +33 -8
- data/lib/frameworks/sproutcore/frameworks/foundation/views/text_field.js +209 -187
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +7 -0
- data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +34 -4
- data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +0 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +68 -9
- data/lib/frameworks/sproutcore/frameworks/testing/system/runner.js +2 -1
- data/lib/sproutcore/rack/builder.rb +45 -25
- data/sproutcore.gemspec +1 -0
- metadata +17 -2
@@ -4,9 +4,9 @@
|
|
4
4
|
// portions copyright @2011 Apple Inc.
|
5
5
|
// License: Licensed under MIT license (see license.js)
|
6
6
|
// ==========================================================================
|
7
|
+
/*global module, test, ok, equals, stop, start */
|
7
8
|
|
8
|
-
|
9
|
-
(function() {
|
9
|
+
(function () {
|
10
10
|
var pane = SC.ControlTestPane.design()
|
11
11
|
.add("empty", SC.TextFieldView, {
|
12
12
|
hint: "Full Name",
|
@@ -85,631 +85,669 @@
|
|
85
85
|
isEditable: NO
|
86
86
|
});
|
87
87
|
|
88
|
-
// ..........................................................
|
89
|
-
// VERIFY STANDARD STATES
|
90
|
-
//
|
91
|
-
pane.verifyEmpty = function verifyEmpty(view, expectedHint) {
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
88
|
+
// ..........................................................
|
89
|
+
// VERIFY STANDARD STATES
|
90
|
+
//
|
91
|
+
pane.verifyEmpty = function verifyEmpty(view, expectedHint) {
|
92
|
+
var input = view.$('input');
|
93
|
+
var layer = view.$();
|
94
|
+
|
95
|
+
ok(!layer.hasClass('not-empty'), 'layer should not have not-empty class');
|
96
|
+
if (SC.browser.isWebkit || (SC.browser.isMozilla &&
|
97
|
+
SC.browser.compare(SC.browser.engineVersion, '2.0') >= 0)) equals(input.val(), '', 'input should have empty value');
|
98
|
+
else equals(input.val(), expectedHint, 'input should have expected hint as value');
|
99
|
+
if (expectedHint) {
|
100
|
+
var hint = view.$('.hint');
|
101
|
+
if (hint.length === 1) {
|
102
|
+
hint = hint.text();
|
103
|
+
} else {
|
104
|
+
hint = view.$('input');
|
105
|
+
hint = hint.attr('placeholder');
|
106
|
+
}
|
107
|
+
equals(hint, expectedHint, 'hint span should have expected hint');
|
108
|
+
}
|
108
109
|
|
109
|
-
};
|
110
|
+
};
|
110
111
|
|
111
|
-
pane.verifyNotEmpty = function verifyNotEmpty(view, expectedValue, expectedHint) {
|
112
|
-
|
113
|
-
|
112
|
+
pane.verifyNotEmpty = function verifyNotEmpty(view, expectedValue, expectedHint) {
|
113
|
+
var input = view.$('input');
|
114
|
+
var layer = view.$();
|
114
115
|
|
115
|
-
|
116
|
-
|
116
|
+
ok(layer.hasClass('not-empty'), 'layer should have not-empty class');
|
117
|
+
equals(input.val(), expectedValue, 'input should have value');
|
117
118
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
119
|
+
if (expectedHint) {
|
120
|
+
var hint = view.$('.hint');
|
121
|
+
if (hint.length === 1) {
|
122
|
+
hint = hint.text();
|
123
|
+
} else {
|
124
|
+
hint = view.$('input');
|
125
|
+
hint = hint.attr('placeholder');
|
126
|
+
}
|
127
|
+
equals(hint, expectedHint, 'hint span should have expected hint');
|
128
|
+
}
|
127
129
|
|
128
|
-
};
|
130
|
+
};
|
129
131
|
|
130
|
-
pane.verifyDisabled = function verifyDisabled(view, isDisabled) {
|
131
|
-
|
132
|
-
|
132
|
+
pane.verifyDisabled = function verifyDisabled(view, isDisabled) {
|
133
|
+
var layer = view.$();
|
134
|
+
var input = view.$('input');
|
133
135
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
};
|
136
|
+
if (isDisabled) {
|
137
|
+
ok(layer.hasClass('disabled'), 'layer should have disabled class');
|
138
|
+
ok(input.attr('disabled'), 'input should have disabled attr');
|
139
|
+
} else {
|
140
|
+
ok(!layer.hasClass('disabled'), 'layer should not have disabled class');
|
141
|
+
ok(!input.attr('disabled'), 'input should not have disabled attr');
|
142
|
+
}
|
143
|
+
};
|
142
144
|
|
143
|
-
pane.verifyReadOnly = function verifyReadonly(view, isReadOnly) {
|
144
|
-
|
145
|
+
pane.verifyReadOnly = function verifyReadonly(view, isReadOnly) {
|
146
|
+
var input = view.$('input');
|
145
147
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
};
|
152
|
-
|
153
|
-
// ..........................................................
|
154
|
-
// TEST INITIAL STATES
|
155
|
-
//
|
156
|
-
|
157
|
-
module('SC.TextFieldView
|
158
|
-
|
159
|
-
test("empty", function() {
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
});
|
164
|
-
|
165
|
-
test("with value", function() {
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
});
|
170
|
-
|
171
|
-
test("password", function() {
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
});
|
176
|
-
|
177
|
-
test("password with hint", function() {
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
});
|
182
|
-
|
183
|
-
test("disabled - empty", function() {
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
});
|
188
|
-
|
189
|
-
test("disabled - with value", function() {
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
});
|
194
|
-
|
195
|
-
test("enabled - not editable - with value", function() {
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
});
|
200
|
-
|
201
|
-
test("textarea - empty", function() {
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
});
|
206
|
-
|
207
|
-
test("textarea - with value", function() {
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
});
|
212
|
-
|
213
|
-
test("textarea - disabled - empty", function() {
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
});
|
218
|
-
|
219
|
-
test("textarea - disabled - with value", function() {
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
});
|
224
|
-
|
225
|
-
// ..........................................................
|
226
|
-
// TEST CHANGING VIEWS
|
227
|
-
//
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
});
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
});
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
equals(view.get('fieldValue'), null, 'should have empty fieldValue');
|
257
|
-
pane.verifyEmpty(view, 'Full Name');
|
258
|
-
});
|
259
|
-
|
260
|
-
test("enabling disabled view", function() {
|
261
|
-
var view = pane.view('disabled - empty');
|
262
|
-
|
263
|
-
// test changing enabled state updates like it should
|
264
|
-
SC.RunLoop.begin();
|
265
|
-
view.set('isEnabled', YES);
|
266
|
-
SC.RunLoop.end();
|
267
|
-
pane.verifyDisabled(view, NO);
|
268
|
-
});
|
269
|
-
|
270
|
-
test("changing isEditable", function() {
|
271
|
-
var view = pane.view('enabled - not editable - with value');
|
272
|
-
|
273
|
-
// test changing isEditable state updates like it should
|
274
|
-
SC.RunLoop.begin();
|
275
|
-
view.set('isEditable', YES);
|
276
|
-
SC.RunLoop.end();
|
277
|
-
pane.verifyReadOnly(view, NO);
|
278
|
-
|
279
|
-
// test changing isEditable state updates like it should
|
280
|
-
SC.RunLoop.begin();
|
281
|
-
view.set('isEditable', NO);
|
282
|
-
SC.RunLoop.end();
|
283
|
-
pane.verifyReadOnly(view, YES);
|
284
|
-
});
|
285
|
-
|
286
|
-
test("changing value from not a textarea to a textarea", function() {
|
287
|
-
// test the the SC.Event for 'change' gets wired up properly to the DOM element when it changes from input to textarea
|
288
|
-
var view = pane.view('empty');
|
289
|
-
SC.RunLoop.begin();
|
290
|
-
view.set('value', 'Original');
|
291
|
-
view.set('isTextArea', YES);
|
292
|
-
SC.RunLoop.end();
|
293
|
-
|
294
|
-
var $textarea = view.$('textarea');
|
295
|
-
|
296
|
-
SC.Event.trigger($textarea, 'focus');
|
297
|
-
|
298
|
-
// simulate typing a letter
|
299
|
-
SC.Event.trigger($textarea, 'keydown');
|
300
|
-
$textarea.val("My New Value");
|
301
|
-
SC.Event.trigger($textarea, 'keyup');
|
302
|
-
SC.Event.trigger($textarea, 'change');
|
303
|
-
view.fieldValueDidChange();
|
304
|
-
|
305
|
-
// wait a little bit to let text field propogate changes
|
306
|
-
stop();
|
307
|
-
|
308
|
-
setTimeout(function() {
|
309
|
-
start();
|
310
|
-
equals(view.get("value"), "My New Value", "SC.Event for change should get wired up properly");
|
311
|
-
}, 100);
|
312
|
-
|
313
|
-
SC.RunLoop.begin();
|
314
|
-
SC.RunLoop.end();
|
315
|
-
});
|
316
|
-
|
317
|
-
|
318
|
-
if (!SC.browser.isIE && !SC.platform.input.placeholder) {
|
319
|
-
test("Changing value to null -- password field", function() {
|
320
|
-
var view = pane.view('password-hint'),
|
321
|
-
input = view.$('input');
|
322
|
-
|
323
|
-
SC.run(function() {
|
148
|
+
if(isReadOnly) {
|
149
|
+
ok(input.attr('readOnly'), 'input should have readOnly attr');
|
150
|
+
} else {
|
151
|
+
ok(!input.attr('readOnly'), 'input should not have readOnly attr');
|
152
|
+
}
|
153
|
+
};
|
154
|
+
|
155
|
+
// ..........................................................
|
156
|
+
// TEST INITIAL STATES
|
157
|
+
//
|
158
|
+
|
159
|
+
module('SC.TextFieldView: Initial States', pane.standardSetup());
|
160
|
+
|
161
|
+
test("empty", function () {
|
162
|
+
var view = pane.view('empty');
|
163
|
+
pane.verifyEmpty(view, 'Full Name');
|
164
|
+
pane.verifyDisabled(view, NO);
|
165
|
+
});
|
166
|
+
|
167
|
+
test("with value", function () {
|
168
|
+
var view = pane.view('with value');
|
169
|
+
pane.verifyNotEmpty(view, 'John Doe', 'Full Name');
|
170
|
+
pane.verifyDisabled(view, NO);
|
171
|
+
});
|
172
|
+
|
173
|
+
test("password", function () {
|
174
|
+
var view = pane.view('password');
|
175
|
+
pane.verifyNotEmpty(view, 'I\'m so secret');
|
176
|
+
pane.verifyDisabled(view, NO);
|
177
|
+
});
|
178
|
+
|
179
|
+
test("password with hint", function () {
|
180
|
+
var view = pane.view('password-hint');
|
181
|
+
pane.verifyNotEmpty(view, 'I\'m so secret', 'Passwerd');
|
182
|
+
pane.verifyDisabled(view, NO);
|
183
|
+
});
|
184
|
+
|
185
|
+
test("disabled - empty", function () {
|
186
|
+
var view = pane.view('disabled - empty');
|
187
|
+
pane.verifyEmpty(view, 'Full Name');
|
188
|
+
pane.verifyDisabled(view, YES);
|
189
|
+
});
|
190
|
+
|
191
|
+
test("disabled - with value", function () {
|
192
|
+
var view = pane.view('disabled - with value');
|
193
|
+
pane.verifyNotEmpty(view, 'John Doe', 'Full Name');
|
194
|
+
pane.verifyDisabled(view, YES);
|
195
|
+
});
|
196
|
+
|
197
|
+
test("enabled - not editable - with value", function () {
|
198
|
+
var view = pane.view('enabled - not editable - with value');
|
199
|
+
pane.verifyNotEmpty(view, 'John Doe', 'Full Name');
|
200
|
+
pane.verifyReadOnly(view, YES);
|
201
|
+
});
|
202
|
+
|
203
|
+
test("textarea - empty", function () {
|
204
|
+
var view = pane.view('empty');
|
205
|
+
pane.verifyEmpty(view, 'Full Name');
|
206
|
+
pane.verifyDisabled(view, NO);
|
207
|
+
});
|
208
|
+
|
209
|
+
test("textarea - with value", function () {
|
210
|
+
var view = pane.view('with value');
|
211
|
+
pane.verifyNotEmpty(view, 'John Doe', 'Full Name');
|
212
|
+
pane.verifyDisabled(view, NO);
|
213
|
+
});
|
214
|
+
|
215
|
+
test("textarea - disabled - empty", function () {
|
216
|
+
var view = pane.view('disabled - empty');
|
217
|
+
pane.verifyEmpty(view, 'Full Name');
|
218
|
+
pane.verifyDisabled(view, YES);
|
219
|
+
});
|
220
|
+
|
221
|
+
test("textarea - disabled - with value", function () {
|
222
|
+
var view = pane.view('disabled - with value');
|
223
|
+
pane.verifyNotEmpty(view, 'John Doe', 'Full Name');
|
224
|
+
pane.verifyDisabled(view, YES);
|
225
|
+
});
|
226
|
+
|
227
|
+
// ..........................................................
|
228
|
+
// TEST CHANGING VIEWS
|
229
|
+
//
|
230
|
+
|
231
|
+
module('SC.TextFieldView: Changing Values', pane.standardSetup());
|
232
|
+
|
233
|
+
test("changing value from empty -> value", function () {
|
234
|
+
var view = pane.view('empty');
|
235
|
+
|
236
|
+
// test changing value updates like it should
|
237
|
+
SC.run(function () {
|
238
|
+
view.set('value', 'John Doe');
|
239
|
+
});
|
240
|
+
pane.verifyNotEmpty(view, 'John Doe', 'Full Name');
|
241
|
+
});
|
242
|
+
|
243
|
+
test("disabling view", function () {
|
244
|
+
var view = pane.view('empty');
|
245
|
+
|
246
|
+
// test changing enabled state updates like it should
|
247
|
+
SC.run(function () {
|
248
|
+
view.set('isEnabled', NO);
|
249
|
+
});
|
250
|
+
pane.verifyDisabled(view, YES);
|
251
|
+
});
|
252
|
+
|
253
|
+
test("changing value to null", function () {
|
254
|
+
var view = pane.view('with value');
|
255
|
+
|
256
|
+
// test changing value updates like it should
|
257
|
+
SC.run(function () {
|
324
258
|
view.set('value', null);
|
325
259
|
});
|
260
|
+
equals(view.get('fieldValue'), null, 'should have empty fieldValue');
|
261
|
+
pane.verifyEmpty(view, 'Full Name');
|
262
|
+
});
|
263
|
+
|
264
|
+
test("enabling disabled view", function () {
|
265
|
+
var view = pane.view('disabled - empty');
|
326
266
|
|
327
|
-
|
328
|
-
|
267
|
+
// test changing enabled state updates like it should
|
268
|
+
SC.run(function () {
|
269
|
+
view.set('isEnabled', YES);
|
270
|
+
});
|
271
|
+
pane.verifyDisabled(view, NO);
|
329
272
|
});
|
330
|
-
}
|
331
273
|
|
332
|
-
|
333
|
-
|
334
|
-
//
|
274
|
+
test("changing isEditable", function () {
|
275
|
+
var view = pane.view('enabled - not editable - with value');
|
335
276
|
|
336
|
-
test
|
337
|
-
|
338
|
-
|
339
|
-
|
277
|
+
// test changing isEditable state updates like it should
|
278
|
+
SC.run(function () {
|
279
|
+
view.set('isEditable', YES);
|
280
|
+
});
|
281
|
+
pane.verifyReadOnly(view, NO);
|
340
282
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
}
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
283
|
+
// test changing isEditable state updates like it should
|
284
|
+
SC.run(function () {
|
285
|
+
view.set('isEditable', NO);
|
286
|
+
});
|
287
|
+
pane.verifyReadOnly(view, YES);
|
288
|
+
});
|
289
|
+
|
290
|
+
test("changing value from not a textarea to a textarea", function () {
|
291
|
+
// test the the SC.Event for 'change' gets wired up properly to the DOM element when it changes from input to textarea
|
292
|
+
var view = pane.view('empty');
|
293
|
+
SC.run(function () {
|
294
|
+
view.set('value', 'Original');
|
295
|
+
view.set('isTextArea', YES);
|
296
|
+
});
|
297
|
+
|
298
|
+
var $textarea = view.$('textarea');
|
299
|
+
|
300
|
+
SC.Event.trigger($textarea, 'focus');
|
301
|
+
|
302
|
+
// simulate typing a letter
|
303
|
+
SC.Event.trigger($textarea, 'keydown');
|
304
|
+
$textarea.val("My New Value");
|
305
|
+
SC.Event.trigger($textarea, 'keyup');
|
306
|
+
SC.Event.trigger($textarea, 'change');
|
307
|
+
SC.run(function () {
|
308
|
+
view.fieldValueDidChange();
|
309
|
+
});
|
310
|
+
|
311
|
+
// wait a little bit to let text field propogate changes
|
312
|
+
stop();
|
313
|
+
|
314
|
+
setTimeout(function () {
|
315
|
+
start();
|
316
|
+
equals(view.get("value"), "My New Value", "SC.Event for change should get wired up properly");
|
317
|
+
}, 100);
|
318
|
+
|
319
|
+
SC.run(function () {
|
320
|
+
});
|
321
|
+
});
|
322
|
+
|
323
|
+
/**
|
324
|
+
There was a bug that when a text field view has a value before it is appended,
|
325
|
+
the hint line-height gets set to 0px. So if the value is removed, the hint is
|
326
|
+
in the wrong spot.
|
327
|
+
*/
|
328
|
+
test("When a manual hint is visible, the line-height of the hint should be correct", function () {
|
329
|
+
var view1 = pane.view('empty'),
|
330
|
+
view2 = pane.view('with value'),
|
331
|
+
hint = view1.$('.hint');
|
332
|
+
|
333
|
+
equals(hint.css('line-height'), "14px", "The line-height of the hint of an empty text field should be");
|
334
|
+
|
335
|
+
SC.run(function () {
|
336
|
+
view2.set('value', null);
|
337
|
+
});
|
338
|
+
|
339
|
+
hint = view2.$('.hint');
|
340
|
+
equals(hint.css('line-height'), "14px", "The line-height of the hint of a non-empty text field should be");
|
341
|
+
});
|
342
|
+
|
343
|
+
|
344
|
+
if (!SC.browser.isIE && !SC.platform.input.placeholder) {
|
345
|
+
test("Changing value to null -- password field", function () {
|
346
|
+
var view = pane.view('password-hint'),
|
347
|
+
input = view.$('input');
|
348
|
+
|
349
|
+
SC.run(function () {
|
350
|
+
view.set('value', null);
|
351
|
+
});
|
352
|
+
|
353
|
+
equals(input.attr('type'), 'text', "When nulled out, field was converted to type text");
|
354
|
+
equals(input.val(), view.get('hint'), "When nulled out, field was given value equal to hint");
|
355
|
+
});
|
367
356
|
}
|
368
|
-
});
|
369
|
-
|
370
|
-
test("Setting and then getting back the selection", function() {
|
371
|
-
var view = pane.view('with value');
|
372
|
-
var fieldElement = view.$input()[0];
|
373
|
-
fieldElement.focus();
|
374
|
-
fieldElement.size = 10; // Avoid Firefox 3.5 issue
|
375
|
-
|
376
|
-
var newSelection = SC.TextSelection.create({start:2, end:5});
|
377
|
-
view.set('selection', newSelection);
|
378
357
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
// ..........................................................
|
386
|
-
// TEST ACCESSORY VIEWS
|
387
|
-
//
|
388
|
-
|
389
|
-
test("Adding left accessory view", function() {
|
390
|
-
var view = pane.view('with value');
|
391
|
-
|
392
|
-
// test adding accessory view adds the view like it should
|
393
|
-
SC.RunLoop.begin();
|
394
|
-
var accessoryView = SC.View.create({
|
395
|
-
layout: { top:1, left:2, width:16, height:16 }
|
396
|
-
});
|
397
|
-
view.set('leftAccessoryView', accessoryView);
|
398
|
-
SC.RunLoop.end();
|
399
|
-
|
400
|
-
ok(view.get('leftAccessoryView') === accessoryView, 'left accessory view should be set to ' + accessoryView.toString());
|
401
|
-
ok(view.get('childViews').length === 1, 'there should only be one child view');
|
402
|
-
ok(view.get('childViews')[0] === accessoryView, 'first child view should be set to ' + accessoryView.toString());
|
403
|
-
|
404
|
-
|
405
|
-
// The hint and padding elements should automatically have their 'left'
|
406
|
-
// values set to the accessory view's offset + width
|
407
|
-
// (18 = 2 left offset + 16 width)
|
408
|
-
var paddingElement = view.$('.padding')[0];
|
409
|
-
ok(paddingElement.style.left === '18px', 'padding element should get 18px left');
|
410
|
-
|
411
|
-
// Test removing the accessory view.
|
412
|
-
SC.RunLoop.begin();
|
413
|
-
view.set('leftAccessoryView', null);
|
414
|
-
SC.RunLoop.end();
|
415
|
-
ok(view.get('childViews').length === 0, 'after removing the left accessory view there should be no child views left');
|
416
|
-
ok(!paddingElement.style.left, 'after removing the left accessory view the padding element should have no left style');
|
417
|
-
});
|
418
|
-
|
419
|
-
test("Adding left accessory view changes style -- using design()", function() {
|
420
|
-
var view = pane.view('with value');
|
421
|
-
|
422
|
-
// test adding accessory view adds the view like it should
|
423
|
-
SC.RunLoop.begin();
|
424
|
-
var accessoryView = SC.View.design({
|
425
|
-
layout: { top:1, left:2, width:16, height:16 }
|
426
|
-
});
|
427
|
-
view.set('leftAccessoryView', accessoryView);
|
428
|
-
SC.RunLoop.end();
|
358
|
+
// ..........................................................
|
359
|
+
// TEST SELECTION SUPPORT
|
360
|
+
//
|
361
|
+
|
362
|
+
|
363
|
+
module('SC.TextFieldView: Selection Support', pane.standardSetup());
|
429
364
|
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
ok(paddingElement.style.left === '18px', 'padding element should get 18px left');
|
435
|
-
|
436
|
-
// Test removing the accessory view.
|
437
|
-
SC.RunLoop.begin();
|
438
|
-
view.set('leftAccessoryView', null);
|
439
|
-
SC.RunLoop.end();
|
440
|
-
ok(!paddingElement.style.left, 'after removing the left accessory view the padding element should have no left style');
|
441
|
-
});
|
365
|
+
test("Setting the selection to a null value should fail", function () {
|
366
|
+
var view = pane.view('with value');
|
367
|
+
var fieldElement = view.$input()[0];
|
368
|
+
fieldElement.size = 10; // Avoid Firefox 3.5 issue
|
442
369
|
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
SC.RunLoop.end();
|
453
|
-
|
454
|
-
ok(view.get('rightAccessoryView') === accessoryView, 'right accessory view should be set to ' + accessoryView.toString());
|
455
|
-
ok(view.get('childViews').length === 1, 'there should only be one child view');
|
456
|
-
ok(view.get('childViews')[0] === accessoryView, 'first child view should be set to ' + accessoryView.toString());
|
457
|
-
|
458
|
-
|
459
|
-
// The hint and padding elements should automatically have their 'right'
|
460
|
-
// values set to the accessory view's offset + width
|
461
|
-
// (20 = 3 right offset + 17 width)
|
462
|
-
var paddingElement = view.$('.padding')[0];
|
463
|
-
ok(paddingElement.style.right === '20px', 'padding element should get 20px right');
|
464
|
-
|
465
|
-
|
466
|
-
// If a right accessory view is set with only 'left' (and not 'right')
|
467
|
-
// defined in its layout, 'left' should be cleared out and 'right' should
|
468
|
-
// be set to 0.
|
469
|
-
SC.RunLoop.begin();
|
470
|
-
accessoryView = SC.View.create({
|
471
|
-
layout: { top:1, left:2, width:16, height:16 }
|
472
|
-
});
|
473
|
-
view.set('rightAccessoryView', accessoryView);
|
474
|
-
SC.RunLoop.end();
|
475
|
-
|
476
|
-
ok( SC.none(view.get('rightAccessoryView').get('layout').left), "right accessory view created with 'left' rather than 'right' in layout should not have a value for layout.left");
|
477
|
-
ok(view.get('rightAccessoryView').get('layout').right === 0, "right accessory view created with 'left' rather than 'right' in layout should have layout.right set to 0");
|
478
|
-
|
479
|
-
|
480
|
-
// Test removing the accessory view.
|
481
|
-
SC.RunLoop.begin();
|
482
|
-
view.set('rightAccessoryView', null);
|
483
|
-
SC.RunLoop.end();
|
484
|
-
ok(view.get('childViews').length === 0, 'after removing the right accessory view there should be no child views left');
|
485
|
-
ok(!paddingElement.style.right, 'after removing the right accessory view the padding element should have no right style');
|
486
|
-
});
|
487
|
-
|
488
|
-
test("Adding right accessory view changes style -- using design()", function() {
|
489
|
-
var view = pane.view('with value');
|
490
|
-
|
491
|
-
// test adding accessory view adds the view like it should
|
492
|
-
SC.RunLoop.begin();
|
493
|
-
var accessoryView = SC.View.design({
|
494
|
-
layout: { top:1, right:3, width:17, height:16 }
|
495
|
-
});
|
496
|
-
view.set('rightAccessoryView', accessoryView);
|
497
|
-
SC.RunLoop.end();
|
498
|
-
|
499
|
-
// The hint and padding elements should automatically have their 'right'
|
500
|
-
// values set to the accessory view's offset + width
|
501
|
-
// (20 = 3 right offset + 17 width)
|
502
|
-
var paddingElement = view.$('.padding')[0];
|
503
|
-
ok(paddingElement.style.right === '20px', 'padding element should get 20px right');
|
504
|
-
|
505
|
-
// Test removing the accessory view.
|
506
|
-
SC.RunLoop.begin();
|
507
|
-
view.set('rightAccessoryView', null);
|
508
|
-
SC.RunLoop.end();
|
509
|
-
ok(!paddingElement.style.right, 'after removing the right accessory view the padding element should have no right style');
|
510
|
-
});
|
511
|
-
|
512
|
-
|
513
|
-
test("Adding both left and right accessory views", function() {
|
514
|
-
var view = pane.view('with value');
|
515
|
-
|
516
|
-
// test adding accessory view adds the view like it should
|
517
|
-
SC.RunLoop.begin();
|
518
|
-
var leftAccessoryView = SC.View.create({
|
519
|
-
layout: { top:1, left:2, width:16, height:16 }
|
520
|
-
});
|
521
|
-
view.set('leftAccessoryView', leftAccessoryView);
|
522
|
-
var rightAccessoryView = SC.View.create({
|
523
|
-
layout: { top:1, right:3, width:17, height:16 }
|
524
|
-
});
|
525
|
-
view.set('rightAccessoryView', rightAccessoryView);
|
526
|
-
SC.RunLoop.end();
|
527
|
-
|
528
|
-
ok(view.get('childViews').length === 2, 'we should have two child views since we added both a left and a right accessory view');
|
529
|
-
|
530
|
-
|
531
|
-
// The hint and padding elements should automatically have their 'left' and
|
532
|
-
// 'right' values set to the accessory views' offset + width
|
533
|
-
// * left: 18 = 2 left offset + 16 width)
|
534
|
-
// * right: 20 = 3 left offset + 17 width)
|
535
|
-
var paddingElement = view.$('.padding')[0];
|
536
|
-
ok(paddingElement.style.left === '18px', 'padding element should get 18px left');
|
537
|
-
ok(paddingElement.style.right === '20px', 'padding element should get 20px right');
|
538
|
-
|
539
|
-
|
540
|
-
// Test removing the accessory views.
|
541
|
-
SC.RunLoop.begin();
|
542
|
-
view.set('rightAccessoryView', null);
|
543
|
-
SC.RunLoop.end();
|
544
|
-
ok(view.get('childViews').length === 1, 'after removing the right accessory view there should be one child view left (the left accessory view)');
|
545
|
-
ok(!paddingElement.style.right, 'after removing the right accessory view the padding element should have no right style');
|
546
|
-
SC.RunLoop.begin();
|
547
|
-
view.set('leftAccessoryView', null);
|
548
|
-
SC.RunLoop.end();
|
549
|
-
ok(view.get('childViews').length === 0, 'after removing both accessory views there should be no child views left');
|
550
|
-
ok(!paddingElement.style.left, 'after removing the left accessory view the padding element should have no left style');
|
551
|
-
});
|
552
|
-
|
553
|
-
test("Adding both left and right accessory views changes style -- using design()", function() {
|
554
|
-
var view = pane.view('with value');
|
555
|
-
|
556
|
-
// test adding accessory view adds the view like it should
|
557
|
-
SC.RunLoop.begin();
|
558
|
-
var leftAccessoryView = SC.View.design({
|
559
|
-
layout: { top:1, left:2, width:16, height:16 }
|
560
|
-
});
|
561
|
-
view.set('leftAccessoryView', leftAccessoryView);
|
562
|
-
var rightAccessoryView = SC.View.design({
|
563
|
-
layout: { top:1, right:3, width:17, height:16 }
|
564
|
-
});
|
565
|
-
view.set('rightAccessoryView', rightAccessoryView);
|
566
|
-
SC.RunLoop.end();
|
567
|
-
|
568
|
-
// The hint and padding elements should automatically have their 'left' and
|
569
|
-
// 'right' values set to the accessory views' offset + width
|
570
|
-
// * left: 18 = 2 left offset + 16 width)
|
571
|
-
// * right: 20 = 3 left offset + 17 width)
|
572
|
-
var paddingElement = view.$('.padding')[0];
|
573
|
-
ok(paddingElement.style.left === '18px', 'padding element should get 18px left');
|
574
|
-
ok(paddingElement.style.right === '20px', 'padding element should get 20px right');
|
575
|
-
|
576
|
-
|
577
|
-
// Test removing the accessory views.
|
578
|
-
SC.RunLoop.begin();
|
579
|
-
view.set('rightAccessoryView', null);
|
580
|
-
SC.RunLoop.end();
|
581
|
-
ok(!paddingElement.style.right, 'after removing the right accessory view the padding element should have no right style');
|
582
|
-
SC.RunLoop.begin();
|
583
|
-
view.set('leftAccessoryView', null);
|
584
|
-
SC.RunLoop.end();
|
585
|
-
ok(!paddingElement.style.left, 'after removing the left accessory view the padding element should have no left style');
|
586
|
-
});
|
587
|
-
|
588
|
-
test("Accessory views should only be instantiated once", function() {
|
589
|
-
var view = pane.view('with value');
|
590
|
-
|
591
|
-
// Test the left accessory view
|
592
|
-
SC.RunLoop.begin();
|
593
|
-
var leftAccessoryViewInitCount = 0;
|
594
|
-
var leftAccessoryView = SC.View.design({
|
595
|
-
layout: { top:1, left:2, width:16, height:16 },
|
596
|
-
init: function() {
|
597
|
-
sc_super();
|
598
|
-
leftAccessoryViewInitCount++;
|
599
|
-
}
|
600
|
-
});
|
601
|
-
view.set('leftAccessoryView', leftAccessoryView);
|
602
|
-
SC.RunLoop.end();
|
603
|
-
|
604
|
-
// Check it
|
605
|
-
equals(leftAccessoryViewInitCount, 1, 'the left accessory view should only be initialized once');
|
606
|
-
|
607
|
-
// Reset to null so it isn't created a second time when rightAccessoryView is set
|
608
|
-
view.set('leftAccessoryView', null);
|
609
|
-
|
610
|
-
// Test the right accessory view
|
611
|
-
SC.RunLoop.begin();
|
612
|
-
var rightAccessoryViewInitCount = 0;
|
613
|
-
var rightAccessoryView = SC.View.design({
|
614
|
-
layout: { top:1, right:3, width:17, height:16 },
|
615
|
-
init: function() {
|
616
|
-
sc_super();
|
617
|
-
rightAccessoryViewInitCount++;
|
370
|
+
var thrownException = null;
|
371
|
+
try {
|
372
|
+
view.set('selection', null);
|
373
|
+
} catch (e) {
|
374
|
+
thrownException = e.message;
|
375
|
+
}
|
376
|
+
ok(thrownException.indexOf !== undefined, 'an exception should have been thrown');
|
377
|
+
if (thrownException.indexOf !== undefined) {
|
378
|
+
ok(thrownException.indexOf('must specify an SC.TextSelection instance') !== -1, 'the exception should be about not specifying an SC.TextSelection instance');
|
618
379
|
}
|
619
380
|
});
|
620
|
-
view.set('rightAccessoryView', rightAccessoryView);
|
621
|
-
SC.RunLoop.end();
|
622
381
|
|
623
|
-
|
624
|
-
|
625
|
-
|
382
|
+
test("Setting the selection to a non-SC.TextSelection value should fail", function () {
|
383
|
+
var view = pane.view('with value');
|
384
|
+
var fieldElement = view.$input()[0];
|
385
|
+
fieldElement.size = 10; // Avoid Firefox 3.5 issue
|
626
386
|
|
387
|
+
var thrownException = null;
|
388
|
+
try {
|
389
|
+
view.set('selection', {start: 0, end: 0});
|
390
|
+
} catch (e) {
|
391
|
+
thrownException = e.message;
|
392
|
+
}
|
393
|
+
ok(thrownException.indexOf !== undefined, 'an exception should have been thrown');
|
394
|
+
if (thrownException.indexOf !== undefined) {
|
395
|
+
ok(thrownException.indexOf('must specify an SC.TextSelection instance') !== -1, 'the exception should be about not specifying an SC.TextSelection instance');
|
396
|
+
}
|
397
|
+
});
|
627
398
|
|
628
|
-
|
629
|
-
|
630
|
-
|
399
|
+
test("Setting and then getting back the selection", function () {
|
400
|
+
var view = pane.view('with value');
|
401
|
+
var fieldElement = view.$input()[0];
|
402
|
+
fieldElement.focus();
|
403
|
+
fieldElement.size = 10; // Avoid Firefox 3.5 issue
|
631
404
|
|
632
|
-
|
633
|
-
|
634
|
-
var input = view.$('input');
|
405
|
+
var newSelection = SC.TextSelection.create({start: 2, end: 5});
|
406
|
+
view.set('selection', newSelection);
|
635
407
|
|
636
|
-
|
637
|
-
|
408
|
+
var fetchedSelection = view.get('selection');
|
409
|
+
ok(fetchedSelection.get('start') === 2, 'the selection should start at index 2');
|
410
|
+
ok(fetchedSelection.get('end') === 5, 'the selection should end at index 4');
|
411
|
+
ok(fetchedSelection.get('length') === 3, 'the selection should have length 3');
|
412
|
+
});
|
638
413
|
|
639
|
-
// verify editing state changed...
|
640
|
-
ok(view.get('isEditing'), 'view.isEditing should be YES');
|
641
|
-
ok(view.$().hasClass('focus'), 'view layer should have focus class');
|
642
414
|
|
643
|
-
// simulate typing a letter
|
644
|
-
SC.Event.trigger(input, 'keydown');
|
645
|
-
SC.Event.trigger(input, 'keyup');
|
646
|
-
input.val('f');
|
647
|
-
SC.Event.trigger(input, 'change');
|
648
415
|
|
649
|
-
//
|
650
|
-
|
416
|
+
// ..........................................................
|
417
|
+
// TEST ACCESSORY VIEWS
|
418
|
+
//
|
651
419
|
|
652
|
-
|
653
|
-
start();
|
420
|
+
module('SC.TextFieldView: Accessory Views', pane.standardSetup());
|
654
421
|
|
655
|
-
|
656
|
-
|
422
|
+
test("Adding left accessory view", function () {
|
423
|
+
var view = pane.view('with value'),
|
424
|
+
accessoryView;
|
425
|
+
|
426
|
+
// test adding accessory view adds the view like it should
|
427
|
+
SC.run(function () {
|
428
|
+
accessoryView = SC.View.create({
|
429
|
+
layout: { top: 1, left: 2, width: 16, height: 16 }
|
430
|
+
});
|
431
|
+
view.set('leftAccessoryView', accessoryView);
|
432
|
+
});
|
433
|
+
|
434
|
+
ok(view.get('leftAccessoryView') === accessoryView, 'left accessory view should be set to ' + accessoryView.toString());
|
435
|
+
ok(view.get('childViews').length === 1, 'there should only be one child view');
|
436
|
+
ok(view.get('childViews')[0] === accessoryView, 'first child view should be set to ' + accessoryView.toString());
|
657
437
|
|
658
|
-
|
659
|
-
|
438
|
+
|
439
|
+
// The hint and padding elements should automatically have their 'left'
|
440
|
+
// values set to the accessory view's offset + width
|
441
|
+
// (18 = 2 left offset + 16 width)
|
442
|
+
var paddingElement = view.$('.padding')[0];
|
443
|
+
ok(paddingElement.style.left === '18px', 'padding element should get 18px left');
|
444
|
+
|
445
|
+
// Test removing the accessory view.
|
446
|
+
SC.run(function () {
|
447
|
+
view.set('leftAccessoryView', null);
|
448
|
+
});
|
449
|
+
ok(view.get('childViews').length === 0, 'after removing the left accessory view there should be no child views left');
|
450
|
+
ok(!paddingElement.style.left, 'after removing the left accessory view the padding element should have no left style');
|
451
|
+
});
|
452
|
+
|
453
|
+
test("Adding left accessory view changes style -- using design()", function () {
|
454
|
+
var view = pane.view('with value');
|
455
|
+
|
456
|
+
// test adding accessory view adds the view like it should
|
457
|
+
SC.run(function () {
|
458
|
+
var accessoryView = SC.View.design({
|
459
|
+
layout: { top: 1, left: 2, width: 16, height: 16 }
|
460
|
+
});
|
461
|
+
view.set('leftAccessoryView', accessoryView);
|
462
|
+
});
|
463
|
+
|
464
|
+
// The hint and padding elements should automatically have their 'left'
|
465
|
+
// values set to the accessory view's offset + width
|
466
|
+
// (18 = 2 left offset + 16 width)
|
467
|
+
var paddingElement = view.$('.padding')[0];
|
468
|
+
ok(paddingElement.style.left === '18px', 'padding element should get 18px left');
|
469
|
+
|
470
|
+
// Test removing the accessory view.
|
471
|
+
SC.run(function () {
|
472
|
+
view.set('leftAccessoryView', null);
|
473
|
+
});
|
474
|
+
ok(!paddingElement.style.left, 'after removing the left accessory view the padding element should have no left style');
|
475
|
+
});
|
476
|
+
|
477
|
+
test("Adding right accessory view", function () {
|
478
|
+
var view = pane.view('with value'),
|
479
|
+
accessoryView;
|
480
|
+
|
481
|
+
// test adding accessory view adds the view like it should
|
482
|
+
SC.run(function () {
|
483
|
+
accessoryView = SC.View.create({
|
484
|
+
layout: { top: 1, right: 3, width: 17, height: 16 }
|
485
|
+
});
|
486
|
+
view.set('rightAccessoryView', accessoryView);
|
487
|
+
});
|
488
|
+
|
489
|
+
ok(view.get('rightAccessoryView') === accessoryView, 'right accessory view should be set to ' + accessoryView.toString());
|
490
|
+
ok(view.get('childViews').length === 1, 'there should only be one child view');
|
491
|
+
ok(view.get('childViews')[0] === accessoryView, 'first child view should be set to ' + accessoryView.toString());
|
492
|
+
|
493
|
+
|
494
|
+
// The hint and padding elements should automatically have their 'right'
|
495
|
+
// values set to the accessory view's offset + width
|
496
|
+
// (20 = 3 right offset + 17 width)
|
497
|
+
var paddingElement = view.$('.padding')[0];
|
498
|
+
ok(paddingElement.style.right === '20px', 'padding element should get 20px right');
|
499
|
+
|
500
|
+
|
501
|
+
// If a right accessory view is set with only 'left' (and not 'right')
|
502
|
+
// defined in its layout, 'left' should be cleared out and 'right' should
|
503
|
+
// be set to 0.
|
504
|
+
SC.run(function () {
|
505
|
+
accessoryView = SC.View.create({
|
506
|
+
layout: { top: 1, left: 2, width: 16, height: 16 }
|
507
|
+
});
|
508
|
+
view.set('rightAccessoryView', accessoryView);
|
509
|
+
});
|
510
|
+
|
511
|
+
ok(SC.none(view.get('rightAccessoryView').get('layout').left), "right accessory view created with 'left' rather than 'right' in layout should not have a value for layout.left");
|
512
|
+
ok(view.get('rightAccessoryView').get('layout').right === 0, "right accessory view created with 'left' rather than 'right' in layout should have layout.right set to 0");
|
513
|
+
|
514
|
+
|
515
|
+
// Test removing the accessory view.
|
516
|
+
SC.run(function () {
|
517
|
+
view.set('rightAccessoryView', null);
|
518
|
+
});
|
519
|
+
ok(view.get('childViews').length === 0, 'after removing the right accessory view there should be no child views left');
|
520
|
+
ok(!paddingElement.style.right, 'after removing the right accessory view the padding element should have no right style');
|
521
|
+
});
|
522
|
+
|
523
|
+
test("Adding right accessory view changes style -- using design()", function () {
|
524
|
+
var view = pane.view('with value');
|
525
|
+
|
526
|
+
// test adding accessory view adds the view like it should
|
527
|
+
SC.run(function () {
|
528
|
+
var accessoryView = SC.View.design({
|
529
|
+
layout: { top: 1, right: 3, width: 17, height: 16 }
|
530
|
+
});
|
531
|
+
view.set('rightAccessoryView', accessoryView);
|
532
|
+
});
|
533
|
+
|
534
|
+
// The hint and padding elements should automatically have their 'right'
|
535
|
+
// values set to the accessory view's offset + width
|
536
|
+
// (20 = 3 right offset + 17 width)
|
537
|
+
var paddingElement = view.$('.padding')[0];
|
538
|
+
ok(paddingElement.style.right === '20px', 'padding element should get 20px right');
|
539
|
+
|
540
|
+
// Test removing the accessory view.
|
541
|
+
SC.run(function () {
|
542
|
+
view.set('rightAccessoryView', null);
|
543
|
+
});
|
544
|
+
ok(!paddingElement.style.right, 'after removing the right accessory view the padding element should have no right style');
|
545
|
+
});
|
546
|
+
|
547
|
+
|
548
|
+
test("Adding both left and right accessory views", function () {
|
549
|
+
var view = pane.view('with value');
|
550
|
+
|
551
|
+
// test adding accessory view adds the view like it should
|
552
|
+
SC.run(function () {
|
553
|
+
var leftAccessoryView = SC.View.create({
|
554
|
+
layout: { top: 1, left: 2, width: 16, height: 16 }
|
555
|
+
});
|
556
|
+
view.set('leftAccessoryView', leftAccessoryView);
|
557
|
+
var rightAccessoryView = SC.View.create({
|
558
|
+
layout: { top: 1, right: 3, width: 17, height: 16 }
|
559
|
+
});
|
560
|
+
view.set('rightAccessoryView', rightAccessoryView);
|
561
|
+
});
|
562
|
+
|
563
|
+
ok(view.get('childViews').length === 2, 'we should have two child views since we added both a left and a right accessory view');
|
564
|
+
|
565
|
+
|
566
|
+
// The hint and padding elements should automatically have their 'left' and
|
567
|
+
// 'right' values set to the accessory views' offset + width
|
568
|
+
// * left: 18 = 2 left offset + 16 width)
|
569
|
+
// * right: 20 = 3 left offset + 17 width)
|
570
|
+
var paddingElement = view.$('.padding')[0];
|
571
|
+
ok(paddingElement.style.left === '18px', 'padding element should get 18px left');
|
572
|
+
ok(paddingElement.style.right === '20px', 'padding element should get 20px right');
|
573
|
+
|
574
|
+
|
575
|
+
// Test removing the accessory views.
|
576
|
+
SC.run(function () {
|
577
|
+
view.set('rightAccessoryView', null);
|
578
|
+
});
|
579
|
+
ok(view.get('childViews').length === 1, 'after removing the right accessory view there should be one child view left (the left accessory view)');
|
580
|
+
ok(!paddingElement.style.right, 'after removing the right accessory view the padding element should have no right style');
|
581
|
+
SC.run(function () {
|
582
|
+
view.set('leftAccessoryView', null);
|
583
|
+
});
|
584
|
+
ok(view.get('childViews').length === 0, 'after removing both accessory views there should be no child views left');
|
585
|
+
ok(!paddingElement.style.left, 'after removing the left accessory view the padding element should have no left style');
|
586
|
+
});
|
587
|
+
|
588
|
+
test("Adding both left and right accessory views changes style -- using design()", function () {
|
589
|
+
var view = pane.view('with value');
|
590
|
+
|
591
|
+
// test adding accessory view adds the view like it should
|
592
|
+
SC.run(function () {
|
593
|
+
var leftAccessoryView = SC.View.design({
|
594
|
+
layout: { top: 1, left: 2, width: 16, height: 16 }
|
595
|
+
});
|
596
|
+
view.set('leftAccessoryView', leftAccessoryView);
|
597
|
+
var rightAccessoryView = SC.View.design({
|
598
|
+
layout: { top: 1, right: 3, width: 17, height: 16 }
|
599
|
+
});
|
600
|
+
view.set('rightAccessoryView', rightAccessoryView);
|
601
|
+
});
|
602
|
+
|
603
|
+
// The hint and padding elements should automatically have their 'left' and
|
604
|
+
// 'right' values set to the accessory views' offset + width
|
605
|
+
// * left: 18 = 2 left offset + 16 width)
|
606
|
+
// * right: 20 = 3 left offset + 17 width)
|
607
|
+
var paddingElement = view.$('.padding')[0];
|
608
|
+
ok(paddingElement.style.left === '18px', 'padding element should get 18px left');
|
609
|
+
ok(paddingElement.style.right === '20px', 'padding element should get 20px right');
|
610
|
+
|
611
|
+
|
612
|
+
// Test removing the accessory views.
|
613
|
+
SC.run(function () {
|
614
|
+
view.set('rightAccessoryView', null);
|
615
|
+
});
|
616
|
+
ok(!paddingElement.style.right, 'after removing the right accessory view the padding element should have no right style');
|
617
|
+
SC.run(function () {
|
618
|
+
view.set('leftAccessoryView', null);
|
619
|
+
});
|
620
|
+
ok(!paddingElement.style.left, 'after removing the left accessory view the padding element should have no left style');
|
621
|
+
});
|
622
|
+
|
623
|
+
test("Accessory views should only be instantiated once", function () {
|
624
|
+
var view = pane.view('with value');
|
625
|
+
var leftAccessoryViewInitCount = 0;
|
626
|
+
var rightAccessoryViewInitCount = 0;
|
627
|
+
|
628
|
+
// Test the left accessory view
|
629
|
+
SC.run(function () {
|
630
|
+
var leftAccessoryView = SC.View.design({
|
631
|
+
layout: { top: 1, left: 2, width: 16, height: 16 },
|
632
|
+
init: function () {
|
633
|
+
sc_super();
|
634
|
+
leftAccessoryViewInitCount++;
|
635
|
+
}
|
636
|
+
});
|
637
|
+
view.set('leftAccessoryView', leftAccessoryView);
|
638
|
+
});
|
639
|
+
|
640
|
+
// Check it
|
641
|
+
equals(leftAccessoryViewInitCount, 1, 'the left accessory view should only be initialized once');
|
642
|
+
|
643
|
+
// Reset to null so it isn't created a second time when rightAccessoryView is set
|
644
|
+
SC.run(function () {
|
645
|
+
view.set('leftAccessoryView', null);
|
646
|
+
});
|
647
|
+
|
648
|
+
// Test the right accessory view
|
649
|
+
SC.run(function () {
|
650
|
+
var rightAccessoryView = SC.View.design({
|
651
|
+
layout: { top: 1, right: 3, width: 17, height: 16 },
|
652
|
+
init: function () {
|
653
|
+
sc_super();
|
654
|
+
rightAccessoryViewInitCount++;
|
655
|
+
}
|
656
|
+
});
|
657
|
+
view.set('rightAccessoryView', rightAccessoryView);
|
658
|
+
});
|
659
|
+
|
660
|
+
// Check it
|
661
|
+
equals(rightAccessoryViewInitCount, 1, 'the right accessory view should only be initialized once');
|
662
|
+
});
|
663
|
+
|
664
|
+
|
665
|
+
// ..........................................................
|
666
|
+
// TEST EVENTS
|
667
|
+
//
|
668
|
+
|
669
|
+
module('SC.TextFieldView: Events', pane.standardSetup());
|
670
|
+
|
671
|
+
test("focus and blurring text field", function () {
|
672
|
+
var view = pane.view('empty');
|
673
|
+
var input = view.$('input');
|
674
|
+
|
675
|
+
// attempt to focus...
|
676
|
+
SC.Event.trigger(input, 'focus');
|
660
677
|
|
661
678
|
// verify editing state changed...
|
662
|
-
ok(
|
663
|
-
ok(
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
679
|
+
ok(view.get('isEditing'), 'view.isEditing should be YES');
|
680
|
+
ok(view.$().hasClass('focus'), 'view layer should have focus class');
|
681
|
+
|
682
|
+
// simulate typing a letter
|
683
|
+
SC.Event.trigger(input, 'keydown');
|
684
|
+
SC.Event.trigger(input, 'keyup');
|
685
|
+
input.val('f');
|
686
|
+
SC.Event.trigger(input, 'change');
|
687
|
+
|
688
|
+
// wait a little bit to let text field propagate changes
|
689
|
+
stop();
|
690
|
+
|
691
|
+
setTimeout(function () {
|
692
|
+
start();
|
693
|
+
|
694
|
+
equals(view.get('value'), 'f', 'view should have new value');
|
695
|
+
ok(view.$().hasClass('not-empty'), 'should have not-empty class');
|
696
|
+
|
697
|
+
// attempt to blur...
|
698
|
+
SC.Event.trigger(input, 'blur');
|
699
|
+
|
700
|
+
// verify editing state changed...
|
701
|
+
ok(!view.get('isEditing'), 'view.isEditing should be NO');
|
702
|
+
ok(!view.$().hasClass('focus'), 'view layer should NOT have focus class');
|
703
|
+
}, 100);
|
704
|
+
|
705
|
+
});
|
706
|
+
|
707
|
+
test("focus and blur an empty text field", function () {
|
708
|
+
var view = pane.view('empty');
|
709
|
+
var input = view.$('input');
|
710
|
+
|
711
|
+
// verify the field is empty and the hint is properly set
|
712
|
+
pane.verifyEmpty(view, 'Full Name');
|
713
|
+
|
714
|
+
// focus and blur the text field
|
715
|
+
SC.Event.trigger(input, 'focus');
|
716
|
+
SC.Event.trigger(input, 'blur');
|
717
|
+
|
718
|
+
// field should still be still be empty with hint properly set
|
719
|
+
pane.verifyEmpty(view, 'Full Name');
|
720
|
+
});
|
721
|
+
|
722
|
+
test("losing first responder should blur", function () {
|
723
|
+
var view = pane.view('empty');
|
724
|
+
var input = view.$('input');
|
725
|
+
var testResponder = SC.Responder.create(SC.ResponderContext, {});
|
726
|
+
|
727
|
+
// preliminary setup
|
728
|
+
view.get('pane').becomeKeyPane();
|
729
|
+
SC.Event.trigger(input, 'focus');
|
730
|
+
|
731
|
+
// verify it did receive focus
|
732
|
+
ok(view.get('focused'), 'view should have focus');
|
733
|
+
|
734
|
+
// tell the pane to make our test responder the first responder
|
735
|
+
view.get('pane').makeFirstResponder(testResponder);
|
736
|
+
|
737
|
+
// verify it no longer has focus
|
738
|
+
ok(!view.get('focused'), 'view should no longer have focus');
|
739
|
+
});
|
740
|
+
|
741
|
+
test("editing a field should not change the cursor position", function () {
|
742
|
+
var textField = pane.view('empty');
|
743
|
+
var input = textField.$('input');
|
744
|
+
input.val('John Doe');
|
745
|
+
textField.set('selection', SC.TextSelection.create({start: 2, end: 3}));
|
746
|
+
SC.Event.trigger(input, 'change');
|
747
|
+
|
748
|
+
ok(input.val() === 'John Doe', 'input value should be \'John Doe\'');
|
749
|
+
var selection = textField.get('selection');
|
750
|
+
ok(selection.get('start') == 2 && selection.get('end') == 3, 'cursor position should be unchanged');
|
751
|
+
});
|
714
752
|
|
715
753
|
})();
|