refactor(browser): merge static & dynamic platforms

This commit is contained in:
Victor Berchet
2016-05-19 14:31:21 -07:00
parent 6c99746f0b
commit 54f8308999
163 changed files with 443 additions and 3958 deletions

View File

@ -1 +0,0 @@
export '../core/private_export.dart';

View File

@ -1,6 +1,52 @@
export * from './src/platform_browser';
export {DomEventsPlugin} from './src/dom/events/dom_events';
export {KeyEventsPlugin} from './src/dom/events/key_events';
export {EventManager, EVENT_MANAGER_PLUGINS} from './src/dom/events/event_manager';
export {HAMMER_GESTURE_CONFIG, HammerGestureConfig} from './src/dom/events/hammer_gestures';
export {ELEMENT_PROBE_PROVIDERS} from './src/dom/debug/ng_probe';
export {By} from './src/dom/debug/by';
export {DOCUMENT} from './src/dom/dom_tokens';
export * from './src/worker_render';
export * from './src/worker_app';
export {BrowserPlatformLocation} from './src/browser/location/browser_platform_location';
export {Title} from './src/browser/title';
export {enableDebugTools, disableDebugTools} from './src/browser/tools/tools';
export {
DomSanitizationService,
SafeHtml,
SafeScript,
SafeStyle,
SafeUrl,
SafeResourceUrl,
SecurityContext
} from './src/security/dom_sanitization_service';
export * from './src/platform/common/browser';
export * from './src/platform/static/browser';
export * from './src/platform/dynamic/browser';
// Web Workers
export {
ClientMessageBroker,
ClientMessageBrokerFactory,
FnArg,
UiArguments
} from './src/web_workers/shared/client_message_broker';
export {
ReceivedMessage,
ServiceMessageBroker,
ServiceMessageBrokerFactory
} from './src/web_workers/shared/service_message_broker';
export {PRIMITIVE} from './src/web_workers/shared/serializer';
export * from './src/web_workers/shared/message_bus';
export {WORKER_APP_LOCATION_PROVIDERS} from './src/web_workers/worker/location_providers';
export {WORKER_RENDER_LOCATION_PROVIDERS} from './src/web_workers/ui/location_providers';
export * from './src/platform/common/worker_render';
export * from './src/platform/common/worker_app';
export * from './src/platform/dynamic/worker_render';
export * from './src/platform/dynamic/worker_app';
export * from './src/platform/static/worker_render';
export * from './src/platform/static/worker_app';
export * from './private_export';

View File

@ -1,6 +0,0 @@
export './src/dom/dom_adapter.dart' show DomAdapter, setRootDomAdapter;
export '../src/animate/animation_builder' show AnimationBuilder, Animation;
export '../src/animate/css_animation_builder' show CssAnimationBuilder;
export '../src/animate/browser_details' show BrowserDetails;
export './src/animate/css_animation_options' show CssAnimationOptions;
export './src/animate/animation' show Animation;

View File

@ -5,7 +5,7 @@ import * as css_animation_options from './src/animate/css_animation_options';
import * as animation from './src/animate/animation';
import * as dom_adapter from './src/dom/dom_adapter';
import * as browser_adapter from './src/browser/browser_adapter';
import * as browser_common from './src/browser_common';
import * as browser_common from './src/platform/common/browser';
export namespace __platform_browser_private__ {
export type DomAdapter = dom_adapter.DomAdapter;
@ -13,25 +13,5 @@ export namespace __platform_browser_private__ {
export function getDOM(): DomAdapter { return dom_adapter.getDOM(); }
export function setDOM(adapter: DomAdapter) { return dom_adapter.setDOM(adapter); }
export var setRootDomAdapter = dom_adapter.setRootDomAdapter;
export type BrowserDomAdapter = browser_adapter.BrowserDomAdapter;
export var BrowserDomAdapter = browser_adapter.BrowserDomAdapter;
export type AnimationBuilder = animation_builder.AnimationBuilder;
export var AnimationBuilder = animation_builder.AnimationBuilder;
export type CssAnimationBuilder = css_animation_builder.CssAnimationBuilder;
export var CssAnimationBuilder = css_animation_builder.CssAnimationBuilder;
export type CssAnimationOptions = css_animation_options.CssAnimationOptions;
export var CssAnimationOptions = css_animation_options.CssAnimationOptions;
export type Animation = animation.Animation;
export var Animation = animation.Animation;
export type BrowserDetails = browser_details.BrowserDetails;
export var BrowserDetails = browser_details.BrowserDetails;
}

View File

@ -1,536 +0,0 @@
library angular.core.facade.dom;
import 'dart:html';
import 'package:angular2/platform/common_dom.dart' show setRootDomAdapter;
import 'generic_browser_adapter.dart' show GenericBrowserDomAdapter;
import 'package:angular2/src/facade/browser.dart';
import 'package:angular2/src/facade/lang.dart' show isBlank, isPresent;
import 'dart:js' as js;
// WARNING: Do not expose outside this class. Parsing HTML using this
// sanitizer is a security risk.
class _IdentitySanitizer implements NodeTreeSanitizer {
void sanitizeTree(Node node) {}
}
final _identitySanitizer = new _IdentitySanitizer();
final _keyCodeToKeyMap = const {
8: 'Backspace',
9: 'Tab',
12: 'Clear',
13: 'Enter',
16: 'Shift',
17: 'Control',
18: 'Alt',
19: 'Pause',
20: 'CapsLock',
27: 'Escape',
32: ' ',
33: 'PageUp',
34: 'PageDown',
35: 'End',
36: 'Home',
37: 'ArrowLeft',
38: 'ArrowUp',
39: 'ArrowRight',
40: 'ArrowDown',
45: 'Insert',
46: 'Delete',
65: 'a',
66: 'b',
67: 'c',
68: 'd',
69: 'e',
70: 'f',
71: 'g',
72: 'h',
73: 'i',
74: 'j',
75: 'k',
76: 'l',
77: 'm',
78: 'n',
79: 'o',
80: 'p',
81: 'q',
82: 'r',
83: 's',
84: 't',
85: 'u',
86: 'v',
87: 'w',
88: 'x',
89: 'y',
90: 'z',
91: 'OS',
93: 'ContextMenu',
96: '0',
97: '1',
98: '2',
99: '3',
100: '4',
101: '5',
102: '6',
103: '7',
104: '8',
105: '9',
106: '*',
107: '+',
109: '-',
110: '.',
111: '/',
112: 'F1',
113: 'F2',
114: 'F3',
115: 'F4',
116: 'F5',
117: 'F6',
118: 'F7',
119: 'F8',
120: 'F9',
121: 'F10',
122: 'F11',
123: 'F12',
144: 'NumLock',
145: 'ScrollLock'
};
final bool _supportsTemplateElement = () {
try {
return new TemplateElement().content != null;
} catch (_) {
return false;
}
}();
class BrowserDomAdapter extends GenericBrowserDomAdapter {
js.JsFunction _setProperty;
js.JsFunction _getProperty;
js.JsFunction _hasProperty;
Map<String, bool> _hasPropertyCache;
BrowserDomAdapter() {
_hasPropertyCache = new Map();
_setProperty = js.context.callMethod(
'eval', ['(function(el, prop, value) { el[prop] = value; })']);
_getProperty = js.context
.callMethod('eval', ['(function(el, prop) { return el[prop]; })']);
_hasProperty = js.context
.callMethod('eval', ['(function(el, prop) { return prop in el; })']);
}
static void makeCurrent() {
setRootDomAdapter(new BrowserDomAdapter());
}
bool hasProperty(Element element, String name) {
// Always return true as the serverside version html_adapter.dart does so.
// TODO: change this once we have schema support.
// Note: This nees to kept in sync with html_adapter.dart!
return true;
}
void setProperty(Element element, String name, Object value) {
var cacheKey = "${element.tagName}.${name}";
var hasProperty = this._hasPropertyCache[cacheKey];
if (hasProperty == null) {
hasProperty = this._hasProperty.apply([element, name]);
this._hasPropertyCache[cacheKey] = hasProperty;
}
if (hasProperty) {
_setProperty.apply([element, name, value]);
}
}
getProperty(Element element, String name) =>
_getProperty.apply([element, name]);
invoke(Element element, String methodName, List args) =>
this.getProperty(element, methodName).apply(args, thisArg: element);
// TODO(tbosch): move this into a separate environment class once we have it
logError(error) {
window.console.error(error);
}
log(error) {
window.console.log(error);
}
logGroup(error) {
window.console.group(error);
this.logError(error);
}
logGroupEnd() {
window.console.groupEnd();
}
@override
Map<String, String> get attrToPropMap => const <String, String>{
'class': 'className',
'innerHtml': 'innerHTML',
'readonly': 'readOnly',
'tabindex': 'tabIndex',
};
Element query(String selector) => document.querySelector(selector);
Element querySelector(el, String selector) => el.querySelector(selector);
ElementList querySelectorAll(el, String selector) =>
el.querySelectorAll(selector);
void on(EventTarget element, String event, callback(arg)) {
// due to https://code.google.com/p/dart/issues/detail?id=17406
// addEventListener misses zones so we use element.on.
element.on[event].listen(callback);
}
Function onAndCancel(EventTarget element, String event, callback(arg)) {
// due to https://code.google.com/p/dart/issues/detail?id=17406
// addEventListener misses zones so we use element.on.
var subscription = element.on[event].listen(callback);
return subscription.cancel;
}
void dispatchEvent(EventTarget el, Event evt) {
el.dispatchEvent(evt);
}
MouseEvent createMouseEvent(String eventType) =>
new MouseEvent(eventType, canBubble: true);
Event createEvent(String eventType) => new Event(eventType, canBubble: true);
void preventDefault(Event evt) {
evt.preventDefault();
}
bool isPrevented(Event evt) {
return evt.defaultPrevented;
}
String getInnerHTML(Element el) => el.innerHtml;
String getOuterHTML(Element el) => el.outerHtml;
void setInnerHTML(Element el, String value) {
el.innerHtml = value;
}
String nodeName(Node el) => el.nodeName;
String nodeValue(Node el) => el.nodeValue;
String type(InputElement el) => el.type;
Node content(TemplateElement el) =>
_supportsTemplateElement ? el.content : el;
Node firstChild(el) => el.firstChild;
Node nextSibling(Node el) => el.nextNode;
Element parentElement(Node el) => el.parentNode;
List<Node> childNodes(Node el) => el.childNodes;
List childNodesAsList(Node el) => childNodes(el).toList();
void clearNodes(Node el) {
el.nodes = const [];
}
void appendChild(Node el, Node node) {
el.append(node);
}
void removeChild(el, Node node) {
node.remove();
}
void replaceChild(Node el, Node newNode, Node oldNode) {
oldNode.replaceWith(newNode);
}
ChildNode remove(ChildNode el) {
return el..remove();
}
void insertBefore(Node el, node) {
el.parentNode.insertBefore(node, el);
}
void insertAllBefore(Node el, Iterable<Node> nodes) {
el.parentNode.insertAllBefore(nodes, el);
}
void insertAfter(Node el, Node node) {
el.parentNode.insertBefore(node, el.nextNode);
}
String getText(Node el) => el.text;
void setText(Node el, String value) {
el.text = value;
}
String getValue(el) => el.value;
void setValue(el, String value) {
el.value = value;
}
bool getChecked(InputElement el) => el.checked;
void setChecked(InputElement el, bool isChecked) {
el.checked = isChecked;
}
Comment createComment(String text) {
return new Comment(text);
}
TemplateElement createTemplate(String html) {
var t = new TemplateElement();
// We do not sanitize because templates are part of the application code
// not user code.
t.setInnerHtml(html, treeSanitizer: _identitySanitizer);
return t;
}
Element createElement(String tagName, [HtmlDocument doc = null]) {
if (doc == null) doc = document;
return doc.createElement(tagName);
}
Element createElementNS(String ns, String tagName, [HtmlDocument doc = null]) {
if (doc == null) doc = document;
return doc.createElementNS(ns, tagName);
}
Text createTextNode(String text, [HtmlDocument doc = null]) {
return new Text(text);
}
createScriptTag(String attrName, String attrValue,
[HtmlDocument doc = null]) {
if (doc == null) doc = document;
var el = doc.createElement('SCRIPT');
el.setAttribute(attrName, attrValue);
return el;
}
StyleElement createStyleElement(String css, [HtmlDocument doc = null]) {
if (doc == null) doc = document;
var el = doc.createElement('STYLE');
el.text = css;
return el;
}
ShadowRoot createShadowRoot(Element el) => el.createShadowRoot();
ShadowRoot getShadowRoot(Element el) => el.shadowRoot;
Element getHost(Element el) => (el as ShadowRoot).host;
clone(Node node) => node.clone(true);
List<Node> getElementsByClassName(Element element, String name) =>
element.getElementsByClassName(name);
List<Node> getElementsByTagName(Element element, String name) =>
element.querySelectorAll(name);
List<String> classList(Element element) => element.classes.toList();
void addClass(Element element, String className) {
element.classes.add(className);
}
void removeClass(Element element, String className) {
element.classes.remove(className);
}
bool hasClass(Element element, String className) =>
element.classes.contains(className);
void setStyle(Element element, String styleName, String styleValue) {
element.style.setProperty(styleName, styleValue);
}
bool hasStyle(Element element, String styleName, [String styleValue]) {
var value = this.getStyle(element, styleName);
return isPresent(styleValue) ? value == styleValue : value.length > 0;
}
void removeStyle(Element element, String styleName) {
element.style.removeProperty(styleName);
}
String getStyle(Element element, String styleName) {
return element.style.getPropertyValue(styleName);
}
String tagName(Element element) => element.tagName;
Map<String, String> attributeMap(Element element) {
var result = {};
result.addAll(element.attributes);
// TODO(tbosch): element.getNamespacedAttributes() somehow does not return the attribute value
var xlinkHref = element.getAttributeNS('http://www.w3.org/1999/xlink', 'href');
if (xlinkHref != null) {
result['xlink:href'] = xlinkHref;
}
return result;
}
bool hasAttribute(Element element, String attribute) =>
element.attributes.containsKey(attribute);
bool hasAttributeNS(Element element, String ns, String attribute) =>
element.getAttributeNS(ns, attribute) != null;
String getAttribute(Element element, String attribute) =>
element.getAttribute(attribute);
String getAttributeNS(Element element, String ns, String attribute) =>
element.getAttributeNS(ns, attribute);
void setAttribute(Element element, String name, String value) {
element.setAttribute(name, value);
}
void setAttributeNS(Element element, String ns, String name, String value) {
element.setAttributeNS(ns, name, value);
}
void removeAttribute(Element element, String name) {
//there is no removeAttribute method as of now in Dart:
//https://code.google.com/p/dart/issues/detail?id=19934
element.attributes.remove(name);
}
void removeAttributeNS(Element element, String ns, String name) {
element.getNamespacedAttributes(ns).remove(name);
}
Node templateAwareRoot(Element el) => el is TemplateElement ? el.content : el;
HtmlDocument createHtmlDocument() =>
document.implementation.createHtmlDocument('fakeTitle');
HtmlDocument defaultDoc() => document;
Rectangle getBoundingClientRect(el) => el.getBoundingClientRect();
String getTitle() => document.title;
void setTitle(String newTitle) {
document.title = newTitle;
}
bool elementMatches(n, String selector) =>
n is Element && n.matches(selector);
bool isTemplateElement(Element el) => el is TemplateElement;
bool isTextNode(Node node) => node.nodeType == Node.TEXT_NODE;
bool isCommentNode(Node node) => node.nodeType == Node.COMMENT_NODE;
bool isElementNode(Node node) => node.nodeType == Node.ELEMENT_NODE;
bool hasShadowRoot(Node node) {
return node is Element && node.shadowRoot != null;
}
bool isShadowRoot(Node node) {
return node is ShadowRoot;
}
Node importIntoDoc(Node node) {
return document.importNode(node, true);
}
Node adoptNode(Node node) {
return document.adoptNode(node);
}
String getHref(AnchorElement element) {
return element.href;
}
String getEventKey(KeyboardEvent event) {
int keyCode = event.keyCode;
return _keyCodeToKeyMap.containsKey(keyCode)
? _keyCodeToKeyMap[keyCode]
: 'Unidentified';
}
getGlobalEventTarget(String target) {
if (target == "window") {
return window;
} else if (target == "document") {
return document;
} else if (target == "body") {
return document.body;
}
}
getHistory() {
return window.history;
}
getLocation() {
return window.location;
}
String getBaseHref() {
var href = getBaseElementHref();
if (href == null) {
return null;
}
return _relativePath(href);
}
resetBaseElement() {
baseElement = null;
}
String getUserAgent() {
return window.navigator.userAgent;
}
void setData(Element element, String name, String value) {
element.dataset[name] = value;
}
String getData(Element element, String name) {
return element.dataset[name];
}
getComputedStyle(elem) => elem.getComputedStyle();
// TODO(tbosch): move this into a separate environment class once we have it
setGlobalVar(String path, value) {
var parts = path.split('.');
var obj = js.context;
while (parts.length > 1) {
var name = parts.removeAt(0);
if (obj.hasProperty(name)) {
obj = obj[name];
} else {
obj = obj[name] = new js.JsObject(js.context['Object']);
}
}
obj[parts.removeAt(0)] = value;
}
requestAnimationFrame(callback) {
return window.requestAnimationFrame(callback);
}
cancelAnimationFrame(id) {
window.cancelAnimationFrame(id);
}
num performanceNow() {
return window.performance.now();
}
parse(s) {
throw 'not implemented';
}
}
var baseElement = null;
String getBaseElementHref() {
if (baseElement == null) {
baseElement = document.querySelector('base');
if (baseElement == null) {
return null;
}
}
return baseElement.getAttribute('href');
}
// based on urlUtils.js in AngularJS 1
AnchorElement _urlParsingNode = null;
String _relativePath(String url) {
if (_urlParsingNode == null) {
_urlParsingNode = new AnchorElement();
}
_urlParsingNode.href = url;
var pathname = _urlParsingNode.pathname;
return (pathname[0] == '/') ? pathname : '/${pathname}';
}

View File

@ -1,34 +0,0 @@
import {PromiseWrapper} from '../../src/facade/async';
import {DomAdapter} from '@angular/platform-browser/src/dom/dom_adapter';
import {ElementRef} from '@angular/core/src/linker/element_ref';
export class Rectangle {
left;
right;
top;
bottom;
height;
width;
constructor(left, top, width, height) {
this.left = left;
this.right = left + width;
this.top = top;
this.bottom = top + height;
this.height = height;
this.width = width;
}
}
export class Ruler {
domAdapter: DomAdapter;
constructor(domAdapter: DomAdapter) { this.domAdapter = domAdapter; }
measure(el: ElementRef): Promise<Rectangle> {
var clntRect = <any>this.domAdapter.getBoundingClientRect(el.nativeElement);
// even if getBoundingClientRect is synchronous we use async API in preparation for further
// changes
return PromiseWrapper.resolve(
new Rectangle(clntRect.left, clntRect.top, clntRect.width, clntRect.height));
}
}

View File

@ -1,188 +0,0 @@
library testability.browser_testability;
import 'package:angular2/core.dart';
import 'package:angular2/platform/common_dom.dart';
import 'dart:html';
import 'dart:js' as js;
// Work around http://dartbug.com/17752, copied from
// https://github.com/angular/angular.dart/blob/master/lib/introspection.dart
// Proxies a Dart function that accepts up to 10 parameters.
js.JsFunction _jsFunction(Function fn) {
const Object X = __varargSentinel;
return new js.JsFunction.withThis((thisArg,
[o1 = X,
o2 = X,
o3 = X,
o4 = X,
o5 = X,
o6 = X,
o7 = X,
o8 = X,
o9 = X,
o10 = X]) {
return __invokeFn(fn, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10);
});
}
const Object __varargSentinel = const Object();
__invokeFn(fn, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10) {
var args = [o1, o2, o3, o4, o5, o6, o7, o8, o9, o10];
while (args.length > 0 && identical(args.last, __varargSentinel)) {
args.removeLast();
}
return _jsify(Function.apply(fn, args));
}
// Helper function to JSify a Dart object. While this is *required* to JSify
// the result of a scope.eval(), other uses are not required and are used to
// work around http://dartbug.com/17752 in a convenient way (that bug affects
// dart2js in checked mode.)
_jsify(var obj) {
if (obj == null || obj is js.JsObject) {
return obj;
}
if (obj is _JsObjectProxyable) {
return obj._toJsObject();
}
if (obj is Function) {
return _jsFunction(obj);
}
if ((obj is Map) || (obj is Iterable)) {
var mappedObj = (obj is Map)
? new Map.fromIterables(obj.keys, obj.values.map(_jsify))
: obj.map(_jsify);
if (obj is List) {
return new js.JsArray.from(mappedObj);
} else {
return new js.JsObject.jsify(mappedObj);
}
}
return obj;
}
abstract class _JsObjectProxyable {
js.JsObject _toJsObject();
}
class PublicTestability implements _JsObjectProxyable {
Testability _testability;
PublicTestability(Testability testability) {
this._testability = testability;
}
bool isStable() {
return this._testability.isStable();
}
whenStable(Function callback) {
return this._testability.whenStable(callback);
}
findBindings(Element elem, String binding, bool exactMatch) {
return this._testability.findBindings(elem, binding, exactMatch);
}
js.JsObject _toJsObject() {
return _jsify({
'findBindings': (bindingString, [exactMatch, allowNonElementNodes]) =>
findBindings(bindingString, exactMatch, allowNonElementNodes),
'isStable': () => isStable(),
'whenStable': (callback) => whenStable((didWork) => callback.apply([didWork]))
})..['_dart_'] = this;
}
}
class BrowserGetTestability implements GetTestability {
const BrowserGetTestability();
static init() {
setTestabilityGetter(const BrowserGetTestability());
}
void addToWindow(TestabilityRegistry registry) {
var jsRegistry = js.context['ngTestabilityRegistries'];
if (jsRegistry == null) {
js.context['ngTestabilityRegistries'] = jsRegistry = new js.JsArray();
js.context['getAngularTestability'] =
_jsify((Element elem, [bool findInAncestors = true]) {
var registry = js.context['ngTestabilityRegistries'];
for (int i = 0; i < registry.length; i++) {
var result = registry[i]
.callMethod('getAngularTestability', [elem, findInAncestors]);
if (result != null) return result;
}
throw 'Could not find testability for element.';
});
var getAllAngularTestabilities = () {
var registry = js.context['ngTestabilityRegistries'];
var result = [];
for (int i = 0; i < registry.length; i++) {
var testabilities =
registry[i].callMethod('getAllAngularTestabilities');
if (testabilities != null) result.addAll(testabilities);
}
return _jsify(result);
};
js.context['getAllAngularTestabilities'] =
_jsify(getAllAngularTestabilities);
var whenAllStable = _jsify((callback) {
var testabilities = getAllAngularTestabilities();
var count = testabilities.length;
var didWork = false;
var decrement = _jsify((bool didWork_) {
didWork = didWork || didWork_;
count--;
if (count == 0) {
callback.apply([didWork]);
}
});
testabilities.forEach((testability) {
testability.callMethod('whenStable', [decrement]);
});
});
if (js.context['frameworkStabilizers'] == null) {
js.context['frameworkStabilizers'] = new js.JsArray();
}
js.context['frameworkStabilizers'].add(whenAllStable);
}
jsRegistry.add(this._createRegistry(registry));
}
findTestabilityInTree(TestabilityRegistry registry, dynamic elem, bool findInAncestors) {
if (elem == null) {
return null;
}
var t = registry.getTestability(elem);
if (t != null) {
return t;
} else if (!findInAncestors) {
return null;
}
if (getDOM().isShadowRoot(elem)) {
return this.findTestabilityInTree(registry, getDOM().getHost(elem), true);
}
return this.findTestabilityInTree(registry, getDOM().parentElement(elem), true);
}
js.JsObject _createRegistry(TestabilityRegistry registry) {
var object = new js.JsObject(js.context['Object']);
object['getAngularTestability'] =
_jsify((Element elem, bool findInAncestors) {
var testability = registry.findTestabilityInTree(elem, findInAncestors);
return testability == null
? null
: _jsify(new PublicTestability(testability));
});
object['getAllAngularTestabilities'] = _jsify(() {
var publicTestabilities = registry
.getAllTestabilities()
.map((testability) => new PublicTestability(testability));
return _jsify(publicTestabilities);
});
return object;
}
}

View File

@ -1,114 +0,0 @@
library angular.events;
import 'dart:html';
import './hammer_common.dart';
import 'package:angular2/src/facade/exceptions.dart' show BaseException;
import "package:angular2/src/core/di.dart" show Injectable, Inject, OpaqueToken;
import 'dart:js' as js;
const OpaqueToken HAMMER_GESTURE_CONFIG = const OpaqueToken("HammerGestureConfig");
overrideDefault(js.JsObject mc, String eventName, Object config) {
var jsObj = mc.callMethod('get', [eventName]);
jsObj.callMethod('set', [
new js.JsObject.jsify(config)
]);
}
@Injectable()
class HammerGestureConfig {
List<String> events = [];
Map overrides = {};
buildHammer(Element element) {
var mc = new js.JsObject(js.context['Hammer'], [element]);
overrideDefault(mc, 'pinch', {'enable': true});
overrideDefault(mc, 'rotate', {'enable': true});
this.overrides.forEach((Object config, String eventName) => overrideDefault(mc, eventName, config));
return mc;
}
}
@Injectable()
class HammerGesturesPlugin extends HammerGesturesPluginCommon {
HammerGestureConfig _config;
HammerGesturesPlugin(@Inject(HAMMER_GESTURE_CONFIG) this._config) {}
bool supports(String eventName) {
if (!super.supports(eventName) && !this.isCustomEvent(eventName)) return false;
if (!js.context.hasProperty('Hammer')) {
throw new BaseException(
'Hammer.js is not loaded, can not bind ${eventName} event');
}
return true;
}
addEventListener(Element element, String eventName, Function handler) {
var zone = this.manager.getZone();
eventName = eventName.toLowerCase();
zone.runOutsideAngular(() {
// Creating the manager bind events, must be done outside of angular
var mc = this._config.buildHammer(element);
mc.callMethod('on', [
eventName,
(eventObj) {
zone.runGuarded(() {
var dartEvent = new HammerEvent._fromJsEvent(eventObj);
handler(dartEvent);
});
}
]);
});
}
isCustomEvent(String eventName) { return this._config.events.indexOf(eventName) > -1; }
}
class HammerEvent {
num angle;
num centerX;
num centerY;
int deltaTime;
int deltaX;
int deltaY;
int direction;
int distance;
num rotation;
num scale;
Node target;
int timeStamp;
String type;
num velocity;
num velocityX;
num velocityY;
js.JsObject jsEvent;
HammerEvent._fromJsEvent(js.JsObject event) {
angle = event['angle'];
var center = event['center'];
centerX = center['x'];
centerY = center['y'];
deltaTime = event['deltaTime'];
deltaX = event['deltaX'];
deltaY = event['deltaY'];
direction = event['direction'];
distance = event['distance'];
rotation = event['rotation'];
scale = event['scale'];
target = event['target'];
timeStamp = event['timeStamp'];
type = event['type'];
velocity = event['velocity'];
velocityX = event['velocityX'];
velocityY = event['velocityY'];
jsEvent = event;
}
}

View File

@ -7,42 +7,33 @@ import {
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS,
OpaqueToken,
Testability
} from '@angular/core';
import {wtfInit, SanitizationService} from '../core_private';
import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS} from '@angular/common';
import {
DomSanitizationService,
DomSanitizationServiceImpl
} from './security/dom_sanitization_service';
Testability,
PlatformRef,
getPlatform,
createPlatform,
assertPlatform,
ReflectiveInjector
} from "@angular/core";
import {isBlank} from "../../facade/lang";
import {wtfInit, SanitizationService} from "../../../core_private";
import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS, PlatformLocation} from "@angular/common";
import {DomSanitizationService, DomSanitizationServiceImpl} from "../../security/dom_sanitization_service";
import {BrowserDomAdapter} from "../../browser/browser_adapter";
import {BrowserGetTestability} from "../../browser/testability";
import {getDOM} from "../../dom/dom_adapter";
import {DOCUMENT} from "../../dom/dom_tokens";
import {EVENT_MANAGER_PLUGINS, EventManager} from "../../dom/events/event_manager";
import {DomRootRenderer, DomRootRenderer_} from "../../dom/dom_renderer";
import {SharedStylesHost, DomSharedStylesHost} from "../../dom/shared_styles_host";
import {KeyEventsPlugin} from "../../dom/events/key_events";
import {ELEMENT_PROBE_PROVIDERS} from "../../dom/debug/ng_probe";
import {DomEventsPlugin} from "../../dom/events/dom_events";
import {HAMMER_GESTURE_CONFIG, HammerGestureConfig, HammerGesturesPlugin} from "../../dom/events/hammer_gestures";
import {AnimationBuilder} from "../../animate/animation_builder";
import {BrowserDetails} from "../../animate/browser_details";
import {BrowserPlatformLocation} from "../../browser/location/browser_platform_location";
import {IS_DART} from './facade/lang';
import {BrowserDomAdapter} from './browser/browser_adapter';
import {BrowserGetTestability} from './browser/testability';
import {getDOM} from './dom/dom_adapter';
import {DOCUMENT} from './dom/dom_tokens';
import {EVENT_MANAGER_PLUGINS, EventManager} from './dom/events/event_manager';
import {DomRootRenderer, DomRootRenderer_} from './dom/dom_renderer';
import {SharedStylesHost} from './dom/shared_styles_host';
import {KeyEventsPlugin} from './dom/events/key_events';
import {ELEMENT_PROBE_PROVIDERS} from './dom/debug/ng_probe';
import {DomEventsPlugin} from './dom/events/dom_events';
import {
HAMMER_GESTURE_CONFIG,
HammerGestureConfig,
HammerGesturesPlugin
} from './dom/events/hammer_gestures';
import {DomSharedStylesHost} from './dom/shared_styles_host';
import {AnimationBuilder} from './animate/animation_builder';
import {BrowserDetails} from './animate/browser_details';
import {PlatformLocation} from '@angular/common';
import {BrowserPlatformLocation} from './browser/location/browser_platform_location';
export {Title} from './browser/title';
export {BrowserDomAdapter} from './browser/browser_adapter';
export {enableDebugTools, disableDebugTools} from './browser/tools/tools';
export {By} from './dom/debug/by';
export const BROWSER_PLATFORM_MARKER =
const BROWSER_PLATFORM_MARKER =
/*@ts2dart_const*/ new OpaqueToken('BrowserPlatformMarker');
/**
@ -50,23 +41,13 @@ export const BROWSER_PLATFORM_MARKER =
*
* Used automatically by `bootstrap`, or can be passed to {@link platform}.
*/
export const BROWSER_PROVIDERS: Array<any /*Type | Provider | any[]*/> = /*@ts2dart_const*/[
export const BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = /*@ts2dart_const*/[
/*@ts2dart_Provider*/ {provide: BROWSER_PLATFORM_MARKER, useValue: true},
PLATFORM_COMMON_PROVIDERS,
/*@ts2dart_Provider*/ {provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true},
/*@ts2dart_Provider*/ {provide: PlatformLocation, useClass: BrowserPlatformLocation}
];
function _exceptionHandler(): ExceptionHandler {
// !IS_DART is required because we must rethrow exceptions in JS,
// but must not rethrow exceptions in Dart
return new ExceptionHandler(getDOM(), !IS_DART);
}
function _document(): any {
return getDOM().defaultDoc();
}
export const BROWSER_SANITIZATION_PROVIDERS: Array<any> = /*@ts2dart_const*/[
/* @ts2dart_Provider */ {provide: SanitizationService, useExisting: DomSanitizationService},
/* @ts2dart_Provider */ {provide: DomSanitizationService, useClass: DomSanitizationServiceImpl},
@ -101,11 +82,23 @@ export const BROWSER_APP_COMMON_PROVIDERS: Array<any /*Type | Provider | any[]*/
ELEMENT_PROBE_PROVIDERS
];
export function browserPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PLATFORM_PROVIDERS));
}
return assertPlatform(BROWSER_PLATFORM_MARKER);
}
export {HAMMER_GESTURE_CONFIG, HammerGestureConfig} from '../src/dom/events/hammer_gestures';
export function initDomAdapter() {
function initDomAdapter() {
BrowserDomAdapter.makeCurrent();
wtfInit();
BrowserGetTestability.init();
}
function _exceptionHandler(): ExceptionHandler {
return new ExceptionHandler(getDOM());
}
function _document(): any {
return getDOM().defaultDoc();
}

View File

@ -1,5 +1,5 @@
import {WebWorkerRootRenderer} from '../web_workers/worker/renderer';
import {print} from '../../src/facade/lang';
import {WebWorkerRootRenderer} from '../../web_workers/worker/renderer';
import {print, isBlank} from '../../../src/facade/lang';
import {
PLATFORM_DIRECTIVES,
PLATFORM_PIPES,
@ -7,21 +7,26 @@ import {
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS,
OpaqueToken,
RootRenderer
RootRenderer,
PlatformRef,
getPlatform,
createPlatform,
assertPlatform,
ReflectiveInjector
} from '@angular/core';
import {COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS} from '@angular/common';
import {
ClientMessageBrokerFactory,
ClientMessageBrokerFactory_
} from '../web_workers/shared/client_message_broker';
} from '../../web_workers/shared/client_message_broker';
import {
ServiceMessageBrokerFactory,
ServiceMessageBrokerFactory_
} from '../web_workers/shared/service_message_broker';
import {Serializer} from '../web_workers/shared/serializer';
import {ON_WEB_WORKER} from '../web_workers/shared/api';
import {RenderStore} from '../web_workers/shared/render_store';
import {BROWSER_SANITIZATION_PROVIDERS} from '../browser_common';
} from '../../web_workers/shared/service_message_broker';
import {Serializer} from '../../web_workers/shared/serializer';
import {ON_WEB_WORKER} from '../../web_workers/shared/api';
import {RenderStore} from '../../web_workers/shared/render_store';
import {BROWSER_SANITIZATION_PROVIDERS} from './browser';
class PrintLogger {
log = print;
@ -30,7 +35,7 @@ class PrintLogger {
logGroupEnd() {}
}
export const WORKER_APP_PLATFORM_MARKER =
const WORKER_APP_PLATFORM_MARKER =
/*@ts2dart_const*/ new OpaqueToken('WorkerAppPlatformMarker');
export const WORKER_APP_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
@ -57,6 +62,13 @@ export const WORKER_APP_APPLICATION_COMMON_PROVIDERS: Array<any /*Type | Provide
/* @ts2dart_Provider */ {provide: ExceptionHandler, useFactory: _exceptionHandler, deps: []}
];
export function workerAppPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_APP_PLATFORM_PROVIDERS));
}
return assertPlatform(WORKER_APP_PLATFORM_MARKER);
}
function _exceptionHandler(): ExceptionHandler {
return new ExceptionHandler(new PrintLogger());
}
}

View File

@ -1,40 +1,47 @@
import {IS_DART} from '../../src/facade/lang';
import {MessageBus} from '../web_workers/shared/message_bus';
import {NgZone, Provider, Injector, OpaqueToken, Testability} from '@angular/core';
import {wtfInit} from '../../core_private';
import {isBlank} from "../../../src/facade/lang";
import {MessageBus} from "../../web_workers/shared/message_bus";
import {
NgZone,
Injector,
OpaqueToken,
Testability,
ExceptionHandler,
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS,
RootRenderer,
PLATFORM_INITIALIZER
} from '@angular/core';
import {getDOM} from '../dom/dom_adapter';
import {DomEventsPlugin} from '../dom/events/dom_events';
import {KeyEventsPlugin} from '../dom/events/key_events';
import {HammerGesturesPlugin} from '../dom/events/hammer_gestures';
import {DOCUMENT} from '../dom/dom_tokens';
import {DomRootRenderer, DomRootRenderer_} from '../dom/dom_renderer';
import {DomSharedStylesHost, SharedStylesHost} from '../dom/shared_styles_host';
import {BrowserDetails} from '../animate/browser_details';
import {AnimationBuilder} from '../animate/animation_builder';
import {BrowserGetTestability} from '../browser/testability';
import {BrowserDomAdapter} from '../browser/browser_adapter';
import {MessageBasedRenderer} from '../web_workers/ui/renderer';
PLATFORM_INITIALIZER,
PlatformRef,
getPlatform,
createPlatform,
assertPlatform,
ReflectiveInjector
} from "@angular/core";
import {wtfInit} from "../../../core_private";
import {getDOM} from "../../dom/dom_adapter";
import {DomEventsPlugin} from "../../dom/events/dom_events";
import {KeyEventsPlugin} from "../../dom/events/key_events";
import {HammerGesturesPlugin, HAMMER_GESTURE_CONFIG, HammerGestureConfig} from "../../dom/events/hammer_gestures";
import {DOCUMENT} from "../../dom/dom_tokens";
import {DomRootRenderer, DomRootRenderer_} from "../../dom/dom_renderer";
import {DomSharedStylesHost, SharedStylesHost} from "../../dom/shared_styles_host";
import {BrowserDetails} from "../../animate/browser_details";
import {AnimationBuilder} from "../../animate/animation_builder";
import {BrowserGetTestability} from "../../browser/testability";
import {BrowserDomAdapter} from "../../browser/browser_adapter";
import {MessageBasedRenderer} from "../../web_workers/ui/renderer";
import {
ServiceMessageBrokerFactory,
ServiceMessageBrokerFactory_
} from '../web_workers/shared/service_message_broker';
import {
ClientMessageBrokerFactory,
ClientMessageBrokerFactory_
} from '../web_workers/shared/client_message_broker';
import {Serializer} from '../web_workers/shared/serializer';
import {ON_WEB_WORKER} from '../web_workers/shared/api';
import {RenderStore} from '../web_workers/shared/render_store';
import {HAMMER_GESTURE_CONFIG, HammerGestureConfig} from '../dom/events/hammer_gestures';
import {EventManager, EVENT_MANAGER_PLUGINS} from '../dom/events/event_manager';
import {BROWSER_SANITIZATION_PROVIDERS} from '../browser_common';
} from "../../web_workers/shared/service_message_broker";
import {ClientMessageBrokerFactory, ClientMessageBrokerFactory_} from "../../web_workers/shared/client_message_broker";
import {Serializer} from "../../web_workers/shared/serializer";
import {ON_WEB_WORKER} from "../../web_workers/shared/api";
import {RenderStore} from "../../web_workers/shared/render_store";
import {EventManager, EVENT_MANAGER_PLUGINS} from "../../dom/events/event_manager";
import {BROWSER_SANITIZATION_PROVIDERS} from "../common/browser";
const WORKER_RENDER_PLATFORM_MARKER =
/*@ts2dart_const*/ new OpaqueToken('WorkerRenderPlatformMarker');
export const WORKER_SCRIPT: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken("WebWorkerScript");
@ -47,9 +54,6 @@ export const WORKER_SCRIPT: OpaqueToken = /*@ts2dart_const*/ new OpaqueToken("We
export const WORKER_RENDER_STARTABLE_MESSAGING_SERVICE =
/*@ts2dart_const*/ new OpaqueToken('WorkerRenderStartableMsgService');
export const WORKER_RENDER_PLATFORM_MARKER =
/*@ts2dart_const*/ new OpaqueToken('WorkerRenderPlatformMarker');
export const WORKER_RENDER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = /*@ts2dart_const*/[
PLATFORM_COMMON_PROVIDERS,
/*@ts2dart_const*/ (/* @ts2dart_Provider */ {provide: WORKER_RENDER_PLATFORM_MARKER, useValue: true}),
@ -95,14 +99,21 @@ export function initializeGenericWorkerRenderer(injector: Injector) {
zone.runGuarded(() => { services.forEach((svc) => { svc.start(); }); });
}
export function initWebWorkerRenderPlatform(): void {
function initWebWorkerRenderPlatform(): void {
BrowserDomAdapter.makeCurrent();
wtfInit();
BrowserGetTestability.init();
}
export function workerRenderPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_RENDER_PLATFORM_PROVIDERS));
}
return assertPlatform(WORKER_RENDER_PLATFORM_MARKER);
}
function _exceptionHandler(): ExceptionHandler {
return new ExceptionHandler(getDOM(), !IS_DART);
return new ExceptionHandler(getDOM());
}
function _document(): any {

View File

@ -0,0 +1,106 @@
import {
reflector,
ReflectiveInjector,
coreLoadAndBootstrap,
Type,
ComponentRef
} from '@angular/core';
import {COMPILER_PROVIDERS, XHR} from '@angular/compiler';
import {CachedXHR} from '../../../src/xhr/xhr_cache';
import {isPresent} from '../../../src/facade/lang';
import {XHRImpl} from '../../../src/xhr/xhr_impl';
import {browserPlatform, BROWSER_APP_COMMON_PROVIDERS} from '../common/browser';
import {ReflectionCapabilities} from '../../../core_private';
export const CACHED_TEMPLATE_PROVIDER: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/[{provide: XHR, useClass: CachedXHR}];
/**
* An array of providers that should be passed into `application()` when bootstrapping a component.
*/
export const BROWSER_APP_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/[
BROWSER_APP_COMMON_PROVIDERS,
COMPILER_PROVIDERS,
{provide: XHR, useClass: XHRImpl},
];
/**
* Bootstrapping for Angular applications.
*
* You instantiate an Angular application by explicitly specifying a component to use
* as the root component for your application via the `bootstrap()` method.
*
* ## Simple Example
*
* Assuming this `index.html`:
*
* ```html
* <html>
* <!-- load Angular script tags here. -->
* <body>
* <my-app>loading...</my-app>
* </body>
* </html>
* ```
*
* An application is bootstrapped inside an existing browser DOM, typically `index.html`.
* Unlike Angular 1, Angular 2 does not compile/process providers in `index.html`. This is
* mainly for security reasons, as well as architectural changes in Angular 2. This means
* that `index.html` can safely be processed using server-side technologies such as
* providers. Bindings can thus use double-curly `{{ syntax }}` without collision from
* Angular 2 component double-curly `{{ syntax }}`.
*
* We can use this script code:
*
* {@example core/ts/bootstrap/bootstrap.ts region='bootstrap'}
*
* When the app developer invokes `bootstrap()` with the root component `MyApp` as its
* argument, Angular performs the following tasks:
*
* 1. It uses the component's `selector` property to locate the DOM element which needs
* to be upgraded into the angular component.
* 2. It creates a new child injector (from the platform injector). Optionally, you can
* also override the injector configuration for an app by invoking `bootstrap` with the
* `componentInjectableBindings` argument.
* 3. It creates a new `Zone` and connects it to the angular application's change detection
* domain instance.
* 4. It creates an emulated or shadow DOM on the selected component's host element and loads the
* template into it.
* 5. It instantiates the specified component.
* 6. Finally, Angular performs change detection to apply the initial data providers for the
* application.
*
*
* ## Bootstrapping Multiple Applications
*
* When working within a browser window, there are many singleton resources: cookies, title,
* location, and others. Angular services that represent these resources must likewise be
* shared across all Angular applications that occupy the same browser window. For this
* reason, Angular creates exactly one global platform object which stores all shared
* services, and each angular application injector has the platform injector as its parent.
*
* Each application has its own private injector as well. When there are multiple
* applications on a page, Angular treats each application injector's services as private
* to that application.
*
* ## API
*
* - `appComponentType`: The root component which should act as the application. This is
* a reference to a `Type` which is annotated with `@Component(...)`.
* - `customProviders`: An additional set of providers that can be added to the
* app injector to override default injection behavior.
*
* Returns a `Promise` of {@link ComponentRef}.
*/
export function bootstrap(
appComponentType: Type,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
reflector.reflectionCapabilities = new ReflectionCapabilities();
var appInjector = ReflectiveInjector.resolveAndCreate(
[BROWSER_APP_PROVIDERS, isPresent(customProviders) ? customProviders : []],
browserPlatform().injector);
return coreLoadAndBootstrap(appInjector, appComponentType);
}

View File

@ -0,0 +1,28 @@
import {WORKER_APP_STATIC_APPLICATION_PROVIDERS} from '../static/worker_app';
import {workerAppPlatform} from '../common/worker_app';
import {COMPILER_PROVIDERS, XHR} from '@angular/compiler';
import {WebWorkerXHRImpl} from '../../web_workers/worker/xhr_impl';
import {isPresent} from '../../facade/lang';
import {
Type,
ComponentRef,
ReflectiveInjector,
coreLoadAndBootstrap,
} from '@angular/core';
export const WORKER_APP_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
WORKER_APP_STATIC_APPLICATION_PROVIDERS,
COMPILER_PROVIDERS,
WebWorkerXHRImpl,
/* @ts2dart_Provider */ {provide: XHR, useExisting: WebWorkerXHRImpl}
];
export function bootstrapApp(
appComponentType: Type,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
var appInjector = ReflectiveInjector.resolveAndCreate(
[WORKER_APP_APPLICATION_PROVIDERS, isPresent(customProviders) ? customProviders : []],
workerAppPlatform().injector);
return coreLoadAndBootstrap(appInjector, appComponentType);
}

View File

@ -0,0 +1,31 @@
import {XHR} from "@angular/compiler";
import {XHRImpl} from "../../xhr/xhr_impl";
import {MessageBasedXHRImpl} from "../../web_workers/ui/xhr_impl";
import {WORKER_RENDER_STATIC_APPLICATION_PROVIDERS} from "../static/worker_render";
import {ApplicationRef, ReflectiveInjector} from "@angular/core";
import {workerRenderPlatform, WORKER_SCRIPT, WORKER_RENDER_STARTABLE_MESSAGING_SERVICE} from "../common/worker_render";
import {isPresent} from "../../facade/lang";
import {PromiseWrapper} from "../../facade/async";
export const WORKER_RENDER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
WORKER_RENDER_STATIC_APPLICATION_PROVIDERS,
/* @ts2dart_Provider */ {provide: XHR, useClass: XHRImpl},
MessageBasedXHRImpl,
/* @ts2dart_Provider */ {provide: WORKER_RENDER_STARTABLE_MESSAGING_SERVICE, useExisting: MessageBasedXHRImpl, multi: true},
];
export function bootstrapRender(
workerScriptUri: string,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ApplicationRef> {
var app = ReflectiveInjector.resolveAndCreate(
[
WORKER_RENDER_APPLICATION_PROVIDERS,
/* @ts2dart_Provider */ {provide: WORKER_SCRIPT, useValue: workerScriptUri},
isPresent(customProviders) ? customProviders : []
],
workerRenderPlatform().injector);
// Return a promise so that we keep the same semantics as Dart,
// and we might want to wait for the app side to come up
// in the future...
return PromiseWrapper.resolve(app.get(ApplicationRef));
}

View File

@ -1,43 +1,21 @@
import {
ComponentRef,
coreLoadAndBootstrap,
ReflectiveInjector,
PlatformRef,
getPlatform,
createPlatform,
assertPlatform
ReflectiveInjector
} from '@angular/core';
import {Type, isPresent, isBlank} from './facade/lang';
import {Type, isPresent} from '../../facade/lang';
import {
BROWSER_APP_COMMON_PROVIDERS,
BROWSER_PROVIDERS,
BROWSER_PLATFORM_MARKER
} from './browser_common';
export {ELEMENT_PROBE_PROVIDERS} from './dom/debug/ng_probe';
export {BrowserPlatformLocation} from './browser/location/browser_platform_location';
export {
BROWSER_PROVIDERS,
By,
Title,
enableDebugTools,
disableDebugTools,
} from './browser_common';
browserPlatform
} from '../common/browser';
/**
* An array of providers that should be passed into `application()` when bootstrapping a component
* when all templates have been precompiled offline.
* when all templates have been pre-compiled.
*/
export const BROWSER_APP_STATIC_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/ BROWSER_APP_COMMON_PROVIDERS;
export function browserPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PROVIDERS));
}
return assertPlatform(BROWSER_PLATFORM_MARKER);
}
/**
* See {@link bootstrap} for more information.
*/

View File

@ -0,0 +1,45 @@
import {APP_INITIALIZER, NgZone, ReflectiveInjector, ComponentRef, coreLoadAndBootstrap} from '@angular/core';
import {Type, isPresent} from '../../../src/facade/lang';
import {workerAppPlatform} from '../common/worker_app';
import {WorkerDomAdapter} from '../../web_workers/worker/worker_adapter';
import {
PostMessageBus,
PostMessageBusSink,
PostMessageBusSource
} from '../../web_workers/shared/post_message_bus';
import {WORKER_APP_APPLICATION_COMMON_PROVIDERS} from '../common/worker_app';
import {MessageBus} from '../../web_workers/shared/message_bus';
// TODO(jteplitz602) remove this and compile with lib.webworker.d.ts (#3492)
let _postMessage = {
postMessage: (message: any, transferrables?:[ArrayBuffer]) => {
(<any>postMessage)(message, transferrables);
}
};
export const WORKER_APP_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
WORKER_APP_APPLICATION_COMMON_PROVIDERS,
/* @ts2dart_Provider */ {provide: MessageBus, useFactory: createMessageBus, deps: [NgZone]},
/* @ts2dart_Provider */ {provide: APP_INITIALIZER, useValue: setupWebWorker, multi: true}
];
export function bootstrapStaticApp(
appComponentType: Type,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
var appInjector = ReflectiveInjector.resolveAndCreate(
[WORKER_APP_STATIC_APPLICATION_PROVIDERS, isPresent(customProviders) ? customProviders : []],
workerAppPlatform().injector);
return coreLoadAndBootstrap(appInjector, appComponentType);
}
function createMessageBus(zone: NgZone): MessageBus {
let sink = new PostMessageBusSink(_postMessage);
let source = new PostMessageBusSource();
let bus = new PostMessageBus(sink, source);
bus.attachToZone(zone);
return bus;
}
function setupWebWorker(): void {
WorkerDomAdapter.makeCurrent();
}

View File

@ -2,17 +2,24 @@ import {
PostMessageBus,
PostMessageBusSink,
PostMessageBusSource
} from '../web_workers/shared/post_message_bus';
import {MessageBus} from '../web_workers/shared/message_bus';
} from '../../web_workers/shared/post_message_bus';
import {MessageBus} from '../../web_workers/shared/message_bus';
import {Injector, Injectable, APP_INITIALIZER} from '@angular/core';
import {
WORKER_RENDER_APPLICATION_COMMON_PROVIDERS,
WORKER_SCRIPT,
initializeGenericWorkerRenderer
} from './worker_render_common';
import {BaseException} from '../../src/facade/exceptions';
} from '../common/worker_render';
import {BaseException} from '../../../src/facade/exceptions';
export {WORKER_RENDER_STARTABLE_MESSAGING_SERVICE} from './worker_render_common';
import {isPresent} from '../../facade/lang';
import {PromiseWrapper} from '../../facade/async';
import {
ApplicationRef,
ReflectiveInjector,
} from '@angular/core';
import {workerRenderPlatform} from '../common/worker_render';
/**
* Wrapper class that exposes the Worker
@ -33,7 +40,7 @@ export class WebWorkerInstance {
/**
* An array of providers that should be passed into `application()` when initializing a new Worker.
*/
export const WORKER_RENDER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = /*@ts2dart_const*/[
export const WORKER_RENDER_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = /*@ts2dart_const*/[
WORKER_RENDER_APPLICATION_COMMON_PROVIDERS, WebWorkerInstance,
/*@ts2dart_Provider*/ {
provide: APP_INITIALIZER,
@ -48,6 +55,23 @@ export const WORKER_RENDER_APPLICATION_PROVIDERS: Array<any /*Type | Provider |
}
];
export function bootstrapStaticRender(
workerScriptUri: string,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ApplicationRef> {
var app = ReflectiveInjector.resolveAndCreate(
[
WORKER_RENDER_STATIC_APPLICATION_PROVIDERS,
/* @ts2dart_Provider */ {provide: WORKER_SCRIPT, useValue: workerScriptUri},
isPresent(customProviders) ? customProviders : []
],
workerRenderPlatform().injector);
// Return a promise so that we keep the same semantics as Dart,
// and we might want to wait for the app side to come up
// in the future...
return PromiseWrapper.resolve(app.get(ApplicationRef));
}
function initWebWorkerApplication(injector: Injector): void {
var scriptUri: string;
try {

View File

@ -1,35 +0,0 @@
export {DomEventsPlugin} from './dom/events/dom_events';
export {KeyEventsPlugin} from './dom/events/key_events';
export {EventManager, EVENT_MANAGER_PLUGINS} from './dom/events/event_manager';
export {ELEMENT_PROBE_PROVIDERS} from './dom/debug/ng_probe';
export {
BROWSER_APP_COMMON_PROVIDERS,
BROWSER_SANITIZATION_PROVIDERS,
BROWSER_PROVIDERS,
By,
Title,
enableDebugTools,
disableDebugTools,
HAMMER_GESTURE_CONFIG,
HammerGestureConfig
} from './browser_common';
export {DOCUMENT} from './dom/dom_tokens';
export {
DomSanitizationService,
SafeHtml,
SafeScript,
SafeStyle,
SafeUrl,
SafeResourceUrl,
SecurityContext
} from './security/dom_sanitization_service';
export {
bootstrapStatic,
browserPlatform,
BROWSER_APP_STATIC_PROVIDERS,
BrowserPlatformLocation
} from './platform_browser_static';

View File

@ -1,223 +0,0 @@
library angular2.src.web_workers.debug_tools.multi_client_server_message_bus;
import 'dart:io';
import 'dart:convert' show JSON;
import 'dart:async';
import 'package:angular2/src/web_workers/shared/messaging_api.dart';
import 'package:angular2/src/web_workers/shared/generic_message_bus.dart';
// TODO(jteplitz602): Remove hard coded result type and
// clear messageHistory once app is done with it #3859
class MultiClientServerMessageBus extends GenericMessageBus {
bool hasPrimary = false;
@override
MultiClientServerMessageBusSink get sink => super.sink;
@override
MultiClientServerMessageBusSource get source => super.source;
MultiClientServerMessageBus(MultiClientServerMessageBusSink sink,
MultiClientServerMessageBusSource source)
: super(sink, source);
MultiClientServerMessageBus.fromHttpServer(HttpServer server)
: super(new MultiClientServerMessageBusSink(),
new MultiClientServerMessageBusSource()) {
source.onResult.listen(_resultReceived);
server.listen((HttpRequest request) {
if (request.uri.path == "/ws") {
WebSocketTransformer.upgrade(request).then((WebSocket socket) {
var wrapper = new WebSocketWrapper(
sink.messageHistory, sink.resultMarkers, socket);
if (!hasPrimary) {
wrapper.setPrimary(true);
hasPrimary = true;
}
sink.addConnection(wrapper);
source.addConnection(wrapper);
wrapper.stream.listen(null, onDone: _handleDisconnect(wrapper));
});
}
});
}
void _resultReceived(_) {
sink.resultReceived();
}
Function _handleDisconnect(WebSocketWrapper wrapper) {
return () {
sink.removeConnection(wrapper);
if (wrapper.isPrimary) {
hasPrimary = false;
}
};
}
}
class WebSocketWrapper {
WebSocket _socket;
Stream stream;
int _numResultsReceived = 0;
bool _isPrimary = false;
bool caughtUp = false;
List<String> _messageHistory;
List<int> _resultMarkers;
StreamController<String> _sendStream;
WebSocketWrapper(this._messageHistory, this._resultMarkers, this._socket) {
stream = _socket.asBroadcastStream();
stream.listen((encodedMessage) {
var messages = JSON.decode(encodedMessage);
messages.forEach((data) {
var message = data['message'];
if (message is Map && message.containsKey("type")) {
if (message['type'] == 'result') {
resultReceived();
}
}
});
});
_sendStream = new StreamController<String>();
_socket.addStream(_sendStream.stream);
}
void send(String data) {
_sendStream.add(data);
}
bool get isPrimary => _isPrimary;
void resultReceived() {
if (!isPrimary && !caughtUp) {
_numResultsReceived++;
sendToMarker(_numResultsReceived);
}
}
void setPrimary(bool primary) {
_isPrimary = primary;
if (primary) {
caughtUp = true;
}
}
// Sends up to the given result marker
void sendToMarker(int markerIndex) {
int numMessages;
int curr;
if (markerIndex >= _resultMarkers.length) {
// we're past the final result marker so send all messages in history
curr = (_resultMarkers.length > 0)
? _resultMarkers[_resultMarkers.length - 1]
: 0;
numMessages = _messageHistory.length - curr;
caughtUp = true;
} else {
curr = (markerIndex == 0) ? 0 : _resultMarkers[markerIndex - 1];
var end = _resultMarkers[markerIndex];
numMessages = end - curr;
}
while (numMessages > 0) {
send(_messageHistory[curr]);
curr++;
numMessages--;
}
}
}
class MultiClientServerMessageBusSink extends GenericMessageBusSink {
final List<String> messageHistory = new List<String>();
final Set<WebSocketWrapper> openConnections = new Set<WebSocketWrapper>();
final List<int> resultMarkers = new List<int>();
void resultReceived() {
resultMarkers.add(messageHistory.length);
}
void addConnection(WebSocketWrapper webSocket) {
openConnections.add(webSocket);
// send messages up to the first result marker to this socket
webSocket.sendToMarker(0);
}
void removeConnection(WebSocketWrapper webSocket) {
openConnections.remove(webSocket);
}
@override
void sendMessages(List<dynamic> messages) {
String encodedMessages = JSON.encode(messages);
openConnections.forEach((WebSocketWrapper webSocket) {
if (webSocket.caughtUp) {
webSocket.send(encodedMessages);
}
});
messageHistory.add(encodedMessages);
}
}
class MultiClientServerMessageBusSource extends GenericMessageBusSource {
Function onResultReceived;
final StreamController mainController;
final StreamController resultController = new StreamController();
MultiClientServerMessageBusSource._(controller)
: mainController = controller,
super(controller.stream);
factory MultiClientServerMessageBusSource() {
return new MultiClientServerMessageBusSource._(
new StreamController.broadcast());
}
Stream get onResult => resultController.stream;
void addConnection(WebSocketWrapper webSocket) {
if (webSocket.isPrimary) {
webSocket.stream.listen((encodedMessages) {
var decodedMessages = _decodeMessages(encodedMessages);
decodedMessages.forEach((decodedMessage) {
var message = decodedMessage['message'];
if (message is Map && message.containsKey("type")) {
if (message['type'] == 'result') {
// tell the bus that a result was received on the primary
resultController.add(message);
}
}
});
mainController.add(decodedMessages);
});
} else {
webSocket.stream.listen((encodedMessages) {
// handle events from non-primary connection.
var decodedMessages = _decodeMessages(encodedMessages);
var eventMessages = new List<Map<String, dynamic>>();
decodedMessages.forEach((decodedMessage) {
var channel = decodedMessage['channel'];
if (channel == EVENT_CHANNEL) {
eventMessages.add(decodedMessage);
}
});
if (eventMessages.length > 0) {
mainController.add(eventMessages);
}
});
}
}
List<dynamic> _decodeMessages(dynamic messages) {
return JSON.decode(messages);
}
// This is a noop for the MultiClientBus because it has to decode the JSON messages before
// the generic bus receives them in order to check for results and forward events
// from the non-primary connection.
@override
List<dynamic> decodeMessages(dynamic messages) {
return messages;
}
}

View File

@ -1,88 +0,0 @@
library angular2.src.web_workers.debug_tools.single_client_server_message_bus;
import 'dart:io';
import 'dart:convert' show JSON;
import 'package:angular2/src/web_workers/shared/generic_message_bus.dart';
class SingleClientServerMessageBus extends GenericMessageBus {
bool connected = false;
@override
SingleClientServerMessageBusSink get sink => super.sink;
@override
SingleClientServerMessageBusSource get source => super.source;
SingleClientServerMessageBus(SingleClientServerMessageBusSink sink,
SingleClientServerMessageBusSource source)
: super(sink, source);
SingleClientServerMessageBus.fromHttpServer(HttpServer server)
: super(new SingleClientServerMessageBusSink(),
new SingleClientServerMessageBusSource()) {
server.listen((HttpRequest request) {
if (request.uri.path == "/ws") {
if (!connected) {
WebSocketTransformer.upgrade(request).then((WebSocket socket) {
sink.setConnection(socket);
var stream = socket.asBroadcastStream();
source.attachTo(stream);
stream.listen(null, onDone: _handleDisconnect);
}).catchError((error) {
throw error;
connected = false;
});
connected = true;
} else {
// refuse additional clients
request.response.statusCode = HttpStatus.SERVICE_UNAVAILABLE;
request.response.write("Maximum number of clients connected.");
request.response.close();
}
}
});
}
void _handleDisconnect() {
sink.removeConnection();
connected = false;
}
}
class SingleClientServerMessageBusSink extends GenericMessageBusSink {
final List<String> _messageBuffer = new List<String>();
WebSocket _socket = null;
void setConnection(WebSocket webSocket) {
_socket = webSocket;
_sendBufferedMessages();
}
void removeConnection() {
_socket = null;
}
@override
void sendMessages(List<dynamic> message) {
String encodedMessages = JSON.encode(message);
if (_socket != null) {
_socket.add(encodedMessages);
} else {
_messageBuffer.add(encodedMessages);
}
}
void _sendBufferedMessages() {
_messageBuffer.forEach((message) => _socket.add(message));
_messageBuffer.clear();
}
}
class SingleClientServerMessageBusSource extends GenericMessageBusSource {
SingleClientServerMessageBusSource() : super(null);
@override
List<dynamic> decodeMessages(dynamic messages) {
return JSON.decode(messages);
}
}

View File

@ -1,34 +0,0 @@
library angular2.src.web_workers.worker.web_socket_message_bus;
import 'dart:html';
import 'dart:convert' show JSON;
import 'package:angular2/src/web_workers/shared/generic_message_bus.dart';
class WebSocketMessageBus extends GenericMessageBus {
WebSocketMessageBus(
WebSocketMessageBusSink sink, WebSocketMessageBusSource source)
: super(sink, source);
WebSocketMessageBus.fromWebSocket(WebSocket webSocket)
: super(new WebSocketMessageBusSink(webSocket),
new WebSocketMessageBusSource(webSocket));
}
class WebSocketMessageBusSink extends GenericMessageBusSink {
final WebSocket _webSocket;
WebSocketMessageBusSink(this._webSocket);
void sendMessages(List<dynamic> messages) {
_webSocket.send(JSON.encode(messages));
}
}
class WebSocketMessageBusSource extends GenericMessageBusSource {
WebSocketMessageBusSource(WebSocket webSocket) : super(webSocket.onMessage);
List<dynamic> decodeMessages(MessageEvent event) {
var messages = event.data;
return JSON.decode(messages);
}
}

View File

@ -1,156 +0,0 @@
library angular2.src.web_workers.shared.generic_message_bus;
import 'dart:async';
import 'package:angular2/src/facade/async.dart' show EventEmitter;
import 'package:angular2/src/web_workers/shared/message_bus.dart'
show MessageBus, MessageBusSink, MessageBusSource;
import 'package:angular2/src/core/zone/ng_zone.dart';
import 'package:angular2/src/facade/lang.dart';
import 'package:angular2/src/facade/exceptions.dart';
class GenericMessageBus implements MessageBus {
final MessageBusSink _sink;
final MessageBusSource _source;
MessageBusSink get sink => _sink;
MessageBusSource get source => _source;
GenericMessageBus(MessageBusSink sink, MessageBusSource source)
: _sink = sink,
_source = source;
void attachToZone(NgZone zone) {
_sink.attachToZone(zone);
_source.attachToZone(zone);
}
void initChannel(String channel, [bool runInZone = true]) {
_sink.initChannel(channel, runInZone);
_source.initChannel(channel, runInZone);
}
EventEmitter from(String channel) {
return _source.from(channel);
}
EventEmitter to(String channel) {
return _sink.to(channel);
}
}
abstract class GenericMessageBusSink implements MessageBusSink {
NgZone _zone;
final _channels = new Map<String, _Channel>();
final _messageBuffer = new List<dynamic>();
void attachToZone(NgZone zone) {
_zone = zone;
_zone.runOutsideAngular(() {
_zone.onStable.listen((_) {
if (_messageBuffer.length > 0) {
sendMessages(_messageBuffer);
_messageBuffer.clear();
}
});
});
}
void initChannel(String channelName, [bool runInZone = true]) {
if (_channels.containsKey(channelName)) {
throw new BaseException("${channelName} has already been initialized.");
}
var emitter = new EventEmitter();
var channel = new _Channel(emitter, runInZone);
emitter.listen((data) {
var message = {'channel': channelName, 'message': data};
if (runInZone) {
_messageBuffer.add(message);
} else {
sendMessages([message]);
}
});
_channels[channelName] = channel;
}
EventEmitter to(String channelName) {
if (_channels.containsKey(channelName)) {
return _channels[channelName].emitter;
} else {
throw new BaseException(
"${channelName} is not set up. Did you forget to call initChannel?");
}
}
void sendMessages(List<dynamic> messages);
}
abstract class GenericMessageBusSource implements MessageBusSource {
Stream _stream;
final _channels = new Map<String, _Channel>();
NgZone _zone;
Stream get stream => _stream;
GenericMessageBusSource(Stream stream) {
attachTo(stream);
}
void attachTo(Stream stream) {
_stream = stream;
if (stream != null) {
stream.listen((messages) {
List<dynamic> decodedMessages = decodeMessages(messages);
if (decodedMessages != null) {
decodedMessages.forEach((message) => _handleMessage(message));
}
});
}
}
void attachToZone(NgZone zone) {
_zone = zone;
}
void initChannel(String channelName, [bool runInZone = true]) {
if (_channels.containsKey(channelName)) {
throw new BaseException("${channelName} has already been initialized.");
}
var emitter = new EventEmitter();
var channelInfo = new _Channel(emitter, runInZone);
_channels[channelName] = channelInfo;
}
EventEmitter from(String channelName) {
if (_channels.containsKey(channelName)) {
return _channels[channelName].emitter;
} else {
throw new BaseException(
"${channelName} is not set up. Did you forget to call initChannel?");
}
}
void _handleMessage(dynamic data) {
var channelName = data['channel'];
if (_channels.containsKey(channelName)) {
var channelInfo = _channels[channelName];
if (channelInfo.runInZone) {
_zone.run(() => channelInfo.emitter.add(data['message']));
} else {
channelInfo.emitter.add(data['message']);
}
}
}
List<dynamic> decodeMessages(dynamic message);
}
class _Channel {
EventEmitter emitter;
bool runInZone;
_Channel(this.emitter, this.runInZone);
}

View File

@ -1,33 +0,0 @@
library angular2.src.web_workers.shared.isolate_message_bus;
import 'dart:isolate';
import 'package:angular2/src/web_workers/shared/generic_message_bus.dart';
class IsolateMessageBus extends GenericMessageBus {
IsolateMessageBus(IsolateMessageBusSink sink, IsolateMessageBusSource source)
: super(sink, source);
}
class IsolateMessageBusSink extends GenericMessageBusSink {
final SendPort _port;
IsolateMessageBusSink(SendPort port) : _port = port;
@override
void sendMessages(List<dynamic> messages) {
_port.send(messages);
}
}
class IsolateMessageBusSource extends GenericMessageBusSource {
IsolateMessageBusSource(ReceivePort port) : super(port.asBroadcastStream());
@override
List<dynamic> decodeMessages(dynamic messages) {
if (messages is SendPort) {
return null;
}
return messages;
}
}

View File

@ -5,3 +5,4 @@
export const RENDERER_CHANNEL = "ng-Renderer";
export const EVENT_CHANNEL = "ng-Events";
export const ROUTER_CHANNEL = "ng-Router";
export const XHR_CHANNEL = "ng-XHR";

View File

@ -1,3 +0,0 @@
// PostMessageBus can't be implemented in dart since dart doesn't use postMessage
// This file is only here to prevent ts2dart from trying to transpile the PostMessageBus
library angular2.src.web_workers.shared.post_message_bus;

View File

@ -1,108 +0,0 @@
library angular2.src.web_workers.event_serializer;
import 'dart:core';
import 'dart:html';
// List of all elements with HTML value attribute.
// Taken from: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
final Set<String> NODES_WITH_VALUE = new Set<String>.from([
"input",
"select",
"option",
"button",
"li",
"meter",
"progress",
"param",
"textarea"
]);
Map<String, dynamic> serializeGenericEvent(dynamic e) {
var serialized = new Map<String, dynamic>();
serialized['bubbles'] = e.bubbles;
serialized['cancelable'] = e.cancelable;
serialized['defaultPrevented'] = e.defaultPrevented;
serialized['eventPhase'] = e.eventPhase;
serialized['timeStamp'] = e.timeStamp;
serialized['type'] = e.type;
return serialized;
}
// TODO(jteplitz602): Allow users to specify the properties they need rather than always
// adding value #3374
Map<String, dynamic> serializeEventWithTarget(dynamic e) {
var serializedEvent = serializeGenericEvent(e);
return addTarget(e, serializedEvent);
}
Map<String, dynamic> serializeMouseEvent(dynamic e) {
var serialized = new Map<String, dynamic>();
serialized['altKey'] = e.altKey;
serialized['bubbles'] = e.bubbles;
serialized['button'] = e.button;
serialized['cancelable'] = e.cancelable;
serialized['client'] = serializePoint(e.client);
serialized['ctrlKey'] = e.ctrlKey;
serialized['defaultPrevented'] = e.defaultPrevented;
serialized['detail'] = e.detail;
serialized['eventPhase'] = e.eventPhase;
serialized['layer'] = serializePoint(e.layer);
serialized['metaKey'] = e.metaKey;
serialized['offset'] = serializePoint(e.offset);
serialized['page'] = serializePoint(e.page);
serialized['region'] = e.region;
serialized['screen'] = serializePoint(e.screen);
serialized['shiftKey'] = e.shiftKey;
serialized['timeStamp'] = e.timeStamp;
serialized['type'] = e.type;
return serialized;
}
Map<String, dynamic> serializePoint(Point point) {
var serialized = new Map<String, dynamic>();
serialized['magnitude'] = point.magnitude;
serialized['x'] = point.x;
serialized['y'] = point.y;
return serialized;
}
Map<String, dynamic> serializeKeyboardEvent(dynamic e) {
var serialized = new Map<String, dynamic>();
serialized['altKey'] = e.altKey;
serialized['bubbles'] = e.bubbles;
serialized['cancelable'] = e.cancelable;
serialized['charCode'] = e.charCode;
serialized['ctrlKey'] = e.ctrlKey;
serialized['defaultPrevented'] = e.defaultPrevented;
serialized['detail'] = e.detail;
serialized['eventPhase'] = e.eventPhase;
serialized['keyCode'] = e.keyCode;
serialized['keyLocation'] = e.keyLocation;
serialized['location'] = e.location;
serialized['repeat'] = e.repeat;
serialized['shiftKey'] = e.shiftKey;
serialized['timeStamp'] = e.timeStamp;
serialized['type'] = e.type;
//return addTarget(e, serialized);
return serialized;
}
Map<String, dynamic> serializeTransitionEvent(dynamic e) {
var serialized = serializeGenericEvent(e);
serialized['propertyName'] = e.propertyName;
serialized['elapsedTime'] = e.elapsedTime;
serialized['pseudoElement'] = e.pseudoElement;
return addTarget(e, serialized);
}
// TODO(jteplitz602): #3374. See above.
Map<String, dynamic> addTarget(
dynamic e, Map<String, dynamic> serializedEvent) {
if (NODES_WITH_VALUE.contains(e.target.tagName.toLowerCase())) {
serializedEvent['target'] = {'value': e.target.value};
if (e.target is InputElement) {
serializedEvent['target']['files'] = e.target.files;
}
}
return serializedEvent;
}

View File

@ -0,0 +1,24 @@
import {Injectable} from '@angular/core';
import {PRIMITIVE} from '../shared/serializer';
import {ServiceMessageBrokerFactory} from '../shared/service_message_broker';
import {XHR_CHANNEL} from '../shared/messaging_api';
import {XHR} from '@angular/compiler';
import {FunctionWrapper} from '../../facade/lang';
/**
* XHR requests triggered on the worker side are executed on the UI side.
*
* This is only strictly required for Dart where the isolates do not have access to XHRs.
*
* @internal
*/
@Injectable()
export class MessageBasedXHRImpl {
constructor(private _brokerFactory: ServiceMessageBrokerFactory, private _xhr: XHR) {}
start(): void {
var broker = this._brokerFactory.createMessageBroker(XHR_CHANNEL);
broker.registerMethod("get", [PRIMITIVE], FunctionWrapper.bind(this._xhr.get, this._xhr),
PRIMITIVE);
}
}

View File

@ -1,73 +0,0 @@
library angular2.src.web_workers.worker.event_deserializer;
class GenericEvent {
Map<String, dynamic> properties;
EventTarget _target = null;
GenericEvent(this.properties);
bool get bubbles => properties['bubbles'];
bool get cancelable => properties['cancelable'];
bool get defaultPrevented => properties['defaultPrevented'];
int get eventPhase => properties['eventPhase'];
int get timeStamp => properties['timeStamp'];
String get type => properties['type'];
bool get altKey => properties['altKey'];
int get charCode => properties['charCode'];
bool get ctrlKey => properties['ctrlKey'];
int get detail => properties['detail'];
int get keyCode => properties['keyCode'];
int get keyLocation => properties['keyLocation'];
Point get layer => _getPoint('layer');
int get location => properties['location'];
bool get repeat => properties['repeat'];
bool get shiftKey => properties['shiftKey'];
int get button => properties['button'];
Point get client => _getPoint('client');
bool get metaKey => properties['metaKey'];
Point get offset => _getPoint('offset');
Point get page => _getPoint('page');
Point get screen => _getPoint('screen');
String get propertyName => properties['propertyName'];
num get elapsedTime => properties['elapsedTime'];
String get pseudoElement => properties['pseudoElement'];
EventTarget get target {
if (_target != null) {
return _target;
} else if (properties.containsKey("target")) {
_target = new EventTarget(properties['target']);
return _target;
} else {
return null;
}
}
dynamic _getPoint(name) {
Map<String, dynamic> point = properties[name];
return new Point(point['x'], point['y'], point['magnitude']);
}
}
class EventTarget {
dynamic value;
EventTarget(Map<String, dynamic> properties) {
value = properties['value'];
}
}
class Point {
int x;
int y;
double magnitude;
Point(this.x, this.y, this.magnitude);
}
GenericEvent deserializeGenericEvent(Map<String, dynamic> serializedEvent) {
return new GenericEvent(serializedEvent);
}

View File

@ -1,390 +0,0 @@
library angular2.dom.webWorkerAdapter;
import 'abstract_html_adapter.dart';
import 'package:angular2/platform/common_dom.dart';
/**
* This adapter is required to log error messages.
*
* Note: other methods all throw as the DOM is not accessible directly
* in web worker context.
*/
class WebWorkerDomAdapter implements DomAdapter {
static void makeCurrent() {
setRootDomAdapter(new WebWorkerDomAdapter());
}
logError(error) {
print('${error}');
}
log(error) {
print('${error}');
}
logGroup(error) {
print('${error}');
}
logGroupEnd() {}
hasProperty(element, String name) {
throw 'not implemented';
}
void setProperty(Element element, String name, Object value) =>
throw 'not implemented';
getProperty(Element element, String name) => throw 'not implemented';
invoke(Element element, String methodName, List args) =>
throw 'not implemented';
get attrToPropMap => throw 'not implemented';
set attrToPropMap(value) {
throw 'readonly';
}
getGlobalEventTarget(String target) {
throw 'not implemented';
}
getTitle() {
throw 'not implemented';
}
setTitle(String newTitle) {
throw 'not implemented';
}
String getEventKey(event) {
throw 'not implemented';
}
void replaceChild(el, newNode, oldNode) {
throw 'not implemented';
}
dynamic getBoundingClientRect(el) {
throw 'not implemented';
}
Type getXHR() => throw 'not implemented';
Element parse(String templateHtml) => throw 'not implemented';
query(selector) {
throw 'not implemented';
}
querySelector(el, String selector) {
throw 'not implemented';
}
List querySelectorAll(el, String selector) {
throw 'not implemented';
}
on(el, evt, listener) {
throw 'not implemented';
}
Function onAndCancel(el, evt, listener) {
throw 'not implemented';
}
dispatchEvent(el, evt) {
throw 'not implemented';
}
createMouseEvent(eventType) {
throw 'not implemented';
}
createEvent(eventType) {
throw 'not implemented';
}
preventDefault(evt) {
throw 'not implemented';
}
isPrevented(evt) {
throw 'not implemented';
}
getInnerHTML(el) => throw 'not implemented';
getOuterHTML(el) => throw 'not implemented';
String nodeName(node) => throw 'not implemented';
String nodeValue(node) => throw 'not implemented';
String type(node) {
throw 'not implemented';
}
content(node) => throw 'not implemented';
firstChild(el) => throw 'not implemented';
nextSibling(el) => throw 'not implemented';
parentElement(el) => throw 'not implemented';
List childNodes(el) => throw 'not implemented';
List childNodesAsList(el) => throw 'not implemented';
clearNodes(el) {
throw 'not implemented';
}
appendChild(el, node) => throw 'not implemented';
removeChild(el, node) {
throw 'not implemented';
}
remove(el) => throw 'not implemented';
insertBefore(el, node) {
throw 'not implemented';
}
insertAllBefore(el, nodes) {
throw 'not implemented';
}
insertAfter(el, node) {
throw 'not implemented';
}
setInnerHTML(el, value) {
throw 'not implemented';
}
getText(el) => throw 'not implemented';
setText(el, String value) => throw 'not implemented';
getValue(el) {
throw 'not implemented';
}
setValue(el, String value) {
throw 'not implemented';
}
getChecked(el) {
throw 'not implemented';
}
setChecked(el, bool value) {
throw 'not implemented';
}
createComment(String text) => throw 'not implemented';
createTemplate(String html) => throw 'not implemented';
createElement(tagName, [doc]) => throw 'not implemented';
createElementNS(ns, tagName, [doc]) {
throw 'not implemented';
}
createTextNode(String text, [doc]) => throw 'not implemented';
createScriptTag(String attrName, String attrValue, [doc]) {
throw 'not implemented';
}
createStyleElement(String css, [doc]) {
throw 'not implemented';
}
createShadowRoot(el) {
throw 'not implemented';
}
getShadowRoot(el) {
throw 'not implemented';
}
getHost(el) {
throw 'not implemented';
}
clone(node) => throw 'not implemented';
getElementsByClassName(element, String name) {
throw 'not implemented';
}
getElementsByTagName(element, String name) {
throw 'not implemented';
}
List classList(element) => throw 'not implemented';
addClass(element, String className) {
throw 'not implemented';
}
removeClass(element, String className) {
throw 'not implemented';
}
hasClass(element, String className) => throw 'not implemented';
setStyle(element, String styleName, String styleValue) {
throw 'not implemented';
}
bool hasStyle(Element element, String styleName, [String styleValue]) {
throw 'not implemented';
}
removeStyle(element, String styleName) {
throw 'not implemented';
}
getStyle(element, String styleName) {
throw 'not implemented';
}
String tagName(element) => throw 'not implemented';
attributeMap(element) => throw 'not implemented';
hasAttribute(element, String attribute) => throw 'not implemented';
hasAttributeNS(element, String ns, String attribute) {
throw 'not implemented';
}
getAttribute(element, String attribute) => throw 'not implemented';
getAttributeNS(element, String ns, String attribute) {
throw 'not implemented';
}
setAttribute(element, String name, String value) {
throw 'not implemented';
}
setAttributeNS(element, String ns, String name, String value) {
throw 'not implemented';
}
removeAttribute(element, String attribute) {
throw 'not implemented';
}
removeAttributeNS(element, String ns, String attribute) {
throw 'not implemented';
}
templateAwareRoot(el) => throw 'not implemented';
createHtmlDocument() {
throw 'not implemented';
}
defaultDoc() {
throw 'not implemented';
}
bool elementMatches(n, String selector) {
throw 'not implemented';
}
bool isTemplateElement(Element el) => throw 'not implemented';
bool isTextNode(node) => throw 'not implemented';
bool isCommentNode(node) => throw 'not implemented';
bool isElementNode(node) => throw 'not implemented';
bool hasShadowRoot(node) {
throw 'not implemented';
}
bool isShadowRoot(node) {
throw 'not implemented';
}
importIntoDoc(node) {
throw 'not implemented';
}
adoptNode(node) {
throw 'not implemented';
}
String getHref(element) {
throw 'not implemented';
}
void resolveAndSetHref(element, baseUrl, href) {
throw 'not implemented';
}
List getDistributedNodes(Node) {
throw 'not implemented';
}
bool supportsDOMEvents() => throw 'not implemented';
bool supportsNativeShadowDOM() => throw 'not implemented';
getHistory() => throw 'not implemented';
getLocation() {
throw 'not implemented';
}
getBaseHref() {
throw 'not implemented';
}
resetBaseElement() {
throw 'not implemented';
}
String getUserAgent() => throw 'not implemented';
void setData(Element element, String name, String value) {
throw 'not implemented';
}
getComputedStyle(element) {
throw 'not implemented';
}
String getData(Element element, String name) => throw 'not implemented';
// TODO(tbosch): move this into a separate environment class once we have it
setGlobalVar(String name, value) {
throw 'not implemented';
}
requestAnimationFrame(callback) {
throw 'not implemented';
}
cancelAnimationFrame(id) {
throw 'not implemented';
}
performanceNow() {
throw 'not implemented';
}
getAnimationPrefix() {
throw 'not implemented';
}
getTransitionEnd() {
throw 'not implemented';
}
supportsAnimation() {
throw 'not implemented';
}
}

View File

@ -0,0 +1,31 @@
import {Injectable} from '@angular/core';
import {XHR} from '@angular/compiler';
import {
FnArg,
UiArguments,
ClientMessageBroker,
ClientMessageBrokerFactory
} from '../shared/client_message_broker';
import {XHR_CHANNEL} from '../shared/messaging_api';
/**
* Implementation of compiler/xhr that relays XHR requests to the UI side where they are sent
* and the result is proxied back to the worker.
*
* This is only strictly required for Dart where isolates do not have access to the XHRs.
*/
@Injectable()
export class WebWorkerXHRImpl extends XHR {
private _messageBroker: ClientMessageBroker;
constructor(messageBrokerFactory: ClientMessageBrokerFactory) {
super();
this._messageBroker = messageBrokerFactory.createMessageBroker(XHR_CHANNEL);
}
get(url: string): Promise<string> {
var fnArgs: FnArg[] = [new FnArg(url, null)];
var args: UiArguments = new UiArguments("get", fnArgs);
return this._messageBroker.runOnService(args, String);
}
}

View File

@ -1,37 +0,0 @@
library angular2.src.platform.worker_app;
import 'package:angular2/src/core/zone/ng_zone.dart';
import 'package:angular2/src/platform/server/webworker_adapter.dart';
import 'package:angular2/src/platform/worker_app_common.dart';
import 'package:angular2/core.dart';
import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart';
import 'package:angular2/src/web_workers/shared/message_bus.dart';
import 'dart:isolate';
const OpaqueToken RENDER_SEND_PORT = const OpaqueToken("RenderSendPort");
const List<dynamic> WORKER_APP_APPLICATION_PROVIDERS = const [
WORKER_APP_APPLICATION_COMMON,
const Provider(MessageBus,
useFactory: createMessageBus, deps: const [NgZone, RENDER_SEND_PORT]),
const Provider(APP_INITIALIZER, useValue: setupIsolate, multi: true)
];
MessageBus createMessageBus(NgZone zone, SendPort replyTo) {
ReceivePort rPort = new ReceivePort();
var sink = new WebWorkerMessageBusSink(replyTo, rPort);
var source = new IsolateMessageBusSource(rPort);
var bus = new IsolateMessageBus(sink, source);
bus.attachToZone(zone);
return bus;
}
setupIsolate() {
WebWorkerDomAdapter.makeCurrent();
}
class WebWorkerMessageBusSink extends IsolateMessageBusSink {
WebWorkerMessageBusSink(SendPort sPort, ReceivePort rPort) : super(sPort) {
sPort.send(rPort.sendPort);
}
}

View File

@ -1,34 +0,0 @@
import {APP_INITIALIZER, NgZone} from '@angular/core';
import {WorkerDomAdapter} from '../web_workers/worker/worker_adapter';
import {
PostMessageBus,
PostMessageBusSink,
PostMessageBusSource
} from '../web_workers/shared/post_message_bus';
import {WORKER_APP_APPLICATION_COMMON_PROVIDERS} from './worker_app_common';
import {MessageBus} from '../web_workers/shared/message_bus';
// TODO(jteplitz602) remove this and compile with lib.webworker.d.ts (#3492)
let _postMessage = {
postMessage: (message: any, transferrables?:[ArrayBuffer]) => {
(<any>postMessage)(message, transferrables);
}
};
export const WORKER_APP_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = [
WORKER_APP_APPLICATION_COMMON_PROVIDERS,
/* @ts2dart_Provider */ {provide: MessageBus, useFactory: createMessageBus, deps: [NgZone]},
/* @ts2dart_Provider */ {provide: APP_INITIALIZER, useValue: setupWebWorker, multi: true}
];
function createMessageBus(zone: NgZone): MessageBus {
let sink = new PostMessageBusSink(_postMessage);
let source = new PostMessageBusSource();
let bus = new PostMessageBus(sink, source);
bus.attachToZone(zone);
return bus;
}
function setupWebWorker(): void {
WorkerDomAdapter.makeCurrent();
}

View File

@ -1,64 +0,0 @@
library angular2.src.platform.worker_render;
import 'package:angular2/src/platform/worker_render_common.dart'
show
WORKER_RENDER_APPLICATION_COMMON_PROVIDERS,
WORKER_RENDER_MESSAGING_PROVIDERS,
WORKER_SCRIPT,
initializeGenericWorkerRenderer;
import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart';
import 'package:angular2/src/web_workers/shared/message_bus.dart';
import 'package:angular2/core.dart';
import 'package:angular2/src/core/di.dart';
import 'dart:isolate';
import 'dart:async';
const WORKER_RENDER_APP_PROVIDERS = WORKER_RENDER_APPLICATION_COMMON_PROVIDERS;
Future<List> initIsolate(String scriptUri) async {
var instance = await spawnIsolate(Uri.parse(scriptUri));
return [
WORKER_RENDER_APPLICATION_COMMON,
new Provider(WebWorkerInstance, useValue: instance),
new Provider(APP_INITIALIZER,
useFactory: (injector) => () => initializeGenericWorkerRenderer(injector),
multi: true,
deps: [Injector]),
new Provider(MessageBus, useValue: instance.bus)
];
}
/**
* Spawns a new class and initializes the WebWorkerInstance
*/
Future<WebWorkerInstance> spawnIsolate(Uri uri) async {
var receivePort = new ReceivePort();
var isolateEndSendPort = receivePort.sendPort;
var isolate = await Isolate.spawnUri(uri, const [], isolateEndSendPort);
var source = new UIMessageBusSource(receivePort);
var sendPort = await source.sink;
var sink = new IsolateMessageBusSink(sendPort);
var bus = new IsolateMessageBus(sink, source);
return new WebWorkerInstance(isolate, bus);
}
class UIMessageBusSource extends IsolateMessageBusSource {
UIMessageBusSource(ReceivePort port) : super(port);
Future<SendPort> get sink => stream.firstWhere((message) {
return message is SendPort;
});
}
/**
* Wrapper class that exposes the Isolate
* and underlying {@link MessageBus} for lower level message passing.
*/
class WebWorkerInstance {
Isolate worker;
MessageBus bus;
WebWorkerInstance(this.worker, this.bus);
}

View File

@ -1,51 +0,0 @@
library angular2.platform.worker_app;
import "package:angular2/src/platform/worker_app_common.dart";
import "package:angular2/src/platform/worker_app.dart";
import 'package:angular2/core.dart';
import 'package:angular2/src/facade/lang.dart';
import 'dart:isolate';
import 'dart:async';
export "package:angular2/src/platform/worker_app_common.dart"
show WORKER_APP_PLATFORM_PROVIDERS, WORKER_APP_APPLICATION_COMMON_PROVIDERS;
export "package:angular2/src/core/angular_entrypoint.dart"
show AngularEntrypoint;
export "package:angular2/src/platform/worker_app.dart"
show WORKER_APP_APPLICATION_PROVIDERS, RENDER_SEND_PORT;
export 'package:angular2/src/web_workers/shared/client_message_broker.dart'
show ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments;
export 'package:angular2/src/web_workers/shared/service_message_broker.dart'
show ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory;
export 'package:angular2/src/web_workers/shared/serializer.dart' show PRIMITIVE;
export 'package:angular2/src/web_workers/shared/message_bus.dart';
export 'package:angular2/src/web_workers/worker/location_providers.dart'
show WORKER_APP_ROUTER;
PlatformRef _platform = null;
SendPort _renderSendPort = null;
PlatformRef workerAppPlatform(SendPort renderSendPort) {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate([
WORKER_APP_PLATFORM_PROVIDERS,
new Provider(RENDER_SEND_PORT, useValue: renderSendPort)
]));
}
var platform = assertPlatform(WORKER_APP_PLATFORM_MARKER);
if (platform.injector.get(RENDER_SEND_PORT, null) != renderSendPort) {
throw 'Platform has already been created with a different SendPort. Please destroy it first.';
}
return platform;
}
Future<ComponentRef<dynamic>> bootstrapApp(
SendPort renderSendPort,
Type appComponentType,
[List<dynamic /*Type | Provider | any[]*/> customProviders]) {
var appInjector = ReflectiveInjector.resolveAndCreate([
WORKER_APP_APPLICATION_PROVIDERS,
isPresent(customProviders) ? customProviders : []
], workerAppPlatform(renderSendPort).injector);
return coreLoadAndBootstrap(appInjector, appComponentType);
}

View File

@ -1,52 +0,0 @@
import {isPresent, isBlank} from './facade/lang';
import {
WORKER_APP_PLATFORM_PROVIDERS,
WORKER_APP_PLATFORM_MARKER
} from './webworker/worker_app_common';
import {WORKER_APP_APPLICATION_PROVIDERS} from './webworker/worker_app';
import {
PlatformRef,
Type,
ComponentRef,
ReflectiveInjector,
coreLoadAndBootstrap,
getPlatform,
createPlatform,
assertPlatform
} from '@angular/core';
export {
WORKER_APP_PLATFORM_PROVIDERS,
WORKER_APP_APPLICATION_COMMON_PROVIDERS
} from './webworker/worker_app_common';
export {WORKER_APP_APPLICATION_PROVIDERS} from './webworker/worker_app';
export {
ClientMessageBroker,
ClientMessageBrokerFactory,
FnArg,
UiArguments
} from './web_workers/shared/client_message_broker';
export {
ReceivedMessage,
ServiceMessageBroker,
ServiceMessageBrokerFactory
} from './web_workers/shared/service_message_broker';
export {PRIMITIVE} from './web_workers/shared/serializer';
export * from './web_workers/shared/message_bus';
export {WORKER_APP_LOCATION_PROVIDERS} from './web_workers/worker/location_providers';
export function workerAppPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_APP_PLATFORM_PROVIDERS));
}
return assertPlatform(WORKER_APP_PLATFORM_MARKER);
}
export function bootstrapStaticApp(
appComponentType: Type,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef<any>> {
var appInjector = ReflectiveInjector.resolveAndCreate(
[WORKER_APP_APPLICATION_PROVIDERS, isPresent(customProviders) ? customProviders : []],
workerAppPlatform().injector);
return coreLoadAndBootstrap(appInjector, appComponentType);
}

View File

@ -1,49 +0,0 @@
library angular2.platform.worker_render;
import 'package:angular2/src/platform/worker_render.dart';
import 'package:angular2/src/platform/worker_render_common.dart';
import 'package:angular2/core.dart';
import 'package:angular2/src/facade/lang.dart';
import 'dart:async';
export 'package:angular2/src/platform/worker_render_common.dart'
show
WORKER_SCRIPT,
WORKER_RENDER_PLATFORM,
WORKER_RENDER_APPLICATION_COMMON,
initializeGenericWorkerRenderer;
export 'package:angular2/src/platform/worker_render.dart'
show WebWorkerInstance;
export '../src/web_workers/shared/client_message_broker.dart'
show ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments;
export '../src/web_workers/shared/service_message_broker.dart'
show ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory;
export '../src/web_workers/shared/serializer.dart' show PRIMITIVE;
export '../src/web_workers/shared/message_bus.dart';
export '../src/web_workers/ui/location_providers.dart' show WORKER_RENDER_ROUTER;
const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION_COMMON;
PlatformRef workerStaticRenderPlatform() {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_RENDER_PLATFORM));
}
return assertPlatform(WORKER_RENDER_PLATFORM_MARKER);
}
Future<ApplicationRef> bootstrapStaticRender(
String workerScriptUri,
[List<dynamic /*Type | Provider | any[]*/> customProviders]) {
return initIsolate(workerScriptUri).then( (appProviders) {
var appInjector = ReflectiveInjector.resolveAndCreate([
appProviders,
isPresent(customProviders) ? customProviders : []
], workerRenderPlatform().injector);
return appInjector.get(ApplicationRef);
});
}

View File

@ -1,66 +0,0 @@
import {isPresent, isBlank} from './facade/lang';
import {PromiseWrapper} from './facade/async';
import {
ApplicationRef,
PlatformRef,
ReflectiveInjector,
getPlatform,
createPlatform,
assertPlatform
} from '@angular/core';
import {WORKER_RENDER_APPLICATION_PROVIDERS} from './webworker/worker_render';
import {
WORKER_SCRIPT,
WORKER_RENDER_PLATFORM_PROVIDERS,
WORKER_RENDER_PLATFORM_MARKER
} from './webworker/worker_render_common';
export {
WORKER_SCRIPT,
WORKER_RENDER_PLATFORM_PROVIDERS,
initializeGenericWorkerRenderer,
WORKER_RENDER_APPLICATION_COMMON_PROVIDERS
} from './webworker/worker_render_common';
export {
WORKER_RENDER_APPLICATION_PROVIDERS,
WORKER_RENDER_STARTABLE_MESSAGING_SERVICE,
WebWorkerInstance
} from './webworker/worker_render';
export {
ClientMessageBroker,
ClientMessageBrokerFactory,
FnArg,
UiArguments
} from './web_workers/shared/client_message_broker';
export {
ReceivedMessage,
ServiceMessageBroker,
ServiceMessageBrokerFactory
} from './web_workers/shared/service_message_broker';
export {PRIMITIVE} from './web_workers/shared/serializer';
export * from './web_workers/shared/message_bus';
export {WORKER_RENDER_LOCATION_PROVIDERS} from '../src/web_workers/ui/location_providers';
export function workerRenderPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_RENDER_PLATFORM_PROVIDERS));
}
return assertPlatform(WORKER_RENDER_PLATFORM_MARKER);
}
export function bootstrapStaticRender(
workerScriptUri: string,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ApplicationRef> {
var app = ReflectiveInjector.resolveAndCreate(
[
WORKER_RENDER_APPLICATION_PROVIDERS,
/* @ts2dart_Provider */ {provide: WORKER_SCRIPT, useValue: workerScriptUri},
isPresent(customProviders) ? customProviders : []
],
workerRenderPlatform().injector);
// Return a promise so that we keep the same semantics as Dart,
// and we might want to wait for the app side to come up
// in the future...
return PromiseWrapper.resolve(app.get(ApplicationRef));
}

View File

@ -0,0 +1,31 @@
import {XHR} from '@angular/compiler';
import {BaseException} from '../../src/facade/exceptions';
import {global} from '../../src/facade/lang';
import {PromiseWrapper} from '../../src/facade/promise';
/**
* An implementation of XHR that uses a template cache to avoid doing an actual
* XHR.
*
* The template cache needs to be built and loaded into window.$templateCache
* via a separate mechanism.
*/
export class CachedXHR extends XHR {
private _cache: {[url: string]: string};
constructor() {
super();
this._cache = (<any>global).$templateCache;
if (this._cache == null) {
throw new BaseException('CachedXHR: Template cache was not found in $templateCache.');
}
}
get(url: string): Promise<string> {
if (this._cache.hasOwnProperty(url)) {
return PromiseWrapper.resolve(this._cache[url]);
} else {
return PromiseWrapper.reject('CachedXHR: Did not find cached template for ' + url, null);
}
}
}

View File

@ -0,0 +1,39 @@
import {XHR} from '@angular/compiler';
import {PromiseWrapper, PromiseCompleter} from '../../src/facade/promise';
import {isPresent} from '../../src/facade/lang';
export class XHRImpl extends XHR {
get(url: string): Promise<string> {
var completer: PromiseCompleter < string >= PromiseWrapper.completer();
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'text';
xhr.onload = function() {
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
var response = isPresent(xhr.response) ? xhr.response : xhr.responseText;
// normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
var status = xhr.status === 1223 ? 204 : xhr.status;
// fix status code when it is 0 (0 status is undocumented).
// Occurs when accessing file resources or on Android 4.1 stock browser
// while retrieving files from application cache.
if (status === 0) {
status = response ? 200 : 0;
}
if (200 <= status && status <= 300) {
completer.resolve(response);
} else {
completer.reject(`Failed to load ${url}`, null);
}
};
xhr.onerror = function() { completer.reject(`Failed to load ${url}`, null); };
xhr.send();
return completer.promise;
}
}

View File

@ -10,27 +10,21 @@ import {
xdescribe,
xit
} from '@angular/core/testing/testing_internal';
import {
fakeAsync,
flushMicrotasks,
Log,
tick,
} from '@angular/core/testing';
import {Log} from '@angular/core/testing';
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
import {IS_DART, isPresent, stringify} from '../../src/facade/lang';
import {BROWSER_PROVIDERS} from '@angular/platform-browser';
import {BROWSER_APP_DYNAMIC_PROVIDERS} from '@angular/platform-browser-dynamic';
import {bootstrap} from '@angular/platform-browser-dynamic';
import {ApplicationRef, PlatformRef} from '@angular/core/src/application_ref';
import {stringify} from '../../src/facade/lang';
import {BROWSER_PLATFORM_PROVIDERS} from '@angular/platform-browser';
import {BROWSER_APP_PROVIDERS} from '@angular/platform-browser';
import {bootstrap} from '@angular/platform-browser';
import {ApplicationRef} from '@angular/core/src/application_ref';
import {Console} from '@angular/core/src/console';
import {Component, Directive, OnDestroy} from '@angular/core';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {DOCUMENT} from '@angular/platform-browser/src/dom/dom_tokens';
import {PromiseWrapper, TimerWrapper} from '../../src/facade/async';
import {PromiseWrapper} from '../../src/facade/async';
import {
provide,
Inject,
Injector,
PLATFORM_INITIALIZER,
APP_INITIALIZER,
coreLoadAndBootstrap,
@ -215,9 +209,9 @@ export function main() {
it('should unregister change detectors when components are disposed',
inject([AsyncTestCompleter], (async) => {
var platform = createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PROVIDERS));
var platform = createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PLATFORM_PROVIDERS));
var app =
ReflectiveInjector.resolveAndCreate([BROWSER_APP_DYNAMIC_PROVIDERS, testProviders],
ReflectiveInjector.resolveAndCreate([BROWSER_APP_PROVIDERS, testProviders],
platform.injector)
.get(ApplicationRef);
coreLoadAndBootstrap(app.injector, HelloRootCmp)
@ -251,7 +245,7 @@ export function main() {
it("should run platform initializers", inject([Log], (log: Log) => {
let p = createPlatform(ReflectiveInjector.resolveAndCreate([
BROWSER_PROVIDERS,
BROWSER_PLATFORM_PROVIDERS,
provide(PLATFORM_INITIALIZER, {useValue: log.fn("platform_init1"), multi: true}),
provide(PLATFORM_INITIALIZER, {useValue: log.fn("platform_init2"), multi: true})
]));
@ -259,7 +253,7 @@ export function main() {
log.clear();
var a = ReflectiveInjector.resolveAndCreate(
[
BROWSER_APP_DYNAMIC_PROVIDERS,
BROWSER_APP_PROVIDERS,
provide(APP_INITIALIZER, {useValue: log.fn("app_init1"), multi: true}),
provide(APP_INITIALIZER, {useValue: log.fn("app_init2"), multi: true})
],

View File

@ -1,5 +0,0 @@
import 'dart:html';
Rectangle createRectangle(left, top, width, height) {
return new Rectangle(left, top, width, height);
}

View File

@ -1,50 +0,0 @@
import {
inject,
describe,
it,
expect,
} from '@angular/core/testing/testing_internal';
import {AsyncTestCompleter, SpyObject} from '@angular/core/testing/testing_internal';
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
import {Ruler, Rectangle} from '@angular/platform-browser/src/browser/ruler';
import {createRectangle} from './rectangle_mock';
import {SpyDomAdapter, SpyElementRef} from '@angular/core/test/spies';
function assertDimensions(rect: Rectangle, left, right, top, bottom, width, height) {
expect(rect.left).toEqual(left);
expect(rect.right).toEqual(right);
expect(rect.top).toEqual(top);
expect(rect.bottom).toEqual(bottom);
expect(rect.width).toEqual(width);
expect(rect.height).toEqual(height);
}
export function main() {
describe('ruler service', () => {
it('should allow measuring ElementRefs', inject([AsyncTestCompleter], (async) => {
var ruler = new Ruler(SpyObject.stub(
new SpyDomAdapter(), {'getBoundingClientRect': createRectangle(10, 20, 200, 100)}));
var elRef = <any>new SpyElementRef();
ruler.measure(elRef).then((rect) => {
assertDimensions(rect, 10, 210, 20, 120, 200, 100);
async.done();
});
}));
it('should return 0 for all rectangle values while measuring elements in a document fragment',
inject([AsyncTestCompleter], (async) => {
var ruler = new Ruler(getDOM());
var elRef = <any>new SpyElementRef();
elRef.prop("nativeElement", getDOM().createElement('div'));
ruler.measure(elRef).then((rect) => {
// here we are using an element created in a doc fragment so all the measures will come
// back as 0
assertDimensions(rect, 0, 0, 0, 0, 0, 0);
async.done();
});
}));
});
}

View File

@ -0,0 +1 @@
<p>hey</p>

View File

@ -1,5 +1,5 @@
import {describe, it, iit, ddescribe, expect} from '@angular/core/testing';
import {BrowserDetection} from '@angular/platform-browser/testing';
import {BrowserDetection} from '../testing/browser_util';
import {StringMapWrapper} from '../src/facade/collection';
export function main() {

View File

@ -0,0 +1,194 @@
import {
it,
iit,
xit,
describe,
ddescribe,
xdescribe,
expect,
beforeEach,
beforeEachProviders,
inject,
} from '@angular/core/testing';
import {
async,
fakeAsync,
flushMicrotasks,
Log,
tick,
} from '@angular/core/testing';
import {ROUTER_FAKE_PROVIDERS} from '@angular/router/testing';
import {ROUTER_DIRECTIVES, Routes, Route} from '@angular/router';
import {Component, bind} from '@angular/core';
import {PromiseWrapper} from '../src/facade/promise';
import {XHR} from '@angular/compiler';
import {XHRImpl} from '../src/xhr/xhr_impl';
import {TestComponentBuilder} from '@angular/compiler/testing';
// Components for the tests.
class FancyService {
value: string = 'real value';
getAsyncValue() { return Promise.resolve('async value'); }
getTimeoutValue() {
return new Promise((resolve, reject) => { setTimeout(() => {resolve('timeout value')}, 10); })
}
}
@Component({
selector: 'external-template-comp',
templateUrl: '/base/modules/@angular/platform-browser/test/static_assets/test.html'
})
class ExternalTemplateComp {
}
@Component({selector: 'bad-template-comp', templateUrl: 'non-existant.html'})
class BadTemplateUrl {
}
@Component({
selector: 'test-router-cmp',
template: `<a [routerLink]="['One']">one</a> <a [routerLink]="['Two']">two</a><router-outlet></router-outlet>`,
directives: [ROUTER_DIRECTIVES]
})
@Routes([
new Route({path: '/One', component: BadTemplateUrl}),
new Route({path: '/Two', component: ExternalTemplateComp}),
])
class TestRouterComponent {
}
// Tests for angular2/testing bundle specific to the browser environment.
// For general tests, see test/testing/testing_public_spec.ts.
export function main() {
describe('test APIs for the browser', () => {
describe('angular2 jasmine matchers', () => {
describe('toHaveCssClass', () => {
it('should assert that the CSS class is present', () => {
var el = document.createElement('div');
el.classList.add('matias');
expect(el).toHaveCssClass('matias');
});
it('should assert that the CSS class is not present', () => {
var el = document.createElement('div');
el.classList.add('matias');
expect(el).not.toHaveCssClass('fatias');
});
});
describe('toHaveCssStyle', () => {
it('should assert that the CSS style is present', () => {
var el = document.createElement('div');
expect(el).not.toHaveCssStyle('width');
el.style.setProperty('width', '100px');
expect(el).toHaveCssStyle('width');
});
it('should assert that the styles are matched against the element', () => {
var el = document.createElement('div');
expect(el).not.toHaveCssStyle({width: '100px', height: '555px'});
el.style.setProperty('width', '100px');
expect(el).toHaveCssStyle({width: '100px'});
expect(el).not.toHaveCssStyle({width: '100px', height: '555px'});
el.style.setProperty('height', '555px');
expect(el).toHaveCssStyle({height: '555px'});
expect(el).toHaveCssStyle({width: '100px', height: '555px'});
});
});
});
describe('using the async helper', () => {
var actuallyDone: boolean;
beforeEach(() => { actuallyDone = false; });
afterEach(() => { expect(actuallyDone).toEqual(true); });
it('should run async tests with XHRs', async(() => {
var xhr = new XHRImpl();
xhr.get('/base/modules/@angular/platform-browser/test/static_assets/test.html')
.then(() => { actuallyDone = true; });
}),
10000); // Long timeout here because this test makes an actual XHR.
});
describe('using the test injector with the inject helper', () => {
describe('setting up Providers', () => {
beforeEachProviders(() => [bind(FancyService).toValue(new FancyService())]);
it('provides a real XHR instance',
inject([XHR], (xhr) => { expect(xhr).toBeAnInstanceOf(XHRImpl); }));
it('should allow the use of fakeAsync', fakeAsync(inject([FancyService], (service) => {
var value;
service.getAsyncValue().then(function(val) { value = val; });
tick();
expect(value).toEqual('async value');
})));
});
});
describe('errors', () => {
var originalJasmineIt: any;
var patchJasmineIt = () => {
var deferred = PromiseWrapper.completer();
originalJasmineIt = jasmine.getEnv().it;
jasmine.getEnv().it = (description: string, fn) => {
var done = () => { deferred.resolve() };
(<any>done).fail = (err) => { deferred.reject(err) };
fn(done);
return null;
};
return deferred.promise;
};
var restoreJasmineIt = () => { jasmine.getEnv().it = originalJasmineIt; };
it('should fail when an XHR fails', (done) => {
var itPromise = patchJasmineIt();
it('should fail with an error from a promise',
async(inject([TestComponentBuilder],
(tcb) => { return tcb.createAsync(BadTemplateUrl); })));
itPromise.then(() => { done.fail('Expected test to fail, but it did not'); }, (err) => {
expect(err).toEqual('Uncaught (in promise): Failed to load non-existant.html');
done();
});
restoreJasmineIt();
}, 10000);
});
describe('test component builder', function() {
it('should allow an external templateUrl',
async(inject([TestComponentBuilder],
(tcb: TestComponentBuilder) => {
tcb.createAsync(ExternalTemplateComp)
.then((componentFixture) => {
componentFixture.detectChanges();
expect(componentFixture.debugElement.nativeElement)
.toHaveText('from external template\n');
});
})),
10000); // Long timeout here because this test makes an actual XHR, and is slow on Edge.
});
});
describe('apps with router components', () => {
beforeEachProviders(() => [ROUTER_FAKE_PROVIDERS]);
it('should build without a problem',
async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
tcb.createAsync(TestRouterComponent)
.then((fixture) => { expect(fixture.nativeElement).toHaveText('one two'); });
})));
});
}

View File

@ -1,7 +0,0 @@
library angular2.test.testing.testing_spec;
/**
* This is intentionally left blank. The public test lib is only for TS/JS
* apps.
*/
main() {}

View File

@ -1,29 +0,0 @@
library angular2.test.web_workers.debug_tools.bootstrap;
import 'package:angular2/src/platform/server/html_adapter.dart';
import "package:angular2/src/testing/testing_internal_core.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart";
import "package:angular2/src/platform/worker_app_common.dart"
show WORKER_APP_APPLICATION_COMMON;
import "package:angular2/platform/worker_app.dart" show WORKER_APP_PLATFORM;
import "package:angular2/core.dart";
import "../shared/web_worker_test_util.dart";
import "dart:convert";
main() {
Html5LibDomAdapter.makeCurrent();
testSetup();
describe("WORKER_APP_COMMON_PROVIDERS", () {
it("should be able to load in a Dart VM", () {
reflector.reflectionCapabilities = new ReflectionCapabilities();
var buses = createPairedMessageBuses();
disposePlatform();
var platform = createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_APP_PLATFORM));
var appInjector = ReflectiveInjector.resolveAndCreate(WORKER_APP_APPLICATION_COMMON,
platform.injector);
appInjector.get(ApplicationRef);
});
});
}

View File

@ -1,24 +0,0 @@
library angular2.test.web_workers.debug_tools.message_bus_common;
import "dart:convert" show JSON;
import "package:angular2/src/web_workers/shared/message_bus.dart";
import "package:angular2/src/testing/testing_internal_core.dart"
show AsyncTestCompleter, expect, SpyObject;
var MESSAGE = const {'test': 10};
const CHANNEL = "TEST_CHANNEL";
void expectSinkSendsEncodedJson(SpyObject socket, MessageBusSink sink,
String sendMethodName, AsyncTestCompleter async) {
socket.spy(sendMethodName).andCallFake((message) {
expectMessageEquality(message, MESSAGE, CHANNEL);
async.done();
});
sink.to(CHANNEL).add(MESSAGE);
}
void expectMessageEquality(String message, Map expectedData, String channel) {
expect(JSON.decode(message)).toEqual([
{'channel': channel, 'message': expectedData}
]);
}

View File

@ -1,235 +0,0 @@
library angular2.test.web_workers.debug_tools.multi_client_server_message_bus;
import "dart:io";
import "dart:async";
import "package:angular2/src/testing/testing_internal_core.dart"
show
AsyncTestCompleter,
SpyObject,
beforeEach,
beforeEachProviders,
describe,
expect,
iit,
inject,
it,
proxy,
testSetup;
import 'package:angular2/src/platform/server/html_adapter.dart';
import "package:angular2/src/web_workers/debug_tools/multi_client_server_message_bus.dart";
import "package:angular2/src/web_workers/shared/messaging_api.dart";
import "./message_bus_common.dart";
import "./spy_web_socket.dart";
import "dart:convert" show JSON;
import 'dart:math';
main() {
Html5LibDomAdapter.makeCurrent();
testSetup();
List<String> messageHistory = new List<String>();
List<int> resultMarkers = new List<int>();
describe("MultiClientServerMessageBusSink", () {
const CHANNEL = "TEST_CHANNEL";
var MESSAGE = const {'test': 10};
beforeEach(() {
messageHistory.clear();
resultMarkers.clear();
});
it(
"should send messages to all connected clients",
inject([AsyncTestCompleter], (async) {
const NUM_CLIENTS = 5;
var sink = new MultiClientServerMessageBusSink();
sink.initChannel(CHANNEL, false);
int numMessagesSent = 0;
// initialize all the sockets
var sockets = new List<WebSocketWrapper>(NUM_CLIENTS);
for (var i = 0; i < sockets.length; i++) {
var messageSent =
false; // ensure this socket only receives one message
var socketWrapper = createSocket(messageHandler: (message) {
expect(messageSent).toEqual(false);
messageSent = true;
expectMessageEquality(message, MESSAGE, CHANNEL);
numMessagesSent++;
if (numMessagesSent == NUM_CLIENTS) {
async.done();
}
});
var socket = socketWrapper.socket;
sockets[i] =
new WebSocketWrapper(messageHistory, resultMarkers, socket);
sink.addConnection(sockets[i]);
}
sink.to(CHANNEL).add(MESSAGE);
}));
});
describe("WebSocketWrapper", () {
beforeEach(() {
messageHistory.clear();
resultMarkers.clear();
});
/**
* Generates the given number of random messages, inserts them into messageHistory,
* and then returns a cloned version of messageHistory
*/
List<String> generateRandomMessages(int numMessages) {
const MAX = 1 << 31;
var random = new Random();
for (var i = 0; i < numMessages; i++) {
var message = {'value': random.nextInt(MAX)};
messageHistory.add(JSON.encode([
{'channel': CHANNEL, 'message': message}
]));
}
// copy the message history to ensure the test fails if the wrapper modifies the list
return new List.from(messageHistory);
}
it(
"should send all messages when there are no markers",
inject([AsyncTestCompleter], (async) {
const NUM_MESSAGES = 10;
var messageHistoryClone = generateRandomMessages(NUM_MESSAGES);
int numMessagesSent = 0;
var socketWrapper = createSocket(messageHandler: (message) {
expect(message).toEqual(messageHistoryClone[numMessagesSent]);
//expectMessageEquality(message, expected, CHANNEL);
numMessagesSent++;
if (numMessagesSent == messageHistoryClone.length) {
async.done();
}
});
var wrapper = new WebSocketWrapper(
messageHistory, resultMarkers, socketWrapper.socket);
wrapper.sendToMarker(0);
}));
it(
"should send between two markers",
inject([AsyncTestCompleter], (async) {
const NUM_MESSAGES = 50;
const FIRST_MARKER = 5;
const SECOND_MARKER = 15;
var messageHistoryClone = generateRandomMessages(NUM_MESSAGES);
int numMessagesSent = 0;
resultMarkers.add(FIRST_MARKER);
resultMarkers.add(SECOND_MARKER);
var socketWrapper = createSocket(messageHandler: (message) {
expect(message)
.toEqual(messageHistoryClone[FIRST_MARKER + numMessagesSent]);
numMessagesSent++;
if (numMessagesSent == SECOND_MARKER - FIRST_MARKER) {
async.done();
}
});
var wrapper = new WebSocketWrapper(
messageHistory, resultMarkers, socketWrapper.socket);
wrapper.sendToMarker(1);
}));
});
describe("MultiClientServerMessageBusSource", () {
beforeEach(() {
messageHistory.clear();
resultMarkers.clear();
});
void sendMessage(StreamController controller, dynamic message) {
controller.add(JSON.encode([message]));
}
void testForwardingMessages(bool primary, bool events, Function done) {
var result = createSocket();
var controller = result.controller;
var socket =
new WebSocketWrapper(messageHistory, resultMarkers, result.socket);
socket.setPrimary(primary);
var source = new MultiClientServerMessageBusSource();
source.addConnection(socket);
var channel = events ? EVENT_CHANNEL : CHANNEL;
source.initChannel(channel, false);
source.from(channel).listen((message) {
expect(message).toEqual(MESSAGE);
done();
});
var message = {'channel': channel, 'message': MESSAGE};
sendMessage(controller, message);
}
it(
"should forward messages from the primary",
inject([AsyncTestCompleter], (async) {
testForwardingMessages(true, false, async.done);
}));
it(
"should forward event channel messages from non primaries",
inject([AsyncTestCompleter], (async) {
testForwardingMessages(false, true, async.done);
}));
it(
"should forward event channel messages from the primary",
inject([AsyncTestCompleter], (async) {
testForwardingMessages(true, true, async.done);
}));
it(
"should mark results from the primary",
inject([AsyncTestCompleter], (async) {
var result = createSocket();
var controller = result.controller;
var socket = new WebSocketWrapper(
messageHistory, resultMarkers, result.socket);
socket.setPrimary(true);
var source = new MultiClientServerMessageBusSource();
source.onResult.listen((result) => async.done());
source.initChannel(CHANNEL, false);
source.addConnection(socket);
var message = {
'channel': CHANNEL,
'message': {'type': 'result'}
};
sendMessage(controller, message);
}));
});
}
/**
* Returns a new SpyWebSocket that calls messageHandler when a new message is sent.
* Also returns a StreamController instance that you can use to send messages to anything
* that is subscribed to this socket.
*/
SpySocketWrapper createSocket({Function messageHandler}) {
var socket = new SpyWebSocket();
if (messageHandler != null) {
socket.spy("add").andCallFake(messageHandler);
socket
.spy("addStream")
.andCallFake((Stream stream) => stream.listen(messageHandler));
}
var controller = new StreamController<String>.broadcast();
socket.spy("asBroadcastStream").andCallFake(() => controller.stream);
return new SpySocketWrapper(socket, controller);
}
class SpySocketWrapper {
SpyWebSocket socket;
StreamController controller;
SpySocketWrapper(this.socket, this.controller);
}

View File

@ -1,106 +0,0 @@
library angular2.test.web_workers.debug_tools.single_client_server_message_bus;
import "dart:io";
import "dart:async";
import "package:angular2/src/testing/testing_internal_core.dart"
show
AsyncTestCompleter,
SpyObject,
beforeEach,
beforeEachProviders,
describe,
expect,
inject,
it,
proxy,
testSetup;
import 'package:angular2/src/platform/server/html_adapter.dart';
import "package:angular2/src/web_workers/debug_tools/single_client_server_message_bus.dart";
import "./message_bus_common.dart";
import "./spy_web_socket.dart";
import "dart:convert" show JSON;
main() {
Html5LibDomAdapter.makeCurrent();
testSetup();
var MESSAGE = const {'test': 10};
const CHANNEL = "TEST_CHANNEL";
describe("SingleClientServerMessageBusSink", () {
it(
"should send JSON encoded data over the WebSocket",
inject([AsyncTestCompleter], (async) {
var socket = new SpyWebSocket();
var sink = new SingleClientServerMessageBusSink();
sink.initChannel(CHANNEL, false);
sink.setConnection(socket);
expectSinkSendsEncodedJson(socket, sink, "add", async);
}));
it(
"should buffer messages before connect",
inject([AsyncTestCompleter], (async) {
var sink = new SingleClientServerMessageBusSink();
sink.initChannel(CHANNEL, false);
sink.to(CHANNEL).add(MESSAGE);
var socket = new SpyWebSocket();
socket.spy("add").andCallFake((message) {
expectMessageEquality(message, MESSAGE, CHANNEL);
async.done();
});
sink.setConnection(socket);
}));
it(
"should buffer messages in between disconnect and connect",
inject([AsyncTestCompleter], (async) {
var SECOND_MESSAGE = const {'test': 12, 'second': 'hi'};
var sink = new SingleClientServerMessageBusSink();
sink.initChannel(CHANNEL, false);
sink.to(CHANNEL).add(MESSAGE);
var socket = new SpyWebSocket();
sink.setConnection(socket);
int numMessages = 0;
socket.spy("add").andCallFake((message) {
numMessages++;
if (numMessages == 1) {
expectMessageEquality(message, MESSAGE, CHANNEL);
} else {
expectMessageEquality(message, SECOND_MESSAGE, CHANNEL);
async.done();
}
});
sink.removeConnection();
sink.to(CHANNEL).add(SECOND_MESSAGE);
sink.setConnection(socket);
}));
});
describe("SingleClientServerMessageBusSource", () {
it(
"should decode JSON messages and emit them",
inject([AsyncTestCompleter], (async) {
StreamController<String> controller =
new StreamController.broadcast();
var source = new SingleClientServerMessageBusSource();
source.initChannel(CHANNEL, false);
source.attachTo(controller.stream);
source.from(CHANNEL).listen((message) {
expect(message).toEqual(MESSAGE);
async.done();
});
controller.add(JSON.encode([
{'channel': CHANNEL, 'message': MESSAGE}
]));
}));
});
}

View File

@ -1,15 +0,0 @@
/**
* Contains code shared between all server message bus tests
*/
library angular2.test.web_workers.debug_tools.server_message_bus_common;
import "package:angular2/src/testing/testing_internal_core.dart";
import "dart:io";
@proxy
class SpyWebSocket extends SpyObject implements WebSocket {
SpyWebSocket() : super(SpyWebSocket);
noSuchMethod(m) {
return super.noSuchMethod(m);
}
}

View File

@ -1,67 +0,0 @@
library angular2.test.web_workers.debug_tools.web_socket_server_message_bus;
import "package:angular2/testing_internal.dart"
show
AsyncTestCompleter,
inject,
describe,
it,
expect,
beforeEach,
beforeEachProviders,
SpyObject;
import "package:angular2/src/web_workers/debug_tools/web_socket_message_bus.dart";
import "dart:html" show WebSocket, MessageEvent;
import "./message_bus_common.dart";
import "dart:async";
import "dart:convert" show JSON;
main() {
var MESSAGE = const {'test': 10};
const CHANNEL = "TEST_CHANNEL";
describe("WebSocketMessageBusSink", () {
it(
"should send JSON encoded data over the WebSocket",
inject([AsyncTestCompleter], (async) {
var socket = new SpyWebSocket();
var sink = new WebSocketMessageBusSink(socket);
sink.initChannel(CHANNEL, false);
expectSinkSendsEncodedJson(socket, sink, "send", async);
}));
});
describe("WebSocketMessageBusSource", () {
it(
"should decode JSON messages and emit them",
inject([AsyncTestCompleter], (async) {
var socket = new SpyWebSocket();
StreamController<MessageEvent> controller =
new StreamController.broadcast();
socket.spy("get:onMessage").andCallFake(() => controller.stream);
var source = new WebSocketMessageBusSource(socket);
source.initChannel(CHANNEL, false);
source.from(CHANNEL).listen((message) {
expect(message).toEqual(MESSAGE);
async.done();
});
var event = new SpyMessageEvent();
event.spy("get:data").andCallFake(() => JSON.encode([
{'channel': CHANNEL, 'message': MESSAGE}
]));
controller.add(event);
}));
});
}
@proxy
class SpyMessageEvent extends SpyObject implements MessageEvent {
SpyMessageEvent() : super(SpyMessageEvent);
}
@proxy
class SpyWebSocket extends SpyObject implements WebSocket {
SpyWebSocket() : super(SpyWebSocket);
}

View File

@ -1,20 +0,0 @@
library angular2.test.web_workers.shared.message_bus_util;
import 'dart:isolate';
import 'package:angular2/src/web_workers/shared/message_bus.dart'
show MessageBus;
import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart';
/*
* Returns an IsolateMessageBus thats sink is connected to its own source.
* Useful for testing the sink and source.
*/
MessageBus createConnectedMessageBus() {
var receivePort = new ReceivePort();
var sendPort = receivePort.sendPort;
var sink = new IsolateMessageBusSink(sendPort);
var source = new IsolateMessageBusSource(receivePort);
return new IsolateMessageBus(sink, source);
}

View File

@ -1,21 +0,0 @@
library angular2.test.web_workers.worker.mock_event_emitter;
import 'dart:core';
import 'dart:async';
import "package:angular2/src/facade/async.dart";
class MockEventEmitter<T> extends EventEmitter<T> {
final controller = new StreamController.broadcast(sync: true);
@override
StreamSubscription listen(void onData(dynamic line),
{void onError(Error error), void onDone(), bool cancelOnError}) {
return controller.stream.listen(onData,
onError: onError, onDone: onDone, cancelOnError: cancelOnError);
}
@override
void add(value) {
controller.add(value);
}
}

View File

@ -1,7 +0,0 @@
library web_workers.spies;
import 'package:angular2/src/web_workers/shared/client_message_broker.dart';
import 'package:angular2/src/testing/testing_internal_core.dart';
@proxy
class SpyMessageBroker extends SpyObject implements ClientMessageBroker {}

View File

@ -0,0 +1,29 @@
import {inject, describe, it, expect} from '@angular/core/testing/testing_internal';
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
import {SpyMessageBroker} from '@angular/platform-browser/test/web_workers/worker/spies';
import {WebWorkerXHRImpl} from '@angular/platform-browser/src/web_workers/worker/xhr_impl';
import {PromiseWrapper} from '../../../src/facade/async';
import {
MockMessageBrokerFactory,
expectBrokerCall
} from '@angular/platform-browser/test/web_workers/shared/web_worker_test_util';
export function main() {
describe("WebWorkerXHRImpl", () => {
it("should pass requests through the broker and return the response",
inject([AsyncTestCompleter], (async) => {
const URL = "http://www.example.com/test";
const RESPONSE = "Example response text";
var messageBroker = new SpyMessageBroker();
expectBrokerCall(messageBroker, "get", [URL],
(_) => { return PromiseWrapper.wrap(() => { return RESPONSE; }); });
var xhrImpl = new WebWorkerXHRImpl(new MockMessageBrokerFactory(<any>messageBroker));
xhrImpl.get(URL).then((response) => {
expect(response).toEqual(RESPONSE);
async.done();
});
}));
});
}

View File

@ -0,0 +1,3 @@
export function setTemplateCache(cache): void {
(<any>window).$templateCache = cache;
}

View File

@ -0,0 +1,85 @@
import {Component, provide} from '@angular/core';
import {UrlResolver, XHR} from '@angular/compiler';
import {
beforeEach,
beforeEachProviders,
ddescribe,
describe,
iit,
inject,
it,
xit
} from '@angular/core/testing/testing_internal';
import {expect} from '@angular/platform-browser/testing';
import {AsyncTestCompleter} from '@angular/core/testing/testing_internal';
import {
fakeAsync,
flushMicrotasks,
Log,
tick,
} from '@angular/core/testing';
import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing';
import {BaseException} from '../../src/facade/exceptions';
import {CachedXHR} from '../../src/xhr/xhr_cache';
import {setTemplateCache} from './xhr_cache_setter';
export function main() {
describe('CachedXHR', () => {
var xhr: CachedXHR;
function createCachedXHR(): CachedXHR {
setTemplateCache({'test.html': '<div>Hello</div>'});
return new CachedXHR();
}
beforeEachProviders(() => [
provide(UrlResolver, {useClass: TestUrlResolver}),
provide(XHR, {useFactory: createCachedXHR})
]);
it('should throw exception if $templateCache is not found', () => {
setTemplateCache(null);
expect(() => { xhr = new CachedXHR(); })
.toThrowErrorWith('CachedXHR: Template cache was not found in $templateCache.');
});
it('should resolve the Promise with the cached file content on success',
inject([AsyncTestCompleter], (async) => {
setTemplateCache({'test.html': '<div>Hello</div>'});
xhr = new CachedXHR();
xhr.get('test.html')
.then((text) => {
expect(text).toEqual('<div>Hello</div>');
async.done();
});
}));
it('should reject the Promise on failure', inject([AsyncTestCompleter], (async) => {
xhr = new CachedXHR();
xhr.get('unknown.html')
.then((text) => { throw new BaseException('Not expected to succeed.'); })
.catch((error) => { async.done(); });
}));
it('should allow fakeAsync Tests to load components with templateUrl synchronously',
fakeAsync(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
let fixture = tcb.createFakeAsync(TestComponent);
// This should initialize the fixture.
tick();
expect(fixture.debugElement.children[0].nativeElement).toHaveText('Hello');
})));
});
}
@Component({selector: 'test-cmp', templateUrl: 'test.html'})
class TestComponent {
}
class TestUrlResolver extends UrlResolver {
resolve(baseUrl: string, url: string): string {
// Don't use baseUrl to get the same URL as templateUrl.
// This is to remove any difference between Dart and TS tests.
return url;
}
}

View File

@ -0,0 +1,48 @@
import {
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
it,
xit,
AsyncTestCompleter
} from '@angular/core/testing/testing_internal';
import {XHRImpl} from '../../src/xhr/xhr_impl';
import {PromiseWrapper} from '../../src/facade/async';
import {IS_DART} from '../../src/facade/lang';
export function main() {
describe('XHRImpl', () => {
var xhr: XHRImpl;
// TODO(juliemr): This file currently won't work with dart unit tests run using
// exclusive it or describe (iit or ddescribe). This is because when
// pub run test is executed against this specific file the relative paths
// will be relative to here, so url200 should look like
// static_assets/200.html.
// We currently have no way of detecting this.
var urlBase = IS_DART ? '' : '/base/modules/@angular/';
var url200 = urlBase + 'platform-browser/test/browser/static_assets/200.html';
var url404 = '/bad/path/404.html';
beforeEach(() => { xhr = new XHRImpl(); });
it('should resolve the Promise with the file content on success',
inject([AsyncTestCompleter], (async) => {
xhr.get(url200).then((text) => {
expect(text.trim()).toEqual('<p>hey</p>');
async.done();
});
}), 10000);
it('should reject the Promise on failure', inject([AsyncTestCompleter], (async) => {
PromiseWrapper.catchError(xhr.get(url404), (e) => {
expect(e).toEqual(`Failed to load ${url404}`);
async.done();
return null;
});
}), 10000);
});
}

View File

@ -1,3 +1,5 @@
export * from './testing/browser_util';
export * from './testing/browser_static';
export * from './testing/matchers';
export * from './testing/browser';
export * from './testing/dom_test_component_renderer';

View File

@ -0,0 +1,37 @@
import {
TEST_BROWSER_STATIC_PLATFORM_PROVIDERS,
ADDITIONAL_TEST_BROWSER_STATIC_PROVIDERS
} from './browser_static';
import {BROWSER_APP_PROVIDERS} from '../index';
import {DirectiveResolver, ViewResolver} from '@angular/compiler';
import {
MockDirectiveResolver,
MockViewResolver,
TestComponentRenderer,
TestComponentBuilder
} from '@angular/compiler/testing';
import {DOMTestComponentRenderer} from './dom_test_component_renderer';
/**
* Default platform providers for testing.
*/
export const TEST_BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/[TEST_BROWSER_STATIC_PLATFORM_PROVIDERS];
export const ADDITIONAL_TEST_BROWSER_PROVIDERS = [
/*@ts2dart_Provider*/ {provide: DirectiveResolver, useClass: MockDirectiveResolver},
/*@ts2dart_Provider*/ {provide: ViewResolver, useClass: MockViewResolver},
TestComponentBuilder,
/*@ts2dart_Provider*/ {provide: TestComponentRenderer, useClass: DOMTestComponentRenderer},
];
/**
* Default application providers for testing.
*/
export const TEST_BROWSER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/[
BROWSER_APP_PROVIDERS,
ADDITIONAL_TEST_BROWSER_STATIC_PROVIDERS,
ADDITIONAL_TEST_BROWSER_PROVIDERS
];

View File

@ -1,5 +1,5 @@
import {APP_ID, NgZone, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER} from '@angular/core';
import {BROWSER_APP_COMMON_PROVIDERS} from '../src/browser_common';
import {BROWSER_APP_COMMON_PROVIDERS} from '../src/platform/common/browser';
import {BrowserDomAdapter} from '../src/browser/browser_adapter';
import {AnimationBuilder} from '../src/animate/animation_builder';
import {MockAnimationBuilder} from './animation_builder_mock';
@ -29,7 +29,7 @@ export const TEST_BROWSER_STATIC_PLATFORM_PROVIDERS: Array<any /*Type | Provider
/*@ts2dart_Provider*/{provide: PLATFORM_INITIALIZER, useValue: initBrowserTests, multi: true}
];
export const ADDITIONAL_TEST_BROWSER_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
export const ADDITIONAL_TEST_BROWSER_STATIC_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/[
/*@ts2dart_Provider*/ {provide: APP_ID, useValue: 'a'},
ELEMENT_PROBE_PROVIDERS,
@ -43,4 +43,4 @@ export const ADDITIONAL_TEST_BROWSER_PROVIDERS: Array<any /*Type | Provider | an
* Default application providers for testing without a compiler.
*/
export const TEST_BROWSER_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/*@ts2dart_const*/[BROWSER_APP_COMMON_PROVIDERS, ADDITIONAL_TEST_BROWSER_PROVIDERS];
/*@ts2dart_const*/[BROWSER_APP_COMMON_PROVIDERS, ADDITIONAL_TEST_BROWSER_STATIC_PROVIDERS];

View File

@ -0,0 +1,24 @@
import {Inject, Injectable} from '@angular/core';
import {DOCUMENT} from '../src/dom/dom_tokens';
import {getDOM} from '../src/dom/dom_adapter';
import {TestComponentRenderer} from '@angular/compiler/testing';
import {el} from './browser_util';
/**
* A DOM based implementation of the TestComponentRenderer.
*/
@Injectable()
export class DOMTestComponentRenderer extends TestComponentRenderer {
constructor(@Inject(DOCUMENT) private _doc) { super(); }
insertRootElement(rootElId: string) {
let rootEl = el(`<div id="${rootElId}"></div>`);
// TODO(juliemr): can/should this be optional?
let oldRoots = getDOM().querySelectorAll(this._doc, '[id^=root]');
for (let i = 0; i < oldRoots.length; i++) {
getDOM().remove(oldRoots[i]);
}
getDOM().appendChild(this._doc.body, rootEl);
}
}

View File

@ -1,3 +0,0 @@
library angular2.e2e_util;
// empty as this file is node.js specific and should not be transpiled to dart

View File

@ -1,136 +0,0 @@
library testing.matchers;
import 'dart:async';
import 'package:guinness2/guinness2.dart' as gns;
import 'package:angular2/src/platform/dom/dom_adapter.dart' show DOM;
import 'package:angular2/src/facade/lang.dart' show isString;
Expect expect(actual, [matcher]) {
final expect = new Expect(actual);
if (matcher != null) expect.to(matcher);
return expect;
}
const _u = const Object();
bool elementContainsStyle(element, styles) {
var allPassed = true;
if (isString(styles)) {
allPassed = getDOM().hasStyle(element, styles);
} else {
styles.forEach((prop, style) {
allPassed = allPassed && getDOM().hasStyle(element, prop, style);
});
}
return allPassed;
}
expectErrorMessage(actual, expectedMessage) {
expect(actual.toString()).toContain(expectedMessage);
}
expectException(Function actual, expectedMessage) {
try {
actual();
} catch (e, s) {
expectErrorMessage(e, expectedMessage);
}
}
class Expect extends gns.Expect {
Expect(actual) : super(actual);
NotExpect get not => new NotExpect(actual);
void toEqual(expected) => toHaveSameProps(expected);
void toContainError(message) => expectErrorMessage(this.actual, message);
void toThrowError([message = ""]) => toThrowWith(message: message);
void toThrowErrorWith(message) => expectException(this.actual, message);
void toBePromise() => gns.guinness.matchers.toBeTrue(actual is Future);
void toHaveCssClass(className) =>
gns.guinness.matchers.toBeTrue(getDOM().hasClass(actual, className));
void toHaveCssStyle(styles) {
gns.guinness.matchers.toBeTrue(elementContainsStyle(actual, styles));
}
void toMatchPattern(pattern) =>
gns.guinness.matchers.toBeTrue(pattern.hasMatch(actual));
void toImplement(expected) => toBeA(expected);
void toBeNaN() =>
gns.guinness.matchers.toBeTrue(double.NAN.compareTo(actual) == 0);
void toHaveText(expected) => _expect(elementText(actual), expected);
void toHaveBeenCalledWith([a = _u, b = _u, c = _u, d = _u, e = _u, f = _u]) =>
_expect(_argsMatch(actual, a, b, c, d, e, f), true,
reason: 'method invoked with correct arguments');
Function get _expect => gns.guinness.matchers.expect;
// TODO(tbosch): move this hack into Guinness
_argsMatch(spyFn, [a0 = _u, a1 = _u, a2 = _u, a3 = _u, a4 = _u, a5 = _u]) {
var calls = spyFn.calls;
final toMatch = _takeDefined([a0, a1, a2, a3, a4, a5]);
if (calls.isEmpty) {
return false;
} else {
gns.SamePropsMatcher matcher = new gns.SamePropsMatcher(toMatch);
for (var i = 0; i < calls.length; i++) {
var call = calls[i];
// TODO: create a better error message, not just 'Expected: <true> Actual: <false>'.
// For hacking this is good:
// print(call.positionalArguments);
if (matcher.matches(call.positionalArguments, null)) {
return true;
}
}
return false;
}
}
List _takeDefined(List iter) => iter.takeWhile((_) => _ != _u).toList();
}
class NotExpect extends gns.NotExpect {
NotExpect(actual) : super(actual);
void toEqual(expected) => toHaveSameProps(expected);
void toBePromise() => gns.guinness.matchers.toBeFalse(actual is Future);
void toHaveCssClass(className) =>
gns.guinness.matchers.toBeFalse(getDOM().hasClass(actual, className));
void toHaveCssStyle(styles) {
gns.guinness.matchers.toBeFalse(elementContainsStyle(actual, styles));
}
void toMatchPattern(pattern) =>
gns.guinness.matchers.toBeFalse(pattern.hasMatch(actual));
void toBeNull() => gns.guinness.matchers.toBeFalse(actual == null);
Function get _expect => gns.guinness.matchers.expect;
}
String elementText(n) {
hasNodes(n) {
var children = getDOM().childNodes(n);
return children != null && children.length > 0;
}
if (n is Iterable) {
return n.map(elementText).join("");
}
if (getDOM().isCommentNode(n)) {
return '';
}
if (getDOM().isElementNode(n) && getDOM().tagName(n) == 'CONTENT') {
return elementText(getDOM().getDistributedNodes(n));
}
if (getDOM().hasShadowRoot(n)) {
return elementText(getDOM().childNodesAsList(getDOM().getShadowRoot(n)));
}
if (hasNodes(n)) {
return elementText(getDOM().childNodesAsList(n));
}
return getDOM().getText(n);
}

View File

@ -1,3 +0,0 @@
library angular2.testing.perf_util;
// empty as this file is node.js specific and should not be transpiled to dart

View File

@ -1,178 +0,0 @@
library angular2.src.testing.testing_internal_core;
import 'dart:async';
import 'package:guinness2/guinness2.dart' as gns;
export 'package:guinness2/guinness2.dart'
hide
Expect,
expect,
NotExpect,
beforeEach,
it,
iit,
xit,
describe,
ddescribe,
xdescribe,
SpyObject,
SpyFunction;
export 'matchers.dart' show expect, Expect, NotExpect;
import 'package:angular2/src/core/reflection/reflection.dart';
import 'package:angular2/src/core/reflection/reflection_capabilities.dart';
import 'package:angular2/src/core/di/provider.dart' show bind;
import 'package:angular2/src/facade/collection.dart' show StringMapWrapper;
import 'async_test_completer.dart';
export 'async_test_completer.dart' show AsyncTestCompleter;
import 'test_injector.dart';
export 'test_injector.dart' show inject;
TestInjector _testInjector = getTestInjector();
bool _inIt = false;
bool _initialized = false;
List<dynamic> _platformProviders = [];
List<dynamic> _applicationProviders = [];
void setDartBaseTestProviders(List<dynamic> platform, List<dynamic> application) {
_platformProviders = platform;
_applicationProviders = application;
}
void testSetup() {
if (_initialized) {
return;
}
_initialized = true;
reflector.reflectionCapabilities = new ReflectionCapabilities();
setBaseTestProviders(_platformProviders, _applicationProviders);
// beforeEach configuration:
// - clear the bindings before each test,
// - collect the bindings before each test, see beforeEachProviders(),
// - create the test injector to be used in beforeEach() and it()
gns.beforeEach(() {
_testInjector.reset();
});
var completerProvider = bind(AsyncTestCompleter).toFactory(() {
// Mark the test as async when an AsyncTestCompleter is injected in an it(),
if (!_inIt) throw 'AsyncTestCompleter can only be injected in an "it()"';
return new AsyncTestCompleter();
});
gns.beforeEach(() {
_testInjector.addProviders([completerProvider]);
});
}
/**
* Allows overriding default providers defined in test_injector.js.
*
* The given function must return a list of DI providers.
*
* Example:
*
* beforeEachProviders(() => [
* bind(Compiler).toClass(MockCompiler),
* bind(SomeToken).toValue(myValue),
* ]);
*/
void beforeEachProviders(Function fn) {
testSetup();
gns.beforeEach(() {
var providers = fn();
if (providers != null) _testInjector.addProviders(providers);
});
}
@Deprecated('using beforeEachProviders instead')
void beforeEachBindings(Function fn) {
beforeEachProviders(fn);
}
void beforeEach(fn) {
testSetup();
gns.beforeEach(fn);
}
void _it(gnsFn, name, fn) {
testSetup();
gnsFn(name, () {
_inIt = true;
var retVal = fn();
_inIt = false;
return retVal;
});
}
void it(name, fn, [timeOut = null]) {
_it(gns.it, name, fn);
}
void iit(name, fn, [timeOut = null]) {
_it(gns.iit, name, fn);
}
void xit(name, fn, [timeOut = null]) {
_it(gns.xit, name, fn);
}
void describe(name, fn) {
testSetup();
gns.describe(name, fn);
}
void ddescribe(name, fn) {
testSetup();
gns.ddescribe(name, fn);
}
void xdescribe(name, fn) {
testSetup();
gns.xdescribe(name, fn);
}
class SpyFunction extends gns.SpyFunction {
SpyFunction(String name) : super(name);
// TODO: vsavkin move to guinness
andReturn(value) {
return andCallFake(([a0, a1, a2, a3, a4, a5]) => value);
}
}
class SpyObject extends gns.SpyObject {
final Map<String, SpyFunction> _spyFuncs = {};
SpyObject([arg]) {}
SpyFunction spy(String funcName) =>
_spyFuncs.putIfAbsent(funcName, () => new SpyFunction(funcName));
void prop(String funcName, value) {
_spyFuncs
.putIfAbsent("get:${funcName}", () => new SpyFunction(funcName))
.andReturn(value);
}
static stub([object = null, config = null, overrides = null]) {
if (object is! SpyObject) {
overrides = config;
config = object;
object = new SpyObject();
}
var m = StringMapWrapper.merge(config, overrides);
StringMapWrapper.forEach(m, (value, key) {
object.spy(key).andReturn(value);
});
return object;
}
}
bool isInInnerZone() => Zone.current['_innerZone'] == true;

View File

@ -15,7 +15,9 @@
"@angular/core": ["../../../dist/packages-dist/core"],
"@angular/core/testing": ["../../../dist/packages-dist/core/testing"],
"@angular/common": ["../../../dist/packages-dist/common"],
"@angular/common/testing": ["../../../dist/packages-dist/common/testing"]
"@angular/common/testing": ["../../../dist/packages-dist/common/testing"],
"@angular/compiler": ["../../../dist/packages-dist/compiler"],
"@angular/compiler/testing": ["../../../dist/packages-dist/compiler/testing"]
},
"rootDir": ".",
"sourceMap": true,

View File

@ -15,7 +15,9 @@
"@angular/core": ["../../../dist/packages-dist/core"],
"@angular/core/testing": ["../../../dist/packages-dist/core/testing"],
"@angular/common": ["../../../dist/packages-dist/common"],
"@angular/common/testing": ["../../../dist/packages-dist/common/testing"]
"@angular/common/testing": ["../../../dist/packages-dist/common/testing"],
"@angular/compiler": ["../../../dist/packages-dist/compiler"],
"@angular/compiler/testing": ["../../../dist/packages-dist/compiler/testing"]
},
"rootDir": ".",
"sourceMap": true,