mirror of
https://github.com/kunalja/VariantEditor.git
synced 2026-07-22 13:00:32 +00:00
format doccument
This commit is contained in:
parent
e53a453567
commit
ce82bcaeba
3 changed files with 1029 additions and 1019 deletions
300
src/main.ts
300
src/main.ts
|
|
@ -28,36 +28,36 @@ class ClickableVariantWidget extends WidgetType {
|
|||
span.className = 'variant-active-option clickable-variant';
|
||||
span.setAttribute('data-full-variant', this.fullVariant);
|
||||
span.setAttribute('data-variant-index', this.variantIndex);
|
||||
|
||||
|
||||
// Add click handler
|
||||
span.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
|
||||
// Select the entire variant in the editor
|
||||
const state = view.state;
|
||||
const doc = state.doc;
|
||||
|
||||
|
||||
// Find the positions in the current state
|
||||
const from = this.from;
|
||||
const to = this.to;
|
||||
|
||||
|
||||
// Set the selection to the entire variant
|
||||
view.dispatch({
|
||||
selection: {anchor: from, head: to}
|
||||
selection: { anchor: from, head: to }
|
||||
});
|
||||
|
||||
|
||||
// Call the highlightSelection method
|
||||
this.plugin.highlightSelection();
|
||||
});
|
||||
|
||||
|
||||
return span;
|
||||
}
|
||||
|
||||
eq(other: ClickableVariantWidget): boolean {
|
||||
return this.text === other.text &&
|
||||
this.fullVariant === other.fullVariant &&
|
||||
this.variantIndex === other.variantIndex;
|
||||
return this.text === other.text &&
|
||||
this.fullVariant === other.fullVariant &&
|
||||
this.variantIndex === other.variantIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -73,13 +73,13 @@ export default class VariantEditor extends Plugin {
|
|||
// Store the selection range
|
||||
private selectionFrom: number | null = null;
|
||||
private selectionTo: number | null = null;
|
||||
|
||||
|
||||
async onload() {
|
||||
try {
|
||||
// Bind the method to ensure proper 'this' context
|
||||
this.highlightSelection = this.highlightSelection.bind(this);
|
||||
this.clearHighlight = this.clearHighlight.bind(this);
|
||||
|
||||
|
||||
// Register the command with a direct function reference
|
||||
this.addCommand({
|
||||
id: 'variant-editor-highlight',
|
||||
|
|
@ -87,24 +87,24 @@ export default class VariantEditor extends Plugin {
|
|||
hotkeys: [{ modifiers: ["Mod"], key: "h" }],
|
||||
callback: () => this.highlightSelection()
|
||||
});
|
||||
|
||||
|
||||
// Register the clear command
|
||||
this.addCommand({
|
||||
id: 'variant-editor-clear-highlight',
|
||||
name: 'Variant Editor: Clear Highlighting',
|
||||
callback: () => this.clearHighlight()
|
||||
});
|
||||
|
||||
|
||||
// Register command to commit all variants in selection or document
|
||||
this.addCommand({
|
||||
id: 'variant-editor-commit-all',
|
||||
name: 'Variant Editor: Commit All Variants in Selection/Document',
|
||||
editorCallback: (editor) => this.commitAllVariants(editor)
|
||||
});
|
||||
|
||||
|
||||
// Register the editor extension for dimming
|
||||
this.dimExtension = this.createDimExtension();
|
||||
|
||||
|
||||
// Register the editor extension for variant indicators
|
||||
this.registerEditorExtension(this.createVariantIndicatorExtension());
|
||||
this.registerEditorExtension(this.dimExtension);
|
||||
|
|
@ -116,7 +116,7 @@ export default class VariantEditor extends Plugin {
|
|||
onunload() {
|
||||
this.clearHighlight();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates an extension that styles variant syntax to show only the active variant
|
||||
* while keeping the original text editable
|
||||
|
|
@ -124,48 +124,48 @@ export default class VariantEditor extends Plugin {
|
|||
private createVariantIndicatorExtension(): Extension {
|
||||
// Store a reference to the plugin instance for the widget to use
|
||||
const pluginInstance = this;
|
||||
|
||||
|
||||
return ViewPlugin.fromClass(
|
||||
class {
|
||||
decorations: DecorationSet;
|
||||
|
||||
|
||||
constructor(view: EditorView) {
|
||||
this.decorations = this.buildDecorations(view);
|
||||
}
|
||||
|
||||
|
||||
update(update: ViewUpdate) {
|
||||
if (update.docChanged || update.viewportChanged) {
|
||||
this.decorations = this.buildDecorations(update.view);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buildDecorations(view: EditorView): DecorationSet {
|
||||
const builder = new RangeSetBuilder<Decoration>();
|
||||
|
||||
for (let {from, to} of view.visibleRanges) {
|
||||
|
||||
for (let { from, to } of view.visibleRanges) {
|
||||
const text = view.state.doc.sliceString(from, to);
|
||||
const variantRegex = /\{\{([^{}]+?)\}\}\^(\d+)/g;
|
||||
let match;
|
||||
|
||||
|
||||
while ((match = variantRegex.exec(text)) !== null) {
|
||||
const matchStart = from + match.index;
|
||||
const matchEnd = matchStart + match[0].length;
|
||||
const fullMatch = match[0];
|
||||
const variantsText = match[1];
|
||||
const activeIndex = parseInt(match[2], 10);
|
||||
|
||||
|
||||
// Find the position of the active variant
|
||||
let pos = 0;
|
||||
if (activeIndex === 0) {
|
||||
pos += 2; // Skip past the opening {{
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < activeIndex; i++) {
|
||||
pos = fullMatch.indexOf('|', pos) + 1;
|
||||
}
|
||||
|
||||
|
||||
const activeVariantStart = matchStart + pos;
|
||||
const activeVariantEnd = activeVariantStart + variantsText.split('|')[activeIndex].length;
|
||||
|
||||
|
||||
// Add three decorations for each variant:
|
||||
// 1. Hide everything before the active variant
|
||||
builder.add(
|
||||
|
|
@ -179,7 +179,7 @@ export default class VariantEditor extends Plugin {
|
|||
}
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
// 2. Show the active variant as a clickable widget
|
||||
const activeVariantText = variantsText.split('|')[activeIndex];
|
||||
builder.add(
|
||||
|
|
@ -196,7 +196,7 @@ export default class VariantEditor extends Plugin {
|
|||
)
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
// 3. Hide everything after the active variant
|
||||
builder.add(
|
||||
activeVariantEnd,
|
||||
|
|
@ -211,7 +211,7 @@ export default class VariantEditor extends Plugin {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return builder.finish();
|
||||
}
|
||||
},
|
||||
|
|
@ -220,11 +220,11 @@ export default class VariantEditor extends Plugin {
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private createDimExtension(): Extension {
|
||||
// Get reference to the plugin instance for the view plugin to use
|
||||
const pluginInstance = this;
|
||||
|
||||
|
||||
// Create a state field to track cursor position changes
|
||||
const cursorTrackingField = StateField.define({
|
||||
create(state) {
|
||||
|
|
@ -234,115 +234,115 @@ export default class VariantEditor extends Plugin {
|
|||
if (transaction.selection) {
|
||||
const selection = transaction.newSelection.main;
|
||||
const currentLine = transaction.newDoc.lineAt(selection.head).number;
|
||||
|
||||
|
||||
// Store the current cursor line
|
||||
if (pluginInstance.previousCursorLine === null) {
|
||||
pluginInstance.previousCursorLine = currentLine;
|
||||
}
|
||||
|
||||
|
||||
// If we have an active line and cursor moved to a different line, clear dimming
|
||||
if (pluginInstance.activeLine !== null &&
|
||||
currentLine !== pluginInstance.activeLine &&
|
||||
currentLine !== pluginInstance.previousCursorLine) {
|
||||
if (pluginInstance.activeLine !== null &&
|
||||
currentLine !== pluginInstance.activeLine &&
|
||||
currentLine !== pluginInstance.previousCursorLine) {
|
||||
// Schedule clearing on next tick to avoid update-during-update
|
||||
setTimeout(() => {
|
||||
pluginInstance.clearHighlight();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
|
||||
// Update previous cursor line
|
||||
pluginInstance.previousCursorLine = currentLine;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Create the view plugin for decorations
|
||||
const dimPlugin = ViewPlugin.fromClass(
|
||||
class implements PluginValue {
|
||||
decorations: DecorationSet;
|
||||
|
||||
|
||||
constructor(view: EditorView) {
|
||||
this.decorations = this.buildDecorations(view);
|
||||
}
|
||||
|
||||
update(update: ViewUpdate) {
|
||||
|
||||
update(update: ViewUpdate) {
|
||||
// Update decorations if needed
|
||||
if (update.docChanged || update.viewportChanged || pluginInstance.activeLine !== null) {
|
||||
this.decorations = this.buildDecorations(update.view);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buildDecorations(view: EditorView): DecorationSet {
|
||||
// If no active line is set, return empty decorations
|
||||
if (pluginInstance.activeLine === null) {
|
||||
return Decoration.none;
|
||||
}
|
||||
|
||||
// Collect all decorations first, then sort and add them
|
||||
const allDecorations = [];
|
||||
const activeLine = pluginInstance.activeLine;
|
||||
|
||||
// First pass: Collect line decorations for all lines except the active one
|
||||
for (let i = 1; i <= view.state.doc.lines; i++) {
|
||||
if (i !== activeLine) {
|
||||
try {
|
||||
const line = view.state.doc.line(i);
|
||||
const decoration = Decoration.line({
|
||||
attributes: { class: "fh-dim" }
|
||||
});
|
||||
allDecorations.push({
|
||||
from: line.from,
|
||||
to: line.from,
|
||||
decoration: decoration
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`Error creating decoration for line ${i}:`, e);
|
||||
// If no active line is set, return empty decorations
|
||||
if (pluginInstance.activeLine === null) {
|
||||
return Decoration.none;
|
||||
}
|
||||
|
||||
// Collect all decorations first, then sort and add them
|
||||
const allDecorations = [];
|
||||
const activeLine = pluginInstance.activeLine;
|
||||
|
||||
// First pass: Collect line decorations for all lines except the active one
|
||||
for (let i = 1; i <= view.state.doc.lines; i++) {
|
||||
if (i !== activeLine) {
|
||||
try {
|
||||
const line = view.state.doc.line(i);
|
||||
const decoration = Decoration.line({
|
||||
attributes: { class: "fh-dim" }
|
||||
});
|
||||
allDecorations.push({
|
||||
from: line.from,
|
||||
to: line.from,
|
||||
decoration: decoration
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`Error creating decoration for line ${i}:`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second pass: Collect highlight decoration only for the currently selected text
|
||||
if (pluginInstance.selectedText && activeLine <= view.state.doc.lines && pluginInstance.selectionFrom !== null && pluginInstance.selectionTo !== null) {
|
||||
try {
|
||||
// Use the exact selection positions instead of searching for all instances
|
||||
const start = pluginInstance.selectionFrom;
|
||||
const end = pluginInstance.selectionTo;
|
||||
|
||||
allDecorations.push({
|
||||
from: start,
|
||||
to: end,
|
||||
decoration: Decoration.mark({
|
||||
attributes: { class: "fh-highlight" }
|
||||
})
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`Error creating highlight decoration:`, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort all decorations by from position
|
||||
allDecorations.sort((a, b) => a.from - b.from);
|
||||
|
||||
// Now add them to the builder in sorted order
|
||||
const builder = new RangeSetBuilder<Decoration>();
|
||||
for (const { from, to, decoration } of allDecorations) {
|
||||
try {
|
||||
builder.add(from, to, decoration);
|
||||
} catch (e) {
|
||||
console.error(`Error adding decoration at position ${from}:`, e);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second pass: Collect highlight decoration only for the currently selected text
|
||||
if (pluginInstance.selectedText && activeLine <= view.state.doc.lines && pluginInstance.selectionFrom !== null && pluginInstance.selectionTo !== null) {
|
||||
try {
|
||||
// Use the exact selection positions instead of searching for all instances
|
||||
const start = pluginInstance.selectionFrom;
|
||||
const end = pluginInstance.selectionTo;
|
||||
|
||||
allDecorations.push({
|
||||
from: start,
|
||||
to: end,
|
||||
decoration: Decoration.mark({
|
||||
attributes: { class: "fh-highlight" }
|
||||
})
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(`Error creating highlight decoration:`, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort all decorations by from position
|
||||
allDecorations.sort((a, b) => a.from - b.from);
|
||||
|
||||
// Now add them to the builder in sorted order
|
||||
const builder = new RangeSetBuilder<Decoration>();
|
||||
for (const { from, to, decoration } of allDecorations) {
|
||||
try {
|
||||
builder.add(from, to, decoration);
|
||||
} catch (e) {
|
||||
console.error(`Error adding decoration at position ${from}:`, e);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.finish();
|
||||
}
|
||||
destroy() {}
|
||||
destroy() { }
|
||||
},
|
||||
{
|
||||
decorations: (instance) => instance.decorations
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// Return both extensions
|
||||
return [cursorTrackingField, dimPlugin];
|
||||
}
|
||||
|
|
@ -355,38 +355,38 @@ export default class VariantEditor extends Plugin {
|
|||
|
||||
const editor = view.editor;
|
||||
const selection = editor.listSelections()[0];
|
||||
|
||||
|
||||
// Variants only work within single lines
|
||||
if (selection.anchor.line !== selection.head.line) {
|
||||
new Notice('Selection must be within a single line');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Get the selected text and range
|
||||
const from = {
|
||||
line: Math.min(selection.anchor.line, selection.head.line),
|
||||
ch: Math.min(selection.anchor.ch, selection.head.ch)
|
||||
};
|
||||
|
||||
|
||||
const to = {
|
||||
line: Math.max(selection.anchor.line, selection.head.line),
|
||||
ch: Math.max(selection.anchor.ch, selection.head.ch)
|
||||
};
|
||||
|
||||
|
||||
let selectedText = editor.getRange(from, to);
|
||||
if (!selectedText) return;
|
||||
|
||||
|
||||
this.selectedText = selectedText;
|
||||
|
||||
|
||||
// Setup for variant editing
|
||||
let initialText = selectedText;
|
||||
let initialActiveIndex = 0;
|
||||
let isExistingVariant = false;
|
||||
|
||||
|
||||
// Check if the selection is already a variant
|
||||
const variantRegex = /^\{\{([^{}]+?)\}\}\^(\d+)$/;
|
||||
const variantMatch = selectedText.match(variantRegex);
|
||||
|
||||
|
||||
if (variantMatch) {
|
||||
// Direct selection of a variant
|
||||
initialText = variantMatch[1];
|
||||
|
|
@ -398,27 +398,27 @@ export default class VariantEditor extends Plugin {
|
|||
if (line) {
|
||||
const fullLineRegex = /\{\{([^{}]+?)\}\}\^(\d+)/g;
|
||||
let match;
|
||||
|
||||
|
||||
while ((match = fullLineRegex.exec(line)) !== null) {
|
||||
const matchStart = match.index;
|
||||
const matchEnd = matchStart + match[0].length;
|
||||
|
||||
|
||||
// Check if selection overlaps with the variant at all
|
||||
// This handles partial selections that include any part of the variant
|
||||
if ((from.ch >= matchStart && from.ch < matchEnd) || // Selection starts inside variant
|
||||
(to.ch > matchStart && to.ch <= matchEnd) || // Selection ends inside variant
|
||||
(from.ch <= matchStart && to.ch >= matchEnd)) { // Selection contains variant
|
||||
|
||||
(to.ch > matchStart && to.ch <= matchEnd) || // Selection ends inside variant
|
||||
(from.ch <= matchStart && to.ch >= matchEnd)) { // Selection contains variant
|
||||
|
||||
// Selection overlaps with a variant - capture the entire variant
|
||||
initialText = match[1];
|
||||
initialActiveIndex = parseInt(match[2], 10);
|
||||
isExistingVariant = true;
|
||||
|
||||
|
||||
// Expand selection to cover the entire variant
|
||||
from.ch = matchStart;
|
||||
to.ch = matchEnd;
|
||||
editor.setSelection(from, to);
|
||||
|
||||
|
||||
// Update selectedText to match the expanded selection
|
||||
selectedText = editor.getRange(from, to);
|
||||
break;
|
||||
|
|
@ -426,17 +426,17 @@ export default class VariantEditor extends Plugin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isExistingVariant) {
|
||||
new Notice('Editing existing variant');
|
||||
}
|
||||
|
||||
|
||||
// Set active line for dimming
|
||||
this.activeLine = from.line + 1;
|
||||
|
||||
|
||||
// Store the selected text for highlighting - make sure we use the potentially updated selection
|
||||
this.selectedText = selectedText;
|
||||
|
||||
|
||||
// Convert EditorPosition to absolute character positions for highlighting
|
||||
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
if (activeView) {
|
||||
|
|
@ -447,7 +447,7 @@ export default class VariantEditor extends Plugin {
|
|||
// Convert line/ch positions to absolute character positions
|
||||
const fromPos = editorView.state.doc.line(from.line + 1).from + from.ch;
|
||||
const toPos = editorView.state.doc.line(to.line + 1).from + to.ch;
|
||||
|
||||
|
||||
// Store the exact selection range for highlighting
|
||||
this.selectionFrom = fromPos;
|
||||
this.selectionTo = toPos;
|
||||
|
|
@ -456,10 +456,10 @@ export default class VariantEditor extends Plugin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Force editor refresh to apply decorations
|
||||
this.app.workspace.updateOptions();
|
||||
|
||||
|
||||
// Open the variant editor modal
|
||||
new TextInputModal(
|
||||
this.app,
|
||||
|
|
@ -468,7 +468,7 @@ export default class VariantEditor extends Plugin {
|
|||
// Use the updated cursor positions if provided, otherwise use the original positions
|
||||
const updateFrom = currentFrom || from;
|
||||
const updateTo = currentTo || to;
|
||||
|
||||
|
||||
if (modalClosed) {
|
||||
// Modal was closed without committing (via ESC key or clicking outside)
|
||||
// Clear the highlights
|
||||
|
|
@ -484,18 +484,18 @@ export default class VariantEditor extends Plugin {
|
|||
} else {
|
||||
// Create or update the variant syntax (normal variant creation/update)
|
||||
const variants = variantText.split('|').filter(v => v);
|
||||
|
||||
|
||||
if (variants.length > 0) {
|
||||
const activeIdx = typeof activeIndex === 'number' ? activeIndex : 0;
|
||||
const variantSyntax = `{{${variants.join('|')}}}^${activeIdx}`;
|
||||
|
||||
|
||||
// Use the updated cursor positions for the replacement
|
||||
editor.replaceRange(variantSyntax, updateFrom, updateTo);
|
||||
|
||||
|
||||
// Update the original positions for future updates
|
||||
from.ch = updateFrom.ch;
|
||||
to.ch = updateFrom.ch + variantSyntax.length;
|
||||
|
||||
|
||||
// Update selection positions for highlighting
|
||||
const activeView = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
if (activeView) {
|
||||
|
|
@ -505,11 +505,11 @@ export default class VariantEditor extends Plugin {
|
|||
// Convert updated line/ch positions to absolute character positions
|
||||
const fromPos = editorView.state.doc.line(updateFrom.line + 1).from + updateFrom.ch;
|
||||
const toPos = editorView.state.doc.line(updateFrom.line + 1).from + updateFrom.ch + variantSyntax.length;
|
||||
|
||||
|
||||
// Update the exact selection range for highlighting
|
||||
this.selectionFrom = fromPos;
|
||||
this.selectionTo = toPos;
|
||||
|
||||
|
||||
// Force editor refresh to update decorations
|
||||
this.app.workspace.updateOptions();
|
||||
} catch (e) {
|
||||
|
|
@ -517,7 +517,7 @@ export default class VariantEditor extends Plugin {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const action = isExistingVariant ? 'Updated' : 'Created';
|
||||
// Only show notice on explicit user action, not on every update
|
||||
if (commitVariant) {
|
||||
|
|
@ -548,7 +548,7 @@ export default class VariantEditor extends Plugin {
|
|||
let text: string;
|
||||
let from: EditorPosition;
|
||||
let to: EditorPosition;
|
||||
|
||||
|
||||
const selection = editor.listSelections()[0];
|
||||
if (selection && (selection.anchor.line !== selection.head.line || selection.anchor.ch !== selection.head.ch)) {
|
||||
// Use the selection
|
||||
|
|
@ -556,12 +556,12 @@ export default class VariantEditor extends Plugin {
|
|||
line: Math.min(selection.anchor.line, selection.head.line),
|
||||
ch: Math.min(selection.anchor.ch, selection.head.ch)
|
||||
};
|
||||
|
||||
|
||||
to = {
|
||||
line: Math.max(selection.anchor.line, selection.head.line),
|
||||
ch: Math.max(selection.anchor.ch, selection.head.ch)
|
||||
};
|
||||
|
||||
|
||||
text = editor.getRange(from, to);
|
||||
} else {
|
||||
// Use the entire document
|
||||
|
|
@ -569,23 +569,23 @@ export default class VariantEditor extends Plugin {
|
|||
to = { line: editor.lineCount() - 1, ch: editor.getLine(editor.lineCount() - 1).length };
|
||||
text = editor.getValue();
|
||||
}
|
||||
|
||||
|
||||
// Find all variants in the text
|
||||
const variantRegex = /\{\{([^{}]+?)\}\}\^(\d+)/g;
|
||||
let match;
|
||||
let variantsFound = 0;
|
||||
let lastIndex = 0;
|
||||
let result = '';
|
||||
|
||||
|
||||
// Process each variant
|
||||
while ((match = variantRegex.exec(text)) !== null) {
|
||||
// Add text before this variant
|
||||
result += text.substring(lastIndex, match.index);
|
||||
|
||||
|
||||
// Extract variant information
|
||||
const variants = match[1].split('|');
|
||||
const activeIndex = parseInt(match[2], 10);
|
||||
|
||||
|
||||
// Add the active variant text
|
||||
if (activeIndex >= 0 && activeIndex < variants.length) {
|
||||
result += variants[activeIndex];
|
||||
|
|
@ -594,17 +594,17 @@ export default class VariantEditor extends Plugin {
|
|||
// If active index is invalid, keep the original text
|
||||
result += match[0];
|
||||
}
|
||||
|
||||
|
||||
// Update lastIndex for next iteration
|
||||
lastIndex = match.index + match[0].length;
|
||||
}
|
||||
|
||||
|
||||
// Add any remaining text
|
||||
result += text.substring(lastIndex);
|
||||
|
||||
|
||||
// Replace the text in the editor
|
||||
editor.replaceRange(result, from, to);
|
||||
|
||||
|
||||
// Show a notice with the results
|
||||
if (variantsFound > 0) {
|
||||
new Notice(`Committed ${variantsFound} variant${variantsFound === 1 ? '' : 's'}`);
|
||||
|
|
@ -616,7 +616,7 @@ export default class VariantEditor extends Plugin {
|
|||
new Notice('Error committing variants');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private clearHighlight(): void {
|
||||
try {
|
||||
// Reset state
|
||||
|
|
@ -625,7 +625,7 @@ export default class VariantEditor extends Plugin {
|
|||
this.selectedText = null;
|
||||
this.selectionFrom = null;
|
||||
this.selectionTo = null;
|
||||
|
||||
|
||||
// Force editor refresh
|
||||
const view = this.app.workspace.getActiveViewOfType(MarkdownView);
|
||||
if (view) hackToRerender(view);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
38
styles.css
38
styles.css
|
|
@ -36,10 +36,11 @@
|
|||
}
|
||||
|
||||
/* Make highlighted text stand out even when selected */
|
||||
.cm-line .cm-selectionBackground ~ .fh-highlight,
|
||||
.cm-line .cm-selectionBackground + .fh-highlight,
|
||||
.cm-line .cm-selectionBackground~.fh-highlight,
|
||||
.cm-line .cm-selectionBackground+.fh-highlight,
|
||||
.cm-line .fh-highlight.cm-selectionBackground {
|
||||
background-color: rgba(255, 207, 64, 0.6) !important; /* Lighter yellow that shows through selection */
|
||||
background-color: rgba(255, 207, 64, 0.6) !important;
|
||||
/* Lighter yellow that shows through selection */
|
||||
mix-blend-mode: normal;
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
@ -160,7 +161,8 @@
|
|||
inset: -2px;
|
||||
padding: 2px;
|
||||
background: linear-gradient(135deg, #8b5cf6, #ec4899, #f97316);
|
||||
border-radius: 10px; /* Match the row border-radius + 2px for the inset */
|
||||
border-radius: 10px;
|
||||
/* Match the row border-radius + 2px for the inset */
|
||||
mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
mask-composite: exclude;
|
||||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
|
|
@ -305,7 +307,8 @@
|
|||
/* Special handling for active rows with drag indicators */
|
||||
.variant-editor-row-active.drag-over-top::after,
|
||||
.variant-editor-row-active.drag-over-bottom::after {
|
||||
z-index: 20; /* Higher z-index to appear above the rainbow border */
|
||||
z-index: 20;
|
||||
/* Higher z-index to appear above the rainbow border */
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -353,12 +356,16 @@
|
|||
.variant-editor-button {
|
||||
min-width: 144px;
|
||||
max-width: 216px;
|
||||
padding: 10px 24px !important; /* Reduced vertical padding to make buttons thinner */
|
||||
border-radius: 8px !important; /* Match variant row border-radius */
|
||||
padding: 10px 24px !important;
|
||||
/* Reduced vertical padding to make buttons thinner */
|
||||
border-radius: 8px !important;
|
||||
/* Match variant row border-radius */
|
||||
font-size: 16px !important;
|
||||
font-weight: 600 !important;
|
||||
transition: all 0.25s cubic-bezier(0.25, 0.1, 0.25, 1) !important; /* Improved animation curve */
|
||||
border: 1px solid #333 !important; /* Match variant row border */
|
||||
transition: all 0.25s cubic-bezier(0.25, 0.1, 0.25, 1) !important;
|
||||
/* Improved animation curve */
|
||||
border: 1px solid #333 !important;
|
||||
/* Match variant row border */
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1) !important;
|
||||
text-align: center !important;
|
||||
color: white !important;
|
||||
|
|
@ -367,13 +374,15 @@
|
|||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
gap: 10px !important;
|
||||
height: 42px !important; /* Reduced height by 10px */
|
||||
height: 42px !important;
|
||||
/* Reduced height by 10px */
|
||||
}
|
||||
|
||||
|
||||
|
||||
.variant-editor-commit-button {
|
||||
background-color: #7E6BDC !important; /* Obsidian purple */
|
||||
background-color: #7E6BDC !important;
|
||||
/* Obsidian purple */
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
|
|
@ -404,7 +413,8 @@
|
|||
/* Style the variant editor modal */
|
||||
.variant-editor-modal {
|
||||
max-width: 90vw !important;
|
||||
width: 460px !important; /* Reduced from 500px to 460px (40px less) */
|
||||
width: 460px !important;
|
||||
/* Reduced from 500px to 460px (40px less) */
|
||||
max-height: 80vh !important;
|
||||
padding: 0;
|
||||
overflow-y: auto !important;
|
||||
|
|
@ -461,7 +471,7 @@
|
|||
}
|
||||
|
||||
/* Remove background dimming for variant editor modal */
|
||||
.variant-editor-no-dim ~ .modal-bg {
|
||||
.variant-editor-no-dim~.modal-bg {
|
||||
background-color: transparent !important;
|
||||
backdrop-filter: none !important;
|
||||
}
|
||||
|
|
@ -470,4 +480,4 @@
|
|||
outline: none;
|
||||
border-color: var(--interactive-accent);
|
||||
box-shadow: 0 0 0 2px rgba(var(--interactive-accent-rgb), 0.2);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue