@@ -45,7 +45,7 @@ export class HtmlQueryResultsRenderer {
4545 private readonly taskLineRenderer : TaskLineRenderer ;
4646
4747 private readonly ulElementStack : HTMLUListElement [ ] = [ ] ;
48- private readonly renderedListItems : Set < ListItem > = new Set < ListItem > ( ) ;
48+ private readonly addedListItems : Set < ListItem > = new Set < ListItem > ( ) ;
4949
5050 private readonly queryRendererParameters : QueryRendererParameters ;
5151
@@ -125,7 +125,7 @@ export class HtmlQueryResultsRenderer {
125125 this . getters . query ( ) . debug ( `[render] Render called: plugin state: ${ state } ; searching ${ tasks . length } tasks` ) ;
126126
127127 if ( this . getters . query ( ) . queryLayoutOptions . explainQuery ) {
128- this . createExplanation ( ) ;
128+ this . renderExplanation ( ) ;
129129 }
130130
131131 const queryResult = this . getters . query ( ) . applyQueryToTasks ( tasks ) ;
@@ -160,7 +160,7 @@ export class HtmlQueryResultsRenderer {
160160 }
161161
162162 // Use the 'explain' instruction to enable this
163- private createExplanation ( ) {
163+ private renderExplanation ( ) {
164164 const explanationAsString = explainResults (
165165 this . getters . source ( ) ,
166166 GlobalFilter . getInstance ( ) ,
@@ -189,19 +189,19 @@ export class HtmlQueryResultsRenderer {
189189 // will be empty, and no headings will be added.
190190 await this . addGroupHeadings ( group . groupHeadings ) ;
191191
192- this . renderedListItems . clear ( ) ;
192+ this . addedListItems . clear ( ) ;
193193 // TODO re-extract the method to include this back
194194 const taskList = createAndAppendElement ( 'ul' , this . getContent ( ) ) ;
195195 this . ulElementStack . push ( taskList ) ;
196196 try {
197- await this . createTaskList ( group . tasks ) ;
197+ await this . addTaskList ( group . tasks ) ;
198198 } finally {
199199 this . ulElementStack . pop ( ) ;
200200 }
201201 }
202202 }
203203
204- private async createTaskList ( listItems : ListItem [ ] ) : Promise < void > {
204+ private async addTaskList ( listItems : ListItem [ ] ) : Promise < void > {
205205 const taskList = this . currentULElement ( ) ;
206206 taskList . classList . add (
207207 'contains-task-list' ,
@@ -213,40 +213,72 @@ export class HtmlQueryResultsRenderer {
213213 const groupingAttribute = this . getGroupingAttribute ( ) ;
214214 if ( groupingAttribute && groupingAttribute . length > 0 ) taskList . dataset . taskGroupBy = groupingAttribute ;
215215
216+ if ( this . getters . query ( ) . queryLayoutOptions . hideTree ) {
217+ await this . addFlatTaskList ( listItems ) ;
218+ } else {
219+ await this . addTreeTaskList ( listItems ) ;
220+ }
221+ }
222+
223+ /**
224+ * Old-style rendering of tasks:
225+ * - What is rendered:
226+ * - Only task lines that match the query are rendered, as a flat list
227+ * - The order that lines are rendered:
228+ * - Tasks are rendered in the order specified in 'sort by' instructions and default sort order.
229+ * @param listItems
230+ * @private
231+ */
232+ private async addFlatTaskList ( listItems : ListItem [ ] ) : Promise < void > {
216233 for ( const [ listItemIndex , listItem ] of listItems . entries ( ) ) {
217- if ( this . getters . query ( ) . queryLayoutOptions . hideTree ) {
218- /* Old-style rendering of tasks:
219- * - What is rendered:
220- * - Only task lines that match the query are rendered, as a flat list
221- * - The order that lines are rendered:
222- * - Tasks are rendered in the order specified in 'sort by' instructions and default sort order.
223- */
224- if ( listItem instanceof Task ) {
225- await this . addTask ( listItem , listItemIndex , [ ] ) ;
226- }
234+ if ( listItem instanceof Task ) {
235+ await this . addTask ( listItem , listItemIndex , [ ] ) ;
236+ }
237+ }
238+ }
239+
240+ /** New-style rendering of tasks:
241+ * - What is rendered:
242+ * - Task lines that match the query are rendered, as a tree.
243+ * - Currently, all child tasks and list items of the found tasks are shown,
244+ * including any child tasks that did not match the query.
245+ * - The order that lines are rendered:
246+ * - The top-level/outermost tasks are sorted in the order specified in 'sort by'
247+ * instructions and default sort order.
248+ * - Child tasks (and list items) are shown in their original order in their Markdown file.
249+ * @param listItems
250+ * @private
251+ */
252+ private async addTreeTaskList ( listItems : ListItem [ ] ) : Promise < void > {
253+ for ( const [ listItemIndex , listItem ] of listItems . entries ( ) ) {
254+ if ( this . alreadyAdded ( listItem ) ) {
255+ continue ;
256+ }
257+
258+ if ( this . willBeAddedLater ( listItem , listItems ) ) {
259+ continue ;
260+ }
261+
262+ if ( listItem instanceof Task ) {
263+ await this . addTask ( listItem , listItemIndex , listItem . children ) ;
227264 } else {
228- /* New-style rendering of tasks:
229- * - What is rendered:
230- * - Task lines that match the query are rendered, as a tree.
231- * - Currently, all child tasks and list items of the found tasks are shown,
232- * including any child tasks that did not match the query.
233- * - The order that lines are rendered:
234- * - The top-level/outermost tasks are sorted in the order specified in 'sort by'
235- * instructions and default sort order.
236- * - Child tasks (and list items) are shown in their original order in their Markdown file.
237- */
238- await this . addTaskOrListItemAndChildren ( listItem , listItemIndex , listItems ) ;
265+ await this . addListItem ( listItem , listItemIndex , listItem . children ) ;
266+ }
267+ this . addedListItems . add ( listItem ) ;
268+
269+ for ( const childTask of listItem . children ) {
270+ this . addedListItems . add ( childTask ) ;
239271 }
240272 }
241273 }
242274
243- private willBeRenderedLater ( listItem : ListItem , listItems : ListItem [ ] ) {
275+ private willBeAddedLater ( listItem : ListItem , listItems : ListItem [ ] ) {
244276 const closestParentTask = listItem . findClosestParentTask ( ) ;
245277 if ( ! closestParentTask ) {
246278 return false ;
247279 }
248280
249- if ( ! this . renderedListItems . has ( closestParentTask ) ) {
281+ if ( ! this . addedListItems . has ( closestParentTask ) ) {
250282 // This task is a direct or indirect child of another task that we are waiting to draw,
251283 // so don't draw it yet, it will be done recursively later.
252284 if ( listItems . includes ( closestParentTask ) ) {
@@ -257,33 +289,8 @@ export class HtmlQueryResultsRenderer {
257289 return false ;
258290 }
259291
260- private alreadyRendered ( listItem : ListItem ) {
261- return this . renderedListItems . has ( listItem ) ;
262- }
263-
264- private async addTaskOrListItemAndChildren ( listItem : ListItem , taskIndex : number , listItems : ListItem [ ] ) {
265- if ( this . alreadyRendered ( listItem ) ) {
266- return ;
267- }
268-
269- if ( this . willBeRenderedLater ( listItem , listItems ) ) {
270- return ;
271- }
272-
273- await this . createTaskOrListItem ( listItem , taskIndex ) ;
274- this . renderedListItems . add ( listItem ) ;
275-
276- for ( const childTask of listItem . children ) {
277- this . renderedListItems . add ( childTask ) ;
278- }
279- }
280-
281- private async createTaskOrListItem ( listItem : ListItem , taskIndex : number ) : Promise < void > {
282- if ( listItem instanceof Task ) {
283- await this . addTask ( listItem , taskIndex , listItem . children ) ;
284- } else {
285- await this . addListItem ( listItem , taskIndex , listItem . children ) ;
286- }
292+ private alreadyAdded ( listItem : ListItem ) {
293+ return this . addedListItems . has ( listItem ) ;
287294 }
288295
289296 private async addListItem ( listItem : ListItem , listItemIndex : number , children : ListItem [ ] ) : Promise < void > {
@@ -298,7 +305,7 @@ export class HtmlQueryResultsRenderer {
298305 const taskList1 = createAndAppendElement ( 'ul' , listItemElement ) ;
299306 this . ulElementStack . push ( taskList1 ) ;
300307 try {
301- await this . createTaskList ( children ) ;
308+ await this . addTaskList ( children ) ;
302309 } finally {
303310 this . ulElementStack . pop ( ) ;
304311 }
@@ -347,7 +354,7 @@ export class HtmlQueryResultsRenderer {
347354 const taskList1 = createAndAppendElement ( 'ul' , listItem ) ;
348355 this . ulElementStack . push ( taskList1 ) ;
349356 try {
350- await this . createTaskList ( children ) ;
357+ await this . addTaskList ( children ) ;
351358 } finally {
352359 this . ulElementStack . pop ( ) ;
353360 }
0 commit comments