refactor: block storage (#1952)

This commit is contained in:
Mo
2022-11-06 07:51:41 -06:00
committed by GitHub
parent 7d64b1c0ff
commit 40a1a27444
21 changed files with 417 additions and 221 deletions

View File

@@ -1,3 +1,4 @@
import { NoteType } from '@standardnotes/features'
import { createNote } from './../../Utilities/Test/SpecUtils'
describe('SNNote Tests', () => {
@@ -34,4 +35,61 @@ describe('SNNote Tests', () => {
expect(note.noteType).toBe(undefined)
})
it('should getBlock', () => {
const note = createNote({
text: 'some text',
blocksItem: {
blocks: [
{
id: '123',
type: NoteType.Authentication,
editorIdentifier: '456',
content: 'foo',
},
],
},
})
expect(note.getBlock('123')).toStrictEqual({
id: '123',
type: NoteType.Authentication,
editorIdentifier: '456',
content: 'foo',
})
})
it('should getBlock with no blocks', () => {
const note = createNote({
text: 'some text',
})
expect(note.getBlock('123')).toBe(undefined)
})
it('should getBlock with no blocksItem', () => {
const note = createNote({
text: 'some text',
})
expect(note.getBlock('123')).toBe(undefined)
})
it('should get indexOfBlock', () => {
const note = createNote({
text: 'some text',
blocksItem: {
blocks: [
{
id: '123',
type: NoteType.Authentication,
editorIdentifier: '456',
content: 'foo',
},
],
},
})
expect(note.indexOfBlock({ id: '123' })).toBe(0)
})
})

View File

@@ -48,4 +48,17 @@ export class SNNote extends DecryptedItem<NoteContent> implements NoteContentSpe
getBlock(id: string): NoteBlock | undefined {
return this.blocksItem?.blocks.find((block) => block.id === id)
}
indexOfBlock(block: { id: string }): number | undefined {
if (!this.blocksItem) {
return undefined
}
const index = this.blocksItem.blocks.findIndex((b) => b.id === block.id)
if (index === -1) {
return undefined
}
return index
}
}

View File

@@ -4,41 +4,10 @@ export type NoteBlock = {
id: string
type: NoteType
editorIdentifier: string
size?: { width: number; height: number }
content: string
size?: { width: number; height: number }
}
export interface NoteBlocks {
blocks: NoteBlock[]
}
export function bracketSyntaxForBlock(block: { id: NoteBlock['id'] }): { open: string; close: string } {
return {
open: `<Block id=${block.id}>`,
close: `</Block id=${block.id}>`,
}
}
export function stringIndexOfBlock(
text: string,
block: { id: NoteBlock['id'] },
): { begin: number; end: number } | undefined {
const brackets = bracketSyntaxForBlock(block)
const startIndex = text.indexOf(brackets.open)
if (startIndex === -1) {
return undefined
}
const endIndex = text.indexOf(brackets.close) + brackets.close.length
return {
begin: startIndex,
end: endIndex,
}
}
export function blockContentToNoteTextRendition(block: { id: NoteBlock['id'] }, content: string): string {
const brackets = bracketSyntaxForBlock(block)
return `${brackets.open}${content}${brackets.close}`
}

View File

@@ -21,4 +21,99 @@ describe('note mutator', () => {
expect(result.content.editorIdentifier).toEqual(FeatureIdentifier.MarkdownProEditor)
})
it('should addBlock to new note', () => {
const note = createNote({})
const mutator = new NoteMutator(note, MutationType.NoUpdateUserTimestamps)
mutator.addBlock({ type: NoteType.Code, id: '123', editorIdentifier: 'markdown', content: 'test' })
const result = mutator.getResult()
expect(result.content.blocksItem).toEqual({
blocks: [{ type: NoteType.Code, id: '123', editorIdentifier: 'markdown', content: 'test' }],
})
})
it('should addBlock to existing note', () => {
const note = createNote({
blocksItem: {
blocks: [{ type: NoteType.Code, id: '123', editorIdentifier: 'markdown', content: 'test' }],
},
})
const mutator = new NoteMutator(note, MutationType.NoUpdateUserTimestamps)
mutator.addBlock({ type: NoteType.RichText, id: '456', editorIdentifier: 'richy', content: 'test' })
const result = mutator.getResult()
expect(result.content.blocksItem).toEqual({
blocks: [
{ type: NoteType.Code, id: '123', editorIdentifier: 'markdown', content: 'test' },
{ type: NoteType.RichText, id: '456', editorIdentifier: 'richy', content: 'test' },
],
})
})
it('should removeBlock', () => {
const note = createNote({
blocksItem: {
blocks: [
{ type: NoteType.Code, id: '123', editorIdentifier: 'markdown', content: 'test' },
{ type: NoteType.Code, id: '456', editorIdentifier: 'markdown', content: 'test' },
],
},
})
const mutator = new NoteMutator(note, MutationType.NoUpdateUserTimestamps)
mutator.removeBlock({ type: NoteType.Code, id: '123', editorIdentifier: 'markdown', content: 'test' })
const result = mutator.getResult()
expect(result.content.blocksItem).toEqual({
blocks: [{ type: NoteType.Code, id: '456', editorIdentifier: 'markdown', content: 'test' }],
})
})
it('should changeBlockContent', () => {
const note = createNote({
blocksItem: {
blocks: [
{ type: NoteType.Code, id: '123', editorIdentifier: 'markdown', content: 'old content 1' },
{ type: NoteType.Code, id: '456', editorIdentifier: 'markdown', content: 'old content 2' },
],
},
})
const mutator = new NoteMutator(note, MutationType.NoUpdateUserTimestamps)
mutator.changeBlockContent('123', 'new content')
const result = mutator.getResult()
expect(result.content.blocksItem).toEqual({
blocks: [
{ type: NoteType.Code, id: '123', editorIdentifier: 'markdown', content: 'new content' },
{ type: NoteType.Code, id: '456', editorIdentifier: 'markdown', content: 'old content 2' },
],
})
})
it('should changeBlockSize', () => {
const note = createNote({
blocksItem: {
blocks: [
{ type: NoteType.Code, id: '123', editorIdentifier: 'markdown', content: 'test' },
{ type: NoteType.Code, id: '456', editorIdentifier: 'markdown', content: 'test' },
],
},
})
const mutator = new NoteMutator(note, MutationType.NoUpdateUserTimestamps)
mutator.changeBlockSize('123', { width: 10, height: 20 })
const result = mutator.getResult()
expect(result.content.blocksItem).toEqual({
blocks: [
{
type: NoteType.Code,
id: '123',
editorIdentifier: 'markdown',
content: 'test',
size: { width: 10, height: 20 },
},
{ type: NoteType.Code, id: '456', editorIdentifier: 'markdown', content: 'test' },
],
})
})
})

View File

@@ -5,8 +5,8 @@ import { NoteToNoteReference } from '../../Abstract/Reference/NoteToNoteReferenc
import { ContentType } from '@standardnotes/common'
import { ContentReferenceType } from '../../Abstract/Item'
import { FeatureIdentifier, NoteType } from '@standardnotes/features'
import { blockContentToNoteTextRendition, bracketSyntaxForBlock, NoteBlock, stringIndexOfBlock } from './NoteBlocks'
import { removeFromArray } from '@standardnotes/utils'
import { NoteBlock } from './NoteBlocks'
import { filterFromArray } from '@standardnotes/utils'
export class NoteMutator extends DecryptedItemMutator<NoteContent> {
set title(title: string) {
@@ -51,10 +51,6 @@ export class NoteMutator extends DecryptedItemMutator<NoteContent> {
}
this.mutableContent.blocksItem.blocks.push(block)
const brackets = bracketSyntaxForBlock(block)
this.text += `${brackets.open}${block.content}${brackets.close}`
}
removeBlock(block: NoteBlock): void {
@@ -62,37 +58,24 @@ export class NoteMutator extends DecryptedItemMutator<NoteContent> {
return
}
removeFromArray(this.mutableContent.blocksItem.blocks, block)
const location = stringIndexOfBlock(this.mutableContent.text, block)
if (location) {
this.mutableContent.text = this.mutableContent.text.slice(location.begin, location.end)
}
filterFromArray(this.mutableContent.blocksItem.blocks, { id: block.id })
}
changeBlockContent(blockId: string, content: string): void {
const block = this.mutableContent.blocksItem?.blocks.find((b) => b.id === blockId)
const blockIndex = this.mutableContent.blocksItem?.blocks.findIndex((b) => {
return b.id === blockId
})
if (blockIndex == null || blockIndex === -1) {
return
}
const block = this.mutableContent.blocksItem?.blocks[blockIndex]
if (!block) {
return
}
block.content = content
const location = stringIndexOfBlock(this.mutableContent.text, block)
if (location) {
const replaceRange = (s: string, start: number, end: number, substitute: string) => {
return s.substring(0, start) + substitute + s.substring(end)
}
this.mutableContent.text = replaceRange(
this.mutableContent.text,
location.begin,
location.end,
blockContentToNoteTextRendition({ id: blockId }, content),
)
}
}
changeBlockSize(blockId: string, size: { width: number; height: number }): void {