Skip to content

Commit 17b69fa

Browse files
authored
Merge pull request #3672 from ilandikov/refactor/store-queryRendererParameters
refactor: store `QueryRendererParameters` in `HtmlQueryResultsRenderer`
2 parents f2615b3 + 4fc8806 commit 17b69fa

File tree

4 files changed

+88
-115
lines changed

4 files changed

+88
-115
lines changed

src/Renderer/HtmlQueryResultsRenderer.ts

Lines changed: 36 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ export class HtmlQueryResultsRenderer {
4747
private readonly ulElementStack: HTMLUListElement[] = [];
4848
private readonly renderedListItems: Set<ListItem> = new Set<ListItem>();
4949

50+
private readonly queryRendererParameters: QueryRendererParameters;
51+
5052
constructor(
5153
renderMarkdown: (
5254
app: App,
@@ -58,13 +60,15 @@ export class HtmlQueryResultsRenderer {
5860
obsidianComponent: Component | null,
5961
obsidianApp: App,
6062
textRenderer: TextRenderer,
63+
queryRendererParameters: QueryRendererParameters,
6164
getters: QueryResultsRendererGetters,
6265
) {
6366
this.renderMarkdown = renderMarkdown;
6467
this.obsidianComponent = obsidianComponent;
6568
this.obsidianApp = obsidianApp;
6669
this.textRenderer = textRenderer;
6770
this.getters = getters;
71+
this.queryRendererParameters = queryRendererParameters;
6872

6973
this.taskLineRenderer = new TaskLineRenderer({
7074
textRenderer: this.textRenderer,
@@ -79,17 +83,13 @@ export class HtmlQueryResultsRenderer {
7983
return this.getters.tasksFile().path;
8084
}
8185

82-
public async renderQuery(
83-
state: State | State.Warm,
84-
tasks: Task[],
85-
queryRendererParameters: QueryRendererParameters,
86-
) {
86+
public async renderQuery(state: State | State.Warm, tasks: Task[]) {
8787
// Don't log anything here, for any state, as it generates huge amounts of
8888
// console messages in large vaults, if Obsidian was opened with any
8989
// notes with tasks code blocks in Reading or Live Preview mode.
9090
const error = this.getters.query().error;
9191
if (state === State.Warm && error === undefined) {
92-
await this.renderQuerySearchResults(tasks, state, queryRendererParameters);
92+
await this.renderQuerySearchResults(tasks, state);
9393
} else if (error) {
9494
this.renderErrorMessage(error);
9595
} else {
@@ -106,11 +106,7 @@ export class HtmlQueryResultsRenderer {
106106
return content;
107107
}
108108

109-
private async renderQuerySearchResults(
110-
tasks: Task[],
111-
state: State.Warm,
112-
queryRendererParameters: QueryRendererParameters,
113-
) {
109+
private async renderQuerySearchResults(tasks: Task[], state: State.Warm) {
114110
const queryResult = this.explainAndPerformSearch(state, tasks);
115111

116112
if (queryResult.searchErrorMessage !== undefined) {
@@ -119,7 +115,7 @@ export class HtmlQueryResultsRenderer {
119115
return;
120116
}
121117

122-
await this.renderSearchResults(queryResult, queryRendererParameters);
118+
await this.renderSearchResults(queryResult);
123119
}
124120

125121
private explainAndPerformSearch(state: State.Warm, tasks: Task[]) {
@@ -138,13 +134,13 @@ export class HtmlQueryResultsRenderer {
138134
return queryResult;
139135
}
140136

141-
private async renderSearchResults(queryResult: QueryResult, queryRendererParameters: QueryRendererParameters) {
137+
private async renderSearchResults(queryResult: QueryResult) {
142138
const measureRender = new PerformanceTracker(`Render: ${this.getters.query().queryId} - ${this.filePath}`);
143139
measureRender.start();
144140

145141
this.addCopyButton(queryResult);
146142

147-
await this.addAllTaskGroups(queryResult.taskGroups, queryRendererParameters);
143+
await this.addAllTaskGroups(queryResult.taskGroups);
148144

149145
const totalTasksCount = queryResult.totalTasksCount;
150146
this.addTaskCount(queryResult);
@@ -187,10 +183,7 @@ export class HtmlQueryResultsRenderer {
187183
});
188184
}
189185

190-
private async addAllTaskGroups(
191-
tasksSortedLimitedGrouped: TaskGroups,
192-
queryRendererParameters: QueryRendererParameters,
193-
) {
186+
private async addAllTaskGroups(tasksSortedLimitedGrouped: TaskGroups) {
194187
for (const group of tasksSortedLimitedGrouped.groups) {
195188
// If there were no 'group by' instructions, group.groupHeadings
196189
// will be empty, and no headings will be added.
@@ -201,17 +194,14 @@ export class HtmlQueryResultsRenderer {
201194
const taskList = createAndAppendElement('ul', this.getContent());
202195
this.ulElementStack.push(taskList);
203196
try {
204-
await this.createTaskList(group.tasks, queryRendererParameters);
197+
await this.createTaskList(group.tasks);
205198
} finally {
206199
this.ulElementStack.pop();
207200
}
208201
}
209202
}
210203

211-
private async createTaskList(
212-
listItems: ListItem[],
213-
queryRendererParameters: QueryRendererParameters,
214-
): Promise<void> {
204+
private async createTaskList(listItems: ListItem[]): Promise<void> {
215205
const taskList = this.currentULElement();
216206
taskList.classList.add(
217207
'contains-task-list',
@@ -232,7 +222,7 @@ export class HtmlQueryResultsRenderer {
232222
* - Tasks are rendered in the order specified in 'sort by' instructions and default sort order.
233223
*/
234224
if (listItem instanceof Task) {
235-
await this.addTask(listItem, listItemIndex, queryRendererParameters, []);
225+
await this.addTask(listItem, listItemIndex, []);
236226
}
237227
} else {
238228
/* New-style rendering of tasks:
@@ -245,7 +235,7 @@ export class HtmlQueryResultsRenderer {
245235
* instructions and default sort order.
246236
* - Child tasks (and list items) are shown in their original order in their Markdown file.
247237
*/
248-
await this.addTaskOrListItemAndChildren(listItem, listItemIndex, queryRendererParameters, listItems);
238+
await this.addTaskOrListItemAndChildren(listItem, listItemIndex, listItems);
249239
}
250240
}
251241
}
@@ -271,12 +261,7 @@ export class HtmlQueryResultsRenderer {
271261
return this.renderedListItems.has(listItem);
272262
}
273263

274-
private async addTaskOrListItemAndChildren(
275-
listItem: ListItem,
276-
taskIndex: number,
277-
queryRendererParameters: QueryRendererParameters,
278-
listItems: ListItem[],
279-
) {
264+
private async addTaskOrListItemAndChildren(listItem: ListItem, taskIndex: number, listItems: ListItem[]) {
280265
if (this.alreadyRendered(listItem)) {
281266
return;
282267
}
@@ -285,32 +270,23 @@ export class HtmlQueryResultsRenderer {
285270
return;
286271
}
287272

288-
await this.createTaskOrListItem(listItem, taskIndex, queryRendererParameters);
273+
await this.createTaskOrListItem(listItem, taskIndex);
289274
this.renderedListItems.add(listItem);
290275

291276
for (const childTask of listItem.children) {
292277
this.renderedListItems.add(childTask);
293278
}
294279
}
295280

296-
private async createTaskOrListItem(
297-
listItem: ListItem,
298-
taskIndex: number,
299-
queryRendererParameters: QueryRendererParameters,
300-
): Promise<void> {
281+
private async createTaskOrListItem(listItem: ListItem, taskIndex: number): Promise<void> {
301282
if (listItem instanceof Task) {
302-
await this.addTask(listItem, taskIndex, queryRendererParameters, listItem.children);
283+
await this.addTask(listItem, taskIndex, listItem.children);
303284
} else {
304-
await this.addListItem(listItem, taskIndex, listItem.children, queryRendererParameters);
285+
await this.addListItem(listItem, taskIndex, listItem.children);
305286
}
306287
}
307288

308-
private async addListItem(
309-
listItem: ListItem,
310-
listItemIndex: number,
311-
children: ListItem[],
312-
queryRendererParameters: QueryRendererParameters,
313-
): Promise<void> {
289+
private async addListItem(listItem: ListItem, listItemIndex: number, children: ListItem[]): Promise<void> {
314290
const listItemElement = await this.taskLineRenderer.renderListItem(
315291
this.currentULElement(),
316292
listItem,
@@ -322,20 +298,15 @@ export class HtmlQueryResultsRenderer {
322298
const taskList1 = createAndAppendElement('ul', listItemElement);
323299
this.ulElementStack.push(taskList1);
324300
try {
325-
await this.createTaskList(children, queryRendererParameters);
301+
await this.createTaskList(children);
326302
} finally {
327303
this.ulElementStack.pop();
328304
}
329305
}
330306
}
331307

332-
private async addTask(
333-
task: Task,
334-
taskIndex: number,
335-
queryRendererParameters: QueryRendererParameters,
336-
children: ListItem[],
337-
): Promise<void> {
338-
const isFilenameUnique = this.isFilenameUnique({ task }, queryRendererParameters.allMarkdownFiles);
308+
private async addTask(task: Task, taskIndex: number, children: ListItem[]): Promise<void> {
309+
const isFilenameUnique = this.isFilenameUnique({ task }, this.queryRendererParameters.allMarkdownFiles());
339310
const listItem = await this.taskLineRenderer.renderTaskLine({
340311
parentUlElement: this.currentULElement(),
341312
task,
@@ -358,11 +329,11 @@ export class HtmlQueryResultsRenderer {
358329
const shortMode = this.getters.query().queryLayoutOptions.shortMode;
359330

360331
if (!this.getters.query().queryLayoutOptions.hideBacklinks) {
361-
this.addBacklinks(extrasSpan, task, shortMode, isFilenameUnique, queryRendererParameters);
332+
this.addBacklinks(extrasSpan, task, shortMode, isFilenameUnique);
362333
}
363334

364335
if (!this.getters.query().queryLayoutOptions.hideEditButton) {
365-
this.addEditButton(extrasSpan, task, queryRendererParameters);
336+
this.addEditButton(extrasSpan, task);
366337
}
367338

368339
if (!this.getters.query().queryLayoutOptions.hidePostponeButton && shouldShowPostponeButton(task)) {
@@ -376,21 +347,25 @@ export class HtmlQueryResultsRenderer {
376347
const taskList1 = createAndAppendElement('ul', listItem);
377348
this.ulElementStack.push(taskList1);
378349
try {
379-
await this.createTaskList(children, queryRendererParameters);
350+
await this.createTaskList(children);
380351
} finally {
381352
this.ulElementStack.pop();
382353
}
383354
}
384355
}
385356

386-
private addEditButton(listItem: HTMLElement, task: Task, queryRendererParameters: QueryRendererParameters) {
357+
private addEditButton(listItem: HTMLElement, task: Task) {
387358
const editTaskPencil = createAndAppendElement('a', listItem);
388359
editTaskPencil.classList.add('tasks-edit');
389360
editTaskPencil.title = 'Edit task';
390361
editTaskPencil.href = '#';
391362

392363
editTaskPencil.addEventListener('click', (event: MouseEvent) =>
393-
queryRendererParameters.editTaskPencilClickHandler(event, task, queryRendererParameters.allTasks),
364+
this.queryRendererParameters.editTaskPencilClickHandler(
365+
event,
366+
task,
367+
this.queryRendererParameters.allTasks(),
368+
),
394369
);
395370
}
396371

@@ -438,13 +413,7 @@ export class HtmlQueryResultsRenderer {
438413
);
439414
}
440415

441-
private addBacklinks(
442-
listItem: HTMLElement,
443-
task: Task,
444-
shortMode: boolean,
445-
isFilenameUnique: boolean | undefined,
446-
queryRendererParameters: QueryRendererParameters,
447-
) {
416+
private addBacklinks(listItem: HTMLElement, task: Task, shortMode: boolean, isFilenameUnique: boolean | undefined) {
448417
const backLink = createAndAppendElement('span', listItem);
449418
backLink.classList.add('tasks-backlink');
450419

@@ -472,11 +441,11 @@ export class HtmlQueryResultsRenderer {
472441

473442
// Go to the line the task is defined at
474443
link.addEventListener('click', async (ev: MouseEvent) => {
475-
await queryRendererParameters.backlinksClickHandler(ev, task);
444+
await this.queryRendererParameters.backlinksClickHandler(ev, task);
476445
});
477446

478447
link.addEventListener('mousedown', async (ev: MouseEvent) => {
479-
await queryRendererParameters.backlinksMousedownHandler(ev, task);
448+
await this.queryRendererParameters.backlinksMousedownHandler(ev, task);
480449
});
481450

482451
if (!shortMode) {

src/Renderer/QueryRenderer.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { TasksFile } from '../Scripting/TasksFile';
2121
import { DateFallback } from '../DateTime/DateFallback';
2222
import type { Task } from '../Task/Task';
2323
import { type BacklinksEventHandler, type EditButtonClickHandler, QueryResultsRenderer } from './QueryResultsRenderer';
24-
import { createAndAppendElement } from './TaskLineRenderer';
24+
import { TaskLineRenderer, createAndAppendElement } from './TaskLineRenderer';
2525

2626
type RenderParams = { tasks: Task[]; state: State };
2727

@@ -129,6 +129,14 @@ class QueryRenderChild extends MarkdownRenderChild {
129129
MarkdownRenderer.render,
130130
this,
131131
this.app,
132+
TaskLineRenderer.obsidianMarkdownRenderer,
133+
{
134+
allTasks: () => this.plugin.getTasks(),
135+
allMarkdownFiles: () => this.app.vault.getMarkdownFiles(),
136+
backlinksClickHandler: createBacklinksClickHandler(this.app),
137+
backlinksMousedownHandler: createBacklinksMousedownHandler(this.app),
138+
editTaskPencilClickHandler: createEditTaskPencilClickHandler(this.app),
139+
},
132140
);
133141

134142
this.queryResultsRenderer.query.debug('[render] QueryRenderChild.constructor() entered');
@@ -317,13 +325,7 @@ class QueryRenderChild extends MarkdownRenderChild {
317325

318326
private async renderResults(state: State, tasks: Task[]) {
319327
const content = createAndAppendElement('div', this.containerEl);
320-
await this.queryResultsRenderer.render(state, tasks, content, {
321-
allTasks: this.plugin.getTasks(),
322-
allMarkdownFiles: this.app.vault.getMarkdownFiles(),
323-
backlinksClickHandler: createBacklinksClickHandler(this.app),
324-
backlinksMousedownHandler: createBacklinksMousedownHandler(this.app),
325-
editTaskPencilClickHandler: createEditTaskPencilClickHandler(this.app),
326-
});
328+
await this.queryResultsRenderer.render(state, tasks, content);
327329

328330
this.containerEl.firstChild?.replaceWith(content);
329331
}

src/Renderer/QueryResultsRenderer.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { getQueryForQueryRenderer } from '../Query/QueryRendererHelper';
66
import type { TasksFile } from '../Scripting/TasksFile';
77
import type { Task } from '../Task/Task';
88
import { HtmlQueryResultsRenderer } from './HtmlQueryResultsRenderer';
9-
import { TaskLineRenderer, type TextRenderer } from './TaskLineRenderer';
9+
import type { TextRenderer } from './TaskLineRenderer';
1010

1111
export type BacklinksEventHandler = (ev: MouseEvent, task: Task) => Promise<void>;
1212
export type EditButtonClickHandler = (event: MouseEvent, task: Task, allTasks: Task[]) => void;
@@ -19,8 +19,8 @@ export type EditButtonClickHandler = (event: MouseEvent, task: Task, allTasks: T
1919
* for user interactions, like handling backlinks and editing tasks.
2020
*/
2121
export interface QueryRendererParameters {
22-
allTasks: Task[];
23-
allMarkdownFiles: TFile[];
22+
allTasks: () => Task[];
23+
allMarkdownFiles: () => TFile[];
2424
backlinksClickHandler: BacklinksEventHandler;
2525
backlinksMousedownHandler: BacklinksEventHandler;
2626
editTaskPencilClickHandler: EditButtonClickHandler;
@@ -68,7 +68,8 @@ export class QueryResultsRenderer {
6868
) => Promise<void>,
6969
obsidianComponent: Component | null,
7070
obsidianApp: App,
71-
textRenderer: TextRenderer = TaskLineRenderer.obsidianMarkdownRenderer,
71+
textRenderer: TextRenderer,
72+
queryRendererParameters: QueryRendererParameters,
7273
) {
7374
this.source = source;
7475
this._tasksFile = tasksFile;
@@ -88,11 +89,18 @@ export class QueryResultsRenderer {
8889
break;
8990
}
9091

91-
this.htmlRenderer = new HtmlQueryResultsRenderer(renderMarkdown, obsidianComponent, obsidianApp, textRenderer, {
92-
source: () => this.source,
93-
tasksFile: () => this._tasksFile,
94-
query: () => this.query,
95-
});
92+
this.htmlRenderer = new HtmlQueryResultsRenderer(
93+
renderMarkdown,
94+
obsidianComponent,
95+
obsidianApp,
96+
textRenderer,
97+
queryRendererParameters,
98+
{
99+
source: () => this.source,
100+
tasksFile: () => this._tasksFile,
101+
query: () => this.query,
102+
},
103+
);
96104
}
97105

98106
private makeQueryFromSourceAndTasksFile() {
@@ -130,14 +138,9 @@ export class QueryResultsRenderer {
130138
return this.tasksFile.path;
131139
}
132140

133-
public async render(
134-
state: State | State.Warm,
135-
tasks: Task[],
136-
content: HTMLDivElement,
137-
queryRendererParameters: QueryRendererParameters,
138-
) {
141+
public async render(state: State | State.Warm, tasks: Task[], content: HTMLDivElement) {
139142
this.htmlRenderer.content = content;
140-
await this.htmlRenderer.renderQuery(state, tasks, queryRendererParameters);
143+
await this.htmlRenderer.renderQuery(state, tasks);
141144
this.htmlRenderer.content = null;
142145
}
143146
}

0 commit comments

Comments
 (0)