Compare commits

...

12 Commits

3 changed files with 139 additions and 13 deletions
+4 -5
View File
@@ -1,5 +1,5 @@
<p align="center"> <p align="center">
<img src="./icon-192.png" /> <img src="https://pascar.run/icon-192.png" />
</p> </p>
<p align="center"> <p align="center">
@@ -31,12 +31,11 @@ runs entirely in your browser - no server, no internet.
## Portability ## Portability
Pascar is a self-contained single HTML file. Pascar is a self-contained single HTML file.
If you want this to be portable in your USB stick, you just need to download this single file [pascar.html](https://github.com/potentzero/pascar/releases/latest/download/pascar.html) and use it. If you want this to be portable in your USB stick, you just need to download this single file [pascar.html](https://git.ennt.io/mysticmode/pascar/releases/download/v0.1.0/pascar.html) and use it.
## License ## License
This software is license under **MIT License**. Please refer the [LICENSE](./LICENSE) text for more detail. This software is license under **MIT License**. Please refer the [LICENSE](./LICENSE) text for more detail.
## Contributing ## Contributing
Feel free to contribute by creating an issue or diving into the code and PRs. I do not accept external contributions. For feature requests and bug reports,
please get in touch with me at my email - tildezero@gmail.com
I do not have a Code of Conduct, but a simple rule - be nice when you deal with others.
+1 -1
View File
File diff suppressed because one or more lines are too long
+131 -4
View File
@@ -185,6 +185,84 @@
} }
/* Textarea */ /* Textarea */
#editor-panel {
display: flex;
flex: 1;
min-width: 0;
overflow: hidden;
}
#preview-panel {
display: none;
flex: 1;
min-width: 0;
overflow: auto;
border-left: 1px solid var(--border);
background: #fff;
color: #222;
padding: 12px;
}
#preview-panel.active {
display: block;
}
#preview {
width: 100%;
min-height: 100%;
overflow-wrap: break-word;
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
line-height: 1.5;
}
#preview h1,
#preview h2,
#preview h3,
#preview h4,
#preview h5,
#preview h6 {
color: #222222;
margin-top: 1rem;
margin-bottom: 0.5rem;
}
#preview p,
#preview li,
#preview pre,
#preview code,
#preview blockquote {
color: #222222;
}
#preview pre {
background: #111111;
padding: 10px;
border-radius: 4px;
overflow: auto;
}
#preview code {
color: #ffffff;
padding: 2px 4px;
border-radius: 3px;
}
#preview a {
color: #7db4ff;
text-decoration: none;
}
#preview blockquote {
border-left: 4px solid #555555;
padding-left: 12px;
margin: 0.75rem 0;
}
#preview blockquote p {
color: #555555;
}
#editor { #editor {
flex: 1; flex: 1;
background: var(--bg); background: var(--bg);
@@ -522,6 +600,7 @@
font-size: 13px; font-size: 13px;
} }
</style> </style>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
</head> </head>
<body> <body>
@@ -647,8 +726,13 @@
<!-- Main Editor Area --> <!-- Main Editor Area -->
<div id="editor-area"> <div id="editor-area">
<div id="editor-panel">
<div id="line-numbers"></div> <div id="line-numbers"></div>
<textarea id="editor" spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off"></textarea> <textarea id="editor" spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off"></textarea>
</div>
<div id="preview-panel" class="preview-panel">
<div id="preview"></div>
</div>
<!-- Modal Overlay --> <!-- Modal Overlay -->
<div id="dialog-overlay"> <div id="dialog-overlay">
@@ -952,6 +1036,8 @@
const gotoBar = document.getElementById("goto-bar"); const gotoBar = document.getElementById("goto-bar");
const gotoInput = document.getElementById("goto-input"); const gotoInput = document.getElementById("goto-input");
const menuBar = document.getElementById("menu-bar"); const menuBar = document.getElementById("menu-bar");
const previewPanel = document.getElementById("preview-panel");
const preview = document.getElementById("preview");
// -- State // -- State
let fileName = "Untitled"; let fileName = "Untitled";
@@ -964,13 +1050,14 @@
let lastReplace = ""; let lastReplace = "";
let notifTimer = null; let notifTimer = null;
let replaceMode = false; let replaceMode = false;
let markdownPreview = false;
// -- Initial Content // -- Initial Content
editor.value = [ editor.value = [
"Pascar", "Pascar",
"======", "======",
"", "",
"A faithful offline recreation of the classic MS-DOS Editor", "A browser-based offline recreation of the classic MS-DOS Editor for the modern needs of today.",
"Runs entirely in your browser - no server, no internet.", "Runs entirely in your browser - no server, no internet.",
"", "",
"QUICK START", "QUICK START",
@@ -1037,6 +1124,36 @@
(isModified ? "* " : "") + fileName + " - Pascar"; (isModified ? "* " : "") + fileName + " - Pascar";
} }
function isMarkdownFile(name) {
return /\.md$/i.test(name);
}
function setMarkdownPreview(active) {
markdownPreview = active;
previewPanel.classList.toggle("active", active);
if (active) {
renderMarkdownPreview();
} else {
preview.innerHTML = "";
}
}
function renderMarkdownPreview() {
if (!markdownPreview) return;
if (typeof marked === "undefined") {
preview.innerHTML =
"<p><em>Marked.js failed to load. Markdown preview is unavailable.</em></p>";
return;
}
try {
preview.innerHTML = marked.parse(editor.value || "");
} catch (err) {
preview.innerHTML =
`<p><em>Error rendering markdown:</em></p><pre>${escHtml(err.message)}</pre>`;
}
}
// -- Notifications // -- Notifications
function showNotif(msg, dur = 2500) { function showNotif(msg, dur = 2500) {
notif.textContent = msg; notif.textContent = msg;
@@ -1049,6 +1166,7 @@
editor.addEventListener("input", () => { editor.addEventListener("input", () => {
isModified = true; isModified = true;
updateAll(); updateAll();
if (markdownPreview) renderMarkdownPreview();
}); });
editor.addEventListener("keyup", updateStatus); editor.addEventListener("keyup", updateStatus);
editor.addEventListener("click", updateStatus); editor.addEventListener("click", updateStatus);
@@ -1196,7 +1314,13 @@
}); });
document.addEventListener("click", (e) => { document.addEventListener("click", (e) => {
if (e.target.closest("#menu-bar")) closeAll(); // If the click is inside the menu-bar, do not close all
if (e.target.closest("#menu-bar")) return;
// If any menu-item or dropdown is open, close all
if (document.querySelectorAll('.menu-item.active, .dropdown.open').length > 0) {
closeAll();
}
}); });
// -- Global Keyboard Shortcuts // -- Global Keyboard Shortcuts
@@ -1444,6 +1568,7 @@
fileName = "Untitled"; fileName = "Untitled";
fileHandle = null; fileHandle = null;
isModified = false; isModified = false;
setMarkdownPreview(false);
updateAll(); updateAll();
editor.focus(); editor.focus();
} }
@@ -1493,6 +1618,7 @@
fileName = file.name; fileName = file.name;
editor.value = await file.text(); editor.value = await file.text();
isModified = false; isModified = false;
setMarkdownPreview(isMarkdownFile(fileName));
updateAll(); updateAll();
editor.focus(); editor.focus();
showNotif(`Opened: ${fileName}`); showNotif(`Opened: ${fileName}`);
@@ -1513,6 +1639,7 @@
reader.onload = (e) => { reader.onload = (e) => {
editor.value = e.target.result; editor.value = e.target.result;
isModified = false; isModified = false;
setMarkdownPreview(isMarkdownFile(fileName));
updateAll(); updateAll();
editor.focus(); editor.focus();
showNotif(`Opened: ${fileName}`); showNotif(`Opened: ${fileName}`);
@@ -1576,6 +1703,7 @@
await writable.write(editor.value); await writable.write(editor.value);
await writable.close(); await writable.close();
isModified = false; isModified = false;
setMarkdownPreview(isMarkdownFile(fileName));
updateStatus(); updateStatus();
showNotif(`Saved: ${fileName}`); showNotif(`Saved: ${fileName}`);
} catch (err) { } catch (err) {
@@ -1904,7 +2032,6 @@
}); });
dialogOv.addEventListener("click", (e) => { dialogOv.addEventListener("click", (e) => {
if (e.target.id == "source-code-link") { if (e.target.id == "source-code-link") {
window.open("https://github.com/potentzero/pascar", "_blank");
return; return;
} }
e.preventDefault(); e.preventDefault();
@@ -1927,7 +2054,7 @@
Open &amp; save files via your local filesystem. Open &amp; save files via your local filesystem.
</div> </div>
<div style="font-size:14px;line-height:1.6;text-align:center;"> <div style="font-size:14px;line-height:1.6;text-align:center;">
<a id="source-code-link" style="color:#295991;" href="https://github.com/potentzero/pascar" target="_blank">Source code</a> <a id="source-code-link" style="color:#295991;" href="https://git.ennt.io/mysticmode/pascar" target="_blank">Source code</a>
by Nirmal Kumar R. by Nirmal Kumar R.
</div> </div>
<div class="dialog-buttons"><button class="btn primary" id="d-about-ok">OK</button></div> <div class="dialog-buttons"><button class="btn primary" id="d-about-ok">OK</button></div>