Skip to content

Commit

Permalink
refactor: refactor span to glyph (#1611)
Browse files Browse the repository at this point in the history
* refactor: refactor span to glyph

* refactor: rename span to glyph

* refactor: fix some lint warning

* refactor: add isJustifiable and adjustability to glyph

* refactor: add isJustifiable and adjustability to glyph

* fix: span to glyph

* test: add test cases for baseAdjustability
  • Loading branch information
Jocs authored Mar 18, 2024
1 parent e4231eb commit 7fb6d35
Show file tree
Hide file tree
Showing 27 changed files with 762 additions and 625 deletions.
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"commentTranslate.hover.enabled": true,
"commentTranslate.source": "Google",
"cSpell.words": [
"adjustability",
"Bandings",
"Catmull",
"clazz",
Expand Down Expand Up @@ -51,6 +52,7 @@
"Lerp",
"linebreak",
"linebreaker",
"linebreaking",
"Liti",
"localforage",
"LRTBV",
Expand All @@ -61,12 +63,15 @@
"numfmt",
"Overlines",
"Pacifico",
"Plass",
"pnmp",
"ponyfill",
"PWDEBUG",
"Quan",
"redi",
"shrinkability",
"Sider",
"strechability",
"SUMIF",
"SUMIFS",
"Tahoma",
Expand Down
13 changes: 5 additions & 8 deletions packages/docs/src/commands/commands/delete.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@ import type { ICommand, IDocumentBody, IMutationInfo, IParagraph, ITextRun } fro
import {
CommandType,
ICommandService,
IUndoRedoService,
IUniverInstanceService,
TextX,
TextXActionType,
UpdateDocsAttributeType,
} from '@univerjs/core';
import type { IActiveTextRange, ITextRangeWithStyle, TextRange } from '@univerjs/engine-render';
import { getParagraphBySpan, hasListSpan, isFirstSpan, isIndentBySpan } from '@univerjs/engine-render';
import { getParagraphByGlyph, hasListGlyph, type IActiveTextRange, isFirstGlyph, isIndentByGlyph, type ITextRangeWithStyle, type TextRange } from '@univerjs/engine-render';

import { DocSkeletonManagerService } from '../../services/doc-skeleton-manager.service';
import type { ITextActiveRange } from '../../services/text-selection-manager.service';
Expand Down Expand Up @@ -64,20 +62,20 @@ export const DeleteLeftCommand: ICommand = {
const preSpan = skeleton.findNodeByCharIndex(startOffset);

// is in bullet list?
const preIsBullet = hasListSpan(preSpan);
const preIsBullet = hasListGlyph(preSpan);
// is in indented paragraph?
const preIsIndent = isIndentBySpan(preSpan, docDataModel.getBody());
const preIsIndent = isIndentByGlyph(preSpan, docDataModel.getBody());

let cursor = startOffset;

// Get the deleted span. It maybe null or undefined when the preSpan is first span in skeleton.
const span = skeleton.findNodeByCharIndex(startOffset - 1);

const isUpdateParagraph =
isFirstSpan(preSpan) && span !== preSpan && (preIsBullet === true || preIsIndent === true);
isFirstGlyph(preSpan) && span !== preSpan && (preIsBullet === true || preIsIndent === true);

if (isUpdateParagraph) {
const paragraph = getParagraphBySpan(preSpan, docDataModel.getBody());
const paragraph = getParagraphByGlyph(preSpan, docDataModel.getBody());

if (paragraph == null) {
return false;
Expand Down Expand Up @@ -264,7 +262,6 @@ export const MergeTwoParagraphCommand: ICommand<IMergeTwoParagraphParams> = {
const textSelectionManagerService = accessor.get(TextSelectionManagerService);
const currentUniverService = accessor.get(IUniverInstanceService);
const commandService = accessor.get(ICommandService);
const undoRedoService = accessor.get(IUndoRedoService);

const { direction, range } = params;

Expand Down
32 changes: 16 additions & 16 deletions packages/docs/src/controllers/move-cursor.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import {
} from '@univerjs/core';
import type {
DocumentSkeleton,
IDocumentSkeletonGlyph,
IDocumentSkeletonLine,
IDocumentSkeletonSpan,
INodePosition,
INodeSearch,
} from '@univerjs/engine-render';
Expand Down Expand Up @@ -294,16 +294,16 @@ export class MoveCursorController extends Disposable {

private _getTopOrBottomPosition(
docSkeleton: DocumentSkeleton,
span: Nullable<IDocumentSkeletonSpan>,
glyph: Nullable<IDocumentSkeletonGlyph>,
direction: boolean
): Nullable<INodePosition> {
if (span == null) {
if (glyph == null) {
return;
}

const offsetLeft = this._getSpanLeftOffsetInLine(span);
const offsetLeft = this._getSpanLeftOffsetInLine(glyph);

const line = this._getNextOrPrevLine(span, direction);
const line = this._getNextOrPrevLine(glyph, direction);

if (line == null) {
return;
Expand All @@ -319,16 +319,16 @@ export class MoveCursorController extends Disposable {
return { ...position, isBack: true };
}

private _getSpanLeftOffsetInLine(span: IDocumentSkeletonSpan) {
const divide = span.parent;
private _getSpanLeftOffsetInLine(glyph: IDocumentSkeletonGlyph) {
const divide = glyph.parent;

if (divide == null) {
return Number.NEGATIVE_INFINITY;
}

const divideLeft = divide.left;

const { left } = span;
const { left } = glyph;

const start = divideLeft + left;

Expand All @@ -337,7 +337,7 @@ export class MoveCursorController extends Disposable {

private _matchPositionByLeftOffset(docSkeleton: DocumentSkeleton, line: IDocumentSkeletonLine, offsetLeft: number) {
const nearestNode: {
span?: IDocumentSkeletonSpan;
glyph?: IDocumentSkeletonGlyph;
distance: number;
} = {
distance: Number.POSITIVE_INFINITY,
Expand All @@ -346,28 +346,28 @@ export class MoveCursorController extends Disposable {
for (const divide of line.divides) {
const divideLeft = divide.left;

for (const span of divide.spanGroup) {
const { left } = span;
for (const glyph of divide.glyphGroup) {
const { left } = glyph;
const leftSide = divideLeft + left;

const distance = Math.abs(offsetLeft - leftSide);

if (distance < nearestNode.distance) {
nearestNode.span = span;
nearestNode.glyph = glyph;
nearestNode.distance = distance;
}
}
}

if (nearestNode.span == null) {
if (nearestNode.glyph == null) {
return;
}

return docSkeleton.findPositionBySpan(nearestNode.span);
return docSkeleton.findPositionByGlyph(nearestNode.glyph);
}

private _getNextOrPrevLine(span: IDocumentSkeletonSpan, direction: boolean) {
const divide = span.parent;
private _getNextOrPrevLine(glyph: IDocumentSkeletonGlyph, direction: boolean) {
const divide = glyph.parent;
if (divide == null) {
return;
}
Expand Down
66 changes: 33 additions & 33 deletions packages/engine-render/src/basics/document-node-tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@
import type { IDocumentBody, Nullable } from '@univerjs/core';
import { checkParagraphHasIndentByStyle, DataStreamTreeTokenType } from '@univerjs/core';

import type { IDocumentSkeletonSpan } from './i-document-skeleton-cached';
import { SpanType } from './i-document-skeleton-cached';
import type { IDocumentSkeletonGlyph } from './i-document-skeleton-cached';
import { GlyphType } from './i-document-skeleton-cached';

export function hasListSpan(span: Nullable<IDocumentSkeletonSpan>) {
const divide = span?.parent;
export function hasListGlyph(glyph: Nullable<IDocumentSkeletonGlyph>) {
const divide = glyph?.parent;

if (divide == null) {
return false;
}

const spanGroup = divide.spanGroup;
const glyphGroup = divide.glyphGroup;

return spanGroup[0]?.spanType === SpanType.LIST;
return glyphGroup[0]?.glyphType === GlyphType.LIST;
}

export function isIndentBySpan(span: Nullable<IDocumentSkeletonSpan>, body?: IDocumentBody) {
const paragraph = getParagraphBySpan(span, body);
export function isIndentByGlyph(glyph: Nullable<IDocumentSkeletonGlyph>, body?: IDocumentBody) {
const paragraph = getParagraphByGlyph(glyph, body);
if (paragraph == null) {
return false;
}
Expand All @@ -46,54 +46,54 @@ export function isIndentBySpan(span: Nullable<IDocumentSkeletonSpan>, body?: IDo
return checkParagraphHasIndentByStyle(paragraphStyle);
}

export function isLastSpan(span: Nullable<IDocumentSkeletonSpan>) {
const divide = span?.parent;
export function isLastGlyph(glyph: Nullable<IDocumentSkeletonGlyph>) {
const divide = glyph?.parent;

const line = divide?.parent;

const spanGroup = divide?.spanGroup;
const glyphGroup = divide?.glyphGroup;

const divides = line?.divides;

if (spanGroup && span && divides && divide) {
const spanIndex = spanGroup.indexOf(span);
if (glyphGroup && glyph && divides && divide) {
const glyphIndex = glyphGroup.indexOf(glyph);
const divideIndex = divides.indexOf(divide);

if (divideIndex === divides.length - 1 && spanIndex === spanGroup.length - 1) {
if (divideIndex === divides.length - 1 && glyphIndex === glyphGroup.length - 1) {
return true;
}
}

return false;
}

export function isFirstSpan(span: Nullable<IDocumentSkeletonSpan>) {
const divide = span?.parent;
export function isFirstGlyph(glyph: Nullable<IDocumentSkeletonGlyph>) {
const divide = glyph?.parent;

const line = divide?.parent;

const spanGroup = divide?.spanGroup;
const glyphGroup = divide?.glyphGroup;

const divides = line?.divides;

if (spanGroup && span && divides && divide) {
const spanIndex = spanGroup.indexOf(span);
if (glyphGroup && glyph && divides && divide) {
const glyphIndex = glyphGroup.indexOf(glyph);
const divideIndex = divides.indexOf(divide);

if (divideIndex === 0 && spanIndex === 0) {
if (divideIndex === 0 && glyphIndex === 0) {
return true;
}

if (divideIndex === 0 && spanIndex === 1 && spanGroup[0].spanType === SpanType.LIST) {
if (divideIndex === 0 && glyphIndex === 1 && glyphGroup[0].glyphType === GlyphType.LIST) {
return true;
}
}

return false;
}

export function getParagraphBySpan(span: Nullable<IDocumentSkeletonSpan>, body?: IDocumentBody) {
const line = span?.parent?.parent;
export function getParagraphByGlyph(glyph: Nullable<IDocumentSkeletonGlyph>, body?: IDocumentBody) {
const line = glyph?.parent?.parent;
if (line == null || body == null) {
return;
}
Expand All @@ -110,39 +110,39 @@ export function getParagraphBySpan(span: Nullable<IDocumentSkeletonSpan>, body?:
}
}

export function isPlaceholderOrSpace(span: Nullable<IDocumentSkeletonSpan>) {
if (span == null) {
export function isPlaceholderOrSpace(glyph: Nullable<IDocumentSkeletonGlyph>) {
if (glyph == null) {
return false;
}

if (
[DataStreamTreeTokenType.PARAGRAPH, DataStreamTreeTokenType.TAB, DataStreamTreeTokenType.SECTION_BREAK].indexOf(
span.streamType
glyph.streamType
) !== -1 ||
span.content === DataStreamTreeTokenType.SPACE
glyph.content === DataStreamTreeTokenType.SPACE
) {
return true;
}

return false;
}

export function isSameLine(span1: Nullable<IDocumentSkeletonSpan>, span2: Nullable<IDocumentSkeletonSpan>) {
if (span1 == null) {
export function isSameLine(glyph1: Nullable<IDocumentSkeletonGlyph>, glyph2: Nullable<IDocumentSkeletonGlyph>) {
if (glyph1 == null) {
return false;
}

if (span2 == null) {
if (glyph2 == null) {
return false;
}

if (span1.parent == null) {
if (glyph1.parent == null) {
return false;
}

if (span2.parent == null) {
if (glyph2.parent == null) {
return false;
}

return span1.parent.parent === span2.parent.parent;
return glyph1.parent.parent === glyph2.parent.parent;
}
Loading

0 comments on commit 7fb6d35

Please sign in to comment.