Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable strict mode on "roosterjs-editor-plugins" - Phase 1 #1289

Merged
merged 11 commits into from
Oct 12, 2022
2 changes: 1 addition & 1 deletion packages/roosterjs-editor-core/lib/editor/Editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@ export default class Editor implements IEditor {
* @param name Name of the attribute
* @param value Value of the attribute
*/
public setEditorDomAttribute(name: string, value: string) {
public setEditorDomAttribute(name: string, value: string | null) {
if (value === null) {
this.getCore().contentDiv.removeAttribute(name);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ const specialCharacters = /[`!@#$%^&*()_+\=\[\]{};':"\\|,.<>\/?~]/;
* Automatically transform -- into hyphen, if typed between two words.
*/
export default class AutoFormat implements EditorPlugin {
private editor: IEditor;
private lastKeyTyped: string;
private editor: IEditor | null = null;
private lastKeyTyped: string | null = null;

/**
* Get a friendly name of this plugin
Expand Down Expand Up @@ -43,6 +43,9 @@ export default class AutoFormat implements EditorPlugin {
* @param event PluginEvent object
*/
onPluginEvent(event: PluginEvent) {
if (!this.editor) {
return;
}
if (
event.eventType === PluginEventType.ContentChanged ||
event.eventType === PluginEventType.MouseDown ||
Expand All @@ -65,26 +68,29 @@ export default class AutoFormat implements EditorPlugin {
keyTyped !== '-'
) {
const searcher = this.editor.getContentSearcherOfCursor(event);
const textBeforeCursor = searcher.getSubStringBefore(3);
const dashes = searcher.getSubStringBefore(2);
const isPrecededByADash = textBeforeCursor[0] === '-';
const isPrecededByASpace = textBeforeCursor[0] === ' ';
const textBeforeCursor = searcher?.getSubStringBefore(3);
const dashes = searcher?.getSubStringBefore(2);
const isPrecededByADash = textBeforeCursor?.[0] === '-';
const isPrecededByASpace = textBeforeCursor?.[0] === ' ';
if (
isPrecededByADash ||
isPrecededByASpace ||
specialCharacters.test(textBeforeCursor[0]) ||
(typeof textBeforeCursor === 'string' &&
specialCharacters.test(textBeforeCursor[0])) ||
dashes !== '--'
) {
return;
}

const textRange = searcher.getRangeFromText(dashes, true /* exactMatch */);
const textRange = searcher?.getRangeFromText(dashes, true /* exactMatch */);
const nodeHyphen = document.createTextNode('—');
this.editor.addUndoSnapshot(
() => {
textRange.deleteContents();
textRange.insertNode(nodeHyphen);
this.editor.select(nodeHyphen, PositionType.End);
if (textRange) {
textRange.deleteContents();
textRange.insertNode(nodeHyphen);
this.editor!.select(nodeHyphen, PositionType.End);
}
},
ChangeSource.Format /*changeSource*/,
true /*canUndoByBackspace*/,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"strict": true
},
"extends": "../../../../tsconfig.json",
"include": ["./**/*.ts"],
"references": [{ "path": "../../../../roosterjs-editor-types/tsconfig.child.json" }]
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ export interface ContextMenuOptions<T> {
* An editor plugin that support showing a context menu using render() function from options parameter
*/
export default class ContextMenu<T> implements EditorPlugin {
private container: HTMLElement;
private editor: IEditor;
private isMenuShowing: boolean;
private container: HTMLElement | null = null;
private editor: IEditor | null = null;
private isMenuShowing: boolean = false;

/**
* Create a new instance of ContextMenu class
Expand Down Expand Up @@ -68,7 +68,7 @@ export default class ContextMenu<T> implements EditorPlugin {
dispose() {
this.onDismiss();

if (this.container) {
if (this.container?.parentNode) {
this.container.parentNode.removeChild(this.container);
this.container = null;
}
Expand All @@ -89,22 +89,24 @@ export default class ContextMenu<T> implements EditorPlugin {
rawEvent.preventDefault();
}

this.initContainer(rawEvent.pageX, rawEvent.pageY);
this.options.render(this.container, items as T[], this.onDismiss);
this.isMenuShowing = true;
if (this.initContainer(rawEvent.pageX, rawEvent.pageY)) {
this.options.render(this.container!, items as T[], this.onDismiss);
this.isMenuShowing = true;
}
}
}

private initContainer(x: number, y: number) {
if (!this.container) {
if (!this.container && this.editor) {
this.container = createElement(
KnownCreateElementDataIndex.ContextMenuWrapper,
this.editor.getDocument()
) as HTMLElement;
this.editor.getDocument().body.appendChild(this.container);
}
this.container.style.left = x + 'px';
this.container.style.top = y + 'px';
this.container?.style.setProperty('left', x + 'px');
this.container?.style.setProperty('top', y + 'px');
return !!this.container;
}

private onDismiss = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"strict": true
},
"extends": "../../../../tsconfig.json",
"include": ["./**/*.ts"],
"references": [
{ "path": "../../../../roosterjs-editor-dom/tsconfig.child.json" },
{ "path": "../../../../roosterjs-editor-types/tsconfig.child.json" }
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ const defaultReplacements: CustomReplacement[] = [
* content edit feature
*/
export default class CustomReplacePlugin implements EditorPlugin {
private longestReplacementLength: number;
private editor: IEditor;
private replacements: CustomReplacement[];
private replacementEndCharacters: Set<string>;
private longestReplacementLength: number | null = null;
private editor: IEditor | null = null;
private replacements: CustomReplacement[] | null = null;
private replacementEndCharacters: Set<string> | null = null;

/**
* Create instance of CustomReplace plugin
Expand Down Expand Up @@ -86,33 +86,29 @@ export default class CustomReplacePlugin implements EditorPlugin {
* @param event PluginEvent object
*/
public onPluginEvent(event: PluginEvent) {
if (event.eventType != PluginEventType.Input || this.editor.isInIME()) {
if (event.eventType != PluginEventType.Input || !this.editor || this.editor.isInIME()) {
return;
}

// Exit early on input events that do not insert a replacement's final character.
if (!event.rawEvent.data || !this.replacementEndCharacters.has(event.rawEvent.data)) {
if (!event.rawEvent.data || !this.replacementEndCharacters?.has(event.rawEvent.data)) {
return;
}

// Get the matching replacement
const range = this.editor.getSelectionRange();
if (range == null) {
const searcher = this.editor.getContentSearcherOfCursor(event);
if (!searcher || this.longestReplacementLength == null) {
return;
}

const searcher = this.editor.getContentSearcherOfCursor(event);
const stringToSearch = searcher.getSubStringBefore(this.longestReplacementLength);
const sourceEditor = this.editor;

const replacement = this.getMatchingReplacement(stringToSearch);
if (replacement == null) {
return;
}

if (
replacement.shouldReplace &&
!replacement.shouldReplace(replacement, searcher.getWordBefore(), sourceEditor)
!replacement ||
(replacement.shouldReplace &&
searcher &&
!replacement.shouldReplace(replacement, searcher.getWordBefore(), this.editor))
) {
return;
}
Expand All @@ -130,19 +126,21 @@ export default class CustomReplacePlugin implements EditorPlugin {
parsingSpan.childNodes.length == 1 ? parsingSpan.childNodes[0] : parsingSpan;

// Switch the node for the selection range
this.editor.addUndoSnapshot(
() => {
matchingRange.deleteContents();
matchingRange.insertNode(nodeToInsert);
this.editor.select(nodeToInsert, PositionType.End);
},
null /*changeSource*/,
true /*canUndoByBackspace*/
);
if (matchingRange) {
this.editor.addUndoSnapshot(
() => {
matchingRange.deleteContents();
matchingRange.insertNode(nodeToInsert);
this.editor?.select(nodeToInsert, PositionType.End);
},
undefined /*changeSource*/,
true /*canUndoByBackspace*/
);
}
}

private getMatchingReplacement(stringToSearch: string): CustomReplacement | null {
if (stringToSearch.length == 0) {
if (stringToSearch.length == 0 || !this.replacements) {
return null;
}
const originalStringToSearch = stringToSearch.replace(/\s/g, ' ');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"strict": true
},
"extends": "../../../../tsconfig.json",
"include": ["./**/*.ts"],
"references": [{ "path": "../../../../roosterjs-editor-types/tsconfig.child.json" }]
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import type { CompatibleChangeSource } from 'roosterjs-editor-types/lib/compatib
* Maintain list numbers of list chain when content is modified by cut/paste/drag&drop
*/
export default class CutPasteListChain implements EditorPlugin {
private chains: VListChain[];
private expectedChangeSource: ChangeSource | CompatibleChangeSource;
private editor: IEditor;
private disposer: () => void;
private chains: VListChain[] | null = null;
private expectedChangeSource: ChangeSource | CompatibleChangeSource | null = null;
private editor: IEditor | null = null;
private disposer: (() => void) | null = null;

/**
* Get a friendly name of this plugin
Expand Down Expand Up @@ -60,7 +60,12 @@ export default class CutPasteListChain implements EditorPlugin {
break;

case PluginEventType.ContentChanged:
if (this.chains?.length > 0 && this.expectedChangeSource == event.source) {
if (
this.chains &&
this.chains.length > 0 &&
this.expectedChangeSource == event.source &&
this.editor
) {
commitListChains(this.editor, this.chains);
this.chains = null;
this.expectedChangeSource = null;
Expand All @@ -74,7 +79,10 @@ export default class CutPasteListChain implements EditorPlugin {
};

private cacheListChains(source: ChangeSource) {
this.chains = VListChain.createListChains(this.editor.getSelectedRegions());
this.expectedChangeSource = source;
const selectedRegions = this.editor?.getSelectedRegions();
if (selectedRegions) {
this.chains = VListChain.createListChains(selectedRegions);
this.expectedChangeSource = source;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"strict": true
},
"extends": "../../../../tsconfig.json",
"include": ["./**/*.ts"],
"references": [
{ "path": "../../../../roosterjs-editor-types/tsconfig.child.json" },
{ "path": "../../../../roosterjs-editor-api/tsconfig.child.json" }
]
}
Loading