Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: SjB/angular.js
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: angular/angular.js
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref

Commits on Jun 20, 2012

  1. fix($location): url rewriting if element was removed

    When user clicks a link, $location needs to intercept this event.  The <a> doesn't have to be target element of the DOM event, so it needs to traverse the DOM, to find first <a> parent.
    
    If the target element was removed from DOM, during the same event, it would throw an exception. This fixes the issue.
    
    Closes angular#1058
    vojtajina committed Jun 20, 2012
    Copy the full SHA
    3da4194 View commit details

Commits on Jun 21, 2012

  1. Copy the full SHA
    1e6d4d5 View commit details
  2. chore(logos): fix shield logo exports

    the previous version is clipped at the top
    IgorMinar committed Jun 21, 2012
    Copy the full SHA
    869143e View commit details
  3. Copy the full SHA
    0d57f13 View commit details

Commits on Jun 22, 2012

  1. Copy the full SHA
    ffb2701 View commit details

Commits on Jun 25, 2012

  1. Copy the full SHA
    3f14a45 View commit details
  2. Copy the full SHA
    9bef436 View commit details
  3. Copy the full SHA
    35706ba View commit details

Commits on Jun 26, 2012

  1. Copy the full SHA
    212f685 View commit details

Commits on Jul 2, 2012

  1. Copy the full SHA
    6d9313a View commit details
  2. Copy the full SHA
    f0a090d View commit details
  3. Copy the full SHA
    a8b0400 View commit details

Commits on Jul 16, 2012

  1. fix(docs): correct typo

    kevinold authored and btford committed Jul 16, 2012
    Copy the full SHA
    5026315 View commit details
  2. fix(docs): Fix spelling, punctuation and grammatical errors on dev gu…

    …ide overview page.
    jamiekrug authored and btford committed Jul 16, 2012
    Copy the full SHA
    1f2d500 View commit details
  3. fix(docs): Fix spelling, punctuation and grammatical errors on dev gu…

    …ide compiler page.
    jamiekrug authored and btford committed Jul 16, 2012
    Copy the full SHA
    2473412 View commit details
  4. fix(docs): Fix spelling, punctuation and grammatical errors on dev gu…

    …ide bootstrap page.
    jamiekrug authored and btford committed Jul 16, 2012
    Copy the full SHA
    c076fe0 View commit details
  5. fix(docs): Fixed typo: changed ngRepeate to ngRepeat.

    Rishabh Rao authored and btford committed Jul 16, 2012
    Copy the full SHA
    4c58501 View commit details

Commits on Jul 18, 2012

  1. fix(docs): Minor grammatical fix

    brettcannon authored and btford committed Jul 18, 2012
    Copy the full SHA
    92a3d28 View commit details
  2. Copy the full SHA
    1613621 View commit details
  3. Copy the full SHA
    01e726b View commit details
  4. Copy the full SHA
    d56d69c View commit details
  5. fix(docs): Fixed some awkward wording

    brettcannon authored and btford committed Jul 18, 2012
    Copy the full SHA
    1fd2b3d View commit details
  6. fix(docs): Grammatical fix

    brettcannon authored and btford committed Jul 18, 2012
    Copy the full SHA
    7f6e132 View commit details

Commits on Jul 19, 2012

  1. fix(docs): Remove a redundant "in".

    brettcannon authored and btford committed Jul 19, 2012
    Copy the full SHA
    64a9cd8 View commit details
  2. Copy the full SHA
    79f2d84 View commit details
  3. fix(docs): Add a missing "the".

    brettcannon authored and btford committed Jul 19, 2012
    Copy the full SHA
    b6b92bd View commit details
  4. fix(docs): Capitalize Angular.

    brettcannon authored and btford committed Jul 19, 2012
    Copy the full SHA
    206371b View commit details
  5. fix(docs): Capitalize "Angular".

    brettcannon authored and btford committed Jul 19, 2012
    Copy the full SHA
    fbfda24 View commit details
  6. fix(docs): Capitalize "APIs"

    brettcannon authored and btford committed Jul 19, 2012
    Copy the full SHA
    ab6937e View commit details
  7. Copy the full SHA
    31c8256 View commit details
  8. fic(docs): Consistently use __bold__ for things that must be done whe…

    …n moving the ng-controller declaration.
    brettcannon authored and btford committed Jul 19, 2012
    Copy the full SHA
    6f9a572 View commit details
  9. fix(docs): Spelling errors

    xrd authored and btford committed Jul 19, 2012
    Copy the full SHA
    17209d5 View commit details
  10. Copy the full SHA
    13b5fd1 View commit details
  11. fix(docs): Capitalize "URL".

    brettcannon authored and btford committed Jul 19, 2012
    Copy the full SHA
    6553fe6 View commit details
  12. fix(docs): "were" -> "where"

    brettcannon authored and btford committed Jul 19, 2012
    Copy the full SHA
    bde931a View commit details
  13. Copy the full SHA
    8c81a0f View commit details
  14. fix(docs): Capitalize Angular.

    brettcannon authored and btford committed Jul 19, 2012
    Copy the full SHA
    5ef9ed8 View commit details

Commits on Jul 20, 2012

  1. Copy the full SHA
    d3952b7 View commit details
  2. Copy the full SHA
    6e2d971 View commit details
  3. refactor($injector): move $injector into the providerCache

    Better than special-casing '$injector' in createInjector.
    taralx authored and IgorMinar committed Jul 20, 2012
    Copy the full SHA
    e3e8813 View commit details

Commits on Jul 21, 2012

  1. fix(docs): "in depth" -> "in-depth"

    brettcannon authored and btford committed Jul 21, 2012
    Copy the full SHA
    a1107e8 View commit details

Commits on Jul 31, 2012

  1. docs: fix icons

    Copy fontawesome during build
    vojtajina committed Jul 31, 2012
    Copy the full SHA
    b84eaff View commit details
  2. docs(guide): hide scenario for directive example

    scenario test for this example would be tricky, we need to teach
    the runner how to inject mocks first.
    vojtajina committed Jul 31, 2012
    Copy the full SHA
    33ad2b4 View commit details

Commits on Aug 4, 2012

  1. Copy the full SHA
    77e6d83 View commit details

Commits on Aug 6, 2012

  1. Copy the full SHA
    eee9a51 View commit details

Commits on Aug 7, 2012

  1. docs(faq): update faq docs

    IgorMinar committed Aug 7, 2012
    Copy the full SHA
    54e4a6f View commit details

Commits on Aug 8, 2012

  1. Copy the full SHA
    c25cb7d View commit details
  2. test(form): fix broken preventDefault test

    the original test relied on incorrect assumptions about how jasmine async
    tests work (when setTimeout is triggered) and how browser reloads a page
    (the sequence of events) and thus the test passes even when the default
    is not prevented.
    
    this change fixes the test by registering an extra submit event handler
    that checks if the default was prevented.
    
    if the default was not prevented, the test will fail and the page will
    be reloaded causing the test runner to panic.
    IgorMinar committed Aug 8, 2012
    Copy the full SHA
    5cec324 View commit details

Commits on Aug 10, 2012

  1. fix(form): prevent page reload when form destroyed

    this fix ensures that we prevent the default action on form submission
    (full page reload) even in cases when the form is being destroyed as
    a result of the submit event handler (e.g. when route change is
    triggered).
    
    The fix is more complicated than I'd like it to be mainly because
    we need to ensure that we don't create circular references between
    js closures and dom elements via DOM event handlers that would then
    result in a memory leak.
    
    Also the differences between IE8, IE9 and normal browsers make testing
    this ugly.
    
    Closes angular#1238
    IgorMinar committed Aug 10, 2012
    Copy the full SHA
    054d40f View commit details
  2. Copy the full SHA
    c0d638a View commit details
Showing 1,869 changed files with 460,340 additions and 67,871 deletions.
509 changes: 509 additions & 0 deletions .circleci/config.yml

Large diffs are not rendered by default.

73 changes: 73 additions & 0 deletions .circleci/env-helpers.inc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
####################################################################################################
# Helpers for defining environment variables for CircleCI.
#
# In CircleCI, each step runs in a new shell. The way to share ENV variables across steps is to
# export them from `$BASH_ENV`, which is automatically sourced at the beginning of every step (for
# the default `bash` shell).
#
# See also https://circleci.com/docs/2.0/env-vars/#using-bash_env-to-set-environment-variables.
####################################################################################################

# Set and print an environment variable.
#
# Use this function for setting environment variables that are public, i.e. it is OK for them to be
# visible to anyone through the CI logs.
#
# Usage: `setPublicVar <name> <value>`
function setPublicVar() {
setSecretVar $1 "$2";
echo "$1=$2";
}

# Set (without printing) an environment variable.
#
# Use this function for setting environment variables that are secret, i.e. should not be visible to
# everyone through the CI logs.
#
# Usage: `setSecretVar <name> <value>`
function setSecretVar() {
# WARNING: Secrets (e.g. passwords, access tokens) should NOT be printed.
# (Keep original shell options to restore at the end.)
local -r originalShellOptions=$(set +o);
set +x -eu -o pipefail;

echo "export $1=\"${2:-}\";" >> $BASH_ENV;

# Restore original shell options.
eval "$originalShellOptions";
}


# Create a function to set an environment variable, when called.
#
# Use this function for creating setter for public environment variables that require expensive or
# time-consuming computaions and may not be needed. When needed, you can call this function to set
# the environment variable (which will be available through `$BASH_ENV` from that point onwards).
#
# Arguments:
# - `<name>`: The name of the environment variable. The generated setter function will be
# `setPublicVar_<name>`.
# - `<code>`: The code to run to compute the value for the variable. Since this code should be
# executed lazily, it must be properly escaped. For example:
# ```sh
# # DO NOT do this:
# createPublicVarSetter MY_VAR "$(whoami)"; # `whoami` will be evaluated eagerly
#
# # DO this isntead:
# createPublicVarSetter MY_VAR "\$(whoami)"; # `whoami` will NOT be evaluated eagerly
# ```
#
# Usage: `createPublicVarSetter <name> <code>`
#
# Example:
# ```sh
# createPublicVarSetter MY_VAR 'echo "FOO"';
# echo $MY_VAR; # Not defined
#
# setPublicVar_MY_VAR;
# source $BASH_ENV;
# echo $MY_VAR; # FOO
# ```
function createPublicVarSetter() {
echo "setPublicVar_$1() { setPublicVar $1 \"$2\"; }" >> $BASH_ENV;
}
69 changes: 69 additions & 0 deletions .circleci/env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env bash

# Variables
readonly projectDir=$(realpath "$(dirname ${BASH_SOURCE[0]})/..")
readonly envHelpersPath="$projectDir/.circleci/env-helpers.inc.sh";

# Load helpers and make them available everywhere (through `$BASH_ENV`).
source $envHelpersPath;
echo "source $envHelpersPath;" >> $BASH_ENV;

####################################################################################################
# Define PUBLIC environment variables for CircleCI.
####################################################################################################
# See https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables for more info.
####################################################################################################
setPublicVar CI "$CI"
setPublicVar PROJECT_ROOT "$projectDir";
# This is the branch being built; e.g. `pull/12345` for PR builds.
setPublicVar CI_BRANCH "$CIRCLE_BRANCH";
setPublicVar CI_BUILD_URL "$CIRCLE_BUILD_URL";
setPublicVar CI_COMMIT "$CIRCLE_SHA1";
setPublicVar CI_GIT_BASE_REVISION "${CIRCLE_GIT_BASE_REVISION}";
setPublicVar CI_GIT_REVISION "${CIRCLE_GIT_REVISION}";
setPublicVar CI_GIT_TAG "${CIRCLE_TAG:-false}";
setPublicVar CI_COMMIT_RANGE "$CIRCLE_GIT_BASE_REVISION..$CIRCLE_GIT_REVISION";
setPublicVar CI_PULL_REQUEST "${CIRCLE_PR_NUMBER:-false}";
setPublicVar CI_REPO_NAME "$CIRCLE_PROJECT_REPONAME";
setPublicVar CI_REPO_OWNER "$CIRCLE_PROJECT_USERNAME";
setPublicVar CI_PR_REPONAME "$CIRCLE_PR_REPONAME";
setPublicVar CI_PR_USERNAME "$CIRCLE_PR_USERNAME";


####################################################################################################
# Define SauceLabs environment variables for CircleCI.
####################################################################################################
setPublicVar BROWSER_PROVIDER "saucelabs"

# The currently latest-1 version of desktop Safari on Saucelabs (v12.0) is unstable and disconnects
# consistently. The latest version (v12.1) works fine.
# TODO: Add `SL_Safari-1` back, once it no longer corresponds to v12.0.
setPublicVar BROWSERS "SL_Chrome,SL_Chrome-1,\
SL_Firefox,SL_Firefox-1,\
SL_Safari,\
SL_iOS,SL_iOS-1,\
SL_IE_9,SL_IE_10,SL_IE_11,\
SL_EDGE,SL_EDGE-1"

setPublicVar SAUCE_LOG_FILE /tmp/angular/sauce-connect.log
setPublicVar SAUCE_READY_FILE /tmp/angular/sauce-connect-ready-file.lock
setPublicVar SAUCE_PID_FILE /tmp/angular/sauce-connect-pid-file.lock
setPublicVar SAUCE_TUNNEL_IDENTIFIER "angularjs-framework-${CIRCLE_BUILD_NUM}-${CIRCLE_NODE_INDEX}"
# Amount of seconds we wait for sauceconnect to establish a tunnel instance. In order to not
# acquire CircleCI instances for too long if sauceconnect failed, we need a connect timeout.
setPublicVar SAUCE_READY_FILE_TIMEOUT 120

####################################################################################################
# Define additional environment variables
####################################################################################################

# NOTE: Make sure the tools used to compute this are available in all executors in `config.yml`.
setPublicVar DIST_TAG $( cat package.json | grep distTag | sed -E 's/^\s*"distTag"\s*:\s*"([^"]+)"\s*,\s*$/\1/' )

####################################################################################################
####################################################################################################
## Source `$BASH_ENV` to make the variables available immediately. ##
## *** NOTE: This must remain the last command in this script. *** ##
####################################################################################################
####################################################################################################
source $BASH_ENV;
18 changes: 18 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# https://editorconfig.org

root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[dropdown-toggle.js]
trim_trailing_whitespace = false
insert_final_newline = false

[htmlparser.js]
insert_final_newline = false
10 changes: 10 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
build/**
docs/app/assets/js/angular-bootstrap/**
docs/config/templates/**
node_modules/**
lib/htmlparser/**
src/angular.bind.js
src/ngParseExt/ucd.js
i18n/closure/**
tmp/**
vendor/**
117 changes: 117 additions & 0 deletions .eslintrc-base.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
{
"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 changes: 17 additions & 0 deletions .eslintrc-browser.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"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
}
}
13 changes: 13 additions & 0 deletions .eslintrc-node.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "./.eslintrc-base.json",
"env": {
"browser": false,
"node": true
},
"parserOptions": {
"ecmaVersion": 2017
},
"plugins": [
"promise"
]
}
25 changes: 25 additions & 0 deletions .eslintrc-todo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
// 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-denylist": ["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 changes: 4 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"root": true,
"extends": "./.eslintrc-node.json"
}
10 changes: 0 additions & 10 deletions .externalToolBuilders/JSTD_Tests.launch

This file was deleted.

10 changes: 0 additions & 10 deletions .externalToolBuilders/JSTD_perf.launch

This file was deleted.

11 changes: 0 additions & 11 deletions .externalToolBuilders/docs.launch

This file was deleted.

7 changes: 0 additions & 7 deletions .externalToolBuilders/gen_docs.launch

This file was deleted.

6 changes: 0 additions & 6 deletions .externalToolBuilders/jsLint.launch

This file was deleted.

5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Auto detect text files and perform LF normalization
* text=auto

# JS files must always use LF for tools to work
*.js eol=lf
42 changes: 42 additions & 0 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# AngularJS is in LTS mode
We are no longer accepting changes that are not critical bug fixes into this project.
See https://blog.angular.io/stable-angularjs-and-long-term-support-7e077635ee9c for more detail.

<!--
IF YOU DON'T FILL OUT THE FOLLOWING INFORMATION WE MIGHT CLOSE YOUR ISSUE WITHOUT INVESTIGATION
-->

<!--
- For *SUPPORT QUESTIONS*, use one of the
[support channels](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question).
- Before submitting, please **SEARCH GITHUB** for a similar issue or PR. -->

**I'm submitting a ...**
<!-- (check one with "x") -->
- [ ] regression from 1.7.0
- [ ] security issue
- [ ] issue caused by a new browser version
- [ ] other <!--(Please do not submit support requests here - see above)-->

**Current behavior:**
<!-- Describe how the bug manifests / how the current features are insufficient. -->

**Expected / new behavior:**
<!-- Describe what the behavior would be without the bug / how the feature would improve AngularJS -->

**Minimal reproduction of the problem with instructions:**
<!--
If the current behavior is a bug or you can illustrate your feature request better with an example,
please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via
https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:yBpEi4).
-->

**AngularJS version:** 1.8.x
<!-- Check whether this is still an issue in the most recent stable or in the snapshot AngularJS
version (https://code.angularjs.org/snapshot/) -->

**Browser:** [all | Chrome XX | Firefox XX | Edge XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView | Opera XX ]
<!-- All browsers where this could be reproduced (and Operating System if relevant) -->

**Anything else:**
<!-- e.g. stacktraces, related issues, suggestions how to fix -->
29 changes: 29 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# AngularJS is in LTS mode
We are no longer accepting changes that are not critical bug fixes into this project.
See https://blog.angular.io/stable-angularjs-and-long-term-support-7e077635ee9c for more detail.

<!-- General PR submission guidelines https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#submit-pr -->
**Does this PR fix a regression since 1.7.0, a security flaw, or a problem caused by a new browser version?**

<!-- If the answer is no, then we will not merge this PR -->


**What is the current behavior? (You can also link to an open issue here)**



**What is the new behavior (if this is a feature change)?**



**Does this PR introduce a breaking change?**



**Please check if the PR fulfills these requirements**
- [ ] The commit message follows our [guidelines](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits)
- [ ] Fix/Feature: [Docs](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#documentation) have been added/updated
- [ ] Fix/Feature: Tests have been added; existing tests pass

**Other information**:

22 changes: 17 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
build/
angularjs.netrc
jstd.log
/build/
/benchpress-build/
.DS_Store
gen_docs.disable
test.disable
regression/temp*.html
performance/temp*.html
.idea/workspace.xml
*~
*.swp
angular.js.tmproj
node_modules
jsTestDriver*.conf
node_modules/
angular.xcodeproj
.firebase/
.idea
*.iml
.agignore
.lvimrc
libpeerconnection.log
npm-debug.log
/tmp/
.vscode
*.log
*.stackdump
scripts/code.angularjs.org-firebase/deploy
scripts/docs.angularjs.org-firebase/deploy
scripts/docs.angularjs.org-firebase/functions/content
29 changes: 29 additions & 0 deletions .mailmap
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Andres Ornelas <aornelas@google.com>
Caitlin Potter <caitpotter88@gmail.com>
Caitlin Potter <caitpotter88@gmail.com> <snowball@defpixel.com>
Di Peng <pengdi@google.com>
Di Peng <pengdi@google.com> <pengdi@go.wustl.edu>
Georgios Kalpakas <kalpakas.g@gmail.com>
Georgios Kalpakas <kalpakas.g@gmail.com> <g.kalpakas@hotmail.com>
Julie Ralph <ju.ralph@gmail.com>
Lucas Galfaso <lgalfaso@gmail.com>
Martin Staffa <mjstaffa@gmail.com>
Martin Staffa <mjstaffa@gmail.com> <mjstaffa@googlemail.com>
Matias Niemelä <matias@yearofmoo.com>
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
Misko Hevery <misko@hevery.com>
Misko Hevery <misko@hevery.com> <misko@google.com>
Igor Minar <igor@angularjs.org>
Igor Minar <igor@angularjs.org> <iiminar@gmail.com>
Igor Minar <igor@angularjs.org> <iminar@google.com>
Igor Minar <igor@angularjs.org> <iminar@dhcp-172-19-37-154.mtv.corp.google.com>
Pawel Kozlowski <pkozlowski.opensource@gmail.com>
Peter Bacon Darwin <pete@bacondarwin.com>
Rodric Haddad <rody@rodyhaddad.com>
Shahar Talmi <shahar.talmi@gmail.com>
Shahar Talmi <shahar.talmi@gmail.com> <shahart@wix.com>
Shyam Seshadri <shyamseshadri@google.com>
Shyam Seshadri <shyamseshadri@google.com> <shyamseshadri@gmail.com>
Vojta Jina <vojta.jina@gmail.com>
Vojta Jina <vojta.jina@gmail.com> <vojta@gemin-i.org>
Vojta Jina <vojta.jina@gmail.com> <vojta@google.com>
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
14.16.1
47 changes: 0 additions & 47 deletions .project

This file was deleted.

10 changes: 0 additions & 10 deletions .settings/.jsdtscope

This file was deleted.

16 changes: 0 additions & 16 deletions .settings/de.loskutov.anyedit.AnyEditTools.prefs

This file was deleted.

1 change: 0 additions & 1 deletion .settings/org.eclipse.wst.jsdt.ui.superType.container

This file was deleted.

1 change: 0 additions & 1 deletion .settings/org.eclipse.wst.jsdt.ui.superType.name

This file was deleted.

16,112 changes: 16,096 additions & 16 deletions CHANGELOG.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Contributor Code of Conduct

The AngularJS project follows the Code of Conduct defined in [the angular/code-of-conduct repository](https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md). Please read it.
246 changes: 246 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
# Contributing to AngularJS

We'd love for you to contribute to our source code and to make AngularJS even better than it is
today! Here are the guidelines we'd like you to follow:

* [Code of Conduct](#coc)
* [Questions and Problems](#question)
* [Issues and Bugs](#issue)
* [Feature Requests](#feature)
* [Improving Documentation](#docs)
* [Issue Submission Guidelines](#submit)
* [Pull Request Submission Guidelines](#submit-pr)
* [Signing the CLA](#cla)

## <a name="coc"></a> Code of Conduct

Help us keep AngularJS open and inclusive. Please read and follow our [Code of Conduct][coc].

## <a name="requests"></a> Questions, Bugs, Features

### <a name="question"></a> Got a Question or Problem?

Do not open issues for general support questions as we want to keep GitHub issues for bug reports
and feature requests. You've got much better chances of getting your question answered on dedicated
support platforms, the best being [Stack Overflow][stackoverflow].

Stack Overflow is a much better place to ask questions since:

- there are thousands of people willing to help on Stack Overflow
- questions and answers stay available for public viewing so your question / answer might help
someone else
- Stack Overflow's voting system assures that the best answers are prominently visible.

To save your and our time, we will systematically close all issues that are requests for general
support and redirect people to the section you are reading right now.

Other channels for support are:
- the [Google Group][groups] discussion list
- the [AngularJS IRC][irc]
- the [AngularJS Gitter][gitter]

### <a name="issue"></a> Found an Issue or Bug?

If you find a bug in the source code, you can help us by submitting an issue to our
[GitHub Repository][github]. Even better, you can submit a Pull Request with a fix.

**Please see the [Submission Guidelines](#submit) below.**

**Special Note for Localization Issues:** AngularJS 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].

### <a name="feature"></a> Missing a Feature?

You can request a new feature by submitting an issue to our [GitHub Repository][github-issues].

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 in an
[GitHub issue][github-issues] that clearly outlines the changes and benefits of the feature.
* **Small Changes** can directly be crafted and submitted to the [GitHub Repository][github]
as a Pull Request. See the section about [Pull Request Submission Guidelines](#submit-pr), and
for detailed information the [core development documentation][developers].

### <a name="docs"></a> Want a Doc Fix?

Should you have a suggestion for the documentation, you can open an issue and outline the problem
or improvement you have - however, creating the doc fix yourself is much better!

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.

If you're making a small change (typo, phrasing) 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. The commit message is preformatted to the right type
and scope, so you only have to add the description.

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 follows the **[Commit Message Guidelines][developers.commits]**.

## <a name="submit"></a> Issue Submission Guidelines
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.

The "[new issue][github-new-issue]" form contains a number of prompts that you should fill out to
make it easier to understand and categorize the issue.

In general, 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
* **AngularJS Version(s)** - is it a regression?
* **Browsers and Operating System** - is this a problem with all browsers or only specific ones?
* **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?
* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
causing the problem (line of code or commit)

Here is a great example of a well defined issue: https://github.com/angular/angular.js/issues/5069.

**If you get help, help others. Good karma rulez!**

## <a name="submit-pr"></a> Pull Request Submission Guidelines
Before you submit your pull request consider the following guidelines:

* Search [GitHub](https://github.com/angular/angular.js/pulls) for an open or closed Pull Request
that relates to your submission. You don't want to duplicate effort.
* Create the [development environment][developers.setup]
* Make your changes in a new git branch:

```shell
git checkout -b my-fix-branch master
```

* Create your patch commit, **including appropriate test cases**.
* Follow our [Coding Rules][developers.rules].
* If the changes affect public APIs, change or add relevant [documentation][developers.documentation].
* Run the AngularJS [unit][developers.tests-unit] and [E2E test][developers.tests-e2e] suites, and ensure that all tests
pass. It is generally sufficient to run the tests only on Chrome, as our continuous integration test will
run the tests on additional browsers.
* Run `yarn grunt eslint` to check that you have followed the automatically enforced coding rules
* Commit your changes using a descriptive commit message that follows our
[commit message conventions][developers.commits]. Adherence to the
[commit message conventions][developers.commits] is required, because release notes are
automatically generated from these messages.

```shell
git commit -a
```
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.

* Before creating the Pull Request, package and run all tests a last time:

```shell
yarn grunt test
```

* Push your branch to GitHub:

```shell
git push origin my-fix-branch
```

* In GitHub, send a pull request to `angular.js:master`. This will trigger the check of the
[Contributor License Agreement](#cla) and the continuous integration tests.

* If you find that the continuous integration tests have failed, look into the logs to find out
if your changes caused test failures, the commit message was malformed etc. If you find that the
tests failed or times out for unrelated reasons, you can ping a team member so that the build can be
restarted.

* If we suggest changes, then:

* Make the required updates.
* Re-run the AngularJS 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).

You can also amend the initial commits and force push them to the branch.

```shell
git rebase master -i
git push origin my-fix-branch -f
```

This is generally easier to follow, but separate commits are useful if the Pull Request contains
iterations that might be interesting to see side-by-side.

That's it! Thank you for your contribution!
#### After your pull request is merged
After your pull request is merged, you can safely delete your branch and pull the changes
from the main (upstream) repository:
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
```shell
git push origin --delete my-fix-branch
```
* Check out the master branch:
```shell
git checkout master -f
```
* Delete the local branch:
```shell
git branch -D my-fix-branch
```
* Update your master with the latest upstream version:
```shell
git pull --ff upstream master
```
## <a name="cla"></a> Signing the Contributor License Agreement (CLA)
Upon submmitting a Pull Request, a friendly bot will ask you to sign our CLA if you haven't done
so before. Unfortunately, this is necessary for documentation changes, too.
It's a quick process, we promise!
* For individuals we have a [simple click-through form][individual-cla].
* For corporations we'll need you to
[print, sign and one of scan+email, fax or mail the form][corporate-cla].



[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
[coc]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
[developers]: DEVELOPERS.md
[developers.commits]: DEVELOPERS.md#commits
[developers.documentation]: DEVELOPERS.md#documentation
[developers.rules]: DEVELOPERS.md#rules
[developers.setup]: DEVELOPERS.md#setup
[developers.tests-e2e]: DEVELOPERS.md#e2e-tests
[developers.tests-unit]: DEVELOPERS.md#unit-tests
[github-issues]: https://github.com/angular/angular.js/issues
[github-new-issue]: https://github.com/angular/angular.js/issues/new
[github]: https://github.com/angular/angular.js
[gitter]: https://gitter.im/angular/angular.js
[Google Closure I18N library]: https://github.com/google/closure-library/tree/master/closure/goog/i18n
[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
[jsfiddle]: http://jsfiddle.net/
[karma-browserstack]: https://github.com/karma-runner/karma-browserstack-launcher
[karma-saucelabs]: https://github.com/karma-runner/karma-sauce-launcher
[plunker]: http://plnkr.co/edit
[stackoverflow]: http://stackoverflow.com/questions/tagged/angularjs

[![Analytics](https://ga-beacon.appspot.com/UA-8594346-11/angular.js/CONTRIBUTING.md?pixel)](https://github.com/igrigorik/ga-beacon)
488 changes: 488 additions & 0 deletions DEVELOPERS.md

Large diffs are not rendered by default.

535 changes: 535 additions & 0 deletions Gruntfile.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License

Copyright (c) 2010-2012 Google, Inc. http://angularjs.org
Copyright (c) 2010-2020 Google LLC. 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
23 changes: 23 additions & 0 deletions README.closure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Using AngularJS with the Closure Compiler
=========================================

The Closure Compiler project contains definitions for the AngularJS JavaScript
in its `contrib/externs` directory.

The definitions contain externs for use with the Closure compiler (aka
JSCompiler). Passing these files to the --externs parameter of a compiler
pass allows using type annotations for AngularJS objects. For example,
AngularJS's $scope objects can be annotated as:
```js
/** @type {angular.Scope} */
var scope = $scope;
```

This allows JSCompiler to type check accesses to scope, give warnings about
missing methods or incorrect arguments, and also prevents renaming of property
accesses with advanced compilation.

The externs are incomplete and maintained on an as-needed basis, but strive to
be correct. Externs for individual modules should be added in separate files.

See https://developers.google.com/closure/compiler/
114 changes: 102 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,109 @@
AngularJS
AngularJS [![CircleCI](https://circleci.com/gh/angular/angular.js/tree/master.svg?style=shield)](https://circleci.com/gh/angular/workflows/angular.js/tree/master)
=========

* Web site: http://angularjs.org
* Tutorial: http://docs.angularjs.org/#!/tutorial
* API Docs: http://docs.angularjs.org
* Developer Guide: http://docs.angularjs.org/#!/guide
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 HTML’s
syntax to express your application’s components clearly and succinctly. It automatically
synchronizes data from your UI (view) with your JavaScript objects (model) through 2-way data
binding. To help you structure your application better and make it easy to test, AngularJS teaches
the browser how to do dependency injection and inversion of control.

Compiling
It also helps with server-side communication, taming async callbacks with promises and deferred objects,
and it makes client-side navigation and deep linking with hashbang urls or HTML5 pushState a
piece of cake. Best of all? It makes development fun!

--------------------

**AngularJS support has officially ended as of January 2022.
[See what ending support means](https://docs.angularjs.org/misc/version-support-status)
and [read the end of life announcement](https://goo.gle/angularjs-end-of-life).**

**Visit [angular.io](https://angular.io) for the actively supported Angular.**

--------------------

* Web site: https://angularjs.org
* Tutorial: https://docs.angularjs.org/tutorial
* API Docs: https://docs.angularjs.org/api
* Developer Guide: https://docs.angularjs.org/guide
* Contribution guidelines: [CONTRIBUTING.md](CONTRIBUTING.md)
* Core Development: [DEVELOPERS.md](DEVELOPERS.md)
* Dashboard: https://dashboard.angularjs.org


Documentation
--------------------
Go to https://docs.angularjs.org

Contribute
--------------------

We've set up a separate document for our
[contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).

Develop
--------------------

We've set up a separate document for
[developers](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md).


[![Analytics](https://ga-beacon.appspot.com/UA-8594346-11/angular.js/README.md?pixel)](https://github.com/igrigorik/ga-beacon)

What to use AngularJS for and when to use it
---------
rake compile
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](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), 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.

#### Interconnection with HTML at the root level
AngularJS uses HTML to define the user's interface. AngularJS also enables the programmer to write
new HTML tags (AngularJS Directives) and increase the readability and understandability of the HTML
code. Directives are AngularJS’s way of bringing additional functionality to HTML. Directives
achieve this by enabling us to invent our own HTML elements. This also helps in making the code DRY
(Don't Repeat Yourself), which means once created, a new directive can be used anywhere within the
application.

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 AngularJS will take care of the dependencies.

#### Data Handling made simple
Data and Data Models in AngularJS are plain JavaScript objects and one can add and change properties
directly on it and loop over objects and arrays at will.

Running Tests
-------------
./server.sh # start the server
open http://localhost:9876/capture # capture browser
./test.sh # run all unit tests
#### 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.

#### 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!

#### 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.
98 changes: 98 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# AngularJS Release instructions


## Compare the list of commits between stable and unstable

There is a script - compare-master-to-stable.js - that helps with this.
We just want to make sure that good commits (low risk fixes + docs fixes) got cherry-picked into stable branch and nothing interesting got merged only into stable branch.


## Pick a release name (for this version)

A super-heroic power (adverb-verb phrase).


## Generate release notes

Example Commit: https://github.com/angular/angular.js/commit/7ab5098c14ee4f195dbfe2681e402fe2dfeacd78

1) Run

```bash
node_modules/.bin/changez -o changes.md -v <new version> <base branch>
```

2) Review the generated file and manually fix typos, group and reorder stuff if needed.
3) Move the content into CHANGELOG.md add release code-names to headers.
4) Push the changes to your private github repo and review.
5) cherry-pick the release notes commit to the appropriate branches.


## Pick a commit to release (for this version)

Usually this will be the commit containing the release notes, but it may also be in the past.


## Run "release" script

```bash
scripts/release/release.sh --git-push-dryrun=false --commit-sha=8822a4f --version-number=1.7.6 --version-name=gravity-manipulation
```

1) The SHA is of the commit to release (could be in the past).

2) The version number and code-name that should be released, not the next version number (e.g. to release 1.2.12 you enter 1.2.12 as release version and the code-name that was picked for 1.2.12, cauliflower-eradication).

3) You will need to have write access to all the AngularJS github dist repositories and publish rights for the AngularJS packages on npm.


## Update GitHub milestones

1) Create the next milestone if it doesn't exist yet-giving ita due date.
2) Move all open issues and PRs for the current milestone to the next milestone<br>
You can do this by filtering the current milestone, selecting via checklist, and moving to the next milestone within the GH issues page.

3) Close the current milestone click the milestones tab and close from there.
4) Create a new holding milestone for the release after next-but don't give it a due date otherwise that will mess up the dashboard.


## Push build artifacts to CDN

Google CDNs are fed with data from google3 every day at 11:15am PT it takes only few minutes for the import to propagate).
If we want to make our files available, we need submit our CLs before this time on the day of the release.


## Don't update the package.json (branchVersion) until the CDN has updated

This is the version used to compute what version to link to in the CDN. If you update this too early then the CDN lookup fails and you end up with 'null, for the version, which breaks the docs.


## Verify angularjs.org download modal has latest version (updates via CI job)

The versions in the modal are updated (based on the versions available on CDN) as part of the CI deploy stage.
(You may need to explicitly trigger the CI job. e.g. re-running the last `deploy` job.)


## Announce the release (via official Google accounts)

Double check that angularjs.org is up to date with the new release version before sharing.

1) Collect a list of contributors

use: `git log --format='%aN' v1.2.12..v1.2.13 | sort -u`

2) Write a blog post (for minor releases, not patch releases) and publish it with the "release" tag
3) Post on twitter as yourself (tweet from your heart; there is no template for this), retweet as @AngularJS


## Party!


## Major Release Tasks

1) Update angularjs.org to use the latest branch.
2) Write up a migration document.
3) Create a new git branch for the version that has been released (e.g. 1.8.x).
4) Check that the build and release scripts still work.
5) Update the dist-tag of the old branch, see https://github.com/angular/angular.js/pull/12722.
6) Write a blog post.
328 changes: 0 additions & 328 deletions Rakefile

This file was deleted.

16 changes: 16 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Security Policy

## Supported Versions

**AngularJS support has officially ended as of January 2022.**
[See what ending support means](https://docs.angularjs.org/misc/version-support-status)
and [read the end of life announcement](https://goo.gle/angularjs-end-of-life).

Visit [angular.io](https://angular.io) for the actively supported Angular.

| Version | Supported | Status | Comments |
| ----------- | ------------------ | --------------------- | ------------------------------------ |
| 1.8.x | :x: | All support ended | |
| 1.3.x-1.7.x | :x: | All support ended | |
| 1.2.x | :x: | All support ended | Last version to provide IE 8 support |
| <1.2.0 | :x: | All support ended | |
135 changes: 135 additions & 0 deletions TRIAGING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Triage new issues/PRs on github

This document shows the steps the AngularJS team is using to triage issues.
The labels are used later on for [planning releases](#assigning-work).


## Automatic processing

We have tools (e.g. [Mary Poppins]) that automatically add comments and labels to issues and PRs.
The following is done automatically so you don't have to worry about it:

* Label `cla: yes` or `cla: no` for pull requests
* Label `GH: *`
* `PR` - issue is a PR
* `issue` - otherwise


## Triaging Process

This process based on the idea of minimizing user pain
[from this blog post](http://www.lostgarden.com/2008/05/improving-bug-triage-with-user-pain.html).

1. Open the list of [non triaged issues](https://github.com/angular/angular.js/issues?q=is%3Aopen+sort%3Acreated-desc+no%3Amilestone)
* Sort by submit date, with the newest issues first
* You don't have to do issues in order; feel free to pick and choose issues as you please.
* You can triage older issues as well
* Triage to your heart's content
1. Assign yourself: Pick an issue that is not assigned to anyone and assign it to you
1. Understandable? - verify if the description of the request is clear.
* If not, [close it][] according to the instructions below and go to the last step.
1. Duplicate?
* If you've seen this issue before [close it][], and go to the last step.
* Check if there are comments that link to a dupe. If so verify that this is indeed a dupe, [close it][], and go to the last step.
1. Bugs:
* Label `Type: Bug`
* Reproducible? - Steps to reproduce the bug are clear. If they are not, ask for a clarification. If there's no reply after a week, [close it][].
* Reproducible on master? - <http://code.angularjs.org/snapshot/>
1. Non bugs:
* Label `Type: Feature`, `Type: Chore`, or `Type: Perf`
* Belongs in core? – Often new features should be implemented as a third-party module rather than an addition to the core.
If this doesn't belong, [close it][], and go to the last step.
* Label `needs: breaking change` - if needed
* Label `needs: public api` - if the issue requires introduction of a new public API
1. Label `browser: *` - if the issue **only** affects a certain browser
1. Label `frequency: *` – How often does this issue come up? How many developers does this affect? Chose just one of the following:
* low - obscure issue affecting a handful of developers
* moderate - impacts a common usage pattern
* high - impacts most or all AngularJS apps
1. Label `severity: *` - How bad is the issue? Chose just one of the following:
* security issue
* regression
* memory leak
* broken expected use - it's hard or impossible for a developer using AngularJS to accomplish something that AngularJS should be able to do
* confusing - unexpected or inconsistent behavior; hard-to-debug
* inconvenience - causes ugly/boilerplate code in apps
1. Label `component: *`
* In rare cases, it's ok to have multiple components.
1. Label `PRs plz!` - These issues are good targets for PRs from the open source community. In addition to applying this label, you must:
* Leave a comment explaining the problem and solution so someone can easily finish it.
* Assign the issue to yourself.
* Give feedback on PRs addressing this issue.
* You are responsible for mentoring contributors helping with this issue.
1. Label `origin: google` for issues from Google
1. Assign a milestone:
* Backlog - triaged fixes and features, should be the default choice
* Current 1.x.y milestone (e.g. 1.3.0-beta-2) - regressions and urgent bugs only


1. Unassign yourself from the issue


## Tips

* Label `resolution: *`
* these tags can be used for labeling a closed issue/PR with a reason why it was closed.
* Right now there are only a few rejection reasons, but we can add more as needed. Feel free to suggest one to a core team member. We don't use this label for issues that were fixed or PRs that were merged.


## Closing an Issue or PR

We're grateful to anyone who takes the time to submit an issue, even if we ultimately decide not to act on it.
Be kind and respectful as you close issues. Be sure to follow the [code of conduct][].

1. Always thank the person who submitted it.
1. If it's a duplicate, link to the older or more descriptive issue that supersedes the one you are closing.
1. Let them know if there's some way for them to follow-up.
* When the issue is unclear or reproducible, note that you'll reopen it if they can clarify or provide a better example. Mention [plunker] or [fiddle] for examples. Watch your notifications and follow-up if they do provide clarification. :)
* If appropriate, suggest implementing a feature as a third-party module.

If in doubt, ask a core team member what to do.
[Brian](https://github.com/btford) is probably the person to ask.
You can mention him in the relevant thread like this: `@btford`.

**Example:**

> 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 to the npm registry.

## Assigning Work

These criteria are then used to calculate a "user pain" score.
Work is assigned weekly to core team members starting with the highest pain, descending down to the lowest.

```
pain = severity × frequency
```

**severity:**

- security issue (6)
- regression (5)
- memory leak (4)
- broken expected use (3)
- confusing (2)
- inconvenience (1)

**frequency:**

- low (1)
- moderate (2)
- high (3)

**Note:** Security issues, regressions, and memory leaks should almost always be set to `frequency: high`.


[![Analytics](https://ga-beacon.appspot.com/UA-8594346-11/angular.js/TRIAGING.md?pixel)](https://github.com/igrigorik/ga-beacon)


[close it]: #closing-an-issue-or-pr
[code of conduct]: https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md
[Mary Poppins]: https://github.com/btford/mary-poppins
[plunker]: http://plnkr.co/
[fiddle]: http://jsfiddle.net/
363 changes: 230 additions & 133 deletions angularFiles.js

Large diffs are not rendered by default.

5 changes: 0 additions & 5 deletions angularjs.ftp

This file was deleted.

11 changes: 11 additions & 0 deletions benchmarks/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"root": true,
"extends": "../.eslintrc-browser.json",

"globals": {
"benchmarkSteps": false,

// Benchmarks are not run in IE 9 so we're fine.
"console": false
}
}
6 changes: 6 additions & 0 deletions benchmarks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Instructions for using benchpress (how to create benchmarks, how to run, how to configure) can be
found at: https://github.com/angular/benchpress/blob/master/README.md.

In this project, there is a configured grunt task for building the benchmarks,
`grunt bp_build`, which places the runnable benchmarks in "/build/benchmarks/".
The existing `grunt webserver` task can be used to serve the built benchmarks at `localhost:8000/build/benchmarks/<benchmark-name>`
44 changes: 44 additions & 0 deletions benchmarks/animation-bp/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'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 changes: 22 additions & 0 deletions benchmarks/animation-bp/bp.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* 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 change: 1 addition & 0 deletions benchmarks/animation-bp/jquery-noop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
28 changes: 28 additions & 0 deletions benchmarks/animation-bp/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<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 changes: 61 additions & 0 deletions benchmarks/bootstrap-compile-bp/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
'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;
}
});

});
172 changes: 172 additions & 0 deletions benchmarks/bootstrap-compile-bp/bootstrap-carousel.tpl.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<!-- 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 -->
595 changes: 595 additions & 0 deletions benchmarks/bootstrap-compile-bp/bootstrap-theme.tpl.html

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions benchmarks/bootstrap-compile-bp/bp.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* eslint-env node */

'use strict';

module.exports = function(config) {
config.set({
scripts: [{
id: 'angular',
src: '/build/angular.js'
},
{
src: 'app.js'
}]
});
};
40 changes: 40 additions & 0 deletions benchmarks/bootstrap-compile-bp/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<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>
58 changes: 58 additions & 0 deletions benchmarks/event-delegation-bp/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use strict';

var app = angular.module('eventDelegationBenchmark', []);

app.directive('noopDir', function() {
return {
compile: function($element, $attrs) {
return function($scope, $element) {
return 1;
};
}
};
});

app.directive('nativeClick', ['$parse', function($parse) {
return {
compile: function($element, $attrs) {
$parse($attrs.tstEvent);
return function($scope, $element) {
$element[0].addEventListener('click', function() {
console.log('clicked');
}, false);
};
}
};
}]);

app.directive('dlgtClick', function() {
return {
compile: function($element, $attrs) {
// We don't setup the global event listeners as the costs are small and one time only...
}
};
});

app.controller('DataController', function DataController($rootScope) {
this.ngRepeatCount = 1000;
this.rows = [];
var self = this;

benchmarkSteps.push({
name: '$apply',
fn: function() {
var oldRows = self.rows;
$rootScope.$apply(function() {
self.rows = [];
});
self.rows = oldRows;
if (self.rows.length !== self.ngRepeatCount) {
self.rows = [];
for (var i = 0; i < self.ngRepeatCount; i++) {
self.rows.push('row' + i);
}
}
$rootScope.$apply();
}
});
});
14 changes: 14 additions & 0 deletions benchmarks/event-delegation-bp/bp.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-env node */

'use strict';

module.exports = function(config) {
config.set({
scripts: [{
id: 'angular',
src: '/build/angular.js'
}, {
src: 'app.js'
}]
});
};
139 changes: 139 additions & 0 deletions benchmarks/event-delegation-bp/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<div ng-app="eventDelegationBenchmark">
<div ng-controller="DataController as ctrl">
<div class="container-fluid">

<p>
Impact of event delegation.
</p>

<p>
<label>
Number of ngRepeats:
<input type="number" ng-model="ctrl.ngRepeatCount">
</label>
</p>

<p>
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="ngClick">ngClick</label></div>
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="ngClickNoJqLite">ngClick without jqLite</label></div>
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="ngShow">baseline: ng-show</label></div>
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="textInterpolation">baseline: text interpolation</label></div>
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="dlgtClick">delegate event directive (only compile)</label></div>
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="noopDir">baseline: noop directive (compile and link)</label></div>
<div class="radio"><label><input type=radio ng-model="benchmarkType" value="noop">baseline: no directive</label></div>
</p>

<p>
How to read the results:
<ul>
<li>The benchmark measures how long it takes to instantiate a given number of directives</li>
<li>ngClick is compared against ngShow and text interpolation as baseline. The results show
how expensive ngClick is compared to other very simple directives that touch the DOM.
</li>
<li>To measure the impact of jqLite.on vs element.addEventListener there is also a benchmark
that as a modified version of ngClick that uses element.addEventListener.
</li>
<li>The delegate event directive is compared against a noop directive with a compile and link function and the case with no directives.
The result shows how expensive it is to add a link function to a directive, as the delegate event directive has none.
</li>
</ul>
</p>

<p>
Results as of 7/31/2014:
<ul>
<li>ngClick is very close to ngShow and text interpolation, especially when looking at a version of ngClick that does not use jqLite.on but element.addEventListener instead.</li>
<li>A delegate event directive that has no link function has the same speed as a directive with link function. I.e. ngClick is slower compared to the delegate event directive only because ngClick touches
the DOM for every element</li>
<li>A delegate event directive could be about 50% faster than ngClick. However, the overall performance
benefit depends on how many (and which) other directives are used on the same element
and what other things are part of the measures use case.
E.g. rows of a table with ngRepeat that use ngClick will probably also contain text interpolation.
</li>
</ul>
</p>

Debug output:
<ng-switch on="benchmarkType">
<div ng-switch-when="ngClick">
<div>
<span ng-repeat="row in ctrl.rows">
<span ng-click="a()">1</span>
<span ng-click="a()">1</span>
<span ng-click="a()">1</span>
<span ng-click="a()">1</span>
</span>
</div>
</div>
<div ng-switch-when="ngClickNoJqLite">
<div>
<span ng-repeat="row in ctrl.rows">
<span native-click="a()">1</span>
<span native-click="a()">1</span>
<span native-click="a()">1</span>
<span native-click="a()">1</span>
<span native-click="a()">1</span>
</span>
</div>
</div>
<div ng-switch-when="ngShow">
<div>
<span ng-repeat="row in ctrl.rows">
<span ng-show="true">1</span>
<span ng-show="true">1</span>
<span ng-show="true">1</span>
<span ng-show="true">1</span>
<span ng-show="true">1</span>
</span>
</div>
</div>
<div ng-switch-when="textInterpolation">
<div>
<span ng-repeat="row in ctrl.rows">
<span>{{row}}</span>
<span>{{row}}</span>
<span>{{row}}</span>
<span>{{row}}</span>
<span>{{row}}</span>
</span>
</div>
</div>
<div ng-switch-when="dlgtClick">
<div>
<span ng-repeat="row in ctrl.rows">
<span dlgt-click="a()">1</span>
<span dlgt-click="a()">1</span>
<span dlgt-click="a()">1</span>
<span dlgt-click="a()">1</span>
<span dlgt-click="a()">1</span>
</span>
</div>
</div>
<div ng-switch-when="noopDir">
<div>
<span ng-repeat="row in ctrl.rows">
<span noop-dir>1</span>
<span noop-dir>1</span>
<span noop-dir>1</span>
<span noop-dir>1</span>
<span noop-dir>1</span>
</span>
</div>
</div>
<div ng-switch-when="noop">
<div>
<span ng-repeat="row in ctrl.rows">
<span>1</span>
<span>1</span>
<span>1</span>
<span>1</span>
<span>1</span>
</span>
</div>
</div>

</ng-switch>

</div>
</div>
</div>
187 changes: 187 additions & 0 deletions benchmarks/largetable-bp/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
'use strict';

var app = angular.module('largetableBenchmark', []);

app.config(function($compileProvider) {
if ($compileProvider.debugInfoEnabled) {
$compileProvider.debugInfoEnabled(false);
}
});

app.filter('noop', function() {
return function(input) {
return input;
};
});

app.controller('DataController', function DataController($scope, $rootScope) {
var totalRows = 1000;
var totalColumns = 20;

var data = $scope.data = [];
$scope.digestDuration = '?';
$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++) {
data[i] = [];
for (var j = 0; j < totalColumns; j++) {
data[i][j] = {
i: i, j: j,
iFn: iGetter,
jFn: jGetter
};
}
}

var previousType;

benchmarkSteps.push({
name: 'destroy',
fn: function() {
$scope.$apply(function() {
previousType = $scope.benchmarkType;
$scope.benchmarkType = 'none';
});
}
});

benchmarkSteps.push({
name: 'create',
fn: function() {
$scope.$apply(function() {
$scope.benchmarkType = previousType;
});
}
});

benchmarkSteps.push({
name: '$apply',
fn: function() {
$rootScope.$apply();
}
});
});


app.directive('baselineBindingTable', function() {
return {
restrict: 'E',
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');
template.appendChild(document.createElement('span'));
template.appendChild(document.createTextNode(':'));
template.appendChild(document.createElement('span'));
template.appendChild(document.createTextNode('|'));

for (i = 0; i < 1000; i++) {
row = document.createElement('div');
$element[0].appendChild(row);
for (j = 0; j < 20; j++) {
cell = template.cloneNode(true);
row.appendChild(cell);
cell.childNodes[0].textContent = i;
cell.childNodes[2].textContent = j;
cell.ng3992 = 'xxx';
comment = document.createComment('ngRepeat end: bar in foo');
row.appendChild(comment);
}

comment = document.createComment('ngRepeat end: foo in foos');
$element[0].appendChild(comment);
}
}
};
});


app.directive('baselineInterpolationTable', function() {
return {
restrict: 'E',
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');

for (i = 0; i < 1000; i++) {
row = document.createElement('div');
$element[0].appendChild(row);
for (j = 0; j < 20; j++) {
cell = template.cloneNode(true);
row.appendChild(cell);
cell.textContent = '' + i + ':' + j + '|';
cell.ng3992 = 'xxx';
comment = document.createComment('ngRepeat end: bar in foo');
row.appendChild(comment);
}

comment = document.createComment('ngRepeat end: foo in foos');
$element[0].appendChild(comment);
}
}
};
});



/*
the fastest
240/44
app.directive('baselineTable', function() {
return function($scope, $element) {
var i, j, row, cell;
for (i = 0; i < 1000; i++) {
row = document.createElement('div');
for (j = 0; j < 20; j++) {
cell = document.createElement('span');
cell.textContent = '' + i + ':' + j;
row.appendChild(cell);
}
$element[0].appendChild(row);
}
};
});
*/

/*
with comments and expando
232/90
app.directive('baselineTable', function() {
return function($scope, $element) {
var i, j, row, cell, comment;
for (i = 0; i < 1000; i++) {
row = document.createElement('div');
$element[0].appendChild(row);
for (j = 0; j < 20; j++) {
cell = document.createElement('span');
row.appendChild(cell);
cell.textContent = '' + i + ':' + j;
cell.ng3992 = 'xxx';
comment = document.createComment('ngRepeat end: bar in foo');
row.appendChild(comment);
}
comment = document.createComment('ngRepeat end: foo in foos');
$element[0].appendChild(comment);
}
};
});
*/
19 changes: 19 additions & 0 deletions benchmarks/largetable-bp/bp.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* eslint-env node */

'use strict';

module.exports = function(config) {
config.set({
scripts: [{
id: 'jquery',
src: 'jquery-noop.js'
},
{
id: 'angular',
src: '/build/angular.js'
},
{
src: 'app.js'
}]
});
};
1 change: 1 addition & 0 deletions benchmarks/largetable-bp/jquery-noop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
106 changes: 106 additions & 0 deletions benchmarks/largetable-bp/main.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<style>
[ng-cloak] { display: none; }
</style>
<div ng-app="largetableBenchmark" ng-cloak>
<div ng-controller="DataController">
<div class="container-fluid">
<p>
Large table rendered with AngularJS
</p>

<div><label><input type="radio" ng-model="benchmarkType" value="none">none: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="baselineBinding">baseline binding: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="baselineInterpolation">baseline interpolation: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="ngBind">ngBind: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="ngBindOnce">ngBindOnce: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="interpolation">interpolation: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="bindOnceInterpolation">interpolation + bind-once: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="interpolationAttr">attribute interpolation: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="ngBindFn">ngBind + fnInvocation: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="interpolationFn">interpolation + fnInvocation: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="ngBindFilter">ngBind + filter: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="interpolationFilter">interpolation + filter: </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="ngModelConstName">ngModel (const name): </label></div>
<div><label><input type="radio" ng-model="benchmarkType" value="ngModelInterpName">ngModel (interp name): </label></div>

<ng-switch on="benchmarkType">
<baseline-binding-table ng-switch-when="baselineBinding">
</baseline-binding-table>
<baseline-interpolation-table ng-switch-when="baselineInterpolation">
</baseline-interpolation-table>
<div ng-switch-when="ngBind">
<h2>baseline binding</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row">
<span ng-bind="column.i"></span>:<span ng-bind="column.j"></span>|
</span>
</div>
</div>
<div ng-switch-when="ngBindOnce">
<h2>baseline binding once</h2>
<div ng-repeat="row in ::data">
<span ng-repeat="column in ::row">
<span ng-bind="::column.i"></span>:<span ng-bind="::column.j"></span>|
</span>
</div>
</div>
<div ng-switch-when="interpolation">
<h2>baseline interpolation</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row">{{column.i}}:{{column.j}}|</span>
</div>
</div>
<div ng-switch-when="bindOnceInterpolation">
<h2>baseline one-time interpolation</h2>
<div ng-repeat="row in ::data">
<span ng-repeat="column in ::row">{{::column.i}}:{{::column.j}}|</span>
</div>
</div>
<div ng-switch-when="interpolationAttr">
<h2>attribute interpolation</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row" i="{{column.i}}" j="{{column.j}}">i,j attrs</span>
</div>
</div>
<div ng-switch-when="ngBindFn">
<h2>bindings with functions</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row"><span ng-bind="column.iFn()"></span>:<span ng-bind="column.jFn()"></span>|</span>
</div>
</div>
<div ng-switch-when="interpolationFn">
<h2>interpolation with functions</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row">{{column.iFn()}}:{{column.jFn()}}|</span>
</div>
</div>
<div ng-switch-when="ngBindFilter">
<h2>bindings with filter</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row"><span ng-bind="column.i | noop"></span>:<span ng-bind="column.j | noop"></span>|</span>
</div>
</div>
<div ng-switch-when="interpolationFilter">
<h2>interpolation with filter</h2>
<div ng-repeat="row in data">
<span ng-repeat="column in row">{{column.i | noop}}:{{column.j | noop}}|</span>
</div>
</div>
<div ng-switch-when="ngModelConstName">
<h2>ngModel (const name)</h2>
<div ng-repeat="row in data">
<input type="text" ng-model="row.i" name="constName" />
<input type="text" ng-model="row.j" />
</div>
</div>
<div ng-switch-when="ngModelInterpName">
<h2>ngModel (interp name)</h2>
<div ng-repeat="(rowIdx, row) in data">
<input type="text" ng-model="row.i" name="input-{{rowIdx}}" />
<input type="text" ng-model="row.j" name="input2-{{rowIdx}}" />
</div>
</div>
</ng-switch>
</div>
</div>
</div>
108 changes: 108 additions & 0 deletions benchmarks/ng-class-bp/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
'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 changes: 15 additions & 0 deletions benchmarks/ng-class-bp/bp.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* eslint-env node */

'use strict';

module.exports = function(config) {
config.set({
scripts: [{
id: 'angular',
src: '/build/angular.js'
},
{
src: 'app.js'
}]
});
};
Loading