인코딩 문제 해결
This commit is contained in:
parent
d1afcdea7a
commit
b943ba02c9
|
@ -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",
|
||||
|
|
15
package.json
15
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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue