diff options
author | elioat <{ID}+{username}@users.noreply.github.com> | 2024-10-09 17:08:42 -0400 |
---|---|---|
committer | elioat <{ID}+{username}@users.noreply.github.com> | 2024-10-09 17:08:42 -0400 |
commit | fef378a7b14e39d0697bee448f5e74798a86103e (patch) | |
tree | 8f38f11182d1053301336f161d145daa14189dd1 /html | |
parent | df555325b246c6a8369ed57f80fae5ed065ac74f (diff) | |
download | tour-fef378a7b14e39d0697bee448f5e74798a86103e.tar.gz |
*
Diffstat (limited to 'html')
-rw-r--r-- | html/file-system/index.html | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/html/file-system/index.html b/html/file-system/index.html new file mode 100644 index 0000000..cd2e70d --- /dev/null +++ b/html/file-system/index.html @@ -0,0 +1,291 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Files and Folders</title> + <style> + body { + font-family: Arial, sans-serif; + background-color: beige; + display: flex; + flex-direction: column; + align-items: center; + } + #navigation { + display: flex; + flex-wrap: wrap; + justify-content: center; + margin: 0.625em 0; + } + #navigation button { + margin: 0.3125em; + padding: 0.625em 0.9375em; + font-size: 1em; + flex-grow: 1; + min-width: 7.5em; + } + #currentPath { + font-weight: bold; + margin: 0.625em 0; + } + ul { + list-style-type: none; + width: 100%; + max-width: 37.5em; + } + li { + margin: 0.3125em 0; + cursor: pointer; + } + .file, .folder { + display: inline-block; + padding: 0.3125em 0; + cursor: pointer; + font-size: 1.125em; + } + .file { + color: teal; + } + .folder { + color: black; + } + #editor { + margin-top: 1.25em; + width: 100%; + max-width: 37.5em; + } + #editor textarea { + width: 100%; + height: 9.375em; + font-size: 1em; + padding: 0.625em; + box-sizing: border-box; + resize: none; + } + h1 { + text-align: center; + font-size: 1.5em; + margin-top: 0.625em; + } + @media (max-width: 37.5em) { + h1 { + font-size: 1.25em; + } + #navigation button { + font-size: 0.875em; + padding: 0.5em 0.625em; + } + .file, .folder { + font-size: 1em; + } + #editor textarea { + height: 7.5em; + font-size: 0.875em; + } + } + </style> +</head> +<body> + +<div id="navigation"> + <button onclick="goToRoot()">Go to Root</button> + <button onclick="goUp()">Go Up One Level</button> + <button onclick="createFolderPrompt()">Create Folder</button> + <button onclick="createFilePrompt()">Create File</button> + <button onclick="cutItem()">Cut</button> + <button onclick="pasteItem()">Paste</button> + <button onclick="deleteItem()">Delete</button> +</div> + +<p id="currentPath">Current Folder: /</p> + +<ul id="fileSystemTree"></ul> + +<div id="editor"> + <h3>File Editor</h3> + <textarea id="fileContent" placeholder="Select a file to edit"></textarea> + <button onclick="saveFileContent()">Save</button> +</div> + +<script> + let fileSystem = JSON.parse(localStorage.getItem('fileSystem')) || { root: { type: 'folder', children: {} } }; + let currentFolderPath = 'root'; + let currentFilePath = null; + let cutItemPath = null; // For storing the path of the item being cut + + function saveFileSystem() { + localStorage.setItem('fileSystem', JSON.stringify(fileSystem)); + } + + function getFolder(path) { + let parts = path.split('/'); + let current = fileSystem.root; + for (let part of parts) { + if (part && current.children[part]) { + current = current.children[part]; + } + } + return current; + } + + function createFile(path, name, content = '') { + let folder = getFolder(path); + folder.children[name] = { type: 'file', content }; + saveFileSystem(); + renderFileSystem(); + } + + function createFolder(path, name) { + let folder = getFolder(path); + folder.children[name] = { type: 'folder', children: {} }; + saveFileSystem(); + renderFileSystem(); + } + + function moveItem(oldPath, newPath, itemName) { + let oldFolder = getFolder(oldPath); + let newFolder = getFolder(newPath); + newFolder.children[itemName] = oldFolder.children[itemName]; + delete oldFolder.children[itemName]; + saveFileSystem(); + renderFileSystem(); + } + + function deleteItem() { + if (!currentFilePath && currentFolderPath === 'root') { + alert("Can't delete the root folder!"); + return; + } + + let [parentPath, itemName] = (currentFilePath || currentFolderPath).split(/\/([^\/]+)$/); + let parentFolder = getFolder(parentPath); + + // Check if the item to delete is a folder with children + if (parentFolder.children[itemName].type === 'folder') { + let childCount = Object.keys(parentFolder.children[itemName].children).length; + if (childCount > 0) { + let confirmDelete = confirm(`Are you sure you want to delete the folder "${itemName}" and all its contents?`); + if (!confirmDelete) return; + } + } + + // Delete the file/folder + delete parentFolder.children[itemName]; + saveFileSystem(); + + // After deletion, reset selection to the parent folder + currentFilePath = null; + currentFolderPath = parentPath || 'root'; + document.getElementById('currentPath').textContent = currentFolderPath.replace('root', '') || '/'; + renderFileSystem(); + } + + function editFileContent(path, fileName, newContent) { + let folder = getFolder(path); + folder.children[fileName].content = newContent; + saveFileSystem(); + } + + function saveFileContent() { + if (currentFilePath) { + let [path, fileName] = currentFilePath.split(/\/([^\/]+)$/); + let content = document.getElementById('fileContent').value; + editFileContent(path, fileName, content); + } + } + + // Recursive function to render the file system + function renderFileSystem(folder = fileSystem.root, parentElement = document.getElementById('fileSystemTree'), path = 'root') { + parentElement.innerHTML = ''; // Clear existing tree + for (const [name, item] of Object.entries(folder.children)) { + let listItem = document.createElement('li'); + + // Create a separate clickable span for the folder or file name + let clickableName = document.createElement('span'); + clickableName.textContent = name; + clickableName.classList.add(item.type === 'file' ? 'file' : 'folder'); + listItem.appendChild(clickableName); + + // Folder click sets the current folder path + clickableName.onclick = () => { + if (item.type === 'folder') { + currentFolderPath = `${path}/${name}`; + currentFilePath = null; + document.getElementById('currentPath').textContent = currentFolderPath.replace('root', ''); + renderFileSystem(); // Re-render after changing the folder + } else if (item.type === 'file') { + currentFilePath = `${path}/${name}`; + document.getElementById('fileContent').value = item.content; + } + }; + + // If it's a folder, render its children recursively + if (item.type === 'folder') { + let nestedList = document.createElement('ul'); + renderFileSystem(item, nestedList, `${path}/${name}`); + listItem.appendChild(nestedList); + } + + parentElement.appendChild(listItem); + } + } + + // Navigation: Go to root + function goToRoot() { + currentFolderPath = 'root'; + currentFilePath = null; + document.getElementById('currentPath').textContent = '/'; + renderFileSystem(); + } + + // Navigation: Go up one level + function goUp() { + if (currentFolderPath !== 'root') { + let parts = currentFolderPath.split('/'); + parts.pop(); // Remove the current folder + currentFolderPath = parts.join('/') || 'root'; + currentFilePath = null; + document.getElementById('currentPath').textContent = currentFolderPath.replace('root', '') || '/'; + renderFileSystem(); + } + } + + // Cut a file or folder (select it for moving) + function cutItem() { + cutItemPath = currentFilePath || currentFolderPath; // Store the path of the selected file/folder + alert(`Cut: ${cutItemPath}`); + } + + // Paste a cut item into the current folder + function pasteItem() { + if (!cutItemPath) { + alert('No item selected to move.'); + return; + } + + let [oldPath, itemName] = cutItemPath.split(/\/([^\/]+)$/); + moveItem(oldPath, currentFolderPath, itemName); + cutItemPath = null; // Reset the cut item + alert(`Moved to: ${currentFolderPath}`); + } + + function createFilePrompt() { + let name = prompt('Enter file name:'); + if (name) { + createFile(currentFolderPath, name); + } + } + + function createFolderPrompt() { + let name = prompt('Enter folder name:'); + if (name) { + createFolder(currentFolderPath, name); + } + } + + renderFileSystem(); +</script> + +</body> +</html> \ No newline at end of file |