diff --git a/demos/cdn/demo-config.json b/demos/cdn/demo-config.json index e4220552a4..2dceccd1fd 100644 --- a/demos/cdn/demo-config.json +++ b/demos/cdn/demo-config.json @@ -1,7 +1,4 @@ { - "tags": [ - "editing", - "viewing" - ], - "title": "CDN" -} \ No newline at end of file + "tags": ["editing", "viewing"], + "title": "CDN" +} diff --git a/demos/cdn/file-upload.css b/demos/cdn/file-upload.css index 8e5aa64cc5..61ba20361d 100644 --- a/demos/cdn/file-upload.css +++ b/demos/cdn/file-upload.css @@ -1,10 +1,10 @@ .file-upload-button { - cursor: pointer; - padding: 8px 12px; - border-radius: 8px; - margin: 10px; - outline: none; - border: none; - background-color: #1355ff; - color: white; -} \ No newline at end of file + cursor: pointer; + padding: 8px 12px; + border-radius: 8px; + margin: 10px; + outline: none; + border: none; + background-color: #1355ff; + color: white; +} diff --git a/demos/cdn/file-upload.js b/demos/cdn/file-upload.js index 519d52dacb..c0e5879ad6 100644 --- a/demos/cdn/file-upload.js +++ b/demos/cdn/file-upload.js @@ -3,7 +3,7 @@ const fileInput = document.querySelector('.file-upload-input'); uploadBtn.addEventListener('click', () => fileInput.click()); fileInput.addEventListener('change', (event) => { - const file = event.target.files?.[0]; - const uploadEvent = new CustomEvent("file-upload", { detail: file }); - if (file) window.dispatchEvent(uploadEvent); -}); \ No newline at end of file + const file = event.target.files?.[0]; + const uploadEvent = new CustomEvent('file-upload', { detail: file }); + if (file) window.dispatchEvent(uploadEvent); +}); diff --git a/demos/chrome-extension/chrome-extension/background.js b/demos/chrome-extension/chrome-extension/background.js index ad128903ab..cc54872e6f 100644 --- a/demos/chrome-extension/chrome-extension/background.js +++ b/demos/chrome-extension/chrome-extension/background.js @@ -8,12 +8,12 @@ importScripts('dist/docx-validator.bundle.js'); function updateIcon(enabled) { const suffix = enabled ? '' : '-disabled'; const iconPath = { - "16": `icons/icon-16x16${suffix}.png`, - "19": `icons/icon-19x19${suffix}.png`, - "48": `icons/icon-48x48${suffix}.png`, - "128": `icons/icon-128x128${suffix}.png` + 16: `icons/icon-16x16${suffix}.png`, + 19: `icons/icon-19x19${suffix}.png`, + 48: `icons/icon-48x48${suffix}.png`, + 128: `icons/icon-128x128${suffix}.png`, }; - + chrome.action.setIcon({ path: iconPath }); } @@ -26,9 +26,9 @@ chrome.storage.sync.get(['extensionEnabled'], (result) => { // Create context menu on installation for selecting text chrome.runtime.onInstalled.addListener(() => { chrome.contextMenus.create({ - id: "openSelectedInSuperdoc", - title: "Open selected content in SuperDoc", - contexts: ["selection"] + id: 'openSelectedInSuperdoc', + title: 'Open selected content in SuperDoc', + contexts: ['selection'], }); }); @@ -55,13 +55,13 @@ async function handleDownloadFile(request, _sender, sendResponse) { const downloadId = await chrome.downloads.download({ url: request.url, filename: request.filename, - saveAs: true + saveAs: true, }); // Track this download to ignore it if downloaded from viewer viewerDownloadIds.add(downloadId); console.log('File download initiated:', request.filename, 'ID:', downloadId); - + sendResponse({ success: true, downloadId: downloadId }); } catch (error) { console.error('Error downloading file:', error); @@ -72,8 +72,8 @@ async function handleDownloadFile(request, _sender, sendResponse) { // Action to handler mapping const messageHandlers = { - 'toggleExtension': handleToggleExtension, - 'downloadFile': handleDownloadFile, + toggleExtension: handleToggleExtension, + downloadFile: handleDownloadFile, }; // Listen for messages @@ -87,13 +87,13 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { // Handle context menu clicks chrome.contextMenus.onClicked.addListener(async (info, tab) => { - if (!(info.menuItemId === "openSelectedInSuperdoc" && info.selectionText)) return; + if (!(info.menuItemId === 'openSelectedInSuperdoc' && info.selectionText)) return; // Send message to content script to capture HTML and open in SuperDoc try { await chrome.tabs.sendMessage(tab.id, { action: 'captureSelectedHTML', - selectedText: info.selectionText + selectedText: info.selectionText, }); } catch (error) { console.error('Error sending message to content script:', error); @@ -109,14 +109,14 @@ chrome.downloads.onChanged.addListener(async (downloadDelta) => { console.log('Extension disabled, ignoring download'); return; } - + // Check if this is a download from viewer - if so, ignore it, otherwise we get endless loop of opening modals if (viewerDownloadIds.has(downloadDelta.id)) { viewerDownloadIds.delete(downloadDelta.id); console.log('Ignoring viewer download completion:', downloadDelta.id); return; } - + try { await processDownload(downloadDelta.id); } catch (error) { @@ -131,7 +131,7 @@ async function sendMessageToActiveTab(action, payload) { await chrome.tabs.sendMessage(tabs[0].id, { action, - ...payload + ...payload, }); } catch (error) { console.error('Error sending message to content script:', error); @@ -144,19 +144,19 @@ async function processDownload(downloadId) { const download = downloads[0]; const filename = download.filename.toLowerCase(); - + // File type handlers // We will handle markdown like html, since they are interoperable (to a point) const fileHandlers = { '.docx': processDocxFile, '.md': processMarkdownFile, - '.markdown': processMarkdownFile + '.markdown': processMarkdownFile, }; const extension = filename.substring(filename.lastIndexOf('.')); const handler = fileHandlers[extension]; if (!handler) throw new Error(`No handler for file type: ${extension}`); - + await handler(download); } @@ -165,7 +165,7 @@ async function processDocxFile(download) { // fetch and stringify (actual blob was getting dropped on message to viewer.js) const response = await fetch(`file://${download.filename}`); // background scripts let us do cool stuff like this const blob = await response.blob(); - + // Validate and correct the DOCX file // Some DOCX files are generate with little to no style info or a poor schema, // here we try to fill in the blanks. @@ -178,7 +178,7 @@ async function processDocxFile(download) { console.error('Error validating DOCX:', error); // Continue with original blob if validation fails } - + // convert to b64, actual blobs were getting dropped on message to content script const base64Data = await new Promise((resolve, reject) => { const reader = new FileReader(); @@ -186,15 +186,15 @@ async function processDocxFile(download) { reader.onerror = reject; reader.readAsDataURL(correctedBlob); }); - + // Send message to content script to display modal await sendMessageToActiveTab('displayDOCX', { data: { filename: download.filename, mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', fileSize: correctedBlob.size, - base64Data - } + base64Data, + }, }); } @@ -202,62 +202,62 @@ async function processMarkdownFile(download) { // Fetch the markdown file content const response = await fetch(`file://${download.filename}`); const markdownText = await response.text(); - + // Convert markdown to HTML const htmlContent = markdownToHtml(markdownText); - + // Send message to content script with HTML content await sendMessageToActiveTab('displayMarkdown', { data: { filename: download.filename, htmlContent: htmlContent, - originalMarkdown: markdownText - } + originalMarkdown: markdownText, + }, }); } // Simple markdown to HTML converter function markdownToHtml(markdown) { let html = markdown; - + // Headers html = html.replace(/^### (.*$)/gim, '
$1');
-
+
// Inline code
html = html.replace(/`(.*?)`/gim, '$1');
-
+
// Links
html = html.replace(/\[([^\]]*)\]\(([^\)]*)\)/gim, '$1');
-
+
// Images
html = html.replace(/!\[([^\]]*)\]\(([^\)]*)\)/gim, '');
html = html.replace(/\n/gim, '
');
-
+
// Clean up empty paragraphs
html = html.replace(/
<\/p>/gim, ''); html = html.replace(/
( ( ' + html + ')/gim, '$1');
html = html.replace(/(<\/pre>)<\/p>/gim, '$1');
-
+
// Wrap in paragraphs
html = '
File: ${data.filename}
@@ -286,14 +284,14 @@ function showFallback(data) {
// Initialize SuperDoc with HTML content for markdown files
async function initSuperdocWithHTML(data) {
console.log('Initializing SuperDoc with HTML content');
-
+
try {
if (!window.SuperDocLibrary?.SuperDoc) {
console.error('SuperDocLibrary not available');
showMarkdownFallback(data);
return;
}
-
+
// Create a simple HTML document structure
const htmlContent = `
@@ -314,8 +312,7 @@ async function initSuperdocWithHTML(data) {