Compare commits

...

419 Commits

Author SHA1 Message Date
0700c8a252 docs(changelog): update change log to 2.0.0-beta.17. 2016-04-28 11:47:32 -07:00
c79e657fcd chore(release): bump version to 2.0.0-beta.17. 2016-04-28 11:39:20 -07:00
d9648887b8 fix(metadata): Do not attach module names to metadata.
The filename contains the module name as resolved by users, so the top-level module name is uneeded.
Module names on references are replaced by capturing the import syntax from the module.
This allows readers of the metadata to do the module resolution themselves.

Fixes #8225
Fixes #8082

Closes #8256
2016-04-28 01:58:13 +00:00
35cd0ded22 chore(testing): Refactor test methods to have a uniform interface.
Remove FunctionWithParamTokens.

All test wrappers async, fakeAsync and inject now return just a Function instead of FunctionWithParamTokens. This makes them directly consumable by the test framework. Also the test framework code does not have to handle a union of Function and FunctionWithParamTokens everywhere.

The Function returned by the above methods are considered asynchronous by the test framework if they return a Promise, synchronous otherwise.

Closes #8257
2016-04-28 01:16:25 +00:00
d2efac18ed feat(core): separate refs from vars.
Introduces `ref-` to give a name to an element or a directive (also works for `<template>` elements), and `let-` to introduce an input variable for a `<template>` element.

BREAKING CHANGE:
- `#...` now always means `ref-`.
- `<template #abc>` now defines a reference to the TemplateRef, instead of an input variable used inside of the template.
- `#...` inside of a *ngIf, … directives is deprecated.
  Use `let …` instead.
- `var-...` is deprecated. Replace with `let-...` for `<template>` elements and `ref-` for non `<template>` elements.

Closes #7158

Closes #8264
2016-04-28 01:13:40 +00:00
ff2ae7a2e1 fix(testing): allow test component builder to override directives from lists
When a component uses a list of directives, such as `ROUTER_DIRECTIVES`,
make `TestComponentBuilder#overrideDirective` work properly for members
of the list.

Closes #7397

Closes #8217
2016-04-28 00:56:45 +00:00
e1058a4d8a Revert "feat(compiler): ElementSchema now has explicit DOM schema information"
This reverts commit d327ac4b43.
2016-04-27 17:41:57 -07:00
d327ac4b43 feat(compiler): ElementSchema now has explicit DOM schema information
This makes the schema available for offline compile compiler as well.

Closes #8179
2016-04-27 22:57:28 +00:00
1ad2a02b11 fix(core): properly evaluate expressions with conditional and boolean operators
Fixes #8235
Fixes #8244

Closes #8282
2016-04-27 21:25:50 +00:00
1e8864c4a5 fix(compiler): Allow templates to access variables that are declared afterwards.
Fixes #8261
2016-04-27 11:22:44 -07:00
c209836fd0 fix(changelog): fix changelog script.
One charecter missing from
140a878a3d
2016-04-26 16:12:59 -07:00
7d1b6af073 style(global): group multiple imports from same module
Closes #7802

Closes #8209
2016-04-26 22:40:30 +00:00
140a878a3d chore(changelog): regenerate changelog for beta.16 including refactor
- the script explicitly takes input for the starting tag.
- the script only prepends changes.
2016-04-26 15:33:35 -07:00
b62bccf254 build(npm): update rxjs to 5.0.0-beta.6
Closes #6871
Closes #8047
2016-04-26 21:16:37 +00:00
39eb34739a chore(changelog): fix changelog with messages about testing zone deps
Closes #8253
2016-04-26 19:01:12 +00:00
969b55326c docs(changelog): update change log to beta.16 2016-04-25 22:08:32 -07:00
2c8371654a chore(release): bump version to beta.16 2016-04-25 21:48:58 -07:00
5a897cf299 feat(router): add Router and RouterOutlet
Closes #8173
2016-04-25 22:41:33 +00:00
ef67a0c57f feat(router): add router metadata 2016-04-25 22:41:33 +00:00
ef6163e652 feat(router): implement recognizer 2016-04-25 22:41:33 +00:00
f6985671dd feat(router): implement RouterUrlParser 2016-04-25 22:41:33 +00:00
90a1f7d5c4 feat(router): add UrlSegment, RouteSegment, and Tree 2016-04-25 22:41:33 +00:00
3e114227f8 refactor(core): support importUri in StaticReflector
Closes #8195
2016-04-25 22:14:29 +00:00
6103aa0a46 fix(release): Fix the package.json zone.js requirement to 0.6.12 2016-04-25 15:10:06 -07:00
b7c6feff28 chore(release): release the metadata collector
Closes #8197
2016-04-25 21:48:07 +00:00
b48d907697 docs(template-syntax): rename elvis operator
Closes #8196
2016-04-25 21:26:33 +00:00
676ddfa065 docs(cheatsheet): add Directive to cheatsheet
Closes #8170
2016-04-25 20:41:34 +00:00
c8d00dc191 fix(codegen): add explicit any to class fields
fixes #8204

Closes #8205
2016-04-25 20:21:18 +00:00
0b6865d6c6 chore: Remove AngularEntrypoint from TS
Closes #8158
2016-04-25 17:35:05 +00:00
67d05eb65f fix(compiler): use DI order for change detection order.
Closes #8198
2016-04-25 09:36:46 -07:00
152a117d5c fix(compiler): properly implement pure pipes and change pipe syntax
Pure pipes as well as arrays and maps are
implemented via proxy functions. This is
faster than the previous implementation
and also generates less code.

BREAKING CHANGE:
- pipes now take a variable number of arguments, and not an array that contains all arguments.
2016-04-25 09:04:22 -07:00
d6626309fd Revert "fix(compiler): only call pure pipes if their input changed."
This reverts commit 8db62151d2.
2016-04-25 07:53:49 -07:00
c3daccd83b fix(forms): ensure select model updates in firefox and ie
Closes #6573

Closes #8148
2016-04-22 21:23:20 +00:00
8db62151d2 fix(compiler): only call pure pipes if their input changed. 2016-04-21 16:20:19 -07:00
bab81a9831 feat(test): Implement fakeAsync using the FakeAsyncTestZoneSpec from zone.js.
Update the version of zone.js to @0.6.12 that contains the new FakeAsyncTestZoneSpec.

The new fakeAsync zone handles errors better and clearPendingTimers() is no longer required to be called after handling an error and is deprecated.

The fakeAsync test zone will now throw an error if an XHR is attemtped within the test since that cannot be controlled synchronously in the test(Need to be mocked out with a service implementation that doesn't involve XHRs).

This commit also allows fakeAsync to wrap inject to make it consistent with async test zone.

BREAKING CHANGE:

inject can no longer wrap fakeAsync while fakeAsync can wrap inject. So the order in existing tests with inject and fakeAsync has to be switched as follows:

Before:
```
inject([...], fakeAsync((...) => {...}))
```

After:
```
fakeAsync(inject([...], (...) => {...}))
```

Closes #8142
2016-04-21 22:11:00 +00:00
cc86fee1d1 fix(compiler): support string tokens with . inside. 2016-04-21 11:17:49 -07:00
386cc5dbb6 fix(transformers): support query.read
Closes #8172
2016-04-21 10:12:59 -07:00
2f7045720a fix(core): various minor compiler fixes
Closes #8162
2016-04-21 09:13:02 -07:00
9889c21aaa fix(metadata): emit metadata rooted at 'angular2'
fixes #8144

closes #8147
2016-04-20 17:14:53 -04:00
e69cb40de3 fix(forms): number input should report null when blank
Closes #6932

Closes #8141
2016-04-20 20:33:18 +00:00
12837e1c17 fix(forms): improve error message when ngFormModel is missing a form
Closes #8136

Closes #8143
2016-04-20 20:10:50 +00:00
9092ac79d4 refactor(core): support non reflective bootstrap.
This changes Angular so that it can be used without reflection (assuming a codegen for injectors).

BREAKIKNG CHANGE:
- Drops `APP_COMPONENT` provider. Instead, inject
  `ApplicationRef` and read its `componentTypes` property.
- long form bootstrap has changed into the following:
  ```
  var platform = createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PROVIDERS));
  var appInjector =
    ReflectiveInjector.resolveAndCreate([BROWSER_APP_PROVIDERS, appProviders], platform.injector);
  coreLoadAndBootstrap(appInjector, MyApp);
  ```
2016-04-20 11:34:11 -07:00
0a7d10ba55 refactor(core): separate reflective injector from Injector interface
BREAKING CHANGE:
- Injector was renamed into `ReflectiveInjector`,
  as `Injector` is only an abstract class with one method on it
- `Injector.getOptional()` was changed into `Injector.get(token, notFoundValue)`
  to make implementing injectors simpler
- `ViewContainerRef.createComponent` now takes an `Injector`
  instead of `ResolvedProviders`. If a reflective injector
  should be used, create one before calling this method.
  (e.g. via `ReflectiveInjector.resolveAndCreate(…)`.
2016-04-20 11:28:13 -07:00
efbd446d18 refactor(core): add Query.read and remove DynamicComponentLoader.loadIntoLocation.
This adds the feature for `@ViewChild`/`@ViewChildren`/`@ContentChild`/`@ContentChildren` to define what to read from the queried element.

E.g. `@ViewChild(`someVar`, read: ViewContainerRef)` will locate the element with a variable `someVar` on it and return a `ViewContainerRef` for it.

Background: With this change, Angular knows exactly at which elements there will be `ViewConainerRef`s as the user has to ask explicitly of them. This simplifies codegen and will make converting Angular templates into server side templates simpler as well.

BREAKING CHANGE:
- `DynamicComponentLoader.loadIntoLocation` has been removed. Use `@ViewChild(‘myVar’, read: ViewContainerRef)` to get hold of a `ViewContainerRef` at an element with variable `myVar`.
- `DynamicComponentLoader.loadNextToLocation` now takes a `ViewContainerRef` instead of an `ElementRef`.
- `AppViewManager` is renamed into `ViewUtils` and is a mere private utility service.
2016-04-20 11:28:00 -07:00
c06b0a2371 refactor(codegen): produce .ngfactory.dart/ts files instead of .template.dart/ts files.
This is needed as we will soon store other
things into the generated files, not
only the templates.
2016-04-20 11:27:34 -07:00
0c600cf6e3 refactor(core): introduce ComponentFactory.
Each compile template now exposes a `<CompName>NgFactory` variable
with an instance of a `ComponentFactory`.
Calling `ComponentFactory.create` returns a `ComponentRef` that can
be used directly.

BREAKING CHANGE:
- `Compiler` is renamed to `ComponentResolver`,
  `Compiler.compileInHost` has been renamed to `ComponentResolver.resolveComponent`.
- `ComponentRef.dispose` is renamed to `ComponentRef.destroy`
- `ViewContainerRef.createHostView` is renamed to `ViewContainerRef.createComponent`
- `ComponentFixture_` has been removed, the class `ComponentFixture`
  can now be created directly as it is no more using private APIs.
2016-04-20 11:27:26 -07:00
41404057cf fix(build): ignore Dart warnings for external code. 2016-04-20 10:51:58 -07:00
f4e6994634 feat(NgTemplateOutlet): add NgTemplateOutlet directive
This commits adds a new NgTemplateOutlet directive that can be
used to create embeded views from a supplied TemplateRef.

Closes #7615

Closes #8021
2016-04-20 04:28:59 +00:00
b602bd8c83 refactor(Location): out of router and into platform/common
closes https://github.com/angular/angular/issues/4943

BREAKING CHANGE:

`Location` and other related providers have been moved out of `router` and into `platform/common`. `BrowserPlatformLocation` is not meant to be used directly however advanced configurations may use it via the following import change.

Before:

```
import {
  PlatformLocation,
  Location,
  LocationStrategy,
  HashLocationStrategy,
  PathLocationStrategy,
  APP_BASE_HREF}
from 'angular2/router';

import {BrowserPlatformLocation} from 'angular2/src/router/location/browser_platform_location';
```

After:

```
import {
  PlatformLocation,
  Location,
  LocationStrategy,
  HashLocationStrategy,
  PathLocationStrategy,
  APP_BASE_HREF}
from 'angular2/platform/common';

import {BrowserPlatformLocation} from 'angular2/src/platform/browser/location/browser_platform_location';
```

Closes #7962
2016-04-20 04:28:47 +00:00
30c43521d3 fix(http) : set response.ok based on given status code
Closes #8056
2016-04-20 04:28:27 +00:00
45f5df371d docs(markdown): add missing space between markdown ### and text, turn h1 into h3s, remove bold.
Closes #7996
2016-04-20 04:09:31 +00:00
43e31c5abb docs(): fix a typo: patform -> platform
Closes #8081
2016-04-18 19:53:19 -07:00
13c8b13343 Add BREAKING CHANGE to CHANGELOG for b.15
Dart apps that import angular2/bootstrap.dart ran in beta.14, but fail in beta.15.

Closes #8071
2016-04-18 19:53:19 -07:00
0fc9ec248e fix(upgrade): clean up scope when element is destroyed
Closes #8102
2016-04-19 01:06:14 +00:00
d094a85647 fix(angular_1_router): Removed arrow function from module template
Closes #8076
2016-04-19 00:44:17 +00:00
22c05b0834 fix(tests): remove payload size check 2016-04-18 17:08:55 -07:00
8490921fb3 feat(tests): manage asynchronous tests using zones
Instead of using injectAsync and returning a promise, use the `async` function
to wrap tests. This will run the test inside a zone which does not complete
the test until all asynchronous tasks have been completed.

`async` may be used with the `inject` function, or separately.

BREAKING CHANGE:

`injectAsync` is now deprecated. Instead, use the `async` function
to wrap any asynchronous tests.

Before:
```
it('should wait for returned promises', injectAsync([FancyService], (service) => {
  return service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); });
}));

it('should wait for returned promises', injectAsync([], () => {
  return somePromise.then(() => { expect(true).toEqual(true); });
}));
```

After:
```
it('should wait for returned promises', async(inject([FancyService], (service) => {
  service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); });
})));

// Note that if there is no injection, we no longer need `inject` OR `injectAsync`.
it('should wait for returned promises', async(() => {
  somePromise.then() => { expect(true).toEqual(true); });
}));
```

Closes #7735
2016-04-18 15:59:07 -07:00
ecb9bb96f0 docs(): fix broken links
Closes #8028
2016-04-18 20:12:37 +00:00
75463cd8df chore(perf): return perf metrics from AngularProfiler
Closes #8075
2016-04-18 19:48:52 +00:00
c6244d1470 feat(i18n): add support for nested expansion forms
Closes #7977
2016-04-18 19:38:12 +00:00
22ae2d0976 cleanup(html_parser): cleanup to fix analyzer warnings 2016-04-18 19:38:12 +00:00
88b0a239c4 feat(i18n): support plural and gender special forms 2016-04-18 19:38:12 +00:00
7c9717bba8 feat(html_parser): support special forms used by i18n { exp, plural, =0 {} } 2016-04-18 19:38:11 +00:00
7f297666ca feat(html_lexer): support special forms used by i18n { exp, plural, =0 {} } 2016-04-18 19:38:11 +00:00
d99823e2fd docs(core): fix some grammar
Closes #8055
2016-04-18 19:34:17 +00:00
bb9fb21fac feat(i18n): add custom placeholder names
Closes #7799

Closes #8057
2016-04-18 19:14:15 +00:00
b64672b23c fix(dart) reverts protobuf to last working version
Closes #8125
2016-04-18 18:28:43 +00:00
930f58718b Revert "feat(i18n): add support for custom placeholder names"
This reverts commit 2abb414cfb.
2016-04-14 15:36:40 -07:00
2b34c88b69 refactor(view_compiler): codegen DI and Queries
BREAKING CHANGE:
- Renderer:
  * renderComponent method is removed form `Renderer`, only present on `RootRenderer`
  * Renderer.setDebugInfo is removed. Renderer.createElement / createText / createTemplateAnchor
    now take the DebugInfo directly.
- Query semantics:
  * Queries don't work with dynamically loaded components.
  * e.g. for router-outlet: loaded components can't be queries via @ViewQuery,
    but router-outlet emits an event `activate` now that emits the activated component
- Exception classes and the context inside changed (renamed fields)
- DebugElement.attributes is an Object and not a Map in JS any more
- ChangeDetectorGenConfig was renamed into CompilerConfig
- AppViewManager.createEmbeddedViewInContainer / AppViewManager.createHostViewInContainer
  are removed, use the methods in ViewContainerRef instead
- Change detection order changed:
  * 1. dirty check component inputs
  * 2. dirty check content children
  * 3. update render nodes

Closes #6301
Closes #6567
2016-04-13 14:43:48 -07:00
45f09ba686 docs(changelog): update changelog to beta.15 2016-04-13 14:39:17 -07:00
bb62905bef chore(release): bump version to beta.15 2016-04-13 14:39:17 -07:00
7bc9b19418 cleanup(tests): remove unused imports
Closes #6784
2016-04-13 13:24:04 -07:00
e9f7a00910 docs(metadata): Add more docs of ViewChild and ViewChildren
Closes #7174
2016-04-13 13:24:04 -07:00
a5d6b6db8b fix(WebWorker): Fix textarea value not being sent to the worker
Closes #7439
Closes #7828
2016-04-13 13:24:04 -07:00
fc496813e2 fix(7877): StaticReflector returns empty results instead of undefined.
Reflector always returns either an empty object or an empty list if no
metadata is recorded for the class. StaticReflector matches this
behavior.

Closes #7986
2016-04-13 13:23:54 -07:00
2abb414cfb feat(i18n): add support for custom placeholder names
Closes #7799
Closes #8010
2016-04-13 13:23:42 -07:00
0e56aaf189 fix: remove typescript references to d.ts files from benchpress and e2e tests
using "/// <reference" is incorrect because it makes our code non-portable. The correct solution is to provide
these typings as ambient typings as an additional entry point - which we already do.

Closes #8050
2016-04-13 13:23:27 -07:00
3412aba46e feat(typescript): update to 1.9 nightly.
To workaround https://github.com/Microsoft/TypeScript/issues/7573
we must remove the readonly keyword from generated .d.ts files.
This solution will not scale, but will probably buy enough time to require our users move to a 2.0 beta.

Closes #8003
2016-04-13 18:54:58 +00:00
347e71af7d chore(travis): enable the typescript@next build
Fixes #7050
2016-04-13 18:54:58 +00:00
d24df799d3 Revert "feat(iterable_differ): support immutable lists"
In Dart, ImmutableLists are just a projection of an underlying list.
I.e. if the underlying list changes, the ImmutableList also changes.
So we can't make optimizations based on checking whether a collection
is an ImmutableList.

This reverts commit a10c02cb41.

Closes #8023
2016-04-13 17:02:48 +00:00
01e6b8c7ed fix(build): ignore dart warnings The name … is shown, but not used
See https://github.com/angular/angular/issues/8044

Closes #8045
2016-04-13 09:49:33 -07:00
60727c4d2b revert(format): Revert "chore(format): update to latest formatter"
This reverts commit 03627aa84d.
2016-04-12 09:41:01 -07:00
03627aa84d chore(format): update to latest formatter
Closes #7958
2016-04-11 22:15:23 +00:00
83b8f59297 feat(transformers): special case Profiler 2016-04-11 14:32:22 -07:00
c6f454f51d docs: remove duplicate 'directives' from example
Closes #7963
2016-04-11 21:29:21 +00:00
ccff17599a feat(ngFor): Support convenience view local in ngFor
Closes #8013
2016-04-11 21:27:48 +00:00
fb2773b8f3 docs(router): fix wording of hashchange explanation
Closes #7776
2016-04-11 21:11:11 +00:00
5110121f6e docs(ViewQuery): fix typo in documentation
fix typo that confusingly refers to `@Query` rather than `@ViewQuery`.

Closes #7870
2016-04-11 21:04:08 +00:00
27cf897239 chore: upgrade zone.js to v0.6.10
Closes #7818
Closes #7721

Closes #7888
2016-04-11 21:03:59 +00:00
5d33a12af4 chore(gulpfile): turn off mangle for prod
Closes #7988
2016-04-11 20:50:14 +00:00
08b295603c fix(7987): Incremental build works with new trees
Closes #7989
2016-04-11 20:28:34 +00:00
3b60503d2b feat(transformers): changes transformers to collect information about providers and resolve identifiers during linking 2016-04-10 19:36:16 -07:00
3c2473bac6 Fixed typo in documentation
Closes #7943
2016-04-08 23:27:36 +00:00
f9426709ef chore(build): Fix errors reported using 1.9.
Closes #7954
2016-04-08 21:53:50 +00:00
e1e44a910e fix(select): set value individually from ngModel
Closes #7975

Closes #7978
2016-04-08 21:08:05 +00:00
f371c9066d build(broccoli): Clean-up TypeScript build
The TypeScript parser now only references files that are in broccoli trees.

Closes #7941
2016-04-08 19:30:39 +00:00
85c1927993 build(broccoli): AngularBuilder compiles with TypeScript 1.8+.
Beginning with 1.8, if a modules has both a .ts and .d.ts file, the .js
file is not written.

Closes #7947
2016-04-08 19:24:04 +00:00
a596b887ff feat(compiler): Add an implementation for XHR that uses a template cache to load template files.
Useful for avoiding doing an actual XHR during testing.
Part of the solution for #4051 (Other part is a Karma plugin that will create the template cache).

Closes #7940
2016-04-08 19:05:05 +00:00
6cbf99086e feat(gestures): allow override of Hammer default configuration
Closes #7924
2016-04-08 18:53:58 +00:00
26a3390549 refactor(dart/transform): Remove deprecated angular2/bootstrap
BREAKING CHANGE

Remove the deprecated angular2/bootstrap.ts &
angular2/bootstrap_static.ts libraries.

Browser entry points should import angular2/platform/browser which
supplies the `bootstrap` function.

Closes #7650
2016-04-08 18:28:35 +00:00
9a1959f77a build(tslint): re-enable linter and fix violations
fixes #7798

Closes #7800
2016-04-07 23:11:02 +00:00
226e662cf1 feat(parser): TemplateParser.tryParse() returns both the AST and errors
The language service (#7482) always needs the AST even if there are errors
in the template.

Closes #7858
2016-04-07 22:00:46 +00:00
7a1a1b80ed Roll forward to 0.1.24
Closes #7867
2016-04-07 21:58:48 +00:00
529988bc81 Fix DDC errors 2016-04-07 21:58:48 +00:00
c17dc1c057 fix(7837): MetadataCollector takes no parameters for the constructor.
MetadataCollector no longer requires a ts.LanguageService parameter
it didn't use.

Closes #7838
2016-04-07 21:38:07 +00:00
09a95a692e docs(cheatsheet/dart): fix imports
Closes #7872
2016-04-07 21:23:14 +00:00
247964af62 fix(upgrade): make upgradeAdapter upgrade angular 1 components correctly
With this fix, the $onInit function of an upgraded angular 1 component is called and input bindings (<) are created.

Closes #7951
2016-04-07 20:19:46 +00:00
5e2bc5c593 fix(RouterLink): ignore optional parameters when checking for active routes
fixes #6459
Closes #7834
2016-04-07 19:41:14 +00:00
28e657d857 fix(payload): increase payload size limit temporarily 2016-04-07 11:42:13 -07:00
06ad112998 docs(changelog): update change log to beta.14 2016-04-07 10:19:35 -07:00
cfa1d17afe chore(release): bump version to beta.14 2016-04-07 10:09:46 -07:00
3ca6df87b8 fix(select): update name from ng-value to ngValue
Closes #7939
2016-04-06 22:47:21 +00:00
e310bee9e2 feat(dart/transform): Avoid print in transformer code.
Replace direct uses of `print` in the transformer with explicit uses of
stderr.

Add a few @override annotations for clarification of other `print`
implementations.

Clarify error message on incorrect custom_annotations value.

Closes #7855
2016-04-06 22:31:08 +00:00
4902244cce fix(router): allow forward slashes in query parameters
Closes #7824
2016-04-06 22:01:12 +00:00
8db97b0b7a fix(forms): support both value and ng-value 2016-04-06 14:37:57 -07:00
9be04f8d38 fix(upgrade): leak when angular1 destroys element
Fixes #6401

Closes #7935
2016-04-06 19:58:10 +00:00
74e2bd7e3e fix(select): support objects as select values
Closes #4843

Closes #7842
2016-04-06 17:05:38 +00:00
52d3980d02 Revert "feat(transformers): changes transformers to collect information about providers and resolve identifiers during linking"
This reverts commit 4e9809bcb2.
2016-04-06 09:26:03 -07:00
4e9809bcb2 feat(transformers): changes transformers to collect information about providers and resolve identifiers during linking
Closes #7380
2016-04-04 22:59:43 +00:00
bd8a4215dd refactor(core): remove @Injectable as only classes that are instantiated via DI need it 2016-04-04 22:59:43 +00:00
d23b973e7a refactor(forms): extract Validators.required into a variable as transformers cannot resolve statics 2016-04-04 22:59:43 +00:00
0dbf959548 feat(static-reflector): Added StaticReflector
Added a static reflector that uses metadta produced during build
or, additionally, directly from typescript, to produce the metadata
used by Angular code generation compiler.
2016-04-01 14:45:43 -07:00
20812f446f docs(changelog): fix formatting 2016-03-30 18:10:41 -07:00
27a4d0ce11 docs(changelog): update change log to beta.13 2016-03-30 17:23:38 -07:00
9dec4c7485 chore(release): bump version to beta.13 2016-03-30 17:21:51 -07:00
90c87fa6ad fix(codegen): stringify using an opaque ID when toString contains parens.
Using toString results in 'function (_arg1, arg2) {' when using closure compiler for 6-to-5.

Closes #7825
2016-03-30 23:43:35 +00:00
291928feb1 chore(scripts): log out of npm 2016-03-30 16:20:21 -07:00
c9c52fb353 build(pubspec): Clean up pubspec files
Add a direct dependency on package:path.
Remove dependency on package:quiver
2016-03-29 14:30:00 -07:00
0bcfcde63d fix(Router): handling of special chars in dynamic segments
Closes #7804
2016-03-29 20:24:28 +00:00
1c20a62611 feat(dart): Add a dev-mode check for undeclared lifecycle interfaces
Add a check in ReflectionCapabilities#interfaces which determines if
the passed-in type implements a Lifecycle Interface but does not declare
that it does so.

See https://goo.gl/b07Kii for details.

Closes #6849
2016-03-29 10:55:06 -07:00
8430927e6b feat(i18n): update transformers to read a xmb file when provided and use I18nHtmlParser in this case
Closes #7790
2016-03-28 19:54:13 +00:00
d2ca7d81c8 feat(i18n): reexport I18nHtmlParser through the i18n barrel 2016-03-28 19:54:13 +00:00
756121acc1 feat(i18n): update I18nHtmlParser to accept parsed messages 2016-03-28 19:54:13 +00:00
d7e1175df0 feat(i18n): implement xmb deserialization 2016-03-28 19:54:12 +00:00
66cd84e0d5 refactor(i18n): rename serialize into serializeXmb 2016-03-28 19:54:12 +00:00
506f4ce1e5 feat(compiler): Resolvers now use DI to create reflector
Also introduced ReflectorReader when only read-only access to the reflector
is needed.

Closes #7762
2016-03-28 13:52:32 -05:00
a0387d2835 doc(Router): improve the example for routerOnActivate 2016-03-28 10:25:03 -07:00
9bdd5951d9 docs(forms): update the docs to reflect the current behavior
Closes #6504
2016-03-28 10:22:24 -07:00
111afcdff1 fix(build): MetadataCollector correctly collects property metadata
Fixes #7772

Closes #7773
2016-03-25 21:52:06 +00:00
85f3dc2fb5 chore(build): Produce .d.ts files for build tools
Closes #7763
2016-03-25 18:23:00 +00:00
430f367c2f fix(upgrade): make ngUpgrade work with testability API
Closes #7603
2016-03-25 17:27:45 +00:00
d272f96e23 feat(i18n): implement an i18n-aware html parser
Closes #7738
2016-03-24 20:36:19 +00:00
73a84a7098 refactor(i18n): remove utility functions into a separate file 2016-03-24 20:36:19 +00:00
17c8ec8a5d feat(html_parser): change HtmlElementAst to store both the start and the end positions 2016-03-24 20:36:19 +00:00
a1880c3576 feat(facade): add ListWrapper.flatten 2016-03-24 20:36:19 +00:00
91999e016e feat(facade): add RegExpWrapper.replaceAll to replace all matches using the provided function 2016-03-24 20:36:19 +00:00
aa966f5de2 feat(Compiler): Allow overriding the projection selector
fixes #6303

BREAKING CHANGE:

For static content projection, elements with *-directives are now matched against the element itself vs the template before.

    <p *ngIf="condition" foo></p>

Before:

    // Use the implicit template for projection
    <ng-content select="template"></ng-content>

After:

    // Use the actual element for projection
    <ng-content select="p[foo]"></ng-content>
Closes #7742
2016-03-24 20:09:34 +00:00
3e593b8221 chore(test.typings): instrument against examples folder
chore(typing_spec): delete unused typing_spec files

Closes #7743
2016-03-24 19:25:07 +00:00
440aca86a3 chore(examples): fix implied imports in examples for testing built typings 2016-03-24 19:25:07 +00:00
09f4d6f52d chore(refactor): Refactored metadata collector
Renamed MetadataExtractor to MetadataCollector
Reorganized to split src from tests

Closes #7492
2016-03-24 18:52:06 +00:00
3f57fa6e0e chore(build): Added tests for metadata extractor
Adds unit test to metadata extractor classes
Fixes issues found while testing
2016-03-24 18:52:06 +00:00
ae876d1317 feat(build): Persisting decorator metadata
This allows determing what the runtime metadata will be for a
class without having to loading and running the corresponding
.js file.
2016-03-24 18:52:06 +00:00
6de68e2f1f feat(compiler): assert that Component.style is an array
Part of #7481 (effort to improve error messages)

Closes #7559
2016-03-24 15:21:16 +00:00
49527ab495 fix(ngFor): give more instructive error when binding to non-iterable
Before, you'd get an error like:

```
EXCEPTION: Cannot find a differ supporting object ‘[object Object]’ in [users in UsersCmp@2:14]
```

Now, you get:

```
EXCEPTION: Cannot find a differ supporting object ‘[object Object]’ of type 'Object'. Did you mean to bind ngFor to an Array? in [users in UsersCmp@2:14]
```
2016-03-24 15:21:16 +00:00
0898bca939 chore: bump version to beta.12 w/ changelog 2016-03-23 15:56:38 -07:00
d940387beb chore: upgrade zone.js to v0.6.6
Closes #7730
Closes #7737
2016-03-23 20:48:23 +00:00
27c45b05cf Update ISSUE_TEMPLATE.md 2016-03-23 12:53:10 -07:00
90f09d551f Update ISSUE_TEMPLATE.md 2016-03-23 12:50:01 -07:00
3739588e97 chore: build cjs code prior to launching e2e tests
Closes #6783

Closes #7725
2016-03-22 22:09:33 +00:00
0730b753f2 chore(ddc): add e2e test infra + first test 2016-03-22 22:09:33 +00:00
cad693de0f refactor(NgZoneImpl): ensure zone spec is available
trace could be true (in dev mode) while there is no long stack trace spec
Closes #7702
2016-03-22 18:46:12 +00:00
bf911fc992 chore: upgrade zone.js@0.6.5
Closes #7700
2016-03-22 08:21:10 -07:00
fb6d791ce9 test(angular1_router): check that link generation works with baseHref
Closes #7489
2016-03-22 02:19:09 +00:00
0f8efce799 fix(angular1_router): support link generation with custom hashPrefixes 2016-03-22 02:19:09 +00:00
69c1405196 fix(angular_1_router): ng-link is generating wrong hrefs
At the moment ng-link is generating html5mode URLs for `href`s.
Instead it should check whether or not html5mode is enabled and create
the `href`s accordingly. The renaming in the `getLink` function is
aligning it to `RouterLink`'s `_updateLink`.

Closes #7423
2016-03-22 02:19:09 +00:00
980491b08f chore(angular1_router): tighten up the build regex replacement 2016-03-22 02:19:09 +00:00
72e24663ad refactor(dart/transform): Migrates tests to use package:test
Pt 4 of migrating from package:guinness + package:unittest =>
package:test.

This PR migrates DeferredRewriter & DirectiveMetadataLinker unit tests.

Closes #7703
2016-03-22 02:13:16 +00:00
363ed5140e docs(bundles/overview.md): fix typo
Closes #7677
2016-03-22 01:53:35 +00:00
b0f585ab08 build(npm): bump Angular version in our shrinkwrap files 2016-03-22 01:53:35 +00:00
8b67b07580 fix(package.json): remove es6-promise from the peerDependency list
As of zone.js@0.6* we no longer require an es6-promise polyfill. The polyfill is only needed on browsers that don't
have native Promise support.
2016-03-22 01:53:35 +00:00
5c330ea492 chore(publish): run router publish with additional memory
Closes #7408
2016-03-22 00:20:08 +00:00
06eaaf0ac5 chore(angular1_router): bump version to v0.2.0 2016-03-22 00:20:08 +00:00
9820271243 chore(script): publish angular 1 router to latest tag in npm 2016-03-22 00:20:08 +00:00
b6507e37ef feat(dart/transform): Use angular2/platform/browser as bootstrap lib
Update the Angular 2 transformer to recognize
`package:angular2/platform/browser.dart` as the library which exports
the `bootstrap` function.

Update playground, examples, benchmarks, & tests to import bootstrap from
platform/browser.

Closes #7647
2016-03-21 00:58:17 +00:00
c194f6695d chore: bump version to beta.11 w/ changelog 2016-03-18 14:42:31 -07:00
967ae3e1b8 fix(common): remove @internal annotation on SwitchView
Closes #7657
2016-03-18 13:16:50 -07:00
a5e6eaaebc chore: upgrade es6-shim to v0.35.0
Closes #7653
2016-03-18 13:16:15 -07:00
d4e9b55fb6 fix: make sure that Zone does not show up in angular2.d.ts
Closes #7655
2016-03-18 19:41:30 +00:00
048bd280dd chore: re-enable all tests (accidental ddescribe checkin) 2016-03-18 19:41:30 +00:00
8326ab3240 feat(i18n): add a simple dart script extracting all i18n messages from a package
Closes #7620
2016-03-17 16:45:16 -07:00
a7fe983be2 feat(i18n): create i18n barrel 2016-03-17 16:45:15 -07:00
e1f8e54e34 feat(i18n): implement xmb serializer 2016-03-17 16:45:15 -07:00
2b165944ea refactor(i18n): move message and id into a separate file 2016-03-17 16:45:15 -07:00
ea11b3f1f8 docs(changelog): update change log to beta.10 2016-03-17 15:06:28 -07:00
3bd87147ab chore(release): bump version to beta.10 2016-03-17 15:06:27 -07:00
2f581ffc88 fix(router): RouterOutlet loads component twice in a race condition
Closes #7497

Closes #7545
2016-03-16 22:34:54 +00:00
d61aaac400 chore(): remove all angular2_material code. 2016-03-16 13:37:37 -07:00
310620fd12 chore: upgrade to new Zone.js API v0.6.2
BREAKING CHANGE

Removed deprecated API from NgZone
- `NgZone.overrideOnTurnStart`
- `NgZone.overrideOnTurnDone`
- `NgZone.overrideOnEventDone`
- `NgZone.overrideOnErrorHandler`

Rename NgZone API
- `NgZone.onTurnStart` => `NgZone.onUnstable`
- `NgZone.onTurnDone` => `NgZone.onMicrotaskEmpty`
- `NgZone.onEventDone` => `NgZone.onStable`

Closes #7345
2016-03-16 18:05:09 +00:00
f9fb72fb0e chore(core): remove @View annotation
Closes #7495
2016-03-14 23:26:20 +00:00
095db673c5 feat(i18n): implement a simple version of message extractor
Closes #7454
2016-03-14 21:50:00 +00:00
70d18b5b53 feat(compiler): change html parser to preserve comments 2016-03-14 21:50:00 +00:00
f1796d67f4 feat(facade): add .values to StringMapWrapper 2016-03-14 21:50:00 +00:00
cb38d72ff4 feat(shadow_css): support /deep/ and >>>
Fixes #7562

Closes #7563
2016-03-11 22:14:26 +00:00
b72bab49aa feat(core): introduce a CSS lexer/parser 2016-03-11 13:54:01 -08:00
201475e8d8 cleanup(testing): clean up public api spec
Change the old public api spec to check only the exported top-level symbols. This will make sure that Dart and JS do not diverge. The new public api spec verifies the TS api.

Closes #7447
2016-03-11 19:24:29 +00:00
c25b9fcf97 docs(core): update <content> to <ng-content> 2016-03-11 11:19:52 -08:00
8755a8e188 docs(): fix typo 2016-03-11 11:18:59 -08:00
127fbfd5a6 Revert "feat(core): introduce a CSS lexer/parser"
This reverts commit 293fa5505b.

The rebased commit broke CI: https://travis-ci.org/angular/angular/jobs/115388814
2016-03-11 11:14:58 -08:00
f33dda79e9 chore(build): disable broken FirefoxBeta on SauceLabs
See #7560.
2016-03-11 10:57:44 -08:00
293fa5505b feat(core): introduce a CSS lexer/parser 2016-03-11 10:42:29 -08:00
df1f78e302 feat(i18n): add ngPlural directive 2016-03-10 09:55:21 -08:00
43bb31c6c6 refactor(dart/transform): Use targeted transformers
TL;DR: Modify pubspec.yaml files to use the recommended "targeted"
transformers. The unified "simple" angular2 transformer still works as
always, but we want to encourage use of the targeted transformers
whereever possible.

See [the wiki](https://github.com/angular/angular/wiki/Advanced-Transformer-Configuration)
for details about targeted transformers.

See #1872
2016-03-10 09:30:47 -08:00
169869a195 test(matchers): add support for toMatchPattern in tests 2016-03-09 21:31:15 -08:00
b691da26af chore(facade): add enum index lookup support 2016-03-09 21:30:03 -08:00
8e3e45097a fix(router): handle URL that does not match a route
Closes #7349
Closes #7203
2016-03-09 20:48:52 -08:00
aa43d2f87b docs(changelog): update change log to beta 9 2016-03-09 16:37:30 -08:00
128acbb6eb fix(change_detection): fix a memory leak 2016-03-09 16:24:51 -08:00
5824866a83 fix(closure): don't throw from top-level
workaround for http://b/27151095
2016-03-09 16:22:35 -08:00
0d58b137a7 fix(router/instruction): ensure toLinkUrl includes extra params
Closes #7367
2016-03-09 16:21:43 -08:00
b5c769e1e4 chore(release): bump version to beta.9 2016-03-09 14:38:23 -08:00
7f22bd62ab test(angular_1_router): apply annotations to controller constructors
Until Angular 1.5.1 is released, the `$routeConfig` and `$routerCanActivate`
annotations for components must live on the controller constructor.

In Angular 1.5.1, it will automatically copy these annotations across from
the component definition file.

Closes #7319
2016-03-09 21:50:24 +00:00
83f0e7c975 test(angular_1_router): fix router_spec tests
These tests were registering new components after the application had
been bootstrapped, which is not a valid use case for synchronous routes
in Angular 1.

In particular it was registering the "root" component, which caused the
`$rootRouter` to blow up, when it was instantiated, pointing to a root
component that did not yet exist.
2016-03-09 21:50:24 +00:00
adef68b4d6 refactor(angular_1_router): remove directiveIntrospector
The directiveIntrospector was a bit of a hack to allow the router to
read the `$routeConfig` annocation and `$routerCanActivate` hook from
directives when they were registered.

It turns out that if we put these properties on the component controller's
constructor function (i.e. as static class methods) then we can simply
use the `$injector` to access it as required.

Currently, people put the properties directly on their component definition
objects. In Angular 1.5.1, we will copy these properties onto the controller
constructor to maintain a simple migration path. But going forward it may be
better to encourage people to add the properties directly to the controller
constructor.
2016-03-09 21:50:24 +00:00
14f0e9ada8 chore: fix DDC errors / warnings
Closes #7195
2016-03-08 22:17:32 +00:00
ef9e40e82b refactor(dart/transform): Migrates tests to use package:test
Pt 3 of migrating from package:guinness + package:unittest => package:test.

This PR migrates DirectiveProcessor & InlinerForTest unit tests.

Closes #7475
2016-03-08 01:39:23 +00:00
41e38e4330 fix hammer_gestures infinite loop 2016-03-08 01:37:40 +00:00
2c7c3e3c69 feat(TAG_DEFINITIONS): include <meta> and <base>
needed to parse index.html as a component template
Closes #7455
2016-03-08 01:03:20 +00:00
756f5d884f refactor(dart/transform): AnnotationMatcher tests
These were previously not being run.

Bring them up to modern usage, move them to package:test, and include
them in transform.server.spec.dart.

Closes #7463
2016-03-08 00:47:35 +00:00
45fd6f0a41 feat(transformers): change 'Missing Identifier' to be an error
Closes #7403
2016-03-08 00:08:36 +00:00
75ae4a9159 ci(publish-build-artifacts.sh): skip all the work for builds other than upstream/master
Closes #7413
2016-03-05 19:54:22 +00:00
37d18d0112 ci(travis): publish artifacts only from the upstream/master jobs 2016-03-05 19:54:22 +00:00
773fe8f8c5 ci(travis): simplify job status reporting 2016-03-05 19:54:22 +00:00
4da2b19ea0 docs(CONTRIBUTING.md): clarify the difference between build and ci commit message scopes 2016-03-05 19:54:22 +00:00
9f3547e35d ci(travis): fix typo in webhooks config 2016-03-05 19:54:22 +00:00
5a79358727 ci(travis): fix indentation in of the .travis.yaml 2016-03-05 19:54:22 +00:00
85bfbc13c1 ci(travis): clean up matrix environmental variables
remove all unnecessary ones.
2016-03-05 19:54:22 +00:00
1a01af9e68 ci(travis): clean up, reorganize and document before_install and install scripts
Functionally this should be a noop change.
2016-03-05 19:54:22 +00:00
dd95e901df ci(travis): remove bogus environmental variable 2016-03-05 19:54:22 +00:00
9782d8c32e ci(travis): better document before_cache script 2016-03-05 19:54:22 +00:00
80764c6f71 ci(travis): use gcc v4.8 to compile npm native modules on Node v4 and v5 2016-03-05 19:54:22 +00:00
d9e78e4fa8 build(analytics): allow build analytics to take previous exit code as the first argument 2016-03-05 19:54:22 +00:00
10fedd0dfc ci(analytics): correctly report CI job errors as errors 2016-03-05 19:54:22 +00:00
315e73c47c ci(analytics): report Travis ID without the build number prefix
We need to track latency of individual jobs over time, but don't care to know what's the build ID that these jobs are associted with.
2016-03-05 19:54:22 +00:00
912717ff31 ci(analytics): fix TRAVIS_PULL_REQUEST reporting
process.env.TRAVIS_PULL_REQUEST contains a string and not a boolean value, so we need
to compare it to a string literal rather than do boolean arithmetics.
2016-03-05 19:54:22 +00:00
b857fd1eeb Revert "feat(transformers): collect provider information"
This reverts commit 81beb1c788.

Broke Google3.
2016-03-04 13:51:26 -08:00
6dce4f49c2 feat(router): Added method to get current instruction
This method delegates to the root router to get the current complete instruction.
2016-03-04 02:10:58 -08:00
15e16148f4 feat(dart/transform): Create standalone transformers for phases
Create transformers that allow specifying transformer actions on
specific libraries.

* angular2/transform/codegen: Generates all necessary code.
* angular2/transform/reflection_rewriter: Replaces `bootstrap` calls in
  application entry points to remove transitive dart:mirrors import,
  resulting in smaller code size & faster execution.
* angular2/transform/deferred_rewriter: Rewrites deferred imports and
  `loadLibrary` calls to initialize Angular2 and preserve deferred
  operation.

Proper configuration of these three transformers can replace the single
angular2 transformer, resulting in significant performance gains for
builds of large angular2 apps.

Update angular2 itself to declare the codegen transformer, since it has
neither deferred imports nor application entry points.

Remove the undocumented & unused quick_transformer.
2016-03-04 09:52:44 +00:00
ae49085481 fix(angular_1_router): Renamed require statements after TypeScript files are transpiled
The require function was causing failures when bundled using Browserify and SystemJS

Closes #7049
2016-03-04 09:31:24 +00:00
11e8aa26f6 feat(angular1_router): Add ng-link-active class to active ng-link
Closes #6882
2016-03-04 09:30:58 +00:00
81beb1c788 feat(transformers): collect provider information 2016-03-04 01:19:25 -08:00
6402d61f69 chore: fix up ngClass for types/export missing public API
Closes #7202
2016-03-04 08:03:55 +00:00
5a59e44765 chore(test): migrate Dart tests to package:test
Instead of running with karma and the karma-dart shim, run dart
tests directly using the new package:test runner. This migrates
away from package:unittest.

Fixes a couple tests, mostly associated with depending on absolute
URLs or editing the test providers after an injector had already
been created.

Remove karma-dart and associated files. Change gupfiles to run tests
via `pub run test` instead.
2016-03-04 02:27:44 +00:00
7455b907d1 Revert "feat(dart): Add a dev-mode check for undeclared lifecycle interfaces"
This reverts commit a3d7629134.

Needs co-ordination with google3 changes.
2016-03-03 18:00:18 -08:00
579b890446 chore(dart) Update dev dependency on code_tranformers
Closes https://github.com/angular/angular/issues/6665
2016-03-03 23:12:02 +00:00
19a08f3a43 feat(compiler): Added spans to HTML parser errors
Allows using the HTML parser in contexts errors are reported in a development tool such as an editor.
2016-03-03 22:51:57 +00:00
a3d7629134 feat(dart): Add a dev-mode check for undeclared lifecycle interfaces
Add a check in `ReflectionCapabilities#interfaces` which determines if
the passed-in type implements a Lifecycle Interface but does not declare
that it does so.

See https://goo.gl/b07Kii for details.

Closes #6849
2016-03-03 22:45:50 +00:00
bc9644e86e chore: add github issue / pr template 2016-03-03 14:06:11 -08:00
a10c02cb41 feat(iterable_differ): support immutable lists
Closes #7127
2016-03-03 18:29:01 +00:00
9936e347ff chore(build): Remove circular dependency in Angular 2 ES5 output.
Remove couple of circular dependency between modules in Angular 2 ES5 output caused by exception_handler.ts and router_providers.ts.

Fix the build/checkCircularDependency gulp task to call madge properly to detect the circular deps.

Closes #7287
2016-03-03 17:42:33 +00:00
7d44b8230e fix(router): support outlets within dynamic components
Fixes internal b/27294172
2016-03-03 06:49:29 -08:00
75343eb340 feat(router): add regex matchers
@petebacondarwin deserves credit for most of this commit.

This allows you to specify a regex and serializer function instead
of the path DSL in your route declaration.

```
@RouteConfig([
  { regex: '[a-z]+.[0-9]+',
    serializer: (params) => `{params.a}.params.b}`,
    component: MyComponent }
])
class Component {}
```

Closes #7325
Closes #7126
2016-03-02 16:08:19 -08:00
2548ce86db fix(angular1_router): rename router component binding to $router
The current router is passed to the current component via a binding.
To indicate that this is an angular provided object, this commit
renames the binding to `$router`.

BREAKING CHANGE:

The recently added binding of the current router to the current component
has been renamed from `router` to `$router`.

So now the recommended set up for your bindings in your routed component
is:

```js
{
  ...
  bindings: {
    $router: '<'
  }
}
```
2016-03-02 16:08:19 -08:00
5586c29492 fix(angular1_router): support templateUrl components 2016-03-02 16:08:19 -08:00
1174473e9c fix(angular1_router): rename router component binding to $router
The current router is passed to the current component via a binding.
To indicate that this is an angular provided object, this commit
renames the binding to `$router`.

BREAKING CHANGE:

The recently added binding of the current router to the current component
has been renamed from `router` to `$router`.

So now the recommended set up for your bindings in your routed component
is:

```js
{
  ...
  bindings: {
    $router: '<'
  }
}
```
2016-03-02 16:08:19 -08:00
1d49b3e36b fix(build): Use fixed version of Chromium Canary that will be updated manually instead of automatically using the latest Chrome canary 2016-03-02 15:35:07 -08:00
2830df4190 docs(changelog): update change log to beta 8 2016-03-02 11:32:38 -08:00
143cf89b5f chore(release): bump version to beta. 2016-03-02 11:31:25 -08:00
69c1694900 fix(WebWorker): Make MessageBus EventEmitter synchronous 2016-03-01 23:23:17 +00:00
01fe7f5fac fix(WebWorker): Fix PostMessageBusSink and Source undefined error.
Closes #7156
2016-03-01 14:40:09 -08:00
9aedef208f fix(test): fix a broken test 2016-03-01 14:38:55 -08:00
39b6e0efba feat(transformers): collect information for CompileDiDependencyMetadata 2016-03-01 13:28:36 -08:00
f60fa14767 feat(core): drop ChangeDetectionStrategy.OnPushObserve
BREAKING CHANGE:

`OnPushObserve` was an experimental
feature for Dart and had
conceptual performance problems,
as setting up observables is slow.
Use `OnPush` instead.
2016-03-01 13:28:10 -08:00
d900f5c075 chore(tests): lengthen timeout for templateUrl test
This was flaking on Travis occasionally because the TestComponentBuilder
is actually doing an XHR, and it was slow on the Edge browser.

Closes #7293
2016-03-01 21:01:56 +00:00
391a9edabb chore(build): use Chromium in Travis for JS tests 2016-03-01 11:24:44 -08:00
28a78117eb refactor(dart/transform): Migrates tests to use package:test
Our transformer unit tests currently use package:guinness, which uses
package:unittest under the covers. package:unittest has been updated and
renamed package:test, so for simplicity migrate test to use package:test
syntax.
2016-03-01 19:20:06 +00:00
eeb594c010 fix(dart/payload): Fix runtime error in hello_world payload app
The hello_world app used to measure Dart payload size was broken by a
change in
7ae23adaff.

This breakage does not materially affect the size of the generated code,
(before fix: 298819, after fix: 298825), and since it was a runtime
error it was not noticed & not a problem.

Update the app to work again.

Closes #7358
2016-03-01 18:51:12 +00:00
0bb10d6bb6 feat(transformers): makes the map of resolved identifiers configurable
Closes #7359
2016-03-01 17:57:19 +00:00
59629a0801 feat(i18n): added i18nPlural and i18nSelect pipes
Closes #7268
2016-03-01 16:40:48 +00:00
b5e6319fa9 feat(core): add more debug APIs to inspect the application form a browser
Adds `window.getAllAngularRootElements()`
Adds `ng.coreTokens.ApplicationRef`
Adds `ng.coreTokens.Ngzone`

Closes #7045
Closes #7161
2016-03-01 16:01:28 +00:00
c9a3df970b feat(di): drop support for injecting types with generics in Dart
BREAKING CHANGE:
In Dart we used to support injecting types with generics. As this feature is hard to implement with the upcoming codegen we are dropping it.

Merge cl/115454020 in G3 with this change.
Closes #7262
2016-03-01 05:43:49 +00:00
f72f137261 ci(dart): Uncomment dart.dev build and make it required
Workaround for https://github.com/dart-lang/dartdoc/issues/1099: remove
the `--input=.` parameter to `dartdoc`.

Closes #6823, #6410

Closes #6958
2016-03-01 01:21:27 +00:00
ee3c580e88 fix(transformers): replace an error with a warning when cannot resolve a symbol 2016-02-29 16:03:13 -08:00
05c185a7b1 fix(transformers): record reflection info about abstract classes
Closes #7347
2016-02-29 22:57:22 +00:00
b47f80ec76 fix(Router): Query strings are copied for HashLocationStrategy
b/27210802 P1

Closes #7298
2016-02-29 18:44:56 +00:00
ebd438ff5e fix(change_detection): allow to destroy OnPush components inside of a host event.
Closes #7192
2016-02-29 18:44:13 +00:00
331b9c1317 fix(transformers): special case types some built-in types, so they can be resolved 2016-02-29 10:34:34 -08:00
4a93f58b8b fix(web_worker): wait for bindings in kitchen sink spec 2016-02-26 10:34:32 -08:00
ebe531bf92 feat(transformers): collect data needed for the template compiler
Closes #7299
2016-02-26 17:56:40 +00:00
1779caf5f8 fix(core): support ngFor that has an ngIf as last node
Fixes #6304
Closes #6878
2016-02-25 23:42:17 +00:00
6ef2121e6a feat(pipes): add ReplacePipe for string manipulation
add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.

feat(pipes): add ReplacePipe for string manipulation

add commonly used pipe that is missing  from framework.
2016-02-25 22:56:13 +00:00
38cb526f60 feat(forms/validators): pattern validator
Adding static pattern validation method to Validators

Adding a directive for the pattern validator

Applying clang-format rules to modified files

Updating public api spec for new pattern validator

Adding pattern validator to public api guard tool

For #5411

Closes #5561
2016-02-25 22:39:15 +00:00
f6a8d04c32 fix(web_workers): make waitForElementText function more stable 2016-02-25 14:28:20 -08:00
4b3b5d7c53 cleanup(build): fix jsserve not to throw 2016-02-25 13:39:02 -08:00
abff302e52 chore(tests): fix broken test from using the wrong xit
Also, run clang-format.
2016-02-25 10:50:59 -08:00
e1f6679c75 chore: make incremental dart tests work again 2016-02-25 10:26:11 -08:00
aaafdf03ce test(testing): add a test to ensure fakeAsync works with angular2/testing 2016-02-25 10:22:18 -08:00
ee298baa1b test(router): disable a flaky test 2016-02-25 10:21:53 -08:00
d1abada5b7 build(travis): do not cache npm modules 2016-02-24 17:56:55 -08:00
ab36ea097b fix(differ): clean up stale identity change refs
Closes #7193
2016-02-24 17:56:55 -08:00
8bb66a5eb3 chore: noImplicitAny fixes 2016-02-24 15:29:00 -08:00
cfc1e56dd8 refact(angular1_router): make the $$router binding one-time
This binding is never going to change so we can make it a one-time binding

Closes #6978
2016-02-24 21:15:34 +00:00
a1c3be21ec fix(angular1_router): rename $route service to $rootRouter
The singleton service that represents the top level router was called
`$router` but this is confusing since there are actually lots of routers,
which depend upon where you are in the DOM. This is similar to the situation
with scopes.

This commit clarifies this singleton by renaming it to `$rootRouter`.

BREAKING CHANGE:

The `$router` injectable service has been renamed to `$rootRouter`
2016-02-24 21:15:34 +00:00
edad8e3f56 fix(angular1_router): rename router component binding to $router
The current router is passed to the current component via a binding.
To indicate that this is an angular provided object, this commit
renames the binding to `$router`.

BREAKING CHANGE:

The recently added binding of the current router to the current component
has been renamed from `router` to `$router`.

So now the recommended set up for your bindings in your routed component
is:

```js
{
  ...
  bindings: {
    $router: '<'
  }
}
```
2016-02-24 21:15:34 +00:00
d4a4d81173 fix(angular1_router): support templateUrl components 2016-02-24 21:15:34 +00:00
e7470d557d feat(core): Add QueryList.forEach to public api. 2016-02-19 19:23:46 -05:00
b634a25ae0 feat(core): Add QueryList#forEach 2016-02-19 19:23:46 -05:00
c1a0af514f feat(test): add withProviders for per test providers
Closes #5128
2016-02-19 19:23:46 -05:00
c6afea61f1 fix(DomRenderer): correctly handle namespaced attributes 2016-02-19 19:23:46 -05:00
ce10fe92b2 chore(travis): remove problematic chromebeta target for now 2016-02-19 10:43:59 -08:00
b81b1fb81c revert: fix(change_detection): allow to destroy OnPush components inside of a host event
This reverts commit 280b86ec55.
2016-02-19 10:34:03 -08:00
280b86ec55 fix(change_detection): allow to destroy OnPush components inside of a host event. 2016-02-18 17:54:24 -08:00
2f5a2ba671 docs(changelog): update changelog to beta.7 2016-02-18 13:28:10 -08:00
c45ec6f1be chore(release): bump version to beta.7 2016-02-18 13:28:08 -08:00
530470e0ce chore(travis): add an integration hook for the angular hubot daemon 2016-02-17 16:38:42 -08:00
ce72ccf9e8 build(npm): bump zone.js version to 0.15.5 2016-02-17 16:28:50 -08:00
46d9c87ddc build(package): bump rxjs to 5.0.0-beta.2
Closes #7001
2016-02-17 16:28:50 -08:00
d736c31fea test(material): disable problematic e2e test
LGTM from Victor and Jeff in person :)
2016-02-17 16:18:33 -08:00
a7e9bc97f6 ci(typescript): add typescript_next build
Install typescript@next before build.js and test.typings.
Restore the regular version before travis caches node_modules/.

Fixes #6368
2016-02-16 17:29:29 -08:00
265703b950 fix(typing): Remove re-export of the Promise built-in type.
Instead, ts2dart can add the 'dart:async' import whenever
Promise is used.

Fixes #6468
2016-02-12 20:45:41 -08:00
ae275fa4e4 chore(ts2dart): update ts2dart to 0.7.24 2016-02-12 20:45:35 -08:00
3478d5d450 fix(angular_1_router): Added DI string tokens
Closes #4269

Closes #7031
2016-02-12 21:15:34 +00:00
e72dc16dbe docs(changelog): update changelog to beta.6 2016-02-11 16:03:00 -08:00
40a043275d chore(release): bump version to beta.6 2016-02-11 15:59:34 -08:00
f161b5cc28 chore(zone.js): update to 0.5.14 2016-02-11 14:39:41 -08:00
117d57e121 Revert "chore(zone.js) : update to 0.5.14"
This reverts commit 3dcce706fd.
2016-02-11 14:38:06 -08:00
3dcce706fd chore(zone.js) : update to 0.5.14 2016-02-11 14:15:59 -08:00
efb89b83e1 Revert "fix(DomRenderer): correctly handle namespaced attributes"
This reverts commit 61cf499b0b.
2016-02-11 13:44:16 -08:00
3d96c2337f Revert "feat(svg): Provide support for SVG foreignObject by adding xhtml namespace"
This reverts commit eb688f2c8e.
2016-02-11 13:39:02 -08:00
19cfb4eb12 fix(build): publish typings directory to our npm snapshot branch 2016-02-11 11:35:43 -08:00
3d715a2f7b fix(typings): publish es6 typings rather than postinstall.
Despite local testing, multiple users failed to run the postinstall to install typings.
Instead, we can distribute the typings we installed locally.

This is an alternative to #7003.
This also reverts rxjs to beta.1 since we have errors using beta.2, being addressed
in #7001.

Fixes #7000
2016-02-11 11:04:42 -08:00
c7261c295c docs(changelog): update change log to beta.5 2016-02-10 16:31:01 -08:00
1a26f8edd6 chore(release): bump version to beta.5 2016-02-10 16:30:18 -08:00
fc887774da fix(release): need to depend on latest rxjs and zone.js
The version in our package.json gets copied to the one we publish, and users need the latest of these.
2016-02-10 16:29:58 -08:00
7cbf88a691 docs(changelog): update change log to beta.4 2016-02-10 16:04:17 -08:00
1cb1c139cf chore(release): bump version to beta.4 2016-02-10 16:04:17 -08:00
1fd924f7d5 refactor(dart/transform): Simplify deferred rewriting
Simplify the DeferredRewriting and move package:quiver to a dev
dependency.

Closes #6994
2016-02-10 23:43:57 +00:00
eb688f2c8e feat(svg): Provide support for SVG foreignObject by adding xhtml namespace
Closes #6192
2016-02-10 23:23:34 +00:00
61cf499b0b fix(DomRenderer): correctly handle namespaced attributes
Closes #6363
2016-02-10 22:34:13 +00:00
f1f5b45361 feat(typings): install es6-shim typings to a location users can reference.
This makes the upgrade to beta.4 as simple as adding one reference tag, only when --target=es5
Implements option 3 from https://docs.google.com/document/d/1vgepQPkuHS4P3rzANQpoMIDIXe0Rl9Z2QyTtb8dpMoI/edit
2016-02-10 14:13:27 -08:00
50548fb565 fix(forms): use strict runtimeType checks instead of instanceof
Currently, validators extending built-in validators are treated as built-in.
This can result in an error when both a real built-in validator and a custom one are applied to the same element.

Closes #6981
2016-02-10 09:23:59 -08:00
8f47aa3530 fix(forms): add RadioButtonValueAccessor to the list of default value accessors 2016-02-09 15:28:08 -08:00
df7885c9f5 fix(router): Added route data to normalized async route
Closes #6802
2016-02-09 22:08:45 +00:00
0f10624b08 fix(ngFor): update view locals if identity changes
Closes #6923
2016-02-09 22:06:06 +00:00
6f1ef33e32 fix(router): fix url path for star segment in path recognizer
Url path of star segments should equal the original path.

If you register the route `/app/*location` and invoke a url like `/app/foo/bar`
the PathRecognizer should return a url path equal to the invoked url.

Before this patch, everything after `foo` was ignored, which resulted in a
redirect to `/app/foo` which was probably not intended (at least in the angular
1.5 component router).

Closes #6976
2016-02-09 21:45:06 +00:00
231773ea76 fix(compiler): use event names for matching directives
Closes #6870
2016-02-09 13:16:08 -08:00
e725542703 fix(forms): add support for radio buttons
Closes #6877
2016-02-09 19:47:50 +00:00
2337469753 style(angular1_router): license year updated
Closes #6219
2016-02-08 17:21:00 -08:00
55122cd57a fix(angular1-router): add missing wrapper methods
Closes #6763
Closes #6861
Closes #6861
2016-02-08 17:19:50 -08:00
7e0f02f96e fix(upgrade): fix infinite $rootScope.$digest()
Fixes #6385
Closes #6386
2016-02-08 17:18:52 -08:00
e7ad03cba6 fix(core): add detail to dehydrated detector exception
- at least I know what component is causing the error with this. without it the exception is so generic that it's not useful.

Closes #6939
2016-02-08 17:17:37 -08:00
74be3d3fde fix(core): mute mode printing in console in prod mode
Closes #6873
2016-02-08 17:16:19 -08:00
a15ca23469 refactor(mock): update variable names in directive_resolver_mock.ts
Closes #5056
2016-02-08 17:11:43 -08:00
de77700da0 fix(di): throw if a token uses more than 20 dependencies.
Fixes #6690
Closes #6869
2016-02-08 16:21:57 -08:00
e73fee7156 fix(router): fixed the location wrapper for angular1
In angular2 `Location.path()` returns the complete path including query string. In angular1 the query parameters are missing. Similar to this `Location.go` does accept two parameters (path *and query*).

Closes #6943
2016-02-08 16:18:26 -08:00
72ab35bceb test(angular1_router): test that location handles query strings
See 6698
2016-02-08 16:18:13 -08:00
0f22dce036 feat(angular1_router): allow component to bind to router 2016-02-08 16:18:13 -08:00
c6036435f0 fix(router): don't prepend / unnecessarily to Location paths
Closes #6729
Closes #5502
2016-02-08 16:18:13 -08:00
d86be245b8 fix(angular1-router): add support for using the component helper
In Angular 1.5 there is a new helper method for creating component directives.
See https://docs.angularjs.org/guide/component for more information about components.

These kind of directives only match the `E` element form and the previously component
router only created HTML that matched directives that matched the `A` attribute form.

This commit changes the `<ng-outlet>` directive so that it generates custom HTML
elements rather divs with custom attributes to trigger the relevant component to
appear in the DOM.

Going forward, Angular 1.5 users are encouraged to create their router components
using the following style:

```
myModule.componnet('component-name', {
  // component definition object
});
```

Closes angular/angular.js#13860
Closes #6076
Closes #5278

BREAKING CHANGE:

The component router now creates custom element HTML rather than custom attribute
HTML, in order to create a new component. So rather than

```html
<div custom-component></div>
```

it now creates

```html
<custom-component></custom-component>
```

If you defined you router components using the `directive()` helper and
specified the `restrict` properties such that element matching was not allowed,
e.g. `restrict: 'A'` then these components will no longer be instantiated
by the component router and the outlet will be empty.

The fix is to include `E` in the `restrict` property.

`restrict: 'EA'`

Note that this does not affect directives that did not specify the `restrict`
property as the default for this property is already `EA`.
2016-02-08 16:18:13 -08:00
a26053d3ff docs(cheatsheet): fix Dart cheatsheet
Also deletes an extraneous period from the JS cheatsheet.

Closes #5936
2016-02-08 15:58:22 -08:00
24d5b665e1 docs(HostBindingMetadata): Removed brackets from host bindings in HostBindingsMetadata example
Closes #6941
2016-02-08 15:55:49 -08:00
aa98fad338 docs: fix typo in 01_templates.md
Replace `an` with `a`

Closes #6842
2016-02-08 15:52:30 -08:00
9cb6dbbbab docs: fixed typo in documentation
Closes #6842
2016-02-08 15:30:15 -08:00
e21718faa9 docs(router): Updated inconsistencies in router docs
Closes #6805
2016-02-08 22:31:04 +00:00
b0f7d59e64 revert: chore: update the version of ts2dart
This reverts commit 22929a1671.

This commits makes our build red without the other commit that was already reverted.

More info at: https://github.com/angular/angular/pull/6825#issuecomment-181592303
2016-02-08 14:13:00 -08:00
b86829f492 revert: feat(transformers): collect information about di dependencies and providers
This reverts commit 86c40f8474.

Reason: new issues were discovered during the g3sync. @vsavkin is working on fixing them.
2016-02-08 12:15:03 -08:00
22929a1671 chore: update the version of ts2dart
Closes #6804
2016-02-05 21:56:33 +00:00
86c40f8474 feat(transformers): collect information about di dependencies and providers 2016-02-05 21:56:33 +00:00
16b521794c fix(build): don't try to copy .d.ts files into the npm distro
Fixes #6921
2016-02-05 11:53:15 -08:00
2a70f4e4c7 fix(typings): Don't expose typing dependencies to users.
This resolves Duplicate Identifier issues seen by many users,
at the expense of more typings installation required in some
cases.

Removes the quickstart hack of placing all needed dependencies
typings files in our distribution. Removes dependencies on
nodejs from angular2/core.

Fixes #5973
Fixes #5807
Fixes #6266

Angular now depends on es6-promise and es6-collections
(and a handful of manual typings) rather than all of es6-shim.

Fixes #5242

We previously had an undocumented breaking change, this is now
documented in this commit.

Fixes #6817

BREAKING CHANGE:

Transitive typings are no longer included in the distribution.
You may need to install typings in your project using
http://github.com/typings/typings

Users now must rely on getting typings from:
- one of the peerDependencies, such as rxjs, which exposes
  typings via the moduleResolution=node mechanism.
  (see https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages)
  This happens automatically.
- Using --target ES5 now requires manual installation of
  es6-promise and es6-collections typings.
- Using some angular APIs may introduce a dependency on eg. nodejs
  or jasmine, and those typings need manual installation as well.

Closes #6267
2016-02-04 22:42:40 +00:00
2f31c4c1c5 chore(typings): use mainline DefinitelyTyped repo rather than a fork.
The upstream Jasmine typings don't define a type for the global
object with Jasmine methods polluting it, so just use any.

Also zone.js has a different name upstream.
2016-02-04 22:42:40 +00:00
1435763383 chore(deps): update ts2dart and zone.js 2016-02-04 22:42:40 +00:00
05238df89b docs(changelog): add missing breaking change for beta.3 2016-02-03 11:43:17 -08:00
772d60d9fe docs(changelog): changelog for beta.3 2016-02-03 10:36:06 -08:00
24086bf0bb chore(release): bump version to beta.3 2016-02-03 10:36:06 -08:00
9b0e10e9a7 fix(compiler): fix interpolation regexp
- Fix the interpolation regexp to match newline characters (i.e. `\n` and `\r`)

Closes #6056
2016-02-03 15:21:55 +00:00
995a9e0cf8 fix(router): fix incorrect url param value coercion of 1 to true
seriliazeParams is coercing a value of 1 to true, which causes the value to be completey dropped.
Change the test from double equals to triple equals to prevent this from happening.

Closes #5346

Closes #6286
2016-02-03 15:00:24 +00:00
b55f1764b5 fix(Headers): serializable toJSON
fixes #6073

Closes #6714
2016-02-03 14:03:01 +00:00
5e9daed2e8 docs(http.ts): Fix MockBackend examples using backend.connections observer
Properly format observer examples.
2016-02-03 05:58:40 -08:00
aa8c5aa2e2 docs(http): fix example usage of MockBackend 2016-02-03 05:57:08 -08:00
f2c7946cca chore(http): make all typings explicit 2016-02-03 05:31:40 -08:00
da1fcfd820 fix(WebWorkers): Fix flaky WebWorker test
Closes #6851
2016-02-03 05:30:11 -08:00
dbeff6f548 style(ReflectionCapabilities) _zipTypesAndAnnotations, not _zipTypesAndAnnotaions
I was stepping through the Reflector and came across this little guy.

Closes #6535
2016-02-03 03:57:06 +00:00
26e60d658a fix(async): handle synchronous initial value in async pipe
Closes #5996
2016-02-03 03:56:52 +00:00
c2ceb7fba4 fix(Validators): fix Validators.required marking number zero as invalid
Closes #6617
2016-02-03 03:34:42 +00:00
4bfe49cd42 docs(core): update QueryList's onChange to changes.subscribe 2016-02-02 19:23:03 -08:00
cee2318110 feat(ngFor): add custom trackBy function support
Make it possible to track items in iterables in custom ways (e.g. by ID or index), rather than simply by identity.

Closes #6779
2016-02-03 01:03:31 +00:00
cfef76f683 refactor(dart/transform): Error in name convert funcs on unexpected input
Issue raised in PR #6745.
Previously, the transformer name conversion functions could return the
input string on unexpected input, which is almost certainly an error.

`throw` in this case instead, so we know early that something has likely
gone wrong.

Closes #6753
2016-02-02 23:46:27 +00:00
f56df65d48 perf(dart/transform): Only process deferred libs when necessary
Previously, every .dart file in a package was processed to ensure proper
initialization of deferred loaded libraries.

Update the transformer to avoid processing libraries which we know do
not import any deferred libraries.

Closes #6745
2016-02-02 23:06:36 +00:00
3a40cd79f0 build(router): make the build.js script portable to g3 2016-02-02 13:58:51 -08:00
6acc99729c build(router): refactor angular1 router build script 2016-02-02 13:58:51 -08:00
99e6500a2d feat(upgrade): support bindToController with binding definitions
Since angular 1.4 we can also pass controller bindings directly to bindToController, making this syntax more convenient

Closes #4784
2016-02-02 13:27:22 -08:00
5c782d6ba8 Typo: Hash_consing wiki link wrong Markdown syntax 2016-02-02 11:53:30 -08:00
4e43d6f769 docs(http): Added base request options for test example 2016-02-02 11:51:42 -08:00
3529ee9973 docs(cheatsheet): change as to name in routing section 2016-02-02 11:43:29 -08:00
29aa6a6c1c change event to use camel case 2016-02-02 11:42:26 -08:00
7918f3c1fc docs(changelog): fix header for 2.0.0-beta.0 2016-02-02 11:39:23 -08:00
2f4e176054 docs(developer): add linting instructions 2016-02-02 11:34:00 -08:00
d4565fdaf3 Update CHANGELOG.md
Fixed phrasing on breaking changes. It's just one breaking change so just requires one bullet point to explain the before/after.
2016-02-02 11:24:35 -08:00
2a302aa73a fix(docs): rxjs/add/operators/map -> rxjs/add/operator/map (no 's').
Was it with 's' before?
2016-02-02 11:22:10 -08:00
31b819e9c2 test: fix transformer tests 2016-02-02 10:21:40 -08:00
27daeaff5e fix(karma): fix running karma via gulp
As described below, the karma server showdown process can crash, if the done() function, provided
by gulp is referenced directly instead of wrapped in a closure function
http://stackoverflow.com/questions/26614738/issue-running-karma-task-from-gulp

Reformat the gulpfile.js

Squashing the two commits
2016-02-02 06:22:53 -08:00
3e9b532409 fix(dart/transform): Handle edge cases in ReflectionRemover
Handle some cases which would previously result in broken code.

- Importing bootstrap.dart deferred
- Using combinators when importing bootstrap.dart
- Importing bootstrap.dart with a prefix

Closes #6749
2016-02-01 15:17:44 -08:00
c5aa6d17ef docs: Fix small formatting issue in changeling
Closes #6660
2016-02-01 15:16:35 -08:00
e480b0798e docs: Kebab-case does not work. Change to camelCase.
Closes #6630
2016-02-01 15:15:46 -08:00
8a645d5e44 chore(zone.js): update to 0.5.11
Closes #6751
2016-02-01 21:53:42 +00:00
321193889f fix(zone): correct incorrect calls to zone 2016-02-01 21:53:42 +00:00
566d3ede04 test(dart/transform): Update unit tests to expect code in <file>.template.dart
Closes #6711
2016-02-01 21:21:38 +00:00
8c36aa866a feat(dart/transform): Generate all code into <file>.template.dart
Previously, we generated the code to initialize the reflector into the
<file>.ng_deps.dart and the compiled template and change detector code
into <file>.template.dart.

Update the transformer to generate all code into <file>.template.dart to
avoid the additional HTTP requests necessary when debugging
applications in Dartium.
2016-02-01 21:21:37 +00:00
ed2dbf2db7 ci(dart): comment out dart.dev build
See #6823
2016-02-01 12:53:27 -08:00
36a0e04604 fix(circle): pre-dependencies npm install npm
Fixes #6777
2016-02-01 11:26:25 -08:00
8867afdaab fix(build): Revert "build(dart): Make Dart dev build required"
This reverts commit a199772508.
2016-02-01 11:17:57 -08:00
a199772508 build(dart): Make Dart dev build required
Previously, we allowed the Dart dev build to fail presubmit tests.
Make it a required build from now on.

Closes #6410
2016-02-01 07:12:40 -08:00
b008f542fa chore(changelog): improve breaking change description for beta.2 2016-01-30 19:45:17 -08:00
a78dcfa5f3 chore(tests): fix broken linker integration test and fix DebugNode export
Fixes two small issues introduced with pr #6555
2016-01-29 14:29:49 -08:00
e1bf3d33f8 feat(debug): replace DebugElement with new Debug DOM
Now, using `ng.probe(element)` in the browser console returns
a DebugElement when in dev mode.

`ComponentFixture#debugElement` also returns a new DebugElement.

Breaking Change:

This is a breaking change for unit tests. The API for the DebugElement
has changed. Now, there is a DebugElement or DebugNode for every node
in the DOM, not only nodes with an ElementRef. `componentViewChildren` is
removed, and `childNodes` is a list of ElementNodes corresponding to every
child in the DOM. `query` no longer takes a scope parameter, since
the entire rendered DOM is included in the `childNodes`.

Before:

```
componentFixture.debugElement.componentViewChildren[0];
```

After
```
// Depending on the DOM structure of your component, the
// index may have changed or the first component child
// may be a sub-child.
componentFixture.debugElement.children[0];
```

Before:

```
debugElement.query(By.css('div'), Scope.all());
```

After:

```
debugElement.query(By.css('div'));
```

Before:

```
componentFixture.debugElement.elementRef;
```

After:

```
componentFixture.elementRef;
```
2016-01-29 11:28:10 -08:00
ae7d2ab515 fix(bundle): add angular2/platform/testing/browser to SystemJS testing bundle 2016-01-29 13:58:06 +01:00
c6adbf602c fix(query): don’t cross component boundaries
Closes #6759
2016-01-28 23:38:40 +00:00
1f7a41c963 fix(query): update view queries that query directives in embedded views
Fixes #6747
2016-01-28 14:40:53 -08:00
f4f614f3a9 docs(changelog): update change log to beta.2 2016-01-28 12:01:18 -08:00
94139c351f chore(release): bump version to beta.2 2016-01-28 12:01:18 -08:00
fc5b128b43 chore(ci): deflake test and turn on saucelabs_required
Fixes #6725

Closes #6733
2016-01-28 03:18:08 +00:00
68a799af2e tools: implement public api spec
Closes #6309
2016-01-27 21:19:05 +00:00
16d9c60a0e chore(circleci): use a github token when running tsd
Also increase the heap size limit as a workaround for
https://github.com/angular/angular/issues/5229

Fixes #6602
2016-01-27 13:16:57 -08:00
c0b5e7a672 chore(ci): turn off saucelabs_required
Reenable once #6723 fixed.
2016-01-27 11:52:32 -08:00
6932b29acb chore(ci): bump up the error count for dart DDC. 2016-01-27 11:19:56 -08:00
c2a38c05aa fix(WebWorkers): Add support for transitionend events.
Closes #6649
2016-01-26 21:09:01 -08:00
8bea667a0b feat(WebWorker): Add Router Support for WebWorker Apps
Closes #3563.
2016-01-26 21:07:12 -08:00
800c8f196f chore(ddc): make DDC build non-experimental 2016-01-26 21:04:34 -08:00
42231f5719 feat(change_detection): allow all legal programs in the dev mode
BEFORE:

The following would throw in the dev mode because `f` would return a new array when called by checkNoChanges.

@Component({
  template: `
    {{f()}}
  `
})
class A {
  f() { return [1]; }
}

AFTER:

The checkNoChanges function compares only primitives types for equality, and deeply compares iterables. Other objects cannot cause checkNoChanges to throw. This means that the dev mode would never fail given a legal program, but may allow some illegal programs.
2016-01-26 21:01:19 -08:00
1137 changed files with 46477 additions and 36973 deletions

16
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,16 @@
**IMPORTANT**: This repository's issues are reserved for feature requests and bug reports. Do not submit support requests here, see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question.
**Steps to reproduce and a minimal demo of the problem**
_Use https://plnkr.co or similar -- try this template as a starting point: http://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5_
_What steps should we try in your demo to see the problem?_
**Current behavior**
**Expected/desired behavior**
**Other information**

24
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,24 @@
* **Please check if the PR fulfills these requirements**
- [ ] The commit message follows our guidelines: https://github.com/angular/angular/blob/master/CONTRIBUTING.md#commit-message-format
- [ ] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)
* **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...)
* **What is the current behavior?** (You can also link to an open issue here)
* **What is the new behavior (if this is a feature change)?**
* **Does this PR introduce a breaking change?** (What changes might users need to make in their application due to this PR?)
* **Other information**:

1
.gitignore vendored
View File

@ -22,6 +22,7 @@ tmp
*.js.map
# Or type definitions we mirror from github
# (NB: these lines are removed in publish-build-artifacts.sh)
**/typings/**/*.d.ts
**/typings/tsd.cached.json

View File

@ -1,7 +1,7 @@
language: node_js
sudo: false
node_js:
- '5.4.1'
- '5.4.1'
branches:
except:
@ -9,73 +9,91 @@ branches:
cache:
directories:
- node_modules
- $HOME/.pub-cache
- $HOME/.chrome/chromium
before_cache:
# Undo the pollution of the typescript_next build before the cache is primed for future use
- if [[ "$MODE" == "typescript_next" ]]; then npm install typescript; fi
env:
global:
- KARMA_BROWSERS=DartiumWithWebPlatform
- E2E_BROWSERS=Dartium
- LOGS_DIR=/tmp/angular-build/logs
- SAUCE_USERNAME=angular-ci
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
- BROWSER_STACK_USERNAME=angularteam1
- BROWSER_STACK_ACCESS_KEY=BWCd4SynLzdDcv8xtzsB
- ARCH=linux-x64
- DART_DEV_VERSION=latest
- DART_STABLE_VERSION=latest
# Token for tsd to increase github rate limit
# See https://github.com/DefinitelyTyped/tsd#tsdrc
# This does not use http://docs.travis-ci.com/user/environment-variables/#Secure-Variables
# because those are not visible for pull requests, and those should also be reliable.
# This SSO token belongs to github account angular-github-ratelimit-token which has no access
# (password is in Valentine)
- TSDRC='{"token":"ef474500309daea53d5991b3079159a29520a40b"}'
# GITHUB_TOKEN_ANGULAR
- secure: "fq/U7VDMWO8O8SnAQkdbkoSe2X92PVqg4d044HmRYVmcf6YbO48+xeGJ8yOk0pCBwl3ISO4Q2ot0x546kxfiYBuHkZetlngZxZCtQiFT9kyId8ZKcYdXaIW9OVdw3Gh3tQyUwDucfkVhqcs52D6NZjyE2aWZ4/d1V4kWRO/LMgo="
# Use newer verison of GCC to that is required to compile native npm modules for Node v4+ on Ubuntu Precise
# more info: https://docs.travis-ci.com/user/languages/javascript-with-nodejs#Node.js-v4-(or-io.js-v3)-compiler-requirements
- CXX=g++-4.8
- KARMA_DART_BROWSERS=DartiumWithWebPlatform
# No sandbox mode is needed for Chromium in Travis, it crashes otherwise: https://sites.google.com/a/chromium.org/chromedriver/help/chrome-doesn-t-start
- KARMA_JS_BROWSERS=ChromeNoSandbox
- E2E_BROWSERS=ChromeOnTravis
- LOGS_DIR=/tmp/angular-build/logs
- SAUCE_USERNAME=angular-ci
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
- BROWSER_STACK_USERNAME=angularteam1
- BROWSER_STACK_ACCESS_KEY=BWCd4SynLzdDcv8xtzsB
- ARCH=linux-x64
- DART_DEV_VERSION=latest
- DART_STABLE_VERSION=latest
- DART_CHANNEL=stable
- DART_VERSION=$DART_STABLE_VERSION
# Token for tsd to increase github rate limit
# See https://github.com/DefinitelyTyped/tsd#tsdrc
# This does not use http://docs.travis-ci.com/user/environment-variables/#Secure-Variables
# because those are not visible for pull requests, and those should also be reliable.
# This SSO token belongs to github account angular-github-ratelimit-token which has no access
# (password is in Valentine)
- TSDRC='{"token":"ef474500309daea53d5991b3079159a29520a40b"}'
# GITHUB_TOKEN_ANGULAR
- secure: "fq/U7VDMWO8O8SnAQkdbkoSe2X92PVqg4d044HmRYVmcf6YbO48+xeGJ8yOk0pCBwl3ISO4Q2ot0x546kxfiYBuHkZetlngZxZCtQiFT9kyId8ZKcYdXaIW9OVdw3Gh3tQyUwDucfkVhqcs52D6NZjyE2aWZ4/d1V4kWRO/LMgo="
matrix:
# Order: a slower build first, so that we don't occupy an idle travis worker waiting for others to complete.
- MODE=dart DART_CHANNEL=stable DART_VERSION=$DART_STABLE_VERSION
- MODE=dart DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
- MODE=saucelabs_required DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
- MODE=browserstack_required DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
- MODE=saucelabs_optional DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
- MODE=browserstack_optional DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
- MODE=dart_experimental DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
- MODE=js DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
- MODE=router DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
- MODE=build_only DART_CHANNEL=stable DART_VERSION=$DART_STABLE_VERSION
- MODE=lint DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION
- MODE=payload DART_CHANNEL=stable DART_VERSION=$DART_STABLE_VERSION
- MODE=dart
- MODE=dart DART_CHANNEL=dev
- MODE=saucelabs_required
- MODE=browserstack_required
- MODE=saucelabs_optional
- MODE=browserstack_optional
- MODE=dart_ddc
- MODE=js
- MODE=router
- MODE=build_only
- MODE=typescript_next
- MODE=lint
matrix:
allow_failures:
- env: "MODE=saucelabs_optional DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION"
- env: "MODE=browserstack_optional DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION"
- env: "MODE=dart_experimental DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION"
# TODO(alxhub): remove when dartdoc #1039 is in dev channel
- env: "MODE=dart DART_CHANNEL=dev DART_VERSION=$DART_DEV_VERSION"
- env: "MODE=saucelabs_optional"
- env: "MODE=browserstack_optional"
addons:
firefox: "38.0"
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
before_install:
- npm install -g npm@3.5.3
- node tools/analytics/build-analytics start ci job
- node tools/analytics/build-analytics start ci before_install
- echo ${TSDRC} > .tsdrc
- export DISPLAY=:99.0
- export GIT_SHA=$(git rev-parse HEAD)
- ./scripts/ci/init_android.sh
- ./scripts/ci/install_dart.sh ${DART_CHANNEL} ${DART_VERSION} ${ARCH}
- sh -e /etc/init.d/xvfb start
- if [[ -e SKIP_TRAVIS_TESTS ]]; then { cat SKIP_TRAVIS_TESTS ; exit 0; } fi
- '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_BRANCH}" = "master" ] && SAUCE_USERNAME="angular2-ci" && SAUCE_ACCESS_KEY="693ebc16208a-0b5b-1614-8d66-a2662f4e" || true'
- node tools/analytics/build-analytics success ci before_install
- node tools/analytics/build-analytics start ci job
- node tools/analytics/build-analytics start ci before_install
- echo ${TSDRC} > .tsdrc
- export CHROME_BIN=$HOME/.chrome/chromium/chrome-linux/chrome
- export DISPLAY=:99.0
- export GIT_SHA=$(git rev-parse HEAD)
- ./scripts/ci/init_android.sh
- sh -e /etc/init.d/xvfb start
# Use a separate SauseLabs account for upstream/master builds in order for Sauce to create a badge representing the status of just upstream/master
- '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_BRANCH}" = "master" ] && SAUCE_USERNAME="angular2-ci" && SAUCE_ACCESS_KEY="693ebc16208a-0b5b-1614-8d66-a2662f4e" || true'
- node tools/analytics/build-analytics success ci before_install
install:
- node tools/analytics/build-analytics start ci install
# Check the size of caches
# Install version of npm that we are locked against
- npm install -g npm@3.5.3
# Install version of Chromium that we are locked against
- ./scripts/ci/install_chromium.sh
# Install version of Dart based on the matrix build variables
- ./scripts/ci/install_dart.sh ${DART_CHANNEL} ${DART_VERSION} ${ARCH}
# Print the size of caches to ease debugging
- du -sh ./node_modules || true
# Install npm dependecies
# check-node-modules will exit(1) if we don't need to install
@ -84,33 +102,33 @@ install:
- node tools/analytics/build-analytics success ci install
before_script:
- node tools/analytics/build-analytics start ci before_script
- mkdir -p $LOGS_DIR
- ./scripts/ci/presubmit-queue-setup.sh
- node tools/analytics/build-analytics success ci before_script
- node tools/analytics/build-analytics start ci before_script
- mkdir -p $LOGS_DIR
- ./scripts/ci/presubmit-queue-setup.sh
- node tools/analytics/build-analytics success ci before_script
script:
- node tools/analytics/build-analytics start ci script
- ./scripts/ci/build_and_test.sh ${MODE}
- node tools/analytics/build-analytics success ci script
- node tools/analytics/build-analytics start ci script
- ./scripts/ci/build_and_test.sh ${MODE}
- node tools/analytics/build-analytics success ci script
after_script:
- node tools/analytics/build-analytics start ci after_script
- ./scripts/ci/print-logs.sh
- ./scripts/ci/after-script.sh
- ./scripts/publish/publish-build-artifacts.sh
- node tools/analytics/build-analytics success ci after_script
- if [[ $TRAVIS_TEST_RESULT -eq 0 ]]; then node tools/analytics/build-analytics success ci job; else node tools/analytics/build-analytics error ci job; fi
- node tools/analytics/build-analytics start ci after_script
- ./scripts/ci/print-logs.sh
- ./scripts/ci/after-script.sh
- ./scripts/publish/publish-build-artifacts.sh
- node tools/analytics/build-analytics success ci after_script
- tools/analytics/build-analytics $TRAVIS_TEST_RESULT ci job
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/1ef62e23078036f9cee4
# trigger Buildtime Trend Service to parse Travis CI log
- https://buildtimetrend.herokuapp.com/travis
- https://webhooks.gitter.im/e/1ef62e23078036f9cee4
# trigger Buildtime Trend Service to parse Travis CI log
- https://buildtimetrend.herokuapp.com/travis
- http://104.197.9.155:8484/hubot/travis/activity
on_success: always # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: false # default: false
on_start: never # default: never
slack:
secure: EP4MzZ8JMyNQJ4S3cd5LEPWSMjC7ZRdzt3veelDiOeorJ6GwZfCDHncR+4BahDzQAuqyE/yNpZqaLbwRWloDi15qIUsm09vgl/1IyNky1Sqc6lEknhzIXpWSalo4/T9ZP8w870EoDvM/UO+LCV99R3wS8Nm9o99eLoWVb2HIUu0=

View File

@ -1,3 +1,693 @@
<a name="2.0.0-beta.17"></a>
# 2.0.0-beta.17 (2016-04-28)
### Bug Fixes
* **changelog:** fix changelog script. ([c209836](https://github.com/angular/angular/commit/c209836))
* **compiler:** Allow templates to access variables that are declared afterwards. ([1e8864c](https://github.com/angular/angular/commit/1e8864c)), closes [#8261](https://github.com/angular/angular/issues/8261)
* **core:** properly evaluate expressions with conditional and boolean operators ([1ad2a02](https://github.com/angular/angular/commit/1ad2a02)), closes [#8235](https://github.com/angular/angular/issues/8235) [#8244](https://github.com/angular/angular/issues/8244) [#8282](https://github.com/angular/angular/issues/8282)
* **metadata:** Do not attach module names to metadata. ([d964888](https://github.com/angular/angular/commit/d964888)), closes [#8225](https://github.com/angular/angular/issues/8225) [#8082](https://github.com/angular/angular/issues/8082) [#8256](https://github.com/angular/angular/issues/8256)
* **testing:** allow test component builder to override directives from lists ([ff2ae7a](https://github.com/angular/angular/commit/ff2ae7a)), closes [#7397](https://github.com/angular/angular/issues/7397) [#8217](https://github.com/angular/angular/issues/8217)
### Features
* **compiler:** ElementSchema now has explicit DOM schema information ([d327ac4](https://github.com/angular/angular/commit/d327ac4)), closes [#8179](https://github.com/angular/angular/issues/8179)
* **core:** separate refs from vars. ([d2efac1](https://github.com/angular/angular/commit/d2efac1)), closes [#7158](https://github.com/angular/angular/issues/7158) [#8264](https://github.com/angular/angular/issues/8264)
### BREAKING CHANGES
* - `#...` now always means `ref-`.
- `<template #abc>` now defines a reference to the TemplateRef, instead of an input variable used inside of the template.
- `#...` inside of a *ngIf, … directives is deprecated.
Use `let …` instead.
- `var-...` is deprecated. Replace with `let-...` for `<template>` elements and `ref-` for non `<template>` elements.
<a name="2.0.0-beta.16"></a>
# 2.0.0-beta.16 (2016-04-26)
### Bug Fixes
* **angular_1_router:** Removed arrow function from module template ([d094a85](https://github.com/angular/angular/commit/d094a85)), closes [#8076](https://github.com/angular/angular/issues/8076)
* **build:** ignore Dart warnings for external code. ([4140405](https://github.com/angular/angular/commit/4140405))
* **codegen:** add explicit any to class fields ([c8d00dc](https://github.com/angular/angular/commit/c8d00dc)), closes [#8204](https://github.com/angular/angular/issues/8204) [#8205](https://github.com/angular/angular/issues/8205)
* **compiler:** only call pure pipes if their input changed. ([8db6215](https://github.com/angular/angular/commit/8db6215))
* **compiler:** properly implement pure pipes and change pipe syntax ([152a117](https://github.com/angular/angular/commit/152a117))
* **compiler:** support string tokens with `.` inside. ([cc86fee](https://github.com/angular/angular/commit/cc86fee))
* **compiler:** use DI order for change detection order. ([67d05eb](https://github.com/angular/angular/commit/67d05eb)), closes [#8198](https://github.com/angular/angular/issues/8198)
* **core:** various minor compiler fixes ([2f70457](https://github.com/angular/angular/commit/2f70457)), closes [#8162](https://github.com/angular/angular/issues/8162)
* **forms:** ensure select model updates in firefox and ie ([c3daccd](https://github.com/angular/angular/commit/c3daccd)), closes [#6573](https://github.com/angular/angular/issues/6573) [#8148](https://github.com/angular/angular/issues/8148)
* **forms:** improve error message when ngFormModel is missing a form ([12837e1](https://github.com/angular/angular/commit/12837e1)), closes [#8136](https://github.com/angular/angular/issues/8136) [#8143](https://github.com/angular/angular/issues/8143)
* **forms:** number input should report null when blank ([e69cb40](https://github.com/angular/angular/commit/e69cb40)), closes [#6932](https://github.com/angular/angular/issues/6932) [#8141](https://github.com/angular/angular/issues/8141)
* **metadata:** emit metadata rooted at 'angular2' ([9889c21](https://github.com/angular/angular/commit/9889c21)), closes [#8144](https://github.com/angular/angular/issues/8144) [#8147](https://github.com/angular/angular/issues/8147)
* **release:** Fix the package.json zone.js requirement to 0.6.12 ([6103aa0](https://github.com/angular/angular/commit/6103aa0))
* **tests:** remove payload size check ([22c05b0](https://github.com/angular/angular/commit/22c05b0))
* **transformers:** support `query.read` ([386cc5d](https://github.com/angular/angular/commit/386cc5d)), closes [#8172](https://github.com/angular/angular/issues/8172)
* **upgrade:** clean up scope when element is destroyed ([0fc9ec2](https://github.com/angular/angular/commit/0fc9ec2)), closes [#8102](https://github.com/angular/angular/issues/8102)
### Features
* **codegen:** produce `.ngfactory.dart/ts` files instead of `.template.dart/ts` files. ([c06b0a2](https://github.com/angular/angular/commit/c06b0a2))
* **core:** add `Query.read` and remove `DynamicComponentLoader.loadIntoLocation`. ([efbd446](https://github.com/angular/angular/commit/efbd446))
* **core:** introduce ComponentFactory. ([0c600cf](https://github.com/angular/angular/commit/0c600cf))
* **core:** separate reflective injector from Injector interface ([0a7d10b](https://github.com/angular/angular/commit/0a7d10b))
* **core:** support importUri in StaticReflector ([3e11422](https://github.com/angular/angular/commit/3e11422)), closes [#8195](https://github.com/angular/angular/issues/8195)
* **core:** support non reflective bootstrap. ([9092ac7](https://github.com/angular/angular/commit/9092ac7))
* **html_lexer:** support special forms used by i18n { exp, plural, =0 {} } ([7f29766](https://github.com/angular/angular/commit/7f29766))
* **html_parser:** support special forms used by i18n { exp, plural, =0 {} } ([7c9717b](https://github.com/angular/angular/commit/7c9717b))
* **i18n:** add custom placeholder names ([bb9fb21](https://github.com/angular/angular/commit/bb9fb21)), closes [#7799](https://github.com/angular/angular/issues/7799) [#8057](https://github.com/angular/angular/issues/8057)
* **i18n:** add support for nested expansion forms ([c6244d1](https://github.com/angular/angular/commit/c6244d1)), closes [#7977](https://github.com/angular/angular/issues/7977)
* **i18n:** support plural and gender special forms ([88b0a23](https://github.com/angular/angular/commit/88b0a23))
* **Location:** out of router and into platform/common ([b602bd8](https://github.com/angular/angular/commit/b602bd8)), closes [#7962](https://github.com/angular/angular/issues/7962)
* **NgTemplateOutlet:** add NgTemplateOutlet directive ([f4e6994](https://github.com/angular/angular/commit/f4e6994)), closes [#7615](https://github.com/angular/angular/issues/7615) [#8021](https://github.com/angular/angular/issues/8021)
* **router:** add Router and RouterOutlet ([5a897cf](https://github.com/angular/angular/commit/5a897cf)), closes [#8173](https://github.com/angular/angular/issues/8173)
* **router:** add router metadata ([ef67a0c](https://github.com/angular/angular/commit/ef67a0c))
* **router:** add UrlSegment, RouteSegment, and Tree ([90a1f7d](https://github.com/angular/angular/commit/90a1f7d))
* **router:** implement recognizer ([ef6163e](https://github.com/angular/angular/commit/ef6163e))
* **router:** implement RouterUrlParser ([f698567](https://github.com/angular/angular/commit/f698567))
* **test:** Implement fakeAsync using the FakeAsyncTestZoneSpec from zone.js. ([bab81a9](https://github.com/angular/angular/commit/bab81a9)), closes [#8142](https://github.com/angular/angular/issues/8142)
* **tests:** manage asynchronous tests using zones ([8490921](https://github.com/angular/angular/commit/8490921)), closes [#7735](https://github.com/angular/angular/issues/7735)
* **view_compiler:** codegen DI and Queries ([2b34c88](https://github.com/angular/angular/commit/2b34c88)), closes [#6301](https://github.com/angular/angular/issues/6301) [#6567](https://github.com/angular/angular/issues/6567)
### BREAKING CHANGES
* - pipes now take a variable number of arguments, and not an array that contains all arguments.
* inject can no longer wrap fakeAsync while fakeAsync can wrap inject. So the order in existing tests with inject and fakeAsync has to be switched as follows:
Before:
```
inject([...], fakeAsync((...) => {...}))
```
After:
```
fakeAsync(inject([...], (...) => {...}))
```
You will also need to add the dependency
`'node_modules/zone.js/dist/fake-async-test.js'`
as a served file in your Karma or other test configuration.
* - Injector was renamed into `ReflectiveInjector`,
as `Injector` is only an abstract class with one method on it
- `Injector.getOptional()` was changed into `Injector.get(token, notFoundValue)`
to make implementing injectors simpler
- `ViewContainerRef.createComponent` now takes an `Injector`
instead of `ResolvedProviders`. If a reflective injector
should be used, create one before calling this method.
(e.g. via `ReflectiveInjector.resolveAndCreate(…)`.
* - `DynamicComponentLoader.loadIntoLocation` has been removed. Use `@ViewChild(myVar, read: ViewContainerRef)` to get hold of a `ViewContainerRef` at an element with variable `myVar`. Then call `DynamicComponentLoader.loadNextToLocation`.
- `DynamicComponentLoader.loadNextToLocation` now takes a `ViewContainerRef` instead of an `ElementRef`.
- `AppViewManager` is renamed into `ViewUtils` and is a mere private utility service.
* - `Compiler` is renamed to `ComponentResolver`,
`Compiler.compileInHost` has been renamed to `ComponentResolver.resolveComponent`.
- `ComponentRef.dispose` is renamed to `ComponentRef.destroy`
- `ViewContainerRef.createHostView` is renamed to `ViewContainerRef.createComponent`
- `ComponentFixture_` has been removed, the class `ComponentFixture`
can now be created directly as it is no more using private APIs.
* `Location` and other related providers have been moved out of `router` and into `platform/common`. `BrowserPlatformLocation` is not meant to be used directly however advanced configurations may use it via the following import change.
Before:
```
import {
PlatformLocation,
Location,
LocationStrategy,
HashLocationStrategy,
PathLocationStrategy,
APP_BASE_HREF}
from 'angular2/router';
import {BrowserPlatformLocation} from 'angular2/src/router/location/browser_platform_location';
```
After:
```
import {
PlatformLocation,
Location,
LocationStrategy,
HashLocationStrategy,
PathLocationStrategy,
APP_BASE_HREF}
from 'angular2/platform/common';
import {BrowserPlatformLocation} from 'angular2/src/platform/browser/location/browser_platform_location';
```
* `injectAsync` is now deprecated. Instead, use the `async` function
to wrap any asynchronous tests.
You will also need to add the dependency
`'node_modules/zone.js/dist/async-test.js'`
as a served file in your Karma or other test configuration.
Before:
```
it('should wait for returned promises', injectAsync([FancyService], (service) => {
return service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); });
}));
it('should wait for returned promises', injectAsync([], () => {
return somePromise.then(() => { expect(true).toEqual(true); });
}));
```
After:
```
it('should wait for returned promises', async(inject([FancyService], (service) => {
service.getAsyncValue().then((value) => { expect(value).toEqual('async value'); });
})));
// Note that if there is no injection, we no longer need `inject` OR `injectAsync`.
it('should wait for returned promises', async(() => {
somePromise.then() => { expect(true).toEqual(true); });
}));
```
* - Renderer:
* renderComponent method is removed form `Renderer`, only present on `RootRenderer`
* Renderer.setDebugInfo is removed. Renderer.createElement / createText / createTemplateAnchor
now take the DebugInfo directly.
- Query semantics:
* Queries don't work with dynamically loaded components.
* e.g. for router-outlet: loaded components can't be queries via @ViewQuery,
but router-outlet emits an event `activate` now that emits the activated component
- Exception classes and the context inside changed (renamed fields)
- DebugElement.attributes is an Object and not a Map in JS any more
- ChangeDetectorGenConfig was renamed into CompilerConfig
- AppViewManager.createEmbeddedViewInContainer / AppViewManager.createHostViewInContainer
are removed, use the methods in ViewContainerRef instead
- Change detection order changed:
* 1. dirty check component inputs
* 2. dirty check content children
* 3. update render nodes
<a name="2.0.0-beta.15"></a>
# 2.0.0-beta.15 (2016-04-13)
### Bug Fixes
* **7837:** MetadataCollector takes no parameters for the constructor. ([c17dc1c](https://github.com/angular/angular/commit/c17dc1c)), closes [#7838](https://github.com/angular/angular/issues/7838)
* **7987:** Incremental build works with new trees ([08b2956](https://github.com/angular/angular/commit/08b2956)), closes [#7989](https://github.com/angular/angular/issues/7989)
* **build:** ignore dart warnings `The name … is shown, but not used` ([01e6b8c](https://github.com/angular/angular/commit/01e6b8c)), closes [#8045](https://github.com/angular/angular/issues/8045)
* **payload:** increase payload size limit temporarily ([28e657d](https://github.com/angular/angular/commit/28e657d))
* **RouterLink:** ignore optional parameters when checking for active routes ([5e2bc5c](https://github.com/angular/angular/commit/5e2bc5c)), closes [#6459](https://github.com/angular/angular/issues/6459) [#7834](https://github.com/angular/angular/issues/7834)
* **select:** set value individually from ngModel ([e1e44a9](https://github.com/angular/angular/commit/e1e44a9)), closes [#7975](https://github.com/angular/angular/issues/7975) [#7978](https://github.com/angular/angular/issues/7978)
* **upgrade:** make upgradeAdapter upgrade angular 1 components correctly ([247964a](https://github.com/angular/angular/commit/247964a)), closes [#7951](https://github.com/angular/angular/issues/7951)
### Features
* **compiler:** Add an implementation for XHR that uses a template cache to load template files. ([a596b88](https://github.com/angular/angular/commit/a596b88)), closes [#7940](https://github.com/angular/angular/issues/7940)
* **gestures:** allow override of Hammer default configuration ([6cbf990](https://github.com/angular/angular/commit/6cbf990)), closes [#7924](https://github.com/angular/angular/issues/7924)
* **ngFor:** Support convenience view local in ngFor ([ccff175](https://github.com/angular/angular/commit/ccff175)), closes [#8013](https://github.com/angular/angular/issues/8013)
* **parser:** TemplateParser.tryParse() returns both the AST and errors ([226e662](https://github.com/angular/angular/commit/226e662)), closes [#7858](https://github.com/angular/angular/issues/7858)
* **transformers:** changes transformers to collect information about providers and resolve identifi ([3b60503](https://github.com/angular/angular/commit/3b60503))
* **transformers:** special case Profiler ([83b8f59](https://github.com/angular/angular/commit/83b8f59))
* **typescript:** update to 1.9 nightly. ([3412aba](https://github.com/angular/angular/commit/3412aba)), closes [#8003](https://github.com/angular/angular/issues/8003)
### BREAKING CHANGES
* In Dart files, `import 'package:angular2/bootstrap.dart'` no longer works.
Instead, use `import 'package:angular2/platform/browser.dart'`.
### Reverts
* Revert "chore(format): update to latest formatter" ([60727c4](https://github.com/angular/angular/commit/60727c4))
<a name="2.0.0-beta.14"></a>
# 2.0.0-beta.14 (2016-04-07)
### Bug Fixes
* **forms:** support both value and ng-value ([8db97b0](https://github.com/angular/angular/commit/8db97b0))
* **router:** allow forward slashes in query parameters ([4902244](https://github.com/angular/angular/commit/4902244)), closes [#7824](https://github.com/angular/angular/issues/7824)
* **select:** support objects as select values ([74e2bd7](https://github.com/angular/angular/commit/74e2bd7)), closes [#4843](https://github.com/angular/angular/issues/4843) [#7842](https://github.com/angular/angular/issues/7842)
* **select:** update name from ng-value to ngValue ([3ca6df8](https://github.com/angular/angular/commit/3ca6df8)), closes [#7939](https://github.com/angular/angular/issues/7939)
* **upgrade:** leak when angular1 destroys element ([9be04f8](https://github.com/angular/angular/commit/9be04f8)), closes [#6401](https://github.com/angular/angular/issues/6401) [#7935](https://github.com/angular/angular/issues/7935)
### Features
* **dart/transform:** Avoid `print` in transformer code. ([e310bee](https://github.com/angular/angular/commit/e310bee)), closes [#7855](https://github.com/angular/angular/issues/7855)
* **static-reflector:** Added StaticReflector ([0dbf959](https://github.com/angular/angular/commit/0dbf959))
<a name="2.0.0-beta.13"></a>
# 2.0.0-beta.13 (2016-03-31)
### Bug Fixes
* **build:** MetadataCollector correctly collects property metadata ([111afcd](https://github.com/angular/angular/commit/111afcd)), closes [#7772](https://github.com/angular/angular/issues/7772) [#7773](https://github.com/angular/angular/issues/7773)
* **codegen:** stringify using an opaque ID when toString contains parens. ([90c87fa](https://github.com/angular/angular/commit/90c87fa)), closes [#7825](https://github.com/angular/angular/issues/7825)
* **ngFor:** give more instructive error when binding to non-iterable ([49527ab](https://github.com/angular/angular/commit/49527ab))
* **Router:** handling of special chars in dynamic segments ([0bcfcde](https://github.com/angular/angular/commit/0bcfcde)), closes [#7804](https://github.com/angular/angular/issues/7804)
* **upgrade:** make ngUpgrade work with testability API ([430f367](https://github.com/angular/angular/commit/430f367)), closes [#7603](https://github.com/angular/angular/issues/7603)
### Features
* **build:** Persisting decorator metadata ([ae876d1](https://github.com/angular/angular/commit/ae876d1))
* **compiler:** assert that Component.style is an array ([6de68e2](https://github.com/angular/angular/commit/6de68e2)), closes [#7559](https://github.com/angular/angular/issues/7559)
* **compiler:** Resolvers now use DI to create reflector ([506f4ce](https://github.com/angular/angular/commit/506f4ce)), closes [#7762](https://github.com/angular/angular/issues/7762)
* **Compiler:** Allow overriding the projection selector ([aa966f5](https://github.com/angular/angular/commit/aa966f5)), closes [#6303](https://github.com/angular/angular/issues/6303) [#7742](https://github.com/angular/angular/issues/7742)
* **dart:** Add a dev-mode check for undeclared lifecycle interfaces ([1c20a62](https://github.com/angular/angular/commit/1c20a62)), closes [#6849](https://github.com/angular/angular/issues/6849)
* **facade:** add ListWrapper.flatten ([a1880c3](https://github.com/angular/angular/commit/a1880c3))
* **facade:** add RegExpWrapper.replaceAll to replace all matches using the provided function ([91999e0](https://github.com/angular/angular/commit/91999e0))
* **html_parser:** change HtmlElementAst to store both the start and the end positions ([17c8ec8](https://github.com/angular/angular/commit/17c8ec8))
* **i18n:** implement an i18n-aware html parser ([d272f96](https://github.com/angular/angular/commit/d272f96)), closes [#7738](https://github.com/angular/angular/issues/7738)
* **i18n:** implement xmb deserialization ([d7e1175](https://github.com/angular/angular/commit/d7e1175))
* **i18n:** reexport I18nHtmlParser through the i18n barrel ([d2ca7d8](https://github.com/angular/angular/commit/d2ca7d8))
* **i18n:** update I18nHtmlParser to accept parsed messages ([756121a](https://github.com/angular/angular/commit/756121a))
* **i18n:** update transformers to read a xmb file when provided and use I18nHtmlParser in t ([8430927](https://github.com/angular/angular/commit/8430927)), closes [#7790](https://github.com/angular/angular/issues/7790)
### BREAKING CHANGES
* For static content projection, elements with *-directives are now matched against the element itself vs the template before.
`<p *ngIf="condition" foo></p>`
Before:
```html
// Use the implicit template for projection
<ng-content select="template"></ng-content>
```
After:
```html
// Use the actual element for projection
<ng-content select="p[foo]"></ng-content>
```
<a name="2.0.0-beta.12"></a>
# 2.0.0-beta.12 (2016-03-23)
### Bug Fixes
* **angular_1_router:** ng-link is generating wrong hrefs ([69c1405](https://github.com/angular/angular/commit/69c1405)), closes [#7423](https://github.com/angular/angular/issues/7423)
* **angular1_router:** support link generation with custom hashPrefixes ([0f8efce](https://github.com/angular/angular/commit/0f8efce))
* **package.json:** remove es6-promise from the peerDependency list ([8b67b07](https://github.com/angular/angular/commit/8b67b07))
### Features
* **dart/transform:** Use angular2/platform/browser as bootstrap lib ([b6507e3](https://github.com/angular/angular/commit/b6507e3)), closes [#7647](https://github.com/angular/angular/issues/7647)
<a name="2.0.0-beta.11"></a>
# 2.0.0-beta.11 (2016-03-18)
### Bug Fixes
* make sure that Zone does not show up in angular2.d.ts ([d4e9b55](https://github.com/angular/angular/commit/d4e9b55fb69d87f948d02905d34fc78221adb11a))
* **common:** remove @internal annotation on SwitchView ([967ae3e](https://github.com/angular/angular/commit/967ae3e)), closes [#7657](https://github.com/angular/angular/issues/7657)
* **router:** RouterOutlet loads component twice in a race condition ([2f581ff](https://github.com/angular/angular/commit/2f581ff)), closes [#7497](https://github.com/angular/angular/issues/7497) [#7545](https://github.com/angular/angular/issues/7545)
### Features
* **i18n:** add a simple dart script extracting all i18n messages from a package ([8326ab3](https://github.com/angular/angular/commit/8326ab3)), closes [#7620](https://github.com/angular/angular/issues/7620)
* **i18n:** create i18n barrel ([a7fe983](https://github.com/angular/angular/commit/a7fe983))
* **i18n:** implement xmb serializer ([e1f8e54](https://github.com/angular/angular/commit/e1f8e54))
<a name="2.0.0-beta.10"></a>
# 2.0.0-beta.10 (2016-03-17)
### Bug Fixes
* **change_detection:** fix a memory leak ([128acbb](https://github.com/angular/angular/commit/128acbb))
* **closure:** don't throw from top-level ([5824866](https://github.com/angular/angular/commit/5824866))
* **router:** handle URL that does not match a route ([8e3e450](https://github.com/angular/angular/commit/8e3e450)), closes [#7349](https://github.com/angular/angular/issues/7349) [#7203](https://github.com/angular/angular/issues/7203)
* **router/instruction:** ensure toLinkUrl includes extra params ([0d58b13](https://github.com/angular/angular/commit/0d58b13)), closes [#7367](https://github.com/angular/angular/issues/7367)
### Features
* **compiler:** change html parser to preserve comments ([70d18b5](https://github.com/angular/angular/commit/70d18b5))
* **core:** introduce a CSS lexer/parser ([b72bab4](https://github.com/angular/angular/commit/b72bab4))
* **core:** introduce a CSS lexer/parser ([293fa55](https://github.com/angular/angular/commit/293fa55))
* **facade:** add .values to StringMapWrapper ([f1796d6](https://github.com/angular/angular/commit/f1796d6))
* **i18n:** add ngPlural directive ([df1f78e](https://github.com/angular/angular/commit/df1f78e))
* **i18n:** implement a simple version of message extractor ([095db67](https://github.com/angular/angular/commit/095db67)), closes [#7454](https://github.com/angular/angular/issues/7454)
* **shadow_css:** support `/deep/` and `>>>` ([cb38d72](https://github.com/angular/angular/commit/cb38d72)), closes [#7562](https://github.com/angular/angular/issues/7562) [#7563](https://github.com/angular/angular/issues/7563)
* **TAG_DEFINITIONS:** include <meta> and <base> ([2c7c3e3](https://github.com/angular/angular/commit/2c7c3e3)), closes [#7455](https://github.com/angular/angular/issues/7455)
### BREAKING CHANGES
Removed deprecated API from NgZone
- `NgZone.overrideOnTurnStart`
- `NgZone.overrideOnTurnDone`
- `NgZone.overrideOnEventDone`
- `NgZone.overrideOnErrorHandler`
Rename NgZone API
- `NgZone.onTurnStart` => `NgZone.onUnstable`
- `NgZone.onTurnDone` => `NgZone.onMicrotaskEmpty`
- `NgZone.onEventDone` => `NgZone.onStable`
<a name="2.0.0-beta.9"></a>
# 2.0.0-beta.9 (2016-03-09)
### Bug Fixes
* **angular_1_router:** Renamed require statements after TypeScript files are transpiled ([ae49085](https://github.com/angular/angular/commit/ae49085)), closes [#7049](https://github.com/angular/angular/issues/7049)
* **angular1_router:** rename `router` component binding to `$router` ([2548ce8](https://github.com/angular/angular/commit/2548ce8))
* **angular1_router:** rename `router` component binding to `$router` ([1174473](https://github.com/angular/angular/commit/1174473))
* **angular1_router:** support templateUrl components ([5586c29](https://github.com/angular/angular/commit/5586c29))
* **build:** Use fixed version of Chromium Canary that will be updated manually instead of au ([1d49b3e](https://github.com/angular/angular/commit/1d49b3e))
* **router:** support outlets within dynamic components ([7d44b82](https://github.com/angular/angular/commit/7d44b82))
### Features
* **angular1_router:** Add ng-link-active class to active ng-link ([11e8aa2](https://github.com/angular/angular/commit/11e8aa2)), closes [#6882](https://github.com/angular/angular/issues/6882)
* **compiler:** Added spans to HTML parser errors ([19a08f3](https://github.com/angular/angular/commit/19a08f3))
* **dart:** Add a dev-mode check for undeclared lifecycle interfaces ([a3d7629](https://github.com/angular/angular/commit/a3d7629)), closes [#6849](https://github.com/angular/angular/issues/6849)
* **dart/transform:** Create standalone transformers for phases ([15e1614](https://github.com/angular/angular/commit/15e1614))
* **iterable_differ:** support immutable lists ([a10c02c](https://github.com/angular/angular/commit/a10c02c)), closes [#7127](https://github.com/angular/angular/issues/7127)
* **router:** add regex matchers ([75343eb](https://github.com/angular/angular/commit/75343eb)), closes [#7325](https://github.com/angular/angular/issues/7325) [#7126](https://github.com/angular/angular/issues/7126)
* **router:** Added method to get current instruction ([6dce4f4](https://github.com/angular/angular/commit/6dce4f4))
* **transformers:** change 'Missing Identifier' to be an error ([45fd6f0](https://github.com/angular/angular/commit/45fd6f0)), closes [#7403](https://github.com/angular/angular/issues/7403)
* **transformers:** collect provider information ([81beb1c](https://github.com/angular/angular/commit/81beb1c))
### BREAKING CHANGES
* The recently added binding of the current router to the current component
has been renamed from `router` to `$router`.
So now the recommended set up for your bindings in your routed component
is:
```js
{
...
bindings: {
$router: '<'
}
}
```
* The recently added binding of the current router to the current component
has been renamed from `router` to `$router`.
So now the recommended set up for your bindings in your routed component
is:
```js
{
...
bindings: {
$router: '<'
}
}
```
<a name="2.0.0-beta.8"></a>
# 2.0.0-beta.8 (2016-03-02)
### Bug Fixes
* **angular1_router:** rename `$route` service to `$rootRouter` ([a1c3be2](https://github.com/angular/angular/commit/a1c3be2))
* **angular1_router:** rename `router` component binding to `$router` ([edad8e3](https://github.com/angular/angular/commit/edad8e3))
* **angular1_router:** support templateUrl components ([d4a4d81](https://github.com/angular/angular/commit/d4a4d81))
* **change_detection:** allow to destroy `OnPush` components inside of a host event. ([280b86e](https://github.com/angular/angular/commit/280b86e))
* **change_detection:** allow to destroy `OnPush` components inside of a host event. ([ebd438f](https://github.com/angular/angular/commit/ebd438f)), closes [#7192](https://github.com/angular/angular/issues/7192)
* **core:** support `ngFor` that has an `ngIf` as last node ([1779caf](https://github.com/angular/angular/commit/1779caf)), closes [#6304](https://github.com/angular/angular/issues/6304) [#6878](https://github.com/angular/angular/issues/6878)
* **dart/payload:** Fix runtime error in hello_world payload app ([eeb594c](https://github.com/angular/angular/commit/eeb594c)), closes [#7358](https://github.com/angular/angular/issues/7358)
* **differ:** clean up stale identity change refs ([ab36ea0](https://github.com/angular/angular/commit/ab36ea0)), closes [#7193](https://github.com/angular/angular/issues/7193)
* **DomRenderer:** correctly handle namespaced attributes ([c6afea6](https://github.com/angular/angular/commit/c6afea6))
* **Router:** Query strings are copied for HashLocationStrategy ([b47f80e](https://github.com/angular/angular/commit/b47f80e)), closes [#7298](https://github.com/angular/angular/issues/7298)
* **test:** fix a broken test ([9aedef2](https://github.com/angular/angular/commit/9aedef2))
* **transformers:** record reflection info about abstract classes ([05c185a](https://github.com/angular/angular/commit/05c185a)), closes [#7347](https://github.com/angular/angular/issues/7347)
* **transformers:** replace an error with a warning when cannot resolve a symbol ([ee3c580](https://github.com/angular/angular/commit/ee3c580))
* **transformers:** special case types some built-in types, so they can be resolved ([331b9c1](https://github.com/angular/angular/commit/331b9c1))
* **web_worker:** wait for bindings in kitchen sink spec ([4a93f58](https://github.com/angular/angular/commit/4a93f58))
* **web_workers:** make waitForElementText function more stable ([f6a8d04](https://github.com/angular/angular/commit/f6a8d04))
* **WebWorker:** Fix PostMessageBusSink and Source undefined error. ([01fe7f5](https://github.com/angular/angular/commit/01fe7f5)), closes [#7156](https://github.com/angular/angular/issues/7156)
* **WebWorker:** Make MessageBus EventEmitter synchronous ([69c1694](https://github.com/angular/angular/commit/69c1694))
### Features
* **core:** Add `QueryList.forEach` to public api. ([e7470d5](https://github.com/angular/angular/commit/e7470d5))
* **core:** Add `QueryList#forEach` ([b634a25](https://github.com/angular/angular/commit/b634a25))
* **core:** add more debug APIs to inspect the application form a browser ([b5e6319](https://github.com/angular/angular/commit/b5e6319)), closes [#7045](https://github.com/angular/angular/issues/7045) [#7161](https://github.com/angular/angular/issues/7161)
* **core:** drop `ChangeDetectionStrategy.OnPushObserve` ([f60fa14](https://github.com/angular/angular/commit/f60fa14))
* **di:** drop support for injecting types with generics in Dart ([c9a3df9](https://github.com/angular/angular/commit/c9a3df9)), closes [#7262](https://github.com/angular/angular/issues/7262)
* **forms/validators:** pattern validator ([38cb526](https://github.com/angular/angular/commit/38cb526)), closes [#5561](https://github.com/angular/angular/issues/5561)
* **i18n:** added i18nPlural and i18nSelect pipes ([59629a0](https://github.com/angular/angular/commit/59629a0)), closes [#7268](https://github.com/angular/angular/issues/7268)
* **pipes:** add ReplacePipe for string manipulation ([6ef2121](https://github.com/angular/angular/commit/6ef2121))
* **test:** add withProviders for per test providers ([c1a0af5](https://github.com/angular/angular/commit/c1a0af5)), closes [#5128](https://github.com/angular/angular/issues/5128)
* **transformers:** collect data needed for the template compiler ([ebe531b](https://github.com/angular/angular/commit/ebe531b)), closes [#7299](https://github.com/angular/angular/issues/7299)
* **transformers:** collect information for CompileDiDependencyMetadata ([39b6e0e](https://github.com/angular/angular/commit/39b6e0e))
* **transformers:** makes the map of resolved identifiers configurable ([0bb10d6](https://github.com/angular/angular/commit/0bb10d6)), closes [#7359](https://github.com/angular/angular/issues/7359)
### BREAKING CHANGES
* `OnPushObserve` was an experimental
feature for Dart and had
conceptual performance problems,
as setting up observables is slow.
Use `OnPush` instead.
* In Dart we used to support injecting types with generics. As this feature is hard to implement with the upcoming codegen we are dropping it.
Merge cl/115454020 in G3 with this change.
* The `$router` injectable service has been renamed to `$rootRouter`
* The recently added binding of the current router to the current component
has been renamed from `router` to `$router`.
So now the recommended set up for your bindings in your routed component
is:
```js
{
...
bindings: {
$router: '<'
}
}
```
<a name="2.0.0-beta.7"></a>
# 2.0.0-beta.7 (2016-02-18)
### Bug Fixes
* **angular_1_router:** Added DI string tokens ([3478d5d](https://github.com/angular/angular/commit/3478d5d)), closes [#4269](https://github.com/angular/angular/issues/4269) [#7031](https://github.com/angular/angular/issues/7031)
* **typing:** Remove re-export of the Promise built-in type. ([265703b](https://github.com/angular/angular/commit/265703b)), closes [#6468](https://github.com/angular/angular/issues/6468)
<a name="2.0.0-beta.6"></a>
# 2.0.0-beta.6 (2016-02-11)
### Bug Fixes
* **angular1-router:** add missing wrapper methods ([55122cd](https://github.com/angular/angular/commit/55122cd)), closes [#6763](https://github.com/angular/angular/issues/6763) [#6861](https://github.com/angular/angular/issues/6861) [#6861](https://github.com/angular/angular/issues/6861)
* **angular1-router:** add support for using the component helper ([d86be24](https://github.com/angular/angular/commit/d86be24)), closes [angular/angular.js#13860](https://github.com/angular/angular.js/issues/13860) [#6076](https://github.com/angular/angular/issues/6076) [#5278](https://github.com/angular/angular/issues/5278)
* **async:** handle synchronous initial value in async pipe ([26e60d6](https://github.com/angular/angular/commit/26e60d6)), closes [#5996](https://github.com/angular/angular/issues/5996)
* **build:** don't try to copy .d.ts files into the npm distro ([16b5217](https://github.com/angular/angular/commit/16b5217)), closes [#6921](https://github.com/angular/angular/issues/6921)
* **compiler:** fix interpolation regexp ([9b0e10e](https://github.com/angular/angular/commit/9b0e10e)), closes [#6056](https://github.com/angular/angular/issues/6056)
* **compiler:** use event names for matching directives ([231773e](https://github.com/angular/angular/commit/231773e)), closes [#6870](https://github.com/angular/angular/issues/6870)
* **core:** add detail to dehydrated detector exception ([e7ad03c](https://github.com/angular/angular/commit/e7ad03c)), closes [#6939](https://github.com/angular/angular/issues/6939)
* **core:** mute mode printing in console in prod mode ([74be3d3](https://github.com/angular/angular/commit/74be3d3)), closes [#6873](https://github.com/angular/angular/issues/6873)
* **di:** throw if a token uses more than 20 dependencies. ([de77700](https://github.com/angular/angular/commit/de77700)), closes [#6690](https://github.com/angular/angular/issues/6690) [#6869](https://github.com/angular/angular/issues/6869)
* **forms:** add RadioButtonValueAccessor to the list of default value accessors ([8f47aa3](https://github.com/angular/angular/commit/8f47aa3))
* **forms:** add support for radio buttons ([e725542](https://github.com/angular/angular/commit/e725542)), closes [#6877](https://github.com/angular/angular/issues/6877)
* **forms:** use strict runtimeType checks instead of instanceof ([50548fb](https://github.com/angular/angular/commit/50548fb)), closes [#6981](https://github.com/angular/angular/issues/6981)
* **Headers:** serializable toJSON ([b55f176](https://github.com/angular/angular/commit/b55f176)), closes [#6073](https://github.com/angular/angular/issues/6073) [#6714](https://github.com/angular/angular/issues/6714)
* **ngFor:** update view locals if identity changes ([0f10624](https://github.com/angular/angular/commit/0f10624)), closes [#6923](https://github.com/angular/angular/issues/6923)
* **router:** Added route data to normalized async route ([df7885c](https://github.com/angular/angular/commit/df7885c)), closes [#6802](https://github.com/angular/angular/issues/6802)
* **router:** don't prepend `/` unnecessarily to Location paths ([c603643](https://github.com/angular/angular/commit/c603643)), closes [#6729](https://github.com/angular/angular/issues/6729) [#5502](https://github.com/angular/angular/issues/5502)
* **router:** fix incorrect url param value coercion of 1 to true ([995a9e0](https://github.com/angular/angular/commit/995a9e0)), closes [#5346](https://github.com/angular/angular/issues/5346) [#6286](https://github.com/angular/angular/issues/6286)
* **router:** fix url path for star segment in path recognizer ([6f1ef33](https://github.com/angular/angular/commit/6f1ef33)), closes [#6976](https://github.com/angular/angular/issues/6976)
* **router:** fixed the location wrapper for angular1 ([e73fee7](https://github.com/angular/angular/commit/e73fee7)), closes [#6943](https://github.com/angular/angular/issues/6943)
* **typings:** Don't expose typing dependencies to users. ([2a70f4e](https://github.com/angular/angular/commit/2a70f4e)), closes [#5973](https://github.com/angular/angular/issues/5973) [#5807](https://github.com/angular/angular/issues/5807) [#6266](https://github.com/angular/angular/issues/6266) [#5242](https://github.com/angular/angular/issues/5242) [#6817](https://github.com/angular/angular/issues/6817) [#6267](https://github.com/angular/angular/issues/6267)
* **upgrade:** fix infinite $rootScope.$digest() ([7e0f02f](https://github.com/angular/angular/commit/7e0f02f)), closes [#6385](https://github.com/angular/angular/issues/6385) [#6386](https://github.com/angular/angular/issues/6386)
* **Validators:** fix Validators.required marking number zero as invalid ([c2ceb7f](https://github.com/angular/angular/commit/c2ceb7f)), closes [#6617](https://github.com/angular/angular/issues/6617)
* **WebWorkers:** Fix flaky WebWorker test ([da1fcfd](https://github.com/angular/angular/commit/da1fcfd)), closes [#6851](https://github.com/angular/angular/issues/6851)
### Features
* **angular1_router:** allow component to bind to router ([0f22dce](https://github.com/angular/angular/commit/0f22dce))
* **typings:** install es6-shim typings to a location users can reference. ([f1f5b45](https://github.com/angular/angular/commit/f1f5b45))
### BREAKING CHANGES
Transitive typings are no longer included in the distribution.
If you use `--target=es5`, you will need to add a line somewhere in your
application (for example, at the top of the `.ts` file where you call `bootstrap`):
```
///<reference path="node_modules/angular2/typings/browser.d.ts"/>
```
(Note that if your file is not in the same directory as `node_modules`, you'll
need to add one or more `../` to the start of that path.)
If you have unit tests, you need to install typings in your project using
http://github.com/typings/typings
And install typings such as `jasmine`, `angular-protractor`, or `selenium-webdriver`
to satisfy the type-checker.
If you rely on es6 APIs other than Promises and Collections, you will need to
install the es6-shim typing instead of using the <reference> tag above.
Angular previously exposed typings for the entire ES6 API.
<a name="2.0.0-beta.5"></a>
# 2.0.0-beta.5 (2016-02-10)
This release was incorrect; replaced with beta.6.
<a name="2.0.0-beta.4"></a>
# 2.0.0-beta.4 (2016-02-10)
This release was incorrect; replaced with beta.6.
<a name="2.0.0-beta.3"></a>
# 2.0.0-beta.3 (2016-02-03)
### Bug Fixes
* **bundle:** add angular2/platform/testing/browser to SystemJS testing bundle ([ae7d2ab](https://github.com/angular/angular/commit/ae7d2ab))
* **circle:** pre-dependencies `npm install npm` ([36a0e04](https://github.com/angular/angular/commit/36a0e04)), closes [#6777](https://github.com/angular/angular/issues/6777)
* **dart/transform:** Handle edge cases in ReflectionRemover ([3e9b532](https://github.com/angular/angular/commit/3e9b532)), closes [#6749](https://github.com/angular/angular/issues/6749)
* **docs:** `rxjs/add/operators/map` -> `rxjs/add/operator/map` (no 's'). ([2a302aa](https://github.com/angular/angular/commit/2a302aa))
* **karma:** fix running karma via gulp ([27daeaf](https://github.com/angular/angular/commit/27daeaf))
* **query:** dont cross component boundaries ([c6adbf6](https://github.com/angular/angular/commit/c6adbf6)), closes [#6759](https://github.com/angular/angular/issues/6759)
* **query:** update view queries that query directives in embedded views ([1f7a41c](https://github.com/angular/angular/commit/1f7a41c)), closes [#6747](https://github.com/angular/angular/issues/6747)
* **WebWorkers:** Add support for transitionend events. ([c2a38c0](https://github.com/angular/angular/commit/c2a38c0)), closes [#6649](https://github.com/angular/angular/issues/6649)
* **zone:** correct incorrect calls to zone ([3211938](https://github.com/angular/angular/commit/3211938))
### Features
* **change_detection:** allow all legal programs in the dev mode ([42231f5](https://github.com/angular/angular/commit/42231f5))
* **dart/transform:** Generate all code into <file>.template.dart ([8c36aa8](https://github.com/angular/angular/commit/8c36aa8))
* **debug:** replace DebugElement with new Debug DOM ([e1bf3d3](https://github.com/angular/angular/commit/e1bf3d3))
* **ngFor:** add custom trackBy function support ([cee2318](https://github.com/angular/angular/commit/cee2318)), closes [#6779](https://github.com/angular/angular/issues/6779)
* **upgrade:** support bindToController with binding definitions ([99e6500](https://github.com/angular/angular/commit/99e6500)), closes [#4784](https://github.com/angular/angular/issues/4784)
* **WebWorker:** Add Router Support for WebWorker Apps ([8bea667](https://github.com/angular/angular/commit/8bea667)), closes [#3563](https://github.com/angular/angular/issues/3563)
### Performance Improvements
* **dart/transform:** Only process deferred libs when necessary ([f56df65](https://github.com/angular/angular/commit/f56df65)), closes [#6745](https://github.com/angular/angular/issues/6745)
### BREAKING CHANGES
This is a breaking change for unit tests. The API for the DebugElement
has changed. Now, there is a DebugElement or DebugNode for every node
in the DOM, not only nodes with an ElementRef. `componentViewChildren` is
removed, and `childNodes` is a list of ElementNodes corresponding to every
child in the DOM. `query` no longer takes a scope parameter, since
the entire rendered DOM is included in the `childNodes`.
Before:
```
componentFixture.debugElement.componentViewChildren[0];
```
After
```
// Depending on the DOM structure of your component, the
// index may have changed or the first component child
// may be a sub-child.
componentFixture.debugElement.children[0];
```
Before:
```
debugElement.query(By.css('div'), Scope.all());
```
After:
```
debugElement.query(By.css('div'));
```
Before:
```
componentFixture.debugElement.elementRef;
```
After:
```
componentFixture.elementRef;
```
<a name="2.0.0-beta.2"></a>
# 2.0.0-beta.2 (2016-01-28)
### Bug Fixes
* **bundles:** testing bundle should include browser platform ([4a41442](https://github.com/angular/angular/commit/4a41442)), closes [#6626](https://github.com/angular/angular/issues/6626)
* **ChangeDetection:** chain expressions evaluate to the last expression (codegen) ([933a911](https://github.com/angular/angular/commit/933a911)), closes [#4782](https://github.com/angular/angular/issues/4782) [#5892](https://github.com/angular/angular/issues/5892)
* **core:** always remove DOM listeners and stream subscriptions ([0ae7775](https://github.com/angular/angular/commit/0ae7775))
* **Dart:** make some playground samples run with Dart Dev Compiler ([3e65d14](https://github.com/angular/angular/commit/3e65d14)), closes [#6441](https://github.com/angular/angular/issues/6441)
* **dart/transform:** Ensure template codegen is completed sync ([5f0baaa](https://github.com/angular/angular/commit/5f0baaa)), closes [#6603](https://github.com/angular/angular/issues/6603)
* **ddc:** router, compiler, web worker fixes for DDC ([db87bae](https://github.com/angular/angular/commit/db87bae)), closes [#6693](https://github.com/angular/angular/issues/6693)
* **ddc:** type fixes necessary to bring DDC severe count to 0 ([4282297](https://github.com/angular/angular/commit/4282297))
* **ddc:** use dynamic types in reflection typedefs ([c785a1e](https://github.com/angular/angular/commit/c785a1e)), closes [#6437](https://github.com/angular/angular/issues/6437)
* **directive:** throw if output the same event more than once ([8c37b7e](https://github.com/angular/angular/commit/8c37b7e))
* **HtmlLexer:** fix for unicode chars ([a24ee6a](https://github.com/angular/angular/commit/a24ee6a)), closes [#6036](https://github.com/angular/angular/issues/6036) [#6061](https://github.com/angular/angular/issues/6061)
* **perf:** faster looseIdentical implementation ([761c6d0](https://github.com/angular/angular/commit/761c6d0)), closes [#6364](https://github.com/angular/angular/issues/6364)
* **template_compiler:** Fix erroneous cycle detection ([eda4c3e](https://github.com/angular/angular/commit/eda4c3e)), closes [#6404](https://github.com/angular/angular/issues/6404) [#6474](https://github.com/angular/angular/issues/6474)
* **testing:** remove test zone for now and rely on returned promises ([c72ed99](https://github.com/angular/angular/commit/c72ed99)), closes [#6359](https://github.com/angular/angular/issues/6359) [#6601](https://github.com/angular/angular/issues/6601)
* **transformer:** record HostBinding annotations applied to getters ([a593ffa](https://github.com/angular/angular/commit/a593ffa)), closes [#6283](https://github.com/angular/angular/issues/6283)
* **web_workers:** support @AngularEntrypoint in web workers ([ac85cbb](https://github.com/angular/angular/commit/ac85cbb)), closes [#6013](https://github.com/angular/angular/issues/6013)
### Features
* **core/application_ref:** Allow asyncronous app initializers. ([df3074f](https://github.com/angular/angular/commit/df3074f)), closes [#5929](https://github.com/angular/angular/issues/5929) [#6063](https://github.com/angular/angular/issues/6063)
* **dart/transform:** DirectiveProcessor: do not process generated files ([78bfdf7](https://github.com/angular/angular/commit/78bfdf7)), closes [#6517](https://github.com/angular/angular/issues/6517)
* **dart/transform:** Promote missing Directive warning to error ([47a3b4d](https://github.com/angular/angular/commit/47a3b4d)), closes [#6519](https://github.com/angular/angular/issues/6519) [#6568](https://github.com/angular/angular/issues/6568)
* **test:** allow tests to specify the platform and application providers used ([b0cebdb](https://github.com/angular/angular/commit/b0cebdb)), closes [#5351](https://github.com/angular/angular/issues/5351) [#5585](https://github.com/angular/angular/issues/5585) [#5975](https://github.com/angular/angular/issues/5975)
* **testability:** Expose function frameworkStabilizers ([69ae363](https://github.com/angular/angular/commit/69ae363)), closes [#5485](https://github.com/angular/angular/issues/5485)
### BREAKING CHANGES
* `Renderer.listen` now has to return a function that
removes the event listener.
* TemplateRef.elementRef is now read-only.
* Tests are now required to use `setBaseTestProviders`
to set up. Assuming your tests are run on a browser, setup would change
as follows.
Before:
```js
// Somewhere in test setup
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
BrowserDomAdapter.makeCurrent
```
After:
```js
// Somewhere in the test setup
import {setBaseTestProviders} from 'angular2/testing';
import {
TEST_BROWSER_PLATFORM_PROVIDERS,
TEST_BROWSER_APPLICATION_PROVIDERS
} from 'angular2/platform/testing/browser';
setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS,
TEST_BROWSER_APPLICATION_PROVIDERS);
```
<a name="2.0.0-beta.1"></a>
# 2.0.0-beta.1 catamorphic-involution (2016-01-08)
@ -43,6 +733,7 @@
take a native element instead of an ElementRef
* `Renderer` interface now operates on plain native nodes,
instead of `RenderElementRef`s or `RenderViewRef`s
<a name="2.0.0-beta.0"></a>
# 2.0.0-beta.0 somnambulant-inauguration (2015-12-15)
@ -64,10 +755,7 @@
### BREAKING CHANGES
* Before
Previously Angular would run in dev prod mode by default, and you could enable the dev mode by calling enableDevMode.
After
Now, Angular runs in the dev mode by default, and you can enable the prod mode by calling enableProdMode.
* Previously, Angular would run in dev prod mode by default, and you could enable the dev mode by calling enableDevMode. Now, Angular runs in the dev mode by default, and you can enable the prod mode by calling enableProdMode.
@ -144,11 +832,11 @@ bundle. `ngUpgrade` has a dedicated `upgrade.js` bundle now.
* `Observable` are no more re-exported from `angular2/core`
Before
Before
```
import {Observable} from 'angular2/core'
```
After
After
```
import {Observable} from 'rxjs/Observable';
```
@ -369,7 +1057,7 @@ import * as core from 'angular2/core';
* Operators and Observables from RxJS (e.g. .map(), .toArray(), .toPromise(), etc ) now need to be explicitly imported (once per operator in your app)
```
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operators/map';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/interval';
Observable.interval(1000).subscribe(...);

View File

@ -180,8 +180,8 @@ Must be one of the following:
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **perf**: A code change that improves performance
* **test**: Adding missing tests or correcting existing tests
* **build**: Changes that affect the build system, CI configuration or external dependencies (example scopes: gulp, broccoli, npm)
* **ci**: Any changes to our CI configuration files and scripts (Travis, Circle CI, BrowserStack, SauceLabs)
* **build**: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
* **ci**: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
* **chore**: Other changes that don't modify `src` or `test` files
### Scope

View File

@ -9,7 +9,7 @@ JS and Dart versions. It also explains the basic mechanics of using `git`, `node
* [Installing NPM Modules and Dart Packages](#installing-npm-modules-and-dart-packages)
* [Build commands](#build-commands)
* [Running Tests Locally](#running-tests-locally)
* [Formatting](#clang-format)
* [Code Style](#code-style)
* [Project Information](#project-information)
* [CI using Travis](#ci-using-travis)
* [Transforming Dart code](#transforming-dart-code)
@ -227,7 +227,9 @@ Angular specific command line options when running protractor:
Angular specific command line options when running protractor (e.g. force gc, ...):
`$(npm bin)/protractor protractor-{js|dart2js}-conf.js --ng-help`
## Formatting with <a name="clang-format">clang-format</a>
## Code Style
### Formatting with <a name="clang-format">clang-format</a>
We use [clang-format](http://clang.llvm.org/docs/ClangFormat.html) to automatically enforce code
style for our TypeScript code. This allows us to focus our code reviews more on the content, and
@ -273,6 +275,14 @@ to some whitespace difference.
* `clang-format` integrations are also available for many popular editors (`vim`, `emacs`,
`Sublime Text`, etc.).
### Linting
We use [tslint](https://github.com/palantir/tslint) for linting. See linting rules in [gulpfile](gulpfile.js). To lint, run
```shell
$ gulp lint
```
## Generating the API documentation
The following gulp task will generate the API docs in the `dist/angular.io/partials/api/angular2`:

View File

@ -117,7 +117,7 @@ speed things up is to use plain class fields in your expressions and avoid any
kinds of computation. Example:
```typescript
@View({
@Component({
template: '<button [enabled]="isEnabled">{{title}}</button>'
})
class FancyButton {

View File

@ -4,8 +4,9 @@
var CIconfiguration = {
'Chrome': { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
'Firefox': { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
'ChromeBeta': { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
'FirefoxBeta': { unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}},
// FirefoxBeta should be required:true
// https://github.com/angular/angular/issues/7560
'FirefoxBeta': { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: false}},
'ChromeDev': { unitTest: {target: null, required: true}, e2e: {target: null, required: true}},
'FirefoxDev': { unitTest: {target: null, required: true}, e2e: {target: null, required: true}},
'IE9': { unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}},

View File

@ -1,6 +1,21 @@
machine:
node:
version: 5.4.1
dependencies:
pre:
- npm install -g npm
override:
- npm install:
environment:
# Token for tsd to increase github rate limit
# See https://github.com/DefinitelyTyped/tsd#tsdrc
# This is not hidden using https://circleci.com/docs/fork-pr-builds#details
# because those are not visible for pull requests, and those should also be reliable.
# This SSO token belongs to github account angular-github-ratelimit-token which has no access
# (password is in Valentine)
TSD_GITHUB_TOKEN: ef474500309daea53d5991b3079159a29520a40b
test:
override:
- npm run build

View File

@ -40,9 +40,9 @@ if (cliArgs.projects) {
cliArgs.projects.split(',').sort().join(',');
}
// --projects=angular2,angular2_material => {angular2: true, angular2_material: true}
// --projects=angular2 => {angular2: true}
var allProjects =
'angular1_router,angular2,angular2_material,benchmarks,benchmarks_external,benchpress,playground,payload_tests,bundle_deps';
'angular1_router,angular2,benchmarks,benchmarks_external,benchpress,playground,payload_tests,bundle_deps';
var cliArgsProjects = (cliArgs.projects || allProjects)
.split(',')
.reduce((map, projectName) => {
@ -57,7 +57,7 @@ function printModulesWarning() {
console.warn(
"Pro Tip: Did you know that you can speed up your build by specifying project name(s)?");
console.warn(" It's like pressing the turbo button in the old days, but better!");
console.warn(" Examples: --project=angular2 or --project=angular2,angular2_material");
console.warn(" Examples: --project=angular2 or --project=angular2");
}
}
@ -132,7 +132,8 @@ var CONFIG = {
dev: {es6: 'dist/js/dev/es6', es5: 'dist/js/dev/es5'},
prod: {es6: 'dist/js/prod/es6', es5: 'dist/js/prod/es5'},
cjs: 'dist/js/cjs',
dart2js: 'dist/js/dart2js'
dart2js: 'dist/js/dart2js',
dart_dev_compiler: 'dist/js/ddc'
},
dart: 'dist/dart',
docs: 'dist/docs',
@ -155,7 +156,7 @@ var HTTP_BUNDLE_CONTENT = 'angular2/http - rxjs/* - ' + ANGULAR2_BUNDLE_CONFIG.j
var ROUTER_BUNDLE_CONTENT = 'angular2/router + angular2/router/router_link_dsl - rxjs/* - ' +
ANGULAR2_BUNDLE_CONFIG.join(' - ');
var TESTING_BUNDLE_CONTENT =
'angular2/testing + angular2/http/testing + angular2/router/testing - rxjs/* - ' +
'angular2/testing + angular2/http/testing + angular2/router/testing + angular2/platform/testing/browser - rxjs/* - ' +
ANGULAR2_BUNDLE_CONFIG.join(' - ');
var UPGRADE_BUNDLE_CONTENT = 'angular2/upgrade - rxjs/* - ' + ANGULAR2_BUNDLE_CONFIG.join(' - ');
@ -176,8 +177,8 @@ var PAYLOAD_TESTS_CONFIG = {
return path.join(__dirname, CONFIG.dest.js.prod.es5, 'payload_tests', caseName,
'ts/' + packaging);
},
systemjs: {sizeLimits: {'uncompressed': 850 * 1024, 'gzip level=9': 165 * 1024}},
webpack: {sizeLimits: {'uncompressed': 550 * 1024, 'gzip level=9': 120 * 1024}}
systemjs: {sizeLimits: {'uncompressed': 880 * 1024, 'gzip level=9': 170 * 1024}},
webpack: {sizeLimits: {'uncompressed': 560 * 1024, 'gzip level=9': 130 * 1024}}
}
};
@ -344,9 +345,8 @@ gulp.task('lint', ['build.tools'], function() {
gulp.task('build/checkCircularDependencies', function(done) {
var madge = require('madge');
var dependencyObject = madge(CONFIG.dest.js.dev.es5, {
var dependencyObject = madge([CONFIG.dest.js.dev.es5], {
format: 'cjs',
paths: [CONFIG.dest.js.dev.es5],
extensions: ['.js'],
onParseFile: function(data) { data.src = data.src.replace(/\/\* circular \*\//g, "//"); }
});
@ -370,6 +370,10 @@ function jsServeDartJs() {
return jsserve(gulp, gulpPlugins, {path: CONFIG.dest.js.dart2js, port: 8002})();
}
function jsServeDartDevCompiler() {
return jsserve(gulp, gulpPlugins, {path: CONFIG.dest.js.dart_dev_compiler, port: 8003})();
}
function proxyServeDart() {
return jsserve(gulp, gulpPlugins, {
port: 8002,
@ -383,7 +387,7 @@ function proxyServeDart() {
// ------------------
// web servers
gulp.task('serve.js.dev', ['build.js.dev'], function(neverDone) {
gulp.task('serve.js.dev', ['build.js.dev', 'build.js.cjs'], function(neverDone) {
var watch = require('./tools/build/watch');
watch('modules/**', {ignoreInitial: true}, '!broccoli.js.dev');
@ -392,24 +396,24 @@ gulp.task('serve.js.dev', ['build.js.dev'], function(neverDone) {
gulp.task('serve.js.prod', jsServeProd);
gulp.task('serve.e2e.dev', ['build.js.dev', 'build.js.cjs', 'build.css.material'],
function(neverDone) {
var watch = require('./tools/build/watch');
gulp.task('serve.e2e.dev', ['build.js.dev', 'build.js.cjs'], function(neverDone) {
var watch = require('./tools/build/watch');
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.dev', '!build.js.cjs']);
jsServeDev();
});
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.dev', '!build.js.cjs']);
jsServeDev();
});
gulp.task('serve.e2e.prod', ['build.js.prod', 'build.js.cjs', 'build.css.material'],
function(neverDone) {
var watch = require('./tools/build/watch');
gulp.task('serve.e2e.prod', ['build.js.prod', 'build.js.cjs'], function(neverDone) {
var watch = require('./tools/build/watch');
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.prod', '!build.js.cjs']);
jsServeProd();
});
watch('modules/**', {ignoreInitial: true}, ['!broccoli.js.prod', '!build.js.cjs']);
jsServeProd();
});
gulp.task('serve.js.dart2js', jsServeDartJs);
gulp.task('serve.js.ddc', jsServeDartDevCompiler);
gulp.task('!proxyServeDart', proxyServeDart);
gulp.task('serve.dart', function(done) {
@ -441,7 +445,7 @@ gulp.task('serve.e2e.dart', ['build.js.cjs'], function(neverDone) {
// Note: we are not using build.dart as the dart analyzer takes too long...
watch('modules/**', {ignoreInitial: true}, ['!build/tree.dart', '!build.js.cjs']);
runSequence('build/packages.dart', 'build/pubspec.dart', 'build.dart.material.css', 'serve.dart');
runSequence('build/packages.dart', 'build/pubspec.dart', 'serve.dart');
});
@ -463,12 +467,12 @@ function runKarma(configFile, done) {
gulp.task('test.js', function(done) {
runSequence('test.unit.tools/ci', 'test.transpiler.unittest', 'test.unit.js/ci',
'test.unit.cjs/ci', 'test.typings', sequenceComplete(done));
'test.unit.cjs/ci', 'test.typings', 'check-public-api', sequenceComplete(done));
});
gulp.task('test.dart', function(done) {
runSequence('versions.dart', 'test.transpiler.unittest', 'test.unit.dart/ci',
'test.dart.angular2_testing/ci', sequenceComplete(done));
sequenceComplete(done));
});
gulp.task('versions.dart', function() { dartSdk.logVersion(DART_SDK); });
@ -627,13 +631,16 @@ gulp.task('!test.unit.router/karma-run', function(done) {
});
});
gulp.task('buildRouter.dev', function() { buildRouter(); });
gulp.task('buildRouter.dev', function() {
var modulesSrcDir = __dirname + '/modules';
var distDir = __dirname + '/dist';
buildRouter(modulesSrcDir, distDir);
});
gulp.task('test.unit.dart', function(done) {
printModulesWarning();
runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
'!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css',
'!test.unit.dart/karma-server', '!test.unit.dart/karma-run', function(error) {
'!build/remove-pub-symlinks', function(error) {
var watch = require('./tools/build/watch');
// if initial build failed (likely due to build or formatting step) then exit
@ -642,9 +649,10 @@ gulp.task('test.unit.dart', function(done) {
done(error);
return;
}
// treatTestErrorsAsFatal = false;
watch(['modules/angular2/**'], {ignoreInitial: true},
['!build/tree.dart', '!test.unit.dart/karma-run']);
watch(['modules/angular2/**'],
['!build/tree.dart', '!test.unit.dart/run/angular2']);
});
});
@ -703,7 +711,7 @@ gulp.task('!build.payload.js.webpack', function() {
.then(function() { // pad bundle with mandatory dependencies
return new Promise(function(resolve, reject) {
gulp.src([
'node_modules/zone.js/dist/zone-microtask.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/long-stack-trace-zone.js',
'node_modules/reflect-metadata/Reflect.js',
CASE_PATH + '/app-bundle.js'
@ -771,8 +779,7 @@ gulp.task('!checkAndReport.payload.js', function() {
gulp.task('watch.dart.dev', function(done) {
runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
'!build/change_detect.dart', '!build/remove-pub-symlinks', 'build.dart.material.css',
function(error) {
'!build/remove-pub-symlinks', function(error) {
var watch = require('./tools/build/watch');
// if initial build failed (likely due to build or formatting step) then exit
@ -782,24 +789,11 @@ gulp.task('watch.dart.dev', function(done) {
return;
}
watch(['modules/angular2/**'], {ignoreInitial: true}, ['!build/tree.dart']);
watch(['modules/angular2/**', 'modules_dart/**'], {ignoreInitial: true},
['!build/tree.dart', 'build/pure-packages.dart']);
});
});
gulp.task('!test.unit.dart/karma-run', function(done) {
// run the run command in a new process to avoid duplicate logging by both server and runner from
// a single process
runKarma('karma-dart.conf.js', done);
});
gulp.task('!test.unit.dart/karma-server', function() {
var karma = require('karma');
new karma.Server({configFile: __dirname + '/karma-dart.conf.js', reporters: 'dots'}).start();
});
gulp.task('test.unit.router/ci', function(done) {
var karma = require('karma');
@ -826,7 +820,7 @@ gulp.task('test.unit.js/ci', function(done) {
reporters: ['dots'],
browsers: browserConf.browsersToRun
},
done)
function(err) { done(); })
.start();
});
@ -847,25 +841,63 @@ gulp.task('test.unit.js.browserstack/ci', function(done) {
});
gulp.task('test.unit.dart/ci', function(done) {
var karma = require('karma');
var browserConf = getBrowsersFromCLI(null, true);
new karma.Server(
{
configFile: __dirname + '/karma-dart.conf.js',
singleRun: true,
reporters: ['dots'],
browsers: browserConf.browsersToRun
},
done)
.start();
runSequence('test.dart.dartium_symlink', '!test.unit.dart/run/angular2',
'!test.unit.dart/run/angular2_testing', '!test.unit.dart/run/benchpress',
sequenceComplete(done));
});
// At the moment, dart test requires dartium to be an executable on the path.
// Make a temporary directory and symlink dartium from there (just for this command)
// so that it can run.
// TODO(juliemr): this won't work with windows - remove the hack and make this platform agnostic.
var dartiumTmpdir = path.join(os.tmpdir(), 'dartium' + new Date().getTime().toString());
var dartiumPathPrefix = 'PATH=$PATH:' + dartiumTmpdir + ' ';
gulp.task(
'test.dart.dartium_symlink',
shell.task(['mkdir ' + dartiumTmpdir, 'ln -s $DARTIUM_BIN ' + dartiumTmpdir + '/dartium']));
gulp.task('!test.unit.dart/run/angular2', function() {
var pubtest = require('./tools/build/pubtest');
return pubtest({
dir: path.join(CONFIG.dest.dart, 'angular2'),
dartiumTmpdir: dartiumTmpdir,
command: DART_SDK.PUB,
files: '**/*_spec.dart',
bunchFiles: true,
useExclusiveTests: true
});
});
gulp.task('!test.unit.dart/run/angular2_testing', function() {
var pubtest = require('./tools/build/pubtest');
return pubtest({
dir: path.join(CONFIG.dest.dart, 'angular2_testing'),
dartiumTmpdir: dartiumTmpdir,
command: DART_SDK.PUB,
files: '**/*_test.dart',
useExclusiveTests: true
});
});
gulp.task('!test.unit.dart/run/benchpress', function() {
var pubtest = require('./tools/build/pubtest');
return pubtest({
dir: path.join(CONFIG.dest.dart, 'benchpress'),
dartiumTmpdir: dartiumTmpdir,
command: DART_SDK.PUB,
files: '**/*_spec.dart',
useExclusiveTests: true
});
});
gulp.task('test.unit.cjs/ci', function(done) {
runJasmineTests(['dist/js/cjs/{angular2,benchpress}/test/**/*_spec.js'], done);
});
gulp.task('check-public-api',
function(done) { runJasmineTests(['dist/tools/public_api_guard/**/*_spec.js'], done); });
gulp.task('test.unit.cjs', ['build/clean.js', 'build.tools'], function(neverDone) {
var watch = require('./tools/build/watch');
@ -880,21 +912,20 @@ gulp.task('test.unit.cjs', ['build/clean.js', 'build.tools'], function(neverDone
gulp.task('test.unit.dartvm', function(neverDone) {
var watch = require('./tools/build/watch');
runSequence(
'build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
'!build/change_detect.dart', '!test.unit.dartvm/run', function(error) {
// Watch for changes made in the TS and Dart code under "modules" and
// run ts2dart and test change detector generator prior to rerunning the
// tests.
watch('modules/angular2/**', {ignoreInitial: true},
['!build/tree.dart', '!build/change_detect.dart', '!test.unit.dartvm/run']);
runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
'!test.unit.dartvm/run', function(error) {
// Watch for changes made in the TS and Dart code under "modules" and
// run ts2dart and test change detector generator prior to rerunning the
// tests.
watch('modules/angular2/**', {ignoreInitial: true},
['!build/tree.dart', '!test.unit.dartvm/run']);
// Watch for changes made in Dart code under "modules_dart", then copy it
// to dist and run test change detector generator prior to retunning the
// tests.
watch('modules_dart/**', {ignoreInitial: true},
['build/pure-packages.dart', '!build/change_detect.dart', '!test.unit.dartvm/run']);
});
// Watch for changes made in Dart code under "modules_dart", then copy it
// to dist and run test change detector generator prior to retunning the
// tests.
watch('modules_dart/**', {ignoreInitial: true},
['build/pure-packages.dart', '!test.unit.dartvm/run']);
});
});
gulp.task('!test.unit.dartvm/run',
@ -925,24 +956,6 @@ gulp.task('test.server.dart', runServerDartTests(gulp, gulpPlugins, {dest: 'dist
gulp.task('test.transpiler.unittest',
function(done) { runJasmineTests(['tools/transpiler/unittest/**/*.js'], done); });
// At the moment, dart test requires dartium to be an executable on the path.
// Make a temporary directory and symlink dartium from there (just for this command)
// so that it can run.
var dartiumTmpdir = path.join(os.tmpdir(), 'dartium' + new Date().getTime().toString());
gulp.task('test.dart.angular2_testing/ci', ['build/pubspec.dart'], function(done) {
runSequence('test.dart.angular2_testing_symlink', 'test.dart.angular2_testing',
sequenceComplete(done));
});
gulp.task(
'test.dart.angular2_testing_symlink',
shell.task(['mkdir ' + dartiumTmpdir, 'ln -s $DARTIUM_BIN ' + dartiumTmpdir + '/dartium']));
gulp.task('test.dart.angular2_testing',
shell.task(['PATH=$PATH:' + dartiumTmpdir + ' pub run test -p dartium'],
{'cwd': 'dist/dart/angular2_testing'}));
// -----------------
// Pre-test checks
@ -968,22 +981,40 @@ gulp.task('static-checks', ['!build.tools'], function(done) {
// distributed in our npm package, and loaded from node_modules by
// the typescript compiler.
// Make sure the two typings tests are isolated, by running this one in a tempdir
// Make sure the typings tests are isolated, by running in a tempdir
var tmpdir = path.join(os.tmpdir(), 'test.typings', new Date().getTime().toString());
gulp.task('!pre.test.typings.layoutNodeModule', ['build.js.cjs'], function() {
return gulp.src(['dist/js/cjs/angular2/**/*', 'node_modules/rxjs/**'], {base: 'dist/js/cjs'})
gulp.task('!pre.test.typings.layoutNodeModule', function() {
return gulp.src(['dist/js/cjs/angular2/**/*', 'node_modules/rxjs/**/*'], {base: 'dist/js/cjs'})
.pipe(gulp.dest(path.join(tmpdir, 'node_modules')));
});
gulp.task('!pre.test.typings.copyTypingsSpec', function() {
return gulp.src(['typing_spec/*.ts'], {base: 'typing_spec'}).pipe(gulp.dest(path.join(tmpdir)));
gulp.task('!pre.test.typings.copyDeps', function() {
return gulp.src(
[
'modules/angular2/typings/angular-protractor/*.ts',
'modules/angular2/typings/jasmine/*.ts',
'modules/angular2/typings/selenium-webdriver/*.ts',
],
{base: 'modules/angular2/typings'})
.pipe(gulp.dest(tmpdir));
});
gulp.task('test.typings',
['!pre.test.typings.layoutNodeModule', '!pre.test.typings.copyTypingsSpec'], function() {
gulp.task('!pre.test.typings.copyTypingsSpec', function() {
return gulp.src(['modules/angular2/examples/**/*.ts']).pipe(gulp.dest(tmpdir));
});
gulp.task('!test.typings',
[
'!pre.test.typings.layoutNodeModule',
'!pre.test.typings.copyTypingsSpec',
'!pre.test.typings.copyDeps'
],
function() {
var tsc = require('gulp-typescript');
return gulp.src([tmpdir + '/**'])
return gulp.src([tmpdir + '/**/*.ts', '!' + tmpdir + '/node_modules/**/*'])
.pipe(tsc({
target: 'ES5',
target: 'ES6',
module: 'commonjs',
experimentalDecorators: true,
noImplicitAny: true,
@ -992,6 +1023,9 @@ gulp.task('test.typings',
}));
});
gulp.task('test.typings', ['build.js.cjs'],
function(done) { runSequence('!test.typings', sequenceComplete(done)); });
// -----------------
// orchestrated targets
@ -1011,6 +1045,7 @@ gulp.task('build/pure-packages.dart/standalone', function() {
'modules_dart/**/*',
'!modules_dart/**/*.proto',
'!modules_dart/**/packages{,/**}',
'!modules_dart/**/.packages',
'!modules_dart/payload{,/**}',
'!modules_dart/transform{,/**}',
])
@ -1034,15 +1069,15 @@ gulp.task('build/pure-packages.dart/angular2', function() {
// Builds all Dart packages, but does not compile them
gulp.task('build/packages.dart', function(done) {
runSequence('lint_protos.dart', 'build/tree.dart', 'build/pure-packages.dart',
runSequence('lint_protos.dart', 'pubget.dart', 'build/tree.dart', 'build/pure-packages.dart',
// Run after 'build/tree.dart' because broccoli clears the dist/dart folder
'!build/pubget.angular2.dart', '!build/change_detect.dart', sequenceComplete(done));
'!build/pubget.angular2.dart', sequenceComplete(done));
});
// Builds and compiles all Dart packages
gulp.task('build.dart', function(done) {
runSequence('build/packages.dart', 'build/pubspec.dart', 'build/analyze.dart',
'build/check.apidocs.dart', 'build.dart.material.css', sequenceComplete(done));
'build/check.apidocs.dart', sequenceComplete(done));
});
@ -1061,25 +1096,26 @@ gulp.task('!build.tools', function() {
.pipe(tsc({
target: 'ES5',
module: 'commonjs',
declaration: true,
// Don't use the version of typescript that gulp-typescript depends on
// see https://github.com/ivogabe/gulp-typescript#typescript-version
typescript: require('typescript')
}))
.on('error',
function(error) {
// nodejs doesn't propagate errors from the src stream into the final
// stream so we are
// forwarding the error into the final stream
stream.emit('error', error);
})
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/tools'))
.on('end', function() {
var AngularBuilder =
require('./dist/tools/broccoli/angular_builder').AngularBuilder;
angularBuilder =
new AngularBuilder({outputPath: 'dist', dartSDK: DART_SDK, logs: logs});
});
}));
stream =
merge2([stream.js.pipe(gulp.dest('dist/tools')), stream.dts.pipe(gulp.dest('dist/tools'))])
.on('error',
function(error) {
// nodejs doesn't propagate errors from the src stream into the final
// stream so we are
// forwarding the error into the final stream
stream.emit('error', error);
})
.pipe(sourcemaps.write('.'))
.on('end', function() {
var AngularBuilder = require('./dist/tools/broccoli/angular_builder').AngularBuilder;
angularBuilder =
new AngularBuilder({outputPath: 'dist', dartSDK: DART_SDK, logs: logs});
});
return stream;
});
@ -1101,9 +1137,8 @@ gulp.task('!broccoli.js.prod', () => angularBuilder.rebuildBrowserProdTree({
useBundles: cliArgs.useBundles
}));
gulp.task('build.js.dev', ['build/clean.js'], function(done) {
runSequence('broccoli.js.dev', 'build.css.material', sequenceComplete(done));
});
gulp.task('build.js.dev', ['build/clean.js'],
function(done) { runSequence('broccoli.js.dev', sequenceComplete(done)); });
gulp.task('build.js.prod', ['build.tools'],
function(done) { runSequence('!broccoli.js.prod', sequenceComplete(done)); });
@ -1171,7 +1206,8 @@ gulp.task('!bundle.js.prod', ['build.js.prod'], function() {
// minified production build
gulp.task('!bundle.js.min', ['build.js.prod'], function() {
var bundler = require('./tools/build/bundle');
var bundlerConfig = {sourceMaps: true, minify: true};
var bundlerConfig =
{sourceMaps: true, minify: true, mangle: false, uglify: {compress: {keep_fnames: true}}};
return bundler.bundle(bundleConfig, NG2_BUNDLE_CONTENT, './dist/build/angular2.min.js',
bundlerConfig)
@ -1344,7 +1380,7 @@ gulp.task('!bundle.ng.polyfills', ['clean'],
var JS_DEV_DEPS = [
licenseWrap('node_modules/zone.js/LICENSE', true),
'node_modules/zone.js/dist/zone-microtask.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/long-stack-trace-zone.js',
licenseWrap('node_modules/reflect-metadata/LICENSE', true),
'node_modules/reflect-metadata/Reflect.js'
@ -1431,70 +1467,7 @@ gulp.task('gen_protos.dart', function(done) {
done);
});
// change detection codegen
gulp.task('build.change_detect.dart', function(done) {
return runSequence('build/packages.dart', '!build/pubget.angular2.dart',
'!build/change_detect.dart', done);
});
gulp.task('!build/change_detect.dart', function(done) {
var fs = require('fs');
var spawn = require('child_process').spawn;
var changeDetectDir = path.join(CONFIG.dest.dart, 'angular2/test/core/change_detection/');
var srcDir = path.join(changeDetectDir, 'generator');
var destDir = path.join(changeDetectDir, 'generated');
var dartStream = fs.createWriteStream(path.join(destDir, 'change_detector_classes.dart'));
var genMain = path.join(srcDir, 'gen_change_detectors.dart');
var proc = spawn(DART_SDK.VM, [genMain], {stdio: ['ignore', 'pipe', 'inherit']});
proc.on('error', function(code) {
done(new Error('Failed while generating change detector classes. Please run manually: ' +
DART_SDK.VM + ' ' + dartArgs.join(' ')));
});
proc.on('close', function() {
dartStream.close();
done();
});
proc.stdout.pipe(dartStream);
});
// ------------
// angular material testing rules
gulp.task('build.css.material', function() {
var autoprefixer = require('gulp-autoprefixer');
var sass = require('gulp-sass');
return gulp.src('modules/*/src/**/*.scss')
.pipe(sass())
.pipe(autoprefixer())
.pipe(gulp.dest(CONFIG.dest.js.prod.es5))
.pipe(gulp.dest(CONFIG.dest.js.dev.es5))
.pipe(gulp.dest(CONFIG.dest.js.dart2js + '/examples/packages'));
});
gulp.task('build.js.material', function(done) {
runSequence('build.js.dev', 'build.css.material', sequenceComplete(done));
});
gulp.task('build.dart2js.material', function(done) {
runSequence('build.dart', 'build.css.material', sequenceComplete(done));
});
gulp.task('build.dart.material.css', function() {
var autoprefixer = require('gulp-autoprefixer');
var sass = require('gulp-sass');
return gulp.src('dist/dart/angular2_material/src/**/*.scss')
.pipe(sass())
.pipe(autoprefixer())
.pipe(gulp.dest('dist/dart/angular2_material/lib/src'));
});
gulp.task('build.dart.material', ['build/packages.dart'], function(done) {
runSequence('build/packages.dart', 'build.dart.material.css', sequenceComplete(done));
});
gulp.task('cleanup.builder', function() { return angularBuilder.cleanup(); });

View File

@ -1,86 +0,0 @@
// This module provides a customFileHandler for karma
// that serves files with urls like /packages_<timestamp>/...
// with maximum cache.
// We are using these urls when we spawn isolates
// so that the isolates don't reload files every time.
var common = require('karma/lib/middleware/common');
var fs = require('fs');
var DART_EVAL_PATH_RE = /.*\/packages_\d+\/(.*)$/;
module.exports = createFactory;
function createFactory(proxyPaths) {
return {
'framework:dart-evalcache': ['factory', dartEvalCacheFactory]
};
function dartEvalCacheFactory(emitter, logger, customFileHandlers) {
var filesPromise = new common.PromiseContainer();
emitter.on('file_list_modified', function(files) {
filesPromise.set(Promise.resolve(files));
});
var serveFile = common.createServeFile(fs);
var log = logger.create('dart-evalcache');
customFileHandlers.push({
urlRegex: DART_EVAL_PATH_RE,
handler: handler
});
// See source_files handler
function handler(request, response, fa, fb, basePath) {
return filesPromise.then(function(files) {
try {
var requestedFilePath = mapUrlToFile(request.url, proxyPaths, basePath, log);
// TODO(vojta): change served to be a map rather then an array
var file = findByPath(files.served, requestedFilePath);
if (file) {
serveFile(file.contentPath || file.path, response, function() {
common.setHeavyCacheHeaders(response);
}, file.content);
} else {
response.writeHead(404);
response.end('Not found');
}
} catch (e) {
log.error(e.stack);
response.writeHead(500);
response.end('Error', e.stack);
}
});
}
};
}
function mapUrlToFile(url, proxyPaths, basePath, log) {
var originalUrl = url;
url = url.indexOf('?') > -1 ? url.substring(0, url.indexOf('?')) : url;
var match = DART_EVAL_PATH_RE.exec(url);
var packagePath = match[1];
var result = null;
var lastProxyFromLength = 0;
Object.keys(proxyPaths).forEach(function(proxyFrom) {
if (startsWith(packagePath, proxyFrom) && proxyFrom.length > lastProxyFromLength) {
lastProxyFromLength = proxyFrom.length;
result = proxyPaths[proxyFrom] + packagePath.substring(proxyFrom.length);
}
});
return basePath + '/' + result;
}
function startsWith(string, subString) {
return string.length >= subString.length && string.slice(0, subString.length) === subString;
}
function findByPath(files, path) {
for (var i = 0; i < files.length; i++) {
if (files[i].path === path) {
return files[i];
}
}
return null;
}

View File

@ -1,82 +0,0 @@
var browserProvidersConf = require('./browser-providers.conf.js');
var packageSources = {
// Dependencies installed with `pub install`.
'unittest': 'packages/unittest',
'guinness': 'packages/guinness',
'matcher': 'packages/matcher',
'stack_trace': 'packages/stack_trace',
'collection': 'packages/collection',
'path': 'packages/path',
'observe': 'packages/observe',
'quiver': 'packages/quiver',
'intl': 'packages/intl',
'smoke': 'packages/smoke',
'logging': 'packages/logging',
'utf': 'packages/utf',
// Local dependencies, transpiled from the source.
'angular2': 'dist/dart/angular2/lib',
'angular2/test/': 'dist/dart/angular2/test/',
'http': 'dist/dart/http/lib',
'angular2_material': 'dist/dart/angular2_material/lib',
'benchpress': 'dist/dart/benchpress/lib',
'examples': 'dist/dart/examples/lib'
};
var proxyPaths = {};
Object.keys(packageSources).map(function(packageName) {
var filePath = packageSources[packageName];
proxyPaths['/packages/'+packageName] = '/base/'+filePath;
});
// Karma configuration
// Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT)
module.exports = function(config) {
config.set({
frameworks: ['dart-unittest', 'dart-evalcache'],
files: [
// Init and configure guiness.
{pattern: 'test-init.dart', included: true},
// Unit test files needs to be included.
{pattern: 'dist/dart/**/*_spec.dart', included: true, watched: false},
// Karma-dart via the dart-unittest framework generates
// `__adapter_unittest.dart` that imports these files.
{pattern: 'dist/dart/**', included: false, watched: false},
// Dependencies, installed with `pub install`.
{pattern: 'packages/**/*.dart', included: false, watched: false},
// Init and configure guiness.
{pattern: 'test-main.dart', included: true},
{pattern: 'modules/**/test/**/static_assets/**', included: false, watched: false},
],
exclude: [
'dist/dart/**/packages/**',
'modules/angular1_router/**'
],
karmaDartImports: {
guinness: 'package:guinness/guinness_html.dart'
},
// Map packages to the correct urls where Karma serves them.
proxies: proxyPaths,
customLaunchers: browserProvidersConf.customLaunchers,
browsers: ['DartiumWithWebPlatform'],
port: 9877,
plugins: [
require('karma-dart'),
require('karma-chrome-launcher'),
require('karma-sauce-launcher'),
require('./karma-dart-evalcache')(packageSources)
]
});
};

View File

@ -17,10 +17,11 @@ module.exports = function(config) {
// include Angular v1 for upgrade module testing
'node_modules/angular/angular.min.js',
// zone-microtask must be included first as it contains a Promise monkey patch
'node_modules/zone.js/dist/zone-microtask.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/zone.js/dist/long-stack-trace-zone.js',
'node_modules/zone.js/dist/jasmine-patch.js',
'node_modules/zone.js/dist/async-test.js',
'node_modules/zone.js/dist/fake-async-test.js',
// Including systemjs because it defines `__eval`, which produces correct stack traces.
'modules/angular2/src/testing/shims_for_IE.js',

View File

@ -4,35 +4,47 @@ var fs = require('fs');
var ts = require('typescript');
var files = [
'lifecycle_annotations_impl.ts',
'utils.ts',
'url_parser.ts',
'route_recognizer.ts',
'route_config_impl.ts',
'async_route_handler.ts',
'sync_route_handler.ts',
'component_recognizer.ts',
'lifecycle/lifecycle_annotations_impl.ts',
'lifecycle/route_lifecycle_reflector.ts',
'route_config/route_config_impl.ts',
'route_config/route_config_normalizer.ts',
'rules/route_handlers/async_route_handler.ts',
'rules/route_handlers/sync_route_handler.ts',
'rules/rules.ts',
'rules/rule_set.ts',
'rules/route_paths/route_path.ts',
'rules/route_paths/param_route_path.ts',
'rules/route_paths/regex_route_path.ts',
'instruction.ts',
'path_recognizer.ts',
'route_config_nomalizer.ts',
'route_lifecycle_reflector.ts',
'route_registry.ts',
'router.ts'
];
var PRELUDE = '(function(){\n';
var POSTLUDE = '\n}());\n';
var FACADES = fs.readFileSync(__dirname + '/lib/facades.es5', 'utf8');
var DIRECTIVES = fs.readFileSync(__dirname + '/src/ng_outlet.ts', 'utf8');
var moduleTemplate = fs.readFileSync(__dirname + '/src/module_template.js', 'utf8');
function main() {
var dir = __dirname + '/../angular2/src/router/';
function main(modulesDirectory) {
var angular1RouterModuleDirectory = modulesDirectory + '/angular1_router';
var facades = fs.readFileSync(
angular1RouterModuleDirectory + '/lib/facades.es5', 'utf8');
var directives = fs.readFileSync(
angular1RouterModuleDirectory + '/src/ng_outlet.ts', 'utf8');
var moduleTemplate = fs.readFileSync(
angular1RouterModuleDirectory + '/src/module_template.js', 'utf8');
var dir = modulesDirectory + '/angular2/src/router/';
var sharedCode = files.reduce(function (prev, file) {
return prev + transform(fs.readFileSync(dir + file, 'utf8'));
}, '');
var out = moduleTemplate.replace('//{{FACADES}}', FACADES).replace('//{{SHARED_CODE}}', sharedCode);
return PRELUDE + transform(DIRECTIVES) + out + POSTLUDE;
// we have to use a function callback for replace to prevent it from interpreting `$`
// as a replacement command character
var out = moduleTemplate.replace('//{{FACADES}}', function() { return facades; })
.replace('//{{SHARED_CODE}}', function() { return sharedCode; });
return PRELUDE + transform(directives) + out + POSTLUDE;
}
/*
@ -41,9 +53,10 @@ function main() {
*/
var IMPORT_RE = new RegExp("import \\{?([\\w\\n_, ]+)\\}? from '(.+)';?", 'g');
var INJECT_RE = new RegExp("@Inject\\(ROUTER_PRIMARY_COMPONENT\\)", 'g');
var IMJECTABLE_RE = new RegExp("@Injectable\\(\\)", 'g');
var INJECTABLE_RE = new RegExp("@Injectable\\(\\)", 'g');
var REQUIRE_RE = new RegExp("require\\('(.*?)'\\);", 'g');
function transform(contents) {
contents = contents.replace(INJECT_RE, '').replace(IMJECTABLE_RE, '');
contents = contents.replace(INJECT_RE, '').replace(INJECTABLE_RE, '');
contents = contents.replace(IMPORT_RE, function (match, imports, includePath) {
//TODO: remove special-case
if (isFacadeModule(includePath) || includePath === './router_outlet') {
@ -51,10 +64,15 @@ function transform(contents) {
}
return match;
});
return ts.transpile(contents, {
contents = ts.transpile(contents, {
target: ts.ScriptTarget.ES5,
module: ts.ModuleKind.CommonJS
});
// Rename require functions from transpiled imports
contents = contents.replace(REQUIRE_RE, 'routerRequire(\'$1\');');
return contents;
}
function isFacadeModule(modulePath) {
@ -62,10 +80,29 @@ function isFacadeModule(modulePath) {
modulePath === 'angular2/src/core/reflection/reflection';
}
module.exports = function () {
var dist = __dirname + '/../../dist';
if (!fs.existsSync(dist)) {
fs.mkdirSync(dist);
module.exports = function(modulesDirectory, outputDirectory) {
if (!fs.existsSync(outputDirectory)) {
fs.mkdirSync(outputDirectory);
}
fs.writeFileSync(dist + '/angular_1_router.js', main());
fs.writeFileSync(
outputDirectory + '/angular_1_router.js', main(modulesDirectory));
};
// CLI entry point
if (require.main === module) {
try {
var args = process.argv;
args.shift(); // node
args.shift(); // scriptfile.js
if (args.length < 2) {
console.log("usage: $0 outFile path/to/modules");
process.exit(1);
}
var outfile = args.shift();
var directory = args.shift();
fs.writeFileSync(outfile, main(directory));
} catch (e) {
console.log(e.message);
process.exit(1);
}
}

View File

@ -12,9 +12,9 @@
<script src="../../dist/angular_1_router.js"></script>
<script>
angular.module('myApp', ['ngComponentRouter'])
.controller('MyCtrl', ['$router', function ($router) {
console.log($router);
$router.navigateByUrl('/')
.controller('MyCtrl', ['$rootRouter', function ($rootRouter) {
console.log($rootRouter);
$rootRouter.navigateByUrl('/')
.then(console.log.bind(console, 'resolve'), console.log.bind(console, 'reject'));
}]);
</script>

View File

@ -173,6 +173,10 @@ var StringMapWrapper = {
var List = Array;
var ListWrapper = {
toJSON: function(l) {
return JSON.stringify(l);
},
clear: function (l) {
l.length = 0;
},
@ -247,6 +251,10 @@ var ListWrapper = {
};
var StringWrapper = {
charCodeAt: function(s, i) {
return s.charCodeAt(i);
},
equals: function (s1, s2) {
return s1 === s2;
},
@ -303,8 +311,14 @@ Location.prototype.subscribe = function () {
//TODO: implement
};
Location.prototype.path = function () {
return $location.path();
return $location.url();
};
Location.prototype.go = function (url) {
return $location.path(url);
Location.prototype.go = function (path, query) {
return $location.url(path + query);
};
Location.prototype.prepareExternalUrl = function(url) {
if (url.length > 0 && !url.startsWith('/')) {
url = '/' + url;
}
return $location.$$html5 ? '.' + url : '#' + $locationHashPrefix + url;
};

View File

@ -4,9 +4,33 @@ angular.module('ngComponentRouter').
// Because Angular 1 has no notion of a root component, we use an object with unique identity
// to represent this. Can be overloaded with a component name
value('$routerRootComponent', new Object()).
factory('$router', ['$q', '$location', '$$directiveIntrospector', '$browser', '$rootScope', '$injector', '$routerRootComponent', routerFactory]);
function routerFactory($q, $location, $$directiveIntrospector, $browser, $rootScope, $injector, $routerRootComponent) {
// Unfortunately, $location doesn't expose what the current hashPrefix is
// So we have to monkey patch the $locationProvider to capture this value
provider('$locationHashPrefix', ['$locationProvider', $locationHashPrefixProvider]).
factory('$rootRouter', ['$q', '$location', '$browser', '$rootScope', '$injector', '$routerRootComponent', '$locationHashPrefix', routerFactory]);
function $locationHashPrefixProvider($locationProvider) {
// Get hold of the original hashPrefix method
var hashPrefixFn = $locationProvider.hashPrefix.bind($locationProvider);
// Read the current hashPrefix (in case it was set before this monkey-patch occurred)
var hashPrefix = hashPrefixFn();
// Override the helper so that we can read any changes to the prefix (after this monkey-patch)
$locationProvider.hashPrefix = function(prefix) {
if (angular.isDefined(prefix)) {
hashPrefix = prefix;
}
return hashPrefixFn(prefix);
}
// Return the final hashPrefix as the value of this service
this.$get = function() { return hashPrefix; };
}
function routerFactory($q, $location, $browser, $rootScope, $injector, $routerRootComponent, $locationHashPrefix) {
// When this file is processed, the line below is replaced with
// the contents of `../lib/facades.es5`.
@ -17,17 +41,30 @@ function routerFactory($q, $location, $$directiveIntrospector, $browser, $rootSc
OpaqueToken: function () {},
Inject: function () {}
};
var require = function () {return exports;};
var routerRequire = function () {return exports;};
// When this file is processed, the line below is replaced with
// the contents of the compiled TypeScript classes.
//{{SHARED_CODE}}
function getComponentConstructor(name) {
var serviceName = name + 'Directive';
if ($injector.has(serviceName)) {
var definitions = $injector.get(serviceName);
if (definitions.length > 1) {
throw new BaseException('too many directives named "' + name + '"');
}
return definitions[0].controller;
} else {
throw new BaseException('directive "' + name + '" is not registered');
}
}
//TODO: this is a hack to replace the exiting implementation at run-time
exports.getCanActivateHook = function (directiveName) {
var factory = $$directiveIntrospector.getTypeByName(directiveName);
return factory && factory.$canActivate && function (next, prev) {
return $injector.invoke(factory.$canActivate, null, {
var controller = getComponentConstructor(directiveName);
return controller.$canActivate && function (next, prev) {
return $injector.invoke(controller.$canActivate, null, {
$nextInstruction: next,
$prevInstruction: prev
});
@ -45,19 +82,34 @@ function routerFactory($q, $location, $$directiveIntrospector, $browser, $rootSc
var RouteRegistry = exports.RouteRegistry;
var RootRouter = exports.RootRouter;
// Override this method to actually get hold of the child routes
RouteRegistry.prototype.configFromComponent = function (component) {
var that = this;
if (isString(component)) {
// Don't read the annotations component a type more than once
// this prevents an infinite loop if a component routes recursively.
if (this._rules.has(component)) {
return;
}
var controller = getComponentConstructor(component);
if (angular.isArray(controller.$routeConfig)) {
controller.$routeConfig.forEach(function (config) {
var loader = config.loader;
if (isPresent(loader)) {
config = angular.extend({}, config, { loader: function() { return $injector.invoke(loader); } });
}
that.config(component, config);
});
}
}
}
var registry = new RouteRegistry($routerRootComponent);
var location = new Location();
$$directiveIntrospector(function (name, factory) {
if (angular.isArray(factory.$routeConfig)) {
factory.$routeConfig.forEach(function (config) {
registry.config(name, config);
});
}
});
var router = new RootRouter(registry, location, $routerRootComponent);
$rootScope.$watch(function () { return $location.path(); }, function (path) {
$rootScope.$watch(function () { return $location.url(); }, function (path) {
if (router.lastNavigationAttempt !== path) {
router.navigateByUrl(path);
}

View File

@ -1,51 +1,6 @@
///<reference path="../typings/angularjs/angular.d.ts"/>
/*
* decorates $compileProvider so that we have access to routing metadata
*/
function compilerProviderDecorator($compileProvider,
$$directiveIntrospectorProvider: DirectiveIntrospectorProvider) {
let directive = $compileProvider.directive;
$compileProvider.directive = function(name: string, factory: Function) {
$$directiveIntrospectorProvider.register(name, factory);
return directive.apply(this, arguments);
};
}
/*
* private service that holds route mappings for each controller
*/
class DirectiveIntrospectorProvider {
private directiveBuffer: any[] = [];
private directiveFactoriesByName: {[name: string]: Function} = {};
private onDirectiveRegistered: (name: string, factory: Function) => any = null;
register(name: string, factory: Function) {
if (angular.isArray(factory)) {
factory = factory[factory.length - 1];
}
this.directiveFactoriesByName[name] = factory;
if (this.onDirectiveRegistered) {
this.onDirectiveRegistered(name, factory);
} else {
this.directiveBuffer.push({name: name, factory: factory});
}
}
$get() {
let fn: any = newOnControllerRegistered => {
this.onDirectiveRegistered = newOnControllerRegistered;
while (this.directiveBuffer.length > 0) {
let directive = this.directiveBuffer.pop();
this.onDirectiveRegistered(directive.name, directive.factory);
}
};
fn.getTypeByName = name => this.directiveFactoriesByName[name];
return fn;
}
}
/**
* @name ngOutlet
@ -61,8 +16,8 @@ class DirectiveIntrospectorProvider {
*
* The value for the `ngOutlet` attribute is optional.
*/
function ngOutletDirective($animate, $q: ng.IQService, $router) {
let rootRouter = $router;
function ngOutletDirective($animate, $q: ng.IQService, $rootRouter) {
let rootRouter = $rootRouter;
return {
restrict: 'AE',
@ -145,7 +100,7 @@ function ngOutletDirective($animate, $q: ng.IQService, $router) {
}
activate(instruction) {
let previousInstruction = this.currentInstruction;
this.previousInstruction = this.currentInstruction;
this.currentInstruction = instruction;
let componentName = this.controller.$$componentName = instruction.componentType;
@ -154,11 +109,14 @@ function ngOutletDirective($animate, $q: ng.IQService, $router) {
throw new Error('Component is not a string for ' + instruction.urlPath);
}
this.controller.$$routeParams = instruction.params;
this.controller.$$template = '<div ' + dashCase(componentName) + '></div>';
this.controller.$$template = '<' + dashCase(componentName) + ' $router="::$$router"></' +
dashCase(componentName) + '>';
this.controller.$$router = this.router.childRouter(instruction.componentType);
this.controller.$$outlet = this;
let newScope = scope.$new();
newScope.$$router = this.controller.$$router;
this.deferredActivation = $q.defer();
let clone = $transclude(newScope, clone => {
$animate.enter(clone, null, this.currentElement || element);
@ -167,15 +125,7 @@ function ngOutletDirective($animate, $q: ng.IQService, $router) {
this.currentElement = clone;
this.currentScope = newScope;
// TODO: prefer the other directive retrieving the controller
// by debug mode
this.currentController = this.currentElement.children().eq(0).controller(componentName);
if (this.currentController && this.currentController.$routerOnActivate) {
return this.currentController.$routerOnActivate(instruction, previousInstruction);
}
return $q.when();
return this.deferredActivation.promise;
}
}
@ -198,21 +148,32 @@ function ngOutletFillContentDirective($compile) {
link: (scope, element, attrs, ctrl) => {
let template = ctrl.$$template;
element.html(template);
let link = $compile(element.contents());
link(scope);
// TODO: move to primary directive
let componentInstance = scope[ctrl.$$componentName];
if (componentInstance) {
ctrl.$$currentComponent = componentInstance;
componentInstance.$router = ctrl.$$router;
componentInstance.$routeParams = ctrl.$$routeParams;
}
$compile(element.contents())(scope);
}
};
}
function routerTriggerDirective($q) {
return {
require: '^ngOutlet',
priority: -1000,
link: function(scope, element, attr, ngOutletCtrl) {
var promise = $q.when();
var outlet = ngOutletCtrl.$$outlet;
var currentComponent = outlet.currentController =
element.controller(ngOutletCtrl.$$componentName);
if (currentComponent.$routerOnActivate) {
promise = $q.when(currentComponent.$routerOnActivate(outlet.currentInstruction,
outlet.previousInstruction));
}
promise.then(outlet.deferredActivation.resolve, outlet.deferredActivation.reject);
}
};
}
/**
* @name ngLink
* @description
@ -225,8 +186,8 @@ function ngOutletFillContentDirective($compile) {
*
* ```js
* angular.module('myApp', ['ngComponentRouter'])
* .controller('AppController', ['$router', function($router) {
* $router.config({ path: '/user/:id', component: 'user' });
* .controller('AppController', ['$rootRouter', function($rootRouter) {
* $rootRouter.config({ path: '/user/:id', component: 'user' });
* this.user = { name: 'Brian', id: 123 };
* });
* ```
@ -237,23 +198,32 @@ function ngOutletFillContentDirective($compile) {
* </div>
* ```
*/
function ngLinkDirective($router, $parse) {
let rootRouter = $router;
function ngLinkDirective($rootRouter, $parse) {
return {require: '?^^ngOutlet', restrict: 'A', link: ngLinkDirectiveLinkFn};
function ngLinkDirectiveLinkFn(scope, element, attrs, ctrl) {
let router = (ctrl && ctrl.$$router) || rootRouter;
let router = (ctrl && ctrl.$$router) || $rootRouter;
if (!router) {
return;
}
let instruction = null;
let navigationInstruction = null;
let link = attrs.ngLink || '';
function getLink(params) {
instruction = router.generate(params);
return './' + angular.stringifyInstruction(instruction);
navigationInstruction = router.generate(params);
scope.$watch(function() { return router.isRouteActive(navigationInstruction); },
function(active) {
if (active) {
element.addClass('ng-link-active');
} else {
element.removeClass('ng-link-active');
}
});
const navigationHref = navigationInstruction.toLinkUrl();
return $rootRouter._location.prepareExternalUrl(navigationHref);
}
let routeParamsGetter = $parse(link);
@ -267,11 +237,11 @@ function ngLinkDirective($router, $parse) {
}
element.on('click', event => {
if (event.which !== 1 || !instruction) {
if (event.which !== 1 || !navigationInstruction) {
return;
}
$router.navigateByInstruction(instruction);
$rootRouter.navigateByInstruction(navigationInstruction);
event.preventDefault();
});
}
@ -285,13 +255,7 @@ function dashCase(str: string): string {
* A module for adding new a routing system Angular 1.
*/
angular.module('ngComponentRouter', [])
.directive('ngOutlet', ngOutletDirective)
.directive('ngOutlet', ngOutletFillContentDirective)
.directive('ngLink', ngLinkDirective);
/*
* A module for inspecting controller constructors
*/
angular.module('ng')
.provider('$$directiveIntrospector', DirectiveIntrospectorProvider)
.config(compilerProviderDecorator);
.directive('ngOutlet', ['$animate', '$q', '$rootRouter', ngOutletDirective])
.directive('ngOutlet', ['$compile', ngOutletFillContentDirective])
.directive('ngLink', ['$rootRouter', '$parse', ngLinkDirective])
.directive('$router', ['$q', routerTriggerDirective]);

View File

@ -1,4 +1,4 @@
/** @license Copyright 2014-2015 Google, Inc. http://github.com/angular/angular/LICENSE */
/** @license Copyright 2014-2016 Google, Inc. http://github.com/angular/angular/LICENSE */
(function () {
'use strict';
@ -24,12 +24,12 @@
.directive('a', anchorLinkDirective)
// Connects the legacy $routeProvider config shim to Component Router's config.
.run(['$route', '$router', function ($route, $router) {
.run(['$route', '$rootRouter', function ($route, $rootRouter) {
$route.$$subscribe(function (routeDefinition) {
if (!angular.isArray(routeDefinition)) {
routeDefinition = [routeDefinition];
}
$router.config(routeDefinition);
$rootRouter.config(routeDefinition);
});
}]);
@ -116,53 +116,41 @@
console.warn('Route for "' + path + '" should use "controllerAs".');
}
var directiveName = routeObjToRouteName(routeCopy, path);
var componentName = routeObjToRouteName(routeCopy, path);
if (!directiveName) {
if (!componentName) {
throw new Error('Could not determine a name for route "' + path + '".');
}
routeDefinition.component = directiveName;
routeDefinition.name = route.name || upperCase(directiveName);
routeDefinition.component = componentName;
routeDefinition.name = route.name || upperCase(componentName);
var directiveController = routeCopy.controller;
var directiveDefinition = {
scope: false,
var componentDefinition = {
controller: directiveController,
controllerAs: routeCopy.controllerAs,
templateUrl: routeCopy.templateUrl,
template: routeCopy.template
};
controllerAs: routeCopy.controllerAs
var directiveFactory = function () {
return directiveDefinition;
};
if (routeCopy.templateUrl) componentDefinition.templateUrl = routeCopy.templateUrl;
if (routeCopy.template) componentDefinition.template = routeCopy.template;
// if we have route resolve options, prepare a wrapper controller
if (directiveController && routeCopy.resolve) {
var originalController = directiveController;
var resolvedLocals = {};
directiveDefinition.controller = ['$injector', '$scope', function ($injector, $scope) {
componentDefinition.controller = ['$injector', '$scope', function ($injector, $scope) {
var locals = angular.extend({
$scope: $scope
}, resolvedLocals);
var ctrl = $injector.instantiate(originalController, locals);
if (routeCopy.controllerAs) {
locals.$scope[routeCopy.controllerAs] = ctrl;
}
return ctrl;
return $injector.instantiate(originalController, locals);
}];
// we take care of controllerAs in the directive controller wrapper
delete directiveDefinition.controllerAs;
// we resolve the locals in a canActivate block
directiveFactory.$canActivate = function() {
componentDefinition.controller.$canActivate = function() {
var locals = angular.extend({}, routeCopy.resolve);
angular.forEach(locals, function(value, key) {
@ -179,7 +167,7 @@
}
// register the dynamically created directive
$compileProvider.directive(directiveName, directiveFactory);
$compileProvider.component(componentName, componentDefinition);
}
if (subscriptionFn) {
subscriptionFn(routeDefinition);
@ -253,12 +241,12 @@
}
function $routeParamsFactory($router, $rootScope) {
function $routeParamsFactory($rootRouter, $rootScope) {
// the identity of this object cannot change
var paramsObj = {};
$rootScope.$on('$routeChangeSuccess', function () {
var newParams = $router._currentInstruction && $router._currentInstruction.component.params;
var newParams = $rootRouter.currentInstruction && $rootRouter.currentInstruction.component.params;
angular.forEach(paramsObj, function (val, name) {
delete paramsObj[name];
@ -274,7 +262,7 @@
/**
* Allows normal anchor links to kick off routing.
*/
function anchorLinkDirective($router) {
function anchorLinkDirective($rootRouter) {
return {
restrict: 'E',
link: function (scope, element) {
@ -293,8 +281,8 @@
}
var href = element.attr(hrefAttrName);
if (href && $router.recognize(href)) {
$router.navigateByUrl(href);
if (href && $rootRouter.recognize(href)) {
$rootRouter.navigateByUrl(href);
event.preventDefault();
}
});

View File

@ -1,38 +0,0 @@
'use strict';
describe('$$directiveIntrospector', function () {
var $compileProvider;
beforeEach(function() {
module('ng');
module('ngComponentRouter');
module(function(_$compileProvider_) {
$compileProvider = _$compileProvider_;
});
});
it('should call the introspector function whenever a directive factory is registered', inject(function ($$directiveIntrospector) {
var spy = jasmine.createSpy();
$$directiveIntrospector(spy);
function myDir(){}
$compileProvider.directive('myDir', myDir);
expect(spy).toHaveBeenCalledWith('myDir', myDir);
}));
it('should call the introspector function whenever a directive factory is registered with array annotations', inject(function ($$directiveIntrospector) {
var spy = jasmine.createSpy();
$$directiveIntrospector(spy);
function myDir(){}
$compileProvider.directive('myDir', ['foo', myDir]);
expect(spy).toHaveBeenCalledWith('myDir', myDir);
}));
it('should retrieve a factory based on directive name', inject(function ($$directiveIntrospector) {
function myDir(){}
$compileProvider.directive('myDir', ['foo', myDir]);
expect($$directiveIntrospector.getTypeByName('myDir')).toBe(myDir);
}));
});

View File

@ -5,7 +5,7 @@ describe('ngOutlet animations', function () {
$animate,
$compile,
$rootScope,
$router,
$rootRouter,
$compileProvider;
beforeEach(function () {
@ -17,15 +17,18 @@ describe('ngOutlet animations', function () {
$compileProvider = _$compileProvider_;
});
inject(function (_$animate_, _$compile_, _$rootScope_, _$router_) {
inject(function (_$animate_, _$compile_, _$rootScope_, _$rootRouter_) {
$animate = _$animate_;
$compile = _$compile_;
$rootScope = _$rootScope_;
$router = _$router_;
$rootRouter = _$rootRouter_;
});
registerComponent('userCmp', {
template: '<div>hello {{userCmp.$routeParams.name}}</div>'
template: '<div>hello {{userCmp.$routeParams.name}}</div>',
$routerOnActivate: function(next) {
this.$routeParams = next.params;
}
});
});
@ -38,11 +41,11 @@ describe('ngOutlet animations', function () {
compile('<div ng-outlet></div>');
$router.config([
$rootRouter.config([
{ path: '/user/:name', component: 'userCmp' }
]);
$router.navigateByUrl('/user/brian');
$rootRouter.navigateByUrl('/user/brian');
$rootScope.$digest();
expect(elt.text()).toBe('hello brian');
@ -51,7 +54,7 @@ describe('ngOutlet animations', function () {
expect(item.event).toBe('enter');
// navigate to pete
$router.navigateByUrl('/user/pete');
$rootRouter.navigateByUrl('/user/pete');
$rootScope.$digest();
expect(elt.text()).toBe('hello pete');

View File

@ -4,7 +4,7 @@ describe('Navigation lifecycle', function () {
var elt,
$compile,
$rootScope,
$router,
$rootRouter,
$compileProvider;
beforeEach(function () {
@ -14,10 +14,10 @@ describe('Navigation lifecycle', function () {
$compileProvider = _$compileProvider_;
});
inject(function (_$compile_, _$rootScope_, _$router_) {
inject(function (_$compile_, _$rootScope_, _$rootRouter_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
$router = _$router_;
$rootRouter = _$rootRouter_;
});
registerComponent('oneCmp', {
@ -38,12 +38,12 @@ describe('Navigation lifecycle', function () {
$routerOnActivate: spy
});
$router.config([
$rootRouter.config([
{ path: '/a', component: 'activateCmp' }
]);
compile('<div>outer { <div ng-outlet></div> }</div>');
$router.navigateByUrl('/a');
$rootRouter.navigateByUrl('/a');
$rootScope.$digest();
expect(spy).toHaveBeenCalled();
@ -56,12 +56,12 @@ describe('Navigation lifecycle', function () {
$routerOnActivate: spy
});
$router.config([
$rootRouter.config([
{ path: '/user/:name', component: 'userCmp' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/user/brian');
$rootRouter.navigateByUrl('/user/brian');
$rootScope.$digest();
expect(spy).toHaveBeenCalledWith(instructionFor('userCmp'), undefined);
@ -75,15 +75,15 @@ describe('Navigation lifecycle', function () {
$routerOnActivate: spy
});
$router.config([
$rootRouter.config([
{ path: '/user/:name', component: 'oneCmp' },
{ path: '/post/:id', component: 'activateCmp' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/user/brian');
$rootRouter.navigateByUrl('/user/brian');
$rootScope.$digest();
$router.navigateByUrl('/post/123');
$rootRouter.navigateByUrl('/post/123');
$rootScope.$digest();
expect(spy).toHaveBeenCalledWith(instructionFor('activateCmp'),
instructionFor('oneCmp'));
@ -98,12 +98,12 @@ describe('Navigation lifecycle', function () {
}
});
$router.config([
$rootRouter.config([
{ path: '/user', component: 'userCmp' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/user');
$rootRouter.navigateByUrl('/user');
$rootScope.$digest();
expect(injectedScope).toBeDefined();
@ -116,15 +116,15 @@ describe('Navigation lifecycle', function () {
$routerOnDeactivate: spy
});
$router.config([
$rootRouter.config([
{ path: '/a', component: 'deactivateCmp' },
{ path: '/b', component: 'oneCmp' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/a');
$rootRouter.navigateByUrl('/a');
$rootScope.$digest();
$router.navigateByUrl('/b');
$rootRouter.navigateByUrl('/b');
$rootScope.$digest();
expect(spy).toHaveBeenCalled();
});
@ -136,15 +136,15 @@ describe('Navigation lifecycle', function () {
$routerOnDeactivate: spy
});
$router.config([
$rootRouter.config([
{ path: '/user/:name', component: 'deactivateCmp' },
{ path: '/post/:id', component: 'oneCmp' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/user/brian');
$rootRouter.navigateByUrl('/user/brian');
$rootScope.$digest();
$router.navigateByUrl('/post/123');
$rootRouter.navigateByUrl('/post/123');
$rootScope.$digest();
expect(spy).toHaveBeenCalledWith(instructionFor('oneCmp'),
instructionFor('deactivateCmp'));
@ -166,15 +166,15 @@ describe('Navigation lifecycle', function () {
}
});
$router.config([
$rootRouter.config([
{ path: '/a', component: 'deactivateCmp' },
{ path: '/b', component: 'activateCmp' }
]);
compile('outer { <div ng-outlet></div> }');
$router.navigateByUrl('/a');
$rootRouter.navigateByUrl('/a');
$rootScope.$digest();
$router.navigateByUrl('/b');
$rootRouter.navigateByUrl('/b');
$rootScope.$digest();
expect(log).toEqual(['deactivate', 'activate']);
@ -203,19 +203,19 @@ describe('Navigation lifecycle', function () {
}
});
$router.config([
$rootRouter.config([
{ path: '/on-reuse/:number/...', component: 'reuseCmp' },
{ path: '/two', component: 'twoCmp', name: 'Two'}
]);
compile('outer { <div ng-outlet></div> }');
$router.navigateByUrl('/on-reuse/1/a');
$rootRouter.navigateByUrl('/on-reuse/1/a');
$rootScope.$digest();
expect(log).toEqual([]);
expect(cmpInstanceCount).toBe(1);
expect(elt.text()).toBe('outer { reuse {one} }');
$router.navigateByUrl('/on-reuse/2/b');
$rootRouter.navigateByUrl('/on-reuse/2/b');
$rootScope.$digest();
expect(log).toEqual(['reuse: on-reuse/1 -> on-reuse/2']);
expect(cmpInstanceCount).toBe(1);
@ -245,19 +245,19 @@ describe('Navigation lifecycle', function () {
}
});
$router.config([
$rootRouter.config([
{ path: '/never-reuse/:number/...', component: 'reuseCmp' },
{ path: '/two', component: 'twoCmp', name: 'Two'}
]);
compile('outer { <div ng-outlet></div> }');
$router.navigateByUrl('/never-reuse/1/a');
$rootRouter.navigateByUrl('/never-reuse/1/a');
$rootScope.$digest();
expect(log).toEqual([]);
expect(cmpInstanceCount).toBe(1);
expect(elt.text()).toBe('outer { reuse {one} }');
$router.navigateByUrl('/never-reuse/2/b');
$rootRouter.navigateByUrl('/never-reuse/2/b');
$rootScope.$digest();
expect(log).toEqual([]);
expect(cmpInstanceCount).toBe(2);
@ -274,12 +274,12 @@ describe('Navigation lifecycle', function () {
$routerOnActivate: spy
});
$router.config([
$rootRouter.config([
{ path: '/a', component: 'activateCmp' }
]);
compile('outer { <div ng-outlet></div> }');
$router.navigateByUrl('/a');
$rootRouter.navigateByUrl('/a');
$rootScope.$digest();
expect(spy).not.toHaveBeenCalled();
@ -296,12 +296,12 @@ describe('Navigation lifecycle', function () {
$routerOnActivate: activateSpy
});
$router.config([
$rootRouter.config([
{ path: '/a', component: 'activateCmp' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/a');
$rootRouter.navigateByUrl('/a');
$rootScope.$digest();
expect(canActivateSpy).toHaveBeenCalled();
@ -320,12 +320,12 @@ describe('Navigation lifecycle', function () {
$routerOnActivate: spy
});
$router.config([
$rootRouter.config([
{ path: '/a', component: 'activateCmp' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/a');
$rootRouter.navigateByUrl('/a');
$rootScope.$digest();
expect(spy).toHaveBeenCalled();
@ -341,17 +341,17 @@ describe('Navigation lifecycle', function () {
spy.$inject = ['$nextInstruction', '$http'];
$router.config([
$rootRouter.config([
{ path: '/user/:name', component: 'activateCmp' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/user/brian');
$rootRouter.navigateByUrl('/user/brian');
$rootScope.$digest();
expect(spy).toHaveBeenCalled();
var args = spy.calls.mostRecent().args;
expect(args[0].params).toEqual({name: 'brian'});
expect(args[0].params).toEqual(jasmine.objectContaining({name: 'brian'}));
expect(args[1]).toBe($http);
}));
@ -364,17 +364,17 @@ describe('Navigation lifecycle', function () {
}
});
$router.config([
$rootRouter.config([
{ path: '/a', component: 'activateCmp' },
{ path: '/b', component: 'oneCmp' }
]);
compile('outer { <div ng-outlet></div> }');
$router.navigateByUrl('/a');
$rootRouter.navigateByUrl('/a');
$rootScope.$digest();
expect(elt.text()).toBe('outer { hi }');
$router.navigateByUrl('/b');
$rootRouter.navigateByUrl('/b');
$rootScope.$digest();
expect(elt.text()).toBe('outer { hi }');
});
@ -388,17 +388,17 @@ describe('Navigation lifecycle', function () {
}
});
$router.config([
$rootRouter.config([
{ path: '/a', component: 'activateCmp' },
{ path: '/b', component: 'oneCmp' }
]);
compile('outer { <div ng-outlet></div> }');
$router.navigateByUrl('/a');
$rootRouter.navigateByUrl('/a');
$rootScope.$digest();
expect(elt.text()).toBe('outer { hi }');
$router.navigateByUrl('/b');
$rootRouter.navigateByUrl('/b');
$rootScope.$digest();
expect(elt.text()).toBe('outer { one }');
});
@ -414,12 +414,12 @@ describe('Navigation lifecycle', function () {
$routerOnActivate: spy
});
$router.config([
$rootRouter.config([
{ path: '/a', component: 'activateCmp' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/a');
$rootRouter.navigateByUrl('/a');
$rootScope.$digest();
expect(spy).toHaveBeenCalled();
@ -433,15 +433,15 @@ describe('Navigation lifecycle', function () {
$routerCanDeactivate: spy
});
$router.config([
$rootRouter.config([
{ path: '/user/:name', component: 'deactivateCmp' },
{ path: '/post/:id', component: 'oneCmp' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/user/brian');
$rootRouter.navigateByUrl('/user/brian');
$rootScope.$digest();
$router.navigateByUrl('/post/123');
$rootRouter.navigateByUrl('/post/123');
$rootScope.$digest();
expect(spy).toHaveBeenCalledWith(instructionFor('oneCmp'),
instructionFor('deactivateCmp'));
@ -466,10 +466,10 @@ describe('Navigation lifecycle', function () {
}
if (options.$canActivate) {
factory.$canActivate = options.$canActivate;
controller.$canActivate = options.$canActivate;
}
if (options.$routeConfig) {
factory.$routeConfig = options.$routeConfig;
controller.$routeConfig = options.$routeConfig;
}
$compileProvider.directive(name, factory);

View File

@ -5,7 +5,7 @@ describe('navigation', function () {
var elt,
$compile,
$rootScope,
$router,
$rootRouter,
$compileProvider;
beforeEach(function () {
@ -15,49 +15,79 @@ describe('navigation', function () {
$compileProvider = _$compileProvider_;
});
inject(function (_$compile_, _$rootScope_, _$router_) {
inject(function (_$compile_, _$rootScope_, _$rootRouter_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
$router = _$router_;
$rootRouter = _$rootRouter_;
});
registerComponent('userCmp', {
template: '<div>hello {{userCmp.$routeParams.name}}</div>'
registerDirective('userCmp', {
template: '<div>hello {{userCmp.$routeParams.name}}</div>',
$routerOnActivate: function(next) {
this.$routeParams = next.params;
}
});
registerComponent('oneCmp', {
registerDirective('oneCmp', {
template: '<div>{{oneCmp.number}}</div>',
controller: function () {this.number = 'one'}
});
registerComponent('twoCmp', {
registerDirective('twoCmp', {
template: '<div>{{twoCmp.number}}</div>',
controller: function () {this.number = 'two'}
});
registerComponent('threeCmp', {
template: '<div>{{$ctrl.number}}</div>',
controller: function () {this.number = 'three'}
});
registerComponent('getParams', {
template: '<div>{{$ctrl.params.x}}</div>',
controller: function () {
this.$routerOnActivate = function(next) {
this.params = next.params;
};
}
})
});
it('should work in a simple case', function () {
compile('<ng-outlet></ng-outlet>');
$router.config([
$rootRouter.config([
{ path: '/', component: 'oneCmp' }
]);
$router.navigateByUrl('/');
$rootRouter.navigateByUrl('/');
$rootScope.$digest();
expect(elt.text()).toBe('one');
});
it('should work with components created by the `mod.component()` helper', function () {
compile('<ng-outlet></ng-outlet>');
$rootRouter.config([
{ path: '/', component: 'threeCmp' }
]);
$rootRouter.navigateByUrl('/');
$rootScope.$digest();
expect(elt.text()).toBe('three');
});
it('should navigate between components with different parameters', function () {
$router.config([
$rootRouter.config([
{ path: '/user/:name', component: 'userCmp' }
]);
compile('<ng-outlet></ng-outlet>');
$router.navigateByUrl('/user/brian');
$rootRouter.navigateByUrl('/user/brian');
$rootScope.$digest();
expect(elt.text()).toBe('hello brian');
$router.navigateByUrl('/user/igor');
$rootRouter.navigateByUrl('/user/igor');
$rootScope.$digest();
expect(elt.text()).toBe('hello igor');
});
@ -68,7 +98,7 @@ describe('navigation', function () {
function ParentController() {
instanceCount += 1;
}
registerComponent('parentCmp', {
registerDirective('parentCmp', {
template: 'parent { <ng-outlet></ng-outlet> }',
$routeConfig: [
{ path: '/user/:name', component: 'userCmp' }
@ -76,17 +106,17 @@ describe('navigation', function () {
controller: ParentController
});
$router.config([
$rootRouter.config([
{ path: '/parent/...', component: 'parentCmp' }
]);
compile('<ng-outlet></ng-outlet>');
$router.navigateByUrl('/parent/user/brian');
$rootRouter.navigateByUrl('/parent/user/brian');
$rootScope.$digest();
expect(instanceCount).toBe(1);
expect(elt.text()).toBe('parent { hello brian }');
$router.navigateByUrl('/parent/user/igor');
$rootRouter.navigateByUrl('/parent/user/igor');
$rootScope.$digest();
expect(instanceCount).toBe(1);
expect(elt.text()).toBe('parent { hello igor }');
@ -94,6 +124,25 @@ describe('navigation', function () {
it('should work with nested outlets', function () {
registerDirective('childCmp', {
template: '<div>inner { <div ng-outlet></div> }</div>',
$routeConfig: [
{ path: '/b', component: 'oneCmp' }
]
});
$rootRouter.config([
{ path: '/a/...', component: 'childCmp' }
]);
compile('<div>outer { <div ng-outlet></div> }</div>');
$rootRouter.navigateByUrl('/a/b');
$rootScope.$digest();
expect(elt.text()).toBe('outer { inner { one } }');
});
it('should work when parent route has empty path', inject(function ($location) {
registerComponent('childCmp', {
template: '<div>inner { <div ng-outlet></div> }</div>',
$routeConfig: [
@ -101,61 +150,77 @@ describe('navigation', function () {
]
});
$router.config([
{ path: '/a/...', component: 'childCmp' }
$rootRouter.config([
{ path: '/...', component: 'childCmp' }
]);
compile('<div>outer { <div ng-outlet></div> }</div>');
$router.navigateByUrl('/a/b');
$rootRouter.navigateByUrl('/b');
$rootScope.$digest();
expect(elt.text()).toBe('outer { inner { one } }');
});
expect($location.path()).toBe('/b');
}));
it('should work with recursive nested outlets', function () {
registerComponent('recurCmp', {
registerDirective('recurCmp', {
template: '<div>recur { <div ng-outlet></div> }</div>',
$routeConfig: [
{ path: '/recur', component: 'recurCmp' },
{ path: '/end', component: 'oneCmp' }
]});
$router.config([
$rootRouter.config([
{ path: '/recur', component: 'recurCmp' },
{ path: '/', component: 'oneCmp' }
]);
compile('<div>root { <div ng-outlet></div> }</div>');
$router.navigateByUrl('/recur/recur/end');
$rootRouter.navigateByUrl('/recur/recur/end');
$rootScope.$digest();
expect(elt.text()).toBe('root { one }');
});
it('should change location path', inject(function ($location) {
$router.config([
$rootRouter.config([
{ path: '/user', component: 'userCmp' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/user');
$rootRouter.navigateByUrl('/user');
$rootScope.$digest();
expect($location.path()).toBe('/user');
}));
it('should pass through query terms to the location', inject(function ($location) {
$rootRouter.config([
{ path: '/user', component: 'userCmp' }
]);
compile('<div ng-outlet></div>');
$rootRouter.navigateByUrl('/user?x=y');
$rootScope.$digest();
expect($location.path()).toBe('/user');
expect($location.search()).toEqual({ x: 'y'});
}));
it('should change location to the canonical route', inject(function ($location) {
compile('<div ng-outlet></div>');
$router.config([
$rootRouter.config([
{ path: '/', redirectTo: ['/User'] },
{ path: '/user', component: 'userCmp', name: 'User' }
]);
$router.navigateByUrl('/');
$rootRouter.navigateByUrl('/');
$rootScope.$digest();
expect($location.path()).toBe('/user');
@ -163,7 +228,7 @@ describe('navigation', function () {
it('should change location to the canonical route with nested components', inject(function ($location) {
registerComponent('childRouter', {
registerDirective('childRouter', {
template: '<div>inner { <div ng-outlet></div> }</div>',
$routeConfig: [
{ path: '/new-child', component: 'oneCmp', name: 'NewChild'},
@ -171,7 +236,7 @@ describe('navigation', function () {
]
});
$router.config([
$rootRouter.config([
{ path: '/old-parent/old-child', redirectTo: ['/NewParent', 'NewChild'] },
{ path: '/old-parent/old-child-two', redirectTo: ['/NewParent', 'NewChildTwo'] },
{ path: '/new-parent/...', component: 'childRouter', name: 'NewParent' }
@ -179,13 +244,13 @@ describe('navigation', function () {
compile('<div ng-outlet></div>');
$router.navigateByUrl('/old-parent/old-child');
$rootRouter.navigateByUrl('/old-parent/old-child');
$rootScope.$digest();
expect($location.path()).toBe('/new-parent/new-child');
expect(elt.text()).toBe('inner { one }');
$router.navigateByUrl('/old-parent/old-child-two');
$rootRouter.navigateByUrl('/old-parent/old-child-two');
$rootScope.$digest();
expect($location.path()).toBe('/new-parent/new-child-two');
@ -194,7 +259,7 @@ describe('navigation', function () {
it('should navigate when the location path changes', inject(function ($location) {
$router.config([
$rootRouter.config([
{ path: '/one', component: 'oneCmp' }
]);
compile('<div ng-outlet></div>');
@ -206,36 +271,42 @@ describe('navigation', function () {
}));
it('should expose a "navigating" property on $router', inject(function ($q) {
it('should navigate when the location query changes', inject(function ($location) {
$rootRouter.config([
{ path: '/get/params', component: 'getParams' }
]);
compile('<div ng-outlet></div>');
$location.url('/get/params?x=y');
$rootScope.$digest();
expect(elt.text()).toBe('y');
}));
it('should expose a "navigating" property on $rootRouter', inject(function ($q) {
var defer;
registerComponent('pendingActivate', {
registerDirective('pendingActivate', {
$canActivate: function () {
defer = $q.defer();
return defer.promise;
}
});
$router.config([
$rootRouter.config([
{ path: '/pending-activate', component: 'pendingActivate' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/pending-activate');
$rootRouter.navigateByUrl('/pending-activate');
$rootScope.$digest();
expect($router.navigating).toBe(true);
expect($rootRouter.navigating).toBe(true);
defer.resolve();
$rootScope.$digest();
expect($router.navigating).toBe(false);
expect($rootRouter.navigating).toBe(false);
}));
function registerComponent(name, options) {
var controller = options.controller || function () {};
['$routerOnActivate', '$routerOnDeactivate', '$routerOnReuse', '$routerCanReuse', '$routerCanDeactivate'].forEach(function (hookName) {
if (options[hookName]) {
controller.prototype[hookName] = options[hookName];
}
});
function registerDirective(name, options) {
var controller = getController(options);
function factory() {
return {
template: options.template || '',
@ -243,20 +314,46 @@ describe('navigation', function () {
controller: controller
};
}
if (options.$canActivate) {
factory.$canActivate = options.$canActivate;
}
if (options.$routeConfig) {
factory.$routeConfig = options.$routeConfig;
}
applyStaticProperties(controller, options);
$compileProvider.directive(name, factory);
}
function registerComponent(name, options) {
var definition = {
template: options.template || '',
controller: getController(options),
}
applyStaticProperties(definition.controller, options);
$compileProvider.component(name, definition);
}
function compile(template) {
elt = $compile('<div>' + template + '</div>')($rootScope);
$rootScope.$digest();
return elt;
}
function getController(options) {
var controller = options.controller || function () {};
[
'$routerOnActivate', '$routerOnDeactivate',
'$routerOnReuse', '$routerCanReuse',
'$routerCanDeactivate'
].forEach(function (hookName) {
if (options[hookName]) {
controller.prototype[hookName] = options[hookName];
}
});
return controller;
}
function applyStaticProperties(target, options) {
['$canActivate', '$routeConfig'].forEach(function(property) {
if (options[property]) {
target[property] = options[property];
}
});
}
});

View File

@ -2,30 +2,14 @@
describe('router', function () {
var elt,
$compile,
$rootScope,
$router,
$compileProvider;
var elt, testMod;
beforeEach(function () {
module('ng');
module('ngComponentRouter');
module(function($provide) {
$provide.value('$routerRootComponent', 'app');
});
module(function (_$compileProvider_) {
$compileProvider = _$compileProvider_;
});
inject(function (_$compile_, _$rootScope_, _$router_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
$router = _$router_;
});
testMod = angular.module('testMod', ['ngComponentRouter'])
.value('$routerRootComponent', 'app');
});
it('should work with a provided root component', inject(function($location) {
it('should work with a provided root component', function() {
registerComponent('homeCmp', {
template: 'Home'
});
@ -37,43 +21,197 @@ describe('router', function () {
]
});
compile('<app></app>');
module('testMod');
compileApp();
$location.path('/');
$rootScope.$digest();
expect(elt.text()).toBe('Home');
}));
inject(function($location, $rootScope) {
$location.path('/');
$rootScope.$digest();
expect(elt.text()).toBe('Home');
});
});
it('should bind the component to the current router', function() {
var router;
registerComponent('homeCmp', {
bindings: { $router: '=' },
controller: function($scope, $element) {
this.$routerOnActivate = function() {
router = this.$router;
};
},
template: 'Home'
});
registerComponent('app', {
template: '<div ng-outlet></div>',
$routeConfig: [
{ path: '/', component: 'homeCmp' }
]
});
module('testMod');
compileApp();
inject(function($location, $rootScope) {
$location.path('/');
$rootScope.$digest();
var homeElement = elt.find('home-cmp');
expect(homeElement.text()).toBe('Home');
expect(homeElement.isolateScope().$ctrl.$router).toBeDefined();
expect(router).toBeDefined();
})
});
it('should work when an async route is provided route data', function() {
registerComponent('homeCmp', {
template: 'Home ({{$ctrl.isAdmin}})',
$routerOnActivate: function(next, prev) {
this.isAdmin = next.routeData.data.isAdmin;
}
});
registerComponent('app', {
template: '<div ng-outlet></div>',
$routeConfig: [
{ path: '/', loader: function($q) { return $q.when('homeCmp'); }, data: { isAdmin: true } }
]
});
module('testMod');
compileApp();
inject(function($location, $rootScope) {
$location.path('/');
$rootScope.$digest();
expect(elt.text()).toBe('Home (true)');
});
});
it('should work with a templateUrl component', function() {
var $routerOnActivate = jasmine.createSpy('$routerOnActivate');
registerComponent('homeCmp', {
templateUrl: 'homeCmp.html',
$routerOnActivate: $routerOnActivate
});
registerComponent('app', {
template: '<div ng-outlet></div>',
$routeConfig: [
{ path: '/', component: 'homeCmp' }
]
});
module('testMod');
inject(function($location, $rootScope, $httpBackend) {
$httpBackend.expectGET('homeCmp.html').respond('Home');
compileApp();
$location.path('/');
$rootScope.$digest();
$httpBackend.flush();
var homeElement = elt.find('home-cmp');
expect(homeElement.text()).toBe('Home');
expect($routerOnActivate).toHaveBeenCalled();
})
});
it('should provide the current instruction', function() {
registerComponent('homeCmp', {
template: 'Home ({{homeCmp.isAdmin}})'
});
registerComponent('app', {
template: '<div ng-outlet></div>',
$routeConfig: [
{ path: '/', component: 'homeCmp', name: 'Home' }
]
});
module('testMod');
inject(function($rootScope, $rootRouter, $location) {
compileApp();
$location.path('/');
$rootScope.$digest();
var instruction = $rootRouter.generate(['/Home']);
expect($rootRouter.currentInstruction).toEqual(instruction);
});
});
it('should provide the root level router', function() {
registerComponent('homeCmp', {
template: 'Home ({{homeCmp.isAdmin}})',
bindings: {
$router: '<'
}
});
registerComponent('app', {
template: '<div ng-outlet></div>',
$routeConfig: [
{ path: '/', component: 'homeCmp', name: 'Home' }
]
});
module('testMod');
inject(function($rootScope, $rootRouter, $location) {
compileApp();
$location.path('/');
$rootScope.$digest();
var homeElement = elt.find('home-cmp');
expect(homeElement.isolateScope().$ctrl.$router.root).toEqual($rootRouter);
});
});
function registerComponent(name, options) {
var controller = options.controller || function () {};
['$onActivate', '$onDeactivate', '$onReuse', '$canReuse', '$canDeactivate'].forEach(function (hookName) {
var definition = {
bindings: options.bindings,
controller: getController(options),
};
if (options.template) definition.template = options.template;
if (options.templateUrl) definition.templateUrl = options.templateUrl;
applyStaticProperties(definition.controller, options);
angular.module('testMod').component(name, definition);
}
function compileApp() {
inject(function($compile, $rootScope) {
elt = $compile('<div><app></app</div>')($rootScope);
$rootScope.$digest();
});
return elt;
}
function getController(options) {
var controller = options.controller || function () {};
[
'$routerOnActivate', '$routerOnDeactivate',
'$routerOnReuse', '$routerCanReuse',
'$routerCanDeactivate'
].forEach(function (hookName) {
if (options[hookName]) {
controller.prototype[hookName] = options[hookName];
}
});
function factory() {
return {
template: options.template || '',
controllerAs: name,
controller: controller
};
}
if (options.$canActivate) {
factory.$canActivate = options.$canActivate;
}
if (options.$routeConfig) {
factory.$routeConfig = options.$routeConfig;
}
$compileProvider.directive(name, factory);
return controller;
}
function compile(template) {
elt = $compile('<div>' + template + '</div>')($rootScope);
$rootScope.$digest();
return elt;
function applyStaticProperties(target, options) {
['$canActivate', '$routeConfig'].forEach(function(property) {
if (options[property]) {
target[property] = options[property];
}
});
}
});

View File

@ -5,7 +5,7 @@ describe('ngRoute shim', function () {
var elt,
$compile,
$rootScope,
$router,
$rootRouter,
$compileProvider,
$routeProvider;
@ -18,10 +18,10 @@ describe('ngRoute shim', function () {
$routeProvider = _$routeProvider_;
});
inject(function (_$compile_, _$rootScope_, _$router_) {
inject(function (_$compile_, _$rootScope_, _$rootRouter_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
$router = _$router_;
$rootRouter = _$rootRouter_;
});
});
@ -36,7 +36,7 @@ describe('ngRoute shim', function () {
compile('<ng-outlet></ng-outlet>');
$router.navigateByUrl('/');
$rootRouter.navigateByUrl('/');
$rootScope.$digest();
expect(elt.text()).toBe('one');
@ -55,7 +55,7 @@ describe('ngRoute shim', function () {
compile('root {<ng-outlet></ng-outlet>}');
$router.navigateByUrl('/');
$rootRouter.navigateByUrl('/');
$rootScope.$digest();
expect(elt.text()).toBe('root {one}');
}));
@ -76,7 +76,7 @@ describe('ngRoute shim', function () {
compile('<ng-outlet></ng-outlet>');
$router.navigateByUrl('/');
$rootRouter.navigateByUrl('/');
$rootScope.$digest();
expect(elt.text()).toBe('value: 42');
@ -94,11 +94,11 @@ describe('ngRoute shim', function () {
compile('<ng-outlet></ng-outlet>');
$router.navigateByUrl('/user/brian');
$rootRouter.navigateByUrl('/user/brian');
$rootScope.$digest();
expect(elt.text()).toBe('hello brian');
$router.navigateByUrl('/user/igor');
$rootRouter.navigateByUrl('/user/igor');
$rootScope.$digest();
expect(elt.text()).toBe('hello igor');
});
@ -115,7 +115,7 @@ describe('ngRoute shim', function () {
compile('<ng-outlet></ng-outlet>');
$router.navigateByUrl('/home/foo/bar/123');
$rootRouter.navigateByUrl('/home/foo/bar/123');
$rootScope.$digest();
expect(elt.text()).toBe('rest: foo/bar/123');
});
@ -129,7 +129,7 @@ describe('ngRoute shim', function () {
compile('root {<ng-outlet></ng-outlet>}');
$router.navigateByUrl('/home/test');
$rootRouter.navigateByUrl('/home/test');
$rootScope.$digest();
expect(elt.text()).toBe('root {}');
expect(console.warn)
@ -150,7 +150,7 @@ describe('ngRoute shim', function () {
compile('root {<ng-outlet></ng-outlet>}');
$router.navigateByUrl('/');
$rootRouter.navigateByUrl('/');
$rootScope.$digest();
expect(elt.text()).toBe('root {welcome home!}');
expect($location.path()).toBe('/home');
@ -169,7 +169,7 @@ describe('ngRoute shim', function () {
compile('root {<ng-outlet></ng-outlet>}');
$router.navigateByUrl('/somewhere');
$rootRouter.navigateByUrl('/somewhere');
$rootScope.$digest();
expect(elt.text()).toBe('root {welcome home!}');
expect($location.path()).toBe('/home');

View File

@ -2,169 +2,191 @@
describe('ngLink', function () {
var elt,
$compile,
$rootScope,
$router,
$compileProvider;
describe('html5Mode enabled', function () {
runHrefTestsAndExpectPrefix('/', true);
});
beforeEach(function () {
module('ng');
module('ngComponentRouter');
module(function (_$compileProvider_) {
$compileProvider = _$compileProvider_;
describe('html5Mode disabled', function () {
runHrefTestsAndExpectPrefix('', false, '');
});
describe('html5Mode disabled, with hash prefix', function () {
runHrefTestsAndExpectPrefix('', false, '!');
});
describe('html5Mode enabled', function () {
runHrefTestsAndExpectPrefix('/moo', true);
});
describe('html5Mode disabled', function () {
runHrefTestsAndExpectPrefix('/moo', false, '');
});
describe('html5Mode disabled, with hash prefix', function () {
runHrefTestsAndExpectPrefix('/moo', false, '!');
});
function runHrefTestsAndExpectPrefix(baseHref, html5Mode, hashPrefix) {
var prefix = html5Mode ? '.' : '#' + hashPrefix;
it('should allow linking from the parent to the child', function () {
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
configureRouter([
{ path: '/a', component: 'oneCmp' },
{ path: '/b', component: 'twoCmp', name: 'Two' }
]);
var elt = compile('<a ng-link="[\'/Two\']">link</a> | outer { <div ng-outlet></div> }');
navigateTo('/a');
expect(elt.find('a').attr('href')).toBe(prefix + '/b');
});
inject(function (_$compile_, _$rootScope_, _$router_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
$router = _$router_;
it('should allow linking from the child and the parent', function () {
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
configureRouter([
{ path: '/a', component: 'oneCmp' },
{ path: '/b', component: 'twoCmp', name: 'Two' }
]);
var elt = compile('outer { <div ng-outlet></div> }');
navigateTo('/b');
expect(elt.find('a').attr('href')).toBe(prefix + '/b');
});
registerComponent('userCmp', '<div>hello {{userCmp.$routeParams.name}}</div>', function () {});
registerComponent('oneCmp', '<div>{{oneCmp.number}}</div>', function () {this.number = 'one'});
registerComponent('twoCmp', '<div><a ng-link="[\'/Two\']">{{twoCmp.number}}</a></div>', function () {this.number = 'two'});
});
it('should allow params in routerLink directive', function () {
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
registerComponent('twoLinkCmp', '<div><a ng-link="[\'/Two\', {param: \'lol\'}]">{{twoLinkCmp.number}}</a></div>', function () {this.number = 'two'});
configureRouter([
{ path: '/a', component: 'twoLinkCmp' },
{ path: '/b/:param', component: 'twoCmp', name: 'Two' }
]);
var elt = compile('<div ng-outlet></div>');
navigateTo('/a');
expect(elt.find('a').attr('href')).toBe(prefix + '/b/lol');
});
it('should allow linking from the parent to the child', function () {
$router.config([
{ path: '/a', component: 'oneCmp' },
{ path: '/b', component: 'twoCmp', name: 'Two' }
]);
compile('<a ng-link="[\'/Two\']">link</a> | outer { <div ng-outlet></div> }');
it('should update the href of links with bound params', function () {
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
registerComponent('twoLinkCmp', '<div><a ng-link="[\'/Two\', {param: $ctrl.number}]">{{$ctrl.number}}</a></div>', function () {this.number = 43});
configureRouter([
{ path: '/a', component: 'twoLinkCmp' },
{ path: '/b/:param', component: 'twoCmp', name: 'Two' }
]);
$router.navigateByUrl('/a');
$rootScope.$digest();
expect(elt.find('a').attr('href')).toBe('./b');
});
it('should allow linking from the child and the parent', function () {
$router.config([
{ path: '/a', component: 'oneCmp' },
{ path: '/b', component: 'twoCmp', name: 'Two' }
]);
compile('outer { <div ng-outlet></div> }');
$router.navigateByUrl('/b');
$rootScope.$digest();
expect(elt.find('a').attr('href')).toBe('./b');
});
var elt = compile('<div ng-outlet></div>');
navigateTo('/a');
expect(elt.find('a').text()).toBe('43');
expect(elt.find('a').attr('href')).toBe(prefix + '/b/43');
});
it('should allow params in routerLink directive', function () {
registerComponent('twoLinkCmp', '<div><a ng-link="[\'/Two\', {param: \'lol\'}]">{{twoLinkCmp.number}}</a></div>', function () {this.number = 'two'});
it('should navigate on left-mouse click when a link url matches a route', function () {
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
configureRouter([
{ path: '/', component: 'oneCmp' },
{ path: '/two', component: 'twoCmp', name: 'Two'}
]);
$router.config([
{ path: '/a', component: 'twoLinkCmp' },
{ path: '/b/:param', component: 'twoCmp', name: 'Two' }
]);
compile('<div ng-outlet></div>');
var elt = compile('<a ng-link="[\'/Two\']">link</a> | <div ng-outlet></div>');
expect(elt.text()).toBe('link | one');
expect(elt.find('a').attr('href')).toBe(prefix + '/two');
$router.navigateByUrl('/a');
$rootScope.$digest();
expect(elt.find('a').attr('href')).toBe('./b/lol');
});
it('should update the href of links with bound params', function () {
registerComponent('twoLinkCmp', '<div><a ng-link="[\'/Two\', {param: twoLinkCmp.number}]">{{twoLinkCmp.number}}</a></div>', function () {this.number = 'param'});
$router.config([
{ path: '/a', component: 'twoLinkCmp' },
{ path: '/b/:param', component: 'twoCmp', name: 'Two' }
]);
compile('<div ng-outlet></div>');
$router.navigateByUrl('/a');
$rootScope.$digest();
expect(elt.find('a').attr('href')).toBe('./b/param');
});
it('should navigate on left-mouse click when a link url matches a route', function () {
$router.config([
{ path: '/', component: 'oneCmp' },
{ path: '/two', component: 'twoCmp', name: 'Two'}
]);
compile('<a ng-link="[\'/Two\']">link</a> | <div ng-outlet></div>');
$rootScope.$digest();
expect(elt.text()).toBe('link | one');
expect(elt.find('a').attr('href')).toBe('./two');
elt.find('a')[0].click();
$rootScope.$digest();
expect(elt.text()).toBe('link | two');
});
it('should not navigate on non-left mouse click when a link url matches a route', inject(function ($router) {
$router.config([
{ path: '/', component: 'oneCmp' },
{ path: '/two', component: 'twoCmp', name: 'Two'}
]);
compile('<a ng-link="[\'/Two\']">link</a> | <div ng-outlet></div>');
$rootScope.$digest();
expect(elt.text()).toBe('link | one');
elt.find('a').triggerHandler({ type: 'click', which: 3 });
$rootScope.$digest();
expect(elt.text()).toBe('link | one');
}));
// See https://github.com/angular/router/issues/206
it('should not navigate a link without an href', function () {
$router.config([
{ path: '/', component: 'oneCmp' },
{ path: '/two', component: 'twoCmp', name: 'Two'}
]);
expect(function () {
compile('<a>link</a>');
$rootScope.$digest();
expect(elt.text()).toBe('link');
elt.find('a')[0].click();
$rootScope.$digest();
}).not.toThrow();
});
inject(function($rootScope) { $rootScope.$digest(); });
expect(elt.text()).toBe('link | two');
});
function registerComponent(name, template, config) {
var controller = function () {};
it('should not navigate on non-left mouse click when a link url matches a route', function() {
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
configureRouter([
{ path: '/', component: 'oneCmp' },
{ path: '/two', component: 'twoCmp', name: 'Two'}
]);
function factory() {
return {
var elt = compile('<a ng-link="[\'/Two\']">link</a> | <div ng-outlet></div>');
expect(elt.text()).toBe('link | one');
elt.find('a').triggerHandler({ type: 'click', which: 3 });
inject(function($rootScope) { $rootScope.$digest(); });
expect(elt.text()).toBe('link | one');
});
// See https://github.com/angular/router/issues/206
it('should not navigate a link without an href', function () {
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
configureRouter([
{ path: '/', component: 'oneCmp' },
{ path: '/two', component: 'twoCmp', name: 'Two'}
]);
expect(function () {
var elt = compile('<a>link</a>');
expect(elt.text()).toBe('link');
elt.find('a')[0].click();
inject(function($rootScope) { $rootScope.$digest(); });
}).not.toThrow();
});
it('should add an ng-link-active class on the current link', function() {
setup({baseHref: baseHref, html5Mode: html5Mode, hashPrefix: hashPrefix});
configureRouter([
{ path: '/', component: 'oneCmp', name: 'One' }
]);
var elt = compile('<a ng-link="[\'/One\']">one</a> | <div ng-outlet></div>');
navigateTo('/');
expect(elt.find('a').attr('class')).toBe('ng-link-active');
});
}
function registerComponent(name, template, controller) {
module(function($compileProvider) {
$compileProvider.component(name, {
template: template,
controllerAs: name,
controller: controller
};
}
});
});
}
if (!template) {
template = '';
}
if (angular.isArray(config)) {
factory.annotations = [new angular.annotations.RouteConfig(config)];
} else if (typeof config === 'function') {
controller = config;
} else if (typeof config === 'object') {
if (config.canActivate) {
controller.$canActivate = config.canActivate;
}
}
$compileProvider.directive(name, factory);
function setup(config) {
module(function($provide) {
$provide.decorator('$browser', function($delegate) {
$delegate.baseHref = function() { return config.baseHref; };
return $delegate;
});
});
module('ngComponentRouter');
module(function($locationProvider) {
$locationProvider.html5Mode(config.html5Mode);
$locationProvider.hashPrefix(config.hashPrefix);
});
registerComponent('userCmp', '<div>hello {{$ctrl.$routeParams.name}}</div>', function () {});
registerComponent('oneCmp', '<div>{{$ctrl.number}}</div>', function () {this.number = 'one'});
registerComponent('twoCmp', '<div><a ng-link="[\'/Two\']">{{$ctrl.number}}</a></div>', function () {this.number = 'two'});
}
function configureRouter(routeConfig) {
inject(function($rootRouter) {
$rootRouter.config(routeConfig);
});
}
function compile(template) {
elt = $compile('<div>' + template + '</div>')($rootScope);
$rootScope.$digest();
var elt;
inject(function($compile, $rootScope) {
elt = $compile('<div>' + template + '</div>')($rootScope);
$rootScope.$digest();
});
return elt;
}
function navigateTo(url) {
inject(function($rootRouter, $rootScope) {
$rootRouter.navigateByUrl(url);
$rootScope.$digest();
});
}
});

View File

@ -22,7 +22,7 @@ function provideHelpers(fn, preInject) {
var elt,
$compile,
$rootScope,
$router,
$rootRouter,
$templateCache,
$controllerProvider;
@ -32,10 +32,10 @@ function provideHelpers(fn, preInject) {
$controllerProvider = _$controllerProvider_;
});
inject(function(_$compile_, _$rootScope_, _$router_, _$templateCache_) {
inject(function(_$compile_, _$rootScope_, _$rootRouter_, _$templateCache_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
$router = _$router_;
$rootRouter = _$rootRouter_;
$templateCache = _$templateCache_;
});
@ -72,7 +72,7 @@ function provideHelpers(fn, preInject) {
fn({
registerComponent: registerComponent,
$router: $router,
$rootRouter: $rootRouter,
put: put,
compile: compile
})

View File

@ -1,12 +1,12 @@
{
"version": "v4",
"repo": "angular/DefinitelyTyped",
"repo": "DefinitelyTyped/DefinitelyTyped",
"ref": "master",
"path": "typings",
"bundle": "typings/tsd.d.ts",
"installed": {
"angularjs/angular.d.ts": {
"commit": "746b9a892629060bc853e792afff536e0ec4655e"
"commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
}
}
}

View File

@ -0,0 +1,17 @@
/**
* @module
* @description
* Alternative implementation of the router. Experimental.
*/
export {Router, RouterOutletMap} from './src/alt_router/router';
export {RouteSegment} from './src/alt_router/segments';
export {Routes} from './src/alt_router/metadata/decorators';
export {Route} from './src/alt_router/metadata/metadata';
export {RouterUrlParser, DefaultRouterUrlParser} from './src/alt_router/router_url_parser';
export {OnActivate} from './src/alt_router/interfaces';
import {RouterOutlet} from './src/alt_router/directives/router_outlet';
import {CONST_EXPR} from './src/facade/lang';
export const ROUTER_DIRECTIVES: any[] = CONST_EXPR([RouterOutlet]);

View File

@ -10,8 +10,9 @@ export 'package:angular2/common.dart';
export 'package:angular2/instrumentation.dart';
export 'package:angular2/src/core/angular_entrypoint.dart' show AngularEntrypoint;
export 'package:angular2/src/core/application_tokens.dart'
hide APP_COMPONENT_REF_PROMISE, APP_ID_RANDOM_PROVIDER;
hide APP_ID_RANDOM_PROVIDER;
export 'package:angular2/src/platform/dom/dom_tokens.dart';
export 'package:angular2/src/platform/dom/dom_adapter.dart';
export 'package:angular2/src/platform/dom/events/event_manager.dart';
export 'package:angular2/src/compiler/url_resolver.dart';
export 'package:angular2/src/compiler/compiler.dart' show UrlResolver, DirectiveResolver, ViewResolver;

View File

@ -1,6 +0,0 @@
/**
* See {@link bootstrap} for more information.
* @deprecated
*/
export {bootstrap} from 'angular2/platform/browser';
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';

View File

@ -1,6 +0,0 @@
/**
* See {@link bootstrap} for more information.
* @deprecated
*/
export {bootstrapStatic} from 'angular2/platform/browser_static';
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';

View File

@ -1,4 +1,4 @@
export * from './src/common/pipes';
export * from './src/common/directives';
export * from './src/common/forms';
export * from './src/common/common_directives';
export * from './src/common/common_directives';

View File

@ -3,6 +3,35 @@
* @description
* Starting point to import all compiler APIs.
*/
export * from './src/compiler/url_resolver';
export * from './src/compiler/xhr';
export * from './src/compiler/compiler';
export {
PLATFORM_DIRECTIVES,
PLATFORM_PIPES,
COMPILER_PROVIDERS,
TEMPLATE_TRANSFORMS,
CompilerConfig,
RenderTypes,
UrlResolver,
DEFAULT_PACKAGE_URL_PROVIDER,
createOfflineCompileUrlResolver,
XHR,
ViewResolver,
DirectiveResolver,
PipeResolver,
SourceModule,
NormalizedComponentWithViewDirectives,
OfflineCompiler,
CompileMetadataWithIdentifier,
CompileMetadataWithType,
CompileIdentifierMetadata,
CompileDiDependencyMetadata,
CompileProviderMetadata,
CompileFactoryMetadata,
CompileTokenMetadata,
CompileTypeMetadata,
CompileQueryMetadata,
CompileTemplateMetadata,
CompileDirectiveMetadata,
CompilePipeMetadata
} from 'angular2/src/compiler/compiler';
export * from 'angular2/src/compiler/template_ast';

View File

@ -6,18 +6,18 @@ export './src/core/util.dart';
export 'package:angular2/src/facade/lang.dart' show enableProdMode;
export './src/core/di.dart' hide ForwardRefFn, resolveForwardRef, forwardRef;
export './src/facade/facade.dart';
export './src/core/application_ref.dart' show platform, createNgZone, PlatformRef, ApplicationRef;
export './src/core/application_ref.dart' show createPlatform, assertPlatform,
disposePlatform, getPlatform,
coreLoadAndBootstrap, coreBootstrap, createNgZone, PlatformRef, ApplicationRef;
export './src/core/application_tokens.dart' show APP_ID,
APP_COMPONENT,
APP_INITIALIZER,
PACKAGE_ROOT_URL,
PLATFORM_INITIALIZER;
export './src/core/zone.dart';
export './src/core/render.dart';
export './src/core/linker.dart';
export './src/core/debug/debug_element.dart' show DebugElement,
Scope,
inspectElement,
export './src/core/debug/debug_node.dart' show DebugElement,
DebugNode,
asNativeElements;
export './src/core/testability/testability.dart';
export './src/core/change_detection.dart';

View File

@ -9,10 +9,19 @@ export * from './src/core/prod_mode';
export * from './src/core/di';
export * from './src/facade/facade';
export {enableProdMode} from 'angular2/src/facade/lang';
export {platform, createNgZone, PlatformRef, ApplicationRef} from './src/core/application_ref';
export {
createPlatform,
assertPlatform,
disposePlatform,
getPlatform,
coreBootstrap,
coreLoadAndBootstrap,
createNgZone,
PlatformRef,
ApplicationRef
} from './src/core/application_ref';
export {
APP_ID,
APP_COMPONENT,
APP_INITIALIZER,
PACKAGE_ROOT_URL,
PLATFORM_INITIALIZER
@ -20,12 +29,7 @@ export {
export * from './src/core/zone';
export * from './src/core/render';
export * from './src/core/linker';
export {
DebugElement,
Scope,
inspectElement,
asNativeElements
} from './src/core/debug/debug_element';
export {DebugElement, DebugNode, asNativeElements} from './src/core/debug/debug_node';
export * from './src/core/testability/testability';
export * from './src/core/change_detection';
export * from './src/core/platform_directives_and_pipes';

View File

@ -32,7 +32,7 @@ filename | list of barrels | dev/prod | minified?
`angular2-all.umd.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade`| prod | no
`angular2-all.umd.min.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade` | prod | yes
`angular2-all.umd.dev.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade` | dev | no
`angular2-all-testing.umd.dev.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade`, `angular2/testing`, `angular2/http/testing`, `angular2/router/testing` | dev | no
`angular2-all-testing.umd.dev.js` | `angular2/core`, `angular2/common`, `angular2/compiler`, `angular2/platform/browser`, `angular2/platform/common_dom`, `angular2/http`, `angular2/router`, `angular2/instrumentation`, `angular2/upgrade`, `angular2/testing`, `angular2/http/testing`, `angular2/router/testing`, `angular2/platform/testing/browser` | dev | no
**Warning**: bundles in the `UMD` format are _not_ "additive". A single application should use only one bundle from the above list.
@ -55,7 +55,7 @@ filename | list of barrels | dev/prod | minified?
`upgrade.js` | `angular2/upgrade` | prod | no
`upgrade.min.js` | `angular2/upgrade` | prod | yes
`upgrade.dev.js` | `angular2/upgrade` | dev | no
`testing.dev.js` | `angular2/testing`, `angular2/http/testing`, `angular2/router/testing` | dev | no
`testing.dev.js` | `angular2/testing`, `angular2/http/testing`, `angular2/router/testing`, `angular2/platform/testing/browser` | dev | no
**Note**: bundles in the `System.register` format are "additive" - it is quite common to include several bundles in one application.
For example people using Angular 2 with `http` and `router` would include: `angular2.js`, `http.js` and `router.js`.
@ -72,7 +72,7 @@ An example of an Angular 2 project built with WebPack can be found in the [angul
Polyfills are required for Angular 2 to function properly (the exact list depends on the browser used) and external dependencies ([zone.js](https://github.com/angular/zone.js)).
To ease setup of Angular 2 applications there is one file - `angular2-polyfills.js` - that combines:
* a pollyfill mandatory for all browsers: [reflect-metadata](https://www.npmjs.com/package/reflect-metadata)
* a polyfill mandatory for all browsers: [reflect-metadata](https://www.npmjs.com/package/reflect-metadata)
* [zone.js](https://github.com/angular/zone.js)
**Note**: `angular2-polyfills.js` contains code that should be loaded into the browser as the very first code of the web application even before the module loader. The preferred solution is to load the mentioned file in a `script` tag as early as possible.

View File

@ -3,8 +3,8 @@ Bootstrapping
@cheatsheetIndex 0
@description
{@target ts}`import {bootstrap} from 'angular2/platform/browser';`{@endtarget}
{@target js}Available from the `ng.platform.browser` namespace.{@endtarget}
{@target dart}`import 'package:angular2/bootstrap.dart';`{@endtarget}
{@target js}Available from the `ng.platform.browser` namespace{@endtarget}
{@target dart}`import 'package:angular2/platform/browser.dart';`{@endtarget}
@cheatsheetItem
syntax(ts dart):

View File

@ -4,7 +4,7 @@ Built-in directives
@description
{@target ts}`import {NgIf, ...} from 'angular2/common';`{@endtarget}
{@target js}Available from the `ng.common` namespace{@endtarget}
{@target dart}`import 'package:angular2/common.dart';`{@endtarget}
{@target dart}Available using `platform_directives` in pubspec{@endtarget}
@cheatsheetItem
syntax:
@ -14,7 +14,7 @@ Removes or recreates a portion of the DOM tree based on the showSection expressi
@cheatsheetItem
syntax:
`<li *ngFor="#item of list">`|`*ngFor`
`<li *ngFor="let item of list">`|`*ngFor`
description:
Turns the li element and its contents into a template, and uses that to instantiate a view for each item in list.

View File

@ -18,6 +18,18 @@ class MyComponent() {}`|`@Component(...)`
description:
Declares that a class is a component and provides metadata about the component.
@cheatsheetItem
syntax(ts):
`@Directive({...})
class MyDirective() {}`|`@Directive({...})`
syntax(js):
`var MyDirective = ng.core.Directive({...}).Class({...})`|`ng.core.Directive({...})`
syntax(dart):
`@Directive(...)
class MyDirective() {}`|`@Directive(...)`
description:
Declares that a class is a directive and provides metadata about the directive.
@cheatsheetItem
syntax(ts):
`@Pipe({...})

View File

@ -4,7 +4,7 @@ Forms
@description
{@target ts}`import {FORM_DIRECTIVES} from 'angular2/common';`{@endtarget}
{@target js}Available from `ng.common.FORM_DIRECTIVES`{@endtarget}
{@target dart}`import 'package:angular2/common.dart';`{@endtarget}
{@target dart}Available using `platform_directives` in pubspec{@endtarget}
@cheatsheetItem
syntax:

View File

@ -10,16 +10,16 @@ Routing and navigation
@cheatsheetItem
syntax(ts):
`@RouteConfig([
{ path: '/:myParam', component: MyComponent, as: 'MyCmp' },
{ path: '/staticPath', component: ..., as: ...},
{ path: '/*wildCardParam', component: ..., as: ...}
{ path: '/:myParam', component: MyComponent, name: 'MyCmp' },
{ path: '/staticPath', component: ..., name: ...},
{ path: '/*wildCardParam', component: ..., name: ...}
])
class MyComponent() {}`|`@RouteConfig`
syntax(js):
`var MyComponent = ng.router.RouteConfig([
{ path: '/:myParam', component: MyComponent, as: 'MyCmp' },
{ path: '/staticPath', component: ..., as: ...},
{ path: '/*wildCardParam', component: ..., as: ...}
{ path: '/:myParam', component: MyComponent, name: 'MyCmp' },
{ path: '/staticPath', component: ..., name: ...},
{ path: '/*wildCardParam', component: ..., name: ...}
]).Class({
constructor: function() {}
});`|`ng.router.RouteConfig`

View File

@ -77,4 +77,4 @@ Transforms the current value of expression `cardNumber` via the pipe called `myC
syntax:
`<p>Employer: {{employer?.companyName}}</p>`|`{{employer?.companyName}}`
description:
The Elvis operator (`?`) means that the `employer` field is optional and if `undefined`, the rest of the expression should be ignored.
The safe navigation operator (`?`) means that the `employer` field is optional and if `undefined`, the rest of the expression should be ignored.

View File

@ -433,7 +433,7 @@ Finally, we can move the `ngFor` keyword to the left hand side and prefix it wit
```
<ul>
<li *ngFor="var person of people; var i=index">{{i}}. {{person}}<li>
<li *ngFor="let person of people; var i=index">{{i}}. {{person}}<li>
</ul>
```
@ -456,7 +456,7 @@ Where
* `local` is a local identifier for local variables.
* `internal` is an internal variable which the directive exports for binding.
* `key` is an attribute name usually only used to trigger a specific directive.
* `keyExpression` is an property name to which the expression will be bound to.
* `keyExpression` is a property name to which the expression will be bound to.
* `varExport` allows exporting of directive internal state as variables for further binding. If no `internal` name
is specified, the exporting is to an implicit variable.
* `microsyntax` allows you to build a simple microsyntax which can still clearly identify which expressions bind to

View File

@ -112,9 +112,7 @@ Example of a component:
'title', | - title mapped to component title
'open' | - open attribute mapped to component's open property
], |
}) |
@View({ | View annotation
templateUrl: 'pane.html' | - URL of template HTML
templateUrl: 'pane.html' | URL of template HTML
}) |
class Pane { | Component controller class
title:string; | - title property
@ -227,11 +225,9 @@ class MyService {} | Assume a service which needs to be inject
|
@Component({ | Assume a top level application component which
selector: 'my-app', | configures the services to be injected.
viewBindings: [MyService] |
}) |
@View({ | Assume we have a template that needs to be
templateUrl: 'my_app.html', | configured with directives to be injected.
directives: [House] |
viewBindings: [MyService], |
templateUrl: 'my_app.html', | Assume we have a template that needs to be
directives: [House] | configured with directives to be injected.
}) |
class MyApp {} |
|
@ -273,8 +269,6 @@ Here is an example of the kinds of injections which can be achieved:
```
@Component({ |
selector: 'my-app' |
}) |
@View({ |
templateUrl: 'my_app.html', |
directives: [Form, FieldSet, |
Field, Primary] |
@ -329,8 +323,6 @@ Shadow DOM provides an encapsulation for components, so as a general rule it doe
```
@Component({
selector: '[kid]'
})
@View({
templateUrl: 'kid.html',
directives: []
})
@ -347,8 +339,6 @@ class Kid {
@Component({
selector: '[dad]'
})
@View({
templateUrl: 'dad.html',
directives: [Kid]
})
@ -361,9 +351,7 @@ class Dad {
@Component({
selector: '[grandpa]',
viewBindings: []
})
@View({
viewBindings: [],
templateUrl: 'grandpa.html',
directives: [Dad]
})

View File

@ -94,7 +94,7 @@ Let's start with a View such as:
```
<ul>
<li template="ngFor: #person of people">{{person}}</li>
<li template="ngFor: let person of people">{{person}}</li>
</ul>
```

View File

@ -179,9 +179,7 @@ Both `MyComponent` and `MyDirective` are created on the same element.
],
viewBindings: [
bind('viewService').toValue('View_MyComponentService')
]
})
@View({
],
template: `<needs-view-service></needs-view-service>`,
directives: [NeedsViewService]
})

View File

@ -1,8 +1,8 @@
import {provide} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {bootstrap} from 'angular2/platform/browser';
import {UrlResolver} from 'angular2/compiler';
var MyApp;
var MyApp: any;
// #docregion url_resolver
class MyUrlResolver extends UrlResolver {

View File

@ -1,16 +1,8 @@
import {DebugElement, Scope} from 'angular2/core';
import {DebugElement} from 'angular2/core';
var debugElement: DebugElement;
var predicate;
var predicate: any;
// #docregion scope_all
debugElement.query(predicate, Scope.all);
// #enddocregion
// #docregion scope_light
debugElement.query(predicate, Scope.light);
// #enddocregion
// #docregion scope_view
debugElement.query(predicate, Scope.view);
debugElement.query(predicate);
// #enddocregion

View File

@ -1,4 +1,10 @@
import {Inject, Injector, forwardRef, resolveForwardRef, ForwardRefFn} from 'angular2/core';
import {
Inject,
ReflectiveInjector,
forwardRef,
resolveForwardRef,
ForwardRefFn
} from 'angular2/core';
// #docregion forward_ref_fn
var ref = forwardRef(() => Lock);
@ -13,7 +19,7 @@ class Door {
// Only at this point Lock is defined.
class Lock {}
var injector = Injector.resolveAndCreate([Door, Lock]);
var injector = ReflectiveInjector.resolveAndCreate([Door, Lock]);
var door = injector.get(Door);
expect(door instanceof Door).toBe(true);
expect(door.lock instanceof Lock).toBe(true);

View File

@ -1,9 +1,9 @@
import {bootstrap} from 'angular2/bootstrap';
import {bootstrap} from 'angular2/platform/browser';
import {NG_VALIDATORS} from 'angular2/common';
import {Provider} from 'angular2/core';
let MyApp = null;
let myValidator = null;
let MyApp: Function = null;
let myValidator: any = null;
// #docregion ng_validators
bootstrap(MyApp, [new Provider(NG_VALIDATORS, {useValue: myValidator, multi: true})]);

View File

@ -1,6 +1,6 @@
import {Component, provide} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {Observable} from 'rxjs/Observable';
import {bootstrap} from 'angular2/platform/browser';
import {Observable, Subscriber} from 'rxjs/Rx';
// #docregion AsyncPipe
@Component({
@ -37,8 +37,9 @@ export class AsyncPipeExample {
// #docregion AsyncPipeObservable
@Component({selector: "task-cmp", template: "Time: {{ time | async }}"})
class Task {
time = new Observable<number>(
observer => { setInterval(_ => observer.next(new Date().getTime()), 500); });
time = new Observable<number>((observer: Subscriber<number>) => {
setInterval(() => observer.next(new Date().getTime()), 500);
});
}
// #enddocregion

View File

@ -1,5 +1,5 @@
import {Component, provide} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {bootstrap} from 'angular2/platform/browser';
// #docregion DatePipe
@Component({

View File

@ -1,5 +1,5 @@
import {Component, provide} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {bootstrap} from 'angular2/platform/browser';
// #docregion JsonPipe
@Component({

View File

@ -1,5 +1,5 @@
import {Component, provide} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {bootstrap} from 'angular2/platform/browser';
// #docregion LowerUpperPipe
@Component({
@ -12,7 +12,7 @@ import {bootstrap} from 'angular2/bootstrap';
})
export class LowerUpperPipeExample {
value: string;
change(value) { this.value = value; }
change(value: string) { this.value = value; }
}
// #enddocregion

View File

@ -1,5 +1,5 @@
import {Component, provide} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {bootstrap} from 'angular2/platform/browser';
// #docregion NumberPipe
@Component({

View File

@ -1,5 +1,5 @@
import {Component, provide} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {bootstrap} from 'angular2/platform/browser';
// #docregion SlicePipe_string
@Component({
@ -22,7 +22,7 @@ export class SlicePipeStringExample {
@Component({
selector: 'slice-list-example',
template: `<div>
<li *ngFor="var i of collection | slice:1:3">{{i}}</li>
<li *ngFor="let i of collection | slice:1:3">{{i}}</li>
</div>`
})
export class SlicePipeListExample {

View File

@ -1,6 +1,6 @@
import {Component, Attribute, Directive, Pipe} from 'angular2/core';
var CustomDirective;
var CustomDirective: Function;
// #docregion component
@Component({selector: 'greet', template: 'Hello {{name}}!', directives: [CustomDirective]})
@ -20,7 +20,7 @@ class Page {
// #docregion attributeMetadata
@Directive({selector: 'input'})
class InputAttrDirective {
constructor(@Attribute('type') type) {
constructor(@Attribute('type') type: string) {
// type would be 'text' in this example
}
}
@ -38,6 +38,6 @@ class InputDirective {
// #docregion pipe
@Pipe({name: 'lowercase'})
class Lowercase {
transform(v, args) { return v.toLowerCase(); }
transform(v: string, args: any[]) { return v.toLowerCase(); }
}
// #enddocregion

View File

@ -1,4 +1,4 @@
import {Component, platform} from 'angular2/core';
import {Component, createPlatform, coreLoadAndBootstrap, ReflectiveInjector} from 'angular2/core';
import {BROWSER_PROVIDERS, BROWSER_APP_PROVIDERS} from 'angular2/platform/browser';
var appProviders: any[] = [];
@ -8,6 +8,8 @@ var appProviders: any[] = [];
class MyApp {
}
var app = platform(BROWSER_PROVIDERS).application([BROWSER_APP_PROVIDERS, appProviders]);
app.bootstrap(MyApp);
var platform = createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PROVIDERS));
var appInjector =
ReflectiveInjector.resolveAndCreate([BROWSER_APP_PROVIDERS, appProviders], platform.injector);
coreLoadAndBootstrap(appInjector, MyApp);
// #enddocregion

View File

@ -1,7 +1,7 @@
// #docregion enableProdMode
import {enableProdMode} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {MyComponent} from 'my_component';
import {bootstrap} from 'angular2/platform/browser';
import {MyComponent} from './my_component';
enableProdMode();
bootstrap(MyComponent);

View File

@ -1,8 +1,8 @@
// #docregion Observable
import {Observable} from 'rxjs/Observable';
var obs = new Observable<number>(obs => {
import {Observable, Subscriber} from 'rxjs/Rx';
var obs = new Observable<number>((obs: Subscriber<number>) => {
var i = 0;
setInterval(_ => { obs.next(++i); }, 1000);
setInterval(() => { obs.next(++i); }, 1000);
});
obs.subscribe(i => console.log(`${i} seconds elapsed`));
// #enddocregion

View File

@ -1,10 +1,10 @@
// #docregion Observable
import {Observable} from 'rxjs/Observable';
import {Observable, Subscriber} from 'rxjs/Rx';
import 'rxjs/add/operator/map';
var obs = new Observable(obs => {
var obs = new Observable<number>((obs: Subscriber<any>) => {
var i = 0;
setInterval(_ => obs.next(++i), 1000);
setInterval(() => obs.next(++i), 1000);
});
obs.map(i => `${i} seconds elapsed`).subscribe(msg => console.log(msg));
obs.map((i: number) => `${i} seconds elapsed`).subscribe(msg => console.log(msg));
// #enddocregion

View File

@ -1,10 +1,10 @@
// #docregion Observable
import {Observable} from 'rxjs/Observable';
import {Observable, Subscriber} from 'rxjs/Rx';
import {map} from 'rxjs/operator/map';
var obs = new Observable(obs => {
var obs = new Observable<number>((sub: Subscriber<number>) => {
var i = 0;
setInterval(_ => obs.next(++i), 1000);
setInterval(() => sub.next(++i), 1000);
});
map.call(obs, i => `${i} seconds elapsed`).subscribe(msg => console.log(msg));
map.call(obs, (i: number) => `${i} seconds elapsed`).subscribe((msg: string) => console.log(msg));
// #enddocregion

View File

@ -1,17 +1,17 @@
import {By} from 'angular2/platform/browser';
import {DebugElement, Scope} from 'angular2/core';
import {DebugElement} from 'angular2/core';
var debugElement: DebugElement;
class MyDirective {}
// #docregion by_all
debugElement.query(By.all(), Scope.all);
debugElement.query(By.all());
// #enddocregion
// #docregion by_css
debugElement.query(By.css('[attribute]'), Scope.all);
debugElement.query(By.css('[attribute]'));
// #enddocregion
// #docregion by_directive
debugElement.query(By.directive(MyDirective), Scope.all);
debugElement.query(By.directive(MyDirective));
// #enddocregion

View File

@ -7,4 +7,4 @@ class MyAppComponent {
// #docregion providers
bootstrap(MyAppComponent, [ELEMENT_PROBE_PROVIDERS]);
// #enddocregion
// #enddocregion

View File

@ -1,12 +1,7 @@
import {provide, Component} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {
CanActivate,
RouteConfig,
ComponentInstruction,
APP_BASE_HREF,
ROUTER_DIRECTIVES
} from 'angular2/router';
import {bootstrap} from 'angular2/platform/browser';
import {CanActivate, RouteConfig, ComponentInstruction, ROUTER_DIRECTIVES} from 'angular2/router';
import {APP_BASE_HREF} from 'angular2/platform/common';
function checkIfWeHavePermission(instruction: ComponentInstruction) {
return instruction.params['id'] == '1';

View File

@ -1,7 +1,7 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
import {Promise} from 'angular2/src/facade/async';
import {verifyNoBrowserErrors, browser} from 'angular2/src/testing/e2e_util';
import {expect} from 'angular2/testing';
function waitForElement(selector) {
function waitForElement(selector: string) {
var EC = (<any>protractor).ExpectedConditions;
// Waits for the element with id 'abc' to be present on the dom.
browser.wait(EC.presenceOf($(selector)), 20000);

View File

@ -1,13 +1,13 @@
import {provide, Component} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {bootstrap} from 'angular2/platform/browser';
import {
CanDeactivate,
RouteConfig,
RouteParams,
ComponentInstruction,
ROUTER_DIRECTIVES,
APP_BASE_HREF
ROUTER_DIRECTIVES
} from 'angular2/router';
import {APP_BASE_HREF} from 'angular2/platform/common';
// #docregion routerCanDeactivate
@Component({

View File

@ -1,7 +1,7 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
import {Promise} from 'angular2/src/facade/async';
import {verifyNoBrowserErrors, browser} from 'angular2/src/testing/e2e_util';
import {expect} from 'angular2/testing';
function waitForElement(selector) {
function waitForElement(selector: string) {
var EC = (<any>protractor).ExpectedConditions;
// Waits for the element with id 'abc' to be present on the dom.
browser.wait(EC.presenceOf($(selector)), 20000);

View File

@ -1,24 +0,0 @@
<!doctype html>
<html>
<head>
<title>Routing Reuse Lifecycle Example</title>
<base href="/">
<script src="http://cdn.rawgit.com/google/traceur-compiler/90da568c7aa8e53ea362db1fc211fbb4f65b5e94/bin/traceur-runtime.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/systemjs/0.18.4/system.js"></script>
<script>System.config({ baseURL: '/', defaultJSExtensions: true});</script>
<script src="/bundle/angular2.dev.js"></script>
<script src="/bundle/router.dev.js"></script>
</head>
<body>
<example-app>
Loading...
</example-app>
<script>
var filename = 'angular2/examples/router/ts/on_activate/on_activate_example';
System.import(filename).then(function(m) {
m.main();
}, console.error.bind(console));
</script>
</body>
</html>

View File

@ -1,21 +1,30 @@
import {Component, provide} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {
OnActivate,
ComponentInstruction,
RouteConfig,
ROUTER_DIRECTIVES,
APP_BASE_HREF
} from 'angular2/router';
import {bootstrap} from 'angular2/platform/browser';
import {OnActivate, ComponentInstruction, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {APP_BASE_HREF} from 'angular2/platform/common';
// #docregion routerOnActivate
@Component({selector: 'my-cmp', template: `<div>routerOnActivate: {{log}}</div>`})
class MyCmp implements OnActivate {
@Component({template: `Child`})
class ChildCmp {
}
@Component({
template: `
<h2>Parent</h2> (<router-outlet></router-outlet>)
<p>{{log}}</p>`,
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([{path: '/child', name: 'Child', component: ChildCmp}])
class ParentCmp implements OnActivate {
log: string = '';
routerOnActivate(next: ComponentInstruction, prev: ComponentInstruction) {
this.log = `Finished navigating from "${prev ? prev.urlPath : 'null'}" to "${next.urlPath}"`;
return new Promise(resolve => {
// The ChildCmp gets instantiated only when the Promise is resolved
setTimeout(() => resolve(null), 1000);
});
}
}
// #enddocregion
@ -24,23 +33,19 @@ class MyCmp implements OnActivate {
@Component({
selector: 'example-app',
template: `
<h1>My App</h1>
<h1>My app</h1>
<nav>
<a [routerLink]="['/HomeCmp']" id="home-link">Navigate Home</a> |
<a [routerLink]="['/ParamCmp', {param: 1}]" id="param-link">Navigate with a Param</a>
<a [routerLink]="['Parent', 'Child']">Child</a>
</nav>
<router-outlet></router-outlet>
`,
directives: [ROUTER_DIRECTIVES]
})
@RouteConfig([
{path: '/', component: MyCmp, name: 'HomeCmp'},
{path: '/:param', component: MyCmp, name: 'ParamCmp'}
])
class AppCmp {
@RouteConfig([{path: '/parent/...', name: 'Parent', component: ParentCmp}])
export class AppCmp {
}
export function main() {
return bootstrap(
AppCmp, [provide(APP_BASE_HREF, {useValue: '/angular2/examples/router/ts/on_activate'})]);

View File

@ -1,34 +0,0 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
import {Promise} from 'angular2/src/facade/async';
function waitForElement(selector) {
var EC = (<any>protractor).ExpectedConditions;
// Waits for the element with id 'abc' to be present on the dom.
browser.wait(EC.presenceOf($(selector)), 20000);
}
describe('on activate example app', function() {
afterEach(verifyNoBrowserErrors);
var URL = 'angular2/examples/router/ts/on_activate/';
it('should update the text when navigating between routes', function() {
browser.get(URL);
waitForElement('my-cmp');
expect(element(by.css('my-cmp')).getText())
.toContain('routerOnActivate: Finished navigating from "null" to ""');
element(by.css('#param-link')).click();
waitForElement('my-cmp');
expect(element(by.css('my-cmp')).getText())
.toContain('routerOnActivate: Finished navigating from "" to "1"');
browser.navigate().back();
waitForElement('my-cmp');
expect(element(by.css('my-cmp')).getText())
.toContain('routerOnActivate: Finished navigating from "1" to ""');
});
});

View File

@ -1,12 +1,7 @@
import {Component, Injectable, provide} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {
OnDeactivate,
ComponentInstruction,
RouteConfig,
ROUTER_DIRECTIVES,
APP_BASE_HREF
} from 'angular2/router';
import {bootstrap} from 'angular2/platform/browser';
import {OnDeactivate, ComponentInstruction, RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';
import {APP_BASE_HREF} from 'angular2/platform/common';
@Injectable()
@ -41,7 +36,7 @@ class MyCmp implements OnDeactivate {
<router-outlet></router-outlet>
<div id="log">
<h2>Log:</h2>
<p *ngFor="#logItem of logService.logs">{{ logItem }}</p>
<p *ngFor="let logItem of logService.logs">{{ logItem }}</p>
</div>
`,
directives: [ROUTER_DIRECTIVES]

View File

@ -1,7 +1,7 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
import {Promise} from 'angular2/src/facade/async';
import {verifyNoBrowserErrors, browser} from 'angular2/src/testing/e2e_util';
import {expect} from 'angular2/testing';
function waitForElement(selector) {
function waitForElement(selector: string) {
var EC = (<any>protractor).ExpectedConditions;
// Waits for the element with id 'abc' to be present on the dom.
browser.wait(EC.presenceOf($(selector)), 20000);

View File

@ -1,15 +1,15 @@
import {Component, provide} from 'angular2/core';
import {bootstrap} from 'angular2/bootstrap';
import {bootstrap} from 'angular2/platform/browser';
import {
CanActivate,
RouteConfig,
ComponentInstruction,
ROUTER_DIRECTIVES,
APP_BASE_HREF,
CanReuse,
RouteParams,
OnReuse
} from 'angular2/router';
import {APP_BASE_HREF} from 'angular2/platform/common';
// #docregion reuseCmp

View File

@ -1,7 +1,7 @@
import {verifyNoBrowserErrors} from 'angular2/src/testing/e2e_util';
import {Promise} from 'angular2/src/facade/async';
import {verifyNoBrowserErrors, browser} from 'angular2/src/testing/e2e_util';
import {expect} from 'angular2/testing';
function waitForElement(selector) {
function waitForElement(selector: string) {
var EC = (<any>protractor).ExpectedConditions;
// Waits for the element with id 'abc' to be present on the dom.
browser.wait(EC.presenceOf($(selector)), 20000);

View File

@ -73,7 +73,7 @@ describe('some component', () => {
// #docregion beforeEachProviders
describe('some component', () => {
beforeEachProviders(() => [provide(MyService, {useClass: MyMockService})]);
it('uses MyService', inject([MyService], (service) => {
it('uses MyService', inject([MyService], (service: MyMockService) => {
// service is an instance of MyMockService.
}));
});
@ -81,7 +81,7 @@ describe('some component', () => {
// #docregion afterEach
describe('some component', () => {
afterEach((done) => { db.reset().then((_) => done()); });
afterEach((done: Function) => { db.reset().then((_: any) => done()); });
it('uses the db', () => {
// This test can leave the database in a dirty state.
// The afterEach will ensure it gets reset.

View File

@ -56,7 +56,7 @@ export {URLSearchParams} from './src/http/url_search_params';
* <div>
* <h1>People</h1>
* <ul>
* <li *ngFor="#person of people">
* <li *ngFor="let person of people">
* {{person.name}}
* </li>
* </ul>
@ -141,7 +141,8 @@ export {URLSearchParams} from './src/http/url_search_params';
* // Send a response to the request
* connection.mockRespond(response);
* });
* });
* }
* });
*
* http.get('people.json').observer({
* next: res => {
@ -156,7 +157,8 @@ export const HTTP_PROVIDERS: any[] = [
// issue: https://github.com/angular/angular/issues/3183
provide(Http,
{
useFactory: (xhrBackend, requestOptions) => new Http(xhrBackend, requestOptions),
useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
new Http(xhrBackend, requestOptions),
deps: [XHRBackend, RequestOptions]
}),
BrowserXhr,
@ -192,7 +194,7 @@ export const HTTP_BINDINGS = HTTP_PROVIDERS;
* <div>
* <h1>People</h1>
* <ul>
* <li *ngFor="#person of people">
* <li *ngFor="let person of people">
* {{person.name}}
* </li>
* </ul>
@ -268,7 +270,8 @@ export const HTTP_BINDINGS = HTTP_PROVIDERS;
* // Send a response to the request
* connection.mockRespond(response);
* });
* });
* }
* });
* jsonp.get('people.json').observer({
* next: res => {
@ -283,7 +286,8 @@ export const JSONP_PROVIDERS: any[] = [
// issue: https://github.com/angular/angular/issues/3183
provide(Jsonp,
{
useFactory: (jsonpBackend, requestOptions) => new Jsonp(jsonpBackend, requestOptions),
useFactory: (jsonpBackend: JSONPBackend, requestOptions: RequestOptions) =>
new Jsonp(jsonpBackend, requestOptions),
deps: [JSONPBackend, RequestOptions]
}),
BrowserJsonp,

9
modules/angular2/i18n.ts Normal file
View File

@ -0,0 +1,9 @@
/**
* @module
* @description
* Entry point to i18n
*/
export * from './src/i18n/message';
export * from './src/i18n/xmb_serializer';
export * from './src/i18n/message_extractor';
export * from './src/i18n/i18n_html_parser';

View File

@ -1,36 +0,0 @@
/**
* Declarations angular depends on for compilation to ES6.
* This file is also used to propagate our transitive typings
* to users.
*/
/// <reference path="../typings/zone/zone.d.ts"/>
/// <reference path="../typings/hammerjs/hammerjs.d.ts"/>
// TODO: ideally the node.d.ts reference should be scoped only for files that need and not to all
// the code including client code
/// <reference path="../typings/node/node.d.ts" />
declare var assert: any;
interface BrowserNodeGlobal {
Object: typeof Object;
Array: typeof Array;
Map: typeof Map;
Set: typeof Set;
Date: typeof Date;
RegExp: typeof RegExp;
JSON: typeof JSON;
Math: typeof Math;
assert(condition: any): void;
Reflect: any;
zone: Zone;
getAngularTestability: Function;
getAllAngularTestabilities: Function;
frameworkStabilizers: Array<Function>;
setTimeout: Function;
clearTimeout: Function;
setInterval: Function;
clearInterval: Function;
}

View File

@ -1,7 +1,52 @@
/**
* Declarations angular depends on for compilation to ES6.
* This file is also used to propagate our transitive typings
* to users.
* Subset of es6-shim typings.
* Angular should not require use of ES6 runtime but some API usages are already present.
* See https://github.com/angular/angular/issues/5242
* TODO(alexeagle): remove methods below which may not be present in targeted browser
*/
/// <reference path="../typings/es6-shim/es6-shim.d.ts"/>
/// <reference path="./globals-es6.d.ts"/>
declare type PromiseConstructor = typeof Promise;
interface String {
/**
* Returns true if the sequence of elements of searchString converted to a String is the
* same as the corresponding elements of this object (converted to a String) starting at
* position. Otherwise returns false.
*/
startsWith(searchString: string, position?: number): boolean;
/**
* Returns true if the sequence of elements of searchString converted to a String is the
* same as the corresponding elements of this object (converted to a String) starting at
* endPosition length(this). Otherwise returns false.
*/
endsWith(searchString: string, endPosition?: number): boolean;
}
interface Array<T> {
/**
* Returns the value of the first element in the array where predicate is true, and undefined
* otherwise.
* @param predicate find calls predicate once for each element of the array, in ascending
* order, until it finds one where predicate returns true. If such an element is found, find
* immediately returns that element value. Otherwise, find returns undefined.
* @param thisArg If provided, it will be used as the this value for each invocation of
* predicate. If it is not provided, undefined is used instead.
*/
find(predicate: (value: T, index: number, obj: Array<T>) => boolean, thisArg?: any): T;
/**
* Returns the this object after filling the section identified by start and end with value
* @param value value to fill array section with
* @param start index to start filling the array at. If start is negative, it is treated as
* length+start where length is the length of the array.
* @param end index to stop filling the array at. If end is negative, it is treated as
* length+end.
*/
fill(value: T, start?: number, end?: number): T[];
}
interface NumberConstructor {
/**
* Returns true if the value passed is an integer, false otherwise.
* @param number A numeric value.
*/
isInteger(number: number): boolean;
}

View File

@ -9,7 +9,6 @@
"repository": <%= JSON.stringify(packageJson.repository) %>,
"devDependencies": <%= JSON.stringify(packageJson.defaultDevDependencies) %>,
"peerDependencies": {
"es6-promise": "<%= packageJson.dependencies['es6-promise'] %>",
"es6-shim": "<%= packageJson.dependencies['es6-shim'] %>",
"reflect-metadata": "<%= packageJson.dependencies['reflect-metadata'] %>",
"rxjs": "<%= packageJson.dependencies['rxjs'] %>",

View File

@ -1,8 +1,9 @@
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
export * from 'angular2/src/core/angular_entrypoint';
export {
BROWSER_PROVIDERS,
ELEMENT_PROBE_BINDINGS,
CACHED_TEMPLATE_PROVIDER,
ELEMENT_PROBE_PROVIDERS,
ELEMENT_PROBE_PROVIDERS_PROD_MODE,
inspectNativeElement,
BrowserDomAdapter,
By,
@ -12,14 +13,24 @@ export {
disableDebugTools
} from 'angular2/src/platform/browser_common';
import {Type, isPresent, CONST_EXPR} from 'angular2/src/facade/lang';
import {Promise} from 'angular2/src/facade/promise';
import {Type, isPresent, isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
import {
BROWSER_PROVIDERS,
BROWSER_APP_COMMON_PROVIDERS
BROWSER_APP_COMMON_PROVIDERS,
BROWSER_PLATFORM_MARKER
} from 'angular2/src/platform/browser_common';
import {COMPILER_PROVIDERS} from 'angular2/compiler';
import {ComponentRef, platform, reflector} from 'angular2/core';
import {
ComponentRef,
coreLoadAndBootstrap,
reflector,
ReflectiveInjector,
PlatformRef,
OpaqueToken,
getPlatform,
createPlatform,
assertPlatform
} from 'angular2/core';
import {ReflectionCapabilities} from 'angular2/src/core/reflection/reflection_capabilities';
import {XHRImpl} from "angular2/src/platform/browser/xhr_impl";
import {XHR} from 'angular2/compiler';
@ -34,6 +45,13 @@ export const BROWSER_APP_PROVIDERS: Array<any /*Type | Provider | any[]*/> = CON
new Provider(XHR, {useClass: XHRImpl}),
]);
export function browserPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PROVIDERS));
}
return assertPlatform(BROWSER_PLATFORM_MARKER);
}
/**
* Bootstrapping for Angular applications.
*
@ -106,7 +124,8 @@ export function bootstrap(
appComponentType: Type,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef> {
reflector.reflectionCapabilities = new ReflectionCapabilities();
let appProviders =
isPresent(customProviders) ? [BROWSER_APP_PROVIDERS, customProviders] : BROWSER_APP_PROVIDERS;
return platform(BROWSER_PROVIDERS).application(appProviders).bootstrap(appComponentType);
var appInjector = ReflectiveInjector.resolveAndCreate(
[BROWSER_APP_PROVIDERS, isPresent(customProviders) ? customProviders : []],
browserPlatform().injector);
return coreLoadAndBootstrap(appInjector, appComponentType);
}

View File

@ -1,8 +1,8 @@
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
export * from 'angular2/src/core/angular_entrypoint';
export {
BROWSER_PROVIDERS,
ELEMENT_PROBE_BINDINGS,
ELEMENT_PROBE_PROVIDERS,
ELEMENT_PROBE_PROVIDERS_PROD_MODE,
inspectNativeElement,
BrowserDomAdapter,
By,
@ -11,13 +11,21 @@ export {
disableDebugTools
} from 'angular2/src/platform/browser_common';
import {Type, isPresent} from 'angular2/src/facade/lang';
import {Promise} from 'angular2/src/facade/promise';
import {Type, isPresent, isBlank} from 'angular2/src/facade/lang';
import {
BROWSER_PROVIDERS,
BROWSER_APP_COMMON_PROVIDERS
BROWSER_APP_COMMON_PROVIDERS,
BROWSER_PLATFORM_MARKER
} from 'angular2/src/platform/browser_common';
import {ComponentRef, platform} from 'angular2/core';
import {
ComponentRef,
coreLoadAndBootstrap,
ReflectiveInjector,
PlatformRef,
getPlatform,
createPlatform,
assertPlatform
} from 'angular2/core';
/**
* An array of providers that should be passed into `application()` when bootstrapping a component
@ -27,6 +35,13 @@ import {ComponentRef, platform} from 'angular2/core';
export const BROWSER_APP_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
BROWSER_APP_COMMON_PROVIDERS;
export function browserStaticPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(BROWSER_PROVIDERS));
}
return assertPlatform(BROWSER_PLATFORM_MARKER);
}
/**
* See {@link bootstrap} for more information.
*/
@ -39,5 +54,7 @@ export function bootstrapStatic(appComponentType: Type,
let appProviders =
isPresent(customProviders) ? [BROWSER_APP_PROVIDERS, customProviders] : BROWSER_APP_PROVIDERS;
return platform(BROWSER_PROVIDERS).application(appProviders).bootstrap(appComponentType);
var appInjector =
ReflectiveInjector.resolveAndCreate(appProviders, browserStaticPlatform().injector);
return coreLoadAndBootstrap(appInjector, appComponentType);
}

View File

@ -0,0 +1,5 @@
/**
* Platform agnostic services.
* Can be used both in the browser and on the server.
*/
export * from 'angular2/src/platform/location';

View File

@ -1,5 +1,6 @@
/**
* This is a set of classes and objects that can be used both in the browser and on the server.
* This is a set of DOM related classes and objects that can be used both in the browser and on the
* server.
*/
export {DOM, setRootDomAdapter, DomAdapter} from 'angular2/src/platform/dom/dom_adapter';
export {DomRenderer} from 'angular2/src/platform/dom/dom_renderer';
@ -12,4 +13,4 @@ export {
EventManagerPlugin
} from 'angular2/src/platform/dom/events/event_manager';
export * from 'angular2/src/platform/dom/debug/by';
export * from 'angular2/src/platform/dom/debug/debug_element_view_listener';
export * from 'angular2/src/platform/dom/debug/ng_probe';

View File

@ -2,14 +2,17 @@ import {
TEST_BROWSER_STATIC_PLATFORM_PROVIDERS,
ADDITIONAL_TEST_BROWSER_PROVIDERS
} from 'angular2/platform/testing/browser_static';
import {BROWSER_APP_PROVIDERS} from 'angular2/platform/browser';
import {CONST_EXPR} from 'angular2/src/facade/lang';
/**
* Default patform providers for testing.
* Providers for using template cache to avoid actual XHR.
* Re-exported here so that tests import from a single place.
*/
export {CACHED_TEMPLATE_PROVIDER} from 'angular2/platform/browser';
/**
* Default platform providers for testing.
*/
export const TEST_BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
CONST_EXPR([TEST_BROWSER_STATIC_PLATFORM_PROVIDERS]);

View File

@ -1,12 +1,11 @@
import {
APP_ID,
DirectiveResolver,
NgZone,
Provider,
ViewResolver,
PLATFORM_COMMON_PROVIDERS,
PLATFORM_INITIALIZER
} from 'angular2/core';
import {DirectiveResolver, ViewResolver} from 'angular2/compiler';
import {BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common';
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
@ -15,7 +14,7 @@ import {MockAnimationBuilder} from 'angular2/src/mock/animation_builder_mock';
import {MockDirectiveResolver} from 'angular2/src/mock/directive_resolver_mock';
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
import {LocationStrategy} from 'angular2/src/router/location_strategy';
import {LocationStrategy} from 'angular2/platform/common';
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
import {XHRImpl} from "angular2/src/platform/browser/xhr_impl";
@ -37,7 +36,7 @@ function initBrowserTests() {
}
/**
* Default patform providers for testing without a compiler.
* Default platform providers for testing without a compiler.
*/
export const TEST_BROWSER_STATIC_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
CONST_EXPR([

View File

@ -1,14 +1,14 @@
import {
APP_ID,
DirectiveResolver,
NgZone,
Provider,
ViewResolver,
PLATFORM_COMMON_PROVIDERS,
PLATFORM_INITIALIZER,
APPLICATION_COMMON_PROVIDERS,
Renderer
} from 'angular2/core';
import {DirectiveResolver, ViewResolver} from 'angular2/compiler';
import {Parse5DomAdapter} from 'angular2/src/platform/server/parse5_adapter';
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
@ -16,7 +16,6 @@ import {MockAnimationBuilder} from 'angular2/src/mock/animation_builder_mock';
import {MockDirectiveResolver} from 'angular2/src/mock/directive_resolver_mock';
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
import {LocationStrategy} from 'angular2/src/router/location_strategy';
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
import {TestComponentBuilder} from 'angular2/src/testing/test_component_builder';
@ -28,7 +27,7 @@ import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
import {RootRenderer} from 'angular2/src/core/render/api';
import {DomRootRenderer, DomRootRenderer_} from 'angular2/src/platform/dom/dom_renderer';
import {DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
import {DomSharedStylesHost, SharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
import {
EventManager,
@ -36,6 +35,7 @@ import {
ELEMENT_PROBE_PROVIDERS
} from 'angular2/platform/common_dom';
import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
import {LocationStrategy} from 'angular2/platform/common';
import {CONST_EXPR} from 'angular2/src/facade/lang';
@ -47,7 +47,7 @@ function initServerTests() {
}
/**
* Default patform providers for testing.
* Default platform providers for testing.
*/
export const TEST_SERVER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
PLATFORM_COMMON_PROVIDERS,
@ -78,6 +78,7 @@ export const TEST_SERVER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | an
new Provider(EVENT_MANAGER_PLUGINS, {useClass: DomEventsPlugin, multi: true}),
new Provider(XHR, {useClass: XHR}),
new Provider(APP_ID, {useValue: 'a'}),
new Provider(SharedStylesHost, {useExisting: DomSharedStylesHost}),
DomSharedStylesHost,
ELEMENT_PROBE_PROVIDERS,
new Provider(DirectiveResolver, {useClass: MockDirectiveResolver}),

View File

@ -1,5 +1,12 @@
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, WORKER_APP_APPLICATION_COMMON;
export "package:angular2/src/core/angular_entrypoint.dart"
@ -12,3 +19,33 @@ 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/router_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,
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 distroy it first.';
}
return platform;
}
Future<ComponentRef> bootstrapApp(
SendPort renderSendPort,
Type appComponentType,
[List<dynamic /*Type | Provider | any[]*/> customProviders]) {
var appInjector = ReflectiveInjector.resolveAndCreate([
WORKER_APP_APPLICATION,
isPresent(customProviders) ? customProviders : []
], workerAppPlatform(renderSendPort).injector);
return coreLoadAndBootstrap(appInjector, appComponentType);
}

View File

@ -1,3 +1,20 @@
import {isPresent, isBlank} from 'angular2/src/facade/lang';
import {
WORKER_APP_PLATFORM,
WORKER_APP_PLATFORM_MARKER
} from 'angular2/src/platform/worker_app_common';
import {WORKER_APP_APPLICATION} from 'angular2/src/platform/worker_app';
import {
PlatformRef,
Type,
ComponentRef,
ReflectiveInjector,
coreLoadAndBootstrap,
getPlatform,
createPlatform,
assertPlatform
} from 'angular2/core';
export {
WORKER_APP_PLATFORM,
WORKER_APP_APPLICATION_COMMON
@ -8,12 +25,28 @@ export {
ClientMessageBrokerFactory,
FnArg,
UiArguments
} from '../src/web_workers/shared/client_message_broker';
} from 'angular2/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 {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
} from 'angular2/src/web_workers/shared/service_message_broker';
export {PRIMITIVE} from 'angular2/src/web_workers/shared/serializer';
export * from 'angular2/src/web_workers/shared/message_bus';
export {WORKER_APP_ROUTER} from 'angular2/src/web_workers/worker/router_providers';
export function workerAppPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_APP_PLATFORM));
}
return assertPlatform(WORKER_APP_PLATFORM_MARKER);
}
export function bootstrapApp(
appComponentType: Type,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ComponentRef> {
var appInjector = ReflectiveInjector.resolveAndCreate(
[WORKER_APP_APPLICATION, isPresent(customProviders) ? customProviders : []],
workerAppPlatform().injector);
return coreLoadAndBootstrap(appInjector, appComponentType);
}

View File

@ -1,5 +1,11 @@
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,
@ -8,7 +14,7 @@ export 'package:angular2/src/platform/worker_render_common.dart'
initializeGenericWorkerRenderer;
export 'package:angular2/src/platform/worker_render.dart'
show WORKER_RENDER_APPLICATION, initIsolate, WebWorkerInstance;
show WORKER_RENDER_APPLICATION, WebWorkerInstance;
export '../src/web_workers/shared/client_message_broker.dart'
show ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments;
@ -18,7 +24,26 @@ export '../src/web_workers/shared/service_message_broker.dart'
export '../src/web_workers/shared/serializer.dart' show PRIMITIVE;
export '../src/web_workers/shared/message_bus.dart';
export '../src/web_workers/ui/router_providers.dart' show WORKER_RENDER_ROUTER;
import 'package:angular2/src/platform/worker_render_common.dart';
const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION_COMMON;
PlatformRef workerRenderPlatform() {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_RENDER_PLATFORM));
}
return assertPlatform(WORKER_RENDER_PLATFORM_MARKER);
}
Future<ApplicationRef> bootstrapRender(
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,3 +1,21 @@
import {isPresent, isBlank} from 'angular2/src/facade/lang';
import {PromiseWrapper} from 'angular2/src/facade/async';
import {
ApplicationRef,
PlatformRef,
ReflectiveInjector,
Provider,
getPlatform,
createPlatform,
assertPlatform
} from 'angular2/core';
import {WORKER_RENDER_APPLICATION} from 'angular2/src/platform/worker_render';
import {
WORKER_SCRIPT,
WORKER_RENDER_PLATFORM,
WORKER_RENDER_PLATFORM_MARKER
} from 'angular2/src/platform/worker_render_common';
export {
WORKER_SCRIPT,
WORKER_RENDER_PLATFORM,
@ -18,9 +36,33 @@ export {
} from '../src/web_workers/shared/service_message_broker';
export {PRIMITIVE} from '../src/web_workers/shared/serializer';
export * from '../src/web_workers/shared/message_bus';
import {WORKER_RENDER_APPLICATION} from 'angular2/src/platform/worker_render';
/**
* @deprecated Use WORKER_RENDER_APPLICATION
*/
export const WORKER_RENDER_APP = WORKER_RENDER_APPLICATION;
export {WORKER_RENDER_ROUTER} from 'angular2/src/web_workers/ui/router_providers';
export function workerRenderPlatform(): PlatformRef {
if (isBlank(getPlatform())) {
createPlatform(ReflectiveInjector.resolveAndCreate(WORKER_RENDER_PLATFORM));
}
return assertPlatform(WORKER_RENDER_PLATFORM_MARKER);
}
export function bootstrapRender(
workerScriptUri: string,
customProviders?: Array<any /*Type | Provider | any[]*/>): Promise<ApplicationRef> {
var pf = ReflectiveInjector.resolveAndCreate(WORKER_RENDER_PLATFORM);
var app = ReflectiveInjector.resolveAndCreate(
[
WORKER_RENDER_APPLICATION,
new Provider(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

@ -17,16 +17,19 @@ dependencies:
intl: '^0.12.4'
logging: '>=0.9.0 <0.12.0'
observe: '^0.13.1'
protobuf: '^0.5.0'
quiver: '^0.21.4'
path: '^1.0.0'
protobuf: '0.5.1'
source_span: '^1.0.0'
stack_trace: '^1.1.1'
build: '>=0.0.1'
dev_dependencies:
code_transformers: '>=0.2.9+4 <0.4.0'
transformer_test: '^0.2.0'
guinness: '^0.1.18'
guinness2: '0.0.5'
quiver: '^0.21.4'
test: '^0.12.6'
transformers:
- angular2
- angular2/transform/codegen
- $dart2js:
commandLineOptions:
- --show-package-warnings

View File

@ -5,33 +5,22 @@
*/
export {Router} from './src/router/router';
export {RouterOutlet} from './src/router/router_outlet';
export {RouterLink} from './src/router/router_link';
export {RouterOutlet} from './src/router/directives/router_outlet';
export {RouterLink} from './src/router/directives/router_link';
export {RouteParams, RouteData} from './src/router/instruction';
export {PlatformLocation} from './src/router/platform_location';
export {RouteRegistry, ROUTER_PRIMARY_COMPONENT} from './src/router/route_registry';
export {LocationStrategy, APP_BASE_HREF} from './src/router/location_strategy';
export {HashLocationStrategy} from './src/router/hash_location_strategy';
export {PathLocationStrategy} from './src/router/path_location_strategy';
export {Location} from './src/router/location';
export * from './src/router/route_config_decorator';
export * from './src/router/route_config/route_config_decorator';
export * from './src/router/route_definition';
export {OnActivate, OnDeactivate, OnReuse, CanDeactivate, CanReuse} from './src/router/interfaces';
export {CanActivate} from './src/router/lifecycle_annotations';
export {CanActivate} from './src/router/lifecycle/lifecycle_annotations';
export {Instruction, ComponentInstruction} from './src/router/instruction';
export {OpaqueToken} from 'angular2/core';
export {ROUTER_PROVIDERS_COMMON} from 'angular2/src/router/router_providers_common';
export {ROUTER_PROVIDERS, ROUTER_BINDINGS} from 'angular2/src/router/router_providers';
import {PlatformLocation} from './src/router/platform_location';
import {LocationStrategy} from './src/router/location_strategy';
import {PathLocationStrategy} from './src/router/path_location_strategy';
import {Router, RootRouter} from './src/router/router';
import {RouterOutlet} from './src/router/router_outlet';
import {RouterLink} from './src/router/router_link';
import {RouteRegistry, ROUTER_PRIMARY_COMPONENT} from './src/router/route_registry';
import {Location} from './src/router/location';
import {ApplicationRef, provide, OpaqueToken, Provider} from 'angular2/core';
import {RouterOutlet} from './src/router/directives/router_outlet';
import {RouterLink} from './src/router/directives/router_link';
import {CONST_EXPR} from './src/facade/lang';
import {BaseException} from 'angular2/src/facade/exceptions';
/**
* A list of directives. To use the router directives like {@link RouterOutlet} and
@ -56,63 +45,3 @@ import {BaseException} from 'angular2/src/facade/exceptions';
* ```
*/
export const ROUTER_DIRECTIVES: any[] = CONST_EXPR([RouterOutlet, RouterLink]);
/**
* A list of {@link Provider}s. To use the router, you must add this to your application.
*
* ### Example ([live demo](http://plnkr.co/edit/iRUP8B5OUbxCWQ3AcIDm))
*
* ```
* import {Component} from 'angular2/core';
* import {
* ROUTER_DIRECTIVES,
* ROUTER_PROVIDERS,
* RouteConfig
* } from 'angular2/router';
*
* @Component({directives: [ROUTER_DIRECTIVES]})
* @RouteConfig([
* {...},
* ])
* class AppCmp {
* // ...
* }
*
* bootstrap(AppCmp, [ROUTER_PROVIDERS]);
* ```
*/
export const ROUTER_PROVIDERS: any[] = CONST_EXPR([
RouteRegistry,
CONST_EXPR(new Provider(LocationStrategy, {useClass: PathLocationStrategy})),
PlatformLocation,
Location,
CONST_EXPR(new Provider(
Router,
{
useFactory: routerFactory,
deps: CONST_EXPR([RouteRegistry, Location, ROUTER_PRIMARY_COMPONENT, ApplicationRef])
})),
CONST_EXPR(new Provider(
ROUTER_PRIMARY_COMPONENT,
{useFactory: routerPrimaryComponentFactory, deps: CONST_EXPR([ApplicationRef])}))
]);
/**
* Use {@link ROUTER_PROVIDERS} instead.
*
* @deprecated
*/
export const ROUTER_BINDINGS = ROUTER_PROVIDERS;
function routerFactory(registry, location, primaryComponent, appRef) {
var rootRouter = new RootRouter(registry, location, primaryComponent);
appRef.registerDisposeListener(() => rootRouter.dispose());
return rootRouter;
}
function routerPrimaryComponentFactory(app) {
if (app.componentTypes.length == 0) {
throw new BaseException("Bootstrap at least one component before injecting Router.");
}
return app.componentTypes[0];
}

View File

@ -1,9 +1,9 @@
import {TEMPLATE_TRANSFORMS} from 'angular2/compiler';
import {Provider} from 'angular2/core';
import {RouterLinkTransform} from 'angular2/src/router/router_link_transform';
import {RouterLinkTransform} from 'angular2/src/router/directives/router_link_transform';
import {CONST_EXPR} from 'angular2/src/facade/lang';
export {RouterLinkTransform} from 'angular2/src/router/router_link_transform';
export {RouterLinkTransform} from 'angular2/src/router/directives/router_link_transform';
/**
* Enables the router link DSL.

View File

@ -0,0 +1,34 @@
import {
ResolvedReflectiveProvider,
Directive,
DynamicComponentLoader,
ViewContainerRef,
Input,
ComponentRef,
ComponentFactory,
ReflectiveInjector
} from 'angular2/core';
import {RouterOutletMap} from '../router';
import {isPresent} from 'angular2/src/facade/lang';
@Directive({selector: 'router-outlet'})
export class RouterOutlet {
private _loaded: ComponentRef;
public outletMap: RouterOutletMap;
@Input() name: string = "";
constructor(parentOutletMap: RouterOutletMap, private _location: ViewContainerRef) {
parentOutletMap.registerOutlet("", this);
}
load(factory: ComponentFactory, providers: ResolvedReflectiveProvider[],
outletMap: RouterOutletMap): ComponentRef {
if (isPresent(this._loaded)) {
this._loaded.destroy();
}
this.outletMap = outletMap;
let inj = ReflectiveInjector.fromResolvedProviders(providers, this._location.parentInjector);
this._loaded = this._location.createComponent(factory, this._location.length, inj, []);
return this._loaded;
}
}

View File

@ -0,0 +1,6 @@
import {RouteSegment, Tree} from './segments';
export interface OnActivate {
routerOnActivate(curr: RouteSegment, prev?: RouteSegment, currTree?: Tree<RouteSegment>,
prevTree?: Tree<RouteSegment>): void;
}

View File

@ -0,0 +1,5 @@
import './interfaces.dart';
bool hasLifecycleHook(String name, Object obj) {
if (name == "routerOnActivate") return obj is OnActivate;
return false;
}

Some files were not shown because too many files have changed in this diff Show More