Skip to content

Commit

Permalink
Fixed traverseSelection & History Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
GuilhermeF03 committed Apr 25, 2024
1 parent e370e1b commit 517a143
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 117 deletions.
16 changes: 6 additions & 10 deletions code/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
"eslint-plugin-playwright": "^1.6.0",
"lodash": "^4.17.21",
"msw": "^2.2.14",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"react-icons": "^5.1.0",
"react-router-dom": "^6.23.0",
"slate": "^0.103.0",
Expand All @@ -47,27 +47,23 @@
"@typescript-eslint/parser": "^7.7.1",
"@vite-pwa/assets-generator": "^0.2.4",
"@vitejs/plugin-react": "^4.2.1",
"@vitest/coverage-v8": "^1.5.1",
"@vitest/ui": "^1.5.1",
"@vitest/coverage-v8": "^1.5.2",
"@vitest/ui": "^1.5.2",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-hooks": "^4.6.1",
"eslint-plugin-react-refresh": "^0.4.6",
"jsdom": "^24.0.0",
"knip": "^5.10.0",
"prettier": "^3.2.5",
"sass": "^1.75.0",
"typescript": "^5.4.5",
"vite": "^5.2.10",
"vite-plugin-pwa": "^0.19.8",
"vite-plugin-qrcode": "^0.2.3",
"vite-tsconfig-paths": "^4.3.2",
"vitest": "^1.5.1",
"workbox-build": "^7.1.0",
"workbox-cli": "^7.1.0",
"workbox-precaching": "^7.1.0"
"vitest": "^1.5.2"
}
}
45 changes: 27 additions & 18 deletions code/client/src/editor/crdt/fugue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {

type TraverseOptions = {
returnDeleted?: boolean;
returnLineBreaks?: boolean;
};

/**
Expand Down Expand Up @@ -45,8 +46,7 @@ export class Fugue {
* @param values
*/
insertLocal(cursor: Cursor, ...values: NodeInsert[] | string[]): InsertOperation[] {
let line = cursor.line;
let column = cursor.column;
let { line, column } = cursor;
return values.map(value => {
const node = typeof value === 'string' ? nodeInsert(value, []) : value;
const operation = this.getInsertOperation({ line, column }, node);
Expand Down Expand Up @@ -100,9 +100,10 @@ export class Fugue {
/**
* Relives the nodes from the given start index and given length.
* @param selection
* @param options
*/
reviveLocal(selection: Selection): ReviveOperation[] {
const nodes = Array.from(this.traverseBySelection(selection, { returnDeleted: true }));
reviveLocal(selection: Selection, options?: TraverseOptions): ReviveOperation[] {
const nodes = Array.from(this.traverseBySelection(selection, { ...options, returnDeleted: true }));
return nodes.map(node => this.reviveNode(node.id));
}

Expand Down Expand Up @@ -248,15 +249,15 @@ export class Fugue {
*/
*traverseBySelection(selection: Selection, options?: TraverseOptions): IterableIterator<FugueNode> {
const { start, end } = selection;
const { returnDeleted } = options || { returnDeleted: false };
let lineCounter = 0;
let columnCounter = 0;
let inBounds = false;
let finished = false;
const { returnDeleted, returnLineBreaks } = {
returnDeleted: options?.returnDeleted || false,
returnLineBreaks: options?.returnLineBreaks || false,
};
let lineCounter = 0,
columnCounter = 0;
let inBounds = false,
finished = false;
for (const node of this.traverseTree(returnDeleted)) {
if (finished) break;

// update counters
if (node.value === '\n') {
lineCounter++;
columnCounter = 0;
Expand All @@ -268,16 +269,24 @@ export class Fugue {
}

// yield node if in bounds
if (inBounds) {
if (inBounds && (returnLineBreaks || (!returnLineBreaks && node.value !== '\n'))) {
yield node;
}

// end condition
if (lineCounter === end.line && columnCounter === end.column) {
finished = true;
}
finished =
lineCounter === end.line &&
columnCounter === end.column &&
((!returnLineBreaks && node.value !== '\n') || returnLineBreaks);

if (finished) break;

columnCounter++;
// increment column counter
if (node.value !== '\n') {
columnCounter++;
} else if (returnLineBreaks) {
// don't ignore line breaks
columnCounter++;
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions code/client/src/editor/domain/document/history/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export default (fugue: Fugue, communication: Communication): HistoryDomainOperat
* @param cursor
*/
function splitNode({ cursor }: SplitNodeOperation) {
return fugue.reviveLocal({ start: cursor, end: cursor });
return fugue.reviveLocal({ start: cursor, end: cursor }, { returnLineBreaks: true });
}

/**
Expand All @@ -121,7 +121,7 @@ export default (fugue: Fugue, communication: Communication): HistoryDomainOperat
* @param set_mode
*/
function setNode({ selection, properties }: SetNodeOperation | UnsetNodeOperation, set_mode: boolean) {
const type = Object.keys(properties)[0];
const type = properties.type;
const styleType = getStyleType(type);

return styleType === 'block'
Expand Down
1 change: 0 additions & 1 deletion code/client/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';
Expand Down
12 changes: 6 additions & 6 deletions code/client/src/pwa/inject-config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CustomInjectManifestOptions } from 'vite-plugin-pwa';

export const injectConfig: Partial<CustomInjectManifestOptions> = {
minify: false,
enableWorkboxModulesLogs: true,
};
// import { CustomInjectManifestOptions } from 'vite-plugin-pwa';
//
// export const injectConfig: Partial<CustomInjectManifestOptions> = {
// minify: false,
// enableWorkboxModulesLogs: true,
// };
90 changes: 45 additions & 45 deletions code/client/src/pwa/manifest-config.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
import { ManifestOptions } from 'vite-plugin-pwa';

export const manifestConfig: Partial<ManifestOptions> = {
name: 'NoteSpace',
short_name: 'NoteSpace',
start_url: '/',
scope: '.',
display: 'standalone',
background_color: '#ffffff',
theme_color: '#ffffff',
orientation: 'portrait-primary',
icons: [
{
src: '/android-chrome-192x192.png',
sizes: '192x192',
type: 'image/png',
purpose: 'any maskable',
},
{
src: '/android-chrome-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable',
},
/* favicon */
{
src: '/favicon-16x16.png',
sizes: '16x16',
type: 'image/png',
purpose: 'any maskable',
},
{
src: '/favicon-32x32.png',
sizes: '32x32',
type: 'image/png',
purpose: 'any maskable',
},
{
src: '/apple-touch-icon.png',
sizes: '180x180',
type: 'image/png',
purpose: 'any maskable',
},
],
};
// import { ManifestOptions } from 'vite-plugin-pwa';
//
// export const manifestConfig: Partial<ManifestOptions> = {
// name: 'NoteSpace',
// short_name: 'NoteSpace',
// start_url: '/',
// scope: '.',
// display: 'standalone',
// background_color: '#ffffff',
// theme_color: '#ffffff',
// orientation: 'portrait-primary',
// icons: [
// {
// src: '/android-chrome-192x192.png',
// sizes: '192x192',
// type: 'image/png',
// purpose: 'any maskable',
// },
// {
// src: '/android-chrome-512x512.png',
// sizes: '512x512',
// type: 'image/png',
// purpose: 'any maskable',
// },
// /* favicon */
// {
// src: '/favicon-16x16.png',
// sizes: '16x16',
// type: 'image/png',
// purpose: 'any maskable',
// },
// {
// src: '/favicon-32x32.png',
// sizes: '32x32',
// type: 'image/png',
// purpose: 'any maskable',
// },
// {
// src: '/apple-touch-icon.png',
// sizes: '180x180',
// type: 'image/png',
// purpose: 'any maskable',
// },
// ],
// };
40 changes: 20 additions & 20 deletions code/client/src/pwa/pwa-config.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { injectConfig } from './inject-config.ts';
import { manifestConfig } from './manifest-config.ts';
import { VitePWAOptions } from 'vite-plugin-pwa';

export const pwaConfig: Partial<VitePWAOptions> = {
mode: 'development',
base: '/',
strategies: 'injectManifest',
srcDir: './src/pwa',
filename: 'sw.ts',
//injectRegister: false,
injectManifest: injectConfig,
registerType: 'autoUpdate',
manifest: manifestConfig,
devOptions: {
enabled: true,
navigateFallback: '../../index.html',
type: 'module',
},
};
// import { injectConfig } from './inject-config.ts';
// import { manifestConfig } from './manifest-config.ts';
// import { VitePWAOptions } from 'vite-plugin-pwa';
//
// export const pwaConfig: Partial<VitePWAOptions> = {
// mode: 'development',
// base: '/',
// strategies: 'injectManifest',
// srcDir: './src/pwa',
// filename: 'sw.ts',
// //injectRegister: false,
// injectManifest: injectConfig,
// registerType: 'autoUpdate',
// manifest: manifestConfig,
// devOptions: {
// enabled: true,
// navigateFallback: '../../index.html',
// type: 'module',
// },
// };
16 changes: 8 additions & 8 deletions code/client/src/pwa/sw.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { cleanupOutdatedCaches, precacheAndRoute } from 'workbox-precaching';

declare let self: ServiceWorkerGlobalScope;

precacheAndRoute(self.__WB_MANIFEST);

// this will clean up old caches that are not needed anymore
cleanupOutdatedCaches();
// import { cleanupOutdatedCaches, precacheAndRoute } from 'workbox-precaching';
//
// declare let self: ServiceWorkerGlobalScope;
//
// precacheAndRoute(self.__WB_MANIFEST);
//
// // this will clean up old caches that are not needed anymore
// cleanupOutdatedCaches();
12 changes: 6 additions & 6 deletions code/client/tests/editor/crdt/fugue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,18 +175,18 @@ describe('Fugue', () => {
const nodes = Array.from(fugue.traverseBySelection(selection));

// then
expect(nodes).toHaveLength(2);
expect(nodes.map(node => node.value).join('')).toEqual('ab');
expect(nodes).toHaveLength(3);
expect(nodes.map(node => node.value).join('')).toEqual('abc');
});

it('should return the nodes in the given selections', () => {
// given
const cursor: Cursor = { line: 0, column: 0 };
const line1 = 'abcdef';
const line2 = 'ghijkl';
const selection1: Selection = { start: { line: 0, column: 1 }, end: { line: 0, column: 3 } };
const selection2: Selection = { start: { line: 0, column: 3 }, end: { line: 0, column: 5 } };
const selection3: Selection = { start: { line: 0, column: 3 }, end: { line: 1, column: 4 } };
const selection1: Selection = { start: { line: 0, column: 1 }, end: { line: 0, column: 2 } };
const selection2: Selection = { start: { line: 0, column: 3 }, end: { line: 0, column: 4 } };
const selection3: Selection = { start: { line: 0, column: 3 }, end: { line: 1, column: 3 } };

// when
fugue.insertLocal(cursor, ...line1.split(''));
Expand All @@ -200,7 +200,7 @@ describe('Fugue', () => {
// then
expect(nodes1.map(node => node.value).join('')).toEqual('bc');
expect(nodes2.map(node => node.value).join('')).toEqual('de');
expect(nodes3.map(node => node.value).join('')).toEqual('def\nghij');
expect(nodes3.map(node => node.value).join('')).toEqual('defghij');
});

it('should return all nodes until the given separator', () => {
Expand Down
3 changes: 2 additions & 1 deletion code/client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{
"compilerOptions": {
"target": "ESNext",
"target": "ES2022",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"allowImportingTsExtensions": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
Expand Down
1 change: 1 addition & 0 deletions code/client/tsconfig.node.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"compilerOptions": {
"target": "es2022",
"composite": true,
"module": "esnext",
"moduleResolution": "nodenext",
Expand Down

0 comments on commit 517a143

Please sign in to comment.