[Blazor] Add more eslint rules and apply auto fixes (#9004)

This commit is contained in:
Javier Calvarro Nelson 2019-04-04 20:22:12 +02:00 committed by GitHub
parent facb0018eb
commit 237b19b2b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 173 additions and 57 deletions

View File

@ -33,7 +33,37 @@ module.exports = {
}],
"comma-style": ["error", "last"],
"comma-spacing": ["error", { "after": true }],
"no-trailing-spaces": ["error"]
"no-trailing-spaces": ["error"],
"curly": ["error"],
"dot-location": ["error", "property"],
"eqeqeq": ["error", "always"],
"no-eq-null": ["error"],
"no-multi-spaces": ["error"],
"no-unused-labels": ["error"],
"require-await": ["error"],
"array-bracket-newline": ["error", { "multiline": true, "minItems": 4 }],
"array-bracket-spacing": ["error", "never"],
"array-element-newline": ["error", { "minItems": 3 }],
"block-spacing": ["error"],
"func-call-spacing": ["error", "never"],
"function-paren-newline": ["error", "multiline"],
"key-spacing": ["error", { "mode": "strict" }],
"keyword-spacing": ["error", { "before": true }],
"lines-between-class-members": ["error", "always"],
"new-parens": ["error"],
"no-multi-assign": ["error"],
"no-multiple-empty-lines": ["error"],
"no-unneeded-ternary": ["error"],
"no-whitespace-before-property": ["error"],
"one-var": ["error", "never"],
"space-before-function-paren": ["error", {
"anonymous": "never",
"named": "never",
"asyncArrow": "always"
}],
"space-in-parens": ["error", "never"],
"space-infix-ops": ["error"]
},
globals: {
DotNet: "readonly"

View File

@ -9,6 +9,6 @@ window['Blazor'] = {
_internal: {
attachRootComponentToElement,
http: httpInternalFunctions,
uriHelper: uriHelperInternalFunctions
}
};
uriHelper: uriHelperInternalFunctions,
},
};

View File

@ -5,9 +5,13 @@ import { ReconnectDisplay } from './ReconnectDisplay';
import { ILogger, LogLevel } from '../Logging/ILogger';
export class AutoReconnectCircuitHandler implements CircuitHandler {
public static readonly MaxRetries = 5;
public static readonly RetryInterval = 3000;
public static readonly DialogId = 'components-reconnect-modal';
public reconnectDisplay: ReconnectDisplay;
public logger: ILogger;
public constructor(logger: ILogger) {
@ -20,6 +24,7 @@ export class AutoReconnectCircuitHandler implements CircuitHandler {
}
});
}
public onConnectionUp(): void {
this.reconnectDisplay.hide();
}

View File

@ -3,6 +3,7 @@ import { ComponentDescriptor, MarkupRegistrationTags, StartComponentComment, End
export class CircuitDescriptor {
public circuitId: string;
public components: ComponentDescriptor[];
public constructor(circuitId: string, components: ComponentDescriptor[]) {

View File

@ -23,8 +23,11 @@ export interface MarkupRegistrationTags {
export class ComponentDescriptor {
public registrationTags: MarkupRegistrationTags;
public componentId: number;
public circuitId: string;
public rendererId: number;
public constructor(componentId: number, circuitId: string, rendererId: number, descriptor: MarkupRegistrationTags) {

View File

@ -2,9 +2,13 @@ import { ReconnectDisplay } from './ReconnectDisplay';
import { AutoReconnectCircuitHandler } from './AutoReconnectCircuitHandler';
export class DefaultReconnectDisplay implements ReconnectDisplay {
modal: HTMLDivElement;
message: HTMLHeadingElement;
button: HTMLButtonElement;
addedToDom: boolean = false;
constructor(private document: Document) {
this.modal = this.document.createElement('div');
this.modal.id = AutoReconnectCircuitHandler.DialogId;
@ -21,7 +25,7 @@ export class DefaultReconnectDisplay implements ReconnectDisplay {
'background-color: #fff',
'opacity: 0.8',
'text-align: center',
'font-weight: bold'
'font-weight: bold',
];
this.modal.style.cssText = modalStyles.join(';');
@ -31,6 +35,7 @@ export class DefaultReconnectDisplay implements ReconnectDisplay {
this.button.addEventListener('click', () => window['Blazor'].reconnect());
}
show(): void {
if (!this.addedToDom) {
this.addedToDom = true;
@ -40,9 +45,11 @@ export class DefaultReconnectDisplay implements ReconnectDisplay {
this.button.style.display = 'none';
this.message.textContent = 'Attempting to reconnect to the server...';
}
hide(): void {
this.modal.style.display = 'none';
}
failed(): void {
this.button.style.display = 'block';
this.message.textContent = 'Failed to reconnect to the server.';

View File

@ -7,7 +7,9 @@ export default class RenderQueue {
private static renderQueues = new Map<number, RenderQueue>();
private nextBatchId = 2;
public browserRendererId: number;
public logger: ILogger;
public constructor(browserRendererId: number, logger: ILogger) {

View File

@ -1,22 +1,29 @@
import { ReconnectDisplay } from "./ReconnectDisplay";
import { ReconnectDisplay } from './ReconnectDisplay';
export class UserSpecifiedDisplay implements ReconnectDisplay {
static readonly ShowClassName = 'components-reconnect-show';
static readonly HideClassName = 'components-reconnect-hide';
static readonly FailedClassName = 'components-reconnect-failed';
constructor(private dialog: HTMLElement) {
}
show(): void {
this.removeClasses();
this.dialog.classList.add(UserSpecifiedDisplay.ShowClassName);
}
hide(): void {
this.removeClasses();
this.dialog.classList.add(UserSpecifiedDisplay.HideClassName);
}
failed(): void {
this.removeClasses();
this.dialog.classList.add(UserSpecifiedDisplay.FailedClassName);
}
private removeClasses() {
this.dialog.classList.remove(UserSpecifiedDisplay.ShowClassName, UserSpecifiedDisplay.HideClassName, UserSpecifiedDisplay.FailedClassName);
}

View File

@ -21,7 +21,7 @@ export const monoPlatform: Platform = {
// mono.js assumes the existence of this
window['Browser'] = {
init: () => { }
init: () => { },
};
// Emscripten works by expecting the module config to be a global
window['Module'] = createEmscriptenModuleInstance(loadAssemblyUrls, resolve, reject);
@ -60,7 +60,7 @@ export const monoPlatform: Platform = {
try {
const argsBuffer = Module.stackAlloc(args.length);
const exceptionFlagManagedInt = Module.stackAlloc(4);
for (var i = 0; i < args.length; ++i) {
for (let i = 0; i < args.length; ++i) {
Module.setValue(argsBuffer + i * 4, args[i], 'i32');
}
Module.setValue(exceptionFlagManagedInt, 0, 'i32');
@ -80,8 +80,8 @@ export const monoPlatform: Platform = {
toJavaScriptString: function toJavaScriptString(managedString: System_String) {
// Comments from original Mono sample:
//FIXME this is wastefull, we could remove the temp malloc by going the UTF16 route
//FIXME this is unsafe, cuz raw objects could be GC'd.
// FIXME this is wastefull, we could remove the temp malloc by going the UTF16 route
// FIXME this is unsafe, cuz raw objects could be GC'd.
const utf8 = mono_string_get_utf8(managedString);
const res = Module.UTF8ToString(utf8);
@ -206,11 +206,27 @@ function createEmscriptenModuleInstance(loadAssemblyUrls: string[], onReady: ()
module.preRun.push(() => {
// By now, emscripten should be initialised enough that we can capture these methods for later use
const mono_wasm_add_assembly = Module.cwrap('mono_wasm_add_assembly', null, ['string', 'number', 'number']);
const mono_wasm_add_assembly = Module.cwrap('mono_wasm_add_assembly', null, [
'string',
'number',
'number',
]);
assembly_load = Module.cwrap('mono_wasm_assembly_load', 'number', ['string']);
find_class = Module.cwrap('mono_wasm_assembly_find_class', 'number', ['number', 'string', 'string']);
find_method = Module.cwrap('mono_wasm_assembly_find_method', 'number', ['number', 'string', 'number']);
invoke_method = Module.cwrap('mono_wasm_invoke_method', 'number', ['number', 'number', 'number']);
find_class = Module.cwrap('mono_wasm_assembly_find_class', 'number', [
'number',
'string',
'string',
]);
find_method = Module.cwrap('mono_wasm_assembly_find_method', 'number', [
'number',
'string',
'number',
]);
invoke_method = Module.cwrap('mono_wasm_invoke_method', 'number', [
'number',
'number',
'number',
]);
mono_string_get_utf8 = Module.cwrap('mono_wasm_string_get_utf8', 'number', ['number']);
mono_string = Module.cwrap('mono_wasm_string_from_js', 'number', ['string']);
@ -264,12 +280,12 @@ function toAbsoluteUrl(possiblyRelativeUrl: string) {
function asyncLoad(url) {
return new Promise<Uint8Array>((resolve, reject) => {
var xhr = new XMLHttpRequest;
const xhr = new XMLHttpRequest();
xhr.open('GET', url, /* async: */ true);
xhr.responseType = 'arraybuffer';
xhr.onload = function xhr_onload() {
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
var asm = new Uint8Array(xhr.response);
const asm = new Uint8Array(xhr.response);
resolve(asm);
} else {
reject(xhr);
@ -295,12 +311,12 @@ function attachInteropInvoker() {
const assemblyNameOrDotNetObjectId = dotNetObjectId
? dotNetObjectId.toString()
: assemblyName;
monoPlatform.callMethod(dotNetDispatcherBeginInvokeMethodHandle, null, [
callId ? monoPlatform.toDotNetString(callId.toString()) : null,
monoPlatform.toDotNetString(assemblyNameOrDotNetObjectId!),
monoPlatform.toDotNetString(methodIdentifier),
monoPlatform.toDotNetString(argsJson)
monoPlatform.toDotNetString(argsJson),
]);
},
@ -309,7 +325,7 @@ function attachInteropInvoker() {
assemblyName ? monoPlatform.toDotNetString(assemblyName) : null,
monoPlatform.toDotNetString(methodIdentifier),
dotNetObjectId ? monoPlatform.toDotNetString(dotNetObjectId.toString()) : null,
monoPlatform.toDotNetString(argsJson)
monoPlatform.toDotNetString(argsJson),
]) as System_String;
return resultJsonStringPtr
? monoPlatform.toJavaScriptString(resultJsonStringPtr)

View File

@ -24,8 +24,8 @@ export interface Platform {
// We don't actually instantiate any of these at runtime. For perf it's preferable to
// use the original 'number' instances without any boxing. The definitions are just
// for compile-time checking, since TypeScript doesn't support nominal types.
export interface MethodHandle { MethodHandle__DO_NOT_IMPLEMENT: any };
export interface System_Object { System_Object__DO_NOT_IMPLEMENT: any };
export interface MethodHandle { MethodHandle__DO_NOT_IMPLEMENT: any }
export interface System_Object { System_Object__DO_NOT_IMPLEMENT: any }
export interface System_String extends System_Object { System_String__DO_NOT_IMPLEMENT: any }
export interface System_Array<T> extends System_Object { System_Array__DO_NOT_IMPLEMENT: any }
export interface Pointer { Pointer__DO_NOT_IMPLEMENT: any }

View File

@ -11,7 +11,9 @@ const rootComponentsPendingFirstRender: { [componentId: number]: LogicalElement
export class BrowserRenderer {
private eventDelegator: EventDelegator;
private childComponentLocations: { [componentId: number]: LogicalElement } = {};
private browserRendererId: number;
public constructor(browserRendererId: number) {
@ -388,7 +390,8 @@ function raiseEvent(event: Event, browserRendererId: number, eventHandlerId: num
'Microsoft.AspNetCore.Components.Browser',
'DispatchEvent',
eventDescriptor,
JSON.stringify(eventArgs.data));
JSON.stringify(eventArgs.data)
);
}
function clearElement(element: Element) {
@ -400,7 +403,7 @@ function clearElement(element: Element) {
function clearBetween(start: Node, end: Node): void {
const logicalParent = getLogicalParent(start as unknown as LogicalElement);
if(!logicalParent){
if (!logicalParent){
throw new Error("Can't clear between nodes. The start node does not have a logical parent.");
}
const children = getLogicalChildrenArray(logicalParent);

View File

@ -1,8 +1,23 @@
import { EventForDotNet, UIEventArgs } from './EventForDotNet';
import { EventForDotNet, UIEventArgs } from './EventForDotNet';
const nonBubblingEvents = toLookup([
'abort', 'blur', 'change', 'error', 'focus', 'load', 'loadend', 'loadstart', 'mouseenter', 'mouseleave',
'progress', 'reset', 'scroll', 'submit', 'unload', 'DOMNodeInsertedIntoDocument', 'DOMNodeRemovedFromDocument'
'abort',
'blur',
'change',
'error',
'focus',
'load',
'loadend',
'loadstart',
'mouseenter',
'mouseleave',
'progress',
'reset',
'scroll',
'submit',
'unload',
'DOMNodeInsertedIntoDocument',
'DOMNodeRemovedFromDocument',
]);
export interface OnEventCallback {
@ -14,7 +29,9 @@ export interface OnEventCallback {
// event listeners as required (and also maps actual events back to the given callback).
export class EventDelegator {
private static nextEventDelegatorId = 0;
private eventsCollectionKey: string;
private eventInfoStore: EventInfoStore;
constructor(private onEvent: OnEventCallback) {
@ -93,6 +110,7 @@ export class EventDelegator {
// for a given event name changes between zero and nonzero
class EventInfoStore {
private infosByEventHandlerId: { [eventHandlerId: number]: EventHandlerInfo } = {};
private countByEventName: { [eventName: string]: number } = {};
constructor(private globalListener: EventListener) {
@ -155,7 +173,7 @@ interface EventHandlerInfosForElement {
// can only have one attribute with a given name, hence only one event handler with
// that name at any one time.
// So to keep things simple, only track one EventHandlerInfo per (element, eventName)
[eventName: string]: EventHandlerInfo
[eventName: string]: EventHandlerInfo;
}
interface EventHandlerInfo {
@ -166,6 +184,8 @@ interface EventHandlerInfo {
function toLookup(items: string[]): { [key: string]: boolean } {
const result = {};
items.forEach(value => { result[value] = true; });
items.forEach(value => {
result[value] = true;
});
return result;
}

View File

@ -103,8 +103,8 @@ function parseDragEvent(event: any) {
ctrlKey: event.ctrlKey,
shiftKey: event.shiftKey,
altKey: event.altKey,
metaKey: event.metaKey
}
metaKey: event.metaKey,
};
}
function parseWheelEvent(event: WheelEvent) {
@ -113,7 +113,7 @@ function parseWheelEvent(event: WheelEvent) {
deltaX: event.deltaX,
deltaY: event.deltaY,
deltaZ: event.deltaZ,
deltaMode: event.deltaMode
deltaMode: event.deltaMode,
};
}
@ -123,8 +123,8 @@ function parseErrorEvent(event: ErrorEvent) {
message: event.message,
filename: event.filename,
lineno: event.lineno,
colno: event.colno
}
colno: event.colno,
};
}
function parseProgressEvent(event: ProgressEvent) {
@ -132,7 +132,7 @@ function parseProgressEvent(event: ProgressEvent) {
type: event.type,
lengthComputable: event.lengthComputable,
loaded: event.loaded,
total: event.total
total: event.total,
};
}
@ -140,7 +140,7 @@ function parseTouchEvent(event: TouchEvent) {
function parseTouch(touchList: TouchList) {
const touches: UITouchPoint[] = [];
for (let i = 0; i < touchList.length; i++) {
const touch = touchList[i];
touches.push({
@ -150,7 +150,7 @@ function parseTouchEvent(event: TouchEvent) {
screenX: touch.screenX,
screenY: touch.screenY,
pageX: touch.pageX,
pageY: touch.pageY
pageY: touch.pageY,
});
}
return touches;
@ -165,7 +165,7 @@ function parseTouchEvent(event: TouchEvent) {
ctrlKey: event.ctrlKey,
shiftKey: event.shiftKey,
altKey: event.altKey,
metaKey: event.metaKey
metaKey: event.metaKey,
};
}
@ -179,7 +179,7 @@ function parseKeyboardEvent(event: KeyboardEvent) {
ctrlKey: event.ctrlKey,
shiftKey: event.shiftKey,
altKey: event.altKey,
metaKey: event.metaKey
metaKey: event.metaKey,
};
}
@ -193,7 +193,7 @@ function parsePointerEvent(event: PointerEvent) {
tiltX: event.tiltX,
tiltY: event.tiltY,
pointerType: event.pointerType,
isPrimary: event.isPrimary
isPrimary: event.isPrimary,
};
}
@ -210,7 +210,7 @@ function parseMouseEvent(event: MouseEvent) {
ctrlKey: event.ctrlKey,
shiftKey: event.shiftKey,
altKey: event.altKey,
metaKey: event.metaKey
metaKey: event.metaKey,
};
}

View File

@ -46,12 +46,12 @@ export function toLogicalRootCommentElement(start: Comment, end: Comment): Logic
// |- *div
// |- *component
// |- *footer
if(!start.parentNode){
if (!start.parentNode){
throw new Error(`Comment not connected to the DOM ${start.textContent}`);
}
const parent = start.parentNode;
const parentLogicalElement = toLogicalElement(parent, /* allow existing contents */ true);
const parentLogicalElement = toLogicalElement(parent, /* allow existing contents */ true);
const children = getLogicalChildrenArray(parentLogicalElement);
Array.from(parent.childNodes).forEach(n => children.push(n as unknown as LogicalElement));
start[logicalParentPropname] = parentLogicalElement;

View File

@ -55,9 +55,13 @@ export class OutOfProcessRenderBatch implements RenderBatch {
}
diffReader: RenderTreeDiffReader;
editReader: RenderTreeEditReader;
frameReader: RenderTreeFrameReader;
arrayRangeReader: ArrayRangeReader;
arraySegmentReader: ArraySegmentReader;
}

View File

@ -13,30 +13,48 @@ export class SharedMemoryRenderBatch implements RenderBatch {
}
// Keep in sync with memory layout in RenderBatch.cs
updatedComponents() { return platform.readStructField<Pointer>(this.batchAddress, 0) as any as ArrayRange<RenderTreeDiff>; }
referenceFrames() { return platform.readStructField<Pointer>(this.batchAddress, arrayRangeReader.structLength) as any as ArrayRange<RenderTreeDiff>; }
disposedComponentIds() { return platform.readStructField<Pointer>(this.batchAddress, arrayRangeReader.structLength * 2) as any as ArrayRange<number>; }
disposedEventHandlerIds() { return platform.readStructField<Pointer>(this.batchAddress, arrayRangeReader.structLength * 3) as any as ArrayRange<number>; }
updatedComponents() {
return platform.readStructField<Pointer>(this.batchAddress, 0) as any as ArrayRange<RenderTreeDiff>;
}
referenceFrames() {
return platform.readStructField<Pointer>(this.batchAddress, arrayRangeReader.structLength) as any as ArrayRange<RenderTreeDiff>;
}
disposedComponentIds() {
return platform.readStructField<Pointer>(this.batchAddress, arrayRangeReader.structLength * 2) as any as ArrayRange<number>;
}
disposedEventHandlerIds() {
return platform.readStructField<Pointer>(this.batchAddress, arrayRangeReader.structLength * 3) as any as ArrayRange<number>;
}
updatedComponentsEntry(values: ArrayValues<RenderTreeDiff>, index: number) {
return arrayValuesEntry(values, index, diffReader.structLength);
}
referenceFramesEntry(values: ArrayValues<RenderTreeFrame>, index: number) {
return arrayValuesEntry(values, index, frameReader.structLength);
}
disposedComponentIdsEntry(values: ArrayValues<number>, index: number) {
const pointer = arrayValuesEntry(values, index, /* int length */ 4);
return platform.readInt32Field(pointer as any as Pointer);
}
disposedEventHandlerIdsEntry(values: ArrayValues<number>, index: number) {
const pointer = arrayValuesEntry(values, index, /* int length */ 4);
return platform.readInt32Field(pointer as any as Pointer);
}
arrayRangeReader = arrayRangeReader;
arraySegmentReader = arraySegmentReader;
diffReader = diffReader;
editReader = editReader;
frameReader = frameReader;
}

View File

@ -5,7 +5,7 @@ const nativeDecoder = typeof TextDecoder === 'function'
export const decodeUtf8: (bytes: Uint8Array) => string
= nativeDecoder ? nativeDecoder.decode.bind(nativeDecoder) : decodeImpl;
/*!
/* !
Logic in decodeImpl is derived from fast-text-encoding
https://github.com/samthor/fast-text-encoding
@ -22,12 +22,12 @@ function decodeImpl(bytes: Uint8Array): string {
while (pos < len) {
const byte1 = bytes[pos++];
if (byte1 === 0) {
break; // NULL
break; // NULL
}
if ((byte1 & 0x80) === 0) { // 1-byte
if ((byte1 & 0x80) === 0) { // 1-byte
out.push(byte1);
} else if ((byte1 & 0xe0) === 0xc0) { // 2-byte
} else if ((byte1 & 0xe0) === 0xc0) { // 2-byte
const byte2 = bytes[pos++] & 0x3f;
out.push(((byte1 & 0x1f) << 6) | byte2);
} else if ((byte1 & 0xf0) === 0xe0) {
@ -44,7 +44,7 @@ function decodeImpl(bytes: Uint8Array): string {
if (codepoint > 0xffff) {
// codepoint &= ~0x10000;
codepoint -= 0x10000;
out.push((codepoint >>> 10) & 0x3ff | 0xd800)
out.push((codepoint >>> 10) & 0x3ff | 0xd800);
codepoint = 0xdc00 | codepoint & 0x3ff;
}
out.push(codepoint);

View File

@ -8,8 +8,8 @@ let allocateArrayMethod: MethodHandle;
// These are the functions we're making available for invocation from .NET
export const internalFunctions = {
sendAsync
}
sendAsync,
};
async function sendAsync(id: number, body: System_Array<any>, jsonFetchArgs: System_String) {
let response: Response;
@ -37,7 +37,7 @@ function dispatchSuccessResponse(id: number, response: Response, responseData: A
const responseDescriptor: ResponseDescriptor = {
statusCode: response.status,
statusText: response.statusText,
headers: []
headers: [],
};
response.headers.forEach((value, name) => {
responseDescriptor.headers.push([name, value]);

View File

@ -3,7 +3,7 @@ import '@dotnet/jsinterop';
let hasRegisteredEventListeners = false;
// Will be initialized once someone registers
let notifyLocationChangedCallback: { assemblyName: string, functionName: string } | null = null;
let notifyLocationChangedCallback: { assemblyName: string; functionName: string } | null = null;
// These are the functions we're making available for invocation from .NET
export const internalFunctions = {
@ -11,7 +11,7 @@ export const internalFunctions = {
navigateTo,
getBaseURI: () => document.baseURI,
getLocationHref: () => location.href,
}
};
function enableNavigationInterception(assemblyName: string, functionName: string) {
if (hasRegisteredEventListeners || assemblyName === undefined || functionName === undefined) {
@ -80,7 +80,7 @@ function findClosestAncestor(element: Element | null, tagName: string) {
? null
: element.tagName === tagName
? element
: findClosestAncestor(element.parentElement, tagName)
: findClosestAncestor(element.parentElement, tagName);
}
function isWithinBaseUriSpace(href: string) {