Compare commits
174 Commits
Author | SHA1 | Date | |
---|---|---|---|
77f531b6f7 | |||
3041240cbc | |||
257ac83095 | |||
bc93d47129 | |||
3f61071638 | |||
ea571aa9d1 | |||
40cd0371d2 | |||
8356577670 | |||
45d3c8093b | |||
e7eec2e44b | |||
c44b93253c | |||
cd444bc2ba | |||
e9ae26a272 | |||
f9856974e3 | |||
b3c6409763 | |||
4c3e9a32d2 | |||
2700952040 | |||
6d92c99c49 | |||
7cefb3efd4 | |||
1c0ab3468d | |||
b5ede01c09 | |||
98b1a9dcfe | |||
c277c198d2 | |||
b7d7609872 | |||
415e3e06ed | |||
0f7a850699 | |||
1e2525b8a7 | |||
bc9f534bf4 | |||
ea2a3ca705 | |||
802e996e64 | |||
aa7dd1267b | |||
91916e7113 | |||
0e92f1eee5 | |||
4ac3b2e2bd | |||
20ce134961 | |||
c01f3409f3 | |||
71580c8e37 | |||
e58f8b7be0 | |||
046c96a3f1 | |||
00e6569e0f | |||
5dbf9f721b | |||
c63bc02846 | |||
2f3308e4f0 | |||
cc5e4fb93f | |||
3ab9947c7f | |||
b1f92db22b | |||
bda1e52b50 | |||
1084ebc091 | |||
5a3af00398 | |||
7a088af3ff | |||
3e8d8ec2f5 | |||
d4ea7f1f7e | |||
23096501e2 | |||
023874426e | |||
aeffcdd417 | |||
6d7d7c77e3 | |||
8da6c369e5 | |||
d0f2bae62b | |||
062af7a725 | |||
9d1d70a563 | |||
5f908eedbf | |||
a3eac19831 | |||
cace4dea64 | |||
a012ffbd5b | |||
2065149d73 | |||
44e604b131 | |||
4503b28295 | |||
f8fcea333f | |||
a09782b8ac | |||
bfeceb3d3e | |||
1a5735d5c0 | |||
43d4446ec0 | |||
91edfb8be0 | |||
9d0a6554a3 | |||
8fff438767 | |||
b2ae08f272 | |||
c78542f124 | |||
b52c97cf70 | |||
929739c736 | |||
85bde4ff90 | |||
5b5b8254b1 | |||
ac8871fb7f | |||
6b2b1eae9d | |||
b3f096219f | |||
224d9dcd4a | |||
31a0c2a6c2 | |||
c251a5a4d1 | |||
81e571b908 | |||
80a9de0a57 | |||
d1e2ac86fd | |||
9a0d326f4f | |||
ce3024017a | |||
c8adef2dab | |||
778e1c2602 | |||
35bfa1437f | |||
4d83078cd2 | |||
64d005de05 | |||
0c822b75f9 | |||
e0a9cfb5e2 | |||
f8dff83d4b | |||
e411cd124a | |||
df4e85907c | |||
1498dc2dca | |||
abfde44afb | |||
eb9d431487 | |||
9060fb7031 | |||
7fbe547f78 | |||
cda6a215f2 | |||
a8430db45d | |||
5e2bf292e5 | |||
efded24527 | |||
30ac643d1d | |||
d9725016ad | |||
3f94759b14 | |||
9a46420aaf | |||
6a11d7e2a0 | |||
4fd9988251 | |||
a4fcd07792 | |||
078a928fab | |||
5d90aede4e | |||
658a18cdab | |||
6d240cf687 | |||
dca176e232 | |||
6c4845515b | |||
c2ce832f65 | |||
c726d27331 | |||
c4b7862e1b | |||
39472e102b | |||
1fafc5ca18 | |||
07a26647ac | |||
817821e553 | |||
398db3e9f0 | |||
d5fa4dc146 | |||
0ae3518fa9 | |||
e0f9a1b3f3 | |||
2604f429c7 | |||
ecada17ad4 | |||
fa3751ec9e | |||
f85a969219 | |||
d0a1e42e50 | |||
4f14a09895 | |||
8d28fe9df9 | |||
6715f056b0 | |||
32c018cbfe | |||
a403c4f7f5 | |||
bf656d64b8 | |||
3b183ce9b5 | |||
f635c3ecec | |||
dd6e8424aa | |||
1035c6a3ee | |||
b49b274a16 | |||
a4ebf3fb6d | |||
9997ab5ef9 | |||
c109aada2c | |||
57ce13aa1c | |||
2fd127d000 | |||
2f28e6a62d | |||
bf1a13e5e1 | |||
ab9e114fee | |||
448ab9c465 | |||
d769b441c0 | |||
50ccbe744d | |||
b29e709208 | |||
017a087f9b | |||
4b522572e6 | |||
3808434eec | |||
34aff0b3a1 | |||
7cb4183f58 | |||
960d32dd4f | |||
be0382b50c | |||
7ac4b76336 | |||
00b5c7b49b | |||
96f38562bd | |||
94b98aa819 |
16
.bazelrc
16
.bazelrc
@ -1,11 +1,3 @@
|
||||
# Load any settings specific to the current user
|
||||
try-import .bazelrc.user
|
||||
################################
|
||||
# Settings for Angular team members only
|
||||
################################
|
||||
# To enable this feature check the "Remote caching" section in docs/BAZEL.md.
|
||||
build:angular-team --remote_http_cache=https://storage.googleapis.com/angular-team-cache
|
||||
|
||||
###############################
|
||||
# Typescript / Angular / Sass #
|
||||
###############################
|
||||
@ -32,18 +24,12 @@ build --symlink_prefix=/
|
||||
# Performance: avoid stat'ing input files
|
||||
build --watchfs
|
||||
|
||||
# Turn off legacy external runfiles
|
||||
run --nolegacy_external_runfiles
|
||||
test --nolegacy_external_runfiles
|
||||
|
||||
###############################
|
||||
# Release support #
|
||||
# Turn on these settings with #
|
||||
# --config=release #
|
||||
###############################
|
||||
|
||||
# Releases should always be stamped with version control info
|
||||
build:release --workspace_status_command=./tools/bazel_stamp_vars.sh
|
||||
build --workspace_status_command=./tools/bazel_stamp_vars.sh
|
||||
|
||||
###############################
|
||||
# Output #
|
||||
|
@ -1,42 +0,0 @@
|
||||
# Heavily based on https://github.com/StefanScherer/dockerfiles-windows/ images.
|
||||
# Combines the node windowsservercore image with the Bazel Prerequisites (https://docs.bazel.build/versions/master/install-windows.html).
|
||||
# msys install taken from https://github.com/StefanScherer/dockerfiles-windows/issues/30
|
||||
# VS redist install taken from https://github.com/StefanScherer/dockerfiles-windows/blob/master/apache/Dockerfile
|
||||
# The nanoserver image won't work because MSYS2 does not run in it https://github.com/Alexpux/MSYS2-packages/issues/1493
|
||||
|
||||
# Before building this image, you must locally build node-windows:10.13.0-windowsservercore-1803.
|
||||
# Clone https://github.com/StefanScherer/dockerfiles-windows/commit/4ce7101a766b9b880ac262479dd9126b64d656cf and build using
|
||||
# docker build -t node-windows:10.13.0-windowsservercore-1803 --build-arg core=microsoft/windowsservercore:1803 --build-arg target=microsoft/windowsservercore:1803 .
|
||||
FROM node-windows:10.13.0-windowsservercore-1803
|
||||
|
||||
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
|
||||
|
||||
# Install 7zip to extract msys2
|
||||
RUN Invoke-WebRequest -UseBasicParsing 'https://www.7-zip.org/a/7z1805-x64.exe' -OutFile 7z.exe
|
||||
# For some reason the last letter in the destination directory is lost. So '/D=C:\\7zip0' will extract to '/D=C:\\7zip'.
|
||||
RUN Start-Process -FilePath 'C:\\7z.exe' -ArgumentList '/S', '/D=C:\\7zip0' -NoNewWindow -Wait
|
||||
|
||||
# Extract msys2
|
||||
RUN Invoke-WebRequest -UseBasicParsing 'http://repo.msys2.org/distrib/x86_64/msys2-base-x86_64-20180531.tar.xz' -OutFile msys2.tar.xz
|
||||
RUN Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'e', 'msys2.tar.xz' -Wait
|
||||
RUN Start-Process -FilePath 'C:\\7zip\\7z' -ArgumentList 'x', 'msys2.tar', '-oC:\\' -Wait
|
||||
RUN Remove-Item msys2.tar.xz
|
||||
RUN Remove-Item msys2.tar
|
||||
RUN Remove-Item 7z.exe
|
||||
RUN Remove-Item -Recurse 7zip
|
||||
|
||||
# Add MSYS2 to PATH, and set BAZEL_SH
|
||||
RUN [Environment]::SetEnvironmentVariable('Path', $env:Path + ';C:\msys64\usr\bin', [System.EnvironmentVariableTarget]::Machine)
|
||||
RUN [Environment]::SetEnvironmentVariable('BAZEL_SH', 'C:\msys64\usr\bin\bash.exe', [System.EnvironmentVariableTarget]::Machine)
|
||||
|
||||
# Install Microsoft Visual C++ Redistributable for Visual Studio 2015
|
||||
RUN Invoke-WebRequest -UseBasicParsing 'https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe' -OutFile vc_redist.x64.exe
|
||||
RUN Start-Process 'c:\\vc_redist.x64.exe' -ArgumentList '/Install', '/Passive', '/NoRestart' -NoNewWindow -Wait
|
||||
RUN Remove-Item vc_redist.x64.exe
|
||||
|
||||
# Add a fix for https://github.com/docker/for-win/issues/2920 as entry point to the container.
|
||||
SHELL ["cmd", "/c"]
|
||||
COPY "fix-msys64.cmd" "C:\\fix-msys64.cmd"
|
||||
ENTRYPOINT cmd /C C:\\fix-msys64.cmd && cmd /c
|
||||
|
||||
CMD ["cmd.exe"]
|
@ -1,96 +0,0 @@
|
||||
# BuildKite configuration
|
||||
|
||||
This folder contains configuration for the [BuildKite](https://buildkite.com) based CI checks for
|
||||
this repository.
|
||||
|
||||
BuildKite is a CI provider that provides build coordination and reports while we provide the
|
||||
infrastructure.
|
||||
|
||||
CI runs are triggered by new PRs and will show up on the GitHub checks interface, along with the
|
||||
other current CI solutions.
|
||||
|
||||
Currently it is only used for tests on Windows platforms.
|
||||
|
||||
|
||||
## The build pipeline
|
||||
|
||||
BuildKite uses a pipeline for each repository. The `pipeline.yml` file defines pipeline
|
||||
[build steps](https://buildkite.com/docs/pipelines/defining-steps) for this repository.
|
||||
|
||||
Run results can be seen in the GitHub checks interface and in the
|
||||
[pipeline dashboard](https://buildkite.com/angular/angular).
|
||||
|
||||
Although most configuration is done via `pipeline.yml`, some options are only available
|
||||
in the online [pipeline settings](https://buildkite.com/angular/angular/settings).
|
||||
|
||||
|
||||
## Infrastructure
|
||||
|
||||
BuildKite does not provide the host machines where the builds runs, providing instead the
|
||||
[BuildKite Agent](https://buildkite.com/docs/agent/v3) that should be run our own infrastructure.
|
||||
|
||||
|
||||
### Agents
|
||||
|
||||
This agent polls the BuildKite API for builds, runs them, and reports back the results.
|
||||
Agents are the unit of concurrency: each agent can run one build at any given time.
|
||||
Adding agents allows more builds to be ran at the same time.
|
||||
|
||||
Individual agents can have tags, and pipeline steps can target only agents with certain tags via the
|
||||
`agents` field in `pipeline.yml`.
|
||||
For example: agents on Windows machines are tagged as `windows`, and the Windows specific build
|
||||
steps list `windows: true` in their `agents` field.
|
||||
|
||||
You can see the current agent pool, along with their tags, in the
|
||||
[agents list](https://buildkite.com/organizations/angular/agents).
|
||||
|
||||
|
||||
### Our host machines
|
||||
|
||||
We use [Google Cloud](https://cloud.google.com/) as our cloud provider, under the
|
||||
[Angular project](https://console.cloud.google.com/home/dashboard?project=internal-200822).
|
||||
To access this project you need need to be logged in with a Google account that's a member of
|
||||
team@angular.io.
|
||||
For googlers this may be your google.com account, for others it is an angular.io account.
|
||||
|
||||
In this project we have a number of Windows VMs running, each of them with several agents.
|
||||
The `provision-windows-buildkite.ps1` file contains instructions on how to create new host VMs that
|
||||
are fully configured to run the BuildKite agents as services.
|
||||
|
||||
Our pipeline uses [docker-buildkite-plugin](https://github.com/buildkite-plugins/docker-buildkite-plugin)
|
||||
to run build steps inside docker containers.
|
||||
This way we achieve isolation and hermeticity.
|
||||
|
||||
The `Dockerfile` file describes a custom Docker image that includes NodeJs, Yarn, and the Bazel
|
||||
pre-requisites on Windows.
|
||||
|
||||
To upload a new version of the docker image, follow any build instructions in `Dockerfile` and then
|
||||
run `docker build -t angular/node-bazel-windows:NEW_VERSION`, followed by
|
||||
`docker push angular/node-bazel-windows:NEW_VERSION`.
|
||||
After being pushed it should be available online, and you can use the new version in `pipeline.yml`.
|
||||
|
||||
|
||||
## Caretaker
|
||||
|
||||
BuildKite status can be found at https://www.buildkitestatus.com/.
|
||||
|
||||
Issues related to the BuildKite setup should be escalated to the Tools Team via the current
|
||||
caretaker, followed by Alex Eagle and Filipe Silva.
|
||||
|
||||
Support requests should be submitted via email to support@buildkite.com and cc Igor, Misko, Alex,
|
||||
Jeremy and Manu
|
||||
|
||||
|
||||
## Rollout strategy
|
||||
|
||||
At the moment our BuildKite CI uses 1 host VM running 4 agents, thus being capable of 4 concurrent
|
||||
builds.
|
||||
The only test running is `bazel test //tools/ts-api-guardian:all`, and the PR check is not
|
||||
mandatory.
|
||||
|
||||
In the future we should add cache support to speed up the initial `yarn` install, and also Bazel
|
||||
remote caching to speed up Bazel builds.
|
||||
|
||||
After the current setup is verified as stable and reliable the GitHub PR check can become mandatory.
|
||||
|
||||
The tests ran should also be expanded to cover most, if not all, of the Bazel tests.
|
@ -1,6 +0,0 @@
|
||||
@echo off
|
||||
REM Fix for https://github.com/docker/for-win/issues/2920
|
||||
REM echo "Fixing msys64 folder..."
|
||||
REM Touch all .dll files inside C:\msys64\
|
||||
forfiles /p C:\msys64\ /s /m *.dll /c "cmd /c Copy /B @path+,, >NUL"
|
||||
REM echo "Fixed msys64 folder."
|
@ -1,10 +0,0 @@
|
||||
steps:
|
||||
- label: windows-test
|
||||
commands:
|
||||
- "yarn install --frozen-lockfile --non-interactive --network-timeout 100000"
|
||||
- "yarn bazel test //tools/ts-api-guardian:all --noshow_progress"
|
||||
plugins:
|
||||
- docker#v2.1.0:
|
||||
image: "filipesilva/node-bazel-windows:0.0.2"
|
||||
agents:
|
||||
windows: true
|
@ -1,92 +0,0 @@
|
||||
# PowerShell script to provision a Windows Server with BuildKite
|
||||
# This script follows https://buildkite.com/docs/agent/v3/windows.
|
||||
|
||||
# Instructions
|
||||
|
||||
# VM creation:
|
||||
# In Google Cloud Platform, create a Compute Engine instance.
|
||||
# We recommend machine type n1-highcpu-16 (16 vCPUs, 14.4 GB memory).
|
||||
# Use a windows boot disk with container support such as
|
||||
# "Windows Server version 1803 Datacenter Core for Containers".
|
||||
# Give it a name, then click "Create".
|
||||
|
||||
# VM setup:
|
||||
# In the Compute Engine menu, select "VM Instances". Click on the VM name you chose before.
|
||||
# Click "Set Windows Password" to choose a username and password.
|
||||
# Click RDP to open a remote desktop via browser, using the username and password.
|
||||
# In the Windows command prompt start an elevated powershell by inputing
|
||||
# "powershell -Command "Start-Process PowerShell -Verb RunAs" followed by Enter.
|
||||
# Download and execute this script from GitHub, passing the token (mandatory), tags (optional)
|
||||
# and number of agents (optional) as args:
|
||||
# ```
|
||||
# Invoke-WebRequest -Uri https://raw.githubusercontent.com/angular/angular/master/.buildkite/provision-windows-buildkite.ps1 -OutFile provision.ps1
|
||||
# .\provision.ps1 -token "MY_TOKEN" -tags "windows=true,another_tag=true" -agents 4
|
||||
# ```
|
||||
# The VM should restart and be fully configured.
|
||||
|
||||
# Creating extra VMs
|
||||
# You can create an image of the current VM by following the instructions below.
|
||||
# https://cloud.google.com/compute/docs/instances/windows/creating-windows-os-image
|
||||
# Then create a new VM and choose "Custom images".
|
||||
|
||||
|
||||
# Script proper.
|
||||
|
||||
# Get the token and tags from arguments.
|
||||
param (
|
||||
[Parameter(Mandatory=$true)][string]$token,
|
||||
[string]$tags = ""
|
||||
[Int]$agents = 1
|
||||
)
|
||||
|
||||
# Allow HTTPS
|
||||
[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls"
|
||||
|
||||
# Helper to add to PATH.
|
||||
# Will take current PATH so avoid running it after anything to modifies only the powershell session path.
|
||||
function Add-Path ([string]$newPathItem) {
|
||||
$Env:Path+= ";" + $newPathItem + ";"
|
||||
[Environment]::SetEnvironmentVariable("Path",$env:Path, [System.EnvironmentVariableTarget]::Machine)
|
||||
}
|
||||
|
||||
# Install Git for Windows
|
||||
Write-Host "Installing Git for Windows."
|
||||
Invoke-WebRequest -Uri https://github.com/git-for-windows/git/releases/download/v2.19.1.windows.1/Git-2.19.1-64-bit.exe -OutFile git.exe
|
||||
.\git.exe /VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /COMPONENTS="icons,ext\reg\shellhere,assoc,assoc_sh" /DIR="C:\git"
|
||||
Add-Path "C:\git\bin"
|
||||
Remove-Item git.exe
|
||||
|
||||
# Download NSSM (https://nssm.cc/) to run the BuildKite agent as a service.
|
||||
Write-Host "Downloading NSSM."
|
||||
Invoke-WebRequest -Uri https://nssm.cc/ci/nssm-2.24-101-g897c7ad.zip -OutFile nssm.zip
|
||||
Expand-Archive -Path nssm.zip -DestinationPath C:\nssm
|
||||
Add-Path "C:\nssm\nssm-2.24-101-g897c7ad\win64"
|
||||
Remove-Item nssm.zip
|
||||
|
||||
# Run the BuildKite agent install script
|
||||
Write-Host "Installing BuildKite agent."
|
||||
$env:buildkiteAgentToken = $token
|
||||
$env:buildkiteAgentTags = $tags
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||
iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/buildkite/agent/master/install.ps1'))
|
||||
|
||||
# Configure the BuildKite agent clone and timestamp behavior
|
||||
Add-Content C:\buildkite-agent\buildkite-agent.cfg "`ngit-clone-flags=--config core.autocrlf=input --config core.eol=lf --config core.longpaths=true --config core.symlinks=true`n"
|
||||
Add-Content C:\buildkite-agent\buildkite-agent.cfg "`ntimestamp-lines=true`n"
|
||||
|
||||
# Register the BuildKite agent service using NSSM, so that it persists through restarts and is
|
||||
# restarted if the process dies.
|
||||
for ($i=1; $i -le $agents; $i++)
|
||||
{
|
||||
$agentName = "buildkite-agent-$i"
|
||||
Write-Host "Registering $agentName as a service."
|
||||
nssm.exe install $agentName "C:\buildkite-agent\bin\buildkite-agent.exe" "start"
|
||||
nssm.exe set $agentName AppStdout "C:\buildkite-agent\$agentName.log"
|
||||
nssm.exe set $agentName AppStderr "C:\buildkite-agent\$agentName.log"
|
||||
nssm.exe status $agentName
|
||||
nssm.exe start $agentName
|
||||
nssm.exe status $agentName
|
||||
}
|
||||
|
||||
# Restart the machine.
|
||||
Restart-Computer
|
@ -16,6 +16,10 @@ test --test_tag_filters=-manual
|
||||
# (e.g. /etc/bazel.bazelrc vs. tools/bazel.rc)
|
||||
build --announce_rc
|
||||
|
||||
# Create dist/bin symlink to $(bazel info bazel-bin)
|
||||
# We use this when uploading artifacts after the build finishes
|
||||
build --symlink_prefix=dist/
|
||||
|
||||
# Workaround https://github.com/bazelbuild/bazel/issues/3645
|
||||
# Bazel doesn't calculate the memory ceiling correctly when running under Docker.
|
||||
# Limit Bazel to consuming resources that fit in CircleCI "xlarge" class
|
||||
|
@ -33,18 +33,24 @@ var_6: &job_defaults
|
||||
docker:
|
||||
- image: *default_docker_image
|
||||
|
||||
var_7: &start-xvfb
|
||||
run:
|
||||
name: Running X virtual framebuffer
|
||||
command: Xvfb :99 -screen 0 1280x1024x24
|
||||
background: true
|
||||
|
||||
# After checkout, rebase on top of master.
|
||||
# Similar to travis behavior, but not quite the same.
|
||||
# See https://discuss.circleci.com/t/1662
|
||||
var_7: &post_checkout
|
||||
var_8: &post_checkout
|
||||
post: git pull --ff-only origin "refs/pull/${CI_PULL_REQUEST//*pull\//}/merge"
|
||||
|
||||
var_8: &yarn_install
|
||||
var_9: &yarn_install
|
||||
run:
|
||||
name: Running Yarn install
|
||||
command: yarn install --frozen-lockfile --non-interactive
|
||||
|
||||
var_9: &setup_circleci_bazel_config
|
||||
var_10: &setup_circleci_bazel_config
|
||||
run:
|
||||
name: Setting up CircleCI bazel configuration
|
||||
command: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
|
||||
@ -90,37 +96,13 @@ jobs:
|
||||
- run: sudo cp .circleci/bazel.rc /etc/bazel.bazelrc
|
||||
- run: yarn bazel test //... --build_tag_filters=-ivy-only,local --test_tag_filters=-ivy-only,local
|
||||
|
||||
- save_cache:
|
||||
key: *cache_key
|
||||
paths:
|
||||
- "node_modules"
|
||||
- "~/bazel_repository_cache"
|
||||
|
||||
# Temporary job to test what will happen when we flip the Ivy flag to true
|
||||
test_ivy_aot:
|
||||
<<: *job_defaults
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout:
|
||||
<<: *post_checkout
|
||||
- restore_cache:
|
||||
key: *cache_key
|
||||
- *define_env_vars
|
||||
- *setup_circleci_bazel_config
|
||||
- *yarn_install
|
||||
- *setup_bazel_remote_execution
|
||||
|
||||
# We need to explicitly specify the --symlink_prefix option because otherwise we would
|
||||
# not be able to easily find the output bin directory when uploading artifacts for size
|
||||
# measurements.
|
||||
- run: yarn test-ivy-aot //... --symlink_prefix=dist/
|
||||
|
||||
# Publish bundle artifacts which will be used to calculate the size change. **Note**: Make
|
||||
# sure that the size plugin from the Angular robot fetches the artifacts from this CircleCI
|
||||
# job (see .github/angular-robot.yml). Additionally any artifacts need to be stored with the
|
||||
# following path format: "{projectName}/{context}/{fileName}". This format is necessary
|
||||
# because otherwise the bot is not able to pick up the artifacts from CircleCI. See:
|
||||
# https://github.com/angular/github-robot/blob/master/functions/src/plugins/size.ts#L392-L394
|
||||
# CircleCI will allow us to go back and view/download these artifacts from past builds.
|
||||
# Also we can use a service like https://buildsize.org/ to automatically track binary size of these artifacts.
|
||||
# The destination keys need be format {projectName}/{context}/{fileName} so that the github-robot can process them for size calculations
|
||||
# projectName should remain consistant to group files
|
||||
# context and fileName can be almost anything (within usual URI rules)
|
||||
# There should only be exactly 2 forward slashes in the path
|
||||
# This is so they're backwards compatiable with the existing data we have on bundle sizes
|
||||
- store_artifacts:
|
||||
path: dist/bin/packages/core/test/bundling/hello_world/bundle.min.js
|
||||
destination: core/hello_world/bundle
|
||||
@ -133,6 +115,46 @@ jobs:
|
||||
- store_artifacts:
|
||||
path: dist/bin/packages/core/test/bundling/todo/bundle.min.js.br
|
||||
destination: core/todo/bundle.br
|
||||
- save_cache:
|
||||
key: *cache_key
|
||||
paths:
|
||||
- "node_modules"
|
||||
- "~/bazel_repository_cache"
|
||||
|
||||
# Temporary job to test what will happen when we flip the Ivy flag to true
|
||||
test_ivy_jit:
|
||||
<<: *job_defaults
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
# don't run this job on the patch branch (to preserve resources)
|
||||
- run: circleci step halt
|
||||
- checkout:
|
||||
<<: *post_checkout
|
||||
- restore_cache:
|
||||
key: *cache_key
|
||||
- *define_env_vars
|
||||
- *setup_circleci_bazel_config
|
||||
- *yarn_install
|
||||
- *setup_bazel_remote_execution
|
||||
|
||||
- run: yarn test-ivy-jit //...
|
||||
|
||||
test_ivy_aot:
|
||||
<<: *job_defaults
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
# don't run this job on the patch branch (to preserve resources)
|
||||
- run: circleci step halt
|
||||
- checkout:
|
||||
<<: *post_checkout
|
||||
- restore_cache:
|
||||
key: *cache_key
|
||||
- *define_env_vars
|
||||
- *setup_circleci_bazel_config
|
||||
- *yarn_install
|
||||
- *setup_bazel_remote_execution
|
||||
|
||||
- run: yarn test-ivy-aot //...
|
||||
|
||||
test_aio:
|
||||
<<: *job_defaults
|
||||
@ -145,6 +167,7 @@ jobs:
|
||||
- restore_cache:
|
||||
key: *cache_key
|
||||
- *define_env_vars
|
||||
- *start-xvfb
|
||||
# Build aio
|
||||
- run: yarn --cwd aio build --progress=false
|
||||
# Lint the code
|
||||
@ -173,6 +196,7 @@ jobs:
|
||||
- restore_cache:
|
||||
key: *cache_key
|
||||
- *define_env_vars
|
||||
- *start-xvfb
|
||||
# Deploy angular.io to production (if necessary)
|
||||
- run: setPublicVar CI_STABLE_BRANCH "$(npm info @angular/core dist-tags.latest | sed -r 's/^\s*([0-9]+\.[0-9]+)\.[0-9]+.*$/\1.x/')"
|
||||
- run: yarn --cwd aio deploy-production
|
||||
@ -190,6 +214,7 @@ jobs:
|
||||
- attach_workspace:
|
||||
at: dist
|
||||
- *define_env_vars
|
||||
- *start-xvfb
|
||||
# Build aio (with local Angular packages)
|
||||
- run: yarn --cwd aio build-local --progress=false
|
||||
# Run PWA-score tests
|
||||
@ -230,6 +255,7 @@ jobs:
|
||||
- attach_workspace:
|
||||
at: dist
|
||||
- *define_env_vars
|
||||
- *start-xvfb
|
||||
# Install root
|
||||
- *yarn_install
|
||||
# Install aio
|
||||
@ -250,6 +276,7 @@ jobs:
|
||||
- attach_workspace:
|
||||
at: dist
|
||||
- *define_env_vars
|
||||
- *start-xvfb
|
||||
# Install root
|
||||
- *yarn_install
|
||||
# Install aio
|
||||
@ -275,7 +302,6 @@ jobs:
|
||||
# The `destination` needs to be kept in synch with the value of
|
||||
# `AIO_ARTIFACT_PATH` in `aio/aio-builds-setup/Dockerfile`
|
||||
destination: aio/dist/aio-snapshot.tgz
|
||||
- run: node ./aio/scripts/create-preview $CIRCLE_BUILD_NUM
|
||||
|
||||
# This job should only be run on PR builds, where `CI_PULL_REQUEST` is not `false`.
|
||||
test_aio_preview:
|
||||
@ -289,6 +315,7 @@ jobs:
|
||||
- restore_cache:
|
||||
key: *cache_key
|
||||
- *define_env_vars
|
||||
- *start-xvfb
|
||||
- run: yarn install --cwd aio --frozen-lockfile --non-interactive
|
||||
- run:
|
||||
name: Wait for preview and run tests
|
||||
@ -348,6 +375,7 @@ jobs:
|
||||
- attach_workspace:
|
||||
at: dist
|
||||
- *define_env_vars
|
||||
- *start-xvfb
|
||||
- run: ./integration/run_tests.sh
|
||||
|
||||
# This job updates the content of repos like github.com/angular/core-builds
|
||||
@ -391,6 +419,7 @@ jobs:
|
||||
- restore_cache:
|
||||
key: *cache_key
|
||||
- *define_env_vars
|
||||
- *start-xvfb
|
||||
- run:
|
||||
name: Run tests against the deployed apps
|
||||
command: ./aio/scripts/test-production.sh $CI_AIO_MIN_PWA_SCORE
|
||||
@ -405,6 +434,7 @@ workflows:
|
||||
jobs:
|
||||
- lint
|
||||
- test
|
||||
- test_ivy_jit
|
||||
- test_ivy_aot
|
||||
- build-packages-dist
|
||||
- test_aio
|
||||
@ -442,6 +472,7 @@ workflows:
|
||||
requires:
|
||||
# Only publish if tests and integration tests pass
|
||||
- test
|
||||
- test_ivy_jit
|
||||
- test_ivy_aot
|
||||
- integration_test
|
||||
# Only publish if `aio`/`docs` tests using the locally built Angular packages pass
|
||||
@ -462,3 +493,7 @@ workflows:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
notify:
|
||||
webhooks:
|
||||
- url: https://ngbuilds.io/circle-build
|
||||
|
@ -1,107 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Usage (cli):
|
||||
* ```
|
||||
* node create-preview <build-number> <job-name> <webhook-url>
|
||||
* ```
|
||||
*
|
||||
* Usage (JS):
|
||||
* ```js
|
||||
* require('./trigger-webhook').
|
||||
* triggerWebhook(buildNumber, jobName, webhookUrl).
|
||||
* then(...);
|
||||
* ```
|
||||
*
|
||||
* Triggers a notification webhook with CircleCI specific info.
|
||||
*
|
||||
* It can be used for notifying external servers and trigger operations based on CircleCI job status
|
||||
* (e.g. triggering the creation of a preview based on previously stored build atrifacts).
|
||||
*
|
||||
* The body of the sent payload is of the form:
|
||||
* ```json
|
||||
* {
|
||||
* "payload": {
|
||||
* "build_num": ${buildNumber}
|
||||
* "build_parameters": {
|
||||
* "CIRCLE_JOB": "${jobName}"
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* When used from JS, it returns a promise which resolves to an object of the form:
|
||||
* ```json
|
||||
* {
|
||||
* "statucCode": ${statusCode},
|
||||
* "responseText": "${responseText}"
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* NOTE:
|
||||
* - When used from the cli, the command will exit with an error code if the response's status code
|
||||
* is outside the [200, 400) range.
|
||||
* - When used from JS, the returned promise will be resolved, even if the response's status code is
|
||||
* outside the [200, 400) range. It is up to the caller to decide how this should be handled.
|
||||
*/
|
||||
|
||||
// Imports
|
||||
const {request} = require('https');
|
||||
|
||||
// Exports
|
||||
module.exports = {
|
||||
triggerWebhook,
|
||||
};
|
||||
|
||||
// Run
|
||||
if (require.resolve === module) {
|
||||
_main(process.argv.slice(2));
|
||||
}
|
||||
|
||||
// Helpers
|
||||
function _main(args) {
|
||||
triggerWebhook(...args).
|
||||
then(({statusCode, responseText}) => (200 <= statusCode && statusCode < 400) ?
|
||||
console.log(`Status: ${statusCode}\n${responseText}`) :
|
||||
Promise.reject(new Error(`Request failed (status: ${statusCode}): ${responseText}`))).
|
||||
catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
function postJson(url, data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const opts = {method: 'post', headers: {'Content-Type': 'application/json'}};
|
||||
const onResponse = res => {
|
||||
const statusCode = res.statusCode || -1;
|
||||
let responseText = '';
|
||||
|
||||
res.
|
||||
on('error', reject).
|
||||
on('data', d => responseText += d).
|
||||
on('end', () => resolve({statusCode, responseText}));
|
||||
};
|
||||
|
||||
request(url, opts, onResponse).
|
||||
on('error', reject).
|
||||
end(JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
|
||||
async function triggerWebhook(buildNumber, jobName, webhookUrl) {
|
||||
if (!buildNumber || !jobName || !webhookUrl || isNaN(buildNumber)) {
|
||||
throw new Error(
|
||||
'Missing or invalid arguments.\n' +
|
||||
'Expected: buildNumber (number), jobName (string), webhookUrl (string)');
|
||||
}
|
||||
|
||||
const data = {
|
||||
payload: {
|
||||
build_num: +buildNumber,
|
||||
build_parameters: {CIRCLE_JOB: jobName},
|
||||
},
|
||||
};
|
||||
|
||||
return postJson(webhookUrl, data);
|
||||
}
|
61
.github/ISSUE_TEMPLATE.md
vendored
61
.github/ISSUE_TEMPLATE.md
vendored
@ -1,10 +1,59 @@
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
<!--
|
||||
PLEASE HELP US PROCESS GITHUB ISSUES FASTER BY PROVIDING THE FOLLOWING INFORMATION.
|
||||
|
||||
Please help us process issues more efficiently by filing an
|
||||
issue using one of the following templates:
|
||||
ISSUES MISSING IMPORTANT INFORMATION MAY BE CLOSED WITHOUT INVESTIGATION.
|
||||
-->
|
||||
|
||||
https://github.com/angular/angular/issues/new/choose
|
||||
## I'm submitting a...
|
||||
<!-- Check one of the following options with "x" -->
|
||||
<pre><code>
|
||||
[ ] Regression (a behavior that used to work and stopped working in a new release)
|
||||
[ ] Bug report <!-- Please search GitHub for a similar issue or PR before submitting -->
|
||||
[ ] Performance issue
|
||||
[ ] Feature request
|
||||
[ ] Documentation issue or request
|
||||
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
|
||||
[ ] Other... Please describe:
|
||||
</code></pre>
|
||||
|
||||
Thank you!
|
||||
## Current behavior
|
||||
<!-- Describe how the issue manifests. -->
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
## Expected behavior
|
||||
<!-- Describe what the desired behavior would be. -->
|
||||
|
||||
|
||||
## Minimal reproduction of the problem with instructions
|
||||
<!--
|
||||
For bug reports please provide the *STEPS TO REPRODUCE* and if possible a *MINIMAL DEMO* of the problem via
|
||||
https://stackblitz.com or similar (you can use this template as a starting point: https://stackblitz.com/fork/angular-gitter).
|
||||
-->
|
||||
|
||||
## What is the motivation / use case for changing the behavior?
|
||||
<!-- Describe the motivation or the concrete use case. -->
|
||||
|
||||
|
||||
## Environment
|
||||
|
||||
<pre><code>
|
||||
Angular version: X.Y.Z
|
||||
<!-- Check whether this is still an issue in the most recent Angular version -->
|
||||
|
||||
Browser:
|
||||
- [ ] Chrome (desktop) version XX
|
||||
- [ ] Chrome (Android) version XX
|
||||
- [ ] Chrome (iOS) version XX
|
||||
- [ ] Firefox version XX
|
||||
- [ ] Safari (desktop) version XX
|
||||
- [ ] Safari (iOS) version XX
|
||||
- [ ] IE version XX
|
||||
- [ ] Edge version XX
|
||||
|
||||
For Tooling issues:
|
||||
- Node version: XX <!-- run `node --version` -->
|
||||
- Platform: <!-- Mac, Linux, Windows -->
|
||||
|
||||
Others:
|
||||
<!-- Anything else relevant? Operating system version, IDE, package manager, HTTP server, ... -->
|
||||
</code></pre>
|
||||
|
63
.github/ISSUE_TEMPLATE/1-bug-report.md
vendored
63
.github/ISSUE_TEMPLATE/1-bug-report.md
vendored
@ -1,63 +0,0 @@
|
||||
---
|
||||
name: "\U0001F41EBug report"
|
||||
about: Report a bug in the Angular Framework
|
||||
---
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Oh hi there! 😄
|
||||
|
||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
||||
|
||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||
|
||||
|
||||
# 🐞 bug report
|
||||
|
||||
### Affected Package
|
||||
<!-- Can you pin-point one or more @angular/* packages as the source of the bug? -->
|
||||
<!-- ✍️edit: --> The issue is caused by package @angular/....
|
||||
|
||||
|
||||
### Is this a regression?
|
||||
|
||||
<!-- Did this behavior use to work in the previous version? -->
|
||||
<!-- ✍️--> Yes, the previous version in which this bug was not present was: ....
|
||||
|
||||
|
||||
### Description
|
||||
|
||||
<!-- ✍️--> A clear and concise description of the problem...
|
||||
|
||||
|
||||
## 🔬 Minimal Reproduction
|
||||
<!--
|
||||
Please create and share minimal reproduction of the issue starting with this template: https://stackblitz.com/fork/angular-issue-repro2
|
||||
-->
|
||||
<!-- ✍️--> https://stackblitz.com/...
|
||||
|
||||
<!--
|
||||
If StackBlitz is not suitable for reproduction of your issue, please create a minimal GitHub repository with the reproduction of the issue. Share the link to the repo below along with step-by-step instructions to reproduce the problem, as well as expected and actual behavior.
|
||||
-->
|
||||
|
||||
## 🔥 Exception or Error
|
||||
<pre><code>
|
||||
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
|
||||
<!-- ✍️-->
|
||||
|
||||
</code></pre>
|
||||
|
||||
|
||||
## 🌍 Your Environment
|
||||
|
||||
**Angular Version:**
|
||||
<pre><code>
|
||||
<!-- run `ng version` and paste output below -->
|
||||
<!-- ✍️-->
|
||||
|
||||
</code></pre>
|
||||
|
||||
**Anything else relevant?**
|
||||
<!-- ✍️Is this a browser specific issue? If so, please specify the browser and version. -->
|
||||
|
||||
<!-- ✍️Do any of these matter: operating system, IDE, package manager, HTTP server, ...? If so, please mention it below. -->
|
32
.github/ISSUE_TEMPLATE/2-feature-request.md
vendored
32
.github/ISSUE_TEMPLATE/2-feature-request.md
vendored
@ -1,32 +0,0 @@
|
||||
---
|
||||
name: "\U0001F680Feature request"
|
||||
about: Suggest a feature for Angular Framework
|
||||
|
||||
---
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Oh hi there! 😄
|
||||
|
||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
||||
|
||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||
|
||||
|
||||
# 🚀 feature request
|
||||
|
||||
### Relevant Package
|
||||
<!-- Can you pin-point one or more @angular/* packages the are relevant for this feature request? -->
|
||||
<!-- ✍️edit: --> This feature request is for @angular/....
|
||||
|
||||
|
||||
### Description
|
||||
<!-- ✍️--> A clear and concise description of the problem or missing capability...
|
||||
|
||||
|
||||
### Describe the solution you'd like
|
||||
<!-- ✍️--> If you have a solution in mind, please describe it.
|
||||
|
||||
|
||||
### Describe alternatives you've considered
|
||||
<!-- ✍️--> Have you considered any alternative solutions or workarounds?
|
55
.github/ISSUE_TEMPLATE/3-docs-bug.md
vendored
55
.github/ISSUE_TEMPLATE/3-docs-bug.md
vendored
@ -1,55 +0,0 @@
|
||||
---
|
||||
name: "📚 Docs or angular.io issue report"
|
||||
about: Report an issue in Angular's documentation or angular.io application
|
||||
|
||||
---
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Oh hi there! 😄
|
||||
|
||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
||||
|
||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||
|
||||
# 📚 Docs or angular.io bug report
|
||||
|
||||
### Description
|
||||
|
||||
<!-- ✍️edit:--> A clear and concise description of the problem...
|
||||
|
||||
|
||||
## 🔬 Minimal Reproduction
|
||||
|
||||
### What's the affected URL?**
|
||||
<!-- ✍️edit:--> https://angular.io/...
|
||||
|
||||
### Reproduction Steps**
|
||||
<!-- If applicable please list the steps to take to reproduce the issue -->
|
||||
<!-- ✍️edit:-->
|
||||
|
||||
### Expected vs Actual Behavior**
|
||||
<!-- If applicable please describe the difference between the expected and actual behavior after following the repro steps. -->
|
||||
<!-- ✍️edit:-->
|
||||
|
||||
|
||||
## 📷Screenshot
|
||||
<!-- Often a screenshot can help to capture the issue better than a long description. -->
|
||||
<!-- ✍️upload a screenshot:-->
|
||||
|
||||
|
||||
## 🔥 Exception or Error
|
||||
<pre><code>
|
||||
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
|
||||
<!-- ✍️-->
|
||||
|
||||
</code></pre>
|
||||
|
||||
|
||||
## 🌍 Your Environment
|
||||
|
||||
### Browser info
|
||||
<!-- ✍️Is this a browser specific issue? If so, please specify the device, browser, and version. -->
|
||||
|
||||
### Anything else relevant?
|
||||
<!-- ✍️Please provide additional info if necessary. -->
|
@ -1,11 +0,0 @@
|
||||
---
|
||||
name: ⚠️ Security issue disclosure
|
||||
about: Report a security issue in Angular Framework, Material, or CLI
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please read https://angular.io/guide/security#report-issues on how to disclose security related issues.
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
16
.github/ISSUE_TEMPLATE/5-support-request.md
vendored
16
.github/ISSUE_TEMPLATE/5-support-request.md
vendored
@ -1,16 +0,0 @@
|
||||
---
|
||||
name: "❓Support request"
|
||||
about: Questions and requests for support
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please do not file questions or support requests on the GitHub issues tracker.
|
||||
|
||||
You can get your questions answered using other communication channels. Please see:
|
||||
https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
|
||||
|
||||
Thank you!
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
13
.github/ISSUE_TEMPLATE/6-angular-cli.md
vendored
13
.github/ISSUE_TEMPLATE/6-angular-cli.md
vendored
@ -1,13 +0,0 @@
|
||||
---
|
||||
name: "\U0001F6E0️Angular CLI"
|
||||
about: Issues and feature requests for Angular CLI
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please file any Angular CLI issues at: https://github.com/angular/angular-cli/issues/new
|
||||
|
||||
For the time being, we keep Angular CLI issues in a separate repository.
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
13
.github/ISSUE_TEMPLATE/7-angular-material.md
vendored
13
.github/ISSUE_TEMPLATE/7-angular-material.md
vendored
@ -1,13 +0,0 @@
|
||||
---
|
||||
name: "\U0001F48EAngular Material"
|
||||
about: Issues and feature requests for Angular Material
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please file any Angular Material issues at: https://github.com/angular/material2/issues/new
|
||||
|
||||
For the time being, we keep Angular Material issues in a separate repository.
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
3
.github/angular-robot.yml
vendored
3
.github/angular-robot.yml
vendored
@ -4,7 +4,7 @@
|
||||
size:
|
||||
disabled: false
|
||||
maxSizeIncrease: 2000
|
||||
circleCiStatusName: "ci/circleci: test_ivy_aot"
|
||||
circleCiStatusName: "ci/circleci: test"
|
||||
|
||||
# options for the merge plugin
|
||||
merge:
|
||||
@ -50,7 +50,6 @@ merge:
|
||||
- "**/BUILD.bazel"
|
||||
- "packages/**/integrationtest/**"
|
||||
- "packages/**/test/**"
|
||||
- "packages/compiler-cli/src/ngcc/**"
|
||||
|
||||
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable
|
||||
mergeConflictComment: "Hi @{{PRAuthor}}! This PR has merge conflicts due to recent upstream merges.
|
||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,8 +1,7 @@
|
||||
.DS_STORE
|
||||
|
||||
/dist/
|
||||
/bazel-*
|
||||
/integration/bazel/bazel-*
|
||||
bazel-*
|
||||
e2e_test.*
|
||||
node_modules
|
||||
bower_components
|
||||
@ -30,7 +29,3 @@ yarn-error.log
|
||||
|
||||
# rollup-test output
|
||||
/modules/rollup-test/dist/
|
||||
|
||||
# User specific bazel settings
|
||||
.bazelrc.user
|
||||
|
||||
|
@ -98,7 +98,6 @@ groups:
|
||||
- IgorMinar #fallback
|
||||
- mhevery
|
||||
- vikerman #fallback
|
||||
- kara
|
||||
|
||||
build-and-ci:
|
||||
conditions:
|
||||
@ -109,9 +108,8 @@ groups:
|
||||
- "*.lock"
|
||||
- "tools/*"
|
||||
exclude:
|
||||
- "aio/*"
|
||||
- "packages/core/test/bundling/*"
|
||||
- "tools/public_api_guard/*"
|
||||
- "aio/*"
|
||||
users:
|
||||
- IgorMinar #primary
|
||||
- alexeagle
|
||||
@ -212,7 +210,6 @@ groups:
|
||||
- mhevery #fallback
|
||||
- IgorMinar #fallback
|
||||
- jenniferfell #docs only
|
||||
- kara
|
||||
|
||||
compiler/i18n:
|
||||
conditions:
|
||||
@ -225,7 +222,6 @@ groups:
|
||||
- IgorMinar #fallback
|
||||
- mhevery #fallback
|
||||
- jenniferfell #docs only
|
||||
- kara
|
||||
|
||||
compiler:
|
||||
conditions:
|
||||
@ -237,7 +233,6 @@ groups:
|
||||
- mhevery
|
||||
- IgorMinar #fallback
|
||||
- jenniferfell #docs only
|
||||
- kara
|
||||
|
||||
compiler-cli/ngtools:
|
||||
conditions:
|
||||
@ -247,7 +242,6 @@ groups:
|
||||
- hansl
|
||||
- filipesilva #fallback
|
||||
- IgorMinar #fallback
|
||||
- kara
|
||||
|
||||
compiler-cli:
|
||||
conditions:
|
||||
@ -262,7 +256,6 @@ groups:
|
||||
- alxhub
|
||||
- IgorMinar #fallback
|
||||
- mhevery #fallback
|
||||
- kara
|
||||
|
||||
common:
|
||||
conditions:
|
||||
@ -275,7 +268,6 @@ groups:
|
||||
- pkozlowski-opensource #primary
|
||||
- IgorMinar #fallback
|
||||
- mhevery #fallback
|
||||
- kara
|
||||
|
||||
forms:
|
||||
conditions:
|
||||
@ -341,7 +333,6 @@ groups:
|
||||
- IgorMinar #fallback
|
||||
- mhevery #fallback
|
||||
- jenniferfell #docs only
|
||||
- kara
|
||||
|
||||
testing:
|
||||
conditions:
|
||||
@ -375,7 +366,6 @@ groups:
|
||||
- IgorMinar #fallback
|
||||
- mhevery #fallback
|
||||
- jenniferfell #docs only
|
||||
- kara
|
||||
|
||||
platform-browser:
|
||||
conditions:
|
||||
@ -385,7 +375,6 @@ groups:
|
||||
- mhevery #primary
|
||||
# needs secondary
|
||||
- IgorMinar #fallback
|
||||
- kara
|
||||
|
||||
platform-server:
|
||||
conditions:
|
||||
@ -408,7 +397,6 @@ groups:
|
||||
- mhevery #primary
|
||||
# needs secondary
|
||||
- IgorMinar #fallback
|
||||
- kara
|
||||
|
||||
service-worker:
|
||||
conditions:
|
||||
@ -442,7 +430,6 @@ groups:
|
||||
- IgorMinar #fallback
|
||||
- mhevery #fallback
|
||||
- jenniferfell #docs only
|
||||
- kara
|
||||
|
||||
benchpress:
|
||||
conditions:
|
||||
|
170
CHANGELOG.md
170
CHANGELOG.md
@ -1,155 +1,3 @@
|
||||
<a name="7.1.2"></a>
|
||||
## [7.1.2](https://github.com/angular/angular/compare/7.1.1...7.1.2) (2018-12-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bazel:** do not throw error when writing tsickle externs ([#27200](https://github.com/angular/angular/issues/27200)) ([079c4b3](https://github.com/angular/angular/commit/079c4b3))
|
||||
* **bazel:** do not throw if ts compile action does not create esm5 outputs ([#27401](https://github.com/angular/angular/issues/27401)) ([9b4d959](https://github.com/angular/angular/commit/9b4d959))
|
||||
* **bazel:** ng_package cannot be run multiple times without clean ([#27200](https://github.com/angular/angular/issues/27200)) ([1ca2923](https://github.com/angular/angular/commit/1ca2923))
|
||||
* **bazel:** ng_package not generating UMD bundles on windows ([#27200](https://github.com/angular/angular/issues/27200)) ([e476c38](https://github.com/angular/angular/commit/e476c38))
|
||||
* **bazel:** ng_package should correctly map to source maps in secondary entry-points ([#27313](https://github.com/angular/angular/issues/27313)) ([fc2c23e](https://github.com/angular/angular/commit/fc2c23e)), closes [#25510](https://github.com/angular/angular/issues/25510)
|
||||
* **compiler-cli:** flatModuleIndex files not generated on windows with multiple input files ([#27200](https://github.com/angular/angular/issues/27200)) ([8087b6b](https://github.com/angular/angular/commit/8087b6b))
|
||||
* **compiler-cli:** ngtsc shim files not being generated on case-insensitive platforms ([#27466](https://github.com/angular/angular/issues/27466)) ([84f2928](https://github.com/angular/angular/commit/84f2928)), closes [/github.com/Microsoft/TypeScript/blob/3e4c5c95abd515eb9713b881d27ab3a93cc00461/src/compiler/sys.ts#L681-L682](https://github.com//github.com/Microsoft/TypeScript/blob/3e4c5c95abd515eb9713b881d27ab3a93cc00461/src/compiler/sys.ts/issues/L681-L682)
|
||||
* **platform-server:** add [@angular](https://github.com/angular)/http to the list of peerDependencies ([#27307](https://github.com/angular/angular/issues/27307)) ([236ac06](https://github.com/angular/angular/commit/236ac06)), closes [#26154](https://github.com/angular/angular/issues/26154)
|
||||
|
||||
|
||||
|
||||
<a name="7.1.1"></a>
|
||||
## [7.1.1](https://github.com/angular/angular/compare/7.1.0...7.1.1) (2018-11-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **core:** export a value for InjectFlags ([#27279](https://github.com/angular/angular/issues/27279)) ([bdf5f3e](https://github.com/angular/angular/commit/bdf5f3e)), closes [#27251](https://github.com/angular/angular/issues/27251)
|
||||
|
||||
|
||||
|
||||
<a name="7.1.0"></a>
|
||||
# [7.1.0](https://github.com/angular/angular/compare/7.1.0-rc.0...7.1.0) (2018-11-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
|
||||
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
|
||||
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
|
||||
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
|
||||
* **compiler:** generate inputs with aliases properly ([#26774](https://github.com/angular/angular/issues/26774)) ([19fcfc3](https://github.com/angular/angular/commit/19fcfc3))
|
||||
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([56f44be](https://github.com/angular/angular/commit/56f44be))
|
||||
* **core:** ignore comment nodes under unsafe elements ([#25879](https://github.com/angular/angular/issues/25879)) ([d5cbcef](https://github.com/angular/angular/commit/d5cbcef))
|
||||
* **core:** Remove static dependency from [@angular](https://github.com/angular)/core to [@angular](https://github.com/angular)/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
|
||||
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([95743e3](https://github.com/angular/angular/commit/95743e3))
|
||||
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([aed95fd](https://github.com/angular/angular/commit/aed95fd))
|
||||
* **core:** ensure that `ɵdefineNgModule` is available in flat-file formats ([#26403](https://github.com/angular/angular/issues/26403)) ([a64859b](https://github.com/angular/angular/commit/a64859b))
|
||||
* **router:** remove type bludgeoning of context and outlet when running CanDeactivate ([#26496](https://github.com/angular/angular/issues/26496)) ([496372d](https://github.com/angular/angular/commit/496372d)), closes [#18253](https://github.com/angular/angular/issues/18253)
|
||||
* **service-worker:** add typing to public api guard and fix lint errors ([#25860](https://github.com/angular/angular/issues/25860)) ([1061875](https://github.com/angular/angular/commit/1061875))
|
||||
* **upgrade:** improve downgrading-related error messages ([#26217](https://github.com/angular/angular/issues/26217)) ([7dbc103](https://github.com/angular/angular/commit/7dbc103))
|
||||
* **upgrade:** make typings compatible with older AngularJS typings ([#26880](https://github.com/angular/angular/issues/26880)) ([64647af](https://github.com/angular/angular/commit/64647af)), closes [#26420](https://github.com/angular/angular/issues/26420)
|
||||
* **compiler-cli:** add missing tslib dependency ([#27063](https://github.com/angular/angular/issues/27063)) ([c31e78f](https://github.com/angular/angular/commit/c31e78f))
|
||||
* **compiler-cli:** only pass canonical genfile paths to compiler host ([#27062](https://github.com/angular/angular/issues/27062)) ([0ada23a](https://github.com/angular/angular/commit/0ada23a))
|
||||
* **router:** add `relativeLinkResolution` to `recognize` operator ([#26990](https://github.com/angular/angular/issues/26990)) ([a752971](https://github.com/angular/angular/commit/a752971)), closes [#26983](https://github.com/angular/angular/issues/26983)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **bazel:** Bazel workspace schematics ([#26971](https://github.com/angular/angular/issues/26971)) ([b07bd30](https://github.com/angular/angular/commit/b07bd30))
|
||||
* **router:** add prioritizedGuardValue operator optimization and allowing UrlTree return from guard ([#26478](https://github.com/angular/angular/issues/26478)) ([fdfedce](https://github.com/angular/angular/commit/fdfedce))
|
||||
* **compiler:** ability to mark an InvokeFunctionExpr as pure ([#26860](https://github.com/angular/angular/issues/26860)) ([4dfa71f](https://github.com/angular/angular/commit/4dfa71f))
|
||||
* **forms:** add updateOn option to FormBuilder ([#24599](https://github.com/angular/angular/issues/24599)) ([e9e804f](https://github.com/angular/angular/commit/e9e804f))
|
||||
* **router:** allow guards to return UrlTree as well as boolean ([#26521](https://github.com/angular/angular/issues/26521)) ([081f95c](https://github.com/angular/angular/commit/081f95c))
|
||||
* **router:** allow redirect from guards by returning UrlTree ([#26521](https://github.com/angular/angular/issues/26521)) ([152ca66](https://github.com/angular/angular/commit/152ca66))
|
||||
* **router:** guard returning UrlTree cancels current navigation and redirects ([#26521](https://github.com/angular/angular/issues/26521)) ([4e9f2e5](https://github.com/angular/angular/commit/4e9f2e5)), closes [#24618](https://github.com/angular/angular/issues/24618)
|
||||
* **service-worker:** add typing for messagesClicked in SwPush service ([#25860](https://github.com/angular/angular/issues/25860)) ([c78c221](https://github.com/angular/angular/commit/c78c221))
|
||||
* **service-worker:** close notifications and focus window on click ([#25860](https://github.com/angular/angular/issues/25860)) ([f5d5a3d](https://github.com/angular/angular/commit/f5d5a3d))
|
||||
* **service-worker:** handle 'notificationclick' events ([#25860](https://github.com/angular/angular/issues/25860)) ([cf6ea28](https://github.com/angular/angular/commit/cf6ea28)), closes [#20956](https://github.com/angular/angular/issues/20956) [#22311](https://github.com/angular/angular/issues/22311)
|
||||
* **upgrade:** support downgrading multiple modules ([#26217](https://github.com/angular/angular/issues/26217)) ([93837e9](https://github.com/angular/angular/commit/93837e9)), closes [#26062](https://github.com/angular/angular/issues/26062)
|
||||
* **router:** add pathParamsChange mode for runGuardsAndResolvers ([#26861](https://github.com/angular/angular/issues/26861)) ([bf6ac6c](https://github.com/angular/angular/commit/bf6ac6c)), closes [#18253](https://github.com/angular/angular/issues/18253)
|
||||
|
||||
|
||||
<a name="7.1.0-rc.0"></a>
|
||||
# [7.1.0-rc.0](https://github.com/angular/angular/compare/7.1.0-beta.2...7.1.0-rc.0) (2018-11-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler-cli:** add missing tslib dependency ([#27063](https://github.com/angular/angular/issues/27063)) ([c31e78f](https://github.com/angular/angular/commit/c31e78f))
|
||||
* **compiler-cli:** only pass canonical genfile paths to compiler host ([#27062](https://github.com/angular/angular/issues/27062)) ([0ada23a](https://github.com/angular/angular/commit/0ada23a))
|
||||
* **router:** add `relativeLinkResolution` to `recognize` operator ([#26990](https://github.com/angular/angular/issues/26990)) ([a752971](https://github.com/angular/angular/commit/a752971)), closes [#26983](https://github.com/angular/angular/issues/26983)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **router:** add pathParamsChange mode for runGuardsAndResolvers ([#26861](https://github.com/angular/angular/issues/26861)) ([bf6ac6c](https://github.com/angular/angular/commit/bf6ac6c)), closes [#18253](https://github.com/angular/angular/issues/18253)
|
||||
|
||||
|
||||
|
||||
<a name="7.0.4"></a>
|
||||
## [7.0.4](https://github.com/angular/angular/compare/7.0.3...7.0.4) (2018-11-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler-cli:** add missing tslib dependency ([#27063](https://github.com/angular/angular/issues/27063)) ([4348c47](https://github.com/angular/angular/commit/4348c47))
|
||||
* **compiler-cli:** only pass canonical genfile paths to compiler host ([#27062](https://github.com/angular/angular/issues/27062)) ([188e9ce](https://github.com/angular/angular/commit/188e9ce))
|
||||
* **router:** add `relativeLinkResolution` to `recognize` operator ([#26990](https://github.com/angular/angular/issues/26990)) ([d304427](https://github.com/angular/angular/commit/d304427)), closes [#26983](https://github.com/angular/angular/issues/26983)
|
||||
|
||||
|
||||
|
||||
<a name="7.1.0-beta.2"></a>
|
||||
# [7.1.0-beta.2](https://github.com/angular/angular/compare/7.1.0-beta.1...7.1.0-beta.2) (2018-11-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([aed95fd](https://github.com/angular/angular/commit/aed95fd))
|
||||
* **core:** ensure that `ɵdefineNgModule` is available in flat-file formats ([#26403](https://github.com/angular/angular/issues/26403)) ([a64859b](https://github.com/angular/angular/commit/a64859b))
|
||||
* **router:** remove type bludgeoning of context and outlet when running CanDeactivate ([#26496](https://github.com/angular/angular/issues/26496)) ([496372d](https://github.com/angular/angular/commit/496372d)), closes [#18253](https://github.com/angular/angular/issues/18253)
|
||||
* **service-worker:** add typing to public api guard and fix lint errors ([#25860](https://github.com/angular/angular/issues/25860)) ([1061875](https://github.com/angular/angular/commit/1061875))
|
||||
* **upgrade:** improve downgrading-related error messages ([#26217](https://github.com/angular/angular/issues/26217)) ([7dbc103](https://github.com/angular/angular/commit/7dbc103))
|
||||
* **upgrade:** make typings compatible with older AngularJS typings ([#26880](https://github.com/angular/angular/issues/26880)) ([64647af](https://github.com/angular/angular/commit/64647af)), closes [#26420](https://github.com/angular/angular/issues/26420)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **compiler:** ability to mark an InvokeFunctionExpr as pure ([#26860](https://github.com/angular/angular/issues/26860)) ([4dfa71f](https://github.com/angular/angular/commit/4dfa71f))
|
||||
* **forms:** add updateOn option to FormBuilder ([#24599](https://github.com/angular/angular/issues/24599)) ([e9e804f](https://github.com/angular/angular/commit/e9e804f))
|
||||
* **router:** allow guards to return UrlTree as well as boolean ([#26521](https://github.com/angular/angular/issues/26521)) ([081f95c](https://github.com/angular/angular/commit/081f95c))
|
||||
* **router:** allow redirect from guards by returning UrlTree ([#26521](https://github.com/angular/angular/issues/26521)) ([152ca66](https://github.com/angular/angular/commit/152ca66))
|
||||
* **router:** guard returning UrlTree cancels current navigation and redirects ([#26521](https://github.com/angular/angular/issues/26521)) ([4e9f2e5](https://github.com/angular/angular/commit/4e9f2e5)), closes [#24618](https://github.com/angular/angular/issues/24618)
|
||||
* **service-worker:** add typing for messagesClicked in SwPush service ([#25860](https://github.com/angular/angular/issues/25860)) ([c78c221](https://github.com/angular/angular/commit/c78c221))
|
||||
* **service-worker:** close notifications and focus window on click ([#25860](https://github.com/angular/angular/issues/25860)) ([f5d5a3d](https://github.com/angular/angular/commit/f5d5a3d))
|
||||
* **service-worker:** handle 'notificationclick' events ([#25860](https://github.com/angular/angular/issues/25860)) ([cf6ea28](https://github.com/angular/angular/commit/cf6ea28)), closes [#20956](https://github.com/angular/angular/issues/20956) [#22311](https://github.com/angular/angular/issues/22311)
|
||||
* **upgrade:** support downgrading multiple modules ([#26217](https://github.com/angular/angular/issues/26217)) ([93837e9](https://github.com/angular/angular/commit/93837e9)), closes [#26062](https://github.com/angular/angular/issues/26062)
|
||||
|
||||
|
||||
|
||||
<a name="7.0.3"></a>
|
||||
## [7.0.3](https://github.com/angular/angular/compare/7.0.2...7.0.3) (2018-11-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([4d532df](https://github.com/angular/angular/commit/4d532df))
|
||||
* **router:** remove type bludgeoning of context and outlet when running CanDeactivate ([#26496](https://github.com/angular/angular/issues/26496)) ([dc05385](https://github.com/angular/angular/commit/dc05385)), closes [#18253](https://github.com/angular/angular/issues/18253)
|
||||
* **upgrade:** make typings compatible with older AngularJS typings ([#26880](https://github.com/angular/angular/issues/26880)) ([315d95c](https://github.com/angular/angular/commit/315d95c)), closes [#26420](https://github.com/angular/angular/issues/26420)
|
||||
|
||||
|
||||
|
||||
<a name="7.1.0-beta.1"></a>
|
||||
# [7.1.0-beta.1](https://github.com/angular/angular/compare/7.1.0-beta.0...7.1.0-beta.1) (2018-10-31)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **compiler:** generate inputs with aliases properly ([#26774](https://github.com/angular/angular/issues/26774)) ([19fcfc3](https://github.com/angular/angular/commit/19fcfc3))
|
||||
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([56f44be](https://github.com/angular/angular/commit/56f44be))
|
||||
* **core:** ignore comment nodes under unsafe elements ([#25879](https://github.com/angular/angular/issues/25879)) ([d5cbcef](https://github.com/angular/angular/commit/d5cbcef))
|
||||
* **core:** Remove static dependency from [@angular](https://github.com/angular)/core to [@angular](https://github.com/angular)/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
|
||||
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([95743e3](https://github.com/angular/angular/commit/95743e3))
|
||||
|
||||
|
||||
|
||||
<a name="7.0.2"></a>
|
||||
## [7.0.2](https://github.com/angular/angular/compare/7.0.1...7.0.2) (2018-10-31)
|
||||
|
||||
@ -162,23 +10,6 @@
|
||||
|
||||
|
||||
|
||||
<a name="7.1.0-beta.0"></a>
|
||||
# [7.1.0-beta.0](https://github.com/angular/angular/compare/7.0.0-rc.1...7.1.0-beta.0) (2018-10-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
|
||||
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
|
||||
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
|
||||
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **router:** add prioritizedGuardValue operator optimization and allowing UrlTree return from guard ([#26478](https://github.com/angular/angular/issues/26478)) ([fdfedce](https://github.com/angular/angular/commit/fdfedce))
|
||||
|
||||
|
||||
|
||||
<a name="7.0.1"></a>
|
||||
## [7.0.1](https://github.com/angular/angular/compare/7.0.0...7.0.1) (2018-10-24)
|
||||
|
||||
@ -260,7 +91,6 @@ To learn about the release highlights and our new CLI-powered update workflow fo
|
||||
### Bug Fixes
|
||||
|
||||
* **platform-browser:** fix [#22155](https://github.com/angular/angular/issues/22155), destroy hammer manager when `HammerInstance.off()` is run ([#22156](https://github.com/angular/angular/issues/22156)) ([3b4d9dc](https://github.com/angular/angular/commit/3b4d9dc))
|
||||
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([623adbb](https://github.com/angular/angular/commit/623adbb)), closes [#26208](https://github.com/angular/angular/issues/26208)
|
||||
|
||||
|
||||
|
||||
|
15
WORKSPACE
15
WORKSPACE
@ -21,14 +21,6 @@ rules_angular_dependencies()
|
||||
# These are the dependencies only for us
|
||||
rules_angular_dev_dependencies()
|
||||
|
||||
# Install transitive deps of rules_typescript
|
||||
load("@build_bazel_rules_typescript//:package.bzl", "rules_typescript_dependencies")
|
||||
rules_typescript_dependencies()
|
||||
|
||||
# Install transitive deps of rules_nodejs
|
||||
load("@build_bazel_rules_nodejs//:package.bzl", "rules_nodejs_dependencies")
|
||||
rules_nodejs_dependencies()
|
||||
|
||||
#
|
||||
# Point Bazel to WORKSPACEs that live in subdirectories
|
||||
#
|
||||
@ -61,12 +53,13 @@ node_repositories(
|
||||
node_version = "10.9.0",
|
||||
package_json = ["//:package.json"],
|
||||
preserve_symlinks = True,
|
||||
yarn_version = "1.12.1",
|
||||
yarn_version = "1.9.2",
|
||||
)
|
||||
|
||||
local_repository(
|
||||
yarn_install(
|
||||
name = "npm",
|
||||
path = "tools/npm_workspace",
|
||||
package_json = "//tools:npm/package.json",
|
||||
yarn_lock = "//tools:npm/yarn.lock",
|
||||
)
|
||||
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
|
||||
|
3
aio/.gitignore
vendored
3
aio/.gitignore
vendored
@ -44,3 +44,6 @@ protractor-results*.txt
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# copied dependencies
|
||||
src/assets/js/lunr*
|
||||
|
@ -41,6 +41,8 @@ Here are the most important tasks you might need to use:
|
||||
- `yarn example-e2e --filter=foo` - limit e2e tests to those containing the word "foo"
|
||||
- `yarn example-e2e --setup --local` - run e2e tests with the local version of Angular contained in the "dist" folder
|
||||
|
||||
* `yarn build-ie-polyfills` - generates a js file of polyfills that can be loaded in Internet Explorer.
|
||||
|
||||
## Developing on Windows
|
||||
The `packages/` directory may contain Linux-specific symlinks, which are not recognized by Windows.
|
||||
These unresolved links cause the docs generation process to fail because it cannot locate certain files.
|
||||
@ -48,7 +50,7 @@ These unresolved links cause the docs generation process to fail because it cann
|
||||
> Hint: The following steps require administration rights or [Windows Developer Mode](https://docs.microsoft.com/en-us/windows/uwp/get-started/enable-your-device-for-development) enabled!
|
||||
|
||||
To fix this problem, run `scripts/windows/create-symlinks.sh`. This command creates temporary files where the symlinks used to be. Make sure not to commit those files with your documentation changes.
|
||||
When you are done making and testing your documentation changes, you can restore the original symlinks and delete the temporary files by running `scripts/windows/remove-symlinks.sh`.
|
||||
When you are done making and testing your documentation changes, you can restore the original symlinks and delete the temporary files by running `scripts/windows/remove-symlinks.sh`.
|
||||
|
||||
It's necessary to remove the temporary files, because otherwise they're displayed as local changes in your git working copy and certain operations are blocked.
|
||||
|
||||
|
@ -7,7 +7,7 @@ import {CircleCiApi} from '../common/circle-ci-api';
|
||||
import {GithubApi} from '../common/github-api';
|
||||
import {GithubPullRequests} from '../common/github-pull-requests';
|
||||
import {GithubTeams} from '../common/github-teams';
|
||||
import {assert, assertNotMissingOrEmpty, computeShortSha, Logger} from '../common/utils';
|
||||
import {assert, assertNotMissingOrEmpty, Logger} from '../common/utils';
|
||||
import {BuildCreator} from './build-creator';
|
||||
import {ChangedPrVisibilityEvent, CreatedBuildEvent} from './build-events';
|
||||
import {BuildRetriever} from './build-retriever';
|
||||
@ -144,10 +144,7 @@ export class PreviewServerFactory {
|
||||
const artifactPath = await buildRetriever.downloadBuildArtifact(buildNum, pr, sha, cfg.buildArtifactPath);
|
||||
const isPublic = await buildVerifier.getPrIsTrusted(pr);
|
||||
await buildCreator.create(pr, sha, artifactPath, isPublic);
|
||||
|
||||
res.sendStatus(isPublic ? 201 : 202);
|
||||
logger.log(`PR:${pr}, SHA:${computeShortSha(sha)}, Build:${buildNum} - ` +
|
||||
`Successfully created ${isPublic ? 'public' : 'non-public'} preview.`);
|
||||
} catch (err) {
|
||||
logger.error('CircleCI webhook error', err);
|
||||
respondWithError(res, err);
|
||||
|
@ -46,7 +46,7 @@
|
||||
"@types/shelljs": "^0.8.0",
|
||||
"@types/supertest": "^2.0.5",
|
||||
"nodemon": "^1.18.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"npm-run-all": "^4.1.3",
|
||||
"supertest": "^3.1.0",
|
||||
"tslint": "^5.11.0",
|
||||
"tslint-jasmine-noSkipOrFocus": "^1.0.9",
|
||||
|
@ -129,7 +129,7 @@ ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
|
||||
ansi-styles@^3.2.1:
|
||||
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
dependencies:
|
||||
@ -384,7 +384,7 @@ chalk@^1.1.3:
|
||||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1:
|
||||
chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
|
||||
dependencies:
|
||||
@ -532,10 +532,9 @@ cross-spawn@^5.0.1:
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
cross-spawn@^6.0.5:
|
||||
cross-spawn@^6.0.4:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
|
||||
dependencies:
|
||||
nice-try "^1.0.4"
|
||||
path-key "^2.0.1"
|
||||
@ -1631,17 +1630,16 @@ npm-packlist@^1.1.6:
|
||||
ignore-walk "^3.0.1"
|
||||
npm-bundled "^1.0.1"
|
||||
|
||||
npm-run-all@^4.1.5:
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba"
|
||||
integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==
|
||||
npm-run-all@^4.1.3:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.3.tgz#49f15b55a66bb4101664ce270cb18e7103f8f185"
|
||||
dependencies:
|
||||
ansi-styles "^3.2.1"
|
||||
chalk "^2.4.1"
|
||||
cross-spawn "^6.0.5"
|
||||
ansi-styles "^3.2.0"
|
||||
chalk "^2.1.0"
|
||||
cross-spawn "^6.0.4"
|
||||
memorystream "^0.3.1"
|
||||
minimatch "^3.0.4"
|
||||
pidtree "^0.3.0"
|
||||
ps-tree "^1.1.0"
|
||||
read-pkg "^3.0.0"
|
||||
shell-quote "^1.6.1"
|
||||
string.prototype.padend "^3.0.0"
|
||||
@ -1788,11 +1786,6 @@ pause-stream@0.0.11:
|
||||
dependencies:
|
||||
through "~2.3"
|
||||
|
||||
pidtree@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.0.tgz#f6fada10fccc9f99bf50e90d0b23d72c9ebc2e6b"
|
||||
integrity sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg==
|
||||
|
||||
pify@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
|
||||
|
@ -11,13 +11,13 @@ Install the CLI using the `npm` package manager:
|
||||
npm install -g @angular/cli
|
||||
</code-example>
|
||||
|
||||
For details about changes between versions, and information about updating from previous releases,
|
||||
For details about changes between versions, and information about updating from previous releases,
|
||||
see the Releases tab on GitHub: https://github.com/angular/angular-cli/releases
|
||||
|
||||
## Basic workflow
|
||||
|
||||
Invoke the tool on the command line through the `ng` executable.
|
||||
Online help is available on the command line.
|
||||
Invoke the tool on the command line through the `ng` executable.
|
||||
Online help is available on the command line.
|
||||
Enter the following to list commands or options for a given command (such as [generate](cli/generate)) with a short description.
|
||||
|
||||
<code-example format="." language="bash">
|
||||
@ -34,34 +34,33 @@ ng serve
|
||||
</code-example>
|
||||
|
||||
In your browser, open http://localhost:4200/ to see the new app run.
|
||||
When you use the [ng serve](cli/serve) command to build an app and serve it locally, the server automatically rebuilds the app and reloads the page when you change any of the source files.
|
||||
|
||||
## Workspaces and project files
|
||||
|
||||
The [ng new](cli/new) command creates an *Angular workspace* folder and generates a new app skeleton.
|
||||
The [ng new](cli/new) command creates an *Angular workspace* folder and generates a new app skeleton.
|
||||
A workspace can contain multiple apps and libraries.
|
||||
The initial app created by the [ng new](cli/new) command is at the top level of the workspace.
|
||||
The initial app created by the [ng new](cli/new) command is at the top level of the workspace.
|
||||
When you generate an additional app or library in a workspace, it goes into a `projects/` subfolder.
|
||||
|
||||
A newly generated app contains the source files for a root module, with a root component and template.
|
||||
A newly generated app contains the source files for a root module, with a root component and template.
|
||||
Each app has a `src` folder that contains the logic, data, and assets.
|
||||
|
||||
You can edit the generated files directly, or add to and modify them using CLI commands.
|
||||
Use the [ng generate](cli/generate) command to add new files for additional components and services, and code for new pipes, directives, and so on.
|
||||
You can edit the generated files directly, or add to and modify them using CLI commands.
|
||||
Use the [ng generate](cli/generate) command to add new files for additional components and services, and code for new pipes, directives, and so on.
|
||||
Commands such as [add](cli/add) and [generate](cli/generate), which create or operate on apps and libraries, must be executed from within a workspace or project folder.
|
||||
|
||||
* See more about the [Workspace file structure](guide/file-structure).
|
||||
|
||||
### Workspace and project configuration
|
||||
When you use the [ng serve](cli/serve) command to build an app and serve it locally, the server automatically rebuilds the app and reloads the page when you change any of the source files.
|
||||
|
||||
A single workspace configuration file, `angular.json`, is created at the top level of the workspace.
|
||||
This is where you can set per-project defaults for CLI command options, and specify configurations to use when the CLI builds a project for different targets.
|
||||
A single workspace configuration file, `angular.json`, is created at the top level of the workspace.
|
||||
This is where you can set workspace-wide defaults, and specify configurations to use when the CLI builds a project for different targets.
|
||||
|
||||
The [ng config](cli/config) command lets you set and retrieve configuration values from the command line, or you can edit the `angular.json` file directly.
|
||||
Note that option names in the configuration file must use [camelCase](guide/glossary#case-types), while option names supplied to commands can use either camelCase or dash-case.
|
||||
|
||||
* See more about [Workspace Configuration](guide/workspace-config).
|
||||
* See the [complete schema](https://github.com/angular/angular-cli/wiki/angular-workspace) for `angular.json`.
|
||||
<!-- * Learn more about *configuration options for Angular(links to new guide or topics TBD)*. -->
|
||||
|
||||
|
||||
## CLI command-language syntax
|
||||
|
||||
@ -71,20 +70,20 @@ Command syntax is shown as follows:
|
||||
|
||||
* Most commands, and some options, have aliases. Aliases are shown in the syntax statement for each command.
|
||||
|
||||
* Option names are prefixed with a double dash (--).
|
||||
Option aliases are prefixed with a single dash (-).
|
||||
* Option names are prefixed with a double dash (--).
|
||||
Option aliases are prefixed with a single dash (-).
|
||||
Arguments are not prefixed.
|
||||
For example: `ng build my-app -c production`
|
||||
|
||||
* Typically, the name of a generated artifact can be given as an argument to the command or specified with the --name option.
|
||||
* Typically, the name of a generated artifact can be given as an argument to the command or specified with the --name option.
|
||||
|
||||
* Argument and option names can be given in either
|
||||
[camelCase or dash-case](guide/glossary#case-types).
|
||||
* Argument and option names can be given in either
|
||||
[camelCase or dash-case](guide/glossary#case-types).
|
||||
`--myOptionName` is equivalent to `--my-option-name`.
|
||||
|
||||
### Boolean and enumerated options
|
||||
|
||||
Boolean options have two forms: `--thisOption` sets the flag, `--noThisOption` clears it.
|
||||
Boolean options have two forms: `--thisOption` sets the flag, `--noThisOption` clears it.
|
||||
If neither option is supplied, the flag remains in its default state, as listed in the reference documentation.
|
||||
|
||||
Allowed values are given with each enumerated option description, with the default value in **bold**.
|
||||
@ -95,6 +94,7 @@ Options that specify files can be given as absolute paths, or as paths relative
|
||||
|
||||
### Schematics
|
||||
|
||||
The [ng generate](cli/generate) and [ng add](cli/add) commands take as an argument the artifact or library to be generated or added to the current project.
|
||||
In addition to any general options, each artifact or library defines its own options in a *schematic*.
|
||||
Schematic options are supplied to the command in the same format as immediate command options.
|
||||
The [ng generate](cli/generate) and [ng add](cli/add) commands take as an argument the artifact or library to be generated or added to the current project.
|
||||
In addition to any general options, each artifact or library defines its own options in a *schematic*.
|
||||
Schematic options are supplied to the command in the same format as immediate command options.
|
||||
|
||||
|
@ -9,7 +9,7 @@ import { AdComponent } from './ad.component';
|
||||
selector: 'app-ad-banner',
|
||||
// #docregion ad-host
|
||||
template: `
|
||||
<div class="ad-banner-example">
|
||||
<div class="ad-banner">
|
||||
<h3>Advertisements</h3>
|
||||
<ng-template ad-host></ng-template>
|
||||
</div>
|
||||
|
@ -18,6 +18,6 @@
|
||||
color: black;
|
||||
}
|
||||
|
||||
.ad-banner-example {
|
||||
.ad-banner {
|
||||
width: 400px;
|
||||
}
|
@ -72,15 +72,15 @@
|
||||
<h2>You submitted the following:</h2>
|
||||
<div class="row">
|
||||
<div class="col-xs-3">Name</div>
|
||||
<div class="col-xs-9">{{ model.name }}</div>
|
||||
<div class="col-xs-9 pull-left">{{ model.name }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3">Alter Ego</div>
|
||||
<div class="col-xs-9">{{ model.alterEgo }}</div>
|
||||
<div class="col-xs-9 pull-left">{{ model.alterEgo }}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3">Power</div>
|
||||
<div class="col-xs-9">{{ model.power }}</div>
|
||||
<div class="col-xs-9 pull-left">{{ model.power }}</div>
|
||||
</div>
|
||||
<br>
|
||||
<button class="btn btn-primary" (click)="submitted=false">Edit</button>
|
||||
|
@ -10,7 +10,7 @@ describe('Security E2E Tests', () => {
|
||||
expect(interpolated.getText())
|
||||
.toContain('Template <script>alert("0wned")</script> <b>Syntax</b>');
|
||||
let bound = element(By.className('e2e-inner-html-bound'));
|
||||
expect(bound.getText()).toContain('Template Syntax');
|
||||
expect(bound.getText()).toContain('Template alert("0wned") Syntax');
|
||||
let bold = element(By.css('.e2e-inner-html-bound b'));
|
||||
expect(bold.getText()).toContain('Syntax');
|
||||
});
|
||||
|
@ -7,8 +7,7 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
h3 {
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
text-align: center; margin-bottom: 0;
|
||||
}
|
||||
[class*='col-'] {
|
||||
padding-right: 20px;
|
||||
|
@ -17,8 +17,7 @@ button {
|
||||
border: none;
|
||||
padding: 5px 10px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
cursor: pointer; cursor: hand;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #cfd8dc;
|
||||
|
@ -16,8 +16,7 @@ a {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
h3 {
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
text-align: center; margin-bottom: 0;
|
||||
}
|
||||
h4 {
|
||||
position: relative;
|
||||
|
@ -18,8 +18,7 @@ button {
|
||||
border: none;
|
||||
padding: 5px 10px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
cursor: pointer; cursor: hand;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #cfd8dc;
|
||||
|
@ -16,8 +16,7 @@ a {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
h3 {
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
text-align: center; margin-bottom: 0;
|
||||
}
|
||||
h4 {
|
||||
position: relative;
|
||||
|
@ -3,7 +3,7 @@
|
||||
border-bottom: 1px solid gray;
|
||||
border-left: 1px solid gray;
|
||||
border-right: 1px solid gray;
|
||||
width: 195px;
|
||||
width:195px;
|
||||
height: 16px;
|
||||
padding: 5px;
|
||||
background-color: white;
|
||||
|
@ -2,7 +2,7 @@
|
||||
<h4>Hero Search</h4>
|
||||
|
||||
<!-- #docregion input -->
|
||||
<input #searchBox id="search-box" (input)="search(searchBox.value)" />
|
||||
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
|
||||
<!-- #enddocregion input -->
|
||||
|
||||
<ul class="search-result">
|
||||
|
@ -1,11 +1,7 @@
|
||||
// #docregion , init
|
||||
import { InMemoryDbService } from 'angular-in-memory-web-api';
|
||||
import { Hero } from './hero';
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class InMemoryDataService implements InMemoryDbService {
|
||||
createDb() {
|
||||
const heroes = [
|
||||
|
@ -16,8 +16,7 @@ a {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
h3 {
|
||||
text-align: center;
|
||||
margin-bottom: 0;
|
||||
text-align: center; margin-bottom: 0;
|
||||
}
|
||||
h4 {
|
||||
position: relative;
|
||||
|
@ -18,8 +18,7 @@ button {
|
||||
border: none;
|
||||
padding: 5px 10px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
cursor: hand;
|
||||
cursor: pointer; cursor: hand;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #cfd8dc;
|
||||
|
@ -3,7 +3,7 @@
|
||||
border-bottom: 1px solid gray;
|
||||
border-left: 1px solid gray;
|
||||
border-right: 1px solid gray;
|
||||
width: 195px;
|
||||
width:195px;
|
||||
height: 16px;
|
||||
padding: 5px;
|
||||
background-color: white;
|
||||
|
@ -1,7 +1,7 @@
|
||||
<div id="search-component">
|
||||
<h4>Hero Search</h4>
|
||||
|
||||
<input #searchBox id="search-box" (input)="search(searchBox.value)" />
|
||||
<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
|
||||
|
||||
<ul class="search-result">
|
||||
<li *ngFor="let hero of heroes | async" >
|
||||
|
@ -3,7 +3,7 @@
|
||||
<div class="nf-container l-flex-wrap flex-center">
|
||||
<img src="assets/images/support/angular-404.svg" width="300" height="300"/>
|
||||
<div class="nf-response l-flex-wrap">
|
||||
<h1 class="no-anchor no-toc">Page Not Found</h1>
|
||||
<h1 class="no-toc">Page Not Found</h1>
|
||||
<p>We're sorry. The page you are looking for cannot be found.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -56,9 +56,7 @@ A component and its template together define a *view*. A component can contain a
|
||||
When you create a component, it's associated directly with a single view, called the *host view*. The host view can be the root of a view hierarchy, which can contain *embedded views*, which are in turn the host views of other components. Those components can be in the same NgModule, or can be imported from other NgModules. Views in the tree can be nested to any depth.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
**Note:** The hierarchical structure of views is a key factor in the way Angular detects and responds to changes in the DOM and app data.
|
||||
|
||||
**Note:** The hierarchical structure of views is a key factor in the way Angular detects and responds to changes in the DOM and app data.
|
||||
</div>
|
||||
|
||||
## NgModules and JavaScript modules
|
||||
|
@ -48,7 +48,7 @@ Similarly, use the `@Injectable()` decorator to indicate that a component or oth
|
||||
|
||||
* An injector creates dependencies, and maintains a *container* of dependency instances that it reuses if possible.
|
||||
|
||||
* A *provider* is an object that tells an injector how to obtain or create a dependency.
|
||||
* A *provider* is an object that tell an injector how to obtain or create a dependency.
|
||||
|
||||
For any dependency that you need in your app, you must register a provider with the app's injector,
|
||||
so that the injector can use the provider to create new instances.
|
||||
|
@ -32,11 +32,11 @@ For example:
|
||||
|
||||
The base file `environment.ts`, contains the default environment settings. For example:
|
||||
|
||||
```
|
||||
<code-example language="none" class="code-shell">
|
||||
export const environment = {
|
||||
production: false
|
||||
};
|
||||
```
|
||||
</code-example>
|
||||
|
||||
The `build` command uses this as the build target when no environment is specified.
|
||||
You can add further variables, either as additional properties on the environment object, or as separate objects.
|
||||
@ -144,11 +144,7 @@ You can add additional configurations as required. To add a staging environment,
|
||||
You can add more configuration options to this target environment as well.
|
||||
Any option that your build supports can be overridden in a build target configuration.
|
||||
|
||||
To build using the staging configuration, run the following command:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng build --configuration=staging
|
||||
</code-example>
|
||||
To build using the staging configuration, run `ng build --configuration=staging`.
|
||||
|
||||
You can also configure the `serve` command to use the targeted build configuration if you add it to the "serve:configurations" section of `angular.json`:
|
||||
|
||||
|
@ -192,7 +192,7 @@ Here are two sample components and the `AdComponent` interface for reference:
|
||||
The final ad banner looks like this:
|
||||
|
||||
<figure>
|
||||
<img src="generated/images/guide/dynamic-component-loader/ads-example.gif" alt="Ads">
|
||||
<img src="generated/images/guide/dynamic-component-loader/ads.gif" alt="Ads">
|
||||
</figure>
|
||||
|
||||
|
||||
|
@ -107,7 +107,7 @@ The recently-developed [custom elements](https://developer.mozilla.org/en-US/doc
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Firefox</td>
|
||||
<td>Supported natively as of version 63. In older versions: Set the <code>dom.webcomponents.enabled</code> and <code>dom.webcomponents.customelements.enabled</code> preferences to true.</td>
|
||||
<td> Set the <code>dom.webcomponents.enabled</code> and <code>dom.webcomponents.customelements.enabled</code> preferences to true. Planned to be enabled by default in version 63.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Edge</td>
|
||||
|
@ -20,15 +20,16 @@ The top level of the workspace contains a number of workspace-wide configuration
|
||||
| :--------------------- | :------------------------------------------|
|
||||
| `.editorconfig` | Configuration for code editors. See [EditorConfig](https://editorconfig.org/). |
|
||||
| `.gitignore` | Specifies intentionally untracked files that [Git](https://git-scm.com/) should ignore. |
|
||||
| `angular.json` | CLI configuration defaults for all projects in the workspace, including configuration options for build, serve, and test tools that the CLI uses, such as [TSLint](https://palantir.github.io/tslint/), [Karma](https://karma-runner.github.io/), and [Protractor](http://www.protractortest.org/). For details, see [Angular Workspace Configuration](guide/workspace-config). |
|
||||
| `angular.json` | CLI configuration for all projects in the workspace, including configuration options for build, serve, and test tools that the CLI uses, such as [Karma](https://karma-runner.github.io/) and [Protractor](http://www.protractortest.org/). |
|
||||
| `node_modules` | Provides [npm packages](guide/npm-packages) to the entire workspace. |
|
||||
| `package.json` | Configures [npm package dependencies](guide/npm-packages) that are available to all projects in the workspace. See [npm documentation](https://docs.npmjs.com/files/package.json) for the specific format and contents of this file. |
|
||||
| `package-lock.json` | Provides version information for all packages installed into `node_modules` by the npm client. See [npm documentation](https://docs.npmjs.com/files/package-lock.json) for details. If you use the yarn client, this file will be [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) instead. |
|
||||
| `tsconfig.json` | Default [TypeScript](https://www.typescriptlang.org/) configuration for apps in the workspace, including TypeScript and Angular template compiler options. See [TypeScript Configuration](guide/typescript-configuration). |
|
||||
| `tslint.json` | Default [TSLint](https://palantir.github.io/tslint/) configuration for apps in the workspace. |
|
||||
| `package.json` | Lists package dependencies. See [npm documentation](https://docs.npmjs.com/files/package.json) for the specific format and contents of this file.|
|
||||
| `tsconfig.app.json` | Default [TypeScript](https://www.typescriptlang.org/) configuration for apps in the workspace. |
|
||||
| `tsconfig.spec.json` | Default TypeScript configuration for e2e test apps in the workspace. |
|
||||
| `tslint.json` | Default [TSLint](https://palantir.github.io/tslint/) configuration for apps in the workspace. |
|
||||
| `README.md` | Introductory documentation. |
|
||||
| `package-lock.json` | Provides version information for all packages installed into `node_modules` by the npm client. See [npm documentation](https://docs.npmjs.com/files/package-lock.json) for details. If you use the yarn client, this file will be [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) instead. |
|
||||
|
||||
All projects within a workspace share a [CLI configuration context](guide/workspace-config).
|
||||
All projects within a workspace share this configuration context.
|
||||
Project-specific [TypeScript](https://www.typescriptlang.org/) configuration files inherit from the workspace-wide `tsconfig.*.json`, and app-specific [TSLint](https://palantir.github.io/tslint/) configuration files inherit from the workspace-wide `tslint.json`.
|
||||
|
||||
### Default app project files
|
||||
@ -39,9 +40,9 @@ This initial app is the *default app* for CLI commands (unless you change the de
|
||||
A newly generated app contains the source files for a root module, with a root component and template.
|
||||
When the workspace file structure is in place, you can use the `ng generate` command on the command line to add functionality and data to the initial app.
|
||||
|
||||
<div class="alert is-helpful">
|
||||
<div class="alert is-helpful>
|
||||
|
||||
Besides using the CLI on the command line, you can also use an interactive development environment like [Angular Console](https://angularconsole.com/), or manipulate files directly in the app's source folder and configuration files.
|
||||
Besides using the CLI on the command line, You can also use an interactive development environment like [Angular Console](https://angular.console.com), or manipulate files directly in the app's source folder and configuration files.
|
||||
|
||||
</div>
|
||||
|
||||
@ -103,6 +104,18 @@ my-app/
|
||||
|
||||
Inside the `src/` folder, the `app/` folder contains your app's logic and data. Angular components, templates, and styles go here. An `assets/` subfolder contains images and anything else your app needs. Files at the top level of `src/` support testing and running your app.
|
||||
|
||||
<code-example language="none" linenums="false">
|
||||
src/
|
||||
app/
|
||||
app.component.css
|
||||
app.component.html
|
||||
app.component.spec.ts
|
||||
app.component.ts
|
||||
app.module.ts
|
||||
assets/...
|
||||
...
|
||||
</code-example>
|
||||
|
||||
| APP SOURCE FILES | PURPOSE |
|
||||
| :-------------------------- | :------------------------------------------|
|
||||
| `app/app.component.ts` | Defines the logic for the app's root component, named `AppComponent`. The view associated with this root component becomes the root of the [view hierarchy](guide/glossary#view-hierarchy) as you add components and services to your app. |
|
||||
|
@ -317,30 +317,6 @@ Within Angular, use [NgModules](guide/glossary#ngmodule) to make public parts av
|
||||
|
||||
{@a F}
|
||||
|
||||
{@a form-control}
|
||||
|
||||
## form control
|
||||
|
||||
A instance of `FormControl`, which is a fundamental building block for Angular forms. Together with `FormGroup` and `FormArray`, tracks the value, validation, and status of a form input element.
|
||||
|
||||
Read more forms in the [Introduction to forms in Angular](guide/forms-overview).
|
||||
|
||||
{@a form-model}
|
||||
|
||||
## form model
|
||||
|
||||
The "source of truth" for the value and validation status of a form input element at a given point in time. When using [reactive forms](guide/glossary#reactive-forms), the form model is created explicitly in the component class. When using [template-driven forms](guide/glossary#template-driven-forms), the form model is implicitly created by directives.
|
||||
|
||||
Learn more about reactive and template-driven forms in the [Introduction to forms in Angular](guide/forms-overview).
|
||||
|
||||
{@a form-validation}
|
||||
|
||||
## form validation
|
||||
|
||||
A check that runs when form values change and reports whether the given values are correct and complete, according to the defined constraints. Reactive forms apply [validator functions](guide/form-validation#adding-to-reactive-forms). Template-driven forms use [validator directives](guide/form-validation#adding-to-template-driven-forms).
|
||||
|
||||
|
||||
To learn more, see [Form Validation](guide/form-validation).
|
||||
|
||||
{@a G}
|
||||
|
||||
@ -349,14 +325,6 @@ To learn more, see [Form Validation](guide/form-validation).
|
||||
|
||||
{@a I}
|
||||
|
||||
|
||||
{@a immutability}
|
||||
|
||||
## immutability
|
||||
|
||||
The ability to alter the state of a value after its creation. [Reactive forms](guide/glossary#reactive-forms) perform immutable changes in that
|
||||
each change to the data model produces a new data model rather than modifying the existing one. [Template-driven forms](guide/glossary#template-driven-forms) perform mutable changes with `NgModel` and [two-way data binding](guide/glossary#data-binding) to modify the existing data model in place.
|
||||
|
||||
{@a injectable}
|
||||
|
||||
## injectable
|
||||
@ -607,15 +575,14 @@ Learn more in [Dependency Injection](guide/dependency-injection).
|
||||
A framework for building Angular forms through code in a component.
|
||||
The alternative is a [template-driven form](guide/glossary#template-driven-forms).
|
||||
|
||||
When using reactive forms:
|
||||
When building reactive forms:
|
||||
|
||||
* The "source of truth", the form model, is defined in the component class.
|
||||
* Validation is set up through validation functions rather than valdation directives.
|
||||
* Each control is explicitly created in the component class by creating a `FormControl` instance manually or with `FormBuilder`.
|
||||
* The "source of truth" is the component. The validation is defined using code in the component.
|
||||
* Each control is explicitly created in the component class with `new FormControl()` or with `FormBuilder`.
|
||||
* The template input elements do *not* use `ngModel`.
|
||||
* The associated Angular directives are prefixed with `form`, such as `formControl`, `formGroup`, and `formControlName`.
|
||||
* The associated Angular directives are prefixed with `Form`, such as `FormGroup()`, `FormControl()`, and `FormControlName()`.
|
||||
|
||||
The alternative is a template-driven form. For an introduction and comparison of both forms approaches, see [Introduction to Angular Forms](guide/forms-overview).
|
||||
Reactive forms are powerful, flexible, and a good choice for more complex data-entry form scenarios, such as dynamic generation of form controls.
|
||||
|
||||
{@a router}
|
||||
{@a router-module}
|
||||
@ -730,14 +697,16 @@ Additional templates, represented by `TemplateRef` objects, can define alternati
|
||||
A format for building Angular forms using HTML forms and input elements in the view.
|
||||
The alternative format uses the [reactive forms](guide/glossary#reactive-forms) framework.
|
||||
|
||||
When using template-driven forms:
|
||||
When building template-driven forms:
|
||||
|
||||
* The "source of truth" is the template. The validation is defined using attributes on the individual input elements.
|
||||
* [Two-way binding](guide/glossary#data-binding) with `ngModel` keeps the component model synchronized with the user's entry into the input elements.
|
||||
* Behind the scenes, Angular creates a new control for each input element, provided you have set up a `name` attribute and two-way binding for each input.
|
||||
* The associated Angular directives are prefixed with `ng` such as `ngForm`, `ngModel`, and `ngModelGroup`.
|
||||
|
||||
The alternative is a reactive form. For an introduction and comparison of both forms approaches, see [Introduction to Angular Forms](guide/forms-overview).
|
||||
Template-driven forms are convenient, quick, and simple. They are a good choice for many basic data-entry form scenarios.
|
||||
|
||||
Read about how to build template-driven forms in [Forms](guide/forms).
|
||||
|
||||
{@a template-expression}
|
||||
|
||||
|
@ -81,7 +81,7 @@ The following support packages are included as dependencies in the default `pack
|
||||
|
||||
Package name | Description
|
||||
---------------------------------------- | --------------------------------------------------
|
||||
[**rxjs**](https://github.com/ReactiveX/rxjs) | Many Angular APIs return [_observables_](guide/glossary#observable). RxJS is an implementation of the proposed [Observables specification](https://github.com/tc39/proposal-observable) currently before the [TC39](https://www.ecma-international.org/memento/tc39-m.htm) committee, which determines standards for the JavaScript language.
|
||||
[**rxjs**](https://github.com/ReactiveX/rxjs) | Many Angular APIs return [_observables_](guide/glossary#observable). RxJS is an implementation of the proposed [Observables specification](https://github.com/zenparsing/es-observable) currently before the [TC39](http://www.ecma-international.org/memento/TC39.htm) committee, which determines standards for the JavaScript language.
|
||||
[**zone.js**](https://github.com/angular/zone.js) | Angular relies on zone.js to run Angular's change detection processes when native JavaScript operations raise events. Zone.js is an implementation of a [specification](https://gist.github.com/mhevery/63fdcdf7c65886051d55) currently before the [TC39](http://www.ecma-international.org/memento/TC39.htm) committee that determines standards for the JavaScript language.
|
||||
|
||||
|
||||
|
@ -3066,13 +3066,11 @@ A guard's return value controls the router's behavior:
|
||||
|
||||
* If it returns `true`, the navigation process continues.
|
||||
* If it returns `false`, the navigation process stops and the user stays put.
|
||||
* If it returns a `UrlTree`, the current navigation cancels and a new navigation is initiated to the `UrlTree` returned.
|
||||
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
**Note:** The guard can also tell the router to navigate elsewhere, effectively canceling the current navigation. When
|
||||
doing so inside a guard, the guard should return `false`;
|
||||
**Note:** The guard can also tell the router to navigate elsewhere, effectively canceling the current navigation.
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -119,7 +119,7 @@ vulnerability. For example, code contained in a `<script>` tag is executed:
|
||||
|
||||
|
||||
Angular recognizes the value as unsafe and automatically sanitizes it, which removes the `<script>`
|
||||
tag but keeps safe content such as the `<b>` element.
|
||||
tag but keeps safe content such as the text content of the `<script>` tag and the `<b>` element.
|
||||
|
||||
|
||||
<figure>
|
||||
|
@ -190,7 +190,7 @@ which you must adjust to start Chrome without sandboxing.
|
||||
|
||||
We'll be using [Headless Chrome](https://developers.google.com/web/updates/2017/04/headless-chrome#cli) in these examples.
|
||||
|
||||
* In the Karma configuration file, `karma.conf.js`, add a custom launcher called ChromeHeadlessCI below browsers:
|
||||
* In the Karma configuration file, `karma.conf.js`, add a custom launcher called ChromeNoSandbox below browsers:
|
||||
```
|
||||
browsers: ['Chrome'],
|
||||
customLaunchers: {
|
||||
@ -684,7 +684,7 @@ and returns a [`ComponentFixture`](#component-fixture).
|
||||
|
||||
Do not re-configure `TestBed` after calling `createComponent`.
|
||||
|
||||
The `createComponent` method freezes the current `TestBed` definition,
|
||||
The `createComponent` method freezes the current `TestBed`definition,
|
||||
closing it to further configuration.
|
||||
|
||||
You cannot call any more `TestBed` configuration methods, not `configureTestingModule()`,
|
||||
|
@ -62,7 +62,7 @@ Your app may have to launch faster to engage these users before they decide to d
|
||||
|
||||
With Angular Universal, you can generate landing pages for the app that look like the complete app.
|
||||
The pages are pure HTML, and can display even if JavaScript is disabled.
|
||||
The pages don't handle browser events, but they _do_ support navigation through the site using [`routerLink`](guide/router#router-link).
|
||||
The pages don't handle browser events, but they _do_ support navigation through the site using `[routerLink](guide/router#router-link)`.
|
||||
|
||||
In practice, you'll serve a static version of the landing page to hold the user's attention.
|
||||
At the same time, you'll load the full Angular app behind it.
|
||||
|
@ -281,28 +281,22 @@ The differences between `downgradeModule()` and `UpgradeModule` end here. The re
|
||||
`upgrade/static` APIs and concepts work in the exact same way for both types of hybrid apps.
|
||||
See [Upgrading from AngularJS](guide/upgrade) to learn about:
|
||||
|
||||
- [Using Angular Components from AngularJS Code](guide/upgrade#using-angular-components-from-angularjs-code).<br />
|
||||
_NOTE: If you are downgrading multiple modules, you need to specify the name of the downgraded
|
||||
module each component belongs to, when calling `downgradeComponent()`._
|
||||
- [Using Angular Components from AngularJS Code](guide/upgrade#using-angular-components-from-angularjs-code).
|
||||
- [Using AngularJS Component Directives from Angular Code](guide/upgrade#using-angularjs-component-directives-from-angular-code).
|
||||
- [Projecting AngularJS Content into Angular Components](guide/upgrade#projecting-angularjs-content-into-angular-components).
|
||||
- [Transcluding Angular Content into AngularJS Component Directives](guide/upgrade#transcluding-angular-content-into-angularjs-component-directives).
|
||||
- [Making AngularJS Dependencies Injectable to Angular](guide/upgrade#making-angularjs-dependencies-injectable-to-angular).
|
||||
- [Making Angular Dependencies Injectable to AngularJS](guide/upgrade#making-angular-dependencies-injectable-to-angularjs).<br />
|
||||
_NOTE: If you are downgrading multiple modules, you need to specify the name of the downgraded
|
||||
module each injectable belongs to, when calling `downgradeInjectable()`._
|
||||
- [Making Angular Dependencies Injectable to AngularJS](guide/upgrade#making-angular-dependencies-injectable-to-angularjs).
|
||||
|
||||
<div class="alert is-important">
|
||||
|
||||
While it is possible to downgrade injectables, downgraded injectables will not be available until
|
||||
the Angular module that provides them is instantiated. In order to be safe, you need to ensure
|
||||
that the downgraded injectables are not used anywhere _outside_ the part of the app where it is
|
||||
guaranteed that their module has been instantiated.
|
||||
the Angular module is instantiated. In order to be safe, you need to ensure that the downgraded
|
||||
injectables are not used anywhere _outside_ the part of the app that is controlled by Angular.
|
||||
|
||||
For example, it is _OK_ to use a downgraded service in an upgraded component that is only used
|
||||
from a downgraded Angular component provided by the same Angular module as the injectable, but it
|
||||
is _not OK_ to use it in an AngularJS component that may be used independently of Angular or use
|
||||
it in a downgraded Angular component from a different module.
|
||||
from Angular components, but it is _not OK_ to use it in an AngularJS component that may be used
|
||||
independently of Angular.
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -78,7 +78,7 @@ Each target object specifies the `builder` for that target, which is the npm pac
|
||||
}
|
||||
</code-example>
|
||||
|
||||
* The `architect/build` section configures defaults for options of the `ng build` command. See [Build target](#build-target) below for more information.
|
||||
* The `architect/build` section configures defaults for options of the `ng build` command. See [Build target]{#build-target} below for more information.
|
||||
|
||||
* The `architect/serve` section overrides build defaults and supplies additional serve defaults for the `ng serve` command. In addition to the options available for the `ng build` command, it adds options related to serving the app.
|
||||
|
||||
|
Before Width: | Height: | Size: 851 KiB After Width: | Height: | Size: 851 KiB |
Binary file not shown.
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 2.3 KiB |
@ -422,8 +422,8 @@
|
||||
"picture": "minko.jpg",
|
||||
"twitter": "mgechev",
|
||||
"website": "http://blog.mgechev.com",
|
||||
"bio": "Software engineer who enjoys theoretical computer science and its practical applications. Speaker, author of the book 'Switching to Angular', codelyzer, Guess.js, and the Go linter revive. Working for faster and more reliable software.",
|
||||
"group": "Angular"
|
||||
"bio": "Software engineer who enjoys theoretical computer science and its practical applications. Author of the books 'Switching to Angular 2' and 'Getting Started with Angular', speaker and blogger. Working on tooling for Angular and TypeScript.",
|
||||
"group": "GDE"
|
||||
},
|
||||
|
||||
"uri": {
|
||||
|
@ -13,6 +13,18 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- ReactiveConf -->
|
||||
<tr>
|
||||
<th><a href="https://reactiveconf.com/" title="ReactiveConf">ReactiveConf</a></th>
|
||||
<td>Prague, Czech Republic</td>
|
||||
<td>October 29-31, 2018</td>
|
||||
</tr>
|
||||
<!-- AngularConnect-->
|
||||
<tr>
|
||||
<th><a href="http://angularconnect.com" title="AngularConnect">AngularConnect</a></th>
|
||||
<td>London, United Kingdom</td>
|
||||
<td>November 5-7, 2018</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -26,18 +38,6 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- ReactiveConf -->
|
||||
<tr>
|
||||
<th><a href="https://reactiveconf.com/" title="ReactiveConf">ReactiveConf</a></th>
|
||||
<td>Prague, Czech Republic</td>
|
||||
<td>October 29-31, 2018</td>
|
||||
</tr>
|
||||
<!-- AngularConnect-->
|
||||
<tr>
|
||||
<th><a href="http://angularconnect.com" title="AngularConnect">AngularConnect</a></th>
|
||||
<td>London, United Kingdom</td>
|
||||
<td>November 5-7, 2018</td>
|
||||
</tr>
|
||||
<!-- AngularMix -->
|
||||
<tr>
|
||||
<th><a href="https://angularmix.com/" title="AngularMix">AngularMix</a></th>
|
||||
|
@ -22,12 +22,6 @@
|
||||
"rev": true,
|
||||
"title": "Made with Angular",
|
||||
"url": "https://www.madewithangular.com/"
|
||||
},
|
||||
"angular-subreddit": {
|
||||
"desc": "An Angular-dedicated subreddit.",
|
||||
"rev": true,
|
||||
"title": "Angular Subreddit",
|
||||
"url": "https://www.reddit.com/r/Angular2/"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -155,13 +149,6 @@
|
||||
"rev": true,
|
||||
"title": "AngularCommerce",
|
||||
"url": "https://github.com/NodeArt/angular-commerce"
|
||||
},
|
||||
"ngx-api-utils": {
|
||||
"desc": "ngx-api-utils is a lean library of utilities and helpers to quickly integrate any HTTP API (REST, Ajax, and any other) with Angular.",
|
||||
"logo": "",
|
||||
"rev": true,
|
||||
"title": "ngx-api-utils",
|
||||
"url": "https://github.com/ngx-api-utils/ngx-api-utils"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1,5 +1,7 @@
|
||||
<h1>Test Code Page</h1>
|
||||
|
||||
<p>Current location is <current-location></current-location></p>
|
||||
|
||||
<h2><code-tabs></h2>
|
||||
|
||||
<p>No linenums at code-tabs level</p>
|
||||
@ -118,20 +120,3 @@ Try this <live-example></live-example>.
|
||||
<live-example embedded name="testy" stackblitz="super-stackblitz"></live-example>
|
||||
|
||||
<p>More text follows ...</p>
|
||||
|
||||
<p>Getting Started Widgets</p>
|
||||
|
||||
<p>Interpolation</p>
|
||||
<aio-gs-interpolation></aio-gs-interpolation>
|
||||
|
||||
<p>Property Binding</p>
|
||||
<aio-gs-property-binding></aio-gs-property-binding>
|
||||
|
||||
<p>Event Binding</p>
|
||||
<aio-gs-event-binding></aio-gs-event-binding>
|
||||
|
||||
<p>NgIf</p>
|
||||
<aio-gs-ng-if></aio-gs-ng-if>
|
||||
|
||||
<p>NgFor</p>
|
||||
<aio-gs-ng-for></aio-gs-ng-for>
|
||||
|
@ -19,7 +19,7 @@ To set up your development environment, follow these instructions in [Getting St
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
||||
**Note:** You do not need to complete the entire Getting Started. After you complete the above two sections of Getting Started, your environment is set up. Continue below to create the Tour of Heroes workspace and an initial app project.
|
||||
**Note:**: You do not need to complete the entire Getting Started. After you complete the above two sections of Getting Started, your environment is set up. Continue below to create the Tour of Heroes workspace and an initial app project.
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -77,13 +77,8 @@ _after importing the `HttpClientModule`_,
|
||||
The `forRoot()` configuration method takes an `InMemoryDataService` class
|
||||
that primes the in-memory database.
|
||||
|
||||
The class `src/app/in-memory-data.service.ts` is generated by the following command:
|
||||
|
||||
<code-example language="sh" class="code-shell">
|
||||
ng generate service InMemoryData
|
||||
</code-example>
|
||||
|
||||
This class has the following content:
|
||||
The _Tour of Heroes_ sample creates such a class
|
||||
`src/app/in-memory-data.service.ts` which has the following content:
|
||||
|
||||
<code-example path="toh-pt6/src/app/in-memory-data.service.ts" region="init" header="src/app/in-memory-data.service.ts" linenums="false"></code-example>
|
||||
|
||||
@ -251,7 +246,7 @@ Here is the final version of `getHeroes` with the `tap` that logs the operation.
|
||||
|
||||
Most web APIs support a _get by id_ request in the form `:baseURL/:id`.
|
||||
|
||||
Here, the _base URL_ is the `heroesURL` defined in the [Heroes and HTTP](tutorial/toh-pt6#heroes-and-http) section (`api/heroes`) and _id_ is
|
||||
Here, the _base URL_ is the `heroesURL` defined in the [Heroes and HTTP](http://localhost:4800/tutorial/toh-pt6#heroes-and-http) section (`api/heroes`) and _id_ is
|
||||
the number of the hero that you want to retrieve. For example, `api/heroes/11`.
|
||||
|
||||
Add a `HeroService.getHero()` method to make that request:
|
||||
@ -466,7 +461,7 @@ Replace the generated `HeroSearchComponent` _template_ with a text box and a lis
|
||||
Add private CSS styles to `hero-search.component.css`
|
||||
as listed in the [final code review](#herosearchcomponent) below.
|
||||
|
||||
As the user types in the search box, an *input* event binding calls the component's `search()`
|
||||
As the user types in the search box, a *keyup* event binding calls the component's `search()`
|
||||
method with the new search box value.
|
||||
|
||||
{@a asyncpipe}
|
||||
@ -516,7 +511,7 @@ You can also push values into that `Observable` by calling its `next(value)` met
|
||||
as the `search()` method does.
|
||||
|
||||
The `search()` method is called via an _event binding_ to the
|
||||
textbox's `input` event.
|
||||
textbox's `keystroke` event.
|
||||
|
||||
<code-example path="toh-pt6/src/app/hero-search/hero-search.component.html" region="input"></code-example>
|
||||
|
||||
|
@ -12,13 +12,13 @@
|
||||
"/app/search/search-worker.js",
|
||||
"/assets/images/favicons/favicon.ico",
|
||||
"/assets/js/*.js",
|
||||
"/generated/lunr.min.js",
|
||||
"/*.css",
|
||||
"/*.js"
|
||||
],
|
||||
"urls": [
|
||||
"https://fonts.googleapis.com/**",
|
||||
"https://fonts.gstatic.com/s/**"
|
||||
"https://fonts.gstatic.com/s/**",
|
||||
"https://maxcdn.bootstrapcdn.com/**"
|
||||
]
|
||||
}
|
||||
}, {
|
||||
|
@ -7,7 +7,7 @@
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"preinstall": "node ../tools/yarn/check-yarn.js",
|
||||
"postinstall": "node tools/cli-patches/patch.js",
|
||||
"postinstall": "node tools/cli-patches/patch.js && uglifyjs node_modules/lunr/lunr.js -c -m -o src/assets/js/lunr.min.js --source-map",
|
||||
"aio-use-local": "node tools/ng-packages-installer overwrite . --debug",
|
||||
"aio-use-npm": "node tools/ng-packages-installer restore .",
|
||||
"aio-check-local": "node tools/ng-packages-installer check .",
|
||||
@ -18,14 +18,14 @@
|
||||
"build-for": "yarn ~~build --configuration",
|
||||
"prebuild-local": "yarn setup-local",
|
||||
"build-local": "yarn ~~build --configuration=stable",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js a176d127a",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 4faa81e25",
|
||||
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint && yarn tools-lint",
|
||||
"test": "yarn check-env && ng test",
|
||||
"pree2e": "yarn check-env && yarn update-webdriver",
|
||||
"e2e": "ng e2e --no-webdriver-update",
|
||||
"presetup": "yarn --cwd .. install && yarn install --frozen-lockfile && yarn ~~check-env && yarn ~~clean-generated && yarn boilerplate:remove",
|
||||
"setup": "yarn aio-use-npm && yarn example-use-npm",
|
||||
"postsetup": "yarn ~~build-ie-polyfills && yarn ~~minify-lunr && yarn boilerplate:add && yarn extract-cli-command-docs && yarn docs",
|
||||
"postsetup": "yarn boilerplate:add && yarn build-ie-polyfills && yarn extract-cli-command-docs && yarn docs",
|
||||
"presetup-local": "yarn presetup",
|
||||
"setup-local": "yarn aio-use-local && yarn example-use-local",
|
||||
"postsetup-local": "yarn postsetup",
|
||||
@ -61,18 +61,17 @@
|
||||
"generate-stackblitz": "node ./tools/stackblitz-builder/generateStackblitz",
|
||||
"generate-zips": "node ./tools/example-zipper/generateZips",
|
||||
"build-404-page": "node scripts/build-404-page",
|
||||
"build-ie-polyfills": "yarn webpack-cli src/ie-polyfills.js -o src/generated/ie-polyfills.min.js --mode production",
|
||||
"update-webdriver": "webdriver-manager update --standalone false --gecko false $CHROMEDRIVER_VERSION_ARG",
|
||||
"~~check-env": "node scripts/check-environment",
|
||||
"~~clean-generated": "node --eval \"require('shelljs').rm('-rf', 'src/generated')\"",
|
||||
"~~build": "ng build",
|
||||
"post~~build": "yarn build-404-page",
|
||||
"~~build-ie-polyfills": "webpack-cli src/ie-polyfills.js -o src/generated/ie-polyfills.min.js --mode production",
|
||||
"~~http-server": "http-server",
|
||||
"~~minify-lunr": "uglifyjs node_modules/lunr/lunr.js -c -m -o src/generated/lunr.min.js --source-map"
|
||||
"~~http-server": "http-server"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.9.0 <11.0.0",
|
||||
"yarn": ">=1.10.1 <1.13.0"
|
||||
"yarn": ">=1.9.2 <2.0.0"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
@ -105,7 +104,7 @@
|
||||
"@types/jasminewd2": "^2.0.4",
|
||||
"@types/node": "~6.0.60",
|
||||
"archiver": "^1.3.0",
|
||||
"canonical-path": "1.0.0",
|
||||
"canonical-path": "^0.0.2",
|
||||
"chalk": "^2.1.0",
|
||||
"cjson": "^0.5.0",
|
||||
"codelyzer": "~4.2.1",
|
||||
@ -142,7 +141,7 @@
|
||||
"lighthouse": "^3.2.1",
|
||||
"lodash": "^4.17.4",
|
||||
"lunr": "^2.1.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"npm-run-all": "^4.1.3",
|
||||
"protractor": "^5.2.0",
|
||||
"rehype": "^6.0.0",
|
||||
"rehype-slug": "^2.0.0",
|
||||
|
@ -2,9 +2,10 @@
|
||||
"aio": {
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime": 3713,
|
||||
"main": 500343,
|
||||
"polyfills": 53926
|
||||
"runtime": 3173,
|
||||
"main": 494475,
|
||||
"polyfills": 53926,
|
||||
"prettify": 14917
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Usage:
|
||||
* node create-preview <build-number>
|
||||
*
|
||||
* Triggers the preview server to initiate the preview creation process for the specified CircleCI
|
||||
* build number. It must be called _after_ the build artifacts have been created and stored on
|
||||
* CircleCI.
|
||||
*/
|
||||
|
||||
// Imports
|
||||
const {triggerWebhook} = require('../../.circleci/trigger-webhook');
|
||||
|
||||
// Constants
|
||||
const JOB_NAME = 'aio_preview';
|
||||
const WEBHOOK_URL = 'https://ngbuilds.io/circle-build';
|
||||
|
||||
// Input
|
||||
const buildNumber = process.argv[2];
|
||||
|
||||
// Run
|
||||
triggerWebhook(buildNumber, JOB_NAME, WEBHOOK_URL).
|
||||
then(({statusCode, responseText}) => isSuccess(statusCode) ?
|
||||
console.log(`Status: ${statusCode}\n${responseText}`) :
|
||||
Promise.reject(new Error(`Request failed (status: ${statusCode}): ${responseText}`))).
|
||||
catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// Helpers
|
||||
function isSuccess(statusCode) {
|
||||
// Getting a 409 response from the preview server means that the preview has already been created
|
||||
// for the corresponding PR/SHA, so our objective has been accomplished.
|
||||
return (200 <= statusCode && statusCode < 400) || (statusCode === 409);
|
||||
}
|
@ -29,12 +29,10 @@
|
||||
<aio-top-menu *ngIf="isSideBySide" [nodes]="topMenuNodes"></aio-top-menu>
|
||||
<aio-search-box class="search-container" #searchBox (onSearch)="doSearch($event)" (onFocus)="doSearch($event)"></aio-search-box>
|
||||
<div class="toolbar-external-icons-container">
|
||||
<a href="https://twitter.com/angular" title="Twitter" aria-label="Angular on twitter">
|
||||
<mat-icon svgIcon="logos:twitter"></mat-icon>
|
||||
</a>
|
||||
<a href="https://github.com/angular/angular" title="GitHub" aria-label="Angular on github">
|
||||
<mat-icon svgIcon="logos:github"></mat-icon>
|
||||
</a>
|
||||
<a href="https://twitter.com/angular" title="Twitter">
|
||||
<img src="assets/images/logos/twitter-icon.svg"></a>
|
||||
<a href="https://github.com/angular/angular" title="GitHub">
|
||||
<img src="assets/images/logos/github-icon.svg"></a>
|
||||
</div>
|
||||
</mat-toolbar-row>
|
||||
</mat-toolbar>
|
||||
@ -74,10 +72,3 @@
|
||||
<aio-footer [nodes]="footerNodes" [versionInfo]="versionInfo" ></aio-footer>
|
||||
</footer>
|
||||
|
||||
<!--
|
||||
Work-around to ensure that the `.woff2` file for the 'Material Icons' font will always be fetched.
|
||||
This allows the SW to cache the file (even if there are no icons in the current page) and ensure
|
||||
material icons on other pages are displayed correctly in offline mode.
|
||||
(Note: Instantiate lazily to avoid affecting the initial rendering.)
|
||||
-->
|
||||
<mat-icon class="cdk-visually-hidden" *ngIf="!isStarting"> </mat-icon>
|
||||
|
@ -742,7 +742,7 @@ describe('AppComponent', () => {
|
||||
expect(component.showSearchResults).toBe(true);
|
||||
});
|
||||
|
||||
it('should not intercept clicks on the searchBox', () => {
|
||||
it('should not intercept clicks om the searchBox', () => {
|
||||
component.showSearchResults = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
@ -752,11 +752,6 @@ describe('AppComponent', () => {
|
||||
|
||||
expect(component.showSearchResults).toBe(true);
|
||||
});
|
||||
|
||||
it('should not call `locationService.setSearch` when searchResults are not shown', () => {
|
||||
docViewer.click();
|
||||
expect(locationService.setSearch).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('keyup handling', () => {
|
||||
|
@ -389,10 +389,7 @@ export class AppComponent implements OnInit {
|
||||
|
||||
hideSearchResults() {
|
||||
this.showSearchResults = false;
|
||||
const oldSearch = this.locationService.search();
|
||||
if (oldSearch.search !== undefined) {
|
||||
this.locationService.setSearch('', { ...oldSearch, search: undefined });
|
||||
}
|
||||
this.locationService.setSearch('', { ...this.locationService.search(), search: undefined });
|
||||
}
|
||||
|
||||
focusSearchBox() {
|
||||
|
@ -51,7 +51,7 @@ export const svgIconProviders = [
|
||||
useValue: {
|
||||
name: 'close',
|
||||
svgSource:
|
||||
'<svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<svg fill="#ffffff" focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />' +
|
||||
'<path d="M0 0h24v24H0z" fill="none" />' +
|
||||
'</svg>',
|
||||
@ -61,9 +61,21 @@ export const svgIconProviders = [
|
||||
{
|
||||
provide: SVG_ICONS,
|
||||
useValue: {
|
||||
name: 'insert_comment',
|
||||
name: 'error_outline',
|
||||
svgSource:
|
||||
'<svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<path d="M0 0h24v24H0V0z" fill="none" />' +
|
||||
'<path d="M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z" />' +
|
||||
'</svg>',
|
||||
},
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: SVG_ICONS,
|
||||
useValue: {
|
||||
name: 'insert_comment',
|
||||
svgSource:
|
||||
'<svg fill="#ffffff" focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<path d="M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z" />' +
|
||||
'<path d="M0 0h24v24H0z" fill="none" />' +
|
||||
'</svg>',
|
||||
@ -92,41 +104,6 @@ export const svgIconProviders = [
|
||||
},
|
||||
multi: true,
|
||||
},
|
||||
|
||||
// Namespace: logos
|
||||
{
|
||||
provide: SVG_ICONS,
|
||||
useValue: {
|
||||
namespace: 'logos',
|
||||
name: 'github',
|
||||
svgSource:
|
||||
'<svg focusable="false" viewBox="0 0 51.8 50.4" xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<path d="M25.9,0.2C11.8,0.2,0.3,11.7,0.3,25.8c0,11.3,7.3,20.9,17.5,24.3c1.3,0.2,1.7-0.6,1.7-1.2c0-0.6,0-2.6,0-4.8' +
|
||||
'c-7.1,1.5-8.6-3-8.6-3c-1.2-3-2.8-3.7-2.8-3.7c-2.3-1.6,0.2-1.6,0.2-1.6c2.6,0.2,3.9,2.6,3.9,2.6c2.3,3.9,6,2.8,7.5,2.1' +
|
||||
'c0.2-1.7,0.9-2.8,1.6-3.4c-5.7-0.6-11.7-2.8-11.7-12.7c0-2.8,1-5.1,2.6-6.9c-0.3-0.7-1.1-3.3,0.3-6.8c0,0,2.1-0.7,7,2.6' +
|
||||
'c2-0.6,4.2-0.9,6.4-0.9c2.2,0,4.4,0.3,6.4,0.9c4.9-3.3,7-2.6,7-2.6c1.4,3.5,0.5,6.1,0.3,6.8c1.6,1.8,2.6,4.1,2.6,6.9' +
|
||||
'c0,9.8-6,12-11.7,12.6c0.9,0.8,1.7,2.4,1.7,4.7c0,3.4,0,6.2,0,7c0,0.7,0.5,1.5,1.8,1.2c10.2-3.4,17.5-13,17.5-24.3' +
|
||||
'C51.5,11.7,40.1,0.2,25.9,0.2z" />' +
|
||||
'</svg>',
|
||||
},
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
provide: SVG_ICONS,
|
||||
useValue: {
|
||||
namespace: 'logos',
|
||||
name: 'twitter',
|
||||
svgSource:
|
||||
'<svg focusable="false" viewBox="0 0 50 59" xmlns="http://www.w3.org/2000/svg">' +
|
||||
'<path d="M50,9.3c-1.8,0.8-3.8,1.4-5.9,1.6c2.1-1.3,3.7-3.3,4.5-5.7c-2,1.2-4.2,2-6.5,2.5c-1.9-2-4.5-3.2-7.5-3.2' +
|
||||
'c-5.7,0-10.3,4.6-10.3,10.3c0,0.8,0.1,1.6,0.3,2.3C16.1,16.7,8.5,12.6,3.5,6.4c-0.9,1.5-1.4,3.3-1.4,5.2c0,3.6,1.8,6.7,4.6,8.5' +
|
||||
'C5,20,3.4,19.6,2,18.8c0,0,0,0.1,0,0.1c0,5,3.5,9.1,8.2,10.1c-0.9,0.2-1.8,0.4-2.7,0.4c-0.7,0-1.3-0.1-1.9-0.2' +
|
||||
'c1.3,4.1,5.1,7,9.6,7.1c-3.5,2.8-7.9,4.4-12.7,4.4c-0.8,0-1.6,0-2.4-0.1c4.5,2.9,9.9,4.6,15.7,4.6c18.9,0,29.2-15.6,29.2-29.2' +
|
||||
'c0-0.4,0-0.9,0-1.3C46.9,13.2,48.6,11.4,50,9.3z" />' +
|
||||
'</svg>',
|
||||
},
|
||||
multi: true,
|
||||
},
|
||||
];
|
||||
// tslint:enable: max-line-length
|
||||
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { NgModule, Type } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { ContributorListComponent } from './contributor-list.component';
|
||||
import { ContributorService } from './contributor.service';
|
||||
import { ContributorComponent } from './contributor.component';
|
||||
import { WithCustomElementComponent } from '../element-registry';
|
||||
|
||||
@NgModule({
|
||||
imports: [ CommonModule, MatIconModule ],
|
||||
imports: [ CommonModule ],
|
||||
declarations: [ ContributorListComponent, ContributorComponent ],
|
||||
entryComponents: [ ContributorListComponent ],
|
||||
providers: [ ContributorService ]
|
||||
|
@ -13,16 +13,16 @@ import { CONTENT_URL_PREFIX } from 'app/documents/document.service';
|
||||
|
||||
<div class="contributor-image" [style.background-image]="'url('+pictureBase+(person.picture || noPicture)+')'">
|
||||
<div class="contributor-info">
|
||||
<a *ngIf="person.bio" mat-button class="info-item">
|
||||
<a *ngIf="person.bio" mat-button>
|
||||
View Bio
|
||||
</a>
|
||||
<a *ngIf="person.twitter" mat-icon-button class="info-item icon"
|
||||
<a *ngIf="person.twitter" mat-button class="icon"
|
||||
href="https://twitter.com/{{person.twitter}}" target="_blank" (click)="$event.stopPropagation()">
|
||||
<mat-icon svgIcon="logos:twitter"></mat-icon>
|
||||
<span class="fa fa-twitter fa-2x"></span>
|
||||
</a>
|
||||
<a *ngIf="person.website" mat-icon-button class="info-item icon"
|
||||
<a *ngIf="person.website" mat-button class="icon"
|
||||
href="{{person.website}}" target="_blank" (click)="$event.stopPropagation()">
|
||||
<mat-icon class="link-icon">link</mat-icon>
|
||||
<span class="fa fa-link fa-2x"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -0,0 +1,35 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { LocationService } from 'app/shared/location.service';
|
||||
import { MockLocationService } from 'testing/location.service';
|
||||
import { CurrentLocationComponent } from './current-location.component';
|
||||
|
||||
|
||||
describe('CurrentLocationComponent', () => {
|
||||
let element: HTMLElement;
|
||||
let fixture: ComponentFixture<CurrentLocationComponent>;
|
||||
let locationService: MockLocationService;
|
||||
|
||||
beforeEach(() => {
|
||||
locationService = new MockLocationService('initial/url');
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ CurrentLocationComponent ],
|
||||
providers: [
|
||||
{ provide: LocationService, useValue: locationService }
|
||||
]
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(CurrentLocationComponent);
|
||||
element = fixture.nativeElement;
|
||||
});
|
||||
|
||||
it('should render the current location', () => {
|
||||
fixture.detectChanges();
|
||||
expect(element.textContent).toEqual('initial/url');
|
||||
|
||||
locationService.urlSubject.next('next/url');
|
||||
|
||||
fixture.detectChanges();
|
||||
expect(element.textContent).toEqual('next/url');
|
||||
});
|
||||
});
|
@ -0,0 +1,12 @@
|
||||
/* tslint:disable component-selector */
|
||||
import { Component } from '@angular/core';
|
||||
import { LocationService } from 'app/shared/location.service';
|
||||
|
||||
/** Renders the current location path. */
|
||||
@Component({
|
||||
selector: 'current-location',
|
||||
template: '{{ location.currentPath | async }}'
|
||||
})
|
||||
export class CurrentLocationComponent {
|
||||
constructor(public location: LocationService) { }
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
import { NgModule, Type } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CurrentLocationComponent } from './current-location.component';
|
||||
import { WithCustomElementComponent } from '../element-registry';
|
||||
|
||||
@NgModule({
|
||||
imports: [ CommonModule ],
|
||||
declarations: [ CurrentLocationComponent ],
|
||||
entryComponents: [ CurrentLocationComponent ]
|
||||
})
|
||||
export class CurrentLocationModule implements WithCustomElementComponent {
|
||||
customElementComponent: Type<any> = CurrentLocationComponent;
|
||||
}
|
@ -36,30 +36,18 @@ export const ELEMENT_MODULE_PATHS_AS_ROUTES = [
|
||||
selector: 'code-tabs',
|
||||
loadChildren: './code/code-tabs.module#CodeTabsModule'
|
||||
},
|
||||
{
|
||||
selector: 'current-location',
|
||||
loadChildren: './current-location/current-location.module#CurrentLocationModule'
|
||||
},
|
||||
{
|
||||
selector: 'expandable-section',
|
||||
loadChildren: './expandable-section/expandable-section.module#ExpandableSectionModule'
|
||||
},
|
||||
{
|
||||
selector: 'live-example',
|
||||
loadChildren: './live-example/live-example.module#LiveExampleModule'
|
||||
},
|
||||
{
|
||||
selector: 'aio-gs-interpolation',
|
||||
loadChildren: './getting-started/interpolation/interpolation.module#InterpolationModule'
|
||||
},
|
||||
{
|
||||
selector: 'aio-gs-property-binding',
|
||||
loadChildren: './getting-started/property-binding/property-binding.module#PropertyBindingModule'
|
||||
},
|
||||
{
|
||||
selector: 'aio-gs-event-binding',
|
||||
loadChildren: './getting-started/event-binding/event-binding.module#EventBindingModule'
|
||||
},
|
||||
{
|
||||
selector: 'aio-gs-ng-if',
|
||||
loadChildren: './getting-started/ng-if/ng-if.module#NgIfModule'
|
||||
},
|
||||
{
|
||||
selector: 'aio-gs-ng-for',
|
||||
loadChildren: './getting-started/ng-for/ng-for.module#NgForModule'
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,7 @@
|
||||
<mat-expansion-panel style="background: inherit">
|
||||
<mat-expansion-panel-header>
|
||||
{{title}}
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<ng-content></ng-content>
|
||||
</mat-expansion-panel>
|
@ -0,0 +1,11 @@
|
||||
/* tslint:disable component-selector */
|
||||
import {Component, Input} from '@angular/core';
|
||||
|
||||
/** Custom element wrapper for the material expansion panel with a title input. */
|
||||
@Component({
|
||||
selector: 'aio-expandable-section',
|
||||
templateUrl: 'expandable-section.component.html',
|
||||
})
|
||||
export class ExpandableSectionComponent {
|
||||
@Input() title;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
import { NgModule, Type } from '@angular/core';
|
||||
import { ExpandableSectionComponent } from './expandable-section.component';
|
||||
import { WithCustomElementComponent } from '../element-registry';
|
||||
import { MatExpansionModule } from '@angular/material';
|
||||
|
||||
@NgModule({
|
||||
imports: [ MatExpansionModule ],
|
||||
declarations: [ ExpandableSectionComponent, ],
|
||||
entryComponents: [ ExpandableSectionComponent ]
|
||||
})
|
||||
export class ExpandableSectionModule implements WithCustomElementComponent {
|
||||
customElementComponent: Type<any> = ExpandableSectionComponent;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ContainerComponent } from './container.component';
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<aio-gs-container>
|
||||
<ng-container class="template">Template</ng-container>
|
||||
<ng-container class="data">Data</ng-container>
|
||||
<ng-container class="result">Result</ng-container>
|
||||
</aio-gs-container>
|
||||
`
|
||||
})
|
||||
export class TestComponent {}
|
||||
|
||||
describe('Getting Started Container Component', () => {
|
||||
let fixture: ComponentFixture<ContainerComponent>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ContainerComponent, TestComponent ]
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(TestComponent);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should project the content into the appropriate areas', () => {
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
const pre = compiled.querySelector('pre');
|
||||
const code = compiled.querySelector('code');
|
||||
const tabledata = compiled.querySelectorAll('td');
|
||||
|
||||
expect(pre.textContent).toContain('Template');
|
||||
expect(code.textContent).toContain('Data');
|
||||
expect(tabledata[2].textContent).toContain('Result');
|
||||
});
|
||||
});
|
@ -1,80 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'aio-gs-container',
|
||||
template: `
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Template</th>
|
||||
<th>Data</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<pre><ng-content select=".template"></ng-content></pre>
|
||||
</td>
|
||||
<td>
|
||||
<code><ng-content select=".data"></ng-content></code>
|
||||
</td>
|
||||
<td><ng-content select=".result"></ng-content></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
code {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 760px),
|
||||
(min-device-width: 768px) and (max-device-width: 1024px) {
|
||||
/* Force table to not be like tables anymore */
|
||||
table, thead, tbody, th, td, tr {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Hide table headers (but not display: none;, for accessibility) */
|
||||
thead tr {
|
||||
position: absolute;
|
||||
top: -9999px;
|
||||
left: -9999px;
|
||||
}
|
||||
|
||||
tr { border: 1px solid #ccc; }
|
||||
|
||||
td {
|
||||
/* Behave like a "row" */
|
||||
border: none;
|
||||
border-bottom: 1px solid #eee;
|
||||
position: relative;
|
||||
padding-top: 10%;
|
||||
}
|
||||
|
||||
td:before {
|
||||
/* Now like a table header */
|
||||
position: absolute;
|
||||
/* Top/left values mimic padding */
|
||||
top: 6px;
|
||||
left: 6px;
|
||||
width: 45%;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
/* Label the data */
|
||||
td:nth-of-type(1):before { content: "Template"; }
|
||||
td:nth-of-type(2):before { content: "Data"; }
|
||||
td:nth-of-type(3):before { content: "Result"; }
|
||||
}
|
||||
`
|
||||
]
|
||||
})
|
||||
export class ContainerComponent { }
|
@ -1,10 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ContainerComponent } from './container.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [ CommonModule ],
|
||||
declarations: [ ContainerComponent ],
|
||||
exports: [ ContainerComponent ]
|
||||
})
|
||||
export class ContainerModule { }
|
@ -1,46 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ContainerModule } from '../container/container.module';
|
||||
import { EventBindingComponent } from './event-binding.component';
|
||||
import { createCustomEvent } from '../../../../testing/dom-utils';
|
||||
|
||||
describe('Getting Started Event Binding Component', () => {
|
||||
let component: EventBindingComponent;
|
||||
let fixture: ComponentFixture<EventBindingComponent>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ ContainerModule ],
|
||||
declarations: [ EventBindingComponent ]
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(EventBindingComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
|
||||
spyOn(window, 'alert');
|
||||
});
|
||||
|
||||
it('should update the name property on input change', () => {
|
||||
const text = 'Hello Angular';
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
const input: HTMLInputElement = compiled.querySelector('input');
|
||||
|
||||
|
||||
input.value = text;
|
||||
input.dispatchEvent(createCustomEvent(document, 'input', ''));
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.name).toBe(text);
|
||||
});
|
||||
|
||||
it('should display an alert when the button is clicked', () => {
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
const button: HTMLButtonElement = compiled.querySelector('button');
|
||||
|
||||
button.click();
|
||||
|
||||
expect(window.alert).toHaveBeenCalledWith('Hello, Angular!');
|
||||
});
|
||||
});
|
@ -1,30 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'aio-gs-event-binding',
|
||||
template: `
|
||||
<aio-gs-container>
|
||||
<ng-container class="template"><button (click)="greet(name)">
|
||||
Greet
|
||||
</button></ng-container>
|
||||
|
||||
<ng-container class="data">
|
||||
name = '<input #input (input)="name = input.value" [value]="name">';
|
||||
</ng-container>
|
||||
|
||||
<ng-container class="result">
|
||||
<button (click)="greet(name)">
|
||||
Greet
|
||||
</button>
|
||||
</ng-container>
|
||||
</aio-gs-container>
|
||||
`,
|
||||
preserveWhitespaces: true
|
||||
})
|
||||
export class EventBindingComponent {
|
||||
name = 'Angular';
|
||||
|
||||
greet(name: string) {
|
||||
window.alert(`Hello, ${name}!`);
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
import { NgModule, Type } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { WithCustomElementComponent } from '../../element-registry';
|
||||
import { EventBindingComponent } from './event-binding.component';
|
||||
import { ContainerModule } from '../container/container.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [ CommonModule, ContainerModule ],
|
||||
declarations: [ EventBindingComponent ],
|
||||
exports: [ EventBindingComponent ],
|
||||
entryComponents: [ EventBindingComponent ]
|
||||
})
|
||||
export class EventBindingModule implements WithCustomElementComponent {
|
||||
customElementComponent: Type<any> = EventBindingComponent;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { InterpolationComponent } from './interpolation.component';
|
||||
import { ContainerModule } from '../container/container.module';
|
||||
import { createCustomEvent } from '../../../../testing/dom-utils';
|
||||
|
||||
describe('Getting Started Interpolation Component', () => {
|
||||
let component: InterpolationComponent;
|
||||
let fixture: ComponentFixture<InterpolationComponent>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ ContainerModule ],
|
||||
declarations: [ InterpolationComponent ]
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(InterpolationComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should update the siteName property on input change', () => {
|
||||
const text = 'Hello Angular';
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
const input: HTMLInputElement = compiled.querySelector('input');
|
||||
|
||||
input.value = text;
|
||||
input.dispatchEvent(createCustomEvent(document, 'input', ''));
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.siteName).toBe(text);
|
||||
});
|
||||
|
||||
it('should display the siteName', () => {
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
const header: HTMLHeadingElement = compiled.querySelector('h1');
|
||||
|
||||
expect(header.textContent).toContain('My Store');
|
||||
});
|
||||
});
|
@ -1,20 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'aio-gs-interpolation',
|
||||
template: `
|
||||
<aio-gs-container>
|
||||
<ng-container class="template"><h1>Welcome to {{'{'+'{'}}siteName{{'}'+'}'}}<h1></ng-container>
|
||||
|
||||
<ng-container class="data">
|
||||
siteName = '<input #input (input)="siteName = input.value" [value]="siteName">';
|
||||
</ng-container>
|
||||
|
||||
<ng-container class="result"><h1>Welcome to {{ siteName }}</h1></ng-container>
|
||||
</aio-gs-container>
|
||||
`
|
||||
})
|
||||
export class InterpolationComponent {
|
||||
siteName = 'My Store';
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
import { NgModule, Type } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { WithCustomElementComponent } from '../../element-registry';
|
||||
import { InterpolationComponent } from './interpolation.component';
|
||||
import { ContainerModule } from '../container/container.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [ CommonModule, ContainerModule ],
|
||||
declarations: [ InterpolationComponent ],
|
||||
exports: [ InterpolationComponent ],
|
||||
entryComponents: [ InterpolationComponent ]
|
||||
})
|
||||
export class InterpolationModule implements WithCustomElementComponent {
|
||||
customElementComponent: Type<any> = InterpolationComponent;
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { NgForComponent } from './ng-for.component';
|
||||
import { ContainerModule } from '../container/container.module';
|
||||
import { ProductService } from '../product.service';
|
||||
|
||||
describe('Getting Started NgFor Component', () => {
|
||||
let component: NgForComponent;
|
||||
let fixture: ComponentFixture<NgForComponent>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ ContainerModule ],
|
||||
declarations: [ NgForComponent ],
|
||||
providers: [ ProductService ]
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(NgForComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should display the products', () => {
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
const spans = compiled.querySelectorAll('span');
|
||||
|
||||
expect(spans[0]!.textContent).toContain('Shoes');
|
||||
expect(spans[1]!.textContent).toContain('Phones');
|
||||
});
|
||||
|
||||
it('should display an error message if provided products JSON is invalid', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
component.productsData$.next('bad');
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
component.parseError$.subscribe(error => {
|
||||
expect(error).toBeTruthy();
|
||||
})
|
||||
});
|
||||
});
|
@ -1,46 +0,0 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import { ProductService } from '../product.service';
|
||||
|
||||
@Component({
|
||||
selector: 'aio-gs-ng-for',
|
||||
template: `
|
||||
<aio-gs-container>
|
||||
<ng-container class="template"><span *ngFor="let product of products">
|
||||
{{'{'+'{'}}product{{'}'+'}'}}
|
||||
</span></ng-container>
|
||||
|
||||
<ng-container class="data">
|
||||
products = <input #input (input)="productsData$.next(input.value)" [value]="productsData$ | async">;
|
||||
<div *ngIf="parseError$ | async" class="material-icons" matTooltip="The provided JSON is invalid">error_outline</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container class="result">
|
||||
<span *ngFor="let product of products$ | async">{{product}}</span>
|
||||
</ng-container>
|
||||
</aio-gs-container>
|
||||
`,
|
||||
styles: [`
|
||||
span::after {
|
||||
content: ' ';
|
||||
}
|
||||
`],
|
||||
preserveWhitespaces: true
|
||||
})
|
||||
export class NgForComponent implements OnInit, OnDestroy {
|
||||
productsData$ = this.productService.productsData$;
|
||||
products$ = this.productService.products$;
|
||||
parseError$ = this.productService.parseError$;
|
||||
productsSub: Subscription;
|
||||
|
||||
constructor(private productService: ProductService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.productsSub = this.productService.init().subscribe();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.productsSub.unsubscribe();
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import { NgModule, Type } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { WithCustomElementComponent } from '../../element-registry';
|
||||
import { NgForComponent } from './ng-for.component';
|
||||
import { ContainerModule } from '../container/container.module';
|
||||
import { ProductService } from '../product.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [ CommonModule, ContainerModule, MatTooltipModule ],
|
||||
declarations: [ NgForComponent ],
|
||||
exports: [ NgForComponent ],
|
||||
entryComponents: [ NgForComponent ],
|
||||
providers: [ ProductService ]
|
||||
})
|
||||
export class NgForModule implements WithCustomElementComponent {
|
||||
customElementComponent: Type<any> = NgForComponent;
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { NgIfComponent } from './ng-if.component';
|
||||
import { ContainerModule } from '../container/container.module';
|
||||
import { ProductService } from '../product.service';
|
||||
|
||||
describe('Getting Started NgIf Component', () => {
|
||||
let component: NgIfComponent;
|
||||
let fixture: ComponentFixture<NgIfComponent>;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [ ContainerModule ],
|
||||
declarations: [ NgIfComponent ],
|
||||
providers: [ ProductService ]
|
||||
});
|
||||
|
||||
fixture = TestBed.createComponent(NgIfComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should display the message if products are listed', () => {
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
const paragraph = compiled.querySelector('p');
|
||||
|
||||
expect(paragraph.textContent).toContain('available');
|
||||
});
|
||||
|
||||
it('should not display the message if products list is empty', () => {
|
||||
component.products$.next([]);
|
||||
fixture.detectChanges();
|
||||
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
const paragraph = compiled.querySelector('p');
|
||||
|
||||
expect(paragraph).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should display an error message if provided products JSON is invalid', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
component.productsData$.next('bad');
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
component.parseError$.subscribe(error => {
|
||||
expect(error).toBeTruthy();
|
||||
})
|
||||
});
|
||||
});
|
@ -1,43 +0,0 @@
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
import { ProductService } from '../product.service';
|
||||
|
||||
@Component({
|
||||
selector: 'aio-gs-ng-if',
|
||||
template: `
|
||||
<aio-gs-container>
|
||||
<ng-container class="template"><p *ngIf="products.length > 0">
|
||||
We still have products available.
|
||||
</p></ng-container>
|
||||
|
||||
<ng-container class="data">
|
||||
products = <input #input (input)="productsData$.next(input.value)" [value]="productsData$ | async">;
|
||||
<div *ngIf="parseError$ | async" class="material-icons" matTooltip="The provided JSON is invalid">error_outline</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container class="result">
|
||||
<p *ngIf="(products$ | async)?.length > 0">
|
||||
We still have products available.
|
||||
</p>
|
||||
</ng-container>
|
||||
</aio-gs-container>
|
||||
`,
|
||||
preserveWhitespaces: true
|
||||
})
|
||||
export class NgIfComponent implements OnInit, OnDestroy {
|
||||
productsData$ = this.productService.productsData$;
|
||||
products$ = this.productService.products$;
|
||||
parseError$ = this.productService.parseError$;
|
||||
productsSub: Subscription;
|
||||
|
||||
constructor(private productService: ProductService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.productsSub = this.productService.init().subscribe();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.productsSub.unsubscribe();
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import { NgModule, Type } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { WithCustomElementComponent } from '../../element-registry';
|
||||
import { NgIfComponent } from './ng-if.component';
|
||||
import { ContainerModule } from '../container/container.module';
|
||||
import { ProductService } from '../product.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [ CommonModule, ContainerModule, MatTooltipModule ],
|
||||
declarations: [ NgIfComponent ],
|
||||
exports: [ NgIfComponent ],
|
||||
entryComponents: [ NgIfComponent ],
|
||||
providers: [ ProductService ]
|
||||
})
|
||||
export class NgIfModule implements WithCustomElementComponent {
|
||||
customElementComponent: Type<any> = NgIfComponent;
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { BehaviorSubject, Subject } from 'rxjs';
|
||||
import { tap, debounceTime } from 'rxjs/operators';
|
||||
|
||||
export const PRODUCTS = ['Shoes', 'Phones'];
|
||||
|
||||
@Injectable()
|
||||
export class ProductService {
|
||||
productsData$ = new BehaviorSubject(JSON.stringify(PRODUCTS));
|
||||
products$ = new BehaviorSubject<string[]>(PRODUCTS);
|
||||
parseError$ = new Subject<boolean>();
|
||||
|
||||
init() {
|
||||
return this.productsData$.pipe(
|
||||
debounceTime(250),
|
||||
tap(data => {
|
||||
let parsed;
|
||||
|
||||
try {
|
||||
parsed = JSON.parse(data);
|
||||
} catch (e) {
|
||||
parsed = null;
|
||||
}
|
||||
|
||||
if (parsed && Array.isArray(parsed)) {
|
||||
this.products$.next(parsed);
|
||||
this.parseError$.next(false);
|
||||
} else {
|
||||
this.parseError$.next(true);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user