Changed to TypeScript

Moved third party files to separate folder
This commit is contained in:
Matthew Welch 2021-01-23 16:01:19 -08:00
parent ba4ca341f4
commit 80847801f4
53 changed files with 178 additions and 79 deletions

1
.gitignore vendored
View File

@ -89,3 +89,4 @@ typings/
out/
.idea/
build/

View File

@ -3,7 +3,7 @@
"productName": "webeditor",
"version": "1.1.0",
"description": "My Electron application description",
"main": "src/index.js",
"main": "build/index.js",
"scripts": {
"start": "electron-forge start",
"package": "electron-forge package",
@ -19,7 +19,17 @@
"license": "MIT",
"config": {
"forge": {
"packagerConfig": {},
"packagerConfig": {
"ignore": [
".*\\.ts",
".*\\.map",
".*\\.log",
"test_data",
".idea",
".gitignore",
"tsconfig.json"
]
},
"makers": [
{
"name": "@electron-forge/maker-squirrel",
@ -45,11 +55,14 @@
}
},
"dependencies": {
"@types/jquery": "^3.5.5",
"commonjs": "^0.0.1",
"electron-squirrel-startup": "^1.0.0",
"electron-store": "^6.0.1",
"jquery": "^3.5.1",
"jsdom": "^16.4.0",
"jsonschema": "^1.4.0"
"jsonschema": "^1.4.0",
"typescript": "^4.1.3"
},
"devDependencies": {
"@electron-forge/cli": "6.0.0-beta.52",

View File

@ -3,8 +3,8 @@
<head>
<meta charset="UTF-8">
<title>Web Editor</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="fontawesome/css/all.css">
<link rel="stylesheet" href="../third_party/css/bootstrap.min.css">
<link rel="stylesheet" href="../third_party/fontawesome/css/all.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
@ -86,11 +86,10 @@
module = undefined;
}
</script>
<script src="js/jquery-3.5.1.min.js"></script>
<script src="js/selectable.js"></script>
<script src="js/bootstrap.bundle.min.js"></script>
<script src="../third_party/js/bootstrap.bundle.min.js"></script>
<script>if (window.module) module = window.module;</script>
<script src="js/Sortable.js"></script>
<script src="js/editor.js"></script>
<script>
require("./../build/js/editor.js");
</script>
</body>
</html>

View File

@ -1,9 +1,23 @@
const { app, BrowserWindow, ipcMain, dialog, Menu } = require('electron');
const Store = require("electron-store");
const fs = require("fs");
const path = require("path");
const util = require('util')
let Validator = require("jsonschema").Validator;
import {
app,
BrowserWindow,
ipcMain,
dialog,
Menu,
MenuItemConstructorOptions,
SaveDialogSyncOptions,
OpenDialogSyncOptions
} from 'electron';
import * as Store from "electron-store";
import * as fs from "fs";
import * as path from "path";
import * as util from 'util';
import { Validator } from "jsonschema";
import * as jsdom from "jsdom";
const { JSDOM } = jsdom;
const { window } = new JSDOM();
let $ = require("../third_party/js/jquery-3.5.1.js")(window);
let validator = new Validator();
let all_schemas = [
@ -13,14 +27,10 @@ let all_schemas = [
let schema_updaters = {
"1.0.0_schema.json": update_1_0_0_schema
}
let jsdom = require("jsdom");
const { JSDOM } = jsdom;
const { window } = new JSDOM();
let $ = jQuery = require('jquery')(window);
const store = new Store();
let current_file = null;
let menu_template = [
let menu_template:MenuItemConstructorOptions[] = [
{
label: "File",
submenu: [
@ -163,9 +173,9 @@ function createNew() {
}
function chooseFile(title, for_save=false) {
let options = {
let options:SaveDialogSyncOptions = {
title: title,
defaultPath: store.get("default_dir", app.getPath("documents")),
defaultPath: <string>store.get("default_dir", app.getPath("documents")),
filters: [
{name: 'json', extensions: ['json']},
{name: 'All Files', extensions: ['*']}
@ -176,7 +186,7 @@ function chooseFile(title, for_save=false) {
if (for_save) {
file_path = dialog.showSaveDialogSync(options);
} else {
file_path = dialog.showOpenDialogSync(options);
file_path = dialog.showOpenDialogSync(<OpenDialogSyncOptions>options);
}
if (file_path) {
if (for_save) {
@ -223,7 +233,7 @@ function saveFile(json_data, create_new_file) {
}
function updateRecentFiles(new_file=null) {
let recent_files = store.get("recent_files");
let recent_files = <Array<string>>store.get("recent_files");
if (new_file != null) {
store.set("default_dir", new_file);
if (recent_files.includes(new_file)) {
@ -246,8 +256,8 @@ function updateRecentFiles(new_file=null) {
}
function updateMenuBar() {
let recent_files = store.get("recent_files");
for (let menu of menu_template[0].submenu) {
let recent_files = <Array<string>>store.get("recent_files");
for (let menu of <MenuItemConstructorOptions[]>menu_template[0].submenu) {
if (menu.label === "Open Recent") {
menu.submenu = []
for (let file of recent_files) {
@ -300,18 +310,18 @@ function getUpdatedJson(validation_result) {
function update_1_0_0_schema(json) {
$.each(json, (i, table_data) => {
table_data["id"] = "table"+i;
table_data["id"] = "table"+i.toString();
table_data["tab_name"] = table_data["tab-name"];
delete table_data["tab-name"];
let col_dict = {};
$.each(table_data["col-def"], (j, col_data) => {
col_dict[col_data["field"]] = "column"+j;
col_data["field"] = "column"+j;
col_dict[col_data["field"]] = "column"+j.toString();
col_data["field"] = "column"+j.toString();
});
table_data["columns"] = table_data["col-def"];
delete table_data["col-def"];
$.each(table_data["rows"], (j, row_data) => {
row_data["uid"] = "row"+j;
row_data["uid"] = "row"+j.toString();
$.each(col_dict, (old_key, new_key) => {
row_data[new_key] = row_data[old_key];
delete row_data[old_key];
@ -342,7 +352,7 @@ function duplicateJson(json) {
}
function removeRecentFile(file) {
let recent_files = store.get("recent_files");
let recent_files = <Array<string>>store.get("recent_files");
recent_files.splice(recent_files.indexOf(file), 1);
store.set("recent_files", recent_files);
}

View File

@ -1,4 +1,7 @@
const { ipcRenderer, clipboard } = require('electron');
import { ipcRenderer, clipboard } from 'electron';
import * as $ from "../../third_party/js/jquery-3.5.1.js";
import * as Sortable from "../../third_party/js/Sortable.js"
import * as Selectable from "../../third_party/js/selectable.js"
let json_data;
let tables_data;
let current_table;
@ -6,6 +9,7 @@ let selected_cells = [];
let selection_data;
let is_positioning = false;
let nav = $("nav");
let tables = $("#tables");
let nav_scroll = nav.scrollLeft();
let detail_tab_name = $("#detail-tab-name");
let detail_table_name = $("#detail-table-name");
@ -29,7 +33,7 @@ function saveFile(create_new_file) {
}
function clearPage() {
$("#tables").empty();
tables.empty();
nav.empty();
$("#details input, #details textarea").val("");
selection_data = null;
@ -43,7 +47,7 @@ function refreshPage() {
toggleMovement()
}
function generateTable(table_data, table_index) {
function generateTable(table_data) {
const table_id = table_data["id"];
let a = $("<div>")
.attr("id", table_id + "-nav")
@ -96,7 +100,7 @@ function generateTable(table_data, table_index) {
})
table_div.append(table);
let table_container = $("#tables");
let table_container = tables;
let add_row_div = table_container.find("div[id='add-row-div']");
if (add_row_div.length !== 0) {
add_row_div.before(table_div);
@ -133,7 +137,7 @@ function makeHeader(header_id, header_index, col_title) {
}
function generateTables() {
$("#tables").append($("<div>")
tables.append($("<div>")
.attr("id", "add-col-div")
.css({"position": "absolute", "top": "46px", "right": "0"})
.append($("<button>")
@ -144,9 +148,9 @@ function generateTables() {
insertColumn(current_table, -1)
})))
$.each(tables_data, (i, table_data) => {
generateTable(table_data, i);
generateTable(table_data);
})
$("#tables").append($("<div>")
tables.append($("<div>")
.attr("id", "add-row-div")
.append($("<button>")
.attr("id", "btn-add-row")
@ -173,25 +177,25 @@ function updateDetailsPanel() {
detail_table_description.val(data["table_description"]);
detail_table_hidden.prop("checked", data["table_hidden"]);
if (data["col_id"]) {
detail_column_name.attr("disabled", false);
detail_column_selectable.attr("disabled", false);
detail_column_sortable.attr("disabled", false);
detail_column_name.removeAttr("disabled");
detail_column_selectable.removeAttr("disabled");
detail_column_sortable.removeAttr("disabled");
detail_column_name.val(data["col_name"]);
detail_column_selectable.prop("checked", data["col_selectable"]);
detail_column_sortable.prop("checked", data["col_sortable"]);
} else {
detail_column_name.attr("disabled", true);
detail_column_selectable.attr("disabled", true);
detail_column_sortable.attr("disabled", true);
detail_column_name.attr("disabled", "true");
detail_column_selectable.attr("disabled", "true");
detail_column_sortable.attr("disabled", "true");
detail_column_name.val("");
detail_column_selectable.prop("checked", "");
detail_column_sortable.prop("checked", "");
}
if (data["row_id"]) {
detail_cell_text.attr("disabled", false);
detail_cell_text.removeAttr("disabled");
detail_cell_text.val(data["cell_text"]);
} else {
detail_cell_text.attr("disabled", true);
detail_cell_text.attr("disabled", "true");
detail_cell_text.val("");
}
}
@ -201,7 +205,7 @@ function showTab(table_name) {
disableSelection();
current_table = table_name;
let tab_name = table_name+"-tab";
$("#tables").children().removeClass("show active");
tables.children().removeClass("show active");
nav.children().removeClass("active");
$("#"+tab_name).addClass("show active");
$("#"+table_name+"-nav").addClass("active");
@ -754,7 +758,7 @@ function enableMovement() {
}
});
})
Sortable.create($("nav")[0], {
Sortable.create(nav[0], {
animation: 50,
easing: "cubic-bezier(1, 0, 0, 1)",
draggable: ".table-nav",
@ -780,7 +784,7 @@ function disableMovement() {
sortable_thead.destroy();
}
})
let sortable_nav = Sortable.get($("nav")[0]);
let sortable_nav = Sortable.get(nav[0]);
if (sortable_nav) {
sortable_nav.destroy();
}
@ -874,7 +878,7 @@ function getDeselectingItems(invert) {
}
function getDeselectingNodes() {
return getDeselectingItems().map(function(item) {
return getDeselectingItems(false).map(function(item) {
return item.node;
});
}
@ -948,8 +952,9 @@ function copyToClipboard(cut=false) {
function pasteFromClipboard() {
let text = clipboard.readText();
let rows = text.split("\r\n");
let row_cols = [];
for (let i=0; i < rows.length; i++) {
rows[i] = rows[i].split("\t");
row_cols[i] = rows[i].split("\t");
}
let selectable = getSelectable();
let selected_items = selectable.getSelectedItems();
@ -960,8 +965,8 @@ function pasteFromClipboard() {
let data = getSelectionData();
let row_index = data["row_index"];
let col_index = data["col_index"];
let num_rows_needed = row_index+1+rows.length-(data["num_rows"]+1);
let num_cols_needed = col_index+rows[0].length-data["num_cols"];
let num_rows_needed = row_index+1+row_cols.length-(data["num_rows"]+1);
let num_cols_needed = col_index+row_cols[0].length-data["num_cols"];
for (let i=0; i < num_rows_needed; i++) {
insertRow(current_table);
}
@ -970,18 +975,18 @@ function pasteFromClipboard() {
}
let x = 0;
let y = 0;
for (let i=row_index; i < row_index+rows.length; i++) {
for (let j=col_index; j < col_index+rows[0].length; j++) {
for (let i=row_index; i < row_index+row_cols.length; i++) {
for (let j=col_index; j < col_index+row_cols[0].length; j++) {
let cell_elm;
if (i === -1) {
cell_elm = $(`#${current_table} > thead > tr > th:nth-child(${j+1})`);
tables_data[data["table_index"]]["columns"][j]["title"] = rows[y][x];
tables_data[data["table_index"]]["columns"][j]["title"] = row_cols[y][x];
} else {
cell_elm = $(`#${current_table} > tbody > tr:nth-child(${i+1}) > td:nth-child(${j+1})`);
let row_key = tables_data[data["table_index"]]["columns"][j]["field"];
tables_data[data["table_index"]]["rows"][i][row_key] = rows[y][x];
tables_data[data["table_index"]]["rows"][i][row_key] = row_cols[y][x];
}
cell_elm.text(rows[y][x]);
cell_elm.text(row_cols[y][x]);
x++;
}
y++;
@ -989,6 +994,21 @@ function pasteFromClipboard() {
}
}
function selectAll(event) {
if (event.ctrlKey && event.key === "a") {
event.preventDefault();
let input_focus = $("input:focus, textarea:focus");
if (input_focus.length === 0) {
getSelectable().selectAll();
} else {
$(":focus").select();
}
}
}
function backspaceDelete(event: JQuery.KeyDownEvent) {
}
function getColumnIDs(columns) {
let ids = [];
for (let col of columns) {
@ -1129,16 +1149,11 @@ $(document).on("paste", (event) => {
}
})
$(document).on("keydown", (event) => {
if (event.ctrlKey && event.key.toLowerCase() === "a") {
let input_focus = $("input:focus, textarea:focus");
if (input_focus.length === 0) {
event.preventDefault();
getSelectable().selectAll();
} else {
event.preventDefault();
$(":focus").select();
}
$(document).on("keydown", (event: JQuery.KeyDownEvent) => {
selectAll(event);
let input_focus = $("input:focus, textarea:focus");
if (input_focus.length === 0) {
backspaceDelete(event);
}
})

View File

@ -1,11 +1,12 @@
const { ipcRenderer } = require('electron');
const fs = require("fs");
import { ipcRenderer } from 'electron';
import * as $ from "../../third_party/js/jquery-3.5.1.js";
let recent_files_div = $("#recent-files")
async function showRecentFiles() {
let recent_files = await ipcRenderer.invoke("get-store-value", "recent_files");
$("#recent-files").empty();
recent_files_div.empty();
if (recent_files.length === 0) {
$("#recent-files").css("display", "none");
recent_files_div.css("display", "none");
$("#splash").css("width", "100%")
} else {
for (let file of recent_files) {
@ -22,7 +23,7 @@ async function showRecentFiles() {
recent_file_link.remove();
removeRecentFile(file);
}));
$("#recent-files").append(recent_file_link);
recent_files_div.append(recent_file_link);
}
}
}

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<title>Web Editor</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="../third_party/css/bootstrap.min.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body style="overflow: hidden">
@ -20,9 +20,10 @@
module = undefined;
}
</script>
<script src="js/jquery-3.5.1.min.js"></script>
<script src="js/bootstrap.bundle.min.js"></script>
<script src="../third_party/js/bootstrap.bundle.min.js"></script>
<script>if (window.module) module = window.module;</script>
<script src="js/splash.js"></script>
<script>
require("./../build/js/splash.js");
</script>
</body>
</html>

View File

Before

Width:  |  Height:  |  Size: 730 KiB

After

Width:  |  Height:  |  Size: 730 KiB

View File

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 141 KiB

View File

Before

Width:  |  Height:  |  Size: 896 KiB

After

Width:  |  Height:  |  Size: 896 KiB

View File

@ -51,7 +51,7 @@
/**
* --------------------------------------------------------------------------
* Bootstrap (v5.0.0-beta1): util/index.js
* Bootstrap (v5.0.0-beta1): util/index.ts
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* --------------------------------------------------------------------------
*/

17
tsconfig.json Normal file
View File

@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"removeComments": true,
"noImplicitAny": false,
"suppressImplicitAnyIndexErrors": true,
"lib": [
"ES6",
"DOM"
],
"outDir": "./build",
},
"exclude": [ "node_modules", "out" ],
}

View File

@ -300,6 +300,13 @@
"@types/minimatch" "*"
"@types/node" "*"
"@types/jquery@^3.5.5":
version "3.5.5"
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.5.5.tgz#2c63f47c9c8d96693d272f5453602afd8338c903"
integrity sha512-6RXU9Xzpc6vxNrS6FPPapN1SxSHgQ336WC6Jj/N8q30OiaBZ00l1GBgeP7usjVZPivSkGUfL1z/WW6TX989M+w==
dependencies:
"@types/sizzle" "*"
"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
@ -315,6 +322,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.14.tgz#59e5029a3c2aea34f68b717955381692fd47cafb"
integrity sha512-2U9uLN46+7dv9PiS8VQJcHhuoOjiDPZOLAt0WuA1EanEknIMae+2QbMhayF7cgGqjvRVIfNpt+6jLPczJZFiRw==
"@types/sizzle@*":
version "2.3.2"
resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47"
integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==
"@types/yauzl@^2.9.1":
version "2.9.1"
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.9.1.tgz#d10f69f9f522eef3cf98e30afb684a1e1ec923af"
@ -367,6 +379,11 @@ ansi-escapes@^4.2.1:
dependencies:
type-fest "^0.11.0"
ansi-font@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/ansi-font/-/ansi-font-0.0.2.tgz#890301bd5841462fd39c0b7709afd1f525143331"
integrity sha1-iQMBvVhBRi/TnAt3Ca/R9SUUMzE=
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
@ -742,6 +759,14 @@ commander@^5.0.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
commonjs@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/commonjs/-/commonjs-0.0.1.tgz#65c531dcff6565ca7c95ddfc96622b89cc0294d5"
integrity sha1-ZcUx3P9lZcp8ld38lmIricwClNU=
dependencies:
system ">=0.0.1"
test ">=0.0.5"
compare-version@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080"
@ -3218,6 +3243,11 @@ symbol-tree@^3.2.4:
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
system@>=0.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/system/-/system-2.0.1.tgz#d26a85135ee7f36e054e7f0eec4467f3b1dd9742"
integrity sha512-BwSUSa8LMHZouGadZ34ck3TsrH5s3oMmTKPK+xHdbBnTCZOZMJ38fHGKLAHkBl0PXru1Z4BsymQU4qqvTxWzdQ==
tar@^4.4.12:
version "4.4.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
@ -3239,6 +3269,13 @@ temp@^0.9.0:
mkdirp "^0.5.1"
rimraf "~2.6.2"
test@>=0.0.5:
version "0.6.0"
resolved "https://registry.yarnpkg.com/test/-/test-0.6.0.tgz#5986ac445ec17754322512d104ba32c8a63e938e"
integrity sha1-WYasRF7Bd1QyJRLRBLoyyKY+k44=
dependencies:
ansi-font "0.0.2"
throttleit@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf"
@ -3395,6 +3432,11 @@ typedarray@^0.0.6:
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
typescript@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.3.tgz#519d582bd94cba0cf8934c7d8e8467e473f53bb7"
integrity sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"