Wait for Etch component to render before consuming
The `process.nextTick` hack assumed that ALL Etch components would their
child elements on the same thread. As it turns out, there can be a delay
between constructing a VirtualDOM node and when it's attached to the DOM
tree.
Fixes atom/atom#16133.
MODIFY
lib/get-icon-services.js
lib/get-icon-services.js
@@ -12,6 +12,7 @@ class IconServices {
this.emitter = new Emitter()
this.elementIcons = null
this.elementIconDisposables = new CompositeDisposable()
+ this.elementIconViews = new Map()
this.fileIcons = DefaultFileIcons
}
@@ -32,6 +33,7 @@ class IconServices {
if (this.elementIconDisposables != null) {
this.elementIconDisposables.dispose()
}
+ this.elementIconViews.clear()
if (service) { this.elementIconDisposables = new CompositeDisposable() }
this.elementIcons = service
return this.emitter.emit('did-change')
@@ -48,12 +50,18 @@ class IconServices {
getIconClasses (view) {
let iconClass = ''
if (this.elementIcons) {
- if (!view.iconDisposable) {
- view.iconDisposable = new CompositeDisposable()
- }
- process.nextTick(() => {
- view.iconDisposable.add(this.elementIcons(view.refs.icon, view.filePath))
+ if (!this.elementIconViews.has(view)) {
+ this.waitToAttach(view).then(() => {
+ const iconDisposable = new CompositeDisposable()
+ this.elementIconViews.set(view, iconDisposable)
+ this.elementIconDisposables.add(iconDisposable)
+ iconDisposable.add(this.elementIcons(view.refs.icon, view.filePath))
+ iconDisposable.add(new Disposable(() => {
+ this.elementIconViews.delete(view)
+ this.elementIconDisposables.delete(view)
+ }))
})
+ }
} else {
iconClass = this.fileIcons.iconClassForPath(view.filePath, 'find-and-replace') || ''
if (Array.isArray(iconClass)) {
@@ -62,4 +70,13 @@ class IconServices {
}
return iconClass
}
+
+ async waitToAttach(view, delay = 10){
+ if (view.refs && view.refs.icon instanceof Element) {
+ return Promise.resolve()
+ } else {
+ await new Promise(done => setTimeout(done, delay))
+ return this.waitToAttach(view, delay)
+ }
+ }
}

MODIFY
lib/project/result-view.js
lib/project/result-view.js
@@ -33,10 +33,6 @@ class ResultView {
}
destroy() {
- if (this.iconDisposable) {
- this.iconDisposable.dispose()
- this.iconDisposable = null
- }
return etch.destroy(this)
}

Wait for Etch component to render before consuming

The `process.nextTick` hack assumed that ALL Etch components would their
child elements on the same thread. As it turns out, there can be a delay
between constructing a VirtualDOM node and when it's attached to the DOM
tree.

Fixes atom/atom#16133.