Merge branch 'master' into v4

This commit is contained in:
Adam Bradley
2017-05-01 10:17:51 -05:00
15 changed files with 226 additions and 65 deletions

View File

@ -4,7 +4,7 @@ import { Title, DOCUMENT } from '@angular/platform-browser';
import { IonicApp } from './app-root';
import * as Constants from './app-constants';
import { ClickBlock } from './click-block';
import { runInDev } from '../../util/util';
import { runInDev, assert } from '../../util/util';
import { Config } from '../../config/config';
import { isNav, NavOptions, DIRECTION_FORWARD, DIRECTION_BACK } from '../../navigation/nav-util';
import { MenuController } from './menu-controller';
@ -226,6 +226,8 @@ export class App {
* @hidden
*/
present(enteringView: ViewController, opts: NavOptions, appPortal?: number): Promise<any> {
assert(enteringView.isOverlay, 'presented view controller needs to be an overlay');
const portal = this._appRoot._getPortal(appPortal);
// Set Nav must be set here in order to dimiss() work synchnously.

View File

@ -9,6 +9,7 @@ import { Keyboard } from '../../platform/keyboard';
import { NavControllerBase } from '../../navigation/nav-controller-base';
import { Platform } from '../../platform/platform';
import { TransitionController } from '../../transitions/transition-controller';
import { ViewController } from '../../navigation/view-controller';
/**
* @hidden
@ -40,8 +41,10 @@ export class OverlayPortal extends NavControllerBase {
// on every page change make sure the portal has
// dismissed any views that should be auto dismissed on page change
app.viewDidLeave.subscribe((ev: any) => {
!ev.isOverlay && this.dismissPageChangeViews();
app.viewDidLeave.subscribe((view: ViewController) => {
if (!view.isOverlay) {
this.dismissPageChangeViews();
}
});
}

View File

@ -1,25 +0,0 @@
import { Component, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { IonicApp, IonicModule, App } from '../../../..';
@Component({
templateUrl: 'main.html'
})
export class AppComponent {
constructor(app: App) {
app.setTitle('Basic Buttons');
}
}
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
IonicModule.forRoot(AppComponent)
],
bootstrap: [IonicApp]
})
export class AppModule {}

View File

@ -0,0 +1,9 @@
import { Component } from '@angular/core';
import { PageOne } from '../pages/page-one/page-one';
@Component({
template: '<ion-nav [root]="rootPage"></ion-nav>'
})
export class AppComponent {
rootPage = PageOne;
}

View File

@ -0,0 +1,21 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { IonicApp, IonicModule } from '../../../../..';
import { AppComponent } from './app.component';
import { PageOneModule } from '../pages/page-one/page-one.module';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
IonicModule.forRoot(AppComponent, {}),
PageOneModule
],
bootstrap: [IonicApp],
entryComponents: [
]
})
export class AppModule {}

View File

@ -11,11 +11,11 @@
<h1>H1: The quick brown fox jumps over the lazy dog</h1>
<h2 primary>H2: The quick brown fox jumps over the lazy dog</h2>
<h2 ion-text color="primary">H2: The quick brown fox jumps over the lazy dog</h2>
<h3>H3: The quick brown fox jumps over the lazy dog</h3>
<h4 danger>H4: The quick brown fox jumps over the lazy dog</h4>
<h4 ion-text color="danger">H4: The quick brown fox jumps over the lazy dog</h4>
<h5>H5: The quick brown fox jumps over the lazy dog</h5>
@ -23,9 +23,9 @@
<p>
I saw a werewolf with a Chinese menu in his hand.
Walking through the <sub danger>streets</sub> of Soho in the rain.
He <i primary>was</i> looking for a place called Lee Ho Fook's.
Gonna get a <a secondary>big dish of beef chow mein.</a>
Walking through the <sub ion-text color="danger">streets</sub> of Soho in the rain.
He <i ion-text color="primary">was</i> looking for a place called Lee Ho Fook's.
Gonna get a <a ion-text color="secondary">big dish of beef chow mein.</a>
</p>
<p>
@ -34,7 +34,7 @@
Better stay away from him.
He'll rip your lungs out, Jim.
I'd like to meet his tailor.
<ion-icon danger name="cut"></ion-icon>
<ion-icon ion-text color="danger" name="cut"></ion-icon>
</p>
</ion-content>

View File

@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { IonicPageModule } from '../../../../../..';
import { PageOne } from './page-one';
@NgModule({
declarations: [
PageOne,
],
imports: [
IonicPageModule.forChild(PageOne),
],
entryComponents: [
PageOne,
]
})
export class PageOneModule {}

View File

@ -0,0 +1,10 @@
import { Component } from '@angular/core';
import { IonicPage } from '../../../../../..';
@IonicPage({
name: 'page-one'
})
@Component({
templateUrl: 'page-one.html'
})
export class PageOne { }

View File

@ -134,7 +134,8 @@ export class ItemReorderGesture {
}
private itemForCoord(coord: PointerCoordinates): HTMLElement {
const x = this.offset.x - 100;
const sideOffset = this.plt.isRTL ? 100 : -100;
const x = this.offset.x + sideOffset;
const y = coord.y;
const element = this.plt.getElementFromPoint(x, y);
return findReorderItem(element, this.reorderList.getNativeElement());

View File

@ -151,6 +151,7 @@ export class Select extends BaseInput<any> implements OnDestroy {
_multi: boolean = false;
_options: QueryList<Option>;
_overlay: ActionSheet | Alert | Popover;
_texts: string[] = [];
_text: string = '';
@ -364,6 +365,7 @@ export class Select extends BaseInput<any> implements OnDestroy {
overlay.present(selectOptions);
this._fireFocus();
overlay.onDidDismiss((value: any) => {
this._fireBlur();
@ -371,9 +373,23 @@ export class Select extends BaseInput<any> implements OnDestroy {
this.value = value;
this.ionChange.emit(value);
}
this._overlay = undefined;
});
this._overlay = overlay;
}
/**
* Close the select interface.
*/
close() {
if (!this._overlay || !this.isFocus()) {
return;
}
return this._overlay.dismiss();
}
/**
* @input {boolean} If true, the element can accept multiple values.

View File

@ -1117,7 +1117,7 @@ export class NavControllerBase extends Ion implements NavController {
dismissPageChangeViews() {
for (let view of this._views) {
if (view.data && view.data.dismissOnPageChange) {
view.dismiss().catch(null);
view.dismiss().catch(() => {});
}
}
}

View File

@ -2,30 +2,30 @@ import { NavOptions } from './nav-util';
export interface Nav {
goToRoot(opts: NavOptions): Promise<any>;
};
}
export interface Tabs {
_tabs: Tab[];
select(tabOrIndex: number | Tab, opts: NavOptions): void;
_top: number;
setTabbarPosition(top: number, bottom: number): void;
};
}
export interface Tab {
tabUrlPath: string;
tabTitle: string;
index: number;
};
}
export interface Content {
resize(): void;
};
}
export interface Footer {
};
}
export interface Header {
};
}
export interface Navbar {
setBackButtonText(backButtonText: string): void;

View File

@ -74,29 +74,27 @@ export interface LoadedModule {
/**
* @hidden
*/
export function setupPreloadingImplementation(config: Config, deepLinkConfig: DeepLinkConfig, moduleLoader: ModuleLoader) {
if (config.getBoolean('preloadModules')) {
const linksToLoad = deepLinkConfig.links.filter(link => !!link.loadChildren && link.priority !== 'off');
export function setupPreloadingImplementation(config: Config, deepLinkConfig: DeepLinkConfig, moduleLoader: ModuleLoader): Promise<any> {
if (!deepLinkConfig || !deepLinkConfig.links || !config.getBoolean('preloadModules')) {
return Promise.resolve();
}
const linksToLoad = deepLinkConfig.links.filter(link => !!link.loadChildren && link.priority !== 'off');
// Load the high priority modules first
const highPriorityPromises = linksToLoad.map(link => {
if (link.priority === 'high') {
return moduleLoader.load(link.loadChildren);
}
});
// Load the high priority modules first
const highPriorityPromises = linksToLoad
.filter(link => link.priority === 'high')
.map(link => moduleLoader.load(link.loadChildren));
Promise.all(highPriorityPromises).then(() => {
// Load the low priority modules after the high priority are done
const lowPriorityPromises = linksToLoad.map(link => {
if (link.priority === 'low') {
return moduleLoader.load(link.loadChildren);
}
});
return Promise.all(lowPriorityPromises);
}).catch(err => {
console.error(err.message);
});
}
return Promise.all(highPriorityPromises).then(() => {
// Load the low priority modules after the high priority are done
const lowPriorityPromises = linksToLoad
.filter(link => link.priority === 'low')
.map(link => moduleLoader.load(link.loadChildren));
return Promise.all(lowPriorityPromises);
}).catch(err => {
console.error(err.message);
});
}
/**

View File

@ -1,6 +1,8 @@
import { ModuleLoader, LAZY_LOADED_TOKEN } from '../module-loader';
import { mockModuleLoader, mockNgModuleLoader } from '../mock-providers';
import { ModuleLoader, LAZY_LOADED_TOKEN, setupPreloadingImplementation } from '../module-loader';
import { mockModuleLoader, mockNgModuleLoader, mockConfig } from '../mock-providers';
import { NgModuleLoader } from '../ng-module-loader';
import { Config } from '../../config/config';
import { DeepLinkConfig } from '../../navigation/nav-util';
describe('module-loader', () => {
@ -115,12 +117,119 @@ describe('module-loader', () => {
});
describe('setupPreloadingImplementation', () => {
it('should return a promise', (done: Function) => {
let promise = setupPreloadingImplementation(config, null, moduleLoader);
promise.then((response) => {
done();
}).catch((err: Error) => {
fail(err);
done(err);
});
});
it('should not call ModuleLoader when preloading disabled', (done: Function) => {
spyOn(moduleLoader, 'load').and.returnValue(Promise.resolve());
config.set('preloadModules', false);
const deepLinkConfig: DeepLinkConfig = {
links: []
};
let promise = setupPreloadingImplementation(config, deepLinkConfig, moduleLoader);
promise.then((response) => {
expect(moduleLoader.load).not.toHaveBeenCalled();
done();
}).catch((err: Error) => {
fail(err);
done(err);
});
});
it('should not call ModuleLoader when deepLinkConfig missing', (done: Function) => {
spyOn(moduleLoader, 'load').and.returnValue(Promise.resolve());
config.set('preloadModules', true);
let promise = setupPreloadingImplementation(config, null, moduleLoader);
promise.then((response) => {
expect(moduleLoader.load).not.toHaveBeenCalled();
done();
}).catch((err: Error) => {
fail(err);
done(err);
});
});
it('should not call ModuleLoader when no low or high priority links', (done: Function) => {
spyOn(moduleLoader, 'load').and.returnValue(Promise.resolve());
config.set('preloadModules', true);
const deepLinkConfig: DeepLinkConfig = {
links: [{
loadChildren: 'offString',
priority: 'off'
}]
};
let promise = setupPreloadingImplementation(config, deepLinkConfig, moduleLoader);
promise.then((response) => {
expect(moduleLoader.load).not.toHaveBeenCalled();
done();
}).catch((err: Error) => {
fail(err);
done(err);
});
});
it('should call ModuleLoader when has low priority links', (done: Function) => {
spyOn(moduleLoader, 'load').and.returnValue(Promise.resolve());
config.set('preloadModules', true);
const deepLinkConfig: DeepLinkConfig = {
links: [{
loadChildren: 'lowString',
priority: 'low'
}]
};
let promise = setupPreloadingImplementation(config, deepLinkConfig, moduleLoader);
promise.then((response) => {
expect(moduleLoader.load).toHaveBeenCalledWith('lowString');
done();
}).catch((err: Error) => {
fail(err);
done(err);
});
});
it('should call ModuleLoader when has high priority links', (done: Function) => {
spyOn(moduleLoader, 'load').and.returnValue(Promise.resolve());
config.set('preloadModules', true);
const deepLinkConfig: DeepLinkConfig = {
links: [{
loadChildren: 'highString',
priority: 'high'
}]
};
let promise = setupPreloadingImplementation(config, deepLinkConfig, moduleLoader);
promise.then((response) => {
expect(moduleLoader.load).toHaveBeenCalledWith('highString');
done();
}).catch((err: Error) => {
fail(err);
done(err);
});
});
});
var moduleLoader: ModuleLoader;
var ngModuleLoader: NgModuleLoader;
var config: Config;
beforeEach(() => {
ngModuleLoader = mockNgModuleLoader();
moduleLoader = mockModuleLoader(ngModuleLoader);
config = mockConfig();
});
});