feat: Enhance inline date calculation with improved Live Preview support, type normalization, and plugin cleanup.
This commit is contained in:
101
main.ts
101
main.ts
@@ -110,6 +110,11 @@ function processInlineDateCalc(raw: string, app: App, sourcePath: string): strin
|
||||
else if ((cfg as any).since) type = 'since';
|
||||
else if ((cfg as any).from && (cfg as any).to) type = 'diff';
|
||||
}
|
||||
|
||||
// Normalize type aliases to match fenced code block processor
|
||||
if (type === 'bday') type = 'birthday';
|
||||
if (type === 'until') type = 'countdown';
|
||||
if (type === 'difference') type = 'diff';
|
||||
if (!type) return '';
|
||||
|
||||
// Render result similarly to the block processor
|
||||
@@ -235,6 +240,7 @@ const dateCalcLivePreviewPlugin = (app: App) => ViewPlugin.fromClass(class {
|
||||
const text = view.state.doc.toString();
|
||||
|
||||
// Find inline code spans that start with date-calc:
|
||||
// This regex looks for inline code between backticks
|
||||
const inlineCodeRegex = /`([^`]+)`/g;
|
||||
let match;
|
||||
|
||||
@@ -258,6 +264,9 @@ const dateCalcLivePreviewPlugin = (app: App) => ViewPlugin.fromClass(class {
|
||||
side: 1
|
||||
});
|
||||
builder.add(to, to, widget);
|
||||
|
||||
// Add a debug log to verify when a widget is being created
|
||||
console.log(`Live Preview widget created for: ${codeContent} with result: ${result}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,11 +296,25 @@ class DateCalcInlineRenderer extends MarkdownRenderChild {
|
||||
async render() {
|
||||
const result = processInlineDateCalc(this.raw, this.app, this.sourcePath);
|
||||
if (result) {
|
||||
console.log(`Rendering inline date-calc: ${this.raw} -> ${result}`);
|
||||
|
||||
// In Live Preview, just replace the code element directly
|
||||
const span = document.createElement('span');
|
||||
span.classList.add('date-calc-inline');
|
||||
span.setAttribute('contenteditable', 'false');
|
||||
span.textContent = result;
|
||||
this.target.replaceWith(span);
|
||||
|
||||
// Ensure we properly replace the target element
|
||||
try {
|
||||
this.target.parentNode?.replaceChild(span, this.target);
|
||||
console.log('Successfully replaced code element with result');
|
||||
} catch (e) {
|
||||
console.error('Failed to replace code element:', e);
|
||||
// Fallback: try the original method
|
||||
this.target.replaceWith(span);
|
||||
}
|
||||
} else {
|
||||
console.log(`No result for inline date-calc: ${this.raw}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,69 +328,44 @@ export default class MyPlugin extends Plugin {
|
||||
async onload() {
|
||||
await this.loadSettings();
|
||||
|
||||
// This creates an icon in the left ribbon.
|
||||
const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (_evt: MouseEvent) => {
|
||||
// Called when the user clicks the icon.
|
||||
new Notice('This is a notice!');
|
||||
});
|
||||
// Perform additional things with the ribbon
|
||||
ribbonIconEl.addClass('my-plugin-ribbon-class');
|
||||
|
||||
// This adds a status bar item to the bottom of the app. Does not work on mobile apps.
|
||||
// Add a status bar item showing the plugin is enabled
|
||||
const statusBarItemEl = this.addStatusBarItem();
|
||||
statusBarItemEl.setText('Status Bar Text');
|
||||
statusBarItemEl.setText('Date Calculator Enabled');
|
||||
|
||||
// This adds a simple command that can be triggered anywhere
|
||||
// Debugging command to test plugin functionality
|
||||
this.addCommand({
|
||||
id: 'open-sample-modal-simple',
|
||||
name: 'Open sample modal (simple)',
|
||||
id: 'date-calc-debug',
|
||||
name: 'Debug Date Calculator',
|
||||
callback: () => {
|
||||
new SampleModal(this.app).open();
|
||||
new Notice('Date Calculator plugin is working! Check console for more details.');
|
||||
console.log('Date Calculator plugin debug info:');
|
||||
console.log('Plugin version: 1.0.0');
|
||||
console.log('Plugin enabled: true');
|
||||
console.log('Current file:', this.app.workspace.getActiveFile()?.path);
|
||||
}
|
||||
});
|
||||
// This adds an editor command that can perform some operation on the current editor instance
|
||||
this.addCommand({
|
||||
id: 'sample-editor-command',
|
||||
name: 'Sample editor command',
|
||||
editorCallback: (editor: Editor, _view: MarkdownView) => {
|
||||
console.log(editor.getSelection());
|
||||
editor.replaceSelection('Sample Editor Command');
|
||||
}
|
||||
});
|
||||
// This adds a complex command that can check whether the current state of the app allows execution of the command
|
||||
this.addCommand({
|
||||
id: 'open-sample-modal-complex',
|
||||
name: 'Open sample modal (complex)',
|
||||
checkCallback: (checking: boolean) => {
|
||||
// Conditions to check
|
||||
const markdownView = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
if (markdownView) {
|
||||
// If checking is true, we're simply "checking" if the command can be run.
|
||||
// If checking is false, then we want to actually perform the operation.
|
||||
if (!checking) {
|
||||
new SampleModal(this.app).open();
|
||||
}
|
||||
|
||||
// This command will only show up in Command Palette when the check function returns true
|
||||
return true;
|
||||
}
|
||||
// Command to refresh inline calculations (useful for troubleshooting)
|
||||
this.addCommand({
|
||||
id: 'refresh-date-calc-inline',
|
||||
name: 'Refresh Date Calculations',
|
||||
callback: () => {
|
||||
// Force refresh by triggering layout
|
||||
this.app.workspace.trigger('layout-change');
|
||||
new Notice('Date calculations refreshed!');
|
||||
}
|
||||
});
|
||||
|
||||
// This adds a settings tab so the user can configure various aspects of the plugin
|
||||
this.addSettingTab(new SampleSettingTab(this.app, this));
|
||||
|
||||
// If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
|
||||
// Using this function will automatically remove the event listener when this plugin is disabled.
|
||||
this.registerDomEvent(document, 'click', (evt: MouseEvent) => {
|
||||
console.log('click', evt);
|
||||
});
|
||||
|
||||
// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
|
||||
this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000));
|
||||
|
||||
// Register the Live Preview editor extension for inline date-calc processing
|
||||
// CRITICAL: Register Live Preview extension FIRST and ensure it's properly loaded
|
||||
console.log('Registering Live Preview editor extension for date-calc...');
|
||||
this.registerEditorExtension(dateCalcLivePreviewPlugin(this.app));
|
||||
console.log('Date Calculator Live Preview extension registered successfully!');
|
||||
|
||||
// Add more comprehensive debugging
|
||||
new Notice('Date Calculator loaded with Live Preview support!');
|
||||
|
||||
// Register the `date-calc` code block processor
|
||||
this.registerMarkdownCodeBlockProcessor('date-calc', (source, el, ctx) => {
|
||||
@@ -384,6 +382,7 @@ export default class MyPlugin extends Plugin {
|
||||
|
||||
try {
|
||||
switch (type) {
|
||||
case 'bday':
|
||||
case 'birthday': {
|
||||
// Accept from config or frontmatter fallback
|
||||
const fileCache = this.app.metadataCache.getCache(ctx.sourcePath);
|
||||
@@ -445,7 +444,7 @@ export default class MyPlugin extends Plugin {
|
||||
|
||||
msg = `next one is in ${monthsUntil} months.`;
|
||||
} else if (daysUntil === 0) {
|
||||
msg = `Today! Wish ${pronoun} Happy Birthday!`;
|
||||
msg = `today! Wish ${pronoun} Happy Birthday!`;
|
||||
} else if (daysUntil === 1) {
|
||||
msg = `that's tomorrow!`;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user