improve perf of autosize.js
This commit is contained in:
parent
aed194fced
commit
96303583ad
|
@ -87,6 +87,7 @@
|
|||
margin-top: 10px;
|
||||
resize: none;
|
||||
overflow: hidden;
|
||||
word-wrap: break-word;
|
||||
/* Text must be at least 16px or else iOS Safari zooms in */
|
||||
font-size: 1.2em;
|
||||
/* Hack to make Edge stretch the element all the way to the right.
|
||||
|
@ -152,10 +153,6 @@
|
|||
export default {
|
||||
oncreate() {
|
||||
this.set({inputText: store.get('currentInputTextInCompose')})
|
||||
mark('autosize()')
|
||||
autosize(this.refs.textarea) // TODO: this layout thrashes, could maybe find a better design
|
||||
stop('autosize()')
|
||||
|
||||
const saveText = debounce(() => scheduleIdleTask(() => this.store.save()), 1000)
|
||||
|
||||
this.observe('inputText', inputText => {
|
||||
|
@ -166,6 +163,12 @@
|
|||
saveText()
|
||||
}, {init: false})
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
mark('autosize()')
|
||||
autosize(this.refs.textarea)
|
||||
stop('autosize()')
|
||||
})
|
||||
|
||||
// Avoid input delays by updating these values after a rAF
|
||||
this.observe('inputLengthToDisplay', inputLengthToDisplay => {
|
||||
requestAnimationFrame(() => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Modified from https://github.com/jackmoore/autosize/commit/113f1b345868901619d4b01cda02b09aa1690ebd
|
||||
// Modified from https://github.com/jackmoore/autosize/blob/113f1b3/src/autosize.js
|
||||
// The only change is to remove IE-specific hacks,
|
||||
// remove parent overflow checks, make page resizes more performant,
|
||||
// add deferredUpdate, and add perf marks.
|
||||
|
@ -11,30 +11,13 @@ const map = new Map()
|
|||
let createEvent = (name) => new Event(name, {bubbles: true})
|
||||
|
||||
function assign (ta) {
|
||||
if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || map.has(ta)) return
|
||||
if (!ta || !ta.nodeName || ta.nodeName !== 'TEXTAREA' || map.has(ta)) {
|
||||
return
|
||||
}
|
||||
|
||||
let heightOffset = null
|
||||
let cachedHeight = null
|
||||
|
||||
function init () {
|
||||
const style = window.getComputedStyle(ta, null)
|
||||
|
||||
if (style.resize === 'vertical') {
|
||||
ta.style.resize = 'none'
|
||||
} else if (style.resize === 'both') {
|
||||
ta.style.resize = 'horizontal'
|
||||
}
|
||||
|
||||
if (style.boxSizing === 'content-box') {
|
||||
heightOffset = -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom))
|
||||
} else {
|
||||
heightOffset = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth)
|
||||
}
|
||||
// Fix when a textarea is not on document body and heightOffset is Not a Number
|
||||
if (isNaN(heightOffset)) {
|
||||
heightOffset = 0
|
||||
}
|
||||
|
||||
update()
|
||||
}
|
||||
|
||||
|
@ -50,7 +33,7 @@ function assign (ta) {
|
|||
|
||||
ta.style.height = ''
|
||||
|
||||
let endHeight = ta.scrollHeight + heightOffset
|
||||
let endHeight = ta.scrollHeight
|
||||
|
||||
if (ta.scrollHeight === 0) {
|
||||
// If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM.
|
||||
|
@ -86,32 +69,20 @@ function assign (ta) {
|
|||
|
||||
const pageResize = debounce(update, 1000)
|
||||
|
||||
const destroy = (style => {
|
||||
const destroy = () => {
|
||||
window.removeEventListener('resize', pageResize, false)
|
||||
ta.removeEventListener('input', deferredUpdate, false)
|
||||
ta.removeEventListener('autosize:destroy', destroy, false)
|
||||
ta.removeEventListener('autosize:update', update, false)
|
||||
|
||||
Object.keys(style).forEach(key => {
|
||||
ta.style[key] = style[key]
|
||||
})
|
||||
|
||||
map.delete(ta)
|
||||
}).bind(ta, {
|
||||
height: ta.style.height,
|
||||
resize: ta.style.resize,
|
||||
overflowY: ta.style.overflowY,
|
||||
overflowX: ta.style.overflowX,
|
||||
wordWrap: ta.style.wordWrap
|
||||
})
|
||||
}
|
||||
|
||||
ta.addEventListener('autosize:destroy', destroy, false)
|
||||
|
||||
window.addEventListener('resize', pageResize, false)
|
||||
ta.addEventListener('input', deferredUpdate, false)
|
||||
ta.addEventListener('autosize:update', update, false)
|
||||
ta.style.overflowX = 'hidden'
|
||||
ta.style.wordWrap = 'break-word'
|
||||
|
||||
map.set(ta, {
|
||||
destroy,
|
||||
|
@ -135,32 +106,23 @@ function update (ta) {
|
|||
}
|
||||
}
|
||||
|
||||
let autosize = null
|
||||
|
||||
// Do nothing in Node.js environment and IE8 (or lower)
|
||||
if (!process.browser) {
|
||||
autosize = el => el
|
||||
autosize.destroy = el => el
|
||||
autosize.update = el => el
|
||||
} else {
|
||||
autosize = (el, options) => {
|
||||
if (el) {
|
||||
Array.prototype.forEach.call(el.length ? el : [el], x => assign(x, options))
|
||||
}
|
||||
return el
|
||||
let autosize = (el, options) => {
|
||||
if (el) {
|
||||
Array.prototype.forEach.call(el.length ? el : [el], x => assign(x, options))
|
||||
}
|
||||
autosize.destroy = el => {
|
||||
if (el) {
|
||||
Array.prototype.forEach.call(el.length ? el : [el], destroy)
|
||||
}
|
||||
return el
|
||||
return el
|
||||
}
|
||||
autosize.destroy = el => {
|
||||
if (el) {
|
||||
Array.prototype.forEach.call(el.length ? el : [el], destroy)
|
||||
}
|
||||
autosize.update = el => {
|
||||
if (el) {
|
||||
Array.prototype.forEach.call(el.length ? el : [el], update)
|
||||
}
|
||||
return el
|
||||
return el
|
||||
}
|
||||
autosize.update = el => {
|
||||
if (el) {
|
||||
Array.prototype.forEach.call(el.length ? el : [el], update)
|
||||
}
|
||||
return el
|
||||
}
|
||||
|
||||
export { autosize }
|
||||
|
|
Loading…
Reference in a new issue