mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 19:21:34 +08:00
chore(): begin adding ionic components to mono-repo.
This commit is contained in:
182
packages/ionic-angular/src/util/events.ts
Normal file
182
packages/ionic-angular/src/util/events.ts
Normal file
@ -0,0 +1,182 @@
|
||||
import { DomController } from '../platform/dom-controller';
|
||||
import { Platform } from '../platform/platform';
|
||||
import { ScrollView } from './scroll-view';
|
||||
|
||||
/**
|
||||
* @name Events
|
||||
* @description
|
||||
* Events is a publish-subscribe style event system for sending and responding to application-level
|
||||
* events across your app.
|
||||
*
|
||||
* @usage
|
||||
* ```ts
|
||||
* import { Events } from 'ionic-angular';
|
||||
*
|
||||
* // first page (publish an event when a user is created)
|
||||
* constructor(public events: Events) {}
|
||||
* createUser(user) {
|
||||
* console.log('User created!')
|
||||
* events.publish('user:created', user, Date.now());
|
||||
* }
|
||||
*
|
||||
*
|
||||
* // second page (listen for the user created event after function is called)
|
||||
* constructor(public events: Events) {
|
||||
* events.subscribe('user:created', (user, time) => {
|
||||
* // user and time are the same arguments passed in `events.publish(user, time)`
|
||||
* console.log('Welcome', user, 'at', time);
|
||||
* });
|
||||
* }
|
||||
*
|
||||
* ```
|
||||
* @demo /docs/demos/src/events/
|
||||
*/
|
||||
export class Events {
|
||||
private _channels: any = [];
|
||||
|
||||
/**
|
||||
* Subscribe to an event topic. Events that get posted to that topic will trigger the provided handler.
|
||||
*
|
||||
* @param {string} topic the topic to subscribe to
|
||||
* @param {function} handler the event handler
|
||||
*/
|
||||
subscribe(topic: string, ...handlers: Function[]) {
|
||||
if (!this._channels[topic]) {
|
||||
this._channels[topic] = [];
|
||||
}
|
||||
handlers.forEach((handler) => {
|
||||
this._channels[topic].push(handler);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from the given topic. Your handler will no longer receive events published to this topic.
|
||||
*
|
||||
* @param {string} topic the topic to unsubscribe from
|
||||
* @param {function} handler the event handler
|
||||
*
|
||||
* @return true if a handler was removed
|
||||
*/
|
||||
unsubscribe(topic: string, handler: Function = null) {
|
||||
let t = this._channels[topic];
|
||||
if (!t) {
|
||||
// Wasn't found, wasn't removed
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!handler) {
|
||||
// Remove all handlers for this topic
|
||||
delete this._channels[topic];
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need to find and remove a specific handler
|
||||
let i = t.indexOf(handler);
|
||||
|
||||
if (i < 0) {
|
||||
// Wasn't found, wasn't removed
|
||||
return false;
|
||||
}
|
||||
|
||||
t.splice(i, 1);
|
||||
|
||||
// If the channel is empty now, remove it from the channel map
|
||||
if (!t.length) {
|
||||
delete this._channels[topic];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish an event to the given topic.
|
||||
*
|
||||
* @param {string} topic the topic to publish to
|
||||
* @param {any} eventData the data to send as the event
|
||||
*/
|
||||
publish(topic: string, ...args: any[]) {
|
||||
var t = this._channels[topic];
|
||||
if (!t) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let responses: any[] = [];
|
||||
t.forEach((handler: any) => {
|
||||
responses.push(handler(...args));
|
||||
});
|
||||
return responses;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
export function setupEvents(plt: Platform, dom: DomController): Events {
|
||||
const events = new Events();
|
||||
const win = plt.win();
|
||||
const doc = plt.doc();
|
||||
|
||||
// start listening for resizes XXms after the app starts
|
||||
plt.timeout(() => {
|
||||
win.addEventListener('online', (ev) => {
|
||||
events.publish('app:online', ev);
|
||||
}, false);
|
||||
|
||||
win.addEventListener('offline', (ev) => {
|
||||
events.publish('app:offline', ev);
|
||||
}, false);
|
||||
|
||||
win.addEventListener('orientationchange', (ev) => {
|
||||
events.publish('app:rotated', ev);
|
||||
});
|
||||
|
||||
// When that status taps, we respond
|
||||
win.addEventListener('statusTap', () => {
|
||||
// TODO: Make this more better
|
||||
let el = <HTMLElement>doc.elementFromPoint(plt.width() / 2, plt.height() / 2);
|
||||
if (!el) { return; }
|
||||
|
||||
let contentEle = <any>el.closest('.scroll-content');
|
||||
if (contentEle) {
|
||||
var style = contentEle.style;
|
||||
var scroll = new ScrollView(null, plt, dom);
|
||||
scroll._el = contentEle;
|
||||
// We need to stop scrolling if it's happening and scroll up
|
||||
|
||||
style['WebkitBackfaceVisibility'] = 'hidden';
|
||||
style['WebkitTransform'] = 'translate3d(0,0,0)';
|
||||
|
||||
dom.write(function() {
|
||||
style.overflow = 'hidden';
|
||||
|
||||
function finish() {
|
||||
style.overflow = '';
|
||||
style['WebkitBackfaceVisibility'] = '';
|
||||
style['WebkitTransform'] = '';
|
||||
}
|
||||
|
||||
let didScrollTimeout = plt.timeout(() => {
|
||||
finish();
|
||||
}, 400);
|
||||
|
||||
scroll.scrollTo(0, 0, 300).then(() => {
|
||||
plt.cancelTimeout(didScrollTimeout);
|
||||
finish();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}, 2000);
|
||||
|
||||
return events;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
export function setupProvideEvents(plt: Platform, dom: DomController) {
|
||||
return function() {
|
||||
return setupEvents(plt, dom);
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user