Compare commits

..

181 Commits

Author SHA1 Message Date
Michał Gołębiowski-Owczarek 8ecbb53d28 chore(*): normalize Vojta's email in .mailmap correctly
Closes #16340
2017-11-22 13:26:22 +01:00
Michał Gołębiowski-Owczarek 25b758842a chore(*): add a Git .mailmap with my new name
In this way:
* my past contributions are mapped correctly
* other people's distinct entries are collapsed into one

Closes #16254
2017-10-04 23:25:57 +02:00
Peter Bacon Darwin 8f2d05f370 fix(Angular): do not autobootstrap if the src exists but is empty
In Chrome an empty `src` attribute will be ignored, but in Firefox it seems
happy to prepend the `base[href]` and try to load whatever that is.
2017-02-27 20:47:56 +00:00
Peter Bacon Darwin 56719ec4ac fix(Angular): do not auto bootstrap if the currentScript has been clobbered 2017-02-24 15:04:59 +00:00
Peter Bacon Darwin 7d8ca1bf51 fix(Angular): do not auto bootstrap if the script source is bad and inside SVG 2017-02-24 15:04:54 +00:00
Peter Bacon Darwin 56bfad1d0e test(Angular): refactor auto bootstrap tests 2017-02-24 15:04:50 +00:00
Dimitris Vardoulakis 424f4b8a13 refactor(*): avoid non-existent property warnings from Closure Compiler
Closes #15672
2017-02-02 22:40:07 +02:00
Georgios Kalpakas f73a651461 revert: fix($sce): consider document base URL in 'self' URL policy
This reverts commit 5e28b6ea8c.
Reverting while investigating security implications of 5e28b6e without #15597
(which is possibly a breaking change, thus not suitable for this branch).
2017-01-12 11:22:40 +02:00
Georgios Kalpakas d65636988b test($compile): clean up stray statement after cherry-pick 2017-01-11 19:35:33 +02:00
frederikprijck e75fbc494e fix($compile): allow the usage of "$" in isolate scope property alias
Previously, when using an alias for an isolate scope or `bindings` property
(e.g. `alias: '<attrName'` instead of `attrName: '<'`), a `$compile:iscp` error
was thrown if the attribute name contained a "$".
This commit removes the error by changing the regex to allow "$" characters in
the attribute name when using a property alias.

Fixes: #15586

Closes #15594
2017-01-11 11:55:01 +02:00
Alex Dobkin 5e28b6ea8c fix($sce): consider document base URL in 'self' URL policy
Page authors can use the `<base>` tag in HTML to specify URL to use as a base
when resovling relative URLs. This can cause SCE to reject relative URLs on the
page, because they fail the same-origin test.

To improve compatibility with the `<base>` tag, this commit changes the logic
for matching URLs to the 'self' policy to allow URLs that match the protocol and
domain of the base URL in addition to URLs that match the loading origin.

**Security Note:**
If an attacker can inject a `<base>` tag into the page, they can circumvent SCE
protections. However, injecting a `<base>` tag typically requires the ability to
inject arbitrary HTML into the page, which is a more serious vulnerabilty than
bypassing SCE.

Fixes #15144

Closes #15145
2017-01-10 15:29:26 +02:00
David Jöch 586ec15398 style($log): fix indentation
Closes #15579
2017-01-05 13:04:26 +02:00
Nic Mitchell 8541d25ded chore(*): update copyright year
Closes #15573
2017-01-04 12:25:39 +02:00
Georgios Kalpakas a580f8132b docs(guide/$location): correctly format heading 2017-01-03 22:41:42 +02:00
Georgios Kalpakas 41aa9125b9 fix(angularInit): allow auto-bootstraping from inline script
Some browsers (e.g. Safari 9.x, PhantomJS) do not set `link.origin/protocol`
correctly, when setting `link.href` to `null`, which prevented auto-bootstraping
Angular from scripts without a `src` attribute (i.e. inline scripts).
Inline scripts are on the same origin as the loading page, so auto-bootstraping
should be allowed.

Fixes #15567

Closes #15571
2017-01-03 19:26:50 +02:00
Soumya Ranjan Mohanty b4581e3e99 docs(guide/services): fix syntax for Jasmine v2.x
Closes #15570
2017-01-03 16:17:01 +02:00
Georgios Kalpakas bdb5bc82a3 docs(ngShow/ngHide): improve docs and fix inconsistencies between ngShow/ngHide
Closes #15471
2017-01-03 12:56:59 +02:00
Deco 1cf93fd2b0 docs(tutorial/step_04): fix typo
Closes #15562
2016-12-31 12:32:52 +02:00
supasak 4f3858e7c3 fix($resource): delete $cancelRequest() in toJSON()
Closes #15244
2016-12-29 10:02:20 +02:00
Naomi Black 4993728819 docs(guide/forms): remove implicit bias from example
Closes #15543
2016-12-23 11:44:23 +02:00
sp00m 6933cf64fe fix($$cookieReader): correctly handle forbidden access to document.cookie
In certain cases (e.g. on LG webOS using the `file:` protocol), access to
`document.cookie` may not be allowed and throw an error. This could break
`$http` which relies on `$$cookieReader()` for retrieving the XSRF token.
This commit fixes it by treating `document.cookie` as empty, when access to it
is fordibben.

Fixes  #15523

Closes #15532
2016-12-20 23:35:50 +02:00
Peter Neave 32e656b769 docs(tutorial/step_13): add missing dependency phoneDetails module
Closes #15521
2016-12-19 21:10:02 +02:00
Georgios Kalpakas 11fbc17f65 chore(scripts): fix jenkins scripts 2016-12-16 12:27:04 +02:00
Matias Niemelä 02f045be8d revert: fix($resource): allow params in hostname (except for IPv6 addresses)
This reverts commit 7f45b5fee7.
2016-12-15 17:21:46 -05:00
Peter Bacon Darwin 71083a4455 chore(bower): use npm tool to publish 2016-12-15 20:22:00 +00:00
Peter Bacon Darwin 700aafe3ab chore(package.json): fix dist-tag for 1.5 branch 2016-12-15 20:21:24 +00:00
Jannick Fahlbusch 2b6bfc36ae docs($interval): improve fn description
If no additional arguments are passed, the function is called with the current iteration count.

Closes #15503
2016-12-13 14:16:55 +02:00
Georgios Kalpakas 31716eec4d refactor(testabilityPatch): remove code duplication 2016-12-13 00:14:05 +02:00
Aaron Brewer f670c451f4 docs(ngMessageExp): improve description
Closes #15486
2016-12-11 21:02:51 +02:00
idhindsight 6d0ff9fb7f docs(tutorial/step_09): fix typo (it's --> its)
Closes #15485
2016-12-10 22:28:37 +02:00
Georgios Kalpakas e3d02070ab fix(ngClassOdd/Even): add/remove the correct classes when expression/$index change simultaneously 2016-12-09 12:33:18 +02:00
Georgios Kalpakas a9708de84b fix($rootScope): when adding/removing watchers during $digest
Previously, adding a watcher during a `$digest` (i.e. from within a watcher),
would result in the next watcher getting skipped. Similarly, removing a watcher
during a `$digest` could result in the current watcher being run twice (if the
removed watcher had not run yet in the current `$digest`).

This commit fixes both cases by keeping track of the current watcher index
during a digest and properly updating it when adding/removing watchers.

Fixes #15422

Closes #15424
2016-12-09 10:45:32 +02:00
Georgios Kalpakas 77ed85bcd3 fix(jqLite): silently ignore after() if element has no parent
Previously, the element was always assumed to have a parent and an error was
thrown when that was not the case.
This commit makes jqLite consistent with jQuery, which silently ignores a call
on elements that do not have a parent.

Fixes #15331
Closes #15367

Closes #15475
2016-12-08 18:12:54 +02:00
Georgios Kalpakas 0ddbcafd9e docs(ngMockE2E): correctly document the data arg of $httpBackend.when(...) 2016-12-08 14:54:39 +02:00
Peter Bacon Darwin 536da55705 chore(jenkins): fix yarn and grunt installation 2016-12-07 10:55:54 +00:00
Rob Wu bdeb3392a8 feat(security): do not bootstrap from unknown schemes with a different origin 2016-12-05 21:35:17 +00:00
Georgios Kalpakas 7f45b5fee7 fix($resource): allow params in hostname (except for IPv6 addresses)
Support for IPv6 addresses (in b643f0d) was too aggressive and broke support for params in the
`hostname` part of a URL.
This commit restores support for params in the `hostname`, as long as it is not an IPv6 address.

Fixes #14542

Closes #14906
2016-12-03 10:01:10 +02:00
ojab a3cd7d8011 docs(guide/templates): camelCase directive name for consistency
Closes #15465
2016-12-02 23:41:46 +02:00
Martin Staffa 3a767a9943 chore(doc-gen): render @example tag in ngdoc @method
Currently, ngdoc `@method` ignores `@example` tags and does not output them.
This is usually not a problem, as examples are mostly defined directly
in the `@description` via code blocks or `<example>`
elements. However, some methods still have `@example` tags (possibly
from a previous docs version).

While not absolutely necessary, having special markup for Examples
makes them a) easier to find visually in the docs, and b) easier
to link to as they will have a unique id.

Closes #14722
Closes #15448
2016-12-02 18:29:51 +01:00
Martin Staffa 1d29c91c34 fix(ngOptions): don't add comment nodes as empty options
When the "empty option" element contains a transclusion directive, the result of the compilation always includes a comment node. Since we are adding / removing the "selected" attribute on the empty option, we need to make sure it's an actual element.

To solve this, we take advantage of the fact the each option element has an option directive that tries to register the option with the selectController. With ngOptions, this registerOption function is normally noop'd since it's not possible to add dynamic options. Now if the result of the empty option compilation is a comment, we re-define the function so that it catches empty options when they are actually linked / rendered.

Closes #15454
Closes #15456
2016-12-02 18:20:43 +01:00
Georgios Kalpakas 0e666eb0b9 test($compile): work around Chrome issue with reported size for <foreignObject>
Since Chrome 53-57+, the reported size of `<foreignObject>` elements and their
descendants is affected by global display settings (e.g. font size) and browser
settings (e.g. default zoom level). This could cause tests incorrectly failing
due to such settings.

In order to avoid false negatives, we now compare against the size of the
equivalent, hand-written SVG instead of fixed widths/heights.

Fixes #15333

Closes #15458
2016-12-01 14:51:38 +02:00
Peter Bacon Darwin b748046c04 docs(contribute): mention nvm-windows 2016-11-29 14:43:42 +00:00
Peter Bacon Darwin 3ecaccf719 docs(FAQ) add link to security guide 2016-11-29 14:43:41 +00:00
Peter Bacon Darwin 250fcecae1 chore(grunt): check node, yarn and grunt-cli versions
If global versions of node, yarn or grunt-cli don't match what we expect then blow up.
2016-11-29 14:43:41 +00:00
Peter Bacon Darwin 0b81a26045 chore(grunt): run gulp directly rather than through npm 2016-11-29 14:43:41 +00:00
Peter Bacon Darwin 3205e1c08c chore(utils): install npm-run to simplify scripts 2016-11-29 14:43:41 +00:00
Peter Bacon Darwin dcb5d32055 chore(travis): install grunt-cli globally to simplify scripts 2016-11-29 14:43:41 +00:00
Peter Bacon Darwin d69a64047b chore(jenkins): remove path to grunt
grunt is installed globally on jenkins so we can just use it directly.
2016-11-29 14:43:41 +00:00
Peter Bacon Darwin ebd841165d docs(ComponentRouter): it is unlikely ever to appear on bower or CDN 2016-11-29 14:43:41 +00:00
Peter Bacon Darwin f62079d452 chore(validate-commit): remove redundant scripts 2016-11-29 14:43:40 +00:00
Peter Bacon Darwin ad6ac68509 chore(saucelabs): update sauce-connect to 4.4.1 2016-11-29 14:43:40 +00:00
Peter Bacon Darwin 03ff634598 chore(bower): set clone depth to speed up releases
We already use `git clone ... --depth=1` for the `code.angularjs.org`
repository, which speeds up the cloning of the repository.
2016-11-29 14:43:40 +00:00
Peter Bacon Darwin bf1e3e0eac chore(npm-bundle-deps): remove unused script
This became reduntant as of 507ee2d9ba
2016-11-29 14:43:40 +00:00
Peter Bacon Darwin 0f001786d8 style(*): fix no-useless-escape eslint errors 2016-11-29 14:43:40 +00:00
Peter Bacon Darwin 97eca91927 docs(*): switch from npm to yarn 2016-11-29 14:39:33 +00:00
Peter Bacon Darwin 3821e8a951 chore(dependencies): USE YARN (and node 6) 2016-11-29 14:39:32 +00:00
Martin Staffa 1f61f30799 docs($compile, guide/compiler): add "double compilation" known issue
Related #15278
Closes #15392
2016-11-24 09:37:59 +00:00
Martin Staffa c57779d872 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-24 09:37:59 +00:00
Martin Staffa 404046081d style(ngIfSpec.js, ngIncludeSpec.js): add top level describe 2016-11-24 09:37:59 +00:00
Martin Staffa 5b7ec8c84e fix(select): let ngValue take precedence over option text with multiple interpolations
Fixes #15413
Closes #15420
2016-11-24 09:37:59 +00:00
Martin Staffa 24471cf992 docs(*): add more info about deprecation versions 2016-11-24 09:37:59 +00:00
Georgios Kalpakas 8d644bd066 docs(guide/directive): minor wording and styling fixes 2016-11-24 09:37:59 +00:00
Santi Albo 78eecb43db 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-24 09:37:59 +00:00
Georgios Kalpakas 2791a855a6 docs(error/ng:areq): fix typo 2016-11-24 09:37:59 +00:00
Karthikeyan bbe8ad5698 docs(error/ng:areq): mention common error cause
Closes #15414
2016-11-24 09:37:59 +00:00
Peter Bacon Darwin 5041cf1f32 docs(*): fix up deprecation notices 2016-11-24 09:37:59 +00:00
Peter Bacon Darwin d1bbc2562d chore(docs): deprecation notices for methods and properties
Closes #15351
Closes #15394
2016-11-24 09:37:59 +00:00
Peter Bacon Darwin e19ad74ea4 chore(docs): bring in all templates from dgeni-packages 2016-11-24 09:37:59 +00:00
Arturo Romero 7586fa2b86 docs(guide/Forms): add labels to input elements
Closes #15403
2016-11-24 09:37:58 +00:00
Georgios Kalpakas 70fa4d308a docs(ngModel): fix typo and rephrase for simplicity 2016-11-24 09:37:58 +00:00
Georgios Kalpakas 75c83ff319 fix(ngMock/$controller): respect $compileProvider.preAssignBindingsEnabled()
Fixes #15387

Closes #15395
2016-11-24 09:37:58 +00:00
Peter Bacon Darwin e36dbab396 chore(Gruntfile): lengthen a+ promise test timeout to prevent flakes 2016-11-24 09:37:58 +00:00
Peter Bacon Darwin 4836278830 chore(docs): improve version picker
Closes #15385
2016-11-24 09:37:58 +00:00
Julio Borja Barra 3a8cc38b69 docs(ngModel): fix example
For the example to work correctly, the initial model values have to be empty strings.

Closes #15272
2016-11-24 09:37:58 +00:00
kentwalters a41efb2025 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-24 09:37:58 +00:00
Thomas Grainger b8ce60ac4a docs(angular.isArray): Document that isArray is an alias
Closes #15383
2016-11-24 09:37:58 +00:00
Peter Bacon Darwin 5386fe4316 test(): remove redundant hashPrefix params 2016-11-24 09:37:58 +00:00
Tim Black 82f85eda11 docs(ngRepeat): correct typo
Closes #15378
2016-11-24 09:37:58 +00:00
Kyle Wuolle 5b0e4cae49 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-24 09:37:58 +00:00
Georgios Kalpakas 8c77aeb9b1 docs(ngRepeat): add warning about track by $index with one-time bindings 2016-11-24 09:37:58 +00:00
sathify f9354dc099 chore(docs): apply consistent css property spacing 2016-11-24 09:37:58 +00:00
sathify 7648811a94 chore(docs): use $document[0] 2016-11-24 09:37:58 +00:00
Martin Staffa e1c683be52 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-24 09:37:58 +00:00
Tom Harvey cd298d6272 docs($resourceProvider): correct JS syntax error in code example
Closes #15360
2016-11-24 09:37:58 +00:00
Corey Cacic 1cfb04d5c2 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-24 09:37:58 +00:00
Michał Gołębiowski 6c8450206e chore(*): switch URLs from npmcdn.com to unpkg.com
The domain changed, the old one redirects to the new one.
2016-11-24 09:37:58 +00:00
Kyle Lieber e269ad1244 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-24 09:37:58 +00:00
Erick Delfin 551983e7e1 docs(README.md): mention "Pug" (Jade's new name)
Closes #15338
2016-11-24 09:37:58 +00:00
Jason Bedard 87625a4581 refactor($compile): remove unnecessary assignment
Closes #15337
2016-11-24 09:37:58 +00:00
Josh Soref bcc44f13e5 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-11-24 09:37:58 +00:00
Josh Soref 1b6a1c30ee test(*): fix some inconsequential typos
* select
* synopsis
* params
* template
2016-11-24 09:37:57 +00:00
Martin Staffa a29fceadcd docs(a): remove outdated practice
Using a tags as buttons is bad for accessibility and usability
2016-11-24 09:37:57 +00:00
Martin Staffa 7b997ffa13 chore(docs-app): improve layout when loading partials
By setting the current partial content to hidden, the current height
of the window is maintained until the new content is loaded.
This prevents flickering caused by the scrollbar (dis)appearing and
the footer coming into view.
2016-11-24 09:37:57 +00:00
Erik Smith 89f2be1c10 docs(guide/production): fix typo ("3rd part" --> "3rd party")
Closes #15328
2016-11-24 09:37:57 +00:00
Allan Watson 600509bb67 docs(orderBy): clarify behavior of default comparator wrt null
Document how `orderBy`'s default comparator handles `null` values.

Fixes #15293

Closes #15304
2016-11-24 09:37:57 +00:00
emed 9aae7e8bb6 docs(error/ueoe): add another possible cause
Mention unescaped quotes as another possible cause for this error.

Closes #15313
2016-11-24 09:37:57 +00:00
Georgios Kalpakas 163f08ce86 chore(ng-closure-runner): upgrade to version 0.2.4
Version 0.2.4's `minErr` implementation is up to date with the one in core.

Fixes #14971

Closes #15307
2016-11-24 09:37:57 +00:00
Jonathan Yates f3cb6e309a fix($compile): clean up @-binding observers when re-assigning bindings
Fixes #15268

Closes #15298
2016-11-24 09:37:57 +00:00
Jason Bedard 0abf65b353 test($compile): ensure equal but different instance changes are detected in onChanges
Closes #15300
2016-11-24 09:37:57 +00:00
laranhee 136e65cc04 docs($rootScope): add missing round bracket
Closes #15299
2016-11-24 09:37:57 +00:00
Martin Staffa 593a503484 fix(input[radio]): use non-strict comparison for checkedness
This was introduced during the switch to ESLint (b1bc251#diff-c244afd8def7f268b16ee91a0341c4b2R1691),
but it is a breaking change. In master, we made an exception
for this comparison when we introduced jshint eqeqeq (which was not
backported to 1.5.x).

PR (#15289)
2016-11-24 09:37:57 +00:00
Martin Staffa 48dfeb2006 Revert "chore(doc-gen, docs-app): create plnkr examples with correct Angular version"
This patch relies on a change in the dgeni example package, which
has not been added yet.

This reverts commit 0a2b72360d.
2016-11-24 09:37:57 +00:00
Martin Staffa ffa46b95b9 chore(docs-app): show loader when loading view / partial
Closes #14385
PR (#15280)
2016-11-24 09:37:57 +00:00
Martin Staffa fddc534a13 chore(doc-gen, docs-app): create plnkr examples with correct Angular version
When the docs are based on the snapshot, the plnkr examples must use the snapshot files
from code.angularjs.org

Closes #15267
PR (#15269)
2016-11-24 09:37:57 +00:00
Martin Staffa 4bf8921813 fix($location): prevent infinite digest with IDN urls in Edge
Internationalized Domain Urls, for example urls with Umlaut (Ä, Ö, Ü)
cause infinite digest in Edge 38.14393.0.0 because lastIndexOf doesn't
work correctly in this version when the search string is the same as the haystack string.

The patch uses an implementation based on core.js: https://github.com/zloirock/core-js/blob/v2.4.1/modules/es6.string.starts-with.js#L16

Edge Bug: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/9271625/

Fixes #15217
PR #15235
2016-11-24 09:37:57 +00:00
Georgios Kalpakas ee2e36d810 chore(tutorial): make diagram images responsive
Fixes angular/angular-phonecat#376

Closes #15275
2016-11-24 09:37:57 +00:00
Venkat Ganesan 87a31177b6 docs(input[checkbox]): mention ngChecked
Closes #14465
Closes #15277
2016-11-24 09:37:56 +00:00
Georgii Dolzhykov 95fa35afc4 docs($rootScope.Scope): grammar
Closes #15263
2016-11-24 09:37:56 +00:00
Martin Staffa dd0449c06f test($compile): fix tplrt tests for templateUrl 2016-11-24 09:37:56 +00:00
Martin Staffa e900f457fb refactor(compileSpec): make tests consistent
PR (#15141)
2016-11-24 09:37:56 +00:00
Peter Bacon Darwin b655744676 docs(CHANGELOG): add 1.2.31 release info 2016-11-24 09:37:56 +00:00
Michał Gołębiowski 748fee4ee7 refactor(jqLite): wrap the jqueryVersion binding in a span
Protractor's by.binding selector selects the whole element in which the binding
is contained as otherwise it can't know which bit of text has been interpolated.

It's safer to wrap the binding in a span so that we're sure what the e2e tests
are exactly testing.
2016-11-24 09:37:56 +00:00
Georgios Kalpakas 8e480d8d0c test(validators): fix broken test 2016-11-24 09:37:56 +00:00
Jason Bedard 4513dafd1a fix($parse): validate assignment lval in parser phase
The parser always threw an error in the case of an invalid left-value
assignment but it was an unhelpful:

```
Cannot set property 'undefined' of undefined
```

This commit provides a more meaningful error message, so it is not a
breaking change.

Closes #15234
2016-11-24 09:37:56 +00:00
BobChao87 9bc4ee89c8 refactor(ngModelSpec): use valueFn over curry
Refactor ngModelSpec to use internal helper function `valueFn`.
Use instead of multiple-defining a function called `curry`.

PR (#15231)

Addresses a quick change mentioned in PR 15208 from Issue #14734
2016-11-24 09:37:56 +00:00
Frank Stepanski b1c9075bcf docs(README.md): expand the "Interconnection with HTML" section
Closes #15150
2016-11-24 09:37:56 +00:00
Martin Staffa 44d70b384f docs(changelog): add missing commit and remove empty lines 2016-11-24 09:37:56 +00:00
Georgios Kalpakas 6de412311a docs($http): display the actual default Accept header 2016-11-24 09:37:56 +00:00
Vincent Gillot 49dce2ea4b docs(guide/component-router): fix typo ($routeOnReuse --> $routerOnReuse)
Closes #15224
2016-11-24 09:37:56 +00:00
Michał Gołębiowski 3ab1c3610b tests(jqLite): add basic tests for the bind/unbind aliases 2016-11-24 09:37:56 +00:00
Michał Gołębiowski 7717b96e95 perf(jqLite): move bind/unbind definitions out of the loop
The bind/unbind aliases to on/off were being assinged in every iteration
of the function assigning traversal methods to the prototype. Now it happens
only once.
2016-11-24 09:37:56 +00:00
Michał Gołębiowski cc54e433c2 chore(jqLite): fix a typo in a test name 2016-11-24 09:37:56 +00:00
Michał Gołębiowski 73ed7ef957 docs(jqLite): Document that removeAttr doesn't support multiple attributes
jQuery supports removing multiple attributes in one go, jqLite doesn't.
This is now documented.
2016-11-24 09:37:56 +00:00
Peter Bacon Darwin 2316ad7be9 chore(doc-gen): improve version dropdown info 2016-11-24 09:37:55 +00:00
Georgios Kalpakas e73dc0f31b test(*): introduce the toEqualMinErr() custom Jasmine matcher
Closes #15216
2016-11-24 09:37:55 +00:00
Georgios Kalpakas 9efe8426e5 refactor(*): use the toThrowMinErr() matcher when possible 2016-11-24 09:37:55 +00:00
Georgios Kalpakas feede20a3b docs($http): add deprecation notice for $httpProvider.useLegacyPromiseExtensions() 2016-11-24 09:37:55 +00:00
Justas Brazauskas b4735fdcbd docs(*): fix typos in comments and docs
Closes #15206
2016-11-24 09:37:55 +00:00
Georgios Kalpakas ed8aa16d30 docs($locationProvider): mention the default value for hash-prefix ('') 2016-11-24 09:37:55 +00:00
mrLarbi a5264090b6 feat($anchorScroll): convert numeric hash targets to string
This allows `$anchorScroll(7)` to scroll to `<div id="7">` (although technically, the target ID is a
string, not a number).

Fixes #14680

Closes #15182
2016-11-24 09:37:55 +00:00
Georgios Kalpakas 609264f8b0 docs(ngCsp): fix "directive"'s restrict and hide comment from output 2016-11-24 09:37:55 +00:00
Georgios Kalpakas f159e61893 docs(ngAnimate): fix typo ("an the" --> "an")
Fixes #15194
2016-11-24 09:37:55 +00:00
tijwelch 2875d9f6b0 docs($http): fix typo in headersGetter
Closes #15198
2016-11-24 09:37:55 +00:00
GregoryPorter 5a4e4e928e docs(tutorial): fix typos
- **step_04:** `controllers is one file` --> `controllers in one file`
- **step_06:** `.components.js` --> `.component.js`

Closes #15197
2016-11-24 09:37:55 +00:00
Georgii Dolzhykov eea9c597ac docs(angular.mock.inject): improve formatting
Without backticks, underscores are rendered as italics.

PR (#15186)
2016-11-24 09:37:55 +00:00
pharkare 6aeb442db4 docs(tutorial/index): fix spelling error for word 'standalone'
PR (#15187)
2016-11-24 09:37:55 +00:00
Georgios Kalpakas 22979904fb fix($compile): set attribute value even if ngAttr* contains no interpolation
Previoulsy, when the value of an `ngAttrXyz` attribute did not contain any interpolation, then the
`xyz` attribute was never set.

BTW, this commit adds a negligible overhead (since we have to set up a one-time watcher for
example), but it is justifiable for someone that is using `ngAttrXyz` (instead of `xyz` directly).

(There is also some irrelevant refactoring to remove unnecessary dependencies from tests.)

Fixes #15133

Closes #15149
2016-11-24 09:37:55 +00:00
Elliot Cameron 6c0fd3e26f docs(guide/filter): imrpove explanation of "pure function"
Improve the explanation of what a "pure function" is in simple words. The previous explanation
could be confusing, especially since the term "idempotent" (here used in it's broader
"Computer Science" meaning) is overloaded and has much stricter semantics in Mathematics or pure
Functional Programming.

Closes #15173
2016-11-24 09:37:54 +00:00
Adrian Bordinc db39512236 docs($compile): Fix a typo in the warning header
Closes #15184
2016-11-24 09:37:54 +00:00
Joao Dinis 57ef6a9237 docs(guide/concepts): insert comma
Closes #15166
2016-11-24 09:37:54 +00:00
Georgios Kalpakas 024bc1e160 refactor($resource): use route.defaults (already merged provider.defaults + options)
Closes #15160
2016-11-24 09:37:54 +00:00
Georgios Kalpakas 7e7b5151db refactor($resource): use local references of Angular helpers 2016-11-24 09:37:54 +00:00
Georgios Kalpakas 530395059f fix($resource): pass options when binding default params
`Resource.bind()`, which creates an new Resource class with the same propertiesexcept for the
additional bound default parameters, was not passing the original Resource class' `options`,
resulting in different behavior.
This commit fixes it by passing the `options` when creating the new Resource class.
2016-11-24 09:37:54 +00:00
davidcigital 9ea1e440ea docs(ngCsp): update explanation of CSP rules and how they affect Angular
Update the description of CSP, mainly regarding `unsafe-eval` and `unsafe-inline`. The way it was
presented previously was slightly misleading as it indicated that these were rules forbidding
certain things, when in fact it's a keyword in the CSP that disables the very rule that was
described. The updated text clarifies this better.

Closes #15142
2016-11-24 09:37:54 +00:00
Matt Gilson 9b9f14e52e docs(angular.toJson): add missing param type
Reference:
[JSON.stringify](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify).

Closes #15156
2016-11-24 09:37:54 +00:00
Georgios Kalpakas b11a513429 docs($templateCache): fix typo (template --> templateCache) 2016-11-24 09:37:54 +00:00
Stepan Suvorov a419ff03d4 docs(cacheFactory): remove ng-include practice from docs
Generally we don't use `ngInclude` any more, so this commit updates the
example snippet to use component instead.

Closes #15153
2016-11-24 09:37:54 +00:00
thorn0 9449893763 fix($compile): bindToController should work without controllerAs
Fixes #15088

Closes #15110
2016-11-24 09:37:54 +00:00
Georgios Kalpakas 07e1ba365f fix($compile): do not overwrite values set in $onInit() for <-bound literals
See #15118 for more details.

Fixes #15118

Closes #15123
2016-11-24 09:37:54 +00:00
Georgios Kalpakas 287a5dd4bd refactor(ngOptions): access copy() directly (angular.copy --> copy) 2016-11-24 09:37:54 +00:00
Prashant Singh Pawar 12752f66ac fix($compile): don't throw tplrt error when there is whitespace around a top-level comment
Added new conditional for NODE_TYPE_TEXT inside removeComments method of $compile
Added corresponding unit tests.

Closes #15108
PR (#15132)
2016-11-24 09:37:54 +00:00
Martin Staffa fbdfd193f7 chore(benchmarks): fix order-by benchmark 2016-11-24 09:37:54 +00:00
Austin O'Neil 05896d44ad docs(ngOptions): correct links
remove redundant link to ngOptions and add link to ngRepeat
2016-11-24 09:37:54 +00:00
Georgii Dolzhykov 00b01e09ca docs($compile): remove obsolete sentence
Fixes #15109

Closes #15119
2016-11-24 09:37:54 +00:00
Jason Bedard afc093b8b7 refactor($q): remove unnecessary checks/helpers/wrappers
- Remove internal `makePromise()` helper.
- Remove unnecessary wrapper functions.
- Remove unnecessary check for promises resolving multiple times.
  (By following the Promises/A+ spec, we know this will never happen.)
- Switch from function expressions to (named) function declarations.

Closes #15065
2016-11-24 09:37:54 +00:00
Mohsen Azimi fcffa181ce docs($q): fix typo in race() test description (array --> object)
Closes #15111
2016-11-24 09:37:53 +00:00
Martin Staffa e105dda1de docs(ngSwitch): add separator example 2016-11-24 09:37:53 +00:00
Lucas Galfaso 0e1651bfd2 feat(ngSwitch): allow multiple case matches via optional attribute ngSwitchWhenSeparator
Adds an optional attribute `ngSwitchWhenSeparator` that allows multiple tokens to match a given `ngSwitchWhen`.

Closes #3410
Closes #3516

Closes #10798
2016-11-24 09:37:53 +00:00
Austin O'Neil af4a44cbaf docs(guide/component): clarify when to use directives instead of components
Clarify that components cannot be used to perform actions in compile
and prelink functions.

Closes #15042
PR (#15100)
2016-11-24 09:37:53 +00:00
sethbattin ed89fc8ee6 docs($resourceProvider): include '$' in di in example
The injection argument is missing the '$' in the two examples.  The code fails as written.  This change corrects it.

(#15099)
2016-11-24 09:37:53 +00:00
Martin Staffa 6a7a3250cf docs($compile): link to sections from properties in examples 2016-11-24 09:37:53 +00:00
Martin Staffa 8455d2a797 docs(error/noident): add missing comma
Closes #15086
2016-11-24 09:37:53 +00:00
BobChao87 862dc2532f fix($sanitize): reduce stack height in IE <= 11
Update Internet Explorer-only helper function stripCustomNsAttrs to be less
recursive. Reduce stack height of function causing out of stack space error.

Closes #14928
Closes #15030
2016-11-24 09:37:53 +00:00
Michał Gołębiowski 7d11bc4f91 refactor(jqLite): use the toEqualOneOf matcher in jqLite tests 2016-11-24 09:37:53 +00:00
Michał Gołębiowski 006e05074a refactor(matchers): add the toEqualOneOf matcher 2016-11-24 09:37:53 +00:00
Michał Gołębiowski 1ea884ae7e refactor(jqLite): run more tests on jQuery 2.2, add version detection helpers
(cherry-picked from 6341f4260a)
2016-11-24 09:37:53 +00:00
Georgios Kalpakas c82bb89964 docs($compile): be more explicit about linking not having taken place inside cloneAttachFn
Fixes #15093
2016-11-24 09:37:53 +00:00
Georgios Kalpakas bb7f4a8733 test($compile): extend $onChanges() test to account for one more case
Discussed in https://github.com/angular/angular.js/pull/15098/files#r77770755.
2016-11-24 09:37:53 +00:00
Georgios Kalpakas 0cf5be5264 fix($compile): avoid calling $onChanges() twice for NaN initial values
Closes #15098
2016-11-24 09:37:53 +00:00
Peter Bacon Darwin 584a6b39e4 test($compile): add tests for provider settings
See https://github.com/angular/angular.js/pull/15095#issuecomment-244970426
2016-11-24 09:37:53 +00:00
Peter Bacon Darwin f86576def4 feat($compile): add preAssignBindingsEnabled option
A new option to enable/disable whether directive controllers are assigned bindings before
calling the controller's constructor.

If enabled (true), the compiler assigns the value of each of the bindings to the
properties of the controller object before the constructor of this object is called.

If disabled (false), the compiler calls the constructor first before assigning bindings.

The default value is enabled (true) in Angular 1.5.x but will switch to false in Angular 1.6.x.

See #14580
Closes #15095
2016-11-24 09:37:53 +00:00
Packt 609e807b04 docs(guide/External Resources): add a paid-online course
Closes #15075
2016-11-24 09:37:53 +00:00
Jason Bedard 31d464feef perf($compile): validate directive.restrict property on directive init
This allows the removal of try/catch from addDirective to avoid V8 deopt.

Previously the directive.restrict property was not validated. This would
potentially cause exceptions on each compilation of the directive
requiring a try/catch and potentially causing repeated errors.

New validation when directive.restrict is specified:
* must be a string
* must contain at least one valid character (E, A, C, M)

Cases which previously silently failed (now throw an error):
* values with an indexOf method (such as strings, arrays) which returned
 returned -1 for all valid restrict characters

Cases which previously worked unintentionally (now throw an error):
* arrays with single-character strings of valid restrict characters

PR (#13263)
2016-11-24 09:37:53 +00:00
Martin Staffa 5c9399d18a feat($compile): throw error when directive name or factory fn is invalid
Closes: #15056
PR (#15057)
2016-11-24 09:37:52 +00:00
Georgios Kalpakas a8da25c74d feat($resource): pass status/statusText to success callbacks
Fixes #8341
Closes #8841
PR (#14836)
2016-11-24 09:37:52 +00:00
Georgios Kalpakas 6bb775ccd1 docs(tutorial/step_03): improve explanation of camel-/kebab-casing
Related to #15051.
2016-11-24 09:37:52 +00:00
Wei Wang a4a22266f1 feat($location): add support for selectively rewriting links based on attribute
In HTML5 mode, links can now be selectively rewritten, by setting `mode.rewriteLinks` to a string
(denoting an attribute name). Anchor elements that have the specified attribute will be rewritten,
while other links will remain untouched.

This can be useful in situations where it is desirable to use HTML5 mode without a `<base>` tag, but
still support rewriting specific links only. See #14959 for more details on a possible usecase.

Closes #14976
2016-11-24 09:37:52 +00:00
Benjamin Blackwood 401da6873a docs($resource): add status param to transformResponse signature
Add `status` param to `transformResponse` signature to keep inline with 1b74097.

Closes #15041
2016-11-24 09:37:52 +00:00
Duly Bonheur 311b5faf08 docs(ngRepeat): improve example description
The example seems to also be filtering by age. It threw me off a bit because I was getting results when I entered numbers in the input field.

PR (#15037)
2016-11-24 09:37:52 +00:00
Martin Staffa 6cd911c132 docs($componentController): add more info 2016-11-24 09:37:52 +00:00
Martin Staffa 9ae793d8a6 feat($controller): throw when requested controller is not registered
Previously, it would throw the ng:areq error, which is less
specific and just informs that the requested controller is not defined.
Given how commonly controllers are used
in Angular, it makes sense to have a specific error.

The ng:areq error is still thrown when the registered controller
is not a function.

Closes #14980
PR (#15015)
2016-11-24 09:37:52 +00:00
224 changed files with 17901 additions and 33618 deletions
+29
View File
@@ -0,0 +1,29 @@
Andres Ornelas <aornelas@google.com>
Caitlin Potter <caitpotter88@gmail.com>
Caitlin Potter <caitpotter88@gmail.com> <snowball@defpixel.com>
Di Peng <pengdi@google.com>
Di Peng <pengdi@google.com> <pengdi@go.wustl.edu>
Georgios Kalpakas <kalpakas.g@gmail.com>
Georgios Kalpakas <kalpakas.g@gmail.com> <g.kalpakas@hotmail.com>
Julie Ralph <ju.ralph@gmail.com>
Lucas Galfaso <lgalfaso@gmail.com>
Martin Staffa <mjstaffa@gmail.com>
Martin Staffa <mjstaffa@gmail.com> <mjstaffa@googlemail.com>
Matias Niemelä <matias@yearofmoo.com>
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
Misko Hevery <misko@hevery.com>
Misko Hevery <misko@hevery.com> <misko@google.com>
Igor Minar <igor@angularjs.org>
Igor Minar <igor@angularjs.org> <iiminar@gmail.com>
Igor Minar <igor@angularjs.org> <iminar@google.com>
Igor Minar <igor@angularjs.org> <iminar@dhcp-172-19-37-154.mtv.corp.google.com>
Pawel Kozlowski <pkozlowski.opensource@gmail.com>
Peter Bacon Darwin <pete@bacondarwin.com>
Rodric Haddad <rody@rodyhaddad.com>
Shahar Talmi <shahar.talmi@gmail.com>
Shahar Talmi <shahar.talmi@gmail.com> <shahart@wix.com>
Shyam Seshadri <shyamseshadri@google.com>
Shyam Seshadri <shyamseshadri@google.com> <shyamseshadri@gmail.com>
Vojta Jina <vojta.jina@gmail.com>
Vojta Jina <vojta.jina@gmail.com> <vojta@gemin-i.org>
Vojta Jina <vojta.jina@gmail.com> <vojta@google.com>
+1 -2
View File
@@ -1,2 +1 @@
4
6
+5 -12
View File
@@ -1,7 +1,7 @@
language: node_js
sudo: false
node_js:
- '4.4'
- '6'
cache:
directories:
@@ -36,19 +36,12 @@ addons:
packages:
- g++-4.8
install:
# Check the size of caches
- du -sh ./node_modules ./bower_components/ ./docs/bower_components/ || true
# - npm config set registry http://23.251.144.68
# Disable the spinner, it looks bad on Travis
- npm config set spin false
# Log HTTP requests
- npm config set loglevel http
#- npm install -g npm@2.5
# Install npm dependencies and ensure that npm cache is not stale
- npm install
before_install:
- curl -o- -L https://raw.githubusercontent.com/yarnpkg/yarn/2a0afc73210c7a82082585283e518eeb88ca19ae/scripts/install-latest.sh | bash -s -- --version 0.17.9
- export PATH=$HOME/.yarn/bin:$PATH
before_script:
- du -sh ./node_modules ./bower_components/ ./docs/bower_components/ || true
- ./scripts/travis/before_build.sh
script:
+40 -30
View File
@@ -1,3 +1,25 @@
<a name="1.4.13"></a>
# 1.4.13 croaking-elderweed (2016-10-10)
## Bug Fixes
- **input:** ensure that hidden input values are correct after history back
([693d1334](https://github.com/angular/angular.js/commit/693d1334566f78987f5a361a100db4f889f35abd)
<a name="1.2.31"></a>
# 1.2.31 barking-moustache (2016-10-10)
## Bug Fixes
- **input:** ensure that hidden input values are correct after history back
([7ec663fc](https://github.com/angular/angular.js/commit/7ec663fc708aa7a9a9ce62d2306f24d7a733a86d)
<a name="1.4.12"></a>
# 1.4.12
*Invalid release*
<a name="1.5.8"></a>
# 1.5.8 arbitrary-fallbacks (2016-07-22)
@@ -86,7 +108,7 @@ to make the fixes available to people that still need IE8 support._
- secure `link[href]` as a `RESOURCE_URL`s in `$sce`
([f35f334b](https://github.com/angular/angular.js/commit/f35f334bd3197585bdf034f4b6d9ffa3122dac62),
[#14687](https://github.com/angular/angular.js/issues/14687))
- properly sanitize `xlink:href` attribute interoplation
- properly sanitize `xlink:href` attribute interpolation
([f2fa1ed8](https://github.com/angular/angular.js/commit/f2fa1ed83d18d4e79a36f8c0db1c2524d762e513),
[2687c261](https://github.com/angular/angular.js/commit/2687c26140585d9e3716f9f559390f5d8d598fdf))
- **ngSanitize:** blacklist the attribute `usemap` as it can be used as a security exploit
@@ -137,6 +159,9 @@ content, which is a security risk.
- cope with `$onChanges` hooks throwing
([3749c858](https://github.com/angular/angular.js/commit/3749c85829406ca57cc5729e80696c7f34134068),
[#14444](https://github.com/angular/angular.js/issues/14444), [#14463](https://github.com/angular/angular.js/issues/14463))
- **$location:** initialize `$$absUrl` to empty string
([294d6793f](https://github.com/angular/angular.js/commit/294d6793fd0e0781a257e35a165e0c6fde082fe7),
[#11091](https://github.com/angular/angular.js/issues/11091), [#13565](https://github.com/angular/angular.js/issues/13565), [#14488](https://github.com/angular/angular.js/issues/14488))
- **$parse:** allow arguments to contain filter chains
([cc6dcb4b](https://github.com/angular/angular.js/commit/cc6dcb4bc28aadff4f62d76d6451b0f80b928e69),
[#4175](https://github.com/angular/angular.js/issues/4175), [#4168](https://github.com/angular/angular.js/issues/4168), [#14720](https://github.com/angular/angular.js/issues/14720))
@@ -506,7 +531,7 @@ for more info.
- prevent assignment on constructor properties
([f47e2180](https://github.com/angular/angular.js/commit/f47e218006029f39b4785d820b430de3a0eebcb0),
[#13417](https://github.com/angular/angular.js/issues/13417))
- preserve expensive checks when runnning `$eval` inside an expression
- preserve expensive checks when running `$eval` inside an expression
([96d62cc0](https://github.com/angular/angular.js/commit/96d62cc0fc77248d7e3ec4aa458bac0d3e072629))
- copy `inputs` for expressions with expensive checks
([0b7fff30](https://github.com/angular/angular.js/commit/0b7fff303f46202bbae1ff3ca9d0e5fa76e0fc9a))
@@ -628,7 +653,7 @@ changes section for more information
- handle boolean attributes in `@` bindings
([db5e0ffe](https://github.com/angular/angular.js/commit/db5e0ffe124ac588f01ef0fe79efebfa72f5eec7),
[#13767](https://github.com/angular/angular.js/issues/13767), [#13769](https://github.com/angular/angular.js/issues/13769))
- **$parse:** Preserve expensive checks when runnning $eval inside an expression
- **$parse:** Preserve expensive checks when running $eval inside an expression
([acfda102](https://github.com/angular/angular.js/commit/acfda1022d23ecaea34bbc8931588a0715b3ab03))
- **dateFilter:** follow the CLDR on pattern escape sequences
([1ab4e444](https://github.com/angular/angular.js/commit/1ab4e44443716c33cd857dcb1098d20580dbb0cc),
@@ -1008,26 +1033,20 @@ report any regressions or other issues you find as soon as possible.
- **$parse:** provide a mechanism to access the locals object, `$locals`
([0ea53503](https://github.com/angular/angular.js/commit/0ea535035a3a1a992948490c3533bffb83235052))
- **$resource:** add proper support for cancelling requests, `$cancelRequest()`
([98528be3](https://github.com/angular/angular.js/commit/98528be311b48269ba0e15ba4e3e2ad9b89693a9),
[#9332](https://github.com/angular/angular.js/issues/9332), [#13050](https://github.com/angular/angular.js/issues/13050), [#13058](https://github.com/angular/angular.js/issues/13058), [#13210](https://github.com/angular/angular.js/issues/13210))
- **ngAnimate:** provide ng-[event]-prepare class for structural animations
([6e18b50a](https://github.com/angular/angular.js/commit/6e18b50a5b168848cc526081b0a2a16075ee44bd))
- **ngLocale:** add support for standalone months
([96c73a06](https://github.com/angular/angular.js/commit/96c73a0672f0e46ae9285c482b057bd03ce135ba),
[#3744](https://github.com/angular/angular.js/issues/3744), [#10247](https://github.com/angular/angular.js/issues/10247), [#12642](https://github.com/angular/angular.js/issues/12642), [#12844](https://github.com/angular/angular.js/issues/12844))
- **ngMock:** destroy $rootScope after each test
([b75c0d8d](https://github.com/angular/angular.js/commit/b75c0d8d0549261ece551210a11d8be48c3ab3cc),
[#13433](https://github.com/angular/angular.js/issues/13433))
- **ngTransclude:** don't overwrite the contents with an unfilled optional slot
([0812af49](https://github.com/angular/angular.js/commit/0812af49bd4f4fad4067603ff64dbe720bd6e3e5),
[#13426](https://github.com/angular/angular.js/issues/13426))
- **ngView:** reference resolved locals in scope, `resolveAs: '$resolve'`
([983b0598](https://github.com/angular/angular.js/commit/983b0598121a8c5a3a51a30120e114d7e3085d4d),
[#13400](https://github.com/angular/angular.js/issues/13400))
@@ -1044,30 +1063,24 @@ report any regressions or other issues you find as soon as possible.
- support merging special attribute names in `replace` directives
([a5ff651a](https://github.com/angular/angular.js/commit/a5ff651a59933c2c43b81642454ee458f98e1401),
[#13317](https://github.com/angular/angular.js/issues/13317), [#13318](https://github.com/angular/angular.js/issues/13318))
- **$http:** throw if url passed is not a string
([6628b4f1](https://github.com/angular/angular.js/commit/6628b4f1e5835d997290881c6ba394547883a516),
[#12925](https://github.com/angular/angular.js/issues/12925), [#13444](https://github.com/angular/angular.js/issues/13444))
- **$parse:**
- prevent assignment on constructor properties
([5a674f3b](https://github.com/angular/angular.js/commit/5a674f3bb9d1118d11b333e3b966c01a571c09e6),
[#13417](https://github.com/angular/angular.js/issues/13417))
- handle interceptors with `undefined` expressions
([4473b81c](https://github.com/angular/angular.js/commit/4473b81cdaf16c5509ac53d80b9bdfb0a7ac5f30))
- **$sanitize:** blacklist SVG `<use>` elements
([7a668cdd](https://github.com/angular/angular.js/commit/7a668cdd7d08a7016883eb3c671cbcd586223ae8),
[#13453](https://github.com/angular/angular.js/issues/13453))
- **formatNumber:** cope with large and small number corner cases
([6a0686d4](https://github.com/angular/angular.js/commit/6a0686d434c41445c50b2d9669073802ede77b3b),
[#13394](https://github.com/angular/angular.js/issues/13394), [#8674](https://github.com/angular/angular.js/issues/8674), [#12709](https://github.com/angular/angular.js/issues/12709), [#8705](https://github.com/angular/angular.js/issues/8705), [#12707](https://github.com/angular/angular.js/issues/12707), [#10246](https://github.com/angular/angular.js/issues/10246), [#10252](https://github.com/angular/angular.js/issues/10252))
- **input:** add missing chars to URL validation regex
([e4bb8387](https://github.com/angular/angular.js/commit/e4bb8387952069cca9da06bbc5c87ae576c2bf6f),
[#13379](https://github.com/angular/angular.js/issues/13379), [#13460](https://github.com/angular/angular.js/issues/13460))
- **ngAnimate:**
- consider options.delay value for closing timeout
([7ffb2d3c](https://github.com/angular/angular.js/commit/7ffb2d3c17643303a51eb4e324c365af70fe3824),
@@ -1081,15 +1094,12 @@ report any regressions or other issues you find as soon as possible.
- do not alter the provided options data
([193153c3](https://github.com/angular/angular.js/commit/193153c3d391338a859cb7788ef32a8af05fb920),
[#13040](https://github.com/angular/angular.js/issues/13040), [#13175](https://github.com/angular/angular.js/issues/13175))
- **ngMock:** clear out `$providerInjector` after each test
([a72c12bd](https://github.com/angular/angular.js/commit/a72c12bd7052da9f60da74625409374342b50b73),
[#13397](https://github.com/angular/angular.js/issues/13397), [#13416](https://github.com/angular/angular.js/issues/13416))
- **ngOptions:** don't $dirty multiple select after compilation
([c7a2028a](https://github.com/angular/angular.js/commit/c7a2028ab38cdfc4d956c50b6f41cbccef302165),
[#13211](https://github.com/angular/angular.js/issues/13211), [#13326](https://github.com/angular/angular.js/issues/13326))
- **ngTransclude:**
- don't replace existing content if no transcluded content exists
([c3ae6ed7](https://github.com/angular/angular.js/commit/c3ae6ed78e145a9b0c13de7ef95852ba3c467551),
@@ -1768,7 +1778,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 + '$');
@@ -1884,7 +1894,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 + '$');
@@ -3758,7 +3768,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),
@@ -5915,7 +5925,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.
@@ -7816,7 +7826,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 =
@@ -8602,7 +8612,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))
@@ -8670,7 +8680,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))
@@ -10312,7 +10322,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:**
@@ -10459,14 +10469,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
@@ -10789,7 +10799,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))
@@ -10931,7 +10941,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))
+7 -3
View File
@@ -206,7 +206,9 @@ We have very precise rules over how our git commit messages can be formatted. T
readable messages** that are easy to follow when looking through the **project history**. But also,
we use the git commit messages to **generate the AngularJS change log**.
The commit message formatting can be added using a typical git workflow or through the use of a CLI wizard ([Commitizen](https://github.com/commitizen/cz-cli)). To use the wizard, run `npm run commit` in your terminal after staging your changes in git.
The commit message formatting can be added using a typical git workflow or through the use of a CLI
wizard ([Commitizen](https://github.com/commitizen/cz-cli)). To use the wizard, run `yarn run commit`
in your terminal after staging your changes in git.
### Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
@@ -226,7 +228,8 @@ Any line of the commit message cannot be longer 100 characters! This allows the
to read on GitHub as well as in various git tools.
### Revert
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
### Type
Must be one of the following:
@@ -261,7 +264,8 @@ The body should include the motivation for the change and contrast this with pre
The footer should contain any information about **Breaking Changes** and is also the place to
reference GitHub issues that this commit **Closes**.
**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.
**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.
A detailed explanation can be found in this [document][commit-message-format].
+62 -14
View File
@@ -9,19 +9,64 @@ var versionInfo = require('./lib/versions/version-info');
var path = require('path');
var e2e = require('./test/e2e/tools');
var semver = require('semver');
var exec = require('shelljs').exec;
var pkg = require(__dirname + '/package.json');
// Node.js version checks
if (!semver.satisfies(process.version, pkg.engines.node)) {
reportOrFail('Invalid node version (' + process.version + '). ' +
'Please use a version that satisfies ' + pkg.engines.node);
}
// Yarn version checks
var expectedYarnVersion = pkg.engines.yarn;
var currentYarnVersion = exec('yarn --version', {silent: true}).stdout.trim();
if (!semver.satisfies(currentYarnVersion, expectedYarnVersion)) {
reportOrFail('Invalid yarn version (' + currentYarnVersion + '). ' +
'Please use a version that satisfies ' + expectedYarnVersion);
}
// Grunt CLI version checks
var expectedGruntVersion = pkg.engines.grunt;
var currentGruntVersions = exec('grunt --version', {silent: true}).stdout;
var match = /^grunt-cli v(.+)$/m.exec(currentGruntVersions);
if (!match) {
reportOrFail('Unable to compute the current grunt-cli version. We found:\n' +
currentGruntVersions);
} else {
if (!semver.satisfies(match[1], expectedGruntVersion)) {
reportOrFail('Invalid grunt-cli version (' + match[1] + '). ' +
'Please use a version that satisfies ' + expectedGruntVersion);
}
}
// Ensure Node.js dependencies have been installed
if (!process.env.TRAVIS && !process.env.JENKINS_HOME) {
var yarnOutput = exec('yarn install');
if (yarnOutput.code !== 0) {
throw new Error('Yarn install failed: ' + yarnOutput.stderr);
}
}
module.exports = function(grunt) {
//grunt plugins
// this loads all the node_modules that start with `grunt-` as plugins
require('load-grunt-tasks')(grunt);
// load additional grunt tasks
grunt.loadTasks('lib/grunt');
grunt.loadNpmTasks('angular-benchpress');
// compute version related info for this build
var NG_VERSION = versionInfo.currentVersion;
NG_VERSION.cdn = versionInfo.cdnVersion;
var dist = 'angular-' + NG_VERSION.full;
if (versionInfo.cdnVersion == null) {
throw new Error('Unable to read CDN version, are you offline or has the CDN not been properly pushed?');
throw new Error('Unable to read CDN version, are you offline or has the CDN not been properly pushed?\n' +
'Perhaps you want to set the NG1_BUILD_NO_REMOTE_VERSION_REQUESTS environment variable?');
}
//config
@@ -284,17 +329,16 @@ module.exports = function(grunt) {
},
shell: {
'npm-install': {
command: 'node scripts/npm/check-node-modules.js'
'install-node-dependencies': {
command: 'yarn'
},
'promises-aplus-tests': {
options: {
stdout: false,
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')
}
},
@@ -314,13 +358,6 @@ module.exports = function(grunt) {
}
});
// global beforeEach task
if (!process.env.TRAVIS) {
grunt.task.run('shell:npm-install');
}
//alias tasks
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['eslint', 'package', 'test:unit', 'test:promises-aplus', 'tests:docs', 'test:protractor']);
grunt.registerTask('test:jqlite', 'Run the unit tests with Karma' , ['tests:jqlite']);
@@ -338,7 +375,18 @@ 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']);
};
function reportOrFail(message) {
if (process.env.TRAVIS || process.env.JENKINS_HOME) {
throw new Error(message);
} else {
console.log('===============================================================================');
console.log(message);
console.log('===============================================================================');
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2010-2016 Google, Inc. http://angularjs.org
Copyright (c) 2010-2017 Google, Inc. http://angularjs.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+42 -9
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
@@ -51,24 +51,57 @@ We've set up a separate document for our [contribution guidelines](https://githu
What to use AngularJS for and when to use it
---------
AngularJS is the next generation framework where each component is designed to work with every other component in an interconnected way like a well-oiled machine. AngularJS is JavaScript MVC made easy and done right. (Well it is not really MVC, read on, to understand what this means.)
AngularJS is the next generation framework where each component is designed to work with every other
component in an interconnected way like a well-oiled machine. AngularJS is JavaScript MVC made easy
and done right. (Well it is not really MVC, read on, to understand what this means.)
#### MVC, no, MV* done the right way!
MVC, short for Model-View-Controller, is a design pattern, i.e. how the code should be organized and how the different parts of an application separated for proper readability and debugging. Model is the data and the database. View is the user interface and what the user sees. Controller is the main link between Model and View. These are the three pillars of major programming frameworks present on the market today. On the other hand AngularJS works on MV*, short for Model-View-_Whatever_. The _Whatever_ is AngularJS's way of telling that you may create any kind of linking between the Model and the View here.
MVC, short for Model-View-Controller, is a design pattern, i.e. how the code should be organized and
how the different parts of an application separated for proper readability and debugging. Model is
the data and the database. View is the user interface and what the user sees. Controller is the main
link between Model and View. These are the three pillars of major programming frameworks present on
the market today. On the other hand AngularJS works on MV*, short for Model-View-_Whatever_. The
_Whatever_ is AngularJS's way of telling that you may create any kind of linking between the Model
and the View here.
Unlike other frameworks in any programming language, where MVC, the three separate components, each one has to be written and then connected by the programmer, AngularJS helps the programmer by asking him/her to just create these and everything else will be taken care of by AngularJS.
Unlike other frameworks in any programming language, where MVC, the three separate components, each
one has to be written and then connected by the programmer, AngularJS helps the programmer by asking
him/her to just create these and everything else will be taken care of by AngularJS.
#### Interconnection with HTML at the root level
AngularJS uses HTML to define the user's interface. AngularJS also enables the programmer to write new HTML tags (AngularJS Directives) and increase the readability and understandability of the HTML code. Directives are AngularJSs way of bringing additional functionality to HTML. Directives achieve this by enabling us to invent our own HTML elements. This also helps in making the code DRY (Don't Repeat Yourself), which means once created, a new directive can be used anywhere within the application.
AngularJS uses HTML to define the user's interface. AngularJS also enables the programmer to write
new HTML tags (AngularJS Directives) and increase the readability and understandability of the HTML
code. Directives are AngularJSs way of bringing additional functionality to HTML. Directives
achieve this by enabling us to invent our own HTML elements. This also helps in making the code DRY
(Don't Repeat Yourself), which means once created, a new directive can be used anywhere within the
application.
HTML is also used to determine the wiring of the app. Special attributes in the HTML determine where
to load the app, which components or controllers to use for each element, etc. We specify "what"
gets loaded, but not "how". This declarative approach greatly simplifies app development in a sort
of WYSIWYG way. Rather than spending time on how the program flows and orchestrating the various
moving parts, we simply define what we want and Angular will take care of the dependencies.
#### Data Handling made simple
Data and Data Models in AngularJS are plain JavaScript objects and one can add and change properties directly on it and loop over objects and arrays at will.
Data and Data Models in AngularJS are plain JavaScript objects and one can add and change properties
directly on it and loop over objects and arrays at will.
#### Two-way Data Binding
One of AngularJS's strongest features. Two-way Data Binding means that if something changes in the Model, the change gets reflected in the View instantaneously, and the same happens the other way around. This is also referred to as Reactive Programming, i.e. suppose `a = b + c` is being programmed and after this, if the value of `b` and/or `c` is changed then the value of `a` will be automatically updated to reflect the change. AngularJS uses its "scopes" as a glue between the Model and View and makes these updates in one available for the other.
One of AngularJS's strongest features. Two-way Data Binding means that if something changes in the
Model, the change gets reflected in the View instantaneously, and the same happens the other way
around. This is also referred to as Reactive Programming, i.e. suppose `a = b + c` is being
programmed and after this, if the value of `b` and/or `c` is changed then the value of `a` will be
automatically updated to reflect the change. AngularJS uses its "scopes" as a glue between the Model
and View and makes these updates in one available for the other.
#### Less Written Code and Easily Maintainable Code
Everything in AngularJS is created to enable the programmer to end up writing less code that is easily maintainable and readable by any other new person on the team. Believe it or not, one can write a complete working two-way data binded application in less than 10 lines of code. Try and see for yourself!
Everything in AngularJS is created to enable the programmer to end up writing less code that is
easily maintainable and readable by any other new person on the team. Believe it or not, one can
write a complete working two-way data binded application in less than 10 lines of code. Try and see
for yourself!
#### Testing Ready
AngularJS has Dependency Injection, i.e. it takes care of providing all the necessary dependencies to its controllers whenever required. This helps in making the AngularJS code ready for unit testing by making use of mock dependencies created and injected. This makes AngularJS more modular and easily testable thus in turn helping a team create more robust applications.
AngularJS has Dependency Injection, i.e. it takes care of providing all the necessary dependencies
to its controllers and services whenever required. This helps in making the AngularJS code ready for
unit testing by making use of mock dependencies created and injected. This makes AngularJS more
modular and easily testable thus in turn helping a team create more robust applications.
+1 -1
View File
@@ -95,7 +95,7 @@ You can mention him in the relevant thread like this: `@btford`.
> Thanks for submitting this issue!
> Unfortunately, we don't think this functionality belongs in core.
> The good news is that you could easily implement this as a third-party module and publish it on Bower and/or npm.
> The good news is that you could easily implement this as a third-party module and publish it on Bower and/or to the npm repository.
## Assigning Work
+1 -1
View File
@@ -7,7 +7,7 @@ app.controller('DataController', function DataController($rootScope, $scope) {
this.rows = [];
var self = this;
$scope.benchmarkType = 'basic';
$scope.benchmarkType = 'baseline';
$scope.rawProperty = function(key) {
return function(item) {
+1
View File
@@ -0,0 +1 @@
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
+1 -1
View File
@@ -6,6 +6,6 @@
"jquery-2.2": "jquery#2.2.4",
"jquery-2.1": "jquery#2.1.4",
"closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.3/assets/ng-closure-runner.zip"
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.4/assets/ng-closure-runner.zip"
}
}
-208
View File
@@ -1,208 +0,0 @@
#!/usr/bin/env node
// TODO(vojta): pre-commit hook for validating messages
// TODO(vojta): report errors, currently Q silence everything which really sucks
'use strict';
var child = require('child_process');
var fs = require('fs');
var util = require('util');
var q = require('qq');
var GIT_LOG_CMD = 'git log --grep="%s" -E --format=%s %s..HEAD';
var GIT_TAG_CMD = 'git describe --tags --abbrev=0';
var HEADER_TPL = '<a name="%s"></a>\n# %s (%s)\n\n';
var LINK_ISSUE = '[#%s](https://github.com/angular/angular.js/issues/%s)';
var LINK_COMMIT = '[%s](https://github.com/angular/angular.js/commit/%s)';
var EMPTY_COMPONENT = '$$';
var warn = function() {
console.log('WARNING:', util.format.apply(null, arguments));
};
var parseRawCommit = function(raw) {
if (!raw) return null;
var lines = raw.split('\n');
var msg = {}, match;
msg.hash = lines.shift();
msg.subject = lines.shift();
msg.closes = [];
msg.breaks = [];
lines.forEach(function(line) {
match = line.match(/(?:Closes|Fixes)\s#(\d+)/);
if (match) msg.closes.push(parseInt(match[1], 10));
});
match = raw.match(/BREAKING CHANGE:([\s\S]*)/);
if (match) {
msg.breaking = match[1];
}
msg.body = lines.join('\n');
match = msg.subject.match(/^(.*)\((.*)\):\s(.*)$/);
if (!match || !match[1] || !match[3]) {
warn('Incorrect message: %s %s', msg.hash, msg.subject);
return null;
}
msg.type = match[1];
msg.component = match[2];
msg.subject = match[3];
return msg;
};
var linkToIssue = function(issue) {
return util.format(LINK_ISSUE, issue, issue);
};
var linkToCommit = function(hash) {
return util.format(LINK_COMMIT, hash.substr(0, 8), hash);
};
var currentDate = function() {
var now = new Date();
var pad = function(i) {
return ('0' + i).substr(-2);
};
return util.format('%d-%s-%s', now.getFullYear(), pad(now.getMonth() + 1), pad(now.getDate()));
};
var printSection = function(stream, title, section, printCommitLinks) {
printCommitLinks = printCommitLinks === undefined ? true : printCommitLinks;
var components = Object.getOwnPropertyNames(section).sort();
if (!components.length) return;
stream.write(util.format('\n## %s\n\n', title));
components.forEach(function(name) {
var prefix = '-';
var nested = section[name].length > 1;
if (name !== EMPTY_COMPONENT) {
if (nested) {
stream.write(util.format('- **%s:**\n', name));
prefix = ' -';
} else {
prefix = util.format('- **%s:**', name);
}
}
section[name].forEach(function(commit) {
if (printCommitLinks) {
stream.write(util.format('%s %s\n (%s', prefix, commit.subject, linkToCommit(commit.hash)));
if (commit.closes.length) {
stream.write(',\n ' + commit.closes.map(linkToIssue).join(', '));
}
stream.write(')\n');
} else {
stream.write(util.format('%s %s\n', prefix, commit.subject));
}
});
});
stream.write('\n');
};
var readGitLog = function(grep, from) {
var deferred = q.defer();
// TODO(vojta): if it's slow, use spawn and stream it instead
child.exec(util.format(GIT_LOG_CMD, grep, '%H%n%s%n%b%n==END==', from), function(code, stdout, stderr) {
var commits = [];
stdout.split('\n==END==\n').forEach(function(rawCommit) {
var commit = parseRawCommit(rawCommit);
if (commit) commits.push(commit);
});
deferred.resolve(commits);
});
return deferred.promise;
};
var writeChangelog = function(stream, commits, version) {
var sections = {
fix: {},
feat: {},
perf: {},
breaks: {}
};
commits.forEach(function(commit) {
var section = sections[commit.type];
var component = commit.component || EMPTY_COMPONENT;
if (section) {
section[component] = section[component] || [];
section[component].push(commit);
}
if (commit.breaking) {
sections.breaks[component] = sections.breaks[component] || [];
sections.breaks[component].push({
subject: util.format('due to %s,\n %s', linkToCommit(commit.hash), commit.breaking),
hash: commit.hash,
closes: []
});
}
});
stream.write(util.format(HEADER_TPL, version, version, currentDate()));
printSection(stream, 'Bug Fixes', sections.fix);
printSection(stream, 'Features', sections.feat);
printSection(stream, 'Performance Improvements', sections.perf);
printSection(stream, 'Breaking Changes', sections.breaks, false);
};
var getPreviousTag = function() {
var deferred = q.defer();
child.exec(GIT_TAG_CMD, function(code, stdout, stderr) {
if (code) deferred.reject('Cannot get the previous tag.');
else deferred.resolve(stdout.replace('\n', ''));
});
return deferred.promise;
};
var generate = function(version, file) {
getPreviousTag().then(function(tag) {
console.log('Reading git log since', tag);
readGitLog('^fix|^feat|^perf|BREAKING', tag).then(function(commits) {
console.log('Parsed', commits.length, 'commits');
console.log('Generating changelog to', file || 'stdout', '(', version, ')');
writeChangelog(file ? fs.createWriteStream(file) : process.stdout, commits, version);
});
});
};
// publish for testing
exports.parseRawCommit = parseRawCommit;
exports.printSection = printSection;
// hacky start if not run by jasmine :-D
if (process.argv.join('').indexOf('jasmine-node') === -1) {
generate(process.argv[2], process.argv[3]);
}
-108
View File
@@ -1,108 +0,0 @@
/* global describe: false, beforeEach: false, afterEach: false, it: false, expect: false */
'use strict';
describe('changelog.js', function() {
var ch = require('./changelog');
describe('parseRawCommit', function() {
it('should parse raw commit', function() {
var msg = ch.parseRawCommit(
'9b1aff905b638aa274a5fc8f88662df446d374bd\n' +
'feat(scope): broadcast $destroy event on scope destruction\n' +
'perf testing shows that in chrome this change adds 5-15% overhead\n' +
'when destroying 10k nested scopes where each scope has a $destroy listener\n');
expect(msg.type).toBe('feat');
expect(msg.hash).toBe('9b1aff905b638aa274a5fc8f88662df446d374bd');
expect(msg.subject).toBe('broadcast $destroy event on scope destruction');
expect(msg.body).toBe('perf testing shows that in chrome this change adds 5-15% overhead\n' +
'when destroying 10k nested scopes where each scope has a $destroy listener\n');
expect(msg.component).toBe('scope');
});
it('should parse closed issues', function() {
var msg = ch.parseRawCommit(
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
'feat(ng-list): Allow custom separator\n' +
'bla bla bla\n\n' +
'Closes #123\nCloses #25\n');
expect(msg.closes).toEqual([123, 25]);
});
it('should parse breaking changes', function() {
var msg = ch.parseRawCommit(
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
'feat(ng-list): Allow custom separator\n' +
'bla bla bla\n\n' +
'BREAKING CHANGE: first breaking change\nsomething else\n' +
'another line with more info\n');
expect(msg.breaking).toEqual(' first breaking change\nsomething else\nanother line with more info\n');
});
});
describe('printSection', function() {
var output;
var streamMock = {
write: function(str) {
output += str;
}
};
beforeEach(function() {
output = '';
});
it('should add a new line at the end of each breaking change list item ' +
'when there is 1 item per component', function() {
var title = 'test';
var printCommitLinks = false;
var section = {
module1: [{subject: 'breaking change 1'}],
module2: [{subject: 'breaking change 2'}]
};
var expectedOutput =
'\n## test\n\n' +
'- **module1:** breaking change 1\n' +
'- **module2:** breaking change 2\n' +
'\n';
ch.printSection(streamMock, title, section, printCommitLinks);
expect(output).toBe(expectedOutput);
});
it('should add a new line at the end of each breaking change list item ' +
'when there are multiple items per component', function() {
var title = 'test';
var printCommitLinks = false;
var section = {
module1: [
{subject: 'breaking change 1.1'},
{subject: 'breaking change 1.2'}
],
module2: [
{subject: 'breaking change 2.1'},
{subject: 'breaking change 2.2'}
]
};
var expectedOutput =
'\n## test\n\n' +
'- **module1:**\n' +
' - breaking change 1.1\n' +
' - breaking change 1.2\n' +
'- **module2:**\n' +
' - breaking change 2.1\n' +
' - breaking change 2.2\n' +
'\n';
ch.printSection(streamMock, title, section, printCommitLinks);
expect(output).toBe(expectedOutput);
});
});
});
+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;
}
+237 -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 {
@@ -650,6 +659,19 @@ ul.events > li {
.diagram {
margin-bottom: 10px;
margin-top: 30px;
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;
visibility: hidden;
}
}
@media only screen and (min-width: 769px) and (max-width: 991px) {
@@ -663,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;
@@ -734,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 {
@@ -751,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)) {
@@ -768,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 {
@@ -794,10 +816,10 @@ ul.events > li {
}
#wrapper {
padding-bottom:0px;
padding-bottom: 0px;
}
}
iframe[name="example-anchoringExample"] {
height:400px;
height: 400px;
}
-1
View File
@@ -6,7 +6,6 @@ angular.module('docsApp', [
'ngSanitize',
'ngAnimate',
'DocsController',
'versionsData',
'pagesData',
'navData',
'directives',
+13 -8
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 {
@@ -23,6 +21,11 @@ angular.module('DocsController', [])
$scope.$on('$includeContentLoaded', function() {
var pagePath = $scope.currentPage ? $scope.currentPage.path : $location.path();
$window._gaq.push(['_trackPageview', pagePath]);
$scope.loading = false;
});
$scope.$on('$includeContentError', function() {
$scope.loading = false;
});
$scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) {
@@ -31,6 +34,8 @@ angular.module('DocsController', [])
var currentPage = $scope.currentPage = NG_PAGES[path];
$scope.loading = true;
if (currentPage) {
$scope.partialPath = 'partials/' + path + '.html';
$scope.currentArea = NG_NAVIGATION[currentPage.area];
@@ -53,12 +58,12 @@ 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;
var INDEX_PATH = /^(\/|\/index[^\.]*.html)$/;
var INDEX_PATH = /^(\/|\/index[^.]*.html)$/;
if (!$location.path() || INDEX_PATH.test($location.path())) {
$location.path('/api').replace();
}
+1 -1
View File
@@ -3,7 +3,7 @@
angular.module('errors', ['ngSanitize'])
.filter('errorLink', ['$sanitize', function($sanitize) {
var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.;,\(\)\{\}<>]/g,
var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/g,
MAILTO_REGEXP = /^mailto:/,
STACK_TRACE_REGEXP = /:\d+:\d+$/;
+3 -3
View File
@@ -72,7 +72,7 @@ angular.module('search', [])
.controller('Error404SearchCtrl', ['$scope', '$location', 'docsSearch',
function($scope, $location, docsSearch) {
docsSearch($location.path().split(/[\/\.:]/).pop()).then(function(results) {
docsSearch($location.path().split(/[/.:]/).pop()).then(function(results) {
$scope.results = {};
angular.forEach(results, function(result) {
var area = $scope.results[result.area] || [];
@@ -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 -27
View File
@@ -1,33 +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];
// NaN will give false here
if (minor <= version.minor) {
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];
}
}
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) {
+8 -2
View File
@@ -6,7 +6,7 @@ var packagePath = __dirname;
var Package = require('dgeni').Package;
// Create and export a new Dgeni package called angularjs. This package depends upon
// the ngdoc, nunjucks, and examples packages defined in the dgeni-packages npm module.
// the ngdoc, nunjucks, and examples packages defined in the dgeni-packages node module.
module.exports = new Package('angularjs', [
require('dgeni-packages/ngdoc'),
require('dgeni-packages/nunjucks'),
@@ -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;
})
+2 -2
View File
@@ -34,7 +34,7 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
var areasToSearch;
// Keywords start with "ng:" or one of $, _ or a letter
var KEYWORD_REGEX = /^((ng:|[\$_a-z])[\w\-_]+)/;
var KEYWORD_REGEX = /^((ng:|[$_a-z])[\w\-_]+)/;
// Load up the keywords to ignore, if specified in the config
if (this.ignoreWordsFile) {
@@ -67,7 +67,7 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
function extractWords(text, words, keywordMap) {
var tokens = text.toLowerCase().split(/[\.\s,`'"#]+/mg);
var tokens = text.toLowerCase().split(/[.\s,`'"#]+/mg);
_.forEach(tokens, function(token) {
var match = token.match(KEYWORD_REGEX);
if (match) {
+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 the npm repository 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('yarn info angular versions --json', { silent: true }).stdout.split('\n')[0];
var allVersions = processAllVersionsResponse(JSON.parse(output).data);
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'
@@ -25,7 +25,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'
+1 -1
View File
@@ -4,7 +4,7 @@ var path = require('canonical-path');
/**
* dgService getVersion
* @description
* Find the current version of the bower component (or npm module)
* Find the current version of the bower component (or node module)
*/
module.exports = function getVersion(readFilesProcessor) {
var basePath = readFilesProcessor.basePath;
+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' + v.version + (v.isSnapshot ? ' (snapshot)' : '')) 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">
@@ -220,7 +214,7 @@
<p class="pull-right"><a back-to-top>Back to top</a></p>
<p>
Super-powered by Google ©2010-2016
Super-powered by Google ©2010-2017
( <a id="version"
ng-href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md#{{versionNumber}}"
ng-bind-template="v{{version}}" title="Changelog of this version of Angular JS">
@@ -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 %}
@@ -55,7 +51,7 @@
{% block examples %}
{%- if doc.examples %}
<h2 id="example">Example</h2>
<h2 id="example">Examples</h2>
{%- for example in doc.examples -%}
{$ example | marked $}
{%- endfor -%}
@@ -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 $}
@@ -18,7 +21,9 @@
</li>
<li>
<a href="https://www.npmjs.com/">NPM</a> e.g.
{% code %}npm install {$ doc.packageName $}@X.Y.Z{% endcode %}
{% code %}npm install --save {$ doc.packageName $}@X.Y.Z{% endcode %}
or
{% code %}yarn add {$ doc.packageName $}@X.Y.Z{% endcode %}
</li>
<li>
<a href="http://bower.io">Bower</a> e.g.
@@ -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,39 @@
{% 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 %}
{%- if method.examples %}
<h4 id="{$ doc.name $}.{$ method.name $}-examples">Examples</h4>
{%- for example in method.examples -%}
{$ example | marked $}
{%- endfor -%}
{% 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,18 @@
@ngdoc error
@name $compile:badrestrict
@fullName Invalid Directive Restrict
@description
This error occurs when the restrict property of a directive is not valid.
The directive restrict property must be a string including one of more of the following characters:
* E (element)
* A (attribute)
* C (class)
* M (comment)
For example:
```javascript
restrict: 'E'
restrict: 'EAC'
```
-71
View File
@@ -1,71 +0,0 @@
@ngdoc error
@name $compile:noident
@fullName Controller identifier is required.
@description
When using the `bindToController` feature of AngularJS, a directive is required
to have a Controller identifier, which is initialized in scope with the value of
the controller instance. This can be supplied using the "controllerAs" property
of the directive object, or alternatively by adding " as IDENTIFIER" to the controller
name.
For example, the following directives are valid:
```js
// OKAY, because controller is a string with an identifier component.
directive("okay", function() {
return {
bindToController: true,
controller: "myCtrl as $ctrl"
scope: {
text: "@text"
}
};
});
// OKAY, because the directive uses the controllerAs property to override
// the controller identifier.
directive("okay2", function() {
return {
bindToController: true,
controllerAs: "$ctrl",
controller: function() {
},
scope: {
text: "@text"
}
};
});
```
While the following are invalid:
```js
// BAD, because the controller property is a string with no identifier.
directive("bad", function() {
return {
bindToController: true,
controller: "noIdentCtrl",
scope: {
text: "@text"
}
};
});
// BAD because the controller is not a string (therefore has no identifier),
// and there is no controllerAs property.
directive("bad2", function() {
return {
bindToController: true,
controller: function noControllerAs() {
},
scope: {
text: "@text"
}
};
});
```
@@ -0,0 +1,23 @@
@ngdoc error
@name $controller:ctrlreg
@fullName A controller with this name is not registered.
@description
This error occurs when the {@link ng.$controller `$controller()`} service is called
with a string that does not match any of the registered controllers. The controller service may have
been invoked directly, or indirectly, for example through the {@link ng.ngController `ngController`} directive,
or inside a {@link angular.Module#component component} / {@link angular.Module#directive directive} /
{@link ngRoute.$routeProvider#when route} definition (when using a string for the controller property).
Third-party modules can also instantiate controllers with the {@link ng.$controller `$controller()`} service.
Causes for this error can be:
1. Your reference to the controller has a typo. For example, in
the {@link ng.ngController `ngController`} directive attribute, in a {@link angular.Module#component component}
definition's controller property, or in the call to {@link ng.$controller `$controller()`}.
2. You have not registered the controller (neither via {@link angular.Module#controller `Module.controller`}
nor {@link ng.$controllerProvider#register `$controllerProvider.register()`}.
3. You have a typo in the *registered* controller name.
Please consult the {@link ng.$controller $controller} service api docs to learn more.
+5 -2
View File
@@ -4,6 +4,9 @@
@description
Occurs when an expression is missing tokens at the end of the expression.
For example, forgetting a closing bracket in an expression will trigger this error.
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and fix the expression's syntax.
For example, forgetting to close a bracket or failing to properly escape quotes in an expression
will trigger this error.
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and
fix the expression's syntax.
+6 -3
View File
@@ -3,6 +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 truthy.
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.
+34 -13
View File
@@ -91,15 +91,27 @@ To configure the `$location` service, retrieve the
{@link ng.$locationProvider $locationProvider} and set the parameters as follows:
- **html5Mode(mode)**: {boolean|Object}<br />
`true` or `enabled:true` - see HTML5 mode<br />
`false` or `enabled:false` - see Hashbang mode<br />
`requireBase:true` - see Relative links<br />
default: `enabled:false`
- **html5Mode(mode)**: `{boolean|Object}`<br />
`false` or `{enabled: false}` (default) -
see [Hashbang mode](guide/$location#hashbang-mode-default-mode-)<br />
`true` or `{enabled: true}` -
see [HTML5 mode](guide/$location#html5-mode)<br />
`{..., requireBase: true/false}` (only affects HTML5 mode) -
see [Relative links](guide/$location#relative-links)<br />
`{..., rewriteLinks: true/false/'string'}` (only affects HTML5 mode) -
see [HTML link rewriting](guide/$location#html-link-rewriting)<br />
Default:
```j
{
enabled: false,
requireBase: true,
rewriteLinks: true
}
```
- **hashPrefix(prefix)**: {string}<br />
prefix used for Hashbang URLs (used in Hashbang mode or in legacy browser in Html5 mode)<br />
default: `""`
- **hashPrefix(prefix)**: `{string}`<br />
Prefix used for Hashbang URLs (used in Hashbang mode or in legacy browsers in HTML5 mode).<br />
Default: `''`
### Example configuration
```js
@@ -305,7 +317,7 @@ path and search. If the history API is not supported by a browser, `$location` s
URL. This frees you from having to worry about whether the browser viewing your app supports the
history API or not; the `$location` service makes this transparent to you.
### Html link rewriting
### HTML link rewriting
When you use HTML5 history API mode, you will not need special hashbang links. All you have to do
is specify regular URL links, such as: `<a href="/some?foo=bar">link</a>`
@@ -326,6 +338,18 @@ reload to the original link.
- Links starting with '/' that lead to a different base path<br>
Example: `<a href="/not-my-base/link">link</a>`
If `mode.rewriteLinks` is set to `false` in the `mode` configuration object passed to
`$locationProvider.html5Mode()`, the browser will perform a full page reload for every link.
`mode.rewriteLinks` can also be set to a string, which will enable link rewriting only on anchor
elements that have the given attribute.
For example, if `mode.rewriteLinks` is set to `'internal-link'`:
- `<a href="/some/path" internal-link>link</a>` will be rewritten
- `<a href="/some/path">link</a>` will perform a full page reload
Note that [attribute name normalization](guide/directive#normalization) does not apply here, so
`'internalLink'` will **not** match `'internal-link'`.
### Relative links
@@ -531,7 +555,7 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
</example>
####Browser in HTML5 Fallback mode (Hashbang mode)
#### Browser in HTML5 Fallback mode (Hashbang mode)
<example module="hashbang-mode" name="location-hashbang-mode">
<file name="index.html">
<div ng-controller="LocationController">
@@ -853,6 +877,3 @@ angular.module('locationExample', [])
# Related API
* {@link ng.$location `$location` API}
+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
}
}
}
});
```
+11 -12
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
@@ -149,8 +149,8 @@ You can see the complete application running below.
<h1 class="title">Component Router</h1>
<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>
<!-- Load up the router library - normally you might use npm/yarn and host it locally -->
<script src="https://unpkg.com/@angular/router@0.2.0/angular1/angular_1_router.js"></script>
</file>
<file name="app.js">
@@ -467,13 +467,12 @@ to display list and detail views of Heroes and Crises.
## Install the libraries
It is easier to use npm to install the **Component Router** module. For this guide we will also install
AngularJS itself via npm:
It is easier to use [Yarn](https://yarnpkg.com) or [npm](https://www.npmjs.com) to install the
**Component Router** module. For this guide we will also install AngularJS itself via Yarn:
```bash
npm init
npm install angular@1.5.x --save
npm install @angular/router@0.2.0 --save
yarn init
yarn add angular@1.5.x @angular/router@0.2.0
```
@@ -493,7 +492,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
@@ -749,7 +748,7 @@ The **Lifecycle Hooks** that can be implemented as instance methods on the **Com
* `$routerCanReuse` : called to to determine whether a **Component** can be reused across **Route Definitions**
that match the same type of **Component**, or whether to destroy and instantiate a new **Component** every time.
* `$routerOnActivate` / `$routeOnReuse` : called by the **Router** at the end of a successful navigation. Only
* `$routerOnActivate` / `$routerOnReuse` : called by the **Router** at the end of a successful navigation. Only
one of `$routerOnActivate` and `$routerOnReuse` will be called depending upon the result of a call to
`$routerCanReuse`.
* `$routerCanDeactivate` : called by the **Router** to determine if a **Component** can be removed as part of a
@@ -929,7 +928,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"
+1 -2
View File
@@ -19,8 +19,7 @@ Advantages of Components:
When not to use Components:
- for directives that rely on DOM manipulation, adding event listeners etc, because the compile
and link functions are unavailable
- for directives that need to perform actions in compile and pre-link functions, because they aren't available
- when you need advanced directive definition options like priority, terminal, multi-element
- when you want a directive that is triggered by an attribute or CSS class, rather than an element
+1 -1
View File
@@ -155,7 +155,7 @@ More accurately, the file specifies a constructor function that will be used to
controller instance. The purpose of controllers is to expose variables and functionality to
expressions and directives.
Besides the new file that contains the controller code we also added an
Besides the new file that contains the controller code, we also added an
{@link ng.directive:ngController `ng-controller`} directive to the HTML.
This directive tells Angular that the new `InvoiceController` is responsible for the element with the directive
and all of the element's children.
+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.
+9 -10
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>
@@ -70,7 +71,7 @@ Angular **normalizes** an element's tag and attribute name to determine which el
directives. We typically refer to directives by their case-sensitive
[camelCase](http://en.wikipedia.org/wiki/CamelCase) **normalized** name (e.g. `ngModel`).
However, since HTML is case-insensitive, we refer to directives in the DOM by lower-case
forms, typically using [dash-delimited](http://en.wikipedia.org/wiki/Letter_case#Computers)
forms, typically using [dash-delimited](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles)
attributes on DOM elements (e.g. `ng-model`).
The **normalization** process is as follows:
@@ -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">
+4 -4
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
@@ -138,10 +138,10 @@ You can find a larger list of Angular external libraries at [ngmodules.org](http
[CodeSchool](https://www.codeschool.com/courses/shaping-up-with-angular-js)
* **Paid online:**
[The Angular Course (115 videos that show you how to build a full app)](http://watchandcode.com/courses/angular-course/),
[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)
[WintellectNOW (4 lessons)](http://www.wintellectnow.com/Course/Detail/mastering-angularjs),
[Packt](https://www.packtpub.com/web-development/angularjs-maintaining-web-applications)
* **Paid onsite:**
[angularbootcamp.com](http://angularbootcamp.com/)
+3 -2
View File
@@ -109,8 +109,9 @@ as the first argument. Any filter arguments are passed in as additional argument
function.
The filter function should be a [pure function](http://en.wikipedia.org/wiki/Pure_function), which
means that it should be stateless and idempotent, and not rely for example on other Angular services.
Angular relies on this contract and will by default execute a filter only when the inputs to the function change.
means that it should always return the same result given the same input arguments and should not affect
external state, for example, other Angular services. Angular relies on this contract and will by default
execute a filter only when the inputs to the function change.
{@link guide/filter#stateful-filters Stateful filters} are possible, but less performant.
<div class="alert alert-warning">
+33 -24
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 />
Best Editor: <label><input type="radio" ng-model="user.preference" value="vi" />vi</label>
<label><input type="radio" ng-model="user.preference" value="emacs" />emacs</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>
@@ -356,7 +363,7 @@ In the following example we create two directives:
<file name="script.js">
var app = angular.module('form-example1', []);
var INTEGER_REGEXP = /^\-?\d+$/;
var INTEGER_REGEXP = /^-?\d+$/;
app.directive('integer', function() {
return {
require: 'ngModel',
@@ -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
@@ -111,13 +111,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
+7 -3
View File
@@ -33,7 +33,7 @@ which drives many of these changes.
## Migrating from 1.4 to 1.5
Angular 1.5 takes a big step towards preparing developers for a smoother transition to Angular 2 in
the future. Architecturing your applications using components, multi-slot transclusion, one-way
the future. Architecting your applications using components, multi-slot transclusion, one-way
bindings in isolate scopes, using lifecycle hooks in directive controllers and relying on native ES6
features (such as classes and arrow functions) are now all possible with Angular 1.5.
@@ -605,7 +605,7 @@ The new API on `$cookies` is as follows:
* `getAll`
* `remove`
You must explictly use the methods above in order to access cookie data. This also means that
You must explicitly use the methods above in order to access cookie data. This also means that
you can no longer watch the properties on `$cookies` to detect changes
that occur on the browsers cookies.
@@ -1126,6 +1126,11 @@ app. This is no longer possible within a single module.
### Filters (`orderBy`)
- due to [a097aa95](https://github.com/angular/angular.js/commit/a097aa95b7c78beab6d1b7d521c25f7d9d7843d9),
`orderBy` now treats `null` values (which in JavaScript have type `object`) as having a string
representation of `'null'`.
### Animation (`ngAnimate`)
@@ -1229,7 +1234,6 @@ or simply use:
## Migrating from 1.0 to 1.2
+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.
+2 -2
View File
@@ -221,8 +221,8 @@ it('should clear messages after alert', function() {
notify('two');
notify('third');
expect(mock.alert.callCount).toEqual(2);
expect(mock.alert.mostRecentCall.args).toEqual(["more\ntwo\nthird"]);
expect(mock.alert.calls.count()).toEqual(2);
expect(mock.alert.calls.mostRecent().args).toEqual(["more\ntwo\nthird"]);
});
```
+1 -1
View File
@@ -26,7 +26,7 @@ curly-brace {@link expression expression} bindings:
<!-- Body tag augmented with ngController directive -->
<body ng-controller="MyController">
<input ng-model="foo" value="bar">
<!-- Button tag with ng-click directive, and
<!-- Button tag with ngClick directive, and
string expression 'buttonText'
wrapped in "{{ }}" markup -->
<button ng-click="changeFoo()">{{buttonText}}</button>
+2 -2
View File
@@ -59,7 +59,7 @@ Karma to run against a number of browsers, which is useful for being confident t
works on all browsers you need to support. Karma is executed on the command line and will display
the results of your tests on the command line once they have run in the browser.
Karma is a NodeJS application, and should be installed through npm. Full installation instructions
Karma is a NodeJS application, and should be installed through npm/yarn. Full installation instructions
are available on [the Karma website](http://karma-runner.github.io/0.12/intro/installation.html).
### Jasmine
@@ -461,7 +461,7 @@ describe("Deep Thought", function() {
}));
it("has calculated the answer correctly", inject(function(DeepThought) {
// Because of sharedInjector, we have access to the instance of the DeepThought service
// Because of sharedInjector, we have access to the instance of the DeepThought service
// that was provided to the beforeAll() hook. Therefore we can test the generated answer
expect(DeepThought.answer).toBe(42);
}));
+21 -17
View File
@@ -5,7 +5,7 @@
# Building and Testing AngularJS
This document describes how to set up your development environment to build and test AngularJS, and
explains the basic mechanics of using `git`, `node`, `npm`, `grunt`, and `bower`.
explains the basic mechanics of using `git`, `node`, `yarn`, `grunt`, and `bower`.
See the [contributing guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md)
for how to contribute your own code to AngularJS.
@@ -24,20 +24,27 @@ Before you can build AngularJS, you must install and configure the following dep
machine:
* [Git](http://git-scm.com/): The [Github Guide to
Installing Git](https://help.github.com/articles/set-up-git) is a good source of information.
Installing Git](https://help.github.com/articles/set-up-git) is a good source of information.
* [Node.js v4.x](http://nodejs.org): We use Node to generate the documentation, run a
development web server, run tests, and generate distributable files. Depending on your system, you can install Node either from source or as a
pre-packaged bundle. (Currently our build does not work properly on Node v5 or greater - please use v4.x.)
* [Node.js v6.x (LTS)](http://nodejs.org): We use Node to generate the documentation, run a
development web server, run tests, and generate distributable files. Depending on your system,
you can install Node either from source or as a pre-packaged bundle.
We recommend using [nvm](https://github.com/creationix/nvm) (or [nvm-windows](https://github.com/coreybutler/nvm-windows))
to manage and install Node.js, which makes it easy to change the version of Node.js per project.
* [Yarn](https://yarnpkg.com): We use Yarn to install our Node.js module dependencies (rather than using npm).
There are detailed installation instructions available at https://yarnpkg.com/en/docs/install.
* [Java](http://www.java.com): We minify JavaScript using our
[Closure Tools](https://developers.google.com/closure/) jar. Make sure you have Java (version 7 or higher) installed
and included in your [PATH](http://docs.oracle.com/javase/tutorial/essential/environment/paths.html) variable.
[Closure Tools](https://developers.google.com/closure/) jar. Make sure you have Java (version 7 or higher)
installed and included in your [PATH](http://docs.oracle.com/javase/tutorial/essential/environment/paths.html)
variable.
* [Grunt](http://gruntjs.com): We use Grunt as our build system. Install the grunt command-line tool globally with:
```shell
npm install -g grunt-cli
yarn global add grunt-cli
```
## Forking Angular on Github
@@ -62,12 +69,9 @@ cd angular.js
git remote add upstream "https://github.com/angular/angular.js.git"
# Install node.js dependencies:
npm install
yarn install
# Install bower components:
bower install
# Build AngularJS:
# Build AngularJS (which will install `bower` dependencies automatically):
grunt package
```
@@ -78,11 +82,11 @@ Administrator). This is because `grunt package` creates some symbolic links.
</div>
<div class="alert alert-warning">
**Note:** If you're using Linux, and npm install fails with the message
'Please try running this command again as root/Administrator.', you may need to globally install grunt and bower:
**Note:** If you're using Linux, and `yarn install` fails with the message
'Please try running this command again as root/Administrator.', you may need to globally install `grunt` and `bower`:
<ul>
<li>sudo npm install -g grunt-cli</li>
<li>sudo npm install -g bower</li>
<li>sudo yarn global add grunt-cli</li>
<li>sudo yarn global add bower</li>
</ul>
</div>
+3 -1
View File
@@ -77,6 +77,8 @@ AngularJS was designed to be compatible with other security measures like Conten
(CSP), HTTPS (SSL/TLS) and server-side authentication and authorization that greatly reduce the
possible attack vectors and we highly recommend their use.
Please read {@link security} for more detailed information about securing Angular apps.
### Can I download the source, build, and host the AngularJS environment locally?
@@ -247,7 +249,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
@@ -304,7 +304,7 @@ In that case, you can delete the `node_modules/` directory and run `npm install`
<br />
**Protractor dependencies**
Under the hood, Protractor uses the [Selenium Stadalone Server][selenium], which in turn requires
Under the hood, Protractor uses the [Selenium Standalone Server][selenium], which in turn requires
the [Java Development Kit (JDK)][jdk] to be installed on your local machine. Check this by running
`java -version` from the command line.
+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
+4 -2
View File
@@ -68,8 +68,9 @@ To create a component, we use the {@link angular.Module#component .component()}
{@link module Angular module}. We must provide the name of the component and the Component
Definition Object (CDO for short).
Remember that (since components are also directives) the name of the component is in `camelCase`,
but we will use `kebab-case`, when referring to it in our HTML.
Remember that (since components are also directives) the name of the component is in `camelCase`
(e.g. `myAwesomeComponent`), but we will use `kebab-case` (e.g. `my-awesome-component`) when
referring to it in our HTML. (See [here][case-styles] for a description of different case styles.)
In its simplest form, the CDO will just contain a template and a controller. (We can actually omit
the controller and Angular will create a dummy controller for us. This is useful for simple
@@ -276,6 +277,7 @@ files, so it remains easy to locate as our application grows.
<ul doc-tutorial-nav="3"></ul>
[case-styles]: https://en.wikipedia.org/wiki/Letter_case#Special_case_styles
[jasmine-docs]: http://jasmine.github.io/2.4/introduction.html
[jasmine-home]: http://jasmine.github.io/
[karma]: https://karma-runner.github.io/

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