Skip to content

Commit

Permalink
refactor(editor): contenteditable ast new implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Novout committed Aug 13, 2022
1 parent 6b8b521 commit ea6f27e
Show file tree
Hide file tree
Showing 22 changed files with 2,296 additions and 264 deletions.
1 change: 1 addition & 0 deletions packages/better-write-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"@vueuse/head": "0.7.5",
"@vueuse/integrations": "8.2.5",
"@vueuse/motion": "2.0.0-beta.12",
"better-write-contenteditable-ast": "^0.16.11",
"better-write-image-converter": "^0.16.11",
"better-write-languages": "^0.16.11",
"better-write-plugin-core": "^0.16.11",
Expand Down
41 changes: 0 additions & 41 deletions packages/better-write-app/src/use/block/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { useAbsoluteStore } from '@/store/absolute'
import { useContextStore } from '@/store/context'
import { useEditorStore } from '@/store/editor'
import { Entity, EntityType, ID } from 'better-write-types'
import { ImageToForcePNG } from 'better-write-image-conversor'
import { nextTick, Ref, watch } from 'vue'
import useEmitter from '../emitter'
import { useEntity } from '../entity'
Expand Down Expand Up @@ -193,46 +192,6 @@ export const useBlockText = ({
entity.base().onDelete(props.entity, index.value)
}

// italic entity
if (e.key === 'i' || e.key === 'I') {
if (!value || !entity.utils().isTextBlock(props.entity.type)) return

e.preventDefault()
e.stopPropagation()

setData(
raw.v2().apply({
existent: input.value.innerHTML,
type: 'italic',
input: _input,
})
)

await nextTick

raw.v2().caret().set(_input, offset)
}

// bold entity
if (e.key === 'b' || e.key === 'B') {
if (!value || !entity.utils().isTextBlock(props.entity.type)) return

e.preventDefault()
e.stopPropagation()

setData(
raw.v2().apply({
existent: input.value.innerHTML,
type: 'bold',
input: _input,
})
)

await nextTick

raw.v2().caret().set(_input, offset)
}

// to entity initial
if (e.key === 'ArrowUp') {
e.preventDefault()
Expand Down
13 changes: 4 additions & 9 deletions packages/better-write-app/src/use/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { usePDFStore } from '@/store/pdf'
import { useAbsoluteStore } from '@/store/absolute'
import {
ProjectObject,
ProjectState,
ProjectType,
ContextState,
Entity,
Expand All @@ -21,6 +20,7 @@ import { useStorage } from './storage/storage'
import { useEnv } from './env'
import { useEntity } from './entity'
import { usePlugin } from 'better-write-plugin-core'
import { getRows } from 'better-write-contenteditable-ast'
import { useBreakpoint } from './breakpoint'
import { useRaw } from './raw'
import { useFileSystemAccess } from '@vueuse/core'
Expand Down Expand Up @@ -480,14 +480,9 @@ export const useProject = () => {
const value = page.entities
.filter((ent) => isValidType(ent))
.reduce((conc, ent) => {
const nm = raw
.v2()
.block()
.text()
.parse(ent.raw)
.reduce((acc, value) => {
return (acc += value + '\n')
}, '')
const nm = getRows(ent.raw).reduce((acc, value) => {
return (acc += value + '\n')
}, '')

return (
conc +
Expand Down
98 changes: 8 additions & 90 deletions packages/better-write-app/src/use/raw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,16 +374,6 @@ export const useRaw = () => {
const v2 = () => {
const block = () => {
const text = () => {
const parse = (text: string): string[] => {
return text
.split(utils.regex().divTag())
.map((text) => text.replaceAll('<br>', ' '))
.filter(
(text) =>
text && !text.includes('<div>') && !text.includes('</div>')
)
}

const join = (texts: string[]): string => {
return texts.reduce((acc, text, index) => {
if (index === 0) return (acc += text)
Expand All @@ -400,7 +390,7 @@ export const useRaw = () => {
}, '')
}

return { parse, join }
return { join }
}

const drop = async (e: DragEvent, item: Entity) => {
Expand Down Expand Up @@ -776,81 +766,7 @@ export const useRaw = () => {
return entity.raw
}

const pdf = (raw: string): Array<any> => {
const final: Array<any> = []
let set: false | 'bold' | 'italic' = false

const _raw = substitution.purge(raw)

const rest = _raw.split(useUtils().regex().htmlTags())

rest.forEach((content: string) => {
// italic
if (set === 'italic') {
final.push({
text: content,
italics: true,
})
set = false
return
}

if (content === html().italic().open()) {
set = 'italic'
return
}

if (set === 'bold') {
final.push({
text: content,
bold: true,
})
set = false
return
}

// bold
if (content === html().bold().open()) {
set = 'bold'
return
}

if (
content === html().italic().close() ||
content === html().bold().close()
)
return

/*
// http
if (content.match(useUtils().regex().links())) {
const fin = raw.split(useUtils().regex().links())
fin.forEach((str: string) => {
if (str.match(useUtils().regex().links())) {
final.push({
text: str.replace('http://', '').replace('https://', ''),
link: str,
decoration: 'underline',
})
set = false
} else {
final.push(str)
set = false
}
})
return
}
*/

final.push(content)
})

return final
}

return { apply, editor, pdf, switcher, finder }
return { apply, editor, switcher, finder }
}

const normalize = (
Expand All @@ -859,10 +775,12 @@ export const useRaw = () => {
) => {
const BWTags = (str: string) => {
return str
.replaceAll(html().bold().open(), '')
.replaceAll(html().bold().close(), '')
.replaceAll(html().italic().open(), '')
.replaceAll(html().italic().close(), '')
.replaceAll('<b>', '')
.replaceAll('</b>', '')
.replaceAll('<i>', '')
.replaceAll('</i>', '')
.replaceAll('<u>', '')
.replaceAll('</u>', '')
}

const EditorTags = (str: string) => {
Expand Down
6 changes: 6 additions & 0 deletions packages/better-write-contenteditable-ast/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.vscode
.DS_Store

node_modules
dist
yarn-error.log
6 changes: 6 additions & 0 deletions packages/better-write-contenteditable-ast/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"tabWidth": 2,
"singleQuote": true,
"semi": false,
"vueIndentScriptAndStyle": true
}
10 changes: 10 additions & 0 deletions packages/better-write-contenteditable-ast/build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineBuildConfig } from 'unbuild';

export default defineBuildConfig({
rollup: {
emitCJS: true,
},
declaration: true,
entries: [{ input: 'src/index.ts', outDir: 'dist', name: 'index' }],
externals: [],
});
37 changes: 37 additions & 0 deletions packages/better-write-contenteditable-ast/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "better-write-contenteditable-ast",
"version": "0.16.11",
"author": "Novout",
"license": "MIT",
"keywords": [
"vue",
"hook",
"text",
"editor"
],
"main": "dist/index.cjs",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"scripts": {
"serve": "rimraf ./dist && unbuild",
"test": "echo \"Error: no test specified\"",
"build": "rimraf ./dist && unbuild",
"lint": "prettier --write src/"
},
"files": [
"dist/**/*",
"package.json",
"LICENSE",
"README.md"
],
"dependencies": {
"better-write-types": "^0.16.11",
"hast": "1.0.0",
"hast-util-from-html": "1.0.0"
},
"devDependencies": {
"prettier": "2.5.1",
"rimraf": "3.0.2",
"unbuild": "0.7.0"
}
}
61 changes: 61 additions & 0 deletions packages/better-write-contenteditable-ast/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { fromHtml } from 'hast-util-from-html'
import { Content } from 'hast'
import { TextAST, TextASTElement } from 'better-write-types'

export const getRows = (text: string): string[] => {
return text
.split(new RegExp(/<div>(.*?)<\/div>/))
.map((text) => text.replaceAll('<br>', ' '))
.filter(
(text) => text && !text.includes('<div>') && !text.includes('</div>')
)
}

export const parse = (row: string) => {
const nodes: TextAST[] = []
const _TAG_NAMES_ = {
bold: false,
italic: false,
underline: false,
link: false,
}

const htmlNodes = fromHtml(row, { fragment: true }).children

const elementText = (element: TextASTElement) => {
nodes.push({
text: element.text,
bold: _TAG_NAMES_.bold || false,
italic: _TAG_NAMES_.italic || false,
underline: _TAG_NAMES_.underline || false,
link: _TAG_NAMES_.link || false,
})
}

const textAST = (children: Content[]) => {
children.forEach((node: Content) => {
if (node.type === 'element') {
if (node.tagName === 'b') _TAG_NAMES_.bold = true
if (node.tagName === 'i') _TAG_NAMES_.italic = true
if (node.tagName === 'u') _TAG_NAMES_.underline = true
if (node.tagName === 'a') _TAG_NAMES_.link = true

if (node.children) textAST(node.children)
}

if (node.type === 'text') {
elementText({
text: node.value,
})
}
})

_TAG_NAMES_.bold = false
_TAG_NAMES_.italic = false
_TAG_NAMES_.underline = false
}

textAST(htmlNodes)

return nodes
}
45 changes: 45 additions & 0 deletions packages/better-write-contenteditable-ast/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"include": [
"src/types/index.ts",
"src/**/*.ts",
"test/**/*.ts",
"demo/**/*.ts",
"demo/**/*.d.ts",
"demo/**/*.tsx",
"demo/**/*.vue"
],
"exclude": ["dist", "node_modules"],
"compilerOptions": {
"baseUrl": ".",
"rootDir": ".",
"outDir": "dist",
"sourceMap": false,
"noEmit": true,
"declaration": true,
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"skipLibCheck": true,
"noUnusedLocals": true,
"strictNullChecks": true,
"noImplicitAny": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"suppressImplicitAnyIndexErrors": true,
"strict": true,
"isolatedModules": false,
"experimentalDecorators": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"removeComments": false,
"strictPropertyInitialization": false,
"jsx": "preserve",
"lib": ["esnext", "dom"],
"types": ["node"],
"plugins": [
{
"name": "@vuedx/typescript-plugin-vue"
}
]
}
}
Loading

0 comments on commit ea6f27e

Please sign in to comment.