<!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>