Compare commits

...

547 Commits

Author SHA1 Message Date
Georgios Kalpakas 70724e3918 test($log): fix up to work with IE8 2016-12-07 15:18:07 +02:00
Peter Bacon Darwin 9a0156d258 test($log): fix up to work with Safari 9
On Safari 9.0.2, you are not allowed to write to `sourceUrl` or `line`
on a native Error object.

This commit uses a custom error instead.
2016-12-07 14:39:42 +02:00
Peter Bacon Darwin 5730c665e8 docs(CHANGELOG): add 1.2.32 release notes 2016-10-11 22:49:02 +01:00
Peter Bacon Darwin b8a0ecdd61 fix($compile): ensure that hidden input values are correct after history.back
Due to the nature of some browser's PageCache/BFCache, returning to an Angular
app sometimes causes `input[hidden]` elements to retain the last value
that was stored before the page was navigated away from previously.

This is particularly problematic if the input has an interpolated value.
E.g. `<input type="hidden" value="{{ 1 + 2 }}">` since when the browser
returns, instead of the original interpolation template, the HTML contains
the previous value `<input type="hidden" value="3">`.

This commit instructs the browser not to attempt to reinstate the previous
value when navigating back in history by setting `autocomplete="off"` on
the hidden input element element.
2016-10-11 13:48:38 +01:00
Peter Bacon Darwin ed44dd0659 revert:fix(input): ensure that hidden input values are correct after history.back
This reverts commit 7ec663fc70.
There was a regression against angular-material that relied upon the input directive.
2016-10-11 13:39:13 +01:00
Peter Bacon Darwin a5f4d32d01 chore(bower): fix up URL to closure compiler 2016-10-11 07:48:26 +01:00
Peter Bacon Darwin e4fcf9244b docs(CHANGELOG): update with 1.2.30 and 1.2.31 changes 2016-10-10 23:05:24 +01:00
Peter Bacon Darwin 7ec663fc70 fix(input): ensure that hidden input values are correct after history.back
Due to the nature of some browser's PageCache/BFCache, returning to an Angular
app sometimes causes `input[hidden]` elements to retain the last value
that was stored before the page was navigated away from previously.

This is particularly problematic if the input has an interpolated value.
E.g. `<input type="hidden" value="{{ 1 + 2 }}">` since when the browser
returns, instead of the original interpolation template, the HTML contains
the previous value `<input type="hidden" value="3">`.

This commit instructs the browser not to attempt to reinstate the previous
value when navigating back in history by setting `autocomplete="off"` on
the hidden input element element.
2016-10-10 23:01:20 +01:00
Georgios Kalpakas 2687c26140 fix($compile): detect <a> elements inside <svg> 2016-07-20 23:17:37 +03:00
Igor Minar f2fa1ed83d fix($compile): properly sanitize xlink:href attribute interoplation
Closes #12524
2016-07-20 19:14:51 +03:00
Raphael Jamet f35f334bd3 fix($compile): secure link[href] as a RESOURCE_URLs in $sce.
User-controlled imports or stylesheets can run script in your origin,
which warrants that we require that they are safe `RESOURCE_URL`s.

Closes #14687

BREAKING CHANGE

`link[href]` attributes are now protected via `$sce`, which prevents interpolated
values that fail the `RESOURCE_URL` context tests from being used in interpolation.

For example if the application is running at `https://docs.angularjs.org` then the
following will fail:

```
<link href="{{ 'http://mydomain.org/unsafe.css' }}" rel="stylesheet">
```

By default, `RESOURCE_URL` safe URLs are only allowed from the same domain and protocol
as the application document.

To use URLs from other domains and/or protocols, you may either whitelist them or
wrap it into a trusted value by calling `$sce.trustAsResourceUrl(url)`.
2016-07-20 19:09:47 +03:00
Georgios Kalpakas dd4ce50392 chore(ci): update Safari to v8 2016-07-13 14:14:12 +03:00
Georgios Kalpakas ac0d5286b8 fix($sanitize): blacklist the attribute usemap as it can be used as a security exploit
Backport of 234053f.

Closes #14903

BREAKING CHANGE:

The `$sanitize` service will now remove instances of the `usemap` attribute from any elements passed
to it.

This attribute is used to reference another element by `name` or `id`. Since the `name` and `id`
attributes are already blacklisted, a sanitized `usemap` attribute could only reference unsanitized
content, which is a security risk.
2016-07-13 14:13:27 +03:00
Matias Niemelä 8d83b56334 fix(ngAnimate): do not use event.timeStamp anymore for time tracking
Due to recent changes in Chrome, Firefox and Webkit use of the
event.timeStamp value will lead to unpredictable behaviour due to
precision changes. Therefore it's best to stick entirely to use
`Date.now()` when it comes to confirming the end of transition-
ending values. See #13494 for more info.

Applies to 1.2, 1.3, 1.4 and 1.5.

Closes #13494
Closes #13495
2016-01-05 13:09:20 +00:00
Peter Bacon Darwin b31234e3b1 chore(Gruntfile): replace double quotes with single quotes 2015-12-17 23:00:56 +00:00
Peter Bacon Darwin ffee742a78 chore(GruntFile): fix whitespace in lists 2015-12-17 23:00:56 +00:00
Peter Bacon Darwin 1346b0a562 chore(GruntFile): move validate-angular-files task into its own file
Closes #13569
2015-12-17 23:00:46 +00:00
Matias Niemelä 5fec3da64d chore(build): add a validation step for angularFiles
Closes #13553
2015-12-17 22:59:42 +00:00
Peter Bacon Darwin d662a17e57 chore(angularFiles): add documentation only file to list of files
This prevents errors when checking `validate-angular-files`
2015-12-17 22:40:54 +00:00
Peter Bacon Darwin 07f3ba5d66 chore(npm-shrinkwrap): install glob package 2015-12-17 22:40:51 +00:00
Peter Bacon Darwin eacd9ad853 chore(jenkins): remove unused argument definition 2015-12-17 14:15:43 +00:00
Peter Bacon Darwin 84dc5edd65 chore(jenkins): run Jenkins builds on Node 4 (via nvm)
Closes #13568
2015-12-17 14:12:22 +00:00
Peter Bacon Darwin de8e1121cf chore(jenkins): move jenkins_build.sh to scripts/jenkins/build.sh 2015-12-16 14:23:15 +00:00
Peter Bacon Darwin fb8f1ddd58 chore(travis): update to use node 4.x 2015-12-16 11:17:45 +00:00
Martin Staffa 34e5623542 chore(travis): add a new job that runs ci-checks
Previously, ddescribe, merge-conflicts, jshint, and jscs would run
after unit & e2e tests ran. The order was orginally changed as part of
https://github.com/angular/angular.js/pull/9792.

While the logic is sound that style errors shouldn't block tests from
running, ddescribe should always run. This was not guaraneteed; when
Travis exits with a warning after some browsers have run, ddescribe
doesn't get run and it doesn't become apparent that not
all tests have run.

Additionally, a separate job clearly separates style from test errors,
which e.g. means you can open a PR that includes an iit to speed up
the job, and see immediately if the test passes, because the ddescribe
error is in another job.
2015-12-16 10:30:28 +00:00
Matias Niemelä c95f8677e1 chore(CHANGELOG): update with changes for 1.2.29 2015-09-29 13:18:52 -07:00
Igor Minar 788885c611 build(travis): make sauce connect process query a bit more specific 2015-09-23 14:02:01 -07:00
Igor Minar d58c3778b6 build(travis): fix typo in a comment 2015-09-23 11:00:31 -07:00
Igor Minar b7eaa956e4 build(travis): gracefully shut down the sauce connect tunnel after the tests are done running
This is to prevent sauce connect tunnel leaks.

Closes #12921
2015-09-23 09:40:57 -07:00
Lucas Mirelmann 3d7846bdab style(test): fix style in one test 2015-09-20 21:34:27 +02:00
Lucas Mirelmann c4817cdca4 test($parse): fix test for IE 2015-09-20 19:59:16 +02:00
Lucas Mirelmann afb65c11e5 fix($parse): do not convert to string computed properties multiple times
Do not convert to string properties multiple times.
2015-09-20 13:48:21 +02:00
Peter Bacon Darwin 9d5ac2eb84 chore(travis): upgrade CI builds to latest 2015-09-17 12:17:08 +01:00
Peter Bacon Darwin 19bb53d929 test(privateMocks): fix for the latest version of Safari 2015-09-17 12:16:39 +01:00
Peter Bacon Darwin a4c5fc0a8f chore(bower/publish): move DIST_TAG so that it gets the correct value
In the position that DIST_TAG was being assigned it was trying to get the
`distTag` value from the wrong (i.e. a bower-...) repository.
2015-09-16 23:13:26 +01:00
Peter Bacon Darwin b94a47b1b5 chore(scripts/publish): get dist-tag from package.json
Closes #12722
2015-09-14 21:49:11 +01:00
Lucas Galfaso e6cbd4faa2 fix($parse): throw error when accessing a restricted property indirectly
When accessing an instance thru a computed member and the property is an array,
then also check the string value of the array.

Closes #12833
2015-09-14 21:46:15 +01:00
Scott Davidson fccce96d44 fix($compile): workaround for IE11 MutationObserver
Backport #11796 to 1.2 branch.
IE11 MutationObserver breaks consecutive text nodes into several text nodes.
This patch merges consecutive text nodes into a single node before looking for interpolations.
Also had to modify npm-shrinkwrap.json because i@0.3.2 was unpublished from npm.

Closes #11781
Closes #12613
2015-09-01 17:47:53 +02:00
Matias Niemelä b041b66475 fix(ngAnimate): ensure that minified repaint code isn't removed
Closes #9936
2015-03-31 14:02:40 -07:00
Peter Bacon Darwin 996c7a0904 chore(bower/publish): run local precommit script if available
Closes #11164
2015-02-24 17:23:22 +00:00
Thibault Leruitte e81b2f726c fix($location): strip off empty hash segments when comparing
Backported from e93710fe0e

The url is the same whether or not there is an empty `#` marker at the end.
This prevents unwanted calls to update the browser, since the browser is
automatically applying an empty hash if necessary to prevent page reloads.

Closes #9635
Closes #10748
2015-02-04 14:20:26 +00:00
Julie Ralph 14c50a12a3 chore(testing): bump protractor to version 1.6.0 2015-01-12 11:52:09 -08:00
Rus1 3cbf542af0 docs(ngInclude): replace <tt> with <code>
Using obsolete <tt> HTML tag may not be good for Angular examples

Closes #10594
2014-12-30 15:48:36 -05:00
David Souther d60fbcc8e6 test($exceptionHandlerProvider): call inject() to run tests
In the current angular-mocksSpec, the tests for $exceptionHandlerProvider
call `module` to run tests on `$exceptionHandlerProvider.mode()`, but do
not call `inject()` to pump the module definitions.

Closes #10563
2014-12-23 18:10:53 +00:00
gokulkrishh b19353580d docs(guide/*): spelling/grammar improvements
Closes #10552
2014-12-22 10:49:33 -05:00
Caitlin Potter 77131c0cf6 docs($rootScope): remove erroneous closing parenthesis
Closes #10549
2014-12-22 08:35:17 -05:00
Kevin Primat 643e7ea9aa docs(guide/location): add missing definite article
The sentence was missing a definite article so was unclear. Added one to clarify.

Closes #10547
2014-12-22 08:25:40 -05:00
Peter Bacon Darwin d232151664 refactor(limitTo): no need for all those checks if we use slice
Closes #10537
2014-12-21 14:39:42 +00:00
Peter Bacon Darwin 8d6c594a56 docs($httpBackend): correct grammar
Closes #10496
2014-12-21 10:40:40 +00:00
sandeep b79f583055 docs(guide/index): add book Responsive Web Design with AngularJS
This book explores the AngularJS features that can help a developer for building a responsive application.

Merçi beaucoup~

Closes #10513
2014-12-18 23:58:58 -05:00
Ben Nelson c5eb0b710c docs(api/index): grammar is important and so should you
I changed the word "into" to "within".
Original description underneath ngAnimate reads: "Use ngAnimate to enable animation features into your application".
I changed the text to read: "Use ngAnimate to enable animation features within your application".
The change in wording makes the description read better and gives it a more professional feel.

Closes #10517
2014-12-18 13:50:00 -05:00
Jeff Cross 97a91199ad test(browser): change mock location definition to use defineProperty
The original fix for which this mock location logic was written fixes
a bug in master which also exists in 1.2.x. Cherry-picking the fix
to the 1.2.x branch was difficult because the mock location object
used ES5 get/set syntax, which is not supported in IE8.

This fix changes the implementation to work with IE8 and modern
browsers.

IE8's defineProperty only works on certain types of objects, such as
DOM elements. So the mock location is a div element in this
implementation.
2014-12-17 01:53:07 -08:00
Peter Bacon Darwin 9845cee63e fix($browser): prevent infinite digests when clearing the hash of a url
By using `location.hash` to update the current browser location when only
the hash has changed, we prevent the browser from attempting to reload.

Closes #9629
Closes #9635
Closes #10228
Closes #10308
2014-12-16 22:28:37 -08:00
Jack Kingsman 5f52957503 docs(error/badcfg): add missing "but"
Sentence meaning was unclear; added what I assumed should have been a "but"

Closes #10473
2014-12-16 14:36:08 +00:00
marmalade bfafdd2b63 docs(guide/Scopes): fix capitalization
This sentence should begin with a capital 'R', not a lower case one.

Closes #10472
2014-12-16 14:36:07 +00:00
Peter Bacon Darwin 5bc09b6370 docs(guide/E2E Testing): add '-' to 'end-to-end'
Closes #10458
2014-12-16 14:35:53 +00:00
Zachary Lopez d8a95a9d02 docs(angular.identity): add @param and @returns tags
Closes #10457
2014-12-16 14:35:17 +00:00
Alexander Tseung 8802d5198a docs(tutorial/index): improve capitalization
Improve capitalization in acronyms for better clarity.
2014-12-16 14:34:02 +00:00
Peter Bacon Darwin f2c87672c5 docs(guide/expression): update diff list between JavaScript and Angular expressions
add paragraphs about function declaration, comma and void operators and
RegExp to the diff list in the beginning of articule

Closes #10418
Closes #10452
2014-12-16 14:33:40 +00:00
Peter Bacon Darwin efd0490d9c docs(CHANGELOG): remove reverted commit 2014-12-16 07:56:39 +00:00
Peter Bacon Darwin a0f8a4b257 chore(CHANGELOG): update with changes for 1.2.28 2014-12-15 21:41:40 +00:00
Wes 37310e024d docs(Courses): fix syntax issue in developer guide
The courses section should use commas between links to differentiate the instances of each link

Closes #10448
2014-12-13 21:28:02 -05:00
Caitlin Potter 306e626196 revert feat($compile): add support for ng-attr with camelCased attributes
This reverts commit a1e7eb6360.

This change broke the stable branch builds.

/CC @petebacondarwin / @wesleycho
2014-12-13 20:39:15 -05:00
Dan Tennery-Spalding f31c7492ec docs(API Reference): corrected two typos - two missing commas
In the ngAnimate section, there were two commas missing from two sentences. This is inconsistent with the grammar used in the rest of the API documentation and made the document (slightly) more difficult to read. The two sentences are shown below, with the new commas added:

1. "Once defined, the animation can be triggered"
                           ^
                    comma added

2. "Once registered, the animation can be triggered"
                              ^
                    comma added

Closes #10447
2014-12-13 20:20:40 -05:00
Wesley Cho a1e7eb6360 feat($compile): add support for ng-attr with camelCased attributes
SVG attributes are case sensitive and some have upper case letters in them
This change ensures that we can identify these, when being used with the `ng-attr`
directive, by encoding upper case letters with a preceding underscore.

For example to apply `ng-attr` to the `viewBox` attribute we could write
`ng-attr-view_box` - or any of the other variants: `ng:attr:view_box`,
`data-ng-attr-view_box`, etc.

Closes #9845
Closes #10194
2014-12-09 12:06:04 +00:00
Tobias Davis 169e5326d1 docs($interval): correcting example code indentation
Bueno!

Closes #10372
2014-12-08 16:30:05 -05:00
Georgios Kalpakas bb3b65374d chore(changelog): add test for addition of trailing newline
Adds tests for the functionality added by #9550.

Closes #10358
2014-12-08 13:05:32 -05:00
Giuseppe Caruso ac9336b35a docs(guide/controllers): Just a typo
Gingerbreak would break testing. :)

Oh my gosh he's right, it totally w/ould. That is so embarrassing!

Closes #10353
2014-12-08 10:51:05 -05:00
Ciro Nunes 75787446ee docs(compile): document $attrs.$normalize
Closes #10345
2014-12-05 14:19:46 -05:00
Caitlin Potter 14409d7a7f style(ngHref): make jscs happy ;-; 2014-11-28 22:29:05 -06:00
Sagar Ranglani 370676d4d0 docs(ngHref): fix poor paragraph construction
It was bad.

In order to improve the docs, the inclusion of the last sentence would help define `ngHref` well.

Closes #10254
2014-11-28 22:10:28 -06:00
Caitlin Potter 4c218de4d3 style(*): IE is a real browser, and chakra is pretty solid
- IE9+ do not have issues with Function.prototype.apply() on builtin fns (asked Brian Terlson)
  (NOTE: there may still be corner cases where builtins will not have `apply()` --- this may
  need to be reverted on complaint).
- HTMLScriptElement#text is an IDL-spec'd attribute, and we use it in all cases --- so the
  comment was sort of nonsense.
- The value of `msie` does not depend on whether the user is using a "real" browser or not.

Closes #10242
2014-11-26 14:39:23 -06:00
Lucas Galfaso 929dd15b9b fix(linky): encode double quotes when serializing email addresses
Email addresses can (under certain restrictions) include double quote
characters. See http://tools.ietf.org/html/rfc3696#section-3.

For example, `"Jo Bloggs"@abc.com` is a valid email address.

When serializing emails to the `href` attribute of an anchor element,
we must HTML encode these double quote characters. See
http://www.w3.org/TR/html-markup/syntax.html#syntax-attr-double-quoted

This commit does not attempt to improve the functionality (i.e. regex)
that attempts to identify email addresses in a general string.

Closes #8945
Closes #8964
Closes #5946
Closes #10090
Closes #9256
2014-11-23 22:23:41 +00:00
Georgios Kalpakas 1b9e408ddb fix($route): fix redirection with optional/eager params
Fixes #9742
Closes #10202
2014-11-23 19:24:39 +01:00
thorn0 7505d126fa chore(docs): regroup version selector options into major branches and latest
Before this change we grouped by the  discontinued stable/unstable distinction.

Closes #10053
2014-11-23 14:50:31 +00:00
Caitlin Potter 7044e55feb style($http): make jscs happy 2014-11-21 00:27:45 -05:00
Dustin Chilson bd9e894fb7 docs($http): describe how to remove a header on a per request basis
Closes #10144
2014-11-21 00:27:38 -05:00
Brian Ford ba7e24ec6c chore(scripts): correctly update package.json 2014-11-20 15:21:33 -08:00
Brian Ford e1f98773c7 chore(scripts): fix 1.2.x tag name 2014-11-20 15:02:40 -08:00
Brian Ford 17d8a520ca chore(scripts): publish 1.2.x releases to npm with correct tag 2014-11-20 14:34:26 -08:00
Jeff Cross 84bf883f6d docs(CHANGELOG): update changelog with 1.2.27 2014-11-20 10:31:49 -08:00
samuel durand 38ff199a3c docs($anchorScrollProvider): document disableAutoScrolling method 2014-11-17 14:46:43 +00:00
Brian Westrich 7ff5ec254e docs(tutorial/step-5): include sort and filter in json view experiment
Closes #10082
2014-11-17 14:34:13 +00:00
Brian Westrich a2f2032a20 docs(tutorial/step-4): "unknown" option is actually blank
The name 'unknown' doesn't appear as a choice, the new choice is just blank.
Side note: once I choose one of the non-blank options, I no longer see the blank option.

Closes #10079
2014-11-17 13:47:56 +00:00
Peter Bacon Darwin 16833d0fb6 fix(select): ensure the label attribute is updated in Internet Explorer
Only changing the `<option>` text value is not enough to trigger a render
change in IE. We need to explicit update the `label` property too.

Closes #9621
Closes #10042
2014-11-15 22:55:55 +00:00
Peter Bacon Darwin 2a8a4e7fad test(select): refactor option elements expectations to use toEqualOption matcher
By using a new matcher our tests become less brittle with respect to unimportant
extra attributes.
2014-11-15 18:49:01 +00:00
Judy Tuan beeb64a6f6 docs(misc/Develop): update required Java version 2014-11-14 20:23:15 +00:00
Caitlin Potter e49e7d50c5 chore($q): make jscs happy
jscs loves to be happy and does not love trailing whitespace.
2014-11-14 11:12:37 -05:00
Bernie Telles 3b3de3f876 docs($q): explain what the $q service does in description
Explain what the $q service does in description, instead of origin document.

The original explanation was less accessible to people new to promises and JS in general.

Closes #10056
2014-11-14 11:12:27 -05:00
Chatchavan Wacharamanotham eec78e78d6 docs(guide/compiler): replaced 'locals' with 'scope'
In "Understanding How Scopes Work with Transcluded Directives" section, a text referred to an
obsolete 'locals' instead of 'scope'.

Closes #10018
2014-11-14 11:03:53 -05:00
Caitlin Potter b1f2917696 test(orderBy): add test cases for ordering array-like objects
Closes #10060
2014-11-14 10:23:46 -05:00
Karol Wypchło 409bcb3810 perf(orderBy): copy array with slice instead of for loop
Use array slice method to copy entire array instead of a for loop
http://jsperf.com/new-array-vs-splice-vs-slice/54

Closes #9942
2014-11-14 10:13:29 -05:00
codef0rmer e49a1433fd docs(guide/Index): add book AngularJS UI Development
Matthias and I wrote a book on AngularJS which might be helpful for Angular developers.

Merci~!

Closes #9971
2014-11-11 14:14:07 -05:00
AlexChan c26b5e3c88 docs(ngModel.NgModelController) use $evalAsync instead of $apply for event handling
Have the apply called safely during events by using `$evalAsync` rather than `$apply`
This will help ensure that an apply for a user directive is not called during a digest cycle.

Closes #9891
2014-11-11 13:59:48 -05:00
Chirayu Krishnappa 4d0614fd0d fix($parse, events): prevent accidental misuse of properties on $event
Closes #9969
2014-11-10 15:35:02 -08:00
Chirayu Krishnappa 756640f5aa fix($parse): add quick check for Function constructor in fast path 2014-11-10 15:34:58 -08:00
Michael James d87b7912df docs($q): added IE8 warning to promise.catch()
Closes #9987
2014-11-10 17:30:47 -05:00
Brian Ford bff8041bd0 docs(guide/index): link to security 2014-11-07 10:33:48 -08:00
Brian Ford e0ee491633 docs($parse): formatting, link to security docs 2014-11-07 10:33:31 -08:00
Brian Ford 7dfe82e135 docs(security): add security doc 2014-11-07 10:33:04 -08:00
Lucas Galfaso 9f2a53b33e docs(CHANGELOG): Document breaking change from 23bc92b1
Document the breaking change from 23bc92b1

Closes #9947
2014-11-06 15:28:10 -05:00
rsperberg 9128eac501 docs(guide/concepts): spell "Angular" with cap "A", fix typos
In these two instances, Angular was spelled with a lower-case "a." All occurrences should be spelled
consistently.

Compound adjectives preceding the noun they modify should generally be hyphenated (cf Chicago Manual
of Style, 6.40), e.g., "so-called directives."

Closes #9896
2014-11-06 14:17:24 -05:00
Adir 85e8d5ea67 docs(guide,tutorial): fix outdated Protractor API link
Link to the gh-pages deployment of protractor docs, it's much easier on the eyes.

Closes #9946
2014-11-06 13:58:55 -05:00
danielmbarlow a36863eea3 docs(tutorial/step_12): added 'see phone-detail change'
This one caught me out for a while because, despite the note underneath, I didn't notice the addition
of <div class="phone-images"> and it's repeater until later.

Closes #9924
2014-11-05 12:14:54 -05:00
danielmbarlow 98da7ade7a docs(tutorial/step_12): small change to overview
The bullet points at the beginning of the article were a little hard to understand because they
didn't follow the grammatical form of the preceding articles. I hope these small modifications make
it a little easier for someone else to read.

Closes #9922
2014-11-05 09:10:36 -05:00
danielmbarlow 846fe1b3ef docs(tutorial/step_05): explain need for $httpBackend.flush in tests
There is an excellent explanation for the need for this in the documentation that may be helpful to
tutorial users, so I added a link to it.

Closes #9919
2014-11-05 09:10:28 -05:00
Julie Ralph f4648abe03 chore(ci): update protractor to version 1.4.0 2014-11-04 17:18:30 -08:00
Tobias Gesellchen 5f9a1122e2 chore(.gitignore): ignore IntelliJ IDEA module files
Ignore IntelliJ IDEA modules files in the git repository

Closes #5273
2014-11-04 12:47:26 -05:00
Tero Parviainen 1afeb37756 docs(guide/scope): describe watch depths
Describe and visualize the three watch strategies: By reference, by collection items, and by value.

Closes #9388
2014-11-03 12:44:39 -08:00
Julie Ralph 7809e75a56 chore(ci): fix broken sauce connect download url 2014-10-31 09:24:37 -07:00
Uri Goldshtein 1472c31431 docs(guide/index): add link to angular-meteor
Bueno!

Closes #9844
2014-10-30 11:13:43 -04:00
Ralph Samuel d3b839d986 docs(guide/Scopes): add "the" in front of "DOM" on line 42
Closes #9818
2014-10-29 13:51:34 -04:00
ChristianKohler c8c2386296 chore(docs): clarify comment which was copy&paste from dgeni example
It makes people happy, so why not

Closes #9798
2014-10-27 12:24:02 -04:00
alindberg d0b5bfa454 docs(tutorial/tutorial): instructions to install npm on debian
Additional package required for a Debian install

Closes #9749
2014-10-22 14:17:04 -04:00
Martin Hochel 1fa2d56ba3 docs($http): document $httpProvider.interceptors in $httpProvider documentation
☆.。.:・゜☆ HASHBANG #NGEUROPE ☆.。.:・゜☆

Fixes #9366
Closes #9728
2014-10-22 11:26:43 -04:00
marcin-wosinek efedc643d1 docs($templateCache): clarify inline template
Current doc doesn't state required tag location clear enough. It was
[stack overflow|http://stackoverflow.com/a/16125138] where I've found that requirement

Closes #9741
2014-10-22 10:02:49 -04:00
Jackson Ray Hamilton 34230b30b7 docs(guide/bootstrap): close script tag
Closes #9739
2014-10-22 00:45:52 -04:00
Dwayne Crooks 8354d02805 docs(ngModel.NgModelController): remove extra 'to'
Closes #9702
2014-10-20 21:34:13 +01:00
Bastien Caudan 1426b02980 fix(ngMock): $httpBackend should match data containing Date objects correctly
If a response or expectation contained a date object then `$httpBackend.expect`
was not matching correctly.

This commit encodes then decodes the object being matched to ensure consistency.

Closes #5127
2014-10-20 13:07:07 +01:00
lguyot 29aeee2250 docs(tutorial/step-11): remove excess words
Closes #9690
2014-10-20 12:11:14 +01:00
Augustas 6a8348f715 docs(tutorial/step-7) - correct a url
Closes #9688
2014-10-20 11:44:04 +01:00
Peter Bacon Darwin 38e2856889 docs(guide/introduction): remove ambiguous "code-behind" jargon
This commit tries to remove the jargon and explain in plain English what
it means to add "code-behind" via a directive.

Closes #9684
2014-10-20 10:32:16 +01:00
Peter Bacon Darwin a56435f3ae fix($rootScope.$on) check listener existense while deregistering
Check that listener is still present in $$listeners before decrease
$$listenerCount. It fixes problem with incorrect $$listenerCount after
call deregistering function multiple times.

Closes #9666
Closes #9667
2014-10-19 12:10:58 +01:00
Juan M. Cuello 75082c975c docs(error/dupes): Little fix in explanation text.
Little fix in docs/content/error/ngRepeat/dupes.ngdoc.

Closes #9673
2014-10-18 15:39:12 -04:00
Daniel Luz 31b6bfaaf4 docs(ngEventDirs): update remarks on behavior
The event directives haven't stopped propagation by default in a long time.
If that behavior is desired, the handler may use the provided `$event` to call:

    $event.stopPropagation();

Closes #9640
2014-10-16 16:44:48 -04:00
Ciro Nunes 2d74323e3e docs(ngModel): fix anchor text
Closes #9604
2014-10-14 10:44:36 +01:00
Afshin Mokhtari edc2613ed5 docs(CONTRIBUTING): prototypical -> prototypal
Closes #9608
2014-10-14 10:43:10 +01:00
Richard 6eab8ab187 docs(guide/unit-testing): use whitespace to improve readability
☆.。.:・゜☆ Merci (◜௰◝) ☆.。.:・゜☆

Closes #9572
2014-10-12 23:04:02 -04:00
Georgios Kalpakas 80ce046fd1 chore(CHANGELOG): add an extra new line after each item in the "BREAKING CHANGES" list
This ensures that the next item will appear on a new line and be properly
parsed as new list item (and not as the continuation of the current item),
even if the current item does not end with a newline character.
Currently, it would result is something like this:

    - **item 1**: due to ...
      blah1 blah1 blah1- **item 2**: due to...
      blah2 blah2 blah2

instead of the intended:

    - **item 1**: duo to ...
      ...
    - **item 2**: due to ...
      ...
2014-10-10 19:07:22 +01:00
Chris Inch 315f320e2e docs(guide/compiler): add title to the page 2014-10-09 13:54:20 -07:00
Georgios Kalpakas ec4fe1bcab fix($http): add missing shortcut methods and missing docs
There was some inconsistency in version 1.2.25 regarding the definition
and documentation of shortcut methods in `ng.$http` and
`ngMock[E2E].$httpBackend`. Some methods didn't exist (although documented
as existing), whereas some methods did exist, but wheren't documented.
This commit fixes the above errors and adds tests to verify the existence
of all shortcut methods.
More specificcally, the following issues were addressed:
`ng.$http`: Add the missing `patch()` shortcut method and related docs.
`ng.$http` spec: Add test to verify the existence and functionality of the
`patch()` shortcut method.
`ngMock[E2E].$httpBackend`: Add docs for the (existing) `whenPATCH()`
shortcut method, add the missing `expectHEAD()`/`whenHEAD()` shortcut
methods, fix grammatical errors.
`ngMock[E2E].$httpBackend` spec: Add test to verify the existence of shortcut
methods for all HTTP verbs.

Closes #9180
Closes #9321
2014-10-09 20:13:08 +01:00
bolasblack 3303fe41e4 docs(versions): remove the trailing slash in URLs when switch versions
Because `https://docs.angularjs.org/api/` can handler the trailing slash,
but `https://code.angularjs.org/1.2.24/docs/api` can not.

Fix #9043
Closes #9045
2014-10-09 11:53:37 -07:00
thorn0 f22e5fd980 docs(angular.injector): correct return type 2014-10-09 11:49:30 -07:00
Jakub Zych b11d6c792f style(filters) use consistent quote style and strict equality
before change quotes where mixed and one if contained equality operator instead of identity

Closes #9349
2014-10-09 07:11:43 -04:00
Brian Ford e713f36d7c docs(changelog): more release notes for 1.3.0-rc.5 2014-10-08 15:52:27 -07:00
Brian Ford 8162a1d731 docs(changelog): release notes for 1.3.0-rc.5 2014-10-08 13:37:55 -07:00
Izhaki 1e6f8543e5 docs($compile): note template is ignored with element transclusion 2014-10-08 11:30:49 -07:00
Jesse Palmer 0e293d2a97 docs(ngIf): update out-of-date link 2014-10-08 10:43:19 -07:00
Tobias Bosch 434d7a0903 fix($browser): Cache location.href only during page reload phase
Adds caching for url changes while a reload is happening,
as browsers do not allow to read out the new location the browser
is navigating to.

Removes unnecessary caching from $browser, as IE7-IE9 all
have the new hash value in `location.href` after changing it.
There was a wrong assumption in the previous version of this code
introduced by dca23173e2 and d70711481e.

Adds more tests for #6976
Fixes #9235
Closes #9470
2014-10-07 14:55:54 -07:00
Tobias Bosch a6e6438dae fix($browser): don’t use history api when only the hash changes
Fixes a failing test on IE9 caused as a side effect
of 404b95fe30 being merged
before 0656484d3e.

The test should have been independent on the browser running it
and it is now.

Closes #9423
Closes #9424
2014-10-07 14:54:55 -07:00
Tobias Bosch 3691d2c15f fix($browser): don’t use history api when only the hash changes
Fix jshint error
2014-10-07 14:54:55 -07:00
Tobias Bosch 4cee5fde1b fix($browser): don’t use history api when only the hash changes
IE10/11 have the following problem: When changing the url hash
via `history.pushState()` and then reverting the hash via direct
changes to `location.href` (or via a link) does not fire a
`hashchange` nor `popstate` event.

This commit changes the default behavior as follows:
Uses `location.href`/`location.replace` if the new url differs from
the previous url only in the hash fragment or the browser
does not support history API.
Use `history.pushState`/ `history.replaceState` otherwise.

Fixes #9143
Closes #9406
2014-10-07 14:54:55 -07:00
Ben Harold 5d042592fc docs($injector): fix syntax error
There was a missing parenthesis in $injector test example

Closes #9469
2014-10-07 13:40:19 -04:00
Matias Niemelä f619d032c9 fix($animate): clear the GCS cache even when no animation is detected
$animate will cache subsequent calls to GCS in the event that the element
with the same CSS classes and the same parentNode is being animated. Once the
animation is started then $animate waits for one rAF before flushing the GCS
lookup cache. Prior to this fix, if GCS was unable to detect any transitions
or keyframes on the element then it would simply close the animation, but it
would not trigger the rAF code to flush the cache. This issue caused a bug
which made it difficult to detect why certain animations are not allowed to
fire if the element didn't contain any CSS-based animations beforehand.

Closes #8813
2014-10-07 09:44:44 +03:00
Casey Garland 95f5b86240 docs(guide/index): fix broken link 2014-10-06 16:02:25 -07:00
thorn0 483d91a624 docs($injector): injectors aren't functions
Closes #9453
2014-10-06 18:20:01 -04:00
thorn0 e9339935d4 docs($injector): clean up docs for $injector#has
Fixup return type and param info.

Closes #9452
2014-10-06 16:55:49 -04:00
tommyangelo 3e468523b7 docs(ngBindHtml): explain that angular-sanitize.js is needed to depend on ngSanitize
Added comment. You need to include angular-sanitize.js otherwise you cant use ngSanitize!

Closes #9400
2014-10-06 16:47:58 -04:00
Agam Rafaeli 99f3931e3d docs(guide/introduction): guice has moved to github
Closes #9416
2014-10-06 16:33:13 -04:00
Jesse Palmer 80b78f7461 docs(ngIf): wrap ngIf in code tags
Closes #9435
2014-10-06 16:11:05 -04:00
erikrahm 386c179a94 docs(misc/faq): grammatical error fixes
Merci beaucoup

Closes #9451
Closes #9450
2014-10-06 16:07:39 -04:00
thorn0 054893b555 docs($injector): $injector isn't a function
Closes #9448
2014-10-06 20:21:18 +01:00
Tim Kendrick e865726e00 chore(docs): remove unused gruntUtils import from docs config
As of commit 11c5bb7, the gruntUtils import is no longer needed in the
gitData docs config service.

Closes #9446
2014-10-06 20:19:32 +01:00
Bijan Boustani f9370755d4 docs(guide/introduction): fix grammar style
Changed "you would currently have to write" to "you would otherwise have to write".

Seems to make more sense this way since "currently" presupposes that someone new
to Angular would be coming from a different paradigm, which they may or may not be.

Closes #9428
2014-10-06 20:04:47 +01:00
Peter Bacon Darwin f906603dd6 chore(docs): update to dgeni 0.4.1 and dgeni-packages 0.10.1
Adds a new processor to identify dangling links
2014-10-06 18:08:57 +01:00
Tobias Bosch d7c084f9cf docs($location): clarify guide regarding link handling
The trick with setting `<base href=".">` has not worked since Angular 1.2.0.
It is also misleading that it talks about `$routeProvider.otherwise`
which is not important in this case.

Related to #8869
Closes #8908
2014-10-03 17:15:25 -07:00
Peter Bacon Darwin 5847fc48e7 test($location): fix use of browserTrigger
You must now pass `keys` to the function in a config object.
This bug in the test became apparent because in newer browsers, arrays
have a function called `keys()` and this was causing browserTrigger to
fail. Previously it was quietly passing this test despite being wrong.
2014-10-03 17:15:15 -07:00
Tobias Bosch 1ee9b4ef5e fix($location): revert erroneous logic and backport refactorings from master
Backport of 22948807e3 without enforcing the `<base>` tag and without the new handling for links that only contain hash fragments.

Related to #6162
Closes #8492
2014-10-03 17:15:10 -07:00
Tobias Bosch 430082e6bd refactor(locationSpec): make helper functions take an object
Makes tests more readable
2014-10-03 16:53:56 -07:00
Chris Chua fe7d9dedaa fix($browser): handle async href on url change in <=IE9
Closes #9235
2014-10-03 15:33:31 -07:00
Dominic Watson 029ac8cb80 docs(angular.element): css() method does not retrieve computed styles
The jQuery css() getter functionality utilises getComputedStyle() whereas
jqLite only retrieves what is declared inline on an element.

Closes #7599
2014-10-03 11:58:09 +01:00
Peter Bacon Darwin 45b896a16a fix(orderBy): sort by identity if no predicate is given
Closes #5847
Closes #4579
Closes #9403
2014-10-03 09:54:44 +01:00
Pawel Kozlowski f807d7ab4e fix($location): allow 0 in path() and hash() 2014-10-02 21:32:22 +01:00
Jeff Cross 07d62426f6 docs(CHANGELOG.md): update 1.2.26 release name 2014-10-02 09:46:40 -07:00
Jeff Cross 3a142e79bd docs(changelog.md): update changelog for 1.3.0-rc.4 and 1.2.26 2014-10-01 21:25:57 -07:00
Brian Feister b40130abcf docs(minerr/unpr): note that ctrls cant depend on other ctrls 2014-09-30 14:37:06 -07:00
active-low ee988d40d0 docs(guide/concepts): improve readability 2014-09-30 12:57:32 -07:00
Adam Humphrey ad4d26c525 docs(readme): fix formatting 2014-09-30 12:36:58 -07:00
Justin Walsh f58681564d docs(guide/compiler): change span to block element in draggable example
The draggable example does not work as expected in Chrome (37.0.2062.124 m).
The span disappears when dragged beyond what appears to be a small area.
Changing the span to a block element (with a width of 65px) resolves this issue.
An alternative solution would be to change the span to a div.
2014-09-30 12:30:09 -07:00
thorn0 d23f585f4a docs($compile): add header to example 2014-09-30 11:41:19 -07:00
Jeff Cross 1850f59765 revert: fix(input): always format viewValue as a string inputs with text controls
This reverts commit 1b8b41ad23.

This is a breaking change.
2014-09-30 09:21:53 -07:00
Peter Bacon Darwin 1f182853d4 revert: fix($compile): Resolve leak with asynchronous compilation
This reverts commit 5c9c197305.

This "fix" is not yet ready for 1.2.x as it has lots of issues when JQuery
is loaded.
2014-09-29 22:19:25 +01:00
Caitlin Potter 5036ac905b docs(CHANGELOG.md): put <base> in codeblock
Prevent the tag from being processed (and not rendered). Thanks @davidlehn.

Closes #9331
2014-09-29 17:16:36 -04:00
Brian Ford 11d2242df6 fix(select): make ctrl.hasOption method consistent
Prior to this fix, options added to a select by ngOptions would not cause
`selectCtrl.hasOption` to return `true`

Closes #8761
2014-09-29 13:59:54 -07:00
Peter Bacon Darwin cea23db3de chore(npm-shrinkwrap): update to dgeni-packages 0.10.0 2014-09-29 21:56:43 +01:00
Peter Bacon Darwin 5c9c197305 fix($compile): Resolve leak with asynchronous compilation
Stop an asynchronous compilation when this is performed on an
already destroyed scope

Closes #9199
Closes #9079
Closes #8504
Closes #9197
2014-09-29 21:56:43 +01:00
Peter Bacon Darwin ecb2222ea1 chore(testabilityPatch): add jqLiteCacheSize helper 2014-09-29 21:56:43 +01:00
Julie Ralph 276310e5b5 chore(ci): remove repeated tests running from Travis build
In b2902446eb the doce2e tests were moved
into the 'unit' test job on Travis, but only half of this change ever made
it into v1.2.x. This change fixes up the other half, so that the doce2e
tests are run only once.
2014-09-29 10:55:53 -07:00
Julie Ralph 6afe0dba39 chore(e2e): bump protractor to version 1.3.1 2014-09-29 10:21:05 -07:00
Peter Bacon Darwin 038ca9b9bf chore(docs): fix links to github 2014-09-26 21:22:02 +01:00
Sandeep Panda 44c451e9f5 docs(guide/index): add book AngularJS: Novice to Ninja
I wrote a book on AngularJS (AngularJS: Novice to Ninja).

Closes #9293
2014-09-26 12:29:09 -04:00
Caitlin Potter 1b8b41ad23 fix(input): always format viewValue as a string inputs with text controls
Backported from 1eda18365a

NgModel will format all scope-based values to string when setting the viewValue for
the associated input element. The formatting, however, only applies to input elements
that contain a text, email, url or blank input type. In the event of a null or undefined
scope or model value, the viewValue will be set to null or undefined instead of being
converted to an empty string.

Closes #5936
Closes #9277
2014-09-25 13:49:59 -04:00
Peter Bacon Darwin 37f2265b88 chore(docs): minify javascript 2014-09-25 06:05:17 +01:00
Peter Bacon Darwin 05a2a1d395 chore(docs): remove unused code 2014-09-25 05:50:52 +01:00
Peter Bacon Darwin fc913eea89 chore(docs): improve logo rendering performance 2014-09-25 05:45:33 +01:00
Peter Bacon Darwin f839e4944a chore(protractor): annotate $animate to allow tests to run under strict-di 2014-09-25 05:45:26 +01:00
Peter Bacon Darwin 2aead39486 chore(docs): ensure DI annotations are in place 2014-09-25 05:45:03 +01:00
Jeff Cross 54af406c2e docs(changelog): add release notes for 1.3.0-rc.3 2014-09-23 18:50:20 -07:00
Georgios Kalpakas 930bd40bac docs(ngController): Fix priority value mentioned in the docs
The `@priority 500` part was missing from the ngDoc comment, thus the docs mentioned a priority of 0
(instead of the correct 500).

Closes #9070
2014-09-23 16:25:43 -07:00
Peter Bacon Darwin 4aa4005f5f chore(docs): AngularJS 1.2.x doesn't support '$includeContentError' event 2014-09-23 19:26:04 +01:00
Peter Bacon Darwin d5c04121cb chore(docs): refactor the docs app search for better bootup time
This commit refactors how the search index is built. The docsSearch service
is now defined by a provider, which returns a different implementation of
the service depending upon whether the current browser supports WebWorkers
or now.

* **WebWorker supported**: The index is then built and stored in a new worker.
The service posts and receives messages to and from this worker to make
queries on the search index.

* **WebWorker no supported**: The index is built locally but with a 500ms
delay so that the initial page can render before the browser is blocked as
the index is built.

Also the way that the current app is identified has been modified so we can
slim down the js data files (pages-data.js) to again improve startup time.

Closes #9204
Closes #9203
2014-09-23 19:01:22 +01:00
Andrew Delikat e6996cc457 docs(tutorial/step_05): fix typo 2014-09-22 14:55:24 -07:00
William Chen 33793ec3e1 docs(triaging): fix formatting 2014-09-22 13:15:15 -07:00
Bocharsky Victor c9f8fb2559 docs(guide/$location): fix broken link 2014-09-22 13:12:52 -07:00
Christopher Rains a0229803de docs(tutorial/step_02): fix formatting 2014-09-22 13:09:39 -07:00
James Ferguson 38cb2b348e docs(readme): improve readability 2014-09-22 11:41:00 -07:00
Ariel Mashraki c54287bf8d docs(route): remove irrelevant note
Closes #9196
Closes #9200
2014-09-22 13:30:24 -04:00
Jeff Cross a36515289a chore($http): disable flaky JSONP test
See #9185
2014-09-19 17:20:32 -07:00
Peter Bacon Darwin c59da09d3e docs(limitTo): exclude the e2e test that fails on safari
Safari and doesn't like the minus key to be sent to it via Protractor.
Commenting out rather than using xit so that it passes the build
2014-09-19 22:57:11 +01:00
Peter Bacon Darwin 98ceda2194 docs(limitTo): exclude the e2e test that fails on safari
Safari and doesn't like the minus key to be sent to it via Protractor.
2014-09-19 22:40:30 +01:00
Sekib Omazic fbd620e8ae docs(angular.extend) actually only copies own enumerable properties
Closes #9007
2014-09-19 22:00:51 +01:00
Zahid Mahir 4cfc279d39 docs(tutorial/step-3): correct slight grammar issue
Closes #8996
2014-09-19 21:36:17 +01:00
jimmywarting 6a07009c12 docs(limitTo): fix input type in examples
Closes #8989
2014-09-19 21:33:55 +01:00
Sercan Eraslan f3f65caac2 docs(navigation): side navigation footer overlap problem fix
Closes #8923
2014-09-19 19:26:23 +01:00
Luke Schoen 130fe92cda docs(guide/directive): fix grammar 2014-09-18 16:12:37 -07:00
Matt Kim 3d83973fa4 docs(misc/faq): fix typo 2014-09-18 16:11:09 -07:00
Greg Fedirko 3b171a851d docs(guide/$location): improve readability 2014-09-18 16:08:59 -07:00
Luke Schoen 9782bc2aa2 docs(tutorial): improve readability 2014-09-18 16:01:13 -07:00
Christopher Rains 77be7cc7d9 docs(tutorial): fix formatting
- proper case "jQuery" vs "JQuery"
- wrap ng-view in markdown code `ng-view`
2014-09-18 15:56:23 -07:00
jeffavis 3da5847500 docs(guide/bootstrap): fix missing ngController in example 2014-09-18 15:51:59 -07:00
Rahul Doshi 53e6590e88 docs(guide): add angular-localization module to internationalization section
Closes #9158
2014-09-18 18:00:26 -04:00
Jose Martinez d1c05ad832 docs(error/$controller/noscp): fix example
Fix the "correct" example to have the proper syntax for creating the locals
object and provide a more explicit explanation as to how the scope object
should be provided.
2014-09-17 11:10:03 -07:00
Brian Ford f6f0791867 docs(changelog): release notes for 1.2.25 2014-09-16 15:05:22 -07:00
Brian Ford fb3d158be9 docs(changelog): release notes for 1.3.0-rc.2 2014-09-16 15:05:06 -07:00
Caitlin Potter 06c76694ac fix(ngLocale): Regenerate Locale Files
Fixes number formatting and symbols for many locales.
Adds support for additional locales.
2014-09-16 17:18:52 -04:00
Michael Gallagher b979ee1f03 chore(ngLocale): Include numberformatsymbolext.js in Closure Slurper Script
Adds missing number format and symbol rules to Closure slurper script.

Closes #6179
Closes #9013
2014-09-16 17:18:22 -04:00
Brian Ford d89d59f453 fix(select): update option labels when model changes
Closes #9025
2014-09-16 12:46:53 -07:00
Peter Bacon Darwin e251db9fb3 docs(ngView): remove obsolete comment from code sample
Closes #9086
2014-09-15 20:40:02 +01:00
Peter Bacon Darwin 9cc968689f chore(docs): remove excess indentation from code blocks
dgeni-packages 0.10.0-rc.5 has a fix for this problem, so this commit updates
to that version.
Adds a new e2e test to prove this is fixed.

Closes #8963
2014-09-15 20:39:55 +01:00
Peter Bacon Darwin dea705b2cf test(docs): fix url matching on api e2e tests 2014-09-15 20:39:43 +01:00
Peter Bacon Darwin c4d3e6fd43 chore(docs): ensure all docs e2e tests are run 2014-09-15 20:39:36 +01:00
Peter Bacon Darwin bf24ad144d docs(ngShowHide): use backticks to denote CSS classes and directive names
add backticks around directive names to improve documentation consistency, as it's used in some
parts of the docs already.

Closes #9081
2014-09-15 20:38:50 +01:00
Peter Bacon Darwin b4de7307c3 test(docs): add extra docs e2e tests 2014-09-15 20:35:40 +01:00
Peter Bacon Darwin 9b9a30c7ae test(docs): improve docs e2e tests 2014-09-15 20:35:20 +01:00
Peter Bacon Darwin 8be7b5d125 chore(docs): update to dgeni-0.4.0
* update package with new services and computeId config
* generateIndexPagesProcessor was not using log
* use StringMap not ES6-shim Map in errorNamespaceMap
* remove unused dependencies from generateErrorDocsProcessor
* ensure generatePagesDataProcessor adds its doc to the collection
* debugDumpProcessor was moved to dgeni-packages
2014-09-15 20:33:58 +01:00
Caitlin Potter a3fbf0ff5a test($parse): ensure CSP code paths are used when testing
Previously, the test suite was not actually taking CSP-mode paths when we were expecting it to.

Numerous CSP-mode tests are failing, working on fixing these.
2014-09-12 15:07:37 -04:00
Caitlin Potter f2894c0f1d test($parse): ensure CSP code paths are used when testing
Previously, the test suite was not actually taking CSP-mode paths when we were expecting it to.

Numerous CSP-mode tests are failing, working on fixing these.
2014-09-12 14:51:55 -04:00
Georgii 6d12e8990b refactor(ngEventDirs): remove a useless call
The event names are already lower-case.
2014-09-11 12:57:32 -07:00
Georgios Kalpakas 71d65821c8 docs(CHANGELOG.md): fix typos for ng-switch-changed workaround
Fix the JavaScript errors in the work-around proposed in 0f806d9 in order to emulate the behaviour
of the removed `change` attribute of ngSwitch.

Closes #9034
2014-09-11 15:42:30 -04:00
Justin Walsh ae92658ebf docs(guide/forms): correct grammar 2014-09-11 12:11:28 -07:00
SirTophamHatt 1a53863662 docs(guide/providers): note that services can create functions
The conclusion table incorrectly states that services can not create functions.
New table row added to separate "can create functions" and "can create primitives".
2014-09-10 16:07:53 -07:00
Lucas Galfaso 1b6d74cc9f fix(i18n): fix typo at i18n generation code
Fix typo at i18n generation code. This would remove the
property `macFrac` that has no meaning from all the
generated locales
2014-09-10 15:30:18 -07:00
Peter Bacon Darwin 6fd048a3b7 docs(tutorial/steps-11&12): add warning about bower conflict error
See: https://github.com/angular/angular-phonecat/issues/163#issuecomment-55181854
2014-09-10 22:52:58 +01:00
Michael Silver 50cd3a4210 docs(tutorial): update step 7 to reference angular-phonecat
This changes the example JSON to be the actual bower.json for angular-phonecat,
with name set to angular-phonecat.
2014-09-10 11:45:32 -07:00
standup75 57ac995b8b docs(ngResource): document steps to skip default json serialization/deserialization 2014-09-10 11:42:28 -07:00
Jeff Cross d396f42537 docs(CHANGELOG.md): add upcoming breaking change 2014-09-09 16:21:16 -07:00
Jeff Cross 5ec900a125 docs(CHANGELOG.md): fix wording and remove reverted change 2014-09-09 16:20:20 -07:00
Jeff Cross 66503a6e18 docs(CHANGELOG.md): add changes for 1.3.0-rc.1 and 1.2.24 2014-09-09 15:48:30 -07:00
Jeff Cross 2d8749e8c9 revert: "fix($compile): render nested transclusion at the root of a template"
This reverts commit 9d9cdfb575.

This commit was causing breakages because of its assumption that transcluded
content would be handled predictably, i.e. with ngTransclude, whereas many
use cases involve manipulating transcluded content in linking functions.
2014-09-09 11:08:39 -07:00
Chirayu Krishnappa b39e1d47b9 fix($parse): disallow passing Function to Array.sort
Fix the following exploit:

    hasOwnProperty.constructor.prototype.valueOf = valueOf.call;
    ["a", "alert(1)"].sort(hasOwnProperty.constructor);

The exploit:
• 1. Array.sort takes a comparison function and passes it 2 parameters to compare.
  2. It then calls .valueOf() if the result is not a primitive.
• The Function object conveniently accepts two string arguments so we can use this
  to construct a function.  However, this doesn't do much unless we can execute it.
• We set the valueOf function on Function.prototype to Function.prototype.call.
  This causes the function that we constructed to be executed when sort calls
  .valueOf() on the result of the comparison.

The fix is in two parts.
• Disallow passing unsafe objects to function calls as parameters.
• Do not traverse the Function object when setting a path.
2014-09-09 10:46:36 -07:00
Peter Bacon Darwin 5061d2c97c chore(npm-shrinkwrap): safely update karma to 0.12.23 2014-09-09 10:21:45 +01:00
Peter Bacon Darwin a961291aa2 chore(npm-shrinkwrap): fix karma dependencies
Updating to karma 0.12.13 (in commit 408508ad29)
caused `iit` and `ddescribe` to crash and disconnect the browser stopping the
test run.

It appears that the problem is with one of the dependencies of karma rather
than karma itself. At least one of the karma dependencies updated in line
with karma's dependencies' semver specifications but subtly changed their
behaviour to break karma.  Possibly this is related to chokidar, glob,
minimatch or fsevents.
2014-09-09 10:04:32 +01:00
Peter Bacon Darwin 3068d8e52a docs($filter): remove duplicate documentation of register method 2014-09-08 14:31:47 +01:00
Peter Bacon Darwin d2dd3581a9 docs(form): move param tag outside of main description 2014-09-08 14:31:47 +01:00
Peter Bacon Darwin 53feb272be chore(bower): refactor bower usage
The gulp bower task in the docs app was never actually running since it couldn't
find the bower.json file and was silently failing. Updating to a newer bower
highlighted this issue.

This commit moves the docs app specific bower components into the docs folder.
There are only jquery and closure compiler related components in the project
folder now.

It also improves the gulp bower task to provide better feedback of progress
and errors.
2014-09-08 14:31:47 +01:00
Peter Bacon Darwin 408508ad29 chore(package.json): tidy up dependencies
Sorted dependencies into alphabetic order. If we can keep them like this
it will be much easier to keep track of version changes.

Updated bower and gulp to newer versions.
2014-09-08 14:31:47 +01:00
Peter Bacon Darwin ece7d19115 chore(clean-shrinkwrap): chokidar is fixed since 0.8.2 2014-09-08 12:31:40 +01:00
Pawel Kozlowski 992101da10 refactor($http): simplify buildUrl function
Closes #8955
2014-09-05 20:22:20 -04:00
Peter Bacon Darwin 47f42ecf45 test(orderBy): remove IE8 incompatible test code 2014-09-05 19:46:40 +01:00
Julie Ralph fd995abc9a chore(tests): fix up test for protractor 1.2.0 update
These changes were made to master in 85880a6490
but never made it to the 1.2.x branch.
2014-09-05 11:16:18 -07:00
Julie Ralph 5f9a9747d2 chore(tests): update Protractor to v1.2.0 2014-09-05 10:51:31 -07:00
Vitali Tsevan 94b0f2d35d fix(orderBy): allow arrayLike objects to be ordered
Closes #8944
2014-09-05 11:56:41 +01:00
Jeff Cross c12e8d4665 fix($location): don't call toString on null values 2014-09-04 17:46:51 -07:00
thorn0 c65796d496 fix($location): remove an unused parameter of $location.url 2014-09-04 15:12:04 -07:00
John Reilly 34b43eab5f docs($location): update search description to include number param 2014-09-04 14:55:48 -07:00
Peter Bacon Darwin 9d9cdfb575 fix($compile): render nested transclusion at the root of a template
Closes #8914
Closes #8925
2014-09-04 19:33:03 +01:00
Pawel Kozlowski 68a09ba74d fix($location): allow numeric location setter arguments
Fixes #7054
2014-09-04 10:47:30 -07:00
Peter Bacon Darwin 239d0b1f49 docs(guide): add sortOrder to each page
Finally we can control the order of the guide pages
2014-09-04 17:15:26 +01:00
Peter Bacon Darwin 4e04c73cd3 chore(docs): enable page ordering by @sortOrder tag 2014-09-04 16:49:55 +01:00
Peter Bacon Darwin 6c863e5bba chore(docs): improve searching by member
The keywords processor now also extracts the members (i.e. method, properties
and events) into its own search term property. These are then used in the lunr
search index with higher weighting that normal keywords to push services that
contain the query term as a member higher up the search results.

Closes #7661
2014-09-04 14:23:29 +01:00
Peter Bacon Darwin e0cf7c5bf2 Revert "fix($compile): render nested transclusion at the root of a template"
This reverts commit 466320f691.
2014-09-04 14:15:38 +01:00
Peter Bacon Darwin 466320f691 fix($compile): render nested transclusion at the root of a template
Closes #8914
Closes #8925
2014-09-04 13:45:49 +01:00
Smitha Milli 7e02fa07eb fix(numberFilter): format numbers that round to zero as nonnegative
Previously when a negative number was rounded to 0 by the number filter
it would be formated as a negative number.  This means something like
{{ -0.01 | number: 1 }} would output -0.0.  Now it will ouput 0.0
instead.

Closes #8489
2014-09-03 15:42:07 -07:00
thorn0 9ed9777317 docs(docs.css): improve comma spacing in TOC on mobile 2014-09-03 14:37:43 -07:00
Juampy e661bc9f15 docs($sce:unsafe): fix link to $sce docs
The second link to Strict Contextual Escaping (SCE) points to a 404.

Closes #8514
2014-09-03 16:31:41 -04:00
thorn0 7af210f1de docs(README): fix 'Contribution guidelines' link
The current link leads to a page 'Building and Testing AngularJS'.
This same link is also included in the 'Building AngularJS' section
of the README where it's more relevant.
2014-09-03 13:25:40 -07:00
TLChan b48203f9f2 docs(tutorial/step_05): improve formatting of code identifier
Closes #8557
2014-09-03 16:25:08 -04:00
Zach Pomerantz 789f0f1809 docs(interpolate): fix link text 2014-09-03 13:20:27 -07:00
Vic Metcalfe 8366d545c5 docs(ngBlur): explain blur events 2014-09-03 13:05:07 -07:00
Caitlin Potter 1f5b4c95eb docs(CHANGELOG.md): add breaking change for a9fcb0d0 (v1.2.13)
Closes #8909
2014-09-03 13:14:02 -04:00
Peter Bacon Darwin 910d652ce5 chore(package.json): update to dgeni-packages v0.9.8
Closes #8860
2014-09-03 11:39:35 +01:00
Nicolai Skogheim e5e62a5479 docs(ngRepeat): update step_02.ngdoc with challenge
Add a simple task for the user to better understand ng-repeat.

Close #8757
2014-09-02 16:46:20 -04:00
Shahar Talmi 8f14b726b0 docs($rootScope): document scope properties 2014-09-02 13:35:41 -07:00
Tiago Ribeiro 88b6a9a288 docs(changelog): fix inline formatting 2014-09-02 13:05:07 -07:00
Matias Niemelä d4fc40c282 docs(changelog): release notes for 1.3.0-RC.0 sonic-boltification 2014-09-02 13:04:45 -07:00
Nima Mehanian 653700df5b docs(guide/providers): fix grammar and punctuation 2014-09-02 12:48:57 -07:00
Shahar Talmi 2712c2f197 fix(ngEventDirs): check scope.$$phase only on $rootScope
Closes #8891, #8849
2014-09-02 10:48:12 -07:00
Shahar Talmi 36e6de1d91 fix(input): check scope.$$phase only on $rootScope 2014-09-02 10:48:12 -07:00
Brian Ford 9bf964f1f3 style(ngRepeatSpec): make jshint happy 2014-08-29 15:51:02 -07:00
Tobias Bosch 54f0bc0fe0 fix(ngEventDirs): execute blur and focus expression using scope.$evalAsync
BREAKING CHANGE:
The `blur` and `focus` event fire synchronously, also during DOM operations
that remove elements. This lead to errors as the Angular model was not
in a consistent state. See this [fiddle](http://jsfiddle.net/fq1dq5yb/) for a demo.

This change executes the expression of those events using
`scope.$evalAsync` if an `$apply` is in progress, otherwise
keeps the old behavior.

Fixes #4979
Fixes #5945
Closes #8803
Closes #6910
Closes #5402
2014-08-29 15:31:27 -07:00
Tobias Bosch 2ece4d0347 fix($browser): detect changes to the browser url that happened in sync
Closes #6976.
2014-08-29 15:31:13 -07:00
Smitha Milli 1812af58c2 fix(ngRepeat): improve errors for duplicate items
-Log the value that had the duplicate key, as well as the key
The error that is thrown when items have duplicate track by keys can be
confusing because only the duplicate key is logged.  If the user didn't
provide that key themselves, they may not know what it is or what item
it corresponds to.
2014-08-29 13:54:57 -07:00
Michael Barton 19cb2e3d12 docs($rootScope): remove duplicate $digest()
Closes #8840
2014-08-29 14:38:31 -04:00
Guilbert c92ce4511b docs(filterFilter): add note on negation 2014-08-28 14:57:30 -07:00
Matias Niemelä d7548fdf1c fix(form): ensure concurrent animations use setClass
When addClass and removeClass are called in parallel it may
cause follow-up animations to get blocked. This fix ensures
that the validity state CSS classes are applied at the same
time via $animate.setClass.

Closes #8166
2014-08-27 23:29:44 -04:00
dennishall1 7e239f9485 docs(dateFilter): add example of string literals in format string
Also changes the wording to include the word "escaped" and "escape", which may help users find the
information they're looking for via searching. (ノ◕ヮ◕)ノ*:・゚✧

Closes #8770
2014-08-25 23:18:53 -04:00
Smith fa5daa7693 docs(guide/di): correct spelling behinds > behind
Closes #8749
2014-08-23 16:38:27 -04:00
Brian Ford 00456a8f93 docs(changelog): release notes for 1.2.23 superficial-malady 2014-08-22 15:56:49 -07:00
Brian Ford 0b3022e8e0 docs(changelog): release notes for 1.3.0-beta.19 rafter-ascension 2014-08-22 15:56:33 -07:00
Jeff Cross 456026eff1 fix(input): use lowercase method to account for undefined type 2014-08-22 00:41:02 -07:00
danrbergman 8ec3efd967 docs(guide/module): update tag in description
the reference to 'myApp' module changed in the example from <html> to a <div>. Updating description
to reflect the new <div> tag.

Closes #8720
2014-08-21 23:33:59 -04:00
danrbergman 8528781f85 docs(guide/module): make the use of ng-app explicit in example
Helpful for people new to Angular to see the ng-app declaration in context with the expression
example. This will help illustrate the "Important thing to notice" point which follows: "The
reference to myApp module in <html ng-app="myApp">. This is what bootstraps the app using your
module."

Closes #8673
2014-08-21 22:28:48 -04:00
Sekib Omazic 98f603722d fix(Angular): make Date comparison in equals() NaN-aware
Make angular.equals() Date comparison NaN-aware to prevent infinite digest errors when a dealy watched
date has an invalid value.

Closes #8650
Closes #8715
2014-08-21 21:17:46 -04:00
Caitlin Potter ebece0bcb9 fix(input): by default, do not trim input[type=password] values
Do not trim input[type=password] values

BREAKING CHANGE:

Previously, input[type=password] would trim values by default, and would require an explicit ng-trim="false"
to disable the trimming behaviour. After this CL, ng-trim no longer effects input[type=password], and will
never trim the password value.

Closes #8250
Closes #8230

Conflicts:
	src/ng/directive/input.js
2014-08-21 19:14:27 -04:00
Caitlin Potter 4b7398eeca chore(protractor): enable testing ng-app-included examples
/cc @petebacondarwin / @juliemr please review :>

Blocks #8673
Closes #8677
2014-08-21 18:55:12 -04:00
Casey Flynn 4e79decc30 docs($interval): fix typo in example
It's not "nis", it's "is"! 〜( ̄▽ ̄)〜

Closes #8711
2014-08-21 15:30:16 -04:00
Caitlin Potter 888b0f5400 fix(copy): clear array destinations correctly for non-array sources
Closes #8610
Closes #8702
2014-08-20 21:51:32 -04:00
Jeff Cross aaf9c5e598 fix(minErr): encode btstrpd error input to strip angle brackets
The $sanitize service was returning an empty string to the error page
because the input was usually a single html tag (sometimes it could be
`document`). This fix replaces angle brackets with html entities.

Closes #8683
2014-08-20 17:27:48 -07:00
Henrik Nyh 893d2f8000 docs(ngDisabled): clarify "don't do this" example
It's not clear until you read the whole thing that it's an explanation
of what *not* to do and why, so if you scan the page from the top, you
may use this bad solution.
2014-08-20 15:47:37 -07:00
Brian Ford effc98fdc9 fix(linky): handle quotes around email addresses
Closes #8520
2014-08-20 13:40:31 -07:00
mishoo78 64cdbf3ae9 docs(ngMock): note that inject/module helpers only defined for jasmine / mocha
Closes #8694
2014-08-20 13:44:24 -04:00
Ole Weitz 5bba892ffd docs($cacheFactory): prevent example breaking on key update
The example for $cacheFactory breaks when a user tries to update a value for a key.
Setting a new value for an existing key results in duplicate key entries in the key array, thus
breaking the ng-repeat directive. With this fix the key is only added if it isn't contained in the
cache.

Closes #8214
2014-08-20 10:49:14 -04:00
Izhaki ec27deacfd docs($compile): fix documentation for ?^ controller search
Fixed typo: 'parents parents' to 'parents'

Closes #8690
2014-08-20 09:32:20 -04:00
Caitlin Potter c6e4defcb6 fix($location): rewrite relative URI correctly if path==='/' in legacy html5Mode
Currently, legacy browsers get to use a clever scheme for resolving relative URIs in html5Mode,
and resolve the URI relative to $location.path().

Currently, $location.path() can be '/' under certain circumstances, which means that when we
split $location.path() on '/' and later join by '/' after adding another path component,
we end up with '//pathComponent'. $$rewrite fails to deal with this correctly, and effectively
the $location is never changed from the root path.

This CL corrects this by ensuring that the duplicate '/' situation does not occur when resolving
relative URIs.

Closes #8684
2014-08-19 21:31:20 -04:00
Caitlin Potter 74a7afcb31 fix($location): don't call indexOf() of undefined href attribute
Closes #7721
Closes #8681
2014-08-19 19:16:40 -04:00
Brian Ford 08cc6edd38 chore(jshint): add missing scripturl directive 2014-08-19 14:56:06 -07:00
Brian Ford 4f3870500d fix($sanitize): sanitize javascript urls with comments
Closes #8274
2014-08-19 14:16:01 -07:00
Marty Kane cd0507bc3a docs(guide/di): correct a few awkward sentences
Closes #8678
2014-08-19 16:51:45 -04:00
Izhaki 20eef05195 docs($compile): correct documentation for directive controller ^ notation
`^` searches the element and its parents, not exclusively the element's parents. This confuses
a lot of people :(

Closes #8622
2014-08-19 14:31:36 -04:00
Shahar Talmi a6d7b4bdbd docs(*): use @description instead of @returns for properties
Dgeni-packages was not actually rendering the `@returns` text.

Closes #8639
2014-08-19 14:26:06 -04:00
Baptiste Fontaine 5811c5c35b docs(ngBind): irrelevant text removed from ngBindHtml’s example
The ngBindHtml’s example had a copied line from ngBindTemplate’s that’s irrelevant here.

Closes #8668
2014-08-19 12:39:04 -04:00
Pawel Kozlowski e37e30e93f docs(orderBy): clarify expression usage in a predicate
Closes #8592
2014-08-18 13:32:21 -07:00
Tom Kadwill a0b8ab8d7d docs(tutorial/index): improve wording
Removed repetition of 'machine' and 'local machine'.
I think this change makes the sentence more concise
2014-08-18 13:23:56 -07:00
Jeff Sheets 129c53730c docs($http): correct link to "salt (cryptography)" wikipedia article
Closes #8654
2014-08-18 13:35:24 -04:00
Caitlin Potter 8695138aec docs(misc/contribute): fix syntax highlighting of URLS
Closes #8168
Closes #8169
2014-08-17 21:13:57 -04:00
Shahar Talmi ed56872bb2 fix(ngHref): remove attribute when empty value instead of ignoring
Closes #2755
2014-08-13 15:43:10 -07:00
Peter Bacon Darwin cb183433a0 chore(doc-gen): move e2e tests into docs folder
These tests didn't really fit in the test folder as the docs app is mostly
a separate entity from the AngularJS codebase.
2014-08-13 11:24:53 +01:00
Caitlin Potter 631fbda6a9 docs(CHANGELOG.md): fix typo, it's 1.2.22 not 1.2.2!
Whoops!
2014-08-12 16:53:05 -04:00
Caitlin Potter 4c33b56612 docs(CHANGELOG.md): add changelog for v1.3.0-beta.18 and v1.2.22
Closes #8581
2014-08-12 13:17:04 -04:00
rodyhaddad 93b0c2d892 feat($parse): allow for assignments in ternary operator branches
Closes #8512
Closes #8484
CLoses #5434

Conflicts:
	test/ng/parseSpec.js
2014-08-11 17:04:40 +01:00
Peter Bacon Darwin d262378b7c fix(jqLite): allow triggerHandler() to accept custom event
In some scenarios you want to be able to specify properties on the event
that is passed to the event handler. JQuery does this by overloading the
first parameter (`eventName`). If it is an object with a `type` property
then we assume that it must be a custom event.

In this case the custom event must provide the `type` property which is
the name of the event to be triggered.  `triggerHandler` will continue to
provide dummy default functions for `preventDefault()`, `isDefaultPrevented()`
and `stopPropagation()` but you may override these with your own versions
in your custom object if you wish.

In addition the commit provides some performance and memory usage
improvements by only creating objects and doing work that is necessary.

This commit also renames the parameters inline with jQuery.

Closes #8469
Closes #8505
2014-08-11 12:17:55 +01:00
Peter Bacon Darwin 7729c84ec7 test(docsAppE2E): check that param defaults are shown in docs
Closes https://github.com/angular/dgeni-packages/pull/58
2014-08-10 20:19:23 +01:00
Peter Bacon Darwin dffeef29d7 test(docsAppE2E): tighten CSS selector to only find one element 2014-08-10 20:19:23 +01:00
Peter Bacon Darwin 2e22588ccf chore(package.json): update to dgeni-packages 0.9.7 2014-08-10 17:43:23 +01:00
Caitlin Potter 0b0acb0342 fix($compile): make '='-bindings NaN-aware
Update parent and child scopes correctly when a '='-binding changes from a NaN value.

TBR by angular-core

Closes #8553
Closes #8554

Conflicts:
	test/ng/compileSpec.js
2014-08-10 03:32:13 -04:00
Eddie Hedges 18fc43e828 docs(guide): correct links to unit testing guides
Closes #8548
2014-08-09 14:01:54 -04:00
Caitlin Potter ed47d811e2 chore(travis): specify chrome m34 in protractor configuration
Closes #8541
2014-08-08 17:21:00 -04:00
Derrick Mar a84f9f6178 docs(tutorial/step-10): add mock image data to spec
Closes #8468
Closes #8535
2014-08-08 20:37:42 +01:00
Caitlin Potter 4fbbe1152e docs(http): don't use locale-specific uri for MDN link 2014-08-08 15:32:38 -04:00
Joey Yang df3d941c57 docs($http): fix broken markdown link in withCredentials description
Markdown typo in $http config documentation

Closes #7859
2014-08-08 15:29:50 -04:00
Juampy 2bd3214a55 docs(guide/migration): ngSanitize is out ng core at AngularJS 1.2.21
When using ngBindHTML directive, either ngSanitize or $sce must be used
or this will end in a non-trusted value error.

Closes #8519
2014-08-07 21:04:17 -04:00
James Kleeh fc2abef327 docs(guide/directive): explain how to require multiple controllers
Closes #8524
2014-08-07 15:14:39 +01:00
Andrew Silluron 76a0eb89fb docs($compile): fix typo 'default' spelling
Change spelling of 'defualt' to 'default'

Closes #8476
2014-08-04 18:48:29 -04:00
Caitlin Potter ee57b4c26b docs(CHANGELOG.md): add missing breaking change from 1.3.0-beta.14 2014-08-04 17:29:33 -04:00
Peter Bacon Darwin 29eaabc000 test(select): relax test for IE8 bug
There is a bug in IE8 (http://support.microsoft.com/kb/829907 and
http://yuilibrary.com/forum-archive/forum/viewtopic.php@p=14826.html):
when you clone an `<option>` element the selected attribute on the options
can become invalid.

This is not relevant to the proper behaviour of the `select` directive
since it uses `prop` not `attr` to store the selected status of each
option.

This test is only interested in there being at least on option with
the `selected` attribute, for conformance to accessibility guidelines.
So we can safely relax the test to check this rather than concerning
ourselves with which option actually has this attribute.

Fixes 79538afd7b
Closes #8465
2014-08-03 22:15:59 +01:00
Joseph Spencer 2a6081057f docs($resource): clarify the meaning of @ in paramDefaults
Closes #8457
2014-08-03 17:15:03 +01:00
Peter Bacon Darwin 79538afd7b fix(select): ensure that at least one option has the selected attribute set
Using `prop` to set selected is correct programmatically but accessibility
guidelines suggest that at least on item should have the `selected` attribute
set.

Closes #8366
Closes #8429

Conflicts:
	test/ng/directive/selectSpec.js
2014-08-03 16:37:32 +01:00
rodyhaddad bcfa64e77c chore(travis): rename fetch_bundle script and make it not abort a travis build if it fails
This is useful when the npm-bundle-deps server isn't running,
when the tar never gets served (there's a default timeout on the request),
or when the served file isn't a valid tar.
2014-08-01 19:14:48 -07:00
Peter Bacon Darwin b7a2deed30 docs(ngSubmit): add link to form docs to discourage double submission
Closes #6017
2014-07-31 21:27:04 +01:00
Ken Sheedlo 98ff901bda docs(error/$injector/unpr): inadvertently redefining a module can cause error
Closes #8421
2014-07-31 20:48:32 +01:00
k-funk 428b81cba9 docs($http): add link to $http.path()
Closes #8424
2014-07-31 13:43:48 +01:00
Danielle 5dae9c230e docs(ngMockE2E): remove repeated word
Closes #8411
2014-07-31 13:41:05 +01:00
winsontam c3fad1157e fix($location) don't rewrite location when clicking on "javascript:" or "mailto:" link
Previously, absent a specified target attribute, when clicking on an anchor tag with an href beginning
with either "javascript:" or "mailto:", the framework would rewrite the URL, when it ought not to.

With this change, the browser is prevented from rewriting if the URL begins with a case-insensitive match
for "javascript:" or "mailto:", optionally preceeded by whitespace.

Closes #8407
Closes #8425
Closes #8426
2014-07-31 07:31:33 -04:00
Peter Bacon Darwin 9242c580a1 refact(select): don't recreate selectedSet on every digest loop
In the case of a "multiple" select, the model value is an array, changes
to which don't get picked up by NgModelController as it only looks for
object identity change.

We were rebuilding the `selectedSet` (a hash map of selected items) from
the modelValue on every turn of the digest. This is not needed as we can
simply use `$watchCollection` directly on the `$modelValue` instead.
2014-07-31 07:14:14 +01:00
Peter Bacon Darwin c2860944c6 fix(select): do not update selected property of an option element on digest with no change event
The `render()` method was being invoked on every turn of the digest cycle,
which was inadvertently updating the DOM even when a `change` event had
not been triggered.

This change only calls the `render()` method when `ctrl.$render()` is called,
as part of the NgModelController` lifecycle and when the `modelValue` has
significantly changed.

Closes #8221
Closes #7715
2014-07-30 23:14:40 +01:00
Peter Bacon Darwin e9a00fbdc3 test(select): add extra expectations and comments for clarity 2014-07-30 23:14:40 +01:00
Erin Altenhof-Long d018ac2a9a test(select): add test of updating the model because of ng-change
A regression #7855 was introduced by
https://github.com/angular/angular.js/commit/dc149de9364c66b988f169f67cad39577ba43434
This test ensures that reverting that commit fixes this regression.
In the regression, changes to a bound model in ng-change were not propagated back to the view.

Test for #7855
2014-07-30 23:14:40 +01:00
Erin Altenhof-Long b770c353bc test(select): add test cases for selects with blank disabled options
An earlier commit dc149de936 caused an error where the first option of
a select would be skipped over if it had a blank disabled value. These tests demonstrate that with
that commit in place, blank disabled options are skipped in a select. When the commit is reverted,
the correct behavior is seen that the blank disabled option is still selected in both selects
marked with required and those that have optional choices.

Relates to #7715
2014-07-30 23:14:40 +01:00
Erin Altenhof-Long 812277c257 test(select): add test against updating selected property on digest with no change event
Commit dc149de936 was reverted to fix regressions #7715 and #7855.
This commit introduced this test case and a corresponding fix for preventing the update of the
selected property of an option element on a digest with no change event. Although the previous fix
introduced regressions, the test covers a valid issue and should be included.
2014-07-30 23:14:39 +01:00
Erin Altenhof-Long 61871da9de revert(select): avoid checking option element selected properties in render
This reverts commit dc149de936. That commit fixes a bug caused by
Firefox updating `select.value` on hover. However, it
causes other bugs with select including the issue described in #7715. This issue details how
selects with a blank disabled option skip to the second option. We filed a bug
with Firefox for the problematic behavior the reverted commit addresses
https://bugzilla.mozilla.org/show_bug.cgi?id=1039047, and alternate Angular fixes are being
investigated.

Closes #7715 #7855
2014-07-30 23:14:39 +01:00
Caitlin Potter 9ee075518f fix(ngSanitize): ensure html is a string in htmlParser()
Previously, $sanitize(nonString) would throw. Now, the type is converted to a string before any work
is done.

Closes #8417
Closes #8416
2014-07-30 13:34:14 -04:00
Misha Moroshko afe93eaff8 docs(dateFilter): fix milliseconds example
Closes #8389
2014-07-29 17:49:28 +01:00
Andrew Pham d8f94d1a3f docs(tutorial/step-2): warn reader not to minimise browser that Karma's running on
Closes #8386
2014-07-29 17:40:46 +01:00
Nathan Wiebe f53b53df22 docs(tutorial): clarify sentence in step 02
Separate two sentences with a period, and clarify the wording by making it less technical: "to the DOM"
vs "to the <body> tag".

Closes #8394
2014-07-29 11:42:15 -04:00
Shahar Talmi eab5731afc feat(http): allow caching for JSONP requests
Closes #1947
Closes #8356
2014-07-29 09:40:36 +01:00
Sergio Sanguanini 986c446aaf style(AngularPublic): add whitespace to jshint block
Closes #8360
2014-07-27 14:10:40 +01:00
rodyhaddad 60366c8d0b fix($parse): correctly assign expressions who's path is undefined and that use brackets notation
Closes #8039
2014-07-26 23:28:20 -07:00
Julie Ralph 494c8aa0b3 chore(ci): update sauce connect from 3 to 4.3 for the 1.2.x branch 2014-07-25 14:50:24 -07:00
Ivan Alvarez cd9459e129 docs(tutorial): update step_03.ngdoc
1) The original document is not clear to a new developer in where to place the code.
2) The query.clear() statement to clear the query before the second test is missing in the original document.
3) Refactored to use the query and phoneList variables in both tests, so its easier to read and understand.

Closes #7815
2014-07-25 14:26:49 -07:00
Mitch Robb 2862883bd8 docs(tutorial): update step7 ngdoc to fix grammar
This line was missing an 'as'

Previous:
We also have to add the modules dependencies of our app. By listing these two modules as dependencies of `phonecatApp`, ...

New:
We also have to add the modules *as* dependencies of our app.

Closes #8345
2014-07-25 14:12:59 -07:00
Jeff Cross bbb673a48a docs(changelog): release notes for 1.3.0-beta.17 and 1.2.21 2014-07-25 10:17:16 -07:00
Jeff Cross cd9afd9961 revert: fix(ngHref): remove attribute when empty value instead of ignoring
This reverts commit 948c86c602.

This commit caused tests to fail in IE8 due to a TypeError '0.childNodes is
null or not an object. The issue should be investigated and fixed. Issue #8340
has been opened to investigate.

See this job for failures: https://travis-ci.org/angular/angular.js/jobs/30792508
2014-07-25 09:01:43 -07:00
Shahar Talmi e25ed0d48d fix(angular.copy): clone regexp flags correctly
Closes #5781
Closes #8337
2014-07-25 16:40:14 +01:00
Peter Bacon Darwin cd6d21e78a docs(tutorial/step-2): note that ng-app now needs a module name
Closes #7655
2014-07-25 16:38:55 +01:00
TheMrSteve 9cf5b35e5c docs(tutorial/step-3): note that the server needs to be running before running Protractor
Closes #7142
2014-07-25 16:38:55 +01:00
Jeff Cross 5d11e02008 fix(docs): change plnkr form to open in same window
Form previously posted to target="_blank", but pop-up blockers were causing this to not work.
If a user chose to bypass pop-up blocker one time and click the link, they would arrive at
a new default plnkr, not a plnkr with the desired template.

This fix removes the _blank target, causing the plnkr to open in the current window/tab.
2014-07-24 14:37:49 -07:00
Chris Chua 209e600070 fix(jqLite): triggerHandler support unbind self
Fixes .one if the event is invoked from triggerHandler.

Closes #5984

Conflicts:
	test/jqLiteSpec.js
2014-07-24 13:50:28 -07:00
Igor Minar ceaca57786 revert: perf($parse): don't use reflective calls in generated functions
This reverts commit cbdf0c2afb.

The commit causes tests failures on IE8. I'm not quite sure why and I can't
investigate now.

Failed build: https://travis-ci.org/angular/angular.js/jobs/30756773
2014-07-24 09:07:57 -07:00
Igor Minar cbdf0c2afb perf($parse): don't use reflective calls in generated functions
Chrome and FF are smart enough to notice that the key is is a string literal, so this change doesn't
make a difference there. Safari gets a boost. I haven't tested IE, but it can't cause harm there. :)

http://jsperf.com/fn-dereferencing
2014-07-24 07:43:00 -07:00
Patrick Hallisey 1111076552 docs($resource): note methods list is non-exhaustive
The existing documentation for custom action methods implies that only a small
list of upper case methods can be used for custom $resource actions.
2014-07-23 15:02:44 -07:00
Shahar Talmi 948c86c602 fix(ngHref): remove attribute when empty value instead of ignoring
Closes #2755
2014-07-23 13:42:27 -07:00
Diego Plentz cd63ff497d docs(guide/concepts): update example
The "A first example: Data binding" section it implies that the `required` directive is
doing something, but it isn't.

I just removed the parts the refer to the required directive to avoid confusion.
2014-07-23 11:34:32 -07:00
Karl Yang 9d6240561b docs(tutorial): remove index.html from app url 2014-07-23 10:32:58 -07:00
Chad Smith 05b5245790 docs(guide): remove redundancy in providers guide
Highlighted the Best Practices section, and took the styling from the Services doc.
Also removed some superfluous wording that was in the "Provider Recipe"
2014-07-23 09:21:36 -07:00
Shahar Talmi e6ebfc87c9 refactor(Angular): add isPromiseLike helper function
This can be used internally to remove the repeating pattern of `obj && obj.then`. For now, I don't see a good reason to expose this in angular's public interface.

Conflicts:
	src/Angular.js
2014-07-22 16:35:02 -07:00
Julie Ralph 7f2bcc3933 chore(e2e): protractor version bump to 1.0 2014-07-22 15:29:00 -07:00
Igor Minar 492b0cdf28 perf(forEach): use native for loop instead of forEach for Arrays
Conflicts:
	src/Angular.js
2014-07-22 11:40:59 -07:00
hanstest 51863f80d7 docs(guide/directive): fix formatting 2014-07-22 10:34:08 -07:00
Peter Bacon Darwin 9d4000d689 docs(guide/$location): fix up example protractor tests
Closes #8255
2014-07-22 17:55:48 +01:00
vdyckn bc036c68ac docs(guide/$location) global cntl deprecated
Closes #8255
2014-07-22 17:55:48 +01:00
Shane Keller 580135a9cb docs(guide/scope): add missing period 2014-07-21 17:21:34 -07:00
Jason Hamm da0c5efa72 docs(guide/bootstrap): fix example 2014-07-21 16:53:43 -07:00
Vikram Soni c280d5ab02 Updated e2e spec to remove warning
on
element(by.css(.phones li a)).click();

selenium will throw a warning message that more then one element found.

element.all(by.css('.phones li a')).first().click(); fixes the issue
2014-07-21 16:10:42 -07:00
Jesse Palmer 28c8199cd6 docs(misc/faq): minor formatting fixes 2014-07-21 15:30:13 -07:00
garetht 0252a9889b docs($http) Clarify how to specify JSONP callback.
Make clear that it is the name of the callback that should be `JSON_CALLBACK`, instead of the current vague description.

Closes #8269
2014-07-21 14:55:15 -07:00
Trey Hunner 1c15cdc2d0 style: fix whitespace issues
Closes #8277

Conflicts:
	docs/content/guide/migration.ngdoc
2014-07-21 14:52:06 -07:00
Nick Van Dyck 0bd329d4fd docs(guide/concepts): use protocol relative URL
When accessing the docs from https, the "Accessing the backend example fails
because it contains a hard coded protocol. By making the URL protocol relative,
the example should work over http and https.
2014-07-21 14:45:16 -07:00
Trey Hunner 8db84a16db chore(.editorconfig): add .editorconfig file
Closes #8278
2014-07-21 14:43:59 -07:00
Igor Minar cffcfc73a0 style($http): fix indentation 2014-07-21 14:43:48 -07:00
Peter Bacon Darwin 25eb9b794f docs(ngMock) add @packageName tag to fix invalid module overview pages
Closes #7284
Closes #8038
2014-07-21 21:03:40 +01:00
Peter Bacon Darwin 6941779543 chore(package): update dgeni-package to v0.9.6
This version supports `@packageName` tag that will allow us to fix the docs
for ngMock and ngMockE2E
2014-07-21 21:03:40 +01:00
xi 65f40d2123 docs(ngBind): fix wording
You can not change the use of `{{}}`/`ngBind` based on the time when it is used.
So this should be "if".

Closes #7786
2014-07-18 15:54:57 -07:00
rodyhaddad e159f9626c chore(travis): get npm dependencies from npm-bundle-deps
npm-bundle-deps has been rewritten to be more robust
2014-07-18 15:37:20 -07:00
Peter Bacon Darwin 685a9d040d docs(indexPage): move latest versions to the top
Closes #7513
2014-07-18 22:04:08 +01:00
Igor Minar 8eede099cd perf(ngBindHtml): move addClass to the compile phase
Closes #8261

Conflicts:
	src/ng/directive/ngBind.js
2014-07-18 13:52:06 -07:00
Brian Ford a17d42d706 docs(changelog): release notes for 1.3.0-beta.16 pizza-transubstantiation 2014-07-18 12:21:28 -07:00
Carlo s A. Guillen 60af504c18 fix($location): handle plus character in query strings
Closes #3042
2014-07-18 08:37:59 -07:00
Peter Bacon Darwin 243d9ac72c docs(guide/module): add protractor tests 2014-07-18 11:12:49 +01:00
Peter Bacon Darwin cc8eb91665 style(guide/module): use dot first style when chaining 2014-07-18 11:12:49 +01:00
Nick Van Dyck 8697c3bf4c docs(guide/module) fixed global controller in example
Global controllers have been disallowed in Angular 1.3

Closes #8248
2014-07-18 11:12:49 +01:00
Jason Bedard 3c46c94342 perf(jqLite): expose the low-level jqLite.data/removeData calls
- updated the internal jqLite helpers to use the low-level jqLite.data/removeData to avoid unnecessary jq wrappers and loops
- updated $compile to use the low-level jqLite.data/removeData to avoid unnecessary jq wrappers at link time
2014-07-17 17:18:35 -07:00
Jason Bedard 71eb1901f6 perf($compile): only create jqLite object when necessary 2014-07-17 17:15:21 -07:00
Brian Ford 4e57e28589 docs(triaging): clarify severity and frequency labels 2014-07-17 12:32:23 -07:00
Peter Bacon Darwin 13289c0903 chore(package): update to latest dgeni-packages
This fixes an issue with HTML encoding HTML entities in code blocks
2014-07-17 13:05:00 +01:00
Julie Ralph afdb4f1b76 chore(ci): update protractor to 1.0.0-rc5 and increase global timeout for loading pages
This should help with occasional safari page load timeouts. In a test of
4500 page loads, the current 10 second limit caused 3 errors while a 30 second limit
caused none.

Closes #8231
2014-07-16 23:10:05 -07:00
Josh Schreuder e7999e7447 docs($interval): fix missing square brackets in example
Closes #8228
2014-07-16 20:42:43 -04:00
Caitlin Potter d175bb0131 fix(ngSanitize): follow HTML parser rules for start tags / allow < in text content
ngSanitize will now permit opening braces in text content, provided they are not followed by either
an unescaped backslash, or by an ASCII letter (u+0041 - u+005A, u+0061 - u+007A), in compliance with
rules of the parsing spec, without taking insertion mode into account.

BREAKING CHANGE

Previously, $sanitize would "fix" invalid markup in which a space preceded alphanumeric characters
in a start-tag. Following this change, any opening angle bracket which is not followed by either a
forward slash, or by an ASCII letter (a-z | A-Z) will not be considered a start tag delimiter, per
the HTML parsing spec (http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html).

Closes #8212
Closes #8193
2014-07-16 19:56:39 -04:00
Michał Gołębiowski fe1188daf3 refactor(jshint): reduce duplication & test all JS files
Conflicts:
	src/Angular.js
	src/AngularPublic.js
	src/jqLite.js
	src/ng/directive/input.js
2014-07-16 19:56:14 -04:00
Michał Gołębiowski e1a3a6251f chore(jshint): update grunt-contrib-jshint 2014-07-16 19:19:21 -04:00
Caitlin Potter 25d3d3730d revert: fix(ngSanitize): follow HTML parser rules for start tags / allow < in text content
This reverts commit 36d2658b94.

This commit broke the ci-checks task when ported into v1.2.x --- I will sort this out shortly.
2014-07-16 18:13:17 -04:00
Caitlin Potter af5aacce05 test(jqLite): make iframe contents() test less flaky 2014-07-16 17:47:57 -04:00
Paul Harris 3abd0fb93c test(filter): fix typo in descriptions
Two descriptions contain typo's to the word predicate.

Closes #8004
2014-07-16 17:05:01 -04:00
Caitlin Potter 36d2658b94 fix(ngSanitize): follow HTML parser rules for start tags / allow < in text content
ngSanitize will now permit opening braces in text content, provided they are not followed by either
an unescaped backslash, or by an ASCII letter (u+0041 - u+005A, u+0061 - u+007A), in compliance with
rules of the parsing spec, without taking insertion mode into account.

BREAKING CHANGE

Previously, $sanitize would "fix" invalid markup in which a space preceded alphanumeric characters
in a start-tag. Following this change, any opening angle bracket which is not followed by either a
forward slash, or by an ASCII letter (a-z | A-Z) will not be considered a start tag delimiter, per
the HTML parsing spec (http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html).

Closes #8212
Closes #8193
2014-07-16 16:59:04 -04:00
Izhaki 6ce5a04d42 docs($compile): fix template and replace properties' docs
Closes #8062
2014-07-16 13:43:05 -07:00
Caitlin Potter 929064d9e4 test($http): ignore date-toJSON test if running in IE8
IE8 does not implement Date.prototype.toISOString(), which is necessary for this feature. The
feature still works if this method is polyfilled, but these tests are not run with polyfills.
2014-07-16 12:06:48 -04:00
Caitlin Potter d0b873a4b7 revert: chore(travis): get npm dependencies from npm-bundle-deps
This commit was causing some issues with CI testing, so it's being temporarily removed until that's
resolved.

This reverts commit 8881606cd9.
2014-07-16 11:34:43 -04:00
Almar 2e10659472 docs(misc core): fixed broken angular.copy example
The module was not being registered, and this broke the example for who knows how long!

Closes #8218
2014-07-16 11:30:38 -04:00
Max 2a8493f40c docs(guide/forms): fix controller name in example
The "Binding to form and control state" sample had the wrong controller name

Closes #8206
2014-07-16 11:16:38 +01:00
Dan Barua 2f960f1530 fix($http): fix double-quoted date issue when encoding params
This commit special cases date handling rather than calling toJSON as we always need
a string representation of the object.

$http was wrapping dates in double quotes leading to query strings like this:
  ?date=%222014-07-07T23:00:00.000Z%22

Closes #8150
Closes #6128
Closes #8154
2014-07-15 17:18:38 -07:00
rodyhaddad 3f5f20fe77 chore(travis): get npm dependencies from npm-bundle-deps 2014-07-15 17:09:51 -07:00
Christian 01387c0a8f docs(orderBy filter): fix controller name in example
Closes #8133
Closes #8206
2014-07-15 17:57:03 +01:00
rodyhaddad c0afbfaca5 fix(select): force visual update in IE
IE9, IE10 and IE11 would always show the first <option> as
selected when the user moves from a null <option>
to a non-null one in a non-null <select>.
Even though the model was being updated correctly,
visually, the first <option> always appeared selected.

Setting the `selected` property twice in a row
seems to fix it in all the three versions mentioned above.

Closes #7692
Closes #8158
2014-07-15 09:47:22 -07:00
Shahar Talmi bf13d2683d fix($rootScope): $watchCollection should handle NaN in objects
This fixes a potential infinite digest in $watchCollection when one of the values is NaN. This was previously fixed for arrays, but needs to be handled for objects as well.

Closes #7930
2014-07-15 09:45:13 -07:00
Peter Bacon Darwin fe01a85a8e style(orderBySpec): fix indentation 2014-07-15 14:29:25 +01:00
Peter Bacon Darwin 6b9a332959 style($route): convert tab indent to spaces 2014-07-15 14:01:09 +01:00
Sekib Omazic f1b28847c8 fix(orderBy): correctly order by date values
Closes #6675
Closes #6746
2014-07-15 13:41:27 +01:00
Jason Miller 1b779028fd fix(ngRoute): remove unnecessary call to decodeURIComponent
Since `$location.$$path` is already decoded, doing an extra `decodeURIComponent` is both unnecessary
and can cause problems. Specifically, if the path originally includes an encoded `%` (aka `%25`),
then ngRoute will throw "URIError: URI malformed".

Closes #6326
Closes #6327
2014-07-15 13:24:40 +01:00
Wladimir Coka 49b2a1c8cf refactor($parse): improve readability on conditional assignment
Use logical OR operator instead of if statement

Closes #5065
2014-07-15 12:49:00 +01:00
Wladimir Coka 3e82492fc6 refactor($http): improve readability on conditional assignment
Use ternary operator instead of if statement

Closes #5065
2014-07-15 12:48:48 +01:00
Wladimir Coka 856be44628 refactor(dateFilter): improve readability on conditional assignment
Use ternary operator instead of if statement

Closes #5065
2014-07-15 12:48:39 +01:00
Wladimir Coka dbb21b1531 refactor($compile): improve readability on conditional assignment
Use ternary operator instead of if statement

Closes #5065
2014-07-15 12:48:09 +01:00
Peter Bacon Darwin 3ce56b739c docs(guide/unit-testing): add info on testing element transclude directives
Closes #4505
Closes #8197
2014-07-15 12:40:26 +01:00
Bill Neubauer ecbb374826 docs(tutorial/step-9): link to list of filters rather than filterProvider
Closes #8082
2014-07-15 12:40:26 +01:00
Igor Minar 0e5d31908e fix(csp): fix autodetection of CSP + better docs
CSP spec got changed and it is no longer possible to autodetect if a policy is
active without triggering a CSP error:

https://github.com/w3c/webappsec/commit/18882953ce2d8afca25f685557fef0e0471b2c9a

Now we use `new Function('')` to detect if CSP is on. To prevent error from this
detection to show up in console developers have to use the ngCsp directive.

(This problem became more severe after our recent removal of `simpleGetterFn`
 which made us depend on function constructor for all expressions.)

Closes #8162
Closes #8191
2014-07-14 17:20:06 -07:00
standup75 f1b0d21f97 docs(ngAnimate): ensure the CSS breakdown example uses a compound selector 2014-07-14 11:29:35 -04:00
Igor Minar 58e94dcde9 docs($parse:isecdom): add a section about return values and CoffeeScript
Closes #7973
2014-07-12 20:24:20 -07:00
Erin Altenhof-Long eba192b863 docs(CHANGELOG): add v1.3.0-beta.15 and v1.2.20 changes 2014-07-11 11:26:39 -07:00
rodyhaddad 75099e6137 chore($parse): remove simpleGetter optimizations as they're no longer valid
Closes #8101
2014-07-10 15:17:41 -07:00
perek 172a40931b fix($http) - add ability to remove default headers
Fixes #5784
Closes #5785
2014-07-10 14:38:19 -07:00
Igor Minar 23e5109b64 chore(travis): disable our npm registry cache 2014-07-09 06:43:05 -07:00
Michał Gołębiowski cc84ce3bf5 chore(travis): disable npm spinner & enable HTTP logs; run npm install twice
It's good to have HTTP logs on Travis for debugging purposes and the spinner
doesn't integrate with Travis very well & messes the output.
2014-07-09 12:42:57 +02:00
Michał Gołębiowski bee2d1fbb9 chore(travis): declare Node.js version as '0.10', not 0.10 (which is 0.1) 2014-07-09 11:45:17 +02:00
fuqcool 7101a02c93 docs(error/$sce/insecurl): fix links to $sce and $sceDelegateProvider 2014-07-08 22:40:06 -07:00
Julie Ralph 888be00712 chore(tests): fix warning about a non-unique element locator in e2e tests 2014-07-08 16:28:12 -07:00
Julie Ralph 05597c24c7 chore(e2e): update protractor to 1.0.0-rc4
This change contains a stability improvement to use data URLs instead of
about:blank for resetting the URL.
2014-07-08 16:22:52 -07:00
Domenico Matteo bf55f23325 docs(guide/i18n): fix typo 2014-07-08 03:35:04 -07:00
Brian Ford ab051e78ea docs(select): update example to use a module 2014-07-08 02:32:21 -07:00
Brian Ford 87d46a84c3 docs(guide/expression): update examples to use modules 2014-07-08 02:32:21 -07:00
Brian Ford ae764f1844 docs(linky): update example to use a module 2014-07-08 02:32:21 -07:00
Brian Ford ad8092ed80 docs(angular.copy): update example to use a module 2014-07-08 02:32:21 -07:00
Brian Ford 55e1b3e1c8 docs($sanitize): update example to use a module 2014-07-08 02:32:20 -07:00
Brian Ford 6f465a2b26 docs(guide/scope): update examples to use modules 2014-07-08 02:32:20 -07:00
Brian Ford 3ecac62251 docs(guide/forms): update examples to use modules 2014-07-08 02:32:20 -07:00
Brian Ford c64610269d docs($location): update example to use a module 2014-07-08 02:32:20 -07:00
Brian Ford 5c2302949b docs($cookies): update examples to use modules 2014-07-08 02:32:20 -07:00
Brian Ford 7c84e2632f docs(orderBy): update examples to use modules 2014-07-08 02:32:20 -07:00
Brian Ford 18d18f07db docs(limitTo): update example to use a module 2014-07-08 02:32:20 -07:00
Brian Ford 9f5be534fc docs(ngTransclude): update example to use a module 2014-07-08 02:32:20 -07:00
Brian Ford 1cd7912614 docs($log): update example to use a module 2014-07-08 02:32:19 -07:00
Brian Ford 514da451fc docs(ngPluralize): update example to use a module 2014-07-08 02:32:19 -07:00
Brian Ford 2788cc4e12 docs(ngSwitch): update example to use a module 2014-07-08 02:32:19 -07:00
Brian Ford 7f6322df6a docs(ngInit): update example to use a module 2014-07-08 02:32:19 -07:00
Brian Ford 5bd8613168 docs(ngValue): update example to use a module 2014-07-08 02:32:19 -07:00
Brian Ford 32b507890e docs(ngList): update example to use a module 2014-07-08 02:32:19 -07:00
Brian Ford bfedafdede docs(ngInclude): update example to use a module 2014-07-08 02:32:19 -07:00
Brian Ford cdefbe3425 docs($interval): update example to use a module 2014-07-08 02:32:19 -07:00
Brian Ford f75f4bce82 docs(filters): update examples to use modules 2014-07-08 02:32:19 -07:00
Brian Ford 4349de3d41 docs(ngController): update examples to use modules 2014-07-08 02:32:18 -07:00
Brian Ford df545d7eed docs($window): update example to use a module 2014-07-08 02:32:18 -07:00
Brian Ford 3b5f346314 docs(ngSubmit): update example to use a module 2014-07-08 02:32:18 -07:00
Brian Ford 3aab87b381 docs(ngBind): update examples to use modules 2014-07-08 02:32:18 -07:00
Brian Ford 0973175058 docs($http): update example to use a module 2014-07-08 02:32:18 -07:00
Brian Ford 112da45c07 docs($document): update example to use a module 2014-07-08 02:32:18 -07:00
Brian Ford e3dc85841d docs(ngChange): update example to use a module 2014-07-08 02:32:18 -07:00
Brian Ford ef1c352bc9 docs(ngModel): update examples to use modules 2014-07-08 02:32:18 -07:00
Brian Ford a5b6444324 docs(formDirective): update example to use a module 2014-07-08 02:32:17 -07:00
Brian Ford dd18c00b1d docs($compile): update example to use a module 2014-07-08 02:32:17 -07:00
Shahar Talmi a0fad24dc2 chore(jshint): enforce jshint for tests
Closes #8023
Closes #8026
2014-07-08 00:34:50 -07:00
Shahar Talmi da0e3c99f5 fix(input): escape forward slash in email regexp
This messed up with syntax coloring and variable hovering in chrome developer tools and made debugging really difficult.

Closes #8096
2014-07-07 16:26:27 -04:00
Julie Ralph a41c58e285 chore(tests): increase timeout for navigation in ng-href tests to avoid timeouts
Previously, the timeout for ng-href tests waiting for the url change after a link
was clicked was only 1000 ms. This was causing some flaky timeouts, so increasing
the wait to 5000 ms.
2014-07-07 11:21:33 -07:00
Julie Ralph bce5b49133 chore(e2e): update protractor to 1.0.0-rc2 and add more logging
Use the new options from the reporter to add more logging to end to end tests,
and increase the Jasmine test timeout from 30 seconds to 60 seconds to allow for
legitimately long-lasting tests.
2014-07-07 11:07:48 -07:00
Kevin Brogan 816b84230c fix(input): modify email validation regexp to match rfc1035
Previously, domain parts which began with or ended with a dash, would be accepted as valid. This CL matches Angular's email validation with that of Chromium and Firefox.

Closes #6026
2014-07-07 13:51:58 -04:00
Caitlin Potter 873acf8fab fix(parseKeyValue): ignore properties in prototype chain.
Previously, properties (typically functions) in the prototype chain (Object.prototype) would shadow
query parameters, and cause them to be serialized incorrectly.

This CL guards against this by using hasOwnProperty() to ensure that only own properties are a concern.

Closes #8070
Fixes #8068
2014-07-03 21:58:10 -04:00
Matias Niemelä 9063a0c2e7 chore(ngAnimate): fix broken IE8 tests for ngAnimateChildren 2014-07-04 02:14:57 +03:00
Chris Kuehl 03cbc0d6b1 docs(error/$rootScope/inprog): fix $timeout typo
Closes #8071
2014-07-03 17:33:02 -04:00
Matias Niemelä 931789ec14 feat(ngAnimate): conditionally allow child animations to run in parallel with parent animations
By default ngAnimate prevents child animations from running when a parent is performing an animation.
However there are a cases when an application should allow all child animations to run without blocking
each other. By placing the `ng-animate-children` flag in the template, this effect can now be put to
use within the template.

Closes #7946
2014-07-03 19:35:17 +03:00
Peter Bacon Darwin 9bc807783f docs($httpProvider): revert removal of comments
Related to #7782
2014-07-03 13:29:24 +01:00
Cory Boyd 2d6ee651b1 docs($httpProvider): add missing documentation
Add documentation for $httpProvider default values

Closes #6682
2014-07-03 13:24:48 +01:00
Peter Bacon Darwin 7ca24a8264 chore(docs/css): add margin between ul and p elements
Bootstrap CSS was removing the margin after ul elements if they were
descendents of other ul elements. But if the ul was followed by a p
then this looked terrible.

Related to #5953
2014-07-03 12:51:21 +01:00
Peter Bacon Darwin 1d8e42070a docs(tutorial/step-0): remove hyphen and clarify items
Closes #5953
2014-07-03 12:51:21 +01:00
Robert Kielty fe6b2fbfc4 docs(tutorial/step-7): improve injector information
I attempted to tighten up the language around the DI overview so that it was clearer
and more explicit. The sole responsibilities sentence was semantically jarring and
I think looks better as a list.  Some minor grammar improvements.

Closes #7099
2014-07-03 12:24:15 +01:00
Peter Bacon Darwin 5a222244fb docs(guide/controller): tweak initial example 2014-07-03 12:13:49 +01:00
cranesandcaff 4026074aba docs(guide/controller): only show best practice controller creation
If it is not recommended to use a global function to create controllers,
why should it be shown as possible in the documentation?

One of the most common complaints about AngularJS is that it doesn't enforce
any convention. This is intentional and I generally like this.
However if we can avoid outright bad implementations in examples I believe
we should.

Closes #8011
2014-07-03 12:13:49 +01:00
Peter Bacon Darwin d9a596addd docs(guide/di): further clarification of what can be injected 2014-07-03 10:13:58 +01:00
Artiom Neganov 8c0898b21c docs(guide/di): clarify what "services" can be injected into .config() and .run()
Closes #8106
2014-07-03 10:13:58 +01:00
Mike Haas d9b693bb7a docs($compile): fix minor typo
Closes #8048
2014-07-03 09:51:40 +01:00
Peter Bacon Darwin da94ab2e63 docs($logProvider): debugEnabled is a method not a property
Closes #7824
2014-07-03 09:51:40 +01:00
Peter Bacon Darwin 2fd8dc7061 docs($sce): fix code samples and example
The code samples were using `<pre>` tags rather than code fences (```) so they were
not being displayed correctly.

The inline code example (defined by a `<example>` element) had been placed in an
`@example` jsdoc tag, so rather than appearing inline at the declaration point in
the text, they were being appended to the end of the document in the `Example` section.

Closes #8053
2014-07-03 07:05:32 +01:00
Caitlin Potter 01012a4d7a chore(watchr-docs): remove watchr-docs.rb
This file hasn't changed in forever, and doesn't seem to be in use any longer.

Closes #7978
2014-07-02 17:59:58 -04:00
jpsimons ce84429adf docs($location): update $location.search() jsdoc signature
Closes #8050
2014-07-02 13:55:24 -07:00
Sekib Omazic a26acb64fe fix($location): remove query args when passed in object
Query args will be removed from $location search object if they are passed in as null or undefined object properties

Closes #6565
2014-07-01 08:41:15 -07:00
Igor Minar 7088ed1ed3 docs($parse): add missing 'isecobj' error page 2014-07-01 06:36:50 -07:00
Martin Staffa 7027844d42 fix($http): don't remove content-type header if data is set by request transform
Fixes #7910
2014-06-30 16:58:15 -07:00
Carlo s A. Guillen 16c584ed7f docs(CHANGELOG.md): add changes for 1.3.0-beta.14 and 1.2.19 2014-06-30 16:58:15 -07:00
Michał Gołębiowski b586bfdfab fix(testabilityPatch): fix invocations of angular.mock.dump 2014-06-30 16:58:15 -07:00
Igor Minar 1d69015e3d test($parse): skip Function.prototype.bind test on IE8 2014-06-30 11:22:41 -07:00
Igor Minar f13c33bf10 fix($parse): don't check Function.prototype.bind when it doesn't exist
e.g. IE8 doesn't have it
2014-06-30 11:15:39 -07:00
Igor Minar ba62e975f1 fix($parse): make the window check in ensureSafeObject IE8 friendly 2014-06-30 11:06:18 -07:00
rodyhaddad b89d941cdf style(parseSpec): make jshint happy 2014-06-30 10:50:02 -07:00
rodyhaddad 07fa87a8a8 fix($parse): prevent invocation of Function's bind, call and apply
BREAKING CHANGE:
You can no longer invoke .bind, .call or .apply on a function in angular expressions.
This is to disallow changing the behaviour of existing functions
in an unforseen fashion.
2014-06-30 10:43:29 -07:00
rodyhaddad 0af70eb99e refactor($parse): move around previous security changes made to $parse 2014-06-30 10:40:24 -07:00
Jann Horn cb713e6045 fix($parse): forbid __proto__ properties in angular expressions
__proto__ can be used to mess with global prototypes and it's
deprecated. Therefore, blacklisting it seems like a good idea.

BREAKING CHANGE:
The (deprecated) __proto__ propery does not work inside angular expressions
anymore.
2014-06-30 09:32:38 -07:00
Jann Horn 89ca859734 fix($parse): forbid __{define,lookup}{Getter,Setter}__ properties
It was possible to use `{}.__defineGetter__.call(null, 'alert', (0).valueOf.bind(0))` to set
`window.alert` to a false-ish value, thereby breaking the `isWindow` check, which might lead
to arbitrary code execution in browsers that let you obtain the window object using Array methods.
Prevent that by blacklisting the nasty __{define,lookup}{Getter,Setter}__ properties.

BREAKING CHANGE:
This prevents the use of __{define,lookup}{Getter,Setter}__ inside angular
expressions. If you really need them for some reason, please wrap/bind them to make them
less dangerous, then make them available through the scope object.
2014-06-30 09:29:53 -07:00
Jann Horn bc6fb7cc94 fix($parse): forbid referencing Object in angular expressions
It was possible to run arbitrary JS from inside angular expressions using the
`Object.getOwnPropertyDescriptor` method like this since commit 4ab16aaa:
    ''.sub.call.call(
      ({})["constructor"].getOwnPropertyDescriptor(''.sub.__proto__, "constructor").value,
      null,
      "alert(1)"
    )()
Fix that by blocking access to `Object` because `Object` isn't accessible
without tricks anyway and it provides some other nasty functions.

BREAKING CHANGE:
This prevents the use of `Object` inside angular expressions.
If you need Object.keys, make it accessible in the scope.
2014-06-30 09:26:29 -07:00
Kristian Hellang 0c80df21b6 fix($http): should not read statusText on IE<10 when request is aborted
Commit 1d2414c introduced a regression by retrieving the statusText
of an aborted xhr request. This breaks IE9, which throws a c00c023f
error when accessing properties of an aborted xhr request. The fix
is similar to the one in commit 6f1050d.
2014-06-30 08:09:59 -07:00
vaibhav kohli 3141dbf179 style(Angular.js): remove extra whitespace 2014-06-29 09:42:34 -07:00
Archer aad502bad8 docs(guide/$location): fix a typo
Change "window.location.path" to "window.location.pathname".

Closes #8012
2014-06-28 20:05:32 -07:00
Elnur Abdurrakhimov dca8972367 docs(Getting Started): fix typo
Closes #8015
2014-06-28 19:42:02 -07:00
rodyhaddad 284de57435 test($interval): add tests making sure $interval uses the methods from $window 2014-06-28 17:35:14 -07:00
Praveen f780ccfa1c fix($interval): when canceling, use clearInterval from $window instead of global scope.
In $interval.cancel, use clearInterval from the $window service instead of from global scope.
The variable clearInterval declared above isn't visible here.
2014-06-28 17:35:06 -07:00
Efthymis Sarbanis 55f99e0710 chore: use triple equals comparison with typeof operator.
It is common practice for typeof operator to be used with '==='.

Closes #8009
2014-06-27 16:53:32 -07:00
Domenic Denicola 1a99ca9c08 docs($q): remove unnecessary $scope.apply wrapping
As of Angular 1.2, this kind of thing is no longer necessary (thank goodness!)
2014-06-26 12:37:04 -07:00
Laurent Curau 37500fca83 docs(guide/unit-testing): correct spelling 2014-06-26 12:37:04 -07:00
rodyhaddad 4fe4fc5abf chore(ngMock): replace misplaced comma with semicolon 2014-06-26 12:32:51 -07:00
rodyhaddad 74e1cc683b fix(jqLite): change expando property to a more unique name
This was causing issue when element === window
A better strategy can be thought of later on.
2014-06-26 12:32:30 -07:00
Igor Minar a4faa5cde7 perf(jqLite): don't use reflection to access expandoId
Since we allow only one copy of Angular to be loaded at a time it doesn't
make much sense randomly generate the expando property name and then be
forced to use slow reflective calles to retrieve the IDs.
2014-06-26 12:32:30 -07:00
Eddie Hedges 32cb40b86d docs(guide/introduction): use durandal as an example of a framework
To me knockout is a library that does data binding well.
Durandal is a framework that uses knockout as it's data binding component.
2014-06-26 12:19:56 -07:00
m-tretyak d1cd677433 docs(srcset): fix mistake in example 2014-06-26 12:08:55 -07:00
thorn0 43c735a816 docs($location): hashPrefix, html5Mode are methods
Closes #7915
2014-06-25 14:48:19 -07:00
Caitlin Potter ab2e83c8c8 fix(input): improve html5 validation support
This CL improves mocking support for HTML5 validation, fixes the behaviour which invokes validators.

Previously, an input would only be revalidated if either its value changed, or if it was the empty
string but did not suffer from bad input --- now, it will be revalidated if either the value has
changed, or the value is the empty string, there is a ValidityState for the element, and that
ValidityState is being tested by one of the validators in the pipeline.

Closes #7937
Closes #7957
2014-06-24 08:35:47 -04:00
Igor Minar e5f454c8af fix(numberFilter): correctly round fractions despite floating-point arithmetics issues in JS
Closes #7870
Closes #7878
2014-06-24 00:37:50 -07:00
Igor Minar 67c11b9a39 fix($injector): check if a fn is an array explicitly
This change makes the code easier to read and also fixes a compatibility issue
with opal.js which pollutes the global state by setting $inject property on
Array prototype

Closes #7904
Closes #2653
2014-06-23 17:20:09 -07:00
Zacky Ma 5a306b7ba3 docs(guide/compiler): change {{user}} to {{user.name}} in example
If user has an `actions` property, it should be an object,
which means if you {{user}}, it'll print out the object.
2014-06-23 13:36:04 -07:00
ephigabay 8ce61bf178 docs(ngModelController): update setValidity
Needs to be `$error[validationErrorKey]!=isValid` and not
`$error[validationErrorKey]=isValid`.

See https://github.com/angular/angular.js/blob/master/src/ng/directive/input.js#L1627

Closes #7934
2014-06-23 13:21:44 -07:00
Chaker Nakhli 9d452bc845 docs(ngSrc): srcset used instead of src for img attribute
In `ngSrc` documentation `srcset` is used instead of `src` as `img` element attribute in the example.

Closes #7951
2014-06-23 13:15:03 -07:00
Julie 192fecc790 chore(grunt): check files in src for ddescribe/iit
Previously, only files in test/ were checked. This does not capture
end to end tests, which are in comments in src/.
2014-06-23 11:28:21 -07:00
Julie 32be6369e4 chore(tests): remove a lingering iit in end to end tests 2014-06-23 11:22:37 -07:00
Shahar Talmi 2a45cea0ba fix(input): escape forward slash in email regexp
This messed up with syntax coloring and variable hovering in chrome developer tools and made debugging really difficult.

Closes #7938
2014-06-22 21:28:55 -04:00
Peter Bacon Darwin ea653e4cdd docs($provide): it is a service not an object
Closes #7917
2014-06-20 17:01:10 +01:00
Alex Muntada 03777445e8 docs(tutorial/step-4): fix e2e test
After a protractor update the test syntax had to be changed.

Closes #7919
2014-06-20 14:36:13 +01:00
Neil Giarratana 8b25ea129a docs(ngPluralize): spell Mary's name correctly
Update ngPluralize.js

Just a silly change to the name of one of the examples that appears to be a typo. Changing Marry to
Mary as the first would be a verb and the latter would be an extremely common name.

Closes #7884
2014-06-17 17:44:17 -04:00
Shahar Talmi d71f16e745 fix(injector): allow multiple loading of function modules
Change HashMap to give $$hashKey also for functions so it will be possible to load multiple module
function instances. In order to prevent problem in angular's test suite,  added an option to HashMap
to maintain its own id counter and added cleanup of $$hashKey from all module functions after each
test.

Before this CL, functions were added to the HashMap via toString(), which could potentially return
the same value for different actual instances of a function. This corrects this behaviour by
ensuring that functions are mapped with hashKeys, and ensuring that hashKeys are removed from
functions and objects at the end of tests.

In addition to these changes, the injector uses its own set of UIDs in order to prevent confusingly
breaking tests which expect scopes or ng-repeated items to have specific hash keys.

Closes #7255
2014-06-16 20:45:49 -04:00
Jason Bedard ed59370d80 fix($compile): bind ng-attr-* even if unbound attribute follows ng-attr-*
Previously, <element ng-attr-foo="{{binding}}" foo="bar"></element>'s "foo" attribute would always
equal "bar", because the bound version was overwritten. This CL corrects this behaviour and ensures
that the ordering of attributes does not have an effect on whether or not ng-attr-bound attributes
do their work.
2014-06-16 20:35:13 -04:00
Ahmad Moussawi d8e5acfe27 docs($sce): update the parseAs method name 2014-06-16 13:46:02 -07:00
James Harrison Fisher af59f4e69a docs(ngMock): fix typo providers -> provides
Should be a verb, ☆.。.:・゜☆MERCI BEAUCOUP☆.。.:・゜☆
2014-06-16 11:47:45 -04:00
Colin Casey 24aee81634 refact(select): use prop to modify the select property
jQuery suggests using `prop` rather than `attr` to modify the `select` property of an element.
You can see the full list of migration warnings for jQuery:
https://github.com/jquery/jquery-migrate/blob/master/warnings.md

Closes #4107
Closes #4122
2014-06-14 17:28:12 +01:00
rodyhaddad f81d56e66c docs(CHANGELOG.md): add changes for 1.2.18 2014-06-13 14:52:28 -07:00
1050 changed files with 106710 additions and 16306 deletions
-4
View File
@@ -1,4 +0,0 @@
{
"directory": "bower_components",
"json": "bower.json"
}
+21
View File
@@ -0,0 +1,21 @@
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[src/ngLocale/**]
insert_final_newline = false
[dropdown-toggle.js]
trim_trailing_whitespace = false
insert_final_newline = false
[htmlparser.js]
insert_final_newline = false
+2 -2
View File
@@ -9,10 +9,10 @@ performance/temp*.html
*.swp
angular.js.tmproj
/node_modules/
/components/
/bower_components/
bower_components/
angular.xcodeproj
.idea
*.iml
.agignore
libpeerconnection.log
npm-debug.log
+2
View File
@@ -0,0 +1,2 @@
node_modules/**
lib/htmlparser/**
+5
View File
@@ -0,0 +1,5 @@
{
"extends": ".jshintrc-base",
"node": true,
"globals": {}
}
+19
View File
@@ -0,0 +1,19 @@
{
"bitwise": true,
"immed": true,
"newcap": true,
"noarg": true,
"noempty": true,
"nonew": true,
"trailing": true,
"maxlen": 200,
"boss": true,
"eqnull": true,
"expr": true,
"globalstrict": true,
"laxbreak": true,
"loopfunc": true,
"sub": true,
"undef": true,
"indent": 2
}
+35 -12
View File
@@ -1,6 +1,13 @@
language: node_js
sudo: false
node_js:
- 0.10
- '4.2'
cache:
directories:
- node_modules
- bower_components
- docs/bower_components
branches:
except:
@@ -8,31 +15,47 @@ branches:
env:
matrix:
- JOB=unit
- JOB=e2e TEST_TARGET=jqlite
- JOB=e2e TEST_TARGET=jquery
- JOB=e2e TEST_TARGET=doce2e
- JOB=ci-checks
- JOB=unit BROWSER_PROVIDER=saucelabs
- JOB=docs-e2e BROWSER_PROVIDER=saucelabs
- JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=saucelabs
- JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=saucelabs
global:
- CXX=g++-4.8 # node 4 likes the G++ v4.8 compiler
- SAUCE_USERNAME=angular-ci
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
- LOGS_DIR=/tmp/angular-build/logs
- BROWSER_PROVIDER_READY_FILE=/tmp/sauce-connect-ready
- BROWSER_PROVIDER_READY_FILE=/tmp/browsersprovider-tunnel-ready
# node 4 likes the G++ v4.8 compiler
# see https://docs.travis-ci.com/user/languages/javascript-with-nodejs#Node.js-v4-(or-io.js-v3)-compiler-requirements
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
install:
- npm config set registry http://23.251.144.68
# 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_script:
- mkdir -p $LOGS_DIR
- ./lib/sauce/sauce_connect_setup.sh
- npm install -g grunt-cli
- grunt package
- ./scripts/travis/wait_for_browser_provider.sh
- ./scripts/travis/before_build.sh
script:
- ./scripts/travis/build.sh
after_script:
- ./scripts/travis/tear_down_browser_provider.sh
- ./scripts/travis/print_logs.sh
notifications:
+2713
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -65,13 +65,13 @@ Help us to maximize the effort we can spend fixing issues and adding new
features, by not reporting duplicate issues. Providing the following information will increase the
chances of your issue being dealt with quickly:
* **Overview of the issue** - if an error is being thrown a non-minified stack trace helps
* **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
* **Motivation for or Use Case** - explain why this is a bug for you
* **Angular Version(s)** - is it a regression?
* **Browsers and Operating System** - is this a problem with all browsers or only IE8?
* **Reproduce the error** - provide a live example (using [Plunker][plunker] or
* **Reproduce the Error** - provide a live example (using [Plunker][plunker] or
[JSFiddle][jsfiddle]) or a unambiguous set of steps.
* **Related issues** - has a similar issue been reported before?
* **Related Issues** - has a similar issue been reported before?
* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
causing the problem (line of code or commit)
@@ -119,7 +119,7 @@ Before you submit your pull request consider the following guidelines:
```
* In GitHub, send a pull request to `angular:master`.
* If we suggest changes then
* If we suggest changes then
* Make the required updates.
* Re-run the Angular test suite to ensure tests are still passing.
* Rebase your branch and force push to your GitHub repository (this will update your Pull Request):
@@ -172,7 +172,7 @@ To ensure consistency throughout the source code, keep these rules in mind as yo
* **Do not use namespaces**: Instead, wrap the entire angular code base in an anonymous closure and
export our API explicitly rather than implicitly.
* Wrap all code at **100 characters**.
* Instead of complex inheritance hierarchies, we **prefer simple objects**. We use prototypical
* Instead of complex inheritance hierarchies, we **prefer simple objects**. We use prototypal
inheritance only when absolutely necessary.
* We **love functions and closures** and, whenever possible, prefer them over objects.
* To write concise code that can be better minified, we **use aliases internally** that map to the
@@ -237,7 +237,7 @@ reference GitHub issues that this commit **Closes**.
A detailed explanation can be found in this [document][commit-message-format].
## <a name="cla"></a> Signing the CLA
## <a name="cla"></a> Signing the CLA
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
+26 -9
View File
@@ -1,3 +1,5 @@
'use strict';
var files = require('./angularFiles').files;
var util = require('./lib/grunt/utils.js');
var versionInfo = require('./lib/versions/version-info');
@@ -107,6 +109,12 @@ module.exports = function(grunt) {
options: {
jshintrc: true,
},
node: {
files: { src: ['*.js', 'lib/**/*.js'] },
},
tests: {
files: { src: 'test/**/*.js' },
},
ng: {
files: { src: files['angularSrc'] },
},
@@ -201,7 +209,7 @@ module.exports = function(grunt) {
},
"promises-aplus-adapter": {
dest:'tmp/promises-aplus-adapter++.js',
src:['src/ng/q.js','lib/promises-aplus/promises-aplus-test-adapter.js']
src:['src/ng/q.js', 'lib/promises-aplus/promises-aplus-test-adapter.js']
}
},
@@ -218,14 +226,17 @@ module.exports = function(grunt) {
},
"ddescribe-iit": {
'ddescribe-iit': {
files: [
'src/**/*.js',
'test/**/*.js',
'!test/ngScenario/DescribeSpec.js'
'!test/ngScenario/DescribeSpec.js',
'!src/ng/directive/booleanAttrs.js', // legitimate xit here
'!src/ngScenario/**/*.js'
]
},
"merge-conflict": {
'merge-conflict': {
files: [
'src/**/*',
'test/**/*',
@@ -246,7 +257,11 @@ module.exports = function(grunt) {
compress: {
build: {
options: {archive: 'build/' + dist +'.zip', mode: 'zip'},
src: ['**'], cwd: 'build', expand: true, dot: true, dest: dist + '/'
src: ['**'],
cwd: 'build',
expand: true,
dot: true,
dest: dist + '/'
}
},
@@ -278,8 +293,10 @@ module.exports = function(grunt) {
});
//alias tasks
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['jshint', 'jscs', 'package','test:unit','test:promises-aplus', 'tests:docs', 'test:protractor']);
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['jshint', 'jscs', 'package', 'test:unit', 'test:promises-aplus', 'tests:docs', 'test:protractor']);
grunt.registerTask('test:jqlite', 'Run the unit tests with Karma' , ['tests:jqlite']);
grunt.registerTask('test:jquery', 'Run the jQuery unit tests with Karma', ['tests:jquery']);
grunt.registerTask('test:modules', 'Run the Karma module tests with Karma', ['tests:modules']);
@@ -289,11 +306,11 @@ module.exports = function(grunt) {
grunt.registerTask('test:travis-protractor', 'Run the end to end tests with Protractor for Travis CI builds', ['connect:testserver', 'protractor:travis']);
grunt.registerTask('test:ci-protractor', 'Run the end to end tests with Protractor for Jenkins CI builds', ['webdriver', 'connect:testserver', 'protractor:jenkins']);
grunt.registerTask('test:e2e', 'Alias for test:protractor', ['test:protractor']);
grunt.registerTask('test:promises-aplus',['build:promises-aplus-adapter','shell:promises-aplus-tests']);
grunt.registerTask('test:promises-aplus',['build:promises-aplus-adapter', 'shell:promises-aplus-tests']);
grunt.registerTask('minify', ['bower','clean', 'build', 'minall']);
grunt.registerTask('minify', ['bower', 'clean', 'build', 'minall']);
grunt.registerTask('webserver', ['connect:devserver']);
grunt.registerTask('package', ['bower','clean', 'buildall', 'minall', 'collect-errors', 'docs', 'copy', 'write', 'compress']);
grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'docs', 'copy', 'write', 'compress']);
grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'jshint', 'jscs']);
grunt.registerTask('default', ['package']);
};
+7 -6
View File
@@ -6,16 +6,17 @@ use good old HTML (or HAML, Jade and friends!) as your template language and let
syntax to express your applications components clearly and succinctly. It automatically
synchronizes data from your UI (view) with your JavaScript objects (model) through 2-way data
binding. To help you structure your application better and make it easy to test, AngularJS teaches
the browser how to do dependency injection and inversion of control. Oh yeah and it also helps with
server-side communication, taming async callbacks with promises and deferreds; and makes client-side
navigation and deeplinking with hashbang urls or HTML5 pushState a piece of cake. The best of all:
it makes development fun!
the browser how to do dependency injection and inversion of control.
Oh yeah and it helps with server-side communication, taming async callbacks with promises and
deferreds. It also makes client-side navigation and deeplinking with hashbang urls or HTML5 pushState a
piece of cake. The best of all: it makes development fun!
* Web site: http://angularjs.org
* Tutorial: http://docs.angularjs.org/tutorial
* API Docs: http://docs.angularjs.org/api
* Developer Guide: http://docs.angularjs.org/guide
* Contribution guidelines: http://docs.angularjs.org/misc/contribute
* Contribution guidelines: [CONTRIBUTING.md](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md)
* Dashboard: http://dashboard.angularjs.org
Building AngularJS
@@ -37,7 +38,7 @@ To execute end-to-end (e2e) tests, use:
grunt test:e2e
To learn more about the grunt tasks, run `grunt --help` and also read our
[contribution guidelines](http://docs.angularjs.org/misc/contribute).
[contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
[![Analytics](https://ga-beacon.appspot.com/UA-8594346-11/angular.js/README.md?pixel)](https://github.com/igrigorik/ga-beacon)
+4 -7
View File
@@ -26,7 +26,6 @@ This process based on the idea of minimizing user pain
* You can triage older issues as well
* Triage to your heart's content
1. Assign yourself: Pick an issue that is not assigned to anyone and assign it to you
1. Understandable? - verify if the description of the request is clear.
* If not, [close it][] according to the instructions below and go to the last step.
1. Duplicate?
@@ -36,7 +35,6 @@ This process based on the idea of minimizing user pain
* Label `Type: Bug`
* Reproducible? - Steps to reproduce the bug are clear. If they are not, ask for a clarification. If there's no reply after a week, [close it][].
* Reproducible on master? - <http://code.angularjs.org/snapshot/>
1. Non bugs:
* Label `Type: Feature`, `Type: Chore`, or `Type: Perf`
* Belongs in core? Often new features should be implemented as a third-party module rather than an addition to the core.
@@ -44,11 +42,11 @@ This process based on the idea of minimizing user pain
* Label `needs: breaking change` - if needed
* Label `needs: public api` - if the issue requires introduction of a new public API
1. Label `browser: *` - if the issue **only** affects a certain browser
1. Label `frequency: *` How often does this issue come up? How many developers does this affect?
1. Label `frequency: *` How often does this issue come up? How many developers does this affect? Chose just one of the following:
* low - obscure issue affecting a handful of developers
* moderate - impacts a common usage pattern
* high - impacts most or all Angular apps
1. Label `severity: *` - How bad is the issue?
1. Label `severity: *` - How bad is the issue? Chose just one of the following:
* security issue
* regression
* memory leak
@@ -59,11 +57,10 @@ This process based on the idea of minimizing user pain
* In rare cases, it's ok to have multiple components.
1. Label `PRs plz!` - These issues are good targets for PRs from the open source community. Apply to issues where the problem and solution are well defined in the comments, and it's not too complex.
1. Label `origin: google` for issues from Google
1. Assign a milestone:
* Backlog - triaged fixes and features, should be the default choice
* Backlog - triaged fixes and features, should be the default choice
* Current 1.x.y milestone (e.g. 1.3.0-beta-2) - regressions and urgent bugs only
1. Unassign yourself from the issue
+4 -1
View File
@@ -1,4 +1,6 @@
angularFiles = {
'use strict';
var angularFiles = {
'angularSrc': [
'src/minErr.js',
'src/Angular.js',
@@ -29,6 +31,7 @@ angularFiles = {
'src/ng/q.js',
'src/ng/raf.js',
'src/ng/rootScope.js',
'src/ng/rootElement.js',
'src/ng/sanitizeUri.js',
'src/ng/sce.js',
'src/ng/sniffer.js',
+2 -6
View File
@@ -2,11 +2,7 @@
"name": "AngularJS",
"devDependencies": {
"jquery": "1.10.2",
"lunr.js": "0.4.3",
"open-sans-fontface": "1.0.4",
"google-code-prettify": "1.0.1",
"closure-compiler": "https://closure-compiler.googlecode.com/files/compiler-20130603.zip",
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.3/assets/ng-closure-runner.zip",
"bootstrap": "3.1.1"
"closure-compiler": "https://dl.google.com/closure-compiler/compiler-20130603.zip",
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.3/assets/ng-closure-runner.zip"
}
}
+7 -3
View File
@@ -3,6 +3,8 @@
// 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');
@@ -110,7 +112,7 @@ var printSection = function(stream, title, section, printCommitLinks) {
}
stream.write(')\n');
} else {
stream.write(util.format('%s %s', prefix, commit.subject));
stream.write(util.format('%s %s\n', prefix, commit.subject));
}
});
});
@@ -164,7 +166,7 @@ var writeChangelog = function(stream, commits, version) {
hash: commit.hash,
closes: []
});
};
}
});
stream.write(util.format(HEADER_TPL, version, version, currentDate()));
@@ -172,7 +174,7 @@ var writeChangelog = function(stream, commits, version) {
printSection(stream, 'Features', sections.feat);
printSection(stream, 'Performance Improvements', sections.perf);
printSection(stream, 'Breaking Changes', sections.breaks, false);
}
};
var getPreviousTag = function() {
@@ -186,6 +188,7 @@ var getPreviousTag = function() {
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) {
@@ -199,6 +202,7 @@ var generate = function(version, file) {
// 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) {
+66 -1
View File
@@ -1,3 +1,7 @@
/* global describe: false, beforeEach: false, afterEach: false, it: false, expect: false */
'use strict';
describe('changelog.js', function() {
var ch = require('./changelog');
@@ -13,7 +17,7 @@ describe('changelog.js', function() {
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')
'when destroying 10k nested scopes where each scope has a $destroy listener\n');
expect(msg.component).toBe('scope');
});
@@ -40,4 +44,65 @@ describe('changelog.js', function() {
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);
});
});
});
+3 -1
View File
@@ -1,5 +1,7 @@
#!/usr/local/bin/node
'use strict';
var util = require('util');
var cp = require('child_process');
@@ -143,7 +145,7 @@ then(allInSeries(function (branch) {
return sha + (msg.toLowerCase().indexOf('fix') === -1 ? ' ' : ' * ') + msg;
});
branch.log = log.map(function (line) {
return line.substr(41)
return line.substr(41);
});
return branch;
});
+14 -8
View File
@@ -211,6 +211,10 @@ code.highlighted {
color:maroon;
}
ul + p {
margin-top: 10px;
}
.docs-version-jump {
min-width:100%;
max-width:100%;
@@ -312,10 +316,10 @@ iframe.example {
}
.search-results-group.col-group-api { width:30%; }
.search-results-group.col-group-guide { width:30%; }
.search-results-group.col-group-tutorial { width:25%; }
.search-results-group.col-group-guide,
.search-results-group.col-group-tutorial { width:20%; }
.search-results-group.col-group-misc,
.search-results-group.col-group-error { float:right; clear:both; width:15% }
.search-results-group.col-group-error { width:15%; float: right; }
.search-results-group.col-group-api .search-result {
@@ -387,7 +391,6 @@ iframe.example {
position:fixed;
top:120px;
bottom:0;
padding-bottom:120px;
overflow:auto;
}
@@ -408,6 +411,7 @@ iframe.example {
.main-body-grid .side-navigation {
position:relative;
padding-bottom:120px;
}
.main-body-grid .side-navigation.ng-hide {
@@ -631,12 +635,14 @@ ul.events > li {
display:inline-block;
padding:3px 0;
}
.nav-index-group .nav-index-listing:not(.nav-index-section) + .nav-index-listing:not(.nav-index-section):after {
padding-right:5px;
content:", ";
.nav-index-group .nav-index-listing:not(.nav-index-section):after {
padding-right:5px;
margin-left:-3px;
content:", ";
}
.nav-index-group .nav-index-listing:last-child {
.nav-index-group .nav-index-listing:last-child:after {
content:"";
display:inline-block;
}
.nav-index-group .nav-index-section {
display:block;
+4
View File
@@ -6,6 +6,10 @@
line-height: 1.5;
}
.lang-text * {
color: #333333!important;
}
.pln {
color: #333333;
}
+1 -1
View File
@@ -40,7 +40,7 @@ pre.prettyprint.linenums {
}
ol.linenums {
margin: 0 0 0 33px; /* IE indents via margin-left */
}
}
ol.linenums li {
padding-left: 12px;
font-size:12px;
@@ -1,284 +0,0 @@
'use strict';
var directive = {};
var service = { value: {} };
var DEPENDENCIES = {
'angular.js': 'http://code.angularjs.org/' + angular.version.full + '/angular.min.js',
'angular-resource.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-resource.min.js',
'angular-route.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-route.min.js',
'angular-animate.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-animate.min.js',
'angular-sanitize.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-sanitize.min.js',
'angular-cookies.js': 'http://code.angularjs.org/' + angular.version.full + '/angular-cookies.min.js'
};
function escape(text) {
return text.
replace(/\&/g, '&amp;').
replace(/\</g, '&lt;').
replace(/\>/g, '&gt;').
replace(/"/g, '&quot;');
}
/**
* http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
* http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
*/
function setHtmlIe8SafeWay(element, html) {
var newElement = angular.element('<pre>' + html + '</pre>');
element.empty();
element.append(newElement.contents());
return element;
}
directive.jsFiddle = function(getEmbeddedTemplate, escape, script) {
return {
terminal: true,
link: function(scope, element, attr) {
var name = '',
stylesheet = '<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">\n',
fields = {
html: '',
css: '',
js: ''
};
angular.forEach(attr.jsFiddle.split(' '), function(file, index) {
var fileType = file.split('.')[1];
if (fileType == 'html') {
if (index == 0) {
fields[fileType] +=
'<div ng-app' + (attr.module ? '="' + attr.module + '"' : '') + '>\n' +
getEmbeddedTemplate(file, 2);
} else {
fields[fileType] += '\n\n\n <!-- CACHE FILE: ' + file + ' -->\n' +
' <script type="text/ng-template" id="' + file + '">\n' +
getEmbeddedTemplate(file, 4) +
' </script>\n';
}
} else {
fields[fileType] += getEmbeddedTemplate(file) + '\n';
}
});
fields.html += '</div>\n';
setHtmlIe8SafeWay(element,
'<form class="jsfiddle" method="post" action="http://jsfiddle.net/api/post/library/pure/" target="_blank">' +
hiddenField('title', 'AngularJS Example: ' + name) +
hiddenField('css', '</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> \n' +
stylesheet +
script.angular +
(attr.resource ? script.resource : '') +
'<style>\n' +
fields.css) +
hiddenField('html', fields.html) +
hiddenField('js', fields.js) +
'<button class="btn btn-primary"><i class="icon-white icon-pencil"></i> Edit Me</button>' +
'</form>');
function hiddenField(name, value) {
return '<input type="hidden" name="' + name + '" value="' + escape(value) + '">';
}
}
}
};
directive.ngSetText = ['getEmbeddedTemplate', function(getEmbeddedTemplate) {
return {
restrict: 'CA',
priority: 10,
compile: function(element, attr) {
setHtmlIe8SafeWay(element, escape(getEmbeddedTemplate(attr.ngSetText)));
}
}
}]
directive.ngHtmlWrap = ['reindentCode', 'templateMerge', function(reindentCode, templateMerge) {
return {
compile: function(element, attr) {
var properties = {
head: '',
module: '',
body: element.text()
},
html = "<!doctype html>\n<html ng-app{{module}}>\n <head>\n{{head:4}} </head>\n <body>\n{{body:4}} </body>\n</html>";
angular.forEach((attr.ngHtmlWrap || '').split(' '), function(dep) {
if (!dep) return;
dep = DEPENDENCIES[dep] || dep;
var ext = dep.split(/\./).pop();
if (ext == 'css') {
properties.head += '<link rel="stylesheet" href="' + dep + '" type="text/css">\n';
} else if(ext == 'js') {
properties.head += '<script src="' + dep + '"></script>\n';
} else {
properties.module = '="' + dep + '"';
}
});
setHtmlIe8SafeWay(element, escape(templateMerge(html, properties)));
}
}
}];
directive.ngSetHtml = ['getEmbeddedTemplate', function(getEmbeddedTemplate) {
return {
restrict: 'CA',
priority: 10,
compile: function(element, attr) {
setHtmlIe8SafeWay(element, getEmbeddedTemplate(attr.ngSetHtml));
}
}
}];
directive.ngEvalJavascript = ['getEmbeddedTemplate', function(getEmbeddedTemplate) {
return {
compile: function (element, attr) {
var fileNames = attr.ngEvalJavascript.split(' ');
angular.forEach(fileNames, function(fileName) {
var script = getEmbeddedTemplate(fileName);
try {
if (window.execScript) { // IE
window.execScript(script || '""'); // IE complains when evaling empty string
} else {
window.eval(script + '//@ sourceURL=' + fileName);
}
} catch (e) {
if (window.console) {
window.console.log(script, '\n', e);
} else {
window.alert(e);
}
}
});
}
};
}];
directive.ngEmbedApp = ['$templateCache', '$browser', '$rootScope', '$location', '$sniffer', '$animate',
function($templateCache, $browser, docsRootScope, $location, $sniffer, $animate) {
return {
terminal: true,
link: function(scope, element, attrs) {
var modules = ['ngAnimate'],
embedRootScope,
deregisterEmbedRootScope;
modules.push(['$provide', function($provide) {
$provide.value('$templateCache', $templateCache);
$provide.value('$anchorScroll', angular.noop);
$provide.value('$browser', $browser);
$provide.value('$sniffer', $sniffer);
$provide.value('$animate', $animate);
$provide.provider('$location', function() {
this.$get = ['$rootScope', function($rootScope) {
docsRootScope.$on('$locationChangeSuccess', function(event, oldUrl, newUrl) {
$rootScope.$broadcast('$locationChangeSuccess', oldUrl, newUrl);
});
return $location;
}];
this.html5Mode = angular.noop;
});
$provide.decorator('$rootScope', ['$delegate', function($delegate) {
embedRootScope = $delegate;
// Since we are teleporting the $animate service, which relies on the $$postDigestQueue
// we need the embedded scope to use the same $$postDigestQueue as the outer scope
embedRootScope.$$postDigestQueue = docsRootScope.$$postDigestQueue;
deregisterEmbedRootScope = docsRootScope.$watch(function embedRootScopeDigestWatch() {
embedRootScope.$digest();
});
return embedRootScope;
}]);
}]);
if (attrs.ngEmbedApp) modules.push(attrs.ngEmbedApp);
element.on('click', function(event) {
if (event.target.attributes.getNamedItem('ng-click')) {
event.preventDefault();
}
});
element.bind('$destroy', function() {
deregisterEmbedRootScope();
embedRootScope.$destroy();
});
element.data('$injector', null);
angular.bootstrap(element, modules);
}
};
}];
service.reindentCode = function() {
return function (text, spaces) {
if (!text) return text;
var lines = text.split(/\r?\n/);
var prefix = ' '.substr(0, spaces || 0);
var i;
// remove any leading blank lines
while (lines.length && lines[0].match(/^\s*$/)) lines.shift();
// remove any trailing blank lines
while (lines.length && lines[lines.length - 1].match(/^\s*$/)) lines.pop();
var minIndent = 999;
for (i = 0; i < lines.length; i++) {
var line = lines[0];
var reindentCode = line.match(/^\s*/)[0];
if (reindentCode !== line && reindentCode.length < minIndent) {
minIndent = reindentCode.length;
}
}
for (i = 0; i < lines.length; i++) {
lines[i] = prefix + lines[i].substring(minIndent);
}
lines.push('');
return lines.join('\n');
}
};
service.templateMerge = ['reindentCode', function(indentCode) {
return function(template, properties) {
return template.replace(/\{\{(\w+)(?:\:(\d+))?\}\}/g, function(_, key, indent) {
var value = properties[key];
if (indent) {
value = indentCode(value, indent);
}
return value == undefined ? '' : value;
});
};
}];
service.getEmbeddedTemplate = ['reindentCode', function(reindentCode) {
return function (id) {
var element = document.getElementById(id);
if (!element) {
return null;
}
return reindentCode(angular.element(element).html(), 0);
}
}];
angular.module('bootstrapPrettify', []).directive(directive).factory(service);
+3 -3
View File
@@ -11,7 +11,7 @@ directive.runnableExample = ['$templateCache', '$document', function($templateCa
'ng-repeat="tab in tabs track by $index" ' +
'href="" ' +
'class="btn"' +
'ng-click="setTab($index)">' +
'ng-click="setTab($index)">' +
' {{ tab }}' +
' </a>' +
'</nav>';
@@ -103,7 +103,7 @@ directive.syntax = function() {
restrict: 'A',
link: function(scope, element, attrs) {
function makeLink(type, text, link, icon) {
return '<a href="' + link + '" class="btn syntax-' + type + '" target="_blank" rel="nofollow">' +
return '<a href="' + link + '" class="btn syntax-' + type + '" target="_blank" rel="nofollow">' +
'<span class="' + icon + '"></span> ' + text +
'</a>';
};
@@ -307,7 +307,7 @@ var popoverElement = function() {
return this.titleElement.html(value);
},
content : function(value) {
content : function(value) {
if(value && value.length > 0) {
value = marked(value);
}
+44
View File
@@ -0,0 +1,44 @@
"use strict";
/* jshint browser: true */
/* global importScripts, onmessage: true, postMessage, lunr */
// Load up the lunr library
importScripts('../components/lunr.js-0.4.2/lunr.min.js');
// Create the lunr index - the docs should be an array of object, each object containing
// the path and search terms for a page
var index = lunr(function() {
this.ref('path');
this.field('titleWords', {boost: 50});
this.field('members', { boost: 40});
this.field('keywords', { boost : 20 });
});
// Retrieve the searchData which contains the information about each page to be indexed
var searchData = {};
var searchDataRequest = new XMLHttpRequest();
searchDataRequest.onload = function() {
// Store the pages data to be used in mapping query results back to pages
searchData = JSON.parse(this.responseText);
// Add search terms from each page to the search index
searchData.forEach(function(page) {
index.add(page);
});
postMessage({ e: 'index-ready' });
};
searchDataRequest.open('GET', 'search-data.json');
searchDataRequest.send();
// The worker receives a message everytime the web app wants to query the index
onmessage = function(oEvent) {
var q = oEvent.data.q;
var hits = index.search(q);
var results = [];
// Only return the array of paths to pages
hits.forEach(function(hit) {
results.push(hit.ref);
});
// The results of the query are sent back to the web app via a new message
postMessage({ e: 'query-ready', q: q, d: results });
};
+42
View File
@@ -0,0 +1,42 @@
{
"extends": "../../../.jshintrc-base",
"globals": {
/* jasmine / karma */
"it": false,
"iit": false,
"describe": false,
"ddescribe": false,
"beforeEach": false,
"afterEach": false,
"expect": false,
"jasmine": false,
"spyOn": false,
"waits": false,
"waitsFor": false,
"runs": false,
"dump": false,
/* e2e */
"browser": false,
"element": false,
"by": false,
/* testabilityPatch / matchers */
"inject": false,
"module": false,
"dealoc": false,
"_jQuery": false,
"_jqLiteMode": false,
"sortedHtml": false,
"childrenTagsOf": false,
"assertHidden": false,
"assertVisible": false,
"provideLog": false,
"spyOnlyCallsWithArgs": false,
"createMockStyleSheet": false,
"browserTrigger": false,
"jqLiteCacheSize": false
}
}
@@ -0,0 +1,51 @@
'use strict';
describe("doc.angularjs.org", function() {
describe("API pages", function() {
it("should display links to code on GitHub", function() {
browser.get('index-debug.html#!/api/ng/service/$http');
expect(element(by.css('.improve-docs')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/edit\/.+\/src\/ng\/http\.js/);
browser.get('index-debug.html#!/api/ng/service/$http');
expect(element(by.css('.view-source')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/tree\/.+\/src\/ng\/http\.js#L\d+/);
});
it('should change the page content when clicking a link to a service', function () {
browser.get('');
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
ngBindLink.click();
var pageBody = element(by.css('h1'));
expect(pageBody.getText()).toEqual('ngClick');
});
it('should show the functioning input directive example', function () {
browser.get('index-debug.html#!/api/ng/directive/input');
// Ensure that the page is loaded before trying to switch frames.
browser.waitForAngular();
browser.switchTo().frame('example-input-directive');
var nameInput = element(by.model('user.name'));
nameInput.sendKeys('!!!');
var code = element.all(by.css('tt')).first();
expect(code.getText()).toContain('guest!!!');
});
it("should trim indentation from code blocks", function() {
browser.get('index-debug.html#!/api/ng/type/$rootScope.Scope');
var codeBlocks = element.all(by.css('pre > code.lang-js'));
codeBlocks.each(function(codeBlock) {
var firstSpan = codeBlock.all(by.css('span')).first();
expect(firstSpan.getText()).not.toMatch(/^\W+$/);
});
});
});
});
@@ -0,0 +1,12 @@
'use strict';
describe("provider pages", function() {
it("should show the related service", function() {
browser.get('index-debug.html#!/api/ng/provider/$compileProvider');
var serviceLink = element.all(by.css('ol.api-profile-header-structure li a')).first();
expect(serviceLink.getText()).toEqual('- $compile');
expect(serviceLink.getAttribute('href')).toMatch(/api\/ng\/service\/\$compile/);
});
});
@@ -0,0 +1,22 @@
'use strict';
describe("service pages", function() {
it("should show the related provider if there is one", function() {
browser.get('index-debug.html#!/api/ng/service/$compile');
var providerLink = element.all(by.css('ol.api-profile-header-structure li a')).first();
expect(providerLink.getText()).toEqual('- $compileProvider');
expect(providerLink.getAttribute('href')).toMatch(/api\/ng\/provider\/\$compileProvider/);
browser.get('index-debug.html#!/api/ng/service/$q');
providerLink = element.all(by.css('ol.api-profile-header-structure li a')).first();
expect(providerLink.getText()).not.toEqual('- $qProvider');
expect(providerLink.getAttribute('href')).not.toMatch(/api\/ng\/provider\/\$compileProvider/);
});
it("should show parameter defaults", function() {
browser.get('index-debug.html#!/api/ng/service/$timeout');
expect(element.all(by.css('.input-arguments p em')).first().getText()).toContain('(default: 0)');
});
});
@@ -1,10 +1,12 @@
'use strict';
describe('docs.angularjs.org', function () {
describe('App', function () {
// it('should filter the module list when searching', function () {
// browser.get();
// browser.waitForAngular();
// var search = element(by.input('q'));
// var search = element(by.model('q'));
// search.clear();
// search.sendKeys('ngBind');
@@ -24,21 +26,6 @@ describe('docs.angularjs.org', function () {
});
it('should show the functioning input directive example', function () {
browser.get('index-debug.html#!/api/ng/directive/input');
// Ensure that the page is loaded before trying to switch frames.
browser.waitForAngular();
browser.switchTo().frame('example-input-directive');
var nameInput = element(by.input('user.name'));
nameInput.sendKeys('!!!');
var code = element(by.css('tt'));
expect(code.getText()).toContain('guest!!!');
});
it('should be resilient to trailing slashes', function() {
browser.get('index-debug.html#!/api/ng/function/angular.noop/');
@@ -65,5 +52,15 @@ describe('docs.angularjs.org', function () {
browser.get('index-debug.html#!error/ng/areq?p0=Missing&p1=not%20a%20function,%20got%20undefined');
expect(element(by.css('.minerr-errmsg')).getText()).toEqual("Argument 'Missing' is not a function, got undefined");
});
});
});
describe('Error Handling', function() {
it("should display an error if the page does not exist", function() {
browser.get('index-debug.html#!/api/does/not/exist');
expect(element(by.css('h1')).getText()).toBe('Oops!');
});
});
+3 -3
View File
@@ -6,6 +6,7 @@ angular.module('docsApp', [
'DocsController',
'versionsData',
'pagesData',
'navData',
'directives',
'errors',
'examples',
@@ -13,11 +14,10 @@ angular.module('docsApp', [
'tutorials',
'versions',
'bootstrap',
'bootstrapPrettify',
'ui.bootstrap.dropdown'
])
.config(function($locationProvider) {
.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
});
}]);
+9 -74
View File
@@ -6,31 +6,10 @@ angular.module('DocsController', [])
function($scope, $rootScope, $location, $window, $cookies, openPlunkr,
NG_PAGES, NG_NAVIGATION, NG_VERSION) {
$scope.openPlunkr = openPlunkr;
$scope.docsVersion = NG_VERSION.isSnapshot ? 'snapshot' : NG_VERSION.version;
$scope.fold = function(url) {
if(url) {
$scope.docs_fold = '/notes/' + url;
if(/\/build/.test($window.location.href)) {
$scope.docs_fold = '/build/docs' + $scope.docs_fold;
}
window.scrollTo(0,0);
}
else {
$scope.docs_fold = null;
}
};
var OFFLINE_COOKIE_NAME = 'ng-offline',
INDEX_PATH = /^(\/|\/index[^\.]*.html)$/;
/**********************************
Publish methods
***********************************/
$scope.navClass = function(navItem) {
return {
active: navItem.href && this.currentPage.path,
@@ -38,55 +17,22 @@ angular.module('DocsController', [])
};
};
$scope.afterPartialLoaded = function() {
$scope.$on('$includeContentLoaded', function() {
var pagePath = $scope.currentPage ? $scope.currentPage.path : $location.path();
$window._gaq.push(['_trackPageview', pagePath]);
};
/** stores a cookie that is used by apache to decide which manifest ot send */
$scope.enableOffline = function() {
//The cookie will be good for one year!
var date = new Date();
date.setTime(date.getTime()+(365*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
var value = angular.version.full;
document.cookie = OFFLINE_COOKIE_NAME + "="+value+expires+"; path=" + $location.path;
//force the page to reload so server can serve new manifest file
window.location.reload(true);
};
/**********************************
Watches
***********************************/
});
$scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) {
var currentPage = $scope.currentPage = NG_PAGES[path];
if ( !currentPage && path.charAt(0)==='/' ) {
// Strip off leading slash
path = path.substr(1);
}
currentPage = $scope.currentPage = NG_PAGES[path];
if ( !currentPage && path.charAt(path.length-1) === '/' && path.length > 1 ) {
// Strip off trailing slash
path = path.substr(0, path.length-1);
}
currentPage = $scope.currentPage = NG_PAGES[path];
if ( !currentPage && /\/index$/.test(path) ) {
// Strip off index from the end
path = path.substr(0, path.length - 6);
}
path = path.replace(/^\/?(.+?)(\/index)?\/?$/, '$1');
currentPage = $scope.currentPage = NG_PAGES[path];
if ( currentPage ) {
$scope.currentArea = currentPage && NG_NAVIGATION[currentPage.area];
$scope.partialPath = 'partials/' + path + '.html';
$scope.currentArea = NG_NAVIGATION[currentPage.area];
var pathParts = currentPage.path.split('/');
var breadcrumb = $scope.breadcrumb = [];
var breadcrumbPath = '';
@@ -98,6 +44,7 @@ angular.module('DocsController', [])
} else {
$scope.currentArea = NG_NAVIGATION['api'];
$scope.breadcrumb = [];
$scope.partialPath = 'Error404.html';
}
});
@@ -107,24 +54,12 @@ angular.module('DocsController', [])
$scope.versionNumber = angular.version.full;
$scope.version = angular.version.full + " " + angular.version.codeName;
$scope.subpage = false;
$scope.offlineEnabled = ($cookies[OFFLINE_COOKIE_NAME] == angular.version.full);
$scope.futurePartialTitle = null;
$scope.loading = 0;
$scope.$cookies = $cookies;
$cookies.platformPreference = $cookies.platformPreference || 'gitUnix';
var INDEX_PATH = /^(\/|\/index[^\.]*.html)$/;
if (!$location.path() || INDEX_PATH.test($location.path())) {
$location.path('/api').replace();
}
// bind escape to hash reset callback
angular.element(window).on('keydown', function(e) {
if (e.keyCode === 27) {
$scope.$apply(function() {
$scope.subpage = false;
});
}
});
}]);
+1 -1
View File
@@ -59,4 +59,4 @@ angular.module('errors', ['ngSanitize'])
element.html(errorLinkFilter(interpolate.apply(null, formatArgs), '_blank'));
}
};
}]);
}]);
+7 -2
View File
@@ -2,7 +2,12 @@ angular.module('examples', [])
.factory('formPostData', ['$document', function($document) {
return function(url, fields) {
var form = angular.element('<form style="display: none;" method="post" action="' + url + '" target="_blank"></form>');
/**
* Form previously posted to target="_blank", but pop-up blockers were causing this to not work.
* If a user chose to bypass pop-up blocker one time and click the link, they would arrive at
* a new default plnkr, not a plnkr with the desired template.
*/
var form = angular.element('<form style="display: none;" method="post" action="' + url + '"></form>');
angular.forEach(fields, function(value, name) {
var input = angular.element('<input type="hidden" name="' + name + '">');
input.attr('value', value);
@@ -69,4 +74,4 @@ angular.module('examples', [])
formPostData('http://plnkr.co/edit/?p=preview', postData);
});
};
}]);
}]);
-24
View File
@@ -1,24 +0,0 @@
angular.module('docsApp.navigationService', [])
.factory('navigationService', function($window) {
var service = {
currentPage: null,
currentVersion: null,
changePage: function(newPage) {
},
changeVersion: function(newVersion) {
//TODO =========
// var currentPagePath = '';
// // preserve URL path when switching between doc versions
// if (angular.isObject($rootScope.currentPage) && $rootScope.currentPage.section && $rootScope.currentPage.id) {
// currentPagePath = '/' + $rootScope.currentPage.section + '/' + $rootScope.currentPage.id;
// }
// $window.location = version.url + currentPagePath;
}
};
});
+123 -62
View File
@@ -10,22 +10,35 @@ angular.module('search', [])
$scope.search = function(q) {
var MIN_SEARCH_LENGTH = 2;
if(q.length >= MIN_SEARCH_LENGTH) {
var results = docsSearch(q);
var totalAreas = 0;
for(var i in results) {
++totalAreas;
}
if(totalAreas > 0) {
$scope.colClassName = 'cols-' + totalAreas;
}
$scope.hasResults = totalAreas > 0;
$scope.results = results;
docsSearch(q).then(function(hits) {
var results = {};
angular.forEach(hits, function(hit) {
var area = hit.area;
var limit = (area == 'api') ? 40 : 14;
results[area] = results[area] || [];
if(results[area].length < limit) {
results[area].push(hit);
}
});
var totalAreas = 0;
for(var i in results) {
++totalAreas;
}
if(totalAreas > 0) {
$scope.colClassName = 'cols-' + totalAreas;
}
$scope.hasResults = totalAreas > 0;
$scope.results = results;
});
}
else {
clearResults();
}
if(!$scope.$$phase) $scope.$apply();
};
$scope.submit = function() {
var result;
for(var i in $scope.results) {
@@ -39,76 +52,124 @@ angular.module('search', [])
$scope.hideResults();
}
};
$scope.hideResults = function() {
clearResults();
$scope.q = '';
};
}])
.controller('Error404SearchCtrl', ['$scope', '$location', 'docsSearch', function($scope, $location, docsSearch) {
$scope.results = docsSearch($location.path().split(/[\/\.:]/).pop());
.controller('Error404SearchCtrl', ['$scope', '$location', 'docsSearch',
function($scope, $location, docsSearch) {
docsSearch($location.path().split(/[\/\.:]/).pop()).then(function(results) {
$scope.results = {};
angular.forEach(results, function(result) {
var area = $scope.results[result.area] || [];
area.push(result);
$scope.results[result.area] = area;
});
});
}])
.factory('lunrSearch', function() {
return function(properties) {
if (window.RUNNING_IN_NG_TEST_RUNNER) return null;
var engine = lunr(properties);
return {
store : function(values) {
engine.add(values);
},
search : function(q) {
return engine.search(q);
}
};
};
})
.provider('docsSearch', function() {
.factory('docsSearch', ['$rootScope','lunrSearch', 'NG_PAGES',
function($rootScope, lunrSearch, NG_PAGES) {
if (window.RUNNING_IN_NG_TEST_RUNNER) {
return null;
}
// This version of the service builds the index in the current thread,
// which blocks rendering and other browser activities.
// It should only be used where the browser does not support WebWorkers
function localSearchFactory($http, $timeout, NG_PAGES) {
var index = lunrSearch(function() {
this.ref('id');
this.field('title', {boost: 50});
this.field('keywords', { boost : 20 });
});
console.log('Using Local Search Index');
angular.forEach(NG_PAGES, function(page, key) {
if(page.searchTerms) {
index.store({
id : key,
title : page.searchTerms.titleWords,
keywords : page.searchTerms.keywords
// Create the lunr index
var index = lunr(function() {
this.ref('path');
this.field('titleWords', {boost: 50});
this.field('members', { boost: 40});
this.field('keywords', { boost : 20 });
});
// Delay building the index by loading the data asynchronously
var indexReadyPromise = $http.get('js/search-data.json').then(function(response) {
var searchData = response.data;
// Delay building the index for 500ms to allow the page to render
return $timeout(function() {
// load the page data into the index
angular.forEach(searchData, function(page) {
index.add(page);
});
}, 500);
});
// The actual service is a function that takes a query string and
// returns a promise to the search results
// (In this case we just resolve the promise immediately as it is not
// inherently an async process)
return function(q) {
return indexReadyPromise.then(function() {
var hits = index.search(q);
var results = [];
angular.forEach(hits, function(hit) {
results.push(NG_PAGES[hit.ref]);
});
return results;
});
};
});
}
localSearchFactory.$inject = ['$http', '$timeout', 'NG_PAGES'];
return function(q) {
var results = {
api : [],
tutorial : [],
guide : [],
error : [],
misc : []
// This version of the service builds the index in a WebWorker,
// which does not block rendering and other browser activities.
// It should only be used where the browser does support WebWorkers
function webWorkerSearchFactory($q, $rootScope, NG_PAGES) {
console.log('Using WebWorker Search Index')
var searchIndex = $q.defer();
var results;
var worker = new Worker('js/search-worker.js');
// The worker will send us a message in two situations:
// - when the index has been built, ready to run a query
// - when it has completed a search query and the results are available
worker.onmessage = function(oEvent) {
$rootScope.$apply(function() {
switch(oEvent.data.e) {
case 'index-ready':
searchIndex.resolve();
break;
case 'query-ready':
var pages = oEvent.data.d.map(function(path) {
return NG_PAGES[path];
});
results.resolve(pages);
break;
}
});
};
angular.forEach(index.search(q), function(result) {
var key = result.ref;
var item = NG_PAGES[key];
var area = item.area;
item.path = key;
var limit = area == 'api' ? 40 : 14;
if(results[area].length < limit) {
results[area].push(item);
}
});
return results;
// The actual service is a function that takes a query string and
// returns a promise to the search results
return function(q) {
// We only run the query once the index is ready
return searchIndex.promise.then(function() {
results = $q.defer();
worker.postMessage({ q: q });
return results.promise;
});
};
}
webWorkerSearchFactory.$inject = ['$q', '$rootScope', 'NG_PAGES'];
return {
$get: window.Worker ? webWorkerSearchFactory : localSearchFactory
};
}])
})
.directive('focused', function($timeout) {
return function(scope, element, attrs) {
+15 -16
View File
@@ -1,6 +1,6 @@
angular.module('tutorials', [])
.directive('docTutorialNav', function(templateMerge) {
.directive('docTutorialNav', function() {
var pages = [
'',
'step_00', 'step_01', 'step_02', 'step_03', 'step_04',
@@ -8,23 +8,22 @@ angular.module('tutorials', [])
'step_10', 'step_11', 'step_12', 'the_end'
];
return {
compile: function(element, attrs) {
var seq = 1 * attrs.docTutorialNav,
props = {
seq: seq,
prev: pages[seq],
next: pages[2 + seq],
diffLo: seq ? (seq - 1): '0~1',
diffHi: seq
};
scope: {},
template:
'<a ng-href="tutorial/{{prev}}"><li class="btn btn-primary"><i class="glyphicon glyphicon-step-backward"></i> Previous</li></a>\n' +
'<a ng-href="http://angular.github.io/angular-phonecat/step-{{seq}}/app"><li class="btn btn-primary"><i class="glyphicon glyphicon-play"></i> Live Demo</li></a>\n' +
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{diffLo}}...step-{{diffHi}}"><li class="btn btn-primary"><i class="glyphicon glyphicon-search"></i> Code Diff</li></a>\n' +
'<a ng-href="tutorial/{{next}}"><li class="btn btn-primary">Next <i class="glyphicon glyphicon-step-forward"></i></li></a>',
link: function(scope, element, attrs) {
var seq = 1 * attrs.docTutorialNav;
scope.seq = seq;
scope.prev = pages[seq];
scope.next = pages[2 + seq];
scope.diffLo = seq ? (seq - 1): '0~1';
scope.diffHi = seq;
element.addClass('btn-group');
element.addClass('tutorial-nav');
element.append(templateMerge(
'<a href="tutorial/{{prev}}"><li class="btn btn-primary"><i class="glyphicon glyphicon-step-backward"></i> Previous</li></a>\n' +
'<a href="http://angular.github.io/angular-phonecat/step-{{seq}}/app"><li class="btn btn-primary"><i class="glyphicon glyphicon-play"></i> Live Demo</li></a>\n' +
'<a href="https://github.com/angular/angular-phonecat/compare/step-{{diffLo}}...step-{{diffHi}}"><li class="btn btn-primary"><i class="glyphicon glyphicon-search"></i> Code Diff</li></a>\n' +
'<a href="tutorial/{{next}}"><li class="btn btn-primary">Next <i class="glyphicon glyphicon-step-forward"></i></li></a>', props));
}
};
})
@@ -47,4 +46,4 @@ angular.module('tutorials', [])
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{step ? (step - 1): \'0~1\'}}...step-{{step}}">GitHub</a>\n' +
'</p>'
};
});
});
+20 -4
View File
@@ -1,15 +1,31 @@
"use strict";
angular.module('versions', [])
.controller('DocsVersionsCtrl', ['$scope', '$location', '$window', 'NG_VERSIONS', function($scope, $location, $window, NG_VERSIONS) {
$scope.docs_versions = NG_VERSIONS;
$scope.docs_version = NG_VERSIONS[0];
$scope.docs_versions = 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;
}
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();
var currentPagePath = $location.path().replace(/\/$/, '');
// TODO: We need to do some munging of the path for different versions of the API...
$window.location = version.docsUrl + currentPagePath;
};
}]);
}]);
+3 -3
View File
@@ -19,7 +19,7 @@ describe("DocsController", function() {
it("should update the Google Analytics with currentPage path if currentPage exists", inject(function($window) {
$window._gaq = [];
$scope.currentPage = { path: 'a/b/c' };
$scope.afterPartialLoaded();
$scope.$broadcast('$includeContentLoaded');
expect($window._gaq.pop()).toEqual(['_trackPageview', 'a/b/c']);
}));
@@ -27,8 +27,8 @@ describe("DocsController", function() {
it("should update the Google Analytics with $location.path if currentPage is missing", inject(function($window, $location) {
$window._gaq = [];
spyOn($location, 'path').andReturn('x/y/z');
$scope.afterPartialLoaded();
$scope.$broadcast('$includeContentLoaded');
expect($window._gaq.pop()).toEqual(['_trackPageview', 'x/y/z']);
}));
});
});
});
+10
View File
@@ -0,0 +1,10 @@
{
"name": "AngularJS-docs-app",
"dependencies": {
"jquery": "2.1.1",
"lunr.js": "0.4.3",
"open-sans-fontface": "1.0.4",
"google-code-prettify": "1.0.1",
"bootstrap": "3.1.1"
}
}
+155 -32
View File
@@ -1,43 +1,166 @@
var _ = require('lodash');
"use strict";
var path = require('canonical-path');
var packagePath = __dirname;
var basePackage = require('dgeni-packages/ngdoc');
var examplesPackage = require('dgeni-packages/examples');
var Package = require('dgeni').Package;
module.exports = function(config) {
// 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.
module.exports = new Package('angularjs', [
require('dgeni-packages/ngdoc'),
require('dgeni-packages/nunjucks'),
require('dgeni-packages/examples')
])
config = basePackage(config);
config = examplesPackage(config);
config.append('processing.processors', [
require('./processors/git-data'),
require('./processors/error-docs'),
require('./processors/keywords'),
require('./processors/versions-data'),
require('./processors/pages-data'),
require('./processors/protractor-generate'),
require('./processors/index-page'),
require('./processors/debug-dump')
]);
config.append('processing.tagDefinitions', [
require('./tag-defs/tutorial-step')
]);
.factory(require('./services/errorNamespaceMap'))
.factory(require('./services/getMinerrInfo'))
.factory(require('./services/getVersion'))
.factory(require('./services/gitData'))
config.append('processing.defaultTagTransforms', [
require('dgeni-packages/jsdoc/tag-defs/transforms/trim-whitespace')
]);
.factory(require('./services/deployments/debug'))
.factory(require('./services/deployments/default'))
.factory(require('./services/deployments/jquery'))
.factory(require('./services/deployments/production'))
config.append('processing.inlineTagDefinitions', [
require('./inline-tag-defs/type')
]);
.factory(require('./inline-tag-defs/type'))
config.set('processing.search.ignoreWordsFile', path.resolve(packagePath, 'ignore.words'));
config.prepend('rendering.templateFolders', [
path.resolve(packagePath, 'templates')
]);
.processor(require('./processors/error-docs'))
.processor(require('./processors/index-page'))
.processor(require('./processors/keywords'))
.processor(require('./processors/pages-data'))
.processor(require('./processors/versions-data'))
return config;
};
.config(function(dgeni, log, readFilesProcessor, writeFilesProcessor) {
dgeni.stopOnValidationError = true;
dgeni.stopOnProcessingError = true;
log.level = 'info';
readFilesProcessor.basePath = path.resolve(__dirname,'../..');
readFilesProcessor.sourceFiles = [
{ include: 'src/**/*.js', basePath: 'src' },
{ include: 'docs/content/**/*.ngdoc', basePath: 'docs/content' }
];
writeFilesProcessor.outputFolder = 'build/docs';
})
.config(function(parseTagsProcessor) {
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/tutorial-step'));
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/sortOrder'));
})
.config(function(inlineTagProcessor, typeInlineTagDef) {
inlineTagProcessor.inlineTagDefinitions.push(typeInlineTagDef);
})
.config(function(templateFinder, renderDocsProcessor, gitData) {
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates'));
renderDocsProcessor.extraData.git = gitData;
})
.config(function(computePathsProcessor, computeIdsProcessor) {
computePathsProcessor.pathTemplates.push({
docTypes: ['error'],
pathTemplate: 'error/${namespace}/${name}',
outputPathTemplate: 'partials/error/${namespace}/${name}.html'
});
computePathsProcessor.pathTemplates.push({
docTypes: ['errorNamespace'],
pathTemplate: 'error/${name}',
outputPathTemplate: 'partials/error/${name}.html'
});
computePathsProcessor.pathTemplates.push({
docTypes: ['overview', 'tutorial'],
getPath: function(doc) {
var docPath = path.dirname(doc.fileInfo.relativePath);
if ( doc.fileInfo.baseName !== 'index' ) {
docPath = path.join(docPath, doc.fileInfo.baseName);
}
return docPath;
},
outputPathTemplate: 'partials/${path}.html'
});
computePathsProcessor.pathTemplates.push({
docTypes: ['e2e-test'],
getPath: function() {},
outputPathTemplate: 'ptore2e/${example.id}/${deployment.name}_test.js'
});
computePathsProcessor.pathTemplates.push({
docTypes: ['indexPage'],
pathTemplate: '.',
outputPathTemplate: '${id}.html'
});
computePathsProcessor.pathTemplates.push({
docTypes: ['module' ],
pathTemplate: '${area}/${name}',
outputPathTemplate: 'partials/${area}/${name}.html'
});
computePathsProcessor.pathTemplates.push({
docTypes: ['componentGroup' ],
pathTemplate: '${area}/${moduleName}/${groupType}',
outputPathTemplate: 'partials/${area}/${moduleName}/${groupType}.html'
});
computeIdsProcessor.idTemplates.push({
docTypes: ['overview', 'tutorial', 'e2e-test', 'indexPage'],
getId: function(doc) { return doc.fileInfo.baseName; },
getAliases: function(doc) { return [doc.id]; }
});
computeIdsProcessor.idTemplates.push({
docTypes: ['error', 'errorNamespace'],
getId: function(doc) { return 'error:' + doc.name; },
getAliases: function(doc) { return [doc.id]; }
});
})
.config(function(checkAnchorLinksProcessor) {
checkAnchorLinksProcessor.base = '/';
// We are only interested in docs that have an area (i.e. they are pages)
checkAnchorLinksProcessor.checkDoc = function(doc) { return doc.area; };
})
.config(function(
generateIndexPagesProcessor,
generateProtractorTestsProcessor,
generateExamplesProcessor,
debugDeployment, defaultDeployment,
jqueryDeployment, productionDeployment) {
generateIndexPagesProcessor.deployments = [
debugDeployment,
defaultDeployment,
jqueryDeployment,
productionDeployment
];
generateProtractorTestsProcessor.deployments = [
defaultDeployment,
jqueryDeployment
];
generateExamplesProcessor.deployments = [
debugDeployment,
defaultDeployment,
jqueryDeployment,
productionDeployment
];
});
+15 -10
View File
@@ -1,12 +1,17 @@
var typeClassFilter = require('dgeni-packages/ngdoc/rendering/filters/type-class');
"use strict";
var encoder = new require('node-html-encoder').Encoder();
module.exports = {
name: 'type',
description: 'Replace with markup that displays a nice type',
handlerFactory: function() {
return function(doc, tagName, tagDescription) {
return '<a href="" class="' + typeClassFilter.process(tagDescription) + '">'+encoder.htmlEncode(tagDescription) + '</a>';
};
}
};
/**
* @dgService typeInlineTagDef
* @description
* Replace with markup that displays a nice type
*/
module.exports = function typeInlineTagDef(getTypeClass) {
return {
name: 'type',
handler: function(doc, tagName, tagDescription) {
return '<a href="" class="' + getTypeClass(tagDescription) + '">'+encoder.htmlEncode(tagDescription) + '</a>';
}
};
};
-33
View File
@@ -1,33 +0,0 @@
var fs = require('q-io/fs');
var log = require('winston');
var util = require("util");
module.exports = {
name: 'debug-dump',
runBefore: ['write-files'],
description: 'This processor dumps docs that match a filter to a file',
process: function(docs, config) {
var filter, outputPath, depth;
filter = config.get('processing.debug-dump.filter');
outputPath = config.get('processing.debug-dump.outputPath');
depth = config.get('processing.debug-dump.depth', 2);
if ( filter && outputPath ) {
log.info('Dumping docs:', filter, outputPath);
var filteredDocs = filter(docs);
var dumpedDocs = util.inspect(filteredDocs, depth);
return writeFile(outputPath, dumpedDocs).then(function() {
return docs;
});
}
}
};
function writeFile(file, content) {
return fs.makeTree(fs.directory(file)).then(function() {
return fs.write(file, content, 'wb');
});
}
+42 -49
View File
@@ -1,59 +1,52 @@
"use strict";
var _ = require('lodash');
var log = require('winston');
var path = require('canonical-path');
module.exports = {
name: 'error-docs',
description: 'Compute the various fields for docs in the Error area',
runAfter: ['tags-extracted', 'compute-path'],
runBefore: ['extra-docs-added'],
exports: {
errorNamespaces: ['factory', function() { return {}; }],
minerrInfo: ['factory', function(config) {
var minerrInfoPath = config.get('processing.errors.minerrInfoPath');
if ( !minerrInfoPath ) {
throw new Error('Error in configuration: Please provide a path to the minerr info file (errors.json) ' +
'in the `config.processing.errors.minerrInfoPath` property');
}
return require(minerrInfoPath);
}]
},
process: function(docs, partialNames, errorNamespaces, minerrInfo) {
/**
* @dgProcessor errorDocsProcessor
* @description
* Process "error" docType docs and generate errorNamespace docs
*/
module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
return {
$runAfter: ['tags-extracted'],
$runBefore: ['extra-docs-added'],
$process: function(docs) {
// Create error namespace docs and attach error docs to each
_.forEach(docs, function(doc) {
if ( doc.docType === 'error' ) {
// Create error namespace docs and attach error docs to each
docs.forEach(function(doc) {
var parts, namespaceDoc;
// Parse out the error info from the id
parts = doc.name.split(':');
doc.namespace = parts[0];
doc.name = parts[1];
if ( doc.docType === 'error' ) {
// Parse out the error info from the id
parts = doc.name.split(':');
doc.namespace = parts[0];
doc.name = parts[1];
var namespaceDoc = errorNamespaces[doc.namespace];
if ( !namespaceDoc ) {
// First time we came across this namespace, so create a new one
namespaceDoc = errorNamespaces[doc.namespace] = {
area: doc.area,
name: doc.namespace,
errors: [],
path: path.dirname(doc.path),
outputPath: path.dirname(doc.outputPath) + '.html',
docType: 'errorNamespace'
};
// Get or create the relevant errorNamespace doc
namespaceDoc = errorNamespaceMap.get(doc.namespace);
if ( !namespaceDoc ) {
namespaceDoc = {
area: 'error',
name: doc.namespace,
errors: [],
docType: 'errorNamespace'
};
errorNamespaceMap.set(doc.namespace, namespaceDoc);
}
// Link this error doc to its namespace doc
namespaceDoc.errors.push(doc);
doc.namespaceDoc = namespaceDoc;
doc.formattedErrorMessage = getMinerrInfo().errors[doc.namespace][doc.name];
}
});
// Add this error to the namespace
namespaceDoc.errors.push(doc);
doc.namespace = namespaceDoc;
doc.formattedErrorMessage = minerrInfo.errors[doc.namespace.name][doc.name];
}
});
return docs.concat(_.values(errorNamespaces));
}
errorNamespaceMap.forEach(function(errorNamespace) {
docs.push(errorNamespace);
});
}
};
};
-20
View File
@@ -1,20 +0,0 @@
var gruntUtils = require('../../../lib/grunt/utils');
var versionInfo = require('../../../lib/versions/version-info');
module.exports = {
name: 'git-data',
runBefore: ['reading-files'],
description: 'This processor adds information from the local git repository to the extraData injectable',
exports: {
gitData: ['factory', function() {
return {
version: versionInfo.currentVersion,
versions: versionInfo.previousVersions,
info: versionInfo.gitRepoInfo
};
}]
},
process: function(extraData, gitData) {
extraData.git = gitData;
}
};
+38 -35
View File
@@ -1,40 +1,43 @@
"use strict";
var _ = require('lodash');
var log = require('winston');
var path = require('canonical-path');
module.exports = {
name: 'index-page',
runAfter: ['adding-extra-docs'],
runBefore: ['extra-docs-added'],
description: 'This processor creates docs that will be rendered as the index page for the app',
process: function(docs, config) {
/**
* @dgProcessor generateIndexPagesProcessor
* @description
* This processor creates docs that will be rendered as the index page for the app
*/
module.exports = function generateIndexPagesProcessor() {
return {
deployments: [],
$validate: {
deployments: { presence: true }
},
$runAfter: ['adding-extra-docs'],
$runBefore: ['extra-docs-added'],
$process: function(docs) {
var deployment = config.deployment;
if ( !deployment || !deployment.environments ) {
throw new Error('No deployment environments found in the config.');
// Collect up all the areas in the docs
var areas = {};
docs.forEach(function(doc) {
if ( doc.area ) {
areas[doc.area] = doc.area;
}
});
areas = _.keys(areas);
this.deployments.forEach(function(deployment) {
var indexDoc = _.defaults({
docType: 'indexPage',
areas: areas
}, deployment);
indexDoc.id = 'index' + (deployment.name === 'default' ? '' : '-' + deployment.name);
docs.push(indexDoc);
});
}
// Collect up all the areas in the docs
var areas = {};
_.forEach(docs, function(doc) {
if ( doc.area ) {
areas[doc.area] = doc.area;
}
});
areas = _.keys(areas);
_.forEach(deployment.environments, function(environment) {
var indexDoc = _.defaults({
docType: 'indexPage',
areas: areas
}, environment);
indexDoc.id = 'index' + (environment.name === 'default' ? '' : '-' + environment.name);
// Use .. to put it at the root of the build
indexDoc.outputPath = indexDoc.id + '.html';
docs.push(indexDoc);
});
}
};
};
};
+73 -47
View File
@@ -1,50 +1,64 @@
"use strict";
var _ = require('lodash');
var log = require('winston');
var fs = require('fs');
var path = require('canonical-path');
module.exports = {
name: 'keywords',
runAfter: ['docs-processed'],
runBefore: ['adding-extra-docs'],
description: 'This processor extracts all the keywords from the document',
process: function(docs, config) {
/**
* @dgProcessor generateKeywordsProcessor
* @description
* This processor extracts all the keywords from each document and creates
* a new document that will be rendered as a JavaScript file containing all
* this data.
*/
module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
return {
ignoreWordsFile: undefined,
areasToSearch: ['api', 'guide', 'misc', 'error', 'tutorial'],
propertiesToIgnore: [],
$validate: {
ignoreWordsFile: { },
areasToSearch: { presence: true },
propertiesToIgnore: { }
},
$runAfter: ['memberDocsProcessor'],
$runBefore: ['rendering-docs'],
$process: function(docs) {
// Keywords to ignore
var wordsToIgnore = [];
var propertiesToIgnore;
var areasToSearch;
// Keywords to ignore
var wordsToIgnore = [];
var propertiesToIgnore;
var areasToSearch;
// Keywords start with "ng:" or one of $, _ or a letter
var KEYWORD_REGEX = /^((ng:|[\$_a-z])[\w\-_]+)/;
// Keywords start with "ng:" or one of $, _ or a letter
var KEYWORD_REGEX = /^((ng:|[\$_a-z])[\w\-_]+)/;
// Load up the keywords to ignore, if specified in the config
if ( config.processing.search && config.processing.search.ignoreWordsFile ) {
// Load up the keywords to ignore, if specified in the config
if ( this.ignoreWordsFile ) {
var ignoreWordsPath = path.resolve(config.basePath, config.processing.search.ignoreWordsFile);
wordsToIgnore = fs.readFileSync(ignoreWordsPath, 'utf8').toString().split(/[,\s\n\r]+/gm);
var ignoreWordsPath = path.resolve(readFilesProcessor.basePath, this.ignoreWordsFile);
wordsToIgnore = fs.readFileSync(ignoreWordsPath, 'utf8').toString().split(/[,\s\n\r]+/gm);
log.debug('Loaded ignore words from "' + ignoreWordsPath + '"');
log.silly(wordsToIgnore);
log.debug('Loaded ignore words from "' + ignoreWordsPath + '"');
log.silly(wordsToIgnore);
}
areasToSearch = _.indexBy(config.get('processing.search.areasToSearch', ['api', 'guide', 'misc', 'error', 'tutorial']));
propertiesToIgnore = _.indexBy(config.get('processing.search.propertiesToIgnore', []));
log.debug('Properties to ignore', propertiesToIgnore);
var ignoreWordsMap = _.indexBy(wordsToIgnore);
// If the title contains a name starting with ng, e.g. "ngController", then add the module name
// without the ng to the title text, e.g. "controller".
function extractTitleWords(title) {
var match = /ng([A-Z]\w*)/.exec(title);
if ( match ) {
title = title + ' ' + match[1].toLowerCase();
}
return title;
}
areasToSearch = _.indexBy(this.areasToSearch);
propertiesToIgnore = _.indexBy(this.propertiesToIgnore);
log.debug('Properties to ignore', propertiesToIgnore);
var ignoreWordsMap = _.indexBy(wordsToIgnore);
// If the title contains a name starting with ng, e.g. "ngController", then add the module name
// without the ng to the title text, e.g. "controller".
function extractTitleWords(title) {
var match = /ng([A-Z]\w*)/.exec(title);
if ( match ) {
title = title + ' ' + match[1].toLowerCase();
}
return title;
}
function extractWords(text, words, keywordMap) {
@@ -52,37 +66,49 @@ module.exports = {
_.forEach(tokens, function(token){
var match = token.match(KEYWORD_REGEX);
if (match){
key = match[1];
var key = match[1];
if ( !keywordMap[key]) {
keywordMap[key] = true;
words.push(key);
}
}
});
}
}
});
}
// We are only interested in docs that live in the right area
docs = _.filter(docs, function(doc) { return areasToSearch[doc.area]; });
// We are only interested in docs that live in the right area
docs = _.filter(docs, function(doc) { return areasToSearch[doc.area]; });
_.forEach(docs, function(doc) {
_.forEach(docs, function(doc) {
var words = [];
var keywordMap = _.clone(ignoreWordsMap);
var members = [];
var membersMap = {};
// Search each top level property of the document for search terms
_.forEach(doc, function(value, key) {
if ( _.isString(value) && !propertiesToIgnore[key] ) {
extractWords(value, words, keywordMap);
}
if ( key === 'methods' || key === 'properties' || key === 'events' ) {
_.forEach(value, function(member) {
extractWords(member.name, members, membersMap);
});
}
});
doc.searchTerms = {
titleWords: extractTitleWords(doc.name),
keywords: _.sortBy(words).join(' ')
keywords: _.sortBy(words).join(' '),
members: _.sortBy(members).join(' ')
};
});
});
}
};
}
};
};
+181 -156
View File
@@ -1,6 +1,7 @@
"use strict";
var _ = require('lodash');
var path = require('canonical-path');
var log = require('winston');
var AREA_NAMES = {
api: 'API',
@@ -33,182 +34,206 @@ function getNavGroup(pages, area, pageSorter, pageMapper) {
}
var navGroupMappers = {
api: function(areaPages, area) {
var navGroups = _(areaPages)
.filter('module') // We are not interested in docs that are not in a module
/**
* @dgProcessor generatePagesDataProcessor
* @description
* This processor will create a new doc that will be rendered as a JavaScript file
* containing meta information about the pages and navigation
*/
module.exports = function generatePagesDataProcessor(log) {
.groupBy('module')
.map(function(modulePages, moduleName) {
log.debug('moduleName: ' + moduleName);
var navItems = [];
var modulePage;
var navGroupMappers = {
api: function(areaPages, area) {
var navGroups = _(areaPages)
.filter('module') // We are not interested in docs that are not in a module
_(modulePages)
.groupBy('module')
.groupBy('docType')
.map(function(modulePages, moduleName) {
log.debug('moduleName: ' + moduleName);
var navItems = [];
var modulePage;
.tap(function(docTypes) {
log.debug(_.keys(docTypes));
// Extract the module page from the collection
modulePage = docTypes.module[0];
delete docTypes.module;
})
_(modulePages)
.tap(function(docTypes) {
if ( docTypes.input ) {
docTypes.directive = docTypes.directive || [];
// Combine input docTypes into directive docTypes
docTypes.directive = docTypes.directive.concat(docTypes.input);
delete docTypes.input;
}
})
.groupBy('docType')
.forEach(function(sectionPages, sectionName) {
.tap(function(docTypes) {
log.debug(moduleName, _.keys(docTypes));
// Extract the module page from the collection
modulePage = docTypes.module[0];
delete docTypes.module;
})
sectionPages = _.sortBy(sectionPages, 'name');
.tap(function(docTypes) {
if ( docTypes.input ) {
docTypes.directive = docTypes.directive || [];
// Combine input docTypes into directive docTypes
docTypes.directive = docTypes.directive.concat(docTypes.input);
delete docTypes.input;
}
})
if ( sectionPages.length > 0 ) {
// Push a navItem for this section
navItems.push({
name: sectionName,
type: 'section',
href: path.dirname(sectionPages[0].path)
});
.forEach(function(sectionPages, sectionName) {
// Push the rest of the sectionPages for this section
_.forEach(sectionPages, function(sectionPage) {
sectionPages = _.sortBy(sectionPages, 'name');
if ( sectionPages.length > 0 ) {
// Push a navItem for this section
navItems.push({
name: sectionPage.name,
href: sectionPage.path,
type: sectionPage.docType
name: sectionName,
type: 'section',
href: path.dirname(sectionPages[0].path)
});
});
}
});
// Push the rest of the sectionPages for this section
_.forEach(sectionPages, function(sectionPage) {
navItems.push({
name: sectionPage.name,
href: sectionPage.path,
type: sectionPage.docType
});
});
}
});
return {
name: moduleName,
href: modulePage.path,
type: 'group',
navItems: navItems
};
})
.value();
return navGroups;
},
tutorial: function(pages, area) {
return [getNavGroup(pages, area, 'step', function(page) {
return {
name: moduleName,
href: modulePage.path,
type: 'group',
navItems: navItems
name: page.name,
step: page.step,
href: page.path,
type: 'tutorial'
};
})
.value();
return navGroups;
},
tutorial: function(pages, area) {
return [getNavGroup(pages, area, 'step', function(page) {
return {
name: page.name,
step: page.step,
href: page.path,
type: 'tutorial'
};
})];
},
error: function(pages, area) {
return [getNavGroup(pages, area, 'path', function(page) {
return {
name: page.name,
href: page.path,
type: page.docType === 'errorNamespace' ? 'section' : 'error'
};
})];
},
pages: function(pages, area) {
return [getNavGroup(pages, area, 'path', function(page) {
return {
name: page.name,
href: page.path,
type: 'page'
};
})];
}
};
module.exports = {
name: 'pages-data',
description: 'This plugin will create a new doc that will be rendered as an angularjs module ' +
'which will contain meta information about the pages and navigation',
runAfter: ['adding-extra-docs', 'component-groups-generate', 'compute-path'],
runBefore: ['extra-docs-added'],
process: function(docs, config) {
var outputFolder = config.rendering.outputFolder;
_(docs)
.filter(function(doc) { return doc.area === 'api'; })
.filter(function(doc) { return doc.docType === 'module'; })
.forEach(function(doc) { if ( !doc.path ) {
log.warn('Missing path property for ', doc.id);
}})
.map(function(doc) { return _.pick(doc, ['id', 'module', 'docType', 'area']); })
.tap(function(docs) {
log.debug(docs);
});
// We are only interested in docs that are in a area and not landing pages
var navPages = _.filter(docs, function(page) {
return page.area &&
page.docType != 'componentGroup';
});
// Generate an object collection of pages that is grouped by area e.g.
// - area "api"
// - group "ng"
// - section "directive"
// - ngApp
// - ngBind
// - section "global"
// - angular.element
// - angular.bootstrap
// - section "service"
// - $compile
// - group "ngRoute"
// - section "directive"
// - ngView
// - section "service"
// - $route
//
var areas = {};
_(navPages)
.groupBy('area')
.forEach(function(pages, areaId) {
var area = {
id: areaId,
name: AREA_NAMES[areaId]
})];
},
error: function(pages, area) {
return [getNavGroup(pages, area, 'path', function(page) {
return {
name: page.name,
href: page.path,
type: page.docType === 'errorNamespace' ? 'section' : 'error'
};
areas[areaId] = area;
})];
},
pages: function(pages, area) {
return [getNavGroup(
pages,
area,
function(page) {
return page.sortOrder || page.path;
},
function(page) {
return {
name: page.name,
href: page.path,
type: 'page'
};
}
)];
}
};
var navGroupMapper = navGroupMappers[area.id] || navGroupMappers['pages'];
area.navGroups = navGroupMapper(pages, area);
return {
$runAfter: ['paths-computed', 'generateKeywordsProcessor'],
$runBefore: ['rendering-docs'],
$process: function(docs) {
// We are only interested in docs that are in an area
var pages = _.filter(docs, function(doc) {
return doc.area;
});
// Extract a list of basic page information for mapping paths to partials and for client side searching
var pages = _(docs)
.map(function(doc) {
var page = _.pick(doc, [
'docType', 'id', 'name', 'area', 'outputPath', 'path', 'searchTerms'
]);
return page;
})
.indexBy('path')
.value();
// We are only interested in pages that are not landing pages
var navPages = _.filter(pages, function(page) {
return page.docType != 'componentGroup';
});
// Generate an object collection of pages that is grouped by area e.g.
// - area "api"
// - group "ng"
// - section "directive"
// - ngApp
// - ngBind
// - section "global"
// - angular.element
// - angular.bootstrap
// - section "service"
// - $compile
// - group "ngRoute"
// - section "directive"
// - ngView
// - section "service"
// - $route
//
var areas = {};
_(navPages)
.groupBy('area')
.forEach(function(pages, areaId) {
var area = {
id: areaId,
name: AREA_NAMES[areaId]
};
areas[areaId] = area;
var navGroupMapper = navGroupMappers[area.id] || navGroupMappers['pages'];
area.navGroups = navGroupMapper(pages, area);
});
docs.push({
docType: 'nav-data',
id: 'nav-data',
template: 'nav-data.template.js',
outputPath: 'js/nav-data.js',
areas: areas
});
var docData = {
docType: 'pages-data',
id: 'pages-data',
template: 'pages-data.template.js',
outputPath: 'js/pages-data.js',
areas: areas,
pages: pages
};
docs.push(docData);
}
var searchData = _(pages)
.filter(function(page) {
return page.searchTerms;
})
.map(function(page) {
return _.extend({ path: page.path }, page.searchTerms);
})
.value();
docs.push({
docType: 'json-doc',
id: 'search-data-json',
template: 'json-doc.template.json',
outputPath: 'js/search-data.json',
data: searchData
});
// Extract a list of basic page information for mapping paths to partials and for client side searching
var pageData = _(docs)
.map(function(doc) {
return _.pick(doc, ['name', 'area', 'path']);
})
.indexBy('path')
.value();
docs.push({
docType: 'pages-data',
id: 'pages-data',
template: 'pages-data.template.js',
outputPath: 'js/pages-data.js',
pages: pageData
});
}
};
};
@@ -1,49 +0,0 @@
var _ = require('lodash');
var path = require('canonical-path');
module.exports = {
name: 'protractor-generate',
description: 'Generate a protractor test file from the e2e tests in the examples',
runAfter: ['adding-extra-docs'],
runBefore: ['extra-docs-added'],
process: function(docs, examples, config) {
var protractorFolder = config.get('rendering.protractor.outputFolder', 'ptore2e');
_.forEach(examples, function(example) {
_.forEach(example.files, function(file) {
// Check if it's a Protractor test.
if (file.type !== 'protractor') {
return;
}
// Create new files for the tests.
docs.push(createProtractorDoc(example, file, 'jquery'));
docs.push(createProtractorDoc(example, file, 'jqlite'));
});
});
function createProtractorDoc(example, file, env) {
var protractorDoc = {
docType: 'e2e-test',
id: 'protractorTest' + '-' + example.id,
template: 'protractorTests.template.js',
outputPath: path.join(protractorFolder, example.id, env + '_test.js'),
innerTest: file.fileContents,
pathPrefix: '.', // Hold for if we test with full jQuery
exampleId: example.id,
description: example.doc.id
};
if (env === 'jquery') {
protractorDoc.examplePath = example.outputFolder + '/index-jquery.html';
} else {
protractorDoc.examplePath = example.outputFolder + '/index.html';
}
return protractorDoc;
}
}
};
+28 -32
View File
@@ -1,38 +1,34 @@
"use strict";
var _ = require('lodash');
module.exports = {
name: 'versions-data',
description: 'This plugin will create a new doc that will be rendered as an angularjs module ' +
'which will contain meta information about the versions of angular',
runAfter: ['adding-extra-docs', 'pages-data'],
runBefore: ['extra-docs-added'],
process: function(docs, gitData) {
/**
* @dgProcessor generateVersionDocProcessor
* @description
* This processor will create a new doc that will be rendered as a JavaScript file
* containing meta information about the current versions of AngularJS
*/
module.exports = function generateVersionDocProcessor(gitData) {
return {
$runAfter: ['generatePagesDataProcessor'],
$runBefore: ['rendering-docs'],
$process: function(docs) {
var version = gitData.version;
var versions = gitData.versions;
var versionDoc = {
docType: 'versions-data',
id: 'versions-data',
template: 'versions-data.template.js',
outputPath: 'js/versions-data.js',
currentVersion: gitData.version
};
if ( !version ) {
throw new Error('Invalid configuration. Please provide a valid `source.currentVersion` property');
versionDoc.versions = _(gitData.versions)
.filter(function(version) { return version.major > 0; })
.push(gitData.version)
.reverse()
.value();
docs.push(versionDoc);
}
if ( !versions ) {
throw new Error('Invalid configuration. Please provide a valid `source.previousVersions` property');
}
var versionDoc = {
docType: 'versions-data',
id: 'versions-data',
template: 'versions-data.template.js',
outputPath: 'js/versions-data.js',
};
versionDoc.currentVersion = version;
versionDoc.versions = _(versions)
.filter(function(version) { return version.major > 0; })
.push(version)
.reverse()
.value();
docs.push(versionDoc);
}
};
};
+39
View File
@@ -0,0 +1,39 @@
"use strict";
module.exports = function debugDeployment(getVersion) {
return {
name: 'debug',
examples: {
commonFiles: {
scripts: [ '../../../angular.js' ]
},
dependencyPath: '../../../'
},
scripts: [
'../angular.js',
'../angular-resource.js',
'../angular-route.js',
'../angular-cookies.js',
'../angular-sanitize.js',
'../angular-touch.js',
'../angular-animate.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'js/angular-bootstrap/bootstrap.js',
'js/angular-bootstrap/dropdown-toggle.js',
'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/pages-data.js',
'js/nav-data.js',
'js/docs.js'
],
stylesheets: [
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.css',
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
'css/prettify-theme.css',
'css/docs.css',
'css/animations.css'
]
};
};
@@ -0,0 +1,39 @@
"use strict";
module.exports = function defaultDeployment(getVersion) {
return {
name: 'default',
examples: {
commonFiles: {
scripts: [ '../../../angular.min.js' ]
},
dependencyPath: '../../../'
},
scripts: [
'../angular.min.js',
'../angular-resource.min.js',
'../angular-route.min.js',
'../angular-cookies.min.js',
'../angular-sanitize.min.js',
'../angular-touch.min.js',
'../angular-animate.min.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'js/angular-bootstrap/bootstrap.min.js',
'js/angular-bootstrap/dropdown-toggle.min.js',
'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/pages-data.js',
'js/nav-data.js',
'js/docs.min.js'
],
stylesheets: [
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
'css/prettify-theme.css',
'css/docs.css',
'css/animations.css'
]
};
};
+43
View File
@@ -0,0 +1,43 @@
"use strict";
module.exports = function jqueryDeployment(getVersion) {
return {
name: 'jquery',
examples: {
commonFiles: {
scripts: [
'../../components/jquery-' + getVersion('jquery') + '/jquery.js',
'../../../angular.js'
]
},
dependencyPath: '../../../'
},
scripts: [
'components/jquery-' + getVersion('jquery') + '/jquery.js',
'../angular.min.js',
'../angular-resource.min.js',
'../angular-route.min.js',
'../angular-cookies.min.js',
'../angular-sanitize.min.js',
'../angular-touch.min.js',
'../angular-animate.min.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'js/angular-bootstrap/bootstrap.min.js',
'js/angular-bootstrap/dropdown-toggle.min.js',
'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/pages-data.js',
'js/nav-data.js',
'js/docs.min.js'
],
stylesheets: [
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
'css/prettify-theme.css',
'css/docs.css',
'css/animations.css'
]
};
};
@@ -0,0 +1,42 @@
"use strict";
var versionInfo = require('../../../../lib/versions/version-info');
var cdnUrl = "//ajax.googleapis.com/ajax/libs/angularjs/" + versionInfo.cdnVersion;
module.exports = function productionDeployment(getVersion) {
return {
name: 'production',
examples: {
commonFiles: {
scripts: [ cdnUrl + '/angular.min.js' ]
},
dependencyPath: cdnUrl + '/'
},
scripts: [
cdnUrl + '/angular.min.js',
cdnUrl + '/angular-resource.min.js',
cdnUrl + '/angular-route.min.js',
cdnUrl + '/angular-cookies.min.js',
cdnUrl + '/angular-sanitize.min.js',
cdnUrl + '/angular-touch.min.js',
cdnUrl + '/angular-animate.min.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'js/angular-bootstrap/bootstrap.min.js',
'js/angular-bootstrap/dropdown-toggle.min.js',
'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/pages-data.js',
'js/nav-data.js',
'js/docs.min.js'
],
stylesheets: [
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
'css/prettify-theme.css',
'css/docs.css',
'css/animations.css'
]
};
};
+10
View File
@@ -0,0 +1,10 @@
"use strict";
var StringMap = require('stringmap');
/**
* @dgService errorNamespaceMap
* A map of error namespaces by name.
*/
module.exports = function errorNamespaceMap() {
return new StringMap();
};
+15
View File
@@ -0,0 +1,15 @@
"use strict";
var path = require('canonical-path');
/**
* @dgService minErrInfo
* @description
* Load the error information that was generated during the AngularJS build.
*/
module.exports = function getMinerrInfo(readFilesProcessor) {
return function() {
var minerrInfoPath = path.resolve(readFilesProcessor.basePath, 'build/errors.json');
return require(minerrInfoPath);
};
};
+17
View File
@@ -0,0 +1,17 @@
"use strict";
var path = require('canonical-path');
/**
* dgService getVersion
* @description
* Find the current version of the bower component (or npm module)
*/
module.exports = function getVersion(readFilesProcessor) {
var basePath = readFilesProcessor.basePath;
return function(component, sourceFolder, packageFile) {
sourceFolder = path.resolve(basePath, sourceFolder || 'docs/bower_components');
packageFile = packageFile || 'bower.json';
return require(path.join(sourceFolder,component,packageFile)).version;
};
};
+16
View File
@@ -0,0 +1,16 @@
"use strict";
var versionInfo = require('../../../lib/versions/version-info');
/**
* @dgService gitData
* @description
* Information from the local git repository
*/
module.exports = function gitData() {
return {
version: versionInfo.currentVersion,
versions: versionInfo.previousVersions,
info: versionInfo.gitRepoInfo
};
};
+6
View File
@@ -0,0 +1,6 @@
module.exports = {
name: 'sortOrder',
transforms: function(doc, tag, value) {
return parseInt(value, 10);
}
};
+1 -1
View File
@@ -14,4 +14,4 @@
{$ doc.description | marked $}
</div>
{% endblock %}
{% endblock %}
@@ -25,4 +25,4 @@
</div>
</div>
{% endblock %}
{% endblock %}
+3 -12
View File
@@ -56,15 +56,6 @@
}
})();
// force page reload when new update is available
window.applicationCache && window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
window.applicationCache.swapCache();
window.location.reload();
}
}, false);
// GA asynchronous tracker
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-8594346-3']);
@@ -85,7 +76,7 @@
<div class="row">
<div class="col-md-9 header-branding">
<a class="brand navbar-brand" href="http://angularjs.org">
<img class="logo" src="img/angularjs-for-header-only.svg">
<img width="117" height="30" class="logo" ng-src="img/angularjs-for-header-only.svg">
</a>
<ul class="nav navbar-nav">
<li class="divider-vertical"></li>
@@ -175,7 +166,7 @@
<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 (v.isStable?'Stable':'Unstable') for v in docs_versions"
<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">
@@ -219,7 +210,7 @@
</div>
<div class="grid-right">
<div id="loading" ng-show="loading">Loading...</div>
<div ng-hide="loading" ng-include="currentPage.outputPath || 'Error404.html'" onload="afterPartialLoaded()" autoscroll></div>
<div ng-hide="loading" ng-include="partialPath" autoscroll></div>
</div>
</div>
</section>
@@ -0,0 +1 @@
{$ doc.data | json $}
@@ -0,0 +1,3 @@
// Meta data used by the AngularJS docs app
angular.module('navData', [])
.value('NG_NAVIGATION', {$ doc.areas | json $});
+1 -2
View File
@@ -1,4 +1,3 @@
// Meta data used by the AngularJS docs app
angular.module('pagesData', [])
.value('NG_PAGES', {$ doc.pages | json $})
.value('NG_NAVIGATION', {$ doc.areas | json $});
.value('NG_PAGES', {$ doc.pages | json $});
@@ -1,7 +0,0 @@
describe("{$ doc.description $}", function() {
beforeEach(function() {
browser.get("{$ doc.pathPrefix $}/{$ doc.examplePath $}");
});
{$ doc.innerTest $}
});
@@ -2,15 +2,16 @@
is HTML and wrap each line in a <p> - thus breaking the HTML #}
<div>
<a ng-click="openPlunkr('{$ doc.example.outputFolder $}')" class="btn pull-right">
<a ng-click="openPlunkr('{$ doc.path $}')" class="btn pull-right">
<i class="glyphicon glyphicon-edit">&nbsp;</i>
Edit in Plunker</a>
<div class="runnable-example"
path="{$ doc.example.outputFolder $}"
path="{$ doc.example.deployments.default.path $}"
{%- for attrName, attrValue in doc.example.attributes %}
{$ attrName $}="{$ attrValue $}"{% endfor %}>
{% for fileName, file in doc.example.files %}
{% for fileName, file in doc.example.files %}
<div class="runnable-example-file" {% for attrName, attrValue in file.attributes %}
{$ attrName $}="{$ attrValue $}"{% endfor %}>
{% code -%}
@@ -19,9 +20,9 @@
</div>
{% endfor %}
<iframe class="runnable-example-frame" src="{$ doc.example.outputFolder $}/index.html" name="{$ doc.example.id $}"></iframe>
<iframe class="runnable-example-frame" src="{$ doc.example.deployments.default.outputPath $}" name="{$ doc.example.id $}"></iframe>
</div>
</div>
{# Be aware that we need these extra new lines here or marked will not realise that the <div>
above is HTML and wrap each line in a <p> - thus breaking the HTML #}
above is HTML and wrap each line in a <p> - thus breaking the HTML #}
+1 -1
View File
@@ -1 +1 @@
{% include 'overview.template.html' %}
{% include 'overview.template.html' %}
+3 -3
View File
@@ -128,7 +128,7 @@ Use ngRoute to enable URL routing to your application. The ngRoute module suppor
## {@link ngAnimate ngAnimate}
Use ngAnimate to enable animation features into your application. Various core ng directives will provide
Use ngAnimate to enable animation features within your application. Various core ng directives will provide
animation hooks into your application when ngAnimate is included. Animations are defined by using CSS transitions/animations
or JavaScript callbacks.
@@ -148,7 +148,7 @@ or JavaScript callbacks.
{@link ngAnimate CSS-based animations}
</td>
<td>
Follow ngAnimates CSS naming structure to reference CSS transitions / keyframe animations in AngularJS. Once defined the animation can be triggered by referencing the CSS class within the HTML template code.
Follow ngAnimates CSS naming structure to reference CSS transitions / keyframe animations in AngularJS. Once defined, the animation can be triggered by referencing the CSS class within the HTML template code.
</td>
</tr>
<tr>
@@ -156,7 +156,7 @@ or JavaScript callbacks.
{@link ngAnimate JS-based animations}
</td>
<td>
Use {@link angular.Module#animation module.animation()} to register a JavaScript animation. Once registered the animation can be triggered by referencing the CSS class within the HTML template code.
Use {@link angular.Module#animation module.animation()} to register a JavaScript animation. Once registered, the animation can be triggered by referencing the CSS class within the HTML template code.
</td>
</tr>
</table>
+2 -2
View File
@@ -12,10 +12,10 @@ $controller(MyController);
$controller(MyController, {scope: newScope});
```
To fix the example above please provide a scope to the $controller call:
To fix the example above please provide a scope (using the `$scope` property in the locals object) to the $controller call:
```
$controller(MyController, {$scope, newScope});
$controller(MyController, {$scope: newScope});
```
Please consult the {@link ng.$controller $controller} service api docs to learn more.
+1 -1
View File
@@ -23,4 +23,4 @@ When an instance of `MyCtrl` is created, the service `myService` will be created
by the `$injector`. `myService` depends on itself, which causes the `$injector`
to detect a circular dependency and throw the error.
For more information, see the {@link guide/di Dependency Injection Guide}.
For more information, see the {@link guide/di Dependency Injection Guide}.
+1 -1
View File
@@ -23,4 +23,4 @@ To avoid the error, always use string literals for dependency injection annotati
tokens.
For an explanation of what injection annotations are and how to use them, refer
to the {@link guide/di Dependency Injection Guide}.
to the {@link guide/di Dependency Injection Guide}.
+1 -1
View File
@@ -23,4 +23,4 @@ angular.module("myApp", [])
```
For more information, refer to the {@link auto.$provide#provider
$provide.provider} api doc.
$provide.provider} api doc.
+45 -1
View File
@@ -14,7 +14,7 @@ angular.module('myApp', [])
}]);
```
The above code will fail with `$injector:unpr` if `myService` is not defined.
The above code will fail with `$injector:unpr` if `myService` is not defined.
Making sure each dependency is defined will fix the problem, as noted below.
@@ -25,3 +25,47 @@ angular.module('myApp', [])
// Do something with myService
}]);
```
An unknown provider error can also be caused by accidentally redefining a
module using the `angular.module` API, as shown in the following example.
```
angular.module('myModule', [])
.service('myCoolService', function () { /* ... */ });
angular.module('myModule', [])
// myModule has already been created! This is not what you want!
.directive('myDirective', ['myCoolService', function (myCoolService) {
// This directive definition throws unknown provider, because myCoolService
// has been destroyed.
}]);
```
To fix this problem, make sure you only define each module with the
`angular.module(name, [requires])` syntax once across your entire project.
Retrieve it for subsequent use with `angular.module(name)`. The fixed example
is shown below.
```
angular.module('myModule', [])
.service('myCoolService', function () { /* ... */ });
angular.module('myModule')
.directive('myDirective', ['myCoolService', function (myCoolService) {
// This directive definition does not throw unknown provider.
}]);
```
Attempting to inject one controller into another will also throw an `Unknown provider` error:
```
angular.module('myModule', [])
.controller('MyFirstController', function() { /* ... */ });
.controller('MySecondController', ['MyFirstController', function(MyFirstController) {
// This controller throws an unknown provider error because
// MyFirstController cannot be injected.
}]);
```
Use the `$controller` service if you want to instantiate controllers yourself.
@@ -9,4 +9,4 @@ it hard to reason about whether some combination of concatenated values are
unsafe to use and could easily lead to XSS.
For more information about how AngularJS helps keep your app secure, refer to
the {@link ng.$sce $sce} API doc.
the {@link ng.$sce $sce} API doc.
+31
View File
@@ -14,3 +14,34 @@ perform this check - it's up to the developer to not expose such sensitive and p
directly on the scope chain.
To resolve this error, avoid access to DOM nodes.
# Event Handlers and Return Values
The `$parse:isecdom` error also occurs when an event handler invokes a function that returns a DOM
node.
```html
<button ng-click="iWillReturnDOM()">click me</button>
```
```js
$scope.iWillReturnDOM = function() {
return someDomNode;
}
```
To fix this issue, avoid returning DOM nodes from event handlers.
*Note: This error often means that you are accessing DOM from your controllers, which is usually
a sign of poor coding style that violates separation of concerns.*
# Implicit Returns in CoffeeScript
This error can occur more frequently when using CoffeeScript, which has a feature called implicit
returns. This language feature returns the last dereferenced object in the function when the
function has no explicit return statement.
The solution in this scenario is to add an explicit return statement. For example `return false` to
the function.
+17
View File
@@ -0,0 +1,17 @@
@ngdoc error
@name $parse:isecff
@fullName Referencing 'call', 'apply' and 'bind' Disallowed
@description
Occurs when an expression attempts to invoke Function's 'call', 'apply' or 'bind'.
Angular bans the invocation of 'call', 'apply' and 'bind' from within expressions
since access is a known way to modify the behaviour of existing functions.
To resolve this error, avoid using these methods in expressions.
Example expression that would result in this error:
```
<div>{{user.sendInfo.call({}, true)}}</div>
```
+17 -8
View File
@@ -1,18 +1,27 @@
@ngdoc error
@name $parse:isecfld
@fullName Referencing 'constructor' Field in Expression
@fullName Referencing Disallowed Field in Expression
@description
Occurs when an expression attempts to access an objects constructor field.
Occurs when an expression attempts to access one of the following fields:
AngularJS bans constructor access from within expressions since constructor
access is a known way to execute arbitrary Javascript code.
* __proto__
* __defineGetter__
* __defineSetter__
* __lookupGetter__
* __lookupSetter__
To resolve this error, avoid constructor access. As a last resort, alias
the constructor and access it through the alias instead.
AngularJS bans access to these fields from within expressions since
access is a known way to mess with native objects or
to execute arbitrary Javascript code.
Example expression that would result in this error:
To resolve this error, avoid using these fields in expressions. As a last resort,
alias their value and access them through the alias instead.
Example expressions that would result in this error:
```
<div>{{user.constructor.name}}</div>
<div>{{user.__proto__.hasOwnProperty = $emit}}</div>
<div>{{user.__defineGetter__('name', noop)}}</div>
```
+11
View File
@@ -0,0 +1,11 @@
@ngdoc error
@name $parse:isecobj
@fullName Referencing Object Disallowed
@description
Occurs when an expression attempts to access the 'Object' object (Root object in JavaScript).
Angular bans access to Object from within expressions since access is a known way to modify
the behaviour of existing objects.
To resolve this error, avoid Object access.
+1 -1
View File
@@ -3,7 +3,7 @@
@fullName Response does not match configured parameter
@description
This error occurs when the {@link ngResource.$resource `$resource`} service expects a response that can be deserialized as an array, receives an object, or vice versa.
This error occurs when the {@link ngResource.$resource `$resource`} service expects a response that can be deserialized as an array but receives an object, or vice versa.
By default, all resource actions expect objects, except `query` which expects arrays.
To resolve this error, make sure your `$resource` configuration matches the actual format of the data returned from the server.
+1 -1
View File
@@ -5,4 +5,4 @@
Occurs when you try to use the name `hasOwnProperty` as a name of a parameter.
Generally, a name cannot be `hasOwnProperty` because it is used, internally, on a object
and allowing such a name would break lookups on this object.
and allowing such a name would break lookups on this object.
+1 -1
View File
@@ -35,7 +35,7 @@ var users = [ { name: 'Hank' }, { name: 'Francisco' } ];
$scope.getUsers = function() {
return users;
});
};
```
The maximum number of allowed iterations of the `$digest` cycle is controlled via TTL setting which can be configured via {@link ng.$rootScopeProvider $rootScopeProvider}.
+1 -1
View File
@@ -161,7 +161,7 @@ In this second scenario, we are already inside a `$digest` when the ngFocus dire
call to `$apply()`, causing this error to be thrown.
It is possible to workaround this problem by moving the call to set the focus outside of the digest,
by using `$timeOut(fn, 0, false)`, where the `false` value tells Angular not to wrap this `fn` in a
by using `$timeout(fn, 0, false)`, where the `false` value tells Angular not to wrap this `fn` in a
`$apply` block:
```
+3 -3
View File
@@ -15,9 +15,9 @@ By default, only URLs that belong to the same origin are trusted. These are urls
The {@link ng.directive:ngInclude ngInclude} directive and {@link guide/directive directives} that specify a `templateUrl` require a trusted resource URL.
To load templates from other domains and/or protocols, either adjust the {@link
api/ng.$sceDelegateProvider#resourceUrlWhitelist whitelist}/ {@link
api/ng.$sceDelegateProvider#resourceUrlBlacklist blacklist} or wrap the URL with a call to {@link
api/ng.$sce#trustAsResourceUrl $sce.trustAsResourceUrl}.
ng.$sceDelegateProvider#resourceUrlWhitelist whitelist}/ {@link
ng.$sceDelegateProvider#resourceUrlBlacklist blacklist} or wrap the URL with a call to {@link
ng.$sce#trustAsResourceUrl $sce.trustAsResourceUrl}.
**Note**: The browser's [Same Origin
Policy](https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest) and
+2 -2
View File
@@ -10,7 +10,7 @@ Angular's {@link ng.$sce Strict Contextual Escaping (SCE)} mode
contexts to result in a value that is trusted as safe for use in such a context. (e.g. loading an
Angular template from a URL requires that the URL is one considered safe for loading resources.)
This helps prevent XSS and other security issues. Read more at {@link
api/ng.$sce Strict Contextual Escaping (SCE)}
This helps prevent XSS and other security issues. Read more at
{@link ng.$sce Strict Contextual Escaping (SCE)}
You may want to include the ngSanitize module to use the automatic sanitizing.
+1 -1
View File
@@ -5,4 +5,4 @@
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.
make sure that the value the assertion expects is defined and truthy.
+1 -1
View File
@@ -5,4 +5,4 @@
Occurs when you try to use the name `hasOwnProperty` in a context where it is not allow.
Generally, a name cannot be `hasOwnProperty` because it is used, internally, on a object
and allowing such a name would break lookups on this object.
and allowing such a name would break lookups on this object.
+1 -1
View File
@@ -49,4 +49,4 @@ You can also get this error if you accidentally load AngularJS itself more than
<script src="angular.js"></script>
</body>
</html>
```
```
+1 -1
View File
@@ -7,4 +7,4 @@ This error occurs when attempting to copy an object to itself. Calling {@link
api/angular.copy angular.copy} with a `destination` object deletes
all of the elements or properties on `destination` before copying to it. Copying
an object to itself is not supported. Make sure to check your calls to
`angular.copy` and avoid copying objects or arrays to themselves.
`angular.copy` and avoid copying objects or arrays to themselves.
+1 -1
View File
@@ -7,4 +7,4 @@ Copying Window or Scope instances is not supported because of cyclical and self
references. Avoid copying windows and scopes, as well as any other cyclical or
self-referential structures. Note that trying to deep copy an object containing
cyclical references that is neither a window nor a scope will cause infinite
recursion and a stack overflow.
recursion and a stack overflow.
+1 -1
View File
@@ -15,7 +15,7 @@ For example the issue can be triggered by this *invalid* code:
To resolve this error either ensure that the items in the collection have unique identity or use the `track by` syntax to specify how to track the association between models and DOM.
To resolve the example above can be resolved by using `track by $index`, which will cause the items to be keyed by their position in the array instead of their value:
The example above can be resolved by using `track by $index`, which will cause the items to be keyed by their position in the array instead of their value:
```
<div ng-repeat="value in [4, 4] track by $index"></div>
+314 -122
View File
@@ -1,5 +1,6 @@
@ngdoc overview
@name Using $location
@sortOrder 500
@description
# What does it do?
@@ -60,7 +61,7 @@ changes to $location are reflected into the browser address bar.
<tr>
<td class="head">aware of docroot/context from which the application is loaded</td>
<td>no - window.location.path returns "/docroot/actual/path"</td>
<td>no - window.location.pathname returns "/docroot/actual/path"</td>
<td>yes - $location.path() returns "/actual/path"</td>
</tr>
@@ -163,7 +164,7 @@ encoded.
`$location` service has two configuration modes which control the format of the URL in the browser
address bar: **Hashbang mode** (the default) and the **HTML5 mode** which is based on using the
HTML5 [History API](http://www.w3.org/TR/html5/history.html). Applications use the same API in
HTML5 [History API](http://www.w3.org/TR/html5/introduction.html#history-0). Applications use the same API in
both modes and the `$location` service will work with appropriate URL segments and browser APIs to
facilitate the browser URL change and history management.
@@ -210,6 +211,10 @@ facilitate the browser URL change and history management.
## Hashbang mode (default mode)
In this mode, `$location` uses Hashbang URLs in all browsers.
Angular also does not intercept and rewrite links in this mode. I.e. links work
as expected and also perform full page reloads when other parts of the url
than the hash fragment was changed.
### Example
@@ -240,7 +245,7 @@ it('should show example', inject(
## HTML5 mode
In HTML5 mode, the `$location` service getters and setters interact with the browser URL address
through the HTML5 history API, which allows for use of regular URL path and search segments,
through the HTML5 history API. This allows for use of regular URL path and search segments,
instead of their hashbang equivalents. If the HTML5 History API is not supported by a browser, the
`$location` service will fall back to using the hashbang URLs automatically. This frees you from
having to worry about whether the browser displaying your app supports the history API or not; the
@@ -249,6 +254,10 @@ having to worry about whether the browser displaying your app supports the histo
- Opening a regular URL in a legacy browser -> redirects to a hashbang URL
- Opening hashbang URL in a modern browser -> rewrites to a regular URL
Note that in this mode, Angular intercepts all links (subject to the "Html link rewriting" rules below)
and updates the url in a way that never performs a full page reload.
### Example
```js
@@ -297,8 +306,8 @@ history API or not; the `$location` service makes this transparent to you.
### Html link rewriting
When you use HTML5 history API mode, you will need different links in different browsers, but all you
have to do is specify regular URL links, such as: `<a href="/some?foo=bar">link</a>`
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>`
When a user clicks on this link,
@@ -313,17 +322,9 @@ reload to the original link.
Example: `<a href="/ext/link?a=b" target="_self">link</a>`
- Absolute links that go to a different domain<br>
Example: `<a href="http://angularjs.org/">link</a>`
- Links starting with '/' that lead to a different base path when base is defined<br>
- Links starting with '/' that lead to a different base path<br>
Example: `<a href="/not-my-base/link">link</a>`
When running Angular in the root of a domain, along side perhaps a normal application in the same
directory, the "otherwise" route handler will try to handle all the URLs, including ones that map
to static files.
To prevent this, you can set your base href for the app to `<base href=".">` and then prefix links
to URLs that should be handled with `.`. Now, links to locations, which are not to be routed by Angular,
are not prefixed with `.` and will not be intercepted by the `otherwise` rule in your `$routeProvider`.
### Server side
@@ -352,124 +353,314 @@ legacy browsers and hashbang links in modern browser:
Here you can see two `$location` instances, both in **Html5 mode**, but on different browsers, so
that you can see the differences. These `$location` services are connected to a fake browsers. Each
input represents address bar of the browser.
input represents the address bar of the browser.
Note that when you type hashbang url into first browser (or vice versa) it doesn't rewrite /
redirect to regular / hashbang url, as this conversion happens only during parsing the initial URL
= on page reload.
In this examples we use `<base href="/base/index.html" />`
<example>
In these examples we use `<base href="/base/index.html" />`
#### Browser in HTML5 mode
<example module="html5-mode" name="location-html5-mode">
<file name="index.html">
<div id="html5-mode" ng-controller="Html5Cntl">
<h3>Browser with History API</h3>
<div ng-address-bar browser="html5"></div><br><br>
$location.protocol() = {{$location.protocol()}}<br>
$location.host() = {{$location.host()}}<br>
$location.port() = {{$location.port()}}<br>
$location.path() = {{$location.path()}}<br>
$location.search() = {{$location.search()}}<br>
$location.hash() = {{$location.hash()}}<br>
<a href="http://www.example.com/base/first?a=b">/base/first?a=b</a> |
<a href="http://www.example.com/base/sec/ond?flag#hash">sec/ond?flag#hash</a> |
<a href="/other-base/another?search">external</a>
</div>
<div id="hashbang-mode" ng-controller="HashbangCntl">
<h3>Browser without History API</h3>
<div ng-address-bar browser="hashbang"></div><br><br>
$location.protocol() = {{$location.protocol()}}<br>
$location.host() = {{$location.host()}}<br>
$location.port() = {{$location.port()}}<br>
$location.path() = {{$location.path()}}<br>
$location.search() = {{$location.search()}}<br>
$location.hash() = {{$location.hash()}}<br>
<a href="http://www.example.com/base/first?a=b">/base/first?a=b</a> |
<a href="http://www.example.com/base/sec/ond?flag#hash">sec/ond?flag#hash</a> |
<a href="/other-base/another?search">external</a>
<div ng-controller="LocationController">
<div ng-address-bar></div><br><br>
<div>
$location.protocol() = <span ng-bind="$location.protocol()"></span> <br>
$location.host() = <span ng-bind="$location.host()"></span> <br>
$location.port() = <span ng-bind="$location.port()"></span> <br>
$location.path() = <span ng-bind="$location.path()"></span> <br>
$location.search() = <span ng-bind="$location.search()"></span> <br>
$location.hash() = <span ng-bind="$location.hash()"></span> <br>
</div>
<div id="navigation">
<a href="http://www.example.com/base/first?a=b">/base/first?a=b</a> |
<a href="http://www.example.com/base/sec/ond?flag#hash">sec/ond?flag#hash</a> |
<a href="/other-base/another?search">external</a>
</div>
</div>
</file>
<file name="app.js">
angular.module('html5-mode', ['fake-browser', 'address-bar'])
<file name="script.js">
function FakeBrowser(initUrl, baseHref) {
this.onUrlChange = function(fn) {
this.urlChange = fn;
.constant('initUrl', 'http://www.example.com/base/path?a=b#h')
.constant('baseHref', '/base/index.html')
.value('$sniffer', { history: true })
.controller("LocationController", function($scope, $location) {
$scope.$location = {};
angular.forEach("protocol host port path search hash".split(" "), function(method){
$scope.$location[method] = function(){
var result = $location[method].call($location);
return angular.isObject(result) ? angular.toJson(result) : result;
};
});
})
.config(function($locationProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
})
.run(function($rootElement) {
$rootElement.on('click', function(e) { e.stopPropagation(); });
});
</file>
<file name="fakeBrowser.js">
angular.module('fake-browser', [])
.config(function($provide) {
$provide.decorator('$browser', function($delegate, baseHref, initUrl) {
$delegate.onUrlChange = function(fn) {
this.urlChange = fn;
};
$delegate.url = function() {
return initUrl;
};
this.url = function() {
return initUrl;
};
$delegate.defer = function(fn, delay) {
setTimeout(function() { fn(); }, delay || 0);
};
this.defer = function(fn, delay) {
setTimeout(function() { fn(); }, delay || 0);
};
$delegate.baseHref = function() {
return baseHref;
};
this.baseHref = function() {
return baseHref;
};
return $delegate;
});
});
</file>
this.notifyWhenOutstandingRequests = angular.noop;
}
<file name="addressBar.js">
angular.module('address-bar', [])
.directive('ngAddressBar', function($browser, $timeout) {
return {
template: 'Address: <input id="addressBar" type="text" style="width: 400px" >',
link: function(scope, element, attrs){
var input = element.children("input"), delay;
var browsers = {
html5: new FakeBrowser('http://www.example.com/base/path?a=b#h', '/base/index.html'),
hashbang: new FakeBrowser('http://www.example.com/base/index.html#!/path?a=b#h', '/base/index.html')
};
input.on('keypress keyup keydown', function(event) {
delay = (!delay ? $timeout(fireUrlChange, 250) : null);
event.stopPropagation();
})
.val($browser.url());
function Html5Cntl($scope, $location) {
$scope.$location = $location;
}
function HashbangCntl($scope, $location) {
$scope.$location = $location;
}
function initEnv(name) {
var root = angular.element(document.getElementById(name + '-mode'));
// We must kill a link to the injector for this element otherwise angular will
// complain that it has been bootstrapped already.
root.data('$injector', null);
angular.bootstrap(root, [function($compileProvider, $locationProvider, $provide){
$locationProvider.html5Mode(true).hashPrefix('!');
$provide.value('$browser', browsers[name]);
$provide.value('$sniffer', {history: name == 'html5'});
$compileProvider.directive('ngAddressBar', function() {
return function(scope, elm, attrs) {
var browser = browsers[attrs.browser],
input = angular.element('<input type="text" style="width: 400px">').val(browser.url()),
delay;
input.on('keypress keyup keydown', function() {
if (!delay) {
delay = setTimeout(fireUrlChange, 250);
}
});
browser.url = function(url) {
return input.val(url);
};
elm.append('Address: ').append(input);
function fireUrlChange() {
delay = null;
browser.urlChange(input.val());
}
$browser.url = function(url) {
return url ? input.val(url) : input.val();
};
});
}]);
root.on('click', function(e) {
e.stopPropagation();
});
}
initEnv('html5');
initEnv('hashbang');
function fireUrlChange() {
delay = null;
$browser.urlChange(input.val());
}
}
};
});
</file>
<file name="protractor.js" type="protractor">
var addressBar = element(by.css("#addressBar")),
url = 'http://www.example.com/base/path?a=b#h';
it("should show fake browser info on load", function(){
expect(addressBar.getAttribute('value')).toBe(url);
expect(element(by.binding('$location.protocol')).getText()).toBe('http');
expect(element(by.binding('$location.host')).getText()).toBe('www.example.com');
expect(element(by.binding('$location.port')).getText()).toBe('80');
expect(element(by.binding('$location.path')).getText()).toBe('/path');
expect(element(by.binding('$location.search')).getText()).toBe('{"a":"b"}');
expect(element(by.binding('$location.hash')).getText()).toBe('h');
});
it("should change $location accordingly", function(){
var navigation = element.all(by.css("#navigation a"));
navigation.get(0).click();
expect(addressBar.getAttribute('value')).toBe("http://www.example.com/base/first?a=b");
expect(element(by.binding('$location.protocol')).getText()).toBe('http');
expect(element(by.binding('$location.host')).getText()).toBe('www.example.com');
expect(element(by.binding('$location.port')).getText()).toBe('80');
expect(element(by.binding('$location.path')).getText()).toBe('/first');
expect(element(by.binding('$location.search')).getText()).toBe('{"a":"b"}');
expect(element(by.binding('$location.hash')).getText()).toBe('');
navigation.get(1).click();
expect(addressBar.getAttribute('value')).toBe("http://www.example.com/base/sec/ond?flag#hash");
expect(element(by.binding('$location.protocol')).getText()).toBe('http');
expect(element(by.binding('$location.host')).getText()).toBe('www.example.com');
expect(element(by.binding('$location.port')).getText()).toBe('80');
expect(element(by.binding('$location.path')).getText()).toBe('/sec/ond');
expect(element(by.binding('$location.search')).getText()).toBe('{"flag":true}');
expect(element(by.binding('$location.hash')).getText()).toBe('hash');
});
</file>
</example>
####Browser in HTML5 Fallback mode (Hashbang mode)
<example module="hashbang-mode" name="location-hashbang-mode">
<file name="index.html">
<div ng-controller="LocationController">
<div ng-address-bar></div><br><br>
<div>
$location.protocol() = <span ng-bind="$location.protocol()"></span> <br>
$location.host() = <span ng-bind="$location.host()"></span> <br>
$location.port() = <span ng-bind="$location.port()"></span> <br>
$location.path() = <span ng-bind="$location.path()"></span> <br>
$location.search() = <span ng-bind="$location.search()"></span> <br>
$location.hash() = <span ng-bind="$location.hash()"></span> <br>
</div>
<div id="navigation">
<a href="http://www.example.com/base/first?a=b">/base/first?a=b</a> |
<a href="http://www.example.com/base/sec/ond?flag#hash">sec/ond?flag#hash</a> |
<a href="/other-base/another?search">external</a>
</div>
</div>
</file>
<file name="app.js">
angular.module('hashbang-mode', ['fake-browser', 'address-bar'])
.constant('initUrl', 'http://www.example.com/base/index.html#!/path?a=b#h')
.constant('baseHref', '/base/index.html')
.value('$sniffer', { history: false })
.config(function($locationProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
})
.controller("LocationController", function($scope, $location) {
$scope.$location = {};
angular.forEach("protocol host port path search hash".split(" "), function(method){
$scope.$location[method] = function(){
var result = $location[method].call($location);
return angular.isObject(result) ? angular.toJson(result) : result;
};
});
})
.run(function($rootElement) {
$rootElement.on('click', function(e) {
e.stopPropagation();
});
});
</file>
<file name="fakeBrowser.js">
angular.module('fake-browser', [])
.config(function($provide) {
$provide.decorator('$browser', function($delegate, baseHref, initUrl) {
$delegate.onUrlChange = function(fn) {
this.urlChange = fn;
};
$delegate.url = function() {
return initUrl;
};
$delegate.defer = function(fn, delay) {
setTimeout(function() { fn(); }, delay || 0);
};
$delegate.baseHref = function() {
return baseHref;
};
return $delegate;
});
});
</file>
<file name="addressBar.js">
angular.module('address-bar', [])
.directive('ngAddressBar', function($browser, $timeout) {
return {
template: 'Address: <input id="addressBar" type="text" style="width: 400px" >',
link: function(scope, element, attrs){
var input = element.children("input"), delay;
input.on('keypress keyup keydown', function(event) {
delay = (!delay ? $timeout(fireUrlChange, 250) : null);
event.stopPropagation();
})
.val($browser.url());
$browser.url = function(url) {
return url ? input.val(url) : input.val();
};
function fireUrlChange() {
delay = null;
$browser.urlChange(input.val());
}
}
};
});
</file>
<file name="protractor.js" type="protractor">
var addressBar = element(by.css("#addressBar")),
url = 'http://www.example.com/base/index.html#!/path?a=b#h';
it("should show fake browser info on load", function(){
expect(addressBar.getAttribute('value')).toBe(url);
expect(element(by.binding('$location.protocol')).getText()).toBe('http');
expect(element(by.binding('$location.host')).getText()).toBe('www.example.com');
expect(element(by.binding('$location.port')).getText()).toBe('80');
expect(element(by.binding('$location.path')).getText()).toBe('/path');
expect(element(by.binding('$location.search')).getText()).toBe('{"a":"b"}');
expect(element(by.binding('$location.hash')).getText()).toBe('h');
});
it("should change $location accordingly", function(){
var navigation = element.all(by.css("#navigation a"));
navigation.get(0).click();
expect(addressBar.getAttribute('value')).toBe("http://www.example.com/base/index.html#!/first?a=b");
expect(element(by.binding('$location.protocol')).getText()).toBe('http');
expect(element(by.binding('$location.host')).getText()).toBe('www.example.com');
expect(element(by.binding('$location.port')).getText()).toBe('80');
expect(element(by.binding('$location.path')).getText()).toBe('/first');
expect(element(by.binding('$location.search')).getText()).toBe('{"a":"b"}');
expect(element(by.binding('$location.hash')).getText()).toBe('');
navigation.get(1).click();
expect(addressBar.getAttribute('value')).toBe("http://www.example.com/base/index.html#!/sec/ond?flag#hash");
expect(element(by.binding('$location.protocol')).getText()).toBe('http');
expect(element(by.binding('$location.host')).getText()).toBe('www.example.com');
expect(element(by.binding('$location.port')).getText()).toBe('80');
expect(element(by.binding('$location.path')).getText()).toBe('/sec/ond');
expect(element(by.binding('$location.search')).getText()).toBe('{"flag":true}');
expect(element(by.binding('$location.hash')).getText()).toBe('hash');
});
</file>
</example>
# Caveats
@@ -622,23 +813,24 @@ The Angular's compiler currently does not support two-way binding for methods (s
to the $location object (using {@link input[text] ngModel} directive on an input
field), you will need to specify an extra model property (e.g. `locationPath`) with two {@link ng.$rootScope.Scope#$watch $watchers}
which push $location updates in both directions. For example:
<example>
<example module="locationExample">
<file name="index.html">
<div ng-controller="LocationController">
<input type="text" ng-model="locationPath" />
</div>
</file>
<file name="script.js">
function LocationController($scope, $location) {
$scope.$watch('locationPath', function(path) {
$location.path(path);
});
$scope.$watch(function() {
return $location.path();
}, function(path) {
$scope.locationPath = path;
});
}
angular.module('locationExample', [])
.controller('LocationController', ['$scope', '$location', function ($scope, $location) {
$scope.$watch('locationPath', function(path) {
$location.path(path);
});
$scope.$watch(function() {
return $location.path();
}, function(path) {
$scope.locationPath = path;
});
}]);
</file>
</example>
+1
View File
@@ -1,5 +1,6 @@
@ngdoc overview
@name Animations
@sortOrder 310
@description
+5 -2
View File
@@ -1,5 +1,6 @@
@ngdoc overview
@name Bootstrap
@sortOrder 350
@description
# Bootstrap
@@ -19,7 +20,7 @@ initialization.
<html xmlns:ng="http://angularjs.org" ng-app>
<body>
...
<script src="angular.js">
<script src="angular.js"></script>
</body>
</html>
```
@@ -90,7 +91,9 @@ Here is an example of manually initializing Angular:
<!doctype html>
<html>
<body>
Hello {{'World'}}!
<div ng-controller="MyController">
Hello {{greetMe}}!
</div>
<script src="http://code.angularjs.org/snapshot/angular.js"></script>
<script>
+11 -6
View File
@@ -1,7 +1,10 @@
@ngdoc overview
@name HTML Compiler
@sortOrder 330
@description
# HTML Compiler
<div class="alert alert-warning">
**Note:** this guide is targeted towards developers who are already familiar with AngularJS basics.
@@ -11,7 +14,7 @@ If you want a deeper look into Angular's compilation process, you're in the righ
</div>
# Overview
## Overview
Angular's {@link ng.$compile HTML compiler} allows the developer to teach the
browser new HTML syntax. The compiler allows you to attach behavior to any HTML element or attribute
@@ -84,7 +87,9 @@ Here is a directive which makes any element draggable. Notice the `draggable` at
position: 'relative',
border: '1px solid red',
backgroundColor: 'lightgrey',
cursor: 'pointer'
cursor: 'pointer',
display: 'block',
width: '65px'
});
element.on('mousedown', function(event) {
// Prevent default dragging of selected content
@@ -198,7 +203,7 @@ This should help give you an idea of what Angular does internally.
// Step 3: link the compiled template with the scope.
var element = linkFn(scope);
// Step 4: Append to DOM (optional)
parent.appendChild(element);
```
@@ -226,7 +231,7 @@ moved to the compile function for performance reasons.
To understand, let's look at a real-world example with `ngRepeat`:
```html
Hello {{user}}, you have these actions:
Hello {{user.name}}, you have these actions:
<ul>
<li ng-repeat="action in user.actions">
{{action.description}}
@@ -236,7 +241,7 @@ Hello {{user}}, you have these actions:
When the above example is compiled, the compiler visits every node and looks for directives.
`{{user}}` matches the {@link ng.$interpolate interpolation directive}
`{{user.name}}` matches the {@link ng.$interpolate interpolation directive}
and `ng-repeat` matches the {@link ng.directive:ngRepeat `ngRepeat` directive}.
But {@link ng.directive:ngRepeat ngRepeat} has a dilemma.
@@ -327,7 +332,7 @@ The first issue we have to solve is that the dialog box template expects `title`
But we would like the template's scope property `title` to be the result of interpolating the
`<dialog>` element's `title` attribute (i.e. `"Hello {{username}}"`). Furthermore, the buttons expect
the `onOk` and `onCancel` functions to be present in the scope. This limits the usefulness of the
widget. To solve the mapping issue we use the `locals` to create local variables which the template
widget. To solve the mapping issue we use the `scope` to create local variables which the template
expects as follows:
```js
+14 -16
View File
@@ -1,5 +1,6 @@
@ngdoc overview
@name Conceptual Overview
@sortOrder 200
@description
# Conceptual Overview
@@ -37,10 +38,10 @@ Let's start with input fields for quantity and cost whose values are multiplied
<div ng-app ng-init="qty=1;cost=2">
<b>Invoice:</b>
<div>
Quantity: <input type="number" ng-model="qty" required >
Quantity: <input type="number" ng-model="qty">
</div>
<div>
Costs: <input type="number" ng-model="cost" required >
Costs: <input type="number" ng-model="cost">
</div>
<div>
<b>Total:</b> {{qty * cost | currency}}
@@ -55,22 +56,19 @@ Try out the Live Preview above, and then let's walk through the example and desc
This looks like normal HTML, with some new markup. In Angular, a file like this is called a
<a name="template">"{@link templates template}"</a>. When Angular starts your application, it parses and
processes this new markup from the template using the so called <a name="compiler">"{@link compiler compiler}"</a>.
processes this new markup from the template using the so-called <a name="compiler">"{@link compiler compiler}"</a>.
The loaded, transformed and rendered DOM is then called the <a name="view">"view"</a>.
The first kind of new markup are the so called <a name="directive">"{@link directive directives}"</a>.
The first kind of new markup are the so-called <a name="directive">"{@link directive directives}"</a>.
They apply special behavior to attributes or elements in the HTML. In the example above we use the
{@link ng.directive:ngApp `ng-app`} attribute, which is linked to a directive that automatically
initializes our application. Angular also defines a directive for the {@link ng.directive:input `input`}
element that adds extra behavior to the element. E.g. it is able to automatically validate that the entered
text is non empty by evaluating the `required` attribute.
The {@link ng.directive:ngModel `ng-model`} directive stores/updates
the value of the input field into/from a variable and shows the validation state of the input field by
adding css classes. In the example we use these css classes to mark an empty input field with a red border.
element that adds extra behavior to the element. The {@link ng.directive:ngModel `ng-model`} directive
stores/updates the value of the input field into/from a variable.
<div class="alert alert-info">
**Custom directives to access the DOM**: In Angular, the only place where an application touches the DOM is
within directives. This is good as artifacts that access the DOM are hard to test.
**Custom directives to access the DOM**: In Angular, the only place where an application should access the DOM is
within directives. This is important because artifacts that access the DOM are hard to test.
If you need to access the DOM directly you should write a custom directive for this. The
{@link directive directives guide} explains how to do this.
</div>
@@ -91,7 +89,7 @@ A filter formats the value of an expression for display to the user.
In the example above, the filter {@link ng.filter:currency `currency`} formats a number
into an output that looks like money.
The important thing in the example is that angular provides _live_ bindings:
The important thing in the example is that Angular provides _live_ bindings:
Whenever the input values change, the value of the expressions are automatically
recalculated and the DOM is updated with their values.
The concept behind this is <a name="databinding">"{@link databinding two-way data binding}"</a>.
@@ -152,13 +150,13 @@ different currencies and also pay the invoice.
What changed?
First, there is a new JavaScript file that contains a so called <a name="controller">"{@link controller controller}"</a>.
First, there is a new JavaScript file that contains a so-called <a name="controller">"{@link controller controller}"</a>.
More exactly, the file contains a constructor function that creates the actual 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 a
{@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
This directive tells Angular that the new `InvoiceController` is responsible for the element with the directive
and all of the element's children.
The syntax `InvoiceController as invoice` tells Angular to instantiate the controller
and save it in the variable `invoice` in the current scope.
@@ -265,7 +263,7 @@ services, ...) is created and wired using dependency injection. Within Angular,
the DI container is called the <a name="injector">"{@link di injector}"</a>.
To use DI, there needs to be a place where all the things that should work together are registered.
In Angular, this is the purpose of the so called <a name="module">"{@link module modules}"</a>.
In Angular, this is the purpose of the so-called <a name="module">"{@link module modules}"</a>.
When Angular starts, it will use the configuration of the module with the name defined by the `ng-app` directive,
including the configuration of all modules that this module depends on.
@@ -323,7 +321,7 @@ The following example shows how this is done with Angular:
angular.module('finance3', [])
.factory('currencyConverter', ['$http', function($http) {
var YAHOO_FINANCE_URL_PATTERN =
'http://query.yahooapis.com/v1/public/yql?q=select * from '+
'//query.yahooapis.com/v1/public/yql?q=select * from '+
'yahoo.finance.xchange where pair in ("PAIRS")&format=json&'+
'env=store://datatables.org/alltableswithkeys&callback=JSON_CALLBACK';
var currencies = ['USD', 'EUR', 'CNY'];
+20 -26
View File
@@ -1,5 +1,6 @@
@ngdoc overview
@name Controllers
@sortOrder 220
@description
# Understanding Controllers
@@ -37,27 +38,8 @@ The properties contain the **view model** (the model that will be presented by t
`$scope` properties will be available to the template at the point in the DOM where the Controller
is registered.
The following example shows a very simple constructor function for a Controller, `GreetingController`,
which attaches a `greeting` property containing the string `'Hola!'` to the `$scope`:
```js
function GreetingController($scope) {
$scope.greeting = 'Hola!';
}
```
Once the Controller has been attached to the DOM, the `greeting` property can be data-bound to the
template:
```js
<div ng-controller="GreetingController">
{{ greeting }}
</div>
```
**NOTE**: Although Angular allows you to create Controller functions in the global scope, this is
not recommended. In a real application you should use the `.controller` method of your
{@link module Angular Module} for your application as follows:
The following example demonstrates creating a `GreetingController`, which attaches a `greeting`
property containing the string `'Hola!'` to the `$scope`:
```js
var myApp = angular.module('myApp',[]);
@@ -67,9 +49,24 @@ myApp.controller('GreetingController', ['$scope', function($scope) {
}]);
```
We create an {@link module Angular Module}, `myApp`, for our application. Then we add the controller's
constructor function to the module using the `.controller()` method. This keeps the controller's
constructor function out of the global scope.
<div class="alert alert-info">
We have used an **inline injection annotation** to explicitly specify the dependency
of the Controller on the `$scope` service provided by Angular. See the guide on
[Dependency Injection](http://docs.angularjs.org/guide/di) for more information.
{@link guide/di Dependency Injection} for more information.
</div>
We attach our controller to the DOM using the `ng-controller` directive. The `greeting` property can
now be data-bound to the template:
```js
<div ng-controller="GreetingController">
{{ greeting }}
</div>
```
# Adding Behavior to a Scope Object
@@ -329,10 +326,7 @@ describe('state', function() {
expect(childScope.timeOfDay).toBe('morning');
expect(childScope.name).toBe('Mattie');
expect(grandChildScope.timeOfDay).toBe('evening');
expect(grandChildScope.name).toBe('Gingerbreak Baby');
expect(grandChildScope.name).toBe('Gingerbread Baby');
});
});
```
+1
View File
@@ -1,5 +1,6 @@
@ngdoc overview
@name Working With CSS
@sortOrder 510
@description
+1
View File
@@ -1,5 +1,6 @@
@ngdoc overview
@name Data Binding
@sortOrder 210
@description
Data-binding in Angular apps is the automatic synchronization of data between the model and view
+20 -12
View File
@@ -1,5 +1,6 @@
@ngdoc overview
@name Dependency Injection
@sortOrder 250
@description
# Dependency Injection
@@ -109,7 +110,7 @@ asks the injector to create an instance of the controller and its dependencies.
injector.instantiate(MyController);
```
This is all done behinds the scenes. Notice that by having the `ng-controller` ask the injector to
This is all done behind the scenes. Notice that by having the `ng-controller` ask the injector to
instantiate the class, it can satisfy all of the dependencies of `MyController` without the
controller ever knowing about the injector.
@@ -135,7 +136,7 @@ These can be used interchangeably as you see fit and are equivalent.
### Implicit Dependencies
The simplest way to get hold of the dependencies, is to assume that the function parameter names
The simplest way to get hold of the dependencies is to assume that the function parameter names
are the names of the dependencies.
```js
@@ -144,7 +145,7 @@ function MyController($scope, greeter) {
}
```
Given a function the injector can infer the names of the service to inject by examining the
Given a function the injector can infer the names of the services to inject by examining the
function declaration and extracting the parameter names. In the above example `$scope`, and
`greeter` are two services which need to be injected into the function.
@@ -154,7 +155,7 @@ rename the method parameter names. This makes this way of annotating only useful
### `$inject` Property Annotation
To allow the minifiers to rename the function parameters and still be able to inject right services,
To allow the minifiers to rename the function parameters and still be able to inject the right services,
the function needs to be annotated with the `$inject` property. The `$inject` property is an array
of service names to inject.
@@ -166,7 +167,7 @@ MyController['$inject'] = ['$scope', 'greeter'];
```
In this scenario the ordering of the values in the `$inject` array must match the ordering of the
arguments to inject. Using above code snippet as an example, `$scope` will be injected into
arguments to inject. Using the above code snippet as an example, `$scope` will be injected into
`renamed$scope` and `greeter` into `renamedGreeter`. Care must be taken that the `$inject`
annotation is kept in sync with the actual arguments in the function declaration.
@@ -206,7 +207,7 @@ someModule.factory('greeter', ['$window', function(renamed$window) {
}]);
```
Here, instead of simply providing the factory function, we pass an array, whose elements consist of
Here, instead of simply providing the factory function, we pass an array whose elements consist of
a list of strings (the names of the dependencies) followed by the function itself.
Keep in mind that all of the annotation styles are equivalent and can be used anywhere in Angular
@@ -218,15 +219,22 @@ DI is pervasive throughout Angular. You can use it when defining components or w
and `config` blocks for a module.
- Components such as services, directives, filters and animations are defined by an injectable factory
method or constructor function. These components can be injected with "service" components as
dependencies.
- The `run` and `config` methods accept a function, which can also be injected with "service"
method or constructor function. These components can be injected with "service" and "value"
components as dependencies.
- The `run` method accepts a function, which can be injected with "service", "value" and "constant"
components as dependencies. Note that you cannot inject "providers" into `run` blocks.
- The `config` method accepts a function, which can be injected with "provider" and "constant"
components as dependencies. Note that you cannot inject "service" or "value" components into
configuration
- Controllers are defined by a constructor function, which can be injected with any of the "service"
components as dependencies, but they can also be provided with special dependencies. See "DI in
Controllers" below.
and "value" components as dependencies, but they can also be provided with special dependencies. See
{@link di#controllers Controllers} below for a list of these special dependencies.
See {@link module#module-loading-dependencies Modules} for more details about injecting dependencies
into `run` and `config` blocks.
### Factory Methods
+28 -4
View File
@@ -1,5 +1,6 @@
@ngdoc overview
@name Directives
@sortOrder 300
@description
# Creating Custom Directives
@@ -159,7 +160,7 @@ restrictions, you cannot simply write `cx="{{cx}}"`.
With `ng-attr-cx` you can work around this problem.
If an attribute with a binding is prefixed with the `ngAttr` prefix (denormalized as `ng-attr-`)
then during the binding will be applied to the corresponding unprefixed attribute. This allows
then during the binding it will be applied to the corresponding unprefixed attribute. This allows
you to bind to attributes that would otherwise be eagerly processed by browsers
(e.g. an SVG element's `circle[cx]` attributes).
@@ -352,7 +353,7 @@ element as a customer component.
Our `myCustomer` directive above is great, but it has a fatal flaw. We can only use it once within a
given scope.
In its current implementation, we'd need to create a different controller each time In order to
In its current implementation, we'd need to create a different controller each time in order to
re-use such a directive:
<example module="docsScopeProblemExample">
@@ -475,7 +476,6 @@ within our directive's template:
angular.module('docsIsolationExample', [])
.controller('Controller', ['$scope', function($scope) {
$scope.naomi = { name: 'Naomi', address: '1600 Amphitheatre' };
$scope.vojta = { name: 'Vojta', address: '3456 Somewhere Else' };
}])
.directive('myCustomer', function() {
@@ -537,7 +537,7 @@ where:
In our `link` function, we want to update the displayed time once a second, or whenever a user
changes the time formatting string that our directive binds to. We will use the `$interval` service
to call a handler on a regular basis. This is easier than using `$timeout` but also works better with
end-to-end testing, where we want to ensure that all $timeouts have completed before completing the test.
end-to-end testing, where we want to ensure that all `$timeout`s have completed before completing the test.
We also want to remove the `$interval` if the directive is deleted so we don't introduce a memory leak.
<example module="docsTimeDirective">
@@ -910,6 +910,30 @@ Looking back at `myPane`'s definition, notice the last argument in its `link` fu
When a directive requires a controller, it receives that controller as the fourth argument of its
`link` function. Taking advantage of this, `myPane` can call the `addPane` function of `myTabs`.
If multiple controllers are required, the `require` option of the directive can take an array argument.
The corresponding parameter being sent to the `link` function will also be an array.
```js
angular.module('docsTabsExample', [])
.directive('myPane', function() {
return {
require: ['^myTabs', '^ngModel'],
restrict: 'E',
transclude: true,
scope: {
title: '@'
},
link: function(scope, element, attrs, controllers) {
var tabsCtrl = controllers[0],
modelCtrl = controllers[1];
tabsCtrl.addPane(scope);
},
templateUrl: 'my-pane.html'
};
});
```
Savvy readers may be wondering what the difference is between `link` and `controller`.
The basic difference is that `controller` can expose an API, and `link` functions can interact with
controllers using `require`.
+8 -8
View File
@@ -1,12 +1,12 @@
@workInProgress
@ngdoc overview
@name E2E Testing
@sortOrder 420
@description
# E2E Testing
<div class="alert alert-danger">
**Note:** In the past, end to end testing could be done with a deprecated tool called
**Note:** In the past, end-to-end testing could be done with a deprecated tool called
[Angular Scenario Runner](http://code.angularjs.org/1.2.16/docs/guide/e2e-testing). That tool
is now in maintenance mode.
</div>
@@ -14,7 +14,7 @@ is now in maintenance mode.
As applications grow in size and complexity, it becomes unrealistic to rely on manual testing to
verify the correctness of new features, catch bugs and notice regressions. End to end tests
are the first line of defense for catching bugs, but sometimes issues come up with integration
between components which can't be captured in a unit test. End to end tests are made to find
between components which can't be captured in a unit test. End-to-end tests are made to find
these problems.
We have built [Protractor](https://github.com/angular/protractor), an end
@@ -23,12 +23,12 @@ Angular application.
## Using Protractor
Protractor is a [Node.js](http://nodejs.org) program, and runs end to end tests that are also
Protractor is a [Node.js](http://nodejs.org) program, and runs end-to-end tests that are also
written in JavaScript and run with node. Protractor uses [WebDriver](https://code.google.com/p/selenium/wiki/GettingStarted)
to control browsers and simulate user actions.
For more information on Protractor, view [getting started](https://github.com/angular/protractor/blob/master/docs/getting-started.md)
or the [api docs](https://github.com/angular/protractor/blob/master/docs/api.md).
For more information on Protractor, view [getting started](http://angular.github.io/protractor/#/getting-started)
or the [api docs](http://angular.github.io/protractor/#/api).
Protractor uses [Jasmine](http://jasmine.github.io/1.3/introduction.html) for its test syntax.
As in unit testing, a test file is comprised of one or
@@ -76,8 +76,8 @@ filter the list of items.
## Example
See the [angular-seed](https://github.com/angular/angular-seed) project for more examples, or look
at the embedded examples in the Angular documentation (For example, [$http](http://docs.angularjs.org/api/ng/service/$http)
has an end to end test in the example under the `protractor.js` tag).
at the embedded examples in the Angular documentation (For example, {@link $http $http}
has an end-to-end test in the example under the `protractor.js` tag).
## Caveats

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