mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-22 05:21:52 +08:00
feat(DomController): organize dom reads/writes
This commit is contained in:
@ -10,8 +10,11 @@ import { HttpModule } from '@angular/http';
|
|||||||
import { ActionSheetController } from './components/action-sheet/action-sheet';
|
import { ActionSheetController } from './components/action-sheet/action-sheet';
|
||||||
import { AlertController } from './components/alert/alert';
|
import { AlertController } from './components/alert/alert';
|
||||||
import { App } from './components/app/app';
|
import { App } from './components/app/app';
|
||||||
|
import { AppRootToken } from './components/app/app-root';
|
||||||
|
import { ClickBlock } from './util/click-block';
|
||||||
import { Config, ConfigToken, setupConfig } from './config/config';
|
import { Config, ConfigToken, setupConfig } from './config/config';
|
||||||
import { DeepLinker, setupDeepLinker } from './navigation/deep-linker';
|
import { DeepLinker, setupDeepLinker } from './navigation/deep-linker';
|
||||||
|
import { DomController } from './util/dom-controller';
|
||||||
import { Events, setupProvideEvents } from './util/events';
|
import { Events, setupProvideEvents } from './util/events';
|
||||||
import { Form } from './util/form';
|
import { Form } from './util/form';
|
||||||
import { GestureController } from './gestures/gesture-controller';
|
import { GestureController } from './gestures/gesture-controller';
|
||||||
@ -31,9 +34,7 @@ import { ToastController } from './components/toast/toast';
|
|||||||
import { registerModeConfigs } from './config/mode-registry';
|
import { registerModeConfigs } from './config/mode-registry';
|
||||||
import { registerTransitions } from './transitions/transition-registry';
|
import { registerTransitions } from './transitions/transition-registry';
|
||||||
import { TransitionController } from './transitions/transition-controller';
|
import { TransitionController } from './transitions/transition-controller';
|
||||||
import { AppRootToken } from './components/app/app-root';
|
|
||||||
import { UrlSerializer, setupUrlSerializer, DeepLinkConfigToken } from './navigation/url-serializer';
|
import { UrlSerializer, setupUrlSerializer, DeepLinkConfigToken } from './navigation/url-serializer';
|
||||||
import { ClickBlock } from './util/click-block';
|
|
||||||
/**
|
/**
|
||||||
* Import Overlay Entry Components
|
* Import Overlay Entry Components
|
||||||
*/
|
*/
|
||||||
@ -51,6 +52,7 @@ import { ToastCmp } from './components/toast/toast-component';
|
|||||||
* Export Providers
|
* Export Providers
|
||||||
*/
|
*/
|
||||||
export { Config, setupConfig, ConfigToken } from './config/config';
|
export { Config, setupConfig, ConfigToken } from './config/config';
|
||||||
|
export { DomController } from './util/dom-controller';
|
||||||
export { Platform, setupPlatform, UserAgentToken, DocumentDirToken, DocLangToken, NavigatorPlatformToken } from './platform/platform';
|
export { Platform, setupPlatform, UserAgentToken, DocumentDirToken, DocLangToken, NavigatorPlatformToken } from './platform/platform';
|
||||||
export { Haptic } from './util/haptic';
|
export { Haptic } from './util/haptic';
|
||||||
export { QueryParams, setupQueryParams, UrlToken } from './platform/query-params';
|
export { QueryParams, setupQueryParams, UrlToken } from './platform/query-params';
|
||||||
@ -102,13 +104,13 @@ export { ViewController } from './navigation/view-controller';
|
|||||||
declarations: [
|
declarations: [
|
||||||
ActionSheetCmp,
|
ActionSheetCmp,
|
||||||
AlertCmp,
|
AlertCmp,
|
||||||
|
ClickBlock,
|
||||||
IONIC_DIRECTIVES,
|
IONIC_DIRECTIVES,
|
||||||
LoadingCmp,
|
LoadingCmp,
|
||||||
ModalCmp,
|
ModalCmp,
|
||||||
PickerCmp,
|
PickerCmp,
|
||||||
PopoverCmp,
|
PopoverCmp,
|
||||||
ToastCmp,
|
ToastCmp
|
||||||
ClickBlock
|
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
ActionSheetCmp,
|
ActionSheetCmp,
|
||||||
@ -154,7 +156,7 @@ export class IonicModule {
|
|||||||
// useFactory: ionic app initializers
|
// useFactory: ionic app initializers
|
||||||
{ provide: APP_INITIALIZER, useFactory: registerModeConfigs, deps: [ Config ], multi: true },
|
{ provide: APP_INITIALIZER, useFactory: registerModeConfigs, deps: [ Config ], multi: true },
|
||||||
{ provide: APP_INITIALIZER, useFactory: registerTransitions, deps: [ Config ], multi: true },
|
{ provide: APP_INITIALIZER, useFactory: registerTransitions, deps: [ Config ], multi: true },
|
||||||
{ provide: APP_INITIALIZER, useFactory: setupProvideEvents, deps: [ Platform ], multi: true },
|
{ provide: APP_INITIALIZER, useFactory: setupProvideEvents, deps: [ Platform, DomController ], multi: true },
|
||||||
{ provide: APP_INITIALIZER, useFactory: setupTapClick, deps: [ Config, App, NgZone, GestureController ], multi: true },
|
{ provide: APP_INITIALIZER, useFactory: setupTapClick, deps: [ Config, App, NgZone, GestureController ], multi: true },
|
||||||
|
|
||||||
// useClass
|
// useClass
|
||||||
@ -167,10 +169,11 @@ export class IonicModule {
|
|||||||
ActionSheetController,
|
ActionSheetController,
|
||||||
AlertController,
|
AlertController,
|
||||||
App,
|
App,
|
||||||
|
DomController,
|
||||||
Events,
|
Events,
|
||||||
Form,
|
Form,
|
||||||
Haptic,
|
|
||||||
GestureController,
|
GestureController,
|
||||||
|
Haptic,
|
||||||
Keyboard,
|
Keyboard,
|
||||||
LoadingController,
|
LoadingController,
|
||||||
Location,
|
Location,
|
||||||
|
71
src/util/dom-controller.ts
Normal file
71
src/util/dom-controller.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* Adopted from FastDom
|
||||||
|
* https://github.com/wilsonpage/fastdom
|
||||||
|
* MIT License
|
||||||
|
*/
|
||||||
|
import { nativeRaf } from './dom';
|
||||||
|
import { removeArrayItem } from './util';
|
||||||
|
|
||||||
|
|
||||||
|
export class DomController {
|
||||||
|
private r: Function[] = [];
|
||||||
|
private w: Function[] = [];
|
||||||
|
private q: boolean;
|
||||||
|
|
||||||
|
read(fn: Function, ctx?: any): Function {
|
||||||
|
const task = !ctx ? fn : fn.bind(ctx);
|
||||||
|
this.r.push(task);
|
||||||
|
this.queue();
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
write(fn: Function, ctx?: any): Function {
|
||||||
|
const task = !ctx ? fn : fn.bind(ctx);
|
||||||
|
this.w.push(task);
|
||||||
|
this.queue();
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel(task: any) {
|
||||||
|
return removeArrayItem(this.r, task) || removeArrayItem(this.w, task);
|
||||||
|
}
|
||||||
|
|
||||||
|
private queue() {
|
||||||
|
if (!this.q) {
|
||||||
|
this.q = true;
|
||||||
|
nativeRaf(timestamp => {
|
||||||
|
this.flush(timestamp);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private flush(timestamp: number) {
|
||||||
|
let err;
|
||||||
|
let task;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// ******** DOM READS ****************
|
||||||
|
while (task = this.r.shift()) {
|
||||||
|
task(timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ******** DOM WRITES ****************
|
||||||
|
while (task = this.w.shift()) {
|
||||||
|
task(timestamp);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
err = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.q = false;
|
||||||
|
|
||||||
|
if (this.r.length || this.w.length) {
|
||||||
|
this.queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
import { DomController } from '../util/dom-controller';
|
||||||
import { nativeTimeout, nativeRaf } from '../util/dom';
|
import { nativeTimeout, nativeRaf } from '../util/dom';
|
||||||
import { Platform } from '../platform/platform';
|
import { Platform } from '../platform/platform';
|
||||||
import { ScrollView } from '../util/scroll-view';
|
import { ScrollView } from '../util/scroll-view';
|
||||||
@ -109,7 +110,7 @@ export class Events {
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
export function setupEvents(platform: Platform): Events {
|
export function setupEvents(platform: Platform, dom: DomController): Events {
|
||||||
const events = new Events();
|
const events = new Events();
|
||||||
|
|
||||||
// start listening for resizes XXms after the app starts
|
// start listening for resizes XXms after the app starts
|
||||||
@ -134,7 +135,7 @@ export function setupEvents(platform: Platform): Events {
|
|||||||
|
|
||||||
let content = <HTMLElement>el.closest('.scroll-content');
|
let content = <HTMLElement>el.closest('.scroll-content');
|
||||||
if (content) {
|
if (content) {
|
||||||
var scroll = new ScrollView(content);
|
var scroll = new ScrollView(content, dom);
|
||||||
// We need to stop scrolling if it's happening and scroll up
|
// We need to stop scrolling if it's happening and scroll up
|
||||||
|
|
||||||
content.style['WebkitBackfaceVisibility'] = 'hidden';
|
content.style['WebkitBackfaceVisibility'] = 'hidden';
|
||||||
@ -173,8 +174,8 @@ export function setupEvents(platform: Platform): Events {
|
|||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
export function setupProvideEvents(platform: Platform) {
|
export function setupProvideEvents(platform: Platform, dom: DomController) {
|
||||||
return function() {
|
return function() {
|
||||||
return setupEvents(platform);
|
return setupEvents(platform, dom);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user