Skip to content

Commit

Permalink
Allows text areas to be auto-height while being wrapped in an
Browse files Browse the repository at this point in the history
element that has scrollbars. The wrapper element with the
scroll bar does not need to be a direct parent of the text area.

**update:** fixed a bug that came up in the discussion

This is fixed now: #1933 (comment)

The problem was the check in getScrollContainer()
  • Loading branch information
felixhayashi committed Oct 26, 2015
1 parent a204784 commit d3ab414
Showing 1 changed file with 22 additions and 10 deletions.
32 changes: 22 additions & 10 deletions core/modules/widgets/edit-text.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,31 +211,43 @@ EditTextWidget.prototype.updateEditorDomNode = function(text) {
}
};

/*
Get the first parent element that has scrollbars or use the body as fallback.
*/
EditTextWidget.prototype.getScrollContainer = function(el) {
while(el.parentNode) {
el = el.parentNode;
if(el.scrollTop) {
return el;
}
}
return this.document.body;
};

/*
Fix the height of textareas to fit their content
*/
EditTextWidget.prototype.fixHeight = function() {
var self = this,
domNode = this.domNodes[0];
var domNode = this.domNodes[0];
if(this.editAutoHeight && domNode && !domNode.isTiddlyWikiFakeDom && this.editTag === "textarea") {
// Resize the textarea to fit its content, preserving scroll position
var scrollPosition = $tw.utils.getScrollPosition(),
scrollTop = scrollPosition.y;
// Measure the specified minimum height
domNode.style.height = self.editMinHeight;
// Get the scroll container and register the current scroll position
var container = this.getScrollContainer(domNode),
scrollTop = container.scrollTop;
// Measure the specified minimum height
domNode.style.height = this.editMinHeight;
var minHeight = domNode.offsetHeight;
// Set its height to auto so that it snaps to the correct height
domNode.style.height = "auto";
// Calculate the revised height
var newHeight = Math.max(domNode.scrollHeight + domNode.offsetHeight - domNode.clientHeight,minHeight);
// Only try to change the height if it has changed
if(newHeight !== domNode.offsetHeight) {
domNode.style.height = newHeight + "px";
domNode.style.height = newHeight + "px";
// Make sure that the dimensions of the textarea are recalculated
$tw.utils.forceLayout(domNode);
// Check that the scroll position is still visible before trying to scroll back to it
scrollTop = Math.min(scrollTop,self.document.body.scrollHeight - window.innerHeight);
window.scrollTo(scrollPosition.x,scrollTop);
// Set the container to the position we registered at the beginning
container.scrollTop = scrollTop;
}
}
};
Expand Down

0 comments on commit d3ab414

Please sign in to comment.