Skip to content

Commit 770fb26

Browse files
authored
Merge pull request #3678 from ilandikov/refactor/create-HTMLLIElement
refactor: create `HTMLLIElement` outside of `TaskLineRenderer` methods
2 parents 1638ff5 + 6bb6001 commit 770fb26

File tree

4 files changed

+28
-54
lines changed

4 files changed

+28
-54
lines changed

src/Obsidian/InlineRenderer.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { TaskLayoutOptions } from '../Layout/TaskLayoutOptions';
55
import { QueryLayoutOptions } from '../Layout/QueryLayoutOptions';
66
import { TasksFile } from '../Scripting/TasksFile';
77
import { Task } from '../Task/Task';
8-
import { TaskLineRenderer } from '../Renderer/TaskLineRenderer';
8+
import { TaskLineRenderer, createAndAppendElement } from '../Renderer/TaskLineRenderer';
99
import { TaskLocation } from '../Task/TaskLocation';
1010

1111
/**
@@ -137,8 +137,9 @@ export class InlineRenderer {
137137
}
138138
const dataLine: string = renderedElement.getAttr('data-line') ?? '0';
139139
const taskIndex: number = Number.parseInt(dataLine, 10);
140-
const taskElement = await taskLineRenderer.renderTaskLine({
141-
parentUlElement: element,
140+
const taskElement = createAndAppendElement('li', element);
141+
await taskLineRenderer.renderTaskLine({
142+
li: taskElement,
142143
task,
143144
taskIndex,
144145
isTaskInQueryFile: true,

src/Renderer/HtmlQueryResultsRenderer.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,9 @@ export class HtmlQueryResultsRenderer extends QueryResultsRendererBase {
131131
}
132132

133133
protected async addListItem(listItem: ListItem, listItemIndex: number, children: ListItem[]): Promise<void> {
134-
const listItemElement = await this.taskLineRenderer.renderListItem(
135-
this.currentULElement(),
136-
listItem,
137-
listItemIndex,
138-
);
134+
const taskList = this.currentULElement();
135+
const listItemElement = createAndAppendElement('li', taskList);
136+
await this.taskLineRenderer.renderListItem(listItemElement, listItem, listItemIndex);
139137

140138
if (children.length > 0) {
141139
// TODO re-extract the method to include this back
@@ -151,8 +149,10 @@ export class HtmlQueryResultsRenderer extends QueryResultsRendererBase {
151149

152150
protected async addTask(task: Task, taskIndex: number, children: ListItem[]): Promise<void> {
153151
const isFilenameUnique = this.isFilenameUnique({ task }, this.queryRendererParameters.allMarkdownFiles());
154-
const listItem = await this.taskLineRenderer.renderTaskLine({
155-
parentUlElement: this.currentULElement(),
152+
const parentUlElement = this.currentULElement();
153+
const listItem = createAndAppendElement('li', parentUlElement);
154+
await this.taskLineRenderer.renderTaskLine({
155+
li: listItem,
156156
task,
157157
taskIndex,
158158
isTaskInQueryFile: this.filePath === task.path,

src/Renderer/TaskLineRenderer.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ import type { Moment } from 'moment';
22
import { type App, Component, MarkdownRenderer } from 'obsidian';
33
import { GlobalFilter } from '../Config/GlobalFilter';
44
import { TASK_FORMATS, getSettings } from '../Config/Settings';
5+
import type { AllTaskDateFields } from '../DateTime/DateFieldTypes';
6+
import { splitDateText } from '../DateTime/Postponer';
57
import type { QueryLayoutOptions } from '../Layout/QueryLayoutOptions';
68
import { TaskLayoutComponent, type TaskLayoutOptions } from '../Layout/TaskLayoutOptions';
79
import { replaceTaskWithTasks } from '../Obsidian/File';
810
import { StatusRegistry } from '../Statuses/StatusRegistry';
11+
import type { ListItem } from '../Task/ListItem';
912
import { Task } from '../Task/Task';
1013
import { TaskRegularExpressions } from '../Task/TaskRegularExpressions';
14+
import { DateMenu } from '../ui/Menus/DateMenu';
15+
import { promptForDate } from '../ui/Menus/DatePicker';
1116
import { StatusMenu } from '../ui/Menus/StatusMenu';
12-
import type { AllTaskDateFields } from '../DateTime/DateFieldTypes';
1317
import { defaultTaskSaver, showMenu } from '../ui/Menus/TaskEditingMenu';
14-
import { promptForDate } from '../ui/Menus/DatePicker';
15-
import { splitDateText } from '../DateTime/Postponer';
16-
import { DateMenu } from '../ui/Menus/DateMenu';
17-
import type { ListItem } from '../Task/ListItem';
1818
import { TaskFieldRenderer } from './TaskFieldRenderer';
1919

2020
/**
@@ -126,7 +126,7 @@ export class TaskLineRenderer {
126126
*
127127
* @returns an HTML rendered List Item element (LI) for a task.
128128
* @note Output is based on the {@link DefaultTaskSerializer}'s format, with default (emoji) symbols
129-
* @param parentUlElement HTML element where the task shall be rendered.
129+
* @param li HTML element for the rendered task.
130130
* @param task The task to be rendered.
131131
* @param taskIndex Task's index in the list. This affects `data-line` data attributes of the list item.
132132
* @param isTaskInQueryFile
@@ -135,19 +135,18 @@ export class TaskLineRenderer {
135135
* the file name only. If set to `true`, the full path will be returned.
136136
*/
137137
public async renderTaskLine({
138-
parentUlElement,
138+
li,
139139
task,
140140
taskIndex,
141141
isTaskInQueryFile,
142142
isFilenameUnique,
143143
}: {
144-
parentUlElement: HTMLElement;
144+
li: HTMLLIElement;
145145
task: Task;
146146
taskIndex: number;
147147
isTaskInQueryFile: boolean;
148148
isFilenameUnique?: boolean;
149-
}): Promise<HTMLLIElement> {
150-
const li = createAndAppendElement('li', parentUlElement);
149+
}): Promise<void> {
151150
li.classList.add('task-list-item', 'plugin-tasks-list-item');
152151

153152
const textSpan = createAndAppendElement('span', li);
@@ -202,8 +201,6 @@ export class TaskLineRenderer {
202201
if (this.queryLayoutOptions.shortMode) {
203202
this.addTooltip(task, textSpan, isFilenameUnique);
204203
}
205-
206-
return li;
207204
}
208205

209206
private async taskToHtml(
@@ -459,9 +456,7 @@ export class TaskLineRenderer {
459456
});
460457
}
461458

462-
public async renderListItem(taskList: HTMLUListElement, listItem: ListItem, listItemIndex: number) {
463-
const li = createAndAppendElement('li', taskList);
464-
459+
public async renderListItem(li: HTMLLIElement, listItem: ListItem, listItemIndex: number): Promise<HTMLLIElement> {
465460
if (listItem.statusCharacter) {
466461
const checkbox = createAndAppendElement('input', li);
467462
checkbox.classList.add('task-list-item-checkbox');

tests/Renderer/TaskLineRenderer.test.ts

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { QueryLayoutOptions } from '../../src/Layout/QueryLayoutOptions';
1010
import { TaskLayoutComponent, TaskLayoutOptions, taskLayoutComponents } from '../../src/Layout/TaskLayoutOptions';
1111
import { DateParser } from '../../src/DateTime/DateParser';
1212
import type { TextRenderer } from '../../src/Renderer/TaskLineRenderer';
13-
import { TaskLineRenderer } from '../../src/Renderer/TaskLineRenderer';
13+
import { TaskLineRenderer, createAndAppendElement } from '../../src/Renderer/TaskLineRenderer';
1414
import type { Task } from '../../src/Task/Task';
1515
import { TaskRegularExpressions } from '../../src/Task/TaskRegularExpressions';
1616
import { verifyWithFileExtension } from '../TestingTools/ApprovalTestHelpers';
@@ -47,12 +47,16 @@ async function renderListItem(
4747
taskLayoutOptions: taskLayoutOptions ?? new TaskLayoutOptions(),
4848
queryLayoutOptions: queryLayoutOptions ?? new QueryLayoutOptions(),
4949
});
50-
return await taskLineRenderer.renderTaskLine({
51-
parentUlElement: document.createElement('div'),
50+
const divElement = document.createElement('div');
51+
const li = createAndAppendElement('li', divElement);
52+
await taskLineRenderer.renderTaskLine({
53+
li: li,
5254
task: task,
5355
taskIndex: 0,
5456
isTaskInQueryFile: true,
5557
});
58+
59+
return li;
5660
}
5761

5862
function getTextSpan(listItem: HTMLElement) {
@@ -86,32 +90,6 @@ afterEach(() => {
8690
});
8791

8892
describe('task line rendering - HTML', () => {
89-
it('should render only one List Item for the UL and return it with renderTaskLine()', async () => {
90-
const ulElement = document.createElement('ul');
91-
const taskLineRenderer = new TaskLineRenderer({
92-
textRenderer: mockTextRenderer,
93-
obsidianApp: mockApp,
94-
obsidianComponent: null,
95-
taskLayoutOptions: new TaskLayoutOptions(),
96-
queryLayoutOptions: new QueryLayoutOptions(),
97-
});
98-
const listItem = await taskLineRenderer.renderTaskLine({
99-
parentUlElement: ulElement,
100-
task: new TaskBuilder().build(),
101-
taskIndex: 0,
102-
isTaskInQueryFile: true,
103-
});
104-
105-
// Just one element
106-
expect(ulElement.children.length).toEqual(1);
107-
108-
// It is the rendered one
109-
expect(ulElement.children[0]).toEqual(listItem);
110-
111-
// And it is a ListItem
112-
expect(listItem.nodeName).toEqual('LI');
113-
});
114-
11593
it('creates the correct span structure for a basic task inside a List Item', async () => {
11694
const taskLine = '- [ ] This is a simple task';
11795
const task = fromLine({

0 commit comments

Comments
 (0)