diff --git a/package-lock.json b/package-lock.json index c3a2916..2717779 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,16 @@ { - "name": "obsidian-sample-plugin", + "name": "link-thumbnail-plugin", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "obsidian-sample-plugin", + "name": "link-thumbnail-plugin", "version": "1.0.0", "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3" + }, "devDependencies": { "@codemirror/commands": "6.0.0", "@codemirror/language": "https://github.com/lishid/cm-language", @@ -1587,6 +1590,17 @@ "node": ">=8" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -2087,6 +2101,11 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", diff --git a/package.json b/package.json index 1d688a6..879888d 100644 --- a/package.json +++ b/package.json @@ -12,18 +12,21 @@ "author": "", "license": "MIT", "devDependencies": { + "@codemirror/commands": "6.0.0", + "@codemirror/language": "https://github.com/lishid/cm-language", + "@codemirror/search": "6.0.0", + "@codemirror/view": "6.0.0", "@types/node": "^16.11.6", "@typescript-eslint/eslint-plugin": "5.29.0", "@typescript-eslint/parser": "5.29.0", "builtin-modules": "3.3.0", + "compare-versions": "^4.1.3", "esbuild": "0.17.3", "obsidian": "latest", "tslib": "2.4.0", - "typescript": "4.7.4", - "compare-versions": "^4.1.3", - "@codemirror/search": "6.0.0", - "@codemirror/view": "6.0.0", - "@codemirror/commands": "6.0.0", - "@codemirror/language": "https://github.com/lishid/cm-language" + "typescript": "4.7.4" + }, + "dependencies": { + "iconv-lite": "^0.6.3" } } diff --git a/src/EnbedDecoratiion.ts b/src/EnbedDecoratiion.ts index 8319056..f2626de 100644 --- a/src/EnbedDecoratiion.ts +++ b/src/EnbedDecoratiion.ts @@ -59,7 +59,7 @@ class StatefulDecorationSet { linkEl.addEventListener("click", (e) => e.stopPropagation()); } }); - deco = this.decoCache[token.value] = Decoration.replace({widget: new EmojiWidget(div), block: true}); + deco = this.decoCache[token.value] = Decoration.replace({widget: new ogLinkWidget(div), block: true}); } decorations.push(deco.range(token.from, token.to)); } @@ -147,7 +147,7 @@ function defineStatefulDecoration(): { return {update, field}; } -class EmojiWidget extends WidgetType { +class ogLinkWidget extends WidgetType { private readonly source: HTMLDivElement; constructor(source: HTMLDivElement) { @@ -155,7 +155,7 @@ class EmojiWidget extends WidgetType { this.source = source; } - eq(other: EmojiWidget) { + eq(other: ogLinkWidget) { return other == this; } diff --git a/src/LinkThumbnailWidgetParams.ts b/src/LinkThumbnailWidgetParams.ts index 3d56e87..ac22cb8 100644 --- a/src/LinkThumbnailWidgetParams.ts +++ b/src/LinkThumbnailWidgetParams.ts @@ -1,4 +1,5 @@ import { requestUrl } from "obsidian"; +import { decode } from 'iconv-lite'; // url 정규식 const urlRegex = new RegExp("^(http:\\/\\/www\\.|https:\\/\\/www\\.|http:\\/\\/|https:\\/\\/)?[a-z0-9]+([\\-.]{1}[a-z0-9]+)*\\.[a-z]{2,5}(:[0-9]{1,5})?(\\/.*)?$"); @@ -6,17 +7,30 @@ const urlRegex = new RegExp("^(http:\\/\\/www\\.|https:\\/\\/www\\.|http:\\/\\/| export async function LinkThumbnailWidgetParams(url: string) { const urlArr = urlRegex.exec(url); if (urlArr) { - try { - const response = await requestUrl(url); - const contextType = response.headers["content-type"]; - if (contextType.toLocaleLowerCase().trim() === "text/html;charset=ms949") { - return null; + try { + + const response = await requestUrl({ + url:url, + throw: true + }); + if (response && response.headers && response.headers['content-type'] && !response.headers['content-type']?.includes('text/')) { + throw new Error('Page must return a header content-type with text/'); } - const htmlString = response.text; + // 인코딩 문제 해결 + const bodyArrayBuffer = response.arrayBuffer; + const charset = response.headers["content-type"].replace("text/html;charset=","").toLowerCase(); + + let body; + if (charset.trim() === "utf-8") { + body = Buffer.from(bodyArrayBuffer).toString('utf-8'); + } else { + body = decode(Buffer.from(bodyArrayBuffer), charset); + } + const parser = new DOMParser(); - const document = parser.parseFromString(htmlString, 'text/html'); - + const document = parser.parseFromString(body, 'text/html'); + const ogTitle = document.querySelector("meta[property='og:title']")?.getAttribute("content") || document.querySelector("title")?.textContent || ""; const ogDescription = document.querySelector("meta[property='og:description']")?.getAttribute("content") || ""; let ogImage = document.querySelector("meta[property='og:image']")?.getAttribute("content") || ""; @@ -39,9 +53,8 @@ export async function LinkThumbnailWidgetParams(url: string) { ` return result; } catch (error) { - console.error(error); - return null; + throw new Error(error); } } return null -} \ No newline at end of file +} diff --git a/src/PostProcessor.ts b/src/PostProcessor.ts index c2fb5d1..d27088f 100644 --- a/src/PostProcessor.ts +++ b/src/PostProcessor.ts @@ -16,10 +16,7 @@ export class PostProcessor { // 링크 변환 const linkEls:Element[] = element.findAll("a.external-link:not(.cm-formatting, .markdown-rendered)"); for (const linkEl of linkEls) { - // dataview 클래스를 가진 부모 요소를 확인합니다. - if (linkEl.closest(".dataview") !== null) { - continue; - } + const url = linkEl.innerHTML; const params = await LinkThumbnailWidgetParams(url); if (params != null) {