Compare commits

..

101 Commits

Author SHA1 Message Date
Georgios Kalpakas 25d4e5cca4 fix($http): pass event object to eventHandlers/uploadEventHandlers
Fixes #14436
2016-04-15 14:09:39 +01:00
Peter Bacon Darwin c67112563f revert: refactor($compile): move setting of controller data to single location
Reverted from commit 21d148aedc since it caused
the Angular Material tabs directive to fail.
2016-04-15 14:09:05 +01:00
Jannick Fahlbusch 2b2ec26a75 chore(docsApp): open plnkr.co with HTTPS
Plnkr should be opened via HTTPS instead of HTTP to supress warnings about an insecure connection

Closes #14445
2016-04-15 14:55:13 +02:00
cloverharvest 41f90e5fb0 docs($http): fix a typo (his --> this)
Closes #14430
2016-04-15 01:25:09 +03:00
Adam Demuri a85c591d36 docs(component): document 'require' in angular.component
Closes #14429
2016-04-15 01:12:43 +03:00
Peter Bacon Darwin f276ad0d51 docs(CHANGELOG): add release notes for 1.5.4 2016-04-14 09:13:48 +01:00
Pete Bacon Darwin 33f817b99c feat($componentController): provide isolated scope if none is passed (#14425)
Closes #14425
2016-04-13 18:34:39 +01:00
Martin Staffa 6a4124d0fb perf(ngOptions): use documentFragment to populate select
This changes the way option elements are generated when the ngOption collection changes.
Previously, we would re-use option elements when possible (updating their text and
label). Now, we first remove all currently displayed options and the create new options for the
collection. The new options are first appended to a documentFragment, which is in the end appended
to the selectElement.

Using documentFragment improves render performance in IE with large option collections
(> 100 elements) considerably.

Creating new options from scratch fixes issues in IE where the select would become unresponsive
to user input.

Fixes #13607
Fixes #13239
Fixes #12076
2016-04-13 18:42:10 +02:00
Georgios Kalpakas 26d1b34321 docs(ngView): add known issue about asynchronously loaded ngView
Closes #14424
2016-04-13 18:45:40 +03:00
Georgios Kalpakas 7fba6b603f revert: "fix(ngRoute): allow ngView to be included in an asynchronously loaded template"
This reverts commit 5e37b2a7fd.
Eagerly loading `$route`, could break tests, because it might request the root or default route
template (something `$httpBackend` would know nothing about).

It will be re-applied for `v1.6.x`, with a breaking change notice and possibly a way to disable
the feature is tests.

Fixes #14337
2016-04-13 18:45:06 +03:00
Jason Bedard c115b37c33 perf($compile): use createMap() for directive bindings to allow fast forEach
Closes #12529
2016-04-13 12:05:30 +03:00
Georgii Dolzhykov d20ba95e28 docs(Module): fix parameter names for .decorator()
Closes #14413
2016-04-12 14:52:18 +03:00
aortyl 7945e5010a docs(guide/scope): add comma for readability
Closes #14411
2016-04-11 22:22:36 +03:00
Jason Bedard 21d148aedc refactor($compile): move setting of controller data to single location
Closes #13421
2016-04-11 18:54:41 +01:00
Georgios Kalpakas 4c8aeefb62 fix($compile): do not use noop() as controller for multiple components
Currently, custom annotations are copied from the CDO onto the controller constructor.
Using `noop()` when no controller has been specified, pollutes it with custom annotations and
makes one component's annotations available to all other components that have `noop()` as their
controller.

Fixes #14391
Closes #14402
2016-04-11 18:43:17 +01:00
a510 d384834fde fix($injector): ensure functions with overridden toString() are annotated properly
Closes #14361
2016-04-11 13:03:56 +03:00
David Rodenas Pico f975d8d448 fix(ngClass): fix watching of an array expression containing an object
Closes #14405
2016-04-11 12:40:36 +03:00
Georgios Kalpakas 2602daf993 refactor($compile): remove unnecessary call to isDefined()
(As discussed in https://github.com/angular/angular.js/pull/14406/files#r59131398.)
2016-04-11 12:33:07 +03:00
Gene McCulley 9f681c459a docs(numberFilter): fix the description of the returned value
Closes #14408
2016-04-11 12:28:08 +03:00
Peter Bacon Darwin d9448dcb9f fix($compile): still trigger $onChanges even if the inner value already matches the new value
Closes #14406
2016-04-10 20:31:01 +01:00
Jurko Gospodnetić e9c718a465 fix(ngMock): fix collecting stack trace in inject() on IE10+, PhantomJS
Add support for collecting current stack trace information in browsers
(e.g. IE10+, PhantomJS) that do not automatically store the current stack trace
information in a newly created `Error` object's `stack` property, but
only add it there once the `Error` gets thrown.

The original implementation works fine in Firefox & Chrome, but fails on IE10+
and PhantomJS where it, for example, breaks Karma's error reporting in cases
when an exception is thrown in a test like the following:

```
it('the holy crusade', inject(function() {
  var x = {};
  x.holyGrail();
}));
```

In this case, the ngMock `inject()` implementation would incorrectly add the
word `undefined` at the end of the collected error stack trace information,
thus causing the main error description to be reported back to Karma as
`undefined`.

The added test makes sure this functionality:

- works as expected in browsers supporting JavaScript stack trace
  collection, e.g. Chrome, Firefox, IE10+, Opera & PhantomJS
- does not add any bogus stack track information in browsers that do
  not support JavaScript stack trace collection, e.g. IE9

Fixes #13591
Closes #13592

Closes #13593
2016-04-09 20:51:22 +03:00
Georgios Kalpakas 4dc44f7205 test(helpers): fix error message generation for toHaveBeenCalledOnce[With] matchers
Jasmine 2.4 (maybe earlier) does not support returning an array containing both the "normal" and the
negative error messages. It will always concatenate them.

Closes #14275
2016-04-09 17:06:47 +03:00
Jan Niehusmann 499e1b2adf fix($compile): handle boolean attributes in @ bindings
Commit db5e0ff handles initial values of boolean attributes. The same
change needs to be applied inside the attrs.$observe() call.

Closes #14070
2016-04-09 16:53:41 +03:00
Peter Bacon Darwin 28c6c4dae2 docs(jqlite): add known issue
Closes #14251
2016-04-08 21:27:21 +01:00
Peter Bacon Darwin 791148a328 chore(package.json): update dgeni-packages to 0.12.0
This gives us `@knownissues` tags
2016-04-08 21:27:05 +01:00
Peter Bacon Darwin 01b1845088 feat($http): support handling additional XHR events
Closes #14367
Closes #11547
Closes #1934
2016-04-08 19:16:56 +01:00
Chris Chua 56c861c9e1 feat($http): support handling additional XHR events
Closes #11547
Closes #1934
2016-04-08 19:16:49 +01:00
Martin Staffa 451e0f6175 docs(README): fix typo 2016-04-08 19:00:20 +02:00
Martin Staffa aee7f1c72f docs(guide/accessibility): make jshint happy 2016-04-08 18:55:22 +02:00
Pablo Iván G. Soto 5fe28a0422 docs(README): add https links, improve style 2016-04-08 18:37:04 +02:00
Martin Staffa f56586d9a9 docs(guide/Accessibility): fix markdown errors, tweak layout 2016-04-08 17:32:13 +02:00
mohamed amr ec0baadcb6 feat(ngAria): add support for aria-readonly based on ngReadonly
Closes #14140
Closes #14077
2016-04-08 17:32:12 +02:00
Martin Staffa 9147d5c04a docs(ngComponentRouter): add note about shims needed for IE 2016-04-08 17:32:12 +02:00
Josh cb801378c9 docs(ngComponentRouter): fix typo
Simple typo fix from `betweent he` to `between the`

Closes #14396
2016-04-08 15:47:01 +02:00
Martin Staffa 79604f4628 fix(ngAnimate): remove event listeners only after all listeners have been called
The fix for removing the event callbacks on destroy introduced in
ce7f400011 removed the events too early, so that the event callbacks
for the "close" phase in "leave" animations were not called.

This commit fixes the behavior so that the event callbacks are only removed during on('$destroy')
when no animation is currently active on the element. When an animation is active, the event callbacks
will be removed after all callbacks have run, and if the element has no parent (has been removed from
the DOM).

Closes #14321
2016-04-08 15:47:00 +02:00
Martin Staffa bf6cb8ab0d feat(ngAnimate): let $animate.off() remove all listeners for an element 2016-04-08 15:46:59 +02:00
Andrew de74b3fd85 docs(guide/Components): fix small single letter typo
line 136: 'not' should be 'note'

Closes #14390
2016-04-08 01:32:00 +02:00
Martin Staffa c7a92d2a9a fix(ngAnimate): fire callbacks when document is hidden
Since commit a3a7afd3aa, animations are not run
when the document is hidden (only their structural or class change effects are executed).
However, some libraries rely on the $animate.on() callbacks to be called even when no actual animation
runs.
This commit restores the behavior for the ngAnimate.$animate functions.
Note that callbacks still won't be called if animations are disabled, because this would be be a potential
breaking change, as some applications might rely on this implementation.

Fixes #14120
2016-04-08 01:31:59 +02:00
Martin Staffa da284fc354 test(ngAnimate): test calling callbacks for various constellations 2016-04-08 01:31:58 +02:00
Martin Staffa 90da3059ce fix(ngAnimate): fire callbacks in the correct order for certain skipped animations 2016-04-08 01:31:58 +02:00
SHAHRUKH-KHAN 651fd05eca docs(angular.equals): add example
This Pull requests improves the doc by adding a example to `angular.equals` function.

Closes #14232
2016-04-07 15:17:54 +02:00
glenr4 85d7e09bef docs(ngAnimate): fix toggle button in example
The toggle button code on line 153 only sets bool to true, rather than toggling it.
The proposed change fixes this.

Closes #14387
2016-04-07 15:17:54 +02:00
andykuszyk 243a57648b docs(misc/Getting Started): fix markdown for headings
Closes #14353
2016-04-07 15:17:54 +02:00
Maciej Kołodziejczak 158dec330c docs(ngComponentRouter): fix a typo
Closes #14357
2016-04-07 15:17:53 +02:00
Andrew a1e63c8d4a docs(guide/Components): clarify output events with extra example and note
Add additional line from example which demonstrates using the snake cased attribute binding in
parent component template.
Add note clarifying camelCase to snake-case requirement to use the Output binding callback feature.

Closes #14365
2016-04-07 15:17:53 +02:00
Artur 8cc9978d15 docs(guide/Components): fix typo, improve style
Closes #14384
2016-04-07 15:17:52 +02:00
Robin Janssens 78a404da0e docs($httpBackend): update response data types
Updated docs to reflect that response data can either be an array, object _or_ a string
Technically, response data can be anything that can be handled by angular.copy,
but since string and JSON data is most commonly mocked, the main types are sufficient.

Closes #14346
2016-04-07 15:17:52 +02:00
Michał Gołębiowski f1bb8369b5 refactor(jshint): don't assume browser-only globals
(cherry-picked from ddad26402b)

Fixes #13442
Closes #14345
2016-04-06 20:43:06 +02:00
Peter Bacon Darwin 76b6941b4c docs(componentRouter): add custom installation instructions 2016-04-05 21:10:19 +01:00
Peter Bacon Darwin e72990dc37 fix($compile): don't throw if controller is named 2016-04-04 21:26:13 +01:00
Peter Bacon Darwin f338e96ccc feat($compile): put custom annotations on DDO
Closes #14369
Closes #14279
Closes #14284
2016-04-04 20:07:31 +01:00
Peter Bacon Darwin 0ad2b70862 fix($compile): ensure that $onChanges hook is called correctly
Due to the way that we instantiate controllers, the `$onChanges` hook
was not always available at the time we were trying to trigger the initial
call to this hook. For instance, if the hook was actually defined inside
the constructor function.

This commit fixes that but also fixes the fact that the initial call was
being made in the postDigest anyway, which was incorrect because the
it should have been made before the `$onInit` call.

Closes #14355
Closes #14359
2016-04-01 17:41:41 +01:00
Georgios Kalpakas 5261a374a9 test($browser): fix typo in property name (histroy --> history)
(The semantics of the test aren't affected, because we just needed a falsy value.)
2016-03-31 13:30:25 +03:00
Martin Staffa 832eba5fc9 fix(ngOptions): set select value when model matches disabled option
When ngModel is set to a value that matches a disabled option, ngOptions will now select the option
in the select element, which will set select.val() to the option hash value and visually
show the option value / label as selected in the select box. Previously, disabled
options forced the unknown value.
The previous behavior is inconsistent with both default HTML behavior and select with
ngModel but without ngOptions. Both allow disabled values to be selected programmatically.

A common use case for this behavior is an option that was previously valid, but has
been disabled, and cannot be selected again.

This commit removes a duplicate test, and all other tests that previously checked that disabled
options are not set have been adjusted to the ensure the opposite.

Fixes #12756
2016-03-30 11:42:07 +02:00
cscport 2b569fc0b2 docs(angular.bootstrap): fix capitalization in error message
Closes #14325
2016-03-27 15:43:37 +03:00
Lucas Mirelmann ee6aeb08bf docs(ngParseExt): Fix package name 2016-03-27 00:00:14 +01:00
Peter Bacon Darwin 8d43d8b8e7 feat($compile): add isFirstChange() method to onChanges object
Closes #14318
Closes #14323
2016-03-26 20:06:13 +00:00
Lucas Mirelmann d08f5c6986 feat(ngParseExt): New ngParseExt module
New ngParseExt module

Including this module into an application will extend $parse to allow identifiers
following ES6 identifiers
2016-03-26 20:41:11 +01:00
Lucas Mirelmann 3e7fa19197 feat($parse): Add the ability to define the identifier characters
Add the ability to define the identifier starts and identifier continue characters
2016-03-26 20:41:01 +01:00
Lucas Mirelmann 5d379db72b chore(bower): Add parse-ext repository 2016-03-26 20:40:49 +01:00
Peter Bacon Darwin 514639b585 docs(CHANGELOG): add 1.5.3 release notes 2016-03-25 20:01:45 +00:00
Peter Bacon Darwin 9cd9956dcb feat($compile): add more lifecycle hooks to directive controllers
This change adds in the following new lifecycle hooks, which map in some
way to those in Angular 2:

 * `$onChanges(changesObj)` - Called whenever one-way bindings are updated. The `changesObj` is a hash whose keys
   are the names of the bound properties that have changed, and the values are an object of the form
   `{ currentValue: ..., previousValue: ... }`. Use this hook to trigger updates within a component such as
   cloning the bound value to prevent accidental mutation of the outer value.
 * `$onDestroy` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
   external resources, watches and event handlers.
 * `$postLink` - Called after this controller's element and its children been linked. Similar to the post-link
   function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
   Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
   they are waiting for their template to load asynchronously and their own compilation and linking has been
   suspended until that occurs.

Closes #14127
Closes #14030
Closes #14020
Closes #13991
Closes #14302
2016-03-25 12:56:08 +00:00
Martin Staffa c7813e9ebf fix(ngAnimate): run structural animations with cancelled out class changes
When multiple animations on the same element are queued before a $digest passes,
the animator tries to create as few actual animations as possible by joining / canceling
redundant animations. Class-based animations for example are cancelled when the classes that
are added and removed are the same, and the result is no class-change. This however must only
happen if there's no structural animation currently queued.

Fixes #14249
2016-03-24 00:13:16 +01:00
Martin Staffa ef91b04cdd fix(ngMessages): don't crash when nested messages are removed
Under specific circumstances, ngMessages would go into an infinite loop and crash the
browser / page:
- At least two ngMessage elements are wrapped inside another element (e.g. ngTransclude)
- The first message is currently visible
- The first message is removed (e.g. when the whole ngMessages element is removed by an ngIf)

When a message is removed, it looks for a previous message - in this specific case it would misidentify
the second message for a previous message, which would then cause the first message to be marked as the
second message's next message, resulting in an infinite loop, and crash.

This fix ensures that when searching for previous messages, ngMessage walks the DOM in a way so
that messages that come after the current message are never identified as previous messages.

This commit also detaches and destroys all child ngMessage elements when the ngMessages element is
destroyed, which should improve performance slightly.

Fixes #14183
Closes #14242
2016-03-24 00:13:16 +01:00
Alex Chuev 1acd97e18f docs(guide/component): add missing closing bracket
Closes #14299
2016-03-23 23:58:35 +02:00
Daniel Herman 513199ee9f fix($compile): workaround a GC bug in Chrome < 50
In the version of V8 used in Chrome < 50, the parent of template nodes for
`transclude: "element"` directives would be improperly garbage collected
despite still having been referenced via `parentNode`.

This bug surfaced due to the introduction of lazy transclusion (652b83e),
and appears under certain circumstances when using directive start and end elements.

It should be removed some time after Chrome 50 has been released.

Fixes #14041
Closes #14286
2016-03-23 22:06:17 +01:00
pmadruga 33f3c40e93 docs(error/$compile.baddir): mention "components" in directive name error
Closes #14212
2016-03-23 22:18:54 +02:00
Steve Mao 696cb95d5e docs($q): mention ES2015 (as a "synonym" for ES6) and remove "harmony"
Closes #14294
2016-03-22 12:09:02 +02:00
Georgios Kalpakas 457fd21a1a fix($sniffer): fix history sniffing in Chrome Packaged Apps
Although `window.history` is present in the context of Chrome Packaged Apps, it is not allowed to
access `window.history.pushState` or `window.history.state`, resulting in errors when trying to
"sniff" history support.
This commit fixes it by detecting a Chrome Packaged App (through the presence of
`window.chrome.app.runtime`). Note that `window.chrome.app` is present in the context of "normal"
webpages as well, but it doesn't have the `runtime` property, which is only available to packaged
apps (e.g. see https://developer.chrome.com/apps/api_index).

(It also also contains some style changes for making the structure and layout of `$sniffer` tests
 more consistent.)

Fixes #11932

Closes #13945
2016-03-22 11:57:18 +02:00
Wassim Chegham 3c6dfbf67d docs(guide/component-router): fix typos
Closes #14278
2016-03-22 02:18:44 +02:00
Owen Craig 3277b885c4 fix(formatNumber): handle small numbers correctly when gSize !== lgSize
By using `>=` when comparing the number length to `lgSize`, we'll provide the correct value, when
formatting numbers with different `lgSize` than `gSize`.

Fixes #14289

Closes #14290
2016-03-22 00:11:26 +02:00
Georgios Kalpakas 48a256d04b test(TzDate): fix test in Australia
Probably due to implementation differences in browsers for pre-DST period (see
https://github.com/angular/angular.js/issues/5017 and especially
https://github.com/angular/angular.js/issues/5017#issuecomment-90775226 for context), some
`TzDate` tests had different behavior on different Timezones/Regions (e.g. failed in Australia,
which started to observe DST in 1971).
Since the used year (`1970`) didn't have any particular significance, this commit fixes the issue
by using a year that is more consistently handled by browsers (`2000`).

Fixes #14272

Closes #14285
2016-03-21 20:45:35 +02:00
surya prakash singh 0579430799 docs(input[time]): fix a typo in the example
Closes #14220
2016-03-21 01:26:17 +02:00
Rongduan Zhu 39ac68dac1 docs(guide/component-router): changed path to match diagram
Closes #14277
2016-03-21 00:00:12 +02:00
Georgios Kalpakas 87fb44a5d3 docs(CHANGELOG.md): rearrange v1.5.1 to be right below v1.5.2
Moved the `v1.5.1` section above the `v1.4.10` one, so that it is right below the `v1.5.2` section
for easier reference. Also removed an empty "Breaking Changes" sub-section.

Closes #14283
2016-03-20 22:54:53 +02:00
Georgios Kalpakas 5c76b406f7 chore(ci-checks): fix the ddescribe-iit task for Jasmine 2
Closes #14276
2016-03-20 22:26:06 +02:00
Matias Niemelä f665968daf chore(CHANGELOG): update version reference 2016-03-18 15:37:43 -07:00
Matias Niemelä 5d1291c29d docs(CHANGELOG): add notes for v1.5.2 2016-03-18 15:04:06 -07:00
Martin Staffa ce7f400011 fix(ngAnimate.$animate): remove animation callbacks when the element is removed
The test for this didn't actually test the listener removal. The addClass animation after
the element removal didn't start because the enter animation was still in progress.
2016-03-18 17:10:26 +01:00
Martin Staffa 0fc8516b0c Revert "tests(jQuery): test on both oldest & latest supported jQuery version"
This reverts commit 94572e89c2. The commit snuck
in while cherry-picking commits from master.
2016-03-18 17:08:46 +01:00
Jason Bedard 28b2a9b583 style($compile,$controller): adding function names for debug/tracing
Closes #13420
2016-03-18 15:53:09 +01:00
Jason Bedard e8549372fc style($templateRequest): rename minError var to avoid name conflict
Closes #13701
2016-03-18 15:53:08 +01:00
Jason Bedard 5a434eb74e style(ngModel,ngOptions): make use of declared but unused variables 2016-03-18 15:53:06 +01:00
Jason Bedard 318de4db66 style(*): remove unused variables 2016-03-18 15:53:05 +01:00
Martin Staffa a6c79bf15d docs(guide/Services): add whitespace in code example
Closes #14156
2016-03-18 15:53:04 +01:00
Huc Arnaud c6a10a755e docs(error/tplrt): add missing ' in example code
Missing a ' @ line 46 class='wrapper'

Closes #14258
2016-03-18 15:53:03 +01:00
Maxim Salnikov 1d7bd5bf4f docs(guide/Component Router): fix typo in example code
Closes #14262
2016-03-18 15:53:03 +01:00
Michał Gołębiowski 94572e89c2 tests(jQuery): test on both oldest & latest supported jQuery version 2016-03-18 15:51:30 +01:00
Peter Bacon Darwin fee7bac392 revert: fix($compile): do not add <span> elements to root text nodes
This commit reverts 7617c08da6 which was accidentally
merged into 1.5.x (by @petebacondarwin in a moment of rebase madness) despite
it containing a breaking change.
2016-03-17 09:56:30 +00:00
Georgios Kalpakas dbb3b0f561 docs(CHANGELOG.md): add notes for v1.4.10 2016-03-16 21:17:02 +02:00
Michał Gołębiowski b8bfed6a52 tests(jQuery): make the tests pass on jQuery 3.0.0-beta1
Closes #14229
2016-03-16 18:29:13 +00:00
Georgios Kalpakas 7215a89e7d docs(CHANGELOG.md): fix typo in anchor name 2016-03-16 19:56:23 +02:00
Georgios Kalpakas b7cca56091 docs(CHANGELOG.md): add notes for v1.5.1 2016-03-16 19:53:43 +02:00
Josh Schneider 7338e433f8 docs(guide/component-router): fix incorrect hook name for $canActivate
The hook will most likely be named back to `$routerCanActivate` in the future,
but for now this change is accurate.

Closes #14237
2016-03-16 16:46:03 +00:00
Peter Bacon Darwin 119ed07d5a chore(travis): update node and browser versions 2016-03-16 14:08:10 +00:00
Peter Bacon Darwin 5f98ae8323 chore(package.json): fix up dist-tag
Now that 1.5.x is out of beta we need to change the dist-tag to `latest`
2016-03-16 14:08:10 +00:00
Peter Bacon Darwin 8a598b43bb chore(jenkins): update node version to 4.4 2016-03-16 14:08:10 +00:00
Peter Bacon Darwin e5dff4cfbe chore(jenkins): fix node version chooser in build scripts
The `set-node-version.sh` script was being run in its own shell and so
was not actually changing the current version of node.
2016-03-16 14:08:10 +00:00
Lucas Mirelmann 6c7a9cdd5f chore(*): Upgrade to Jasmine 2.4
Highlights:
New mechanism to run async tests as Jasmine 2 removed `runs`, `waits` and `waitsFor`
The functions `iit`, `ddescribe` and `tthey` were renamed `fit`, `fdescribe` and
`fthey` as the originals came from Karma, Karma no longer bundles Jasmine and the
new function name comes from Jasmine.

Closes #14226
2016-03-16 14:08:09 +00:00
Matias Niemelä 3b34f762fe chore(build): 1.5 versions should stick to 1.5.x 2016-03-16 14:06:49 +00:00
Martin Staffa fa167ba747 docs(guide/animations): fix code block styling 2016-03-16 14:06:49 +00:00
1131 changed files with 59385 additions and 174946 deletions
-11
View File
@@ -1,11 +0,0 @@
bower_components/**
build/**
docs/bower_components/**
docs/app/assets/js/angular-bootstrap/**
docs/config/templates/**
node_modules/**
lib/htmlparser/**
src/angular.bind.js
src/ngParseExt/ucd.js
i18n/closure/**
tmp/**
-117
View File
@@ -1,117 +0,0 @@
{
"rules": {
// Rules are divided into sections from http://eslint.org/docs/rules/
// Possible errors
"comma-dangle": ["error", "never"],
"no-cond-assign": ["error", "except-parens"],
"no-constant-condition": ["error", {"checkLoops": false}],
"no-control-regex": "error",
"no-debugger": "error",
"no-dupe-args": "error",
"no-dupe-keys": "error",
"no-duplicate-case": "error",
"no-empty-character-class": "error",
"no-empty": "error",
"no-ex-assign": "error",
"no-extra-boolean-cast": "error",
"no-extra-semi": "error",
"no-func-assign": "error",
"no-inner-declarations": "error",
"no-invalid-regexp": "error",
"no-irregular-whitespace": "error",
"no-negated-in-lhs": "error",
"no-obj-calls": "error",
"no-regex-spaces": "error",
"no-sparse-arrays": "error",
"no-unreachable": "error",
"use-isnan": "error",
"no-unsafe-finally": "error",
"valid-typeof": "error",
"no-unexpected-multiline": "error",
// Best practices
"accessor-pairs": "error",
"array-callback-return": "error",
"eqeqeq": ["error", "allow-null"],
"no-alert": "error",
"no-caller": "error",
"no-case-declarations": "error",
"no-eval": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-extra-label": "error",
"no-fallthrough": "error",
"no-floating-decimal": "error",
"no-implied-eval": "error",
"no-invalid-this": "error",
"no-iterator": "error",
"no-multi-str": "error",
"no-new-func": "error",
"no-new-wrappers": "error",
"no-new": "error",
"no-octal-escape": "error",
"no-octal": "error",
"no-proto": "error",
"no-redeclare": "error",
"no-return-assign": "error",
"no-script-url": "error",
"no-self-assign": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-throw-literal": "error",
"no-unmodified-loop-condition": "error",
"no-unused-expressions": "error",
"no-unused-labels": "error",
"no-useless-call": "error",
"no-useless-concat": "error",
"no-useless-escape": "error",
"no-void": "error",
"no-with": "error",
"radix": "error",
"wrap-iife": ["error", "inside"],
// Strict mode
"strict": ["error", "global"],
// Variables
"no-delete-var": "error",
"no-label-var": "error",
"no-restricted-globals": ["error", "event"],
"no-shadow-restricted-names": "error",
"no-undef-init": "error",
"no-undef": "error",
"no-unused-vars": ["error", { "vars": "local", "args": "none" }],
// Node.js
"handle-callback-err": "error",
// Stylistic issues
"array-bracket-spacing": ["error", "never"],
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
"comma-style": ["error", "last"],
"eol-last": "error",
"keyword-spacing": "error",
"linebreak-style": ["error", "unix"],
"max-len": ["error", { "code": 200, "ignoreComments": true, "ignoreUrls": true }],
"new-cap": "error",
"new-parens": "error",
"no-array-constructor": "error",
"no-bitwise": "error",
"no-mixed-spaces-and-tabs": "error",
"no-multiple-empty-lines": ["error", { "max": 3, "maxEOF": 1 }],
"no-whitespace-before-property": "error",
"no-spaced-func": "error",
"no-trailing-spaces": "error",
"no-unneeded-ternary": "error",
"quotes": ["error", "single"],
"semi-spacing": "error",
"semi": "error",
"space-before-blocks": ["error", "always"],
"space-before-function-paren": ["error", "never"],
"space-in-parens": ["error", "never"],
"space-infix-ops": "error",
"space-unary-ops": ["error", { "words": true, "nonwords": false }],
"unicode-bom": ["error", "never"]
}
}
-17
View File
@@ -1,17 +0,0 @@
{
"extends": "./.eslintrc-base.json",
"env": {
// Note: don't set `"browser": true`; code in "src/" should be compatible with
// non-browser environments like Node.js with a custom window implementation
// like jsdom. All browser globals should be taken from window.
"browser": false,
"node": false
},
"globals": {
"window": false,
"angular": false
}
}
-8
View File
@@ -1,8 +0,0 @@
{
"extends": "./.eslintrc-base.json",
"env": {
"browser": false,
"node": true
}
}
-25
View File
@@ -1,25 +0,0 @@
{
// This config contains proposed rules that we'd like to have enabled but haven't
// converted the code to adhere yet. If a decision comes to not enable one of these
// rules, it should be removed from the file. Every rule that got enabled in the
// end should be moved from here to a respective section in .eslintrc.json
"rules": {
// Rules are divided into sections from http://eslint.org/docs/rules/
// Best practices
"complexity": ["error", 10],
"dot-notation": "error",
"dot-location": ["error", "property"],
// Stylistic issues
"block-spacing": ["error", "always"],
"comma-spacing": "error",
"id-blacklist": ["error", "event"],
"indent": ["error", 2],
"key-spacing": ["error", { "beforeColon": false, "afterColon": true, "mode": "minimum" }],
"object-curly-spacing": ["error", "never"],
"object-property-newline": ["error", { "allowMultiplePropertiesPerLine": true }],
"operator-linebreak": ["error", "after", { "overrides": { "?": "before", ":": "before" }}]
}
}
-4
View File
@@ -1,4 +0,0 @@
{
"root": true,
"extends": "./.eslintrc-node.json"
}
-3
View File
@@ -20,6 +20,3 @@ libpeerconnection.log
npm-debug.log
/tmp/
/scripts/bower/bower-*
.vscode
*.log
*.stackdump
+48
View File
@@ -0,0 +1,48 @@
{
"excludeFiles": ["src/ngLocale/**"],
"disallowKeywords": ["with"],
"disallowKeywordsOnNewLine": ["else"],
"disallowMixedSpacesAndTabs": true,
"disallowMultipleLineStrings": true,
"disallowNewlineBeforeBlockStatements": true,
"disallowSpaceAfterObjectKeys": true,
"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
"disallowSpaceBeforeBinaryOperators": [","],
"disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
"disallowSpacesInAnonymousFunctionExpression": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInCallExpression": true,
"disallowSpacesInFunctionDeclaration": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInNamedFunctionExpression": {
"beforeOpeningRoundBrace": true
},
"disallowSpacesInsideArrayBrackets": true,
"requireSpaceBeforeKeywords": [
"else",
"while",
"catch"
],
"disallowSpacesInsideParentheses": true,
"disallowTrailingComma": true,
"disallowTrailingWhitespace": true,
"requireCommaBeforeLineBreak": true,
"requireLineFeedAtFileEnd": true,
"requireSpaceAfterBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"],
"requireSpaceBeforeBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"],
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
"requireSpaceBeforeBlockStatements": true,
"requireSpacesInConditionalExpression": {
"afterTest": true,
"beforeConsequent": true,
"afterConsequent": true,
"beforeAlternate": true
},
"requireSpacesInForStatement": true,
"requireSpacesInFunction": {
"beforeOpeningCurlyBrace": true
},
"validateLineBreaks": "LF"
}
+2
View File
@@ -0,0 +1,2 @@
node_modules/**
lib/htmlparser/**
+5
View File
@@ -0,0 +1,5 @@
{
"extends": ".jshintrc-base",
"node": true,
"globals": {}
}
+24
View File
@@ -0,0 +1,24 @@
{
"bitwise": true,
"esversion": 6,
"immed": true,
"newcap": true,
"noarg": true,
"noempty": true,
"nonew": true,
"maxlen": 200,
"boss": true,
"eqnull": true,
"expr": true,
"laxbreak": true,
"loopfunc": true,
"strict": "global",
"sub": true,
"undef": true,
"indent": 2,
"globals": {
"ArrayBuffer": false,
"Uint8Array": false
}
}
-1
View File
@@ -1 +0,0 @@
6
+12 -5
View File
@@ -1,7 +1,7 @@
language: node_js
sudo: false
node_js:
- '6'
- '4.4'
cache:
directories:
@@ -36,12 +36,19 @@ addons:
packages:
- g++-4.8
before_install:
- curl -o- -L https://raw.githubusercontent.com/yarnpkg/yarn/2a0afc73210c7a82082585283e518eeb88ca19ae/scripts/install-latest.sh | bash -s -- --version 0.17.9
- export PATH=$HOME/.yarn/bin:$PATH
install:
# Check the size of caches
- du -sh ./node_modules ./bower_components/ ./docs/bower_components/ || true
# - npm config set registry http://23.251.144.68
# Disable the spinner, it looks bad on Travis
- npm config set spin false
# Log HTTP requests
- npm config set loglevel http
#- npm install -g npm@2.5
# Install npm dependencies and ensure that npm cache is not stale
- npm install
before_script:
- du -sh ./node_modules ./bower_components/ ./docs/bower_components/ || true
- ./scripts/travis/before_build.sh
script:
+50 -3468
View File
File diff suppressed because it is too large Load Diff
+49 -74
View File
@@ -14,75 +14,62 @@ today! Here are the guidelines we'd like you to follow:
- [Further Info](#info)
## <a name="coc"></a> Code of Conduct
Help us keep Angular open and inclusive. Please read and follow our [Code of Conduct][coc].
## <a name="question"></a> Got a Question or Problem?
If you have questions about how to use AngularJS, please direct these to the [Google Group][groups]
discussion list or [StackOverflow][stackoverflow]. We are also available on [IRC][irc] and
[Gitter][gitter].
discussion list or [StackOverflow][stackoverflow]. We are also available on [IRC][irc] and [Gitter][gitter].
## <a name="issue"></a> Found an Issue?
If you find a bug in the source code or a mistake in the documentation, you can help us by
submitting an issue to our [GitHub Repository][github]. Even better you can submit a Pull Request
with a fix.
**Localization Issues:** Angular.js uses the [Google Closure I18N library] to generate
its own I18N files (the ngLocale module). This means that any changes to these files would be lost
the next time that we import the library.
Since the Closure library i18n data is itself auto-generated from the data of the
[Common Locale Data Repository (CLDR)] project, errors in the data should
be reported there. See also the [Closure guide to i18n changes].
***Localization Issue:*** *Angular.js uses the [Google Closure I18N library], to generate its own I18N files. This means that
any changes to these files would be lost the next time that we import the library. The recommended
approach is to submit a patch to the I18N project directly, instead of submitting it here.*
**Please see the [Submission Guidelines](#submit) below.**
**Please see the Submission Guidelines below**.
## <a name="feature"></a> Want a Feature?
You can request a new feature by submitting an issue to our [GitHub Repository][github]. If you
would like to implement a new feature then consider what kind of change it is:
* **Major Changes** that you wish to contribute to the project should be discussed first on our
[dev mailing list][angular-dev] or [IRC][irc] so that we can better coordinate our efforts,
prevent duplication of work, and help you to craft the change so that it is successfully accepted
into the project.
* **Small Changes** can be crafted and submitted to the [GitHub Repository][github] as a Pull
Request.
[dev mailing list][angular-dev] or [IRC][irc] so that we can better coordinate our efforts, prevent
duplication of work, and help you to craft the change so that it is successfully accepted into the
project.
* **Small Changes** can be crafted and submitted to the [GitHub Repository][github] as a Pull Request.
## <a name="docs"></a> Want a Doc Fix?
If you want to help improve the docs, it's a good idea to let others know what you're working on to
minimize duplication of effort. Create a new issue (or comment on a related existing one) to let
others know what you're working on.
minimize duplication of effort. Before starting, check out the issue queue for
[Milestone:Docs Only](https://github.com/angular/angular.js/issues?milestone=24&state=open).
Comment on an issue to let others know what you're working on, or create a new issue if your work
doesn't fit within the scope of any of the existing doc fix projects.
For large fixes, please build and test the documentation before submitting the PR to be sure you
haven't accidentally introduced any layout or formatting issues. You should also make sure that your
commit message starts with "docs" and follows the **[Commit Message Guidelines](#commit)** outlined
below.
For large fixes, please build and test the documentation before submitting the PR to be sure you haven't
accidentally introduced any layout or formatting issues. You should also make sure that your commit message
is labeled "docs:" and follows the **Git Commit Guidelines** outlined below.
If you're just making a small change, don't worry about filing an issue first. Use the friendly blue
"Improve this doc" button at the top right of the doc page to fork the repository in-place and make
a quick change on the fly. When naming the commit, it is advised to follow the commit message
guidelines below, by starting the commit message with **docs** and referencing the filename. Since
this is not obvious and some changes are made on the fly, this is not strictly necessary and we will
understand if this isn't done the first few times.
If you're just making a small change, don't worry about filing an issue first. Use the friendly blue "Improve this doc" button at the top right of the doc page to fork the repository in-place and make a quick change on the fly. When naming the commit, it is advised to still label it according to the commit guidelines below, by starting the commit message with **docs** and referencing the filename. Since this is not obvious and some changes are made on the fly, this is not strictly necessary and we will understand if this isn't done the first few times.
## <a name="submit"></a> Submission Guidelines
### Submitting an Issue
Before you submit your issue search the archive, maybe your question was already answered.
If your issue appears to be a bug, and hasn't been reported, open a new issue. 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:
If your issue appears to be a bug, and hasn't been reported, open a new issue.
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
* **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 specific ones?
* **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
[JSFiddle][jsfiddle]) or an unambiguous set of steps.
* **Related Issues** - has a similar issue been reported before?
@@ -102,22 +89,22 @@ Before you submit your pull request consider the following guidelines:
requests. We cannot accept code without this.
* Make your changes in a new git branch:
```shell
git checkout -b my-fix-branch master
```
```shell
git checkout -b my-fix-branch master
```
* Create your patch, **including appropriate test cases**.
* Follow our [Coding Rules](#rules).
* Run the full Angular test suite, as described in the [developer documentation][dev-doc],
and ensure that all tests pass.
* Commit your changes using a descriptive commit message that follows our
[commit message conventions](#commit) and passes our commit message presubmit hook
(`validate-commit-msg.js`). Adherence to the [commit message conventions](#commit) is required,
because release notes are automatically generated from these messages.
[commit message conventions](#commit-message-format) and passes our commit message presubmit hook
`validate-commit-msg.js`. Adherence to the [commit message conventions](#commit-message-format)
is required because release notes are automatically generated from these messages.
```shell
git commit -a
```
```shell
git commit -a
```
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
* Build your changes locally to ensure all the tests pass:
@@ -132,24 +119,22 @@ Before you submit your pull request consider the following guidelines:
git push origin my-fix-branch
```
In GitHub, send a pull request to `angular:master`.
If we suggest changes, then:
* Make the required updates.
* Re-run the Angular test suite to ensure tests are still passing.
* Commit your changes to your branch (e.g. `my-fix-branch`).
* Push the changes to your GitHub repository (this will update your Pull Request).
* In GitHub, send a pull request to `angular:master`.
* If we suggest changes then:
* Make the required updates.
* Re-run the Angular test suite to ensure tests are still passing.
* Commit your changes to your branch (e.g. `my-fix-branch`).
* Push the changes to your GitHub repository (this will update your Pull Request).
If the PR gets too outdated we may ask you to rebase and force push to update the PR:
```shell
git rebase master -i
git push origin my-fix-branch -f
```
```shell
git rebase master -i
git push origin my-fix-branch -f
```
_WARNING: Squashing or reverting commits and force-pushing thereafter may remove GitHub comments
on code that were previously made by you or others in your commits. Avoid any form of rebasing
unless necessary._
*WARNING. Squashing or reverting commits and forced push thereafter may remove GitHub comments
on code that were previously made by you and others in your commits.*
That's it! Thank you for your contribution!
@@ -183,7 +168,6 @@ from the main (upstream) repository:
```
## <a name="rules"></a> Coding Rules
To ensure consistency throughout the source code, keep these rules in mind as you are working:
* All features or bug fixes **must be tested** by one or more [specs][unit-testing].
@@ -209,9 +193,7 @@ We have very precise rules over how our git commit messages can be formatted. T
readable messages** that are easy to follow when looking through the **project history**. But also,
we use the git commit messages to **generate the AngularJS change log**.
The commit message formatting can be added using a typical git workflow or through the use of a CLI
wizard ([Commitizen](https://github.com/commitizen/cz-cli)). To use the wizard, run `yarn run commit`
in your terminal after staging your changes in git.
The commit message formatting can be added using a typical git workflow or through the use of a CLI wizard ([Commitizen](https://github.com/commitizen/cz-cli)). To use the wizard, run `npm run commit` in your terminal after staging your changes in git.
### Commit Message Format
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
@@ -231,8 +213,7 @@ Any line of the commit message cannot be longer 100 characters! This allows the
to read on GitHub as well as in various git tools.
### Revert
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit.
In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
### Type
Must be one of the following:
@@ -244,7 +225,7 @@ Must be one of the following:
semi-colons, etc)
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **perf**: A code change that improves performance
* **test**: Adding missing or correcting existing tests
* **test**: Adding missing tests
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
generation
@@ -252,8 +233,6 @@ Must be one of the following:
The scope could be anything specifying place of the commit change. For example `$location`,
`$browser`, `$compile`, `$rootScope`, `ngHref`, `ngClick`, `ngView`, etc...
You can use `*` when the change affects more than a single scope.
### Subject
The subject contains succinct description of the change:
@@ -267,10 +246,9 @@ The body should include the motivation for the change and contrast this with pre
### Footer
The footer should contain any information about **Breaking Changes** and is also the place to
[reference GitHub issues that this commit closes][closing-issues].
reference GitHub issues that this commit **Closes**.
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines.
The rest of the commit message is then used for this.
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
A detailed explanation can be found in this [document][commit-message-format].
@@ -291,7 +269,6 @@ You can find out more detailed information about contributing in the
[Google Closure I18N library]: https://github.com/google/closure-library/tree/master/closure/goog/i18n
[angular-dev]: https://groups.google.com/forum/?fromgroups#!forum/angular-dev
[closing-issues]: https://help.github.com/articles/closing-issues-via-commit-messages/
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
[contribute]: http://docs.angularjs.org/misc/contribute
@@ -303,14 +280,12 @@ You can find out more detailed information about contributing in the
[groups]: https://groups.google.com/forum/?fromgroups#!forum/angular
[individual-cla]: http://code.google.com/legal/individual-cla-v1.0.html
[irc]: http://webchat.freenode.net/?channels=angularjs&uio=d4
[js-style-guide]: https://google.github.io/styleguide/javascriptguide.xml
[js-style-guide]: http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
[jsfiddle]: http://jsfiddle.net/
[list]: https://groups.google.com/forum/?fromgroups#!forum/angular
[ngDocs]: https://github.com/angular/angular.js/wiki/Writing-AngularJS-Documentation
[plunker]: http://plnkr.co/edit
[stackoverflow]: http://stackoverflow.com/questions/tagged/angularjs
[unit-testing]: https://docs.angularjs.org/guide/unit-testing
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
[![Analytics](https://ga-beacon.appspot.com/UA-8594346-11/angular.js/CONTRIBUTING.md?pixel)](https://github.com/igrigorik/ga-beacon)
+89 -106
View File
@@ -1,73 +1,21 @@
'use strict';
var serveFavicon = require('serve-favicon');
var serveStatic = require('serve-static');
var serveIndex = require('serve-index');
var files = require('./angularFiles').files;
var util = require('./lib/grunt/utils.js');
var versionInfo = require('./lib/versions/version-info');
var path = require('path');
var e2e = require('./test/e2e/tools');
var semver = require('semver');
var exec = require('shelljs').exec;
var pkg = require(__dirname + '/package.json');
// Node.js version checks
if (!semver.satisfies(process.version, pkg.engines.node)) {
reportOrFail('Invalid node version (' + process.version + '). ' +
'Please use a version that satisfies ' + pkg.engines.node);
}
// Yarn version checks
var expectedYarnVersion = pkg.engines.yarn;
var currentYarnVersion = exec('yarn --version', {silent: true}).stdout.trim();
if (!semver.satisfies(currentYarnVersion, expectedYarnVersion)) {
reportOrFail('Invalid yarn version (' + currentYarnVersion + '). ' +
'Please use a version that satisfies ' + expectedYarnVersion);
}
// Grunt CLI version checks
var expectedGruntVersion = pkg.engines.grunt;
var currentGruntVersions = exec('grunt --version', {silent: true}).stdout;
var match = /^grunt-cli v(.+)$/m.exec(currentGruntVersions);
if (!match) {
reportOrFail('Unable to compute the current grunt-cli version. We found:\n' +
currentGruntVersions);
} else {
if (!semver.satisfies(match[1], expectedGruntVersion)) {
reportOrFail('Invalid grunt-cli version (' + match[1] + '). ' +
'Please use a version that satisfies ' + expectedGruntVersion);
}
}
// Ensure Node.js dependencies have been installed
if (!process.env.TRAVIS && !process.env.JENKINS_HOME) {
var yarnOutput = exec('yarn install');
if (yarnOutput.code !== 0) {
throw new Error('Yarn install failed: ' + yarnOutput.stderr);
}
}
module.exports = function(grunt) {
// this loads all the node_modules that start with `grunt-` as plugins
//grunt plugins
require('load-grunt-tasks')(grunt);
// load additional grunt tasks
grunt.loadTasks('lib/grunt');
grunt.loadNpmTasks('angular-benchpress');
// compute version related info for this build
var NG_VERSION = versionInfo.currentVersion;
NG_VERSION.cdn = versionInfo.cdnVersion;
var dist = 'angular-' + NG_VERSION.full;
if (versionInfo.cdnVersion == null) {
throw new Error('Unable to read CDN version, are you offline or has the CDN not been properly pushed?\n' +
'Perhaps you want to set the NG1_BUILD_NO_REMOTE_VERSION_REQUESTS environment variable?');
}
var dist = 'angular-'+ NG_VERSION.full;
//config
grunt.initConfig({
@@ -86,15 +34,15 @@ module.exports = function(grunt) {
hostname: '0.0.0.0',
base: '.',
keepalive: true,
middleware: function(connect, options) {
middleware: function(connect, options){
var base = Array.isArray(options.base) ? options.base[options.base.length - 1] : options.base;
return [
util.conditionalCsp(),
util.rewrite(),
e2e.middleware(),
serveFavicon('images/favicon.ico'),
serveStatic(base),
serveIndex(base)
connect.favicon('images/favicon.ico'),
connect.static(base),
connect.directory(base)
];
}
}
@@ -106,7 +54,7 @@ module.exports = function(grunt) {
// to avoid https://github.com/joyent/libuv/issues/826
port: 8000,
hostname: '0.0.0.0',
middleware: function(connect, options) {
middleware: function(connect, options){
var base = Array.isArray(options.base) ? options.base[options.base.length - 1] : options.base;
return [
function(req, resp, next) {
@@ -119,8 +67,8 @@ module.exports = function(grunt) {
},
util.conditionalCsp(),
e2e.middleware(),
serveFavicon('images/favicon.ico'),
serveStatic(base)
connect.favicon('images/favicon.ico'),
connect.static(base)
];
}
}
@@ -131,8 +79,6 @@ module.exports = function(grunt) {
tests: {
jqlite: 'karma-jqlite.conf.js',
jquery: 'karma-jquery.conf.js',
'jquery-2.2': 'karma-jquery-2.2.conf.js',
'jquery-2.1': 'karma-jquery-2.1.conf.js',
docs: 'karma-docs.conf.js',
modules: 'karma-modules.conf.js'
},
@@ -141,8 +87,6 @@ module.exports = function(grunt) {
autotest: {
jqlite: 'karma-jqlite.conf.js',
jquery: 'karma-jquery.conf.js',
'jquery-2.2': 'karma-jquery-2.2.conf.js',
'jquery-2.1': 'karma-jquery-2.1.conf.js',
modules: 'karma-modules.conf.js',
docs: 'karma-docs.conf.js'
},
@@ -160,24 +104,68 @@ module.exports = function(grunt) {
tmp: ['tmp']
},
eslint: {
all: {
src: [
'*.js',
'benchmarks/**/*.js',
'docs/**/*.js',
'lib/**/*.js',
'scripts/**/*.js',
'src/**/*.js',
'test/**/*.js',
'i18n/**/*.js',
'!docs/app/assets/js/angular-bootstrap/**',
'!docs/bower_components/**',
'!docs/config/templates/**',
'!src/angular.bind.js',
'!i18n/closure/**',
'!src/ngParseExt/ucd.js'
]
jshint: {
options: {
jshintrc: true,
},
node: {
files: { src: ['*.js', 'lib/**/*.js'] },
},
tests: {
files: { src: 'test/**/*.js' },
},
ng: {
files: { src: files['angularSrc'].concat('!src/angular.bind.js') },
},
ngAnimate: {
files: { src: 'src/ngAnimate/**/*.js' },
},
ngCookies: {
files: { src: 'src/ngCookies/**/*.js' },
},
ngLocale: {
files: { src: 'src/ngLocale/**/*.js' },
},
ngMessageFormat: {
files: { src: 'src/ngMessageFormat/**/*.js' },
},
ngMessages: {
files: { src: 'src/ngMessages/**/*.js' },
},
ngMock: {
files: { src: 'src/ngMock/**/*.js' },
},
ngParseExt: {
files: { src: 'src/ngParseExt/**/*.js' },
},
ngResource: {
files: { src: 'src/ngResource/**/*.js' },
},
ngRoute: {
files: { src: 'src/ngRoute/**/*.js' },
},
ngSanitize: {
files: { src: 'src/ngSanitize/**/*.js' },
},
ngScenario: {
files: { src: 'src/ngScenario/**/*.js' },
},
ngTouch: {
files: { src: 'src/ngTouch/**/*.js' },
},
ngAria: {
files: {src: 'src/ngAria/**/*.js'},
}
},
jscs: {
src: [
'src/**/*.js',
'test/**/*.js',
'!src/angular.bind.js' // we ignore this file since contains an early return statement
],
options: {
config: '.jscsrc'
}
},
@@ -250,7 +238,7 @@ module.exports = function(grunt) {
dest: 'build/angular-parse-ext.js',
src: util.wrap(files['angularModules']['ngParseExt'], 'module')
},
'promises-aplus-adapter': {
"promises-aplus-adapter": {
dest:'tmp/promises-aplus-adapter++.js',
src:['src/ng/q.js', 'lib/promises-aplus/promises-aplus-test-adapter.js']
}
@@ -319,7 +307,7 @@ module.exports = function(grunt) {
compress: {
build: {
options: {archive: 'build/' + dist + '.zip', mode: 'zip'},
options: {archive: 'build/' + dist +'.zip', mode: 'zip'},
src: ['**'],
cwd: 'build',
expand: true,
@@ -329,16 +317,17 @@ module.exports = function(grunt) {
},
shell: {
'install-node-dependencies': {
command: 'yarn'
'npm-install': {
command: 'node scripts/npm/check-node-modules.js'
},
'promises-aplus-tests': {
options: {
stdout: false,
stderr: true,
failOnError: true
},
command: path.normalize('./node_modules/.bin/promises-aplus-tests tmp/promises-aplus-adapter++.js --timeout 2000')
command: path.normalize('./node_modules/.bin/promises-aplus-tests tmp/promises-aplus-adapter++.js')
}
},
@@ -358,15 +347,20 @@ module.exports = function(grunt) {
}
});
// global beforeEach task
if (!process.env.TRAVIS) {
grunt.task.run('shell:npm-install');
}
//alias tasks
grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['eslint', 'package', 'test:unit', 'test:promises-aplus', 'tests:docs', 'test:protractor']);
grunt.registerTask('test', '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 (latest) unit tests with Karma', ['tests:jquery']);
grunt.registerTask('test:jquery-2.2', 'Run the jQuery 2.2 unit tests with Karma', ['tests:jquery-2.2']);
grunt.registerTask('test:jquery-2.1', 'Run the jQuery 2.1 unit tests with Karma', ['tests:jquery-2.1']);
grunt.registerTask('test:jquery', 'Run the jQuery unit tests with Karma', ['tests:jquery']);
grunt.registerTask('test:modules', 'Run the Karma module tests with Karma', ['build', 'tests:modules']);
grunt.registerTask('test:docs', 'Run the doc-page tests with Karma', ['package', 'tests:docs']);
grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', ['test:jqlite', 'test:jquery', 'test:jquery-2.2', 'test:jquery-2.1', 'test:modules']);
grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', ['test:jqlite', 'test:jquery', 'test:modules']);
grunt.registerTask('test:protractor', 'Run the end to end tests with Protractor and keep a test server running in the background', ['webdriver', 'connect:testserver', 'protractor:normal']);
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']);
@@ -375,18 +369,7 @@ module.exports = function(grunt) {
grunt.registerTask('minify', ['bower', 'clean', 'build', 'minall']);
grunt.registerTask('webserver', ['connect:devserver']);
grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'write', 'docs', 'copy', 'compress']);
grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'eslint']);
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']);
};
function reportOrFail(message) {
if (process.env.TRAVIS || process.env.JENKINS_HOME) {
throw new Error(message);
} else {
console.log('===============================================================================');
console.log(message);
console.log('===============================================================================');
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2010-2017 Google, Inc. http://angularjs.org
Copyright (c) 2010-2016 Google, Inc. http://angularjs.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+9 -43
View File
@@ -2,7 +2,7 @@ AngularJS [![Build Status](https://travis-ci.org/angular/angular.js.svg?branch=m
=========
AngularJS lets you write client-side web applications as if you had a smarter browser. It lets you
use good old HTML (or HAML, Jade/Pug and friends!) as your template language and lets you extend HTMLs
use good old HTML (or HAML, Jade and friends!) as your template language and lets you extend HTMLs
syntax to express your applications components clearly and succinctly. It automatically
synchronizes data from your UI (view) with your JavaScript objects (model) through 2-way data
binding. To help you structure your application better and make it easy to test, AngularJS teaches
@@ -19,7 +19,6 @@ piece of cake. Best of all? It makes development fun!
* Contribution guidelines: [CONTRIBUTING.md](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md)
* Dashboard: https://dashboard.angularjs.org
##### Looking for Angular 2? Go here: https://github.com/angular/angular
Building AngularJS
---------
@@ -51,57 +50,24 @@ We've set up a separate document for our [contribution guidelines](https://githu
What to use AngularJS for and when to use it
---------
AngularJS is the next generation framework where each component is designed to work with every other
component in an interconnected way like a well-oiled machine. AngularJS is JavaScript MVC made easy
and done right. (Well it is not really MVC, read on, to understand what this means.)
AngularJS is the next generation framework where each component is designed to work with every other component in an interconnected way like a well-oiled machine. AngularJS is JavaScript MVC made easy and done right. (Well it is not really MVC, read on, to understand what this means.)
#### MVC, no, MV* done the right way!
MVC, short for Model-View-Controller, is a design pattern, i.e. how the code should be organized and
how the different parts of an application separated for proper readability and debugging. Model is
the data and the database. View is the user interface and what the user sees. Controller is the main
link between Model and View. These are the three pillars of major programming frameworks present on
the market today. On the other hand AngularJS works on MV*, short for Model-View-_Whatever_. The
_Whatever_ is AngularJS's way of telling that you may create any kind of linking between the Model
and the View here.
MVC, short for Model-View-Controller, is a design pattern, i.e. how the code should be organized and how the different parts of an application separated for proper readability and debugging. Model is the data and the database. View is the user interface and what the user sees. Controller is the main link between Model and View. These are the three pillars of major programming frameworks present on the market today. On the other hand AngularJS works on MV*, short for Model-View-_Whatever_. The _Whatever_ is AngularJS's way of telling that you may create any kind of linking between the Model and the View here.
Unlike other frameworks in any programming language, where MVC, the three separate components, each
one has to be written and then connected by the programmer, AngularJS helps the programmer by asking
him/her to just create these and everything else will be taken care of by AngularJS.
Unlike other frameworks in any programming language, where MVC, the three separate components, each one has to be written and then connected by the programmer, AngularJS helps the programmer by asking him/her to just create these and everything else will be taken care of by AngularJS.
#### Interconnection with HTML at the root level
AngularJS uses HTML to define the user's interface. AngularJS also enables the programmer to write
new HTML tags (AngularJS Directives) and increase the readability and understandability of the HTML
code. Directives are AngularJSs way of bringing additional functionality to HTML. Directives
achieve this by enabling us to invent our own HTML elements. This also helps in making the code DRY
(Don't Repeat Yourself), which means once created, a new directive can be used anywhere within the
application.
HTML is also used to determine the wiring of the app. Special attributes in the HTML determine where
to load the app, which components or controllers to use for each element, etc. We specify "what"
gets loaded, but not "how". This declarative approach greatly simplifies app development in a sort
of WYSIWYG way. Rather than spending time on how the program flows and orchestrating the various
moving parts, we simply define what we want and Angular will take care of the dependencies.
AngularJS uses HTML to define the user's interface. AngularJS also enables the programmer to write new HTML tags (AngularJS Directives) and increase the readability and understandability of the HTML code. Directives are AngularJSs way of bringing additional functionality to HTML. Directives achieve this by enabling us to invent our own HTML elements. This also helps in making the code DRY (Don't Repeat Yourself), which means once created, a new directive can be used anywhere within the application.
#### Data Handling made simple
Data and Data Models in AngularJS are plain JavaScript objects and one can add and change properties
directly on it and loop over objects and arrays at will.
Data and Data Models in AngularJS are plain JavaScript objects and one can add and change properties directly on it and loop over objects and arrays at will.
#### Two-way Data Binding
One of AngularJS's strongest features. Two-way Data Binding means that if something changes in the
Model, the change gets reflected in the View instantaneously, and the same happens the other way
around. This is also referred to as Reactive Programming, i.e. suppose `a = b + c` is being
programmed and after this, if the value of `b` and/or `c` is changed then the value of `a` will be
automatically updated to reflect the change. AngularJS uses its "scopes" as a glue between the Model
and View and makes these updates in one available for the other.
One of AngularJS's strongest features. Two-way Data Binding means that if something changes in the Model, the change gets reflected in the View instantaneously, and the same happens the other way around. This is also referred to as Reactive Programming, i.e. suppose `a = b + c` is being programmed and after this, if the value of `b` and/or `c` is changed then the value of `a` will be automatically updated to reflect the change. AngularJS uses its "scopes" as a glue between the Model and View and makes these updates in one available for the other.
#### Less Written Code and Easily Maintainable Code
Everything in AngularJS is created to enable the programmer to end up writing less code that is
easily maintainable and readable by any other new person on the team. Believe it or not, one can
write a complete working two-way data binded application in less than 10 lines of code. Try and see
for yourself!
Everything in AngularJS is created to enable the programmer to end up writing less code that is easily maintainable and readable by any other new person on the team. Believe it or not, one can write a complete working two-way data binded application in less than 10 lines of code. Try and see for yourself!
#### Testing Ready
AngularJS has Dependency Injection, i.e. it takes care of providing all the necessary dependencies
to its controllers and services whenever required. This helps in making the AngularJS code ready for
unit testing by making use of mock dependencies created and injected. This makes AngularJS more
modular and easily testable thus in turn helping a team create more robust applications.
AngularJS has Dependency Injection, i.e. it takes care of providing all the necessary dependencies to its controllers whenever required. This helps in making the AngularJS code ready for unit testing by making use of mock dependencies created and injected. This makes AngularJS more modular and easily testable thus in turn helping a team create more robust applications.
+1 -1
View File
@@ -95,7 +95,7 @@ You can mention him in the relevant thread like this: `@btford`.
> Thanks for submitting this issue!
> Unfortunately, we don't think this functionality belongs in core.
> The good news is that you could easily implement this as a third-party module and publish it on Bower and/or to the npm repository.
> The good news is that you could easily implement this as a third-party module and publish it on Bower and/or npm.
## Assigning Work
Vendored Regular → Executable
+6 -22
View File
@@ -5,7 +5,6 @@ var angularFiles = {
'src/minErr.js',
'src/Angular.js',
'src/loader.js',
'src/shallowCopy.js',
'src/stringify.js',
'src/AngularPublic.js',
'src/jqLite.js',
@@ -28,7 +27,6 @@ var angularFiles = {
'src/ng/httpBackend.js',
'src/ng/interpolate.js',
'src/ng/interval.js',
'src/ng/jsonpCallbacks.js',
'src/ng/locale.js',
'src/ng/location.js',
'src/ng/log.js',
@@ -70,7 +68,6 @@ var angularFiles = {
'src/ng/directive/ngInit.js',
'src/ng/directive/ngList.js',
'src/ng/directive/ngModel.js',
'src/ng/directive/ngModelOptions.js',
'src/ng/directive/ngNonBindable.js',
'src/ng/directive/ngOptions.js',
'src/ng/directive/ngPluralize.js',
@@ -81,6 +78,7 @@ var angularFiles = {
'src/ng/directive/ngTransclude.js',
'src/ng/directive/script.js',
'src/ng/directive/select.js',
'src/ng/directive/style.js',
'src/ng/directive/validators.js',
'src/angular.bind.js',
'src/publishExternalApis.js',
@@ -130,7 +128,6 @@ var angularFiles = {
'src/ngResource/resource.js'
],
'ngRoute': [
'src/shallowCopy.js',
'src/ngRoute/route.js',
'src/ngRoute/routeParams.js',
'src/ngRoute/directive/ngView.js'
@@ -140,8 +137,7 @@ var angularFiles = {
'src/ngSanitize/filter/linky.js'
],
'ngMock': [
'src/ngMock/angular-mocks.js',
'src/ngMock/browserTrigger.js'
'src/ngMock/angular-mocks.js'
],
'ngTouch': [
'src/ngTouch/touch.js',
@@ -156,6 +152,7 @@ var angularFiles = {
'angularScenario': [
'src/ngScenario/Scenario.js',
'src/ngScenario/browserTrigger.js',
'src/ngScenario/Application.js',
'src/ngScenario/Describe.js',
'src/ngScenario/Future.js',
@@ -178,7 +175,6 @@ var angularFiles = {
'test/auto/*.js',
'test/ng/**/*.js',
'test/ngAnimate/*.js',
'test/ngMessageFormat/*.js',
'test/ngMessages/*.js',
'test/ngCookies/*.js',
'test/ngResource/*.js',
@@ -210,14 +206,13 @@ var angularFiles = {
'build/docs/docs-scenario.js'
],
'karmaModules': [
"karmaModules": [
'build/angular.js',
'@angularSrcModules',
'test/modules/no_bootstrap.js',
'src/ngScenario/browserTrigger.js',
'test/helpers/*.js',
'test/ngAnimate/*.js',
'test/ngMessageFormat/*.js',
'test/ngMessages/*.js',
'test/ngMock/*.js',
'test/ngCookies/*.js',
'test/ngRoute/**/*.js',
@@ -244,17 +239,6 @@ var angularFiles = {
]
};
['2.1', '2.2'].forEach(function(jQueryVersion) {
angularFiles['karmaJquery' + jQueryVersion] = []
.concat(angularFiles.karmaJquery)
.map(function(path) {
if (path.startsWith('bower_components/jquery')) {
return path.replace(/^bower_components\/jquery/, 'bower_components/jquery-' + jQueryVersion);
}
return path;
});
});
angularFiles['angularSrcModules'] = [].concat(
angularFiles['angularModules']['ngAnimate'],
angularFiles['angularModules']['ngMessageFormat'],
@@ -276,7 +260,7 @@ if (exports) {
Array.prototype.slice.call(arguments, 0).forEach(function(filegroup) {
angularFiles[filegroup].forEach(function(file) {
// replace @ref
var match = file.match(/^@(.*)/);
var match = file.match(/^\@(.*)/);
if (match) {
files = files.concat(angularFiles[match[1]]);
} else {
-11
View File
@@ -1,11 +0,0 @@
{
"root": true,
"extends": "../.eslintrc-browser.json",
"globals": {
"benchmarkSteps": false,
// Benchmarks are not run in IE 9 so we're fine.
"console": false
}
}
-44
View File
@@ -1,44 +0,0 @@
'use strict';
angular
.module('animationBenchmark', ['ngAnimate'], config)
.controller('BenchmarkController', BenchmarkController);
// Functions - Definitions
function config($compileProvider) {
$compileProvider
.commentDirectivesEnabled(false)
.cssClassDirectivesEnabled(false)
.debugInfoEnabled(false);
}
function BenchmarkController($scope) {
var self = this;
var itemCount = 1000;
var items = (new Array(itemCount + 1)).join('.').split('');
benchmarkSteps.push({
name: 'create',
fn: function() {
$scope.$apply(function() {
self.items = items;
});
}
});
benchmarkSteps.push({
name: '$digest',
fn: function() {
$scope.$root.$digest();
}
});
benchmarkSteps.push({
name: 'destroy',
fn: function() {
$scope.$apply(function() {
self.items = [];
});
}
});
}
-22
View File
@@ -1,22 +0,0 @@
/* eslint-env node */
'use strict';
module.exports = function(config) {
config.set({
scripts: [
{
id: 'jquery',
src: 'jquery-noop.js'
}, {
id: 'angular',
src: '/build/angular.js'
}, {
id: 'angular-animate',
src: '/build/angular-animate.js'
}, {
src: 'app.js'
}
]
});
};
-1
View File
@@ -1 +0,0 @@
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
-28
View File
@@ -1,28 +0,0 @@
<style>
[ng-cloak] { display: none !important; }
.animation-container .ng-enter,
.animation-container .ng-leave {
transition: all 0.1s;
}
.animation-container .ng-enter,
.animation-container .ng-leave.ng-leave-active {
opacity: 0;
}
.animation-container .ng-enter.ng-enter-active,
.animation-container .ng-leave {
opacity: 1;
}
</style>
<div ng-app="animationBenchmark" ng-cloak ng-controller="BenchmarkController as bm">
<div class="container-fluid">
<h2>Large collection of elements animated in and out with ngAnimate</h2>
<div class="animation-container">
<div ng-repeat="i in bm.items track by $index">
Just a plain ol' element
</div>
</div>
</div>
</div>
-61
View File
@@ -1,61 +0,0 @@
'use strict';
var app = angular.module('boostrapCompileBenchmark', []);
var commentDirectivesEnabled;
var cssClassDirectivesEnabled;
app.config(function($compileProvider) {
$compileProvider.debugInfoEnabled(false);
commentDirectivesEnabled = window.location.toString().indexOf('comment=disabled') === -1;
cssClassDirectivesEnabled = window.location.toString().indexOf('css=disabled') === -1;
$compileProvider
.commentDirectivesEnabled(commentDirectivesEnabled)
.cssClassDirectivesEnabled(cssClassDirectivesEnabled);
})
.controller('DataController', function DataController($compile, $http, $rootScope) {
this.isEA = !commentDirectivesEnabled && !cssClassDirectivesEnabled;
this.isEAC = !commentDirectivesEnabled && cssClassDirectivesEnabled;
this.isEAM = commentDirectivesEnabled && !cssClassDirectivesEnabled;
this.isEACM = commentDirectivesEnabled && cssClassDirectivesEnabled;
this.repeats = 50;
this.templates = [
'bootstrap-carousel.tpl.html',
'bootstrap-theme.tpl.html'
];
this.html = null;
this.loadTemplate = function() {
this.html = null;
$http.get(window.location.pathname + this.selectedTemplate)
.then(function(response) { this.html = response.data; }.bind(this));
};
this.selectedTemplate = this.templates[0];
this.loadTemplate();
var linkers = [];
benchmarkSteps.push({
name: 'create',
fn: function() {
for (var i = 0; i < this.repeats; i++) {
var linker = $compile(this.html);
linkers.push(linker);
}
}.bind(this)
});
benchmarkSteps.push({
name: 'destroy',
fn: function() {
linkers.length = 0;
}
});
});
@@ -1,172 +0,0 @@
<!-- code from http://getbootstrap.com/examples/carousel -->
<div class="navbar-wrapper">
<div class="container">
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">Nav header</li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
</div>
</div>
<!-- Carousel
================================================== -->
<div id="myCarousel" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
<li data-target="#myCarousel" data-slide-to="2"></li>
</ol>
<div class="carousel-inner" role="listbox">
<div class="item active">
<img class="first-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="First slide">
<div class="container">
<div class="carousel-caption">
<h1>Example headline.</h1>
<p>Note: If you're viewing this page via a <code>file://</code> URL, the "next" and "previous" Glyphicon buttons on the left and right might not load/display properly due to web browser security rules.</p>
<p><a class="btn btn-lg btn-primary" href="#" role="button">Sign up today</a></p>
</div>
</div>
</div>
<div class="item">
<img class="second-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Second slide">
<div class="container">
<div class="carousel-caption">
<h1>Another example headline.</h1>
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
<p><a class="btn btn-lg btn-primary" href="#" role="button">Learn more</a></p>
</div>
</div>
</div>
<div class="item">
<img class="third-slide" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Third slide">
<div class="container">
<div class="carousel-caption">
<h1>One more for good measure.</h1>
<p>Cras justo odio, dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit.</p>
<p><a class="btn btn-lg btn-primary" href="#" role="button">Browse gallery</a></p>
</div>
</div>
</div>
</div>
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div><!-- /.carousel -->
<!-- Marketing messaging and featurettes
================================================== -->
<!-- Wrap the rest of the page in another container to center all the content. -->
<div class="container marketing">
<!-- Three columns of text below the carousel -->
<div class="row">
<div class="col-lg-4">
<img class="img-circle" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Generic placeholder image" width="140" height="140">
<h2>Heading</h2>
<p>Donec sed odio dui. Etiam porta sem malesuada magna mollis euismod. Nullam id dolor id nibh ultricies vehicula ut id elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna.</p>
<p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
</div><!-- /.col-lg-4 -->
<div class="col-lg-4">
<img class="img-circle" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Generic placeholder image" width="140" height="140">
<h2>Heading</h2>
<p>Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras mattis consectetur purus sit amet fermentum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh.</p>
<p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
</div><!-- /.col-lg-4 -->
<div class="col-lg-4">
<img class="img-circle" src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==" alt="Generic placeholder image" width="140" height="140">
<h2>Heading</h2>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
<p><a class="btn btn-default" href="#" role="button">View details &raquo;</a></p>
</div><!-- /.col-lg-4 -->
</div><!-- /.row -->
<!-- START THE FEATURETTES -->
<hr class="featurette-divider">
<div class="row featurette">
<div class="col-md-7">
<h2 class="featurette-heading">First featurette heading. <span class="text-muted">It'll blow your mind.</span></h2>
<p class="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p>
</div>
<div class="col-md-5">
<img class="featurette-image img-responsive center-block" data-src="holder.js/500x500/auto" alt="Generic placeholder image">
</div>
</div>
<hr class="featurette-divider">
<div class="row featurette">
<div class="col-md-7 col-md-push-5">
<h2 class="featurette-heading">Oh yeah, it's that good. <span class="text-muted">See for yourself.</span></h2>
<p class="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p>
</div>
<div class="col-md-5 col-md-pull-7">
<img class="featurette-image img-responsive center-block" data-src="holder.js/500x500/auto" alt="Generic placeholder image">
</div>
</div>
<hr class="featurette-divider">
<div class="row featurette">
<div class="col-md-7">
<h2 class="featurette-heading">And lastly, this one. <span class="text-muted">Checkmate.</span></h2>
<p class="lead">Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.</p>
</div>
<div class="col-md-5">
<img class="featurette-image img-responsive center-block" data-src="holder.js/500x500/auto" alt="Generic placeholder image">
</div>
</div>
<hr class="featurette-divider">
<!-- /END THE FEATURETTES -->
<!-- FOOTER -->
<footer>
<p class="pull-right"><a href="#">Back to top</a></p>
<p>&copy; 2016 Company, Inc. &middot; <a href="#">Privacy</a> &middot; <a href="#">Terms</a></p>
</footer>
</div><!-- /.container -->
@@ -1,595 +0,0 @@
<!-- Fixed navbar -->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Bootstrap theme</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">Nav header</li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container theme-showcase" role="main">
<!-- Main jumbotron for a primary marketing message or call to action -->
<div class="jumbotron">
<h1>Theme example</h1>
<p>This is a template showcasing the optional theme stylesheet included in Bootstrap. Use it as a starting point to create something more unique by building on or modifying it.</p>
</div>
<div class="page-header">
<h1>Buttons</h1>
</div>
<p>
<button type="button" class="btn btn-lg btn-default">Default</button>
<button type="button" class="btn btn-lg btn-primary">Primary</button>
<button type="button" class="btn btn-lg btn-success">Success</button>
<button type="button" class="btn btn-lg btn-info">Info</button>
<button type="button" class="btn btn-lg btn-warning">Warning</button>
<button type="button" class="btn btn-lg btn-danger">Danger</button>
<button type="button" class="btn btn-lg btn-link">Link</button>
</p>
<p>
<button type="button" class="btn btn-default">Default</button>
<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-success">Success</button>
<button type="button" class="btn btn-info">Info</button>
<button type="button" class="btn btn-warning">Warning</button>
<button type="button" class="btn btn-danger">Danger</button>
<button type="button" class="btn btn-link">Link</button>
</p>
<p>
<button type="button" class="btn btn-sm btn-default">Default</button>
<button type="button" class="btn btn-sm btn-primary">Primary</button>
<button type="button" class="btn btn-sm btn-success">Success</button>
<button type="button" class="btn btn-sm btn-info">Info</button>
<button type="button" class="btn btn-sm btn-warning">Warning</button>
<button type="button" class="btn btn-sm btn-danger">Danger</button>
<button type="button" class="btn btn-sm btn-link">Link</button>
</p>
<p>
<button type="button" class="btn btn-xs btn-default">Default</button>
<button type="button" class="btn btn-xs btn-primary">Primary</button>
<button type="button" class="btn btn-xs btn-success">Success</button>
<button type="button" class="btn btn-xs btn-info">Info</button>
<button type="button" class="btn btn-xs btn-warning">Warning</button>
<button type="button" class="btn btn-xs btn-danger">Danger</button>
<button type="button" class="btn btn-xs btn-link">Link</button>
</p>
<div class="page-header">
<h1>Tables</h1>
</div>
<div class="row">
<div class="col-md-6">
<table class="table">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<td>2</td>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<td>3</td>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-6">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<td>2</td>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<td>3</td>
<td>Larry</td>
<td>the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-md-6">
<table class="table table-bordered">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="2">1</td>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<td>Mark</td>
<td>Otto</td>
<td>@TwBootstrap</td>
</tr>
<tr>
<td>2</td>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<td>3</td>
<td colspan="2">Larry the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-6">
<table class="table table-condensed">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<td>2</td>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<td>3</td>
<td colspan="2">Larry the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="page-header">
<h1>Thumbnails</h1>
</div>
<img data-src="holder.js/200x200" class="img-thumbnail" alt="200x200" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPjwhLS0KU291cmNlIFVSTDogaG9sZGVyLmpzLzIwMHgyMDAKQ3JlYXRlZCB3aXRoIEhvbGRlci5qcyAyLjYuMC4KTGVhcm4gbW9yZSBhdCBodHRwOi8vaG9sZGVyanMuY29tCihjKSAyMDEyLTIwMTUgSXZhbiBNYWxvcGluc2t5IC0gaHR0cDovL2ltc2t5LmNvCi0tPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PCFbQ0RBVEFbI2hvbGRlcl8xNTYyY2ExYjA3YiB0ZXh0IHsgZmlsbDojQUFBQUFBO2ZvbnQtd2VpZ2h0OmJvbGQ7Zm9udC1mYW1pbHk6QXJpYWwsIEhlbHZldGljYSwgT3BlbiBTYW5zLCBzYW5zLXNlcmlmLCBtb25vc3BhY2U7Zm9udC1zaXplOjEwcHQgfSBdXT48L3N0eWxlPjwvZGVmcz48ZyBpZD0iaG9sZGVyXzE1NjJjYTFiMDdiIj48cmVjdCB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgZmlsbD0iI0VFRUVFRSIvPjxnPjx0ZXh0IHg9Ijc0LjY5NTMxMjUiIHk9IjEwNC41Ij4yMDB4MjAwPC90ZXh0PjwvZz48L2c+PC9zdmc+" data-holder-rendered="true" style="width: 200px; height: 200px;">
<div class="page-header">
<h1>Labels</h1>
</div>
<h1>
<span class="label label-default">Default</span>
<span class="label label-primary">Primary</span>
<span class="label label-success">Success</span>
<span class="label label-info">Info</span>
<span class="label label-warning">Warning</span>
<span class="label label-danger">Danger</span>
</h1>
<h2>
<span class="label label-default">Default</span>
<span class="label label-primary">Primary</span>
<span class="label label-success">Success</span>
<span class="label label-info">Info</span>
<span class="label label-warning">Warning</span>
<span class="label label-danger">Danger</span>
</h2>
<h3>
<span class="label label-default">Default</span>
<span class="label label-primary">Primary</span>
<span class="label label-success">Success</span>
<span class="label label-info">Info</span>
<span class="label label-warning">Warning</span>
<span class="label label-danger">Danger</span>
</h3>
<h4>
<span class="label label-default">Default</span>
<span class="label label-primary">Primary</span>
<span class="label label-success">Success</span>
<span class="label label-info">Info</span>
<span class="label label-warning">Warning</span>
<span class="label label-danger">Danger</span>
</h4>
<h5>
<span class="label label-default">Default</span>
<span class="label label-primary">Primary</span>
<span class="label label-success">Success</span>
<span class="label label-info">Info</span>
<span class="label label-warning">Warning</span>
<span class="label label-danger">Danger</span>
</h5>
<h6>
<span class="label label-default">Default</span>
<span class="label label-primary">Primary</span>
<span class="label label-success">Success</span>
<span class="label label-info">Info</span>
<span class="label label-warning">Warning</span>
<span class="label label-danger">Danger</span>
</h6>
<p>
<span class="label label-default">Default</span>
<span class="label label-primary">Primary</span>
<span class="label label-success">Success</span>
<span class="label label-info">Info</span>
<span class="label label-warning">Warning</span>
<span class="label label-danger">Danger</span>
</p>
<div class="page-header">
<h1>Badges</h1>
</div>
<p>
<a href="#">Inbox <span class="badge">42</span></a>
</p>
<ul class="nav nav-pills" role="tablist">
<li role="presentation" class="active"><a href="#">Home <span class="badge">42</span></a></li>
<li role="presentation"><a href="#">Profile</a></li>
<li role="presentation"><a href="#">Messages <span class="badge">3</span></a></li>
</ul>
<div class="page-header">
<h1>Dropdown menus</h1>
</div>
<div class="dropdown theme-dropdown clearfix">
<a id="dropdownMenu1" href="#" class="sr-only dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li class="active"><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</div>
<div class="page-header">
<h1>Navs</h1>
</div>
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#">Home</a></li>
<li role="presentation"><a href="#">Profile</a></li>
<li role="presentation"><a href="#">Messages</a></li>
</ul>
<ul class="nav nav-pills" role="tablist">
<li role="presentation" class="active"><a href="#">Home</a></li>
<li role="presentation"><a href="#">Profile</a></li>
<li role="presentation"><a href="#">Messages</a></li>
</ul>
<div class="page-header">
<h1>Navbars</h1>
</div>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">Nav header</li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<nav class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">Nav header</li>
<li><a href="#">Separated link</a></li>
<li><a href="#">One more separated link</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="page-header">
<h1>Alerts</h1>
</div>
<div class="alert alert-success" role="alert">
<strong>Well done!</strong> You successfully read this important alert message.
</div>
<div class="alert alert-info" role="alert">
<strong>Heads up!</strong> This alert needs your attention, but it's not super important.
</div>
<div class="alert alert-warning" role="alert">
<strong>Warning!</strong> Best check yo self, you're not looking too good.
</div>
<div class="alert alert-danger" role="alert">
<strong>Oh snap!</strong> Change a few things up and try submitting again.
</div>
<div class="page-header">
<h1>Progress bars</h1>
</div>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;"><span class="sr-only">60% Complete</span></div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 40%"><span class="sr-only">40% Complete (success)</span></div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" style="width: 20%"><span class="sr-only">20% Complete</span></div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-warning" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%"><span class="sr-only">60% Complete (warning)</span></div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-danger" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100" style="width: 80%"><span class="sr-only">80% Complete (danger)</span></div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-striped" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%"><span class="sr-only">60% Complete</span></div>
</div>
<div class="progress">
<div class="progress-bar progress-bar-success" style="width: 35%"><span class="sr-only">35% Complete (success)</span></div>
<div class="progress-bar progress-bar-warning" style="width: 20%"><span class="sr-only">20% Complete (warning)</span></div>
<div class="progress-bar progress-bar-danger" style="width: 10%"><span class="sr-only">10% Complete (danger)</span></div>
</div>
<div class="page-header">
<h1>List groups</h1>
</div>
<div class="row">
<div class="col-sm-4">
<ul class="list-group">
<li class="list-group-item">Cras justo odio</li>
<li class="list-group-item">Dapibus ac facilisis in</li>
<li class="list-group-item">Morbi leo risus</li>
<li class="list-group-item">Porta ac consectetur ac</li>
<li class="list-group-item">Vestibulum at eros</li>
</ul>
</div><!-- /.col-sm-4 -->
<div class="col-sm-4">
<div class="list-group">
<a href="#" class="list-group-item active">
Cras justo odio
</a>
<a href="#" class="list-group-item">Dapibus ac facilisis in</a>
<a href="#" class="list-group-item">Morbi leo risus</a>
<a href="#" class="list-group-item">Porta ac consectetur ac</a>
<a href="#" class="list-group-item">Vestibulum at eros</a>
</div>
</div><!-- /.col-sm-4 -->
<div class="col-sm-4">
<div class="list-group">
<a href="#" class="list-group-item active">
<h4 class="list-group-item-heading">List group item heading</h4>
<p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
</a>
<a href="#" class="list-group-item">
<h4 class="list-group-item-heading">List group item heading</h4>
<p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
</a>
<a href="#" class="list-group-item">
<h4 class="list-group-item-heading">List group item heading</h4>
<p class="list-group-item-text">Donec id elit non mi porta gravida at eget metus. Maecenas sed diam eget risus varius blandit.</p>
</a>
</div>
</div><!-- /.col-sm-4 -->
</div>
<div class="page-header">
<h1>Panels</h1>
</div>
<div class="row">
<div class="col-sm-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>
<div class="panel-body">
Panel content
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>
<div class="panel-body">
Panel content
</div>
</div>
</div><!-- /.col-sm-4 -->
<div class="col-sm-4">
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>
<div class="panel-body">
Panel content
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>
<div class="panel-body">
Panel content
</div>
</div>
</div><!-- /.col-sm-4 -->
<div class="col-sm-4">
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>
<div class="panel-body">
Panel content
</div>
</div>
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">Panel title</h3>
</div>
<div class="panel-body">
Panel content
</div>
</div>
</div><!-- /.col-sm-4 -->
</div>
<div class="page-header">
<h1>Wells</h1>
</div>
<div class="well">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed diam eget risus varius blandit sit amet non magna. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Cras mattis consectetur purus sit amet fermentum. Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Aenean lacinia bibendum nulla sed consectetur.</p>
</div>
<div class="page-header">
<h1>Carousel</h1>
</div>
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0" class=""></li>
<li data-target="#carousel-example-generic" data-slide-to="1" class=""></li>
<li data-target="#carousel-example-generic" data-slide-to="2" class="active"></li>
</ol>
<div class="carousel-inner" role="listbox">
<div class="item">
<img data-src="holder.js/1140x500/auto/#777:#555/text:First slide" alt="First slide [1140x500]" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTE0MCIgaGVpZ2h0PSI1MDAiIHZpZXdCb3g9IjAgMCAxMTQwIDUwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PCEtLQpTb3VyY2UgVVJMOiBob2xkZXIuanMvMTE0MHg1MDAvYXV0by8jNzc3OiM1NTUvdGV4dDpGaXJzdCBzbGlkZQpDcmVhdGVkIHdpdGggSG9sZGVyLmpzIDIuNi4wLgpMZWFybiBtb3JlIGF0IGh0dHA6Ly9ob2xkZXJqcy5jb20KKGMpIDIwMTItMjAxNSBJdmFuIE1hbG9waW5za3kgLSBodHRwOi8vaW1za3kuY28KLS0+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48IVtDREFUQVsjaG9sZGVyXzE1NjJjYTIxYzRkIHRleHQgeyBmaWxsOiM1NTU7Zm9udC13ZWlnaHQ6Ym9sZDtmb250LWZhbWlseTpBcmlhbCwgSGVsdmV0aWNhLCBPcGVuIFNhbnMsIHNhbnMtc2VyaWYsIG1vbm9zcGFjZTtmb250LXNpemU6NTdwdCB9IF1dPjwvc3R5bGU+PC9kZWZzPjxnIGlkPSJob2xkZXJfMTU2MmNhMjFjNGQiPjxyZWN0IHdpZHRoPSIxMTQwIiBoZWlnaHQ9IjUwMCIgZmlsbD0iIzc3NyIvPjxnPjx0ZXh0IHg9IjM5MC41MDc4MTI1IiB5PSIyNzUuNSI+Rmlyc3Qgc2xpZGU8L3RleHQ+PC9nPjwvZz48L3N2Zz4=" data-holder-rendered="true">
</div>
<div class="item active left">
<img data-src="holder.js/1140x500/auto/#666:#444/text:Second slide" alt="Second slide [1140x500]" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTE0MCIgaGVpZ2h0PSI1MDAiIHZpZXdCb3g9IjAgMCAxMTQwIDUwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PCEtLQpTb3VyY2UgVVJMOiBob2xkZXIuanMvMTE0MHg1MDAvYXV0by8jNjY2OiM0NDQvdGV4dDpTZWNvbmQgc2xpZGUKQ3JlYXRlZCB3aXRoIEhvbGRlci5qcyAyLjYuMC4KTGVhcm4gbW9yZSBhdCBodHRwOi8vaG9sZGVyanMuY29tCihjKSAyMDEyLTIwMTUgSXZhbiBNYWxvcGluc2t5IC0gaHR0cDovL2ltc2t5LmNvCi0tPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PCFbQ0RBVEFbI2hvbGRlcl8xNTYyY2ExZTY3NCB0ZXh0IHsgZmlsbDojNDQ0O2ZvbnQtd2VpZ2h0OmJvbGQ7Zm9udC1mYW1pbHk6QXJpYWwsIEhlbHZldGljYSwgT3BlbiBTYW5zLCBzYW5zLXNlcmlmLCBtb25vc3BhY2U7Zm9udC1zaXplOjU3cHQgfSBdXT48L3N0eWxlPjwvZGVmcz48ZyBpZD0iaG9sZGVyXzE1NjJjYTFlNjc0Ij48cmVjdCB3aWR0aD0iMTE0MCIgaGVpZ2h0PSI1MDAiIGZpbGw9IiM2NjYiLz48Zz48dGV4dCB4PSIzMzUuNjAxNTYyNSIgeT0iMjc1LjUiPlNlY29uZCBzbGlkZTwvdGV4dD48L2c+PC9nPjwvc3ZnPg==" data-holder-rendered="true">
</div>
<div class="item next left">
<img data-src="holder.js/1140x500/auto/#555:#333/text:Third slide" alt="Third slide [1140x500]" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTE0MCIgaGVpZ2h0PSI1MDAiIHZpZXdCb3g9IjAgMCAxMTQwIDUwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+PCEtLQpTb3VyY2UgVVJMOiBob2xkZXIuanMvMTE0MHg1MDAvYXV0by8jNTU1OiMzMzMvdGV4dDpUaGlyZCBzbGlkZQpDcmVhdGVkIHdpdGggSG9sZGVyLmpzIDIuNi4wLgpMZWFybiBtb3JlIGF0IGh0dHA6Ly9ob2xkZXJqcy5jb20KKGMpIDIwMTItMjAxNSBJdmFuIE1hbG9waW5za3kgLSBodHRwOi8vaW1za3kuY28KLS0+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48IVtDREFUQVsjaG9sZGVyXzE1NjJjYTFiNTg5IHRleHQgeyBmaWxsOiMzMzM7Zm9udC13ZWlnaHQ6Ym9sZDtmb250LWZhbWlseTpBcmlhbCwgSGVsdmV0aWNhLCBPcGVuIFNhbnMsIHNhbnMtc2VyaWYsIG1vbm9zcGFjZTtmb250LXNpemU6NTdwdCB9IF1dPjwvc3R5bGU+PC9kZWZzPjxnIGlkPSJob2xkZXJfMTU2MmNhMWI1ODkiPjxyZWN0IHdpZHRoPSIxMTQwIiBoZWlnaHQ9IjUwMCIgZmlsbD0iIzU1NSIvPjxnPjx0ZXh0IHg9IjM3Ny44NjcxODc1IiB5PSIyNzUuNSI+VGhpcmQgc2xpZGU8L3RleHQ+PC9nPjwvZz48L3N2Zz4=" data-holder-rendered="true">
</div>
</div>
<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div> <!-- /container -->
@@ -1,15 +0,0 @@
/* eslint-env node */
'use strict';
module.exports = function(config) {
config.set({
scripts: [{
id: 'angular',
src: '/build/angular.js'
},
{
src: 'app.js'
}]
});
};
-40
View File
@@ -1,40 +0,0 @@
<div ng-app="boostrapCompileBenchmark" ng-cloak>
<div ng-controller="DataController as config">
<p>Please, select which configuration you want to use:</p>
<ul>
<li>
<a href="?comment=disabled&css=disabled">Only EA</a>
<span ng-show="config.isEA">(active)</span>
</li>
<li>
<a href="?comment=disabled">Active EA and classes directives</a>
<span ng-show="config.isEAC">(active)</span>
</li>
<li>
<a href="?css=disabled">Active EA and comment directives</a>
<span ng-show="config.isEAM">(active)</span>
</li>
<li>
<a href="?">Active all directives</a>
<span ng-show="config.isEACM">(active)</span>
</li>
</ul>
<hr>
<p>How many repetitions do you want to do?</p>
<input type="number" ng-model="config.repeats">
<hr>
<p>Template to $compile:</p>
<select
ng-options="template for template in config.templates"
ng-model="config.selectedTemplate"
ng-change="config.loadTemplate()"></select>
<p>The benchmark is
<span ng-show="config.html">Ready!</span>
<span ng-hide="config.html">LOADING!</span>
</p>
</div>
</div>
+7 -8
View File
@@ -1,5 +1,3 @@
'use strict';
var app = angular.module('eventDelegationBenchmark', []);
app.directive('noopDir', function() {
@@ -7,7 +5,7 @@ app.directive('noopDir', function() {
compile: function($element, $attrs) {
return function($scope, $element) {
return 1;
};
}
}
};
});
@@ -15,12 +13,12 @@ app.directive('noopDir', function() {
app.directive('nativeClick', ['$parse', function($parse) {
return {
compile: function($element, $attrs) {
$parse($attrs.tstEvent);
var expr = $parse($attrs.tstEvent);
return function($scope, $element) {
$element[0].addEventListener('click', function() {
console.log('clicked');
}, false);
};
}
}
};
}]);
@@ -28,12 +26,13 @@ app.directive('nativeClick', ['$parse', function($parse) {
app.directive('dlgtClick', function() {
return {
compile: function($element, $attrs) {
var evt = $attrs.dlgtClick;
// We don't setup the global event listeners as the costs are small and one time only...
}
};
});
app.controller('DataController', function DataController($rootScope) {
app.controller('DataController', function($rootScope) {
this.ngRepeatCount = 1000;
this.rows = [];
var self = this;
@@ -48,8 +47,8 @@ app.controller('DataController', function DataController($rootScope) {
self.rows = oldRows;
if (self.rows.length !== self.ngRepeatCount) {
self.rows = [];
for (var i = 0; i < self.ngRepeatCount; i++) {
self.rows.push('row' + i);
for (var i=0; i<self.ngRepeatCount; i++) {
self.rows.push('row'+i);
}
}
$rootScope.$apply();
+2 -6
View File
@@ -1,14 +1,10 @@
/* eslint-env node */
'use strict';
module.exports = function(config) {
config.set({
scripts: [{
id: 'angular',
src: '/build/angular.js'
}, {
src: 'app.js'
},{
src: 'app.js',
}]
});
};
+9 -13
View File
@@ -1,5 +1,3 @@
'use strict';
var app = angular.module('largetableBenchmark', []);
app.config(function($compileProvider) {
@@ -14,23 +12,21 @@ app.filter('noop', function() {
};
});
app.controller('DataController', function DataController($scope, $rootScope) {
app.controller('DataController', function($scope, $rootScope) {
var totalRows = 1000;
var totalColumns = 20;
var data = $scope.data = [];
$scope.digestDuration = '?';
$scope.numberOfBindings = totalRows * totalColumns * 2 + totalRows + 1;
$scope.numberOfBindings = totalRows*totalColumns*2 + totalRows + 1;
$scope.numberOfWatches = '?';
/** @this */
function iGetter() { return this.i; }
/** @this */
function jGetter() { return this.j; }
for (var i = 0; i < totalRows; i++) {
for (var i=0; i<totalRows; i++) {
data[i] = [];
for (var j = 0; j < totalColumns; j++) {
for (var j=0; j<totalColumns; j++) {
data[i][j] = {
i: i, j: j,
iFn: iGetter,
@@ -68,13 +64,14 @@ app.controller('DataController', function DataController($scope, $rootScope) {
});
});
var fn = function() { return 'x'};
app.directive('baselineBindingTable', function() {
return {
restrict: 'E',
link: function($scope, $element) {
link: function ($scope, $element) {
var i, j, row, cell, comment;
var document = window.document;
var template = document.createElement('span');
template.setAttribute('ng-repeat', 'foo in foos');
template.classList.add('ng-scope');
@@ -107,9 +104,8 @@ app.directive('baselineBindingTable', function() {
app.directive('baselineInterpolationTable', function() {
return {
restrict: 'E',
link: function($scope, $element) {
link: function ($scope, $element) {
var i, j, row, cell, comment;
var document = window.document;
var template = document.createElement('span');
template.setAttribute('ng-repeat', 'foo in foos');
template.classList.add('ng-scope');
@@ -184,4 +180,4 @@ app.directive('baselineTable', function() {
};
});
*/
*/
+1 -5
View File
@@ -1,7 +1,3 @@
/* eslint-env node */
'use strict';
module.exports = function(config) {
config.set({
scripts: [{
@@ -13,7 +9,7 @@ module.exports = function(config) {
src: '/build/angular.js'
},
{
src: 'app.js'
src: 'app.js',
}]
});
};
+1 -1
View File
@@ -1 +1 @@
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
//Override me with ?jquery=/bower_components/jquery/dist/jquery.js
-108
View File
@@ -1,108 +0,0 @@
'use strict';
var app = angular.module('ngClassBenchmark', []);
app.controller('DataController', function DataController($scope) {
this.init = function() {
this.numberOfTodos = 1000;
this.implementation = 'tableOptimized';
this.completedPeriodicity = 3;
this.importantPeriodicity = 13;
this.urgentPeriodicity = 29;
this.createTodos(100);
this.setTodosValuesWithSeed(0);
};
this.clearTodos = function() {
this.todos = null;
};
this.createTodos = function(count) {
var i;
this.todos = [];
for (i = 0; i < count; i++) {
this.todos.push({
id: i + 1,
completed: false,
important: false,
urgent: false
});
}
};
this.setTodosValuesWithSeed = function(offset) {
var i, todo;
for (i = 0; i < this.todos.length; i++) {
todo = this.todos[i];
todo.completed = 0 === (i + offset) % this.completedPeriodicity;
todo.important = 0 === (i + offset) % this.importantPeriodicity;
todo.urgent = 0 === (i + offset) % this.urgentPeriodicity;
}
};
this.init();
benchmarkSteps.push({
name: 'setup',
fn: function() {
$scope.$apply();
this.clearTodos();
this.createTodos(this.numberOfTodos);
}.bind(this)
});
benchmarkSteps.push({
name: 'create',
fn: function() {
// initialize data for first time that will construct the DOM
this.setTodosValuesWithSeed(0);
$scope.$apply();
}.bind(this)
});
benchmarkSteps.push({
name: '$apply',
fn: function() {
$scope.$apply();
}
});
benchmarkSteps.push({
name: 'update',
fn: function() {
// move everything but completed
this.setTodosValuesWithSeed(3);
$scope.$apply();
}.bind(this)
});
benchmarkSteps.push({
name: 'unclass',
fn: function() {
// remove all classes
this.setTodosValuesWithSeed(NaN);
$scope.$apply();
}.bind(this)
});
benchmarkSteps.push({
name: 'class',
fn: function() {
// add all classes as the initial state
this.setTodosValuesWithSeed(0);
$scope.$apply();
}.bind(this)
});
benchmarkSteps.push({
name: 'destroy',
fn: function() {
this.clearTodos();
$scope.$apply();
}.bind(this)
});
});
-15
View File
@@ -1,15 +0,0 @@
/* eslint-env node */
'use strict';
module.exports = function(config) {
config.set({
scripts: [{
id: 'angular',
src: '/build/angular.js'
},
{
src: 'app.js'
}]
});
};
-177
View File
@@ -1,177 +0,0 @@
<style>
.gold {
background: gold;
}
.silver {
background: silver;
}
.table tbody tr > td.success {
background-color: #dff0d8;
}
.table tbody tr > td.error {
background-color: #f2dede;
}
.table tbody tr > td.warning {
background-color: #fcf8e3;
}
.table tbody tr > td.info {
background-color: #d9edf7;
}
.completed {
text-decoration: line-through;
}
.important {
font-weight: bold;
}
.urgent {
color: red;
}
</style>
<div ng-app="ngClassBenchmark" ng-cloak class="container-fluid">
<div ng-controller="DataController as benchmark" class="row">
<div class="col-lg-12">
<div class="well">
<h3>Parameters</h3>
<br>
<p>
<label>Number of todos</label><br>
<input type="number" ng-model="benchmark.numberOfTodos">
</p>
<br>
<p>
<label>Implementation</label><br>
<div class="radio">
<label>
<input ng-model="benchmark.implementation" value="tableOptimized"
type="radio" name="implementation">
Table optimized <br>
<code>ng-class="todo.completed && 'success'"</code>
</label>
</div>
<div class="radio">
<label>
<input ng-model="benchmark.implementation" value="table"
type="radio" name="implementation">
Table <br>
<code>ng-class="{success: todo.completed}"</code>
</label>
</div>
<div class="radio">
<label>
<input ng-model="benchmark.implementation" value="list"
type="radio" name="implementation">
List <br>
<code>ng-class="{completed: todo.completed, urgent: todo.urgent, important: todo.important"}</code>
</label>
</div>
<div class="radio">
<label>
<input ng-model="benchmark.implementation" value="singleOptimized"
type="radio" name="implementation">
Single ngClass optimized <br>
<code>
ng-class="{'panel-success': !!benchmark.todos, 'panel-danger': !benchmark.todos}"
</code>
</label>
</div>
<div class="radio">
<label>
<input ng-model="benchmark.implementation" value="single"
type="radio" name="implementation">
Single ngClass <br>
<code>
ng-class="{'panel-success': benchmark.todos, 'panel-danger': !benchmark.todos}"
</code>
</label>
</div>
</p>
</div>
<br>
<h3>Example</h3>
<div ng-switch="benchmark.implementation">
<table ng-switch-when="tableOptimized" class="table">
<thead>
<tr>
<th>todo #id</th>
<th>completed?</th>
<th>urgent?</th>
<th>important?</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="todo in benchmark.todos track by todo.id"
ng-class="todo.completed && 'active'"
ng-class-even="todo.completed && todo.important && 'gold'"
ng-class-odd="todo.completed && todo.important && 'silver'"
>
<td>#{{todo.id}}</td>
<td>{{todo.completed}}</td>
<td ng-class="todo.urgent && 'danger'">{{todo.urgent}}</td>
<td ng-class="todo.important && 'success'">{{todo.important}}</td>
</tr>
</tbody>
</table>
<table ng-switch-when="table" class="table">
<thead>
<tr>
<th>todo #id</th>
<th>completed?</th>
<th>urgent?</th>
<th>important?</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="todo in benchmark.todos track by todo.id"
ng-class="{active: todo.completed}"
ng-class-even="{gold: todo.completed && todo.important}"
ng-class-odd="{silver: todo.completed && todo.important}"
>
<td>#{{todo.id}}</td>
<td>{{todo.completed}}</td>
<td ng-class="{danger: todo.urgent}">{{todo.urgent}}</td>
<td ng-class="{success: todo.important}">{{todo.important}}</td>
</tr>
</tbody>
</table>
<ul ng-switch-when="list">
<li ng-repeat="todo in benchmark.todos track by todo.id"
ng-class="{
completed: todo.completed,
urgent: todo.urgent,
important: todo.important
}">#{{todo.id}}</li>
</ul>
<div ng-switch-when="singleOptimized"
class="panel"
ng-class="{'panel-success': !!benchmark.todos, 'panel-danger': !benchmark.todos}">
<div class="panel-heading">
<h3 class="panel-title">Information</h3>
</div>
<div class="panel-body"> The title is green because there are todos... </div>
</div>
<div ng-switch-when="single"
class="panel"
ng-class="{'panel-success': benchmark.todos, 'panel-danger': !benchmark.todos}">
<div class="panel-heading">
<h3 class="panel-title">Information</h3>
</div>
<div class="panel-body"> The title is green because there are todos... </div>
</div>
</div>
</div>
</div>
</div>
<br><br><br>
Regular → Executable
+1 -1
View File
@@ -1,4 +1,4 @@
'use strict';
"use strict";
/* globals angular, benchmarkSteps */
+2 -6
View File
@@ -1,15 +1,11 @@
/* eslint-env node */
'use strict';
module.exports = function(config) {
config.set({
scripts: [{
scripts: [ {
id: 'angular',
src: '/build/angular.js'
},
{
src: 'app.js'
src: 'app.js',
}]
});
};
View File
+3 -5
View File
@@ -1,13 +1,11 @@
'use strict';
var app = angular.module('orderByBenchmark', []);
app.controller('DataController', function DataController($rootScope, $scope) {
app.controller('DataController', function($rootScope, $scope) {
this.ngRepeatCount = 5000;
this.rows = [];
var self = this;
$scope.benchmarkType = 'baseline';
$scope.benchmarkType = 'basic';
$scope.rawProperty = function(key) {
return function(item) {
@@ -39,7 +37,7 @@ app.controller('DataController', function DataController($rootScope, $scope) {
}
}
}
});
})
benchmarkSteps.push({
name: '$apply',
+5 -9
View File
@@ -1,18 +1,14 @@
/* eslint-env node */
'use strict';
module.exports = function(config) {
config.set({
scripts: [
{
'id': 'jquery',
'src': 'jquery-noop.js'
}, {
"id": "jquery",
"src": "jquery-noop.js"
},{
id: 'angular',
src: '/build/angular.js'
}, {
src: 'app.js'
},{
src: 'app.js',
}]
});
};
-1
View File
@@ -1 +0,0 @@
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
+22 -23
View File
@@ -1,5 +1,3 @@
'use strict';
var app = angular.module('parsedExpressionBenchmark', []);
app.config(function($compileProvider) {
@@ -19,10 +17,11 @@ app.directive('bmPeWatch', function() {
return {
restrict: 'A',
compile: function($element, $attrs) {
$element.text($attrs.bmPeWatch);
$element.text( $attrs.bmPeWatch );
return function($scope, $element, $attrs) {
$scope.$watch($attrs.bmPeWatch, function(val) {
$element.text(val);
});
};
}
@@ -39,9 +38,9 @@ app.directive('bmPeWatchLiteral', function($parse) {
return {
restrict: 'A',
compile: function($element, $attrs) {
$element.text($attrs.bmPeWatchLiteral);
$element.text( $attrs.bmPeWatchLiteral );
return function($scope, $element, $attrs) {
$scope.$watch($parse($attrs.bmPeWatchLiteral, retZero));
$scope.$watch( $parse($attrs.bmPeWatchLiteral, retZero) );
};
}
};
@@ -54,33 +53,33 @@ app.controller('DataController', function($scope, $rootScope) {
var star = '*';
$scope.func = function() { return star; };
$scope.func = function() { return star;};
for (var i = 0; i < totalRows; i++) {
for (var i=0; i<totalRows; i++) {
data.push({
index: i,
odd: i % 2 === 0,
even: i % 2 === 1,
str0: 'foo-' + Math.random() * Date.now(),
str1: 'bar-' + Math.random() * Date.now(),
str2: 'baz-' + Math.random() * Date.now(),
num0: Math.random() * Date.now(),
num1: Math.random() * Date.now(),
num2: Math.random() * Date.now(),
date0: new Date(Math.random() * Date.now()),
date1: new Date(Math.random() * Date.now()),
date2: new Date(Math.random() * Date.now()),
func: function() { return star; },
obj: data[i - 1],
keys: data[i - 1] && (data[i - 1].keys || Object.keys(data[i - 1])),
constructor: data[i - 1]
odd: i%2 === 0,
even: i%2 === 1,
str0: "foo-" + Math.random()*Date.now(),
str1: "bar-" + Math.random()*Date.now(),
str2: "baz-" + Math.random()*Date.now(),
num0: Math.random()*Date.now(),
num1: Math.random()*Date.now(),
num2: Math.random()*Date.now(),
date0: new Date(Math.random()*Date.now()),
date1: new Date(Math.random()*Date.now()),
date2: new Date(Math.random()*Date.now()),
func: function(){ return star; },
obj: data[i-1],
keys: data[i-1] && (data[i-1].keys || Object.keys(data[i-1])),
constructor: data[i-1]
});
}
benchmarkSteps.push({
name: '$apply',
fn: function() {
for (var i = 0; i < 50; i++) {
for (var i=0; i<50; i++) {
$rootScope.$digest();
}
}
+2 -6
View File
@@ -1,15 +1,11 @@
/* eslint-env node */
'use strict';
module.exports = function(config) {
config.set({
scripts: [{
scripts: [ {
id: 'angular',
src: '/build/angular.js'
},
{
src: 'app.js'
src: 'app.js',
}]
});
};
-17
View File
@@ -52,11 +52,6 @@
<label for="functionCalls">Function calls</label>
</li>
<li>
<input type="radio" ng-model="expressionType" value="assignment" id="assignment">
<label for="assignment">Assignment</label>
</li>
<li>
<input type="radio" ng-model="expressionType" value="objectLiterals" id="objectLiterals">
<label for="objectLiterals">Object Literals</label>
@@ -202,18 +197,6 @@
<span bm-pe-watch="row.func(row.func(), row.func())"></span>
</li>
<li ng-switch-when="assignment" ng-repeat="(rowIdx, row) in ::data">
<span bm-pe-watch="row.foo = row.str0"></span>
<span bm-pe-watch="row.obj.foo = row.str1"></span>
<span bm-pe-watch="row.obj.obj.foo = row.str2"></span>
<span bm-pe-watch="row['bar'] = row.num0"></span>
<span bm-pe-watch="row.obj['bar'] = row.num1"></span>
<span bm-pe-watch="row.obj.obj['bar'] = row.num2"></span>
<span bm-pe-watch="row[0] = row.date0"></span>
<span bm-pe-watch="row.obj[0] = row.date1"></span>
<span bm-pe-watch="row.obj.obj[0] = row.date2"></span>
</li>
<li ng-switch-when="objectLiterals" ng-repeat="(rowIdx, row) in ::data">
<span bm-pe-watch-literal="{foo: rowIdx}"></span>
<span bm-pe-watch-literal="{foo: row, bar: rowIdx}"></span>
-104
View File
@@ -1,104 +0,0 @@
'use strict';
/* globals angular, benchmarkSteps */
var app = angular.module('selectBenchmark', []);
app.config(function($compileProvider) {
if ($compileProvider.debugInfoEnabled) {
$compileProvider.debugInfoEnabled(false);
}
});
app.controller('DataController', function($scope, $element) {
$scope.groups = [];
$scope.count = 10000;
function changeOptions() {
$scope.groups = [];
var i = 0;
var group;
while (i < $scope.count) {
if (i % 100 === 0) {
group = {
name: 'group-' + $scope.groups.length,
items: []
};
$scope.groups.push(group);
}
group.items.push({
id: i,
label: 'item-' + i
});
i++;
}
}
var selectElement = $element.find('select');
console.log(selectElement);
benchmarkSteps.push({
name: 'add-options',
fn: function() {
$scope.$apply(function() {
$scope.count = 10000;
changeOptions();
});
}
});
benchmarkSteps.push({
name: 'set-model-1',
fn: function() {
$scope.$apply(function() {
$scope.x = $scope.groups[10].items[0];
});
}
});
benchmarkSteps.push({
name: 'set-model-2',
fn: function() {
$scope.$apply(function() {
$scope.x = $scope.groups[0].items[10];
});
}
});
benchmarkSteps.push({
name: 'remove-options',
fn: function() {
$scope.count = 100;
changeOptions();
}
});
benchmarkSteps.push({
name: 'add-options',
fn: function() {
$scope.$apply(function() {
$scope.count = 10000;
changeOptions();
});
}
});
benchmarkSteps.push({
name: 'set-view-1',
fn: function() {
selectElement.val('2000');
selectElement.triggerHandler('change');
}
});
benchmarkSteps.push({
name: 'set-view-2',
fn: function() {
selectElement.val('1000');
selectElement.triggerHandler('change');
}
});
});
-15
View File
@@ -1,15 +0,0 @@
/* eslint-env node */
'use strict';
module.exports = function(config) {
config.set({
scripts: [{
id: 'angular',
src: '/build/angular.js'
},
{
src: 'app.js'
}]
});
};
-15
View File
@@ -1,15 +0,0 @@
<div ng-app="selectBenchmark" ng-cloak>
<div ng-controller="DataController">
<div class="container-fluid">
<p>
Tests the execution of a select with ngRepeat'ed options with ngValue for rendering during model
and option updates.
</p>
<select ng-model="x">
<optgroup ng-repeat="g in groups track by g.name" label="{{g.name}}">
<option ng-repeat="a in g.items track by a.id" ng-value="a">{{a.label}}</option>
</optgroup>
</select>
</div>
</div>
</div>
+3 -5
View File
@@ -1,11 +1,9 @@
{
"name": "angularjs",
"name": "AngularJS",
"license": "MIT",
"devDependencies": {
"jquery": "3.1.0",
"jquery-2.2": "jquery#2.2.4",
"jquery-2.1": "jquery#2.1.4",
"jquery": "2.1.1",
"closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.4/assets/ng-closure-runner.zip"
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.3/assets/ng-closure-runner.zip"
}
}
Executable
+210
View File
@@ -0,0 +1,210 @@
#!/usr/bin/env node
// TODO(vojta): pre-commit hook for validating messages
// TODO(vojta): report errors, currently Q silence everything which really sucks
'use strict';
var child = require('child_process');
var fs = require('fs');
var util = require('util');
var q = require('qq');
var GIT_LOG_CMD = 'git log --grep="%s" -E --format=%s %s..HEAD';
var GIT_TAG_CMD = 'git describe --tags --abbrev=0';
var HEADER_TPL = '<a name="%s"></a>\n# %s (%s)\n\n';
var LINK_ISSUE = '[#%s](https://github.com/angular/angular.js/issues/%s)';
var LINK_COMMIT = '[%s](https://github.com/angular/angular.js/commit/%s)';
var EMPTY_COMPONENT = '$$';
var warn = function() {
console.log('WARNING:', util.format.apply(null, arguments));
};
var parseRawCommit = function(raw) {
if (!raw) return null;
var lines = raw.split('\n');
var msg = {}, match;
msg.hash = lines.shift();
msg.subject = lines.shift();
msg.closes = [];
msg.breaks = [];
lines.forEach(function(line) {
match = line.match(/(?:Closes|Fixes)\s#(\d+)/);
if (match) msg.closes.push(parseInt(match[1]));
});
match = raw.match(/BREAKING CHANGE:([\s\S]*)/);
if (match) {
msg.breaking = match[1];
}
msg.body = lines.join('\n');
match = msg.subject.match(/^(.*)\((.*)\)\:\s(.*)$/);
if (!match || !match[1] || !match[3]) {
warn('Incorrect message: %s %s', msg.hash, msg.subject);
return null;
}
msg.type = match[1];
msg.component = match[2];
msg.subject = match[3];
return msg;
};
var linkToIssue = function(issue) {
return util.format(LINK_ISSUE, issue, issue);
};
var linkToCommit = function(hash) {
return util.format(LINK_COMMIT, hash.substr(0, 8), hash);
};
var currentDate = function() {
var now = new Date();
var pad = function(i) {
return ('0' + i).substr(-2);
};
return util.format('%d-%s-%s', now.getFullYear(), pad(now.getMonth() + 1), pad(now.getDate()));
};
var printSection = function(stream, title, section, printCommitLinks) {
printCommitLinks = printCommitLinks === undefined ? true : printCommitLinks;
var components = Object.getOwnPropertyNames(section).sort();
if (!components.length) return;
stream.write(util.format('\n## %s\n\n', title));
components.forEach(function(name) {
var prefix = '-';
var nested = section[name].length > 1;
if (name !== EMPTY_COMPONENT) {
if (nested) {
stream.write(util.format('- **%s:**\n', name));
prefix = ' -';
} else {
prefix = util.format('- **%s:**', name);
}
}
section[name].forEach(function(commit) {
if (printCommitLinks) {
stream.write(util.format('%s %s\n (%s', prefix, commit.subject, linkToCommit(commit.hash)));
if (commit.closes.length) {
stream.write(',\n ' + commit.closes.map(linkToIssue).join(', '));
}
stream.write(')\n');
} else {
stream.write(util.format('%s %s\n', prefix, commit.subject));
}
});
});
stream.write('\n');
};
var readGitLog = function(grep, from) {
var deferred = q.defer();
// TODO(vojta): if it's slow, use spawn and stream it instead
child.exec(util.format(GIT_LOG_CMD, grep, '%H%n%s%n%b%n==END==', from), function(code, stdout, stderr) {
var commits = [];
stdout.split('\n==END==\n').forEach(function(rawCommit) {
var commit = parseRawCommit(rawCommit);
if (commit) commits.push(commit);
});
deferred.resolve(commits);
});
return deferred.promise;
};
var writeChangelog = function(stream, commits, version) {
var sections = {
fix: {},
feat: {},
perf: {},
breaks: {}
};
sections.breaks[EMPTY_COMPONENT] = [];
commits.forEach(function(commit) {
var section = sections[commit.type];
var component = commit.component || EMPTY_COMPONENT;
if (section) {
section[component] = section[component] || [];
section[component].push(commit);
}
if (commit.breaking) {
sections.breaks[component] = sections.breaks[component] || [];
sections.breaks[component].push({
subject: util.format("due to %s,\n %s", linkToCommit(commit.hash), commit.breaking),
hash: commit.hash,
closes: []
});
}
});
stream.write(util.format(HEADER_TPL, version, version, currentDate()));
printSection(stream, 'Bug Fixes', sections.fix);
printSection(stream, 'Features', sections.feat);
printSection(stream, 'Performance Improvements', sections.perf);
printSection(stream, 'Breaking Changes', sections.breaks, false);
};
var getPreviousTag = function() {
var deferred = q.defer();
child.exec(GIT_TAG_CMD, function(code, stdout, stderr) {
if (code) deferred.reject('Cannot get the previous tag.');
else deferred.resolve(stdout.replace('\n', ''));
});
return deferred.promise;
};
var generate = function(version, file) {
getPreviousTag().then(function(tag) {
console.log('Reading git log since', tag);
readGitLog('^fix|^feat|^perf|BREAKING', tag).then(function(commits) {
console.log('Parsed', commits.length, 'commits');
console.log('Generating changelog to', file || 'stdout', '(', version, ')');
writeChangelog(file ? fs.createWriteStream(file) : process.stdout, commits, version);
});
});
};
// publish for testing
exports.parseRawCommit = parseRawCommit;
exports.printSection = printSection;
// hacky start if not run by jasmine :-D
if (process.argv.join('').indexOf('jasmine-node') === -1) {
generate(process.argv[2], process.argv[3]);
}
+108
View File
@@ -0,0 +1,108 @@
/* global describe: false, beforeEach: false, afterEach: false, it: false, expect: false */
'use strict';
describe('changelog.js', function() {
var ch = require('./changelog');
describe('parseRawCommit', function() {
it('should parse raw commit', function() {
var msg = ch.parseRawCommit(
'9b1aff905b638aa274a5fc8f88662df446d374bd\n' +
'feat(scope): broadcast $destroy event on scope destruction\n' +
'perf testing shows that in chrome this change adds 5-15% overhead\n' +
'when destroying 10k nested scopes where each scope has a $destroy listener\n');
expect(msg.type).toBe('feat');
expect(msg.hash).toBe('9b1aff905b638aa274a5fc8f88662df446d374bd');
expect(msg.subject).toBe('broadcast $destroy event on scope destruction');
expect(msg.body).toBe('perf testing shows that in chrome this change adds 5-15% overhead\n' +
'when destroying 10k nested scopes where each scope has a $destroy listener\n');
expect(msg.component).toBe('scope');
});
it('should parse closed issues', function() {
var msg = ch.parseRawCommit(
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
'feat(ng-list): Allow custom separator\n' +
'bla bla bla\n\n' +
'Closes #123\nCloses #25\n');
expect(msg.closes).toEqual([123, 25]);
});
it('should parse breaking changes', function() {
var msg = ch.parseRawCommit(
'13f31602f396bc269076ab4d389cfd8ca94b20ba\n' +
'feat(ng-list): Allow custom separator\n' +
'bla bla bla\n\n' +
'BREAKING CHANGE: first breaking change\nsomething else\n' +
'another line with more info\n');
expect(msg.breaking).toEqual(' first breaking change\nsomething else\nanother line with more info\n');
});
});
describe('printSection', function() {
var output;
var streamMock = {
write: function(str) {
output += str;
}
};
beforeEach(function() {
output = '';
});
it('should add a new line at the end of each breaking change list item ' +
'when there is 1 item per component', function() {
var title = 'test';
var printCommitLinks = false;
var section = {
module1: [{subject: 'breaking change 1'}],
module2: [{subject: 'breaking change 2'}]
};
var expectedOutput =
'\n' + '## test\n\n' +
'- **module1:** breaking change 1\n' +
'- **module2:** breaking change 2\n' +
'\n';
ch.printSection(streamMock, title, section, printCommitLinks);
expect(output).toBe(expectedOutput);
});
it('should add a new line at the end of each breaking change list item ' +
'when there are multiple items per component', function() {
var title = 'test';
var printCommitLinks = false;
var section = {
module1: [
{subject: 'breaking change 1.1'},
{subject: 'breaking change 1.2'}
],
module2: [
{subject: 'breaking change 2.1'},
{subject: 'breaking change 2.2'}
]
};
var expectedOutput =
'\n' + '## test\n\n' +
'- **module1:**\n' +
' - breaking change 1.1\n' +
' - breaking change 1.2\n' +
'- **module2:**\n' +
' - breaking change 2.1\n' +
' - breaking change 2.2\n' +
'\n';
ch.printSection(streamMock, title, section, printCommitLinks);
expect(output).toBe(expectedOutput);
});
});
});
@@ -9,72 +9,72 @@ var Q = require('q');
var _ = require('lodash');
var semver = require('semver');
var exec = function(cmd) {
return function() {
var exec = function (cmd) {
return function () {
var args = Array.prototype.slice.call(arguments, 0);
args.unshift(cmd);
var fullCmd = util.format.apply(util, args);
return Q.nfcall(cp.exec, fullCmd).then(function(out) {
return Q.nfcall(cp.exec, fullCmd).then(function (out) {
return out[0].split('\n');
});
};
};
var andThen = function(fn, after) {
return /** @this */ function() {
var andThen = function (fn, after) {
return function () {
return fn.apply(this, arguments).then(after);
};
};
var oneArg = function(fn) {
return function(arg) {
var oneArg = function (fn) {
return function (arg) {
return fn(arg);
};
};
var oneLine = function(lines) {
var oneLine = function (lines) {
return lines[0].trim();
};
var noArgs = function(fn) {
return function() {
var noArgs = function (fn) {
return function () {
return fn();
};
};
var identity = function(i) { return i; };
var identity = function (i) { return i; };
// like Q.all, but runs the commands in series
// useful for ensuring env state (like which branch is checked out)
var allInSeries = function(fn) {
return function(args) {
var allInSeries = function (fn) {
return function (args) {
var results = [];
var def;
while (args.length > 0) {
(function(arg) {
(function (arg) {
if (def) {
def = def.then(function() {
def = def.then(function () {
return fn(arg);
});
} else {
def = fn(arg);
}
def = def.then(function(res) {
def = def.then(function (res) {
results.push(res);
});
})(args.pop());
}(args.pop()));
}
return def.then(function() {
return def.then(function () {
return results;
});
};
};
var compareBranches = function(left, right) {
var compareBranches = function (left, right) {
console.log('# These commits are in ' + left.name + ' but not in ' + right.name + '\n');
console.log(_(left.log).
difference(right.log).
map(function(line) {
map(function (line) {
return left.full[left.log.indexOf(line)]; // lol O(n^2)
}).
value().
@@ -85,43 +85,44 @@ var checkout = oneArg(exec('git checkout %s'));
var getCurrentBranch = andThen(noArgs(exec('git rev-parse --abbrev-ref HEAD')), oneLine);
var getTags = noArgs(exec('git tag'));
var getShaOfTag = oneArg(exec('git rev-list %s | head -n 1'));
var getTheLog = oneArg(exec('git log --pretty=oneline %s..HEAD | cat'));
// remember this so we can restore state
var currentBranch;
getCurrentBranch().
then(function(branch) {
then(function (branch) {
currentBranch = branch;
}).
then(getTags).
then(function(tags) {
then(function (tags) {
return tags.
filter(semver.valid).
map(semver.clean).
sort(semver.rcompare);
}).
then(function(tags) {
var major = semver(tags[0]).major;
then(function (tags) {
var major = tags[0].split('.')[0];
return tags.
filter(function(ver) {
return semver(ver).major === major;
filter(function (ver) {
return semver(ver).major == major;
});
}).
then(function(tags) {
then(function (tags) {
return _(tags).
groupBy(function(tag) {
groupBy(function (tag) {
return tag.split('.')[1];
}).
map(function(group) {
map(function (group) {
return _.first(group);
}).
map(function(tag) {
map(function (tag) {
return 'v' + tag;
}).
value();
}).
then(function(tags) {
then(function (tags) {
var master = tags.pop();
var stable = tags.pop();
@@ -130,38 +131,38 @@ then(function(tags) {
{ name: 'master', tag: master}
];
}).
then(allInSeries(function(branch) {
then(allInSeries(function (branch) {
return checkout(branch.name).
then(function() {
then(function () {
return getTheLog(branch.tag);
}).
then(function(log) {
then(function (log) {
return log.
filter(identity);
}).
then(function(log) {
branch.full = log.map(function(line) {
then(function (log) {
branch.full = log.map(function (line) {
line = line.split(' ');
var sha = line.shift();
var msg = line.join(' ');
return sha + ((/fix\([^)]+\):/i.test(msg)) ? ' * ' : ' ') + msg;
return sha + ((/fix\([^\)]+\):/i.test(msg)) ? ' * ' : ' ') + msg;
});
branch.log = log.map(function(line) {
branch.log = log.map(function (line) {
return line.substr(41);
});
return branch;
});
})).
then(function(pairs) {
then(function (pairs) {
compareBranches(pairs[0], pairs[1]);
console.log('\n');
compareBranches(pairs[1], pairs[0]);
return pairs;
}).
then(function() {
then(function () {
return checkout(currentBranch);
}).
catch(function(e) {
catch(function (e) {
console.log(e.stack);
});
+2 -2
View File
@@ -22,7 +22,7 @@ ul.doc-example > li.doc-example-heading {
span.nojsfiddle {
float: right;
font-size: 14px;
margin-right: 10px;
margin-right:10px;
margin-top: 10px;
}
@@ -42,7 +42,7 @@ form.jsfiddle button {
color: #7989D6;
border-color: #7989D6;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
-webkit-border-radius:8px;
border-radius: 8px;
}
+215 -246
View File
@@ -1,21 +1,21 @@
html, body {
position: relative;
height: 100%;
position:relative;
height:100%;
}
#wrapper {
min-height: 100%;
position: relative;
padding-bottom: 120px;
min-height:100%;
position:relative;
padding-bottom:120px;
}
.footer {
border-top: 20px solid white;
position: absolute;
bottom: 0;
left: 0;
right: 0;
z-index: 100;
border-top:20px solid white;
position:absolute;
bottom:0;
left:0;
right:0;
z-index:100;
padding-top: 2em;
background-color: #333;
color: white;
@@ -23,20 +23,20 @@ html, body {
}
.header-fixed {
position: fixed;
z-index: 1000;
top: 0;
left: 0;
right: 0;
position:fixed;
z-index:1000;
top:0;
left:0;
right:0;
}
.header-branding {
min-height: 41px !important;
min-height:41px!important;
}
.docs-navbar-primary {
border-radius: 0 !important;
margin-bottom: 0 !important;
border-radius:0!important;
margin-bottom:0!important;
}
/* Logo */
@@ -49,7 +49,7 @@ h1,h2,h3,h4,h5,h6 {
}
.subnav-body {
margin: 70px 0 20px;
margin:70px 0 20px;
}
.header .brand {
@@ -58,32 +58,32 @@ h1,h2,h3,h4,h5,h6 {
}
.header .brand img {
margin-top: 5px;
margin-top:5px;
height: 30px;
}
.docs-search {
margin: 10px 0;
padding: 4px 0 4px 20px;
background: white;
border-radius: 20px;
vertical-align: middle;
margin:10px 0;
padding:4px 0 4px 20px;
background:white;
border-radius:20px;
vertical-align:middle;
}
.docs-search > .search-query {
font-size: 14px;
border: 0;
width: 80%;
color: #555;
font-size:14px;
border:0;
width:80%;
color:#555;
}
.docs-search > .search-icon {
font-size: 15px;
margin-right: 10px;
font-size:15px;
margin-right:10px;
}
.docs-search > .search-query:focus {
outline: 0;
outline:0;
}
/* end: Logo */
@@ -101,31 +101,31 @@ h1,h2,h3,h4,h5,h6 {
.naked-list,
.naked-list ul,
.naked-list li {
list-style: none;
margin: 0;
padding: 0;
list-style:none;
margin:0;
padding:0;
}
.nav-index-section a {
font-weight: bold;
font-weight:bold;
font-family: "Open Sans";
color: black !important;
margin-top: 10px;
display: block;
color:black!important;
margin-top:10px;
display:block;
}
.nav-index-group {
margin-bottom: 20px !important;
margin-bottom:20px!important;
}
.nav-index-group-heading {
color: #6F0101;
font-weight: bold;
font-size: 1.2em;
padding: 0;
margin: 0;
border-bottom: 1px soild #aaa;
margin-bottom: 5px;
color:#6F0101;
font-weight:bold;
font-size:1.2em;
padding:0;
margin:0;
border-bottom:1px solid #aaa;
margin-bottom:5px;
}
.nav-index-group .nav-index-listing.current a {
@@ -133,58 +133,58 @@ h1,h2,h3,h4,h5,h6 {
}
.nav-breadcrumb {
margin: 4px 0;
padding: 0;
margin:4px 0;
padding:0;
}
.nav-breadcrumb-entry {
font-family: "Open Sans";
padding: 0;
margin: 0;
font-size: 18px;
display: inline-block;
vertical-align: middle;
padding:0;
margin:0;
font-size:18px;
display:inline-block;
vertical-align:middle;
}
.nav-breadcrumb-entry > .divider {
color: #555;
display: inline-block;
padding-left: 8px;
color:#555;
display:inline-block;
padding-left:8px;
}
.nav-breadcrumb-entry > span,
.nav-breadcrumb-entry > a {
color: #6F0101;
color:#6F0101;
}
.step-list > li:nth-child(1) {
padding-left: 20px;
padding-left:20px;
}
.step-list > li:nth-child(2) {
padding-left: 40px;
padding-left:40px;
}
.step-list > li:nth-child(3) {
padding-left: 60px;
padding-left:60px;
}
.api-profile-header-heading {
margin: 0;
padding: 0;
margin:0;
padding:0;
}
.api-profile-header-structure,
.api-profile-header-structure a {
font-family: "Open Sans";
font-weight: bold;
color: #999;
font-weight:bold;
color:#999;
}
.api-profile-section {
margin-top: 30px;
padding-top: 30px;
border-top: 1px solid #aaa;
margin-top:30px;
padding-top:30px;
border-top:1px solid #aaa;
}
pre {
@@ -196,23 +196,23 @@ pre {
.aside-nav a:link,
.aside-nav a:visited,
.aside-nav a:active {
color: #999;
color:#999;
}
.aside-nav a:hover {
color: black;
color:black;
}
.api-profile-description > p:first-child {
margin: 15px 0;
font-size: 18px;
margin:15px 0;
font-size:18px;
}
p > code,
code.highlighted {
background: #f4f4f4;
border-radius: 5px;
padding: 2px 5px;
color: maroon;
background:#f4f4f4;
border-radius:5px;
padding:2px 5px;
color:maroon;
}
ul + p {
@@ -220,8 +220,8 @@ ul + p {
}
.docs-version-jump {
min-width: 100%;
max-width: 100%;
min-width:100%;
max-width:100%;
}
.picker {
@@ -267,14 +267,14 @@ ul + p {
}
.picker:after {
content: "";
content:"";
position: absolute;
right: 8%;
top: 50%;
z-index: 0;
color: #999;
width: 0;
margin-top: -2px;
margin-top:-2px;
height: 0;
border-top: 6px solid;
border-right: 6px solid transparent;
@@ -287,32 +287,32 @@ iframe.example {
}
.search-results-frame {
clear: both;
display: table;
width: 100%;
clear:both;
display:table;
width:100%;
}
.search-results.ng-hide {
display: none;
display:none;
}
.search-results-container {
padding-bottom: 1em;
border-top: 1px solid #111;
background: #181818;
box-shadow: inset 0 0 10px #111;
padding-bottom:1em;
border-top:1px solid #111;
background:#181818;
box-shadow:inset 0 0 10px #111;
}
.search-results-container .search-results-group {
vertical-align: top;
padding: 10px 10px;
display: inline-block;
vertical-align:top;
padding:10px 10px;
display:inline-block;
}
.search-results-group-heading {
font-family: "Open Sans";
padding-left: 10px;
color: white;
padding-left:10px;
color:white;
}
.search-results-group .search-results {
@@ -321,23 +321,14 @@ iframe.example {
}
.search-results-frame > .search-results-group:first-child > .search-results {
border-right: 1px solid #222;
}
.search-results-group.col-group-api {
width: 30%;
border-right:1px solid #222;
}
.search-results-group.col-group-api { width:30%; }
.search-results-group.col-group-guide,
.search-results-group.col-group-tutorial {
width: 20%;
}
.search-results-group.col-group-tutorial { width:20%; }
.search-results-group.col-group-misc,
.search-results-group.col-group-error {
width: 15%;
float: right;
}
.search-results-group.col-group-error { width:15%; float: right; }
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
.search-results-group.col-group-api .search-results {
@@ -380,14 +371,14 @@ iframe.example {
}
.search-results-group.col-group-api .search-result {
width: 48%;
display: inline-block;
width:48%;
display:inline-block;
padding-left: 12px;
}
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
.search-results-group.col-group-api .search-result {
width: auto;
width:auto;
display: list-item;
}
}
@@ -404,135 +395,135 @@ iframe.example {
border-top-right-radius: 5px;
border-top-left-radius: 5px;
width: 200px;
box-shadow: 0 0 10px #111;
box-shadow:0 0 10px #111;
}
.variables-matrix {
border: 1px solid #ddd;
width: 100%;
margin: 10px 0;
border:1px solid #ddd;
width:100%;
margin:10px 0;
}
.variables-matrix td,
.variables-matrix th {
padding: 10px;
padding:10px;
}
.variables-matrix td {
border-top: 1px solid #eee;
border-top:1px solid #eee;
}
.variables-matrix td + td,
.variables-matrix th + th {
border-left: 1px solid #eee;
border-left:1px solid #eee;
}
.variables-matrix tr:nth-child(even) td {
background: #f5f5f5;
background:#f5f5f5;
}
.variables-matrix th {
background: #f1f1f1;
background:#f1f1f1;
}
.sup-header {
padding-top: 10px;
padding-bottom: 5px;
background: rgba(245,245,245,0.88);
box-shadow: 0 0 2px #999;
padding-top:10px;
padding-bottom:5px;
background:rgba(245,245,245,0.88);
box-shadow:0 0 2px #999;
}
.main-body-grid {
margin-top: 120px;
position: relative;
margin-top:120px;
position:relative;
}
.main-body-grid > .grid-left,
.main-body-grid > .grid-right {
padding: 20px 0;
padding:20px 0;
}
.main-body-grid > .grid-left {
position: fixed;
top: 120px;
bottom: 0;
overflow: auto;
position:fixed;
top:120px;
bottom:0;
overflow:auto;
}
.main-header-grid > .grid-left,
.main-body-grid > .grid-left {
width: 260px;
width:260px;
}
.main-header-grid > .grid-right,
.main-body-grid > .grid-right {
margin-left: 270px;
position: relative;
margin-left:270px;
position:relative;
}
.main-header-grid > .grid-left {
float: left;
float:left;
}
.main-body-grid .side-navigation {
position: relative;
padding-bottom: 120px;
position:relative;
padding-bottom:120px;
}
.main-body-grid .side-navigation.ng-hide {
display: block!important;
display:block!important;
}
.variables-matrix td {
vertical-align: top;
padding: 5px;
vertical-align:top;
padding:5px;
}
.type-hint {
display: inline-block;
display:inline-block;
background: gray;
}
.variables-matrix .type-hint {
text-align: center;
min-width: 60px;
margin: 1px 5px;
text-align:center;
min-width:60px;
margin:1px 5px;
}
.type-hint + .type-hint {
margin-top: 5px;
margin-top:5px;
}
.type-hint-expression {
background: purple;
background:purple;
}
.type-hint-date {
background: pink;
background:pink;
}
.type-hint-string {
background: #3a87ad;
background:#3a87ad;
}
.type-hint-function {
background: green;
background:green;
}
.type-hint-object {
background: #999;
background:#999;
}
.type-hint-array {
background: #F90;;
background:#F90;;
}
.type-hint-boolean {
background: rgb(18, 131, 39);
background:rgb(18, 131, 39);
}
.type-hint-number {
background: rgb(189, 63, 66);
background:rgb(189, 63, 66);
}
.type-hint-regexp {
@@ -544,19 +535,19 @@ iframe.example {
}
.runnable-example-frame {
width: 100%;
height: 300px;
width:100%;
height:300px;
border: 1px solid #ddd;
border-radius: 5px;
border-radius:5px;
}
.runnable-example-tabs {
margin-top: 10px;
margin-bottom: 20px;
margin-top:10px;
margin-bottom:20px;
}
.tutorial-nav {
display: block;
display:block;
}
h1 + ul, h1 + ul > li,
@@ -565,23 +556,23 @@ ul.tutorial-nav, ul.tutorial-nav > li,
.usage > ul, .usage > ul > li,
ul.methods, ul.methods > li,
ul.events, ul.events > li {
list-style: none;
padding: 0;
list-style:none;
padding:0;
}
h2 {
border-top: 1px solid #eee;
margin-top: 30px;
padding-top: 30px;
border-top:1px solid #eee;
margin-top:30px;
padding-top:30px;
}
h4 {
margin-top: 20px;
padding-top: 20px;
margin-top:20px;
padding-top:20px;
}
.btn {
color: #428bca;
color:#428bca;
position: relative;
width: auto;
display: inline-block;
@@ -604,26 +595,26 @@ h4 {
}
.btn + .btn {
margin-left: 10px;
margin-left:10px;
}
.btn:hover, .btn:focus {
color: black !important;
border: 1px solid #ddd !important;
background: white !important;
color: black!important;
border: 1px solid #ddd!important;
background: white!important;
}
.view-source, .improve-docs {
position: relative;
z-index: 100;
position:relative;
z-index:100;
}
.view-source {
margin-right: 10px;
margin-right:10px;
}
.improve-docs {
float: right;
float:right;
}
.return-arguments,
@@ -631,17 +622,17 @@ h4 {
.return-arguments th + th,
.return-arguments td,
.return-arguments td + td {
border-radius: 0;
border: 0;
border-radius:0;
border:0;
}
.return-arguments td:first-child {
width: 100px;
width:100px;
}
ul.methods > li,
ul.events > li {
margin-bottom: 40px;
margin-bottom:40px;
}
.definition-table td {
@@ -656,28 +647,6 @@ ul.events > li {
padding-top: 50px;
}
.diagram {
margin-bottom: 10px;
margin-top: 30px;
max-width: 100%;
}
.deprecation {
margin-top: 15px;
}
.deprecation .title {
float: left;
margin-right: 5px;
}
@media only screen and (min-width: 769px) {
[ng-include="partialPath"].ng-hide {
display: block !important;
visibility: hidden;
}
}
@media only screen and (min-width: 769px) and (max-width: 991px) {
.main-body-grid {
margin-top: 160px;
@@ -689,66 +658,66 @@ ul.events > li {
@media only screen and (max-width : 768px) {
.picker, .picker select {
width: auto;
display: block;
margin-bottom: 10px;
width:auto;
display:block;
margin-bottom:10px;
}
.docs-navbar-primary {
text-align: center;
text-align:center;
}
.main-body-grid {
margin-top: 0;
margin-top:0;
}
.main-header-grid > .grid-left,
.main-body-grid > .grid-left,
.main-header-grid > .grid-right,
.main-body-grid > .grid-right {
display: block;
float: none;
width: auto !important;
margin-left: 0;
display:block;
float:none;
width:auto!important;
margin-left:0;
}
.main-body-grid > .grid-left,
.header-fixed, .footer {
position: static !important;
position:static!important;
}
.main-body-grid > .grid-left {
background: #efefef;
margin-left: -1em;
margin-right: -1em;
padding: 1em;
width: auto !important;
overflow: visible;
background:#efefef;
margin-left:-1em;
margin-right:-1em;
padding:1em;
width:auto!important;
overflow:visible;
}
.main-header-grid > .grid-right,
.main-body-grid > .grid-right {
margin-left: 0;
margin-left:0;
}
.main-body-grid .side-navigation {
display: block !important;
padding-bottom: 50px;
display:block!important;
padding-bottom:50px;
}
.main-body-grid .side-navigation.ng-hide {
display: none !important;
display:none!important;
}
.nav-index-group .nav-index-listing {
display: inline-block;
padding: 3px 0;
display:inline-block;
padding:3px 0;
}
.nav-index-group .nav-index-listing:not(.nav-index-section):after {
padding-right: 5px;
margin-left: -3px;
content: ", ";
padding-right:5px;
margin-left:-3px;
content:", ";
}
.nav-index-group .nav-index-listing:last-child:after {
content: "";
display: inline-block;
content:"";
display:inline-block;
}
.nav-index-group .nav-index-section {
display: block;
display:block;
}
.toc-toggle {
margin-bottom: 20px;
margin-bottom:20px;
}
.toc-close {
position: absolute;
@@ -760,16 +729,16 @@ ul.events > li {
background: #eee;
border-radius: 5px;
width: 100%;
border: 1px solid #ddd;
box-shadow: 0 0 10px #bbb;
border:1px solid #ddd;
box-shadow:0 0 10px #bbb;
}
.navbar-brand {
float: none;
text-align: center;
float:none;
text-align:center;
}
.search-results-container {
padding-bottom: 60px;
text-align: left;
padding-bottom:60px;
text-align:left;
}
.search-results-frame > .search-results-group:first-child > .search-results {
@@ -777,11 +746,11 @@ ul.events > li {
}
.search-results-group {
float: none !important;
display: block !important;
width: auto !important;
border: 0! important;
padding: 0! important;
float:none!important;
display:block!important;
width:auto!important;
border:0!important;
padding:0!important;
}
@supports ((column-count: 2) or (-moz-column-count: 2) or (-ms-column-count: 2) or (-webkit-column-count: 2)) {
@@ -794,15 +763,15 @@ ul.events > li {
}
.search-results-group .search-result {
display: inline-block !important;
padding: 0 5px;
width: auto !important;
display:inline-block!important;
padding:0 5px;
width:auto!important;
text-indent: initial;
margin-left: 0;
}
.search-results-group .search-result:after {
content: ", ";
content:", ";
}
.search-results-group .search-result:before {
@@ -820,10 +789,10 @@ ul.events > li {
}
#wrapper {
padding-bottom: 0px;
padding-bottom:0px;
}
}
iframe[name="example-anchoringExample"] {
height: 400px;
height:400px;
}
Regular → Executable
View File

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 212 B

+11 -12
View File
@@ -1,18 +1,17 @@
'use strict';
/* eslint-env worker */
/* global importScripts, lunr */
"use strict";
/* jshint browser: true */
/* global importScripts, onmessage: true, postMessage, lunr */
// Load up the lunr library
importScripts('../components/lunr-0.7.2/lunr.min.js');
importScripts('../components/lunr.js-0.5.12/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(/** @this */function() {
var index = lunr(function() {
this.ref('path');
this.field('titleWords', {boost: 50});
this.field('members', {boost: 40});
this.field('keywords', {boost: 20});
this.field('members', { boost: 40});
this.field('keywords', { boost : 20 });
});
// Retrieve the searchData which contains the information about each page to be indexed
@@ -26,13 +25,13 @@ searchDataRequest.onload = function() {
searchData.forEach(function(page) {
index.add(page);
});
self.postMessage({e: 'index-ready'});
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
self.onmessage = function(oEvent) {
onmessage = function(oEvent) {
var q = oEvent.data.q;
var hits = index.search(q);
var results = [];
@@ -41,5 +40,5 @@ self.onmessage = function(oEvent) {
results.push(hit.ref);
});
// The results of the query are sent back to the web app via a new message
self.postMessage({e: 'query-ready', q: q, d: results});
};
postMessage({ e: 'query-ready', q: q, d: results });
};
-28
View File
@@ -1,28 +0,0 @@
{
"root": true,
"extends": "../../../.eslintrc-node.json",
"env": {
"jasmine": true,
"protractor": true
},
"globals": {
/* 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
}
}
+45
View File
@@ -0,0 +1,45 @@
{
"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 */
"protractor": false,
"browser": false,
"element": false,
"by": false,
"$": false,
"$$": 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
}
}
+7 -7
View File
@@ -1,10 +1,10 @@
'use strict';
describe('doc.angularjs.org', function() {
describe("doc.angularjs.org", function() {
describe('API pages', function() {
describe("API pages", function() {
it('should display links to code on GitHub', function() {
it("should display links to code on GitHub", function() {
browser.get('build/docs/index.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/);
@@ -12,7 +12,7 @@ describe('doc.angularjs.org', function() {
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() {
it('should change the page content when clicking a link to a service', function () {
browser.get('build/docs/index.html');
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
@@ -23,7 +23,7 @@ describe('doc.angularjs.org', function() {
});
it('should show the functioning input directive example', function() {
it('should show the functioning input directive example', function () {
browser.get('build/docs/index.html#!/api/ng/directive/input');
// Ensure that the page is loaded before trying to switch frames.
@@ -38,7 +38,7 @@ describe('doc.angularjs.org', function() {
expect(code.getText()).toContain('guest!!!');
});
it('should trim indentation from code blocks', function() {
it("should trim indentation from code blocks", function() {
browser.get('build/docs/index.html#!/api/ng/type/$rootScope.Scope');
var codeBlocks = element.all(by.css('pre > code.lang-js'));
@@ -48,4 +48,4 @@ describe('doc.angularjs.org', function() {
});
});
});
});
});
@@ -1,12 +1,12 @@
'use strict';
describe('provider pages', function() {
describe("provider pages", function() {
it('should show the related service', function() {
it("should show the related service", function() {
browser.get('build/docs/index.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/);
});
});
});
@@ -1,8 +1,8 @@
'use strict';
describe('service pages', function() {
describe("service pages", function() {
it('should show the related provider if there is one', function() {
it("should show the related provider if there is one", function() {
browser.get('build/docs/index.html#!/api/ng/service/$compile');
var providerLink = element.all(by.css('ol.api-profile-header-structure li a')).first();
expect(providerLink.getText()).toEqual('- $compileProvider');
@@ -10,13 +10,13 @@ describe('service pages', function() {
browser.get('build/docs/index.html#!/api/ng/service/$q');
providerLink = element.all(by.css('ol.api-profile-header-structure li a')).first();
expect(providerLink.getText()).not.toEqual('- $compileProvider');
expect(providerLink.getText()).not.toEqual('- $qProvider');
expect(providerLink.getAttribute('href')).not.toMatch(/api\/ng\/provider\/\$compileProvider/);
});
it('should show parameter defaults', function() {
it("should show parameter defaults", function() {
browser.get('build/docs/index.html#!/api/ng/service/$timeout');
expect(element.all(by.css('.input-arguments p em')).first().getText()).toContain('(default: 0)');
});
});
});
+13 -13
View File
@@ -1,8 +1,8 @@
'use strict';
var webdriver = require('selenium-webdriver');
var webdriver = require('protractor/node_modules/selenium-webdriver');
describe('docs.angularjs.org', function() {
describe('docs.angularjs.org', function () {
beforeEach(function() {
// read and clear logs from previous tests
@@ -24,7 +24,7 @@ describe('docs.angularjs.org', function() {
});
describe('App', function() {
describe('App', function () {
// it('should filter the module list when searching', function () {
// browser.get();
// browser.waitForAngular();
@@ -38,8 +38,8 @@ describe('docs.angularjs.org', function() {
// });
it('should change the page content when clicking a link to a service', function() {
browser.get('build/docs/index-production.html');
it('should change the page content when clicking a link to a service', function () {
browser.get('build/docs/index.html');
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
ngBindLink.click();
@@ -51,36 +51,36 @@ describe('docs.angularjs.org', function() {
it('should be resilient to trailing slashes', function() {
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/');
browser.get('build/docs/index.html#!/api/ng/function/angular.noop/');
var pageBody = element(by.css('h1'));
expect(pageBody.getText()).toEqual('angular.noop');
});
it('should be resilient to trailing "index"', function() {
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/index');
browser.get('build/docs/index.html#!/api/ng/function/angular.noop/index');
var pageBody = element(by.css('h1'));
expect(pageBody.getText()).toEqual('angular.noop');
});
it('should be resilient to trailing "index/"', function() {
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/index/');
browser.get('build/docs/index.html#!/api/ng/function/angular.noop/index/');
var pageBody = element(by.css('h1'));
expect(pageBody.getText()).toEqual('angular.noop');
});
it('should display formatted error messages on error doc pages', function() {
browser.get('build/docs/index-production.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');
browser.get('build/docs/index.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");
});
it('should display an error if the page does not exist', function() {
browser.get('build/docs/index-production.html#!/api/does/not/exist');
it("should display an error if the page does not exist", function() {
browser.get('build/docs/index.html#!/api/does/not/exist');
expect(element(by.css('h1')).getText()).toBe('Oops!');
});
});
});
});
-8
View File
@@ -1,8 +0,0 @@
{
"root": true,
"extends": "../../../.eslintrc-browser.json",
"globals": {
"lunr": false
}
}
+1 -2
View File
@@ -1,11 +1,10 @@
'use strict';
angular.module('docsApp', [
'ngRoute',
'ngCookies',
'ngSanitize',
'ngAnimate',
'DocsController',
'versionsData',
'pagesData',
'navData',
'directives',
-2
View File
@@ -1,5 +1,3 @@
'use strict';
angular.module('directives', [])
/**
+11 -18
View File
@@ -1,12 +1,12 @@
'use strict';
angular.module('DocsController', ['currentVersionData'])
angular.module('DocsController', [])
.controller('DocsController', [
'$scope', '$rootScope', '$location', '$window', '$cookies',
'NG_PAGES', 'NG_NAVIGATION', 'CURRENT_NG_VERSION',
'NG_PAGES', 'NG_NAVIGATION', 'NG_VERSION',
function($scope, $rootScope, $location, $window, $cookies,
NG_PAGES, NG_NAVIGATION, CURRENT_NG_VERSION) {
NG_PAGES, NG_NAVIGATION, NG_VERSION) {
$scope.docsVersion = NG_VERSION.isSnapshot ? 'snapshot' : NG_VERSION.version;
$scope.navClass = function(navItem) {
return {
@@ -21,22 +21,15 @@ angular.module('DocsController', ['currentVersionData'])
$scope.$on('$includeContentLoaded', function() {
var pagePath = $scope.currentPage ? $scope.currentPage.path : $location.path();
$window._gaq.push(['_trackPageview', pagePath]);
$scope.loading = false;
});
$scope.$on('$includeContentError', function() {
$scope.loading = false;
});
$scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) {
path = path.replace(/^\/?(.+?)(\/index)?\/?$/, '$1');
var currentPage = $scope.currentPage = NG_PAGES[path];
currentPage = $scope.currentPage = NG_PAGES[path];
$scope.loading = true;
if (currentPage) {
if ( currentPage ) {
$scope.partialPath = 'partials/' + path + '.html';
$scope.currentArea = NG_NAVIGATION[currentPage.area];
var pathParts = currentPage.path.split('/');
@@ -44,7 +37,7 @@ angular.module('DocsController', ['currentVersionData'])
var breadcrumbPath = '';
angular.forEach(pathParts, function(part) {
breadcrumbPath += part;
breadcrumb.push({ name: (NG_PAGES[breadcrumbPath] && NG_PAGES[breadcrumbPath].name) || part, url: breadcrumbPath });
breadcrumb.push({ name: (NG_PAGES[breadcrumbPath]&&NG_PAGES[breadcrumbPath].name) || part, url: breadcrumbPath });
breadcrumbPath += '/';
});
} else {
@@ -58,12 +51,12 @@ angular.module('DocsController', ['currentVersionData'])
Initialize
***********************************/
$scope.versionNumber = CURRENT_NG_VERSION.full;
$scope.version = CURRENT_NG_VERSION.full + ' ' + CURRENT_NG_VERSION.codeName;
$scope.versionNumber = angular.version.full;
$scope.version = angular.version.full + " " + angular.version.codeName;
$scope.loading = 0;
var INDEX_PATH = /^(\/|\/index[^.]*.html)$/;
var INDEX_PATH = /^(\/|\/index[^\.]*.html)$/;
if (!$location.path() || INDEX_PATH.test($location.path())) {
$location.path('/api').replace();
}
+14 -16
View File
@@ -1,25 +1,23 @@
'use strict';
angular.module('errors', ['ngSanitize'])
.filter('errorLink', ['$sanitize', function($sanitize) {
var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/g,
.filter('errorLink', ['$sanitize', function ($sanitize) {
var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}<>]/g,
MAILTO_REGEXP = /^mailto:/,
STACK_TRACE_REGEXP = /:\d+:\d+$/;
var truncate = function(text, nchars) {
var truncate = function (text, nchars) {
if (text.length > nchars) {
return text.substr(0, nchars - 3) + '...';
}
return text;
};
return function(text, target) {
return function (text, target) {
if (!text) return text;
var targetHtml = target ? ' target="' + target + '"' : '';
return $sanitize(text.replace(LINKY_URL_REGEXP, function(url) {
return $sanitize(text.replace(LINKY_URL_REGEXP, function (url) {
if (STACK_TRACE_REGEXP.test(url)) {
return url;
}
@@ -27,7 +25,7 @@ angular.module('errors', ['ngSanitize'])
// if we did not match ftp/http/mailto then assume mailto
if (!/^((ftp|https?):\/\/|mailto:)/.test(url)) url = 'mailto:' + url;
return '<a' + targetHtml + ' href="' + url + '">' +
return '<a' + targetHtml + ' href="' + url +'">' +
truncate(url.replace(MAILTO_REGEXP, ''), 60) +
'</a>';
}));
@@ -35,33 +33,33 @@ angular.module('errors', ['ngSanitize'])
}])
.directive('errorDisplay', ['$location', 'errorLinkFilter', function($location, errorLinkFilter) {
var encodeAngleBrackets = function(text) {
.directive('errorDisplay', ['$location', 'errorLinkFilter', function ($location, errorLinkFilter) {
var encodeAngleBrackets = function (text) {
return text.replace(/</g, '&lt;').replace(/>/g, '&gt;');
};
var interpolate = function(formatString) {
var interpolate = function (formatString) {
var formatArgs = arguments;
return formatString.replace(/\{\d+\}/g, function(match) {
return formatString.replace(/\{\d+\}/g, function (match) {
// Drop the braces and use the unary plus to convert to an integer.
// The index will be off by one because of the formatString.
var index = +match.slice(1, -1);
if (index + 1 >= formatArgs.length) {
return match;
}
return formatArgs[index + 1];
return formatArgs[index+1];
});
};
return {
link: function(scope, element, attrs) {
link: function (scope, element, attrs) {
var search = $location.search(),
formatArgs = [attrs.errorDisplay],
formattedText,
i;
for (i = 0; angular.isDefined(search['p' + i]); i++) {
formatArgs.push(search['p' + i]);
for (i = 0; angular.isDefined(search['p'+i]); i++) {
formatArgs.push(search['p'+i]);
}
formattedText = encodeAngleBrackets(interpolate.apply(null, formatArgs));
+16 -18
View File
@@ -1,9 +1,8 @@
'use strict';
angular.module('examples', [])
.directive('runnableExample', [function() {
.directive('runnableExample', ['$templateCache', '$document', function($templateCache, $document) {
var exampleClassNameSelector = '.runnable-example-file';
var doc = $document[0];
var tpl =
'<nav class="runnable-example-tabs" ng-if="tabs">' +
' <a ng-class="{active:$index==activeTabIndex}"' +
@@ -30,12 +29,12 @@ angular.module('examples', [])
return function(scope, element) {
var node = element[0];
var examples = node.querySelectorAll(exampleClassNameSelector);
var tabs = [];
var tabs = [], now = Date.now();
angular.forEach(examples, function(child, index) {
tabs.push(child.getAttribute('name'));
});
if (tabs.length > 0) {
if(tabs.length > 0) {
scope.tabs = tabs;
scope.$on('tabChange', function(e, index, title) {
angular.forEach(examples, function(child) {
@@ -102,7 +101,7 @@ angular.module('examples', [])
},
controllerAs: 'plnkr',
template: '<button ng-click="plnkr.open($event)" class="btn pull-right"> <i class="glyphicon glyphicon-edit">&nbsp;</i> Edit in Plunker</button> ',
controller: [function PlnkrOpenerCtrl() {
controller: [function() {
var ctrl = this;
ctrl.example = {
@@ -114,7 +113,7 @@ angular.module('examples', [])
ctrl.prepareExampleData = function() {
if (ctrl.example.manifest) {
return $q.resolve(ctrl.example);
return $q.when(ctrl.example);
}
return getExampleData(ctrl.examplePath).then(function(data) {
@@ -138,8 +137,8 @@ angular.module('examples', [])
var newWindow = clickEvent.ctrlKey || clickEvent.metaKey;
var postData = {
'tags[0]': 'angularjs',
'tags[1]': 'example',
'tags[0]': "angularjs",
'tags[1]': "example",
'private': true
};
@@ -159,17 +158,16 @@ angular.module('examples', [])
};
ctrl.$onInit = function() {
// Initialize the example data, so it's ready when clicking the open button.
// Otherwise pop-up blockers will prevent a new window from opening
ctrl.prepareExampleData(ctrl.example.path);
};
// Initialize the example data, so it's ready when clicking the open button.
// Otherwise pop-up blockers will prevent a new window from opening
ctrl.prepareExampleData(ctrl.example.path);
}]
};
}])
.factory('getExampleData', ['$http', '$q', function($http, $q) {
return function(exampleFolder) {
return function(exampleFolder){
// Load the manifest for the example
return $http.get(exampleFolder + '/manifest.json')
.then(function(response) {
@@ -184,8 +182,8 @@ angular.module('examples', [])
// The manifests provide the production index file but Plunkr wants
// a straight index.html
if (filename === 'index-production.html') {
filename = 'index.html';
if (filename === "index-production.html") {
filename = "index.html";
}
return {
@@ -201,4 +199,4 @@ angular.module('examples', [])
});
});
};
}]);
}]);
+23 -25
View File
@@ -1,5 +1,3 @@
'use strict';
angular.module('search', [])
.controller('DocsSearchCtrl', ['$scope', '$location', 'docsSearch', function($scope, $location, docsSearch) {
@@ -11,7 +9,7 @@ angular.module('search', [])
$scope.search = function(q) {
var MIN_SEARCH_LENGTH = 2;
if (q.length >= MIN_SEARCH_LENGTH) {
if(q.length >= MIN_SEARCH_LENGTH) {
docsSearch(q).then(function(hits) {
// Make sure the areas are always in the same order
var results = {
@@ -25,24 +23,28 @@ angular.module('search', [])
angular.forEach(hits, function(hit) {
var area = hit.area;
var limit = (area === 'api') ? 40 : 14;
var limit = (area == 'api') ? 40 : 14;
results[area] = results[area] || [];
if (results[area].length < limit) {
if(results[area].length < limit) {
results[area].push(hit);
}
});
var totalAreas = Object.keys(results).length;
if (totalAreas > 0) {
var totalAreas = 0;
for(var i in results) {
++totalAreas;
}
if(totalAreas > 0) {
$scope.colClassName = 'cols-' + totalAreas;
}
$scope.hasResults = totalAreas > 0;
$scope.results = results;
});
} else {
}
else {
clearResults();
}
if (!$scope.$$phase) $scope.$apply();
if(!$scope.$$phase) $scope.$apply();
};
$scope.submit = function() {
@@ -50,14 +52,14 @@ angular.module('search', [])
if ($scope.results.api) {
result = $scope.results.api[0];
} else {
for (var i in $scope.results) {
for(var i in $scope.results) {
result = $scope.results[i][0];
if (result) {
if(result) {
break;
}
}
}
if (result) {
if(result) {
$location.path(result.path);
$scope.hideResults();
}
@@ -72,7 +74,7 @@ angular.module('search', [])
.controller('Error404SearchCtrl', ['$scope', '$location', 'docsSearch',
function($scope, $location, docsSearch) {
docsSearch($location.path().split(/[/.:]/).pop()).then(function(results) {
docsSearch($location.path().split(/[\/\.:]/).pop()).then(function(results) {
$scope.results = {};
angular.forEach(results, function(result) {
var area = $scope.results[result.area] || [];
@@ -90,12 +92,10 @@ angular.module('search', [])
// It should only be used where the browser does not support WebWorkers
function localSearchFactory($http, $timeout, NG_PAGES) {
if (window.console && window.console.log) {
window.console.log('Using Local Search Index');
}
console.log('Using Local Search Index');
// Create the lunr index
var index = lunr(/** @this */ function() {
var index = lunr(function() {
this.ref('path');
this.field('titleWords', {boost: 50});
this.field('members', { boost: 40});
@@ -136,14 +136,12 @@ angular.module('search', [])
// It should only be used where the browser does support WebWorkers
function webWorkerSearchFactory($q, $rootScope, NG_PAGES) {
if (window.console && window.console.log) {
window.console.log('Using WebWorker Search Index');
}
console.log('Using WebWorker Search Index')
var searchIndex = $q.defer();
var results;
var worker = new window.Worker('js/search-worker.js');
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
@@ -151,7 +149,7 @@ angular.module('search', [])
worker.onmessage = function(oEvent) {
$rootScope.$apply(function() {
switch (oEvent.data.e) {
switch(oEvent.data.e) {
case 'index-ready':
searchIndex.resolve();
break;
@@ -202,13 +200,13 @@ angular.module('search', [])
};
})
.directive('docsSearchInput', ['$document', function($document) {
.directive('docsSearchInput', ['$document',function($document) {
return function(scope, element, attrs) {
var ESCAPE_KEY_KEYCODE = 27,
FORWARD_SLASH_KEYCODE = 191;
angular.element($document[0].body).on('keydown', function(event) {
var input = element[0];
if (event.keyCode === FORWARD_SLASH_KEYCODE && $document[0].activeElement !== input) {
if(event.keyCode == FORWARD_SLASH_KEYCODE && document.activeElement != input) {
event.stopPropagation();
event.preventDefault();
input.focus();
@@ -216,7 +214,7 @@ angular.module('search', [])
});
element.on('keydown', function(event) {
if (event.keyCode === ESCAPE_KEY_KEYCODE) {
if(event.keyCode == ESCAPE_KEY_KEYCODE) {
event.stopPropagation();
event.preventDefault();
scope.$apply(function() {
+5 -8
View File
@@ -1,5 +1,3 @@
'use strict';
angular.module('tutorials', [])
.directive('docTutorialNav', function() {
@@ -7,8 +5,7 @@ angular.module('tutorials', [])
'',
'step_00', 'step_01', 'step_02', 'step_03', 'step_04',
'step_05', 'step_06', 'step_07', 'step_08', 'step_09',
'step_10', 'step_11', 'step_12', 'step_13', 'step_14',
'the_end'
'step_10', 'step_11', 'step_12', 'the_end'
];
return {
scope: {},
@@ -22,7 +19,7 @@ angular.module('tutorials', [])
scope.seq = seq;
scope.prev = pages[seq];
scope.next = pages[2 + seq];
scope.diffLo = seq ? (seq - 1) : '0~1';
scope.diffLo = seq ? (seq - 1): '0~1';
scope.diffHi = seq;
element.addClass('btn-group');
@@ -42,11 +39,11 @@ angular.module('tutorials', [])
'<div class="alert alert-info" ng-show="show">\n' +
' <p>Reset the workspace to step {{step}}.</p>' +
' <p><pre>git checkout -f step-{{step}}</pre></p>\n' +
' <p>Refresh your browser or check out this step online: ' +
' <p>Refresh your browser or check out this step online: '+
'<a href="http://angular.github.io/angular-phonecat/step-{{step}}/app">Step {{step}} Live Demo</a>.</p>\n' +
'</div>\n' +
'<p>The most important changes are listed below. You can see the full diff on ' +
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{step ? (step - 1): \'0~1\'}}...step-{{step}}" title="See diff on Github">GitHub</a>.\n' +
'<a ng-href="https://github.com/angular/angular-phonecat/compare/step-{{step ? (step - 1): \'0~1\'}}...step-{{step}}" title="See diff on Github">GitHub</a>\n' +
'</p>'
};
});
});
+26 -35
View File
@@ -1,42 +1,33 @@
'use strict';
/* global console */
"use strict";
angular.module('versions', ['currentVersionData', 'allVersionsData'])
angular.module('versions', [])
.directive('versionPicker', function() {
return {
restrict: 'E',
scope: true,
controllerAs: '$ctrl',
controller: ['$location', '$window', 'CURRENT_NG_VERSION', 'ALL_NG_VERSIONS',
/** @this VersionPickerController */
function VersionPickerController($location, $window, CURRENT_NG_VERSION, ALL_NG_VERSIONS) {
.controller('DocsVersionsCtrl', ['$scope', '$location', '$window', 'NG_VERSIONS', function($scope, $location, $window, NG_VERSIONS) {
$scope.docs_version = NG_VERSIONS[0];
$scope.docs_versions = NG_VERSIONS;
var versionStr = CURRENT_NG_VERSION.isSnapshot ? 'snapshot' : CURRENT_NG_VERSION.version;
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;
}
this.versions = ALL_NG_VERSIONS;
this.selectedVersion = find(ALL_NG_VERSIONS, function(value) { return value.version.version === versionStr; });
this.jumpToDocsVersion = function(value) {
var currentPagePath = $location.path().replace(/\/$/, '');
$window.location = value.docsUrl + currentPagePath;
};
}],
template:
'<div class="picker version-picker">' +
' <select ng-options="v as v.label group by v.group for v in $ctrl.versions"' +
' ng-model="$ctrl.selectedVersion"' +
' ng-change="$ctrl.jumpToDocsVersion($ctrl.selectedVersion)"' +
' class="docs-version-jump">' +
' </select>' +
'</div>'
$scope.getGroupName = function(v) {
return v.isLatest ? 'Latest' : ('v' + v.major + '.' + v.minor + '.x');
};
function find(collection, matcherFn) {
for (var i = 0, ii = collection.length; i < ii; ++i) {
if (matcherFn(collection[i])) {
return collection[i];
}
$scope.jumpToDocsVersion = function(version) {
var currentPagePath = $location.path().replace(/\/$/, ''),
url = '';
if (version.isOldDocsUrl) {
url = version.docsUrl;
}else{
url = version.docsUrl + currentPagePath;
}
}
});
$window.location = url;
};
}]);
-23
View File
@@ -1,23 +0,0 @@
{
"root": true,
"extends": "../../../.eslintrc-browser.json",
"env": {
"jasmine": true
},
"rules": {
// Some rules are not that important in tests and conflict with
// Jasmine or would make it easier to write some tests; we disable
// those ones here.
"no-invalid-this": "off",
"no-throw-literal": "off",
"no-unused-vars": "off"
},
"globals": {
// ngMocks
"module": false,
"inject": true
}
}
+25
View File
@@ -0,0 +1,25 @@
{
"extends": "../../../.jshintrc-base",
"browser": true,
"globals": {
// AngularJS
"angular": false,
// ngMocks
"module": false,
"inject": true,
// Jasmine
"jasmine": false,
"describe": false,
"ddescribe": false,
"xdescribe": false,
"it": false,
"iit": false,
"xit": false,
"beforeEach": false,
"afterEach": false,
"spyOn": false,
"expect": false
}
}
+1 -3
View File
@@ -1,6 +1,4 @@
'use strict';
describe('code', function() {
describe("code", function() {
var prettyPrintOne, oldPP;
var compile, scope;
+5 -12
View File
@@ -1,18 +1,11 @@
'use strict';
describe('DocsController', function() {
describe("DocsController", function() {
var $scope;
angular.module('fake', [])
.value('$cookies', {})
.value('NG_PAGES', {})
.value('NG_NAVIGATION', {});
angular.module('currentVersionData', [])
.value('CURRENT_NG_VERSION', {});
angular.module('allVersionsData', [])
.value('ALL_NG_VERSIONS', {});
.value('NG_NAVIGATION', {})
.value('NG_VERSION', {});
beforeEach(module('fake', 'DocsController'));
beforeEach(inject(function($rootScope, $controller) {
@@ -22,7 +15,7 @@ describe('DocsController', function() {
describe('afterPartialLoaded', function() {
it('should update the Google Analytics with currentPage path if currentPage exists', inject(function($window) {
it("should update the Google Analytics with currentPage path if currentPage exists", inject(function($window) {
$window._gaq = [];
$scope.currentPage = { path: 'a/b/c' };
$scope.$broadcast('$includeContentLoaded');
@@ -30,7 +23,7 @@ describe('DocsController', function() {
}));
it('should update the Google Analytics with $location.path if currentPage is missing', inject(function($window, $location) {
it("should update the Google Analytics with $location.path if currentPage is missing", inject(function($window, $location) {
$window._gaq = [];
spyOn($location, 'path').and.returnValue('x/y/z');
$scope.$broadcast('$includeContentLoaded');
+2 -2
View File
@@ -135,7 +135,7 @@ describe('errors', function() {
}));
it('should set the element\'s HTML', function() {
it('should set the element\s HTML', function() {
var elem = $compile('<span error-display="bar">foo</span>')($rootScope);
expect(elem.html()).toBe('bar');
});
@@ -152,7 +152,7 @@ describe('errors', function() {
it('should pass the interpolated text through `errorLinkFilter`', function() {
$location.search = jasmine.createSpy('search').and.returnValue({p0: 'foo'});
$compile('<span error-display="foo = {0}"></span>')($rootScope);
var elem = $compile('<span error-display="foo = {0}"></span>')($rootScope);
expect(errorLinkFilter).toHaveBeenCalledTimes(1);
expect(errorLinkFilter).toHaveBeenCalledWith('foo = foo', '_blank');
});
+10
View File
@@ -0,0 +1,10 @@
{
"name": "AngularJS-docs-app",
"dependencies": {
"jquery": "2.1.1",
"lunr.js": "0.5.12",
"open-sans-fontface": "1.0.4",
"google-code-prettify": "1.0.1",
"bootstrap": "3.1.1"
}
}
+6 -13
View File
@@ -1,4 +1,4 @@
'use strict';
"use strict";
var path = require('canonical-path');
var packagePath = __dirname;
@@ -6,7 +6,7 @@ var packagePath = __dirname;
var Package = require('dgeni').Package;
// Create and export a new Dgeni package called angularjs. This package depends upon
// the ngdoc, nunjucks, and examples packages defined in the dgeni-packages node module.
// 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'),
@@ -52,12 +52,9 @@ module.exports = new Package('angularjs', [
.config(function(parseTagsProcessor) {
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/deprecated')); // this will override the jsdoc version
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/tutorial-step'));
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/sortOrder'));
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/installation'));
parseTagsProcessor.tagDefinitions.push(require('./tag-defs/this'));
})
@@ -67,11 +64,7 @@ module.exports = new Package('angularjs', [
.config(function(templateFinder, renderDocsProcessor, gitData) {
// We are completely overwriting the folders
templateFinder.templateFolders.length = 0;
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates/examples'));
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates/ngdoc'));
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates/app'));
templateFinder.templateFolders.unshift(path.resolve(packagePath, 'templates'));
renderDocsProcessor.extraData.git = gitData;
})
@@ -94,7 +87,7 @@ module.exports = new Package('angularjs', [
docTypes: ['overview', 'tutorial'],
getPath: function(doc) {
var docPath = path.dirname(doc.fileInfo.relativePath);
if (doc.fileInfo.baseName !== 'index') {
if ( doc.fileInfo.baseName !== 'index' ) {
docPath = path.join(docPath, doc.fileInfo.baseName);
}
return docPath;
@@ -115,12 +108,12 @@ module.exports = new Package('angularjs', [
});
computePathsProcessor.pathTemplates.push({
docTypes: ['module'],
docTypes: ['module' ],
pathTemplate: '${area}/${name}',
outputPathTemplate: 'partials/${area}/${name}.html'
});
computePathsProcessor.pathTemplates.push({
docTypes: ['componentGroup'],
docTypes: ['componentGroup' ],
pathTemplate: '${area}/${moduleName}/${groupType}',
outputPathTemplate: 'partials/${area}/${moduleName}/${groupType}.html'
});
+3 -4
View File
@@ -1,6 +1,5 @@
'use strict';
"use strict";
// eslint-disable-next-line new-cap
var encoder = new require('node-html-encoder').Encoder();
/**
@@ -12,7 +11,7 @@ module.exports = function typeInlineTagDef(getTypeClass) {
return {
name: 'type',
handler: function(doc, tagName, tagDescription) {
return '<a href="" class="' + getTypeClass(tagDescription) + '">' + encoder.htmlEncode(tagDescription) + '</a>';
return '<a href="" class="' + getTypeClass(tagDescription) + '">'+encoder.htmlEncode(tagDescription) + '</a>';
}
};
};
};
+7 -4
View File
@@ -1,4 +1,7 @@
'use strict';
"use strict";
var _ = require('lodash');
var path = require('canonical-path');
/**
* @dgProcessor errorDocsProcessor
@@ -15,7 +18,7 @@ module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
docs.forEach(function(doc) {
var parts, namespaceDoc;
if (doc.docType === 'error') {
if ( doc.docType === 'error' ) {
// Parse out the error info from the id
parts = doc.name.split(':');
@@ -24,7 +27,7 @@ module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
// Get or create the relevant errorNamespace doc
namespaceDoc = errorNamespaceMap.get(doc.namespace);
if (!namespaceDoc) {
if ( !namespaceDoc ) {
namespaceDoc = {
area: 'error',
name: doc.namespace,
@@ -46,4 +49,4 @@ module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
});
}
};
};
};
+4 -3
View File
@@ -1,6 +1,7 @@
'use strict';
"use strict";
var _ = require('lodash');
var path = require('canonical-path');
/**
* @dgProcessor generateIndexPagesProcessor
@@ -20,7 +21,7 @@ module.exports = function generateIndexPagesProcessor() {
// Collect up all the areas in the docs
var areas = {};
docs.forEach(function(doc) {
if (doc.area) {
if ( doc.area ) {
areas[doc.area] = doc.area;
}
});
@@ -39,4 +40,4 @@ module.exports = function generateIndexPagesProcessor() {
});
}
};
};
};
+10 -10
View File
@@ -1,4 +1,4 @@
'use strict';
"use strict";
var _ = require('lodash');
var fs = require('fs');
@@ -34,10 +34,10 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
var areasToSearch;
// Keywords start with "ng:" or one of $, _ or a letter
var KEYWORD_REGEX = /^((ng:|[$_a-z])[\w\-_]+)/;
var KEYWORD_REGEX = /^((ng:|[\$_a-z])[\w\-_]+)/;
// Load up the keywords to ignore, if specified in the config
if (this.ignoreWordsFile) {
if ( this.ignoreWordsFile ) {
var ignoreWordsPath = path.resolve(readFilesProcessor.basePath, this.ignoreWordsFile);
wordsToIgnore = fs.readFileSync(ignoreWordsPath, 'utf8').toString().split(/[,\s\n\r]+/gm);
@@ -59,7 +59,7 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
// without the ng to the title text, e.g. "controller".
function extractTitleWords(title) {
var match = /ng([A-Z]\w*)/.exec(title);
if (match) {
if ( match ) {
title = title + ' ' + match[1].toLowerCase();
}
return title;
@@ -67,12 +67,12 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
function extractWords(text, words, keywordMap) {
var tokens = text.toLowerCase().split(/[.\s,`'"#]+/mg);
_.forEach(tokens, function(token) {
var tokens = text.toLowerCase().split(/[\.\s,`'"#]+/mg);
_.forEach(tokens, function(token){
var match = token.match(KEYWORD_REGEX);
if (match) {
if (match){
var key = match[1];
if (!keywordMap[key]) {
if ( !keywordMap[key]) {
keywordMap[key] = true;
words.push(key);
}
@@ -96,11 +96,11 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
// Search each top level property of the document for search terms
_.forEach(doc, function(value, key) {
if (_.isString(value) && !propertiesToIgnore[key]) {
if ( _.isString(value) && !propertiesToIgnore[key] ) {
extractWords(value, words, keywordMap);
}
if (key === 'methods' || key === 'properties' || key === 'events') {
if ( key === 'methods' || key === 'properties' || key === 'events' ) {
_.forEach(value, function(member) {
extractWords(member.name, members, membersMap);
});
+4 -4
View File
@@ -1,4 +1,4 @@
'use strict';
"use strict";
var _ = require('lodash');
var path = require('canonical-path');
@@ -67,7 +67,7 @@ module.exports = function generatePagesDataProcessor(log) {
})
.tap(function(docTypes) {
if (docTypes.input) {
if ( docTypes.input ) {
docTypes.directive = docTypes.directive || [];
// Combine input docTypes into directive docTypes
docTypes.directive = docTypes.directive.concat(docTypes.input);
@@ -79,7 +79,7 @@ module.exports = function generatePagesDataProcessor(log) {
sectionPages = _.sortBy(sectionPages, 'name');
if (sectionPages.length > 0) {
if ( sectionPages.length > 0 ) {
// Push a navItem for this section
navItems.push({
name: sectionName,
@@ -158,7 +158,7 @@ module.exports = function generatePagesDataProcessor(log) {
// We are only interested in pages that are not landing pages
var navPages = _.filter(pages, function(page) {
return page.docType !== 'componentGroup';
return page.docType != 'componentGroup';
});
// Generate an object collection of pages that is grouped by area e.g.
+16 -90
View File
@@ -1,7 +1,6 @@
'use strict';
"use strict";
var exec = require('shelljs').exec;
var semver = require('semver');
var _ = require('lodash');
/**
* @dgProcessor generateVersionDocProcessor
@@ -13,96 +12,23 @@ module.exports = function generateVersionDocProcessor(gitData) {
return {
$runAfter: ['generatePagesDataProcessor'],
$runBefore: ['rendering-docs'],
// the blacklist is to remove rogue builds that are in the npm repository but not on code.angularjs.org
blacklist: ['1.3.4-build.3588'],
$process: function(docs) {
var blacklist = this.blacklist;
var currentVersion = require('../../../build/version.json');
var output = exec('yarn info angular versions --json', { silent: true }).stdout.split('\n')[0];
var allVersions = processAllVersionsResponse(JSON.parse(output).data);
var versionDoc = {
docType: 'versions-data',
id: 'versions-data',
template: 'versions-data.template.js',
outputPath: 'js/versions-data.js',
currentVersion: gitData.version
};
docs.push({
docType: 'current-version-data',
id: 'current-version-data',
template: 'angular-service.template.js',
outputPath: 'js/current-version-data.js',
ngModuleName: 'currentVersionData',
serviceName: 'CURRENT_NG_VERSION',
serviceValue: currentVersion
});
versionDoc.versions = _(gitData.versions)
.filter(function(version) { return version.major > 0; })
.push(gitData.version)
.reverse()
.value();
docs.push({
docType: 'allversions-data',
id: 'allversions-data',
template: 'angular-service.template.js',
outputPath: 'js/all-versions-data.js',
ngModuleName: 'allVersionsData',
serviceName: 'ALL_NG_VERSIONS',
serviceValue: allVersions
});
function processAllVersionsResponse(versions) {
var latestMap = {};
versions = versions
.filter(function(versionStr) {
return blacklist.indexOf(versionStr) === -1;
})
.map(function(versionStr) {
return semver.parse(versionStr);
})
.filter(function(version) {
return version && version.major > 0;
})
.map(function(version) {
var key = version.major + '.' + version.minor;
var latest = latestMap[key];
if (!latest || version.compare(latest) > 0) {
latestMap[key] = version;
}
return version;
})
.map(function(version) {
return makeOption(version);
})
.reverse();
var latest = sortObject(latestMap, reverse(semver.compare))
.map(function(version) { return makeOption(version, 'Latest'); });
return [makeOption({version: 'snapshot'}, 'Latest', 'master')]
.concat(latest)
.concat(versions);
}
function makeOption(version, group, label) {
return {
version: version,
label: label || 'v' + version.raw,
group: group || 'v' + version.major + '.' + version.minor,
docsUrl: createDocsUrl(version)
};
}
function createDocsUrl(version) {
var url = 'https://code.angularjs.org/' + version.version + '/docs';
// Versions before 1.0.2 had a different docs folder name
if (version.major === 1 && version.minor === 0 && version.patch < 2) {
url += '-' + version.version;
}
return url;
}
function reverse(fn) {
return function(left, right) { return -fn(left, right); };
}
function sortObject(obj, cmp) {
return Object.keys(obj).map(function(key) { return obj[key]; }).sort(cmp);
}
docs.push(versionDoc);
}
};
};
};
+6 -7
View File
@@ -1,11 +1,11 @@
'use strict';
"use strict";
module.exports = function debugDeployment(getVersion) {
return {
name: 'debug',
examples: {
commonFiles: {
scripts: ['../../../angular.js']
scripts: [ '../../../angular.js' ]
},
dependencyPath: '../../../'
},
@@ -17,13 +17,12 @@ module.exports = function debugDeployment(getVersion) {
'../angular-sanitize.js',
'../angular-touch.js',
'../angular-animate.js',
'components/marked-' + getVersion('marked') + '/lib/marked.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'js/angular-bootstrap/dropdown-toggle.js',
'components/lunr-' + getVersion('lunr') + '/lunr.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/current-version-data.js',
'js/all-versions-data.js',
'js/versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/docs.js'
@@ -36,4 +35,4 @@ module.exports = function debugDeployment(getVersion) {
'css/animations.css'
]
};
};
};
+6 -7
View File
@@ -1,11 +1,11 @@
'use strict';
"use strict";
module.exports = function defaultDeployment(getVersion) {
return {
name: 'default',
examples: {
commonFiles: {
scripts: ['../../../angular.min.js']
scripts: [ '../../../angular.min.js' ]
},
dependencyPath: '../../../'
},
@@ -17,13 +17,12 @@ module.exports = function defaultDeployment(getVersion) {
'../angular-sanitize.min.js',
'../angular-touch.min.js',
'../angular-animate.min.js',
'components/marked-' + getVersion('marked') + '/lib/marked.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'js/angular-bootstrap/dropdown-toggle.min.js',
'components/lunr-' + getVersion('lunr') + '/lunr.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/current-version-data.js',
'js/all-versions-data.js',
'js/versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/docs.min.js'
@@ -36,4 +35,4 @@ module.exports = function defaultDeployment(getVersion) {
'css/animations.css'
]
};
};
};
+5 -6
View File
@@ -1,4 +1,4 @@
'use strict';
"use strict";
module.exports = function jqueryDeployment(getVersion) {
return {
@@ -21,13 +21,12 @@ module.exports = function jqueryDeployment(getVersion) {
'../angular-sanitize.min.js',
'../angular-touch.min.js',
'../angular-animate.min.js',
'components/marked-' + getVersion('marked') + '/lib/marked.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'js/angular-bootstrap/dropdown-toggle.min.js',
'components/lunr-' + getVersion('lunr') + '/lunr.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/current-version-data.js',
'js/all-versions-data.js',
'js/versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/docs.min.js'
@@ -40,4 +39,4 @@ module.exports = function jqueryDeployment(getVersion) {
'css/animations.css'
]
};
};
};
+8 -23
View File
@@ -1,30 +1,16 @@
'use strict';
"use strict";
var versionInfo = require('../../../../lib/versions/version-info');
var googleCdnUrl = '//ajax.googleapis.com/ajax/libs/angularjs/';
var angularCodeUrl = '//code.angularjs.org/';
var cdnUrl = googleCdnUrl + versionInfo.cdnVersion;
// The plnkr examples must use the code.angularjs.org repo for the snapshot,
// and the cdn for the tagged version and, if the build is not tagged, the currentVersion.
//
// The currentVersion may not be available on the cdn (e.g. if built locally, or hasn't been pushed
// yet). This will lead to a 404, but this is preferable to loading a version with which the example
// might not work (possibly in subtle ways).
var examplesCdnUrl = versionInfo.currentVersion.isSnapshot ?
(angularCodeUrl + 'snapshot') :
(googleCdnUrl + (versionInfo.currentVersion.version || versionInfo.currentVersion));
var cdnUrl = "//ajax.googleapis.com/ajax/libs/angularjs/" + versionInfo.cdnVersion;
module.exports = function productionDeployment(getVersion) {
return {
name: 'production',
examples: {
commonFiles: {
scripts: [examplesCdnUrl + '/angular.min.js']
scripts: [ cdnUrl + '/angular.min.js' ]
},
dependencyPath: examplesCdnUrl + '/'
dependencyPath: cdnUrl + '/'
},
scripts: [
cdnUrl + '/angular.min.js',
@@ -34,13 +20,12 @@ module.exports = function productionDeployment(getVersion) {
cdnUrl + '/angular-sanitize.min.js',
cdnUrl + '/angular-touch.min.js',
cdnUrl + '/angular-animate.min.js',
'components/marked-' + getVersion('marked') + '/lib/marked.js',
'components/marked-' + getVersion('marked', 'node_modules', 'package.json') + '/lib/marked.js',
'js/angular-bootstrap/dropdown-toggle.min.js',
'components/lunr-' + getVersion('lunr') + '/lunr.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/current-version-data.js',
'https://code.angularjs.org/snapshot/docs/js/all-versions-data.js',
'js/versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/docs.min.js'
@@ -53,4 +38,4 @@ module.exports = function productionDeployment(getVersion) {
'css/animations.css'
]
};
};
};
+2 -2
View File
@@ -1,4 +1,4 @@
'use strict';
"use strict";
var StringMap = require('stringmap');
/**
@@ -7,4 +7,4 @@ var StringMap = require('stringmap');
*/
module.exports = function errorNamespaceMap() {
return new StringMap();
};
};
+1 -1
View File
@@ -1,4 +1,4 @@
'use strict';
"use strict";
var path = require('canonical-path');
+5 -5
View File
@@ -1,17 +1,17 @@
'use strict';
"use strict";
var path = require('canonical-path');
/**
* dgService getVersion
* @description
* Find the current version of the bower component (or node module)
* 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 || 'node_modules');
packageFile = packageFile || 'package.json';
sourceFolder = path.resolve(basePath, sourceFolder || 'docs/bower_components');
packageFile = packageFile || 'bower.json';
return require(path.join(sourceFolder,component,packageFile)).version;
};
};
};
-42
View File
@@ -1,42 +0,0 @@
'use strict';
var OPTION_MATCHER = /^\s*([\w-]+)="([^"]+)"\s+([\s\S]*)/;
var VALID_OPTIONS = ['sinceVersion', 'removeVersion'];
module.exports = {
name: 'deprecated',
transforms: function(doc, tag, value) {
var result = {};
var invalidOptions = [];
value = value.trim();
while (OPTION_MATCHER.test(value)) {
value = value.replace(OPTION_MATCHER, function(_, key, value, rest) {
if (VALID_OPTIONS.indexOf(key) !== -1) {
result[key] = value;
} else {
invalidOptions.push(key);
}
return rest;
});
}
if (invalidOptions.length > 0) {
throw new Error('Invalid options: ' + humanList(invalidOptions) + '. Value options are: ' + humanList(VALID_OPTIONS));
}
result.description = value;
return result;
}
};
function humanList(values, sep, lastSep) {
if (sep === undefined) sep = ', ';
if (lastSep === undefined) lastSep = ' and ';
return values.reduce(function(output, value, index, list) {
output += '"' + value + '"';
switch (list.length - index) {
case 1: return output;
case 2: return output + lastSep;
default: return output + sep;
}
}, '');
}
-33
View File
@@ -1,33 +0,0 @@
'use strict';
/* globals describe, it, expect */
var tagDef = require('./deprecated');
describe('deprecated tag', function() {
describe('transforms', function() {
it('should return the trimmed value if no options', function() {
var tag = tagDef.transforms({}, {}, 'This is the description');
expect(tag.description).toEqual('This is the description');
});
it('should read options', function() {
var tag = tagDef.transforms({}, {}, ' sinceVersion="v1.3.4" removeVersion="v1.4.5" what is left is description');
expect(tag.description).toEqual('what is left is description');
expect(tag.sinceVersion).toEqual('v1.3.4');
expect(tag.removeVersion).toEqual('v1.4.5');
});
it('should cope with carriage returns', function() {
var tag = tagDef.transforms({}, {}, '\nsinceVersion="v1.3.4"\nremoveVersion="v1.4.5"\nwhat is left is description');
expect(tag.description).toEqual('what is left is description');
expect(tag.sinceVersion).toEqual('v1.3.4');
expect(tag.removeVersion).toEqual('v1.4.5');
});
it('should error if there is an invalid option', function() {
expect(function() {
tagDef.transforms({}, {}, ' fromVersion="v1.3.4" toVersion="v1.4.5" what is left is description');
}).toThrowError('Invalid options: "fromVersion" and "toVersion". Value options are: "sinceVersion" and "removeVersion"');
});
});
});
+1 -3
View File
@@ -1,5 +1,3 @@
'use strict';
module.exports = {
name: 'installation'
};
};
+1 -3
View File
@@ -1,8 +1,6 @@
'use strict';
module.exports = {
name: 'sortOrder',
transforms: function(doc, tag, value) {
return parseInt(value, 10);
}
};
};
-5
View File
@@ -1,5 +0,0 @@
'use strict';
module.exports = {
name: 'this'
};
+1 -3
View File
@@ -1,9 +1,7 @@
'use strict';
module.exports = {
name: 'step',
transforms: function(doc, tag, value) {
if (doc.docType !== 'tutorial') {
if ( doc.docType !== 'tutorial' ) {
throw new Error('Invalid tag, step. You should only use this tag on tutorial docs');
}
return parseInt(value,10);

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