Skip to content

Commit 5342a35

Browse files
authored
Merge pull request #3681 from ilandikov/refactor/simplify-HTMLQRR
refactor: simplify `HtmlQueryResultsRenderer` and `QueryResultsRendererBase`
2 parents 508a831 + d53f057 commit 5342a35

File tree

3 files changed

+23
-40
lines changed

3 files changed

+23
-40
lines changed

src/Renderer/HtmlQueryResultsRenderer.ts

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { postponeButtonTitle, shouldShowPostponeButton } from '../DateTime/Postp
33
import { QueryLayout } from '../Layout/QueryLayout';
44
import { TaskLayout } from '../Layout/TaskLayout';
55
import type { GroupDisplayHeading } from '../Query/Group/GroupDisplayHeading';
6-
import type { TaskGroup } from '../Query/Group/TaskGroup';
76
import type { QueryResult } from '../Query/QueryResult';
87
import type { ListItem } from '../Task/ListItem';
98
import type { Task } from '../Task/Task';
@@ -13,6 +12,13 @@ import type { QueryRendererParameters } from './QueryResultsRenderer';
1312
import { QueryResultsRendererBase, type QueryResultsRendererGetters } from './QueryResultsRendererBase';
1413
import { TaskLineRenderer, type TextRenderer, createAndAppendElement } from './TaskLineRenderer';
1514

15+
/**
16+
* HTML-specific implementation of {@link QueryResultsRendererBase} abstract class.
17+
*
18+
* @example
19+
* this.htmlRenderer.content = content;
20+
* await this.htmlRenderer.renderQuery(state, tasks);
21+
*/
1622
export class HtmlQueryResultsRenderer extends QueryResultsRendererBase {
1723
// Renders the description in TaskLineRenderer:
1824
protected readonly textRenderer;
@@ -22,13 +28,13 @@ export class HtmlQueryResultsRenderer extends QueryResultsRendererBase {
2228
protected readonly obsidianComponent: Component | null;
2329
protected readonly obsidianApp: App;
2430

25-
// TODO access this via getContent() for now
26-
public content: HTMLDivElement | null = null;
27-
2831
private readonly taskLineRenderer: TaskLineRenderer;
2932

33+
// document.createElement() creates dummy elements that must be overwritten later
34+
// with the values of elements that will be rendered
35+
public content: HTMLDivElement = document.createElement('div');
3036
private readonly ulElementStack: HTMLUListElement[] = [];
31-
private readonly liElementStack: HTMLLIElement[] = [];
37+
private lastLIElement: HTMLLIElement = document.createElement('li');
3238

3339
private readonly queryRendererParameters: QueryRendererParameters;
3440

@@ -63,15 +69,6 @@ export class HtmlQueryResultsRenderer extends QueryResultsRendererBase {
6369
});
6470
}
6571

66-
private getContent() {
67-
// TODO remove throw
68-
const content = this.content;
69-
if (!content) {
70-
throw new Error('Must initialize content field before calling renderQuery()');
71-
}
72-
return content;
73-
}
74-
7572
protected renderSearchResultsHeader(queryResult: QueryResult): void {
7673
this.addCopyButton(queryResult);
7774
}
@@ -81,22 +78,22 @@ export class HtmlQueryResultsRenderer extends QueryResultsRendererBase {
8178
}
8279

8380
protected renderErrorMessage(errorMessage: string) {
84-
const container = createAndAppendElement('div', this.getContent());
81+
const container = createAndAppendElement('div', this.content);
8582
container.innerHTML = '<pre>' + `Tasks query: ${errorMessage.replace(/\n/g, '<br>')}` + '</pre>';
8683
}
8784

8885
protected renderLoadingMessage() {
89-
this.getContent().textContent = 'Loading Tasks ...';
86+
this.content.textContent = 'Loading Tasks ...';
9087
}
9188

9289
protected renderExplanation(explanation: string | null) {
93-
const explanationsBlock = createAndAppendElement('pre', this.getContent());
90+
const explanationsBlock = createAndAppendElement('pre', this.content);
9491
explanationsBlock.classList.add('plugin-tasks-query-explanation');
9592
explanationsBlock.textContent = explanation;
9693
}
9794

9895
private addCopyButton(queryResult: QueryResult) {
99-
const copyButton = createAndAppendElement('button', this.getContent());
96+
const copyButton = createAndAppendElement('button', this.content);
10097
copyButton.textContent = 'Copy results';
10198
copyButton.classList.add('plugin-tasks-copy-button');
10299
copyButton.addEventListener('click', async () => {
@@ -105,12 +102,9 @@ export class HtmlQueryResultsRenderer extends QueryResultsRendererBase {
105102
});
106103
}
107104

108-
protected async addTaskGroup(group: TaskGroup): Promise<void> {
109-
await this.addTaskList(group.tasks);
110-
}
111-
112105
protected beginTaskList(): void {
113-
const taskListContainer = this.ulElementStack.length > 0 ? this.currentLIElement() : this.getContent();
106+
const isFirstTaskListInContainer = this.ulElementStack.length === 0;
107+
const taskListContainer = isFirstTaskListInContainer ? this.content : this.lastLIElement;
114108
const taskList = createAndAppendElement('ul', taskListContainer);
115109

116110
taskList.classList.add(
@@ -134,19 +128,16 @@ export class HtmlQueryResultsRenderer extends QueryResultsRendererBase {
134128

135129
protected beginListItem() {
136130
const taskList = this.currentULElement();
137-
const listItemElement = createAndAppendElement('li', taskList);
138-
this.liElementStack.push(listItemElement);
131+
this.lastLIElement = createAndAppendElement('li', taskList);
139132
}
140133

141134
protected async addListItem(listItem: ListItem, listItemIndex: number): Promise<void> {
142-
const listItemElement = this.currentLIElement();
143-
144-
await this.taskLineRenderer.renderListItem(listItemElement, listItem, listItemIndex);
135+
await this.taskLineRenderer.renderListItem(this.lastLIElement, listItem, listItemIndex);
145136
}
146137

147138
protected async addTask(task: Task, taskIndex: number): Promise<void> {
148139
const isFilenameUnique = this.isFilenameUnique({ task }, this.queryRendererParameters.allMarkdownFiles());
149-
const listItem = this.currentLIElement();
140+
const listItem = this.lastLIElement;
150141

151142
await this.taskLineRenderer.renderTaskLine({
152143
li: listItem,
@@ -215,7 +206,7 @@ export class HtmlQueryResultsRenderer extends QueryResultsRendererBase {
215206
header = 'h5';
216207
}
217208

218-
const headerEl = createAndAppendElement(header, this.getContent());
209+
const headerEl = createAndAppendElement(header, this.content);
219210
headerEl.classList.add('tasks-group-heading');
220211

221212
if (this.obsidianComponent === null) {
@@ -298,7 +289,7 @@ export class HtmlQueryResultsRenderer extends QueryResultsRendererBase {
298289

299290
private addTaskCount(queryResult: QueryResult) {
300291
if (!this.getters.query().queryLayoutOptions.hideTaskCount) {
301-
const taskCount = createAndAppendElement('div', this.getContent());
292+
const taskCount = createAndAppendElement('div', this.content);
302293
taskCount.classList.add('task-count');
303294
taskCount.textContent = queryResult.totalTasksCountDisplayText();
304295
}
@@ -333,8 +324,4 @@ export class HtmlQueryResultsRenderer extends QueryResultsRendererBase {
333324
private currentULElement(): HTMLUListElement {
334325
return this.ulElementStack[this.ulElementStack.length - 1];
335326
}
336-
337-
private currentLIElement() {
338-
return this.liElementStack[this.liElementStack.length - 1];
339-
}
340327
}

src/Renderer/QueryResultsRenderer.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,5 @@ export class QueryResultsRenderer {
141141
public async render(state: State | State.Warm, tasks: Task[], content: HTMLDivElement) {
142142
this.htmlRenderer.content = content;
143143
await this.htmlRenderer.renderQuery(state, tasks);
144-
this.htmlRenderer.content = null;
145144
}
146145
}

src/Renderer/QueryResultsRendererBase.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { PerformanceTracker } from '../lib/PerformanceTracker';
1010
import { explainResults } from '../Query/QueryRendererHelper';
1111
import { GlobalFilter } from '../Config/GlobalFilter';
1212
import { GlobalQuery } from '../Config/GlobalQuery';
13-
import type { TaskGroup } from '../Query/Group/TaskGroup';
1413

1514
/**
1615
* Because properties in QueryResultsRenderer may be modified during the lifetime of this class,
@@ -116,12 +115,10 @@ export abstract class QueryResultsRendererBase {
116115
await this.addGroupHeadings(group.groupHeadings);
117116

118117
this.addedListItems.clear();
119-
await this.addTaskGroup(group);
118+
await this.addTaskList(group.tasks);
120119
}
121120
}
122121

123-
protected abstract addTaskGroup(group: TaskGroup): Promise<void>;
124-
125122
protected async addTaskList(listItems: ListItem[]): Promise<void> {
126123
this.beginTaskList();
127124

0 commit comments

Comments
 (0)