Compare commits
181 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ecbb53d28 | |||
| 25b758842a | |||
| 8f2d05f370 | |||
| 56719ec4ac | |||
| 7d8ca1bf51 | |||
| 56bfad1d0e | |||
| 424f4b8a13 | |||
| f73a651461 | |||
| d65636988b | |||
| e75fbc494e | |||
| 5e28b6ea8c | |||
| 586ec15398 | |||
| 8541d25ded | |||
| a580f8132b | |||
| 41aa9125b9 | |||
| b4581e3e99 | |||
| bdb5bc82a3 | |||
| 1cf93fd2b0 | |||
| 4f3858e7c3 | |||
| 4993728819 | |||
| 6933cf64fe | |||
| 32e656b769 | |||
| 11fbc17f65 | |||
| 02f045be8d | |||
| 71083a4455 | |||
| 700aafe3ab | |||
| 2b6bfc36ae | |||
| 31716eec4d | |||
| f670c451f4 | |||
| 6d0ff9fb7f | |||
| e3d02070ab | |||
| a9708de84b | |||
| 77ed85bcd3 | |||
| 0ddbcafd9e | |||
| 536da55705 | |||
| bdeb3392a8 | |||
| 7f45b5fee7 | |||
| a3cd7d8011 | |||
| 3a767a9943 | |||
| 1d29c91c34 | |||
| 0e666eb0b9 | |||
| b748046c04 | |||
| 3ecaccf719 | |||
| 250fcecae1 | |||
| 0b81a26045 | |||
| 3205e1c08c | |||
| dcb5d32055 | |||
| d69a64047b | |||
| ebd841165d | |||
| f62079d452 | |||
| ad6ac68509 | |||
| 03ff634598 | |||
| bf1e3e0eac | |||
| 0f001786d8 | |||
| 97eca91927 | |||
| 3821e8a951 | |||
| 1f61f30799 | |||
| c57779d872 | |||
| 404046081d | |||
| 5b7ec8c84e | |||
| 24471cf992 | |||
| 8d644bd066 | |||
| 78eecb43db | |||
| 2791a855a6 | |||
| bbe8ad5698 | |||
| 5041cf1f32 | |||
| d1bbc2562d | |||
| e19ad74ea4 | |||
| 7586fa2b86 | |||
| 70fa4d308a | |||
| 75c83ff319 | |||
| e36dbab396 | |||
| 4836278830 | |||
| 3a8cc38b69 | |||
| a41efb2025 | |||
| b8ce60ac4a | |||
| 5386fe4316 | |||
| 82f85eda11 | |||
| 5b0e4cae49 | |||
| 8c77aeb9b1 | |||
| f9354dc099 | |||
| 7648811a94 | |||
| e1c683be52 | |||
| cd298d6272 | |||
| 1cfb04d5c2 | |||
| 6c8450206e | |||
| e269ad1244 | |||
| 551983e7e1 | |||
| 87625a4581 | |||
| bcc44f13e5 | |||
| 1b6a1c30ee | |||
| a29fceadcd | |||
| 7b997ffa13 | |||
| 89f2be1c10 | |||
| 600509bb67 | |||
| 9aae7e8bb6 | |||
| 163f08ce86 | |||
| f3cb6e309a | |||
| 0abf65b353 | |||
| 136e65cc04 | |||
| 593a503484 | |||
| 48dfeb2006 | |||
| ffa46b95b9 | |||
| fddc534a13 | |||
| 4bf8921813 | |||
| ee2e36d810 | |||
| 87a31177b6 | |||
| 95fa35afc4 | |||
| dd0449c06f | |||
| e900f457fb | |||
| b655744676 | |||
| 748fee4ee7 | |||
| 8e480d8d0c | |||
| 4513dafd1a | |||
| 9bc4ee89c8 | |||
| b1c9075bcf | |||
| 44d70b384f | |||
| 6de412311a | |||
| 49dce2ea4b | |||
| 3ab1c3610b | |||
| 7717b96e95 | |||
| cc54e433c2 | |||
| 73ed7ef957 | |||
| 2316ad7be9 | |||
| e73dc0f31b | |||
| 9efe8426e5 | |||
| feede20a3b | |||
| b4735fdcbd | |||
| ed8aa16d30 | |||
| a5264090b6 | |||
| 609264f8b0 | |||
| f159e61893 | |||
| 2875d9f6b0 | |||
| 5a4e4e928e | |||
| eea9c597ac | |||
| 6aeb442db4 | |||
| 22979904fb | |||
| 6c0fd3e26f | |||
| db39512236 | |||
| 57ef6a9237 | |||
| 024bc1e160 | |||
| 7e7b5151db | |||
| 530395059f | |||
| 9ea1e440ea | |||
| 9b9f14e52e | |||
| b11a513429 | |||
| a419ff03d4 | |||
| 9449893763 | |||
| 07e1ba365f | |||
| 287a5dd4bd | |||
| 12752f66ac | |||
| fbdfd193f7 | |||
| 05896d44ad | |||
| 00b01e09ca | |||
| afc093b8b7 | |||
| fcffa181ce | |||
| e105dda1de | |||
| 0e1651bfd2 | |||
| af4a44cbaf | |||
| ed89fc8ee6 | |||
| 6a7a3250cf | |||
| 8455d2a797 | |||
| 862dc2532f | |||
| 7d11bc4f91 | |||
| 006e05074a | |||
| 1ea884ae7e | |||
| c82bb89964 | |||
| bb7f4a8733 | |||
| 0cf5be5264 | |||
| 584a6b39e4 | |||
| f86576def4 | |||
| 609e807b04 | |||
| 31d464feef | |||
| 5c9399d18a | |||
| a8da25c74d | |||
| 6bb775ccd1 | |||
| a4a22266f1 | |||
| 401da6873a | |||
| 311b5faf08 | |||
| 6cd911c132 | |||
| 9ae793d8a6 |
@@ -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>
|
||||
+5
-12
@@ -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
@@ -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
@@ -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
@@ -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,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
|
||||
|
||||
@@ -2,7 +2,7 @@ AngularJS [ as your template language and lets you extend HTML’s
|
||||
use good old HTML (or HAML, Jade/Pug and friends!) as your template language and lets you extend HTML’s
|
||||
syntax to express your application’s 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 AngularJS’s 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 AngularJS’s 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
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
+1
-1
@@ -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
@@ -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]);
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ angular.module('docsApp', [
|
||||
'ngSanitize',
|
||||
'ngAnimate',
|
||||
'DocsController',
|
||||
'versionsData',
|
||||
'pagesData',
|
||||
'navData',
|
||||
'directives',
|
||||
|
||||
+13
-8
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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+$/;
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
};
|
||||
}]);
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
})
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
@@ -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'
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}, '');
|
||||
}
|
||||
@@ -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 $});
|
||||
+2
-8
@@ -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 $}
|
||||
+5
-9
@@ -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 %}
|
||||
+6
-1
@@ -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"> </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'
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -253,10 +253,10 @@ scopes being created for our view:
|
||||
|
||||
- The root scope
|
||||
- The `MainController` scope, which contains `timeOfDay` and `name` properties
|
||||
- The `ChildController` scope, which inherits the `timeOfDay` property but overrides (hides) the `name`
|
||||
property from the previous
|
||||
- The `GrandChildController` scope, which overrides (hides) both the `timeOfDay` property defined in `MainController`
|
||||
and the `name` property defined in `ChildController`
|
||||
- The `ChildController` scope, which inherits the `timeOfDay` property but overrides (shadows) the
|
||||
`name` property from the previous scope
|
||||
- The `GrandChildController` scope, which overrides (shadows) both the `timeOfDay` property defined
|
||||
in `MainController` and the `name` property defined in `ChildController`
|
||||
|
||||
Inheritance works with methods in the same way as it does with properties. So in our previous
|
||||
examples, all of the properties could be replaced with methods that return string values.
|
||||
|
||||
@@ -8,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">
|
||||
|
||||
@@ -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/)
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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"]);
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}));
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user