Web version code editor implementation

Then I wrote a blog https://blog.csdn.net/woyebuzhidao321/article/details/131495855 a few days ago , which mentioned the api involved in the creation of the vscode web version workspace. In the past two days, I made a web version of the code on a whim Editor, if before October 2020, it may be a fantasy to implement a web version of the code editor. Due to the difficulty of operating local files on the web side, it is difficult to get it out. Until the emergence of , it broke the original bottleneck File System Access API.

October 2020 Chrome 86 Important Update

Chrome 86 launched a stable version in October 2020, and it is now fully applied to platforms such as Android, Chrome OS, Linux, macOS, and Windows. Let's take a look at this important update.

To see all updates, please visit ( https://www.chromestatus.com/features#milestone=86 ).

Added stable features
File system access

Remember the local filesystem in Chrome 83, an experimental feature back then, now stable. By calling showOpenFilePicker the method, you can invoke the file selection window, and then read and write the file through the returned file handle. code show as below:

const pickerOpts = {
    
    
  types: [
    {
    
    
      description: "Images",
      accept: {
    
    
        "image/*": [".png", ".gif", ".jpeg", ".jpg"],
      },
    },
  ],
  excludeAcceptAllOption: true,
  multiple: false,
};
// create a reference for our file handle
let fileHandle;

async function getFile() {
    
    
  // open file picker, destructure the one element returned array
  [fileHandle] = await window.showOpenFilePicker(pickerOpts);

  // run code with our fileHandle
}

Official document address:
https://developer.mozilla.org/en-US/docs/Web/API/window/showOpenFilePicker

vscode网页版Also appeared after this. https://insiders.vscode.dev/

So I followed the big frame to implement a demo
Demo rendering
insert image description here
based on file addition, deletion, modification, and query. Reading and writing speed is very nice

open folder

First open a code directory

$('#openFolderBtn')[0].addEventListener('click', async () => {
    
    
	try {
    
    
	// // 得到异步迭代器
		dirHandle = await window.showDirectoryPicker();

		const createTree = async () => {
    
    
			const root = await createTreeModel(dirHandle);
			fileArr = root;
			treeInit();
		}
		createTree();
		
	} catch (err) {
    
    
		console.log(err)
	}
})

insert image description here
This will pop up a file pop-up window
window.showDirectoryPickerand return a file handle asynchronously. After selecting the file, a prompt will appear
insert image description here
to create a tree data structure.
insert image description here

read file

// 读取文件
async function reader() {
    
    
	if (fileHandle) {
    
    
		let file = await fileHandle.getFile();
		fileName.innerText = file.name;

		let reader = new FileReader();
		reader.onload = function (event) {
    
    
			let contents = escapeHtml(event.target.result);
			$("#textbox")[0].innerHTML = `<pre><code id="code">${
      
      contents}</code></pre>`;
			// hljs.highlightAll();
			hljs.highlightBlock($("#code")[0])
		};
		reader.readAsText(file);
	}
}

fileHandleIt is the corresponding file handle, getFileget the file by calling the method, and then use FileReaderthe constructor to read the file content and display it

open a file

How to open a local file separately

$('#openfile')[0].addEventListener('click', async () => {
    
    
	try {
    
    
		const openFileHandle = await window.showOpenFilePicker({
    
    
			types: [{
    
    
				accept: {
    
    
					"text/plain": [".txt"]
				}
			}],
			multiple: false
		});

		fileHandle = openFileHandle[0];
		reader();
	} catch (err) {
    
    
		console.log(err);
	}
})

Pick a file and open
insert image description here

how to create a folder

$("#createFolder")[0].addEventListener('click', async (e) => {
    
    
	const folderName = prompt('请输入文件夹名称');
	if (folderName) {
    
    
		await dirHandle.getDirectoryHandle(folderName, {
    
     create: true });
		console.log('文件夹创建成功');
		fileArrFlat = [];
		fileArr = await createTreeModel(dirHandle);
		treeInit();
	}
})

dirHandle is window.showDirectoryPickerthe returned file handle, getDirectoryHandlecreated by calling the method.

create a file

// 创建文件
$("#createFile")[0].addEventListener('click', async (e) => {
    
    
	const fileName = prompt('请输入文件名称');
	if (fileName) {
    
    
		try {
    
    
			if (!(await dirHandle.queryPermission()) === 'granted') {
    
    
				alert('文件不允许读写!');
				return;
			}
			const targetFile = await dirHandle.getFileHandle(fileName, {
    
     create: true });

			fileArrFlat = [];
			fileArr = await createTreeModel(dirHandle);
			treeInit();
		} catch (err) {
    
    
			console.log(err)
		}
	}
})

Save as file and write content

// 另存为文件
	$("#textbox")[0].addEventListener('keydown', async (e) => {
    
    
		if (e.ctrlKey && e.which == 83) {
    
    
			e.preventDefault;
			console.log('文件另存为', $("#textbox")[0].innerText)
			try {
    
    
				fileHandle = await window.showSaveFilePicker({
    
    
					types: [{
    
    
						accept: {
    
    
							"text/plain": [".txt"]
						}
					}],
					multiple: false
				});
				const w$ = await fileHandle.createWritable();
				await w$.write($("#textbox")[0].innerText);
				await w$.close();
			} catch (err) {
    
    
				console.log(err);
			}

			return false;
		}
	}, false)

The fileHandle file handle provides the createWritable method to write content to the file.

The code highlighting part is used highLight.js, such an initial version of the web version of the code editor can be done

its compatibility
insert image description here

Guess you like

Origin blog.csdn.net/woyebuzhidao321/article/details/131627691