Skip to content

Commit

Permalink
fix: update text styles
Browse files Browse the repository at this point in the history
  • Loading branch information
Jocs committed Nov 8, 2024
1 parent 1c44aa7 commit bed2074
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 73 deletions.
19 changes: 11 additions & 8 deletions packages/core/src/docs/data-model/text-x/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type { ICustomBlock, ICustomDecoration, ICustomRange, IDocumentBody, IPar
import type { IRetainAction } from './action-types';
import { UpdateDocsAttributeType } from '../../../shared/command-enum';
import { Tools } from '../../../shared/tools';
import { normalizeTextRuns } from './apply-utils/common';
import { coverTextRuns } from './apply-utils/update-apply';

export enum SliceBodyType {
Expand Down Expand Up @@ -65,14 +66,16 @@ export function getBodySlice(
}
}

docBody.textRuns = newTextRuns.map((tr) => {
const { st, ed } = tr;
return {
...tr,
st: st - startOffset,
ed: ed - startOffset,
};
});
docBody.textRuns = normalizeTextRuns(
newTextRuns.map((tr) => {
const { st, ed } = tr;
return {
...tr,
st: st - startOffset,
ed: ed - startOffset,
};
})
);
} else if (returnEmptyArray) {
// In the case of no style before, add the style, removeTextRuns will be empty,
// in this case, you need to add an empty textRun for undo.
Expand Down
118 changes: 77 additions & 41 deletions packages/docs-ui/src/commands/commands/inline-format.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ import type { ITextRangeWithStyle } from '@univerjs/engine-render';
import {
BaselineOffset, BooleanNumber, CommandType,
DOC_RANGE_TYPE,
getBodySlice,
ICommandService, IUniverInstanceService,
JSONX, MemoryCursor,
TextX, TextXActionType,
Tools,
UniverInstanceType,
} from '@univerjs/core';
import { DocSelectionManagerService, RichTextEditingMutation } from '@univerjs/docs';
Expand Down Expand Up @@ -255,6 +257,12 @@ export const SetInlineFormatCommand: ICommand<ISetInlineFormatCommandParams> = {
return false;
}

const body = docDataModel.getSelfOrHeaderFooterModel(segmentId).getBody();

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

const unitId = docDataModel.getUnitId();

let formatValue;
Expand All @@ -266,10 +274,16 @@ export const SetInlineFormatCommand: ICommand<ISetInlineFormatCommandParams> = {
case SetInlineFormatStrikethroughCommand.id: // fallthrough
case SetInlineFormatSubscriptCommand.id: // fallthrough
case SetInlineFormatSuperscriptCommand.id: {
const defaultStyle = docMenuStyleService.getDefaultStyle();
const curTextStyle = getStyleInTextRange(
body,
activeTextRange,
defaultStyle
);

formatValue = getReverseFormatValueInSelection(
docDataModel.getSelfOrHeaderFooterModel(segmentId).getBody()!.textRuns!,
preCommandId,
activeTextRange
curTextStyle,
preCommandId
);

break;
Expand Down Expand Up @@ -423,55 +437,77 @@ function getReverseFormatValue(ts: Nullable<ITextStyle>, key: keyof IStyleBase,
}
}

/**
* When clicking on a Bold menu item, you should un-bold if there is bold in the selections,
* or bold if there is no bold text. This method is used to get the reverse style value calculated
* from textRuns in the selection
*/
// eslint-disable-next-line complexity
export function getStyleInTextRange(
body: IDocumentBody,
textRange: ITextRangeWithStyle,
defaultStyle: ITextStyle
): ITextStyle {
const { startOffset, endOffset, collapsed } = textRange;

function getReverseFormatValueInSelection(
textRuns: ITextRun[],
preCommandId: string,
activeTextRange: ITextRangeWithStyle
): BooleanNumber | ITextDecoration | BaselineOffset {
const key: keyof IStyleBase = COMMAND_ID_TO_FORMAT_KEY_MAP[preCommandId];
const { startOffset, endOffset, collapsed } = activeTextRange;
if (collapsed) {
const textRuns = body.textRuns ?? [];
let textRun: Nullable<ITextRun> = null;

let textRun;

for (let i = textRuns.length - 1; i >= 0; i--) {
const curTextRun = textRuns[i];
if (collapsed) {
for (let i = textRuns.length - 1; i >= 0; i--) {
const curTextRun = textRuns[i];
if (curTextRun.st < startOffset && startOffset <= curTextRun.ed) {
textRun = curTextRun;
break;
}
} else {
if (curTextRun.st <= startOffset && endOffset <= curTextRun.ed) {
textRun = curTextRun;
break;
}
}

return textRun?.ts ? { ...defaultStyle, ...textRun.ts } : defaultStyle;
}

if (textRun) {
const { ts } = textRun;
const reverseValue = getReverseFormatValue(ts, key, preCommandId);
const { textRuns = [] } = getBodySlice(body, startOffset, endOffset);

const style = Tools.deepClone(defaultStyle);

// Get the min font size in range.
style.fs = Math.max(style.fs!, ...textRuns.map((t) => t?.ts?.fs ?? style.fs!));
style.ff = textRuns.find((t) => t.ts?.ff != null)?.ts?.ff ?? style.ff;
style.it = textRuns.length && textRuns.every((t) => t.ts?.it === BooleanNumber.TRUE) ? BooleanNumber.TRUE : BooleanNumber.FALSE;
style.bl = textRuns.length && textRuns.every((t) => t.ts?.bl === BooleanNumber.TRUE) ? BooleanNumber.TRUE : BooleanNumber.FALSE;
style.ul = textRuns.length && textRuns.every((t) => t.ts?.ul?.s === BooleanNumber.TRUE) ? textRuns[0].ts?.ul : style.ul;
style.st = textRuns.length && textRuns.every((t) => t.ts?.st?.s === BooleanNumber.TRUE) ? textRuns[0].ts?.st : style.st;
style.bg = textRuns.find((t) => t.ts?.bg != null)?.ts?.bg ?? style.bg;
style.cl = textRuns.find((t) => t.ts?.cl != null)?.ts?.cl ?? style.cl;

if (reverseValue !== undefined) {
return reverseValue;
const vas = textRuns.filter((t) => t?.ts?.va != null);

if (vas.length > 0 && vas.length === textRuns.length) {
const va = vas[0].ts?.va;
let isSame = true;

for (let i = 1; i < vas.length; i++) {
if (vas[i].ts?.va !== va) {
isSame = false;
break;
}
}
}

if (/bl|it/.test(key)) {
return BooleanNumber.TRUE;
} else if (/ul|st/.test(key)) {
return {
s: BooleanNumber.TRUE,
};
} else {
return preCommandId === SetInlineFormatSubscriptCommand.id
? BaselineOffset.SUBSCRIPT
: BaselineOffset.SUPERSCRIPT;
if (isSame) {
style.va = va;
}
}

return style;
}

/**
* When clicking on a Bold menu item, you should un-bold if there is bold in the selections,
* or bold if there is no bold text. This method is used to get the reverse style value calculated
* from textRuns in the selection
*/

function getReverseFormatValueInSelection(
textStyle: ITextStyle,
preCommandId: string
): BooleanNumber | ITextDecoration | BaselineOffset {
const key: keyof IStyleBase = COMMAND_ID_TO_FORMAT_KEY_MAP[preCommandId];

const reverseValue = getReverseFormatValue(textStyle, key, preCommandId)!;

return reverseValue;
}
30 changes: 6 additions & 24 deletions packages/docs-ui/src/controllers/menu/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import {

import { combineLatest, map, Observable } from 'rxjs';
import { OpenHeaderFooterPanelCommand } from '../../commands/commands/doc-header-footer.command';
import { ResetInlineFormatTextBackgroundColorCommand, SetInlineFormatBoldCommand, SetInlineFormatCommand, SetInlineFormatFontFamilyCommand, SetInlineFormatFontSizeCommand, SetInlineFormatItalicCommand, SetInlineFormatStrikethroughCommand, SetInlineFormatSubscriptCommand, SetInlineFormatSuperscriptCommand, SetInlineFormatTextBackgroundColorCommand, SetInlineFormatTextColorCommand, SetInlineFormatUnderlineCommand } from '../../commands/commands/inline-format.command';
import { getStyleInTextRange, ResetInlineFormatTextBackgroundColorCommand, SetInlineFormatBoldCommand, SetInlineFormatCommand, SetInlineFormatFontFamilyCommand, SetInlineFormatFontSizeCommand, SetInlineFormatItalicCommand, SetInlineFormatStrikethroughCommand, SetInlineFormatSubscriptCommand, SetInlineFormatSuperscriptCommand, SetInlineFormatTextBackgroundColorCommand, SetInlineFormatTextColorCommand, SetInlineFormatUnderlineCommand } from '../../commands/commands/inline-format.command';
import { BulletListCommand, CheckListCommand, getParagraphsInRange, OrderListCommand } from '../../commands/commands/list.command';
import { AlignCenterCommand, AlignJustifyCommand, AlignLeftCommand, AlignOperationCommand, AlignRightCommand } from '../../commands/commands/paragraph-align.command';
import { SwitchDocModeCommand } from '../../commands/commands/switch-doc-mode.command';
Expand Down Expand Up @@ -939,11 +939,10 @@ function getFontStyleAtCursor(accessor: IAccessor) {
};
}

const { startOffset, endOffset, collapsed, segmentId } = activeTextRange;
const { segmentId } = activeTextRange;
const body = docDataModel.getSelfOrHeaderFooterModel(segmentId).getBody();

const textRuns = docDataModel.getSelfOrHeaderFooterModel(segmentId).getBody()?.textRuns;

if (textRuns == null) {
if (body == null) {
return {
ts: {
...defaultTextStyle,
Expand All @@ -952,28 +951,11 @@ function getFontStyleAtCursor(accessor: IAccessor) {
};
}

let textRun;

for (let i = textRuns.length - 1; i >= 0; i--) {
const curTextRun = textRuns[i];
if (collapsed) {
if (curTextRun.st < startOffset && startOffset <= curTextRun.ed) {
textRun = curTextRun;
break;
}
} else {
if (curTextRun.st <= startOffset && endOffset <= curTextRun.ed) {
textRun = curTextRun;
break;
}
}
}
const curTextStyle = getStyleInTextRange(body, activeTextRange, defaultTextStyle);

return {
...textRun,
ts: {
...defaultTextStyle,
...textRun?.ts,
...curTextStyle,
...cacheStyle,
},
};
Expand Down

0 comments on commit bed2074

Please sign in to comment.