From 0878bf1fc306503190ec1871fc9da194ccc0d051 Mon Sep 17 00:00:00 2001 From: Quorafind Date: Thu, 13 Nov 2025 11:38:49 +0800 Subject: [PATCH] refactor: improve code quality and use Obsidian API methods Replace manual style.display manipulation with Obsidian's built-in element visibility methods (.show(), .hide(), .toggle()) and improve code formatting consistency across components. Changes include: - Use .hide()/.show() instead of style.display = "none"/"" - Use .toggle() for visibility toggling - Use .toggleVisibility() for visibility property - Improve code formatting and indentation - Clean up trailing commas and spacing Affected components: KanbanColumn, FilterDropdown, TableHeader, TableView, ReadModeTextMark, DragManager, BulkDateOffsetModal, McpLogModal --- .../features/kanban/kanban-column.ts | 11 +++-- .../features/read-mode/ReadModeTextMark.ts | 6 +-- src/components/features/table/TableHeader.ts | 8 ++-- src/components/features/table/TableView.ts | 2 +- .../task/filter/in-view/filter-dropdown.ts | 48 +++++++++---------- src/components/ui/behavior/DragManager.ts | 2 +- .../ui/date-picker/BulkDateOffsetModal.ts | 6 ++- src/components/ui/modals/McpLogModal.ts | 2 +- 8 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/components/features/kanban/kanban-column.ts b/src/components/features/kanban/kanban-column.ts index e3b0f8c8..004b4db4 100644 --- a/src/components/features/kanban/kanban-column.ts +++ b/src/components/features/kanban/kanban-column.ts @@ -45,7 +45,7 @@ export class KanbanColumnComponent extends Component { override onload(): void { this.element = this.containerEl.createDiv({ cls: "tg-kanban-column", - attr: {"data-status-name": this.statusName}, + attr: { "data-status-name": this.statusName }, }); // Hide column if no tasks and hideEmptyColumns is enabled @@ -67,7 +67,9 @@ export class KanbanColumnComponent extends Component { this.plugin.settings.taskStatusMarks[this.statusName] || " "; checkbox.dataset.task = mark; // Only show the header checkbox as checked for the Completed column - const completedChars = (this.plugin.settings.taskStatuses?.completed || "x|X").split("|"); + const completedChars = ( + this.plugin.settings.taskStatuses?.completed || "x|X" + ).split("|"); checkbox.checked = completedChars.includes(mark); this.registerDomEvent(checkbox, "click", (event) => { @@ -122,7 +124,7 @@ export class KanbanColumnComponent extends Component { new QuickCaptureModal( this.app, this.plugin, - {status: taskStatusSymbol}, + { status: taskStatusSymbol }, true ).open(); }); @@ -256,11 +258,10 @@ export class KanbanColumnComponent extends Component { // Hide/show the column public setVisible(visible: boolean) { + this.element.toggle(visible); if (visible) { - this.element.style.display = ""; this.element.classList.remove("tg-kanban-column-hidden"); } else { - this.element.style.display = "none"; this.element.classList.add("tg-kanban-column-hidden"); } } diff --git a/src/components/features/read-mode/ReadModeTextMark.ts b/src/components/features/read-mode/ReadModeTextMark.ts index 10d29ef9..837cd2c2 100644 --- a/src/components/features/read-mode/ReadModeTextMark.ts +++ b/src/components/features/read-mode/ReadModeTextMark.ts @@ -1,4 +1,4 @@ -import TaskProgressBarPlugin from '@/index'; +import TaskProgressBarPlugin from "@/index"; import { Component, debounce, @@ -7,7 +7,7 @@ import { TFile, } from "obsidian"; import { getTasksAPI } from "@/utils"; -import { parseTaskLine } from '@/utils/task/task-operations'; +import { parseTaskLine } from "@/utils/task/task-operations"; // This component replaces standard checkboxes with custom text marks in reading view export function applyTaskTextMarks({ @@ -363,7 +363,7 @@ class TaskTextMark extends Component { // Show the original checkbox again if (this.originalCheckbox) { - this.originalCheckbox.style.display = ""; + this.originalCheckbox.show(); } super.unload(); diff --git a/src/components/features/table/TableHeader.ts b/src/components/features/table/TableHeader.ts index fe8bdd66..7574206d 100644 --- a/src/components/features/table/TableHeader.ts +++ b/src/components/features/table/TableHeader.ts @@ -163,17 +163,17 @@ export class TableHeader extends Component { this.columnBtn.title = t("Toggle column visibility"); const columnMenu = columnDropdown.createDiv("column-dropdown-menu"); - columnMenu.style.display = "none"; + columnMenu.toggle(false); this.registerDomEvent(this.columnBtn, "click", (e) => { e.stopPropagation(); - const isVisible = columnMenu.style.display !== "none"; - columnMenu.style.display = isVisible ? "none" : "block"; + const isVisible = !columnMenu.isShown(); + columnMenu.toggle(isVisible); }); // Close dropdown when clicking outside this.registerDomEvent(document, "click", () => { - columnMenu.style.display = "none"; + columnMenu.toggle(false); }); // Store column menu for later updates diff --git a/src/components/features/table/TableView.ts b/src/components/features/table/TableView.ts index 37739a67..46373952 100644 --- a/src/components/features/table/TableView.ts +++ b/src/components/features/table/TableView.ts @@ -279,7 +279,7 @@ export class TableView extends Component { // Create loading indicator this.loadingEl = this.tableWrapper.createDiv("task-table-loading"); this.loadingEl.textContent = t("Loading..."); - this.loadingEl.style.display = "none"; + this.loadingEl.toggle(false); } private initializeChildComponents() { diff --git a/src/components/features/task/filter/in-view/filter-dropdown.ts b/src/components/features/task/filter/in-view/filter-dropdown.ts index 387e0b22..ca16c479 100644 --- a/src/components/features/task/filter/in-view/filter-dropdown.ts +++ b/src/components/features/task/filter/in-view/filter-dropdown.ts @@ -15,7 +15,7 @@ export class FilterDropdown extends Component { constructor( options: FilterDropdownOptions, - private plugin: TaskProgressBarPlugin, + private plugin: TaskProgressBarPlugin ) { super(); this.options = options.options; @@ -27,10 +27,10 @@ export class FilterDropdown extends Component { override onload(): void { this.element = this.createDropdownElement(); this.searchInput = this.element.querySelector( - ".filter-dropdown-search", + ".filter-dropdown-search" ) as HTMLInputElement; this.listContainer = this.element.querySelector( - ".filter-dropdown-list", + ".filter-dropdown-list" ) as HTMLElement; this.renderCategoryList(); @@ -89,8 +89,8 @@ export class FilterDropdown extends Component { this.element.style.display = "flex"; // Ensure it's laid out const dropdownHeight = this.element.offsetHeight; const dropdownWidth = this.element.offsetWidth; - this.element.style.display = ""; // Reset display - this.element.style.visibility = ""; // Make visible again + this.element.show(); // Reset display + this.element.toggleVisibility(true); // Default position below the anchor let top = rect.bottom + 8; @@ -132,7 +132,7 @@ export class FilterDropdown extends Component { true, // has arrow false, // not back button false, // not value item - category.id, + category.id ); this.listContainer.appendChild(item); }); @@ -154,7 +154,7 @@ export class FilterDropdown extends Component { this.renderCategoryList(); }, false, // no arrow - true, // is back button + true // is back button ); this.listContainer.appendChild(backButton); @@ -172,18 +172,18 @@ export class FilterDropdown extends Component { private renderFilterValues( values: string[], - searchTerm: string = "", + searchTerm: string = "" ): void { // Remove existing value items and empty state, keeping back button and separator const itemsToRemove = this.listContainer.querySelectorAll( - ".filter-dropdown-value-item, .filter-dropdown-empty", + ".filter-dropdown-value-item, .filter-dropdown-empty" ); itemsToRemove.forEach((item) => item.remove()); const filteredValues = searchTerm ? values.filter((value) => - value.toLowerCase().includes(searchTerm.toLowerCase()), - ) + value.toLowerCase().includes(searchTerm.toLowerCase()) + ) : values; if (filteredValues.length === 0) { @@ -203,7 +203,7 @@ export class FilterDropdown extends Component { }, false, // no arrow false, // not back button - true, // is value item + true // is value item ); this.listContainer.appendChild(item); }); @@ -218,7 +218,7 @@ export class FilterDropdown extends Component { hasArrow: boolean = false, isBackButton: boolean = false, isValueItem: boolean = false, - categoryId: string = "", + categoryId: string = "" ): HTMLElement { const item = createEl("div", { cls: "filter-dropdown-item" }); if (isBackButton) item.classList.add("filter-dropdown-back"); @@ -265,14 +265,14 @@ export class FilterDropdown extends Component { if (this.currentCategory) { this.renderFilterValues( this.currentCategory.options, - searchTerm, + searchTerm ); } else { this.filterCategoryList(searchTerm); } }, 150, - false, // Changed to false: debounce triggers after user stops typing + false // Changed to false: debounce triggers after user stops typing ); this.registerDomEvent(this.searchInput, "input", debouncedSearch); @@ -317,7 +317,7 @@ export class FilterDropdown extends Component { // Go back if backspace is pressed in empty search within a category const backButton = this.listContainer.querySelector( - ".filter-dropdown-back", + ".filter-dropdown-back" ); backButton?.click(); // Simulate click on back button } @@ -335,8 +335,8 @@ export class FilterDropdown extends Component { (category) => category.label.toLowerCase().includes(lowerSearchTerm) || category.options.some((option) => - option.toLowerCase().includes(lowerSearchTerm), - ), + option.toLowerCase().includes(lowerSearchTerm) + ) ); if (filteredOptions.length === 0) { @@ -347,7 +347,7 @@ export class FilterDropdown extends Component { } else { filteredOptions.forEach((category) => { const matchingValues = category.options.filter((option) => - option.toLowerCase().includes(lowerSearchTerm), + option.toLowerCase().includes(lowerSearchTerm) ); const itemContainer = this.listContainer.createEl("div", { @@ -385,7 +385,7 @@ export class FilterDropdown extends Component { e.preventDefault(); this.onSelect(category.id, value); } - }, + } ); }); } else { @@ -393,7 +393,7 @@ export class FilterDropdown extends Component { const categoryItem = this.createListItem( category.label, () => this.showCategoryValues(category), - true, // has arrow + true // has arrow ); itemContainer.appendChild(categoryItem); } @@ -405,13 +405,13 @@ export class FilterDropdown extends Component { private getVisibleFocusableItems(): HTMLElement[] { return Array.from( this.listContainer.querySelectorAll( - `.filter-dropdown-item, .filter-dropdown-value-preview`, - ), + `.filter-dropdown-item, .filter-dropdown-value-preview` + ) ).filter( (el) => el.offsetParent !== null && window.getComputedStyle(el).visibility !== "hidden" && - window.getComputedStyle(el).display !== "none", + window.getComputedStyle(el).display !== "none" ); } diff --git a/src/components/ui/behavior/DragManager.ts b/src/components/ui/behavior/DragManager.ts index cfb7bb97..334a3021 100644 --- a/src/components/ui/behavior/DragManager.ts +++ b/src/components/ui/behavior/DragManager.ts @@ -342,7 +342,7 @@ export class DragManager extends Component { const originalDisplay = elementToHide.style.display; // Only hide if it's the clone, otherwise elementFromPoint gets the original element itself if (this.options.cloneElement) { - elementToHide.style.display = "none"; + elementToHide.hide(); } const elementUnderPointer = document.elementFromPoint( diff --git a/src/components/ui/date-picker/BulkDateOffsetModal.ts b/src/components/ui/date-picker/BulkDateOffsetModal.ts index b82a0cdf..8f6a8452 100644 --- a/src/components/ui/date-picker/BulkDateOffsetModal.ts +++ b/src/components/ui/date-picker/BulkDateOffsetModal.ts @@ -80,12 +80,14 @@ export class BulkDateOffsetModal extends Modal { }); customSection.style.marginTop = "var(--size-4-6)"; customSection.style.paddingTop = "var(--size-4-3)"; - customSection.style.borderTop = "1px solid var(--background-modifier-border)"; + customSection.style.borderTop = + "1px solid var(--background-modifier-border)"; const customLabel = customSection.createEl("label", { text: "Custom offset (days):", }); - customLabel.style.display = "block"; + // customLabel.style.display = "block"; + customLabel.show(); customLabel.style.marginBottom = "var(--size-2-3)"; const customInputContainer = customSection.createDiv(); diff --git a/src/components/ui/modals/McpLogModal.ts b/src/components/ui/modals/McpLogModal.ts index eba03756..df0e3f96 100644 --- a/src/components/ui/modals/McpLogModal.ts +++ b/src/components/ui/modals/McpLogModal.ts @@ -175,7 +175,7 @@ export class McpLogModal extends Modal { const detailsEl = logEntry.createDiv({ cls: "mcp-log-details", }); - detailsEl.style.display = "none"; + detailsEl.hide(); // Arguments if (log.arguments && Object.keys(log.arguments).length > 0) {