Skip to content

Commit

Permalink
fix(docs): optimization of text selection (#3660)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jocs authored Oct 10, 2024
1 parent 16a08bf commit a2f2215
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
* limitations under the License.
*/

import { DocumentSkeletonPageType, getPageFromPath, GlyphType, Liquid } from '@univerjs/engine-render';
import type { IPosition, ITextRange, Nullable } from '@univerjs/core';
import type { DocumentSkeleton, IDocumentOffsetConfig, IDocumentSkeletonColumn, IDocumentSkeletonDivide, IDocumentSkeletonGlyph, IDocumentSkeletonLine, IDocumentSkeletonPage, IDocumentSkeletonRow, IDocumentSkeletonSection, INodePosition, IPoint } from '@univerjs/engine-render';
import { DocumentSkeletonPageType, getPageFromPath, GlyphType, Liquid } from '@univerjs/engine-render';

export enum NodePositionStateType {
NORMAL,
Expand Down
4 changes: 2 additions & 2 deletions packages/docs-ui/src/services/selection/rect-range.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
* limitations under the License.
*/

import type { Documents, DocumentSkeleton, INodePosition, IPoint, ITextSelectionStyle, ThinScene } from '@univerjs/engine-render';
import type { IDocRange } from './range-interface';
import { COLORS, DOC_RANGE_TYPE, type Nullable, RANGE_DIRECTION, Rectangle, Tools } from '@univerjs/core';
import { getColor, NORMAL_TEXT_SELECTION_PLUGIN_STYLE, RegularPolygon } from '@univerjs/engine-render';
import type { Documents, DocumentSkeleton, INodePosition, IPoint, ITextSelectionStyle, ThinScene } from '@univerjs/engine-render';
import { compareNodePositionInTable, NodePositionConvertToRectRange } from './convert-rect-range';
import { TEXT_RANGE_LAYER_INDEX } from './text-range';
import type { IDocRange } from './range-interface';

const RECT_RANGE_KEY_PREFIX = '__DocTableRectRange__';
const ID_LENGTH = 6;
Expand Down
4 changes: 2 additions & 2 deletions packages/docs-ui/src/services/selection/selection-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@
* limitations under the License.
*/

import type { Documents, DocumentSkeleton, Engine, IDocumentSkeletonGlyph, INodePosition, IRectRangeWithStyle, ITextRangeWithStyle, ITextSelectionStyle, Scene } from '@univerjs/engine-render';
import type { IDocRange } from './range-interface';
import { type Nullable, RANGE_DIRECTION, Tools } from '@univerjs/core';
import { getOffsetRectForDom } from '@univerjs/engine-render';
import type { Documents, DocumentSkeleton, Engine, IDocumentSkeletonGlyph, INodePosition, IRectRangeWithStyle, ITextRangeWithStyle, ITextSelectionStyle, Scene } from '@univerjs/engine-render';
import { isInSameTableCell, isValidRectRange } from './convert-rect-range';
import { convertPositionsToRectRanges, RectRange } from './rect-range';
import { TextRange } from './text-range';
import type { IDocRange } from './range-interface';

interface IDocRangeList {
textRanges: TextRange[];
Expand Down
6 changes: 3 additions & 3 deletions packages/engine-render/src/components/docs/doc-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
* limitations under the License.
*/

import { RENDER_CLASS_TYPE } from '../../basics/const';
import type { IDocumentSkeletonGlyph, IDocumentSkeletonLine, IDocumentSkeletonPage } from '../../basics/i-document-skeleton-cached';
import { PageLayoutType } from '../../basics/i-document-skeleton-cached';
import type { IBoundRectNoAngle, IViewportInfo } from '../../basics/vector2';
import type { UniverRenderingContext } from '../../context';
import { RenderComponent } from '../component';
import type { DOCS_EXTENSION_TYPE } from './doc-extension';
import type { DocumentSkeleton } from './layout/doc-skeleton';
import { RENDER_CLASS_TYPE } from '../../basics/const';
import { PageLayoutType } from '../../basics/i-document-skeleton-cached';
import { RenderComponent } from '../component';

export interface IPageMarginLayout {
pageMarginLeft: number;
Expand Down
54 changes: 42 additions & 12 deletions packages/engine-render/src/components/docs/layout/doc-skeleton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -511,10 +511,11 @@ export class DocumentSkeleton extends Skeleton {

const { pages, skeHeaders, skeFooters } = skeletonData;
const editArea = this.findEditAreaByCoord(coord, pageLayoutType, pageMarginLeft, pageMarginTop).editArea;
const pageLength = pages.length;

this._findLiquid.reset();
if (restrictions == null) {
for (let pi = 0, len = pages.length; pi < len; pi++) {
for (let pi = 0; pi < pageLength; pi++) {
const page = pages[pi];
const { headerId, footerId, pageWidth } = page;

Expand All @@ -532,7 +533,8 @@ export class DocumentSkeleton extends Skeleton {
pi,
cache,
x,
y
y,
pageLength
);
}

Expand All @@ -547,7 +549,8 @@ export class DocumentSkeleton extends Skeleton {
pi,
cache,
x,
y
y,
pageLength
);
}
} else {
Expand All @@ -560,7 +563,8 @@ export class DocumentSkeleton extends Skeleton {
pi,
cache,
x,
y
y,
pageLength
);
}

Expand All @@ -575,7 +579,7 @@ export class DocumentSkeleton extends Skeleton {
let exactMatch = null;

if (strict === false) {
for (let pi = 0, len = pages.length; pi < len; pi++) {
for (let pi = 0; pi < pageLength; pi++) {
const page = pages[pi];
const { headerId, footerId, pageWidth } = page;

Expand All @@ -591,7 +595,8 @@ export class DocumentSkeleton extends Skeleton {
pi,
cache,
x,
y
y,
pageLength
);
}

Expand All @@ -606,7 +611,8 @@ export class DocumentSkeleton extends Skeleton {
pi,
cache,
x,
y
y,
pageLength
);
}
} else {
Expand All @@ -619,7 +625,8 @@ export class DocumentSkeleton extends Skeleton {
pi,
cache,
x,
y
y,
pageLength
);
}

Expand All @@ -630,7 +637,7 @@ export class DocumentSkeleton extends Skeleton {
this._translatePage(page, pageLayoutType, pageMarginLeft, pageMarginTop);
}
} else {
for (let pi = 0, len = pages.length; pi < len; pi++) {
for (let pi = 0; pi < pageLength; pi++) {
const page = pages[pi];

if (segmentId) {
Expand All @@ -651,7 +658,8 @@ export class DocumentSkeleton extends Skeleton {
segmentPage,
cache,
x,
y
y,
pageLength
);
}
} else {
Expand All @@ -664,7 +672,8 @@ export class DocumentSkeleton extends Skeleton {
pi,
cache,
x,
y
y,
pageLength
);
}

Expand All @@ -689,6 +698,7 @@ export class DocumentSkeleton extends Skeleton {
cache: INearestCache,
x: number,
y: number,
pageLength: number,
nestLevel: number = 0
// eslint-disable-next-line ts/no-explicit-any
): any {
Expand All @@ -700,11 +710,30 @@ export class DocumentSkeleton extends Skeleton {
const pageTop = this._findLiquid.y + (pageType === DocumentSkeletonPageType.FOOTER ? page.pageHeight - segmentPage.pageHeight : 0);
const pageBottom = pageTop + segmentPage.pageHeight;

const pointInPage = x >= pageLeft
let pointInPage = x >= pageLeft
&& x <= pageRight
&& y >= pageTop
&& y <= pageBottom;

// Handle the outmost page.
if (nestLevel === 0 && pageType === DocumentSkeletonPageType.BODY) {
const isFirstPage = pi === 0;
const isLastPage = pi === pageLength - 1;
// TODO: Use page margin top as page gap now, need to consider the page gap in the future.
const halfMarginTop = page.originMarginTop / 2;

// It's the only page, point always in page.
if (isFirstPage && isLastPage) {
pointInPage = true;
} else if (isFirstPage) {
pointInPage = y <= pageBottom + halfMarginTop;
} else if (isLastPage) {
pointInPage = y >= pageTop - halfMarginTop;
} else {
pointInPage = y >= pageTop - halfMarginTop && y <= pageBottom + halfMarginTop;
}
}

switch (pageType) {
case DocumentSkeletonPageType.HEADER: {
this._findLiquid.translatePagePadding({
Expand Down Expand Up @@ -877,6 +906,7 @@ export class DocumentSkeleton extends Skeleton {
cache,
x,
y,
pageLength,
nestLevel + 1
);

Expand Down

0 comments on commit a2f2215

Please sign in to comment.