mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 20:33:32 +08:00
Merge branch 'master' into v4
This commit is contained in:
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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 {}
|
9
src/components/app/test/typography/app/app.component.ts
Normal file
9
src/components/app/test/typography/app/app.component.ts
Normal 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;
|
||||
}
|
21
src/components/app/test/typography/app/app.module.ts
Normal file
21
src/components/app/test/typography/app/app.module.ts
Normal 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 {}
|
@ -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>
|
@ -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 {}
|
@ -0,0 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { IonicPage } from '../../../../../..';
|
||||
|
||||
@IonicPage({
|
||||
name: 'page-one'
|
||||
})
|
||||
@Component({
|
||||
templateUrl: 'page-one.html'
|
||||
})
|
||||
export class PageOne { }
|
@ -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());
|
||||
|
@ -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.
|
||||
|
@ -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(() => {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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();
|
||||
});
|
||||
|
||||
});
|
||||
|
Reference in New Issue
Block a user