From 91483a1372bbf4fe5a354ef1defe68bfdee40af1 Mon Sep 17 00:00:00 2001 From: Sam Collins <81678+smcllns@users.noreply.github.com> Date: Mon, 18 May 2026 14:15:56 -0700 Subject: [PATCH 1/2] feat: Support .htm extension alongside .html Closes #9 --- main.ts | 16 +++++++++++----- test/test.sh | 4 ++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/main.ts b/main.ts index b89412a..4ebbc0a 100644 --- a/main.ts +++ b/main.ts @@ -11,6 +11,10 @@ import { } from "obsidian"; const VIEW_TYPE_HTML = "html-docs"; +const HTML_EXTENSIONS = ["html", "htm"] as const; +type HtmlExtension = (typeof HTML_EXTENSIONS)[number]; +const isHtmlExtension = (ext: string): ext is HtmlExtension => + (HTML_EXTENSIONS as readonly string[]).includes(ext); interface EmbedContext { containerEl: HTMLElement; @@ -177,7 +181,7 @@ class HtmlView extends FileView { } canAcceptExtension(extension: string): boolean { - return extension === "html"; + return isHtmlExtension(extension); } async onLoadFile(file: TFile): Promise { @@ -258,7 +262,7 @@ export default class HtmlDocsPlugin extends Plugin { VIEW_TYPE_HTML, (leaf: WorkspaceLeaf) => new HtmlView(leaf), ); - this.registerExtensions(["html"], VIEW_TYPE_HTML); + this.registerExtensions([...HTML_EXTENSIONS], VIEW_TYPE_HTML); this.registerExistingHtmlTabNavigation(); this.registerThemeRefresh(); @@ -266,8 +270,10 @@ export default class HtmlDocsPlugin extends Plugin { if (!embedRegistry) { throw new Error("HTML Docs: app.embedRegistry is unavailable; cannot register HTML embeds."); } - embedRegistry.registerExtension("html", (context, file) => new HtmlEmbed(context.containerEl, this, file)); - this.register(() => embedRegistry.unregisterExtension("html")); + for (const ext of HTML_EXTENSIONS) { + embedRegistry.registerExtension(ext, (context, file) => new HtmlEmbed(context.containerEl, this, file)); + this.register(() => embedRegistry.unregisterExtension(ext)); + } // Obsidian hides files with unrecognized extensions in the file // explorer unless "Show all file types" is on; registering the @@ -359,7 +365,7 @@ export default class HtmlDocsPlugin extends Plugin { const file = this.app.metadataCache.getFirstLinkpathDest(linkpath, sourcePath) ?? this.app.vault.getAbstractFileByPath(linkpath); - return file instanceof TFile && file.extension === "html" ? file : null; + return file instanceof TFile && isHtmlExtension(file.extension) ? file : null; } private findOpenHtmlLeaf(file: TFile): WorkspaceLeaf | null { diff --git a/test/test.sh b/test/test.sh index 167c99a..3cbfb1a 100755 --- a/test/test.sh +++ b/test/test.sh @@ -447,9 +447,9 @@ check "theme class re-render flips scheme" "$(echo "$THEME_RERENDER" | jq -r '.a check "theme class re-render swaps blob" "$(echo "$THEME_RERENDER" | jq -r .rerendered)" "true" check "theme class test restores classes" "$(echo "$THEME_RERENDER" | jq -r .restored)" "true" check ".html routes to html-docs view" "$(echo "$REGISTRY" | jq -r .htmlViewType)" "html-docs" -check ".htm is not registered" "$(echo "$REGISTRY" | jq -r .htmViewType)" "null" +check ".htm routes to html-docs view" "$(echo "$REGISTRY" | jq -r .htmViewType)" "html-docs" check ".html embed registered" "$(echo "$REGISTRY" | jq -r .htmlEmbedRegistered)" "true" -check ".htm embed not registered" "$(echo "$REGISTRY" | jq -r .htmEmbedRegistered)" "false" +check ".htm embed registered" "$(echo "$REGISTRY" | jq -r .htmEmbedRegistered)" "true" check "open existing html tab from link" "$(echo "$DEDUPED_NAVIGATION" | jq -r .htmlLeafCount)" "1" check "existing html tab is focused" "$(echo "$DEDUPED_NAVIGATION" | jq -r .activeFile)" "$FIXTURE_REL" check "deferred html state is reused" "$(echo "$DEFERRED_STATE_NAVIGATION" | jq -r .activeIsFakeDeferredLeaf)" "true" From 9ed030761cf16f6688203434173bcb5fe7baa1ff Mon Sep 17 00:00:00 2001 From: Sam Collins <81678+smcllns@users.noreply.github.com> Date: Mon, 18 May 2026 15:07:01 -0700 Subject: [PATCH 2/2] refactor: Inline html/htm checks instead of const+type guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three-similar-lines beats a premature abstraction here — the set of HTML extension aliases is closed at html/htm. --- main.ts | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/main.ts b/main.ts index 4ebbc0a..6784e9c 100644 --- a/main.ts +++ b/main.ts @@ -11,10 +11,6 @@ import { } from "obsidian"; const VIEW_TYPE_HTML = "html-docs"; -const HTML_EXTENSIONS = ["html", "htm"] as const; -type HtmlExtension = (typeof HTML_EXTENSIONS)[number]; -const isHtmlExtension = (ext: string): ext is HtmlExtension => - (HTML_EXTENSIONS as readonly string[]).includes(ext); interface EmbedContext { containerEl: HTMLElement; @@ -181,7 +177,7 @@ class HtmlView extends FileView { } canAcceptExtension(extension: string): boolean { - return isHtmlExtension(extension); + return extension === "html" || extension === "htm"; } async onLoadFile(file: TFile): Promise { @@ -262,7 +258,7 @@ export default class HtmlDocsPlugin extends Plugin { VIEW_TYPE_HTML, (leaf: WorkspaceLeaf) => new HtmlView(leaf), ); - this.registerExtensions([...HTML_EXTENSIONS], VIEW_TYPE_HTML); + this.registerExtensions(["html", "htm"], VIEW_TYPE_HTML); this.registerExistingHtmlTabNavigation(); this.registerThemeRefresh(); @@ -270,10 +266,12 @@ export default class HtmlDocsPlugin extends Plugin { if (!embedRegistry) { throw new Error("HTML Docs: app.embedRegistry is unavailable; cannot register HTML embeds."); } - for (const ext of HTML_EXTENSIONS) { - embedRegistry.registerExtension(ext, (context, file) => new HtmlEmbed(context.containerEl, this, file)); - this.register(() => embedRegistry.unregisterExtension(ext)); - } + embedRegistry.registerExtension("html", (context, file) => new HtmlEmbed(context.containerEl, this, file)); + embedRegistry.registerExtension("htm", (context, file) => new HtmlEmbed(context.containerEl, this, file)); + this.register(() => { + embedRegistry.unregisterExtension("html"); + embedRegistry.unregisterExtension("htm"); + }); // Obsidian hides files with unrecognized extensions in the file // explorer unless "Show all file types" is on; registering the @@ -365,7 +363,7 @@ export default class HtmlDocsPlugin extends Plugin { const file = this.app.metadataCache.getFirstLinkpathDest(linkpath, sourcePath) ?? this.app.vault.getAbstractFileByPath(linkpath); - return file instanceof TFile && isHtmlExtension(file.extension) ? file : null; + return file instanceof TFile && (file.extension === "html" || file.extension === "htm") ? file : null; } private findOpenHtmlLeaf(file: TFile): WorkspaceLeaf | null {