diff --git a/core/package.json b/core/package.json index 57603b36cc..2f497b80ad 100644 --- a/core/package.json +++ b/core/package.json @@ -27,7 +27,7 @@ "ionicons": "4.4.3" }, "devDependencies": { - "@stencil/core": "0.13.0-3", + "@stencil/core": "0.13.0-4", "@stencil/dev-server": "latest", "@stencil/sass": "0.1.0", "@stencil/utils": "latest", @@ -44,7 +44,7 @@ "stylelint": "^9.4.0", "stylelint-order": "^0.8.1", "tslint": "^5.10.0", - "tslint-ionic-rules": "0.0.18", + "tslint-ionic-rules": "0.0.19", "tslint-react": "^3.6.0", "typescript": "^2.9.2", "yargs": "^12.0.1" diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 458b1acabd..f1c538b2b3 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -4011,7 +4011,7 @@ export namespace Components { * The text to display on the ok button. Default: `OK`. */ 'okText': string; - 'open': (ev?: UIEvent | undefined) => Promise; + 'open': (ev?: UIEvent | undefined) => Promise; /** * The text to display when the select is empty. */ diff --git a/core/src/components/back-button/back-button.tsx b/core/src/components/back-button/back-button.tsx index 3bc8707f57..0d2fec9fe3 100644 --- a/core/src/components/back-button/back-button.tsx +++ b/core/src/components/back-button/back-button.tsx @@ -46,11 +46,11 @@ export class BackButton { */ @Prop() text?: string; - private onClick(ev: Event) { + async onClick(ev: Event) { const nav = this.el.closest('ion-nav'); ev.preventDefault(); - if (nav && nav.canGoBack()) { + if (nav && await nav.canGoBack()) { return nav.pop({ skipIfBusy: true }); } return openURL(this.win, this.defaultHref, ev, 'back'); diff --git a/core/src/components/datetime/datetime-util.ts b/core/src/components/datetime/datetime-util.ts index 7df286b0fd..7aa4ba20a4 100644 --- a/core/src/components/datetime/datetime-util.ts +++ b/core/src/components/datetime/datetime-util.ts @@ -11,11 +11,11 @@ export function renderDatetime(template: string, value: DatetimeData | undefined const token = '{' + index + '}'; const text = renderTextFormat(format.f, (value as any)[format.k], value, locale); - if (!hasText && text && (value as any)[format.k] != null) { + if (!hasText && text !== undefined && (value as any)[format.k] != null) { hasText = true; } - tokens.push(token, text); + tokens.push(token, text || ''); template = template.replace(format.f, token); } @@ -32,7 +32,7 @@ export function renderDatetime(template: string, value: DatetimeData | undefined return template; } -export function renderTextFormat(format: string, value: any, date: DatetimeData | undefined, locale: LocaleData): string { +export function renderTextFormat(format: string, value: any, date: DatetimeData | undefined, locale: LocaleData): string | undefined { if ((format === FORMAT_DDDD || format === FORMAT_DDD)) { try { value = (new Date(date!.year!, date!.month! - 1, date!.day)).getDay(); @@ -47,7 +47,7 @@ export function renderTextFormat(format: string, value: any, date: DatetimeData // ignore } - return ''; + return undefined; } if (format === FORMAT_A) { diff --git a/core/src/components/item-sliding/item-sliding.tsx b/core/src/components/item-sliding/item-sliding.tsx index f668c30f9d..7f241a1c0c 100644 --- a/core/src/components/item-sliding/item-sliding.tsx +++ b/core/src/components/item-sliding/item-sliding.tsx @@ -234,9 +234,9 @@ export class ItemSliding { this.setOpenAmount(restingPoint, true); - if (this.state & SlidingState.SwipeEnd && this.rightOptions) { + if ((this.state & SlidingState.SwipeEnd) !== 0 && this.rightOptions) { this.rightOptions.fireSwipeEvent(); - } else if (this.state & SlidingState.SwipeStart && this.leftOptions) { + } else if ((this.state & SlidingState.SwipeStart) !== 0 && this.leftOptions) { this.leftOptions.fireSwipeEvent(); } } diff --git a/core/src/components/menu/test/menu.e2e.ts b/core/src/components/menu/test/menu.e2e.ts new file mode 100644 index 0000000000..d6baa514d5 --- /dev/null +++ b/core/src/components/menu/test/menu.e2e.ts @@ -0,0 +1,34 @@ +import { newE2EPage } from '@stencil/core/testing'; + +describe('menu', () => { + + it('should open menu', async () => { + // create a new e2e test page + const page = await newE2EPage({ + html: ` + + + Content + +
+
+ ` + }); + + const menu = await page.find('ion-menu'); + + expect(menu).toHaveClasses([ + 'menu-type-overlay', + 'menu-side-start', + ]); + + await menu.callMethod('open', false); + await page.waitForChanges(); + + expect(menu).toHaveClasses([ + 'menu-type-overlay', + 'menu-enabled', + 'menu-side-start', + ]); + }); +}); diff --git a/core/src/components/nav-push/nav-push.tsx b/core/src/components/nav-push/nav-push.tsx index 7f834a1ca0..b83c2f3e13 100644 --- a/core/src/components/nav-push/nav-push.tsx +++ b/core/src/components/nav-push/nav-push.tsx @@ -22,7 +22,7 @@ export class NavPush { push() { const nav = this.el.closest('ion-nav'); const toPush = this.component; - if (nav && toPush) { + if (nav && toPush !== undefined) { return nav.push(toPush, this.componentProps, { skipIfBusy: true }); } return Promise.resolve(false); diff --git a/core/src/components/nav-set-root/nav-set-root.tsx b/core/src/components/nav-set-root/nav-set-root.tsx index cc7e2c823f..20c99d9bb3 100644 --- a/core/src/components/nav-set-root/nav-set-root.tsx +++ b/core/src/components/nav-set-root/nav-set-root.tsx @@ -23,7 +23,7 @@ export class NavSetRoot { push() { const nav = this.el.closest('ion-nav'); const toPush = this.component; - if (nav && toPush) { + if (nav && toPush !== undefined) { return nav.setRoot(toPush, this.componentProps, { skipIfBusy: true }); } return Promise.resolve(false); diff --git a/core/src/components/nav/nav.tsx b/core/src/components/nav/nav.tsx index 7e2dce913b..600c8930df 100644 --- a/core/src/components/nav/nav.tsx +++ b/core/src/components/nav/nav.tsx @@ -436,7 +436,7 @@ export class Nav implements NavOutlet { } private canGoBackSync(view = this.getActiveSync()): boolean { - return !!(view && this.getPrevious(view)); + return !!(view && this.getPreviousSync(view)); } private getPreviousSync(view = this.getActiveSync()): ViewController | undefined { diff --git a/core/src/components/router-outlet/route-outlet.tsx b/core/src/components/router-outlet/route-outlet.tsx index 80a91110e1..fe12ad8224 100644 --- a/core/src/components/router-outlet/route-outlet.tsx +++ b/core/src/components/router-outlet/route-outlet.tsx @@ -105,7 +105,7 @@ export class RouterOutlet implements NavOutlet { let resolve!: () => void; this.waitPromise = new Promise(r => resolve = r); - if (p) { + if (p !== undefined) { await p; } return resolve; diff --git a/core/src/components/router/router.tsx b/core/src/components/router/router.tsx index f4bed64cad..cecf5d09a9 100644 --- a/core/src/components/router/router.tsx +++ b/core/src/components/router/router.tsx @@ -219,7 +219,7 @@ export class Router { let resolve!: () => void; this.waitPromise = new Promise(r => resolve = r); - if (p) { + if (p !== undefined) { await p; } return resolve; diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx index 506460eb0e..af1e89af68 100644 --- a/core/src/components/select/select.tsx +++ b/core/src/components/select/select.tsx @@ -471,7 +471,7 @@ export class Select { let addPlaceholderClass = false; let selectText = this.selectedText || this.text; - if (selectText === undefined && this.placeholder) { + if (selectText === undefined && this.placeholder !== undefined) { selectText = this.placeholder; addPlaceholderClass = true; } diff --git a/core/src/components/tab/tab.tsx b/core/src/components/tab/tab.tsx index ae7d888646..2aabf5eda3 100644 --- a/core/src/components/tab/tab.tsx +++ b/core/src/components/tab/tab.tsx @@ -131,7 +131,7 @@ export class Tab { } private prepareLazyLoaded(): Promise { - if (!this.loaded && this.component) { + if (!this.loaded && this.component != null) { this.loaded = true; return attachComponent(this.delegate, this.el, this.component, ['ion-page']); } diff --git a/core/src/components/virtual-scroll/virtual-scroll.tsx b/core/src/components/virtual-scroll/virtual-scroll.tsx index c2e464cafe..f95bef4b93 100644 --- a/core/src/components/virtual-scroll/virtual-scroll.tsx +++ b/core/src/components/virtual-scroll/virtual-scroll.tsx @@ -272,7 +272,7 @@ export class VirtualScroll { } } - private updateCellHeight(cell: Cell, node: HTMLStencilElement) { + private updateCellHeight(cell: Cell, node: any) { const update = () => { if ((node as any)['$ionCell'] === cell) { const style = this.win.getComputedStyle(node); diff --git a/core/src/interface.d.ts b/core/src/interface.d.ts index 447e7270f1..27b889e25d 100644 --- a/core/src/interface.d.ts +++ b/core/src/interface.d.ts @@ -37,7 +37,7 @@ export type PredefinedColors = 'primary' | 'secondary' | 'tertiary' | 'success' export type Color = PredefinedColors | string; export type Mode = 'ios' | 'md'; export type ComponentTags = keyof StencilIntrinsicElements; -export type ComponentRef = Function | HTMLElement | string; +export type ComponentRef = Function | HTMLElement | string | null; export type ComponentProps = T extends ComponentTags ? StencilIntrinsicElements[T] : {[key: string]: any}; export type CssClassMap = { [className: string]: boolean }; export type BackButtonEvent = CustomEvent<{ diff --git a/core/src/utils/hardware-back-button.ts b/core/src/utils/hardware-back-button.ts index 9e7d9d690b..0318b13910 100644 --- a/core/src/utils/hardware-back-button.ts +++ b/core/src/utils/hardware-back-button.ts @@ -1,6 +1,6 @@ import { BackButtonEvent } from '../interface'; -type Handler = () => Promise | void; +type Handler = () => Promise | void | null; interface HandlerRegister { priority: number; @@ -35,7 +35,7 @@ export function startHardwareBackButton(win: Window) { } }); const result = handler!(); - if (result) { + if (result != null) { // tslint:disable-next-line:no-floating-promises result.then(() => busy = false); } diff --git a/core/src/utils/input-shims/hacks/scroll-assist.ts b/core/src/utils/input-shims/hacks/scroll-assist.ts index 9088336c1a..291359da9c 100644 --- a/core/src/utils/input-shims/hacks/scroll-assist.ts +++ b/core/src/utils/input-shims/hacks/scroll-assist.ts @@ -75,7 +75,7 @@ function jsSetFocus( }); } -function hasPointerMoved(threshold: number, startCoord: PointerCoordinates, endCoord: PointerCoordinates) { +function hasPointerMoved(threshold: number, startCoord: PointerCoordinates | undefined, endCoord: PointerCoordinates | undefined) { if (startCoord && endCoord) { const deltaX = (startCoord.x - endCoord.x); const deltaY = (startCoord.y - endCoord.y); diff --git a/core/src/utils/theme.ts b/core/src/utils/theme.ts index 9bf0d621d5..6b91e65fd9 100644 --- a/core/src/utils/theme.ts +++ b/core/src/utils/theme.ts @@ -1,7 +1,7 @@ import { Color, CssClassMap, Mode, RouterDirection } from '../interface'; export function hostContext(selector: string, el: HTMLElement): boolean { - return !!el.closest(selector); + return el.closest(selector) !== null; } /** @@ -38,8 +38,8 @@ export function getClassMap(classes: string | string[] | undefined): CssClassMap return map; } -export async function openURL(win: Window, url: string | undefined, ev: Event | undefined | null, direction?: RouterDirection): Promise { - if (url && url[0] !== '#' && url.indexOf('://') === -1) { +export async function openURL(win: Window, url: string | undefined | null, ev: Event | undefined | null, direction?: RouterDirection): Promise { + if (url != null && url[0] !== '#' && url.indexOf('://') === -1) { const router = win.document.querySelector('ion-router'); if (router) { if (ev != null) { diff --git a/core/tslint.json b/core/tslint.json index acc99d9649..30987e5c35 100644 --- a/core/tslint.json +++ b/core/tslint.json @@ -15,6 +15,7 @@ "no-null-keyword": false, "no-console": false, "no-unbound-method": true, + "no-floating-promises": true, "jsx-key": false, "jsx-self-close": false,