Weekend Project: Online Javascript Code Editor
With the holidays in progress and some free time, I decide to start a new project, something I've wanted to do for a while. Let's build an online code editor with no plugins!
TLDR; dive right in editor.codeeverywhere.ca.
The Concept
There are many editors available, codemirror.net being the most popular, but I wanted to build my own. To learn how they work, and to have a lighter product, one I can extend with features I need in the future.
How to do syntax highlighting?
With some reading, 2 main methods are came up, content editable and overlapping textarea.After testing, content editable seems more problematic in tracking the user's cursor position, so we'll go with overlapping DOM elements.
Here is an example with an offset so you can see the method in action, blue is the text area;
Requirements
- Works standalone
- Syntax highlighting
- Auto compile and output
- Working TAB spacing!
- Auto-brackets
- Infinite loop prevention
- Code sharing ability
Implementation
We decided on overlapping DIVs, one textarea and one pre to the keep line spacing. We use an input event for running the syntax highlighting and keydown to intercept the TAB and other special characters.
A custom CSS attribute on spans avoids regex issues with class="className".
Compilation is done with a debounce on the textarea to avoid constant re-running the script with eval(CODE).
The infinite loop detection works by injecting code into all for/while loops, using a counter up, and breaking on limit to a global variable.
let codeWithLoopCorrect = code.replace(
/(for|while)\s*\((.+)\)\s*{/gi,
";infiniteLoopBreaker_count=0; $1($2){ if(++infiniteLoopBreaker_count>1000) {console.log('<p data-infi>infiniteLoopBreaker (1K Limit)</p>'); break;};"
)
let infiniteLoopBreaker_count = 0
For auto-save, we're using a sessionStorage variable, nothing is sent to the server. The disadvantage is this won't work across machines and your code will be lost when the browser clears the sessionStorage.
Code sharing is done by encoding the textarea value into the URL hash, reading it in on the initial page load.
First working prototype;
That's looking not bad!
bugs and issues
- Multi browser support is un-tested
- Syntax highlighting in nesting still has some issues
- Line numbers don’t account for text wrapping
- Offset will break with a large number of different tokens on one line
future improvements
With all that done, we now have a working product or MVP (minimum viable product);
You can access the project at editor.codeeverywhere.ca or find the code on GitHub: github.com/codeeverywhereca/codeeditor.
Licensed under the MIT License, feel free to link and share.
Some future ideas to add:
- Auto code complete
- Error detection
- Custom themes
- Peer coding, with dual cursors (websockets?)
Have fun with it!