인코딩 문제 해결
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",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "obsidian-sample-plugin",
|
"name": "link-thumbnail-plugin",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"iconv-lite": "^0.6.3"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@codemirror/commands": "6.0.0",
|
"@codemirror/commands": "6.0.0",
|
||||||
"@codemirror/language": "https://github.com/lishid/cm-language",
|
"@codemirror/language": "https://github.com/lishid/cm-language",
|
||||||
|
@ -1587,6 +1590,17 @@
|
||||||
"node": ">=8"
|
"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": {
|
"node_modules/ignore": {
|
||||||
"version": "5.3.1",
|
"version": "5.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
|
||||||
|
@ -2087,6 +2101,11 @@
|
||||||
"queue-microtask": "^1.2.2"
|
"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": {
|
"node_modules/semver": {
|
||||||
"version": "7.6.0",
|
"version": "7.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||||
|
|
15
package.json
15
package.json
|
@ -12,18 +12,21 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"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",
|
"@types/node": "^16.11.6",
|
||||||
"@typescript-eslint/eslint-plugin": "5.29.0",
|
"@typescript-eslint/eslint-plugin": "5.29.0",
|
||||||
"@typescript-eslint/parser": "5.29.0",
|
"@typescript-eslint/parser": "5.29.0",
|
||||||
"builtin-modules": "3.3.0",
|
"builtin-modules": "3.3.0",
|
||||||
|
"compare-versions": "^4.1.3",
|
||||||
"esbuild": "0.17.3",
|
"esbuild": "0.17.3",
|
||||||
"obsidian": "latest",
|
"obsidian": "latest",
|
||||||
"tslib": "2.4.0",
|
"tslib": "2.4.0",
|
||||||
"typescript": "4.7.4",
|
"typescript": "4.7.4"
|
||||||
"compare-versions": "^4.1.3",
|
},
|
||||||
"@codemirror/search": "6.0.0",
|
"dependencies": {
|
||||||
"@codemirror/view": "6.0.0",
|
"iconv-lite": "^0.6.3"
|
||||||
"@codemirror/commands": "6.0.0",
|
|
||||||
"@codemirror/language": "https://github.com/lishid/cm-language"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ class StatefulDecorationSet {
|
||||||
linkEl.addEventListener("click", (e) => e.stopPropagation());
|
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));
|
decorations.push(deco.range(token.from, token.to));
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ function defineStatefulDecoration(): {
|
||||||
return {update, field};
|
return {update, field};
|
||||||
}
|
}
|
||||||
|
|
||||||
class EmojiWidget extends WidgetType {
|
class ogLinkWidget extends WidgetType {
|
||||||
private readonly source: HTMLDivElement;
|
private readonly source: HTMLDivElement;
|
||||||
|
|
||||||
constructor(source: HTMLDivElement) {
|
constructor(source: HTMLDivElement) {
|
||||||
|
@ -155,7 +155,7 @@ class EmojiWidget extends WidgetType {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
eq(other: EmojiWidget) {
|
eq(other: ogLinkWidget) {
|
||||||
return other == this;
|
return other == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { requestUrl } from "obsidian";
|
import { requestUrl } from "obsidian";
|
||||||
|
import { decode } from 'iconv-lite';
|
||||||
|
|
||||||
// url 정규식
|
// 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})?(\\/.*)?$");
|
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) {
|
export async function LinkThumbnailWidgetParams(url: string) {
|
||||||
const urlArr = urlRegex.exec(url);
|
const urlArr = urlRegex.exec(url);
|
||||||
if (urlArr) {
|
if (urlArr) {
|
||||||
try {
|
try {
|
||||||
const response = await requestUrl(url);
|
|
||||||
const contextType = response.headers["content-type"];
|
const response = await requestUrl({
|
||||||
if (contextType.toLocaleLowerCase().trim() === "text/html;charset=ms949") {
|
url:url,
|
||||||
return null;
|
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 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 ogTitle = document.querySelector("meta[property='og:title']")?.getAttribute("content") || document.querySelector("title")?.textContent || "";
|
||||||
const ogDescription = document.querySelector("meta[property='og:description']")?.getAttribute("content") || "";
|
const ogDescription = document.querySelector("meta[property='og:description']")?.getAttribute("content") || "";
|
||||||
let ogImage = document.querySelector("meta[property='og:image']")?.getAttribute("content") || "";
|
let ogImage = document.querySelector("meta[property='og:image']")?.getAttribute("content") || "";
|
||||||
|
@ -39,9 +53,8 @@ export async function LinkThumbnailWidgetParams(url: string) {
|
||||||
`
|
`
|
||||||
return result;
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
throw new Error(error);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,7 @@ export class PostProcessor {
|
||||||
// 링크 변환
|
// 링크 변환
|
||||||
const linkEls:Element[] = element.findAll("a.external-link:not(.cm-formatting, .markdown-rendered)");
|
const linkEls:Element[] = element.findAll("a.external-link:not(.cm-formatting, .markdown-rendered)");
|
||||||
for (const linkEl of linkEls) {
|
for (const linkEl of linkEls) {
|
||||||
// dataview 클래스를 가진 부모 요소를 확인합니다.
|
|
||||||
if (linkEl.closest(".dataview") !== null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const url = linkEl.innerHTML;
|
const url = linkEl.innerHTML;
|
||||||
const params = await LinkThumbnailWidgetParams(url);
|
const params = await LinkThumbnailWidgetParams(url);
|
||||||
if (params != null) {
|
if (params != null) {
|
||||||
|
|
Loading…
Reference in New Issue