6
6
import $ from "jquery" ;
7
7
import ko from "knockout" ;
8
8
import engine from "Magento_Ui/js/lib/knockout/template/engine" ;
9
+ import _ from "underscore" ;
9
10
import Config from "../../config" ;
10
11
import ConfigInterface from "../../config.types" ;
11
12
import ContentTypeCollectionInterface from "../../content-type-collection.types" ;
@@ -93,6 +94,32 @@ export function loadTemplate(name: string): Promise<string> {
93
94
} ) ;
94
95
}
95
96
97
+ /**
98
+ * Assert if the render has finished
99
+ */
100
+ const assertRenderFinished = _ . debounce ( ( element : HTMLElement , expectedCount : number , callback : ( ) => { } ) => {
101
+ if ( element . querySelectorAll ( "[data-content-type]" ) . length === expectedCount ) {
102
+ callback ( ) ;
103
+ }
104
+ } , 50 ) ;
105
+
106
+ /**
107
+ * Iterate over the root container and count all content types
108
+ *
109
+ * @param rootContainer
110
+ * @param count
111
+ */
112
+ function countContentTypes ( rootContainer : ContentTypeCollectionInterface , count ?: number ) {
113
+ count = count || 0 ;
114
+ rootContainer . getChildren ( ) ( ) . forEach ( ( child : ContentTypeCollectionInterface ) => {
115
+ ++ count ;
116
+ if ( typeof child . getChildren !== "undefined" && child . getChildren ( ) ( ) . length > 0 ) {
117
+ count = countContentTypes ( child , count ) ;
118
+ }
119
+ } ) ;
120
+ return count ;
121
+ }
122
+
96
123
/**
97
124
* Perform a render of the provided data
98
125
*
@@ -102,12 +129,23 @@ function render(message: {stageId: string, tree: TreeItem}) {
102
129
return new Promise ( ( resolve , reject ) => {
103
130
createRenderTree ( message . stageId , message . tree ) . then ( ( rootContainer : ContentTypeCollectionInterface ) => {
104
131
const element = document . createElement ( "div" ) ;
105
- engine . waitForFinishRender ( ) . then ( ( ) => {
132
+ /**
133
+ * Setup an event on the element to observe changes and count the expected amount of content types are
134
+ * present within the content.
135
+ */
136
+ const renderFinished = $ . Deferred ( ) ;
137
+ element . addEventListener ( "DOMSubtreeModified" , ( ) => {
138
+ assertRenderFinished ( element , countContentTypes ( rootContainer ) , renderFinished . resolve ) ;
139
+ } ) ;
140
+
141
+ // Combine this event with our engine waitForRenderFinish to ensure rendering is completed
142
+ $ . when ( engine . waitForFinishRender ( ) , renderFinished ) . then ( ( ) => {
106
143
ko . cleanNode ( element ) ;
107
144
const filtered : JQuery = filterHtml ( $ ( element ) ) ;
108
145
const output = decodeAllDataUrlsInString ( filtered . html ( ) ) ;
109
146
resolve ( output ) ;
110
147
} ) ;
148
+
111
149
ko . applyBindingsToNode (
112
150
element ,
113
151
{
0 commit comments