-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathampersand-expanding-textarea-view.js
94 lines (82 loc) · 3.63 KB
/
ampersand-expanding-textarea-view.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
var AmpersandInputView = require( 'ampersand-input-view' );
module.exports = AmpersandInputView.extend({
template: [
'<label>',
'<span data-hook="label"></span>',
'<textarea class="form-input" data-hook="input-primary"></textarea>',
'<textarea class="form-input" data-hook="input-mirror" tabindex="-1" style="position:absolute;top:-9999px;left:0;right:auto;bottom:auto;border:0;word-wrap:break-word;height:0 !important;min-height:0 !important;overflow:hidden;transition:none;-webkit-transition:none;-moz-transition:none;"></textarea>',
'<div data-hook="message-container" class="message message-below message-error">',
'<p data-hook="message-text"></p>',
'</div>',
'</label>'
].join( '' ),
render: function() {
this.renderWithTemplate();
this.input = this.queryByHook( 'input-primary' );
this.inputMirror = this.queryByHook( 'input-mirror' );
// switches out input for textarea if that's what we want
this.handleTypeChange();
this.initInputBindings();
// Skip validation on initial setValue
// if the field is not required
this.setValue( this.inputValue, !this.required );
// Set the initial height of the textarea
// This needs to run after the view has been rendered to the DOM
// to get the propert scrollHeight
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
if ( this.parent && MutationObserver ) {
var observer = new MutationObserver(function() {
this.initTextareaMirror();
this.resizeTextarea();
}.bind( this ));
observer.observe( this.parent.el, {
childList: true
});
} else {
window.setTimeout(function() {
this.initTextareaMirror();
this.resizeTextarea();
}.bind( this ), 250 );
}
},
events: {
'keyup [data-hook="input-primary"]': 'resizeTextarea',
'input [data-hook="input-primary"]': 'resizeTextarea'
},
initTextareaMirror: function() {
var typographyStyles = [
'fontFamily',
'fontSize',
'fontWeight',
'fontStyle',
'letterSpacing',
'textTransform',
'wordSpacing',
'textIndent',
'whiteSpace',
'padding'
];
// test that line-height can be accurately copied.
this.inputMirror.style.lineHeight = '99px';
if ( window.getComputedStyle( this.inputMirror ).lineHeight === '99px' ) {
typographyStyles.push( 'lineHeight' );
}
this.inputMirror.style.lineHeight = '';
for ( var i = 0; i < typographyStyles.length; i++ ) {
this.inputMirror.style[ typographyStyles[ i ]] = window.getComputedStyle( this.input )[ typographyStyles[ i ]];
}
},
resizeTextarea: function() {
var elScrollHeight,
elComputedStyle = window.getComputedStyle( this.input );
this.inputMirror.value = this.input.value;
// Scroll top the top for IE8 and lower
this.inputMirror.scrollTop = 0;
this.inputMirror.scrollTop = 9e4;
elScrollHeight = this.inputMirror.scrollTop;
if ( elComputedStyle.boxSizing === 'border-box' ) {
elScrollHeight += ( parseInt( elComputedStyle.paddingTop ) + parseInt( elComputedStyle.paddingBottom ));
}
this.input.style.height = ( elScrollHeight + 1 ) + 'px';
}
});