diff --git a/src/index.html b/src/index.html
index 2e8620b..d9d4e56 100644
--- a/src/index.html
+++ b/src/index.html
@@ -2,9 +2,6 @@
-
-
-
MarkdownConverter
@@ -1605,6 +1602,6 @@
-
+
diff --git a/src/renderer.js b/src/renderer.js
index 86b9a58..0b83da7 100644
--- a/src/renderer.js
+++ b/src/renderer.js
@@ -3,7 +3,8 @@
* @version 4.3.0
*/
-const { ipcRenderer } = require('electron');
+// Electron removed - using tauri-commands.js
+import { file, events, app, exportDoc, git, pdf, dialog } from './tauri-commands.js';
const marked = require('marked');
const { markedHighlight } = require('marked-highlight');
const createDOMPurify = require('dompurify');
@@ -500,7 +501,7 @@ class TabManager {
// Notify main process about current file for exports
const tab = this.tabs.get(tabId);
- ipcRenderer.send('set-current-file', tab?.filePath || null);
+ const result = await file.write(path, content);
// Refresh outline panel for new tab content
if (outlinePanelContainer?._refreshOutline) outlinePanelContainer._refreshOutline();
@@ -923,7 +924,7 @@ class TabManager {
// Only auto-save if content has changed since last save
if (tab.lastSavedContent !== tab.content) {
- ipcRenderer.send('save-file', { path: tab.filePath, content: tab.content });
+ await file.write(tab.filePath, tab.content);
tab.lastSavedContent = tab.content;
// Show brief auto-save indicator
@@ -962,7 +963,7 @@ class TabManager {
// Save to localStorage and sync with main process
localStorage.setItem('recentFiles', JSON.stringify(this.recentFiles));
- ipcRenderer.send('save-recent-files', this.recentFiles);
+ await app.saveRecentFiles(this.recentFiles);
}
getRecentFiles() {
@@ -1371,7 +1372,7 @@ class TabManager {
this.updateBreadcrumb();
// Notify main process about current file for exports
- ipcRenderer.send('set-current-file', filePath);
+ // handled via event
console.log('File opened successfully');
}
@@ -1488,7 +1489,7 @@ document.addEventListener('DOMContentLoaded', async () => {
sidebarManager.registerPanel('explorer', {
title: 'Explorer',
render: (container) => getRenderExplorerPanel()(container, {
- listDirectory: (dir) => ipcRenderer.invoke('list-directory', dir),
+ listDirectory: (dir) => file.listDirectory(dir),
onFileOpen: (filePath) => ipcRenderer.send('open-file-path', filePath),
currentDir: explorerCurrentDir,
})
@@ -1496,11 +1497,11 @@ document.addEventListener('DOMContentLoaded', async () => {
sidebarManager.registerPanel('git', {
title: 'Git',
render: (container) => getRenderGitPanel()(container, {
- gitStatus: () => ipcRenderer.invoke('git-status'),
- gitDiff: (file) => ipcRenderer.invoke('git-diff', { file }),
- gitStage: (files) => ipcRenderer.invoke('git-stage', { files }),
- gitCommit: (message) => ipcRenderer.invoke('git-commit', { message }),
- gitLog: () => ipcRenderer.invoke('git-log'),
+ gitStatus: () => git.status(tab?.filePath ? path.dirname(tab.filePath) : null),
+ gitDiff: (file) => git.diff(path.dirname(file) || null, file),
+ gitStage: (files) => git.stage(path.dirname(files[0]) || null, files),
+ gitCommit: (message) => git.commit(getGitRepoPath(), message),
+ gitLog: () => git.log(getGitRepoPath()),
})
});
sidebarManager.registerPanel('snippets', {
@@ -1515,7 +1516,7 @@ document.addEventListener('DOMContentLoaded', async () => {
sidebarManager.registerPanel('templates', {
title: 'Templates',
render: (container) => getRenderTemplatesPanel()(container, async (file) => {
- const templateContent = await ipcRenderer.invoke('load-template', file);
+ const templateContent = await ipcRenderer.invoke('load-template', file),
if (templateContent) {
const content = templateContent.replace(/\{\{DATE\}\}/g, new Date().toISOString().split('T')[0]);
tabManager.createNewTab();
@@ -1836,11 +1837,11 @@ document.addEventListener('DOMContentLoaded', async () => {
});
// IPC event listeners
-ipcRenderer.on('file-new', () => {
+events.onFileNew(() => {
tabManager.createNewTab();
});
-ipcRenderer.on('file-opened', (event, data) => {
+events.onFileOpened((event, data) => {
console.log('[RENDERER] file-opened received:', data.path, 'content length:', data.content.length);
if (tabManager) {
tabManager.openFile(data.path, data.content);
@@ -1849,7 +1850,7 @@ ipcRenderer.on('file-opened', (event, data) => {
}
});
-ipcRenderer.on('file-save', () => {
+events.onFileSave(() => {
const currentContent = tabManager.getCurrentContent();
const currentFilePath = tabManager.getCurrentFilePath();
// send to main process which will save or trigger save-as dialog
@@ -1877,12 +1878,12 @@ ipcRenderer.on('get-content-for-spreadsheet', (event, format) => {
ipcRenderer.send('export-spreadsheet', { content: currentContent, format });
});
-ipcRenderer.on('toggle-preview', () => {
+events.onTogglePreview(() => {
tabManager.isPreviewVisible = !tabManager.isPreviewVisible;
tabManager.updatePreviewVisibility();
});
-ipcRenderer.on('toggle-find', () => {
+events.onToggleFind(() => {
if (window.modals.findModal.isOpen()) {
window.modals.findModal.close();
} else {
@@ -1891,7 +1892,7 @@ ipcRenderer.on('toggle-find', () => {
}
});
-ipcRenderer.on('theme-changed', (event, theme) => {
+events.onThemeChanged((event, theme) => {
console.log('[RENDERER] Theme changed to:', theme);
document.body.className = `theme-${theme}`;
@@ -1904,7 +1905,7 @@ ipcRenderer.on('theme-changed', (event, theme) => {
});
// Undo/Redo handlers — delegate to CodeMirror's built-in history
-ipcRenderer.on('undo', () => {
+events.onUndo(() => {
if (tabManager) {
const tab = tabManager.tabs.get(tabManager.activeTabId);
if (tab?.editorView) {
@@ -1913,7 +1914,7 @@ ipcRenderer.on('undo', () => {
}
});
-ipcRenderer.on('redo', () => {
+events.onRedo(() => {
if (tabManager) {
const tab = tabManager.tabs.get(tabManager.activeTabId);
if (tab?.editorView) {
diff --git a/src/tauri-commands.js b/src/tauri-commands.js
new file mode 100644
index 0000000..625d6b5
--- /dev/null
+++ b/src/tauri-commands.js
@@ -0,0 +1,88 @@
+// Tauri Commands Bridge for MarkdownConverter
+// Replaces preload.js — uses Tauri's invoke() instead of ipcRenderer
+
+const { invoke } = window.__TAURI__.core;
+const { listen } = window.__TAURI__.event;
+
+// ============================================
+// FILE OPERATIONS
+// ============================================
+export const file = {
+ read: (path) => invoke('read_file', { path }),
+ write: (path, content) => invoke('write_file', { path, content }),
+ delete: (path) => invoke('delete_file', { path }),
+ exists: (path) => invoke('path_exists', { path }),
+ isDirectory: (path) => invoke('is_directory', { path }),
+ listDirectory: (path) => invoke('list_directory', { path }),
+ ensureDir: (path) => invoke('ensure_directory', { path }),
+ copy: (source, destination) => invoke('copy_path', { source, destination }),
+ move: (source, destination) => invoke('move_path', { source, destination }),
+};
+
+// ============================================
+// EXPORT OPERATIONS
+// ============================================
+export const exportDoc = {
+ markdown: (inputPath, outputPath, format, options) =>
+ invoke('export_markdown', { inputPath, outputPath, format, options }),
+ checkPandoc: () => invoke('check_pandoc_available', {}),
+};
+
+// ============================================
+// GIT OPERATIONS
+// ============================================
+export const git = {
+ status: (repoPath) => invoke('git_status', { repoPath }),
+ stage: (repoPath, path) => invoke('git_stage', { repoPath, path }),
+ commit: (repoPath, message) => invoke('git_commit', { repoPath, message }),
+ log: (repoPath, limit) => invoke('git_log', { repoPath, limit }),
+ diff: (repoPath, path) => invoke('git_diff', { repoPath, path }),
+};
+
+// ============================================
+// APP OPERATIONS
+// ============================================
+export const app = {
+ getVersion: () => invoke('get_app_version'),
+ getRecentFiles: () => invoke('get_recent_files'),
+ saveRecentFiles: (files) => invoke('save_recent_files', { files }),
+};
+
+// ============================================
+// PDF OPERATIONS
+// ============================================
+export const pdf = {
+ getPageCount: (path) => invoke('get_pdf_page_count', { path }),
+ merge: (paths, output) => invoke('merge_pdfs', { paths, output }),
+ split: (input, outputDir, pagesPerSplit) => invoke('split_pdf', { input, outputDir, pagesPerSplit }),
+ rotate: (input, output, degrees) => invoke('rotate_pdf', { input, output, degrees }),
+ deletePages: (input, output, pages) => invoke('delete_pdf_pages', { input, output, pages }),
+};
+
+// ============================================
+// DIALOG OPERATIONS
+// ============================================
+export const dialog = {
+ openFile: () => invoke('open_file_dialog', {}),
+ saveFile: (defaultName) => invoke('save_file_dialog', { defaultName }),
+ selectFolder: () => invoke('select_folder_dialog', {}),
+};
+
+// ============================================
+// EVENT LISTENERS
+// ============================================
+export const events = {
+ onFileNew: (callback) => listen('file-new', callback),
+ onFileOpened: (callback) => listen('file-opened', callback),
+ onFileSave: (callback) => listen('file-save', callback),
+ onTogglePreview: (callback) => listen('toggle-preview', callback),
+ onToggleFind: (callback) => listen('toggle-find', callback),
+ onUndo: (callback) => listen('undo', callback),
+ onRedo: (callback) => listen('redo', callback),
+ onThemeChanged: (callback) => listen('theme-changed', callback),
+ onToggleCommandPalette: (callback) => listen('toggle-command-palette', callback),
+ onToggleSidebarPanel: (callback) => listen('toggle-sidebar-panel', callback),
+ onToggleBottomPanel: (callback) => listen('toggle-bottom-panel', callback),
+ onConversionComplete: (callback) => listen('conversion-complete', callback),
+ onConversionStatus: (callback) => listen('conversion-status', callback),
+};
\ No newline at end of file