Skip to content
This repository has been archived by the owner on Dec 19, 2024. It is now read-only.

Commit

Permalink
Simplify methods used to compute textarea size
Browse files Browse the repository at this point in the history
Updates the underlying textarea height to `auto` thereby updating scrollHeight to a computed value upon change. If the texarea value is not empty, an explicit height is applied to the textarea using the computed scrollHeight. This commit also removes value mirroring.
  • Loading branch information
CTOJoe committed Mar 2, 2016
1 parent 951cf16 commit 3630bf4
Showing 1 changed file with 30 additions and 43 deletions.
73 changes: 30 additions & 43 deletions iron-autogrow-textarea.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,11 @@
-moz-appearance: textarea;
-webkit-appearance: textarea;
overflow: hidden;
@apply(--layout-horizontal);
}

.mirror-text {
visibility: hidden;
word-wrap: break-word;
}

.fit {
@apply(--layout-fit);
.flex {
@apply(--layout-flex);
}

textarea {
Expand All @@ -68,8 +64,10 @@
background: inherit;
color: inherit;
/* see comments in template */
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
height: auto;
font-size: inherit;
font-family: inherit;
line-height: inherit;
Expand Down Expand Up @@ -98,12 +96,8 @@
}
</style>
<template>
<!-- the mirror sizes the input/textarea so it grows with typing -->
<!-- use &#160; instead &nbsp; of to allow this element to be used in XHTML -->
<div id="mirror" class="mirror-text" aria-hidden="true">&#160;</div>

<!-- size the input/textarea with a div, because the textarea has intrinsic size in ff -->
<div class="textarea-container fit">
<div class="textarea-container flex">
<textarea id="textarea"
name$="[[name]]"
autocomplete$="[[autocomplete]]"
Expand Down Expand Up @@ -153,7 +147,7 @@
rows: {
type: Number,
value: 1,
observer: '_updateCached'
observer: '_updateTextareaHeight'
},

/**
Expand All @@ -167,7 +161,7 @@
maxRows: {
type: Number,
value: 0,
observer: '_updateCached'
observer: '_updateTextareaHeight'
},

/**
Expand Down Expand Up @@ -308,7 +302,7 @@
}

this.value = this.bindValue;
this.$.mirror.innerHTML = this._valueForMirror();
this._updateTextareaHeight();
// manually notify because we don't want to notify until after setting value
this.fire('bind-value-changed', {value: this.bindValue});
},
Expand All @@ -317,33 +311,26 @@
this.bindValue = event.path ? event.path[0].value : event.target.value;
},

_constrain: function(tokens) {
var _tokens;
tokens = tokens || [''];
// Enforce the min and max heights for a multiline input to avoid measurement
if (this.maxRows > 0 && tokens.length > this.maxRows) {
_tokens = tokens.slice(0, this.maxRows);
} else {
_tokens = tokens.slice(0);
}
while (this.rows > 0 && _tokens.length < this.rows) {
_tokens.push('');
}
// Use &#160; instead &nbsp; of to allow this element to be used in XHTML.
return _tokens.join('<br/>') + '&#160;';
},

_valueForMirror: function() {
var input = this.textarea;
if (!input) {
return;
}
this.tokens = (input && input.value) ? input.value.replace(/&/gm, '&amp;').replace(/"/gm, '&quot;').replace(/'/gm, '&#39;').replace(/</gm, '&lt;').replace(/>/gm, '&gt;').split('\n') : [''];
return this._constrain(this.tokens);
},

_updateCached: function() {
this.$.mirror.innerHTML = this._constrain(this.tokens);
_updateTextareaHeight: function() {
var textarea = this.textarea;
if (!textarea) {
return;
}

// Update the underlying textarea height to `auto` thereby updating
// scrollHeight. If the texarea value is not empty an explicit height
// is applied to the textarea using scrollHeight.
textarea.style.height = 'auto';

var height = textarea.scrollHeight;
var rows = textarea.value.split('\n').length;
if (this.maxRows > 0 && rows > this.maxRows) {
height = (textarea.scrollHeight / rows) * this.maxRows;
}

if(height) {
textarea.style.height = height + 'px';
}
},

_onValueChanged: function() {
Expand Down

0 comments on commit 3630bf4

Please sign in to comment.