Skip to content

Commit

Permalink
Fix some perf issue and some other changes (#272)
Browse files Browse the repository at this point in the history
* 45000

* 7.2.6
  • Loading branch information
JiuqingSong authored Mar 13, 2019
1 parent 7675a3c commit 60aa561
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 70 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "roosterjs",
"version": "7.2.5",
"version": "7.2.6",
"description": "Framework-independent javascript editor",
"repository": {
"type": "git",
Expand Down
104 changes: 80 additions & 24 deletions packages/roosterjs-editor-api/lib/format/getFormatState.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,101 @@
import { cacheGetElementAtCursor, Editor } from 'roosterjs-editor-core';
import { DocumentCommand, FormatState, PluginEvent, QueryScope } from 'roosterjs-editor-types';
import { getComputedStyles, getTagOfNode, Position } from 'roosterjs-editor-dom';
import {
DocumentCommand,
ElementBasedFormatState,
FormatState,
PendableFormatState,
PluginEvent,
QueryScope,
StyleBasedFormatState,
} from 'roosterjs-editor-types';

type PendableFormatNames = keyof PendableFormatState;

const PendableFormatCommandMap: { [key in PendableFormatNames]: DocumentCommand } = {
isBold: DocumentCommand.Bold,
isItalic: DocumentCommand.Italic,
isUnderline: DocumentCommand.Underline,
isStrikeThrough: DocumentCommand.StrikeThrough,
isSubscript: DocumentCommand.Subscript,
isSuperscript: DocumentCommand.Superscript,
};

/**
* Get format state at cursor
* A format state is a collection of all format related states, e.g.,
* bold, italic, underline, font name, font size, etc.
* @param editor The editor
* @param (Optional) The plugin event, it stores the event cached data for looking up.
* Get Pendable Format State at cursor.
* @param document The HTML Document to get format state from
* @returns A PendableFormatState object which contains the values of pendable format states
*/
export function getPendableFormatState(document: Document): PendableFormatState {
let keys = Object.keys(PendableFormatCommandMap) as PendableFormatNames[];

return keys.reduce(
(state, key) => {
state[key] = document.queryCommandState(PendableFormatCommandMap[key]);
return state;
},
<PendableFormatState>{}
);
}

/**
* Get element based Format State at cursor
* @param editor The editor instance
* @param event (Optional) The plugin event, it stores the event cached data for looking up.
* In this function the event cache is used to get list state and header level. If not passed,
* it will query the node within selection to get the info
* @returns The format state at cursor
* @returns An ElementBasedFormatState object
*/
export default function getFormatState(editor: Editor, event?: PluginEvent): FormatState {
let range = editor.getSelectionRange();
let node = range && Position.getStart(range).normalize().node;
let styles = node ? getComputedStyles(node) : [];
export function getElementBasedFormatState(
editor: Editor,
event?: PluginEvent
): ElementBasedFormatState {
let listTag = getTagOfNode(cacheGetElementAtCursor(editor, event, 'OL,UL'));
let headerTag = getTagOfNode(cacheGetElementAtCursor(editor, event, 'H1,H2,H3,H4,H5,H6'));
let document = editor.getDocument();
return {
fontName: styles[0],
fontSize: styles[1],
textColor: styles[2],
backgroundColor: styles[3],

isBold: document.queryCommandState(DocumentCommand.Bold),
isItalic: document.queryCommandState(DocumentCommand.Italic),
isUnderline: document.queryCommandState(DocumentCommand.Underline),
isStrikeThrough: document.queryCommandState(DocumentCommand.StrikeThrough),
isSubscript: document.queryCommandState(DocumentCommand.Subscript),
isSuperscript: document.queryCommandState(DocumentCommand.Superscript),

return {
isBullet: listTag == 'UL',
isNumbering: listTag == 'OL',
headerLevel: (headerTag && parseInt(headerTag[1])) || 0,

canUnlink: !!editor.queryElements('a[href]', QueryScope.OnSelection)[0],
canAddImageAltText: !!editor.queryElements('img', QueryScope.OnSelection)[0],
isBlockQuote: !!editor.queryElements('blockquote', QueryScope.OnSelection)[0],
};
}

/**
* Get style based Format State at cursor
* @param editor The editor instance
* @returns A StyleBasedFormatState object
*/
export function getStyleBasedFormatState(editor: Editor): StyleBasedFormatState {
let range = editor.getSelectionRange();
let node = range && Position.getStart(range).normalize().node;
let styles = node ? getComputedStyles(node) : [];
return {
fontName: styles[0],
fontSize: styles[1],
textColor: styles[2],
backgroundColor: styles[3],
};
}

/**
* Get format state at cursor
* A format state is a collection of all format related states, e.g.,
* bold, italic, underline, font name, font size, etc.
* @param editor The editor instance
* @param event (Optional) The plugin event, it stores the event cached data for looking up.
* In this function the event cache is used to get list state and header level. If not passed,
* it will query the node within selection to get the info
* @returns The format state at cursor
*/
export default function getFormatState(editor: Editor, event?: PluginEvent): FormatState {
return {
...getPendableFormatState(editor.getDocument()),
...getElementBasedFormatState(editor, event),
...getStyleBasedFormatState(editor),
canUndo: editor.canUndo(),
canRedo: editor.canRedo(),
};
Expand Down
7 changes: 6 additions & 1 deletion packages/roosterjs-editor-api/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ export {
} from './format/clearBlockFormat';
export { default as clearFormat } from './format/clearFormat';
export { default as createLink } from './format/createLink';
export { default as getFormatState } from './format/getFormatState';
export {
default as getFormatState,
getPendableFormatState,
getElementBasedFormatState,
getStyleBasedFormatState,
} from './format/getFormatState';
export { default as insertImage } from './format/insertImage';
export { default as insertTable } from './table/insertTable';
export { default as editTable } from './table/editTable';
Expand Down
17 changes: 9 additions & 8 deletions packages/roosterjs-editor-core/lib/editor/createEditorCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,16 @@ function calcDefaultFormat(node: Node, baseFormat: DefaultFormat): DefaultFormat
}

baseFormat = baseFormat || <DefaultFormat>{};
let styles = getComputedStyles(node);
let { fontFamily, fontSize, textColor, backgroundColor, bold, italic, underline } = baseFormat;
let currentStyles = fontFamily && fontSize && textColor ? null : getComputedStyles(node);
return {
fontFamily: baseFormat.fontFamily || styles[0],
fontSize: baseFormat.fontSize || styles[1],
textColor: baseFormat.textColor || styles[2],
backgroundColor: baseFormat.backgroundColor || '',
bold: baseFormat.bold,
italic: baseFormat.italic,
underline: baseFormat.underline,
fontFamily: fontFamily || currentStyles[0],
fontSize: fontSize || currentStyles[1],
textColor: textColor || currentStyles[2],
backgroundColor: backgroundColor || '',
bold: bold,
italic: italic,
underline: underline,
};
}

Expand Down
14 changes: 12 additions & 2 deletions packages/roosterjs-editor-types/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,19 @@ export { default as BlockElement } from './interface/BlockElement';
export { default as ClipboardData } from './interface/ClipboardData';
export { default as ClipboardItems } from './interface/ClipboardItems';
export { default as DefaultFormat } from './interface/DefaultFormat';
export { default as FormatState } from './interface/FormatState';
export {
default as FormatState,
PendableFormatState,
ElementBasedFormatState,
StyleBasedFormatState,
} from './interface/FormatState';
export { default as InlineElement } from './interface/InlineElement';
export { default as InsertOption, InsertOptionBase, InsertOptionBasic, InsertOptionRange } from './interface/InsertOption';
export {
default as InsertOption,
InsertOptionBase,
InsertOptionBasic,
InsertOptionRange,
} from './interface/InsertOption';
export { default as LinkData } from './interface/LinkData';
export { default as NodePosition } from './interface/NodePosition';
export { default as Rect } from './interface/Rect';
Expand Down
90 changes: 57 additions & 33 deletions packages/roosterjs-editor-types/lib/interface/FormatState.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
/**
* The format state
* Format states that can have pending state.
*
* e.g., When using execCommand('bold') target to a collapsed selection, browser will enter bold state,
* but there isn't a &lt;B&gt; tag until user type something, or the state will be rollback if selection
* is changed.
*/
export default interface FormatState {
/**
* Font name
*/
fontName?: string;

/**
* Font size
*/
fontSize?: string;

export interface PendableFormatState {
/**
* Whether the text is bolded
*/
Expand All @@ -28,15 +22,25 @@ export default interface FormatState {
isUnderline?: boolean;

/**
* Background color
* Whether the text has strike through line
*/
backgroundColor?: string;
isStrikeThrough?: boolean;

/**
* Text color
* Whether the text is in subscript mode
*/
textColor?: string;
isSubscript?: boolean;

/**
* Whether the text is in superscript mode
*/
isSuperscript?: boolean;
}

/**
* Format state represented by DOM element
*/
export interface ElementBasedFormatState {
/**
* Whether the text is in bullet mode
*/
Expand All @@ -48,47 +52,67 @@ export default interface FormatState {
isNumbering?: boolean;

/**
* Whether the text has strike through line
* Whether the text is in block quote
*/
isStrikeThrough?: boolean;
isBlockQuote?: boolean;

/**
* Whether the text is in block quote
* Whether unlink command can be called to the text
*/
isBlockQuote?: boolean;
canUnlink?: boolean;

/**
* Whether the text is in subscript mode
* Whether add image alt text command can be called to the text
*/
isSubscript?: boolean;
canAddImageAltText?: boolean;

/**
* Whether the text is in superscript mode
* Header level (0-6, 0 means no header)
*/
isSuperscript?: boolean;
headerLevel?: number;
}

/**
* Format states represented by CSS style
*/
export interface StyleBasedFormatState {
/**
* Whether unlink command can be called to the text
* Font name
*/
canUnlink?: boolean;
fontName?: string;

/**
* Whether add image alt text command can be called to the text
* Font size
*/
canAddImageAltText?: boolean;
fontSize?: string;

/**
* Background color
*/
backgroundColor?: string;

/**
* Text color
*/
textColor?: string;
}

/**
* The format state
*/
export default interface FormatState
extends PendableFormatState,
ElementBasedFormatState,
StyleBasedFormatState {
/**
* @deprecated Use editor.canUndo() instead
* Whether the content can be undone
*/
canUndo?: boolean;

/**
* @deprecated Use editor.canRedo() instead
* Whether the content ca nbe redone
*/
canRedo?: boolean;

/**
* Header level (0-6, 0 means no header)
*/
headerLevel?: number;
}
2 changes: 1 addition & 1 deletion tools/dts.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ var singleLineComment = /\/\/[^\n]*\n/g;
var multiLineComment = /(^\/\*(\*(?!\/)|[^*])*\*\/\s*)/m;

// 1. [export ][default |declare ](class|interface) <NAME>[ extends| implements <BASECLASS>] {...}
var regClassInterface = /(\/\*(\*(?!\/)|[^*])*\*\/\s*)?(export\s+)?(default\s+|declare\s+)?(interface|class)\s+([a-zA-Z0-9_]+(\s*<[^>]+>)?)((\s+extends|\s+implements)(\s+[0-9a-zA-Z_\.]+(\s*<[^>]+>)?))?\s*{/g;
var regClassInterface = /(\/\*(\*(?!\/)|[^*])*\*\/\s*)?(export\s+)?(default\s+|declare\s+)?(interface|class)\s+([a-zA-Z0-9_]+(\s*<[^>]+>)?)((\s+extends|\s+implements)(\s[0-9a-zA-Z_\.\s,]+(\s*<[^>]+>)?))?\s*{/g;
// 2. [export ][default |declare ]function <NAME>(...)[: <TYPE>];
var regFunction = /(\/\*(\*(?!\/)|[^*])*\*\/\s*)?(export\s+)?(default\s+|declare\s+)?function\s+([a-zA-Z0-9_]+(\s*<[^>]+>)?)\s*(\([^;]+;)/g;
// 3. [export ][default |declare ]const enum <NAME> {...}
Expand Down

0 comments on commit 60aa561

Please sign in to comment.