mirror of
https://github.com/zadam/trilium.git
synced 2025-11-01 19:05:59 +01:00
feat(server): replace jsdom
This commit is contained in:
@@ -2,7 +2,7 @@ import becca from "./becca.js";
|
||||
import log from "../services/log.js";
|
||||
import beccaService from "./becca_service.js";
|
||||
import dateUtils from "../services/date_utils.js";
|
||||
import { JSDOM } from "jsdom";
|
||||
import { parse } from "node-html-parser";
|
||||
import type BNote from "./entities/bnote.js";
|
||||
import { SimilarNote } from "@triliumnext/commons";
|
||||
|
||||
@@ -123,10 +123,10 @@ export function buildRewardMap(note: BNote) {
|
||||
|
||||
if (note.type === "text" && note.isDecrypted) {
|
||||
const content = note.getContent();
|
||||
const dom = new JSDOM(content);
|
||||
const dom = parse(content.toString());
|
||||
|
||||
const addHeadingsToRewardMap = (elName: string, rewardFactor: number) => {
|
||||
for (const el of dom.window.document.querySelectorAll(elName)) {
|
||||
for (const el of dom.querySelectorAll(elName)) {
|
||||
addToRewardMap(el.textContent, rewardFactor);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Request } from "express";
|
||||
import jsdom from "jsdom";
|
||||
import { parse } from "node-html-parser";
|
||||
import path from "path";
|
||||
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
@@ -16,7 +16,6 @@ import log from "../../services/log.js";
|
||||
import noteService from "../../services/notes.js";
|
||||
import utils from "../../services/utils.js";
|
||||
import ws from "../../services/ws.js";
|
||||
const { JSDOM } = jsdom;
|
||||
|
||||
interface Image {
|
||||
src: string;
|
||||
@@ -181,10 +180,10 @@ export function processContent(images: Image[], note: BNote, content: string) {
|
||||
rewrittenContent = `<p>${rewrittenContent}</p>`;
|
||||
}
|
||||
// Create a JSDOM object from the existing HTML content
|
||||
const dom = new JSDOM(rewrittenContent);
|
||||
const dom = parse(rewrittenContent);
|
||||
|
||||
// Get the content inside the body tag and serialize it
|
||||
rewrittenContent = dom.window.document.body.innerHTML;
|
||||
rewrittenContent = dom.querySelector("body")?.innerHTML ?? "";
|
||||
|
||||
return rewrittenContent;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
import becca from "../../becca/becca.js";
|
||||
import { JSDOM } from "jsdom";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
import type BAttribute from "../../becca/entities/battribute.js";
|
||||
import type { Request } from "express";
|
||||
import { HTMLElement, parse, TextNode } from "node-html-parser";
|
||||
import { BacklinkCountResponse, BacklinksResponse } from "@triliumnext/commons";
|
||||
|
||||
interface TreeLink {
|
||||
@@ -241,7 +241,7 @@ function updateDescendantCountMapForSearch(noteIdToDescendantCountMap: Record<st
|
||||
}
|
||||
}
|
||||
|
||||
function removeImages(document: Document) {
|
||||
function removeImages(document: HTMLElement) {
|
||||
const images = document.getElementsByTagName("img");
|
||||
while (images && images.length > 0) {
|
||||
images[0]?.parentNode?.removeChild(images[0]);
|
||||
@@ -249,11 +249,11 @@ function removeImages(document: Document) {
|
||||
}
|
||||
|
||||
const EXCERPT_CHAR_LIMIT = 200;
|
||||
type ElementOrText = Element | Text;
|
||||
type ElementOrText = HTMLElement | TextNode;
|
||||
|
||||
export function findExcerpts(sourceNote: BNote, referencedNoteId: string) {
|
||||
const html = sourceNote.getContent();
|
||||
const document = new JSDOM(html).window.document;
|
||||
const document = parse(html.toString());
|
||||
|
||||
const excerpts: string[] = [];
|
||||
|
||||
@@ -270,8 +270,8 @@ export function findExcerpts(sourceNote: BNote, referencedNoteId: string) {
|
||||
|
||||
let centerEl: HTMLElement = linkEl;
|
||||
|
||||
while (centerEl.tagName !== "BODY" && centerEl.parentElement && (centerEl.parentElement?.textContent?.length || 0) <= EXCERPT_CHAR_LIMIT) {
|
||||
centerEl = centerEl.parentElement;
|
||||
while (centerEl.tagName !== "BODY" && centerEl.parentNode && (centerEl.parentNode?.textContent?.length || 0) <= EXCERPT_CHAR_LIMIT) {
|
||||
centerEl = centerEl.parentNode;
|
||||
}
|
||||
|
||||
const excerptEls: ElementOrText[] = [centerEl];
|
||||
@@ -282,7 +282,7 @@ export function findExcerpts(sourceNote: BNote, referencedNoteId: string) {
|
||||
while (excerptLength < EXCERPT_CHAR_LIMIT) {
|
||||
let added = false;
|
||||
|
||||
const prev: Element | null = left.previousElementSibling;
|
||||
const prev: HTMLElement | null = left.previousElementSibling;
|
||||
|
||||
if (prev) {
|
||||
const prevText = prev.textContent || "";
|
||||
@@ -290,7 +290,7 @@ export function findExcerpts(sourceNote: BNote, referencedNoteId: string) {
|
||||
if (prevText.length + excerptLength > EXCERPT_CHAR_LIMIT) {
|
||||
const prefix = prevText.substr(prevText.length - (EXCERPT_CHAR_LIMIT - excerptLength));
|
||||
|
||||
const textNode = document.createTextNode(`…${prefix}`);
|
||||
const textNode = new TextNode(`…${prefix}`);
|
||||
excerptEls.unshift(textNode);
|
||||
|
||||
break;
|
||||
@@ -302,7 +302,7 @@ export function findExcerpts(sourceNote: BNote, referencedNoteId: string) {
|
||||
added = true;
|
||||
}
|
||||
|
||||
const next: Element | null = right.nextElementSibling;
|
||||
const next: HTMLElement | null = right.nextElementSibling;
|
||||
|
||||
if (next) {
|
||||
const nextText = next.textContent;
|
||||
@@ -310,7 +310,7 @@ export function findExcerpts(sourceNote: BNote, referencedNoteId: string) {
|
||||
if (nextText && nextText.length + excerptLength > EXCERPT_CHAR_LIMIT) {
|
||||
const suffix = nextText.substr(nextText.length - (EXCERPT_CHAR_LIMIT - excerptLength));
|
||||
|
||||
const textNode = document.createTextNode(`${suffix}…`);
|
||||
const textNode = new TextNode(`${suffix}…`);
|
||||
excerptEls.push(textNode);
|
||||
|
||||
break;
|
||||
@@ -327,7 +327,7 @@ export function findExcerpts(sourceNote: BNote, referencedNoteId: string) {
|
||||
}
|
||||
}
|
||||
|
||||
const excerptWrapper = document.createElement("div");
|
||||
const excerptWrapper = new HTMLElement("div", {});
|
||||
excerptWrapper.classList.add("ck-content");
|
||||
excerptWrapper.classList.add("backlink-excerpt");
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { JSDOM } from "jsdom";
|
||||
import { parse, HTMLElement } from "node-html-parser";
|
||||
import shaca from "./shaca/shaca.js";
|
||||
import assetPath from "../services/asset_path.js";
|
||||
import shareRoot from "./share_root.js";
|
||||
@@ -65,8 +65,8 @@ function renderIndex(result: Result) {
|
||||
result.content += "</ul>";
|
||||
}
|
||||
|
||||
export function renderText(result: Result, note: SNote) {
|
||||
const document = new JSDOM(result.content || "").window.document;
|
||||
function renderText(result: Result, note: SNote) {
|
||||
const document = parse(result.content?.toString() || "");
|
||||
|
||||
// Process include notes.
|
||||
for (const includeNoteEl of document.querySelectorAll("section.include-note")) {
|
||||
@@ -79,11 +79,13 @@ export function renderText(result: Result, note: SNote) {
|
||||
const includedResult = getContent(note);
|
||||
if (typeof includedResult.content !== "string") continue;
|
||||
|
||||
const includedDocument = new JSDOM(includedResult.content).window.document;
|
||||
includeNoteEl.replaceWith(...includedDocument.body.childNodes);
|
||||
const includedDocument = parse(includedResult.content).querySelector("body");
|
||||
if (includedDocument) {
|
||||
includeNoteEl.replaceWith(includedDocument);
|
||||
}
|
||||
}
|
||||
|
||||
result.isEmpty = document.body.textContent?.trim().length === 0 && document.querySelectorAll("img").length === 0;
|
||||
result.isEmpty = document.querySelector("body")?.textContent?.trim().length === 0 && document.querySelectorAll("img").length === 0;
|
||||
|
||||
if (!result.isEmpty) {
|
||||
for (const linkEl of document.querySelectorAll("a")) {
|
||||
@@ -99,7 +101,7 @@ export function renderText(result: Result, note: SNote) {
|
||||
}
|
||||
}
|
||||
|
||||
result.content = document.body.innerHTML;
|
||||
result.content = document.querySelector("body")?.innerHTML ?? "";
|
||||
|
||||
if (result.content.includes(`<span class="math-tex">`)) {
|
||||
result.header += `
|
||||
@@ -120,7 +122,7 @@ document.addEventListener("DOMContentLoaded", function() {
|
||||
}
|
||||
}
|
||||
|
||||
function handleAttachmentLink(linkEl: HTMLAnchorElement, href: string) {
|
||||
function handleAttachmentLink(linkEl: HTMLElement, href: string) {
|
||||
const linkRegExp = /attachmentId=([a-zA-Z0-9_]+)/g;
|
||||
let attachmentMatch;
|
||||
if ((attachmentMatch = linkRegExp.exec(href))) {
|
||||
@@ -131,7 +133,8 @@ function handleAttachmentLink(linkEl: HTMLAnchorElement, href: string) {
|
||||
linkEl.setAttribute("href", `api/attachments/${attachmentId}/download`);
|
||||
linkEl.classList.add(`attachment-link`);
|
||||
linkEl.classList.add(`role-${attachment.role}`);
|
||||
linkEl.innerText = attachment.title;
|
||||
linkEl.childNodes.length = 0;
|
||||
linkEl.append(attachment.title);
|
||||
} else {
|
||||
linkEl.removeAttribute("href");
|
||||
}
|
||||
@@ -164,11 +167,8 @@ export function renderCode(result: Result) {
|
||||
if (typeof result.content !== "string" || !result.content?.trim()) {
|
||||
result.isEmpty = true;
|
||||
} else {
|
||||
const document = new JSDOM().window.document;
|
||||
|
||||
const preEl = document.createElement("pre");
|
||||
preEl.appendChild(document.createTextNode(result.content));
|
||||
|
||||
const preEl = new HTMLElement("pre", {});
|
||||
preEl.append(result.content);
|
||||
result.content = preEl.outerHTML;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user