UNPKG

angular2

Version:

Angular 2 - a web framework for modern web apps

140 lines (139 loc) 5.54 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; import { BaseException } from 'angular2/src/facade/exceptions'; import { EventEmitter, ObservableWrapper } from 'angular2/src/facade/async'; import { StringMapWrapper } from 'angular2/src/facade/collection'; import { Injectable } from "angular2/src/core/di"; export class PostMessageBusSink { constructor(_postMessageTarget) { this._postMessageTarget = _postMessageTarget; this._channels = StringMapWrapper.create(); this._messageBuffer = []; } attachToZone(zone) { this._zone = zone; this._zone.runOutsideAngular(() => { ObservableWrapper.subscribe(this._zone.onStable, (_) => { this._handleOnEventDone(); }); }); } initChannel(channel, runInZone = true) { if (StringMapWrapper.contains(this._channels, channel)) { throw new BaseException(`${channel} has already been initialized`); } var emitter = new EventEmitter(false); var channelInfo = new _Channel(emitter, runInZone); this._channels[channel] = channelInfo; emitter.subscribe((data) => { var message = { channel: channel, message: data }; if (runInZone) { this._messageBuffer.push(message); } else { this._sendMessages([message]); } }); } to(channel) { if (StringMapWrapper.contains(this._channels, channel)) { return this._channels[channel].emitter; } else { throw new BaseException(`${channel} is not set up. Did you forget to call initChannel?`); } } _handleOnEventDone() { if (this._messageBuffer.length > 0) { this._sendMessages(this._messageBuffer); this._messageBuffer = []; } } _sendMessages(messages) { this._postMessageTarget.postMessage(messages); } } export class PostMessageBusSource { constructor(eventTarget) { this._channels = StringMapWrapper.create(); if (eventTarget) { eventTarget.addEventListener("message", (ev) => this._handleMessages(ev)); } else { // if no eventTarget is given we assume we're in a WebWorker and listen on the global scope addEventListener("message", (ev) => this._handleMessages(ev)); } } attachToZone(zone) { this._zone = zone; } initChannel(channel, runInZone = true) { if (StringMapWrapper.contains(this._channels, channel)) { throw new BaseException(`${channel} has already been initialized`); } var emitter = new EventEmitter(false); var channelInfo = new _Channel(emitter, runInZone); this._channels[channel] = channelInfo; } from(channel) { if (StringMapWrapper.contains(this._channels, channel)) { return this._channels[channel].emitter; } else { throw new BaseException(`${channel} is not set up. Did you forget to call initChannel?`); } } _handleMessages(ev) { var messages = ev.data; for (var i = 0; i < messages.length; i++) { this._handleMessage(messages[i]); } } _handleMessage(data) { var channel = data.channel; if (StringMapWrapper.contains(this._channels, channel)) { var channelInfo = this._channels[channel]; if (channelInfo.runInZone) { this._zone.run(() => { channelInfo.emitter.emit(data.message); }); } else { channelInfo.emitter.emit(data.message); } } } } /** * A TypeScript implementation of {@link MessageBus} for communicating via JavaScript's * postMessage API. */ export let PostMessageBus = class PostMessageBus { constructor(sink, source) { this.sink = sink; this.source = source; } attachToZone(zone) { this.source.attachToZone(zone); this.sink.attachToZone(zone); } initChannel(channel, runInZone = true) { this.source.initChannel(channel, runInZone); this.sink.initChannel(channel, runInZone); } from(channel) { return this.source.from(channel); } to(channel) { return this.sink.to(channel); } }; PostMessageBus = __decorate([ Injectable(), __metadata('design:paramtypes', [PostMessageBusSink, PostMessageBusSource]) ], PostMessageBus); /** * Helper class that wraps a channel's {@link EventEmitter} and * keeps track of if it should run in the zone. */ class _Channel { constructor(emitter, runInZone) { this.emitter = emitter; this.runInZone = runInZone; } }