Skip to content

Commit

Permalink
feat: RichText observer and formatAll (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
devlzl authored Jan 3, 2024
1 parent 83ece8f commit 3efb6fa
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 12 deletions.
4 changes: 4 additions & 0 deletions src/Kernel/Store/TextStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ export class TextStore {
history.exec(command)
}

getAtoms(index: number, length: number) {
return this._slice(index, length)
}

toPlain(): string {
return this._store.reduce((text, current) => text + current.text, '')
}
Expand Down
12 changes: 12 additions & 0 deletions src/Kernel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,23 @@ import { HistoryManager } from './HistoryManager'
import { Slide } from './Slide'
import { TableBlock } from '@BlockHub/TableBlock/TableBlock'
import { PictureBlock } from '@BlockHub/PictureBlock/PictureBlock'
import { EventManager } from './EventManager'
import { TextAtom } from './Store/TextStore'

interface RichTextStateChange {
selection: {
index: number
length: number
}
atoms: Array<TextAtom>
}

export const kernel = {
currentIndex: 0,
slides: [new Slide([new TextBoxBlock(100, 50), new TableBlock(400, 300, 4, 3), new PictureBlock(100, 300)])],

richTextObserver: new EventManager<RichTextStateChange>(),

get currentSlide() {
return this.slides[this.currentIndex]
},
Expand Down
24 changes: 23 additions & 1 deletion src/RichText/RichText.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import type { AttributeValue, TextStore } from '@Kernel/Store/TextStore'
import { SelectionHandler } from './handler/SelectionHandler'
import { Selection, SelectionHandler } from './handler/SelectionHandler'
import { EventHandler } from './handler/EventHandler'
import { EventManager } from '@Kernel/EventManager'
import { kernel } from '@Kernel/index'

export interface RichTextController {
format(name: string, value: AttributeValue): void
formatAll(name: string, value: AttributeValue): void
}

export class RichText {
Expand All @@ -16,8 +19,19 @@ export class RichText {
setSelectionByInput = this.selectionHandler.setSelectionByInput.bind(this.selectionHandler)
setSelectionByNative = this.selectionHandler.setSelectionByNative.bind(this.selectionHandler)

events = {
selectChange: new EventManager<Selection>(),
}

constructor(textStore: TextStore) {
this.textStore = textStore
this.events.selectChange.on((selection) => {
const atoms = textStore.getAtoms(selection.index, selection.length)
kernel.richTextObserver.emit({
selection: selection,
atoms: atoms,
})
})
}

mount(element: HTMLElement) {
Expand All @@ -34,6 +48,14 @@ export class RichText {
})
this.setSelectionByInput({ index, length })
},
formatAll: (name: string, value: AttributeValue) => {
const index = 0
const length = this.textStore.length
this.textStore.format(index, length, {
[name]: value,
})
this.setSelectionByInput({ index, length })
},
}
}
}
31 changes: 23 additions & 8 deletions src/RichText/handler/EventHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,31 @@ import { handleInput } from './utils/handleInput'

export class EventHandler {
richText: RichText
_isCurrentElement: boolean = false
_isComposing: boolean

constructor(richText: RichText) {
this.richText = richText
this._isComposing = false
}

onSelectionChange() {
const range = document.getSelection()?.getRangeAt(0) as Range
this._isCurrentElement = range.intersectsNode(this.richText.element as HTMLElement)
if (!this._isCurrentElement) {
return
}
if (this._isComposing) {
// prevent modify inner selection by native selection change
return
}
this.richText.setSelectionByNative()
}

onBeforeInput(event: InputEvent) {
if (!this._isCurrentElement) {
return
}
event.preventDefault()
if (this._isComposing) {
return
Expand All @@ -23,10 +40,16 @@ export class EventHandler {
}

onCompositionStart() {
if (!this._isCurrentElement) {
return
}
this._isComposing = true
}

onCompositionEnd(event: CompositionEvent) {
if (!this._isCurrentElement) {
return
}
this._isComposing = false
const data = event.data
// https://github.com/w3c/input-events/issues/137
Expand All @@ -39,14 +62,6 @@ export class EventHandler {
})
}

onSelectionChange() {
if (this._isComposing) {
// prevent modify inner selection by native selection change
return
}
this.richText.setSelectionByNative()
}

mount() {
const element = this.richText.element as HTMLElement
element.addEventListener('beforeinput', this.onBeforeInput.bind(this))
Expand Down
18 changes: 15 additions & 3 deletions src/RichText/handler/SelectionHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,17 @@ export class SelectionHandler {
nativeSelection?.addRange(range)
}

private _setSelection(selection: Selection) {
this._selection = selection
this.richText.events.selectChange.emit(selection)
}

getSelection() {
return { ...this._selection }
}

setSelectionByInput(selection: Selection) {
this._selection = selection
this._setSelection(selection)
this._updateNativeSelection()
}

Expand Down Expand Up @@ -103,9 +108,16 @@ export class SelectionHandler {
}
currentIndex += 1
}
this._selection = {

// avoid _setSelection redundantly
const { index: oldIndex, length: oldLength } = this.getSelection()
if (oldIndex === selectionIndex && oldLength === selectionLength) {
return
}

this._setSelection({
index: selectionIndex,
length: selectionLength,
}
})
}
}
5 changes: 5 additions & 0 deletions src/UserInterface/ToolBar/components/Home/FontStyle.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<script setup lang="ts">
import { FontSizeTwo, AddText, ClearFormat, TextBold, TextItalic, TextUnderline, Strikethrough, BackgroundColor } from '@icon-park/vue-next'
import MenuWrapper from '../MenuWrapper.vue'
import { kernel } from '@Kernel/index'
kernel.richTextObserver.on((newState) => {
console.log('newState', newState)
})
</script>

<template>
Expand Down

0 comments on commit 3efb6fa

Please sign in to comment.