Add sync callout processing and styles

This commit is contained in:
Oleh 2026-02-21 15:11:23 +02:00
parent 50f7a535df
commit 2f303cc71c
3 changed files with 71 additions and 0 deletions

View file

@ -77,6 +77,54 @@ class EmbedManager {
}, 100);
}
async processSyncCallout(calloutEl, ctx) {
// Find the content area of the callout
const contentEl = calloutEl.querySelector('.callout-content');
if (!contentEl || contentEl.dataset.synced === 'true') return;
const internalLinks = contentEl.querySelectorAll('span.internal-embed');
let linksToProcess = [];
internalLinks.forEach(link => {
const path = link.getAttribute('src');
const alias = link.innerText || link.textContent;
if (path) {
const linkText = (alias && alias !== path && !alias.includes(path))
? `![[${path}|${alias}]]`
: `![[${path}]]`;
linksToProcess.push(linkText);
}
});
if (linksToProcess.length === 0) return;
// Mark callout as active only when we found links
calloutEl.addClass('is-synced');
contentEl.dataset.synced = 'true';
contentEl.empty();
// Create container
const syncContainer = contentEl.createDiv('sync-container');
// Apply CSS custom properties
syncContainer.style.setProperty('--sync-embed-height', this.plugin.settings.embedHeight);
syncContainer.style.setProperty('--sync-max-height', this.plugin.settings.maxEmbedHeight);
syncContainer.style.setProperty('--sync-gap', this.plugin.settings.gapBetweenEmbeds);
// Reserve space to avoid Layout Shift, consistent with processSyncBlock
const estimatedHeight = linksToProcess.length * 200; // Rough estimate
syncContainer.style.minHeight = `${estimatedHeight}px`;
for (let i = 0; i < linksToProcess.length; i++) {
await this.processEmbed(linksToProcess[i], syncContainer, ctx, i > 0);
}
// Remove min-height after all loaded
setTimeout(() => {
syncContainer.style.minHeight = '';
}, 100);
}
parseEmbedOptions(line) {
// Parse options like: ![[note|alias{height:500px,title:false}]]
const optionsMatch = line.match(/\{([^}]+)\}\]\]$/);

View file

@ -80,6 +80,14 @@ module.exports = class SyncEmbedPlugin extends Plugin {
this.embedManager.processSyncBlock(source, el, ctx);
});
// Register markdown post processor for sync callouts
this.registerMarkdownPostProcessor((el, ctx) => {
const callouts = el.querySelectorAll('.callout[data-callout="sync"]');
callouts.forEach(callout => {
this.embedManager.processSyncCallout(callout, ctx);
});
});
// Global focus tracking
this.registerDomEvent(document, 'focusin', this.trackFocus.bind(this));
this.registerDomEvent(document, 'focusout', this.trackFocusLoss.bind(this));

View file

@ -29,6 +29,21 @@
border-top: 1px solid var(--background-modifier-border-hover);
}
/* === SYNC CALLOUTS === */
.callout[data-callout="sync"].is-synced {
background-color: var(--background-primary) !important;
padding: 0 !important;
}
.callout[data-callout="sync"].is-synced > .callout-title {
display: none !important;
}
/* Reset margins for ALL callouts inside sync-embeds to fix app.css 1em override */
.sync-embed .callout {
margin: 0 !important;
}
/* === NATIVE OBSIDIAN PADDING SYSTEM (REBUILT) === */
/* 1. Hide the view header */