@ -8,7 +8,7 @@
|
||||
|
||||
import {PlatformRef, StaticProvider} from '@angular/core';
|
||||
|
||||
import {WORKER_SCRIPT, platformWorkerUi} from './worker_render';
|
||||
import {platformWorkerUi, WORKER_SCRIPT} from './worker_render';
|
||||
|
||||
export {VERSION} from './version';
|
||||
export {ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments} from './web_workers/shared/client_message_broker';
|
||||
@ -17,7 +17,7 @@ export {SerializerTypes} from './web_workers/shared/serializer';
|
||||
export {ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory} from './web_workers/shared/service_message_broker';
|
||||
export {WORKER_UI_LOCATION_PROVIDERS} from './web_workers/ui/location_providers';
|
||||
export {WORKER_APP_LOCATION_PROVIDERS} from './web_workers/worker/location_providers';
|
||||
export {WorkerAppModule, platformWorkerApp} from './worker_app';
|
||||
export {platformWorkerApp, WorkerAppModule} from './worker_app';
|
||||
export {platformWorkerUi} from './worker_render';
|
||||
|
||||
/**
|
||||
|
@ -83,8 +83,10 @@ export class ClientMessageBroker {
|
||||
let promise: Promise<any>|null;
|
||||
let id: string|null = null;
|
||||
if (returnType != null) {
|
||||
let completer: PromiseCompleter = undefined !;
|
||||
promise = new Promise((resolve, reject) => { completer = {resolve, reject}; });
|
||||
let completer: PromiseCompleter = undefined!;
|
||||
promise = new Promise((resolve, reject) => {
|
||||
completer = {resolve, reject};
|
||||
});
|
||||
id = this._generateMessageId(args.method);
|
||||
this._pending.set(id, completer);
|
||||
|
||||
@ -117,12 +119,12 @@ export class ClientMessageBroker {
|
||||
|
||||
private _handleMessage(message: ResponseMessageData): void {
|
||||
if (message.type === 'result' || message.type === 'error') {
|
||||
const id = message.id !;
|
||||
const id = message.id!;
|
||||
if (this._pending.has(id)) {
|
||||
if (message.type === 'result') {
|
||||
this._pending.get(id) !.resolve(message.value);
|
||||
this._pending.get(id)!.resolve(message.value);
|
||||
} else {
|
||||
this._pending.get(id) !.reject(message.value);
|
||||
this._pending.get(id)!.reject(message.value);
|
||||
}
|
||||
this._pending.delete(id);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ export interface PostMessageTarget {
|
||||
|
||||
export class PostMessageBusSink implements MessageBusSink {
|
||||
// TODO(issue/24571): remove '!'.
|
||||
private _zone !: NgZone;
|
||||
private _zone!: NgZone;
|
||||
private _channels: {[key: string]: _Channel} = {};
|
||||
private _messageBuffer: Array<Object> = [];
|
||||
|
||||
@ -27,8 +27,13 @@ export class PostMessageBusSink implements MessageBusSink {
|
||||
|
||||
attachToZone(zone: NgZone): void {
|
||||
this._zone = zone;
|
||||
this._zone.runOutsideAngular(
|
||||
() => { this._zone.onStable.subscribe({next: () => { this._handleOnEventDone(); }}); });
|
||||
this._zone.runOutsideAngular(() => {
|
||||
this._zone.onStable.subscribe({
|
||||
next: () => {
|
||||
this._handleOnEventDone();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
initChannel(channel: string, runInZone: boolean = true): void {
|
||||
@ -64,12 +69,14 @@ export class PostMessageBusSink implements MessageBusSink {
|
||||
}
|
||||
}
|
||||
|
||||
private _sendMessages(messages: Array<Object>) { this._postMessageTarget.postMessage(messages); }
|
||||
private _sendMessages(messages: Array<Object>) {
|
||||
this._postMessageTarget.postMessage(messages);
|
||||
}
|
||||
}
|
||||
|
||||
export class PostMessageBusSource implements MessageBusSource {
|
||||
// TODO(issue/24571): remove '!'.
|
||||
private _zone !: NgZone;
|
||||
private _zone!: NgZone;
|
||||
private _channels: {[key: string]: _Channel} = {};
|
||||
|
||||
constructor(eventTarget?: EventTarget) {
|
||||
@ -82,7 +89,9 @@ export class PostMessageBusSource implements MessageBusSource {
|
||||
}
|
||||
}
|
||||
|
||||
attachToZone(zone: NgZone) { this._zone = zone; }
|
||||
attachToZone(zone: NgZone) {
|
||||
this._zone = zone;
|
||||
}
|
||||
|
||||
initChannel(channel: string, runInZone: boolean = true) {
|
||||
if (this._channels.hasOwnProperty(channel)) {
|
||||
@ -114,7 +123,9 @@ export class PostMessageBusSource implements MessageBusSource {
|
||||
if (this._channels.hasOwnProperty(channel)) {
|
||||
const channelInfo = this._channels[channel];
|
||||
if (channelInfo.runInZone) {
|
||||
this._zone.run(() => { channelInfo.emitter.emit(data.message); });
|
||||
this._zone.run(() => {
|
||||
channelInfo.emitter.emit(data.message);
|
||||
});
|
||||
} else {
|
||||
channelInfo.emitter.emit(data.message);
|
||||
}
|
||||
@ -140,9 +151,13 @@ export class PostMessageBus implements MessageBus {
|
||||
this.sink.initChannel(channel, runInZone);
|
||||
}
|
||||
|
||||
from(channel: string): EventEmitter<any> { return this.source.from(channel); }
|
||||
from(channel: string): EventEmitter<any> {
|
||||
return this.source.from(channel);
|
||||
}
|
||||
|
||||
to(channel: string): EventEmitter<any> { return this.sink.to(channel); }
|
||||
to(channel: string): EventEmitter<any> {
|
||||
return this.sink.to(channel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,9 @@ export class RenderStore {
|
||||
private _lookupById = new Map<number, any>();
|
||||
private _lookupByObject = new Map<any, number>();
|
||||
|
||||
allocateId(): number { return this._nextIndex++; }
|
||||
allocateId(): number {
|
||||
return this._nextIndex++;
|
||||
}
|
||||
|
||||
store(obj: any, id: number): void {
|
||||
if (id == null) return;
|
||||
|
@ -42,7 +42,7 @@ export class Serializer {
|
||||
return obj.map(v => this.serialize(v, type));
|
||||
}
|
||||
if (type === SerializerTypes.RENDER_STORE_OBJECT) {
|
||||
return this._renderStore.serialize(obj) !;
|
||||
return this._renderStore.serialize(obj)!;
|
||||
}
|
||||
if (type === SerializerTypes.RENDERER_TYPE_2) {
|
||||
return this._serializeRendererType2(obj);
|
||||
|
@ -63,7 +63,7 @@ export class ServiceMessageBroker {
|
||||
const deserializedArgs = [];
|
||||
for (let i = 0; i < numArgs; i++) {
|
||||
const serializedArg = serializedArgs[i];
|
||||
deserializedArgs[i] = this._serializer.deserialize(serializedArg, signature ![i]);
|
||||
deserializedArgs[i] = this._serializer.deserialize(serializedArg, signature![i]);
|
||||
}
|
||||
|
||||
const promise = method(...deserializedArgs);
|
||||
@ -75,7 +75,7 @@ export class ServiceMessageBroker {
|
||||
|
||||
private _handleMessage(message: ReceivedMessage): void {
|
||||
if (this._methods.has(message.method)) {
|
||||
this._methods.get(message.method) !(message);
|
||||
this._methods.get(message.method)!(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,10 @@ import {MessageBasedPlatformLocation} from './platform_location';
|
||||
* @deprecated platform-webworker is deprecated in Angular and will be removed in version 10
|
||||
*/
|
||||
export const WORKER_UI_LOCATION_PROVIDERS = <StaticProvider[]>[
|
||||
{provide: MessageBasedPlatformLocation, deps: [ServiceMessageBrokerFactory,
|
||||
BrowserPlatformLocation, MessageBus, Serializer]},
|
||||
{
|
||||
provide: MessageBasedPlatformLocation,
|
||||
deps: [ServiceMessageBrokerFactory, BrowserPlatformLocation, MessageBus, Serializer]
|
||||
},
|
||||
{provide: BrowserPlatformLocation, deps: [DOCUMENT]},
|
||||
{provide: PLATFORM_INITIALIZER, useFactory: initUiLocation, multi: true, deps: [Injector]}
|
||||
];
|
||||
|
@ -56,5 +56,7 @@ export class MessageBasedPlatformLocation {
|
||||
});
|
||||
}
|
||||
|
||||
private _setPathname(pathname: string): void { this._platformLocation.pathname = pathname; }
|
||||
private _setPathname(pathname: string): void {
|
||||
this._platformLocation.pathname = pathname;
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import {EventDispatcher} from '../ui/event_dispatcher';
|
||||
@Injectable()
|
||||
export class MessageBasedRenderer2 {
|
||||
// TODO(issue/24571): remove '!'.
|
||||
private _eventDispatcher !: EventDispatcher;
|
||||
private _eventDispatcher!: EventDispatcher;
|
||||
|
||||
constructor(
|
||||
private _brokerFactory: ServiceMessageBrokerFactory, private _bus: MessageBus,
|
||||
@ -40,20 +40,26 @@ export class MessageBasedRenderer2 {
|
||||
const methods: any[][] = [
|
||||
['createRenderer', this.createRenderer, RSO, CRT, P],
|
||||
['createElement', this.createElement, RSO, P, P, P],
|
||||
['createComment', this.createComment, RSO, P, P], ['createText', this.createText, RSO, P, P],
|
||||
['createComment', this.createComment, RSO, P, P],
|
||||
['createText', this.createText, RSO, P, P],
|
||||
['appendChild', this.appendChild, RSO, RSO, RSO],
|
||||
['insertBefore', this.insertBefore, RSO, RSO, RSO, RSO],
|
||||
['removeChild', this.removeChild, RSO, RSO, RSO],
|
||||
['selectRootElement', this.selectRootElement, RSO, P, P],
|
||||
['parentNode', this.parentNode, RSO, RSO, P], ['nextSibling', this.nextSibling, RSO, RSO, P],
|
||||
['parentNode', this.parentNode, RSO, RSO, P],
|
||||
['nextSibling', this.nextSibling, RSO, RSO, P],
|
||||
['setAttribute', this.setAttribute, RSO, RSO, P, P, P],
|
||||
['removeAttribute', this.removeAttribute, RSO, RSO, P, P],
|
||||
['addClass', this.addClass, RSO, RSO, P], ['removeClass', this.removeClass, RSO, RSO, P],
|
||||
['addClass', this.addClass, RSO, RSO, P],
|
||||
['removeClass', this.removeClass, RSO, RSO, P],
|
||||
['setStyle', this.setStyle, RSO, RSO, P, P, P],
|
||||
['removeStyle', this.removeStyle, RSO, RSO, P, P],
|
||||
['setProperty', this.setProperty, RSO, RSO, P, P], ['setValue', this.setValue, RSO, RSO, P],
|
||||
['listen', this.listen, RSO, RSO, P, P, P], ['unlisten', this.unlisten, RSO, RSO],
|
||||
['destroy', this.destroy, RSO], ['destroyNode', this.destroyNode, RSO, P]
|
||||
['setProperty', this.setProperty, RSO, RSO, P, P],
|
||||
['setValue', this.setValue, RSO, RSO, P],
|
||||
['listen', this.listen, RSO, RSO, P, P, P],
|
||||
['unlisten', this.unlisten, RSO, RSO],
|
||||
['destroy', this.destroy, RSO],
|
||||
['destroyNode', this.destroyNode, RSO, P]
|
||||
|
||||
];
|
||||
|
||||
@ -62,7 +68,9 @@ export class MessageBasedRenderer2 {
|
||||
});
|
||||
}
|
||||
|
||||
private destroy(r: Renderer2) { r.destroy(); }
|
||||
private destroy(r: Renderer2) {
|
||||
r.destroy();
|
||||
}
|
||||
|
||||
private destroyNode(r: Renderer2, node: any) {
|
||||
if (r.destroyNode) {
|
||||
@ -87,13 +95,17 @@ export class MessageBasedRenderer2 {
|
||||
this._renderStore.store(r.createText(value), id);
|
||||
}
|
||||
|
||||
private appendChild(r: Renderer2, parent: any, child: any) { r.appendChild(parent, child); }
|
||||
private appendChild(r: Renderer2, parent: any, child: any) {
|
||||
r.appendChild(parent, child);
|
||||
}
|
||||
|
||||
private insertBefore(r: Renderer2, parent: any, child: any, ref: any) {
|
||||
r.insertBefore(parent, child, ref);
|
||||
}
|
||||
|
||||
private removeChild(r: Renderer2, parent: any, child: any) { r.removeChild(parent, child); }
|
||||
private removeChild(r: Renderer2, parent: any, child: any) {
|
||||
r.removeChild(parent, child);
|
||||
}
|
||||
|
||||
private selectRootElement(r: Renderer2, selector: string, id: number) {
|
||||
this._renderStore.store(r.selectRootElement(selector), id);
|
||||
@ -115,9 +127,13 @@ export class MessageBasedRenderer2 {
|
||||
r.removeAttribute(el, name, namespace);
|
||||
}
|
||||
|
||||
private addClass(r: Renderer2, el: any, name: string) { r.addClass(el, name); }
|
||||
private addClass(r: Renderer2, el: any, name: string) {
|
||||
r.addClass(el, name);
|
||||
}
|
||||
|
||||
private removeClass(r: Renderer2, el: any, name: string) { r.removeClass(el, name); }
|
||||
private removeClass(r: Renderer2, el: any, name: string) {
|
||||
r.removeClass(el, name);
|
||||
}
|
||||
|
||||
private setStyle(r: Renderer2, el: any, style: string, value: any, flags: RendererStyleFlags2) {
|
||||
r.setStyle(el, style, value, flags);
|
||||
@ -131,7 +147,9 @@ export class MessageBasedRenderer2 {
|
||||
r.setProperty(el, name, value);
|
||||
}
|
||||
|
||||
private setValue(r: Renderer2, node: any, value: string) { r.setValue(node, value); }
|
||||
private setValue(r: Renderer2, node: any, value: string) {
|
||||
r.setValue(node, value);
|
||||
}
|
||||
|
||||
private listen(r: Renderer2, el: any, elName: string, eventName: string, unlistenId: number) {
|
||||
const listener = (event: any) => {
|
||||
@ -142,5 +160,7 @@ export class MessageBasedRenderer2 {
|
||||
this._renderStore.store(unlisten, unlistenId);
|
||||
}
|
||||
|
||||
private unlisten(r: Renderer2, unlisten: () => boolean) { unlisten(); }
|
||||
private unlisten(r: Renderer2, unlisten: () => boolean) {
|
||||
unlisten();
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import {WebWorkerPlatformLocation} from './platform_location';
|
||||
* @deprecated platform-webworker is deprecated in Angular and will be removed in version 10
|
||||
*/
|
||||
export const WORKER_APP_LOCATION_PROVIDERS: StaticProvider[] = [
|
||||
{ provide: PlatformLocation, useClass: WebWorkerPlatformLocation} as any as StaticProvider, {
|
||||
{provide: PlatformLocation, useClass: WebWorkerPlatformLocation} as any as StaticProvider, {
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: appInitFnFactory,
|
||||
multi: true,
|
||||
|
@ -18,11 +18,11 @@ export class WebWorkerPlatformLocation extends PlatformLocation {
|
||||
private _broker: ClientMessageBroker;
|
||||
private _popStateListeners: Array<Function> = [];
|
||||
private _hashChangeListeners: Array<Function> = [];
|
||||
private _location: LocationType = null !;
|
||||
private _location: LocationType = null!;
|
||||
private _channelSource: EventEmitter<Object>;
|
||||
public initialized: Promise<any>;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
private initializedResolve !: () => void;
|
||||
private initializedResolve!: () => void;
|
||||
|
||||
constructor(
|
||||
brokerFactory: ClientMessageBrokerFactory, bus: MessageBus, private _serializer: Serializer) {
|
||||
@ -56,13 +56,15 @@ export class WebWorkerPlatformLocation extends PlatformLocation {
|
||||
init(): Promise<boolean> {
|
||||
const args: UiArguments = new UiArguments('getLocation');
|
||||
|
||||
return this._broker.runOnService(args, LocationType) !.then(
|
||||
return this._broker.runOnService(args, LocationType)!.then(
|
||||
(val: LocationType) => {
|
||||
this._location = val;
|
||||
this.initializedResolve();
|
||||
return true;
|
||||
},
|
||||
err => { throw new Error(err); });
|
||||
err => {
|
||||
throw new Error(err);
|
||||
});
|
||||
}
|
||||
|
||||
getBaseHrefFromDOM(): string {
|
||||
@ -70,21 +72,37 @@ export class WebWorkerPlatformLocation extends PlatformLocation {
|
||||
'Attempt to get base href from DOM from WebWorker. You must either provide a value for the APP_BASE_HREF token through DI or use the hash location strategy.');
|
||||
}
|
||||
|
||||
onPopState(fn: LocationChangeListener): void { this._popStateListeners.push(fn); }
|
||||
onPopState(fn: LocationChangeListener): void {
|
||||
this._popStateListeners.push(fn);
|
||||
}
|
||||
|
||||
onHashChange(fn: LocationChangeListener): void { this._hashChangeListeners.push(fn); }
|
||||
onHashChange(fn: LocationChangeListener): void {
|
||||
this._hashChangeListeners.push(fn);
|
||||
}
|
||||
|
||||
get href(): string { return this._location ? this._location.href ! : '<unknown>'; }
|
||||
get href(): string {
|
||||
return this._location ? this._location.href! : '<unknown>';
|
||||
}
|
||||
|
||||
get hostname(): string { return this._location ? this._location.host ! : '<unknown>'; }
|
||||
get hostname(): string {
|
||||
return this._location ? this._location.host! : '<unknown>';
|
||||
}
|
||||
|
||||
get port(): string { return this._location ? this._location.port ! : '<unknown>'; }
|
||||
get port(): string {
|
||||
return this._location ? this._location.port! : '<unknown>';
|
||||
}
|
||||
|
||||
get protocol(): string { return this._location ? this._location.protocol ! : '<unknown>'; }
|
||||
get protocol(): string {
|
||||
return this._location ? this._location.protocol! : '<unknown>';
|
||||
}
|
||||
|
||||
get search(): string { return this._location ? this._location.search : '<unknown>'; }
|
||||
get search(): string {
|
||||
return this._location ? this._location.search : '<unknown>';
|
||||
}
|
||||
|
||||
get hash(): string { return this._location ? this._location.hash : '<unknown>'; }
|
||||
get hash(): string {
|
||||
return this._location ? this._location.hash : '<unknown>';
|
||||
}
|
||||
|
||||
set pathname(newPath: string) {
|
||||
if (this._location === null) {
|
||||
@ -129,5 +147,7 @@ export class WebWorkerPlatformLocation extends PlatformLocation {
|
||||
}
|
||||
|
||||
// History API isn't available on WebWorkers, therefore return undefined
|
||||
getState(): unknown { return undefined; }
|
||||
getState(): unknown {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
@ -16,9 +16,11 @@ import {Serializer, SerializerTypes} from '../shared/serializer';
|
||||
|
||||
export class NamedEventEmitter {
|
||||
// TODO(issue/24571): remove '!'.
|
||||
private _listeners !: Map<string, Function[]>;
|
||||
private _listeners!: Map<string, Function[]>;
|
||||
|
||||
listen(eventName: string, callback: Function) { this._getListeners(eventName).push(callback); }
|
||||
listen(eventName: string, callback: Function) {
|
||||
this._getListeners(eventName).push(callback);
|
||||
}
|
||||
|
||||
unlisten(eventName: string, listener: Function) {
|
||||
const listeners = this._getListeners(eventName);
|
||||
@ -97,9 +99,13 @@ export class WebWorkerRendererFactory2 implements RendererFactory2 {
|
||||
return result;
|
||||
}
|
||||
|
||||
freeNode(node: any) { this.renderStore.remove(node); }
|
||||
freeNode(node: any) {
|
||||
this.renderStore.remove(node);
|
||||
}
|
||||
|
||||
allocateId(): number { return this.renderStore.allocateId(); }
|
||||
allocateId(): number {
|
||||
return this.renderStore.allocateId();
|
||||
}
|
||||
|
||||
private _dispatchEvent(message: {[key: string]: any}): void {
|
||||
const element: WebWorkerRenderNode =
|
||||
@ -125,7 +131,9 @@ export class WebWorkerRenderer2 implements Renderer2 {
|
||||
|
||||
private asFnArg = new FnArg(this, SerializerTypes.RENDER_STORE_OBJECT);
|
||||
|
||||
destroy(): void { this.callUIWithRenderer('destroy'); }
|
||||
destroy(): void {
|
||||
this.callUIWithRenderer('destroy');
|
||||
}
|
||||
|
||||
destroyNode(node: any) {
|
||||
this.callUIWithRenderer('destroyNode', [new FnArg(node, SerializerTypes.RENDER_STORE_OBJECT)]);
|
||||
@ -281,7 +289,7 @@ export class WebWorkerRenderer2 implements Renderer2 {
|
||||
listener: (event: any) => boolean): () => void {
|
||||
const unlistenId = this._rendererFactory.allocateId();
|
||||
|
||||
const [targetEl, targetName, fullName]: [any, string | null, string | null] =
|
||||
const [targetEl, targetName, fullName]: [any, string|null, string|null] =
|
||||
typeof target === 'string' ? [null, target, `${target}:${eventName}`] :
|
||||
[target, null, null];
|
||||
|
||||
@ -314,4 +322,6 @@ export class WebWorkerRenderer2 implements Renderer2 {
|
||||
}
|
||||
}
|
||||
|
||||
export class WebWorkerRenderNode { events = new NamedEventEmitter(); }
|
||||
export class WebWorkerRenderNode {
|
||||
events = new NamedEventEmitter();
|
||||
}
|
||||
|
@ -14,7 +14,9 @@ import {ɵDomAdapter as DomAdapter, ɵsetRootDomAdapter as setRootDomAdapter} fr
|
||||
* Note: other methods all throw as the DOM is not accessible directly in web worker context.
|
||||
*/
|
||||
export class WorkerDomAdapter extends DomAdapter {
|
||||
static makeCurrent() { setRootDomAdapter(new WorkerDomAdapter()); }
|
||||
static makeCurrent() {
|
||||
setRootDomAdapter(new WorkerDomAdapter());
|
||||
}
|
||||
|
||||
log(error: any) {
|
||||
// tslint:disable-next-line:no-console
|
||||
@ -42,25 +44,63 @@ export class WorkerDomAdapter extends DomAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
getProperty(el: Element, name: string): any { throw 'not implemented'; }
|
||||
getProperty(el: Element, name: string): any {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
onAndCancel(el: any, evt: any, listener: any): Function { throw 'not implemented'; }
|
||||
dispatchEvent(el: any, evt: any) { throw 'not implemented'; }
|
||||
remove(el: any): Node { throw 'not implemented'; }
|
||||
createElement(tagName: any, doc?: any): HTMLElement { throw 'not implemented'; }
|
||||
createHtmlDocument(): HTMLDocument { throw 'not implemented'; }
|
||||
getDefaultDocument(): Document { throw 'not implemented'; }
|
||||
isElementNode(node: any): boolean { throw 'not implemented'; }
|
||||
isShadowRoot(node: any): boolean { throw 'not implemented'; }
|
||||
supportsDOMEvents(): boolean { throw 'not implemented'; }
|
||||
getGlobalEventTarget(doc: Document, target: string): any { throw 'not implemented'; }
|
||||
getHistory(): History { throw 'not implemented'; }
|
||||
getLocation(): Location { throw 'not implemented'; }
|
||||
getBaseHref(doc: Document): string { throw 'not implemented'; }
|
||||
resetBaseElement(): void { throw 'not implemented'; }
|
||||
getUserAgent(): string { return 'Fake user agent'; }
|
||||
performanceNow(): number { throw 'not implemented'; }
|
||||
onAndCancel(el: any, evt: any, listener: any): Function {
|
||||
throw 'not implemented';
|
||||
}
|
||||
dispatchEvent(el: any, evt: any) {
|
||||
throw 'not implemented';
|
||||
}
|
||||
remove(el: any): Node {
|
||||
throw 'not implemented';
|
||||
}
|
||||
createElement(tagName: any, doc?: any): HTMLElement {
|
||||
throw 'not implemented';
|
||||
}
|
||||
createHtmlDocument(): HTMLDocument {
|
||||
throw 'not implemented';
|
||||
}
|
||||
getDefaultDocument(): Document {
|
||||
throw 'not implemented';
|
||||
}
|
||||
isElementNode(node: any): boolean {
|
||||
throw 'not implemented';
|
||||
}
|
||||
isShadowRoot(node: any): boolean {
|
||||
throw 'not implemented';
|
||||
}
|
||||
supportsDOMEvents(): boolean {
|
||||
throw 'not implemented';
|
||||
}
|
||||
getGlobalEventTarget(doc: Document, target: string): any {
|
||||
throw 'not implemented';
|
||||
}
|
||||
getHistory(): History {
|
||||
throw 'not implemented';
|
||||
}
|
||||
getLocation(): Location {
|
||||
throw 'not implemented';
|
||||
}
|
||||
getBaseHref(doc: Document): string {
|
||||
throw 'not implemented';
|
||||
}
|
||||
resetBaseElement(): void {
|
||||
throw 'not implemented';
|
||||
}
|
||||
getUserAgent(): string {
|
||||
return 'Fake user agent';
|
||||
}
|
||||
performanceNow(): number {
|
||||
throw 'not implemented';
|
||||
}
|
||||
|
||||
supportsCookies(): boolean { return false; }
|
||||
getCookie(name: string): string { throw 'not implemented'; }
|
||||
supportsCookies(): boolean {
|
||||
return false;
|
||||
}
|
||||
getCookie(name: string): string {
|
||||
throw 'not implemented';
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {CommonModule, DOCUMENT, ViewportScroller, ɵNullViewportScroller as NullViewportScroller, ɵPLATFORM_WORKER_APP_ID as PLATFORM_WORKER_APP_ID} from '@angular/common';
|
||||
import {APP_INITIALIZER, ApplicationModule, ErrorHandler, NgModule, NgZone, PLATFORM_ID, PlatformRef, RendererFactory2, StaticProvider, createPlatformFactory, platformCore, ɵINJECTOR_SCOPE as INJECTOR_SCOPE} from '@angular/core';
|
||||
import {APP_INITIALIZER, ApplicationModule, createPlatformFactory, ErrorHandler, NgModule, NgZone, PLATFORM_ID, platformCore, PlatformRef, RendererFactory2, StaticProvider, ɵINJECTOR_SCOPE as INJECTOR_SCOPE} from '@angular/core';
|
||||
import {ɵBROWSER_SANITIZATION_PROVIDERS as BROWSER_SANITIZATION_PROVIDERS} from '@angular/platform-browser';
|
||||
|
||||
import {ON_WEB_WORKER} from './web_workers/shared/api';
|
||||
@ -24,7 +24,7 @@ import {WorkerDomAdapter} from './web_workers/worker/worker_adapter';
|
||||
* @publicApi
|
||||
* @deprecated platform-webworker is deprecated in Angular and will be removed in version 10
|
||||
*/
|
||||
export const platformWorkerApp: (extraProviders?: StaticProvider[] | undefined) => PlatformRef =
|
||||
export const platformWorkerApp: (extraProviders?: StaticProvider[]|undefined) => PlatformRef =
|
||||
createPlatformFactory(
|
||||
platformCore, 'workerApp', [{provide: PLATFORM_ID, useValue: PLATFORM_WORKER_APP_ID}]);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {DOCUMENT, ɵPLATFORM_WORKER_UI_ID as PLATFORM_WORKER_UI_ID} from '@angular/common';
|
||||
import {ErrorHandler, Injectable, InjectionToken, Injector, NgZone, PLATFORM_ID, PLATFORM_INITIALIZER, RendererFactory2, StaticProvider, Testability, createPlatformFactory, isDevMode, platformCore, ɵAPP_ID_RANDOM_PROVIDER as APP_ID_RANDOM_PROVIDER, ɵsetDocument} from '@angular/core';
|
||||
import {createPlatformFactory, ErrorHandler, Injectable, InjectionToken, Injector, isDevMode, NgZone, PLATFORM_ID, PLATFORM_INITIALIZER, platformCore, RendererFactory2, StaticProvider, Testability, ɵAPP_ID_RANDOM_PROVIDER as APP_ID_RANDOM_PROVIDER, ɵsetDocument} from '@angular/core';
|
||||
import {EVENT_MANAGER_PLUGINS, EventManager, HAMMER_GESTURE_CONFIG, HammerGestureConfig, ɵBROWSER_SANITIZATION_PROVIDERS as BROWSER_SANITIZATION_PROVIDERS, ɵBrowserDomAdapter as BrowserDomAdapter, ɵBrowserGetTestability as BrowserGetTestability, ɵDomEventsPlugin as DomEventsPlugin, ɵDomRendererFactory2 as DomRendererFactory2, ɵDomSharedStylesHost as DomSharedStylesHost, ɵHammerGesturesPlugin as HammerGesturesPlugin, ɵKeyEventsPlugin as KeyEventsPlugin, ɵSharedStylesHost as SharedStylesHost} from '@angular/platform-browser';
|
||||
|
||||
import {ON_WEB_WORKER} from './web_workers/shared/api';
|
||||
@ -31,9 +31,9 @@ import {MessageBasedRenderer2} from './web_workers/ui/renderer';
|
||||
@Injectable()
|
||||
export class WebWorkerInstance {
|
||||
// TODO(issue/24571): remove '!'.
|
||||
public worker !: Worker;
|
||||
public worker!: Worker;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
public bus !: MessageBus;
|
||||
public bus!: MessageBus;
|
||||
|
||||
/** @internal */
|
||||
public init(worker: Worker, bus: MessageBus) {
|
||||
@ -122,7 +122,11 @@ function initializeGenericWorkerRenderer(injector: Injector) {
|
||||
|
||||
// initialize message services after the bus has been created
|
||||
const services = injector.get(WORKER_UI_STARTABLE_MESSAGING_SERVICE);
|
||||
zone.runGuarded(() => { services.forEach((svc: any) => { svc.start(); }); });
|
||||
zone.runGuarded(() => {
|
||||
services.forEach((svc: any) => {
|
||||
svc.start();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function messageBusFactory(instance: WebWorkerInstance): MessageBus {
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import {NgZone} from '@angular/core';
|
||||
import {withModule} from '@angular/core/testing/src/test_bed';
|
||||
import {AsyncTestCompleter, MockNgZone, beforeEach, describe, expect, inject, it} from '@angular/core/testing/src/testing_internal';
|
||||
import {AsyncTestCompleter, beforeEach, describe, expect, inject, it, MockNgZone} from '@angular/core/testing/src/testing_internal';
|
||||
import {MessageBus} from '@angular/platform-webworker/src/web_workers/shared/message_bus';
|
||||
|
||||
import {createConnectedMessageBus} from './message_bus_util';
|
||||
@ -20,7 +20,9 @@ import {createConnectedMessageBus} from './message_bus_util';
|
||||
describe('MessageBus', () => {
|
||||
let bus: MessageBus;
|
||||
|
||||
beforeEach(() => { bus = createConnectedMessageBus(); });
|
||||
beforeEach(() => {
|
||||
bus = createConnectedMessageBus();
|
||||
});
|
||||
|
||||
it('should pass messages in the same channel from sink to source',
|
||||
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
|
||||
@ -115,7 +117,9 @@ import {createConnectedMessageBus} from './message_bus_util';
|
||||
* Flushes pending messages and then runs the given function.
|
||||
*/
|
||||
// TODO(mlaval): timeout is fragile, test to be rewritten
|
||||
function flushMessages(fn: () => void) { setTimeout(fn, 50); }
|
||||
function flushMessages(fn: () => void) {
|
||||
setTimeout(fn, 50);
|
||||
}
|
||||
|
||||
it('should buffer messages and wait for the zone to exit before sending',
|
||||
withModule({providers: [{provide: NgZone, useClass: MockNgZone}]})
|
||||
@ -126,7 +130,11 @@ import {createConnectedMessageBus} from './message_bus_util';
|
||||
setup(true, zone);
|
||||
|
||||
let wasCalled = false;
|
||||
bus.from(CHANNEL).subscribe({next: (message: any) => { wasCalled = true; }});
|
||||
bus.from(CHANNEL).subscribe({
|
||||
next: (message: any) => {
|
||||
wasCalled = true;
|
||||
}
|
||||
});
|
||||
bus.to(CHANNEL).emit('hi');
|
||||
|
||||
|
||||
@ -148,7 +156,11 @@ import {createConnectedMessageBus} from './message_bus_util';
|
||||
setup(false, zone);
|
||||
|
||||
let wasCalled = false;
|
||||
bus.from(CHANNEL).subscribe({next: (message: any) => { wasCalled = true; }});
|
||||
bus.from(CHANNEL).subscribe({
|
||||
next: (message: any) => {
|
||||
wasCalled = true;
|
||||
}
|
||||
});
|
||||
bus.to(CHANNEL).emit('hi');
|
||||
|
||||
flushMessages(() => {
|
||||
|
@ -24,7 +24,7 @@ export function createConnectedMessageBus(): MessageBus {
|
||||
|
||||
class MockPostMessage {
|
||||
// TODO(issue/24571): remove '!'.
|
||||
private _listener !: EventListener;
|
||||
private _listener!: EventListener;
|
||||
|
||||
addEventListener(type: string, listener: EventListener, useCapture?: boolean): void {
|
||||
if (type === 'message') {
|
||||
@ -32,5 +32,7 @@ class MockPostMessage {
|
||||
}
|
||||
}
|
||||
|
||||
postMessage(data: any, transfer?: [Transferable]): void { this._listener(<any>{data: data}); }
|
||||
postMessage(data: any, transfer?: [Transferable]): void {
|
||||
this._listener(<any>{data: data});
|
||||
}
|
||||
}
|
||||
|
@ -11,14 +11,18 @@ import {EventEmitter} from '@angular/core';
|
||||
export class MockEventEmitter<T> extends EventEmitter<T> {
|
||||
private _nextFns: Function[] = [];
|
||||
|
||||
constructor() { super(); }
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
subscribe(generator: any): any {
|
||||
this._nextFns.push(generator.next);
|
||||
return new MockDisposable();
|
||||
}
|
||||
|
||||
emit(value: any) { this._nextFns.forEach(fn => fn(value)); }
|
||||
emit(value: any) {
|
||||
this._nextFns.forEach(fn => fn(value));
|
||||
}
|
||||
}
|
||||
|
||||
class MockDisposable {
|
||||
|
@ -11,7 +11,9 @@ import {RenderStore} from '@angular/platform-webworker/src/web_workers/shared/re
|
||||
{
|
||||
describe('RenderStoreSpec', () => {
|
||||
let store: RenderStore;
|
||||
beforeEach(() => { store = new RenderStore(); });
|
||||
beforeEach(() => {
|
||||
store = new RenderStore();
|
||||
});
|
||||
|
||||
it('should allocate ids', () => {
|
||||
expect(store.allocateId()).toBe(0);
|
||||
@ -31,6 +33,5 @@ import {RenderStore} from '@angular/platform-webworker/src/web_workers/shared/re
|
||||
store.store(obj, id);
|
||||
expect(store.deserialize(id)).toBe(obj);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
@ -44,12 +44,14 @@ export function expectBrokerCall(
|
||||
broker.spy('runOnService').and.callFake((args: UiArguments, returnType: Type<any>) => {
|
||||
expect(args.method).toEqual(methodName);
|
||||
if (vals != null) {
|
||||
expect(args.args !.length).toEqual(vals.length);
|
||||
vals.forEach((v, i) => { expect(v).toEqual(args.args ![i].value); });
|
||||
expect(args.args!.length).toEqual(vals.length);
|
||||
vals.forEach((v, i) => {
|
||||
expect(v).toEqual(args.args![i].value);
|
||||
});
|
||||
}
|
||||
let promise: Promise<any>|void = null !;
|
||||
let promise: Promise<any>|void = null!;
|
||||
if (handler != null) {
|
||||
const givenValues = args.args !.map((arg) => arg.value);
|
||||
const givenValues = args.args!.map((arg) => arg.value);
|
||||
if (givenValues.length > 0) {
|
||||
promise = handler(givenValues);
|
||||
} else {
|
||||
@ -116,16 +118,22 @@ export class MockMessageBusSink implements MessageBusSink {
|
||||
* Runs syncronously, and does not support running within the zone.
|
||||
*/
|
||||
export class MockMessageBus extends MessageBus {
|
||||
constructor(public sink: MockMessageBusSink, public source: MockMessageBusSource) { super(); }
|
||||
constructor(public sink: MockMessageBusSink, public source: MockMessageBusSource) {
|
||||
super();
|
||||
}
|
||||
|
||||
initChannel(channel: string, runInZone = true) {
|
||||
this.sink.initChannel(channel, runInZone);
|
||||
this.source.initChannel(channel, runInZone);
|
||||
}
|
||||
|
||||
to(channel: string): MockEventEmitter<any> { return this.sink.to(channel); }
|
||||
to(channel: string): MockEventEmitter<any> {
|
||||
return this.sink.to(channel);
|
||||
}
|
||||
|
||||
from(channel: string): MockEventEmitter<any> { return this.source.from(channel); }
|
||||
from(channel: string): MockEventEmitter<any> {
|
||||
return this.source.from(channel);
|
||||
}
|
||||
|
||||
attachToZone(zone: NgZone) {}
|
||||
}
|
||||
@ -133,6 +141,10 @@ export class MockMessageBus extends MessageBus {
|
||||
export const _ClientMessageBrokerFactory: {new (a: any, b: any): ClientMessageBrokerFactory} =
|
||||
ClientMessageBrokerFactory;
|
||||
export class MockMessageBrokerFactory extends _ClientMessageBrokerFactory {
|
||||
constructor(private _messageBroker: ClientMessageBroker) { super(null !, null !); }
|
||||
createMessageBroker(channel: string, runInZone = true) { return this._messageBroker; }
|
||||
constructor(private _messageBroker: ClientMessageBroker) {
|
||||
super(null!, null!);
|
||||
}
|
||||
createMessageBroker(channel: string, runInZone = true) {
|
||||
return this._messageBroker;
|
||||
}
|
||||
}
|
||||
|
@ -12,14 +12,14 @@ import {MessageBus} from '@angular/platform-webworker/src/web_workers/shared/mes
|
||||
import {LocationType, SerializerTypes} from '@angular/platform-webworker/src/web_workers/shared/serializer';
|
||||
import {WebWorkerPlatformLocation} from '@angular/platform-webworker/src/web_workers/worker/platform_location';
|
||||
|
||||
import {MockMessageBrokerFactory, createPairedMessageBuses, expectBrokerCall} from '../shared/web_worker_test_util';
|
||||
import {createPairedMessageBuses, expectBrokerCall, MockMessageBrokerFactory} from '../shared/web_worker_test_util';
|
||||
|
||||
import {SpyMessageBroker} from './spies';
|
||||
|
||||
{
|
||||
describe('WebWorkerPlatformLocation', () => {
|
||||
let uiBus: MessageBus = null !;
|
||||
let workerBus: MessageBus = null !;
|
||||
let uiBus: MessageBus = null!;
|
||||
let workerBus: MessageBus = null!;
|
||||
let broker: any = null;
|
||||
|
||||
const TEST_LOCATION = new LocationType(
|
||||
@ -29,17 +29,17 @@ import {SpyMessageBroker} from './spies';
|
||||
|
||||
function createWebWorkerPlatformLocation(loc: LocationType): WebWorkerPlatformLocation {
|
||||
broker.spy('runOnService')
|
||||
.and.callFake((args: UiArguments, returnType: Type<any>| SerializerTypes) => {
|
||||
.and.callFake((args: UiArguments, returnType: Type<any>|SerializerTypes) => {
|
||||
if (args.method === 'getLocation') {
|
||||
return Promise.resolve(loc);
|
||||
}
|
||||
});
|
||||
const factory = new MockMessageBrokerFactory(broker);
|
||||
return new WebWorkerPlatformLocation(factory, workerBus, null !);
|
||||
return new WebWorkerPlatformLocation(factory, workerBus, null!);
|
||||
}
|
||||
|
||||
function testPushOrReplaceState(pushState: boolean) {
|
||||
const platformLocation = createWebWorkerPlatformLocation(null !);
|
||||
const platformLocation = createWebWorkerPlatformLocation(null!);
|
||||
const TITLE = 'foo';
|
||||
const URL = 'http://www.example.com/foo';
|
||||
expectBrokerCall(broker, pushState ? 'pushState' : 'replaceState', [null, TITLE, URL]);
|
||||
@ -60,18 +60,18 @@ import {SpyMessageBroker} from './spies';
|
||||
});
|
||||
|
||||
it('should throw if getBaseHrefFromDOM is called', () => {
|
||||
const platformLocation = createWebWorkerPlatformLocation(null !);
|
||||
const platformLocation = createWebWorkerPlatformLocation(null!);
|
||||
expect(() => platformLocation.getBaseHrefFromDOM()).toThrowError();
|
||||
});
|
||||
|
||||
it('should get location on init', () => {
|
||||
const platformLocation = createWebWorkerPlatformLocation(null !);
|
||||
const platformLocation = createWebWorkerPlatformLocation(null!);
|
||||
expectBrokerCall(broker, 'getLocation');
|
||||
(platformLocation as any).init();
|
||||
});
|
||||
|
||||
it('should throw if set pathname is called before init finishes', () => {
|
||||
const platformLocation = createWebWorkerPlatformLocation(null !);
|
||||
const platformLocation = createWebWorkerPlatformLocation(null!);
|
||||
(platformLocation as any).init();
|
||||
expect(() => platformLocation.pathname = 'TEST').toThrowError();
|
||||
});
|
||||
@ -86,8 +86,12 @@ import {SpyMessageBroker} from './spies';
|
||||
});
|
||||
});
|
||||
|
||||
it('should send pushState to render thread', () => { testPushOrReplaceState(true); });
|
||||
it('should send pushState to render thread', () => {
|
||||
testPushOrReplaceState(true);
|
||||
});
|
||||
|
||||
it('should send replaceState to render thread', () => { testPushOrReplaceState(false); });
|
||||
it('should send replaceState to render thread', () => {
|
||||
testPushOrReplaceState(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {ɵgetDOM as getDOM} from '@angular/common';
|
||||
import {Component, ComponentRef, Renderer2, RendererFactory2, RendererType2, destroyPlatform} from '@angular/core';
|
||||
import {Component, ComponentRef, destroyPlatform, Renderer2, RendererFactory2, RendererType2} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing';
|
||||
import {DomRendererFactory2} from '@angular/platform-browser/src/dom/dom_renderer';
|
||||
@ -22,7 +22,7 @@ import {MessageBasedRenderer2} from '@angular/platform-webworker/src/web_workers
|
||||
import {WebWorkerRendererFactory2} from '@angular/platform-webworker/src/web_workers/worker/renderer';
|
||||
import {modifiedInIvy} from '@angular/private/testing';
|
||||
|
||||
import {PairedMessageBuses, createPairedMessageBuses} from '../shared/web_worker_test_util';
|
||||
import {createPairedMessageBuses, PairedMessageBuses} from '../shared/web_worker_test_util';
|
||||
|
||||
let lastCreatedRenderer: Renderer2;
|
||||
|
||||
@ -58,7 +58,7 @@ let lastCreatedRenderer: Renderer2;
|
||||
const domRendererFactory = uiInjector.get(RendererFactory2);
|
||||
|
||||
// Worker side
|
||||
lastCreatedRenderer = null !;
|
||||
lastCreatedRenderer = null!;
|
||||
|
||||
wwRenderStore = new RenderStore();
|
||||
|
||||
@ -69,9 +69,8 @@ let lastCreatedRenderer: Renderer2;
|
||||
{provide: RenderStore, useValue: wwRenderStore},
|
||||
{
|
||||
provide: RendererFactory2,
|
||||
useFactory:
|
||||
(wwSerializer: Serializer) => createWebWorkerRendererFactory2(
|
||||
wwSerializer, uiSerializer, domRendererFactory, uiRenderStore, wwRenderStore),
|
||||
useFactory: (wwSerializer: Serializer) => createWebWorkerRendererFactory2(
|
||||
wwSerializer, uiSerializer, domRendererFactory, uiRenderStore, wwRenderStore),
|
||||
deps: [Serializer],
|
||||
},
|
||||
],
|
||||
@ -79,7 +78,7 @@ let lastCreatedRenderer: Renderer2;
|
||||
});
|
||||
|
||||
function getRenderElement(workerEl: any): any {
|
||||
const id = wwRenderStore.serialize(workerEl) !;
|
||||
const id = wwRenderStore.serialize(workerEl)!;
|
||||
return uiRenderStore.deserialize(id);
|
||||
}
|
||||
|
||||
|
@ -10,5 +10,7 @@ import {SpyObject} from '@angular/core/testing/src/testing_internal';
|
||||
import {ClientMessageBroker} from '@angular/platform-webworker/src/web_workers/shared/client_message_broker';
|
||||
|
||||
export class SpyMessageBroker extends SpyObject {
|
||||
constructor() { super(ClientMessageBroker); }
|
||||
constructor() {
|
||||
super(ClientMessageBroker);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user