Compare commits
217 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 19a0c9324c | |||
| 9ef02e72ab | |||
| 2101126ce7 | |||
| a222d0b452 | |||
| 1b8eb231c9 | |||
| 06baf1869b | |||
| 82597fc12b | |||
| ff52b188a7 | |||
| dc41f465ba | |||
| 6e3b5a57cd | |||
| f003d93a3d | |||
| aac5623247 | |||
| aa03812fd0 | |||
| bcb6a494de | |||
| a1e3f8728e | |||
| 9e8e3e187d | |||
| c6554433cf | |||
| 43d2a75f4e | |||
| 37d2b50812 | |||
| 8f31f1ff43 | |||
| cf84fcf544 | |||
| f63bc3cfde | |||
| a77943110e | |||
| ec97686f2f | |||
| 4ff7b7aa48 | |||
| 57b837bd5c | |||
| 6daca023e4 | |||
| 91b4eb0f69 | |||
| e50ed4da9e | |||
| fe5dd1da8f | |||
| df4c03fa33 | |||
| 8d4e626326 | |||
| 92aef5d456 | |||
| eed13cf732 | |||
| e90200b4de | |||
| 7f36ba77a0 | |||
| 457c58827b | |||
| aae768611f | |||
| ce5ffbf667 | |||
| ab114af850 | |||
| 2759788737 | |||
| c643323c17 | |||
| 9b97a033b0 | |||
| a3226d01fa | |||
| 510d0f946f | |||
| 0b962d4881 | |||
| 71b4daa4e1 | |||
| e0b02a5040 | |||
| a0dd9b0fdd | |||
| 498bef199a | |||
| 17d34b7a98 | |||
| 72359fd097 | |||
| 72882190f2 | |||
| fd2d8a5755 | |||
| fbe84f95a1 | |||
| 3671a43be4 | |||
| f6a1ad528d | |||
| d9128e7b23 | |||
| 0b54c1d4a9 | |||
| 608d623b55 | |||
| 9f30bb5475 | |||
| 182fb18f00 | |||
| 3a9fdceeee | |||
| ee4ac72170 | |||
| eb9fc571a0 | |||
| b4d1e5e492 | |||
| 60394a9d91 | |||
| f5ddb10b56 | |||
| 6a448d3459 | |||
| 6a8c0f5f4a | |||
| 584308fc06 | |||
| 48ad2c44bf | |||
| 100998330a | |||
| b9e85c62be | |||
| 77fad099d2 | |||
| e1f8a6e82b | |||
| 132d767647 | |||
| 9cde98cbc7 | |||
| 1ddbb3ec3e | |||
| 34f40266b2 | |||
| b8c06e3f1b | |||
| a6cf648b3c | |||
| aebde27f1b | |||
| c9be327d53 | |||
| 3dc7d22d90 | |||
| c10c6cac74 | |||
| cee2c4c569 | |||
| a5160c82dc | |||
| 8853312197 | |||
| 049b24de21 | |||
| a9f987a0c9 | |||
| ad4a20d3d2 | |||
| b3972d1b65 | |||
| c3e0d58b3c | |||
| f08156ea9b | |||
| 4bacf5a5da | |||
| df88873bb7 | |||
| c4b1c5e8f1 | |||
| 9822711ad2 | |||
| 30cd764b6d | |||
| 38b75cdb2d | |||
| 6cb8b39af8 | |||
| ebaa336614 | |||
| ef5f567f91 | |||
| 64e5afc478 | |||
| 1e582e4fa4 | |||
| 7421235f24 | |||
| 09ba69078d | |||
| 3536e83d8a | |||
| 3bb1dd5d7f | |||
| 95f964b827 | |||
| c8f78a8ca9 | |||
| f34d48087b | |||
| 2c9ecd01b1 | |||
| a584fb6e15 | |||
| 1f13313f40 | |||
| 5b60303781 | |||
| 10e2552a7d | |||
| ef48b0aa55 | |||
| f57872bca0 | |||
| 2deaf2877e | |||
| 7a146c9cd5 | |||
| 2796ec172b | |||
| 6997c1bf0c | |||
| 4a030f3834 | |||
| f78d8b8ff3 | |||
| f27d19ed60 | |||
| 4a5eaf7bec | |||
| 8513674911 | |||
| 97b74ad6fb | |||
| a47ea79023 | |||
| 5ca0de6487 | |||
| 50a449f053 | |||
| d7422da7d7 | |||
| c7cbc978c6 | |||
| 27146e8a7f | |||
| 5e418b1145 | |||
| f4bb973eb7 | |||
| 848857aa5b | |||
| ee8a05d3f1 | |||
| 275ebbf0ec | |||
| 0f23df4c06 | |||
| 11f700f7bd | |||
| 5785f2a991 | |||
| 2546c29f81 | |||
| 19ea708c9d | |||
| 5cf05d67f2 | |||
| 0377c6f0e8 | |||
| 9c13866824 | |||
| 419a4813e3 | |||
| 131af8272d | |||
| c219a46f59 | |||
| 25f008f541 | |||
| 4a593db79b | |||
| ad4fef0431 | |||
| 8a15fcc1f5 | |||
| f01212ab52 | |||
| 28693a1a67 | |||
| 29fd499552 | |||
| 2f97d9d647 | |||
| 4146b38459 | |||
| 05aab660ce | |||
| 5ecb64849e | |||
| 59dfe1b5a0 | |||
| 50ebfb735c | |||
| 0bdbfe5069 | |||
| 3fc4d6028c | |||
| 2eb12a052b | |||
| bd63b2235c | |||
| f418ffd083 | |||
| 6ab5f8ce4b | |||
| becfeb5aa3 | |||
| eb968c4a68 | |||
| 7f2af3f923 | |||
| cce98ff53a | |||
| b607618342 | |||
| fa50fbaf57 | |||
| f135e2dc05 | |||
| 780351db5e | |||
| a50bb0bfec | |||
| 4d86df6f48 | |||
| bb464d16b4 | |||
| 85b2eb1472 | |||
| 7608f92c6a | |||
| c0bf8db63c | |||
| c95a6737fb | |||
| cd43d24402 | |||
| 086c5d0354 | |||
| 2a2ac5f53a | |||
| 21deaf637a | |||
| 72e15a3a83 | |||
| 174cb4a8c8 | |||
| 33f769b0a1 | |||
| c8abf20558 | |||
| 6dbb183e75 | |||
| bc4844d3b2 | |||
| 708f8b47de | |||
| 5518126d42 | |||
| 5fe73fdc3a | |||
| 394c496bf2 | |||
| 8e1aeba715 | |||
| 0e6e7eb477 | |||
| 183f636816 | |||
| 5f8ed63f2a | |||
| e4f3c94e31 | |||
| 1e5cbcbd93 | |||
| dcf3ec160f | |||
| a7beb5b6d3 | |||
| 1d3b65adc2 | |||
| d528644fe3 | |||
| 6f1bcfc14e | |||
| 996914c6b0 | |||
| fff048d099 | |||
| dcb0da8225 | |||
| b664e20d12 | |||
| 3d68b95028 | |||
| 163aca336d |
@@ -1,509 +0,0 @@
|
||||
# Configuration file for https://circleci.com/gh/angular/angular.js
|
||||
|
||||
# Note: YAML anchors allow an object to be re-used, reducing duplication.
|
||||
# The ampersand declares an alias for an object, then later the `<<: *name`
|
||||
# syntax dereferences it.
|
||||
# See http://blog.daemonl.com/2016/02/yaml.html
|
||||
# To validate changes, use an online parser, eg.
|
||||
# http://yaml-online-parser.appspot.com/
|
||||
|
||||
# CircleCI configuration version
|
||||
# Version 2.1 allows for extra config reuse features
|
||||
# https://circleci.com/docs/2.0/reusing-config/#getting-started-with-config-reuse
|
||||
version: 2.1
|
||||
|
||||
# Workspace persisted by the `setup` job to share build artifacts with other jobs.
|
||||
# https://circleci.com/docs/2.0/workflows/#using-workspaces-to-share-data-among-jobs
|
||||
# https://circleci.com/blog/deep-diving-into-circleci-workspaces/
|
||||
var_workspace_location: &workspace_location ~/
|
||||
|
||||
# Executor Definitions
|
||||
# https://circleci.com/docs/2.0/reusing-config/#authoring-reusable-executors
|
||||
# **NOTE 1**: Pin to exact images using an ID (SHA). See https://circleci.com/docs/2.0/circleci-images/#using-a-docker-image-id-to-pin-an-image-to-a-fixed-version.
|
||||
# (Using the tag in not necessary when pinning by ID, but include it anyway for documentation purposes.)
|
||||
executors:
|
||||
default-executor:
|
||||
parameters:
|
||||
resource_class:
|
||||
type: string
|
||||
default: medium
|
||||
docker:
|
||||
- image: circleci/node:14.16.1@sha256:b094e85848b43209ca83d9bb114d406fe62c75cb73b18c9d8eb1a9c6462c97d4
|
||||
resource_class: << parameters.resource_class >>
|
||||
working_directory: ~/ng
|
||||
cloud-sdk:
|
||||
description: The docker container to use when running gcp-gcs commands
|
||||
docker:
|
||||
- image: google/cloud-sdk:alpine@sha256:7d0cae28cb282b76f2d9babe278c63c910d54f0cceca7a65fdf6806e2b43882e
|
||||
working_directory: ~/ng
|
||||
|
||||
|
||||
# Filter Definitions
|
||||
|
||||
# Filter to run a job on all branches and any `v1.X.Y(-Z)` tags.
|
||||
# Since the jobs need to run on tagged builds too, a `tags` section has to be explicitly specified.
|
||||
# (The `branches` section could be omitted, since it defaults to all branches - just being explicit
|
||||
# here).
|
||||
# See also https://circleci.com/docs/2.0/workflows/#executing-workflows-for-a-git-tag.
|
||||
var-filter-run-always: &run-always
|
||||
filters:
|
||||
branches:
|
||||
only: /.*/
|
||||
tags:
|
||||
only: /v1\.\d+\.\d.*/
|
||||
|
||||
# Filter to run a job when code might need to be deployed - i.e. on builds for the `master` branch.
|
||||
# (Further checks are needed to determine whether a deployment is actually needed, but these are not
|
||||
# possible via filters.)
|
||||
var-filter-run-on-master: &run-on-master
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
tags:
|
||||
ignore: /.*/
|
||||
|
||||
# Filter to run a job when code/docs might need to be deployed - i.e. on tagged builds and on builds
|
||||
# for master and `v1.*.x` branches.
|
||||
# (Further checks are needed to determine whether a deployment is actually needed, but these are not
|
||||
# possible via filters.)
|
||||
var-filter-run-on-tags-and-master-and-version-branches: &run-on-tags-and-master-and-version-branches
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- /v1\.\d+\.x/
|
||||
tags:
|
||||
only: /v1\.\d+\.\d.*/
|
||||
|
||||
# Filter to run a job when docs might need to be deployed - i.e. on builds for `v1.*.x` branches,
|
||||
# which might correspond to the stable branch.
|
||||
# (Further checks are needed to determine whether a deployment is actually needed, but these are not
|
||||
# possible via filters.)
|
||||
var-filter-run-on-version-branches: &run-on-version-branches
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- /v1\.\d+\.x/
|
||||
tags:
|
||||
ignore: /.*/
|
||||
|
||||
|
||||
# Command Definitions
|
||||
# https://circleci.com/docs/2.0/reusing-config/#authoring-reusable-commands
|
||||
commands:
|
||||
skip_on_pr_and_fork_builds:
|
||||
description: Skip a job on pull request and fork builds
|
||||
steps:
|
||||
- run:
|
||||
name: Skip this job if this is a pull request or fork build
|
||||
# Note: Using `CIRCLE_*` env variables (instead of those defined in `env.sh` so that this
|
||||
# step can be run before `init_environment`.
|
||||
command: >
|
||||
if [[ -n "$CIRCLE_PR_NUMBER" ]] ||
|
||||
[[ "$CIRCLE_PROJECT_USERNAME" != "angular" ]] ||
|
||||
[[ "$CIRCLE_PROJECT_REPONAME" != "angular.js" ]]; then
|
||||
echo "Skipping this job, because this is either a pull request or a fork build."
|
||||
circleci step halt
|
||||
fi
|
||||
|
||||
skip_unless_stable_branch:
|
||||
description: Skip a job unless this is the stable branch
|
||||
steps:
|
||||
- run:
|
||||
name: Skip this job unless this is the stable branch
|
||||
command: >
|
||||
if [[ "$DIST_TAG" != "latest" ]]; then
|
||||
echo "Skipping deployment, because this is not the stable branch."
|
||||
circleci step halt
|
||||
fi
|
||||
|
||||
skip_unless_tag_or_master_or_stable_branch:
|
||||
description: Skip a job unless this is a tag or the master or stable branch
|
||||
steps:
|
||||
- run:
|
||||
name: Skip this job unless this is a tag or the master or stable branch
|
||||
command: >
|
||||
if [[ "$CI_GIT_TAG" == "false" ]] &&
|
||||
[[ "$CI_BRANCH" != "master" ]] &&
|
||||
[[ "$DIST_TAG" != "latest" ]]; then
|
||||
echo "Skipping this job, because this is neither a tag nor the master or stable branch."
|
||||
circleci step halt
|
||||
fi
|
||||
|
||||
|
||||
custom_attach_workspace:
|
||||
description: Attach workspace at a predefined location
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: *workspace_location
|
||||
|
||||
# Java is needed for running the Closure Compiler (during the `minall` task).
|
||||
install_java:
|
||||
description: Install java
|
||||
steps:
|
||||
- run:
|
||||
name: Install java
|
||||
command: |
|
||||
sudo apt-get update
|
||||
# Install java runtime
|
||||
sudo apt-get install default-jre
|
||||
|
||||
# Initializes the CI environment by setting up common environment variables.
|
||||
init_environment:
|
||||
description: Initializing environment (setting up variables)
|
||||
steps:
|
||||
- run:
|
||||
name: Set up environment
|
||||
environment:
|
||||
CIRCLE_GIT_BASE_REVISION: << pipeline.git.base_revision >>
|
||||
CIRCLE_GIT_REVISION: << pipeline.git.revision >>
|
||||
command: ./.circleci/env.sh
|
||||
- run:
|
||||
# Configure git as the CircleCI `checkout` command does.
|
||||
# This is needed because we only checkout on the setup job.
|
||||
# Add GitHub to known hosts
|
||||
name: Configure git
|
||||
command: |
|
||||
mkdir -p ~/.ssh
|
||||
echo 'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts
|
||||
git config --global url."ssh://git@github.com".insteadOf "https://github.com" || true
|
||||
git config --global gc.auto 0 || true
|
||||
|
||||
init_saucelabs_environment:
|
||||
description: Sets up a domain that resolves to the local host.
|
||||
steps:
|
||||
- run:
|
||||
name: Preparing environment for running tests on Saucelabs.
|
||||
command: |
|
||||
# For SauceLabs jobs, we set up a domain which resolves to the machine which launched
|
||||
# the tunnel. We do this because devices are sometimes not able to properly resolve
|
||||
# `localhost` or `127.0.0.1` through the SauceLabs tunnel. Using a domain that does not
|
||||
# resolve to anything on SauceLabs VMs ensures that such requests are always resolved
|
||||
# through the tunnel, and resolve to the actual tunnel host machine (i.e. the CircleCI VM).
|
||||
# More context can be found in: https://github.com/angular/angular/pull/35171.
|
||||
setPublicVar SAUCE_LOCALHOST_ALIAS_DOMAIN "angular-ci.local"
|
||||
setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
|
||||
- run:
|
||||
# Sets up a local domain in the machine's host file that resolves to the local
|
||||
# host. This domain is helpful in Saucelabs tests where devices are not able to
|
||||
# properly resolve `localhost` or `127.0.0.1` through the sauce-connect tunnel.
|
||||
name: Setting up alias domain for local host.
|
||||
command: echo "127.0.0.1 $SAUCE_LOCALHOST_ALIAS_DOMAIN" | sudo tee -a /etc/hosts
|
||||
|
||||
start_saucelabs:
|
||||
steps:
|
||||
- run:
|
||||
name: Starting Saucelabs tunnel service
|
||||
command: ./lib/saucelabs/sauce-service.sh start-ready-wait
|
||||
|
||||
stop_saucelabs:
|
||||
steps:
|
||||
- run:
|
||||
name: Stopping Saucelabs tunnel service
|
||||
command: ./lib/saucelabs/sauce-service.sh stop
|
||||
|
||||
run_e2e_tests:
|
||||
parameters:
|
||||
specs:
|
||||
type: string
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- init_saucelabs_environment
|
||||
- start_saucelabs
|
||||
- run:
|
||||
command: yarn grunt test:circleci-protractor --specs="<< parameters.specs >>"
|
||||
no_output_timeout: 30m
|
||||
- stop_saucelabs
|
||||
|
||||
run_e2e_tests_jquery:
|
||||
parameters:
|
||||
specs:
|
||||
type: string
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- init_saucelabs_environment
|
||||
- start_saucelabs
|
||||
- run:
|
||||
environment:
|
||||
USE_JQUERY: 1
|
||||
command: yarn grunt test:circleci-protractor --specs="<< parameters.specs >>"
|
||||
no_output_timeout: 30m
|
||||
- stop_saucelabs
|
||||
|
||||
# Job definitions
|
||||
# Jobs can include parameters that are passed in the workflow job invocation.
|
||||
# https://circleci.com/docs/2.0/reusing-config/#authoring-parameterized-jobs
|
||||
jobs:
|
||||
setup:
|
||||
executor: default-executor
|
||||
steps:
|
||||
- checkout
|
||||
- init_environment
|
||||
- install_java
|
||||
- run:
|
||||
name: Running Yarn install
|
||||
command: yarn install --frozen-lockfile --non-interactive
|
||||
# Yarn's requests sometimes take more than 10mins to complete.
|
||||
no_output_timeout: 45m
|
||||
- run: yarn grunt package
|
||||
# Persist any changes at this point to be reused by further jobs.
|
||||
# **NOTE**: To add new content to the workspace, always persist on the same root.
|
||||
- persist_to_workspace:
|
||||
root: *workspace_location
|
||||
paths:
|
||||
- ./ng
|
||||
|
||||
lint:
|
||||
executor: default-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- run: yarn grunt ci-checks
|
||||
- run: yarn commitplease "$CI_COMMIT_RANGE"
|
||||
- run: yarn grunt validate-angular-files
|
||||
|
||||
unit-test:
|
||||
executor:
|
||||
name: default-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- install_java
|
||||
- init_saucelabs_environment
|
||||
- run: yarn grunt test:promises-aplus
|
||||
- run:
|
||||
command: yarn grunt test:jqlite --browsers="$BROWSERS" --reporters=spec
|
||||
no_output_timeout: 10m
|
||||
- run:
|
||||
command: yarn grunt test:modules --browsers="$BROWSERS" --reporters=spec
|
||||
no_output_timeout: 10m
|
||||
- run:
|
||||
command: yarn grunt test:docs --browsers="$BROWSERS" --reporters=spec
|
||||
no_output_timeout: 10m
|
||||
|
||||
unit-test-jquery:
|
||||
executor:
|
||||
name: default-executor
|
||||
steps:
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- init_saucelabs_environment
|
||||
- run:
|
||||
command: yarn grunt test:jquery --browsers="$BROWSERS" --reporters=spec
|
||||
no_output_timeout: 10m
|
||||
- run:
|
||||
command: yarn grunt test:jquery-2.2 --browsers="$BROWSERS" --reporters=spec
|
||||
no_output_timeout: 10m
|
||||
- run:
|
||||
command: yarn grunt test:jquery-2.1 --browsers="$BROWSERS" --reporters=spec
|
||||
no_output_timeout: 10m
|
||||
|
||||
e2e-test-1:
|
||||
executor:
|
||||
name: default-executor
|
||||
steps:
|
||||
- run_e2e_tests:
|
||||
specs: test/e2e/tests/**/*.js
|
||||
|
||||
e2e-test-2a:
|
||||
executor:
|
||||
name: default-executor
|
||||
steps:
|
||||
- run_e2e_tests:
|
||||
specs: build/docs/ptore2e/example-ng*/**/default_test.js
|
||||
|
||||
e2e-test-2b:
|
||||
executor:
|
||||
name: default-executor
|
||||
steps:
|
||||
- run_e2e_tests:
|
||||
specs: "build/docs/ptore2e/!(example-ng*)/**/default_test.js"
|
||||
|
||||
e2e-test-jquery-1:
|
||||
executor:
|
||||
name: default-executor
|
||||
steps:
|
||||
- run_e2e_tests_jquery:
|
||||
specs: test/e2e/tests/**/*.js
|
||||
|
||||
e2e-test-jquery-2a:
|
||||
executor:
|
||||
name: default-executor
|
||||
steps:
|
||||
- run_e2e_tests_jquery:
|
||||
specs: build/docs/ptore2e/example-ng*/**/jquery_test.js
|
||||
|
||||
e2e-test-jquery-2b:
|
||||
executor:
|
||||
name: default-executor
|
||||
steps:
|
||||
- run_e2e_tests_jquery:
|
||||
specs: build/docs/ptore2e/!(example-ng*)/**/jquery_test.js
|
||||
|
||||
prepare-deployment:
|
||||
executor:
|
||||
name: default-executor
|
||||
steps:
|
||||
- skip_on_pr_and_fork_builds
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- run: yarn grunt prepareDeploy
|
||||
# Write the deployment files to the workspace to be used by deploy-docs and deploy-code
|
||||
- persist_to_workspace:
|
||||
root: *workspace_location
|
||||
paths:
|
||||
- ./ng
|
||||
|
||||
# The `deploy-code-files` job should only run when all of these conditions are true for the build:
|
||||
# - It is for the `angular/angular.js` repository (not a fork).
|
||||
# - It is not for a pull request.
|
||||
# - It is for a tag or the master branch or the stable branch(*).
|
||||
#
|
||||
# *: The stable branch is the one that has the value `latest` in `package.json > distTag`.
|
||||
deploy-code-files:
|
||||
executor:
|
||||
name: cloud-sdk
|
||||
steps:
|
||||
- skip_on_pr_and_fork_builds
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- skip_unless_tag_or_master_or_stable_branch
|
||||
- run: ls scripts/code.angularjs.org-firebase/deploy
|
||||
- run:
|
||||
name: Authenticate and configure Docker
|
||||
command: |
|
||||
echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=-
|
||||
gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
|
||||
- run:
|
||||
name: Sync files to code.angularjs.org
|
||||
command: |
|
||||
gsutil -m rsync -r scripts/code.angularjs.org-firebase/deploy gs://code-angularjs-org-338b8.appspot.com
|
||||
|
||||
# The `deploy-code-firebase` job should only run when all of these conditions are true for the build:
|
||||
# - It is for the `angular/angular.js` repository (not a fork).
|
||||
# - It is not for a pull request.
|
||||
# - It is for the master branch.
|
||||
# (This is enforced via job filters, so we don't need to a step to check it here.)
|
||||
deploy-code-firebase:
|
||||
executor:
|
||||
name: default-executor
|
||||
steps:
|
||||
- skip_on_pr_and_fork_builds
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
# Install dependencies for Firebase functions to prevent parsing errors during deployment.
|
||||
# See https://github.com/angular/angular.js/pull/16453.
|
||||
- run:
|
||||
name: Install dependencies in `scripts/code.angularjs.org-firebase/functions/`.
|
||||
working_directory: scripts/code.angularjs.org-firebase/functions
|
||||
command: yarn install --frozen-lockfile --ignore-engines --non-interactive
|
||||
- run:
|
||||
name: Deploy to Firebase from `scripts/code.angularjs.org-firebase/`.
|
||||
working_directory: scripts/code.angularjs.org-firebase
|
||||
command: |
|
||||
# Do not use `yarn firebase` as that causes the Firebase CLI to look for `firebase.json`
|
||||
# in the root directory, even if run from inside `scripts/code.angularjs.org-firebase/`.
|
||||
firebase=$(yarn bin)/firebase
|
||||
$firebase use
|
||||
$firebase deploy --message "Commit:\ $CI_COMMIT" --non-interactive --token "$FIREBASE_TOKEN"
|
||||
|
||||
# The `deploy-docs` job should only run when all of these conditions are true for the build:
|
||||
# - It is for the `angular/angular.js` repository (not a fork).
|
||||
# - It is not for a pull request.
|
||||
# - It is for the stable branch(*).
|
||||
#
|
||||
# *: The stable branch is the one that has the value `latest` in `package.json > distTag`.
|
||||
deploy-docs:
|
||||
executor:
|
||||
name: default-executor
|
||||
steps:
|
||||
- skip_on_pr_and_fork_builds
|
||||
- custom_attach_workspace
|
||||
- init_environment
|
||||
- skip_unless_stable_branch
|
||||
# Install dependencies for Firebase functions to prevent parsing errors during deployment.
|
||||
# See https://github.com/angular/angular.js/pull/16453.
|
||||
- run:
|
||||
name: Install dependencies in `scripts/docs.angularjs.org-firebase/functions/`.
|
||||
working_directory: scripts/docs.angularjs.org-firebase/functions
|
||||
command: yarn install --frozen-lockfile --ignore-engines --non-interactive
|
||||
- run:
|
||||
name: Deploy to Firebase from `scripts/docs.angularjs.org-firebase/`.
|
||||
working_directory: scripts/docs.angularjs.org-firebase
|
||||
command: |
|
||||
# Do not use `yarn firebase` as that causes the Firebase CLI to look for `firebase.json`
|
||||
# in the root directory, even if run from inside `scripts/docs.angularjs.org-firebase/`.
|
||||
firebase=$(yarn bin)/firebase
|
||||
$firebase use
|
||||
$firebase deploy --message "Commit:\ $CI_COMMIT" --non-interactive --token "$FIREBASE_TOKEN"
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
default_workflow:
|
||||
jobs:
|
||||
- setup:
|
||||
<<: *run-always
|
||||
- lint:
|
||||
<<: *run-always
|
||||
requires:
|
||||
- setup
|
||||
- unit-test:
|
||||
<<: *run-always
|
||||
requires:
|
||||
- setup
|
||||
- unit-test-jquery:
|
||||
<<: *run-always
|
||||
requires:
|
||||
- setup
|
||||
- e2e-test-1:
|
||||
<<: *run-always
|
||||
requires:
|
||||
- setup
|
||||
- e2e-test-2a:
|
||||
<<: *run-always
|
||||
requires:
|
||||
- setup
|
||||
- e2e-test-2b:
|
||||
<<: *run-always
|
||||
requires:
|
||||
- setup
|
||||
- e2e-test-jquery-1:
|
||||
<<: *run-always
|
||||
requires:
|
||||
- setup
|
||||
- e2e-test-jquery-2a:
|
||||
<<: *run-always
|
||||
requires:
|
||||
- setup
|
||||
- e2e-test-jquery-2b:
|
||||
<<: *run-always
|
||||
requires:
|
||||
- setup
|
||||
- prepare-deployment:
|
||||
<<: *run-on-tags-and-master-and-version-branches
|
||||
requires:
|
||||
- setup
|
||||
- lint
|
||||
- unit-test
|
||||
- unit-test-jquery
|
||||
- e2e-test-1
|
||||
- e2e-test-2a
|
||||
- e2e-test-2b
|
||||
- e2e-test-jquery-1
|
||||
- e2e-test-jquery-2a
|
||||
- e2e-test-jquery-2b
|
||||
- deploy-code-files:
|
||||
<<: *run-on-tags-and-master-and-version-branches
|
||||
requires:
|
||||
- prepare-deployment
|
||||
- deploy-code-firebase:
|
||||
<<: *run-on-master
|
||||
requires:
|
||||
- prepare-deployment
|
||||
- deploy-docs:
|
||||
<<: *run-on-version-branches
|
||||
requires:
|
||||
- prepare-deployment
|
||||
@@ -1,73 +0,0 @@
|
||||
####################################################################################################
|
||||
# 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;
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
#!/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;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# https://editorconfig.org
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
|
||||
+2
-1
@@ -1,4 +1,6 @@
|
||||
bower_components/**
|
||||
build/**
|
||||
docs/bower_components/**
|
||||
docs/app/assets/js/angular-bootstrap/**
|
||||
docs/config/templates/**
|
||||
node_modules/**
|
||||
@@ -7,4 +9,3 @@ src/angular.bind.js
|
||||
src/ngParseExt/ucd.js
|
||||
i18n/closure/**
|
||||
tmp/**
|
||||
vendor/**
|
||||
|
||||
+2
-7
@@ -1,13 +1,8 @@
|
||||
{
|
||||
"extends": "./.eslintrc-base.json",
|
||||
|
||||
"env": {
|
||||
"browser": false,
|
||||
"node": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017
|
||||
},
|
||||
"plugins": [
|
||||
"promise"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
// Stylistic issues
|
||||
"block-spacing": ["error", "always"],
|
||||
"comma-spacing": "error",
|
||||
"id-denylist": ["error", "event"],
|
||||
"id-blacklist": ["error", "event"],
|
||||
"indent": ["error", 2],
|
||||
"key-spacing": ["error", { "beforeColon": false, "afterColon": true, "mode": "minimum" }],
|
||||
"object-curly-spacing": ["error", "never"],
|
||||
|
||||
+18
-33
@@ -1,42 +1,27 @@
|
||||
# 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.
|
||||
***Note*: for support questions, please use one of these channels: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#question. This repository's issues are reserved for feature requests and bug reports.**
|
||||
|
||||
<!--
|
||||
IF YOU DON'T FILL OUT THE FOLLOWING INFORMATION WE MIGHT CLOSE YOUR ISSUE WITHOUT INVESTIGATION
|
||||
-->
|
||||
**Do you want to request a *feature* or report a *bug*?**
|
||||
|
||||
<!--
|
||||
- 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. -->
|
||||
**What is the current behavior?**
|
||||
|
||||
**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/) -->
|
||||
**If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (template: http://plnkr.co/edit/tpl:yBpEi4).**
|
||||
|
||||
**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 -->
|
||||
|
||||
**What is the expected behavior?**
|
||||
|
||||
|
||||
|
||||
**What is the motivation / use case for changing the behavior?**
|
||||
|
||||
|
||||
|
||||
**Which versions of Angular, and which browser / OS are affected by this issue? Did this work in previous versions of Angular? Please also test with the latest stable and snapshot (https://code.angularjs.org/snapshot/) versions.**
|
||||
|
||||
|
||||
|
||||
**Other information (e.g. stacktraces, related issues, suggestions how to fix)**
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
# 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.
|
||||
**What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)**
|
||||
|
||||
<!-- 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)**
|
||||
@@ -21,9 +15,9 @@ See https://blog.angular.io/stable-angularjs-and-long-term-support-7e077635ee9c
|
||||
|
||||
|
||||
**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
|
||||
- [ ] The commit message follows our guidelines: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit-message-format
|
||||
- [ ] Tests for the changes have been added (for bug fixes / features)
|
||||
- [ ] Docs have been added / updated (for bug fixes / features)
|
||||
|
||||
**Other information**:
|
||||
|
||||
|
||||
+4
-6
@@ -9,9 +9,9 @@ performance/temp*.html
|
||||
*~
|
||||
*.swp
|
||||
angular.js.tmproj
|
||||
node_modules/
|
||||
/node_modules/
|
||||
bower_components/
|
||||
angular.xcodeproj
|
||||
.firebase/
|
||||
.idea
|
||||
*.iml
|
||||
.agignore
|
||||
@@ -19,9 +19,7 @@ angular.xcodeproj
|
||||
libpeerconnection.log
|
||||
npm-debug.log
|
||||
/tmp/
|
||||
/scripts/bower/bower-*
|
||||
.vscode
|
||||
*.log
|
||||
*.stackdump
|
||||
scripts/code.angularjs.org-firebase/deploy
|
||||
scripts/docs.angularjs.org-firebase/deploy
|
||||
scripts/docs.angularjs.org-firebase/functions/content
|
||||
*.stackdump
|
||||
@@ -1,29 +0,0 @@
|
||||
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>
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- '6'
|
||||
|
||||
cache:
|
||||
yarn: true
|
||||
directories:
|
||||
- bower_components
|
||||
- docs/bower_components
|
||||
|
||||
branches:
|
||||
except:
|
||||
- /^g3_.*$/
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- JOB=ci-checks
|
||||
- JOB=unit BROWSER_PROVIDER=saucelabs
|
||||
- JOB=docs-e2e BROWSER_PROVIDER=saucelabs
|
||||
- JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=saucelabs
|
||||
- JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=saucelabs
|
||||
global:
|
||||
- CXX=g++-4.8 # node 4 likes the G++ v4.8 compiler
|
||||
- SAUCE_USERNAME=angular-ci
|
||||
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
|
||||
- LOGS_DIR=/tmp/angular-build/logs
|
||||
- BROWSER_PROVIDER_READY_FILE=/tmp/browsersprovider-tunnel-ready
|
||||
|
||||
# node 4 likes the G++ v4.8 compiler
|
||||
# see https://docs.travis-ci.com/user/languages/javascript-with-nodejs#Node.js-v4-(or-io.js-v3)-compiler-requirements
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-4.8
|
||||
|
||||
before_script:
|
||||
- du -sh ./node_modules ./bower_components/ ./docs/bower_components/ || true
|
||||
- ./scripts/travis/before_build.sh
|
||||
|
||||
script:
|
||||
- ./scripts/travis/build.sh
|
||||
|
||||
after_script:
|
||||
- ./scripts/travis/tear_down_browser_provider.sh
|
||||
- ./scripts/travis/print_logs.sh
|
||||
|
||||
notifications:
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/d2120f3f2bb39a4531b2
|
||||
- http://104.197.9.155:8484/hubot/travis/activity #hubot-server
|
||||
on_success: always # options: [always|never|change] default: always
|
||||
on_failure: always # options: [always|never|change] default: always
|
||||
on_start: always # default: false
|
||||
+17
-2310
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
# 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.
|
||||
+186
-116
@@ -3,101 +3,85 @@
|
||||
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)
|
||||
- [Code of Conduct](#coc)
|
||||
- [Question or Problem?](#question)
|
||||
- [Issues and Bugs](#issue)
|
||||
- [Feature Requests](#feature)
|
||||
- [Submission Guidelines](#submit)
|
||||
- [Coding Rules](#rules)
|
||||
- [Commit Message Guidelines](#commit)
|
||||
- [Signing the CLA](#cla)
|
||||
- [Further Info](#info)
|
||||
|
||||
## <a name="coc"></a> Code of Conduct
|
||||
|
||||
Help us keep AngularJS open and inclusive. Please read and follow our [Code of Conduct][coc].
|
||||
Help us keep Angular 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?
|
||||
|
||||
### <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].
|
||||
|
||||
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].
|
||||
## <a name="issue"></a> Found an Issue?
|
||||
|
||||
Stack Overflow is a much better place to ask questions since:
|
||||
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.
|
||||
|
||||
- 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.
|
||||
**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].
|
||||
|
||||
### <a name="feature"></a> Missing a Feature?
|
||||
**Please see the [Submission Guidelines](#submit) below.**
|
||||
|
||||
You can request a new feature by submitting an issue to our [GitHub Repository][github-issues].
|
||||
## <a name="feature"></a> Want a Feature?
|
||||
|
||||
If you would like to implement a new feature then consider what kind of change it is:
|
||||
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 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].
|
||||
* **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.
|
||||
|
||||
### <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!
|
||||
## <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.
|
||||
|
||||
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]**.
|
||||
commit message starts with "docs" and follows the **[Commit Message Guidelines](#commit)** outlined
|
||||
below.
|
||||
|
||||
## <a name="submit"></a> Issue Submission Guidelines
|
||||
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.
|
||||
|
||||
## <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.
|
||||
|
||||
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:
|
||||
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?
|
||||
* **Angular 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.
|
||||
@@ -105,43 +89,41 @@ with quickly:
|
||||
* **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.
|
||||
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
|
||||
### Submitting a Pull Request
|
||||
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]
|
||||
* Please sign our [Contributor License Agreement (CLA)](#cla) before sending pull
|
||||
requests. We cannot accept code without this.
|
||||
* 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
|
||||
* 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][developers.commits]. Adherence to the
|
||||
[commit message conventions][developers.commits] is required, because release notes are
|
||||
automatically generated from these messages.
|
||||
[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.
|
||||
|
||||
```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:
|
||||
* Build your changes locally to ensure all the tests pass:
|
||||
|
||||
```shell
|
||||
yarn grunt test
|
||||
grunt test
|
||||
```
|
||||
|
||||
* Push your branch to GitHub:
|
||||
@@ -150,30 +132,24 @@ Before you submit your pull request consider the following guidelines:
|
||||
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.
|
||||
In GitHub, send a pull request to `angular:master`.
|
||||
If we suggest changes, then:
|
||||
|
||||
* 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.
|
||||
* 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 we suggest changes, then:
|
||||
If the PR gets too outdated we may ask you to rebase and force push to update the PR:
|
||||
|
||||
* 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).
|
||||
```shell
|
||||
git rebase master -i
|
||||
git push origin my-fix-branch -f
|
||||
```
|
||||
|
||||
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.
|
||||
_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._
|
||||
|
||||
That's it! Thank you for your contribution!
|
||||
|
||||
@@ -206,41 +182,135 @@ from the main (upstream) repository:
|
||||
git pull --ff upstream master
|
||||
```
|
||||
|
||||
## <a name="cla"></a> Signing the Contributor License Agreement (CLA)
|
||||
## <a name="rules"></a> Coding Rules
|
||||
|
||||
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!
|
||||
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].
|
||||
* All public API methods **must be documented** with ngdoc, an extended version of jsdoc (we added
|
||||
support for markdown and templating via @ngdoc tag). To see how we document our APIs, please check
|
||||
out the existing ngdocs and see [this wiki page][ngDocs].
|
||||
* With the exceptions listed below, we follow the rules contained in
|
||||
[Google's JavaScript Style Guide][js-style-guide]:
|
||||
* **Do not use namespaces**: Instead, wrap the entire angular code base in an anonymous closure and
|
||||
export our API explicitly rather than implicitly.
|
||||
* Wrap all code at **100 characters**.
|
||||
* Instead of complex inheritance hierarchies, we **prefer simple objects**. We use prototypal
|
||||
inheritance only when absolutely necessary.
|
||||
* We **love functions and closures** and, whenever possible, prefer them over objects.
|
||||
* To write concise code that can be better minified, we **use aliases internally** that map to the
|
||||
external API. See our existing code to see what we mean.
|
||||
* We **don't go crazy with type annotations** for private internal APIs unless it's an internal API
|
||||
that is used throughout AngularJS. The best guidance is to do what makes the most sense.
|
||||
|
||||
## <a name="commit"></a> Git Commit Guidelines
|
||||
|
||||
We have very precise rules over how our git commit messages can be formatted. This leads to **more
|
||||
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.
|
||||
|
||||
### Commit Message Format
|
||||
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
|
||||
format that includes a **type**, a **scope** and a **subject**:
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
<BLANK LINE>
|
||||
<body>
|
||||
<BLANK LINE>
|
||||
<footer>
|
||||
```
|
||||
|
||||
The **header** is mandatory and the **scope** of the header is optional.
|
||||
|
||||
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
|
||||
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.
|
||||
|
||||
### Type
|
||||
Must be one of the following:
|
||||
|
||||
* **feat**: A new feature
|
||||
* **fix**: A bug fix
|
||||
* **docs**: Documentation only changes
|
||||
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
|
||||
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
|
||||
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
|
||||
generation
|
||||
|
||||
### Scope
|
||||
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:
|
||||
|
||||
* use the imperative, present tense: "change" not "changed" nor "changes"
|
||||
* don't capitalize first letter
|
||||
* no dot (.) at the end
|
||||
|
||||
### Body
|
||||
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
|
||||
The body should include the motivation for the change and contrast this with previous behavior.
|
||||
|
||||
### 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].
|
||||
|
||||
**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].
|
||||
|
||||
## <a name="cla"></a> Signing the CLA
|
||||
|
||||
Please sign our Contributor License Agreement (CLA) before sending pull requests. For any code
|
||||
changes to be accepted, the CLA must be signed. It's a quick process, we promise!
|
||||
|
||||
* 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].
|
||||
|
||||
## <a name="info"></a> Further Information
|
||||
You can find out more detailed information about contributing in the
|
||||
[AngularJS documentation][contributing].
|
||||
|
||||
|
||||
[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
|
||||
|
||||
[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
|
||||
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
|
||||
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
|
||||
[contribute]: http://docs.angularjs.org/misc/contribute
|
||||
[contributing]: http://docs.angularjs.org/misc/contribute
|
||||
[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
|
||||
[dev-doc]: https://docs.angularjs.org/guide
|
||||
[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
|
||||
[js-style-guide]: https://google.github.io/styleguide/javascriptguide.xml
|
||||
[jsfiddle]: http://jsfiddle.net/
|
||||
[karma-browserstack]: https://github.com/karma-runner/karma-browserstack-launcher
|
||||
[karma-saucelabs]: https://github.com/karma-runner/karma-sauce-launcher
|
||||
[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
|
||||
|
||||
[](https://github.com/igrigorik/ga-beacon)
|
||||
|
||||
-488
@@ -1,488 +0,0 @@
|
||||
# Developing AngularJS
|
||||
|
||||
* [Development Setup](#setup)
|
||||
* [Running Tests](#tests)
|
||||
* [Coding Rules](#rules)
|
||||
* [Commit Message Guidelines](#commits)
|
||||
* [Writing Documentation](#documentation)
|
||||
|
||||
## <a name="setup"> Development Setup
|
||||
|
||||
This document describes how to set up your development environment to build and test AngularJS, and
|
||||
explains the basic mechanics of using `git`, `node`, `yarn` and `grunt`.
|
||||
|
||||
### Installing Dependencies
|
||||
|
||||
Before you can build AngularJS, you must install and configure the following dependencies on your
|
||||
machine:
|
||||
|
||||
* [Git](http://git-scm.com/): The [Github Guide to
|
||||
Installing Git][git-setup] is a good source of information.
|
||||
|
||||
* [Node.js v8.x (LTS)](http://nodejs.org): We use Node to generate the documentation, run a
|
||||
development web server, run tests, and generate distributable files. Depending on your system,
|
||||
you can install Node either from source or as a pre-packaged bundle.
|
||||
|
||||
We recommend using [nvm](https://github.com/creationix/nvm) (or
|
||||
[nvm-windows](https://github.com/coreybutler/nvm-windows))
|
||||
to manage and install Node.js, which makes it easy to change the version of Node.js per project.
|
||||
|
||||
* [Yarn](https://yarnpkg.com): We use Yarn to install our Node.js module dependencies
|
||||
(rather than using npm). See the detailed [installation instructions][yarn-install].
|
||||
|
||||
* [Java](http://www.java.com): We minify JavaScript using
|
||||
[Closure Tools](https://developers.google.com/closure/), which require Java (version 7 or higher)
|
||||
to be installed and included in your
|
||||
[PATH](http://docs.oracle.com/javase/tutorial/essential/environment/paths.html) variable.
|
||||
|
||||
* [Grunt](http://gruntjs.com): We use Grunt as our build system. We're using it as a local dependency,
|
||||
but you can also add the grunt command-line tool globally (with `yarn global add grunt-cli`), which allows
|
||||
you to leave out the `yarn` prefix for all our grunt commands.
|
||||
|
||||
### Forking AngularJS on Github
|
||||
|
||||
To contribute code to AngularJS, you must have a GitHub account so you can push code to your own
|
||||
fork of AngularJS and open Pull Requests in the [GitHub Repository][github].
|
||||
|
||||
To create a Github account, follow the instructions [here](https://github.com/signup/free).
|
||||
Afterwards, go ahead and [fork](http://help.github.com/forking) the
|
||||
[main AngularJS repository][github].
|
||||
|
||||
|
||||
### Building AngularJS
|
||||
|
||||
To build AngularJS, you clone the source code repository and use Grunt to generate the non-minified
|
||||
and minified AngularJS files:
|
||||
|
||||
```shell
|
||||
# Clone your Github repository:
|
||||
git clone https://github.com/<github username>/angular.js.git
|
||||
|
||||
# Go to the AngularJS directory:
|
||||
cd angular.js
|
||||
|
||||
# Add the main AngularJS repository as an upstream remote to your repository:
|
||||
git remote add upstream "https://github.com/angular/angular.js.git"
|
||||
|
||||
# Install JavaScript dependencies:
|
||||
yarn install
|
||||
|
||||
# Build AngularJS:
|
||||
yarn grunt package
|
||||
```
|
||||
|
||||
**Note:** If you're using Windows, you must use an elevated command prompt (right click, run as
|
||||
Administrator). This is because `yarn grunt package` creates some symbolic links.
|
||||
|
||||
The build output is in the `build` directory. It consists of the following files and
|
||||
directories:
|
||||
|
||||
* `angular-<version>.zip` — The complete zip file, containing all of the release build
|
||||
artifacts.
|
||||
|
||||
* `angular.js` / `angular.min.js` — The regular and minified core AngularJS script file.
|
||||
|
||||
* `angular-*.js` / `angular-*.min.js` — All other AngularJS module script files.
|
||||
|
||||
* `docs/` — A directory that contains a standalone version of the docs
|
||||
(same as served in `docs.angularjs.org`).
|
||||
|
||||
### <a name="local-server"></a> Running a Local Development Web Server
|
||||
|
||||
To debug code, run end-to-end tests, and serve the docs, it is often useful to have a local
|
||||
HTTP server. For this purpose, we have made available a local web server based on Node.js.
|
||||
|
||||
1. To start the web server, run:
|
||||
```shell
|
||||
yarn grunt webserver
|
||||
```
|
||||
|
||||
2. To access the local server, enter the following URL into your web browser:
|
||||
```text
|
||||
http://localhost:8000/
|
||||
```
|
||||
By default, it serves the contents of the AngularJS project directory.
|
||||
|
||||
3. To access the locally served docs, visit this URL:
|
||||
```text
|
||||
http://localhost:8000/build/docs/
|
||||
```
|
||||
|
||||
## <a name="tests"> Running Tests
|
||||
|
||||
### <a name="unit-tests"></a> Running the Unit Test Suite
|
||||
|
||||
We write unit and integration tests with Jasmine and execute them with Karma. To run all of the
|
||||
tests once on Chrome run:
|
||||
|
||||
```shell
|
||||
yarn grunt test:unit
|
||||
```
|
||||
|
||||
To run the tests on other browsers use the command line flag:
|
||||
|
||||
```shell
|
||||
yarn grunt test:unit --browsers=Chrome,Firefox
|
||||
```
|
||||
|
||||
**Note:** there should be _no spaces between browsers_. `Chrome, Firefox` is INVALID.
|
||||
|
||||
If you have a Saucelabs or Browserstack account, you can also run the unit tests on these services
|
||||
via our pre-defined customLaunchers. See the [karma config file](/karma-shared.conf.js) for all pre-configured browsers.
|
||||
|
||||
For example, to run the whole unit test suite on selected browsers:
|
||||
|
||||
```shell
|
||||
# Browserstack
|
||||
yarn grunt test:unit --browsers=BS_Chrome,BS_Firefox,BS_Safari,BS_IE_9,BS_IE_10,BS_IE_11,BS_EDGE,BS_iOS_10
|
||||
# Saucelabs
|
||||
yarn grunt test:unit --browsers=SL_Chrome,SL_Firefox,SL_Safari,SL_IE_9,SL_IE_10,SL_IE_11,SL_EDGE,SL_iOS_10
|
||||
```
|
||||
|
||||
Running these commands requires you to set up [Karma Browserstack][karma-browserstack] or
|
||||
[Karma-Saucelabs][karma-saucelabs], respectively.
|
||||
|
||||
During development, however, it's more productive to continuously run unit tests every time the
|
||||
source or test files change. To execute tests in this mode run:
|
||||
|
||||
1. To start the Karma server, capture Chrome browser and run unit tests, run:
|
||||
|
||||
```shell
|
||||
yarn grunt autotest
|
||||
```
|
||||
|
||||
2. To capture more browsers, open this URL in the desired browser (URL might be different if you
|
||||
have multiple instance of Karma running, read Karma's console output for the correct URL):
|
||||
|
||||
```text
|
||||
http://localhost:9876/
|
||||
```
|
||||
|
||||
3. To re-run tests just change any source or test file.
|
||||
|
||||
|
||||
To learn more about all of the preconfigured Grunt tasks run:
|
||||
|
||||
```shell
|
||||
yarn grunt --help
|
||||
```
|
||||
|
||||
|
||||
### <a name="e2e-tests"></a> Running the End-to-end Test Suite
|
||||
|
||||
AngularJS's end to end tests are run with Protractor. Simply run:
|
||||
|
||||
```shell
|
||||
yarn grunt test:e2e
|
||||
```
|
||||
|
||||
This will start the webserver and run the tests on Chrome.
|
||||
|
||||
## <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].
|
||||
* All public API methods **must be documented** with ngdoc, an extended version of jsdoc (we added
|
||||
support for markdown and templating via @ngdoc tag). To see how we document our APIs, please check
|
||||
out the existing source code and see the section about [writing documentation](#documentation)
|
||||
* With the exceptions listed below, we follow the rules contained in
|
||||
[Google's JavaScript Style Guide][js-style-guide]:
|
||||
* **Do not use namespaces**: Instead, wrap the entire AngularJS code base in an anonymous
|
||||
closure and export our API explicitly rather than implicitly.
|
||||
* Wrap all code at **100 characters**.
|
||||
* Instead of complex inheritance hierarchies, we **prefer simple objects**. We use prototypal
|
||||
inheritance only when absolutely necessary.
|
||||
* We **love functions and closures** and, whenever possible, prefer them over objects.
|
||||
* To write concise code that can be better minified, we **use aliases internally** that map to
|
||||
the external API. See our existing code to see what we mean.
|
||||
* We **don't go crazy with type annotations** for private internal APIs unless it's an internal
|
||||
API that is used throughout AngularJS. The best guidance is to do what makes the most sense.
|
||||
|
||||
### Specific topics
|
||||
|
||||
#### Provider configuration
|
||||
|
||||
When adding configuration (options) to [providers][docs.provider], we follow a special pattern.
|
||||
|
||||
- for each option, add a `method` that ...
|
||||
- works as a getter and returns the current value when called without argument
|
||||
- works as a setter and returns itself for chaining when called with argument
|
||||
- for boolean options, uses the naming scheme `<option>Enabled([enabled])`
|
||||
- non-primitive options (e.g. objects) should be copied or the properties assigned explicitly to a
|
||||
new object so that the configuration cannot be changed during runtime.
|
||||
|
||||
For a boolean config example, see [`$compileProvider#debugInfoEnabled`][code.debugInfoEnabled]
|
||||
|
||||
For an object config example, see [`$location.html5Mode`][code.html5Mode]
|
||||
|
||||
#### Throwing errors
|
||||
|
||||
User-facing errors should be thrown with [`minErr`][code.minErr], a special error function that provides
|
||||
errors ids, templated error messages, and adds a link to a detailed error description.
|
||||
|
||||
The `$compile:badrestrict` error is a good example for a well-defined `minErr`:
|
||||
[code][code.badrestrict] and [description][docs.badrestrict].
|
||||
|
||||
|
||||
## <a name="commits"></a> Git Commit Guidelines
|
||||
|
||||
We have very precise rules over how our git commit messages can be formatted. This leads to **more
|
||||
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.
|
||||
|
||||
### Commit Message Format
|
||||
Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
|
||||
format that includes a **type**, a **scope** and a **subject**:
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
<BLANK LINE>
|
||||
<body>
|
||||
<BLANK LINE>
|
||||
<footer>
|
||||
```
|
||||
|
||||
The **header** is mandatory and the **scope** of the header is optional.
|
||||
|
||||
Any line of the commit message cannot be longer than 100 characters! This allows the message to be easier
|
||||
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.
|
||||
|
||||
### Type
|
||||
Must be one of the following:
|
||||
|
||||
* **feat**: A new feature
|
||||
* **fix**: A bug fix
|
||||
* **docs**: Documentation only changes
|
||||
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing
|
||||
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
|
||||
* **chore**: Changes to the build process or auxiliary tools and libraries such as documentation
|
||||
generation
|
||||
|
||||
### Scope
|
||||
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:
|
||||
|
||||
* use the imperative, present tense: "change" not "changed" nor "changes"
|
||||
* don't capitalize first letter
|
||||
* no dot (.) at the end
|
||||
|
||||
### Body
|
||||
Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
|
||||
The body should include the motivation for the change and contrast this with previous behavior.
|
||||
|
||||
### 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].
|
||||
|
||||
**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].
|
||||
|
||||
## <a name="documentation"></a> Writing Documentation
|
||||
|
||||
The AngularJS project uses a form of [jsdoc](http://usejsdoc.org/) called ngdoc for all of its code
|
||||
documentation.
|
||||
|
||||
This means that all the docs are stored inline in the source code and so are kept in sync as it
|
||||
changes.
|
||||
|
||||
There is also extra content (the developer guide, error pages, the tutorial,
|
||||
and misceallenous pages) that live inside the AngularJS repository as markdown files.
|
||||
|
||||
This means that since we generate the documentation from the source code, we can easily provide
|
||||
version-specific documentation by simply checking out a version of AngularJS and running the build.
|
||||
|
||||
Extracting the source code documentation, processing and building the docs is handled by the
|
||||
documentation generation tool [Dgeni][dgeni].
|
||||
|
||||
### Building and viewing the docs locally
|
||||
The docs can be built from scratch using grunt:
|
||||
|
||||
```shell
|
||||
yarn grunt docs
|
||||
```
|
||||
|
||||
This defers the doc-building task to `gulp`.
|
||||
|
||||
Note that the docs app is using the local build files to run. This means you might first have to run
|
||||
the build:
|
||||
|
||||
```shell
|
||||
yarn grunt build
|
||||
```
|
||||
|
||||
(This is also necessary if you are making changes to minErrors).
|
||||
|
||||
To view the docs, see [Running a Local Development Web Server](#local-server).
|
||||
|
||||
### Writing jsdoc
|
||||
The ngdoc utility has basic support for many of the standard jsdoc directives. But in particular it
|
||||
is interested in the following block tags:
|
||||
|
||||
* `@name name` - the name of the ngdoc document
|
||||
* `@param {type} name description` - describes a parameter of a function
|
||||
* `@returns {type} description` - describes what a function returns
|
||||
* `@requires` - normally indicates that a JavaScript module is required; in an Angular service it is
|
||||
used to describe what other services this service relies on
|
||||
* `@property` - describes a property of an object
|
||||
* `@description` - used to provide a description of a component in markdown
|
||||
* `@link` - specifies a link to a URL or a type in the API reference.
|
||||
Links to the API have the following structure:
|
||||
|
||||
* the module namespace, followed by `.` (optional, default `ng`)
|
||||
* the `@ngdoc` type (see below), followed by `:` (optional, automatically inferred)
|
||||
* the name
|
||||
* the method, property, or anchor (optional)
|
||||
* the display name
|
||||
|
||||
For example: `{@link ng.type:$rootScope.Scope#$new Scope.$new()}`.
|
||||
|
||||
* `@example` - specifies an example. This can be a simple code block, or a
|
||||
[runnable example](#the-example-tag).
|
||||
* `@deprecated` - specifies that the following code is deprecated and should not be used.
|
||||
In The AngularJS docs, there are two specific patterns which can be used to further describe
|
||||
the deprecation: `sinceVersion="<version>"` and `removeVersion="<version>"`
|
||||
|
||||
The `type` in `@param` and `@returns` must be wrapped in `{}` curly braces, e.g. `{Object|Array}`.
|
||||
Parameters can be made optional by *either* appending a `=` to the type, e.g. `{Object=}`, *or* by
|
||||
putting the `[name]` in square brackets.
|
||||
Default values are only possible with the second syntax by appending `=<value>` to the parameter
|
||||
name, e.g. `@param {boolean} [ownPropsOnly=false]`.
|
||||
|
||||
Descriptions can contain markdown formatting.
|
||||
|
||||
#### AngularJS-specific jsdoc directives
|
||||
|
||||
In addition to the standard jsdoc tags, there are a number that are specific to the Angular
|
||||
code-base:
|
||||
|
||||
* `@ngdoc` - specifies the type of thing being documented. See below for more detail.
|
||||
* `@eventType emit|broadcast` - specifies whether the event is emitted or broadcast
|
||||
* `@usage` - shows how to use a `function` or `directive`. Is usually automatically generated.
|
||||
* `@knownIssue` - adds info about known quirks, problems, or limitations with the API, and possibly,
|
||||
workarounds. This section is not for bugs.
|
||||
|
||||
The following are specific to directives:
|
||||
|
||||
* `@animations` - specifies the animations a directive supports
|
||||
* `@multiElement` - specifies if a directive can span over multiple elements
|
||||
* `@priority` - specifies a directive's priority
|
||||
* `@restrict` - is extracted to show the usage of a directive. For example, for [E]lement,
|
||||
[A]ttribute, and [C]lass, use `@restrict ECA`
|
||||
* `@scope` - specifies that a directive will create a new scope
|
||||
|
||||
### The `@ngdoc` Directive
|
||||
This directive helps to specify the template used to render the item being documented. For instance,
|
||||
a directive would have different properties to a filter and so would be documented differently. The
|
||||
commonly used types are:
|
||||
|
||||
* `overview` - a general page (guide, api index)
|
||||
* `provider` - AngularJS provider, such as `$compileProvider` or `$httpProvider`.
|
||||
* `service` - injectable AngularJS service, such as `$compile` or `$http`.
|
||||
* `object` - well defined object (often exposed as a service)
|
||||
* `function` - function that will be available to other methods (such as a helper function within
|
||||
the ng module)
|
||||
* `method` - method on an object/service/controller
|
||||
* `property` - property on an object/service/controller
|
||||
* `event` - AngularJS event that will propagate through the `$scope` tree.
|
||||
* `directive` - AngularJS directive
|
||||
* `filter` - AngularJS filter
|
||||
* `error` - minErr error description
|
||||
|
||||
### General documentation with Markdown
|
||||
|
||||
Any text in tags can contain markdown syntax for formatting. Generally, you can use any markdown
|
||||
feature.
|
||||
|
||||
#### Headings
|
||||
|
||||
Only use *h2* headings and lower, as the page title is set in *h1*. Also make sure you follow the
|
||||
heading hierarchy. This ensures correct table of contents are created.
|
||||
|
||||
#### Code blocks
|
||||
In line code can be specified by enclosing the code in back-ticks (\`).
|
||||
A block of multi-line code can be enclosed in triple back-ticks (\`\`\`) but it is formatted better
|
||||
if it is enclosed in <pre>...</pre> tags and the code lines themselves are indented.
|
||||
|
||||
### Writing runnable (live) examples and e2e tests
|
||||
It is possible to embed examples in the documentation along with appropriate e2e tests. These
|
||||
examples and scenarios will be converted to runnable code within the documentation. So it is
|
||||
important that they work correctly. To ensure this, all these e2e scenarios are run as part of the
|
||||
continuous integration tests.
|
||||
|
||||
If you are adding an example with an e2e test, you should [run the test locally](#e2e-tests) first
|
||||
to ensure it passes. You can change `it(...)` to `fit(...)` to run only your test,
|
||||
but make sure you change it back to `it(...)` before committing.
|
||||
|
||||
#### The `<example>` tag
|
||||
This tag identifies a block of HTML that will define a runnable example. It can take the following
|
||||
attributes:
|
||||
|
||||
* `animations` - if set to `true` then this example uses ngAnimate.
|
||||
* `deps` - Semicolon-separated list of additional angular module files to be loaded,
|
||||
e.g. `angular-animate.js`
|
||||
* `name` - every example should have a name. It should start with the component, e.g directive name,
|
||||
and not contain whitespace
|
||||
* `module` - the name of the app module as defined in the example's JavaScript
|
||||
|
||||
Within this tag we provide `<file>` tags that specify what files contain the example code.
|
||||
|
||||
```
|
||||
<example
|
||||
module="angularAppModule"
|
||||
name="exampleName"
|
||||
deps="angular-animate.js;angular-route.js"
|
||||
animations="true">
|
||||
...
|
||||
<file name="index.html">...</file>
|
||||
<file name="script.js">...</file>
|
||||
<file name="animations.css">...</file>
|
||||
<file name="protractor.js">...</file>
|
||||
...
|
||||
</example>
|
||||
```
|
||||
|
||||
You can see an example of a well-defined example [in the `ngRepeat` documentation][code.ngRepeat-example].
|
||||
|
||||
[closing-issues]: https://help.github.com/articles/closing-issues-via-commit-messages/
|
||||
[Closure guide to i18n changes]: https://github.com/google/closure-library/wiki/Internationalization-%28i18n%29-changes-in-Closure-Library
|
||||
[code.badrestrict]: https://github.com/angular/angular.js/blob/202f1809ad14827a6ac6a125157c605d65e0b551/src/ng/compile.js#L1107-L1110
|
||||
[code.debugInfoEnabled]: https://github.com/angular/angular.js/blob/32fbb2e78f53d765fbb170f7cf99e42e072d363b/src/ng/compile.js#L1378-L1413
|
||||
[code.html5Mode]: https://github.com/angular/angular.js/blob/202f1809ad14827a6ac6a125157c605d65e0b551/src/ng/location.js#L752-L797
|
||||
[code.minErr]: https://github.com/angular/angular.js/blob/202f1809ad14827a6ac6a125157c605d65e0b551/src/minErr.js#L53-L113
|
||||
[code.ngRepeat-example]: https://github.com/angular/angular.js/blob/0822d34b10ea0371c260c80a1486a4d508ea5a91/src/ng/directive/ngRepeat.js#L249-L340
|
||||
[commit-message-format]: https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#
|
||||
[Common Locale Data Repository (CLDR)]: http://cldr.unicode.org
|
||||
[corporate-cla]: http://code.google.com/legal/corporate-cla-v1.0.html
|
||||
[dgeni]: https://github.com/angular/dgeni
|
||||
[docs.badrestrict]: docs/content/error/$compile/badrestrict.ngdoc
|
||||
[docs.provider]: https://code.angularjs.org/snapshot/docs/api/auto/service/$provide#provider
|
||||
[git-revert]: https://git-scm.com/docs/git-revert
|
||||
[git-setup]: https://help.github.com/articles/set-up-git
|
||||
[github-issues]: https://github.com/angular/angular.js/issues
|
||||
[github]: https://github.com/angular/angular.js
|
||||
[js-style-guide]: https://google.github.io/styleguide/javascriptguide.xml
|
||||
[karma-browserstack]: https://github.com/karma-runner/karma-browserstack-launcher
|
||||
[karma-saucelabs]: https://github.com/karma-runner/karma-sauce-launcher
|
||||
[unit-testing]: https://docs.angularjs.org/guide/unit-testing
|
||||
[yarn-install]: https://yarnpkg.com/en/docs/install
|
||||
+37
-180
@@ -4,7 +4,6 @@ var serveFavicon = require('serve-favicon');
|
||||
var serveStatic = require('serve-static');
|
||||
var serveIndex = require('serve-index');
|
||||
var files = require('./angularFiles').files;
|
||||
var mergeFilesFor = require('./angularFiles').mergeFilesFor;
|
||||
var util = require('./lib/grunt/utils.js');
|
||||
var versionInfo = require('./lib/versions/version-info');
|
||||
var path = require('path');
|
||||
@@ -14,9 +13,6 @@ var semver = require('semver');
|
||||
var exec = require('shelljs').exec;
|
||||
var pkg = require(__dirname + '/package.json');
|
||||
|
||||
var codeScriptFolder = util.codeScriptFolder;
|
||||
var docsScriptFolder = util.docsScriptFolder;
|
||||
|
||||
// Node.js version checks
|
||||
if (!semver.satisfies(process.version, pkg.engines.node)) {
|
||||
reportOrFail('Invalid node version (' + process.version + '). ' +
|
||||
@@ -32,7 +28,7 @@ if (!semver.satisfies(currentYarnVersion, expectedYarnVersion)) {
|
||||
}
|
||||
|
||||
// Grunt CLI version checks
|
||||
var expectedGruntVersion = pkg.engines['grunt-cli'];
|
||||
var expectedGruntVersion = pkg.engines.grunt;
|
||||
var currentGruntVersions = exec('grunt --version', {silent: true}).stdout;
|
||||
var match = /^grunt-cli v(.+)$/m.exec(currentGruntVersions);
|
||||
if (!match) {
|
||||
@@ -46,13 +42,14 @@ if (!match) {
|
||||
}
|
||||
|
||||
// Ensure Node.js dependencies have been installed
|
||||
if (!process.env.CI) {
|
||||
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
|
||||
@@ -67,12 +64,6 @@ module.exports = function(grunt) {
|
||||
NG_VERSION.cdn = versionInfo.cdnVersion;
|
||||
var dist = 'angular-' + NG_VERSION.full;
|
||||
|
||||
var deployVersion = NG_VERSION.full;
|
||||
|
||||
if (NG_VERSION.isSnapshot) {
|
||||
deployVersion = NG_VERSION.distTag === 'latest' ? 'snapshot-stable' : 'snapshot';
|
||||
}
|
||||
|
||||
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?');
|
||||
@@ -110,14 +101,16 @@ module.exports = function(grunt) {
|
||||
},
|
||||
testserver: {
|
||||
options: {
|
||||
// We start the webserver as a separate process from the E2E tests
|
||||
// We use end2end task (which does not start the webserver)
|
||||
// and start the webserver as a separate process (in travis_build.sh)
|
||||
// to avoid https://github.com/joyent/libuv/issues/826
|
||||
port: 8000,
|
||||
hostname: '0.0.0.0',
|
||||
middleware: function(connect, options) {
|
||||
var base = Array.isArray(options.base) ? options.base[options.base.length - 1] : options.base;
|
||||
return [
|
||||
function(req, resp, next) {
|
||||
// cache GET requests to speed up tests
|
||||
// cache get requests to speed up tests on travis
|
||||
if (req.method === 'GET') {
|
||||
resp.setHeader('Cache-control', 'public, max-age=3600');
|
||||
}
|
||||
@@ -141,9 +134,7 @@ module.exports = function(grunt) {
|
||||
'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',
|
||||
'modules-ngAnimate': 'karma-modules-ngAnimate.conf.js',
|
||||
'modules-ngMock': 'karma-modules-ngMock.conf.js'
|
||||
modules: 'karma-modules.conf.js'
|
||||
},
|
||||
|
||||
|
||||
@@ -159,18 +150,14 @@ module.exports = function(grunt) {
|
||||
|
||||
protractor: {
|
||||
normal: 'protractor-conf.js',
|
||||
circleci: 'protractor-circleci-conf.js'
|
||||
travis: 'protractor-travis-conf.js',
|
||||
jenkins: 'protractor-jenkins-conf.js'
|
||||
},
|
||||
|
||||
|
||||
clean: {
|
||||
build: ['build'],
|
||||
tmp: ['tmp'],
|
||||
deploy: [
|
||||
codeScriptFolder + '/deploy',
|
||||
docsScriptFolder + '/deploy',
|
||||
docsScriptFolder + '/functions/content'
|
||||
]
|
||||
tmp: ['tmp']
|
||||
},
|
||||
|
||||
eslint: {
|
||||
@@ -181,11 +168,11 @@ module.exports = function(grunt) {
|
||||
'docs/**/*.js',
|
||||
'lib/**/*.js',
|
||||
'scripts/**/*.js',
|
||||
'!scripts/*/*/node_modules/**',
|
||||
'src/**/*.js',
|
||||
'test/**/*.js',
|
||||
'i18n/**/*.js',
|
||||
'!docs/app/assets/js/angular-bootstrap/**',
|
||||
'!docs/bower_components/**',
|
||||
'!docs/config/templates/**',
|
||||
'!src/angular.bind.js',
|
||||
'!i18n/closure/**',
|
||||
@@ -195,6 +182,16 @@ module.exports = function(grunt) {
|
||||
},
|
||||
|
||||
build: {
|
||||
scenario: {
|
||||
dest: 'build/angular-scenario.js',
|
||||
src: [
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
util.wrap([files['angularSrc'], files['angularScenario']], 'ngScenario/angular')
|
||||
],
|
||||
styles: {
|
||||
css: ['css/angular.css', 'css/angular-scenario.css']
|
||||
}
|
||||
},
|
||||
angular: {
|
||||
dest: 'build/angular.js',
|
||||
src: util.wrap([files['angularSrc']], 'angular'),
|
||||
@@ -212,12 +209,6 @@ module.exports = function(grunt) {
|
||||
dest: 'build/angular-touch.js',
|
||||
src: util.wrap(files['angularModules']['ngTouch'], 'module')
|
||||
},
|
||||
touchModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-touch.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngTouch'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
mocks: {
|
||||
dest: 'build/angular-mocks.js',
|
||||
src: util.wrap(files['angularModules']['ngMock'], 'module'),
|
||||
@@ -227,42 +218,18 @@ module.exports = function(grunt) {
|
||||
dest: 'build/angular-sanitize.js',
|
||||
src: util.wrap(files['angularModules']['ngSanitize'], 'module')
|
||||
},
|
||||
sanitizeModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-sanitize.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngSanitize'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
resource: {
|
||||
dest: 'build/angular-resource.js',
|
||||
src: util.wrap(files['angularModules']['ngResource'], 'module')
|
||||
},
|
||||
resourceModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-resource.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngResource'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
messageformat: {
|
||||
dest: 'build/angular-message-format.js',
|
||||
src: util.wrap(files['angularModules']['ngMessageFormat'], 'module')
|
||||
},
|
||||
messageformatModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-message-format.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngMessageFormat'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
messages: {
|
||||
dest: 'build/angular-messages.js',
|
||||
src: util.wrap(files['angularModules']['ngMessages'], 'module')
|
||||
},
|
||||
messagesModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-messages.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngMessages'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
animate: {
|
||||
dest: 'build/angular-animate.js',
|
||||
src: util.wrap(files['angularModules']['ngAnimate'], 'module')
|
||||
@@ -271,32 +238,14 @@ module.exports = function(grunt) {
|
||||
dest: 'build/angular-route.js',
|
||||
src: util.wrap(files['angularModules']['ngRoute'], 'module')
|
||||
},
|
||||
routeModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-route.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngRoute'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
cookies: {
|
||||
dest: 'build/angular-cookies.js',
|
||||
src: util.wrap(files['angularModules']['ngCookies'], 'module')
|
||||
},
|
||||
cookiesModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-cookies.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngCookies'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
aria: {
|
||||
dest: 'build/angular-aria.js',
|
||||
src: util.wrap(files['angularModules']['ngAria'], 'module')
|
||||
},
|
||||
ariaModuleTestBundle: {
|
||||
dest: 'build/test-bundles/angular-aria.js',
|
||||
prefix: 'src/module.prefix',
|
||||
src: mergeFilesFor('karmaModules-ngAria'),
|
||||
suffix: 'src/module.suffix'
|
||||
},
|
||||
parseext: {
|
||||
dest: 'build/angular-parse-ext.js',
|
||||
src: util.wrap(files['angularModules']['ngParseExt'], 'module')
|
||||
@@ -328,7 +277,9 @@ module.exports = function(grunt) {
|
||||
files: [
|
||||
'src/**/*.js',
|
||||
'test/**/*.js',
|
||||
'!test/ngScenario/DescribeSpec.js',
|
||||
'!src/ng/directive/attrs.js', // legitimate xit here
|
||||
'!src/ngScenario/**/*.js',
|
||||
'!test/helpers/privateMocks*.js'
|
||||
],
|
||||
options: {
|
||||
@@ -360,53 +311,7 @@ module.exports = function(grunt) {
|
||||
copy: {
|
||||
i18n: {
|
||||
files: [
|
||||
{
|
||||
src: 'src/ngLocale/**',
|
||||
dest: 'build/i18n/',
|
||||
expand: true,
|
||||
flatten: true
|
||||
}
|
||||
]
|
||||
},
|
||||
deployFirebaseCode: {
|
||||
files: [
|
||||
{
|
||||
cwd: 'build',
|
||||
src: '**',
|
||||
dest: codeScriptFolder + '/deploy/' + deployVersion + '/',
|
||||
expand: true
|
||||
}
|
||||
]
|
||||
},
|
||||
deployFirebaseDocs: {
|
||||
files: [
|
||||
// The source files are needed by the embedded examples in the docs app.
|
||||
{
|
||||
src: ['build/angular*.{js,js.map,min.js}', 'build/sitemap.xml'],
|
||||
dest: docsScriptFolder + '/deploy/',
|
||||
expand: true,
|
||||
flatten: true
|
||||
},
|
||||
{
|
||||
cwd: 'build/docs',
|
||||
src: ['**', '!ptore2e/**', '!index*.html'],
|
||||
dest: docsScriptFolder + '/deploy/',
|
||||
expand: true
|
||||
},
|
||||
{
|
||||
src: 'build/docs/index-production.html',
|
||||
dest: docsScriptFolder + '/deploy/index.html'
|
||||
},
|
||||
{
|
||||
src: 'build/docs/index-production.html',
|
||||
dest: docsScriptFolder + '/functions/content/index.html'
|
||||
},
|
||||
{
|
||||
cwd: 'build/docs',
|
||||
src: 'partials/**',
|
||||
dest: docsScriptFolder + '/functions/content/',
|
||||
expand: true
|
||||
}
|
||||
{ src: 'src/ngLocale/**', dest: 'build/i18n/', expand: true, flatten: true }
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -454,78 +359,30 @@ module.exports = function(grunt) {
|
||||
});
|
||||
|
||||
//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', ['eslint', '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:modules', 'Run the Karma module tests with Karma', [
|
||||
'build',
|
||||
'tests:modules',
|
||||
'tests:modules-ngAnimate',
|
||||
'tests:modules-ngMock'
|
||||
]);
|
||||
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: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:circleci-protractor', 'Run the end to end tests with Protractor for CircleCI builds', [
|
||||
'connect:testserver',
|
||||
'protractor:circleci'
|
||||
]);
|
||||
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: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']);
|
||||
grunt.registerTask('test:e2e', 'Alias for test:protractor', ['test:protractor']);
|
||||
grunt.registerTask('test:promises-aplus',[
|
||||
'build:promises-aplus-adapter',
|
||||
'shell:promises-aplus-tests'
|
||||
]);
|
||||
grunt.registerTask('minify', [
|
||||
'clean',
|
||||
'build',
|
||||
'minall'
|
||||
]);
|
||||
grunt.registerTask('test:promises-aplus',['build:promises-aplus-adapter', 'shell:promises-aplus-tests']);
|
||||
|
||||
grunt.registerTask('minify', ['bower', 'clean', 'build', 'minall']);
|
||||
grunt.registerTask('webserver', ['connect:devserver']);
|
||||
grunt.registerTask('package', [
|
||||
'validate-angular-files',
|
||||
'clean',
|
||||
'buildall',
|
||||
'minall',
|
||||
'collect-errors',
|
||||
'write',
|
||||
'docs',
|
||||
'copy:i18n',
|
||||
'compress:build'
|
||||
]);
|
||||
grunt.registerTask('ci-checks', [
|
||||
'ddescribe-iit',
|
||||
'merge-conflict',
|
||||
'eslint'
|
||||
]);
|
||||
grunt.registerTask('prepareDeploy', [
|
||||
'copy:deployFirebaseCode',
|
||||
'copy:deployFirebaseDocs'
|
||||
]);
|
||||
grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'write', 'docs', 'copy', 'compress']);
|
||||
grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'eslint']);
|
||||
grunt.registerTask('default', ['package']);
|
||||
};
|
||||
|
||||
|
||||
function reportOrFail(message) {
|
||||
if (process.env.CI) {
|
||||
if (process.env.TRAVIS || process.env.JENKINS_HOME) {
|
||||
throw new Error(message);
|
||||
} else {
|
||||
console.log('===============================================================================');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2020 Google LLC. http://angularjs.org
|
||||
Copyright (c) 2010-2017 Google, Inc. http://angularjs.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ 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:
|
||||
Angular's $scope objects can be annotated as:
|
||||
```js
|
||||
/** @type {angular.Scope} */
|
||||
var scope = $scope;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
AngularJS [](https://circleci.com/gh/angular/workflows/angular.js/tree/master)
|
||||
AngularJS [](https://travis-ci.org/angular/angular.js)
|
||||
=========
|
||||
|
||||
AngularJS lets you write client-side web applications as if you had a smarter browser. It lets you
|
||||
@@ -12,40 +12,39 @@ It also helps with server-side communication, taming async callbacks with promis
|
||||
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)
|
||||
* 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
|
||||
|
||||
Documentation
|
||||
--------------------
|
||||
Go to https://docs.angularjs.org
|
||||
Building AngularJS
|
||||
---------
|
||||
[Once you have set up your environment](https://docs.angularjs.org/misc/contribute), just run:
|
||||
|
||||
Contribute
|
||||
grunt package
|
||||
|
||||
|
||||
Running tests
|
||||
-------------
|
||||
To execute all unit tests, use:
|
||||
|
||||
grunt test:unit
|
||||
|
||||
To execute end-to-end (e2e) tests, use:
|
||||
|
||||
grunt package
|
||||
grunt test:e2e
|
||||
|
||||
To learn more about the grunt tasks, run `grunt --help`
|
||||
|
||||
Contribute & Develop
|
||||
--------------------
|
||||
|
||||
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).
|
||||
We've set up a separate document for our [contribution guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md).
|
||||
|
||||
|
||||
[](https://github.com/igrigorik/ga-beacon)
|
||||
@@ -57,12 +56,11 @@ component in an interconnected way like a well-oiled machine. AngularJS is JavaS
|
||||
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
|
||||
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.
|
||||
|
||||
@@ -82,7 +80,7 @@ HTML is also used to determine the wiring of the app. Special attributes in the
|
||||
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.
|
||||
moving parts, we simply define what we want and Angular will take care of the dependencies.
|
||||
|
||||
#### Data Handling made simple
|
||||
Data and Data Models in AngularJS are plain JavaScript objects and one can add and change properties
|
||||
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
# 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.
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
# 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 | |
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
# Triage new issues/PRs on github
|
||||
|
||||
This document shows the steps the AngularJS team is using to triage issues.
|
||||
This document shows the steps the Angular team is using to triage issues.
|
||||
The labels are used later on for [planning releases](#assigning-work).
|
||||
|
||||
|
||||
@@ -45,12 +45,12 @@ This process based on the idea of minimizing user pain
|
||||
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
|
||||
* high - impacts most or all Angular 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
|
||||
* broken expected use - it's hard or impossible for a developer using Angular to accomplish something that Angular should be able to do
|
||||
* confusing - unexpected or inconsistent behavior; hard-to-debug
|
||||
* inconvenience - causes ugly/boilerplate code in apps
|
||||
1. Label `component: *`
|
||||
@@ -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 to the npm registry.
|
||||
> The good news is that you could easily implement this as a third-party module and publish it on Bower and/or to the npm repository.
|
||||
|
||||
|
||||
## Assigning Work
|
||||
|
||||
Vendored
+46
-84
@@ -28,7 +28,6 @@ var angularFiles = {
|
||||
'src/ng/httpBackend.js',
|
||||
'src/ng/interpolate.js',
|
||||
'src/ng/interval.js',
|
||||
'src/ng/intervalFactory.js',
|
||||
'src/ng/jsonpCallbacks.js',
|
||||
'src/ng/locale.js',
|
||||
'src/ng/location.js',
|
||||
@@ -41,7 +40,6 @@ var angularFiles = {
|
||||
'src/ng/sanitizeUri.js',
|
||||
'src/ng/sce.js',
|
||||
'src/ng/sniffer.js',
|
||||
'src/ng/taskTrackerFactory.js',
|
||||
'src/ng/templateRequest.js',
|
||||
'src/ng/testability.js',
|
||||
'src/ng/timeout.js',
|
||||
@@ -76,7 +74,6 @@ var angularFiles = {
|
||||
'src/ng/directive/ngNonBindable.js',
|
||||
'src/ng/directive/ngOptions.js',
|
||||
'src/ng/directive/ngPluralize.js',
|
||||
'src/ng/directive/ngRef.js',
|
||||
'src/ng/directive/ngRepeat.js',
|
||||
'src/ng/directive/ngShowHide.js',
|
||||
'src/ng/directive/ngStyle.js',
|
||||
@@ -106,13 +103,13 @@ var angularFiles = {
|
||||
'src/ngAnimate/animateJs.js',
|
||||
'src/ngAnimate/animateJsDriver.js',
|
||||
'src/ngAnimate/animateQueue.js',
|
||||
'src/ngAnimate/animateCache.js',
|
||||
'src/ngAnimate/animation.js',
|
||||
'src/ngAnimate/ngAnimateSwap.js',
|
||||
'src/ngAnimate/module.js'
|
||||
],
|
||||
'ngCookies': [
|
||||
'src/ngCookies/cookies.js',
|
||||
'src/ngCookies/cookieStore.js',
|
||||
'src/ngCookies/cookieWriter.js'
|
||||
],
|
||||
'ngMessageFormat': [
|
||||
@@ -134,7 +131,6 @@ var angularFiles = {
|
||||
],
|
||||
'ngRoute': [
|
||||
'src/shallowCopy.js',
|
||||
'src/routeToRegExp.js',
|
||||
'src/ngRoute/route.js',
|
||||
'src/ngRoute/routeParams.js',
|
||||
'src/ngRoute/directive/ngView.js'
|
||||
@@ -144,13 +140,13 @@ var angularFiles = {
|
||||
'src/ngSanitize/filter/linky.js'
|
||||
],
|
||||
'ngMock': [
|
||||
'src/routeToRegExp.js',
|
||||
'src/ngMock/angular-mocks.js',
|
||||
'src/ngMock/browserTrigger.js'
|
||||
],
|
||||
'ngTouch': [
|
||||
'src/ngTouch/touch.js',
|
||||
'src/ngTouch/swipe.js',
|
||||
'src/ngTouch/directive/ngClick.js',
|
||||
'src/ngTouch/directive/ngSwipe.js'
|
||||
],
|
||||
'ngAria': [
|
||||
@@ -158,8 +154,26 @@ var angularFiles = {
|
||||
]
|
||||
},
|
||||
|
||||
'angularScenario': [
|
||||
'src/ngScenario/Scenario.js',
|
||||
'src/ngScenario/Application.js',
|
||||
'src/ngScenario/Describe.js',
|
||||
'src/ngScenario/Future.js',
|
||||
'src/ngScenario/ObjectModel.js',
|
||||
'src/ngScenario/Runner.js',
|
||||
'src/ngScenario/SpecRunner.js',
|
||||
'src/ngScenario/dsl.js',
|
||||
'src/ngScenario/matchers.js',
|
||||
'src/ngScenario/output/Html.js',
|
||||
'src/ngScenario/output/Json.js',
|
||||
'src/ngScenario/output/Xml.js',
|
||||
'src/ngScenario/output/Object.js'
|
||||
],
|
||||
|
||||
'angularTest': [
|
||||
'test/helpers/*.js',
|
||||
'test/ngScenario/*.js',
|
||||
'test/ngScenario/output/*.js',
|
||||
'test/*.js',
|
||||
'test/auto/*.js',
|
||||
'test/ng/**/*.js',
|
||||
@@ -176,97 +190,55 @@ var angularFiles = {
|
||||
],
|
||||
|
||||
'karma': [
|
||||
'node_modules/jquery/dist/jquery.js',
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'test/jquery_remove.js',
|
||||
'@angularSrc',
|
||||
'@angularSrcModules',
|
||||
'@angularScenario',
|
||||
'@angularTest'
|
||||
],
|
||||
|
||||
'karmaExclude': [
|
||||
'test/jquery_alias.js',
|
||||
'src/angular-bootstrap.js',
|
||||
'src/ngScenario/angular-bootstrap.js',
|
||||
'src/angular.bind.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngAnimate': [
|
||||
'karmaScenario': [
|
||||
'build/angular-scenario.js',
|
||||
'build/docs/docs-scenario.js'
|
||||
],
|
||||
|
||||
'karmaModules': [
|
||||
'build/angular.js',
|
||||
'build/angular-mocks.js',
|
||||
'@angularSrcModules',
|
||||
'test/modules/no_bootstrap.js',
|
||||
'test/helpers/matchers.js',
|
||||
'test/helpers/privateMocks.js',
|
||||
'test/helpers/support.js',
|
||||
'test/helpers/testabilityPatch.js',
|
||||
'@angularSrcModuleNgAnimate',
|
||||
'test/ngAnimate/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngAria': [
|
||||
'@angularSrcModuleNgAria',
|
||||
'test/ngAria/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngCookies': [
|
||||
'@angularSrcModuleNgCookies',
|
||||
'test/ngCookies/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngMessageFormat': [
|
||||
'@angularSrcModuleNgMessageFormat',
|
||||
'test/ngMessageFormat/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngMessages': [
|
||||
'build/angular-animate.js',
|
||||
'@angularSrcModuleNgMessages',
|
||||
'test/ngMessages/**/*.js'
|
||||
],
|
||||
|
||||
// ngMock doesn't include the base because it must use the ngMock src files
|
||||
'karmaModules-ngMock': [
|
||||
'build/angular.js',
|
||||
'src/ngMock/*.js',
|
||||
'test/modules/no_bootstrap.js',
|
||||
'test/helpers/matchers.js',
|
||||
'test/helpers/privateMocks.js',
|
||||
'test/helpers/support.js',
|
||||
'test/helpers/testabilityPatch.js',
|
||||
'src/routeToRegExp.js',
|
||||
'build/angular-animate.js',
|
||||
'test/ngMock/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngResource': [
|
||||
'@angularSrcModuleNgResource',
|
||||
'test/ngResource/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngRoute': [
|
||||
'build/angular-animate.js',
|
||||
'@angularSrcModuleNgRoute',
|
||||
'test/ngRoute/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngSanitize': [
|
||||
'@angularSrcModuleNgSanitize',
|
||||
'test/ngSanitize/**/*.js'
|
||||
],
|
||||
|
||||
'karmaModules-ngTouch': [
|
||||
'@angularSrcModuleNgTouch',
|
||||
'test/ngTouch/**/*.js'
|
||||
'test/helpers/*.js',
|
||||
'test/ngAnimate/*.js',
|
||||
'test/ngMessageFormat/*.js',
|
||||
'test/ngMessages/*.js',
|
||||
'test/ngMock/*.js',
|
||||
'test/ngCookies/*.js',
|
||||
'test/ngRoute/**/*.js',
|
||||
'test/ngResource/*.js',
|
||||
'test/ngSanitize/**/*.js',
|
||||
'test/ngTouch/**/*.js',
|
||||
'test/ngAria/*.js'
|
||||
],
|
||||
|
||||
'karmaJquery': [
|
||||
'node_modules/jquery/dist/jquery.js',
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'test/jquery_alias.js',
|
||||
'@angularSrc',
|
||||
'@angularSrcModules',
|
||||
'@angularScenario',
|
||||
'@angularTest'
|
||||
],
|
||||
|
||||
'karmaJqueryExclude': [
|
||||
'src/angular-bootstrap.js',
|
||||
'src/ngScenario/angular-bootstrap.js',
|
||||
'test/jquery_remove.js',
|
||||
'src/angular.bind.js'
|
||||
]
|
||||
@@ -276,23 +248,13 @@ var angularFiles = {
|
||||
angularFiles['karmaJquery' + jQueryVersion] = []
|
||||
.concat(angularFiles.karmaJquery)
|
||||
.map(function(path) {
|
||||
if (path.startsWith('node_modules/jquery')) {
|
||||
return path.replace(/^node_modules\/jquery/, 'node_modules/jquery-' + jQueryVersion);
|
||||
if (path.startsWith('bower_components/jquery')) {
|
||||
return path.replace(/^bower_components\/jquery/, 'bower_components/jquery-' + jQueryVersion);
|
||||
}
|
||||
return path;
|
||||
});
|
||||
});
|
||||
|
||||
angularFiles['angularSrcModuleNgAnimate'] = angularFiles['angularModules']['ngAnimate'];
|
||||
angularFiles['angularSrcModuleNgAria'] = angularFiles['angularModules']['ngAria'];
|
||||
angularFiles['angularSrcModuleNgCookies'] = angularFiles['angularModules']['ngCookies'];
|
||||
angularFiles['angularSrcModuleNgMessageFormat'] = angularFiles['angularModules']['ngMessageFormat'];
|
||||
angularFiles['angularSrcModuleNgMessages'] = angularFiles['angularModules']['ngMessages'];
|
||||
angularFiles['angularSrcModuleNgResource'] = angularFiles['angularModules']['ngResource'];
|
||||
angularFiles['angularSrcModuleNgRoute'] = angularFiles['angularModules']['ngRoute'];
|
||||
angularFiles['angularSrcModuleNgSanitize'] = angularFiles['angularModules']['ngSanitize'];
|
||||
angularFiles['angularSrcModuleNgTouch'] = angularFiles['angularModules']['ngTouch'];
|
||||
|
||||
angularFiles['angularSrcModules'] = [].concat(
|
||||
angularFiles['angularModules']['ngAnimate'],
|
||||
angularFiles['angularModules']['ngMessageFormat'],
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
|
||||
@@ -29,16 +29,19 @@ app.directive('bmPeWatch', function() {
|
||||
};
|
||||
});
|
||||
|
||||
//Executes the specified expression as a collection watcher
|
||||
app.directive('bmPeWatchCollection', function() {
|
||||
//Executes the specified expression as a watcher
|
||||
//Adds a simple wrapper method to allow use of $watch instead of $watchCollection
|
||||
app.directive('bmPeWatchLiteral', function($parse) {
|
||||
function retZero() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
compile: function($element, $attrs) {
|
||||
$element.text($attrs.bmPeWatchCollection);
|
||||
$element.text($attrs.bmPeWatchLiteral);
|
||||
return function($scope, $element, $attrs) {
|
||||
$scope.$watchCollection($attrs.bmPeWatchCollection, function(val) {
|
||||
$element.text(val);
|
||||
});
|
||||
$scope.$watch($parse($attrs.bmPeWatchLiteral, retZero));
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -69,7 +72,8 @@ app.controller('DataController', function($scope, $rootScope) {
|
||||
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]))
|
||||
keys: data[i - 1] && (data[i - 1].keys || Object.keys(data[i - 1])),
|
||||
constructor: data[i - 1]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
<label for="complexPath">Complex Paths</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="constructorPath" id="constructorPath">
|
||||
<label for="constructorPath">Constructor Paths</label>
|
||||
($parse special cases "constructor" for security)
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="fieldAccess" id="fieldAccess">
|
||||
<label for="fieldAccess">Field Accessors</label>
|
||||
@@ -60,16 +66,6 @@
|
||||
<input type="radio" ng-model="expressionType" value="arrayLiterals" id="arrayLiterals">
|
||||
<label for="arrayLiterals">Array Literals</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="watchCollection" id="watchCollection">
|
||||
<label for="watchCollection">$watchCollection</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="watchCollectionLiterals" id="watchCollectionLiterals">
|
||||
<label for="watchCollectionLiterals">$watchCollection Literals</label>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!--
|
||||
@@ -92,6 +88,17 @@
|
||||
<span bm-pe-watch="row.keys"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="constructorPath" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="row.index"></span>
|
||||
<span bm-pe-watch="row.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.constructor.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.constructor.constructor.index"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="complexPath" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="row.index"></span>
|
||||
<span bm-pe-watch="row.num0"></span>
|
||||
@@ -208,44 +215,27 @@
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="objectLiterals" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="{foo: rowIdx}"></span>
|
||||
<span bm-pe-watch="{foo: row, bar: rowIdx}"></span>
|
||||
<span bm-pe-watch="{0: row, 1: rowIdx, 2: 3}"></span>
|
||||
<span bm-pe-watch="{str: 'foo', num: rowIdx, b: true}"></span>
|
||||
<span bm-pe-watch="{a: {b: {c: {d: {e: {f: rowIdx}}}}}}"></span>
|
||||
<span bm-pe-watch="{a: rowIdx, b: 1, c: 2, d: 3, e: 4, f: 5, g: rowIdx, h: 6, i: 7, j: 8, k: rowIdx}"></span>
|
||||
<span bm-pe-watch-literal="{foo: rowIdx}"></span>
|
||||
<span bm-pe-watch-literal="{foo: row, bar: rowIdx}"></span>
|
||||
<span bm-pe-watch-literal="{0: row, 1: rowIdx, 2: 3}"></span>
|
||||
<span bm-pe-watch-literal="{str: 'foo', num: rowIdx, b: true}"></span>
|
||||
<span bm-pe-watch-literal="{a: {b: {c: {d: {e: {f: rowIdx}}}}}}"></span>
|
||||
<span bm-pe-watch-literal="{a: rowIdx, b: 1, c: 2, d: 3, e: 4, f: 5, g: rowIdx, h: 6, i: 7, j: 8, k: rowIdx}"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="arrayLiterals" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="[rowIdx]"></span>
|
||||
<span bm-pe-watch="[rowIdx, 0]"></span>
|
||||
<span bm-pe-watch="[rowIdx, 0, 1]"></span>
|
||||
<span bm-pe-watch="[rowIdx, 0, 1, 2]"></span>
|
||||
<span bm-pe-watch="[rowIdx, 0, 1, 2, 3]"></span>
|
||||
<span bm-pe-watch="[[], [rowIdx], [], [], [3], [[[]]]]"></span>
|
||||
<span bm-pe-watch="[rowIdx, undefined, null, true, false]"></span>
|
||||
<span bm-pe-watch="[[][0], [0][0], [][rowIdx]]"></span>
|
||||
<span bm-pe-watch="[0, rowIdx]"></span>
|
||||
<span bm-pe-watch="[0, 1, rowIdx]"></span>
|
||||
<span bm-pe-watch="[0, 1, 2, rowIdx]"></span>
|
||||
<span bm-pe-watch="[0, 1, 2, 3, rowIdx]"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="watchCollection" ng-repeat="(rowIdx, row) in data">
|
||||
<span bm-pe-watch-collection="data"></span>
|
||||
<span bm-pe-watch-collection="row.keys"></span>
|
||||
<span bm-pe-watch-collection="thisProbablyDoesntHaveAValue"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="watchCollectionLiterals" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch-collection="[rowIdx, row]"></span>
|
||||
<span bm-pe-watch-collection="[rowIdx, row, num0, str0, date0, obj, g, h, i, j, k, l, m, n, o, p]"></span>
|
||||
<span bm-pe-watch-collection="{a: rowIdx, b: row, c: num0, d: str0, e: date0, f: obj, g: g, h: h, i: i, j: j, k: k, l: l, m: m, n: n, o: o, p: p}"></span>
|
||||
|
||||
<!-- primitive/valueOf-compatible -->
|
||||
<span bm-pe-watch-collection="[rowIdx, row]"></span>
|
||||
<span bm-pe-watch-collection="[rowIdx, num0, str0, date0, date1, h, i, j, k, l, m, n, o, p]"></span>
|
||||
<span bm-pe-watch-collection="{a: rowIdx, c: num0, d: str0, e: date0, g: date1, h: h, i: i, j: j, k: k, l: l, m: m, n: n, o: o, p: p}"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, 0]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, 0, 1]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, 0, 1, 2]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, 0, 1, 2, 3]"></span>
|
||||
<span bm-pe-watch-literal="[[], [rowIdx], [], [], [3], [[[]]]]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, undefined, null, true, false]"></span>
|
||||
<span bm-pe-watch-literal="[[][0], [0][0], [][rowIdx]]"></span>
|
||||
<span bm-pe-watch-literal="[0, rowIdx]"></span>
|
||||
<span bm-pe-watch-literal="[0, 1, rowIdx]"></span>
|
||||
<span bm-pe-watch-literal="[0, 1, 2, rowIdx]"></span>
|
||||
<span bm-pe-watch-literal="[0, 1, 2, 3, rowIdx]"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('repeatAnimateBenchmark', ['ngAnimate'])
|
||||
.config(function($animateProvider) {
|
||||
$animateProvider.classNameFilter(/animate-/);
|
||||
})
|
||||
.run(function($rootScope) {
|
||||
$rootScope.fileType = 'classfilter';
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('repeatAnimateBenchmark', [])
|
||||
.run(function($rootScope) {
|
||||
$rootScope.fileType = 'noanimate';
|
||||
});
|
||||
@@ -1,7 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('repeatAnimateBenchmark', ['ngAnimate'])
|
||||
.run(function($rootScope) {
|
||||
$rootScope.fileType = 'default';
|
||||
});
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [
|
||||
{
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},
|
||||
{
|
||||
id: 'angular-animate',
|
||||
src: '/build/angular-animate.js'
|
||||
},
|
||||
{
|
||||
id: 'app',
|
||||
src: 'app.js'
|
||||
},
|
||||
{
|
||||
src: 'common.js'
|
||||
}]
|
||||
});
|
||||
};
|
||||
@@ -1,120 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var app = angular.module('repeatAnimateBenchmark');
|
||||
|
||||
app.config(function($compileProvider, $animateProvider) {
|
||||
if ($compileProvider.debugInfoEnabled) {
|
||||
$compileProvider.debugInfoEnabled(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
app.run(function($animate) {
|
||||
if ($animate.enabled) {
|
||||
$animate.enabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
app.controller('DataController', function($scope, $rootScope, $animate) {
|
||||
var totalRows = 500;
|
||||
var totalColumns = 20;
|
||||
|
||||
var data = $scope.data = [];
|
||||
|
||||
function fillData() {
|
||||
if ($animate.enabled) {
|
||||
$animate.enabled($scope.benchmarkType !== 'globallyDisabled');
|
||||
}
|
||||
|
||||
for (var i = 0; i < totalRows; i++) {
|
||||
data[i] = [];
|
||||
for (var j = 0; j < totalColumns; j++) {
|
||||
data[i][j] = {
|
||||
i: i
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'enter',
|
||||
fn: function() {
|
||||
$scope.$apply(function() {
|
||||
fillData();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'leave',
|
||||
fn: function() {
|
||||
$scope.$apply(function() {
|
||||
data = $scope.data = [];
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.directive('disableAnimations', function($animate) {
|
||||
return {
|
||||
link: {
|
||||
pre: function(s, e) {
|
||||
$animate.enabled(e, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.directive('noop', function($animate) {
|
||||
return {
|
||||
link: {
|
||||
pre: angular.noop
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.directive('baseline', function($document) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function($scope, $element) {
|
||||
var document = $document[0];
|
||||
|
||||
var i, j, row, cell, comment;
|
||||
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(':'));
|
||||
|
||||
function createList() {
|
||||
for (i = 0; i < $scope.data.length; i++) {
|
||||
row = document.createElement('div');
|
||||
$element[0].appendChild(row);
|
||||
for (j = 0; j < $scope.data[i].length; j++) {
|
||||
cell = template.cloneNode(true);
|
||||
row.appendChild(cell);
|
||||
cell.childNodes[0].textContent = i;
|
||||
cell.ng339 = 'xxx';
|
||||
comment = document.createComment('ngRepeat end: bar in foo');
|
||||
row.appendChild(comment);
|
||||
}
|
||||
|
||||
comment = document.createComment('ngRepeat end: foo in foos');
|
||||
$element[0].appendChild(comment);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$watch('data.length', function(newVal) {
|
||||
if (newVal === 0) {
|
||||
while ($element[0].firstChild) {
|
||||
$element[0].removeChild($element[0].firstChild);
|
||||
}
|
||||
} else {
|
||||
createList();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
})();
|
||||
@@ -1,70 +0,0 @@
|
||||
<div ng-app="repeatAnimateBenchmark" ng-cloak>
|
||||
<div ng-controller="DataController">
|
||||
<div class="container-fluid">
|
||||
<p>
|
||||
Tests rendering of an ngRepeat with 500 elements.<br>
|
||||
Animations can be enabled / disabled in different ways.<br>
|
||||
Two tests require reloading the app with different module / app configurations.
|
||||
</p>
|
||||
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="none">none: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="baseline">baseline (vanilla Javascript): </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'default'" value="enabled">enabled : </label> (requires <a href="./">app.js</a>)</div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'default' && fileType !== 'classfilter'" value="globallyDisabled">globally disabled:</label> (requires <a href="./">app.js</a> or <a href="?app=app-classfilter.js">app-classfilter.js</a>)</div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'default'" value="disabledParentElement">disabled by $animate.enabled() on parent element: </label> (requires <a href="./">app.js</a>)</div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'noanimate'" value="noanimate">Without ngAnimate:</label> (requires <a href="?app=app-noanimate.js">app-noanimate.js</a>)</div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'classfilter'" value="disabledClassFilter">disabled by classNameFilter on element:</label> (requires <a href="?app=app-classfilter.js">app-classfilter.js</a>)</div>
|
||||
|
||||
<ng-switch on="benchmarkType">
|
||||
<baseline ng-switch-when="baseline">
|
||||
</baseline>
|
||||
<div ng-switch-when="noanimate">
|
||||
<div noop>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="enabled">
|
||||
<div noop>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="globallyDisabled">
|
||||
<div noop>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="disabledClassFilter">
|
||||
<div noop>
|
||||
<div ng-repeat="row in data">
|
||||
<span class="disable-animations" ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="disabledParentElement">
|
||||
<div disable-animations>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-switch>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "angularjs",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"jquery": "3.2.1",
|
||||
"jquery-2.2": "jquery#2.2.4",
|
||||
"jquery-2.1": "jquery#2.1.4",
|
||||
"closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
|
||||
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.4/assets/ng-closure-runner.zip"
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,7 @@ body {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#json,
|
||||
#xml {
|
||||
#json, #xml {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
+2
-6
@@ -1,11 +1,7 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
[ng\:cloak],
|
||||
[ng-cloak],
|
||||
[data-ng-cloak],
|
||||
[x-ng-cloak],
|
||||
.ng-cloak,
|
||||
.x-ng-cloak,
|
||||
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],
|
||||
.ng-cloak, .x-ng-cloak,
|
||||
.ng-hide:not(.ng-hide-animate) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@@ -1,37 +1,3 @@
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.eot?v=1.1.0");
|
||||
src: url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.eot?#iefix&v=1.1.0") format("embedded-opentype"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.woff?v=1.1.0") format("woff"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.ttf?v=1.1.0") format("truetype"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Regular/OpenSans-Regular.svg?v=1.1.0#OpenSansBold") format("svg");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.eot?v=1.1.0");
|
||||
src: url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.eot?#iefix&v=1.1.0") format("embedded-opentype"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.woff?v=1.1.0") format("woff"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.ttf?v=1.1.0") format("truetype"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Semibold/OpenSans-Semibold.svg?v=1.1.0#OpenSansBold") format("svg");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: 'Open Sans';
|
||||
src: url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.eot?v=1.1.0");
|
||||
src: url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.eot?#iefix&v=1.1.0") format("embedded-opentype"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.woff?v=1.1.0") format("woff"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.ttf?v=1.1.0") format("truetype"),
|
||||
url("../components/open-sans-fontface-1.4.0/fonts/Bold/OpenSans-Bold.svg?v=1.1.0#OpenSansBold") format("svg");
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
html, body {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
@@ -478,10 +444,10 @@ iframe.example {
|
||||
#navbar-sub {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 5px;
|
||||
background: rgba(245,245,245,1);
|
||||
background: rgba(245,245,245,0.88);
|
||||
box-shadow: 0 0 2px #999;
|
||||
z-index: 1028;
|
||||
top: 57px;
|
||||
top: 83px;
|
||||
}
|
||||
|
||||
.main-body-grid {
|
||||
@@ -713,14 +679,14 @@ ul.events > li {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
@media only screen and (min-width: 769px) {
|
||||
[ng-include="partialPath"].ng-hide {
|
||||
display: block !important;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) and (max-width: 991px) {
|
||||
@media only screen and (min-width: 769px) and (max-width: 991px) {
|
||||
.main-body-grid {
|
||||
margin-top: 160px;
|
||||
}
|
||||
@@ -729,7 +695,7 @@ ul.events > li {
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767px) {
|
||||
@media only screen and (max-width : 768px) {
|
||||
.picker, .picker select {
|
||||
width: auto;
|
||||
display: block;
|
||||
@@ -905,43 +871,6 @@ iframe[name="example-anchoringExample"] {
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
toc-container {
|
||||
display: block;
|
||||
margin: 15px 10px;
|
||||
}
|
||||
|
||||
toc-container b {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
toc-container .btn {
|
||||
padding: 3px 6px;
|
||||
font-size: 13px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
toc-container > div > toc-tree ul {
|
||||
list-style: none;
|
||||
padding-left: 15px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
toc-container > div > toc-tree > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
toc-container > div > toc-tree > ul > li > toc-tree > ul > li toc-tree > ul li {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.dev-status span {
|
||||
padding: 2px 8px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.security span { background-color: orange; }
|
||||
.stable span { background-color: green; color: white; }
|
||||
.current span { background-color: blue; color: white; }
|
||||
|
||||
@media handheld and (max-width:800px), screen and (max-device-width:800px), screen and (max-width:800px) {
|
||||
.navbar {
|
||||
min-height: auto;
|
||||
@@ -982,7 +911,7 @@ toc-container > div > toc-tree > ul > li > toc-tree > ul > li toc-tree > ul li {
|
||||
|
||||
#navbar-sub {
|
||||
position: relative;
|
||||
top: 0;
|
||||
top: 17px;
|
||||
margin-top: 80px;
|
||||
padding-bottom: 0;
|
||||
margin-bottom: 0;
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 183 B After Width: | Height: | Size: 212 B |
@@ -1,4 +0,0 @@
|
||||
User-agent: *
|
||||
|
||||
# The map files are not required by the app
|
||||
Disallow: /*.map$
|
||||
@@ -9,7 +9,6 @@
|
||||
},
|
||||
|
||||
"globals": {
|
||||
"angular": false,
|
||||
/* testabilityPatch / matchers */
|
||||
"inject": false,
|
||||
"module": false,
|
||||
|
||||
@@ -1,48 +1,51 @@
|
||||
'use strict';
|
||||
|
||||
describe('API pages', function() {
|
||||
describe('doc.angularjs.org', 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/);
|
||||
describe('API pages', function() {
|
||||
|
||||
browser.get('build/docs/index.html#!/api/ng/service/$http');
|
||||
expect(element(by.css('.view-source')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/tree\/.+\/src\/ng\/http\.js#L\d+/);
|
||||
});
|
||||
it('should 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/);
|
||||
|
||||
it('should change the page content when clicking a link to a service', function() {
|
||||
browser.get('build/docs/index.html');
|
||||
browser.get('build/docs/index.html#!/api/ng/service/$http');
|
||||
expect(element(by.css('.view-source')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/tree\/.+\/src\/ng\/http\.js#L\d+/);
|
||||
});
|
||||
|
||||
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
|
||||
ngBindLink.click();
|
||||
it('should change the page content when clicking a link to a service', function() {
|
||||
browser.get('build/docs/index.html');
|
||||
|
||||
var mainHeader = element(by.css('.main-body h1 '));
|
||||
expect(mainHeader.getText()).toEqual('ngClick');
|
||||
});
|
||||
var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]'));
|
||||
ngBindLink.click();
|
||||
|
||||
var mainHeader = element(by.css('.main-body h1 '));
|
||||
expect(mainHeader.getText()).toEqual('ngClick');
|
||||
});
|
||||
|
||||
|
||||
it('should show the functioning input directive example', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/directive/input');
|
||||
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.
|
||||
browser.waitForAngular();
|
||||
// Ensure that the page is loaded before trying to switch frames.
|
||||
browser.waitForAngular();
|
||||
|
||||
browser.switchTo().frame('example-input-directive');
|
||||
browser.switchTo().frame('example-input-directive');
|
||||
|
||||
var nameInput = element(by.model('user.name'));
|
||||
nameInput.sendKeys('!!!');
|
||||
var nameInput = element(by.model('user.name'));
|
||||
nameInput.sendKeys('!!!');
|
||||
|
||||
var code = element.all(by.css('tt')).first();
|
||||
expect(code.getText()).toContain('guest!!!');
|
||||
});
|
||||
var code = element.all(by.css('tt')).first();
|
||||
expect(code.getText()).toContain('guest!!!');
|
||||
});
|
||||
|
||||
it('should trim indentation from code blocks', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/type/$rootScope.Scope');
|
||||
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'));
|
||||
codeBlocks.each(function(codeBlock) {
|
||||
var firstSpan = codeBlock.all(by.css('span')).first();
|
||||
expect(firstSpan.getText()).not.toMatch(/^\W+$/);
|
||||
var codeBlocks = element.all(by.css('pre > code.lang-js'));
|
||||
codeBlocks.each(function(codeBlock) {
|
||||
var firstSpan = codeBlock.all(by.css('span')).first();
|
||||
expect(firstSpan.getText()).not.toMatch(/^\W+$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
describe('directives', function() {
|
||||
|
||||
describe('parameter section', function() {
|
||||
|
||||
it('should show the directive name only if it is a param (attribute) with a value', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/directive/ngInclude');
|
||||
expect(getParamNames().getText()).toContain('ngInclude | src');
|
||||
|
||||
browser.get('build/docs/index.html#!/api/ngRoute/directive/ngView');
|
||||
expect(getParamNames().getText()).not.toContain('ngView');
|
||||
});
|
||||
});
|
||||
|
||||
describe('usage section', function() {
|
||||
|
||||
it('should show the directive name if it is a param (attribute) with a value', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/directive/ngInclude');
|
||||
|
||||
expect(getUsageAs('element', 'ng-include').isPresent()).toBe(true);
|
||||
expect(getUsageAs('attribute', 'ng-include').isPresent()).toBe(true);
|
||||
expect(getUsageAs('CSS class', 'ng-include').isPresent()).toBe(true);
|
||||
});
|
||||
|
||||
it('should show the directive name if it is a void param (attribute)', function() {
|
||||
browser.get('build/docs/index.html#!/api/ngRoute/directive/ngView');
|
||||
|
||||
expect(getUsageAs('element', 'ng-view').isPresent()).toBe(true);
|
||||
expect(getUsageAs('attribute', 'ng-view').isPresent()).toBe(true);
|
||||
expect(getUsageAs('CSS class', 'ng-view').isPresent()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function getParamNames() {
|
||||
var argsSection = element(by.className('input-arguments'));
|
||||
|
||||
var paramNames = argsSection.all(by.css('tr td:nth-child(1)'));
|
||||
|
||||
return paramNames;
|
||||
}
|
||||
|
||||
// Based on the type of directive usage, the directive name will show up in the code block
|
||||
// with a specific class
|
||||
var typeClassMap = {
|
||||
element: 'tag',
|
||||
attribute: 'atn',
|
||||
'CSS class': 'atv'
|
||||
};
|
||||
|
||||
function getUsageAs(type, directiveName) {
|
||||
var usage = element(by.className('usage'));
|
||||
|
||||
var as = usage.element(by.cssContainingText('li', 'as ' + type));
|
||||
|
||||
return as.element(by.cssContainingText('span.' + typeClassMap[type], directiveName));
|
||||
}
|
||||
@@ -21,9 +21,6 @@ describe('docs.angularjs.org', function() {
|
||||
console.log('browser console errors: ' + require('util').inspect(filteredLog));
|
||||
}
|
||||
});
|
||||
|
||||
browser.ignoreSynchronization = false;
|
||||
browser.clearMockModules();
|
||||
});
|
||||
|
||||
|
||||
@@ -52,25 +49,6 @@ describe('docs.angularjs.org', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should include the files for the embedded examples from the same domain', function() {
|
||||
browser.get('build/docs/index-production.html#!api/ng/directive/ngClick');
|
||||
|
||||
var origin = browser.executeScript('return document.location.origin;');
|
||||
|
||||
var exampleIFrame = element(by.name('example-ng-click'));
|
||||
|
||||
// This is technically an implementation detail, but if this changes, then there's a good
|
||||
// chance the deployment process changed
|
||||
expect(exampleIFrame.getAttribute('src')).toContain('examples/example-ng-click/index.html');
|
||||
|
||||
browser.switchTo().frame('example-ng-click');
|
||||
|
||||
var scriptEl = element(by.tagName('script'));
|
||||
|
||||
// Ensure the included file is from the same domain
|
||||
expect(scriptEl.getAttribute('src')).toContain(origin);
|
||||
});
|
||||
|
||||
|
||||
it('should be resilient to trailing slashes', function() {
|
||||
browser.get('build/docs/index-production.html#!/api/ng/function/angular.noop/');
|
||||
@@ -105,66 +83,6 @@ describe('docs.angularjs.org', function() {
|
||||
expect(mainHeader.getText()).toEqual('Oops!');
|
||||
});
|
||||
|
||||
it('should set "noindex" if the page does not exist', function() {
|
||||
browser.get('build/docs/index-production.html#!/api/does/not/exist');
|
||||
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
|
||||
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
|
||||
expect(robots.isPresent()).toBe(true);
|
||||
expect(googleBot.isPresent()).toBe(true);
|
||||
});
|
||||
|
||||
it('should remove "noindex" if the page exists', function() {
|
||||
browser.get('build/docs/index-production.html#!/api');
|
||||
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
|
||||
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
|
||||
expect(robots.isPresent()).toBe(false);
|
||||
expect(googleBot.isPresent()).toBe(false);
|
||||
});
|
||||
|
||||
describe('template request error', function() {
|
||||
beforeEach(function() {
|
||||
browser.addMockModule('httpMocker', function() {
|
||||
angular.module('httpMocker', ['ngMock'])
|
||||
.run(['$httpBackend', function($httpBackend) {
|
||||
$httpBackend.whenGET('localhost:8000/build/docs/partials/api.html').respond(500, '');
|
||||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
it('should set "noindex" for robots if the request fails', function() {
|
||||
// index-test includes ngMock
|
||||
browser.get('build/docs/index-test.html#!/api');
|
||||
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
|
||||
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
|
||||
expect(robots.isPresent()).toBe(true);
|
||||
expect(googleBot.isPresent()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('page bootstrap error', function() {
|
||||
beforeEach(function() {
|
||||
browser.addMockModule('httpMocker', function() {
|
||||
// Require a module that does not exist to break the bootstrapping
|
||||
angular.module('httpMocker', ['doesNotExist']);
|
||||
});
|
||||
});
|
||||
|
||||
it('should have "noindex" for robots if bootstrapping fails', function() {
|
||||
browser.get('build/docs/index.html#!/api').catch(function() {
|
||||
// get() will fail on AngularJS bootstrap, but if we continue here, protractor
|
||||
// will assume the app is ready
|
||||
browser.ignoreSynchronization = true;
|
||||
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
|
||||
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
|
||||
expect(robots.isPresent()).toBe(true);
|
||||
expect(googleBot.isPresent()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* This scenario checks the presence of the table of contents for a sample of pages - API and guide.
|
||||
* The expectations are kept vague so that they can be easily adjusted when the docs change.
|
||||
*/
|
||||
|
||||
describe('table of contents', function() {
|
||||
|
||||
it('on provider pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/provider/$controllerProvider');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
expect(text.join('')).toContain('Overview');
|
||||
expect(text.join('')).toContain('Methods');
|
||||
});
|
||||
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(2);
|
||||
|
||||
expect(match[1].all(by.css('li')).count()).toBe(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('on service pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/service/$controller');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
expect(text.join('')).toContain('Overview');
|
||||
expect(text.join('')).toContain('Usage');
|
||||
});
|
||||
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(3);
|
||||
|
||||
expect(match[2].all(by.css('li')).count()).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('on directive pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/directive/input');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
expect(text.join('')).toContain('Overview');
|
||||
expect(text.join('')).toContain('Usage');
|
||||
expect(text.join('')).toContain('Directive Info');
|
||||
});
|
||||
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(4);
|
||||
|
||||
expect(match[2].all(by.css('li')).count()).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('on function pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/function/angular.bind');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
expect(text.join('')).toContain('Overview');
|
||||
expect(text.join('')).toContain('Usage');
|
||||
});
|
||||
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(2);
|
||||
|
||||
expect(match[1].all(by.css('li')).count()).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('on type pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/type/ModelOptions');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
expect(text.join('')).toContain('Overview');
|
||||
expect(text.join('')).toContain('Methods');
|
||||
});
|
||||
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(2);
|
||||
|
||||
expect(match[1].all(by.css('li')).count()).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('on filter pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/filter/date');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
expect(text.join('')).toContain('Overview');
|
||||
expect(text.join('')).toContain('Usage');
|
||||
});
|
||||
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(3);
|
||||
|
||||
expect(match[1].all(by.css('li')).count()).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('on guide pages', function() {
|
||||
browser.get('build/docs/index.html#!/guide/services');
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(5);
|
||||
|
||||
expect(match[1].all(by.css('li')).count()).toBe(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
+2
-135
@@ -1,8 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
var directivesModule = angular.module('directives', []);
|
||||
angular.module('directives', [])
|
||||
|
||||
directivesModule
|
||||
/**
|
||||
* backToTop Directive
|
||||
* @param {Function} $anchorScroll
|
||||
@@ -48,136 +47,4 @@ directivesModule
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
.directive('tocCollector', ['$rootScope', function($rootScope) {
|
||||
return {
|
||||
controller: ['$element', function($element) {
|
||||
/* eslint-disable no-invalid-this */
|
||||
var ctrl = this;
|
||||
|
||||
$rootScope.$on('$includeContentRequested', function() {
|
||||
ctrl.hs = [];
|
||||
ctrl.root = [];
|
||||
});
|
||||
|
||||
this.hs = [];
|
||||
this.root = [];
|
||||
this.element = $element;
|
||||
|
||||
this.register = function(h) {
|
||||
var previousLevel;
|
||||
|
||||
for (var i = ctrl.hs.length - 1; i >= 0; i--) {
|
||||
if (ctrl.hs[i].level === (h.level - 1)) {
|
||||
previousLevel = ctrl.hs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (previousLevel) {
|
||||
previousLevel.children.push(h);
|
||||
} else {
|
||||
this.root.push(h);
|
||||
}
|
||||
|
||||
ctrl.hs.push(h);
|
||||
/* eslint-enable no-invalid-this */
|
||||
};
|
||||
}]
|
||||
};
|
||||
}])
|
||||
|
||||
.component('tocTree', {
|
||||
template: '<ul>' +
|
||||
'<li ng-repeat="item in $ctrl.items">' +
|
||||
'<a ng-href="{{ $ctrl.path }}#{{item.fragment}}">{{item.title}}</a>' +
|
||||
'<toc-tree ng-if="::item.children.length > 0" items="item.children"></toc-tree>' +
|
||||
'</li>' +
|
||||
'</ul>',
|
||||
bindings: {
|
||||
items: '<'
|
||||
},
|
||||
controller: ['$location', /** @this */ function($location) {
|
||||
this.path = $location.path().replace(/^\/?(.+?)(\/index)?\/?$/, '$1');
|
||||
}]
|
||||
})
|
||||
.directive('tocContainer', function() {
|
||||
return {
|
||||
scope: true,
|
||||
restrict: 'E',
|
||||
require: {
|
||||
tocContainer: '',
|
||||
tocCollector: '^^'
|
||||
},
|
||||
controller: function() {
|
||||
this.showToc = true;
|
||||
this.items = [];
|
||||
},
|
||||
controllerAs: '$ctrl',
|
||||
link: function(scope, element, attrs, ctrls) {
|
||||
ctrls.tocContainer.items = ctrls.tocCollector.root;
|
||||
},
|
||||
template: '<div ng-if="::$ctrl.items.length > 1">' +
|
||||
'<b>Contents</b>' +
|
||||
'<button class="btn" ng-click="$ctrl.showToc = !$ctrl.showToc">{{$ctrl.showToc ? \'Hide\' : \'Show\'}}</button><br>' +
|
||||
'<toc-tree items="$ctrl.items" ng-show="$ctrl.showToc"></toc-tree>' +
|
||||
'</div>'
|
||||
};
|
||||
})
|
||||
.directive('header', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
controller: ['$element', function($element) {
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
this.element = $element;
|
||||
}]
|
||||
};
|
||||
})
|
||||
.directive('h1', ['$compile', function($compile) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: {
|
||||
tocCollector: '^^?',
|
||||
header: '^^?'
|
||||
},
|
||||
link: function(scope, element, attrs, ctrls) {
|
||||
if (!ctrls.tocCollector) return;
|
||||
|
||||
var tocContainer = angular.element('<toc-container></toc-container>');
|
||||
var containerElement = ctrls.header ? ctrls.header.element : element;
|
||||
|
||||
containerElement.after(tocContainer);
|
||||
$compile(tocContainer)(scope);
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
for (var i = 2; i <= 5; i++) {
|
||||
registerHDirective(i);
|
||||
}
|
||||
|
||||
function registerHDirective(i) {
|
||||
directivesModule.directive('h' + i, function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: {
|
||||
'tocCollector': '^^?'
|
||||
},
|
||||
link: function(scope, element, attrs, ctrls) {
|
||||
var toc = ctrls.tocCollector;
|
||||
|
||||
if (!toc || !attrs.id) return;
|
||||
|
||||
toc.register({
|
||||
level: i,
|
||||
fragment: attrs.id,
|
||||
title: element.text(),
|
||||
children: []
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
+5
-11
@@ -8,8 +8,6 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
function($scope, $rootScope, $location, $window, $cookies,
|
||||
NG_PAGES, NG_NAVIGATION, CURRENT_NG_VERSION) {
|
||||
|
||||
var errorPartialPath = 'Error404.html';
|
||||
|
||||
$scope.navClass = function(navItem) {
|
||||
return {
|
||||
active: navItem.href && this.currentPage && this.currentPage.path,
|
||||
@@ -18,6 +16,8 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
$scope.$on('$includeContentLoaded', function() {
|
||||
var pagePath = $scope.currentPage ? $scope.currentPage.path : $location.path();
|
||||
$window._gaq.push(['_trackPageview', pagePath]);
|
||||
@@ -26,7 +26,6 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
|
||||
$scope.$on('$includeContentError', function() {
|
||||
$scope.loading = false;
|
||||
$scope.loadingError = true;
|
||||
});
|
||||
|
||||
$scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) {
|
||||
@@ -36,7 +35,6 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
var currentPage = $scope.currentPage = NG_PAGES[path];
|
||||
|
||||
$scope.loading = true;
|
||||
$scope.loadingError = false;
|
||||
|
||||
if (currentPage) {
|
||||
$scope.partialPath = 'partials/' + path + '.html';
|
||||
@@ -52,22 +50,18 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
} else {
|
||||
$scope.currentArea = NG_NAVIGATION['api'];
|
||||
$scope.breadcrumb = [];
|
||||
$scope.partialPath = errorPartialPath;
|
||||
$scope.partialPath = 'Error404.html';
|
||||
}
|
||||
});
|
||||
|
||||
$scope.hasError = function() {
|
||||
return $scope.partialPath === errorPartialPath || $scope.loadingError;
|
||||
};
|
||||
|
||||
/**********************************
|
||||
Initialize
|
||||
***********************************/
|
||||
|
||||
$scope.versionNumber = CURRENT_NG_VERSION.full;
|
||||
$scope.version = CURRENT_NG_VERSION.full + ' ' + CURRENT_NG_VERSION.codeName;
|
||||
$scope.loading = false;
|
||||
$scope.loadingError = false;
|
||||
$scope.loading = 0;
|
||||
|
||||
|
||||
var INDEX_PATH = /^(\/|\/index[^.]*.html)$/;
|
||||
if (!$location.path() || INDEX_PATH.test($location.path())) {
|
||||
|
||||
@@ -55,7 +55,7 @@ angular.module('examples', [])
|
||||
return function(url, newWindow, fields) {
|
||||
/**
|
||||
* If the form posts to target="_blank", pop-up blockers can cause it not to work.
|
||||
* If a user chooses to bypass pop-up blocker one time and click the link, they will arrive at
|
||||
* If a user choses to bypass pop-up blocker one time and click the link, they will arrive at
|
||||
* a new default plnkr, not a plnkr with the desired template. Given this undesired behavior,
|
||||
* some may still want to open the plnk in a new window by opting-in via ctrl+click. The
|
||||
* newWindow param allows for this possibility.
|
||||
@@ -74,7 +74,7 @@ angular.module('examples', [])
|
||||
}])
|
||||
|
||||
.factory('createCopyrightNotice', function() {
|
||||
var COPYRIGHT = 'Copyright ' + (new Date()).getFullYear() + ' Google LLC. All Rights Reserved.\n'
|
||||
var COPYRIGHT = 'Copyright ' + (new Date()).getFullYear() + ' Google Inc. All Rights Reserved.\n'
|
||||
+ 'Use of this source code is governed by an MIT-style license that\n'
|
||||
+ 'can be found in the LICENSE file at http://angular.io/license';
|
||||
var COPYRIGHT_JS_CSS = '\n\n/*\n' + COPYRIGHT + '\n*/';
|
||||
|
||||
@@ -67,12 +67,6 @@ angular.module('search', [])
|
||||
clearResults();
|
||||
$scope.q = '';
|
||||
};
|
||||
|
||||
$scope.handleResultClicked = function($event) {
|
||||
if ($event.which === 1 && !$event.ctrlKey && !$event.metaKey) {
|
||||
$scope.hideResults();
|
||||
}
|
||||
};
|
||||
}])
|
||||
|
||||
|
||||
|
||||
@@ -12,16 +12,10 @@ angular.module('versions', ['currentVersionData', 'allVersionsData'])
|
||||
/** @this VersionPickerController */
|
||||
function VersionPickerController($location, $window, CURRENT_NG_VERSION, ALL_NG_VERSIONS) {
|
||||
|
||||
var versionStr = CURRENT_NG_VERSION.version;
|
||||
|
||||
if (CURRENT_NG_VERSION.isSnapshot) {
|
||||
versionStr = CURRENT_NG_VERSION.distTag === 'latest' ? 'snapshot-stable' : 'snapshot';
|
||||
}
|
||||
var versionStr = CURRENT_NG_VERSION.isSnapshot ? 'snapshot' : CURRENT_NG_VERSION.version;
|
||||
|
||||
this.versions = ALL_NG_VERSIONS;
|
||||
this.selectedVersion = find(ALL_NG_VERSIONS, function(value) {
|
||||
return value.version.version === versionStr;
|
||||
});
|
||||
this.selectedVersion = find(ALL_NG_VERSIONS, function(value) { return value.version.version === versionStr; });
|
||||
|
||||
this.jumpToDocsVersion = function(value) {
|
||||
var currentPagePath = $location.path().replace(/\/$/, '');
|
||||
|
||||
@@ -1,50 +1,40 @@
|
||||
'use strict';
|
||||
|
||||
describe('directives', function() {
|
||||
describe('code', function() {
|
||||
var prettyPrintOne, oldPP;
|
||||
var compile, scope;
|
||||
|
||||
var any = jasmine.any;
|
||||
|
||||
beforeEach(module('directives'));
|
||||
|
||||
beforeEach(module(function($compileProvider) {
|
||||
$compileProvider.debugInfoEnabled(false);
|
||||
}));
|
||||
|
||||
beforeEach(inject(function($rootScope, $compile) {
|
||||
// Provide stub for pretty print function
|
||||
oldPP = window.prettyPrintOne;
|
||||
prettyPrintOne = window.prettyPrintOne = jasmine.createSpy();
|
||||
|
||||
scope = $rootScope.$new();
|
||||
compile = $compile;
|
||||
}));
|
||||
|
||||
describe('code', function() {
|
||||
var prettyPrintOne, oldPP;
|
||||
var any = jasmine.any;
|
||||
|
||||
beforeEach(function() {
|
||||
// Provide stub for pretty print function
|
||||
oldPP = window.prettyPrintOne;
|
||||
prettyPrintOne = window.prettyPrintOne = jasmine.createSpy();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
window.prettyPrintOne = oldPP;
|
||||
});
|
||||
|
||||
|
||||
it('should pretty print innerHTML', function() {
|
||||
compile('<code>var x;</code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith('var x;', null, false);
|
||||
});
|
||||
|
||||
it('should allow language declaration', function() {
|
||||
compile('<code class="lang-javascript"></code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), 'javascript', false);
|
||||
});
|
||||
|
||||
it('supports allow line numbers', function() {
|
||||
compile('<code class="linenum"></code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), null, true);
|
||||
});
|
||||
afterEach(function() {
|
||||
window.prettyPrintOne = oldPP;
|
||||
});
|
||||
|
||||
|
||||
it('should pretty print innerHTML', function() {
|
||||
compile('<code>var x;</code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith('var x;', null, false);
|
||||
});
|
||||
|
||||
it('should allow language declaration', function() {
|
||||
compile('<code class="lang-javascript"></code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), 'javascript', false);
|
||||
});
|
||||
|
||||
it('supports allow line numbers', function() {
|
||||
compile('<code class="linenum"></code>')(scope);
|
||||
expect(prettyPrintOne).toHaveBeenCalledWith(any(String), null, true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ module.exports = new Package('angularjs', [
|
||||
.factory(require('./services/deployments/debug'))
|
||||
.factory(require('./services/deployments/default'))
|
||||
.factory(require('./services/deployments/jquery'))
|
||||
.factory(require('./services/deployments/test'))
|
||||
.factory(require('./services/deployments/production'))
|
||||
|
||||
.factory(require('./inline-tag-defs/type'))
|
||||
@@ -32,7 +31,6 @@ module.exports = new Package('angularjs', [
|
||||
.processor(require('./processors/keywords'))
|
||||
.processor(require('./processors/pages-data'))
|
||||
.processor(require('./processors/versions-data'))
|
||||
.processor(require('./processors/sitemap'))
|
||||
|
||||
|
||||
.config(function(dgeni, log, readFilesProcessor, writeFilesProcessor) {
|
||||
@@ -148,7 +146,6 @@ module.exports = new Package('angularjs', [
|
||||
|
||||
.config(function(checkAnchorLinksProcessor) {
|
||||
checkAnchorLinksProcessor.base = '/';
|
||||
checkAnchorLinksProcessor.errorOnUnmatchedLinks = true;
|
||||
// We are only interested in docs that have an area (i.e. they are pages)
|
||||
checkAnchorLinksProcessor.checkDoc = function(doc) { return doc.area; };
|
||||
})
|
||||
@@ -159,14 +156,12 @@ module.exports = new Package('angularjs', [
|
||||
generateProtractorTestsProcessor,
|
||||
generateExamplesProcessor,
|
||||
debugDeployment, defaultDeployment,
|
||||
jqueryDeployment, testDeployment,
|
||||
productionDeployment) {
|
||||
jqueryDeployment, productionDeployment) {
|
||||
|
||||
generateIndexPagesProcessor.deployments = [
|
||||
debugDeployment,
|
||||
defaultDeployment,
|
||||
jqueryDeployment,
|
||||
testDeployment,
|
||||
productionDeployment
|
||||
];
|
||||
|
||||
|
||||
@@ -5,36 +5,18 @@
|
||||
* @description
|
||||
* Process "error" docType docs and generate errorNamespace docs
|
||||
*/
|
||||
module.exports = function errorDocsProcessor(log, errorNamespaceMap, getMinerrInfo) {
|
||||
module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
|
||||
return {
|
||||
$runAfter: ['tags-extracted'],
|
||||
$runBefore: ['extra-docs-added'],
|
||||
$process: function(docs) {
|
||||
|
||||
// Get the extracted min errors to compare with the error docs, and report any mismatch
|
||||
var collectedErrors = require('../../../build/errors.json').errors;
|
||||
var flatErrors = [];
|
||||
|
||||
for (var namespace in collectedErrors) {
|
||||
for (var error in collectedErrors[namespace]) {
|
||||
flatErrors.push(namespace + ':' + error);
|
||||
}
|
||||
}
|
||||
|
||||
// Create error namespace docs and attach error docs to each
|
||||
docs.forEach(function(doc) {
|
||||
var parts, namespaceDoc;
|
||||
|
||||
if (doc.docType === 'error') {
|
||||
|
||||
var matchingMinErr = flatErrors.indexOf(doc.name);
|
||||
|
||||
if (matchingMinErr === -1) {
|
||||
log.warn('Error doc: ' + doc.name + ' has no matching min error');
|
||||
} else {
|
||||
flatErrors.splice(matchingMinErr, 1);
|
||||
}
|
||||
|
||||
// Parse out the error info from the id
|
||||
parts = doc.name.split(':');
|
||||
doc.namespace = parts[0];
|
||||
@@ -59,10 +41,6 @@ module.exports = function errorDocsProcessor(log, errorNamespaceMap, getMinerrIn
|
||||
}
|
||||
});
|
||||
|
||||
flatErrors.forEach(function(value) {
|
||||
log.warn('No error doc exists for min error: ' + value);
|
||||
});
|
||||
|
||||
errorNamespaceMap.forEach(function(errorNamespace) {
|
||||
docs.push(errorNamespace);
|
||||
});
|
||||
|
||||
@@ -47,13 +47,13 @@ module.exports = function generateKeywordsProcessor(log, readFilesProcessor) {
|
||||
|
||||
}
|
||||
|
||||
areasToSearch = _.keyBy(this.areasToSearch);
|
||||
propertiesToIgnore = _.keyBy(this.propertiesToIgnore);
|
||||
areasToSearch = _.indexBy(this.areasToSearch);
|
||||
propertiesToIgnore = _.indexBy(this.propertiesToIgnore);
|
||||
log.debug('Properties to ignore', propertiesToIgnore);
|
||||
docTypesToIgnore = _.keyBy(this.docTypesToIgnore);
|
||||
docTypesToIgnore = _.indexBy(this.docTypesToIgnore);
|
||||
log.debug('Doc types to ignore', docTypesToIgnore);
|
||||
|
||||
var ignoreWordsMap = _.keyBy(wordsToIgnore);
|
||||
var ignoreWordsMap = _.indexBy(wordsToIgnore);
|
||||
|
||||
// If the title contains a name starting with ng, e.g. "ngController", then add the module name
|
||||
// without the ng to the title text, e.g. "controller".
|
||||
|
||||
@@ -224,7 +224,7 @@ module.exports = function generatePagesDataProcessor(log) {
|
||||
.map(function(doc) {
|
||||
return _.pick(doc, ['name', 'area', 'path']);
|
||||
})
|
||||
.keyBy('path')
|
||||
.indexBy('path')
|
||||
.value();
|
||||
|
||||
docs.push({
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var exclusionRegex = /^index|examples\/|ptore2e\//;
|
||||
|
||||
module.exports = function createSitemap() {
|
||||
return {
|
||||
$runAfter: ['paths-computed'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
$process: function(docs) {
|
||||
docs.push({
|
||||
id: 'sitemap.xml',
|
||||
path: 'sitemap.xml',
|
||||
outputPath: '../sitemap.xml',
|
||||
template: 'sitemap.template.xml',
|
||||
urls: docs.filter(function(doc) {
|
||||
return doc.path &&
|
||||
doc.outputPath &&
|
||||
!exclusionRegex.test(doc.outputPath);
|
||||
}).map(function(doc) {
|
||||
return doc.path;
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -13,11 +13,11 @@ module.exports = function generateVersionDocProcessor(gitData) {
|
||||
return {
|
||||
$runAfter: ['generatePagesDataProcessor'],
|
||||
$runBefore: ['rendering-docs'],
|
||||
// Remove rogue builds that are in the npm repository but not on code.angularjs.org
|
||||
ignoredBuilds: ['1.3.4-build.3588'],
|
||||
// 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 ignoredBuilds = this.ignoredBuilds;
|
||||
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);
|
||||
@@ -47,17 +47,9 @@ module.exports = function generateVersionDocProcessor(gitData) {
|
||||
|
||||
var latestMap = {};
|
||||
|
||||
// When the docs are built on a tagged commit, yarn info won't include the latest release,
|
||||
// so we add it manually based on the local version.json file.
|
||||
var missesCurrentVersion = !currentVersion.isSnapshot && !versions.find(function(version) {
|
||||
return version === currentVersion.version;
|
||||
});
|
||||
|
||||
if (missesCurrentVersion) versions.push(currentVersion.version);
|
||||
|
||||
versions = versions
|
||||
.filter(function(versionStr) {
|
||||
return ignoredBuilds.indexOf(versionStr) === -1;
|
||||
return blacklist.indexOf(versionStr) === -1;
|
||||
})
|
||||
.map(function(versionStr) {
|
||||
return semver.parse(versionStr);
|
||||
@@ -78,28 +70,10 @@ module.exports = function generateVersionDocProcessor(gitData) {
|
||||
})
|
||||
.reverse();
|
||||
|
||||
// List the latest version for each branch
|
||||
var latest = sortObject(latestMap, reverse(semver.compare))
|
||||
.map(function(version) { return makeOption(version, 'Latest'); });
|
||||
|
||||
// Get the stable release with the highest version
|
||||
var highestStableRelease = versions.find(semverIsStable);
|
||||
|
||||
// Generate master and stable snapshots
|
||||
var snapshots = [
|
||||
makeOption(
|
||||
{version: 'snapshot'},
|
||||
'Latest',
|
||||
'master-snapshot'
|
||||
),
|
||||
makeOption(
|
||||
{version: 'snapshot-stable'},
|
||||
'Latest',
|
||||
createSnapshotStableLabel(highestStableRelease)
|
||||
)
|
||||
];
|
||||
|
||||
return snapshots
|
||||
return [makeOption({version: 'snapshot'}, 'Latest', 'master')]
|
||||
.concat(latest)
|
||||
.concat(versions);
|
||||
}
|
||||
@@ -129,19 +103,6 @@ module.exports = function generateVersionDocProcessor(gitData) {
|
||||
function sortObject(obj, cmp) {
|
||||
return Object.keys(obj).map(function(key) { return obj[key]; }).sort(cmp);
|
||||
}
|
||||
|
||||
// Adapted from
|
||||
// https://github.com/kaelzhang/node-semver-stable/blob/34dd29842409295d49889d45871bec55a992b7f6/index.js#L25
|
||||
function semverIsStable(version) {
|
||||
var semverObj = version.version;
|
||||
return semverObj === null ? false : !semverObj.prerelease.length;
|
||||
}
|
||||
|
||||
function createSnapshotStableLabel(version) {
|
||||
var label = version.label.replace(/.$/, 'x') + '-snapshot';
|
||||
|
||||
return label;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -30,6 +30,7 @@ module.exports = function debugDeployment(getVersion) {
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.css',
|
||||
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/angular-topnav.css',
|
||||
'css/docs.css',
|
||||
|
||||
@@ -17,7 +17,7 @@ module.exports = function defaultDeployment(getVersion) {
|
||||
'../angular-sanitize.min.js',
|
||||
'../angular-touch.min.js',
|
||||
'../angular-animate.min.js',
|
||||
'components/marked-' + getVersion('marked') + '/marked.min.js',
|
||||
'components/marked-' + getVersion('marked') + '/lib/marked.js',
|
||||
'js/angular-bootstrap/dropdown-toggle.min.js',
|
||||
'components/lunr-' + getVersion('lunr') + '/lunr.min.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
|
||||
@@ -30,6 +30,7 @@ module.exports = function defaultDeployment(getVersion) {
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
|
||||
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/angular-topnav.css',
|
||||
'css/docs.css',
|
||||
|
||||
+1
@@ -34,6 +34,7 @@ module.exports = function jqueryDeployment(getVersion) {
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
|
||||
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/angular-topnav.css',
|
||||
'css/docs.css',
|
||||
|
||||
@@ -7,25 +7,24 @@ var angularCodeUrl = '//code.angularjs.org/';
|
||||
|
||||
var cdnUrl = googleCdnUrl + versionInfo.cdnVersion;
|
||||
|
||||
// The "examplesDependencyPath" here applies to the examples when they are opened in plnkr.co.
|
||||
// The embedded examples instead always include the files from the *default* deployment,
|
||||
// to ensure that the source files are always available.
|
||||
// The plnkr examples must always use the code.angularjs.org source files.
|
||||
// We cannot rely on the CDN files here, because they are not deployed by the time
|
||||
// docs.angularjs.org and code.angularjs.org need them.
|
||||
var versionPath = versionInfo.currentVersion.isSnapshot ?
|
||||
'snapshot' :
|
||||
versionInfo.currentVersion.version;
|
||||
var examplesDependencyPath = angularCodeUrl + versionPath + '/';
|
||||
// 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));
|
||||
|
||||
module.exports = function productionDeployment(getVersion) {
|
||||
return {
|
||||
name: 'production',
|
||||
examples: {
|
||||
commonFiles: {
|
||||
scripts: [examplesDependencyPath + 'angular.min.js']
|
||||
scripts: [examplesCdnUrl + '/angular.min.js']
|
||||
},
|
||||
dependencyPath: examplesDependencyPath
|
||||
dependencyPath: examplesCdnUrl + '/'
|
||||
},
|
||||
scripts: [
|
||||
cdnUrl + '/angular.min.js',
|
||||
@@ -35,7 +34,7 @@ module.exports = function productionDeployment(getVersion) {
|
||||
cdnUrl + '/angular-sanitize.min.js',
|
||||
cdnUrl + '/angular-touch.min.js',
|
||||
cdnUrl + '/angular-animate.min.js',
|
||||
'components/marked-' + getVersion('marked') + '/marked.min.js',
|
||||
'components/marked-' + getVersion('marked') + '/lib/marked.js',
|
||||
'js/angular-bootstrap/dropdown-toggle.min.js',
|
||||
'components/lunr-' + getVersion('lunr') + '/lunr.min.js',
|
||||
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
|
||||
@@ -48,6 +47,7 @@ module.exports = function productionDeployment(getVersion) {
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.min.css',
|
||||
'components/open-sans-fontface-' + getVersion('open-sans-fontface') + '/open-sans.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/angular-topnav.css',
|
||||
'css/docs.css',
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function testDeployment(getVersion) {
|
||||
return {
|
||||
name: 'test',
|
||||
examples: {
|
||||
commonFiles: {
|
||||
scripts: ['../../../angular.js']
|
||||
},
|
||||
dependencyPath: '../../../'
|
||||
},
|
||||
scripts: [
|
||||
'../angular.js',
|
||||
'../angular-resource.js',
|
||||
'../angular-route.js',
|
||||
'../angular-cookies.js',
|
||||
'../angular-mocks.js',
|
||||
'../angular-sanitize.js',
|
||||
'../angular-touch.js',
|
||||
'../angular-animate.js',
|
||||
'components/marked-' + getVersion('marked') + '/lib/marked.js',
|
||||
'js/angular-bootstrap/dropdown-toggle.js',
|
||||
'components/lunr-' + getVersion('lunr') + '/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/pages-data.js',
|
||||
'js/nav-data.js',
|
||||
'js/docs.js'
|
||||
],
|
||||
stylesheets: [
|
||||
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.css',
|
||||
'css/prettify-theme.css',
|
||||
'css/angular-topnav.css',
|
||||
'css/docs.css',
|
||||
'css/animations.css'
|
||||
]
|
||||
};
|
||||
};
|
||||
@@ -4,13 +4,14 @@ var path = require('canonical-path');
|
||||
/**
|
||||
* dgService getVersion
|
||||
* @description
|
||||
* Find the current version of the node module
|
||||
* Find the current version of the bower component (or node module)
|
||||
*/
|
||||
module.exports = function getVersion(readFilesProcessor) {
|
||||
var sourceFolder = path.resolve(readFilesProcessor.basePath, 'node_modules');
|
||||
var packageFile = 'package.json';
|
||||
var basePath = readFilesProcessor.basePath;
|
||||
|
||||
return function(component) {
|
||||
return require(path.join(sourceFolder, component, packageFile)).version;
|
||||
return function(component, sourceFolder, packageFile) {
|
||||
sourceFolder = path.resolve(basePath, sourceFolder || 'node_modules');
|
||||
packageFile = packageFile || 'package.json';
|
||||
return require(path.join(sourceFolder,component,packageFile)).version;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<pre class="minerr-errmsg" error-display="{$ doc.formattedErrorMessage $}">{$ doc.formattedErrorMessage $}</pre>
|
||||
</div>
|
||||
|
||||
<h2 id="description">Description</h2>
|
||||
<h2>Description</h2>
|
||||
<div class="description">
|
||||
{$ doc.description | marked $}
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
{# Macros #}
|
||||
{%- macro addTag(name, attributes) %}
|
||||
<{$ name $}
|
||||
{%- for attrName, attrValue in attributes -%}
|
||||
{$ ' ' + attrName $}="{$ attrValue $}"
|
||||
{%- endfor -%}
|
||||
></{$ name $}>
|
||||
{%- endmacro -%}
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en" ng-app="docsApp" ng-strict-di ng-controller="DocsController">
|
||||
<head>
|
||||
@@ -21,39 +12,50 @@
|
||||
<title ng-bind-template="AngularJS: {{ currentArea.name }}: {{ currentPage.name || 'Error: Page not found'}}">AngularJS</title>
|
||||
|
||||
<script type="text/javascript">
|
||||
// dynamically add base tag as well as css and javascript files.
|
||||
// we can't add css/js the usual way, because some browsers (FF) eagerly prefetch resources
|
||||
// before the base attribute is added, causing 404 and terribly slow loading of the docs app.
|
||||
(function() {
|
||||
// Dynamically, pre-emptively, add `noindex`, which will be removed when the doc is ready and valid
|
||||
['googlebot', 'robots'].forEach(function(bot) {
|
||||
var tag = document.createElement('meta');
|
||||
tag.name = bot;
|
||||
tag.content = 'noindex';
|
||||
tag.setAttribute('ng-if', 'hasError()');
|
||||
document.head.appendChild(tag);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
// Dynamically add `<base>` tag.
|
||||
(function() {
|
||||
var indexFile = (location.pathname.match(/\/(index[^.]*\.html)/) || ['', ''])[1],
|
||||
rUrl = /(#!\/|api|guide|misc|tutorial|error|index[^.]*\.html).*$/,
|
||||
var indexFile = (location.pathname.match(/\/(index[^\.]*\.html)/) || ['', ''])[1],
|
||||
rUrl = /(#!\/|api|guide|misc|tutorial|error|index[^\.]*\.html).*$/,
|
||||
baseUrl = location.href.replace(rUrl, indexFile),
|
||||
production = location.hostname === 'docs.angularjs.org',
|
||||
headEl = document.getElementsByTagName('head')[0],
|
||||
baseEl = document.createElement('base');
|
||||
sync = true;
|
||||
|
||||
baseEl.setAttribute('href', baseUrl);
|
||||
headEl.appendChild(baseEl);
|
||||
addTag('base', {href: baseUrl});
|
||||
|
||||
|
||||
{% for stylesheet in doc.stylesheets %}addTag('link', {rel: 'stylesheet', href: '{$ stylesheet $}', type: 'text/css'});
|
||||
{% endfor %}
|
||||
|
||||
{% for script in doc.scripts %}addTag('script', {src: '{$ script $}' }, sync);
|
||||
{% endfor %}
|
||||
|
||||
function addTag(name, attributes, sync) {
|
||||
var el = document.createElement(name),
|
||||
attrName;
|
||||
|
||||
for (attrName in attributes) {
|
||||
el.setAttribute(attrName, attributes[attrName]);
|
||||
}
|
||||
|
||||
sync ? document.write(outerHTML(el)) : headEl.appendChild(el);
|
||||
}
|
||||
|
||||
function outerHTML(node){
|
||||
// if IE, Chrome take the internal method otherwise build one
|
||||
return node.outerHTML || (
|
||||
function(n){
|
||||
var div = document.createElement('div'), h;
|
||||
div.appendChild(n);
|
||||
h = div.innerHTML;
|
||||
div = null;
|
||||
return h;
|
||||
})(node);
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
{% for stylesheet in doc.stylesheets %}
|
||||
{$- addTag('link', {rel: 'stylesheet', href: stylesheet, type: 'text/css'}) -$}
|
||||
{% endfor %}
|
||||
{% for script in doc.scripts %}
|
||||
{$- addTag('script', {src: script}) -$}
|
||||
{% endfor %}
|
||||
|
||||
<script type="text/javascript">
|
||||
// GA asynchronous tracker
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-8594346-3']);
|
||||
@@ -106,7 +108,6 @@
|
||||
<li><a href="misc/contribute">Contribute</a></li>
|
||||
<li><a href="https://github.com/angular/angular-seed">Seed App project template</a></li>
|
||||
<li><a href="https://github.com/angular/angular.js">GitHub</a></li>
|
||||
<li><a href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md">Changelog</a></li>
|
||||
<li><a href="http://code.angularjs.org/">Download</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -125,13 +126,13 @@
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div class="search-results-container" ng-show="hasResults" ng-cloak>
|
||||
<div class="search-results-container" ng-show="hasResults">
|
||||
<div class="container">
|
||||
<div class="search-results-frame">
|
||||
<div ng-repeat="(key, value) in results track by key" class="search-results-group" ng-class="colClassName + ' col-group-' + key" ng-show="value.length > 0">
|
||||
<h4 class="search-results-group-heading">{{ key }}</h4>
|
||||
<ul class="search-results">
|
||||
<li ng-repeat="item in value" class="search-result"><a ng-click="handleResultClicked($event)" ng-href="{{ item.path }}">{{ item.name }}</a></li>
|
||||
<li ng-repeat="item in value" class="search-result"><a ng-click="hideResults()" ng-href="{{ item.path }}">{{ item.name }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -142,18 +143,21 @@
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<nav id="navbar-sub" class="sup-header navbar navbar-fixed-top" scroll-y-offset-element ng-cloak>
|
||||
<div class="container main-grid main-header-grid">
|
||||
<p class="site-notice">
|
||||
AngularJS support has officially ended as of January 2022.
|
||||
<a href="https://docs.angularjs.org/misc/version-support-status">
|
||||
See what ending support means
|
||||
</a> and
|
||||
<a href="https://goo.gle/angularjs-end-of-life">
|
||||
read the end of life announcement</a>.<br>
|
||||
Visit <a href="https://angular.io">angular.io</a> for the actively supported
|
||||
Angular.
|
||||
<nav id="navbar-notice" class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<p class="site-notice visible-phone">
|
||||
This site refers to AngularJS (v1.x). <a href="https://angular.io/">Go to the latest Angular</a>.
|
||||
</p>
|
||||
<p class="site-notice visible-desktop">
|
||||
This site and all of its contents are referring to AngularJS (version 1.x),
|
||||
if you are looking for the latest Angular, please visit <a href="https://angular.io/">angular.io</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<nav id="navbar-sub" class="sup-header navbar navbar-fixed-top" scroll-y-offset-element>
|
||||
<div class="container main-grid main-header-grid">
|
||||
<div class="grid-left">
|
||||
<version-picker></version-picker>
|
||||
</div>
|
||||
@@ -169,7 +173,7 @@
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<section role="main" class="container main-body" ng-cloak>
|
||||
<section role="main" class="container main-body">
|
||||
<div class="main-grid main-body-grid">
|
||||
<div class="grid-left">
|
||||
<a class="btn toc-toggle visible-xs" ng-click="toc=!toc">Show / Hide Table of Contents</a>
|
||||
@@ -193,9 +197,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-right">
|
||||
<div ng-show="loading">Loading …</div>
|
||||
<div ng-show="loadingError">There was an error loading this resource. Please try again later.</div>
|
||||
<div ng-hide="loading" ng-include="partialPath" toc-collector autoscroll></div>
|
||||
<div id="loading" ng-show="loading">Loading...</div>
|
||||
<div ng-hide="loading" ng-include="partialPath" autoscroll></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -205,10 +208,10 @@
|
||||
<p class="pull-right"><a back-to-top>Back to top</a></p>
|
||||
|
||||
<p>
|
||||
Super-powered by Google ©2010-2020
|
||||
Super-powered by Google ©2010-2017
|
||||
(<a id="version"
|
||||
ng-href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md#{{versionNumber}}"
|
||||
ng-bind-template="v{{version}}" title="Changelog of this version of AngularJS">
|
||||
ng-bind-template="v{{version}}" title="Changelog of this version of Angular JS">
|
||||
</a>)
|
||||
</p>
|
||||
<p>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
{%- for url in doc.urls %}
|
||||
<url>
|
||||
<loc>https://docs.angularjs.org/{$ url $}</loc>
|
||||
</url>{% endfor %}
|
||||
</urlset>
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
{% block description %}
|
||||
<div class="api-profile-description">
|
||||
<h2 id="overview">Overview</h2>
|
||||
{$ doc.description | marked $}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -52,7 +51,7 @@
|
||||
|
||||
{% block examples %}
|
||||
{%- if doc.examples %}
|
||||
<h2 id="examples">{$ "Examples" if doc.examples | length > 1 else "Example" $}</h2>
|
||||
<h2 id="example">Examples</h2>
|
||||
{%- for example in doc.examples -%}
|
||||
{$ example | marked $}
|
||||
{%- endfor -%}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{% extends "api/api.template.html" %}
|
||||
|
||||
{% block additional %}
|
||||
<h2 id="{$ doc.name $}-info">Directive Info</h2>
|
||||
<h2>Directive Info</h2>
|
||||
<ul>
|
||||
{% if doc.scope %}<li>This directive creates new scope.</li>{% endif %}
|
||||
<li>This directive executes at priority level {$ doc.priority $}.</li>
|
||||
@@ -29,23 +29,10 @@
|
||||
</li>
|
||||
{% endif -%}
|
||||
|
||||
|
||||
{% set hasNameAsParam = false %}
|
||||
|
||||
{# when a directive's name is not a parameter (i.e. doesn't take a value),
|
||||
add the directive name to the list of attributes and/or css classes #}
|
||||
|
||||
{%- for param in doc.params %}
|
||||
{% set hasNameAsParam = true if param.name === doc.name else hasNameAsParam %}
|
||||
{%- endfor %}
|
||||
|
||||
{%- if doc.restrict.attribute -%}
|
||||
<li>as attribute:
|
||||
{% code %}
|
||||
<{$ doc.element $}
|
||||
{%- if not hasNameAsParam %}
|
||||
{$ lib.directiveParam(doc.name, {}, '', '') $}
|
||||
{%- endif -%}
|
||||
{%- for param in doc.params %}
|
||||
{$ lib.directiveParam(param.name, param.type, '="', '"') $}
|
||||
{%- endfor %}>
|
||||
@@ -56,14 +43,10 @@
|
||||
{% endif -%}
|
||||
|
||||
{%- if doc.restrict.cssClass -%}
|
||||
|
||||
<li>as CSS class:
|
||||
{% code %}
|
||||
{% set sep = joiner(' ') %}
|
||||
<{$ doc.element $} class="
|
||||
{%- if not hasNameAsParam -%}
|
||||
{$ sep() $}{$ lib.directiveParam(doc.name, {}, '', '') $}
|
||||
{%- endif -%}
|
||||
{%- for param in doc.params -%}
|
||||
{$ sep() $}{$ lib.directiveParam(param.name, param.type, ': ', ';') $}
|
||||
{%- endfor %}"> ... </{$ doc.element $}>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{% extends "api/api.template.html" %}
|
||||
|
||||
{% block additional %}
|
||||
<h2 id="usage">Usage</h2>
|
||||
<h2>Usage</h2>
|
||||
<h3>In HTML Template Binding</h3>
|
||||
{% if doc.usage %}
|
||||
{$ doc.usage | code $}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
{$ x.deprecatedBlock(doc) $}
|
||||
|
||||
<h2 id="module-installation">Installation</h2>
|
||||
<h2>Installation</h2>
|
||||
{% if doc.installation or doc.installation == '' %}
|
||||
{$ doc.installation | marked $}
|
||||
{% else %}
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
{% if doc.componentGroups.length %}
|
||||
<div class="component-breakdown">
|
||||
<h2 id="module-components">Module Components</h2>
|
||||
<h2>Module Components</h2>
|
||||
{% for componentGroup in doc.componentGroups %}
|
||||
<div>
|
||||
<h3 class="component-heading" id="{$ componentGroup.groupType | dashCase $}">{$ componentGroup.groupType | title $}</h3>
|
||||
@@ -98,7 +98,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if doc.usage %}
|
||||
<h2 id="module-usage">Usage</h2>
|
||||
<h2>Usage</h2>
|
||||
{$ doc.usage | marked $}
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{% import "lib/deprecated.html" as x -%}
|
||||
|
||||
{%- if doc.events %}
|
||||
<h2 id="events">Events</h2>
|
||||
<h2>Events</h2>
|
||||
<ul class="events">
|
||||
{%- for event in doc.events %}
|
||||
<li id="{$ event.name $}">
|
||||
<h3 id="event-{$ event.name $}">{$ event.name $}</h3>
|
||||
<h3>{$ event.name $}</h3>
|
||||
<div>{$ event.description | marked $}</div>
|
||||
|
||||
{$ x.deprecatedBlock(event) $}
|
||||
@@ -27,7 +27,7 @@
|
||||
{% endif -%}
|
||||
{%- if event.params %}
|
||||
<section class="api-section">
|
||||
<h4>Parameters</h4>
|
||||
<h3>Parameters</h3>
|
||||
{$ lib.paramTable(event.params) $}
|
||||
</section>
|
||||
{%- endif -%}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{% import "lib/deprecated.html" as x -%}
|
||||
|
||||
{%- if doc.methods %}
|
||||
<h2 id="{$ doc.name $}-methods">Methods</h2>
|
||||
<h2>Methods</h2>
|
||||
<ul class="methods">
|
||||
{%- for method in doc.methods %}
|
||||
<li>
|
||||
<h3 id="{$ method.name $}">{$ lib.functionSyntax(method) $}</h3>
|
||||
<li id="{$ method.name $}">
|
||||
<h3>{$ lib.functionSyntax(method) $}</h3>
|
||||
<div>{$ method.description | marked $}</div>
|
||||
|
||||
{$ x.deprecatedBlock(method) $}
|
||||
@@ -17,7 +17,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if method.this %}
|
||||
<h4>Method's `this`</h4>
|
||||
<h4>Method's {% code %}this{% endcode %}</h4>
|
||||
{$ method.this | marked $}
|
||||
{% endif %}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
{% endif %}
|
||||
|
||||
{%- if method.examples %}
|
||||
<h4 id="{$ doc.name $}.{$ method.name $}-examples">{$ "Examples" if method.examples | length > 1 else "Example" $}</h4>
|
||||
<h4 id="{$ doc.name $}.{$ method.name $}-examples">Examples</h4>
|
||||
{%- for example in method.examples -%}
|
||||
{$ example | marked $}
|
||||
{%- endfor -%}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% import "lib/macros.html" as lib -%}
|
||||
{%- if doc.params %}
|
||||
<section class="api-section">
|
||||
<h3 id="{$ doc.name $}-arguments">Arguments</h3>
|
||||
<h3>Arguments</h3>
|
||||
{$ lib.paramTable(doc.params) $}
|
||||
</section>
|
||||
{%- endif -%}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{% import "lib/deprecated.html" as x -%}
|
||||
|
||||
{%- if doc.properties %}
|
||||
<h2 id="{$ doc.name $}-properties">Properties</h2>
|
||||
<h2>Properties</h2>
|
||||
<ul class="properties">
|
||||
{%- for property in doc.properties %}
|
||||
<li>
|
||||
<h3 id="{$ property.name $}">{$ property.name | code $}</h3>
|
||||
<li id="{$ property.name $}">
|
||||
<h3>{$ property.name | code $}</h3>
|
||||
{$ lib.typeInfo(property) $}
|
||||
{$ x.deprecatedBlock(property) $}
|
||||
</li>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% import "lib/macros.html" as lib -%}
|
||||
{% if doc.returns -%}
|
||||
<h3 id="{$ doc.name $}-returns">Returns</h3>
|
||||
<h3>Returns</h3>
|
||||
{$ lib.typeInfo(doc.returns) $}
|
||||
{%- endif %}
|
||||
@@ -1,4 +1,4 @@
|
||||
{% if doc.this %}
|
||||
<h3>Method's `this`</h3>
|
||||
<h3>Method's {% code %}this{% endcode %}</h3>
|
||||
{$ doc.this | marked $}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -3,18 +3,7 @@
|
||||
@description
|
||||
|
||||
# AngularJS API Docs
|
||||
<div class="alert alert-warning">
|
||||
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.
|
||||
</div>
|
||||
|
||||
## Welcome to the AngularJS API docs page.
|
||||
|
||||
These pages contain the AngularJS reference materials for version <strong ng-bind="version"></strong>.
|
||||
|
||||
Welcome to the AngularJS API docs page. These pages contain the AngularJS reference materials for version <strong ng-bind="version"></strong>.
|
||||
|
||||
The documentation is organized into **{@link guide/module modules}** which contain various components of an AngularJS application.
|
||||
These components are {@link guide/directive directives}, {@link guide/services services}, {@link guide/filter filters}, {@link guide/providers providers}, {@link guide/templates templates}, global APIs, and testing mocks.
|
||||
@@ -22,14 +11,14 @@ These components are {@link guide/directive directives}, {@link guide/services s
|
||||
There is also a {@link guide/index guide} with articles on various topics, and a list of external resources.
|
||||
|
||||
<div class="alert alert-info">
|
||||
**AngularJS Prefixes `$` and `$$`**:
|
||||
**Angular Prefixes `$` and `$$`**:
|
||||
|
||||
To prevent accidental name collisions with your code,
|
||||
AngularJS prefixes names of public objects with `$` and names of private objects with `$$`.
|
||||
Angular prefixes names of public objects with `$` and names of private objects with `$$`.
|
||||
Please do not use the `$` or `$$` prefix in your code.
|
||||
</div>
|
||||
|
||||
## AngularJS Modules
|
||||
## Angular Modules
|
||||
|
||||
|
||||
## {@link ng ng (core module)}
|
||||
@@ -94,7 +83,7 @@ This module is provided by default and contains the core components of AngularJS
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
The core global API functions are attached to the `angular` object. These core functions are useful for low level JavaScript operations within your application.
|
||||
The core global API functions are attached to the angular object. These core functions are useful for low level JavaScript operations within your application.
|
||||
</p>
|
||||
<p>
|
||||
Some examples include:
|
||||
@@ -141,7 +130,7 @@ Use ngRoute to enable URL routing to your application. The ngRoute module suppor
|
||||
|
||||
## {@link ngAnimate ngAnimate}
|
||||
|
||||
Use ngAnimate to enable animation features within your application. Various core AngularJS directives will provide
|
||||
Use ngAnimate to enable animation features within your application. Various core ng directives will provide
|
||||
animation hooks into your application when ngAnimate is included. Animations are defined by using CSS transitions/animations
|
||||
or JavaScript callbacks.
|
||||
|
||||
@@ -225,7 +214,11 @@ Use the ngCookies module to handle cookie management within your application.
|
||||
{@link ngCookies#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
The {@link ngCookies.$cookies $cookies} service is a convenient wrapper to store simple data within browser cookies.
|
||||
The following services are used for cookie management:
|
||||
<ul>
|
||||
<li>The {@link ngCookies.$cookies $cookie} service is a convenient wrapper to store simple data within browser cookies.</li>
|
||||
<li>{@link ngCookies.$cookieStore $cookieStore} is used to store more complex data using serialization.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:ctxoverride
|
||||
@fullName DOM Property Security Context Override
|
||||
@description
|
||||
|
||||
This error occurs when the security context for a property is defined via {@link ng.$compileProvider#addPropertySecurityContext addPropertySecurityContext()} multiple times under different security contexts.
|
||||
|
||||
For example:
|
||||
|
||||
```js
|
||||
$compileProvider.addPropertySecurityContext("my-element", "src", $sce.MEDIA_URL);
|
||||
$compileProvider.addPropertySecurityContext("my-element", "src", $sce.RESOURCE_URL); //throws
|
||||
```
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
This error occurs when the application's model becomes unstable because some `$onChanges` hooks are causing updates which then trigger
|
||||
further calls to `$onChanges` that can never complete.
|
||||
AngularJS detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
|
||||
Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
|
||||
|
||||
For example, the situation can occur by setting up a `$onChanges()` hook which triggers an event on the component, which subsequently
|
||||
triggers the component's bound inputs to be updated:
|
||||
|
||||
@@ -10,15 +10,13 @@ myModule.directive('directiveName', function factory() {
|
||||
return {
|
||||
...
|
||||
scope: {
|
||||
'localName': '@', // OK
|
||||
'localName2': '&attr', // OK
|
||||
'localName3': '<?attr', // OK
|
||||
'localName4': ' = attr', // OK
|
||||
'localName5': ' =*attr', // OK
|
||||
'localName6': 'attr', // ERROR: missing mode @&=<
|
||||
'localName7': 'attr=', // ERROR: must be prefixed with @&=<
|
||||
'localName8': '=attr?', // ERROR: ? must come directly after the mode
|
||||
'localName9': '<*' // ERROR: * is only valid with =
|
||||
'attrName': '@', // OK
|
||||
'attrName2': '=localName', // OK
|
||||
'attrName3': '<?localName', // OK
|
||||
'attrName4': ' = name', // OK
|
||||
'attrName5': 'name', // ERROR: missing mode @&=
|
||||
'attrName6': 'name=', // ERROR: must be prefixed with @&=
|
||||
'attrName7': '=name?', // ERROR: ? must come directly after the mode
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:missingattr
|
||||
@fullName Missing required attribute
|
||||
@description
|
||||
|
||||
This error may occur only when {@link $compileProvider#strictComponentBindingsEnabled `$compileProvider.strictComponentBindingsEnabled`} is set to `true`.
|
||||
|
||||
If that is the case, then all {@link $compileProvider#component component} controller bindings and
|
||||
{@link $compileProvider#directive directive} scope / controller bindings that are non-optional,
|
||||
must be provided when the directive is instantiated.
|
||||
|
||||
To make a binding optional, add '?' to the definition.
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
|
||||
app.component('myTest', {
|
||||
bindings: {
|
||||
first: '=?', // optional
|
||||
second: '='
|
||||
},
|
||||
controller: function() {
|
||||
...
|
||||
},
|
||||
template: '...'
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
This component will throw `missingattr` for the `second` binding when used as follows:
|
||||
|
||||
```html
|
||||
<my-test></my-test>
|
||||
```
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
@ngdoc error
|
||||
@name $compile:nodomevents
|
||||
@fullName Event Attribute/Property Binding
|
||||
@fullName Interpolated Event Attributes
|
||||
@description
|
||||
|
||||
This error occurs when one tries to create a binding for event handler attributes or properties like `onclick`, `onload`, `onsubmit`, etc.
|
||||
This error occurs when one tries to create a binding for event handler attributes like `onclick`, `onload`, `onsubmit`, etc.
|
||||
|
||||
There is no practical value in binding to these attributes/properties and doing so only exposes your application to security vulnerabilities like XSS.
|
||||
For these reasons binding to event handler attributes and properties (`formaction` and all starting with `on`) is not supported.
|
||||
There is no practical value in binding to these attributes and doing so only exposes your application to security vulnerabilities like XSS.
|
||||
For these reasons binding to event handler attributes (all attributes that start with `on` and `formaction` attribute) is not supported.
|
||||
|
||||
|
||||
An example code that would allow XSS vulnerability by evaluating user input in the window context could look like this:
|
||||
@@ -17,4 +17,4 @@ An example code that would allow XSS vulnerability by evaluating user input in t
|
||||
|
||||
Since the `onclick` evaluates the value as JavaScript code in the window context, setting the `username` model to a value like `javascript:alert('PWND')` would result in script injection when the `div` is clicked.
|
||||
|
||||
Please use the `ng-*` or `ng-on-*` versions instead (such as `ng-click` or `ng-on-click` rather than `onclick`).
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:srcset
|
||||
@fullName Invalid value passed to `attr.$set('srcset', value)`
|
||||
@description
|
||||
|
||||
This error occurs if you try to programmatically set the `srcset` attribute with a non-string value.
|
||||
|
||||
This can be the case if you tried to avoid the automatic sanitization of the `srcset` value by
|
||||
passing a "trusted" value provided by calls to `$sce.trustAsMediaUrl(value)`.
|
||||
|
||||
If you want to programmatically set explicitly trusted unsafe URLs, you should use `$sce.trustAsHtml`
|
||||
on the whole `img` tag and inject it into the DOM using the `ng-bind-html` directive.
|
||||
@@ -0,0 +1,11 @@
|
||||
@ngdoc error
|
||||
@name $compile:tpload
|
||||
@fullName Error Loading Template
|
||||
@description
|
||||
|
||||
This error occurs when {@link ng.$compile `$compile`} attempts to fetch a template from some URL, and the request fails.
|
||||
|
||||
To resolve this error, ensure that the URL of the template is spelled correctly and resolves to correct absolute URL.
|
||||
The [Chrome Developer Tools](https://developers.google.com/chrome-developer-tools/docs/network#network_panel_overview) might also be helpful in determining why the request failed.
|
||||
|
||||
If you are using {@link ng.$templateCache} to pre-load templates, ensure that the cache was populated with the template.
|
||||
@@ -9,9 +9,9 @@ value is `JSON_CALLBACK`.
|
||||
|
||||
`$http` JSONP requests need to attach a callback query parameter to the URL. The name of this
|
||||
parameter is specified in the configuration object (or in the defaults) via the `jsonpCallbackParam`
|
||||
property. You must not provide your own parameter with this name in the configuration of the request.
|
||||
property. You must not provide your own parameter with this name in the configuratio of the request.
|
||||
|
||||
In previous versions of AngularJS, you specified where to add the callback parameter value via the
|
||||
In previous versions of Angular, you specified where to add the callback parameter value via the
|
||||
`JSON_CALLBACK` placeholder. This is no longer allowed.
|
||||
|
||||
To resolve this error, remove any parameters that have the same name as the `jsonpCallbackParam`;
|
||||
|
||||
@@ -15,7 +15,7 @@ In AngularJS `1.2.0` and later, `ngRoute` has been moved to its own module.
|
||||
If you are getting this error after upgrading to `1.2.x` or later, be sure that you've
|
||||
installed {@link ngRoute `ngRoute`}.
|
||||
|
||||
### Monkey-patching AngularJS's `ng` module
|
||||
### Monkey-patching Angular's `ng` module
|
||||
|
||||
This error can also occur if you have tried to add your own components to the `ng` module.
|
||||
This has never been supported and from `1.3.0` it will actually trigger this error.
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
@fullName Expecting end operator
|
||||
@description
|
||||
|
||||
The AngularJS expression is missing the corresponding closing operator.
|
||||
The Angular expression is missing the corresponding closing operator.
|
||||
|
||||
@@ -8,4 +8,4 @@ extension in your interpolation expression. The different choices have to be un
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -9,4 +9,4 @@ bug mentioning the exact version of AngularJS used and we will fix it!
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -14,4 +14,4 @@ future commit and the github issue will help gauge urgency.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
@description
|
||||
|
||||
You must specify the MessageFormat function that you're using right after the
|
||||
comma following the AngularJS expression. Currently, the supported functions are
|
||||
comma following the Angular expression. Currently, the supported functions are
|
||||
"plural" and "select" (for gender selections.)
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -8,4 +8,4 @@ extension keyword in the extended interpolation syntax.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -8,4 +8,4 @@ brace to mark the end of the message.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -9,4 +9,4 @@ braces.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -10,4 +10,4 @@ extensions require that you provide a message for the selection "other".
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -9,4 +9,4 @@ unsupported or invalid.
|
||||
|
||||
For more information about the MessageFormat syntax in interpolation
|
||||
expressions, please refer to MessageFormat extensions section at
|
||||
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -7,4 +7,4 @@ You have attempted to use a MessageFormat extension in your interpolation expres
|
||||
|
||||
Read more about secure contexts at {@link ng.$sce Strict Contextual Escaping
|
||||
(SCE)} and about the MessageFormat extensions at {@link
|
||||
guide/i18n#MessageFormat AngularJS i18n MessageFormat}.
|
||||
guide/i18n#MessageFormat Angular i18n MessageFormat}.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user