Compare commits

...

70 Commits

Author SHA1 Message Date
Peter Bacon Darwin dcfcf81893 docs(CHANGELOG): add release notes for 1.6.0-rc.2 2016-11-24 21:30:56 +00:00
Peter Bacon Darwin d7cc863105 docs(CHANGELOG): add release notes for 1.5.9 2016-11-24 20:16:03 +00:00
Martin Probst 6e91f9c25d style: fix CI failure (#15429) 2016-11-23 23:04:05 -08:00
Martin Probst 7f1b8bdfe1 feat(security): explicitly whitelist URL schemes for bootstrap. (#15427)
Many browsers have some extension URL scheme. It is unclear how many of
those have the security issue of allowing parser-inserted loads of
extension URLs.

To be conservative, this code whitelists the URL schemes that are known
to be subject to CSP, i.e. the ones that are expected and safe.
2016-11-23 15:44:43 -08:00
Michał Gołębiowski cc92da0d67 chore(*): cleanup msie handling; add support comments
1. The conditions checking the msie variable value have been simplified.
There is e.g. no point to check if `msie <= 11` since there IE 12 won't ever
exist.
2. Edge UA-sniffing has been added to tests (only!) where appropriate
3. Support comments for IE/Edge have been added.

Closes #15407
2016-11-23 14:42:04 +00:00
Packt c9bb5b9fa4 docs(external-resources): add new book link and alphabetize
Closes #15421
2016-11-23 14:39:06 +00:00
Michał Gołębiowski c54921008d chore(ngAnimate): cleanup vendor prefixes handling in tests
1. Change all transition/transform/animation-related ss.addRule to
   ss.addPossiblyPrefixedRule to account for the -webkit- prefix.
2. Remove manually added -webkit-prefixed rules in favor of automatically
   handling them in ss.addPossiblyPrefixedRule.

Closes #15406
2016-11-23 14:28:12 +01:00
Martin Staffa 69f59f2d01 docs($compile, guide/compiler): add "double compilation" known issue
Related #15278
Closes #15392
2016-11-23 13:52:48 +01:00
Martin Staffa f4fb6e0983 perf(*): don't trigger digests after enter/leave of structural directives
ngIf, ngInclude, ngSwitch, and ngView now use the `done` callback functions on animation runners returned
by leave/enter animations to do internal cleanup (and $anchorScroll for ngInclude and ngView).
Previously, they were using promise callbacks (`then`), which caused an unnessecary digest.

Background:

In https://github.com/angular/angular.js/commit/bf0f5502b1bbfddc5cdd2f138efd9188b8c652a9, animation
promises where introduced instead of animation callbacks. These promises were however not tied to
the digest cycle, so you had to manually call `$apply` inside them.

This was changed in https://github.com/angular/angular.js/commit/c8700f04fb6fb5dc21ac24de8665c0476d6db5ef,
so animation promise callbacks would always trigger a `$digest`. This meant that several built-in
directives would now trigger additional digests on leave (ngIf, ngSwitch) or enter/leave (ngInclude,
ngView). The `done` callback, which receives a single argument indicating success / failure was
introduced to allow digest-less responses, but wasn't applied to these directives.

Note that this applies to all calls to $animate.enter/leave, even if ngAnimate isn't included, and
no actual animations are running, because the animation runner code is in the core ng module.

Fixes #15322
Closes #15345
2016-11-23 13:30:41 +01:00
Martin Staffa a18be15137 style(ngIfSpec.js, ngIncludeSpec.js): add top level describe 2016-11-23 13:30:41 +01:00
Martin Staffa 05a9d3a73c docs(*): add more info deprecation versions 2016-11-23 00:10:54 +01:00
Georgios Kalpakas 60035f597c docs(guide/directive): minor wording and styling fixes 2016-11-22 14:49:26 +02:00
Georgios Kalpakas 0af21a48e5 docs(CHANGELOG.md): minor fixes/tweaks 2016-11-22 09:48:08 +02:00
Santi Albo 991a2b30e0 fix($sce): fix adjustMatcher to replace multiple '*' and '**'
`adjustMatcher` was only replacing the first occurrences of '*' and '**'
that were found in whitelisted and blacklisted url strings.

Closes ##7897
2016-11-21 14:51:48 +00:00
Peter Bacon Darwin fc4afd0c1b docs(CHANGELOG): add 1.6.0-rc.1 changes
Closes #15364
2016-11-21 13:27:47 +00:00
Peter Bacon Darwin d5109e26e4 docs(CHANGELOG): minor typos and fixes 2016-11-21 13:27:47 +00:00
Georgios Kalpakas cf3c736b61 docs(guide/migrate): fix typo in code (&amp; --> &) 2016-11-21 14:21:55 +02:00
Georgios Kalpakas b343e7a560 docs(error/ng:areq): fix typo 2016-11-21 12:55:11 +02:00
Karthikeyan 5ff5815f51 docs(error/ng:areq): mention common error cause
Closes #15414
2016-11-21 12:51:00 +02:00
Georgios Kalpakas a144c1c022 docs(guide/migration): add "Migrate 1.5 to 1.6" section
Closes #15399
2016-11-18 22:04:12 +00:00
Peter Bacon Darwin d79f9b3693 docs(*): fix up deprecation notices 2016-11-18 13:51:56 +00:00
Peter Bacon Darwin f56926a77d chore(docs): deprecation notices for methods and properties
Closes #15351
Closes #15394
2016-11-18 13:51:56 +00:00
Peter Bacon Darwin 17e98ace48 chore(docs): bring in all templates from dgeni-packages 2016-11-18 11:28:14 +00:00
Peter Bacon Darwin 752c989152 chore(package.json): update to latest dgeni-packages 2016-11-18 11:28:14 +00:00
Peter Bacon Darwin 789790feee fix(ngModelOptions): handle update triggers that are not in debounce list
Closes #15401
2016-11-17 23:38:24 +00:00
Peter Bacon Darwin fd1a93a4b0 refactor(ngModelOptions): internal variables do not start with a $ 2016-11-17 23:38:24 +00:00
Michal Bultrowicz 7d24af110a docs(CONTRIBUTING.md): expand test commit type, add info about closing issues
Expanded "test" to also mean test fixes.
Added a link to the help page about closing issues with commit
messages in the section about the footer.

Closes #15340
2016-11-17 22:17:42 +01:00
Arturo Romero ac7a2daf2e docs(guide/Forms): add labels to input elements
Closes #15403
2016-11-17 19:23:52 +01:00
Peter Bacon Darwin 296cfce40c feat(ngModelOptions): allow options to be inherited from ancestor ngModelOptions
Previously, you had to apply a complete set of `ngModelOptions` at many places in
the DOM where you might want to modify just one or two settings.

This change allows more general settings to be applied nearer to the root of the DOM
and then for more specific settings to inherit those general settings further down
in the DOM.

To prevent unwanted inheritance you must opt-in on a case by case basis:
* To inherit as single property you simply provide the special value `"$inherit"`.
* To inherit all properties not specified locally then include a property `"*": "$inherit"`.

Closes #10922
Closes #15389

BREAKING CHANGE:

The programmatic API for `ngModelOptions` has changed. You must now read options
via the `ngModelController.$options.getOption(name)` method, rather than accessing the
option directly as a property of the `ngModelContoller.$options` object. This does not
affect the usage in templates and only affects custom directives that might have been
reading options for their own purposes.

One benefit of these changes, though, is that the `ngModelControler.$options` property
is now guaranteed to be defined so there is no need to check before accessing.

So, previously:

```
var myOption = ngModelController.$options && ngModelController.$options['my-option'];
```

and now:

```
var myOption = ngModelController.$options.getOption('my-option');
```
2016-11-16 13:46:13 +00:00
Peter Bacon Darwin fb0225a36a revert: feat(ngModelOptions): allow options to be inherited from ancestor ngModelOptions
This reverts commit 87a2ff76af
2016-11-16 13:40:46 +00:00
Georgios Kalpakas 7dd42d31a7 docs(ngModel): fix typo and rephrase for simplicity 2016-11-16 12:35:54 +02:00
Georgios Kalpakas 7d9a791c6a fix(ngMock/$controller): respect $compileProvider.preAssignBindingsEnabled()
Fixes #15387

Closes #15395
2016-11-16 11:41:42 +02:00
Martin Staffa 17ddba873b docs($httpProvider): fix broken layout caused by unclosed `
Closes #15393
2016-11-15 18:52:33 +01:00
Peter Bacon Darwin ce49edc08b chore(docs): improve version picker
Closes #15385
2016-11-15 10:40:20 +00:00
Peter Bacon Darwin 0f45adebea chore(package.json): update to latest version of shelljs 2016-11-15 09:59:18 +00:00
Julio Borja Barra 5419201a3c docs(ngModel): fix example
For the example to work correctly, the initial model values have to be empty strings.

Closes #15272
2016-11-14 12:30:11 +02:00
kentwalters fcf182eb13 docs(guide/controller): change "hides" to "shadows"
"Shadows" should better convey the meaning of "overwriting the value of the property in the child
scope, while leaving the parent scope intact".
"Hides" could give the impression that it makes the property unavailable in the child scope and
leaving "overrides" only, could give the impression that the parent scope would be affected too,
especially to people not familiar with JavaScript's prototypal inheritance.

Closes #15375
2016-11-14 12:05:02 +02:00
Peter Bacon Darwin f582f9e57b chore(promises-tests): make timeout longer (correctly) 2016-11-11 12:34:25 +00:00
Peter Bacon Darwin c3a8b5d9f1 chore(promises-tests): make timeout longer 2016-11-10 22:59:37 +00:00
Thomas Grainger 6f072c8a41 docs(angular.isArray): Document that isArray is an alias
Closes #15383
2016-11-10 22:09:56 +00:00
Peter Bacon Darwin 4aa9534b0f fix($location): throw if the path starts with double (back)slashes
Previously `$location` was rewriting such paths to remove not only the
double slashes but also the first segment of the path, leading to an invalid
path.

In this change, we deem leading double (back)slashes an invalid path and
now throw a `$location:badpath` error if that occurs.

Closes #15365
2016-11-09 10:28:40 +00:00
Peter Bacon Darwin 627459b96d test(): remove redundant hashPrefix params 2016-11-09 10:28:40 +00:00
Tim Black 148cd26030 docs(ngRepeat): correct typo
Closes #15378
2016-11-08 23:17:14 +02:00
Martin Staffa 5ac7daea72 fix(input[radio]): use strict comparison when evaluating checked-ness
Closes #15283
Closes #15288

BREAKING CHANGE:

When using input[radio], the checked status is now determined by doing
a strict comparison between the value of the input and the ngModel.$viewValue.
Previously, this was a non-strict comparison (==).

This means in the following examples the radio is no longer checked:

```
  <!-- this.selected = 0 -->
  <input type="radio" ng-model="$ctrl.selected" value="0" >

  <!-- this.selected = 0; this.value = false; -->
  <input type="radio" ng-model="$ctrl.selected" ng-value="$ctrl.value" >
```

The migration strategy is to convert values that matched with non-strict
conversion so that they will match with strict conversion.
2016-11-08 16:42:39 +01:00
Kyle Wuolle b5a5623fc7 docs(filterFilter): mark the comparator parameter as optional
Mark the `comparator` parameter as optional and mention that it defaults to `false`.

Fixes #15312

Closes #15371
2016-11-07 14:55:09 +02:00
Georgios Kalpakas 3e87f54922 docs(ngRepeat): add warning about track by $index with one-time bindings 2016-11-07 12:50:27 +02:00
NoHomey 810a3e429a docs(CHANGELOG.md): add language ids to code blocks for syntax highlighting
Add missing language identifiers to code blocks used as examples, in order to
have proper syntax highlighting.

Fixes #15356

Closes #15357
2016-11-05 18:09:46 +02:00
sathify fc3e48980b chore(docs): apply consistent css property spacing 2016-11-05 14:29:12 +01:00
sathify a48f64162d chore(docs): use $document[0] 2016-11-05 14:29:12 +01:00
Martin Staffa b28f1fc3fb chore(docs-gen): create plnkr examples with the correct version
- docs for the snapshot will include the snapshot files from code.angularjs.org
- docs for tagged versions will include the files from the (Google) CDN
- docs for local / untagged versions will try to include the files from the (Google) CDN, which will fail. This gives immediate feedback that something is broken.

Closes #15267
Closes #15358
2016-11-05 13:18:48 +01:00
Peter Bacon Darwin 53cb1d7d40 chore(protractor): upgrade to latest 4.0.10
This fixes problems with testing against Chrome 54.
2016-11-05 11:33:14 +00:00
Martin Staffa d80cdeb3af docs($routeProvider): document that one of template or templateUrl is required
Closes #8604
2016-11-04 17:50:13 +01:00
Corey Cacic 6d3329479f docs($cookiesProvider): add example for overwriting defaults on provider
Add an example on how to set default values on `$cookiesProvider`. Many similar services support
overriding the `defaults` object with a new one, but this service only supports changing individual
properties.

Closes #15362
2016-11-04 15:12:12 +02:00
Tom Harvey d71788455d docs($resourceProvider): correct JS syntax error in code example
Closes #15360
2016-11-03 15:42:32 +01:00
Michał Gołębiowski bcd0d4d896 feat($compile): set preAssignBindingsEnabled to false by default
Fixes #15350
Closes #15352

BREAKING CHANGE: Previously, $compileProvider.preAssignBindingsEnabled was
set to true by default. This means bindings were pre-assigned in component
constructors. In Angular 1.5+ the place to put the initialization logic
relying on bindings being present is the controller $onInit method.

To migrate follow the example below:

Before:

```js
angular.module('myApp', [])
  .component('myComponent', {
    bindings: {value: '<'},
    controller: function() {
      this.doubleValue = this.value * 2;
    }
  });
```

After:
```js
angular.module('myApp', [])
  .component('myComponent', {
    bindings: {value: '<'},
    controller: function() {
      this.$onInit = function() {
        this.doubleValue = this.value * 2;
      };
    }
  });
```

If you don't have time to migrate the code at the moment, you can flip the
setting back to true:
```js
angular.module('myApp', [])
  .config(function($compileProvider) {
    $compileProvider.preAssignBindingsEnabled(false);
  })
  .component('myComponent', {
    bindings: {value: '<'},
    controller: function() {
      this.doubleValue = this.value * 2;
    }
  });
```
Don't do this if you're writing a library, though, as you shouldn't change
global configuration then.
2016-11-03 15:23:12 +01:00
Martin Probst 0ff10e1b56 fix(security): do not auto-bootstrap when loaded from an extension.
Extension URIs (`resource://...`) bypass Content-Security-Policy in Chrome and
Firefox and can always be loaded. Now if a site already has a XSS bug, and uses
CSP to protect itself, but the user has an extension installed that uses
Angular, an attacked can load Angular from the extension, and Angular's
auto-bootstrapping can be used to bypass the victim site's CSP protection.

Notes:
- `isAutoBootstrapAllowed` must be initialized on load, so that `currentScript`
  is set correctly.
- The tests are a bit indirect as reproducing the actual scenario is too
  complicated to reproduce (requires signing an extension etc). I have confirmed
  this to be working manually.

Closes #15346
2016-11-02 13:33:12 +00:00
Michał Gołębiowski a7076dc0bb chore(*): switch URLs from npmcdn.com to unpkg.com
The domain changed, the old one redirects to the new one.
2016-11-02 14:32:02 +01:00
Martin Staffa 433c8714f3 fix(docsApp): show correct version number in api index
Previously, the index would show the version of Angular that runs on
the page, not the version for which the docs are. This meant that in
that snapshot docs the stable version was displayed.

The `$scope.docsVersion` value was used in the plnkr opening code, but
has not been used since https://github.com/angular/angular.js/commit/bdec35cebc89e0d80a04eeffbd71ad999fc7e61a.

Closes #15265
2016-11-02 13:22:39 +01:00
Martin Staffa 01d8638114 chore: delete the gdocs.js file
This file was probably used for an early version of the docs, but hasn't been updated since 2011.

Closes #15325
2016-11-02 13:21:31 +01:00
Michał Gołębiowski 856e300046 chore(*): make some files non-executable
The repository contained JS/HTML/PNG files that had the executable bit enabled
for no real reason.

Closes #15339
2016-11-02 11:11:49 +01:00
Kyle Lieber 3b7f29ff63 perf(ngOptions): avoid calls to element.value
In some cases IE11/Edge calls to `element.value` are very slow when the
`element.value` has not been set. Normally, these calls are usualy 0-3 ms
but in these cases it can take 200-300 ms. This can easily add 3 or more
seconds to the load time on a view that has 10 or more select tags using
`ngOptions`.

The line this pull request is changing not only suffers from the performance
issue described above but it also appears to be broken. The code is checking
that `option.value` does not equal `element.value` but then sets `element.value`
to `option.selectValue`.

I don't believe `option.value` is actually defined anywhere and likely it
was always intended to be `option.selectValue`. This means that check would
always be true and since this code has been this way for quite a while and
is causing a performance issue I've just removed the check. This way a call
to `element.value` is never made prior to it's value being set.

Closes #15344
2016-11-01 10:40:58 +00:00
Josh Soref bdf960294a docs(CONTRIBUTING.md): add note about scope wildcard 2016-11-01 10:32:03 +00:00
Jason Bedard 79d2b9a5a6 refactor($parse): remove unused expression arguments
These are no longer required after the removal of the expression sandbox errors

Closes #15276
2016-10-31 10:31:23 +01:00
Martin Staffa e77f717ebf docs(guide/Conceptual Overview): fix external api example
In 1.6, urls accessed with jsonp must be whitelisted via sce. 
However, the yahoo finance api used in the example allows CORS
access via Access-Control-Allow-Origin:"*", so we can simply use
`$http.get` instead.

Closes #15336
2016-10-31 10:29:28 +01:00
Erick Delfin 872bdbd343 docs(README.md): mention "Pug" (Jade's new name)
Closes #15338
2016-10-30 21:28:46 +02:00
Jason Bedard f1e677895e refactor($compile): remove unnecessary assignment
Closes #15337
2016-10-30 13:13:54 +02:00
Martin Staffa 7ed0340488 style(ng/animate.js): remove a newline
Closes #15309
2016-10-29 18:52:03 +02:00
Josh Soref 5cce6e233e docs(*): fix typos
* a
* allows
* angularytics
* animate
* architecting
* asynchronously
* attribute
* back
* browser
* callback
* component
* delimited
* dependencies
* dynamically
* empty
* encoded
* explicitly
* expression
* fails
* guarantees
* hierarchy
* highlight
* identifiers
* immediately
* infinite
* initialized
* inputting
* instance
* interprets
* linking
* location
* misformed
* numerically
* occurring
* overridden
* overwritten
* parameters
* Pluralsight
* precedence
* primitive
* properly
* prototypically
* representation
* response
* separately
* separator
* should
* specifying
* supported
* template
* thrown
* transclude
* transclusion
* transitions
* trigger
* useful
2016-10-29 17:40:21 +02:00
Josh Soref 305e201b71 test(*): fix some inconsequential typos
* select
* synopsis
* params
* template
2016-10-29 17:40:21 +02:00
Erik Smith 47ba51eaf6 docs(guide/production): fix typo ("3rd part" --> "3rd party")
Closes #15328
2016-10-29 12:51:25 +03:00
161 changed files with 7890 additions and 4018 deletions
+261 -50
View File
@@ -1,3 +1,210 @@
<a name="1.6.0-rc.2"></a>
# 1.6.0-rc.2 safety-insurance (2016-11-24)
## Security Fixes
- **bootstrap:** explicitly whitelist URL schemes for bootstrap. (#15427)
([7f1b8b](https://github.com/angular/angular.js/commit/7f1b8bdfe1043871c5ead2ec602efc41e0de5e53))
## Bug Fixes
- **$sce:** fix `adjustMatcher` to replace multiple '*' and '**'
([991a2b](https://github.com/angular/angular.js/commit/991a2b30e00aed1d312e29555e356a795f9e3d62))
## Performance Improvements
- ***:** don't trigger digests after enter/leave of structural directives
([f4fb6e](https://github.com/angular/angular.js/commit/f4fb6e0983a6a700dc4a246a913504550b55f1e9)
[#15322](https://github.com/angular/angular.js/issues/15322))
<a name="1.5.9"></a>
# 1.5.9 timeturning-lockdown (2016-11-24)
This is an interim release primarily to publish some security fixes, in particular a modification to
ensure that Angular 1 can pass the linter checks for Mozilla add-ons.
## Security Fixes
- **bootstrap:**
- do not auto-bootstrap when loaded from an extension
([6ce291](https://github.com/angular/angular.js/commit/6ce2913d99bb0dade6027ba9733295d0aa13b242))
- explicitly whitelist URL schemes for bootstrap (#15427)
([4edd2d](https://github.com/angular/angular.js/commit/4edd2d95c11819ece2dda6e65f95f32638fda218))
- **$location:** throw if the path starts with double (back)slashes
([353e3a](https://github.com/angular/angular.js/commit/353e3a6cd8b3a785b5f73a38236155621048522f))
- **$sniffer:** don't use `history.pushState` in sandboxed Chrome Packaged Apps
([367da5](https://github.com/angular/angular.js/commit/367da583bc12e6f5f01edf757305409cf63fb1f4))
- **$parse:**
- block assigning to fields of a constructor prototype
([d7e31b](https://github.com/angular/angular.js/commit/d7e31b5dc71253edb22190a5850034934e7b778a)
[#14939](https://github.com/angular/angular.js/issues/14939))
- correctly escape unsafe identifier characters
([b01460](https://github.com/angular/angular.js/commit/b014607030835358ed7887e9fd1724cdada56690))
- **$compile:**
- ensure that hidden input values are correct after history.back
([6a2488](https://github.com/angular/angular.js/commit/6a24885771cf8c140b5d2895e92b321e60d86b55))
- lower the $sce context for `src` on video, audio, source, track
([68fb70](https://github.com/angular/angular.js/commit/68fb70ed295119d7b00c670d796c1b4186091adb))
## New Features
- **input:**
- add support for binding to `input[range]`
([2e7121](https://github.com/angular/angular.js/commit/2e7121b8e4dcac23f28e2375e775ca56b6baf252))
- make support for `input[range]` opt-in
([07b876](https://github.com/angular/angular.js/commit/07b8761233aaa3d719d94698296295e51c2a1077))
- fix `step` validation for `input[number][ng-range-input]`
([64f6a6](https://github.com/angular/angular.js/commit/64f6a616d401febc3f06309ed5a5efa46b131717)
[#15257](https://github.com/angular/angular.js/issues/15257))
- **ngMock/$httpBackend:** flush requests in any order
([098b6f](https://github.com/angular/angular.js/commit/098b6f519a53f6348127cd4ce09bca1423cbeb1a))
## Bug Fixes
- **$httpBackend:** complete the request on timeout
([549edc](https://github.com/angular/angular.js/commit/549edc9d0123d50657d5a03ba0c547cb0f91727f)
[#14969](https://github.com/angular/angular.js/issues/14969))
- **ngOptions:** remove selected attribute from unselected options
([d31b3a](https://github.com/angular/angular.js/commit/d31b3a65b65b73ab077026fc028ddf5b6232fba2)
[#14892](https://github.com/angular/angular.js/issues/14892))
## Performance Improvements
- **$parse:** improve performance of assignment expressions
([f83c3d](https://github.com/angular/angular.js/commit/f83c3dea23f910aed25dcf9b85fadf7f11a2a366))
- **$compile:** add provider option to turn off compilation of css class and comment directives
([775c24](https://github.com/angular/angular.js/commit/775c247085765e08845ae45ed19dd0120c61acc1))
<a name="1.6.0-rc.1"></a>
# 1.6.0-rc.1 proximity-warning (2016-11-21)
## New Features
- **ngModelOptions:** allow options to be inherited from ancestor `ngModelOptions` ([296cfc](https://github.com/angular/angular.js/commit/296cfce40c25e9438bfa46a0eb27240707a10ffa) [#10922](https://github.com/angular/angular.js/issues/10922))
- **$compile:** set `preAssignBindingsEnabled` to false by default ([bcd0d4](https://github.com/angular/angular.js/commit/bcd0d4d896d0dfdd988ff4f849c1d40366125858) [#15352](https://github.com/angular/angular.js/issues/15352))
## Bug Fixes
- **ngModelOptions:** handle debounce of `updateOn` triggers that are not in debounce list ([789790](https://github.com/angular/angular.js/commit/789790feee4d6c5b1f5d5b18ecb0ccf6edd36fb3))
- **ngMock/$controller:** respect `$compileProvider.preAssignBindingsEnabled()` ([7d9a79](https://github.com/angular/angular.js/commit/7d9a791c6a8c80d29d6c84afa287c81f2a307439))
- **$location:** throw if the path starts with double (back)slashes ([4aa953](https://github.com/angular/angular.js/commit/4aa9534b0fea732d6492a2863c3ee7e077c8d004))
- **core:** do not auto-bootstrap when loaded from an extension. ([0ff10e](https://github.com/angular/angular.js/commit/0ff10e1b56c6b7c4ac465e35c96a5886e294bac5))
- **input[radio]:** use strict comparison when evaluating checked-ness ([5ac7da](https://github.com/angular/angular.js/commit/5ac7daea72ec31cf337d1d21b13f0d17ff33994f) [#15288](https://github.com/angular/angular.js/issues/15288))
## Reverts
- **ngModelOptions:** allow options to be inherited from ancestor ngModelOptions ([fb0225](https://github.com/angular/angular.js/commit/fb0225a36afb08ab14a808a2fd2d2f39c13fce32))
## Performance Improvements
- **ngOptions:** avoid calls to `element.value` ([3b7f29](https://github.com/angular/angular.js/commit/3b7f29ff63e8bf02327a1430dcc2a4c83915a206))
## Breaking Changes
- **feat($compile): set preAssignBindingsEnabled to false by default ([bcd0d4](https://github.com/angular/angular.js/commit/bcd0d4d896d0dfdd988ff4f849c1d40366125858))**:
Previously, `$compileProvider.preAssignBindingsEnabled` was
set to true by default. This means bindings were pre-assigned in component
constructors. In Angular 1.5+ the place to put the initialization logic
relying on bindings being present is the controller `$onInit` method.
To migrate follow the example below:
Before:
```js
angular.module('myApp', [])
.component('myComponent', {
bindings: {value: '<'},
controller: function() {
this.doubleValue = this.value * 2;
}
});
```
After:
```js
angular.module('myApp', [])
.component('myComponent', {
bindings: {value: '<'},
controller: function() {
this.$onInit = function() {
this.doubleValue = this.value * 2;
};
}
});
```
If you don't have time to migrate the code at the moment, you can flip the
setting back to true:
```js
angular.module('myApp', [])
.config(function($compileProvider) {
$compileProvider.preAssignBindingsEnabled(true);
})
.component('myComponent', {
bindings: {value: '<'},
controller: function() {
this.doubleValue = this.value * 2;
}
});
```
Don't do this if you're writing a library, though, as you shouldn't change
global configuration then.
- **fix(input[radio]): use strict comparison when evaluating checked-ness ([5ac7da](https://github.com/angular/angular.js/commit/5ac7daea72ec31cf337d1d21b13f0d17ff33994f))**:
When using input[radio], the checked status is now determined by doing
a strict comparison between the value of the input and the ngModel.$viewValue.
Previously, this was a non-strict comparison (==).
This means in the following examples the radio is no longer checked:
```
<!-- this.selected = 0 -->
<input type="radio" ng-model="$ctrl.selected" value="0" >
<!-- this.selected = 0; this.value = false; -->
<input type="radio" ng-model="$ctrl.selected" ng-value="$ctrl.value" >
```
The migration strategy is to convert values that matched with non-strict
conversion so that they will match with strict conversion.
- **feat(ngModelOptions): allow options to be inherited from ancestor `ngModelOptions` ([296cfc](https://github.com/angular/angular.js/commit/296cfce40c25e9438bfa46a0eb27240707a10ffa))**:
The programmatic API for `ngModelOptions` has changed. You must now read options
via the `ngModelController.$options.getOption(name)` method, rather than accessing the
option directly as a property of the `ngModelContoller.$options` object. This does not
affect the usage in templates and only affects custom directives that might have been
reading options for their own purposes.
One benefit of these changes, though, is that the `ngModelControler.$options` property
is now guaranteed to be defined so there is no need to check before accessing.
So, previously:
```
var myOption = ngModelController.$options && ngModelController.$options['my-option'];
```
and now:
```
var myOption = ngModelController.$options.getOption('my-option');
```
<a name="1.6.0-rc.0"></a>
# 1.6.0-rc.0 bracing-vortex (2016-10-26)
@@ -86,7 +293,7 @@ Please read the [Sandbox Removal Blog Post](http://angularjs.blogspot.com/2016/0
## Breaking Changes
### **jqLite** due to:
- **[fc0c11](https://github.com/angular/angular.js/commit/fc0c11db845d53061430b7f05e773dcb3fb5b860))**: camelCase keys in `jqLite#data`
- **[fc0c11](https://github.com/angular/angular.js/commit/fc0c11db845d53061430b7f05e773dcb3fb5b860)**: camelCase keys in `jqLite#data`
Previously, keys passed to the data method were left untouched.
Now they are internally camelCased similarly to how jQuery handles it, i.e.
@@ -101,7 +308,7 @@ To migrate the code follow the examples below:
BEFORE:
```
```js
/* 1 */
elem.data('my-key', 2);
elem.data('myKey', 3);
@@ -119,7 +326,7 @@ elem.data('foo-bar'); // 1
AFTER:
```
```js
/* 1 */
// Rename one of the keys as they would now map to the same data slot.
elem.data('my-key', 2);
@@ -152,7 +359,7 @@ Before:
HTML:
```
```html
// All five versions used to be equivalent.
<div ng-style={background_color: 'blue'}></div>
<div ng-style={'background:color': 'blue'}></div>
@@ -163,7 +370,7 @@ HTML:
JS:
```
```js
// All five versions used to be equivalent.
elem.css('background_color', 'blue');
elem.css('background:color', 'blue');
@@ -183,7 +390,7 @@ After:
HTML:
```
```html
// Previous five versions are no longer equivalent but these two still are.
<div ng-style={'background-color': 'blue'}></div>
<div ng-style={backgroundColor: 'blue'}></div>
@@ -191,7 +398,7 @@ HTML:
JS:
```
```js
// Previous five versions are no longer equivalent but these two still are.
elem.css('background-color', 'blue');
elem.css('backgroundColor', 'blue');
@@ -212,39 +419,39 @@ To migrate the code follow the example below:
Before:
```
```js
elem.attr(booleanAttrName, '');
```
After:
```
```js
elem.attr(booleanAttrName, false);
```
or:
```
```js
elem.attr(booleanAttrName, null);
```
- **[4e3624](https://github.com/angular/angular.js/commit/4e3624552284d0e725bf6262b2e468cd2c7682fa)**: remove the attribute for `.attr(attribute, null)`
Invoking `elem.attr(attributeName, null)` would set the
`attributeName` atribute value to a string `"null"`, now it removes the
`attributeName` attribute value to a string `"null"`, now it removes the
attribute instead.
To migrate the code follow the example below:
Before:
```
```js
elem.attr(attributeName, null);
```
After:
```
```js
elem.attr(attributeName, "null");
```
@@ -260,7 +467,7 @@ Before:
HTML:
```
```html
<select multiple>
<option>value 1</option>
<option>value 2</option>
@@ -269,7 +476,7 @@ HTML:
JavaScript:
```
```js
var value = $element.val();
if (value) {
/* do something */
@@ -280,7 +487,7 @@ After:
HTML:
```
```html
<select multiple>
<option>value 1</option>
<option>value 2</option>
@@ -289,7 +496,7 @@ HTML:
JavaScript:
```
```js
var value = $element.val();
if (value.length > 0) {
/* do something */
@@ -302,7 +509,7 @@ JavaScript:
- **[7bc71a](https://github.com/angular/angular.js/commit/7bc71adc63bb6bb609b44dd2d3ea8fb0cd3f300b)**: treat synchronous validators as boolean always
Previously, only a literal `false` return would resolve as the
synchronous validator failing. Now, all traditionally false JavaScript values
synchronous validator failing. Now, all falsy JavaScript values
are treated as failing the validator, as one would naturally expect.
Specifically, the values `0` (the number zero), `null`, `NaN` and `''` (the
@@ -326,12 +533,14 @@ NgModelController and FormController methods without context.
For example
`$scope.$watch('something', myNgModelCtrl.$render)`
```js
$scope.$watch('something', myNgModelCtrl.$render)
```
will no longer work because the `$render` method is passed without any context.
This must now be replaced with
```
```js
$scope.$watch('something', function() {
myNgModelCtrl.$render();
})
@@ -340,6 +549,8 @@ $scope.$watch('something', function() {
or possibly by using `Function.prototype.bind` or `angular.bind`.
### `aria/ngModel` due to:
- **[975a61](https://github.com/angular/angular.js/commit/975a6170efceb2a5e6377c57329731c0636eb8c8)**: do not overwrite the default `$isEmpty()` method for checkboxes
Custom `checkbox`-shaped controls (e.g. checkboxes, menuitemcheckboxes), no longer have a custom
@@ -490,14 +701,14 @@ the `$http.defaults.jsonpCallbackParam` property, which is `"callback"` by defau
Before this change:
```
```js
$http.json('trusted/url?callback=JSON_CALLBACK');
$http.json('other/trusted/url', {params: {cb:'JSON_CALLBACK'}});
```
After this change:
```
```js
$http.json('trusted/url');
$http.json('other/trusted/url', {jsonpCallbackParam:'cb'});
```
@@ -512,24 +723,24 @@ method.**
You configure this list in a module configuration block:
```
```js
appModule.config(['$sceDelegateProvider', function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhiteList([
// Allow same origin resource loads.
'self',
// Allow JSONP calls that match this pattern
'https://some.dataserver.com/**.jsonp?**`
'https://some.dataserver.com/**.jsonp?**'
]);
}]);
```
**Explicitly trusting the URL via the `$sce.trustAsResourceUrl(url)`
method**
method.**
You can pass a trusted object instead of a string as a URL to the `$http`
service:
```
```js
var promise = $http.jsonp($sce.trustAsResourceUrl(url));
```
@@ -595,14 +806,14 @@ ancestor.
It is possible that an `ngModelOptions` directive that does not set a property,
has an ancestor ngModelOptions that does set this property to a value other than
`undefined`. This would cause the `ngModel` and input controls below this `ngModelOptions`
directive to display different behaviour. This is fixed by explictly setting the
directive to display different behaviour. This is fixed by explicitly setting the
property in the `ngModelOptions` to prevent it from inheriting from the ancestor.
For example if you had the following HTML:
```
```html
<form ng-model-options="{updateOn: 'blur'}">
<input ng-model="...">
<input ng-model="..." ng-model-options="{allowInvalid: true}">
</form>
```
@@ -611,9 +822,9 @@ After this change the input will inherit the option to update on blur.
If you want the original behaviour then you will need to specify the option
on the input as well:
```
```html
<form ng-model-options="{updateOn: 'blur'}">
<input ng-model="..." ng-model-options="{updateOn: 'default'}">
<input ng-model="..." ng-model-options="{updateOn: 'default', allowInvalid: true}">
</form>
```
@@ -667,7 +878,7 @@ might have unexpectd side effects in the following cases:
```js
// Assuming the following component:
.compoent('someThing', {
.component('someThing', {
template: '<ng-transclude><!-- Default content goes here --></ng-transclude>'
transclude: {
ignored: 'veryImportantContent'
@@ -725,7 +936,7 @@ The breaking change should be rare, as it relates to incorrect API use that shou
production apps in the first place.
- **fix($compile): secure `link[href]` as a `RESOURCE_URL`s in `$sce`. ([04cad4](https://github.com/angular/angular.js/commit/04cad41d26ebaf44b5ee0c29a152d61f235f3efa))**:
- **[04cad4](https://github.com/angular/angular.js/commit/04cad41d26ebaf44b5ee0c29a152d61f235f3efa)**: secure `link[href]` as a `RESOURCE_URL` in `$sce`
`link[href]` attributes are now protected via `$sce`, which prevents interpolated
values that fail the `RESOURCE_URL` context tests from being used in interpolation.
@@ -754,14 +965,14 @@ A common cases where stray white-space can cause problems is when
attribute values are compared, for example in an $observer:
Before:
```
```js
$attrs.$observe('myAttr', function(newVal) {
if (newVal === 'false') ...
});
```
To migrate, the attribute value should be trimmed manually:
```
```js
$attrs.$observe('myAttr', function(newVal) {
if (newVal.trim() === 'false') ...
});
@@ -884,7 +1095,7 @@ directive attributes).
All owned properties of the `params` object that are not used to replace URL params, will be passed
to `$http` as `config.params` (to be used as query parameters in the URL), even if
`Object.prototype` has a property with same name. E.g.:
`Object.prototype` has a property with the same name. E.g.:
Before:
@@ -901,7 +1112,7 @@ After:
```js
var Foo = $resource('/foo/:id');
Foo.get({id: 42, bar: 'baz', toString: 'hmm'});
// URL: /foo/42?bar=baz&amp;toString=hmm
// URL: /foo/42?bar=baz&toString=hmm
// Note that `toString` _is_ included in the query, as expected :)
```
@@ -1049,7 +1260,7 @@ a "!" prefix. For example, rather than `mydomain.com/#/a/b/c` will become
If you actually wanted to have no hash-prefix then you should configure
this by adding a configuration block to you application:
```
```js
appModule.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix('');
}]);
@@ -2919,7 +3130,7 @@ the built-in pattern validator:
/**
* The built-in directive will call our overwritten validator
* (see below). We just need to update the regex.
* The preLink fn guaranetees our observer is called first.
* The preLink fn guarantees our observer is called first.
*/
if (isString(regex) && regex.length > 0) {
regex = new RegExp('^' + regex + '$');
@@ -3035,7 +3246,7 @@ the built-in pattern validator:
/**
* The built-in directive will call our overwritten validator
* (see below). We just need to update the regex.
* The preLink fn guaranetees our observer is called first.
* The preLink fn guarantees our observer is called first.
*/
if (isString(regex) && regex.length > 0) {
regex = new RegExp('^' + regex + '$');
@@ -4909,7 +5120,7 @@ behavior is undefined.
([96c61fe7](https://github.com/angular/angular.js/commit/96c61fe756d7d3db011818bf0925e3d86ffff8ce),
[#10278](https://github.com/angular/angular.js/issues/10278))
- **orderBy:**
- make object-to-primtiive behavior work for objects with null prototype
- make object-to-primitive behavior work for objects with null prototype
([3aa57528](https://github.com/angular/angular.js/commit/3aa5752894419b4638d5c934879258fa6a1c0d07))
- maintain order in array of objects when predicate is not provided
([8bfeddb5](https://github.com/angular/angular.js/commit/8bfeddb5d671017f4a21b8b46334ac816710b143),
@@ -7066,7 +7277,7 @@ Closes #7336
Previously, it was possible for an action passed to $watch
to be a string, interpreted as an angular expresison. This is no longer supported.
to be a string, interpreted as an angular expression. This is no longer supported.
The action now has to be a function.
Passing an action to $watch is still optional.
@@ -8967,7 +9178,7 @@ The animation mock module has been renamed from `mock.animate` to `ngAnimateMock
After:
```
// POST, PUT and PATCH default headers must be specified seperately,
// POST, PUT and PATCH default headers must be specified separately,
// as they do not share data.
$httpProvider.defaults.headers.post =
$httpProvider.defaults.headers.put =
@@ -9753,7 +9964,7 @@ There are no breaking changes in this release (promise!)
([31c56f54](https://github.com/angular/angular.js/commit/31c56f540045b5270f5b8e235873da855caf3486),
[#4145](https://github.com/angular/angular.js/issues/4145),
[#3964](https://github.com/angular/angular.js/issues/3964))
- **ngTransclude:** detect ngTranslude usage without a transclusion directive
- **ngTransclude:** detect ngTransclude usage without a transclusion directive
([5a1a6b86](https://github.com/angular/angular.js/commit/5a1a6b86a8dbcd8aa4fe9c59fad8d005eead686c),
[#3759](https://github.com/angular/angular.js/issues/3759))
@@ -9821,7 +10032,7 @@ There are no breaking changes in this release (promise!)
- ensure transition-property is not changed when only keyframe animations are in use
([2df3c9f5](https://github.com/angular/angular.js/commit/2df3c9f58def9584455f7c4bfdabbd12aab58bf9),
[#3933](https://github.com/angular/angular.js/issues/3933))
- avoid completing the animation asynchronously unless CSS transtiions/animations are present
- avoid completing the animation asynchronously unless CSS transitions/animations are present
([2a63dfa6](https://github.com/angular/angular.js/commit/2a63dfa6cc7889888f4296fff2944e74ff30b3af),
[#4023](https://github.com/angular/angular.js/issues/4023),
[#3940](https://github.com/angular/angular.js/issues/3940))
@@ -11463,7 +11674,7 @@ This release also contains all bug fixes available in [1.0.2](#1.0.2).
## Features
- **$http:** support custom reponseType
- **$http:** support custom responseType
([e0a54f6b](https://github.com/angular/angular.js/commit/e0a54f6b206dc2b6595f2bc3a17c5932e7477545),
[#1013](https://github.com/angular/angular.js/issues/1013))
- **$interpolate:**
@@ -11610,14 +11821,14 @@ This release also contains all bug fixes available in [1.0.2](#1.0.2).
- allow defining route async dependencies as promises and defer route change until all promises
are resolved
([885fb0dd](https://github.com/angular/angular.js/commit/885fb0dd0743859a8985c23e4d0c1855a2be711e))
- rename template -> tempalteUrl and add support for inline templates
- rename template -> templateUrl and add support for inline templates
([0a6e464a](https://github.com/angular/angular.js/commit/0a6e464a93d9a1e76a624b356054ce9ca4015f55))
- **$compile:** simplify isolate scope bindings and introduce true two-way data-binding between
parent scope and isolate scope
([c3a41ff9](https://github.com/angular/angular.js/commit/c3a41ff9fefe894663c4d4f40a83794521deb14f))
- **$injector:** provide API for retrieving function annotations
([4361efb0](https://github.com/angular/angular.js/commit/4361efb03b79e71bf0cea92b94ff377ed718bad4))
- **$location:** add $locatonChange[start|success] event - since events are cancelable, it's now
- **$location:** add $locationChange[start|success] event - since events are cancelable, it's now
possible to cancel route and location changes.
([92a2e180](https://github.com/angular/angular.js/commit/92a2e1807657c69e1372106b0727675a30f4cbd7))
- **$rootElement:** expose application root element as $rootElement service
@@ -11940,7 +12151,7 @@ This release also contains all bug fixes available in [1.0.2](#1.0.2).
([06d09550](https://github.com/angular/angular.js/commit/06d0955074f79de553cc34fbf945045dc458e064))
- **booleanAttrs:** always convert the model to boolean before setting the element property
([dcb8e076](https://github.com/angular/angular.js/commit/dcb8e0767fbf0a7a55f3b0045fd01b2532ea5441))
- **form:** preperly clean up when invalid widget is removed
- **form:** properly clean up when invalid widget is removed
([21b77ad5](https://github.com/angular/angular.js/commit/21b77ad5c231ab0e05eb89f22005f7ed8d40a6c1))
- **ngHref:** copy even if no binding
([2f5dba48](https://github.com/angular/angular.js/commit/2f5dba488e855bcdbb9304aa809efcb9de7b43e9))
@@ -12082,7 +12293,7 @@ We removed two useless features:
([ee5a5352](https://github.com/angular/angular.js/commit/ee5a5352fd4b94cedee6ef20d4bf2d43ce77e00b),
[#806](https://github.com/angular/angular.js/issues/806))
- **directives:**
- **select:** multiselect failes to update view on selection insert
- **select:** multiselect fails to update view on selection insert
([6ecac8e7](https://github.com/angular/angular.js/commit/6ecac8e71a84792a434d21db2c245b3648c55f18))
- **ngForm:** alias name||ngForm
([823adb23](https://github.com/angular/angular.js/commit/823adb231995e917bc060bfa49453e2a96bac2b6))
+5 -2
View File
@@ -241,7 +241,7 @@ Must be one of the following:
semi-colons, etc)
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **perf**: A code change that improves performance
* **test**: Adding missing tests
* **test**: Adding missing or correcting existing tests
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
generation
@@ -249,6 +249,8 @@ Must be one of the following:
The scope could be anything specifying place of the commit change. For example `$location`,
`$browser`, `$compile`, `$rootScope`, `ngHref`, `ngClick`, `ngView`, etc...
You can use `*` when the change affects more than a single scope.
### Subject
The subject contains succinct description of the change:
@@ -262,7 +264,7 @@ The body should include the motivation for the change and contrast this with pre
### Footer
The footer should contain any information about **Breaking Changes** and is also the place to
reference GitHub issues that this commit **Closes**.
[reference GitHub issues that this commit closes][closing-issues].
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
@@ -285,6 +287,7 @@ You can find out more detailed information about contributing in the
[Google Closure I18N library]: https://github.com/google/closure-library/tree/master/closure/goog/i18n
[angular-dev]: https://groups.google.com/forum/?fromgroups#!forum/angular-dev
[closing-issues]: https://help.github.com/articles/closing-issues-via-commit-messages/
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
[contribute]: http://docs.angularjs.org/misc/contribute
+2 -2
View File
@@ -302,7 +302,7 @@ module.exports = function(grunt) {
stderr: true,
failOnError: true
},
command: path.normalize('./node_modules/.bin/promises-aplus-tests tmp/promises-aplus-adapter++.js')
command: path.normalize('./node_modules/.bin/promises-aplus-tests tmp/promises-aplus-adapter++.js --timeout 2000')
}
},
@@ -346,7 +346,7 @@ module.exports = function(grunt) {
grunt.registerTask('minify', ['bower', 'clean', 'build', 'minall']);
grunt.registerTask('webserver', ['connect:devserver']);
grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'docs', 'copy', 'write', 'compress']);
grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'write', 'docs', 'copy', 'compress']);
grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'eslint']);
grunt.registerTask('default', ['package']);
};
+1 -1
View File
@@ -2,7 +2,7 @@ AngularJS [![Build Status](https://travis-ci.org/angular/angular.js.svg?branch=m
=========
AngularJS lets you write client-side web applications as if you had a smarter browser. It lets you
use good old HTML (or HAML, Jade and friends!) as your template language and lets you extend HTMLs
use good old HTML (or HAML, Jade/Pug and friends!) as your template language and lets you extend HTMLs
syntax to express your applications components clearly and succinctly. It automatically
synchronizes data from your UI (view) with your JavaScript objects (model) through 2-way data
binding. To help you structure your application better and make it easy to test, AngularJS teaches
Vendored Executable → Regular
+1
View File
@@ -70,6 +70,7 @@ var angularFiles = {
'src/ng/directive/ngInit.js',
'src/ng/directive/ngList.js',
'src/ng/directive/ngModel.js',
'src/ng/directive/ngModelOptions.js',
'src/ng/directive/ngNonBindable.js',
'src/ng/directive/ngOptions.js',
'src/ng/directive/ngPluralize.js',
Executable → Regular
View File
View File
View File
View File
View File
View File
View File
View File
View File
+2 -2
View File
@@ -22,7 +22,7 @@ ul.doc-example > li.doc-example-heading {
span.nojsfiddle {
float: right;
font-size: 14px;
margin-right:10px;
margin-right: 10px;
margin-top: 10px;
}
@@ -42,7 +42,7 @@ form.jsfiddle button {
color: #7989D6;
border-color: #7989D6;
-moz-border-radius: 8px;
-webkit-border-radius:8px;
-webkit-border-radius: 8px;
border-radius: 8px;
}
+229 -215
View File
@@ -1,21 +1,21 @@
html, body {
position:relative;
height:100%;
position: relative;
height: 100%;
}
#wrapper {
min-height:100%;
position:relative;
padding-bottom:120px;
min-height: 100%;
position: relative;
padding-bottom: 120px;
}
.footer {
border-top:20px solid white;
position:absolute;
bottom:0;
left:0;
right:0;
z-index:100;
border-top: 20px solid white;
position: absolute;
bottom: 0;
left: 0;
right: 0;
z-index: 100;
padding-top: 2em;
background-color: #333;
color: white;
@@ -23,20 +23,20 @@ html, body {
}
.header-fixed {
position:fixed;
z-index:1000;
top:0;
left:0;
right:0;
position: fixed;
z-index: 1000;
top: 0;
left: 0;
right: 0;
}
.header-branding {
min-height:41px!important;
min-height: 41px !important;
}
.docs-navbar-primary {
border-radius:0!important;
margin-bottom:0!important;
border-radius: 0 !important;
margin-bottom: 0 !important;
}
/* Logo */
@@ -49,7 +49,7 @@ h1,h2,h3,h4,h5,h6 {
}
.subnav-body {
margin:70px 0 20px;
margin: 70px 0 20px;
}
.header .brand {
@@ -58,32 +58,32 @@ h1,h2,h3,h4,h5,h6 {
}
.header .brand img {
margin-top:5px;
margin-top: 5px;
height: 30px;
}
.docs-search {
margin:10px 0;
padding:4px 0 4px 20px;
background:white;
border-radius:20px;
vertical-align:middle;
margin: 10px 0;
padding: 4px 0 4px 20px;
background: white;
border-radius: 20px;
vertical-align: middle;
}
.docs-search > .search-query {
font-size:14px;
border:0;
width:80%;
color:#555;
font-size: 14px;
border: 0;
width: 80%;
color: #555;
}
.docs-search > .search-icon {
font-size:15px;
margin-right:10px;
font-size: 15px;
margin-right: 10px;
}
.docs-search > .search-query:focus {
outline:0;
outline: 0;
}
/* end: Logo */
@@ -101,31 +101,31 @@ h1,h2,h3,h4,h5,h6 {
.naked-list,
.naked-list ul,
.naked-list li {
list-style:none;
margin:0;
padding:0;
list-style: none;
margin: 0;
padding: 0;
}
.nav-index-section a {
font-weight:bold;
font-weight: bold;
font-family: "Open Sans";
color:black!important;
margin-top:10px;
display:block;
color: black !important;
margin-top: 10px;
display: block;
}
.nav-index-group {
margin-bottom:20px!important;
margin-bottom: 20px !important;
}
.nav-index-group-heading {
color:#6F0101;
font-weight:bold;
font-size:1.2em;
padding:0;
margin:0;
border-bottom:1px solid #aaa;
margin-bottom:5px;
color: #6F0101;
font-weight: bold;
font-size: 1.2em;
padding: 0;
margin: 0;
border-bottom: 1px soild #aaa;
margin-bottom: 5px;
}
.nav-index-group .nav-index-listing.current a {
@@ -133,58 +133,58 @@ h1,h2,h3,h4,h5,h6 {
}
.nav-breadcrumb {
margin:4px 0;
padding:0;
margin: 4px 0;
padding: 0;
}
.nav-breadcrumb-entry {
font-family: "Open Sans";
padding:0;
margin:0;
font-size:18px;
display:inline-block;
vertical-align:middle;
padding: 0;
margin: 0;
font-size: 18px;
display: inline-block;
vertical-align: middle;
}
.nav-breadcrumb-entry > .divider {
color:#555;
display:inline-block;
padding-left:8px;
color: #555;
display: inline-block;
padding-left: 8px;
}
.nav-breadcrumb-entry > span,
.nav-breadcrumb-entry > a {
color:#6F0101;
color: #6F0101;
}
.step-list > li:nth-child(1) {
padding-left:20px;
padding-left: 20px;
}
.step-list > li:nth-child(2) {
padding-left:40px;
padding-left: 40px;
}
.step-list > li:nth-child(3) {
padding-left:60px;
padding-left: 60px;
}
.api-profile-header-heading {
margin:0;
padding:0;
margin: 0;
padding: 0;
}
.api-profile-header-structure,
.api-profile-header-structure a {
font-family: "Open Sans";
font-weight:bold;
color:#999;
font-weight: bold;
color: #999;
}
.api-profile-section {
margin-top:30px;
padding-top:30px;
border-top:1px solid #aaa;
margin-top: 30px;
padding-top: 30px;
border-top: 1px solid #aaa;
}
pre {
@@ -196,23 +196,23 @@ pre {
.aside-nav a:link,
.aside-nav a:visited,
.aside-nav a:active {
color:#999;
color: #999;
}
.aside-nav a:hover {
color:black;
color: black;
}
.api-profile-description > p:first-child {
margin:15px 0;
font-size:18px;
margin: 15px 0;
font-size: 18px;
}
p > code,
code.highlighted {
background:#f4f4f4;
border-radius:5px;
padding:2px 5px;
color:maroon;
background: #f4f4f4;
border-radius: 5px;
padding: 2px 5px;
color: maroon;
}
ul + p {
@@ -220,8 +220,8 @@ ul + p {
}
.docs-version-jump {
min-width:100%;
max-width:100%;
min-width: 100%;
max-width: 100%;
}
.picker {
@@ -267,14 +267,14 @@ ul + p {
}
.picker:after {
content:"";
content: "";
position: absolute;
right: 8%;
top: 50%;
z-index: 0;
color: #999;
width: 0;
margin-top:-2px;
margin-top: -2px;
height: 0;
border-top: 6px solid;
border-right: 6px solid transparent;
@@ -287,32 +287,32 @@ iframe.example {
}
.search-results-frame {
clear:both;
display:table;
width:100%;
clear: both;
display: table;
width: 100%;
}
.search-results.ng-hide {
display:none;
display: none;
}
.search-results-container {
padding-bottom:1em;
border-top:1px solid #111;
background:#181818;
box-shadow:inset 0 0 10px #111;
padding-bottom: 1em;
border-top: 1px solid #111;
background: #181818;
box-shadow: inset 0 0 10px #111;
}
.search-results-container .search-results-group {
vertical-align:top;
padding:10px 10px;
display:inline-block;
vertical-align: top;
padding: 10px 10px;
display: inline-block;
}
.search-results-group-heading {
font-family: "Open Sans";
padding-left:10px;
color:white;
padding-left: 10px;
color: white;
}
.search-results-group .search-results {
@@ -321,14 +321,23 @@ iframe.example {
}
.search-results-frame > .search-results-group:first-child > .search-results {
border-right:1px solid #222;
border-right: 1px solid #222;
}
.search-results-group.col-group-api {
width: 30%;
}
.search-results-group.col-group-api { width:30%; }
.search-results-group.col-group-guide,
.search-results-group.col-group-tutorial { width:20%; }
.search-results-group.col-group-tutorial {
width: 20%;
}
.search-results-group.col-group-misc,
.search-results-group.col-group-error { width:15%; float: right; }
.search-results-group.col-group-error {
width: 15%;
float: right;
}
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
.search-results-group.col-group-api .search-results {
@@ -371,14 +380,14 @@ iframe.example {
}
.search-results-group.col-group-api .search-result {
width:48%;
display:inline-block;
width: 48%;
display: inline-block;
padding-left: 12px;
}
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
.search-results-group.col-group-api .search-result {
width:auto;
width: auto;
display: list-item;
}
}
@@ -395,135 +404,135 @@ iframe.example {
border-top-right-radius: 5px;
border-top-left-radius: 5px;
width: 200px;
box-shadow:0 0 10px #111;
box-shadow: 0 0 10px #111;
}
.variables-matrix {
border:1px solid #ddd;
width:100%;
margin:10px 0;
border: 1px solid #ddd;
width: 100%;
margin: 10px 0;
}
.variables-matrix td,
.variables-matrix th {
padding:10px;
padding: 10px;
}
.variables-matrix td {
border-top:1px solid #eee;
border-top: 1px solid #eee;
}
.variables-matrix td + td,
.variables-matrix th + th {
border-left:1px solid #eee;
border-left: 1px solid #eee;
}
.variables-matrix tr:nth-child(even) td {
background:#f5f5f5;
background: #f5f5f5;
}
.variables-matrix th {
background:#f1f1f1;
background: #f1f1f1;
}
.sup-header {
padding-top:10px;
padding-bottom:5px;
background:rgba(245,245,245,0.88);
box-shadow:0 0 2px #999;
padding-top: 10px;
padding-bottom: 5px;
background: rgba(245,245,245,0.88);
box-shadow: 0 0 2px #999;
}
.main-body-grid {
margin-top:120px;
position:relative;
margin-top: 120px;
position: relative;
}
.main-body-grid > .grid-left,
.main-body-grid > .grid-right {
padding:20px 0;
padding: 20px 0;
}
.main-body-grid > .grid-left {
position:fixed;
top:120px;
bottom:0;
overflow:auto;
position: fixed;
top: 120px;
bottom: 0;
overflow: auto;
}
.main-header-grid > .grid-left,
.main-body-grid > .grid-left {
width:260px;
width: 260px;
}
.main-header-grid > .grid-right,
.main-body-grid > .grid-right {
margin-left:270px;
position:relative;
margin-left: 270px;
position: relative;
}
.main-header-grid > .grid-left {
float:left;
float: left;
}
.main-body-grid .side-navigation {
position:relative;
padding-bottom:120px;
position: relative;
padding-bottom: 120px;
}
.main-body-grid .side-navigation.ng-hide {
display:block!important;
display: block!important;
}
.variables-matrix td {
vertical-align:top;
padding:5px;
vertical-align: top;
padding: 5px;
}
.type-hint {
display:inline-block;
display: inline-block;
background: gray;
}
.variables-matrix .type-hint {
text-align:center;
min-width:60px;
margin:1px 5px;
text-align: center;
min-width: 60px;
margin: 1px 5px;
}
.type-hint + .type-hint {
margin-top:5px;
margin-top: 5px;
}
.type-hint-expression {
background:purple;
background: purple;
}
.type-hint-date {
background:pink;
background: pink;
}
.type-hint-string {
background:#3a87ad;
background: #3a87ad;
}
.type-hint-function {
background:green;
background: green;
}
.type-hint-object {
background:#999;
background: #999;
}
.type-hint-array {
background:#F90;;
background: #F90;;
}
.type-hint-boolean {
background:rgb(18, 131, 39);
background: rgb(18, 131, 39);
}
.type-hint-number {
background:rgb(189, 63, 66);
background: rgb(189, 63, 66);
}
.type-hint-regexp {
@@ -535,19 +544,19 @@ iframe.example {
}
.runnable-example-frame {
width:100%;
height:300px;
width: 100%;
height: 300px;
border: 1px solid #ddd;
border-radius:5px;
border-radius: 5px;
}
.runnable-example-tabs {
margin-top:10px;
margin-bottom:20px;
margin-top: 10px;
margin-bottom: 20px;
}
.tutorial-nav {
display:block;
display: block;
}
h1 + ul, h1 + ul > li,
@@ -556,23 +565,23 @@ ul.tutorial-nav, ul.tutorial-nav > li,
.usage > ul, .usage > ul > li,
ul.methods, ul.methods > li,
ul.events, ul.events > li {
list-style:none;
padding:0;
list-style: none;
padding: 0;
}
h2 {
border-top:1px solid #eee;
margin-top:30px;
padding-top:30px;
border-top: 1px solid #eee;
margin-top: 30px;
padding-top: 30px;
}
h4 {
margin-top:20px;
padding-top:20px;
margin-top: 20px;
padding-top: 20px;
}
.btn {
color:#428bca;
color: #428bca;
position: relative;
width: auto;
display: inline-block;
@@ -595,26 +604,26 @@ h4 {
}
.btn + .btn {
margin-left:10px;
margin-left: 10px;
}
.btn:hover, .btn:focus {
color: black!important;
border: 1px solid #ddd!important;
background: white!important;
color: black !important;
border: 1px solid #ddd !important;
background: white !important;
}
.view-source, .improve-docs {
position:relative;
z-index:100;
position: relative;
z-index: 100;
}
.view-source {
margin-right:10px;
margin-right: 10px;
}
.improve-docs {
float:right;
float: right;
}
.return-arguments,
@@ -622,17 +631,17 @@ h4 {
.return-arguments th + th,
.return-arguments td,
.return-arguments td + td {
border-radius:0;
border:0;
border-radius: 0;
border: 0;
}
.return-arguments td:first-child {
width:100px;
width: 100px;
}
ul.methods > li,
ul.events > li {
margin-bottom:40px;
margin-bottom: 40px;
}
.definition-table td {
@@ -653,6 +662,11 @@ ul.events > li {
max-width: 100%;
}
.deprecation .title {
float: left;
margin-right: 5px;
}
@media only screen and (min-width: 769px) {
[ng-include="partialPath"].ng-hide {
display: block !important;
@@ -671,66 +685,66 @@ ul.events > li {
@media only screen and (max-width : 768px) {
.picker, .picker select {
width:auto;
display:block;
margin-bottom:10px;
width: auto;
display: block;
margin-bottom: 10px;
}
.docs-navbar-primary {
text-align:center;
text-align: center;
}
.main-body-grid {
margin-top:0;
margin-top: 0;
}
.main-header-grid > .grid-left,
.main-body-grid > .grid-left,
.main-header-grid > .grid-right,
.main-body-grid > .grid-right {
display:block;
float:none;
width:auto!important;
margin-left:0;
display: block;
float: none;
width: auto !important;
margin-left: 0;
}
.main-body-grid > .grid-left,
.header-fixed, .footer {
position:static!important;
position: static !important;
}
.main-body-grid > .grid-left {
background:#efefef;
margin-left:-1em;
margin-right:-1em;
padding:1em;
width:auto!important;
overflow:visible;
background: #efefef;
margin-left: -1em;
margin-right: -1em;
padding: 1em;
width: auto !important;
overflow: visible;
}
.main-header-grid > .grid-right,
.main-body-grid > .grid-right {
margin-left:0;
margin-left: 0;
}
.main-body-grid .side-navigation {
display:block!important;
padding-bottom:50px;
display: block !important;
padding-bottom: 50px;
}
.main-body-grid .side-navigation.ng-hide {
display:none!important;
display: none !important;
}
.nav-index-group .nav-index-listing {
display:inline-block;
padding:3px 0;
display: inline-block;
padding: 3px 0;
}
.nav-index-group .nav-index-listing:not(.nav-index-section):after {
padding-right:5px;
margin-left:-3px;
content:", ";
padding-right: 5px;
margin-left: -3px;
content: ", ";
}
.nav-index-group .nav-index-listing:last-child:after {
content:"";
display:inline-block;
content: "";
display: inline-block;
}
.nav-index-group .nav-index-section {
display:block;
display: block;
}
.toc-toggle {
margin-bottom:20px;
margin-bottom: 20px;
}
.toc-close {
position: absolute;
@@ -742,16 +756,16 @@ ul.events > li {
background: #eee;
border-radius: 5px;
width: 100%;
border:1px solid #ddd;
box-shadow:0 0 10px #bbb;
border: 1px solid #ddd;
box-shadow: 0 0 10px #bbb;
}
.navbar-brand {
float:none;
text-align:center;
float: none;
text-align: center;
}
.search-results-container {
padding-bottom:60px;
text-align:left;
padding-bottom: 60px;
text-align: left;
}
.search-results-frame > .search-results-group:first-child > .search-results {
@@ -759,11 +773,11 @@ ul.events > li {
}
.search-results-group {
float:none!important;
display:block!important;
width:auto!important;
border:0!important;
padding:0!important;
float: none !important;
display: block !important;
width: auto !important;
border: 0! important;
padding: 0! important;
}
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
@@ -776,15 +790,15 @@ ul.events > li {
}
.search-results-group .search-result {
display:inline-block!important;
padding:0 5px;
width:auto!important;
display: inline-block !important;
padding: 0 5px;
width: auto !important;
text-indent: initial;
margin-left: 0;
}
.search-results-group .search-result:after {
content:", ";
content: ", ";
}
.search-results-group .search-result:before {
@@ -802,10 +816,10 @@ ul.events > li {
}
#wrapper {
padding-bottom:0px;
padding-bottom: 0px;
}
}
iframe[name="example-anchoringExample"] {
height:400px;
height: 400px;
}
Executable → Regular
View File

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 212 B

-1
View File
@@ -6,7 +6,6 @@ angular.module('docsApp', [
'ngSanitize',
'ngAnimate',
'DocsController',
'versionsData',
'pagesData',
'navData',
'directives',
+5 -7
View File
@@ -1,14 +1,12 @@
'use strict';
angular.module('DocsController', [])
angular.module('DocsController', ['currentVersionData'])
.controller('DocsController', [
'$scope', '$rootScope', '$location', '$window', '$cookies',
'NG_PAGES', 'NG_NAVIGATION', 'NG_VERSION',
'NG_PAGES', 'NG_NAVIGATION', 'CURRENT_NG_VERSION',
function($scope, $rootScope, $location, $window, $cookies,
NG_PAGES, NG_NAVIGATION, NG_VERSION) {
$scope.docsVersion = NG_VERSION.isSnapshot ? 'snapshot' : NG_VERSION.version;
NG_PAGES, NG_NAVIGATION, CURRENT_NG_VERSION) {
$scope.navClass = function(navItem) {
return {
@@ -60,8 +58,8 @@ angular.module('DocsController', [])
Initialize
***********************************/
$scope.versionNumber = angular.version.full;
$scope.version = angular.version.full + ' ' + angular.version.codeName;
$scope.versionNumber = CURRENT_NG_VERSION.full;
$scope.version = CURRENT_NG_VERSION.full + ' ' + CURRENT_NG_VERSION.codeName;
$scope.loading = 0;
+2 -2
View File
@@ -202,13 +202,13 @@ angular.module('search', [])
};
})
.directive('docsSearchInput', ['$document',function($document) {
.directive('docsSearchInput', ['$document', function($document) {
return function(scope, element, attrs) {
var ESCAPE_KEY_KEYCODE = 27,
FORWARD_SLASH_KEYCODE = 191;
angular.element($document[0].body).on('keydown', function(event) {
var input = element[0];
if (event.keyCode === FORWARD_SLASH_KEYCODE && window.document.activeElement !== input) {
if (event.keyCode === FORWARD_SLASH_KEYCODE && $document[0].activeElement !== input) {
event.stopPropagation();
event.preventDefault();
input.focus();
+36 -31
View File
@@ -1,37 +1,42 @@
'use strict';
/* global console */
angular.module('versions', [])
angular.module('versions', ['currentVersionData', 'allVersionsData'])
.controller('DocsVersionsCtrl', ['$scope', '$location', '$window', 'NG_VERSIONS', function($scope, $location, $window, NG_VERSIONS) {
$scope.docs_version = NG_VERSIONS[0];
$scope.docs_versions = NG_VERSIONS;
.directive('versionPicker', function() {
return {
restrict: 'E',
scope: true,
controllerAs: '$ctrl',
controller: ['$location', '$window', 'CURRENT_NG_VERSION', 'ALL_NG_VERSIONS',
/** @this VersionPickerController */
function VersionPickerController($location, $window, CURRENT_NG_VERSION, ALL_NG_VERSIONS) {
for (var i = 0, minor = NaN; i < NG_VERSIONS.length; i++) {
var version = NG_VERSIONS[i];
if (version.isSnapshot) {
version.isLatest = true;
continue;
var versionStr = CURRENT_NG_VERSION.isSnapshot ? 'snapshot' : CURRENT_NG_VERSION.version;
this.versions = ALL_NG_VERSIONS;
this.selectedVersion = find(ALL_NG_VERSIONS, function(value) { return value.version.version === versionStr; });
this.jumpToDocsVersion = function(value) {
var currentPagePath = $location.path().replace(/\/$/, '');
$window.location = value.docsUrl + currentPagePath;
};
}],
template:
'<div class="picker version-picker">' +
' <select ng-options="v as v.label group by v.group for v in $ctrl.versions"' +
' ng-model="$ctrl.selectedVersion"' +
' ng-change="$ctrl.jumpToDocsVersion($ctrl.selectedVersion)"' +
' class="docs-version-jump">' +
' </select>' +
'</div>'
};
function find(collection, matcherFn) {
for (var i = 0, ii = collection.length; i < ii; ++i) {
if (matcherFn(collection[i])) {
return collection[i];
}
}
// NaN will give false here
if (minor <= version.minor) {
continue;
}
version.isLatest = true;
minor = version.minor;
}
$scope.getGroupName = function(v) {
return v.isLatest ? 'Latest' : ('v' + v.major + '.' + v.minor + '.x');
};
$scope.jumpToDocsVersion = function(version) {
var currentPagePath = $location.path().replace(/\/$/, ''),
url = '';
if (version.isOldDocsUrl) {
url = version.docsUrl;
} else {
url = version.docsUrl + currentPagePath;
}
$window.location = url;
};
}]);
});
+7 -2
View File
@@ -6,8 +6,13 @@ describe('DocsController', function() {
angular.module('fake', [])
.value('$cookies', {})
.value('NG_PAGES', {})
.value('NG_NAVIGATION', {})
.value('NG_VERSION', {});
.value('NG_NAVIGATION', {});
angular.module('currentVersionData', [])
.value('CURRENT_NG_VERSION', {});
angular.module('allVersionsData', [])
.value('ALL_NG_VERSIONS', {});
beforeEach(module('fake', 'DocsController'));
beforeEach(inject(function($rootScope, $controller) {
+7 -1
View File
@@ -52,10 +52,12 @@ module.exports = new Package('angularjs', [
.config(function(parseTagsProcessor) {
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/deprecated')); // this will override the jsdoc version
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/tutorial-step'));
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/sortOrder'));
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/installation'));
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/this'));
})
@@ -65,7 +67,11 @@ module.exports = new Package('angularjs', [
.config(function(templateFinder, renderDocsProcessor, gitData) {
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates'));
// We are completely overwriting the folders
templateFinder.templateFolders.length = 0;
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates/examples'));
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates/ngdoc'));
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates/app'));
renderDocsProcessor.extraData.git = gitData;
})
+88 -14
View File
@@ -1,6 +1,7 @@
'use strict';
var _ = require('lodash');
var exec = require('shelljs').exec;
var semver = require('semver');
/**
* @dgProcessor generateVersionDocProcessor
@@ -12,23 +13,96 @@ module.exports = function generateVersionDocProcessor(gitData) {
return {
$runAfter: ['generatePagesDataProcessor'],
$runBefore: ['rendering-docs'],
// the blacklist is to remove rogue builds that are in npm but not on code.angularjs.org
blacklist: ['1.3.4-build.3588'],
$process: function(docs) {
var versionDoc = {
docType: 'versions-data',
id: 'versions-data',
template: 'versions-data.template.js',
outputPath: 'js/versions-data.js',
currentVersion: gitData.version
};
var blacklist = this.blacklist;
var currentVersion = require('../../../build/version.json');
var output = exec('npm info angular versions --json', { silent: true }).stdout;
var allVersions = processAllVersionsResponse(JSON.parse(output));
versionDoc.versions = _(gitData.versions)
.filter(function(version) { return version.major > 0; })
.push(gitData.version)
.reverse()
.value();
docs.push({
docType: 'current-version-data',
id: 'current-version-data',
template: 'angular-service.template.js',
outputPath: 'js/current-version-data.js',
ngModuleName: 'currentVersionData',
serviceName: 'CURRENT_NG_VERSION',
serviceValue: currentVersion
});
docs.push(versionDoc);
docs.push({
docType: 'allversions-data',
id: 'allversions-data',
template: 'angular-service.template.js',
outputPath: 'js/all-versions-data.js',
ngModuleName: 'allVersionsData',
serviceName: 'ALL_NG_VERSIONS',
serviceValue: allVersions
});
function processAllVersionsResponse(versions) {
var latestMap = {};
versions = versions
.filter(function(versionStr) {
return blacklist.indexOf(versionStr) === -1;
})
.map(function(versionStr) {
return semver.parse(versionStr);
})
.filter(function(version) {
return version && version.major > 0;
})
.map(function(version) {
var key = version.major + '.' + version.minor;
var latest = latestMap[key];
if (!latest || version.compare(latest) > 0) {
latestMap[key] = version;
}
return version;
})
.map(function(version) {
return makeOption(version);
})
.reverse();
var latest = sortObject(latestMap, reverse(semver.compare))
.map(function(version) { return makeOption(version, 'Latest'); });
return [makeOption({version: 'snapshot'}, 'Latest', 'master')]
.concat(latest)
.concat(versions);
}
function makeOption(version, group, label) {
return {
version: version,
label: label || 'v' + version.raw,
group: group || 'v' + version.major + '.' + version.minor,
docsUrl: createDocsUrl(version)
};
}
function createDocsUrl(version) {
var url = 'https://code.angularjs.org/' + version.version + '/docs';
// Versions before 1.0.2 had a different docs folder name
if (version.major === 1 && version.minor === 0 && version.patch < 2) {
url += '-' + version.version;
}
return url;
}
function reverse(fn) {
return function(left, right) { return -fn(left, right); };
}
function sortObject(obj, cmp) {
return Object.keys(obj).map(function(key) { return obj[key]; }).sort(cmp);
}
}
};
};
+2 -1
View File
@@ -22,7 +22,8 @@ module.exports = function debugDeployment(getVersion) {
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
'js/versions-data.js',
'js/current-version-data.js',
'js/all-versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/docs.js'
+2 -1
View File
@@ -22,7 +22,8 @@ module.exports = function defaultDeployment(getVersion) {
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
'js/versions-data.js',
'js/current-version-data.js',
'js/all-versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/docs.min.js'
+2 -1
View File
@@ -26,7 +26,8 @@ module.exports = function jqueryDeployment(getVersion) {
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
'js/versions-data.js',
'js/current-version-data.js',
'js/all-versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/docs.min.js'
+19 -4
View File
@@ -1,16 +1,30 @@
'use strict';
var versionInfo = require('../../../../lib/versions/version-info');
var cdnUrl = '//ajax.googleapis.com/ajax/libs/angularjs/' + versionInfo.cdnVersion;
var googleCdnUrl = '//ajax.googleapis.com/ajax/libs/angularjs/';
var angularCodeUrl = '//code.angularjs.org/';
var cdnUrl = googleCdnUrl + versionInfo.cdnVersion;
// The plnkr examples must use the code.angularjs.org repo for the snapshot,
// and the cdn for the tagged version and, if the build is not tagged, the currentVersion.
//
// The currentVersion may not be available on the cdn (e.g. if built locally, or hasn't been pushed
// yet). This will lead to a 404, but this is preferable to loading a version with which the example
// might not work (possibly in subtle ways).
var examplesCdnUrl = versionInfo.isSnapshot ?
(angularCodeUrl + 'snapshot') :
(googleCdnUrl + (versionInfo.version || versionInfo.currentVersion));
module.exports = function productionDeployment(getVersion) {
return {
name: 'production',
examples: {
commonFiles: {
scripts: [cdnUrl + '/angular.min.js']
scripts: [examplesCdnUrl + '/angular.min.js']
},
dependencyPath: cdnUrl + '/'
dependencyPath: examplesCdnUrl + '/'
},
scripts: [
cdnUrl + '/angular.min.js',
@@ -25,7 +39,8 @@ module.exports = function productionDeployment(getVersion) {
'components/lunr.js-' + getVersion('lunr.js') + '/lunr.min.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
'js/versions-data.js',
'js/current-version-data.js',
'https://code.angularjs.org/snapshot/docs/js/all-versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/docs.min.js'
+42
View File
@@ -0,0 +1,42 @@
'use strict';
var OPTION_MATCHER = /^\s*([\w-]+)="([^"]+)"\s+([\s\S]*)/;
var VALID_OPTIONS = ['sinceVersion', 'removeVersion'];
module.exports = {
name: 'deprecated',
transforms: function(doc, tag, value) {
var result = {};
var invalidOptions = [];
value = value.trim();
while (OPTION_MATCHER.test(value)) {
value = value.replace(OPTION_MATCHER, function(_, key, value, rest) {
if (VALID_OPTIONS.indexOf(key) !== -1) {
result[key] = value;
} else {
invalidOptions.push(key);
}
return rest;
});
}
if (invalidOptions.length > 0) {
throw new Error('Invalid options: ' + humanList(invalidOptions) + '. Value options are: ' + humanList(VALID_OPTIONS));
}
result.description = value;
return result;
}
};
function humanList(values, sep, lastSep) {
if (sep === undefined) sep = ', ';
if (lastSep === undefined) lastSep = ' and ';
return values.reduce(function(output, value, index, list) {
output += '"' + value + '"';
switch (list.length - index) {
case 1: return output;
case 2: return output + lastSep;
default: return output + sep;
}
}, '');
}
+33
View File
@@ -0,0 +1,33 @@
'use strict';
/* globals describe, it, expect */
var tagDef = require('./deprecated');
describe('deprecated tag', function() {
describe('transforms', function() {
it('should return the trimmed value if no options', function() {
var tag = tagDef.transforms({}, {}, 'This is the description');
expect(tag.description).toEqual('This is the description');
});
it('should read options', function() {
var tag = tagDef.transforms({}, {}, ' sinceVersion="v1.3.4" removeVersion="v1.4.5" what is left is description');
expect(tag.description).toEqual('what is left is description');
expect(tag.sinceVersion).toEqual('v1.3.4');
expect(tag.removeVersion).toEqual('v1.4.5');
});
it('should cope with carriage returns', function() {
var tag = tagDef.transforms({}, {}, '\nsinceVersion="v1.3.4"\nremoveVersion="v1.4.5"\nwhat is left is description');
expect(tag.description).toEqual('what is left is description');
expect(tag.sinceVersion).toEqual('v1.3.4');
expect(tag.removeVersion).toEqual('v1.4.5');
});
it('should error if there is an invalid option', function() {
expect(function() {
tagDef.transforms({}, {}, ' fromVersion="v1.3.4" toVersion="v1.4.5" what is left is description');
}).toThrowError('Invalid options: "fromVersion" and "toVersion". Value options are: "sinceVersion" and "removeVersion"');
});
});
});
@@ -0,0 +1,4 @@
'use strict';
angular.module('{$ doc.ngModuleName $}', [])
.value('{$ doc.serviceName $}', {$ doc.serviceValue | json $});
@@ -165,13 +165,7 @@
<section class="sup-header">
<div class="container main-grid main-header-grid">
<div class="grid-left">
<div ng-controller="DocsVersionsCtrl" class="picker version-picker">
<select ng-options="v as (v.isSnapshot ? v.branch : ('v' + v.version)) group by getGroupName(v) for v in docs_versions"
ng-model="docs_version"
ng-change="jumpToDocsVersion(docs_version)"
class="docs-version-jump">
</select>
</div>
<version-picker></version-picker>
</div>
<div class="grid-right">
<ul class="nav-breadcrumb">
@@ -0,0 +1,21 @@
<!doctype html>
<html lang="en"{% if doc.example['ng-csp'] %} ng-csp{% endif %}>
<head>
<meta charset="UTF-8">
<title>Example - {$ doc.id $}</title>
{% for stylesheet in doc.stylesheets %}<link href="{$ stylesheet.path $}" rel="stylesheet" type="text/css">
{% endfor %}
{% for script in doc.scripts %}<script src="{$ script.path $}"></script>
{% endfor %}
{% if doc.example.fixBase -%}
<script type="text/javascript">
angular.element(document.getElementsByTagName('head')).append(angular.element('<base href="' + window.location.pathname + '" />'));
</script>
{%- endif %}
</head>
<body {% if not doc.example['ng-app-included'] %}ng-app="{$ doc.example.module $}"{% endif %}>
{$ doc.fileContents $}
</body>
</html>
@@ -0,0 +1,8 @@
{
"name": "{$ doc.example.id $}",
"files": [
"index-production.html"
{%- for file in doc.files %},
"{$ file $}"{% endfor %}
]
}
@@ -0,0 +1,10 @@
describe("{$ doc.description $}", function() {
var rootEl;
beforeEach(function() {
rootEl = browser.rootEl;{% if doc['ng-app-included'] %}
browser.rootEl = '[ng-app]';{% endif %}
browser.get("{$ doc.basePath $}{$ doc.example.deployments[doc.deployment.name].outputPath $}");
});
{% if doc['ng-app-included'] %}afterEach(function() { browser.rootEl = rootEl; });{% endif %}
{$ doc.innerTest $}
});
@@ -0,0 +1 @@
{$ doc.fileContents $}
@@ -0,0 +1 @@
{$ doc.fileContents $}
@@ -0,0 +1,4 @@
(function(angular) {
'use strict';
{$ doc.fileContents $}
})(window.angular);
@@ -0,0 +1 @@
{$ doc.fileContents $}
@@ -0,0 +1 @@
{$ doc.fileContents $}
@@ -0,0 +1 @@
{$ doc.fileContents $}
@@ -0,0 +1 @@
{$ doc.fileContents $}
@@ -1,4 +1,5 @@
{% extends "base.template.html" %}
{% import "lib/deprecated.html" as x -%}
{% block content %}
@@ -18,6 +19,8 @@
</header>
{% endblock %}
{$ x.deprecatedBlock(doc) $}
{% block description %}
<div class="api-profile-description">
{$ doc.description | marked $}
@@ -28,18 +31,11 @@
<h2 id="known-issues">Known Issues</h2>
{% for issue in doc.knownIssues -%}
<div class="known-issue">
{$ issue | marked $} {% if not loop.last %}<hr>{% endif %}
{$ issue | marked $}
</div>
{% endfor -%}
{% endif %}
{% if doc.deprecated %}
<fieldset class="deprecated">
<legend>Deprecated API</legend>
{$ doc.deprecated| marked $}
</fieldset>
{% endif %}
<div>
{% block dependencies %}
{%- if doc.requires %}
@@ -0,0 +1,31 @@
{% block content %}
<h1>
{%- if doc.title -%}
{$ doc.title $}
{%- elif doc.moduleName -%}
{$ doc.groupType | title $} components in {$ doc.moduleName | code $}
{%- else -%}
Pages
{%- endif -%}
</h1>
{$ doc.description | marked $}
<div class="component-breakdown">
<div>
<table class="definition-table">
<tr>
<th>Name</th>
<th>Description</th>
</tr>
{% for page in doc.components %}
<tr>
<td>{$ page.id | link(page.name, page) $}</td>
<td>{$ page.description | firstParagraph | marked $}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
{% endblock %}
@@ -0,0 +1,72 @@
{% import "lib/macros.html" as lib -%}
{% extends "api/api.template.html" %}
{% block additional %}
<h2>Directive Info</h2>
<ul>
{% if doc.scope %}<li>This directive creates new scope.</li>{% endif %}
<li>This directive executes at priority level {$ doc.priority $}.</li>
{% if doc.multiElement %}<li>This directive can be used as {@link $compile#-multielement- multiElement}</li>{% endif %}
</ul>
{% block usage %}
<h2 id="usage">Usage</h2>
<div class="usage">
{% if doc.usage %}
{$ doc.usage | marked $}
{% else %}
<ul>
{% if doc.restrict.element %}
<li>as element:
{% if doc.name.indexOf('ng') == 0 -%}
(This directive can be used as custom element, but be aware of <a href="guide/ie">IE restrictions</a>).
{%- endif %}
{% code %}
<{$ doc.name | dashCase $}
{%- for param in doc.params %}
{$ lib.directiveParam(param.alias or param.name, param.type, '="', '"') $}
{%- endfor %}>
...
</{$ doc.name | dashCase $}>
{% endcode %}
</li>
{% endif -%}
{%- if doc.restrict.attribute -%}
<li>as attribute:
{% code %}
<{$ doc.element $}
{%- for param in doc.params %}
{$ lib.directiveParam(param.name, param.type, '="', '"') $}
{%- endfor %}>
...
</{$ doc.element $}>
{% endcode %}
</li>
{% endif -%}
{%- if doc.restrict.cssClass -%}
<li>as CSS class:
{% code %}
{% set sep = joiner(' ') %}
<{$ doc.element $} class="
{%- for param in doc.params -%}
{$ sep() $}{$ lib.directiveParam(param.name, param.type, ': ', ';') $}
{%- endfor %}"> ... </{$ doc.element $}>
{% endcode %}
</li>
{% endif -%}
{%- endif %}
</div>
{% endblock -%}
{%- if doc.animations %}
<h2 id="animations">Animations</h2>
{$ doc.animations | marked $}
{$ 'module:ngAnimate.$animate' | link('Click here', doc) $} to learn more about the steps involved in the animation.
{%- endif -%}
{% include "lib/params.template.html" %}
{% include "lib/events.template.html" %}
{% endblock %}
@@ -0,0 +1,26 @@
{% import "lib/macros.html" as lib -%}
{% extends "api/api.template.html" %}
{% block additional %}
<h2>Usage</h2>
<h3>In HTML Template Binding</h3>
{% if doc.usage %}
{$ doc.usage | code $}
{% else %}
{% code -%}
{{ {$ doc.name $}_expression | {$ doc.name $}
{%- for param in doc.params %}{% if not loop.first %} : {$ param.name $}{% endif %}{% endfor -%}
}}
{%- endcode %}
{% endif %}
<h3>In JavaScript</h3>
{% code -%}
{%- set sep = joiner(', ') -%}
$filter('{$ doc.name $}')({% for param in doc.params %}{$ sep() $}{$ param.name $}{% endfor -%})
{%- endcode %}
{% include "lib/params.template.html" %}
{% include "lib/this.template.html" %}
{% include "lib/returns.template.html" %}
{% endblock %}
@@ -0,0 +1 @@
{% extends "api/object.template.html" %}
@@ -0,0 +1,12 @@
{% import "lib/macros.html" as lib -%}
{% extends "api/directive.template.html" %}
{% block usage %}
<h2>Usage</h2>
{% code %}
<input type="{$ doc.inputType $}"
{%- for param in doc.params %}
{$ lib.directiveParam(param.alias or param.name, param.type, '="', '"') $}
{%- endfor %}>
{% endcode %}
{% endblock %}
@@ -1,10 +1,13 @@
{% extends "base.template.html" %}
{% import "lib/deprecated.html" as x %}
{% block content %}
<h1>
{% if doc.title %}{$ doc.title | marked $}{% else %}{$ doc.name | code $}{% endif %}
</h1>
{$ x.deprecatedBlock(doc) $}
<h2>Installation</h2>
{% if doc.installation or doc.installation == '' %}
{$ doc.installation | marked $}
@@ -0,0 +1,23 @@
{% import "lib/macros.html" as lib %}
{% extends "api/api.template.html" %}
{% block additional %}
{% if doc.params or doc.returns or doc.this or doc.kind == 'function' -%}
<h2 id="usage">Usage</h2>
{% if doc.usage %}
{$ doc.usage | code $}
{% else %}
{$ lib.functionSyntax(doc) $}
{% endif %}
{% include "lib/params.template.html" %}
{% include "lib/this.template.html" %}
{% include "lib/returns.template.html" %}
{%- endif %}
{% include "lib/methods.template.html" %}
{% include "lib/events.template.html" %}
{% include "lib/properties.template.html" %}
{% endblock %}
@@ -0,0 +1,9 @@
{% extends "api/object.template.html" %}
{% block related_components %}
{% if doc.serviceDoc -%}
<li>
<a href="{$ doc.serviceDoc.path $}">- {$ doc.serviceDoc.name $}</a>
</li>
{%- endif %}
{% endblock %}
@@ -0,0 +1,9 @@
{% extends "api/object.template.html" %}
{% block related_components %}
{% if doc.providerDoc -%}
<li>
<a href="{$ doc.providerDoc.path $}">- {$ doc.providerDoc.name $}</a>
</li>
{%- endif %}
{% endblock %}
@@ -0,0 +1 @@
{% extends "api/object.template.html" %}
@@ -0,0 +1,4 @@
<a href='https://github.com/angular/angular.js/edit/{$ git.version.branch $}/{$ doc.fileInfo.projectRelativePath $}?message=docs({$ (doc.area != "api") and (doc.area + "%2F") or "" $}{$ doc.name $})%3A%20describe%20your%20change...{$ (doc.area == "api") and ("#L" + doc.startingLine) or "" $}' class='improve-docs btn btn-primary'><i class="glyphicon glyphicon-edit">&nbsp;</i>Improve this Doc</a>
{% block content %}
{% endblock %}
@@ -0,0 +1,9 @@
{% macro deprecatedBlock(doc) %}{% if doc.deprecated %}
<div class="alert alert-danger deprecation">
<div class="title"><strong>Deprecated:</strong>
{% if doc.deprecated.sinceVersion %}<span class="since">(since {$ doc.deprecated.sinceVersion $}) </span>{% endif %}
{% if doc.deprecated.removeVersion %}<span class="remove">(to be removed in {$ doc.deprecated.removeVersion $}) </span>{% endif %}
</div>
{$ doc.deprecated.description | marked $}
</div>
{% endif %}{% endmacro %}
@@ -0,0 +1,37 @@
{% import "lib/macros.html" as lib -%}
{% import "lib/deprecated.html" as x -%}
{%- if doc.events %}
<h2>Events</h2>
<ul class="events">
{%- for event in doc.events %}
<li id="{$ event.name $}">
<h3>{$ event.name $}</h3>
<div>{$ event.description | marked $}</div>
{$ x.deprecatedBlock(event) $}
{%- if event.eventType == 'listen' %}
<div class="inline">
<h4>Listen on: {$ event.eventTarget $}</h4>
</div>
{%- else %}
<div class="inline">
<h4>Type:</h4>
<div class="type">{$ event.eventType $}</div>
</div>
<div class="inline">
<h4>Target:</h4>
<div class="target">{$ event.eventTarget $}</div>
</div>
{% endif -%}
{%- if event.params %}
<section class="api-section">
<h3>Parameters</h3>
{$ lib.paramTable(event.params) $}
</section>
{%- endif -%}
</li>
{% endfor -%}
</ul>
{% endif -%}
@@ -0,0 +1,32 @@
{% import "lib/macros.html" as lib -%}
{% import "lib/deprecated.html" as x -%}
{%- if doc.methods %}
<h2>Methods</h2>
<ul class="methods">
{%- for method in doc.methods %}
<li id="{$ method.name $}">
<h3>{$ lib.functionSyntax(method) $}</h3>
<div>{$ method.description | marked $}</div>
{$ x.deprecatedBlock(method) $}
{% if method.params %}
<h4>Parameters</h4>
{$ lib.paramTable(method.params) $}
{% endif %}
{% if method.this %}
<h4>Method's {% code %}this{% endcode %}</h4>
{$ method.this | marked $}
{% endif %}
{% if method.returns %}
<h4>Returns</h4>
{$ lib.typeInfo(method.returns) $}
{% endif %}
</li>
{% endfor -%}
</ul>
{%- endif -%}
@@ -0,0 +1,7 @@
{% import "lib/macros.html" as lib -%}
{%- if doc.params %}
<section class="api-section">
<h3>Arguments</h3>
{$ lib.paramTable(doc.params) $}
</section>
{%- endif -%}
@@ -0,0 +1,15 @@
{% import "lib/macros.html" as lib -%}
{% import "lib/deprecated.html" as x -%}
{%- if doc.properties %}
<h2>Properties</h2>
<ul class="properties">
{%- for property in doc.properties %}
<li id="{$ property.name $}">
<h3>{$ property.name | code $}</h3>
{$ lib.typeInfo(property) $}
{$ x.deprecatedBlock(property) $}
</li>
{% endfor -%}
</ul>
{%- endif -%}
@@ -0,0 +1,5 @@
{% import "lib/macros.html" as lib -%}
{% if doc.returns -%}
<h3>Returns</h3>
{$ lib.typeInfo(doc.returns) $}
{%- endif %}
@@ -0,0 +1,4 @@
{% if doc.this %}
<h3>Method's {% code %}this{% endcode %}</h3>
{$ doc.this | marked $}
{% endif %}
@@ -0,0 +1,5 @@
{% extends "base.template.html" %}
{% block content %}
{$ doc.description | marked $}
{% endblock %}
@@ -1,6 +0,0 @@
'use strict';
// Meta data used by the AngularJS docs app
angular.module('versionsData', [])
.value('NG_VERSION', {$ doc.currentVersion | json $})
.value('NG_VERSIONS', {$ doc.versions | json $});
@@ -0,0 +1,9 @@
@ngdoc error
@name $location:badpath
@fullName Invalid Path
@description
This error occurs when the path of a location contains invalid characters.
The most common fault is when the path starts with double slashes (`//`) or backslashes ('\\').
For example if the base path of an application is `https://a.b.c/` then the following path is
invalid `https://a.b.c///d/e/f`.
+6 -4
View File
@@ -3,7 +3,9 @@
@fullName Bad Argument
@description
AngularJS often asserts that certain values will be present and truthy using a
helper function. If the assertion fails, this error is thrown. To fix this problem,
make sure that the value the assertion expects is defined and matches the type mentioned in the
error.
AngularJS often asserts that certain values will be present and truthy using a helper function. If
the assertion fails, this error is thrown. To fix this problem, make sure that the value the
assertion expects is defined and matches the type mentioned in the error.
If the type is `undefined`, make sure any newly added controllers/directives/services are properly
defined and included in the script(s) loaded by your page.
+1 -1
View File
@@ -384,7 +384,7 @@ By default, any `ngAnimate` enabled directives will assume any transition / anim
element are part of an `ngAnimate` animation. This can lead to problems when the styles are actually
for animations that are independent of `ngAnimate`.
For example, an element acts as a loading spinner. It has an inifinite css animation on it, and also an
For example, an element acts as a loading spinner. It has an infinite css animation on it, and also an
{@link ngIf `ngIf`} directive, for which no animations are defined:
```css
+103
View File
@@ -380,3 +380,106 @@ restrict: 'E',
replace: true
```
### Double Compilation, and how to avoid it
Double compilation occurs when an already compiled part of the DOM gets compiled again. This is an
undesired effect and can lead to misbehaving directives, performance issues, and memory
leaks.
A common scenario where this happens is a directive that calls `$compile` in a directive link
function on the directive element. In the following **faulty example**, a directive adds a mouseover behavior
to a button with `ngClick` on it:
```
angular.module('app').directive('addMouseover', function($compile) {
return {
link: function(scope, element, attrs) {
var newEl = angular.element('<span ng-show="showHint"> My Hint</span>');
element.on('mouseenter mouseleave', function() {
scope.$apply('showHint = !showHint');
});
attrs.$set('addMouseover', null); // To stop infinite compile loop
element.append(newEl);
$compile(element)(scope); // Double compilation
}
}
})
```
At first glance, it looks like removing the original `addMouseover` attribute is all there is needed
to make this example work.
However, if the directive element or its children have other directives attached, they will be compiled and
linked again, because the compiler doesn't keep track of which directives have been assigned to which
elements.
This can cause unpredictable behavior, e.g. `ngClick` or other event handlers will be attached
again. It can also degrade performance, as watchers for text interpolation are added twice to the scope.
Double compilation should therefore be avoided. In the above example, only the new element should
be compiled:
```
angular.module('app').directive('addMouseover', function($compile) {
return {
link: function(scope, element, attrs) {
var newEl = angular.element('<span ng-show="showHint"> My Hint</span>');
element.on('mouseenter mouseleave', function() {
scope.$apply('showHint = !showHint');
});
element.append(newEl);
$compile(newEl)(scope); // Only compile the new element
}
}
})
```
Another scenario is adding a directive programmatically to a compiled element and then executing
compile again. See the following **faulty example**:
```html
<input ng-model="$ctrl.value" add-options>
```
```
angular.module('app').directive('addOptions', function($compile) {
return {
link: function(scope, element, attrs) {
attrs.$set('addOptions', null) // To stop infinite compile loop
attrs.$set('ngModelOptions', '{debounce: 1000}');
$compile(element)(scope); // Double compilation
}
}
});
```
In that case, it is necessary to intercept the *initial* compilation of the element:
1. Give your directive the `terminal` property and a higher priority than directives
that should not be compiled twice. In the example, the compiler will only compile directives
which have a priority of 100 or higher.
2. Inside this directive's compile function, add any other directive attributes to the template.
3. Compile the element, but restrict the maximum priority, so that any already compiled directives
(including the `addOptions` directive) are not compiled again.
4. In the link function, link the compiled element with the element's scope.
```
angular.module('app').directive('addOptions', function($compile) {
return {
priority: 100, // ngModel has priority 1
terminal: true,
compile: function(templateElement, templateAttributes) {
templateAttributes.$set('ngModelOptions', '{debounce: 1000}');
// The third argument is the max priority. Only directives with priority < 100 will be compiled,
// therefore we don't need to remove the attribute
var compiled = $compile(templateElement, null, 100);
return function linkFn(scope) {
compiled(scope) // Link compiled element to scope
}
}
}
});
```
+5 -5
View File
@@ -32,8 +32,8 @@ Here is a table of the main concepts used in the Component Router.
| Routing Component | An Angular component with a RouteConfig and an associated Router. |
| RouteDefinition | Defines how the router should navigate to a component based on a URL pattern. |
| ngOutlet | The directive (`<ng-outlet>`) that marks where the router should display a view. |
| ngLink | The directive (`ng-link="..."`) for binding a clickable HTML element to a route, via a Link Paramaters Array. |
| Link Parameters Array | An array that the router inteprets into a routing instruction. We can bind a RouterLink to that array or pass the array as an argument to the Router.navigate method. |
| ngLink | The directive (`ng-link="..."`) for binding a clickable HTML element to a route, via a Link Parameters Array. |
| Link Parameters Array | An array that the router interprets into a routing instruction. We can bind a RouterLink to that array or pass the array as an argument to the Router.navigate method. |
## Component-based Applications
@@ -150,7 +150,7 @@ You can see the complete application running below.
<app></app>
<!-- Load up the router library - normally you might use npm and host it locally -->
<script src="https://npmcdn.com/@angular/router@0.2.0/angular1/angular_1_router.js"></script>
<script src="https://unpkg.com/@angular/router@0.2.0/angular1/angular_1_router.js"></script>
</file>
<file name="app.js">
@@ -493,7 +493,7 @@ You also need to include ES6 shims for browsers that do not support ES6 code (In
<!-- IE required polyfills, in this exact order -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.33.3/es6-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.20/system-polyfills.js"></script>
<script src="https://npmcdn.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
<script src="https://unpkg.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
```
## Create the `app` module
@@ -929,7 +929,7 @@ function HeroListComponent(heroService) {
}
```
Finally, we can use this information to higlight the current hero in the template.
Finally, we can use this information to highlight the current hero in the template.
```html
<div ng-repeat="hero in $ctrl.heroes"
+4 -4
View File
@@ -141,7 +141,7 @@ different currencies and also pay the invoice.
<b>Total:</b>
<span ng-repeat="c in invoice.currencies">
{{invoice.total(c) | currency:c}}
</span>
</span><br>
<button class="btn" ng-click="invoice.pay()">Pay</button>
</div>
</div>
@@ -242,7 +242,7 @@ Let's refactor our example and move the currency conversion into a service in an
<b>Total:</b>
<span ng-repeat="c in invoice.currencies">
{{invoice.total(c) | currency:c}}
</span>
</span><br>
<button class="btn" ng-click="invoice.pay()">Pay</button>
</div>
</div>
@@ -337,7 +337,7 @@ The following example shows how this is done with Angular:
var refresh = function() {
var url = YAHOO_FINANCE_URL_PATTERN.
replace('PAIRS', 'USD' + currencies.join('","USD'));
return $http.jsonp(url).then(function(response) {
return $http.get(url).then(function(response) {
var newUsdToForeignRates = {};
angular.forEach(response.data.query.results.rate, function(rate) {
var currency = rate.id.substring(3,6);
@@ -371,7 +371,7 @@ The following example shows how this is done with Angular:
<b>Total:</b>
<span ng-repeat="c in invoice.currencies">
{{invoice.total(c) | currency:c}}
</span>
</span><br>
<button class="btn" ng-click="invoice.pay()">Pay</button>
</div>
</div>
+4 -4
View File
@@ -253,10 +253,10 @@ scopes being created for our view:
- The root scope
- The `MainController` scope, which contains `timeOfDay` and `name` properties
- The `ChildController` scope, which inherits the `timeOfDay` property but overrides (hides) the `name`
property from the previous
- The `GrandChildController` scope, which overrides (hides) both the `timeOfDay` property defined in `MainController`
and the `name` property defined in `ChildController`
- The `ChildController` scope, which inherits the `timeOfDay` property but overrides (shadows) the
`name` property from the previous scope
- The `GrandChildController` scope, which overrides (shadows) both the `timeOfDay` property defined
in `MainController` and the `name` property defined in `ChildController`
Inheritance works with methods in the same way as it does with properties. So in our previous
examples, all of the properties could be replaced with methods that return string values.
+8 -9
View File
@@ -8,7 +8,8 @@
<div class="alert alert-warning">
**Note:** this guide is targeted towards developers who are already familiar with AngularJS basics.
If you're just getting started, we recommend the {@link tutorial/ tutorial} first.
If you're looking for the **directives API**, we recently moved it to {@link ng.$compile `$compile`}.
If you're looking for the **directives API**, you can find it in the
{@link ng.$compile `$compile` API docs}.
</div>
@@ -58,7 +59,7 @@ The following `<input>` element also **matches** `ngModel`:
<input data-ng-model="foo">
```
And the following <person> element **matches** the `person` directive:
And the following `<person>` element **matches** the `person` directive:
```html
<person>{{name}}</person>
@@ -335,9 +336,7 @@ Let's change our directive to use `restrict: 'E'`:
</file>
</example>
For more on the
{@link ng.$compile#directive-definition-object `restrict`}
property, see the
For more on the `restrict` property, see the
{@link ng.$compile#directive-definition-object API docs}.
<div class="alert alert-info">
@@ -450,8 +449,8 @@ scope: {
The **scope option** is an object that contains a property for each isolate scope binding. In this
case it has just one property:
- Its name (`customerInfo`) corresponds to the
directive's **isolate scope** property `customerInfo`.
- Its name (`customerInfo`) corresponds to the directive's **isolate scope** property,
`customerInfo`.
- Its value (`=info`) tells `$compile` to bind to the `info` attribute.
<div class="alert alert-warning">
@@ -517,8 +516,8 @@ that you explicitly pass in.
<div class="alert alert-warning">
**Note:** Normally, a scope prototypically inherits from its parent. An isolated scope does not.
See the {@link $compile#directive-definition-object
"Directive Definition Object - scope"} section for more information about isolate scopes.
See the {@link $compile#directive-definition-object "Directive Definition Object - scope"} section
for more information about isolate scopes.
</div>
<div class="alert alert-success">
+9 -8
View File
@@ -41,7 +41,7 @@ This is a collection of external, 3rd party resources for learning and developin
##### General
* **Javascript minification: **[Background](http://thegreenpizza.github.io/2013/05/25/building-minification-safe-angular.js-applications/), [ng-annotate automation tool](https://github.com/olov/ng-annotate)
* **Analytics and Logging:** [Angularyitcs (Google Analytics)](http://ngmodules.org/modules/angularytics), [Angulartics (Analytics)](https://github.com/luisfarzati/angulartics), [Logging Client-Side Errors](http://www.bennadel.com/blog/2542-Logging-Client-Side-Errors-With-AngularJS-And-Stacktrace-js.htm)
* **Analytics and Logging:** [Angularytics (Google Analytics)](http://ngmodules.org/modules/angularytics), [Angulartics (Analytics)](https://github.com/luisfarzati/angulartics), [Logging Client-Side Errors](http://www.bennadel.com/blog/2542-Logging-Client-Side-Errors-With-AngularJS-And-Stacktrace-js.htm)
* **SEO:** [By hand](http://www.yearofmoo.com/2012/11/angularjs-and-seo.html), [prerender.io](http://prerender.io/), [Brombone](http://www.brombone.com/), [SEO.js](http://getseojs.com/), [SEO4Ajax](http://www.seo4ajax.com/)
##### Server-Specific
@@ -117,16 +117,17 @@ You can find a larger list of Angular external libraries at [ngmodules.org](http
## General Learning Resources
### Books
* [AngularJS: Up and Running](http://www.amazon.com/AngularJS-Running-Enhanced-Productivity-Structured/dp/1491901942) by Brad Green and Shyam Seshadri
* [Mastering Web App Development](http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821) by Pawel Kozlowski and Pete Bacon Darwin
* [AngularJS Directives](http://www.amazon.com/AngularJS-Directives-Alex-Vanston/dp/1783280336) by Alex Vanston
* [Recipes With AngularJS](http://www.amazon.co.uk/Recipes-Angular-js-Frederik-Dietz-ebook/dp/B00DK95V48) by Frederik Dietz
* [Developing an AngularJS Edge](http://www.amazon.com/Developing-AngularJS-Edge-Christopher-Hiller-ebook/dp/B00CJLFF8K) by Christopher Hiller
* [ng-book: The Complete Book on AngularJS](http://ng-book.com/) by Ari Lerner
* [AngularJS Essentials (Free eBook)](https://www.packtpub.com/packt/free-ebook/angularjs-essentials) by Rodrigo Branas
* [AngularJS : Novice to Ninja](http://www.amazon.in/AngularJS-Novice-Ninja-Sandeep-Panda/dp/0992279453) by Sandeep Panda
* [AngularJS UI Development](http://www.amazon.com/AngularJS-UI-Development-Amit-Ghart-ebook/dp/B00OXVAK7A) by Amit Gharat and Matthias Nehlsen
* [Responsive Web Design with AngularJS](http://www.amazon.com/Responsive-Design-AngularJS-Sandeep-Kumar/dp/178439842X) by Sandeep Kumar Patel
* [AngularJS: Up and Running](http://www.amazon.com/AngularJS-Running-Enhanced-Productivity-Structured/dp/1491901942) by Brad Green and Shyam Seshadri
* [Developing an AngularJS Edge](http://www.amazon.com/Developing-AngularJS-Edge-Christopher-Hiller-ebook/dp/B00CJLFF8K) by Christopher Hiller
* [Mastering Web App Development](http://www.amazon.com/Mastering-Web-Application-Development-AngularJS/dp/1782161821) by Pawel Kozlowski and Pete Bacon Darwin
* [ng-book: The Complete Book on AngularJS](http://ng-book.com/) by Ari Lerner
* [Professional AngularJS](http://www.amazon.com/Professional-AngularJS-Valeri-Karpov/dp/1118832078/)
* [Recipes With AngularJS](http://www.amazon.co.uk/Recipes-Angular-js-Frederik-Dietz-ebook/dp/B00DK95V48) by Frederik Dietz
* [Responsive Web Design with AngularJS](http://www.amazon.com/Responsive-Design-AngularJS-Sandeep-Kumar/dp/178439842X) by Sandeep Kumar Patel
### Videos:
* [egghead.io](http://egghead.io/)
@@ -137,7 +138,7 @@ You can find a larger list of Angular external libraries at [ngmodules.org](http
[CodeAcademy](http://www.codecademy.com/courses/javascript-advanced-en-2hJ3J/0/1),
[CodeSchool](https://www.codeschool.com/courses/shaping-up-with-angular-js)
* **Paid online:**
[Pluralsite (3 courses)](http://www.pluralsight.com/training/Courses/Find?highlight=true&searchTerm=angularjs),
[Pluralsight (3 courses)](http://www.pluralsight.com/training/Courses/Find?highlight=true&searchTerm=angularjs),
[Tuts+](https://tutsplus.com/course/easier-js-apps-with-angular/),
[lynda.com](http://www.lynda.com/AngularJS-tutorials/Up-Running-AngularJS/133318-2.html),
[WintellectNOW (4 lessons)](http://www.wintellectnow.com/Course/Detail/mastering-angularjs),
+32 -23
View File
@@ -26,10 +26,10 @@ for other directives to augment its behavior.
<file name="index.html">
<div ng-controller="ExampleController">
<form novalidate class="simple-form">
Name: <input type="text" ng-model="user.name" /><br />
E-mail: <input type="email" ng-model="user.email" /><br />
Gender: <input type="radio" ng-model="user.gender" value="male" />male
<input type="radio" ng-model="user.gender" value="female" />female<br />
<label>Name: <input type="text" ng-model="user.name" /></label><br />
<label>E-mail: <input type="email" ng-model="user.email" /></label><br />
Gender: <label><input type="radio" ng-model="user.gender" value="male" />male</label>
<label><input type="radio" ng-model="user.gender" value="female" />female</label><br />
<input type="button" ng-click="reset()" value="Reset" />
<input type="submit" ng-click="update(user)" value="Save" />
</form>
@@ -88,10 +88,10 @@ and failing to satisfy its validity.
<file name="index.html">
<div ng-controller="ExampleController">
<form novalidate class="css-form">
Name: <input type="text" ng-model="user.name" required /><br />
E-mail: <input type="email" ng-model="user.email" required /><br />
Gender: <input type="radio" ng-model="user.gender" value="male" />male
<input type="radio" ng-model="user.gender" value="female" />female<br />
<label>Name: <input type="text" ng-model="user.name" required /></label><br />
<label>E-mail: <input type="email" ng-model="user.email" required /></label><br />
Gender: <label><input type="radio" ng-model="user.gender" value="male" />male</label>
<label><input type="radio" ng-model="user.gender" value="female" />female</label><br />
<input type="button" ng-click="reset()" value="Reset" />
<input type="submit" ng-click="update(user)" value="Save" />
</form>
@@ -154,15 +154,17 @@ didn't interact with a control
<file name="index.html">
<div ng-controller="ExampleController">
<form name="form" class="css-form" novalidate>
Name:
<input type="text" ng-model="user.name" name="uName" required="" />
<label>Name:
<input type="text" ng-model="user.name" name="uName" required="" />
</label>
<br />
<div ng-show="form.$submitted || form.uName.$touched">
<div ng-show="form.uName.$error.required">Tell us your name.</div>
</div>
E-mail:
<input type="email" ng-model="user.email" name="uEmail" required="" />
<label>E-mail:
<input type="email" ng-model="user.email" name="uEmail" required="" />
</label>
<br />
<div ng-show="form.$submitted || form.uEmail.$touched">
<span ng-show="form.uEmail.$error.required">Tell us your email.</span>
@@ -170,12 +172,14 @@ didn't interact with a control
</div>
Gender:
<input type="radio" ng-model="user.gender" value="male" />male
<input type="radio" ng-model="user.gender" value="female" />female
<label><input type="radio" ng-model="user.gender" value="male" />male</label>
<label><input type="radio" ng-model="user.gender" value="female" />female</label>
<br />
<label>
<input type="checkbox" ng-model="user.agree" name="userAgree" required="" />
I agree:
</label>
<input ng-show="user.agree" type="text" ng-model="user.agreeSign" required="" />
<br />
<div ng-show="form.$submitted || form.userAgree.$touched">
@@ -236,10 +240,11 @@ will update the model only when the control loses focus (blur event).
<file name="index.html">
<div ng-controller="ExampleController">
<form>
Name:
<input type="text" ng-model="user.name" ng-model-options="{ updateOn: 'blur' }" /><br />
<label>Name:
<input type="text" ng-model="user.name" ng-model-options="{ updateOn: 'blur' }" /></label><br />
<label>
Other data:
<input type="text" ng-model="user.data" /><br />
<input type="text" ng-model="user.data" /></label><br />
</form>
<pre>username = "{{user.name}}"</pre>
<pre>userdata = "{{user.data}}"</pre>
@@ -282,8 +287,8 @@ after last change.
<file name="index.html">
<div ng-controller="ExampleController">
<form>
Name:
<input type="text" ng-model="user.name" ng-model-options="{ debounce: 250 }" /><br />
<label>Name:
<input type="text" ng-model="user.name" ng-model-options="{ debounce: 250 }" /></label><br />
</form>
<pre>username = "{{user.name}}"</pre>
</div>
@@ -335,17 +340,19 @@ In the following example we create two directives:
<file name="index.html">
<form name="form" class="css-form" novalidate>
<div>
<label>
Size (integer 0 - 10):
<input type="number" ng-model="size" name="size"
min="0" max="10" integer />{{size}}<br />
min="0" max="10" integer />{{size}}</label><br />
<span ng-show="form.size.$error.integer">The value is not a valid integer!</span>
<span ng-show="form.size.$error.min || form.size.$error.max">
The value must be in range 0 to 10!</span>
</div>
<div>
<label>
Username:
<input type="text" ng-model="name" name="name" username />{{name}}<br />
<input type="text" ng-model="name" name="name" username />{{name}}</label><br />
<span ng-show="form.name.$pending.username">Checking if this name is available...</span>
<span ng-show="form.name.$error.username">This username is already taken!</span>
</div>
@@ -425,8 +432,10 @@ Note that you can alternatively use `ng-pattern` to further restrict the validat
<file name="index.html">
<form name="form" class="css-form" novalidate>
<div>
Overwritten Email:
<input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" />
<label>
Overwritten Email:
<input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" />
</label>
<span ng-show="form.overwrittenEmail.$error.email">This email format is invalid!</span><br>
Model: {{myEmail}}
</div>
+2 -2
View File
@@ -120,13 +120,13 @@ can be used with `ngAttr` instead. The following is a list of known problematic
### Dynamically changing an interpolated value
You should avoid dynamically changing the content of an interpolated string (e.g. attribute value
or text node). Your changes are likely to be overwriten, when the original string gets evaluated.
or text node). Your changes are likely to be overwritten, when the original string gets evaluated.
This restriction applies to both directly changing the content via JavaScript or indirectly using a
directive.
For example, you should not use interpolation in the value of the `style` attribute (e.g.
`style="color: {{ 'orange' }}; font-weight: {{ 'bold' }};"`) **and** at the same time use a
directive that changes the content of that attributte, such as `ngStyle`.
directive that changes the content of that attribute, such as `ngStyle`.
### Embedding interpolation markup inside expressions
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -88,7 +88,7 @@ Nowadays most of the Angular projects are using only element and attribute direc
and in such projects there is no need to compile comments and classes.
If you are sure that your project only uses element and attribute directives,
and you are not using any 3rd part library that uses
and you are not using any 3rd party library that uses
directives inside element classes or html comments,
you can disable the compilation of directives on element classes and comments
for the whole application.
+1 -1
View File
@@ -247,7 +247,7 @@ If you want to apply a directive to each inner piece of the repeat, put it on a
### `$rootScope` exists, but it can be used for evil
Scopes in Angular form a hierarchy, prototypally inheriting from a root scope at the top of the tree.
Scopes in Angular form a hierarchy, prototypically inheriting from a root scope at the top of the tree.
Usually this can be ignored, since most views have a controller, and therefore a scope, of their own.
Occasionally there are pieces of data that you want to make global to the whole app.
+1 -1
View File
@@ -135,7 +135,7 @@ To learn more about Angular scopes, see the {@link ng.$rootScope.Scope angular s
<div class="alert alert-warning">
<p>
Angular scopes prototypally inherit from their parent scope, all the way up to the *root scope*
Angular scopes prototypically inherit from their parent scope, all the way up to the *root scope*
of the application. As a result, assigning values directly on the scope makes it easy to share
data across different parts of the page and create interactive applications.
While this approach works for prototypes and smaller applications, it quickly leads to tight
+1 -1
View File
@@ -324,7 +324,7 @@ modularity.
The takeaway here is:
* Always be explicit about the dependecies of a sub-module. Do not rely on dependencies inherited
* Always be explicit about the dependencies of a sub-module. Do not rely on dependencies inherited
from a parent module (because that parent module might not be there some day).
<div class="alert alert-success">
-258
View File
@@ -1,258 +0,0 @@
#!/usr/bin/env node
'use strict';
var http = require('http');
var https = require('https');
var fs = require('fs');
var collections = {
'guide': 'https://docs.google.com/feeds/default/private/full/folder%3A0B9PsajIPqzmANGUwMGVhZmYtMTk1ZC00NTdmLWIxMDAtZGI5YWNlZjQ2YjZl/contents',
'api': 'https://docs.google.com/feeds/default/private/full/folder%3A0B7Ovm8bUYiUDYjMwYTc2YWUtZTgzYy00YjIxLThlZDYtYWJlOTFlNzE2NzEw/contents',
'tutorial': 'https://docs.google.com/feeds/default/private/full/folder%3A0B9PsajIPqzmAYWMxYWE3MzYtYzdjYS00OGQxLWJhZjItYzZkMzJiZTRhZjFl/contents',
'cookbook': 'https://docs.google.com/feeds/default/private/full/folder%3A0B7Ovm8bUYiUDNzkxZWM5ZTItN2M5NC00NWIxLTg2ZDMtMmYwNDY1NWM1MGU4/contents',
'misc': 'https://docs.google.com/feeds/default/private/full/folder%3A0B7Ovm8bUYiUDZjVlNmZkYzQtMjZlOC00NmZhLWI5MjAtMGRjZjlkOGJkMDBi/contents'
};
console.log('Google Docs...');
var flag = process && process.argv[2];
if (flag === '--login') {
var username = process.argv[3];
if (username) {
askPassword(function(password) {
login(username, password);
});
} else {
console.log('Missing username!');
}
} else if (flag === '--fetch') {
var collection = process.argv[3];
if (collection) {
fetch(collection, collections[collection]);
} else {
for (collection in collections)
fetch(collection, collections[collection]);
}
} else {
help();
}
function help() {
console.log('Synopsys');
console.log('gdocs.js --login <username>');
console.log('gdocs.js --fetch [<docs collection>]');
process.exit(-1);
}
function fetch(collection, url) {
console.log('fetching a list of docs in collection ' + collection + '...');
request('GET', url, {
headers: {
'Gdata-Version': '3.0',
'Authorization': 'GoogleLogin auth=' + getAuthToken()
}
},
function(chunk) {
var entries = chunk.split('<entry');
entries.shift();
entries.forEach(function(entry) {
var title = entry.match(/<title>(.*?)<\/title>/)[1];
if (title.match(/\.ngdoc$/)) {
var exportUrl = entry.match(/<content type='text\/html' src='(.*?)'\/>/)[1];
download(collection, title, exportUrl);
}
});
}
);
}
function download(collection, name, url) {
console.log('Downloading:', name, '...');
request('GET', url + '&exportFormat=txt',
{
headers: {
'Gdata-Version': '3.0',
'Authorization': 'GoogleLogin auth=' + getAuthToken()
}
},
function(data) {
data = data.replace('\ufeff', '');
data = data.replace(/\r\n/mg, '\n');
// strip out all text annotations
data = data.replace(/\[[a-zA-Z]{1,2}\]/mg, '');
// strip out all docos comments
data = data.replace(/^[^\s_]+:\n\S+[\S\s]*$/m, '');
// fix smart-quotes
data = data.replace(/[“”]/g, '"');
data = data.replace(/[‘’]/g, '\'');
data = data + '\n';
//this should be a bug in Google Doc API, hence need to remove this once the bug is fixed
data = data.replace(/\n\n/g, '\n');
fs.writeFileSync('docs/content/' + collection + '/' + name, reflow(data, 100));
}
);
}
/**
* token=$(curl
* -s https://www.google.com/accounts/ClientLogin
* -d Email=...username...
* -d Passwd=...password...
* -d accountType=GOOGLE
* -d service=writely
* -d Gdata-version=3.0 | cut -d "=" -f 2)
*/
function login(username, password) {
request('POST', 'https://www.google.com/accounts/ClientLogin',
{
data: {
Email: username,
Passwd: password,
accountType: 'GOOGLE',
service: 'writely',
'Gdata-version': '3.0'
},
headers: {
'Content-type': 'application/x-www-form-urlencoded'
}
},
function(chunk) {
var token;
chunk.split('\n').forEach(function(line) {
var parts = line.split('=');
if (parts[0] === 'Auth') {
token = parts[1];
}
});
if (token) {
fs.writeFileSync('tmp/gdocs.auth', token);
console.log('logged in, token saved in \'tmp/gdocs.auth\'');
} else {
console.log('failed to log in');
}
}
);
}
function getAuthToken() {
var pwdFile = 'tmp/gdocs.auth';
try {
fs.statSync(pwdFile);
return fs.readFileSync(pwdFile);
} catch (e) {
console.log('Please log in first...');
}
}
function request(method, url, options, response) {
url = url.match(/http(s?):\/\/(.+?)(\/.*)/);
var isHttps = url[1];
var req = (isHttps ? https : http).request({
host: url[2],
port: (url[1] ? 443 : 80),
path: url[3],
method: method
}, function(res) {
var data;
switch (res.statusCode) {
case 200:
data = [];
res.setEncoding('utf8');
res.on('end', function() { response(data.join('')); });
res.on('close', function() { response(data.join('')); }); // https
res.on('data', function(chunk) { data.push(chunk); });
res.on('error', function(e) { console.log(e); });
break;
case 401:
console.log('Error: Login credentials expired! Please login.');
break;
default:
data = [];
console.log('ERROR: ', res.statusCode);
console.log('REQUEST URL: ', url[0]);
console.log('REQUEST POST: ', options.data);
console.log('REQUEST HEADERS: ', options.headers);
console.log('RESPONSE HEADERS: ', res.headers);
res.on('end', function() { console.log('BODY: ', data.join('')); });
res.on('close', function() { console.log('BODY: ', data.join('')); }); // https
res.on('data', function(chunk) { data.push(chunk); });
res.on('error', function(e) { console.log(e); });
}
});
for (var header in options.headers) {
req.setHeader(header, options.headers[header]);
}
if (options.data)
req.write(encodeData(options.data));
req.on('end', function() {
console.log('end');
});
req.end();
}
function encodeData(obj) {
var pairs = [];
for (var key in obj) {
pairs.push(key + '=' + obj[key]);
}
return pairs.join('&') + '\n';
}
function askPassword(callback) {
var stdin = process.openStdin(),
stdio = process.binding('stdio');
stdio.setRawMode();
console.log('Enter your password:');
var password = '';
stdin.on('data', function(c) {
c = c + '';
switch (c) {
case '\n':
case '\r':
case '\u0004':
stdio.setRawMode(false);
stdin.pause();
callback(password);
break;
case '\u0003':
process.exit();
break;
default:
password += c;
break;
}
});
}
function reflow(text, margin) {
var lines = [];
text.split(/\n/).forEach(function(line) {
var col = 0;
var reflowLine = '';
function flush() {
reflowLine = reflowLine.replace(/\s*$/, '');
lines.push(reflowLine);
reflowLine = '';
col = 0;
}
line.replace(/\s*\S*\s*/g, function(chunk) {
if (col + chunk.length > margin) flush();
reflowLine += chunk;
col += chunk.length;
});
flush();
});
return lines.join('\n');
}
+5 -5
View File
@@ -53,7 +53,7 @@ var getGitRepoInfo = function() {
* @return {String} The codename if found, otherwise null/undefined
*/
var getCodeName = function(tagName) {
var gitCatOutput = shell.exec('git cat-file -p ' + tagName, {silent:true}).output;
var gitCatOutput = shell.exec('git cat-file -p ' + tagName, {silent:true}).stdout;
var tagMessage = gitCatOutput.match(/^.*codename.*$/mg)[0];
var codeName = tagMessage && tagMessage.match(/codename\((.*)\)/)[1];
if (!codeName) {
@@ -69,7 +69,7 @@ var getCodeName = function(tagName) {
* @return {String} The build segment of the version
*/
function getBuild() {
var hash = shell.exec('git rev-parse --short HEAD', {silent: true}).output.replace('\n', '');
var hash = shell.exec('git rev-parse --short HEAD', {silent: true}).stdout.replace('\n', '');
return 'sha.' + hash;
}
@@ -87,7 +87,7 @@ var getTaggedVersion = function() {
var gitTagResult = shell.exec('git describe --exact-match', {silent:true});
if (gitTagResult.code === 0) {
var tag = gitTagResult.output.trim();
var tag = gitTagResult.stdout.trim();
var version = semver.parse(tag);
if (version && checkBranchPattern(version.version, currentPackage.branchPattern)) {
@@ -113,7 +113,7 @@ var getPreviousVersions = function() {
var query = NO_REMOTE_REQUESTS ? 'git tag' : 'git ls-remote --tags ' + repo_url;
var tagResults = shell.exec(query, {silent: true});
if (tagResults.code === 0) {
return _(tagResults.output.match(/v[0-9].*[0-9]$/mg))
return _(tagResults.stdout.match(/v[0-9].*[0-9]$/mg))
.map(function(tag) {
var version = semver.parse(tag);
return version;
@@ -159,7 +159,7 @@ var getCdnVersion = function() {
{silent: true});
if (cdnResult.code === 0) {
// --write-out appends its content to the general request response, so extract it
var statusCode = cdnResult.output.split('\n').pop().trim();
var statusCode = cdnResult.stdout.split('\n').pop().trim();
if (statusCode === '200') {
cdnVersion = version;
}
+852 -250
View File
File diff suppressed because it is too large Load Diff
+1603 -637
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -33,7 +33,7 @@
"cross-spawn": "^4.0.0",
"cz-conventional-changelog": "1.1.4",
"dgeni": "^0.4.0",
"dgeni-packages": "^0.14.0",
"dgeni-packages": "^0.16.0",
"event-stream": "~3.1.0",
"glob": "^6.0.1",
"grunt": "^1.0.1",
@@ -73,7 +73,7 @@
"marked": "~0.3.0",
"node-html-encoder": "0.0.2",
"promises-aplus-tests": "~2.1.0",
"protractor": "^4.0.2",
"protractor": "^4.0.10",
"q": "~1.0.0",
"q-io": "^1.10.9",
"qq": "^0.3.5",
@@ -84,7 +84,7 @@
"serve-favicon": "^2.3.0",
"serve-index": "^1.8.0",
"serve-static": "^1.11.1",
"shelljs": "~0.3.0",
"shelljs": "^0.7.5",
"sorted-object": "^1.0.0",
"stringmap": "^0.2.2"
},
+36 -1
View File
@@ -169,6 +169,7 @@ var
angularModule,
uid = 0;
// Support: IE 9-11 only
/**
* documentMode is an IE-only property
* http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
@@ -601,7 +602,7 @@ function isDate(value) {
* @kind function
*
* @description
* Determines if a reference is an `Array`.
* Determines if a reference is an `Array`. Alias of Array.isArray.
*
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is an `Array`.
@@ -1279,6 +1280,7 @@ function fromJson(json) {
var ALL_COLONS = /:/g;
function timezoneToOffset(timezone, fallback) {
// Support: IE 9-11 only, Edge 13-14+
// IE/Edge do not "understand" colon (`:`) in timezone
timezone = timezone.replace(ALL_COLONS, '');
var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
@@ -1444,6 +1446,34 @@ function getNgAttribute(element, ngAttr) {
return null;
}
function allowAutoBootstrap(document) {
if (!document.currentScript) {
return true;
}
var src = document.currentScript.getAttribute('src');
var link = document.createElement('a');
link.href = src;
var scriptProtocol = link.protocol;
var docLoadProtocol = document.location.protocol;
if (docLoadProtocol === scriptProtocol) {
return true;
}
switch (scriptProtocol) {
case 'http:':
case 'https:':
case 'ftp:':
case 'blob:':
case 'file:':
case 'data:':
return true;
default:
return false;
}
}
// Cached as it has to run during loading so that document.currentScript is available.
var isAutoBootstrapAllowed = allowAutoBootstrap(window.document);
/**
* @ngdoc directive
* @name ngApp
@@ -1602,6 +1632,11 @@ function angularInit(element, bootstrap) {
}
});
if (appElement) {
if (!isAutoBootstrapAllowed) {
window.console.error('Angular: disabling automatic bootstrap. <script> protocol indicates ' +
'an extension, document.location.href does not match.');
return;
}
config.strictDi = getNgAttribute(appElement, 'strict-di') !== null;
bootstrap(appElement, module ? [module] : [], config);
}
-2
View File
@@ -79,7 +79,6 @@
$jsonpCallbacksProvider,
$LocationProvider,
$LogProvider,
$ModelOptionsProvider,
$ParseProvider,
$RootScopeProvider,
$QProvider,
@@ -247,7 +246,6 @@ function publishExternalAPI(angular) {
$jsonpCallbacks: $jsonpCallbacksProvider,
$location: $LocationProvider,
$log: $LogProvider,
$modelOptions: $ModelOptionsProvider,
$parse: $ParseProvider,
$rootScope: $RootScopeProvider,
$q: $QProvider,
+2 -1
View File
@@ -849,8 +849,9 @@ function createInjector(modulesToLoad, strictDi) {
}
function isClass(func) {
// Support: IE 9-11 only
// IE 9-11 do not support classes and IE9 leaks with the code below.
if (msie <= 11 || typeof func !== 'function') {
if (msie || typeof func !== 'function') {
return false;
}
var result = func.$$ngIsClass;
-1
View File
@@ -252,7 +252,6 @@ var $AnimateProvider = ['$provide', /** @this */ function($provide) {
var reservedRegex = new RegExp('(\\s+|\\/)' + NG_ANIMATE_CLASSNAME + '(\\s+|\\/)');
if (reservedRegex.test(this.$$classNameFilter.toString())) {
throw $animateMinErr('nongcls','$animateProvider.classNameFilter(regex) prohibits accepting a regex value which matches/contains the "{0}" CSS class.', NG_ANIMATE_CLASSNAME);
}
}
}
+14 -4
View File
@@ -402,7 +402,7 @@
* * defines the parent to which the `cloneLinkingFn` will add the cloned elements.
* * default: `$element.parent()` resp. `$element` for `transclude:'element'` resp. `transclude:true`.
* * only needed for transcludes that are allowed to contain non html elements (e.g. SVG elements)
* and when the `cloneLinkinFn` is passed,
* and when the `cloneLinkingFn` is passed,
* as those elements need to created and cloned in a special way when they are defined outside their
* usual containers (e.g. like `<svg>`).
* * See also the `directive.templateNamespace` property.
@@ -943,6 +943,16 @@
*
* For information on how the compiler works, see the
* {@link guide/compiler Angular HTML Compiler} section of the Developer Guide.
*
* @knownIssue
*
* ### Double Compilation
*
Double compilation occurs when an already compiled part of the DOM gets
compiled again. This is an undesired effect and can lead to misbehaving directives, performance issues,
and memory leaks. Refer to the Compiler Guide {@link guide/compiler#double-compilation-and-how-to-avoid-it
section on double compilation} for an in-depth explanation and ways to avoid it.
*
*/
var $compileMinErr = minErr('$compile');
@@ -1379,7 +1389,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
*
* The default value is true in Angular 1.5.x but will switch to false in Angular 1.6.x.
*/
var preAssignBindingsEnabled = true;
var preAssignBindingsEnabled = false;
this.preAssignBindingsEnabled = function(enabled) {
if (isDefined(enabled)) {
preAssignBindingsEnabled = enabled;
@@ -1949,6 +1959,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
for (var i = 0; i < nodeList.length; i++) {
attrs = new Attributes();
// Support: IE 11 only
// Workaround for #11781 and #14924
if (msie === 11) {
mergeConsecutiveTextNodes(nodeList, i, notLiveList);
@@ -2222,7 +2233,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
/**
* Given a node with an directive-start it collects all of the siblings until it finds
* Given a node with a directive-start it collects all of the siblings until it finds
* directive-end.
* @param node
* @param attrStart
@@ -2409,7 +2420,6 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
}
if (!directive.templateUrl && directive.controller) {
directiveValue = directive.controller;
controllerDirectives = controllerDirectives || createMap();
assertNoDuplicate('\'' + directiveName + '\' controller',
controllerDirectives[directiveName], directive, $compileNode);
+3 -1
View File
@@ -61,7 +61,9 @@ function $ControllerProvider() {
* @description If called, allows `$controller` to find controller constructors on `window`
*
* @deprecated
* This method of finding controllers has been deprecated. This will be removed in 1.7.
* sinceVersion="v1.3.0"
* removeVersion="v1.7.0"
* This method of finding controllers has been deprecated.
*/
this.allowGlobals = function() {
globals = true;
+3 -2
View File
@@ -426,10 +426,11 @@ forEach(['src', 'srcset', 'href'], function(attrName) {
attr.$set(name, value);
// on IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
// Support: IE 9-11 only
// On IE, if "ng:src" directive declaration is used and "src" attribute doesn't exist
// then calling element.setAttribute('src', 'foo') doesn't do anything, so we need
// to set the property as well to achieve the desired effect.
// we use attr[attrName] value since $set can sanitize the url.
// We use attr[attrName] value since $set can sanitize the url.
if (msie && propName) element.prop(propName, attr[name]);
});
}
+2 -4
View File
@@ -1234,7 +1234,7 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) {
var type = lowercase(element[0].type);
// In composition mode, users are still inputing intermediate text buffer,
// In composition mode, users are still inputting intermediate text buffer,
// hold the listener until composition is done.
// More about composition events: https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
if (!$sniffer.android) {
@@ -1811,9 +1811,7 @@ function radioInputType(scope, element, attr, ctrl) {
if (doTrim) {
value = trim(value);
}
// Strict comparison would cause a BC
// eslint-disable-next-line eqeqeq
element[0].checked = (value == ctrl.$viewValue);
element[0].checked = (value === ctrl.$viewValue);
};
attr.$observe('value', ctrl.$render);

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