Skip to content

Instantly share code, notes, and snippets.

@lewdev
Last active June 19, 2024 10:09
Show Gist options
  • Save lewdev/d06bb3b8a42c319f2fbfe56135ef8e01 to your computer and use it in GitHub Desktop.
Save lewdev/d06bb3b8a42c319f2fbfe56135ef8e01 to your computer and use it in GitHub Desktop.
πŸ’» Address Bar Code Editor Bookmarklet (743b)

πŸ’» Address Bar Code Editor Bookmarklet (845b)

In the latest iteration my code editor, I've made big practical improvements to my bookmarklet HTML code editor. I built ExText which was supposed to be my go-to HTML editor because it displays line numbers, but I realized that it wasn't as useful and I find myself comfortably using the bookmarklet much more frequently.

  • Displays line number, cursor position by column, selected text size, cursor offset, and total length
  • Displays count of highlighted text
  • Favicon that helps distinguish the editor in your tabs
  • Includes a minimal code template:
    <p id=o></p>
    <script>
    o.innerHTML = 0;
    </script>
  • Press Ctrl + Enter to run your code.
data:text/html,<title>code</title><link rel=icon href='data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 99 99"><text y="1em" font-size="72">&%23128187;</text></svg>'><textarea id=d spellcheck=false onkeypress=e=event;k=e.keyCode;(e.ctrlKey&&k==13)||k==10?f.srcdoc=d.value:0 style=resize:none;filter:invert(><p id=o></p>%0d<script>%0do.innerHTML = 0;%0d</script></textarea><iframe id=f></iframe><p id=p style=position:fixed;bottom:1;color:white;background:black></p><script>D=null,d.onkeyup=d.onclick=n=>{clearTimeout(D),D=setTimeout(n=>{A=d.selectionStart,B=d.selectionEnd,V=d.value,E=V.substr(0,B).split`\n`,p.innerHTML=`Ln:${E.length}, Col:${E.pop().length+1}, ${A==B?"Pos:"+B:"Sel:"+(B-A)}, Len:${V.length}`},99)}</script><style>*{box-sizing:border-box;margin:0}textarea,iframe{width:50%;height:100%;vertical-align:top}

It's a little hefty for a bookmarklet but it does everything you need. I was having trouble with coding on this because the console would give me errors with line numbers and I'd end up copy-pasting my code into Notepad++ to see where the error was.

The title and favicon use 174b, but it just makes it usable. I could also remove the text labels indicating the line, column, and postion, but it's not a lot of extra text and visually useful.

Find out the 'line' (row) number of the cursor in a textarea

How to do I find the line number of your cursor in a textarea? The short of it is this:

const cursorPos = textareaElem.selectionEnd;
textareaElem.value.substr(0, cursorPos).split`\n`.length;

I also posted on an answer to Stack Overflow to this question. The other answers pointed me in the right direction, but didn't give answers I was satisfied with.

Here's a minimal implementation of a text editor with such features that I put into my answer. I implemented an optimization so that the code doesn't have to run for every key press and mouse click.

<textarea id=d style="width:100vw;height:calc(100vh - 2em)"></textarea>
<p id=p></p>
<script>
D = null;
d.onkeydown = d.onclick = _ => {
  clearTimeout(D);
  D = setTimeout(_=>{
    A = d.selectionStart;
    B = d.selectionEnd;
    V = d.value;
    E = V.substr(0, B).split`\n`;
    p.innerHTML = `Ln:${E.length}, Col:${E.pop().length+1}, ${A==B?'Pos:'+B:'Sel:'+(B-A)}, Len:${V.length}`
  }, 99)
}
</script><style>*{box-sizing:border-box;margin:0}

And of course, the bookmarklet version (399b):

data:text/html,<body onload="D=null,d.onkeydown=d.onclick=n=>{clearTimeout(D),D=setTimeout(n=>{A=d.selectionStart,B=d.selectionEnd,V=d.value,E=V.substr(0,B).split`\n`,p.innerHTML=`Ln:${E.length}, Col:${E.pop().length+1}, ${A==B?'Pos:'+B:'Sel:'+(B-A)}, Len:${V.length}`},99)}"><textarea id=d style="width:100vw;height:calc(100vh - 2em)"></textarea><p id=p></p><style>*{box-sizing:border-box;margin:0}

πŸ“ Text Editor Additional Features

This is like re-inventing the wheel, but as a "tinycode" coder, I like creating things at it's bare minimum so that we're left with a very efficient tool that does only what you want it to.

So here I enabled going to a given line by entering Ctrl + g and entering a number to go to the given line so that you can find the source of your errors quickly.

My next feature would be "Find and Replace" because it's what I felt was lacking. Otherwise, I don't have much more I need to code fairly productively.

<textarea id=d style="width:100vw;height:calc(100vh - 2em)"></textarea>
<p id=p></p>
<script>
D = null;
S="selection";
d.onkeydown = d.onclick = e => {
  clearTimeout(D);
  D = setTimeout(_=>{
    A = d[S+"Start"];
    B = d[S+"End"];
    V = d.value;
    E = V.substr(0, B).split`\n`;
    p.innerHTML = `Ln:${E.length}, Col:${E.pop().length+1}, ${A==B?'Pos:'+B:'Sel:'+(B-A)}, Len:${V.length}`
  }, 99)

  // goto line by pressing `Ctrl + g`
  if (e.ctrlKey) {
    if (e.key === 'g') {
    const line = parseInt(prompt("Go to line"));
    E = V.split`\n`;
    if (!isNaN(line) && line > 0 && line < E.length) {
      const end = E.slice(0, line).join`\n`.length;
      d[S+"Start"] = end - E[line - 1].length;
      d[S+"End"] = end;
    }
    else p.innerHTML = `<h1>Invalid line input`;
    e
  }

  // find & replace  
  if (e.ctrlKey && e.key === '!') {
    console.log("find & replace");
  }
};

</script><style>*{box-sizing:border-box;margin:0}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment