* Improve typescript null checking in places * Iterate * Fix Timer.ts
This commit is contained in:
parent
97506cbcdb
commit
9743852380
43 changed files with 155 additions and 154 deletions
|
@ -32,7 +32,7 @@ export function setSelection(editor: HTMLDivElement, model: EditorModel, selecti
|
|||
}
|
||||
|
||||
function setDocumentRangeSelection(editor: HTMLDivElement, model: EditorModel, range: Range): void {
|
||||
const sel = document.getSelection();
|
||||
const sel = document.getSelection()!;
|
||||
sel.removeAllRanges();
|
||||
const selectionRange = document.createRange();
|
||||
const start = getNodeAndOffsetForPosition(editor, model, range.start);
|
||||
|
@ -50,7 +50,7 @@ export function setCaretPosition(editor: HTMLDivElement, model: EditorModel, car
|
|||
range.setStart(node, offset);
|
||||
range.collapse(true);
|
||||
|
||||
const sel = document.getSelection();
|
||||
const sel = document.getSelection()!;
|
||||
if (sel.rangeCount === 1) {
|
||||
const existingRange = sel.getRangeAt(0);
|
||||
if (
|
||||
|
@ -124,7 +124,7 @@ function findNodeInLineForPart(parts: Part[], partIndex: number): { lineIndex: n
|
|||
let lineIndex = 0;
|
||||
let nodeIndex = -1;
|
||||
|
||||
let prevPart = null;
|
||||
let prevPart: Part | undefined;
|
||||
// go through to parts up till (and including) the index
|
||||
// to find newline parts
|
||||
for (let i = 0; i <= partIndex; ++i) {
|
||||
|
@ -132,7 +132,7 @@ function findNodeInLineForPart(parts: Part[], partIndex: number): { lineIndex: n
|
|||
if (part.type === Type.Newline) {
|
||||
lineIndex += 1;
|
||||
nodeIndex = -1;
|
||||
prevPart = null;
|
||||
prevPart = undefined;
|
||||
} else {
|
||||
nodeIndex += 1;
|
||||
if (needsCaretNodeBefore(part, prevPart)) {
|
||||
|
|
|
@ -51,7 +51,7 @@ export function longestBacktickSequence(text: string): number {
|
|||
}
|
||||
|
||||
function isListChild(n: Node): boolean {
|
||||
return LIST_TYPES.includes(n.parentNode?.nodeName);
|
||||
return LIST_TYPES.includes(n.parentNode?.nodeName || "");
|
||||
}
|
||||
|
||||
function parseAtRoomMentions(text: string, pc: PartCreator, opts: IParseOptions): Part[] {
|
||||
|
|
|
@ -31,7 +31,7 @@ export default class HistoryManager {
|
|||
private newlyTypedCharCount = 0;
|
||||
private currentIndex = -1;
|
||||
private changedSinceLastPush = false;
|
||||
private lastCaret: Caret = null;
|
||||
private lastCaret: Caret | null = null;
|
||||
private nonWordBoundarySinceLastPush = false;
|
||||
private addedSinceLastPush = false;
|
||||
private removedSinceLastPush = false;
|
||||
|
@ -65,7 +65,7 @@ export default class HistoryManager {
|
|||
// as long as you've only been adding or removing since the last push
|
||||
if (this.addedSinceLastPush !== this.removedSinceLastPush) {
|
||||
// add steps by word boundary, up to MAX_STEP_LENGTH characters
|
||||
const str = diff.added ? diff.added : diff.removed;
|
||||
const str = diff.added ? diff.added : diff.removed!;
|
||||
const isWordBoundary = str === " " || str === "\t" || str === "\n";
|
||||
if (this.nonWordBoundarySinceLastPush && isWordBoundary) {
|
||||
return true;
|
||||
|
|
|
@ -51,13 +51,13 @@ type ManualTransformCallback = () => Caret;
|
|||
export default class EditorModel {
|
||||
private _parts: Part[];
|
||||
private readonly _partCreator: PartCreator;
|
||||
private activePartIdx: number = null;
|
||||
private _autoComplete: AutocompleteWrapperModel = null;
|
||||
private autoCompletePartIdx: number = null;
|
||||
private activePartIdx: number | null = null;
|
||||
private _autoComplete: AutocompleteWrapperModel | null = null;
|
||||
private autoCompletePartIdx: number | null = null;
|
||||
private autoCompletePartCount = 0;
|
||||
private transformCallback: TransformCallback = null;
|
||||
private transformCallback: TransformCallback | null = null;
|
||||
|
||||
public constructor(parts: Part[], partCreator: PartCreator, private updateCallback: UpdateCallback = null) {
|
||||
public constructor(parts: Part[], partCreator: PartCreator, private updateCallback: UpdateCallback | null = null) {
|
||||
this._parts = parts;
|
||||
this._partCreator = partCreator;
|
||||
this.transformCallback = null;
|
||||
|
|
|
@ -455,7 +455,7 @@ class AtRoomPillPart extends RoomPillPart {
|
|||
}
|
||||
|
||||
class UserPillPart extends PillPart {
|
||||
public constructor(userId, displayName, private member: RoomMember) {
|
||||
public constructor(userId, displayName, private member?: RoomMember) {
|
||||
super(userId, displayName);
|
||||
}
|
||||
|
||||
|
@ -625,7 +625,7 @@ export class PartCreator {
|
|||
|
||||
public userPill(displayName: string, userId: string): UserPillPart {
|
||||
const member = this.room.getMember(userId);
|
||||
return new UserPillPart(userId, displayName, member);
|
||||
return new UserPillPart(userId, displayName, member || undefined);
|
||||
}
|
||||
|
||||
private static isRegionalIndicator(c: string): boolean {
|
||||
|
|
|
@ -79,6 +79,8 @@ export default class DocumentPosition implements IPosition {
|
|||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return this; // impossible but Typescript doesn't believe us
|
||||
}
|
||||
|
||||
public backwardsWhile(model: EditorModel, predicate: Predicate): DocumentPosition {
|
||||
|
@ -104,6 +106,8 @@ export default class DocumentPosition implements IPosition {
|
|||
offset = parts[index].text.length;
|
||||
}
|
||||
}
|
||||
|
||||
return this; // impossible but Typescript doesn't believe us
|
||||
}
|
||||
|
||||
public asOffset(model: EditorModel): DocumentOffset {
|
||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
|||
import { Part, Type } from "./parts";
|
||||
import EditorModel from "./model";
|
||||
|
||||
export function needsCaretNodeBefore(part: Part, prevPart: Part): boolean {
|
||||
export function needsCaretNodeBefore(part: Part, prevPart?: Part): boolean {
|
||||
const isFirst = !prevPart || prevPart.type === Type.Newline;
|
||||
return !part.acceptsCaret && (isFirst || !prevPart.acceptsCaret);
|
||||
}
|
||||
|
@ -30,9 +30,9 @@ export function needsCaretNodeAfter(part: Part, isLastOfLine: boolean): boolean
|
|||
function insertAfter(node: HTMLElement, nodeToInsert: HTMLElement): void {
|
||||
const next = node.nextSibling;
|
||||
if (next) {
|
||||
node.parentElement.insertBefore(nodeToInsert, next);
|
||||
node.parentElement!.insertBefore(nodeToInsert, next);
|
||||
} else {
|
||||
node.parentElement.appendChild(nodeToInsert);
|
||||
node.parentElement!.appendChild(nodeToInsert);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,11 +58,11 @@ function updateCaretNode(node: HTMLElement): void {
|
|||
}
|
||||
}
|
||||
|
||||
export function isCaretNode(node: HTMLElement): boolean {
|
||||
return node && node.tagName === "SPAN" && node.className === "caretNode";
|
||||
export function isCaretNode(node?: Node | null): node is HTMLElement {
|
||||
return !!node && node instanceof HTMLElement && node.tagName === "SPAN" && node.className === "caretNode";
|
||||
}
|
||||
|
||||
function removeNextSiblings(node: ChildNode): void {
|
||||
function removeNextSiblings(node: ChildNode | null): void {
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
@ -83,13 +83,13 @@ function removeChildren(parent: HTMLElement): void {
|
|||
}
|
||||
|
||||
function reconcileLine(lineContainer: ChildNode, parts: Part[]): void {
|
||||
let currentNode;
|
||||
let prevPart;
|
||||
let currentNode: ChildNode | null = null;
|
||||
let prevPart: Part | undefined;
|
||||
const lastPart = parts[parts.length - 1];
|
||||
|
||||
for (const part of parts) {
|
||||
const isFirst = !prevPart;
|
||||
currentNode = isFirst ? lineContainer.firstChild : currentNode.nextSibling;
|
||||
currentNode = isFirst ? lineContainer.firstChild : currentNode!.nextSibling;
|
||||
|
||||
if (needsCaretNodeBefore(part, prevPart)) {
|
||||
if (isCaretNode(currentNode)) {
|
||||
|
@ -109,18 +109,18 @@ function reconcileLine(lineContainer: ChildNode, parts: Part[]): void {
|
|||
if (currentNode && part) {
|
||||
part.updateDOMNode(currentNode);
|
||||
} else if (part) {
|
||||
currentNode = part.toDOMNode();
|
||||
currentNode = part.toDOMNode() as ChildNode;
|
||||
// hooks up nextSibling for next iteration
|
||||
lineContainer.appendChild(currentNode);
|
||||
}
|
||||
|
||||
if (needsCaretNodeAfter(part, part === lastPart)) {
|
||||
if (isCaretNode(currentNode.nextSibling)) {
|
||||
currentNode = currentNode.nextSibling;
|
||||
updateCaretNode(currentNode);
|
||||
if (isCaretNode(currentNode?.nextSibling)) {
|
||||
currentNode = currentNode!.nextSibling;
|
||||
updateCaretNode(currentNode as HTMLElement);
|
||||
} else {
|
||||
const caretNode = createCaretNode();
|
||||
insertAfter(currentNode, caretNode);
|
||||
insertAfter(currentNode as HTMLElement, caretNode);
|
||||
currentNode = caretNode;
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ function reconcileEmptyLine(lineContainer: HTMLElement): void {
|
|||
}
|
||||
|
||||
export function renderModel(editor: HTMLDivElement, model: EditorModel): void {
|
||||
const lines = model.parts.reduce(
|
||||
const lines = model.parts.reduce<Part[][]>(
|
||||
(linesArr, part) => {
|
||||
if (part.type === Type.Newline) {
|
||||
linesArr.push([]);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue