Skip to content

Commit 7e6cf09

Browse files
committed
Updated link cleaning to apply proper classes to plugin-generated links
1 parent 2ec8b7b commit 7e6cf09

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

src/utils/styles.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/**
77
* Auto Card Link styles.
88
*/
9-
export const autoCardLink = `.auto-card-link-container{container-type:inline-size;position:relative;overflow:hidden;user-select:none;--auto-card-link-button-width:calc(var(--icon-size, 18px) + var(--size-2-3, 6px));--auto-card-link-indent-size:2.5em}&[data-auto-card-link-depth="1"]{margin-left:calc(var(--auto-card-link-indent-size) * 1)}&[data-auto-card-link-depth="2"]{margin-left:calc(var(--auto-card-link-indent-size) * 2)}&[data-auto-card-link-depth="3"]{margin-left:calc(var(--auto-card-link-indent-size) * 3)}&[data-auto-card-link-depth="4"]{margin-left:calc(var(--auto-card-link-indent-size) * 4)}&[data-auto-card-link-depth="5"]{margin-left:calc(var(--auto-card-link-indent-size) * 5)}&[data-auto-card-link-depth="6"]{margin-left:calc(var(--auto-card-link-indent-size) * 6)}&[data-auto-card-link-depth="7"]{margin-left:calc(var(--auto-card-link-indent-size) * 7)}.auto-card-link-title{white-space:normal!important;--lh:1.5em;line-height:var(--lh);height:calc(var(--lh) * 3);overflow:hidden;text-overflow:ellipsis}.auto-card-link-card{display:flex;flex-direction:row-reverse;height:8em;transition:20ms ease-in;cursor:pointer;text-decoration:none;color:var(--link-external-color,var(--highlight));background:var(--background-primary-alt,var(--darkgray));border:solid var(--border-width) var(--divider-color,var(--lightgray));border-radius:var(--radius-s,4px)}.auto-card-link-main{display:flex;flex-grow:1;flex-direction:column;justify-content:space-between;gap:.18em;padding:.5em .6em;overflow:hidden;text-align:left}.auto-card-link-description{overflow:hidden;--lh:1.4em;line-height:var(--lh);height:calc(var(--lh) * 3);color:var(--text-muted,var(--darkgray));font-size:var(--font-smallest, .9em)}.auto-card-link-host{font-size:var(--font-smallest, .9em);display:flex;flex-direction:row;align-items:center;text-overflow:ellipsis;white-space:nowrap}&:hover{color:var(--link-external-color-hover,var(--tertiary))}.auto-card-link-thumbnail{margin:0;width:unset!important;border-radius:var(--radius-s,4px) 0 0 var(--radius-s,4px)!important;height:100%;object-fit:cover;max-width:50%!important;pointer-events:none}.auto-card-link-container svg.external-icon{display: none}`;
9+
export const autoCardLink = `.auto-card-link-container{background-color:transparent;container-type:inline-size;position:relative;overflow:hidden;user-select:none;--auto-card-link-button-width:calc(var(--icon-size, 18px) + var(--size-2-3, 6px));--auto-card-link-indent-size:2.5em}&[data-auto-card-link-depth="1"]{margin-left:calc(var(--auto-card-link-indent-size) * 1)}&[data-auto-card-link-depth="2"]{margin-left:calc(var(--auto-card-link-indent-size) * 2)}&[data-auto-card-link-depth="3"]{margin-left:calc(var(--auto-card-link-indent-size) * 3)}&[data-auto-card-link-depth="4"]{margin-left:calc(var(--auto-card-link-indent-size) * 4)}&[data-auto-card-link-depth="5"]{margin-left:calc(var(--auto-card-link-indent-size) * 5)}&[data-auto-card-link-depth="6"]{margin-left:calc(var(--auto-card-link-indent-size) * 6)}&[data-auto-card-link-depth="7"]{margin-left:calc(var(--auto-card-link-indent-size) * 7)}.auto-card-link-title{white-space:normal!important;--lh:1.5em;line-height:var(--lh);height:calc(var(--lh) * 3);overflow:hidden;text-overflow:ellipsis}.auto-card-link-card{display:flex;flex-direction:row-reverse;height:8em;transition:20ms ease-in;cursor:pointer;text-decoration:none;color:var(--link-external-color,var(--highlight));background:var(--background-primary-alt,var(--darkgray));border:solid var(--border-width) var(--divider-color,var(--lightgray));border-radius:var(--radius-s,4px)}.auto-card-link-main{display:flex;flex-grow:1;flex-direction:column;justify-content:space-between;gap:.18em;padding:.5em .6em;overflow:hidden;text-align:left}.auto-card-link-description{overflow:hidden;--lh:1.4em;line-height:var(--lh);height:calc(var(--lh) * 3);color:var(--text-muted,var(--darkgray));font-size:var(--font-smallest, .9em)}.auto-card-link-host{font-size:var(--font-smallest, .9em);display:flex;flex-direction:row;align-items:center;text-overflow:ellipsis;white-space:nowrap}&:hover{color:var(--link-external-color-hover,var(--tertiary))}.auto-card-link-thumbnail{margin:0;width:unset!important;border-radius:var(--radius-s,4px) 0 0 var(--radius-s,4px)!important;height:100%;object-fit:cover;max-width:50%!important;pointer-events:none}.auto-card-link-container svg.external-icon{display: none}`;
1010

1111
/**
1212
* Datacore Callout styles.

src/utils/utils.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,16 +313,20 @@ function sanitizeHTMLToString(
313313
div: HTMLDivElement,
314314
serializer: XMLSerializer,
315315
): string {
316+
const styleTags = div.querySelectorAll("style");
317+
316318
// Let Obsidian handle the sanitization
317319
const sanitizedHtml = sanitizeHTMLToDom(div.innerHTML);
318320

319321
let container = document.createElement("div");
320322
container.appendChild(sanitizedHtml);
321323

322-
removeUnwantedElements(container, "script, style, link, meta, title");
324+
removeUnwantedElements(container, "script, link, meta, title");
323325

324326
// Remove unwanted attributes from internal links
325-
const internalLinks = container.querySelectorAll("a.internal-link, a.tag");
327+
const internalLinks = container.querySelectorAll(
328+
"a.internal-link, a.tag, a:not(.external-link):not(.internal-link):not(.tag)",
329+
);
326330

327331
if (internalLinks.length > 0) {
328332
cleanAnchorLinks(container);
@@ -372,12 +376,38 @@ function sanitizeHTMLToString(
372376
return cleanQueryResult(result);
373377
}
374378

379+
styleTags.forEach((styleTag) => {
380+
container.append(styleTag);
381+
});
382+
383+
cleanDatacoreAttributes(container);
384+
375385
// Serialize the sanitized HTML back to a string
376386
const serializedHtml = serializer.serializeToString(container);
377387

378388
return serializedHtml.replace(' xmlns="http://www.w3.org/1999/xhtml"', "");
379389
}
380390

391+
/**
392+
* Cleans datacore attributes from the container.
393+
* This is useful for removing Obsidian-specific attributes that are not needed in Quartz.
394+
*
395+
* @param container - The HTMLDivElement containing the HTML content to clean.
396+
*/
397+
function cleanDatacoreAttributes(container: HTMLDivElement): void {
398+
const datacoreAttributes = ["__source", "__self"];
399+
400+
const elements = container.querySelectorAll(
401+
`${datacoreAttributes.map((attr) => `[${attr}]`).join(", ")}`,
402+
);
403+
404+
elements.forEach((element) => {
405+
datacoreAttributes.forEach((attr) => {
406+
element.removeAttribute(attr);
407+
});
408+
});
409+
}
410+
381411
/**
382412
* Converts callouts in the container to a Quartz-compatible format.
383413
* This function replaces the callout elements with a Quartz-compatible blockquote format.
@@ -480,12 +510,22 @@ function convertCallouts(container: HTMLDivElement): HTMLDivElement {
480510
* @param container - The HTMLDivElement containing the anchor links to clean.
481511
*/
482512
function cleanAnchorLinks(container: HTMLDivElement): void {
483-
const internalLinks = container.querySelectorAll("a.internal-link, a.tag");
513+
const internalLinks = container.querySelectorAll(
514+
"a.internal-link, a.tag, a:not(.external-link):not(.internal-link):not(.tag)",
515+
);
484516

485517
internalLinks.forEach((link) => {
486518
link.removeAttribute("target");
487519
link.removeAttribute("rel");
488520
link.removeAttribute("data-href");
521+
522+
if (link.hasAttribute("href")) {
523+
if (link.getAttribute("href")?.startsWith("http")) {
524+
link.classList.add("external-link");
525+
} else {
526+
link.classList.add("internal-link");
527+
}
528+
}
489529
});
490530
}
491531

0 commit comments

Comments
 (0)