Conform more code to strict null checking (#10167)
* Conform more code to strict null checking * Delint * Iterate PR based on feedback
This commit is contained in:
parent
f7bea2cae5
commit
4574c665ea
103 changed files with 517 additions and 495 deletions
|
@ -45,7 +45,7 @@ export function isSlashCommand(model: EditorModel): boolean {
|
|||
return false;
|
||||
}
|
||||
|
||||
export function getSlashCommand(model: EditorModel): [Command, string, string] {
|
||||
export function getSlashCommand(model: EditorModel): [Command | undefined, string | undefined, string] {
|
||||
const commandText = model.parts.reduce((text, part) => {
|
||||
// use mxid to textify user pills in a command and room alias/id for room pills
|
||||
if (part.type === Type.UserPill || part.type === Type.RoomPill) {
|
||||
|
@ -69,7 +69,7 @@ export async function runSlashCommand(
|
|||
if (result.promise) {
|
||||
try {
|
||||
if (cmd.category === CommandCategories.messages || cmd.category === CommandCategories.effects) {
|
||||
messageContent = await result.promise;
|
||||
messageContent = (await result.promise) ?? null;
|
||||
} else {
|
||||
await result.promise;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ export function walkDOMDepthFirst(rootNode: Node, enterNodeCallback: Predicate,
|
|||
} else if (node.nextSibling) {
|
||||
node = node.nextSibling;
|
||||
} else {
|
||||
while (!node.nextSibling && node !== rootNode) {
|
||||
while (node && !node.nextSibling && node !== rootNode) {
|
||||
node = node.parentElement;
|
||||
if (node !== rootNode) {
|
||||
leaveNodeCallback(node);
|
||||
|
|
|
@ -127,7 +127,7 @@ export default class EditorModel {
|
|||
return this._parts;
|
||||
}
|
||||
|
||||
public get autoComplete(): AutocompleteWrapperModel {
|
||||
public get autoComplete(): AutocompleteWrapperModel | null {
|
||||
if (this.activePartIdx === this.autoCompletePartIdx) {
|
||||
return this._autoComplete;
|
||||
}
|
||||
|
@ -212,12 +212,12 @@ export default class EditorModel {
|
|||
const transformAddedLen = this.getTransformAddedLen(newPosition, inputType, diff);
|
||||
newPosition = this.positionForOffset(caretOffset + transformAddedLen, true);
|
||||
}
|
||||
this.updateCallback(newPosition, inputType, diff);
|
||||
this.updateCallback?.(newPosition, inputType, diff);
|
||||
return acPromise;
|
||||
}
|
||||
|
||||
private getTransformAddedLen(newPosition: DocumentPosition, inputType: string, diff: IDiff): number {
|
||||
const result = this.transformCallback(newPosition, inputType, diff);
|
||||
const result = this.transformCallback?.(newPosition, inputType, diff);
|
||||
return Number.isFinite(result) ? (result as number) : 0;
|
||||
}
|
||||
|
||||
|
@ -268,13 +268,13 @@ export default class EditorModel {
|
|||
// rerender even if editor contents didn't change
|
||||
// to make sure the MessageEditor checks
|
||||
// model.autoComplete being empty and closes it
|
||||
this.updateCallback(pos);
|
||||
this.updateCallback?.(pos);
|
||||
};
|
||||
|
||||
private mergeAdjacentParts(): void {
|
||||
let prevPart: Part | undefined;
|
||||
for (let i = 0; i < this._parts.length; ++i) {
|
||||
let part = this._parts[i];
|
||||
let part: Part | undefined = this._parts[i];
|
||||
const isEmpty = !part.text.length;
|
||||
const isMerged = !isEmpty && prevPart && prevPart.merge?.(part);
|
||||
if (isEmpty || isMerged) {
|
||||
|
@ -452,13 +452,13 @@ export default class EditorModel {
|
|||
*/
|
||||
public transform(callback: ManualTransformCallback): Promise<void> {
|
||||
const pos = callback();
|
||||
let acPromise: Promise<void> = null;
|
||||
let acPromise: Promise<void> | null = null;
|
||||
if (!(pos instanceof Range)) {
|
||||
acPromise = this.setActivePart(pos, true);
|
||||
} else {
|
||||
acPromise = Promise.resolve();
|
||||
}
|
||||
this.updateCallback(pos);
|
||||
this.updateCallback?.(pos);
|
||||
return acPromise;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -422,7 +422,7 @@ class RoomPillPart extends PillPart {
|
|||
|
||||
protected setAvatar(node: HTMLElement): void {
|
||||
let initialLetter = "";
|
||||
let avatarUrl = Avatar.avatarUrlForRoom(this.room, 16, 16, "crop");
|
||||
let avatarUrl = Avatar.avatarUrlForRoom(this.room ?? null, 16, 16, "crop");
|
||||
if (!avatarUrl) {
|
||||
initialLetter = Avatar.getInitialLetter(this.room?.name || this.resourceId) ?? "";
|
||||
avatarUrl = Avatar.defaultAvatarUrlForString(this.room?.roomId ?? this.resourceId);
|
||||
|
@ -541,7 +541,7 @@ export class PartCreator {
|
|||
public constructor(
|
||||
private readonly room: Room,
|
||||
private readonly client: MatrixClient,
|
||||
autoCompleteCreator: AutoCompleteCreator = null,
|
||||
autoCompleteCreator: AutoCompleteCreator | null = null,
|
||||
) {
|
||||
// pre-create the creator as an object even without callback so it can already be passed
|
||||
// to PillCandidatePart (e.g. while deserializing) and set later on
|
||||
|
@ -574,7 +574,7 @@ export class PartCreator {
|
|||
return this.plain(text);
|
||||
}
|
||||
|
||||
public deserializePart(part: SerializedPart): Part {
|
||||
public deserializePart(part: SerializedPart): Part | undefined {
|
||||
switch (part.type) {
|
||||
case Type.Plain:
|
||||
return this.plain(part.text);
|
||||
|
@ -612,7 +612,7 @@ export class PartCreator {
|
|||
public roomPill(alias: string, roomId?: string): RoomPillPart {
|
||||
let room: Room | undefined;
|
||||
if (roomId || alias[0] !== "#") {
|
||||
room = this.client.getRoom(roomId || alias);
|
||||
room = this.client.getRoom(roomId || alias) ?? undefined;
|
||||
} else {
|
||||
room = this.client.getRooms().find((r) => {
|
||||
return r.getCanonicalAlias() === alias || r.getAltAliases().includes(alias);
|
||||
|
@ -691,7 +691,7 @@ export class CommandPartCreator extends PartCreator {
|
|||
return new CommandPart(text, this.autoCompleteCreator);
|
||||
}
|
||||
|
||||
public deserializePart(part: SerializedPart): Part {
|
||||
public deserializePart(part: SerializedPart): Part | undefined {
|
||||
if (part.type === Type.Command) {
|
||||
return this.command(part.text);
|
||||
} else {
|
||||
|
|
|
@ -93,8 +93,8 @@ function reconcileLine(lineContainer: ChildNode, parts: Part[]): void {
|
|||
|
||||
if (needsCaretNodeBefore(part, prevPart)) {
|
||||
if (isCaretNode(currentNode as Element)) {
|
||||
updateCaretNode(currentNode);
|
||||
currentNode = currentNode.nextSibling;
|
||||
updateCaretNode(currentNode!);
|
||||
currentNode = currentNode!.nextSibling;
|
||||
} else {
|
||||
lineContainer.insertBefore(createCaretNode(), currentNode);
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ interface ISerializeOpts {
|
|||
export function htmlSerializeIfNeeded(
|
||||
model: EditorModel,
|
||||
{ forceHTML = false, useMarkdown = true }: ISerializeOpts = {},
|
||||
): string {
|
||||
): string | undefined {
|
||||
if (!useMarkdown) {
|
||||
return escapeHtml(textSerialize(model)).replace(/\n/g, "<br/>");
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ export function htmlSerializeIfNeeded(
|
|||
return htmlSerializeFromMdIfNeeded(md, { forceHTML });
|
||||
}
|
||||
|
||||
export function htmlSerializeFromMdIfNeeded(md: string, { forceHTML = false } = {}): string {
|
||||
export function htmlSerializeFromMdIfNeeded(md: string, { forceHTML = false } = {}): string | undefined {
|
||||
// copy of raw input to remove unwanted math later
|
||||
const orig = md;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue