Skip to content
This repository has been archived by the owner on Aug 4, 2023. It is now read-only.

Commit

Permalink
Manual Reintegration of Changes
Browse files Browse the repository at this point in the history
  • Loading branch information
StevenEWright committed Aug 1, 2023
1 parent 4af804e commit e7cfb65
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 67 deletions.
25 changes: 23 additions & 2 deletions codejar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,22 @@ export function CodeJar(editor: HTMLElement, highlight: (e: HTMLElement, pos?: P
function handleSelfClosingCharacters(event: KeyboardEvent) {
const open = `([{'"`
const close = `)]}'"`
if (open.includes(event.key)) {
const codeAfter = afterCursor()
const codeBefore = beforeCursor()
const escapeCharacter = codeBefore.substr(codeBefore.length - 1) === '\\'
const charAfter = codeAfter.substr(0, 1)
if (close.includes(event.key) && !escapeCharacter && charAfter === event.key) {
// We already have closing char next to cursor.
// Move one char to right.
const pos = save()
preventDefault(event)
pos.start = ++pos.end
restore(pos)
} else if (
open.includes(event.key)
&& !escapeCharacter
&& (`"'`.includes(event.key) || ['', ' ', '\n'].includes(charAfter))
) {
preventDefault(event)
const pos = save()
const wrapText = pos.start == pos.end ? '' : getSelection().toString()
Expand Down Expand Up @@ -441,12 +456,18 @@ export function CodeJar(editor: HTMLElement, highlight: (e: HTMLElement, pos?: P

function visit(editor: HTMLElement, visitor: (el: Node) => 'stop' | undefined) {
const queue: Node[] = []

if (editor.firstChild) queue.push(editor.firstChild)

let el = queue.pop()

while (el) {
if (visitor(el) === 'stop') break
if (visitor(el) === 'stop')
break

if (el.nextSibling) queue.push(el.nextSibling)
if (el.firstChild) queue.push(el.firstChild)

el = queue.pop()
}
}
Expand Down
65 changes: 0 additions & 65 deletions demo.html

This file was deleted.

67 changes: 67 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CodeJar – a micro code editor</title>
<link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/styles/github.min.css" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
min-height: 100vh;
background: #F6F8F8;
}

main {
max-width: 800px;
margin: 40px auto;
padding: 20px;
}

.editor {
background: #fff;
border-radius: 6px;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
font-family: "Source Code Pro", monospace;
font-size: 14px;
font-weight: 400;
min-height: 240px;
letter-spacing: normal;
line-height: 20px;
padding: 10px;
tab-size: 4;
}
</style>
</head>
<body>
<main>
<div class="editor language-js"></div>
</main>
<script type="module">
import {CodeJar} from './dist/codejar.js'
import {withLineNumbers} from './dist/linenumbers.js'

const editor = document.querySelector('.editor')

const highlight = editor => {
// highlight.js does not trim old tags,
// let's do it by this hack.
editor.textContent = editor.textContent
hljs.highlightBlock(editor)
}

const jar = CodeJar(editor, withLineNumbers(highlight))

jar.updateCode(localStorage.getItem('code'))
jar.onUpdate(code => {
localStorage.setItem('code', code)
})
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/highlight.min.js"></script>
</body>
</html>
88 changes: 88 additions & 0 deletions linenumbers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
type Options = {
class: string
wrapClass: string
width: string
backgroundColor: string
color: string
}

export function withLineNumbers(
highlight: (e: HTMLElement) => void,
options: Partial<Options> = {}
) {
const opts: Options = {
class: "codejar-linenumbers",
wrapClass: "codejar-wrap",
width: "35px",
backgroundColor: "rgba(128, 128, 128, 0.15)",
color: "",
...options
}

let lineNumbers: HTMLElement
return function (editor: HTMLElement) {
highlight(editor)

if (!lineNumbers) {
lineNumbers = init(editor, opts)
editor.addEventListener("scroll", () => lineNumbers.style.top = `-${editor.scrollTop}px`);
}

const code = editor.textContent || ""
const linesCount = code.replace(/\n+$/, "\n").split("\n").length + 1

let text = ""
for (let i = 1; i < linesCount; i++) {
text += `${i}\n`
}

lineNumbers.innerText = text
}
}

function init(editor: HTMLElement, opts: Options): HTMLElement {
const css = getComputedStyle(editor)

const wrap = document.createElement("div")
wrap.className = opts.wrapClass
wrap.style.position = "relative"

const gutter = document.createElement("div")
gutter.className = opts.class
wrap.appendChild(gutter)

// Add own styles
gutter.style.position = "absolute"
gutter.style.top = "0px"
gutter.style.left = "0px"
gutter.style.bottom = "0px"
gutter.style.width = opts.width
gutter.style.overflow = "hidden"
gutter.style.backgroundColor = opts.backgroundColor
gutter.style.color = opts.color || css.color
gutter.style.setProperty("mix-blend-mode", "difference")

// Copy editor styles
gutter.style.fontFamily = css.fontFamily
gutter.style.fontSize = css.fontSize
gutter.style.lineHeight = css.lineHeight
gutter.style.paddingTop = css.paddingTop
gutter.style.paddingLeft = css.paddingLeft
gutter.style.borderTopLeftRadius = css.borderTopLeftRadius
gutter.style.borderBottomLeftRadius = css.borderBottomLeftRadius

// Add line numbers
const lineNumbers = document.createElement("div");
lineNumbers.style.position = "relative";
lineNumbers.style.top = "0px"
gutter.appendChild(lineNumbers)

// Tweak editor styles
editor.style.paddingLeft = `calc(${opts.width} + ${gutter.style.paddingLeft})`
editor.style.whiteSpace = "pre"

// Swap editor with a wrap
editor.parentNode!.insertBefore(wrap, editor)
wrap.appendChild(editor)
return lineNumbers
}

0 comments on commit e7cfb65

Please sign in to comment.