Skip to content

Commit

Permalink
geaw
Browse files Browse the repository at this point in the history
  • Loading branch information
chee committed Jan 19, 2021
1 parent 4434981 commit 19c836e
Show file tree
Hide file tree
Showing 8 changed files with 4,360 additions and 1,743 deletions.
2 changes: 1 addition & 1 deletion packages/editor/src/convert-to-html.ts
Expand Up @@ -2,6 +2,7 @@ import type * as md from "mdast"
import {html, TemplateResult} from "lit-html"
import {spread} from "@open-wc/lit-helpers"
import * as is from "./is"
import u from "unist-builder"

type Handler = (node: md.Content | md.Root, parent: md.Parent | md.Root) => any

Expand Down Expand Up @@ -224,7 +225,6 @@ let handlers: Handlers = {
// return html`<mayo-text ...="${spread(spreadable(node))}" .node=${node}
// >${node.value}</mayo-text
// >`
// }
return node.value
},

Expand Down
2 changes: 2 additions & 0 deletions packages/editor/src/elements/index.ts
Expand Up @@ -87,6 +87,8 @@ export type {

export default [
MayoDocumentElement,
MayoSidebarElement,
MayoSidebarFileElement,
MayoBreakElement,
MayoCodeElement,
MayoInlineCodeElement,
Expand Down
58 changes: 35 additions & 23 deletions packages/editor/src/elements/mayo-document.ts
Expand Up @@ -16,6 +16,8 @@ import {MayoElement, MayoParentElement} from "./markdown/mayo-element"
// @ts-ignore
import compact from "mdast-util-compact"
import {visit} from "unist-utils-core"
import {insertParagraph} from "../utils"
import * as is from "../is"

export default class MayoDocumentElement extends HTMLElement {
@target document: HTMLElement
Expand Down Expand Up @@ -82,6 +84,7 @@ export default class MayoDocumentElement extends HTMLElement {

handleInput(event: BeforeInputEvent) {
// TODO multiple ranges?

let range: StaticRange = event.getTargetRanges()[0]
let isCaret =
range.endContainer == range.startContainer &&
Expand All @@ -95,19 +98,13 @@ export default class MayoDocumentElement extends HTMLElement {
let startNode: md.Content = startElement.node
let endNode: md.Content = startElement.node

let startBlockElement =
startElement.type == "block"
? startElement
: (startElement.closest(
'[mayo-type="block"]'
)! as MayoParentElement<any>)
let startBlockElement = startElement.block
? startElement
: (startElement.closest("[block]")! as MayoParentElement<any>)

let endBlockElement =
endElement.type == "block"
? endElement
: (endElement.closest(
'[mayo-type="block"]'
)! as MayoParentElement<any>)
let endBlockElement = endElement.block
? endElement
: (endElement.closest("[block]")! as MayoParentElement<any>)

// the index of the start block in the mayo-document (y)
let startBlockIndex = Array.from(this.document.children).indexOf(
Expand All @@ -120,20 +117,20 @@ export default class MayoDocumentElement extends HTMLElement {

// the index of the start element in the start block (x)
let startElementIndex = 0
if (startElement.type == "inline") {
if (startElement.inline) {
startElementIndex = startBlockElement.interestingChildren.indexOf(
startElement
)
} else if (startElement.type == "block") {
} else if (startElement.block) {
startElementIndex = startBlockElement.interestingChildren.indexOf(
range.startContainer
)
}

let endElementIndex = 0
if (endElement.type == "inline") {
if (endElement.inline) {
endElementIndex = endBlockElement.interestingChildren.indexOf(endElement)
} else if (endElement.type == "block") {
} else if (endElement.block) {
endElementIndex = endBlockElement.interestingChildren.indexOf(
range.endContainer
)
Expand Down Expand Up @@ -177,13 +174,28 @@ export default class MayoDocumentElement extends HTMLElement {
}
case "insertParagraph": {
let id = shortId()
visit(
this.ast,
range.startContainer.parentElement.node,
(node, index, parents) => {
console.log(node, index, parents)
}
)
if ("value" in startElement.node) {
// TODO isLiteralElement typeguard
insertParagraph(this.ast, startElement.node, range.startOffset, id)
} else if (startElement == startBlockElement) {
insertParagraph(
this.ast,
startElement.node.children[startElementIndex],
range.startOffset,
id
)
} else {
let idx = startElement.interestingChildren.indexOf(
range.startContainer
)
insertParagraph(
this.ast,
startElement.node.children[idx],
range.startOffset,
id
)
}

this.setAttribute("dirty", "true")
this.update()
this.updateSelection({
Expand Down
7 changes: 6 additions & 1 deletion packages/editor/src/elements/mayo-sidebar-file.ts
Expand Up @@ -28,10 +28,15 @@ export default class MayoSidebarFileElement extends LitElement {
}
`
}

new() {
localStorage.setItem("file", " ")
}

render() {
let [name, ext] = this.path!.split(".")

return html`<a href="${this.path!}" class="link">
return html`<a href="${this.path!}" @click=${this.new} class="link">
<span class="name">${name}</span>
<span class="ext">${ext}</span>
</a>`
Expand Down
128 changes: 101 additions & 27 deletions packages/editor/src/utils.ts
@@ -1,35 +1,109 @@
import {find, visit, SKIP, EXIT} from "unist-utils-core"
import {find, visit, SKIP, EXIT, findAll, selectAll} from "unist-utils-core"
// @ts-ignore
import uremove from "unist-util-remove"
import {Node} from "unist"
import * as unist from "unist"
import * as md from "mdast"
import u from "unist-builder"
import * as is from "./is"

export function insertParagraph(
root: md.Parent,
target: md.Text | md.InlineCode,
offset: number,
id?: string
) {
if (!target || (target.type != "text" && target.type != "inlineCode")) {
throw new Error(
`must have a text or inlineCode target, got ${target?.type}`
)
}
let [left, right] = split(root, target, offset)
let t = selectAll<md.Text | md.InlineCode>("text, inlineCode", right)
if (t.length == 1) {
let [node] = t
if (node.value.length == 0) {
node.type = "text"
node.value = " "
}
}

visit(root, target, (node, index, parents) => {
node.value = left.value
let firstp = parents[parents.length - 1]
let prest = firstp.children.slice(index + 1)

let rest: unist.Node[] = []
if (target.type == "text" || target.type == "inlineCode") {
parents.forEach((parent, index) => {
if (is.inline(parent.type)) {
let idx = parents[index - 1].children.indexOf(parent)
parents[index - 1].children.splice(idx, 1, left)
if (!rest.length) {
rest = parents[index - 1].children.slice(idx + 1)
}
rest.forEach((n: unist.Node) => remove(parents[index - 1], {}, n))
}
})
}
parents.forEach((parent, index) => {
if (is.block(parent.type) && is.leaf(parent.type)) {
let idx = parents[index - 1].children.indexOf(parent)
let opts = {}
if (id) {
opts.id = id
}
prest.forEach((n: unist.Node) => remove(parents[index - 1], {}, n))
if (parent != firstp) {
prest = []
}
parents[index - 1].children.splice(
idx + 1,
0,
u("paragraph", opts, [right, ...rest, ...prest])
)
}
})
return EXIT
})
}

export function split(
root: md.Content | md.Parent,
target: md.Content,
root: md.Parent,
target: md.Text | md.InlineCode,
offset: number
) {
visit<md.Content | md.Parent, md.Parent>(
root,
target,
(n, index, parents) => {
if (n.type == "text" || n.type == "inlineCode") {
let orig = n.value as string
n.value = orig.slice(0, offset)
console.log("length", parents.length)
let text = u("text", {}, orig.slice(offset))
let idx = index
for (let i = parents.length - 2; i > -1; i--) {
idx = parents[i].children.indexOf(parents[i + 1])
}
console.log({idx})
console.log(parents[0].children.indexOf(parents[1]))
parents[0].children.splice(idx - 1 + 1, 0, text)
let leftText = target.value.slice(0, offset)
let rightText = target.value.slice(offset)

let leftNode = u(target.type, leftText)
let rightNode = u(target.type, rightText)
let leftStack = []
let rightStack = []

visit(root, target, (node, index, parents) => {
let nextpc = parents[parents.length - 1].children.slice(0, index)
let nextac = parents[parents.length - 1].children.slice(index + 1)
for (let i = parents.length - 1; i > 0; i--) {
let highParent = parents[i - 1]
let lowParent = parents[i]
let idx = highParent.children.indexOf(lowParent)
let pc = highParent.children.slice(0, idx)
let ac = highParent.children.slice(idx + 1)
if (is.inline(lowParent.type)) {
leftNode = u(lowParent.type, [...nextpc, leftNode])
rightNode = u(lowParent.type, [rightNode, ...nextac])
}
nextpc = pc
nextac = ac
if (is.block(lowParent.type)) {
break
}
return EXIT
}
)

return EXIT
})

return [leftNode, rightNode]
}

export function demoteFully(
Expand Down Expand Up @@ -69,15 +143,15 @@ export function demoteFully(
})
}

export function toString(node: Node) {
export function toString(node: unist.Node) {
return (
(node && node.value) ||
("children" in node && toStringAll(node.children)) ||
""
)
}

function toStringAll(values: Node[]): string {
function toStringAll(values: unist.Node[]): string {
var result = []
var index = -1

Expand Down Expand Up @@ -110,10 +184,10 @@ interface RemoveOptions {
}

export function remove(
tree: Node,
tree: unist.Node,
options: RemoveOptions,
condition: string | object | ((node: Node) => boolean)
): Node | null | undefined {
condition: string | object | ((node: unist.Node) => boolean)
): unist.Node | null | undefined {
return uremove(tree, options, condition)
}

Expand Down

0 comments on commit 19c836e

Please sign in to comment.