diff --git a/build.bat b/build.bat
new file mode 100644
index 0000000..d66153f
--- /dev/null
+++ b/build.bat
@@ -0,0 +1,2 @@
+@echo off
+npx electron-builder
\ No newline at end of file
diff --git a/electron-builder.json b/electron-builder.json
index 48ceb75..4188f8e 100644
--- a/electron-builder.json
+++ b/electron-builder.json
@@ -4,8 +4,14 @@
"directories": {
"output": "dist"
},
- "files": ["!filePresets/**"],
- "extraResources": [{ "from": "filePresets", "to": "../filePresets" }],
+ "files": ["!filePresets/**", "!front/editor/highlighter.css"],
+ "extraResources": [
+ { "from": "filePresets", "to": "../filePresets" },
+ {
+ "from": "front/editor/highlighter.css",
+ "to": "../front/editor/highlighter.css"
+ }
+ ],
"icon": "resources/icon/icon.ico",
"win": {
"target": "zip",
diff --git a/front/editor/editor.html b/front/editor/editor.html
index c9a3e4e..776b367 100644
--- a/front/editor/editor.html
+++ b/front/editor/editor.html
@@ -4,7 +4,6 @@
WebBox
-
diff --git a/front/editor/editor.js b/front/editor/editor.js
index 8cd0253..28bccb4 100644
--- a/front/editor/editor.js
+++ b/front/editor/editor.js
@@ -1,6 +1,6 @@
/*
///////////////////////////////////////////////////////////////
- Index - Search with Ctrl + F (VSCode)
+ editor.js / Index - Search with Ctrl + F (VSCode)
///////////////////////////////////////////////////////////////
- Module Import
@@ -22,6 +22,8 @@
- New File Dialog
- Open Viewer
- Pick Opened Display Dialog
+ - Load Highlighter
+ - Handle Window Deletion
- Others
*/
@@ -41,6 +43,7 @@ const {
const highlighter = require("./highlight");
const { getCaretPosition, setCaretPosition } = require("./modules/caret");
const fs = require("fs");
+const path = require("path");
///////////////////////////////////////////////////////////////
// Setup Needle DB
@@ -382,11 +385,9 @@ document.addEventListener("keydown", async (event) => {
}
} else if (event.key.toLowerCase() === "w") {
event.preventDefault();
+ if (currentFile === null) return;
if (event.shiftKey) {
- if (
- currentFile === null ||
- (!currentFile.endsWith(".html") && !currentFile.endsWith(".htm"))
- ) {
+ if (!currentFile.endsWith(".html") && !currentFile.endsWith(".htm")) {
ipcRenderer.send("new-window");
} else {
ipcRenderer.invoke("new-window-set", currentFile).then((response) => {
@@ -575,8 +576,19 @@ async function refreshEditor() {
});
OpenedDisplays.forEach((e) => {
+ Array.from(document.getElementById("windowPicker").children).forEach(
+ (child) => {
+ child.remove();
+ }
+ );
+ //
+ const noOption = document.createElement("option");
+ noOption.value = "none";
+ noOption.innerHTML = "(none)";
+ document.getElementById("windowPicker").appendChild(noOption);
+
const option = document.createElement("option");
- option.value = e.window;
+ option.value = e.fileLink;
const splittedFileLink = e.fileLink.split("\\");
option.innerHTML = `${splittedFileLink[splittedFileLink.length - 2]}\\${splittedFileLink[splittedFileLink.length - 1]}`;
document.getElementById("windowPicker").appendChild(option);
@@ -746,20 +758,33 @@ createBtn.addEventListener("click", () => {
if (args.dir == null || args.name == null || args.preset == null) {
alert("Argument missing.");
} else {
- ipcRenderer.invoke("createFile", args).then((response) => {
- if (response == 0) {
- openFile(`${args.dir}\\${args.name}`, () => {
- loadFileIntoEditor(`${args.dir}\\${args.name}`);
- });
- document.getElementById("filenameField").value = "";
- dir = null;
- document.getElementById("fileDirLbl").innerHTML = "No folder selected";
- document.getElementById("presetPicker").value = "none";
- document.getElementById("newFileDialog").close();
- } else {
- alert("Error in file creation");
+ let filedata = "";
+
+ if (args.preset !== "none") {
+ filedata = fs.readFileSync(args.preset, { encoding: "utf-8" });
+ }
+
+ let ans = 0;
+
+ fs.writeFile(`${args.dir}\\${args.name}`, filedata, function (err) {
+ if (err) {
+ ans = err;
+ throw err;
}
});
+
+ if (ans == 0) {
+ openFile(`${args.dir}\\${args.name}`, () => {
+ loadFileIntoEditor(`${args.dir}\\${args.name}`);
+ });
+ document.getElementById("filenameField").value = "";
+ dir = null;
+ document.getElementById("fileDirLbl").innerHTML = "No folder selected";
+ document.getElementById("presetPicker").value = "none";
+ document.getElementById("newFileDialog").close();
+ } else {
+ alert("Error in file creation");
+ }
}
});
@@ -770,11 +795,9 @@ createBtn.addEventListener("click", () => {
const openViewerBtn = document.getElementById("OpenViewerBtn");
openViewerBtn.addEventListener("click", (event) => {
+ if (currentFile === null) return;
if (event.shiftKey) {
- if (
- currentFile === null ||
- (!currentFile.endsWith(".html") && !currentFile.endsWith(".htm"))
- ) {
+ if (!currentFile.endsWith(".html") && !currentFile.endsWith(".htm")) {
ipcRenderer.send("new-window");
} else {
ipcRenderer.invoke("new-window-set", currentFile).then((response) => {
@@ -807,7 +830,7 @@ cancelDisplayPickBtn.addEventListener("click", () => {
const pickWindowBtn = document.getElementById("pickWindowBtn");
pickWindowBtn.addEventListener("click", () => {
- if (document.getElementById("windowPicker").value != "none") {
+ if (document.getElementById("windowPicker").value !== "none") {
OpenedFiles.SET(
OpenedFiles.FINDQUICKINDEX("fileLink", currentFile),
"linkedDisplay",
@@ -815,9 +838,34 @@ pickWindowBtn.addEventListener("click", () => {
);
pickOpenedDisplayDialog.close();
document.getElementById("windowPicker").value = "none";
+ } else {
+ pickOpenedDisplayDialog.close();
}
});
+//////////////////////////////////////////////////////////
+// Load Highlighter
+/////////////////////////////////////////////////////////
+
+const cssPath = path.join(process.cwd(), "front", "editor", "highlighter.css");
+
+const link = document.createElement("link");
+link.rel = "stylesheet";
+link.href = `file://${cssPath}`;
+document.head.appendChild(link);
+
+//////////////////////////////////////////////////////////
+// Handle Window Deletion
+/////////////////////////////////////////////////////////
+
+ipcRenderer.on("deleteWindow", (event, fileLink) => {
+ const linkedEditors = OpenedFiles.SEARCH("linkedDisplay", fileLink);
+
+ linkedEditors.forEach((e) => {
+ OpenedFiles.SET(e, "linkedDisplay", null);
+ });
+});
+
/////////////////////////////////////////////////////////
// Others
/////////////////////////////////////////////////////////
diff --git a/main.js b/main.js
index 1b72816..c59f556 100644
--- a/main.js
+++ b/main.js
@@ -1,36 +1,53 @@
-// Import libraries
-const {
- app,
- BrowserWindow,
- ipcMain,
- dialog,
- webContents
-} = require("electron");
-const fs = require("fs");
-const needle = require("needle-db");
+/*
+///////////////////////////////////////////////////////////////
+ main.js / Index - Search with Ctrl + F (VSCode)
+///////////////////////////////////////////////////////////////
+
+ - Module Import
+ - Setup Needle DB
+ - Setup Main Editor
+ - Handle New Window Creation
+ - Handle file picking
+ - Handle directory picking
+ - Handle window closures
+ - Handle Display Restart
+ - Others
+
+*/
+
+///////////////////////////////////////////////////////////////
+// Module Import
+///////////////////////////////////////////////////////////////
-// Setup OpenedDisplaysDB
+const { app, BrowserWindow, ipcMain, dialog } = require("electron");
+const launchWindow = require("./modules/launchWindow");
+
+///////////////////////////////////////////////////////////////
+// Setup Needle DB
+///////////////////////////////////////////////////////////////
+
+const needle = require("needle-db");
const openedDisplays = new needle();
openedDisplays.NEWCOLUMN("fileLink");
openedDisplays.NEWCOLUMN("window");
-// Import Dependencies
-const launchWindow = require("./modules/launchWindow");
-
-// Setup Window
+///////////////////////////////////////////////////////////////
+// Setup Main Editor
+///////////////////////////////////////////////////////////////
+let mainWindow = null;
const createWindow = () => {
- const window = launchWindow("./front/editor/editor.html", {
+ mainWindow = launchWindow("./front/editor/editor.html", {
width: 600,
height: 600,
minWidth: 600,
minHeight: 400,
webPreferences: { nodeIntegration: true, contextIsolation: false }
+ //autoHideMenuBar: true // Commented out for debugging
});
- window.on("closed", () => {
- // TODO: Save editor state
+ mainWindow.on("closed", () => {
app.quit();
});
};
@@ -45,6 +62,36 @@ app.on("window-all-closed", () => {
if (process.platform !== "darwin") app.quit();
});
+///////////////////////////////////////////////////////////////
+// Handle New Window Creation
+// - Handle set window creation
+///////////////////////////////////////////////////////////////
+
+function createNewDisplay(fileLink) {
+ const newWdwFMT = openedDisplays.FORMAT();
+
+ newWdwFMT.SET("fileLink", fileLink);
+ newWdwFMT.SET(
+ "window",
+ launchWindow(fileLink, {
+ width: 500,
+ height: 500,
+ webPreferences: { nodeIntegration: true }
+ })
+ );
+
+ openedDisplays.PUSH(newWdwFMT);
+
+ openedDisplays
+ .READ(openedDisplays.FINDQUICKINDEX("fileLink", fileLink), "window")
+ .webContents.on("destroyed", () => {
+ openedDisplays.DELETE(
+ openedDisplays.FINDQUICKINDEX("fileLink", fileLink)
+ );
+ mainWindow.webContents.send("deleteWindow", fileLink);
+ });
+}
+
ipcMain.on("new-window", async () => {
const result = await dialog.showOpenDialog({
properties: ["openFile"],
@@ -59,29 +106,14 @@ ipcMain.on("new-window", async () => {
});
}
if (!result.canceled && result.filePaths && result.filePaths[0] && flag) {
- const newWdwFMT = openedDisplays.FORMAT();
-
- newWdwFMT.SET("fileLink", result.filePaths[0]);
- newWdwFMT.SET(
- "window",
- launchWindow(result.filePaths[0], { width: 500, height: 500 })
- );
-
- openedDisplays.PUSH(newWdwFMT);
-
- openedDisplays
- .READ(
- openedDisplays.FINDQUICKINDEX("fileLink", result.filePaths[0]),
- "window"
- )
- .webContents.on("destroyed", () => {
- openedDisplays.DELETE(
- openedDisplays.FINDQUICKINDEX("fileLink", result.filePaths[0])
- );
- });
+ createNewDisplay(result.filePaths[0]);
}
});
+///////////////////////////////////////////////////////////////
+// Handle New Window Creation: Handle set window creation
+///////////////////////////////////////////////////////////////
+
ipcMain.handle("new-window-set", async (event, args) => {
var flag = true;
if (openedDisplays.GETJSONDATA().length > 0) {
@@ -92,22 +124,14 @@ ipcMain.handle("new-window-set", async (event, args) => {
});
}
if (flag == false) return -1;
- const newWdwFMT = openedDisplays.FORMAT();
-
- newWdwFMT.SET("fileLink", args);
- newWdwFMT.SET("window", launchWindow(args, { width: 500, height: 500 }));
-
- openedDisplays.PUSH(newWdwFMT);
-
- openedDisplays
- .READ(openedDisplays.FINDQUICKINDEX("fileLink", args), "window")
- .webContents.on("destroyed", () => {
- openedDisplays.DELETE(openedDisplays.FINDQUICKINDEX("fileLink", args));
- });
-
- return openedDisplays.FINDQUICKINDEX("fileLink", args);
+ createNewDisplay(args);
+ return args;
});
+///////////////////////////////////////////////////////////////
+// Handle file picking
+///////////////////////////////////////////////////////////////
+
ipcMain.handle("filePickerDialog", async () => {
const result = await dialog.showOpenDialog({
properties: ["openFile"],
@@ -136,6 +160,10 @@ ipcMain.handle("filePickerDialog", async () => {
return result.filePaths[0];
});
+///////////////////////////////////////////////////////////////
+// Handle directory picking
+///////////////////////////////////////////////////////////////
+
ipcMain.handle("get-dir", async () => {
const result = await dialog.showOpenDialog({
properties: ["openDirectory"]
@@ -148,24 +176,10 @@ ipcMain.handle("get-dir", async () => {
}
});
-ipcMain.handle("createFile", (event, args) => {
- let filedata = "";
-
- if (args.preset !== "none") {
- filedata = fs.readFileSync(args.preset, { encoding: "utf-8" });
- }
-
- let ans = 0;
-
- fs.writeFile(`${args.dir}\\${args.name}`, filedata, function (err) {
- if (err) {
- ans = err;
- throw err;
- }
- });
-
- return ans;
-});
+///////////////////////////////////////////////////////////////
+// Handle window closures
+// - Force Close
+///////////////////////////////////////////////////////////////
ipcMain.on("closeWindow", (event) => {
const senderWindow = BrowserWindow.getAllWindows().find(
@@ -177,6 +191,10 @@ ipcMain.on("closeWindow", (event) => {
}
});
+///////////////////////////////////////////////////////////////
+// Handle window closure: Force Close
+///////////////////////////////////////////////////////////////
+
ipcMain.on("forceCloseWindow", (event) => {
const senderWindow = BrowserWindow.getAllWindows().find(
(win) => win.webContents === event.sender
@@ -187,6 +205,25 @@ ipcMain.on("forceCloseWindow", (event) => {
}
});
+///////////////////////////////////////////////////////////////
+// Handle Display Restart
+///////////////////////////////////////////////////////////////
+
+ipcMain.on("restartDisplay", (event, args) => {
+ openedDisplays
+ .READ(openedDisplays.FINDQUICKINDEX("fileLink", args), "window")
+ .loadFile(
+ openedDisplays.READ(
+ openedDisplays.FINDQUICKINDEX("fileLink", args),
+ "fileLink"
+ )
+ );
+});
+
+///////////////////////////////////////////////////////////////
+// Others
+///////////////////////////////////////////////////////////////
+
ipcMain.on("printOnBackConsole", (event, args) => {
console.log(args);
});
@@ -199,23 +236,8 @@ ipcMain.handle("pickOpenedDisplay", async () => {
return openedDisplaysReduced;
});
-ipcMain.on(
- "connectWindowSelection",
- (event, value, callerFile, CallerWindow) => {
- webContents
- .fromId(CallerWindow)
- .send("syncLinkedDisplay", callerFile, value);
- }
-);
-
ipcMain.on("printOpenedDisplays", () => {
// Function for debugging
console.log(openedDisplays.GETJSONDATA());
});
-
-ipcMain.on("restartDisplay", (event, args) => {
- openedDisplays
- .READ(args, "window")
- .loadFile(openedDisplays.READ(args, "fileLink"));
-});