improve perf of autosize.js
This commit is contained in:
parent
aed194fced
commit
96303583ad
|
@ -87,6 +87,7 @@
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
resize: none;
|
resize: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
word-wrap: break-word;
|
||||||
/* Text must be at least 16px or else iOS Safari zooms in */
|
/* Text must be at least 16px or else iOS Safari zooms in */
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
/* Hack to make Edge stretch the element all the way to the right.
|
/* Hack to make Edge stretch the element all the way to the right.
|
||||||
|
@ -152,10 +153,6 @@
|
||||||
export default {
|
export default {
|
||||||
oncreate() {
|
oncreate() {
|
||||||
this.set({inputText: store.get('currentInputTextInCompose')})
|
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)
|
const saveText = debounce(() => scheduleIdleTask(() => this.store.save()), 1000)
|
||||||
|
|
||||||
this.observe('inputText', inputText => {
|
this.observe('inputText', inputText => {
|
||||||
|
@ -166,6 +163,12 @@
|
||||||
saveText()
|
saveText()
|
||||||
}, {init: false})
|
}, {init: false})
|
||||||
|
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
mark('autosize()')
|
||||||
|
autosize(this.refs.textarea)
|
||||||
|
stop('autosize()')
|
||||||
|
})
|
||||||
|
|
||||||
// Avoid input delays by updating these values after a rAF
|
// Avoid input delays by updating these values after a rAF
|
||||||
this.observe('inputLengthToDisplay', inputLengthToDisplay => {
|
this.observe('inputLengthToDisplay', inputLengthToDisplay => {
|
||||||
requestAnimationFrame(() => {
|
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,
|
// The only change is to remove IE-specific hacks,
|
||||||
// remove parent overflow checks, make page resizes more performant,
|
// remove parent overflow checks, make page resizes more performant,
|
||||||
// add deferredUpdate, and add perf marks.
|
// add deferredUpdate, and add perf marks.
|
||||||
|
@ -11,30 +11,13 @@ const map = new Map()
|
||||||
let createEvent = (name) => new Event(name, {bubbles: true})
|
let createEvent = (name) => new Event(name, {bubbles: true})
|
||||||
|
|
||||||
function assign (ta) {
|
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
|
let cachedHeight = null
|
||||||
|
|
||||||
function init () {
|
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()
|
update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +33,7 @@ function assign (ta) {
|
||||||
|
|
||||||
ta.style.height = ''
|
ta.style.height = ''
|
||||||
|
|
||||||
let endHeight = ta.scrollHeight + heightOffset
|
let endHeight = ta.scrollHeight
|
||||||
|
|
||||||
if (ta.scrollHeight === 0) {
|
if (ta.scrollHeight === 0) {
|
||||||
// If the scrollHeight is 0, then the element probably has display:none or is detached from the DOM.
|
// 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 pageResize = debounce(update, 1000)
|
||||||
|
|
||||||
const destroy = (style => {
|
const destroy = () => {
|
||||||
window.removeEventListener('resize', pageResize, false)
|
window.removeEventListener('resize', pageResize, false)
|
||||||
ta.removeEventListener('input', deferredUpdate, false)
|
ta.removeEventListener('input', deferredUpdate, false)
|
||||||
ta.removeEventListener('autosize:destroy', destroy, false)
|
ta.removeEventListener('autosize:destroy', destroy, false)
|
||||||
ta.removeEventListener('autosize:update', update, false)
|
ta.removeEventListener('autosize:update', update, false)
|
||||||
|
|
||||||
Object.keys(style).forEach(key => {
|
|
||||||
ta.style[key] = style[key]
|
|
||||||
})
|
|
||||||
|
|
||||||
map.delete(ta)
|
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)
|
ta.addEventListener('autosize:destroy', destroy, false)
|
||||||
|
|
||||||
window.addEventListener('resize', pageResize, false)
|
window.addEventListener('resize', pageResize, false)
|
||||||
ta.addEventListener('input', deferredUpdate, false)
|
ta.addEventListener('input', deferredUpdate, false)
|
||||||
ta.addEventListener('autosize:update', update, false)
|
ta.addEventListener('autosize:update', update, false)
|
||||||
ta.style.overflowX = 'hidden'
|
|
||||||
ta.style.wordWrap = 'break-word'
|
|
||||||
|
|
||||||
map.set(ta, {
|
map.set(ta, {
|
||||||
destroy,
|
destroy,
|
||||||
|
@ -135,32 +106,23 @@ function update (ta) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let autosize = null
|
let autosize = (el, options) => {
|
||||||
|
|
||||||
// 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) {
|
if (el) {
|
||||||
Array.prototype.forEach.call(el.length ? el : [el], x => assign(x, options))
|
Array.prototype.forEach.call(el.length ? el : [el], x => assign(x, options))
|
||||||
}
|
}
|
||||||
return el
|
return el
|
||||||
}
|
}
|
||||||
autosize.destroy = el => {
|
autosize.destroy = el => {
|
||||||
if (el) {
|
if (el) {
|
||||||
Array.prototype.forEach.call(el.length ? el : [el], destroy)
|
Array.prototype.forEach.call(el.length ? el : [el], destroy)
|
||||||
}
|
}
|
||||||
return el
|
return el
|
||||||
}
|
}
|
||||||
autosize.update = el => {
|
autosize.update = el => {
|
||||||
if (el) {
|
if (el) {
|
||||||
Array.prototype.forEach.call(el.length ? el : [el], update)
|
Array.prototype.forEach.call(el.length ? el : [el], update)
|
||||||
}
|
}
|
||||||
return el
|
return el
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export { autosize }
|
export { autosize }
|
||||||
|
|
Loading…
Reference in a new issue