diff --git a/package-lock.json b/package-lock.json
index e767aa445..cdd1e372a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -128,7 +128,6 @@
"integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.27.1",
@@ -2959,7 +2958,8 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/@types/markdown-it": {
"version": "14.1.2",
@@ -2976,7 +2976,8 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/@types/node": {
"version": "24.2.1",
@@ -3289,8 +3290,7 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz",
"integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==",
- "license": "MIT",
- "peer": true
+ "license": "MIT"
},
"node_modules/@xtuc/ieee754": {
"version": "1.2.0",
@@ -3321,7 +3321,6 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -3355,7 +3354,6 @@
"version": "8.12.0",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
@@ -3736,7 +3734,6 @@
}
],
"license": "MIT",
- "peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001733",
"electron-to-chromium": "^1.5.199",
@@ -3839,7 +3836,6 @@
"integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==",
"dev": true,
"license": "Apache-2.0",
- "peer": true,
"dependencies": {
"@chevrotain/cst-dts-gen": "11.0.3",
"@chevrotain/gast": "11.0.3",
@@ -6020,7 +6016,6 @@
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
"license": "MIT",
- "peer": true,
"dependencies": {
"argparse": "^2.0.1",
"entities": "^4.4.0",
@@ -6906,7 +6901,6 @@
"url": "https://github.com/sponsors/ai"
}
],
- "peer": true,
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.0",
@@ -7061,7 +7055,6 @@
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -7228,7 +7221,6 @@
"version": "6.12.6",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -8061,7 +8053,6 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"license": "MIT",
- "peer": true,
"engines": {
"node": ">=12"
},
@@ -8333,7 +8324,6 @@
"integrity": "sha512-B4t+nJqytPeuZlHuIKTbalhljIFXeNRqrUGAQgTGlfOl2lXXKXw+yZu6bicycP+PUlM44CxBjCFD6aciKFT3LQ==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.8",
@@ -8383,7 +8373,6 @@
"integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==",
"dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"@discoveryjs/json-ext": "^0.6.1",
"@webpack-cli/configtest": "^3.0.1",
diff --git a/src/lib/run.js b/src/lib/run.js
index 709217531..559c29ad6 100644
--- a/src/lib/run.js
+++ b/src/lib/run.js
@@ -4,9 +4,7 @@ import alert from "dialogs/alert";
import box from "dialogs/box";
import markdownIt from "markdown-it";
import anchor from "markdown-it-anchor";
-import markdownItFootnote from "markdown-it-footnote";
import MarkdownItGitHubAlerts from "markdown-it-github-alerts";
-import markdownItTaskLists from "markdown-it-task-lists";
import mimeType from "mime-types";
import mustache from "mustache";
import browser from "plugins/browser";
@@ -16,7 +14,7 @@ import $_console from "views/console.hbs";
import $_markdown from "views/markdown.hbs";
import constants from "./constants";
import EditorFile from "./editorFile";
-import openFolder, { addedFolder } from "./openFolder";
+import openFolder from "./openFolder";
import appSettings from "./settings";
/**@type {Server} */
@@ -60,7 +58,6 @@ async function run(
const uuid = helpers.uuid();
let isLoading = false;
- let isFallback = false;
let filename, pathName, extension;
let port = appSettings.value.serverPort;
let EXECUTING_SCRIPT = uuid + "_script.js";
@@ -83,21 +80,11 @@ async function run(
try {
const fs = fsOperation(activeFile.uri);
const res = await fs.readFile();
- let text = new TextDecoder().decode(res);
-
- if (!/^<\?xml/.test(text)) {
- text = `\n` + text;
- }
-
- const blob = new Blob([text], { type: mimeType.lookup(extension) });
- const url = URL.createObjectURL(blob);
+ const blob = new Blob([new Uint8Array(res)], {
+ type: mimeType.lookup(extension),
+ });
- box(
- filename,
- `
-

-
`,
- );
+ box(filename, `
`);
} catch (err) {
helpers.error(err);
}
@@ -137,17 +124,17 @@ async function run(
}
function startConsole() {
+ runConsole();
+ start();
+ }
+
+ function runConsole() {
if (!isConsole) EXECUTING_SCRIPT = activeFile.filename;
isConsole = true;
target = "inapp";
filename = "console.html";
-
- //this extra www is incorrect because asset_directory itself has www
- //but keeping it in case something depends on it
pathName = `${ASSETS_DIRECTORY}www/`;
port = constants.CONSOLE_PORT;
-
- start();
}
function start() {
@@ -165,7 +152,6 @@ async function run(
}
function startServer() {
- //isFallback = true;
webServer?.stop();
webServer = CreateServer(port, openBrowser, onError);
webServer.setOnRequestHandler(handleRequest);
@@ -186,19 +172,14 @@ async function run(
* @param {string} req.requestId
* @param {string} req.path
*/
- async function handleRequest(req) {
+ function handleRequest(req) {
const reqId = req.requestId;
let reqPath = req.path.substring(1);
- console.log(`XREQPATH ${reqPath}`);
- console.log(req);
-
- if (!reqPath || (reqPath.endsWith("/") && reqPath.length === 1)) {
- reqPath = getRelativePath();
+ if (!reqPath || reqPath.endsWith("/")) {
+ reqPath += "index.html";
}
- console.log(`XREQPATH1 ${reqPath}`);
-
const ext = Url.extname(reqPath);
let url = null;
@@ -208,7 +189,7 @@ async function run(
isConsole ||
appSettings.value.console === appSettings.CONSOLE_LEGACY
) {
- url = `${ASSETS_DIRECTORY}/build/console.js`;
+ url = `${ASSETS_DIRECTORY}/js/build/console.build.js`;
} else {
url = `${DATA_STORAGE}/eruda.js`;
}
@@ -266,111 +247,10 @@ async function run(
}
let url = activeFile.uri;
-
let file = activeFile.SAFMode === "single" ? activeFile : null;
if (pathName) {
- const projectFolder = addedFolder[0];
- const query = url.split("?")[1];
- let rootFolder = "";
-
- if (
- projectFolder !== undefined &&
- pathName.includes(projectFolder.url)
- ) {
- rootFolder = projectFolder.url;
- } else {
- rootFolder = pathName;
- }
-
- if (
- (rootFolder.startsWith("ftp:") || rootFolder.startsWith("sftp:")) &&
- rootFolder.includes("?")
- ) {
- rootFolder = rootFolder.split("?")[0];
- }
-
- rootFolder = rootFolder.replace(/\/+$/, ""); // remove trailing slash
- reqPath = reqPath.replace(/^\/+/, ""); // remove leading slash
-
- const rootParts = rootFolder.split("/");
- const pathParts = reqPath.split("/");
-
- if (pathParts[0] === rootParts[rootParts.length - 1]) {
- pathParts.shift();
- }
-
- function removePrefix(str, prefix) {
- if (str.startsWith(prefix)) {
- return str.slice(prefix.length);
- }
- return str;
- }
-
- function findOverlap(a, b) {
- // Start with the smallest possible overlap (1 character) and increase
- let maxOverlap = "";
-
- // Check all possible overlapping lengths
- for (let i = 1; i <= Math.min(a.length, b.length); i++) {
- // Get the ending substring of a with length i
- const endOfA = a.slice(-i);
- // Get the starting substring of b with length i
- const startOfB = b.slice(0, i);
-
- // If they match, we have a potential overlap
- if (endOfA === startOfB) {
- maxOverlap = endOfA;
- }
- }
-
- return maxOverlap;
- }
-
- console.log(`RootFolder ${rootFolder}`);
- console.log(`PARTS ${pathParts.join("/")}`);
-
- let fullPath;
- // Skip overlap detection for GitHub URIs as it causes path corruption
- if (rootFolder.startsWith("gh://")) {
- fullPath = Url.join(rootFolder, pathParts.join("/"));
- } else {
- const overlap = findOverlap(rootFolder, pathParts.join("/"));
- if (overlap !== "") {
- fullPath = Url.join(
- rootFolder,
- removePrefix(pathParts.join("/"), overlap),
- );
- } else {
- fullPath = Url.join(rootFolder, pathParts.join("/"));
- }
- }
-
- console.log(`Full PATH ${fullPath}`);
-
- const urlFile = fsOperation(fullPath);
-
- // Skip stat check for GitHub URIs as they are handled differently
- if (!fullPath.startsWith("gh://")) {
- const stats = await urlFile.stat();
-
- if (!stats.exists) {
- error(reqId);
- return;
- }
-
- if (!stats.isFile) {
- if (fullPath.endsWith("/")) {
- fullPath += "index.html";
- } else {
- fullPath += "/index.html";
- }
- }
- }
-
- // Add back the query if present
- url = query ? `${fullPath}?${query}` : fullPath;
-
+ url = Url.join(pathName, reqPath);
file = editorManager.getFile(url, "uri");
} else if (!activeFile.uri) {
file = activeFile;
@@ -397,8 +277,6 @@ async function run(
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-"),
})
- .use(markdownItTaskLists)
- .use(markdownItFootnote)
.render(file.session.getValue());
const doc = mustache.render($_markdown, {
html,
@@ -411,15 +289,11 @@ async function run(
default:
if (file && file.loaded && file.isUnsaved) {
- if (file.filename.endsWith(".html")) {
- sendHTML(file.session.getValue(), reqId);
- } else {
- sendText(
- file.session.getValue(),
- reqId,
- mimeType.lookup(file.filename),
- );
- }
+ sendText(
+ file.session.getValue(),
+ reqId,
+ mimeType.lookup(file.filename),
+ );
} else if (url) {
if (reqPath === "favicon.ico") {
sendIco(ASSETS_DIRECTORY, reqId);
@@ -451,7 +325,7 @@ async function run(
* @param {string} reqId
*/
function sendIco(assets, reqId) {
- const ico = Url.join(assets, "favicon.ico");
+ const ico = Url.join(assets, "res/logo/favicon.ico");
sendFile(ico, reqId);
}
@@ -573,20 +447,10 @@ async function run(
* @returns
*/
async function sendFileContent(url, id, mime, processText) {
- let fs = fsOperation(url);
+ const fs = fsOperation(url);
if (!(await fs.exists())) {
- const xfs = fsOperation(Url.join(pathName, filename));
-
- if (await xfs.exists()) {
- fs = xfs;
- isFallback = true;
- console.log(`fallback ${Url.join(pathName, filename)}`);
- } else {
- console.log(`${url} doesnt exists`);
- error(id);
- }
-
+ error(id);
return;
}
@@ -616,208 +480,18 @@ async function run(
});
}
- function makeUriAbsoluteIfNeeded(uri) {
- const termuxRootEncoded =
- "content://com.termux.documents/tree/%2Fdata%2Fdata%2Fcom.termux%2Ffiles%2Fhome";
- const termuxRootDecoded = "/data/data/com.termux/files/home";
-
- if (uri.startsWith(termuxRootEncoded)) {
- // Extract subpath after `::` if already absolute
- if (uri.includes("::")) return uri;
-
- const decodedPath = decodeURIComponent(uri.split("tree/")[1] || "");
- return `${termuxRootEncoded}::${decodedPath}/`;
- }
-
- return uri;
- }
-
- function getRelativePath() {
- // Get the project url
- const projectFolder = addedFolder[0];
-
- // FIXED: Better root folder determination for Termux URIs
- let rootFolder = pathName;
-
- // Special handling for Termux URIs - extract the actual root from the URI structure
- if (
- activeFile &&
- activeFile.uri &&
- activeFile.uri.includes("com.termux.documents") &&
- activeFile.uri.includes("tree/")
- ) {
- // Extract the tree part and decode it to get the actual root path
- const treeMatch = activeFile.uri.match(/tree\/([^:]+)/);
- if (treeMatch) {
- try {
- const decodedRoot = decodeURIComponent(treeMatch[1]);
- rootFolder = decodedRoot;
- console.log(`DEBUG - Termux root folder set to: ${rootFolder}`);
- } catch (e) {
- console.error("Error decoding Termux root:", e);
- }
- }
- } else if (
- projectFolder !== undefined &&
- pathName &&
- pathName.includes(projectFolder.url)
- ) {
- rootFolder = projectFolder.url;
- }
-
- //make the uri absolute if necessary
- rootFolder = makeUriAbsoluteIfNeeded(rootFolder);
-
- // Parent of the file
- let filePath = pathName;
-
- if (rootFolder.startsWith("ftp:") || rootFolder.startsWith("sftp:")) {
- if (rootFolder.includes("?")) {
- rootFolder = rootFolder.split("?")[0];
- }
- }
-
- //remove the query string if present this is needs to be removed because the url is not valid
- if (filePath.startsWith("ftp:") || rootFolder.startsWith("sftp:")) {
- if (filePath.includes("?")) {
- filePath = filePath.split("?")[0];
- }
- }
-
- // Create full file path
- let temp = Url.join(filePath, filename);
-
- // Special handling for Termux URIs
- if (temp.includes("com.termux.documents") && temp.includes("::")) {
- try {
- const [, realPath] = temp.split("::");
-
- console.log(`DEBUG - realPath: ${realPath}`);
- console.log(`DEBUG - rootFolder: ${rootFolder}`);
-
- // Ensure rootFolder doesn't have trailing slash for comparison
- const normalizedRoot = rootFolder.replace(/\/+$/, "");
-
- // Check if realPath starts with rootFolder
- if (realPath.startsWith(normalizedRoot)) {
- // Remove the rootFolder from the beginning of realPath
- let relativePath = realPath.substring(normalizedRoot.length);
-
- // Remove leading slash if present
- relativePath = relativePath.replace(/^\/+/, "");
-
- console.log(`DEBUG - relativePath: ${relativePath}`);
-
- if (relativePath) {
- return relativePath;
- }
- }
- } catch (e) {
- console.error("Error handling Termux URI:", e);
- }
- }
-
- // Handle other content:// URIs
- if (temp.includes("content://") && temp.includes("::")) {
- try {
- // Get the part after :: which contains the actual file path
- const afterDoubleColon = temp.split("::")[1];
-
- if (afterDoubleColon) {
- // Extract the rootFolder's content path if it has ::
- let rootFolderPath = rootFolder;
- if (rootFolder.includes("::")) {
- rootFolderPath = rootFolder.split("::")[1];
- }
-
- // If rootFolder doesn't have ::, try to extract the last part of the path
- if (!rootFolderPath.includes("::")) {
- const rootParts = rootFolder.split("/");
- const lastPart = rootParts[rootParts.length - 1];
-
- // Check if the lastPart is encoded
- if (lastPart.includes("%3A")) {
- // Try to decode it
- try {
- const decoded = decodeURIComponent(lastPart);
- rootFolderPath = decoded;
- } catch (e) {
- console.error("Error decoding URI component:", e);
- rootFolderPath = lastPart;
- }
- } else {
- rootFolderPath = lastPart;
- }
- }
-
- // Use direct string replacement instead of path component comparison
- const normalizedRoot = rootFolderPath.replace(/\/+$/, "");
- if (afterDoubleColon.startsWith(normalizedRoot)) {
- let relativePath = afterDoubleColon.substring(
- normalizedRoot.length,
- );
- // Remove leading slash if present
- relativePath = relativePath.replace(/^\/+/, "");
-
- if (relativePath) {
- return relativePath;
- }
- }
- }
- } catch (e) {
- console.error("Error parsing content URI:", e);
- }
- }
-
- // For regular paths or if content:// URI parsing failed
- // Try to find a common prefix between rootFolder and temp
- // and remove it from temp
- try {
- const rootParts = rootFolder.split("/");
- const tempParts = temp.split("/");
-
- let commonIndex = 0;
- for (let i = 0; i < Math.min(rootParts.length, tempParts.length); i++) {
- if (rootParts[i] === tempParts[i]) {
- commonIndex = i + 1;
- } else {
- break;
- }
- }
-
- if (commonIndex > 0) {
- return tempParts.slice(commonIndex).join("/");
- }
- } catch (e) {
- console.error("Error finding common path:", e);
- }
-
- // If all else fails, just return the filename
- if (filename) {
- return filename;
- }
-
- console.log("Unable to determine relative path, returning full path");
- return temp;
- }
-
/**
* Opens the preview in browser
*/
function openBrowser() {
- let url = "";
- if (pathName === null && !activeFile.location) {
- url = `http://localhost:${port}/__unsaved_file__`;
- } else {
- url = `http://localhost:${port}/${getRelativePath()}`;
- }
-
+ console.count("openBrowser");
+ const src = `http://localhost:${port}/${filename}`;
if (target === "browser") {
- system.openInBrowser(url);
+ system.openInBrowser(src);
return;
}
- browser.open(url, isConsole);
+ browser.open(src, isConsole);
}
}