sproutcore 1.10.1 → 1.10.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -5,9 +5,9 @@
|
|
5
5
|
// License: Licensed under MIT license (see license.js)
|
6
6
|
// ==========================================================================
|
7
7
|
|
8
|
-
sc_require('views/field')
|
9
|
-
sc_require('system/text_selection')
|
10
|
-
sc_require('mixins/static_layout')
|
8
|
+
sc_require('views/field');
|
9
|
+
sc_require('system/text_selection');
|
10
|
+
sc_require('mixins/static_layout');
|
11
11
|
sc_require('mixins/editable');
|
12
12
|
|
13
13
|
SC.AUTOCAPITALIZE_NONE = 'none';
|
@@ -350,7 +350,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
350
350
|
|
351
351
|
init: function () {
|
352
352
|
var val = this.get('value');
|
353
|
-
this._hintON = ((!val || val && val.length===0) && !this.get('hintOnFocus')) ? YES : NO;
|
353
|
+
this._hintON = ((!val || val && val.length === 0) && !this.get('hintOnFocus')) ? YES : NO;
|
354
354
|
|
355
355
|
var continuouslyUpdatesValue = this.get('continouslyUpdatesValue');
|
356
356
|
if (continuouslyUpdatesValue !== null && continuouslyUpdatesValue !== undefined) {
|
@@ -398,62 +398,59 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
398
398
|
end = null;
|
399
399
|
|
400
400
|
if (!element.value) {
|
401
|
-
start = end = 0
|
402
|
-
}
|
403
|
-
else {
|
401
|
+
start = end = 0;
|
402
|
+
} else {
|
404
403
|
// In IE8, input elements don't have hasOwnProperty() defined.
|
405
404
|
try {
|
406
405
|
if ('selectionStart' in element) {
|
407
|
-
start = element.selectionStart
|
406
|
+
start = element.selectionStart;
|
408
407
|
}
|
409
408
|
if ('selectionEnd' in element) {
|
410
|
-
end = element.selectionEnd
|
409
|
+
end = element.selectionEnd;
|
411
410
|
}
|
412
411
|
}
|
413
412
|
// In Firefox when you ask the selectionStart or End of a hidden
|
414
413
|
// input, sometimes it throws a weird error.
|
415
414
|
// Adding this to just ignore it.
|
416
|
-
catch (e){
|
415
|
+
catch (e) {
|
417
416
|
return null;
|
418
417
|
}
|
419
418
|
|
420
419
|
// Support Internet Explorer.
|
421
|
-
if (start === null || end === null
|
422
|
-
var selection = document.selection
|
420
|
+
if (start === null || end === null) {
|
421
|
+
var selection = document.selection;
|
423
422
|
if (selection) {
|
424
|
-
var type = selection.type
|
423
|
+
var type = selection.type;
|
425
424
|
if (type && (type === 'None' || type === 'Text')) {
|
426
|
-
range = selection.createRange()
|
425
|
+
range = selection.createRange();
|
427
426
|
|
428
427
|
if (!this.get('isTextArea')) {
|
429
428
|
// Input tag support. Figure out the starting position by
|
430
429
|
// moving the range's start position as far left as possible
|
431
430
|
// and seeing how many characters it actually moved over.
|
432
|
-
var length = range.text.length
|
433
|
-
start = Math.abs(range.moveStart('character', 0 - (element.value.length + 1)))
|
434
|
-
end = start + length
|
435
|
-
}
|
436
|
-
else {
|
431
|
+
var length = range.text.length;
|
432
|
+
start = Math.abs(range.moveStart('character', 0 - (element.value.length + 1)));
|
433
|
+
end = start + length;
|
434
|
+
} else {
|
437
435
|
// Textarea support. Unfortunately, this case is a bit more
|
438
436
|
// complicated than the input tag case. We need to create a
|
439
437
|
// "dummy" range to help in the calculations.
|
440
|
-
var dummyRange = range.duplicate()
|
441
|
-
dummyRange.moveToElementText(element)
|
442
|
-
dummyRange.setEndPoint('EndToStart', range)
|
443
|
-
start = dummyRange.text.length
|
444
|
-
end = start + range.text.length
|
438
|
+
var dummyRange = range.duplicate();
|
439
|
+
dummyRange.moveToElementText(element);
|
440
|
+
dummyRange.setEndPoint('EndToStart', range);
|
441
|
+
start = dummyRange.text.length;
|
442
|
+
end = start + range.text.length;
|
445
443
|
}
|
446
444
|
}
|
447
445
|
}
|
448
446
|
}
|
449
447
|
}
|
450
|
-
|
451
|
-
|
452
|
-
else {
|
448
|
+
|
449
|
+
return SC.TextSelection.create({ start: start, end: end });
|
450
|
+
} else {
|
453
451
|
return null;
|
454
452
|
}
|
455
|
-
}
|
456
|
-
else {
|
453
|
+
} else {
|
457
454
|
// The client is setting the value. Make sure the new value is a text
|
458
455
|
// selection object.
|
459
456
|
if (!value || !value.kindOf || !value.kindOf(SC.TextSelection)) {
|
@@ -462,17 +459,17 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
462
459
|
|
463
460
|
if (element) {
|
464
461
|
if (element.setSelectionRange) {
|
465
|
-
element.setSelectionRange(value.get('start'), value.get('end'))
|
466
|
-
}
|
467
|
-
else {
|
462
|
+
element.setSelectionRange(value.get('start'), value.get('end'));
|
463
|
+
} else {
|
468
464
|
// Support Internet Explorer.
|
469
|
-
range = element.createTextRange()
|
470
|
-
start = value.get('start')
|
471
|
-
range.move('character', start)
|
472
|
-
range.moveEnd('character', value.get('end') - start)
|
473
|
-
range.select()
|
465
|
+
range = element.createTextRange();
|
466
|
+
start = value.get('start');
|
467
|
+
range.move('character', start);
|
468
|
+
range.moveEnd('character', value.get('end') - start);
|
469
|
+
range.select();
|
474
470
|
}
|
475
471
|
}
|
472
|
+
|
476
473
|
return value;
|
477
474
|
}
|
478
475
|
|
@@ -487,8 +484,11 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
487
484
|
// INTERNAL SUPPORT
|
488
485
|
//
|
489
486
|
|
490
|
-
// Note:
|
491
|
-
|
487
|
+
// Note: isEnabledInPane is required here because it is used in the renderMixin function of
|
488
|
+
// SC.Control. It is not a display property directly in SC.Control, because the use of it in
|
489
|
+
// SC.Control is only applied to input fields, which very few consumers of SC.Control have.
|
490
|
+
// TODO: Pull the disabled attribute updating out of SC.Control.
|
491
|
+
displayProperties: ['isBrowserFocusable', 'formattedHint', 'fieldValue', 'isEditing', 'isEditable', 'isEnabledInPane', 'leftAccessoryView', 'rightAccessoryView', 'isTextArea'],
|
492
492
|
|
493
493
|
createChildViews: function () {
|
494
494
|
sc_super();
|
@@ -502,29 +502,29 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
502
502
|
accessoryViewObserver: function () {
|
503
503
|
var classNames,
|
504
504
|
viewProperties = ['leftAccessoryView', 'rightAccessoryView'],
|
505
|
-
len = viewProperties.length
|
505
|
+
len = viewProperties.length, i, viewProperty, previousView,
|
506
506
|
accessoryView;
|
507
507
|
|
508
|
-
for (i=0; i<len; i++) {
|
508
|
+
for (i = 0; i < len; i++) {
|
509
509
|
viewProperty = viewProperties[i];
|
510
510
|
|
511
511
|
// Is there an accessory view specified?
|
512
|
-
previousView = this['_'+viewProperty]
|
513
|
-
accessoryView = this.get(viewProperty)
|
512
|
+
previousView = this['_' + viewProperty];
|
513
|
+
accessoryView = this.get(viewProperty);
|
514
514
|
|
515
515
|
// If the view is the same, there's nothing to do. Otherwise, remove
|
516
516
|
// the old one (if any) and add the new one.
|
517
517
|
if (! (previousView &&
|
518
518
|
accessoryView &&
|
519
|
-
(previousView === accessoryView)
|
519
|
+
(previousView === accessoryView))) {
|
520
520
|
|
521
521
|
// If there was a previous previous accessory view, remove it now.
|
522
522
|
if (previousView) {
|
523
523
|
// Remove the "sc-text-field-accessory-view" class name that we had
|
524
524
|
// added earlier.
|
525
|
-
classNames = previousView.get('classNames')
|
526
|
-
classNames = classNames.without('sc-text-field-accessory-view')
|
527
|
-
previousView.set('classNames', classNames)
|
525
|
+
classNames = previousView.get('classNames');
|
526
|
+
classNames = classNames.without('sc-text-field-accessory-view');
|
527
|
+
previousView.set('classNames', classNames);
|
528
528
|
|
529
529
|
if (previousView.createdByParent) {
|
530
530
|
this.removeChildAndDestroy(previousView);
|
@@ -533,7 +533,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
533
533
|
}
|
534
534
|
|
535
535
|
// Tidy up.
|
536
|
-
previousView = this['_'+viewProperty] = this['_created' + viewProperty] = null;
|
536
|
+
previousView = this['_' + viewProperty] = this['_created' + viewProperty] = null;
|
537
537
|
}
|
538
538
|
|
539
539
|
// If there's a new accessory view to add, do so now.
|
@@ -551,24 +551,23 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
551
551
|
|
552
552
|
// Add in the "sc-text-field-accessory-view" class name so that the
|
553
553
|
// z-index gets set correctly.
|
554
|
-
classNames = accessoryView.get('classNames')
|
555
|
-
var className = 'sc-text-field-accessory-view'
|
554
|
+
classNames = accessoryView.get('classNames');
|
555
|
+
var className = 'sc-text-field-accessory-view';
|
556
556
|
if (classNames.indexOf(className) < 0) {
|
557
557
|
classNames = SC.clone(classNames);
|
558
|
-
classNames.push(className)
|
558
|
+
classNames.push(className);
|
559
559
|
accessoryView.set('classNames', classNames);
|
560
560
|
}
|
561
561
|
|
562
562
|
// Actually add the view to our hierarchy and cache a reference.
|
563
|
-
this.appendChild(accessoryView)
|
564
|
-
this['_'+viewProperty] = accessoryView
|
563
|
+
this.appendChild(accessoryView);
|
564
|
+
this['_' + viewProperty] = accessoryView;
|
565
565
|
}
|
566
566
|
}
|
567
567
|
}
|
568
568
|
}.observes('leftAccessoryView', 'rightAccessoryView'),
|
569
569
|
|
570
570
|
render: function (context, firstTime) {
|
571
|
-
sc_super() ;
|
572
571
|
var v, accessoryViewWidths, leftAdjustment, rightAdjustment;
|
573
572
|
|
574
573
|
// always have at least an empty string
|
@@ -584,12 +583,12 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
584
583
|
// if we could add in the original padding, too, but there's no efficient
|
585
584
|
// way to do that without first rendering the element somewhere on/off-
|
586
585
|
// screen, and we don't want to take the performance hit.)
|
587
|
-
accessoryViewWidths = this._getAccessoryViewWidths()
|
588
|
-
leftAdjustment = accessoryViewWidths
|
589
|
-
rightAdjustment = accessoryViewWidths
|
586
|
+
accessoryViewWidths = this._getAccessoryViewWidths();
|
587
|
+
leftAdjustment = accessoryViewWidths.left;
|
588
|
+
rightAdjustment = accessoryViewWidths.right;
|
590
589
|
|
591
|
-
if (leftAdjustment) leftAdjustment += 'px'
|
592
|
-
if (rightAdjustment) rightAdjustment += 'px'
|
590
|
+
if (leftAdjustment) leftAdjustment += 'px';
|
591
|
+
if (rightAdjustment) rightAdjustment += 'px';
|
593
592
|
|
594
593
|
this._renderField(context, firstTime, v, leftAdjustment, rightAdjustment);
|
595
594
|
},
|
@@ -602,7 +601,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
602
601
|
_forceRenderFirstTime: NO,
|
603
602
|
|
604
603
|
/** @private */
|
605
|
-
_renderFieldLikeFirstTime: function (){
|
604
|
+
_renderFieldLikeFirstTime: function () {
|
606
605
|
this.set('_forceRenderFirstTime', YES);
|
607
606
|
}.observes('isTextArea'),
|
608
607
|
|
@@ -611,33 +610,33 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
611
610
|
// TODO: The cleanest thing might be to create a sub- rendering context
|
612
611
|
// here, but currently SC.RenderContext will render sibling
|
613
612
|
// contexts as parent/child.
|
614
|
-
|
615
613
|
var hint = this.get('formattedHint'),
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
614
|
+
hintOnFocus = this.get('hintOnFocus'),
|
615
|
+
hintString = '',
|
616
|
+
maxLength = this.get('maxLength'),
|
617
|
+
isTextArea = this.get('isTextArea'),
|
618
|
+
isEnabledInPane = this.get('isEnabledInPane'),
|
619
|
+
isEditable = this.get('isEditable'),
|
620
|
+
autoCorrect = this.get('autoCorrect'),
|
621
|
+
autoCapitalize = this.get('autoCapitalize'),
|
622
|
+
isBrowserFocusable = this.get('isBrowserFocusable'),
|
623
|
+
spellCheckString = '', autocapitalizeString = '', autocorrectString = '',
|
624
|
+
activeStateString = '', browserFocusableString = '',
|
625
|
+
name, adjustmentStyle, type, paddingElementStyle,
|
626
|
+
fieldClassNames, isOldSafari;
|
628
627
|
|
629
628
|
context.setClass('text-area', isTextArea);
|
630
629
|
|
631
630
|
//Adding this to differentiate between older and newer versions of safari
|
632
631
|
//since the internal default field padding changed
|
633
|
-
isOldSafari= SC.browser.isWebkit &&
|
634
|
-
SC.browser.compare(SC.browser.engineVersion, '532')<0;
|
632
|
+
isOldSafari = SC.browser.isWebkit &&
|
633
|
+
SC.browser.compare(SC.browser.engineVersion, '532') < 0;
|
635
634
|
context.setClass('oldWebKitFieldPadding', isOldSafari);
|
636
635
|
|
637
636
|
|
638
637
|
if (firstTime || this._forceRenderFirstTime) {
|
639
638
|
this._forceRenderFirstTime = NO;
|
640
|
-
|
639
|
+
activeStateString = isEnabledInPane ? (isEditable ? '' : ' readonly="readonly"') : ' disabled="disabled"';
|
641
640
|
name = this.get('layerId');
|
642
641
|
|
643
642
|
spellCheckString = this.get('spellCheckEnabled') ? ' spellcheck="true"' : ' spellcheck="false"';
|
@@ -655,10 +654,10 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
655
654
|
}
|
656
655
|
|
657
656
|
if (!isBrowserFocusable) {
|
658
|
-
|
657
|
+
browserFocusableString = ' tabindex="-1"';
|
659
658
|
}
|
660
659
|
|
661
|
-
|
660
|
+
// if hint is on and we don't want it to show on focus, create one
|
662
661
|
if (SC.platform.input.placeholder && !hintOnFocus) {
|
663
662
|
hintString = ' placeholder="' + hint + '"';
|
664
663
|
}
|
@@ -667,24 +666,24 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
667
666
|
|
668
667
|
// Render the padding element, with any necessary positioning
|
669
668
|
// adjustments to accommodate accessory views.
|
670
|
-
adjustmentStyle = ''
|
669
|
+
adjustmentStyle = '';
|
671
670
|
if (leftAdjustment || rightAdjustment) {
|
672
|
-
adjustmentStyle = 'style="'
|
673
|
-
if (leftAdjustment) adjustmentStyle += 'left:' + leftAdjustment + ';'
|
674
|
-
if (rightAdjustment) adjustmentStyle += 'right:' + rightAdjustment + ';'
|
675
|
-
adjustmentStyle += '"'
|
671
|
+
adjustmentStyle = 'style="';
|
672
|
+
if (leftAdjustment) adjustmentStyle += 'left:' + leftAdjustment + ';';
|
673
|
+
if (rightAdjustment) adjustmentStyle += 'right:' + rightAdjustment + ';';
|
674
|
+
adjustmentStyle += '"';
|
676
675
|
}
|
677
|
-
context.push('<div class="padding" '+adjustmentStyle+'>');
|
676
|
+
context.push('<div class="padding" ' + adjustmentStyle + '>');
|
678
677
|
|
679
678
|
value = this.get('escapeHTML') ? SC.RenderContext.escapeHTML(value) : value;
|
680
|
-
if (this._hintON && !SC.platform.input.placeholder && (!value || (value && value.length===0))) {
|
679
|
+
if (this._hintON && !SC.platform.input.placeholder && (!value || (value && value.length === 0))) {
|
681
680
|
value = hint;
|
682
681
|
context.setClass('sc-hint', YES);
|
683
682
|
}
|
684
683
|
|
685
684
|
if (hintOnFocus) {
|
686
|
-
var hintStr = '<div aria-hidden="true" class="hint '+
|
687
|
-
(isTextArea ? '':'ellipsis')+'%@">'+ hint + '</div>';
|
685
|
+
var hintStr = '<div aria-hidden="true" class="hint ' +
|
686
|
+
(isTextArea ? '':'ellipsis') + '%@">' + hint + '</div>';
|
688
687
|
context.push(hintStr.fmt(value ? ' sc-hidden': ''));
|
689
688
|
}
|
690
689
|
|
@@ -692,13 +691,12 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
692
691
|
|
693
692
|
// Render the input/textarea field itself, and close off the padding.
|
694
693
|
if (isTextArea) {
|
695
|
-
context.push('<textarea aria-label="' + hint + '"
|
696
|
-
'" '+
|
697
|
-
spellCheckString + autocorrectString +
|
698
|
-
|
699
|
-
value+ '</textarea></div>')
|
700
|
-
}
|
701
|
-
else {
|
694
|
+
context.push('<textarea aria-label="' + hint + '" class="' + fieldClassNames + '" aria-multiline="true"' +
|
695
|
+
'" name="' + name + '"' + activeStateString + hintString +
|
696
|
+
spellCheckString + autocorrectString + autocapitalizeString +
|
697
|
+
browserFocusableString + ' maxlength="' + maxLength +
|
698
|
+
'">' + value + '</textarea></div>');
|
699
|
+
} else {
|
702
700
|
type = this.get('type');
|
703
701
|
|
704
702
|
// Internet Explorer won't let us change the type attribute later
|
@@ -711,20 +709,19 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
711
709
|
type = 'password';
|
712
710
|
}
|
713
711
|
|
714
|
-
context.push('<input aria-label="' + hint + '" class="'+fieldClassNames+'" type="'+ type+
|
715
|
-
'" name="'+ name + '"
|
716
|
-
|
717
|
-
' maxlength="'+ maxLength
|
718
|
-
|
712
|
+
context.push('<input aria-label="' + hint + '" class="' + fieldClassNames + '" type="' + type +
|
713
|
+
'" name="' + name + '"' + activeStateString + hintString +
|
714
|
+
spellCheckString + autocorrectString + autocapitalizeString +
|
715
|
+
browserFocusableString + ' maxlength="' + maxLength +
|
716
|
+
'" value="' + value + '"' + '/></div>');
|
719
717
|
}
|
720
|
-
}
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
val = this.get('value');
|
718
|
+
} else {
|
719
|
+
var input = this.$input(),
|
720
|
+
element = input[0],
|
721
|
+
val = this.get('value');
|
725
722
|
|
726
|
-
if (hintOnFocus)
|
727
|
-
else if (!hintOnFocus)
|
723
|
+
if (hintOnFocus) context.$('.hint')[0].innerHTML = hint;
|
724
|
+
else if (!hintOnFocus) element.placeholder = hint;
|
728
725
|
|
729
726
|
// IE8 has problems aligning the input text in the center
|
730
727
|
// This is a workaround for centering it.
|
@@ -733,18 +730,17 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
733
730
|
}
|
734
731
|
|
735
732
|
if (!val || (val && val.length === 0)) {
|
736
|
-
if (this.get('isPassword')) {
|
733
|
+
if (this.get('isPassword')) { element.type = 'password'; }
|
737
734
|
|
738
735
|
if (!SC.platform.input.placeholder && this._hintON) {
|
739
736
|
if (!this.get('isFirstResponder')) {
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
input.val(hint);
|
737
|
+
// Internet Explorer doesn't allow you to modify the type afterwards
|
738
|
+
// jQuery throws an exception as well, so set attribute directly
|
739
|
+
context.setClass('sc-hint', YES);
|
740
|
+
input.val(hint);
|
745
741
|
} else {
|
746
|
-
|
747
|
-
|
742
|
+
// Internet Explorer doesn't allow you to modify the type afterwards
|
743
|
+
// jQuery throws an exception as well, so set attribute directly
|
748
744
|
context.setClass('sc-hint', NO);
|
749
745
|
input.val('');
|
750
746
|
}
|
@@ -774,38 +770,31 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
774
770
|
} else {
|
775
771
|
input.attr('tabindex', '-1');
|
776
772
|
}
|
773
|
+
|
777
774
|
// Enable/disable the actual input/textarea as appropriate.
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
} else if (!isEditable) {
|
784
|
-
element.disabled = null ;
|
785
|
-
element.readOnly = 'true' ;
|
786
|
-
} else {
|
787
|
-
element.disabled = null ;
|
788
|
-
element.readOnly = null ;
|
789
|
-
}
|
775
|
+
if (!isEditable) {
|
776
|
+
input.attr('readOnly', true);
|
777
|
+
} else {
|
778
|
+
input.attr('readOnly', null);
|
779
|
+
}
|
790
780
|
|
781
|
+
if (element) {
|
791
782
|
// Adjust the padding element to accommodate any accessory views.
|
792
783
|
paddingElementStyle = element.parentNode.style;
|
793
784
|
if (leftAdjustment) {
|
794
785
|
if (paddingElementStyle.left !== leftAdjustment) {
|
795
|
-
paddingElementStyle.left = leftAdjustment
|
786
|
+
paddingElementStyle.left = leftAdjustment;
|
796
787
|
}
|
797
|
-
}
|
798
|
-
|
799
|
-
paddingElementStyle.left = null ;
|
788
|
+
} else {
|
789
|
+
paddingElementStyle.left = null;
|
800
790
|
}
|
801
791
|
|
802
792
|
if (rightAdjustment) {
|
803
793
|
if (paddingElementStyle.right !== rightAdjustment) {
|
804
|
-
paddingElementStyle.right = rightAdjustment
|
794
|
+
paddingElementStyle.right = rightAdjustment;
|
805
795
|
}
|
806
|
-
}
|
807
|
-
|
808
|
-
paddingElementStyle.right = null ;
|
796
|
+
} else {
|
797
|
+
paddingElementStyle.right = null;
|
809
798
|
}
|
810
799
|
}
|
811
800
|
}
|
@@ -815,7 +804,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
815
804
|
var widths = {},
|
816
805
|
accessoryViewPositions = ['left', 'right'],
|
817
806
|
numberOfAccessoryViewPositions = accessoryViewPositions.length, i,
|
818
|
-
position, accessoryView,
|
807
|
+
position, accessoryView, width, layout, offset, frame;
|
819
808
|
for (i = 0; i < numberOfAccessoryViewPositions; i++) {
|
820
809
|
position = accessoryViewPositions[i];
|
821
810
|
accessoryView = this['_' + position + 'AccessoryView'];
|
@@ -842,16 +831,19 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
842
831
|
// HANDLE NATIVE CONTROL EVENTS
|
843
832
|
//
|
844
833
|
|
834
|
+
/**
|
835
|
+
Override of SC.FieldView.prototype.didCreateLayer.
|
836
|
+
*/
|
845
837
|
didCreateLayer: function () {
|
846
838
|
sc_super();
|
839
|
+
|
847
840
|
if (!SC.platform.input.placeholder) this.invokeLast(this._setInitialPlaceHolderIE);
|
848
841
|
// For some strange reason if we add focus/blur events to textarea
|
849
842
|
// inmediately they won't work. However if I add them at the end of the
|
850
843
|
// runLoop it works fine.
|
851
844
|
if (this.get('isTextArea')) {
|
852
845
|
this.invokeLast(this._addTextAreaEvents);
|
853
|
-
}
|
854
|
-
else {
|
846
|
+
} else {
|
855
847
|
this._addTextAreaEvents();
|
856
848
|
|
857
849
|
// In Firefox, for input fields only (that is, not textarea elements),
|
@@ -865,11 +857,15 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
865
857
|
SC.Event.add(input, 'keypress', this, this._firefox_dispatch_keypress);
|
866
858
|
}
|
867
859
|
}
|
860
|
+
},
|
868
861
|
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
862
|
+
/**
|
863
|
+
SC.View view state callback.
|
864
|
+
|
865
|
+
Once the view is appended, fix up the text layout to sc-hints and inputs.
|
866
|
+
*/
|
867
|
+
didAppendToDocument: function () {
|
868
|
+
this._fixupTextLayout();
|
873
869
|
},
|
874
870
|
|
875
871
|
/** @private
|
@@ -884,7 +880,9 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
884
880
|
}
|
885
881
|
|
886
882
|
if (this.get('hintOnFocus') && !this.get('isTextArea')) {
|
887
|
-
|
883
|
+
var hintJQ = this.$('.hint');
|
884
|
+
|
885
|
+
hintJQ.css('line-height', hintJQ.outerHeight() + 'px');
|
888
886
|
}
|
889
887
|
},
|
890
888
|
|
@@ -895,7 +893,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
895
893
|
if (!SC.platform.input.placeholder && this._hintON) {
|
896
894
|
var input = this.$input(),
|
897
895
|
currentValue = input.val();
|
898
|
-
if (!currentValue || (currentValue && currentValue.length===0)) {
|
896
|
+
if (!currentValue || (currentValue && currentValue.length === 0)) {
|
899
897
|
input.val(this.get('formattedHint'));
|
900
898
|
}
|
901
899
|
}
|
@@ -940,10 +938,10 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
940
938
|
*/
|
941
939
|
_textField_fieldDidFocus: function (evt) {
|
942
940
|
SC.run(function () {
|
943
|
-
this.set('focused',YES);
|
941
|
+
this.set('focused', YES);
|
944
942
|
this.fieldDidFocus(evt);
|
945
943
|
var val = this.get('value');
|
946
|
-
if (!SC.platform.input.placeholder && ((!val) || (val && val.length===0))) {
|
944
|
+
if (!SC.platform.input.placeholder && ((!val) || (val && val.length === 0))) {
|
947
945
|
this._hintON = NO;
|
948
946
|
}
|
949
947
|
}, this);
|
@@ -954,13 +952,13 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
954
952
|
*/
|
955
953
|
_textField_fieldDidBlur: function (evt) {
|
956
954
|
SC.run(function () {
|
957
|
-
this.set('focused',NO);
|
955
|
+
this.set('focused', NO);
|
958
956
|
// passing the original event here instead that was potentially set from
|
959
|
-
//
|
957
|
+
// losing the responder on the inline text editor so that we can
|
960
958
|
// use it for the delegate to end editing
|
961
959
|
this.fieldDidBlur(this._origEvent || evt);
|
962
960
|
var val = this.get('value');
|
963
|
-
if (!SC.platform.input.placeholder && !this.get('hintOnFocus') && ((!val) || (val && val.length===0))) {
|
961
|
+
if (!SC.platform.input.placeholder && !this.get('hintOnFocus') && ((!val) || (val && val.length === 0))) {
|
964
962
|
this._hintON = YES;
|
965
963
|
}
|
966
964
|
}, this);
|
@@ -990,7 +988,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
990
988
|
},
|
991
989
|
|
992
990
|
fieldDidBlur: function (evt) {
|
993
|
-
this.resignFirstResponder(evt)
|
991
|
+
this.resignFirstResponder(evt);
|
994
992
|
|
995
993
|
if (this.get('commitOnBlur')) this.commitEditing(evt);
|
996
994
|
|
@@ -1004,7 +1002,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1004
1002
|
|
1005
1003
|
/** @private */
|
1006
1004
|
_field_fieldValueDidChange: function (evt) {
|
1007
|
-
if (this.get('focused')){
|
1005
|
+
if (this.get('focused')) {
|
1008
1006
|
SC.run(function () {
|
1009
1007
|
this.fieldValueDidChange(NO);
|
1010
1008
|
}, this);
|
@@ -1019,9 +1017,9 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1019
1017
|
I welcome someone else to find a better solution to this problem. However, please make sure that it
|
1020
1018
|
works with pasting via shortcut, context menu and the application menu on *All Browsers*.
|
1021
1019
|
*/
|
1022
|
-
_textField_inputDidChange: function() {
|
1020
|
+
_textField_inputDidChange: function () {
|
1023
1021
|
var timerNotPending = SC.empty(this._fieldValueDidChangeTimer) || !this._fieldValueDidChangeTimer.get('isValid');
|
1024
|
-
if(this.get('applyImmediately') && timerNotPending) {
|
1022
|
+
if (this.get('applyImmediately') && timerNotPending) {
|
1025
1023
|
this.invokeLater(this.fieldValueDidChange, 10);
|
1026
1024
|
}
|
1027
1025
|
},
|
@@ -1036,9 +1034,9 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1036
1034
|
|
1037
1035
|
if (this.getFieldValue()) {
|
1038
1036
|
this.$('.hint').addClass('sc-hidden');
|
1039
|
-
}
|
1040
|
-
else {
|
1037
|
+
} else {
|
1041
1038
|
this.$('.hint').removeClass('sc-hidden');
|
1039
|
+
this._fixupTextLayout();
|
1042
1040
|
}
|
1043
1041
|
}.observes('value'),
|
1044
1042
|
|
@@ -1061,9 +1059,9 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1061
1059
|
valueLen = value ? value.length : 0,
|
1062
1060
|
responder;
|
1063
1061
|
|
1064
|
-
if (!selection
|
1062
|
+
if (!selection || ((selection.get('length') === 0 && (selection.get('start') === 0) || selection.get('end') === valueLen))) {
|
1065
1063
|
responder = SC.RootResponder.responder;
|
1066
|
-
if(evt.keyCode===9) return;
|
1064
|
+
if (evt.keyCode === 9) return;
|
1067
1065
|
responder.keypress.call(responder, evt);
|
1068
1066
|
evt.stopPropagation();
|
1069
1067
|
}
|
@@ -1089,9 +1087,10 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1089
1087
|
var inp = this.$input()[0];
|
1090
1088
|
try {
|
1091
1089
|
if (inp) inp.focus();
|
1092
|
-
} catch(e){}
|
1090
|
+
} catch (e) {}
|
1091
|
+
|
1093
1092
|
if (!this._txtFieldMouseDown) {
|
1094
|
-
this.invokeLast(this._selectRootElement)
|
1093
|
+
this.invokeLast(this._selectRootElement);
|
1095
1094
|
}
|
1096
1095
|
}
|
1097
1096
|
},
|
@@ -1111,8 +1110,8 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1111
1110
|
SC.browser.compare(SC.browser.osVersion, '10.7') === 0;
|
1112
1111
|
|
1113
1112
|
if (!(SC.browser.name === SC.BROWSER.safari &&
|
1114
|
-
isLion && SC.buildLocale==='ko-kr')) {
|
1115
|
-
inputElem.select()
|
1113
|
+
isLion && SC.buildLocale === 'ko-kr')) {
|
1114
|
+
inputElem.select();
|
1116
1115
|
}
|
1117
1116
|
}
|
1118
1117
|
else this._textField_selectionDidChange();
|
@@ -1147,7 +1146,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1147
1146
|
},
|
1148
1147
|
|
1149
1148
|
/** @private */
|
1150
|
-
insertText: function(chr, evt) {
|
1149
|
+
insertText: function (chr, evt) {
|
1151
1150
|
var which = evt.which,
|
1152
1151
|
keyCode = evt.keyCode,
|
1153
1152
|
maxLengthReached = false;
|
@@ -1157,8 +1156,8 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1157
1156
|
var val = this.get('value');
|
1158
1157
|
|
1159
1158
|
// This code is nasty. It's thanks gecko .keycode table that has charters like & with the same keycode as up arrow key
|
1160
|
-
if (val && ((!SC.browser.isMozilla && which>47) ||
|
1161
|
-
(SC.browser.isMozilla && ((which>32 && which<43) || which>47) && !(keyCode>36 && keyCode<41))) &&
|
1159
|
+
if (val && ((!SC.browser.isMozilla && which > 47) ||
|
1160
|
+
(SC.browser.isMozilla && ((which > 32 && which < 43) || which > 47) && !(keyCode > 36 && keyCode < 41))) &&
|
1162
1161
|
(val.length >= this.get('maxLength'))) {
|
1163
1162
|
maxLengthReached = true;
|
1164
1163
|
}
|
@@ -1166,7 +1165,6 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1166
1165
|
// validate keyDown...
|
1167
1166
|
// do not validate on touch, as it prevents return.
|
1168
1167
|
if ((this.performValidateKeyDown(evt) || SC.platform.touch) && !maxLengthReached) {
|
1169
|
-
this._isKeyDown = YES;
|
1170
1168
|
evt.allowDefault();
|
1171
1169
|
} else {
|
1172
1170
|
evt.stop();
|
@@ -1183,20 +1181,44 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1183
1181
|
},
|
1184
1182
|
|
1185
1183
|
/** @private */
|
1186
|
-
insertTab: function(evt) {
|
1184
|
+
insertTab: function (evt) {
|
1187
1185
|
// Don't handle if default tabbing hasn't been enabled.
|
1188
|
-
if (!this.get('defaultTabbingEnabled'))
|
1186
|
+
if (!this.get('defaultTabbingEnabled')) {
|
1187
|
+
evt.preventDefault();
|
1188
|
+
return false;
|
1189
|
+
}
|
1190
|
+
|
1189
1191
|
// Otherwise, handle.
|
1190
|
-
var view =
|
1192
|
+
var view = this.get('nextValidKeyView');
|
1191
1193
|
if (view) view.becomeFirstResponder();
|
1192
1194
|
else evt.allowDefault();
|
1193
|
-
return YES
|
1195
|
+
return YES; // handled
|
1194
1196
|
},
|
1195
1197
|
|
1196
|
-
// If this is a multi-line field, then allow the new line to proceed.
|
1197
1198
|
/** @private */
|
1198
|
-
|
1199
|
-
if
|
1199
|
+
insertBacktab: function (evt) {
|
1200
|
+
// Don't handle if default tabbing hasn't been enabled.
|
1201
|
+
if (!this.get('defaultTabbingEnabled')) {
|
1202
|
+
evt.preventDefault();
|
1203
|
+
return false;
|
1204
|
+
}
|
1205
|
+
|
1206
|
+
// Otherwise, handle.
|
1207
|
+
var view = this.get('previousValidKeyView');
|
1208
|
+
if (view) view.becomeFirstResponder();
|
1209
|
+
else evt.allowDefault();
|
1210
|
+
return YES; // handled
|
1211
|
+
},
|
1212
|
+
|
1213
|
+
/**
|
1214
|
+
@private
|
1215
|
+
|
1216
|
+
Invoked when the user presses return. If this is a multi-line field,
|
1217
|
+
then allow the newline to proceed. Otherwise, try to commit the
|
1218
|
+
edit.
|
1219
|
+
*/
|
1220
|
+
insertNewline: function (evt) {
|
1221
|
+
if (this.get('isTextArea') || evt.isIMEInput) {
|
1200
1222
|
evt.allowDefault();
|
1201
1223
|
return YES; // handled
|
1202
1224
|
}
|
@@ -1204,37 +1226,37 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1204
1226
|
},
|
1205
1227
|
|
1206
1228
|
/** @private */
|
1207
|
-
deleteForward: function(evt) {
|
1229
|
+
deleteForward: function (evt) {
|
1208
1230
|
evt.allowDefault();
|
1209
1231
|
return YES;
|
1210
1232
|
},
|
1211
1233
|
|
1212
1234
|
/** @private */
|
1213
|
-
deleteBackward: function(evt) {
|
1235
|
+
deleteBackward: function (evt) {
|
1214
1236
|
evt.allowDefault();
|
1215
1237
|
return YES;
|
1216
1238
|
},
|
1217
1239
|
|
1218
1240
|
/** @private */
|
1219
|
-
moveLeft: function(evt) {
|
1241
|
+
moveLeft: function (evt) {
|
1220
1242
|
evt.allowDefault();
|
1221
1243
|
return YES;
|
1222
1244
|
},
|
1223
1245
|
|
1224
1246
|
/** @private */
|
1225
|
-
moveRight: function(evt) {
|
1247
|
+
moveRight: function (evt) {
|
1226
1248
|
evt.allowDefault();
|
1227
1249
|
return YES;
|
1228
1250
|
},
|
1229
1251
|
|
1230
1252
|
/** @private */
|
1231
|
-
selectAll: function(evt) {
|
1253
|
+
selectAll: function (evt) {
|
1232
1254
|
evt.allowDefault();
|
1233
1255
|
return YES;
|
1234
1256
|
},
|
1235
1257
|
|
1236
1258
|
/** @private */
|
1237
|
-
moveUp: function(evt) {
|
1259
|
+
moveUp: function (evt) {
|
1238
1260
|
if (this.get('isTextArea')) {
|
1239
1261
|
evt.allowDefault();
|
1240
1262
|
return YES;
|
@@ -1243,7 +1265,7 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1243
1265
|
},
|
1244
1266
|
|
1245
1267
|
/** @private */
|
1246
|
-
moveDown: function(evt) {
|
1268
|
+
moveDown: function (evt) {
|
1247
1269
|
if (this.get('isTextArea')) {
|
1248
1270
|
evt.allowDefault();
|
1249
1271
|
return YES;
|
@@ -1259,34 +1281,34 @@ SC.TextFieldView = SC.FieldView.extend(SC.Editable,
|
|
1259
1281
|
// element's values won't be updated until after this event is finished
|
1260
1282
|
// processing.
|
1261
1283
|
this.notifyPropertyChange('selection');
|
1262
|
-
this._isKeyDown = NO;
|
1263
1284
|
evt.allowDefault();
|
1264
1285
|
return YES;
|
1265
1286
|
},
|
1266
1287
|
|
1267
1288
|
mouseDown: function (evt) {
|
1268
|
-
var fieldValue = this.get('fieldValue'); // use 'fieldValue' since we want actual text
|
1269
|
-
this._txtFieldMouseDown=YES;
|
1270
|
-
this.becomeFirstResponder();
|
1271
1289
|
if (!this.get('isEnabledInPane')) {
|
1272
1290
|
evt.stop();
|
1273
1291
|
return YES;
|
1274
1292
|
} else {
|
1293
|
+
this._txtFieldMouseDown = YES;
|
1294
|
+
this.becomeFirstResponder();
|
1295
|
+
|
1275
1296
|
return sc_super();
|
1276
1297
|
}
|
1277
1298
|
},
|
1278
1299
|
|
1279
1300
|
mouseUp: function (evt) {
|
1280
|
-
this._txtFieldMouseDown=NO;
|
1281
|
-
// The caret/selection could have moved. In some browsers, though, the
|
1282
|
-
// element's values won't be updated until after this event is finished
|
1283
|
-
// processing.
|
1284
|
-
this.notifyPropertyChange('selection');
|
1301
|
+
this._txtFieldMouseDown = NO;
|
1285
1302
|
|
1286
1303
|
if (!this.get('isEnabledInPane')) {
|
1287
1304
|
evt.stop();
|
1288
1305
|
return YES;
|
1289
1306
|
}
|
1307
|
+
|
1308
|
+
// The caret/selection could have moved. In some browsers, though, the
|
1309
|
+
// element's values won't be updated until after this event is finished
|
1310
|
+
// processing.
|
1311
|
+
this.notifyPropertyChange('selection');
|
1290
1312
|
return sc_super();
|
1291
1313
|
},
|
1292
1314
|
|