}
create_directory(path) {
+ if (path == "") {
+ return { type:"dir", elems:this.folders }
+ }
+
let parts = path.split("/");
let name = parts.at(-1);
return root[root.length - 1];
}
+ get_containing_directory(path) {
+ let last_slash = path.lastIndexOf("/");
+ if (last_slash == -1) return "";
+
+ return path.substring(0, last_slash);
+ }
+
+ create_file(path, contents) {
+ let containing_dir = this.get_containing_directory(path);
+ let dir = this.create_directory(containing_dir);
+
+ let filename = path.substring(path.lastIndexOf("/") + 1);
+
+ let existing = dir.elems.find(x => x == filename)
+ if (existing) {
+ return existing;
+ }
+
+ dir.elems.push({
+ name: filename,
+ type: "file",
+ contents
+ })
+
+ return dir.elems[dir.elems.length - 1];
+ }
+
+ remove(path) {
+ let containing_dir = this.get_containing_directory(path);
+ let dir = this.create_directory(containing_dir);
+
+ let filename = path.substring(path.lastIndexOf("/") + 1);
+ dir.elems.splice(dir.elems.findIndex(x => x.name == filename), 1);
+ }
+
+ // Returns null if the item at the path does not exist
lookup(path) {
let parts = path.split("/");
+
+ let root = { type:"dir", elems:this.folders };
+ let i;
+ for (i=0; i<parts.length; i++) {
+ if (root.type == "dir") {
+ let elems = root.elems.filter(x => x.name == parts[i]);
+ if (elems.length != 1) {
+ root = null;
+ break;
+ }
- let root = this.folders;
- for (let part of parts) {
- if (!Array.isArray(root)) return null;
+ root = elems[0];
- let elems = root.filter((x) => x.name == part);
- if (elems.length != 1) return null;
+ } else if (root.type == "file") {
+ if (root.name != parts[i] || i != parts.length - 1) {
+ root = null;
+ }
- root = elems[0];
- if (root.type == "dir") {
- root = root.elems;
+ break;
}
}
return root;
}
+ move_file(old_path, new_path) {
+ let existing = this.lookup(old_path);
+ }
+
build_folder_view(onclick, selector=".folder-root") {
let $root = $(selector);
let output = "";
switch (t.type) {
case "dir": {
- output += `<div class="folder-item directory ${t.state}">
+ output += `<div class="folder-item directory ${t.state}" data-filename="${name}">
<i class="fa ${t.state == "open" ? "fa-folder-open" : "fa-folder"}"></i>
${t.name}
<i class="folder-item-button fa fa-trash"></i>
$root.html(root_html);
$root.find(".folder-item").click(onclick);
+ $root.find(".folder-item i.fa-pencil-alt").click(folder_start_rename);
+ $root.find(".folder-item i.fa-trash").click(folder_start_remove);
}
save() {
let $target = $(e.target);
if ($target.hasClass("file")) {
- let editor = ace.edit("code-editor");
let filename = $target.attr("data-filename");
- let file = folders.lookup(filename);
- editor.setValue(file.contents);
- editor.clearSelection();
+ folder_open_file(filename);
}
if ($target.hasClass("directory")) {
$target.next().removeClass("hidden");
}
}
-}
\ No newline at end of file
+}
+
+function folder_open_file(filename) {
+ let editor = ace.edit("code-editor");
+ let file = folders.lookup(filename);
+ editor.setValue(file.contents);
+ editor.clearSelection();
+}
+
+function folder_start_create_file() {
+ let $modal = $("#create-file-modal");
+ $modal.find("input").val("");
+ $modal.modal();
+}
+
+function folder_finalize_create_file() {
+ let $modal = $("#create-file-modal");
+ let path = $modal.find("input").val();
+
+ folders.create_file(path, "");
+ folders.save();
+ folders.build_folder_view(folder_item_click);
+
+ folder_open_file(path);
+
+ $.modal.close();
+}
+
+function folder_start_rename(e) {
+ let filename = $(e.target).parent().attr("data-filename");
+ let $modal = $("#rename-modal");
+ $modal.find("input").val(filename);
+ $modal.attr("data-filename", filename);
+ $modal.modal();
+}
+
+function folder_finalize_rename(e) {
+ let $modal = $("#rename-modal");
+ let current_filename = $modal.attr("data-filename");
+ let new_filename = $modal.find("input").val();
+ $.modal.close();
+
+ folders.move_file(current_filename, new_filename);
+ folders.save();
+ folders.build_folder_view(folder_item_click);
+
+ folder_open_file(new_filename);
+}
+
+function folder_start_remove(e) {
+ let filename = $(e.target).parent().attr("data-filename");
+ let $modal = $("#remove-modal");
+ $modal.find("p").html(`Are you sure you want to remove ${filename}?`);
+ $modal.attr("data-filename", filename);
+ $modal.modal();
+}
+
+function folder_finalize_remove() {
+ let $modal = $("#remove-modal");
+ let filename = $modal.attr("data-filename");
+
+ folders.remove(filename);
+ folders.save();
+ folders.build_folder_view(folder_item_click);
+
+ $.modal.close();
+}
+
let editor_keybind_mode = "normal";
let editor_theme = "chrome";
let ui_theme = "dark";
+let ui_mode = "simple";
let input_shared_buffer = new SharedArrayBuffer(1024 * Uint8Array.BYTES_PER_ELEMENT);
let canvas_shared_buffer = new SharedArrayBuffer(7 * Int32Array.BYTES_PER_ELEMENT);
} else {
disable_ide_mode();
}
+
+ ui_mode = value;
+ persist_settings();
}
function persist_settings() {
localStorage["editor_theme"] = editor_theme;
localStorage["editor_keybind_mode"] = editor_keybind_mode;
localStorage["ui_theme"] = ui_theme;
+ localStorage["ui_mode"] = ui_mode;
}
function load_settings() {
editor_theme = localStorage["editor_theme"];
editor_keybind_mode = localStorage["editor_keybind_mode"];
ui_theme = localStorage["ui_theme"] || ui_theme;
+ ui_mode = localStorage["ui_mode"] || ui_mode;
load_split_sizes();
change_editor_theme(editor_theme);
change_keybindings(editor_keybind_mode);
change_ui_theme(ui_theme);
+ change_ui_mode(ui_mode);
}
async function handle_drop(e) {
populate_examples();
load_settings();
- change_ui_mode("ide");
make_resizer("main-horizontal-divider", "--folder-width", "", (e) => {
save_split_sizes();
<div class="tab-line"><span>Storage</span></div>
<div class="menu-bar" style="border-bottom: 2px solid var(--light-background-color); margin-bottom: 12px">
<div style="text-align: center">
- <button title="New File" onclick="prompt_create_file()"><i class="fas fa-plus"></i></button>
+ <button title="New File" onclick="folder_start_create_file()"><i class="fas fa-plus"></i></button>
<button title="Save" onclick="prompt_save()"><i class="fas fa-save"></i></button>
<button title="Upload" onclick="prompt_upload()"><i class="fas fa-upload"></i></button>
<button title="Download" onclick="prompt_download()"><i class="fas fa-download"></i></button>
<div class="file-list"> </div>
</div>
+
+ <div id="create-file-modal" class="modal">
+ <h2>Create File</h2>
+ <input type="text" name="create-name" placeholder="Path" value="" />
+ <br/>
+ <button onclick="folder_finalize_create_file()">Create</button>
+ </div>
+
+ <div id="rename-modal" class="modal">
+ <h2>Rename</h2>
+ <input type="text" id="rename-name" name="rename-name" placeholder="Name" value="" />
+ <br/>
+ <button onclick="folder_finalize_rename()">Rename</button>
+ </div>
+
+ <div id="remove-modal" class="modal">
+ <h2>Remove</h2>
+ <p></p>
+ <br/>
+ <button onclick="folder_finalize_remove()">Remove</button>
+ </div>
</body>
</html>