Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions desktop-app/resources/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ <h1 class="h4 mb-0 me-2">Markdown Viewer</h1>
<li><a class="dropdown-item" href="#" id="import-from-github"><i class="bi bi-github me-2"></i>From GitHub</a></li>
</ul>
</div>
<input type="file" id="file-input" class="file-input" accept=".md,.markdown,text/markdown">
<input type="file" id="file-input" class="file-input" accept=".md,.markdown,text/markdown" multiple>

<div class="dropdown">
<button class="tool-button dropdown-toggle" type="button" id="exportDropdown" data-bs-toggle="dropdown" aria-expanded="false" title="Export Markdown">
Expand Down Expand Up @@ -1016,7 +1016,7 @@ <h3 class="modal-section-title">Open-source credits</h3>
<div id="drag-overlay" class="drag-overlay" aria-hidden="true">
<div class="drag-overlay-inner">
<i class="bi bi-cloud-arrow-up drag-overlay-icon"></i>
<p class="drag-overlay-text">Drop your Markdown file anywhere</p>
<p class="drag-overlay-text">Drop your Markdown files anywhere</p>
<p class="drag-overlay-sub">.md or .markdown files supported</p>
</div>
</div>
Expand All @@ -1039,7 +1039,7 @@ <h3 class="modal-section-title">Open-source credits</h3>
</div>
<textarea id="markdown-editor" placeholder="Type or paste your Markdown here..."></textarea>
<div class="drop-hint" aria-hidden="true">
<i class="bi bi-cloud-arrow-up me-1"></i>Drop a .md file anywhere to open it
<i class="bi bi-cloud-arrow-up me-1"></i>Drop .md files anywhere to open them
</div>
</div>
<!-- Resize Divider - Story 1.3 -->
Expand Down
108 changes: 72 additions & 36 deletions desktop-app/resources/js/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -4453,31 +4453,75 @@ document.addEventListener("DOMContentLoaded", async function () {
}
}

function isMarkdownFile(file) {
return Boolean(file) && (
file.type === "text/markdown" ||
/\.(md|markdown)$/i.test(file.name || "")
);
}

function getMarkdownFileTitle(file) {
return (file && file.name ? file.name : "document.md").replace(/\.(md|markdown)$/i, "");
}

function importMarkdownFile(file) {
if (file.size > 10 * 1024 * 1024) {
alert('File is too large (maximum 10MB supported).');
return;
}
return new Promise(function(resolve) {
if (!file) {
resolve(false);
return;
}

if (file.size > 10 * 1024 * 1024) {
alert('File is too large (maximum 10MB supported).');
resolve(false);
return;
}

const reader = new FileReader();
reader.onload = function(e) {
const text = e.target.result || '';
const reader = new FileReader();
reader.onload = function(e) {
const text = e.target.result || '';

// Simple binary check: look for null bytes in the first 8KB
const checkLength = Math.min(text.length, 8000);
for (let i = 0; i < checkLength; i++) {
if (text.charCodeAt(i) === 0) {
alert('Cannot import: The selected file appears to be a binary file.');
return;
// Simple binary check: look for null bytes in the first 8KB
const checkLength = Math.min(text.length, 8000);
for (let i = 0; i < checkLength; i++) {
if (text.charCodeAt(i) === 0) {
alert('Cannot import: The selected file appears to be a binary file.');
resolve(false);
return;
}
}

newTab(text, getMarkdownFileTitle(file));
resolve(true);
};
reader.onerror = function() {
alert('Failed to read the file. Please check permissions and try again.');
resolve(false);
};
reader.readAsText(file);
});
}

async function importMarkdownFiles(fileList, options) {
const settings = options || {};
const files = Array.from(fileList || []);
const markdownFiles = files.filter(isMarkdownFile);

if (!markdownFiles.length) {
if (settings.showInvalidAlert !== false) {
alert("Please upload Markdown files (.md or .markdown)");
}
return 0;
}

newTab(text, file.name.replace(/\.md$/i, ''));
};
reader.onerror = function() {
alert('Failed to read the file. Please check permissions and try again.');
};
reader.readAsText(file);
let importedCount = 0;
for (const file of markdownFiles) {
if (await importMarkdownFile(file)) {
importedCount++;
}
}

return importedCount;
}

function isMarkdownPath(path) {
Expand Down Expand Up @@ -9879,12 +9923,12 @@ document.addEventListener("DOMContentLoaded", async function () {
});
}

fileInput.addEventListener("change", function (e) {
const file = e.target.files[0];
if (file) {
importMarkdownFile(file);
fileInput.addEventListener("change", async function (e) {
try {
await importMarkdownFiles(e.target.files);
} finally {
this.value = "";
}
this.value = "";
});

exportMd.addEventListener("click", function () {
Expand Down Expand Up @@ -14235,19 +14279,11 @@ document.addEventListener("DOMContentLoaded", async function () {
handleDrop(e);
}, false);

function handleDrop(e) {
async function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
if (files.length) {
const file = files[0];
const isMarkdownFile =
file.type === "text/markdown" ||
/\.(md|markdown)$/i.test(file.name || "");
if (isMarkdownFile) {
importMarkdownFile(file);
} else {
alert("Please upload a Markdown file (.md or .markdown)");
}
const files = dt && dt.files;
if (files && files.length) {
await importMarkdownFiles(files);
}
}

Expand Down
6 changes: 3 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ <h1 class="h4 mb-0 me-2">Markdown Viewer</h1>
<li><a class="dropdown-item" href="#" id="import-from-github"><i class="bi bi-github me-2"></i>From GitHub</a></li>
</ul>
</div>
<input type="file" id="file-input" class="file-input" accept=".md,.markdown,text/markdown">
<input type="file" id="file-input" class="file-input" accept=".md,.markdown,text/markdown" multiple>

<div class="dropdown">
<button class="tool-button dropdown-toggle" type="button" id="exportDropdown" data-bs-toggle="dropdown" aria-expanded="false" title="Export Markdown">
Expand Down Expand Up @@ -1100,7 +1100,7 @@ <h3 class="modal-section-title">Open-source credits</h3>
<div id="drag-overlay" class="drag-overlay" aria-hidden="true">
<div class="drag-overlay-inner">
<i class="bi bi-cloud-arrow-up drag-overlay-icon"></i>
<p class="drag-overlay-text">Drop your Markdown file anywhere</p>
<p class="drag-overlay-text">Drop your Markdown files anywhere</p>
<p class="drag-overlay-sub">.md or .markdown files supported</p>
</div>
</div>
Expand All @@ -1123,7 +1123,7 @@ <h3 class="modal-section-title">Open-source credits</h3>
</div>
<textarea id="markdown-editor" placeholder="Type, paste, or import Markdown here..." aria-label="Markdown editor input with live preview"></textarea>
<div class="drop-hint" aria-hidden="true">
<i class="bi bi-cloud-arrow-up me-1"></i>Drop a .md file anywhere to open it
<i class="bi bi-cloud-arrow-up me-1"></i>Drop .md files anywhere to open them
</div>
</div>
<!-- Resize Divider - Story 1.3 -->
Expand Down
108 changes: 72 additions & 36 deletions script.js
Original file line number Diff line number Diff line change
Expand Up @@ -4684,31 +4684,75 @@ ${selector} .arrowheadPath {
}
}

function isMarkdownFile(file) {
return Boolean(file) && (
file.type === "text/markdown" ||
/\.(md|markdown)$/i.test(file.name || "")
);
}

function getMarkdownFileTitle(file) {
return (file && file.name ? file.name : "document.md").replace(/\.(md|markdown)$/i, "");
}

function importMarkdownFile(file) {
if (file.size > 10 * 1024 * 1024) {
alert('File is too large (maximum 10MB supported).');
return;
}
return new Promise(function(resolve) {
if (!file) {
resolve(false);
return;
}

if (file.size > 10 * 1024 * 1024) {
alert('File is too large (maximum 10MB supported).');
resolve(false);
return;
}

const reader = new FileReader();
reader.onload = function(e) {
const text = e.target.result || '';
const reader = new FileReader();
reader.onload = function(e) {
const text = e.target.result || '';

// Simple binary check: look for null bytes in the first 8KB
const checkLength = Math.min(text.length, 8000);
for (let i = 0; i < checkLength; i++) {
if (text.charCodeAt(i) === 0) {
alert('Cannot import: The selected file appears to be a binary file.');
return;
// Simple binary check: look for null bytes in the first 8KB
const checkLength = Math.min(text.length, 8000);
for (let i = 0; i < checkLength; i++) {
if (text.charCodeAt(i) === 0) {
alert('Cannot import: The selected file appears to be a binary file.');
resolve(false);
return;
}
}

newTab(text, getMarkdownFileTitle(file));
resolve(true);
};
reader.onerror = function() {
alert('Failed to read the file. Please check permissions and try again.');
resolve(false);
};
reader.readAsText(file);
});
}

async function importMarkdownFiles(fileList, options) {
const settings = options || {};
const files = Array.from(fileList || []);
const markdownFiles = files.filter(isMarkdownFile);

if (!markdownFiles.length) {
if (settings.showInvalidAlert !== false) {
alert("Please upload Markdown files (.md or .markdown)");
}
return 0;
}

newTab(text, file.name.replace(/\.md$/i, ''));
};
reader.onerror = function() {
alert('Failed to read the file. Please check permissions and try again.');
};
reader.readAsText(file);
let importedCount = 0;
for (const file of markdownFiles) {
if (await importMarkdownFile(file)) {
importedCount++;
}
}

return importedCount;
}

function isMarkdownPath(path) {
Expand Down Expand Up @@ -10110,12 +10154,12 @@ ${selector} .arrowheadPath {
});
}

fileInput.addEventListener("change", function (e) {
const file = e.target.files[0];
if (file) {
importMarkdownFile(file);
fileInput.addEventListener("change", async function (e) {
try {
await importMarkdownFiles(e.target.files);
} finally {
this.value = "";
}
this.value = "";
});

exportMd.addEventListener("click", function () {
Expand Down Expand Up @@ -14466,19 +14510,11 @@ ${selector} .arrowheadPath {
handleDrop(e);
}, false);

function handleDrop(e) {
async function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
if (files.length) {
const file = files[0];
const isMarkdownFile =
file.type === "text/markdown" ||
/\.(md|markdown)$/i.test(file.name || "");
if (isMarkdownFile) {
importMarkdownFile(file);
} else {
alert("Please upload a Markdown file (.md or .markdown)");
}
const files = dt && dt.files;
if (files && files.length) {
await importMarkdownFiles(files);
}
}

Expand Down
Loading