Compare commits

..

62 Commits
6.0.4 ... 6.0.6

Author SHA1 Message Date
e81982ef90 release: cut the v6.0.6 release 2018-06-20 15:57:10 -07:00
776bc38999 test(animations): properly reference body node for SSR environments (#23300)
PR Close #23300
2018-06-20 11:00:42 -07:00
7e7ef8ee25 docs: More edits (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
dd90d92573 docs: More form control API edits (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
1b862820e9 docs: Added multicast to observable descriptions (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
1a642231cd docs: formatting (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
138e0d79cd docs: More form control API references fixes (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
f0a43716e2 docs(docs-infra): Update with review changes (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
2be27fb888 docs(forms): update API reference for FormControl (#24255)
PR Close #24255
2018-06-19 10:53:14 -07:00
74f07f40e0 docs: Remove outdated Webpack guide and example (#24478)
A supporting Webpack guide will be introduced as part of the guidance
for ejecting from the Angular CLI.

Closes #23937

PR Close #24478
2018-06-18 15:03:22 -07:00
aa66e84e44 docs: push animation api doc changes back to stable (#24525)
PR Close #24525
2018-06-15 09:55:58 -07:00
e1bc3f5c1a build(docs-infra): ensure all headings are sentence cased (#24527)
PR Close #24527
2018-06-15 09:13:46 -07:00
f5b366147b fix(core): Injector correctly honors the @Self flag (#24520)
Injector was incorrectly returning instance from parent injector even
when `@Self` was specified.

PR Close #24520
2018-06-14 16:42:08 -07:00
3147a92ee9 build: fix broken circleci build (#24513)
Bazel 0.14 allocates memory differently and runs out of RAM on a 4G circleci worker
so use an xlarge machine for the integration_test job.
Cherry-pick of #24512 onto patch branch.

PR Close #24513
2018-06-14 14:15:20 -07:00
ffedbde0b3 test(bazel): fix flakey bazel integration e2e test (#24522)
PR Close #24522
2018-06-14 14:15:00 -07:00
e543c734ab fix(compiler): support . in import statements. (#20634)
fix #20363

PR Close #20634
2018-06-13 20:29:22 -07:00
fbe6871a94 build(aio): add github links to API doc members (#24000)
This change adds Github edit and view links to methods
and decorator options.

It is possible to add these to properties also but the
UI is rather tight as these are displayed in a table.

PR Close #24000
2018-06-13 16:51:59 -07:00
f43cb9398c build(aio): compute breadcrums for all API doc types (#24000)
PR Close #24000
2018-06-13 16:51:59 -07:00
1e04df9ac7 build(aio): fix decorator doc "inherited from" heading (#24000)
We should not include the package path in the inherited
from heading for decorator API docs

PR Close #24000
2018-06-13 16:51:59 -07:00
840ca05fe8 fix(aio): tidy up API doc styles (#24000)
* Code anchors should inherit the font size from their container
* Table headings should align with content

PR Close #24000
2018-06-13 16:51:59 -07:00
facc9d498d build(aio): fix broken doc-gen unit test (#24000)
PR Close #24000
2018-06-13 16:51:59 -07:00
9d0999027f build(aio): remove invalid H3 usage notes heading (#24000)
This heading is too high for the section because the
method name is a H3 but it cannot be a H4 because
usage notes may contain H4 headings.

PR Close #24000
2018-06-13 16:51:59 -07:00
c00dd5a3f3 build(aio): rearrange processors to ensure we catch all content errors (#24000)
PR Close #24000
2018-06-13 16:51:59 -07:00
3908a63381 docs: fix invalid headings (#24000)
PR Close #24000
2018-06-13 16:51:54 -07:00
20f9e51b8f build(aio): map H3 headings into H4 headings for certain templates (#24000)
The sections such as methods and decorator options are already headed
by a H3 heading so we need to map the H3 headings in the API doc source
down to H4 headings.

This commit includes general heading mapping functionality accessible via
the `marked` Nunjucks filter.

PR Close #24000
2018-06-13 16:47:42 -07:00
232203242a build(aio): rearrange decorator API doc template (#24000)
The overview of the decorator options is now a table.
The detailed description of each option is now a full section.

PR Close #24000
2018-06-13 16:47:42 -07:00
0ca634e697 build(aio): remove unused @linkDocs alias for @link jsdoc tag (#24000)
PR Close #24000
2018-06-13 16:47:42 -07:00
7fd9918024 docs: remove unnecessary @linkDocs tags (#24000)
It is cleaner and simpler to use just a straightforward link.

PR Close #24000
2018-06-13 16:47:42 -07:00
b0aacb81d4 build(aio): improve automatic linking of code items (#24000)
This commit adds new link disambiguators that mean that more
code links can be generated automatically in a sensible way.

The best example is the use of properties within class, interface and
enum documentation.

PR Close #24000
2018-06-13 16:47:42 -07:00
6c850eb031 docs(aio): remove unused guide doc (#24000)
This was erroneously committed into master, when it was really only
supposed to demo what the pages might look like.

PR Close #24000
2018-06-13 16:47:42 -07:00
0df61ad107 build(aio): refactor the decorator doc processing (#24000)
PR Close #24000
2018-06-13 16:47:42 -07:00
fa985ac067 build(aio): do not allow @usageNotes on properties (#24000)
PR Close #24000
2018-06-13 16:47:42 -07:00
06f9197361 build(aio): update to latest dgeni-packages@0.26.2 (#24000)
This update allows us to autolink to methods and properties, which
means that we can change things like `{@link transition transition()}`
to just `transition()`.

PR Close #24000
2018-06-13 16:47:42 -07:00
c2bad1249e build(aio): add content rule to prevent usageNotes in non-export API docs (#24000)
This commit also factors out `API_CONTAINED_DOC_TYPES` to be used by
both `filterContainedDocs` and `addAllowedPropertiesRules`.

PR Close #24000
2018-06-13 16:47:42 -07:00
9d69ff8ddd build(aio): don't constrain checkContentRules to run before another processor (#24000)
We don't really care when this processor runs as long as it happens
after the tags have been extracted.
By not constraining its `runBefore` property we can ensure that other
processors can be run before it.

PR Close #24000
2018-06-13 16:47:42 -07:00
3fd33f8eb0 build(aio): do not try to auto-link to internal API items (#24000)
This would cause dangling links since the target, being internal,
would not exist in the docs.

PR Close #24000
2018-06-13 16:47:42 -07:00
501a243b3f build(aio): don't render @Annotation tags (#24000)
Because we were "ignoring" these tags they were being
rendered as part of the previous tag.
What we really want to do is know about them, so that we
don't break the doc-gen but then ignore them when rendering.

PR Close #24000
2018-06-13 16:47:42 -07:00
b91b9efc91 release: cut the v6.0.5 release 2018-06-13 15:00:28 -07:00
03718c95ce docs: change capitalization for css hex color values (#23511)
PR Close #23511
2018-06-13 13:31:30 -07:00
0834710c18 docs(aio): remove links to outdated live examples from the API documenation (#23966)
Closes #21525

PR Close #23966
2018-06-13 13:29:13 -07:00
9a9a7de9a4 docs: add message property to compose-message component (#24310)
PR Close #24310
2018-06-13 13:28:47 -07:00
ff51691221 docs: fix typo (#24470)
PR Close #24470
2018-06-13 11:54:26 -07:00
2ad90ab0d3 docs: fix wording in 4-10 (#24385)
PR Close #24385
2018-06-13 11:53:20 -07:00
c5872e6782 docs(aio): Reorganize style guide sections on prefixing components/directives (#22571)
Closes https://github.com/angular/angular/issues/22081

PR Close #22571
2018-06-13 11:20:43 -07:00
d20877bf3f fix(router): fix lazy loading of aux routes (#23459)
Fixes #10981

PR Close #23459
2018-06-13 11:20:20 -07:00
b3089b4963 build: update buildifier to latest (#24296) (#24453)
this matches the version in ngcontainer:0.3.1

PR Close #24296

PR Close #24453
2018-06-13 11:19:59 -07:00
880b03101e build: update to Bazel 0.14.0 (#24296) (#24453)
Also update usage of the ctx.actions.args to a newer preferred API

PR Close #24296

PR Close #24453
2018-06-13 11:19:59 -07:00
451d996414 docs: change aio scope to docs-infra (#24410)
Related to #24295

PR Close #24410
2018-06-12 11:36:14 -07:00
ea3669e334 fix(bazel): Allow ng_module to depend on targets w no deps (#24446)
PR Close #24446
2018-06-12 11:35:53 -07:00
ea2987c7af fix(service-worker): fix SwPush.unsubscribe() (#24162)
Fixes #24095

PR Close #24162
2018-06-11 14:04:31 -04:00
5b823dedcc test(service-worker): allow SwPush tests to run on Node.js (#24162)
PR Close #24162
2018-06-11 14:04:30 -04:00
80f7c83bdd test(service-worker): add tests for SwPush (#24162)
PR Close #24162
2018-06-11 14:04:30 -04:00
53072b10da refactor(service-worker): minor mocks refactoring (#24162)
PR Close #24162
2018-06-11 14:04:30 -04:00
30c2f560b1 build(docs-infra): ensure dist/ directory is cleaned before running tsc --watch (#24372)
PR Close #24372
2018-06-11 09:18:46 -07:00
18c4976f3b build(docs-infra): upgrade preview server to latest @types/shelljs (#24372)
PR Close #24372
2018-06-11 09:18:46 -07:00
0139173c7c fix(animations): always render end-state styles for orphaned DOM nodes (#24236)
This patch ensures that any destination animation styling (state values)
are always applied even if the DOM node is not apart of the DOM.

PR Close #24236
2018-06-08 16:35:27 -07:00
f3c9954a68 docs: adds information about the VSCode clang-format extension (#24351)
PR Close #24351
2018-06-08 16:35:06 -07:00
e8765352e8 fix(docs-infra): use script nomodule to load IE polyfills, skip other polyfills (#24317)
This commit includes two changes:
1. It changes the unreliable dynamic way of loading IE polyfills to use
   `<script nomodule>` instead - for IE it's equivalent to a regular script tag
   while modern browsers will ignore it.
2. It removes other polyfills for browsers not supporting `Object.assign` as
   this API is supported by Chrome 45+, Firefox 34+ and Safari 9+ i.e. it's been
   supported for some time.

Note that as of June 2018 Googlebot uses Chrome 41 to render sites to be
indexed. Chrome 41 doesn't support `Object.assign` but it also doesn't support
ES6 modules so it'll load polyfills meant for IE - which it should do anyway
as it doesn't support most of ES6.

Fixes #23647

PR Close #24317
2018-06-08 13:34:06 -07:00
9e61ad897e build(docs-infra): ensure stability is computed before the API list (#24356)
Previously the API list was being generated before the stability had
been computed. This meant that the API list page showed no API docs
when filtering by `stable` stability status.

Closes #24329

PR Close #24356
2018-06-08 13:33:32 -07:00
0d81151cbc docs(aio): add mix and connect to front page campaigns (#24357)
PR Close #24357
2018-06-08 13:31:28 -07:00
70319722a1 docs(aio): Added resource link to Amexio Canvas Web Based IDE (#24336)
PR Close #24336
2018-06-07 18:46:32 -04:00
cfa5b6567d build(bazel): fix ng_package rollup root dir for fesm2015 output (#24298)
PR Close #24298
2018-06-07 17:56:10 -04:00
184 changed files with 2822 additions and 4197 deletions

View File

@ -12,8 +12,8 @@
## IMPORTANT
# If you change the `docker_image` version, also change the `cache_key` suffix and the version of
# `com_github_bazelbuild_buildtools` in the `/WORKSPACE` file.
var_1: &docker_image angular/ngcontainer:0.3.0
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.0
var_1: &docker_image angular/ngcontainer:0.3.2
var_2: &cache_key v2-angular-{{ .Branch }}-{{ checksum "yarn.lock" }}-0.3.2
# Define common ENV vars
var_3: &define_env_vars
@ -149,6 +149,10 @@ jobs:
# See comments inside the integration/run_tests.sh script.
integration_test:
<<: *job_defaults
# Note: we run Bazel in one of the integration tests, and it can consume >2G
# of memory. Together with the system under test, this can exhaust the RAM
# on a 4G worker so we use a larger machine here too.
resource_class: xlarge
steps:
- *define_env_vars
- checkout:

View File

@ -1,3 +1,28 @@
<a name="6.0.6"></a>
## [6.0.6](https://github.com/angular/angular/compare/6.0.5...6.0.6) (2018-06-20)
### Bug Fixes
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([e543c73](https://github.com/angular/angular/commit/e543c73)), closes [#20363](https://github.com/angular/angular/issues/20363)
* **core:** Injector correctly honors the @Self flag ([#24520](https://github.com/angular/angular/issues/24520)) ([f5b3661](https://github.com/angular/angular/commit/f5b3661))
<a name="6.0.5"></a>
## [6.0.5](https://github.com/angular/angular/compare/6.0.4...6.0.5) (2018-06-13)
### Bug Fixes
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([0139173](https://github.com/angular/angular/commit/0139173))
* **bazel:** Allow ng_module to depend on targets w no deps ([#24446](https://github.com/angular/angular/issues/24446)) ([ea3669e](https://github.com/angular/angular/commit/ea3669e))
* **docs-infra:** use script nomodule to load IE polyfills, skip other polyfills ([#24317](https://github.com/angular/angular/issues/24317)) ([e876535](https://github.com/angular/angular/commit/e876535)), closes [#23647](https://github.com/angular/angular/issues/23647)
* **router:** fix lazy loading of aux routes ([#23459](https://github.com/angular/angular/issues/23459)) ([d20877b](https://github.com/angular/angular/commit/d20877b)), closes [#10981](https://github.com/angular/angular/issues/10981)
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([ea2987c](https://github.com/angular/angular/commit/ea2987c)), closes [#24095](https://github.com/angular/angular/issues/24095)
<a name="6.0.4"></a>
## [6.0.4](https://github.com/angular/angular/compare/6.0.3...6.0.4) (2018-06-06)

View File

@ -227,10 +227,15 @@ The following is the list of supported scopes:
There are currently a few exceptions to the "use package name" rule:
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g. public path changes, package.json changes done to all packages, d.ts file/format changes, changes to bundles, etc.
* **packaging**: used for changes that change the npm package layout in all of our packages, e.g.
public path changes, package.json changes done to all packages, d.ts file/format changes, changes
to bundles, etc.
* **changelog**: used for updating the release notes in CHANGELOG.md
* **aio**: used for docs-app (angular.io) related changes within the /aio directory of the repo
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all packages (e.g. `style: add missing semicolons`)
* **docs-infra**: used for docs-app (angular.io) related changes within the /aio directory of the
repo
* none/empty string: useful for `style`, `test` and `refactor` changes that are done across all
packages (e.g. `style: add missing semicolons`) and for docs changes that are not related to a
specific package (e.g. `docs: fix typo in tutorial`).
### Subject
The subject contains a succinct description of the change:
@ -269,7 +274,7 @@ changes to be accepted, the CLA must be signed. It's a quick process, we promise
* https://help.github.com/articles/about-commit-email-addresses/
* https://help.github.com/articles/blocking-command-line-pushes-that-expose-your-personal-email-address/
Note that if you have more than one Git identity, it is important to verify that you are logged in with the same ID with which you signed the CLA, before you commit changes. If not, your PR will fail the CLA check.
Note that if you have more than one Git identity, it is important to verify that you are logged in with the same ID with which you signed the CLA, before you commit changes. If not, your PR will fail the CLA check.
<hr>

View File

@ -34,13 +34,13 @@ http_archive(
# This commit matches the version of buildifier in angular/ngcontainer
# If you change this, also check if it matches the version in the angular/ngcontainer
# version in /.circleci/config.yml
BAZEL_BUILDTOOLS_VERSION = "fd9878fd5de921e0bbab3dcdcb932c2627812ee1"
BAZEL_BUILDTOOLS_VERSION = "82b21607e00913b16fe1c51bec80232d9d6de31c"
http_archive(
name = "com_github_bazelbuild_buildtools",
url = "https://github.com/bazelbuild/buildtools/archive/%s.zip" % BAZEL_BUILDTOOLS_VERSION,
strip_prefix = "buildtools-%s" % BAZEL_BUILDTOOLS_VERSION,
sha256 = "27bb461ade23fd44ba98723ad98f84ee9c83cd3540b773b186a1bc5037f3d862",
sha256 = "edb24c2f9c55b10a820ec74db0564415c0cf553fa55e9fc709a6332fb6685eff",
)
# Fetching the Bazel source code allows us to compile the Skylark linter
@ -77,7 +77,7 @@ http_archive(
load("@build_bazel_rules_nodejs//:defs.bzl", "check_bazel_version", "node_repositories", "yarn_install")
check_bazel_version("0.13.0")
check_bazel_version("0.14.0")
node_repositories(package_json = ["//:package.json"])
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")

View File

@ -52,8 +52,7 @@ export class BuildCleaner {
protected removeDir(dir: string) {
try {
if (shell.test('-d', dir)) {
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
(shell as any).chmod('-R', 'a+w', dir);
shell.chmod('-R', 'a+w', dir);
shell.rm('-rf', dir);
}
} catch (err) {

View File

@ -106,8 +106,7 @@ export class BuildCreator extends EventEmitter {
}
try {
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
(shell as any).chmod('-R', 'a-w', outputDir);
shell.chmod('-R', 'a-w', outputDir);
shell.rm('-f', inputFile);
resolve();
} catch (err) {

View File

@ -98,8 +98,7 @@ class Helper {
const prDir = this.getPrDir(pr, isPublic);
if (fs.existsSync(prDir)) {
// Undocumented signature (see https://github.com/shelljs/shelljs/pull/663).
(shell as any).chmod('-R', 'a+w', prDir);
shell.chmod('-R', 'a+w', prDir);
shell.rm('-rf', prDir);
}
}

View File

@ -8,7 +8,7 @@
"scripts": {
"prebuild": "yarn clean-dist",
"build": "tsc",
"build-watch": "yarn tsc --watch",
"build-watch": "yarn build --watch",
"clean-dist": "node --eval \"require('shelljs').rm('-rf', 'dist')\"",
"dev": "concurrently --kill-others --raw --success first \"yarn build-watch\" \"yarn test-watch\"",
"lint": "tslint --project tsconfig.json",
@ -33,7 +33,7 @@
"@types/jasmine": "^2.6.0",
"@types/jsonwebtoken": "^7.2.3",
"@types/node": "^8.0.30",
"@types/shelljs": "^0.7.4",
"@types/shelljs": "^0.8.0",
"@types/supertest": "^2.0.3",
"concurrently": "^3.5.0",
"nodemon": "^1.12.1",

View File

@ -69,9 +69,9 @@
"@types/express-serve-static-core" "*"
"@types/mime" "*"
"@types/shelljs@^0.7.4":
version "0.7.4"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.4.tgz#137b5f31306eaff4de120ffe5b9d74b297809cfc"
"@types/shelljs@^0.8.0":
version "0.8.0"
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.0.tgz#0caa56b68baae4f68f44e0dd666ab30b098e3632"
dependencies:
"@types/glob" "*"
"@types/node" "*"

View File

@ -15,6 +15,7 @@ export class ComposeMessageComponent {
@HostBinding('style.position') position = 'absolute';
details: string;
message: string;
sending = false;
constructor(private router: Router) {}

View File

@ -18,11 +18,11 @@ nav a {
border-radius: 4px;
}
nav a:visited, a:link {
color: #607D8B;
color: #607d8b;
}
nav a:hover {
color: #039be5;
background-color: #CFD8DC;
background-color: #cfd8dc;
}
nav a.active {
color: #039be5;

View File

@ -33,11 +33,11 @@ h4 {
color: #eee;
max-height: 120px;
min-width: 120px;
background-color: #607D8B;
background-color: #607d8b;
border-radius: 2px;
}
.module:hover {
background-color: #EEE;
background-color: #eee;
cursor: pointer;
color: #607d8b;
}

View File

@ -1,12 +0,0 @@
// #docregion
var path = require('path');
var _root = path.resolve(__dirname, '..');
function root(args) {
args = Array.prototype.slice.call(arguments, 0);
return path.join.apply(path, [_root].concat(args));
}
exports.root = root;
// #enddocregion

View File

@ -1,17 +0,0 @@
// #docregion
Error.stackTraceLimit = Infinity;
require('core-js/es6');
require('core-js/es7/reflect');
require('zone.js/dist/zone');
require('zone.js/dist/zone-testing');
var appContext = require.context('../src', true, /\.spec\.ts/);
appContext.keys().forEach(appContext);
var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());

View File

@ -1,39 +0,0 @@
// #docregion
var webpackConfig = require('./webpack.test');
module.exports = function (config) {
var _config = {
basePath: '',
frameworks: ['jasmine'],
files: [
{pattern: './config/karma-test-shim.js', watched: false}
],
preprocessors: {
'./config/karma-test-shim.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
},
webpackServer: {
noInfo: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome'],
singleRun: true
};
config.set(_config);
};
// #enddocregion

View File

@ -1,81 +0,0 @@
// #docplaster
// #docregion
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');
module.exports = {
// #docregion entries, one-entry, two-entries
entry: {
// #enddocregion one-entry, two-entries
'polyfills': './src/polyfills.ts',
// #docregion two-entries
'vendor': './src/vendor.ts',
// #docregion one-entry
'app': './src/main.ts'
},
// #enddocregion entries, one-entry, two-entries
// #docregion resolve
resolve: {
extensions: ['.ts', '.js']
},
// #enddocregion resolve
// #docregion loaders
module: {
rules: [
{
test: /\.ts$/,
loaders: [
{
loader: 'awesome-typescript-loader',
options: { configFileName: helpers.root('src', 'tsconfig.json') }
} , 'angular2-template-loader'
]
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader?name=assets/[name].[hash].[ext]'
},
{
test: /\.css$/,
exclude: helpers.root('src', 'app'),
loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader?sourceMap' })
},
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw-loader'
}
]
},
// #enddocregion loaders
// #docregion plugins
plugins: [
// Workaround for angular/angular#11580
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)@angular/,
helpers.root('./src'), // location of your src
{} // a map of your routes
),
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
// #enddocregion plugins
};
// #enddocregion

View File

@ -1,26 +0,0 @@
// #docregion
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');
module.exports = webpackMerge(commonConfig, {
devtool: 'cheap-module-eval-source-map',
output: {
path: helpers.root('dist'),
publicPath: '/',
filename: '[name].js',
chunkFilename: '[id].chunk.js'
},
plugins: [
new ExtractTextPlugin('[name].css')
],
devServer: {
historyApiFallback: true,
stats: 'minimal'
}
});
// #enddocregion

View File

@ -1,41 +0,0 @@
// #docregion
var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
module.exports = webpackMerge(commonConfig, {
devtool: 'source-map',
output: {
path: helpers.root('dist'),
publicPath: '/',
filename: '[name].[hash].js',
chunkFilename: '[id].[hash].chunk.js'
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
mangle: {
keep_fnames: true
}
}),
new ExtractTextPlugin('[name].[hash].css'),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
}),
new webpack.LoaderOptionsPlugin({
htmlLoader: {
minimize: false // workaround for ng2
}
})
]
});
// #enddocregion

View File

@ -1,55 +0,0 @@
// #docregion
var webpack = require('webpack');
var helpers = require('./helpers');
module.exports = {
devtool: 'inline-source-map',
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
loaders: [
{
loader: 'awesome-typescript-loader',
options: { configFileName: helpers.root('src', 'tsconfig.json') }
} , 'angular2-template-loader'
]
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'null-loader'
},
{
test: /\.css$/,
exclude: helpers.root('src', 'app'),
loader: 'null-loader'
},
{
test: /\.css$/,
include: helpers.root('src', 'app'),
loader: 'raw-loader'
}
]
},
plugins: [
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)@angular/,
helpers.root('./src'), // location of your src
{} // a map of your routes
)
]
}
// #enddocregion

View File

@ -1,21 +0,0 @@
'use strict'; // necessary for es6 output in node
import { browser, element, by } from 'protractor';
describe('QuickStart E2E Tests', function () {
let expectedMsg = 'Hello from Angular App with Webpack';
beforeEach(function () {
browser.get('');
});
it(`should display: ${expectedMsg}`, function () {
expect(element(by.css('h1')).getText()).toEqual(expectedMsg);
});
it('should display an image', function () {
expect(element(by.css('img')).isPresent()).toBe(true);
});
});

View File

@ -1,5 +0,0 @@
{
"build": "build:webpack",
"run": "serve:cli",
"projectType": "systemjs"
}

View File

@ -1,2 +0,0 @@
// #docregion
module.exports = require('./config/karma.conf.js');

View File

@ -1,49 +0,0 @@
{
"name": "angular2-webpack",
"version": "1.0.0",
"description": "A webpack starter for Angular",
"scripts": {
"start": "webpack-dev-server --inline --progress --port 8080",
"test": "karma start",
"build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"
},
"license": "MIT",
"dependencies": {
"@angular/common": "~4.2.0",
"@angular/compiler": "~4.2.0",
"@angular/core": "~4.2.0",
"@angular/forms": "~4.2.0",
"@angular/http": "~4.2.0",
"@angular/platform-browser": "~4.2.0",
"@angular/platform-browser-dynamic": "~4.2.0",
"@angular/router": "~4.2.0",
"core-js": "^2.4.1",
"rxjs": "5.0.1",
"zone.js": "^0.8.4"
},
"devDependencies": {
"@types/node": "^6.0.45",
"@types/jasmine": "2.5.36",
"angular2-template-loader": "^0.6.0",
"awesome-typescript-loader": "^3.0.4",
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "2.0.0-beta.5",
"file-loader": "^0.9.0",
"html-loader": "^0.4.3",
"html-webpack-plugin": "^2.16.1",
"jasmine-core": "^2.4.1",
"karma": "^1.2.0",
"karma-chrome-launcher": "^2.0.0",
"karma-jasmine": "^1.0.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^2.0.1",
"null-loader": "^0.1.1",
"raw-loader": "^0.5.1",
"rimraf": "^2.5.2",
"style-loader": "^0.13.1",
"typescript": "~2.3.1",
"webpack": "2.2.1",
"webpack-dev-server": "2.4.1",
"webpack-merge": "^3.0.0"
}
}

View File

@ -1,9 +0,0 @@
/* #docregion */
main {
padding: 1em;
font-family: Arial, Helvetica, sans-serif;
text-align: center;
margin-top: 50px;
display: block;
}
/* #enddocregion */

View File

@ -1,7 +0,0 @@
<!-- #docregion -->
<main>
<h1>Hello from Angular App with Webpack</h1>
<img src="../assets/images/angular.png">
</main>
<!-- #enddocregion -->

View File

@ -1,16 +0,0 @@
// #docregion
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('App', () => {
beforeEach(() => {
TestBed.configureTestingModule({ declarations: [AppComponent]});
});
it ('should work', () => {
let fixture = TestBed.createComponent(AppComponent);
expect(fixture.componentInstance instanceof AppComponent).toBe(true, 'should create AppComponent');
});
});
// #enddocregion

View File

@ -1,16 +0,0 @@
// #docplaster
// #docregion
// #docregion component
import { Component } from '@angular/core';
// #enddocregion component
import '../assets/css/styles.css';
// #docregion component
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent { }
// #enddocregion

View File

@ -1,16 +0,0 @@
// #docregion
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
imports: [
BrowserModule
],
declarations: [
AppComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }

View File

@ -1,6 +0,0 @@
/* #docregion */
body {
background: #0147A7;
color: #fff;
}
/* #enddocregion */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -1,14 +0,0 @@
<!-- #docregion -->
<!DOCTYPE html>
<html>
<head>
<base href="/">
<title>Angular With Webpack</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>
<!-- #enddocregion -->

View File

@ -1,14 +0,0 @@
// #docregion
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app/app.module';
// #docregion enable-prod
if (process.env.ENV === 'production') {
enableProdMode();
}
// #enddocregion enable-prod
platformBrowserDynamic().bootstrapModule(AppModule);
// #enddocregion

View File

@ -1,12 +0,0 @@
// #docregion
import 'core-js/es6';
import 'core-js/es7/reflect';
require('zone.js/dist/zone');
if (process.env.ENV === 'production') {
// Production
} else {
// Development and test
Error['stackTraceLimit'] = Infinity;
require('zone.js/dist/long-stack-trace-zone');
}

View File

@ -1,13 +0,0 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es2015", "dom"],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}

View File

@ -1,18 +0,0 @@
// TODO(i): this no longer works. we need to review this example and if absolutely necessary rewrite it to use the
// rxjs-compat package
// #docregion
// Angular
import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';
import '@angular/core';
import '@angular/common';
import '@angular/http';
import '@angular/router';
// RxJS
import 'rxjs';
// Other vendors for example jQuery, Lodash or Bootstrap
// You can import js, ts, css, sass, ...
// #enddocregion

View File

@ -1,3 +0,0 @@
// #docregion
module.exports = require('./config/webpack.dev.js');
// #enddocregion

View File

@ -1,12 +0,0 @@
{
"files":[
"!**/*.d.ts",
"!**/*.js",
"!**/*.[0-9].*",
"config/**/*",
"webpack.config.js",
"karma.webpack.conf.js"
],
"removeSystemJsConfig": true,
"type": "webpack"
}

View File

@ -1,175 +0,0 @@
<div class="breadcrumb">
<a href="#">API<a> / <a href="#">@core<a>
</div>
<header class="api-header">
<h1><label class="api-status-label experimental">experimental</label><label class="api-type-label class">class</label>Class Name</h1>
</header>
<div class="page-actions">
<a href="#"><label class="raised page-label"><i class="material-icons">mode_edit</i>suggest edits</label></a>
<a href="#"><label class="raised page-label"><i class="material-icons">code</i>view source</label></a>
</div>
<p>Class description goes here. This is a short and to the point one or two sentence description that easily introduces the reader to the class.</p>
<div class="api-body">
<section>
<h2>Overview</h2>
<code-example language="ts" hidecopy="true" ng-version="5.2.0"><aio-code class="simple-code" ng-reflect-ng-class="[object Object]" ng-reflect-code="
class <a href=&quot;api/core/Compi" ng-reflect-hide-copy="true" ng-reflect-language="ts" ng-reflect-linenums="" ng-reflect-path="" ng-reflect-region="" ng-reflect-title=""><pre class="prettyprint lang-ts">
<code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><a href="api/core/Compiler" class="code-anchor"><span class="typ">Compiler</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#compileModuleSync"><span class="pln">compileModuleSync</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;):</span><span class="pln"> </span><span class="typ">NgModuleFactory</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAsync"><span class="pln">compileModuleAsync</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;):</span><span class="pln"> </span><span class="typ">Promise</span><span class="pun">&lt;</span><span class="typ">NgModuleFactory</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;&gt;</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAndAllComponentsSync"><span class="pln">compileModuleAndAllComponentsSync</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;):</span><span class="pln"> </span><span class="typ">ModuleWithComponentFactories</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#compileModuleAndAllComponentsAsync"><span class="pln">compileModuleAndAllComponentsAsync</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;(</span><span class="pln">moduleType</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;):</span><span class="pln"> </span><span class="typ">Promise</span><span class="pun">&lt;</span><span class="typ">ModuleWithComponentFactories</span><span class="pun">&lt;</span><span class="pln">T</span><span class="pun">&gt;&gt;</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#clearCache"><span class="pln">clearCache</span><span class="pun">():</span><span class="pln"> </span><span class="kwd">void</span></a><span class="pln">
</span><a class="code-anchor" href="api/core/Compiler#clearCacheFor"><span class="pln">clearCacheFor</span><span class="pun">(</span><span class="pln">type</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Type</span><span class="pun">&lt;</span><span class="pln">any</span><span class="pun">&gt;)</span></a><span class="pln">
</span><span class="pun">}</span></code>
</pre></aio-code></code-example>
</section>
<section>
<h2>Description</h2>
<p>The longer class description goes here which can include multiple paragraphs.</p>
</p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
<h3>Subclasses</h3>
<ul>
<li><a href="#">Subclass1</a></li>
<li><a href="#">Subclass2</a></li>
<li><a href="#">Subclass3</a></li>
</ul>
<h3>See Also</h3>
<ul>
<li><a href="#">Link1</a></li>
<li><a href="#">Link2</a></li>
</ul>
</section>
<section>
<h2>Constructor</h2>
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-">
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
</pre></aio-code></code-example>
</section>
<section>
<h2>Properties</h2>
<table class="is-full-width list-table">
<thead>
<tr>
<th>Property</th>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code><strong>Property1</strong></code>
</td>
<td><label class="property-type-label type">Type</label></td>
<td>Description goes here</td>
</tr>
<tr>
<td>
<code><strong>Property2</strong></code>
</td>
<td>Type</td>
<td>Description goes here</td>
</tr>
<tr>
<td>
<code><strong>Property3</strong></code>
</td>
<td>Type</td>
<td>Description goes here</td>
</tr>
</tbody>
</table>
</section>
<section class="api-method">
<h2>Methods</h2>
<table class="is-full-width item-table">
<thead>
<tr>
<th>Method1Name( )</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>Description goes here</p>
<br>
<p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
</td>
</tr>
</tbody>
</table>
<table class="is-full-width api-method item-table">
<thead>
<tr>
<th>Method2Name( )</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<p>Description goes here</p>
<hr>
<h5>Declaration</h5>
<code-example language="ts" hidecopy="true" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-ts">
<code class="animated fadeIn"><span class="kwd">class</span><span class="pln"> </span><a href="api/animations/AnimationBuilder" class="code-anchor"><span class="typ">AnimationBuilder</span></a><span class="pln"> </span><span class="pun">{</span><span class="pln"></span><a class="code-anchor" href="api/animations/AnimationBuilder#build"><span class="pln">build</span><span class="pun">(</span><span class="pln">animation</span><span class="pun">:</span><span class="pln"> </span><span class="typ">AnimationMetadata</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">AnimationMetadata</span><span class="pun">[]):</span><span class="pln"> </span><span class="typ">AnimationFactory</span></a><span class="pln"></span><span class="pun">}</span></code></pre>
</aio-code>
</code-example>
<h6>Parameters</h6>
<h6>Returns</h6>
<p>Returns information and results goes here.</p>
<h6>Errors</h6>
<p>Error information goes here</p>
<hr>
<p>Further details provided as needed. Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball.</p><hr>
<h6>Overloads</h6>
<table class="is-full-width">
<tbody>
<tr>
<td>
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-">
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
</pre></aio-code></code-example>
</td>
<td>Description goes here</td>
</tr>
<tr>
<td>
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-">
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
</pre></aio-code></code-example>
</td>
<td>Description goes here</td>
</tr>
</tbody>
</table>
<hr>
<h5>Example: Descriptive Title of Method Example</h5>
<p>Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball. Ham hock picanha burgdoggen pork belly rump bacon cupim. Bacon kielbasa sirloin shank strip steak ground round. Bresaola cow salami meatloaf pork chop leberkas flank turducken biltong meatball chuck pork tri-tip chicken. Ribeye corned beef shoulder, meatloaf strip steak jerky porchetta capicola alcatra ham.</p>
</td>
</tr>
</tbody>
</table>
</section>
<section>
<h2>Example: Descriptive Title of Combined Example Goes Here</h2>
<p>Intro description text about what the example is and how it can be used.</p>
<code-example hidecopy="true" class="no-box api-heading" ng-version="5.2.0">
<aio-code class="simple-code"><pre class="prettyprint lang-">
<code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">element</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">,</span><span class="pln"> keyframes</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="pun">[</span><span class="pln">key</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">]:</span><span class="pln"> </span><span class="kwd">string</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> number</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}[],</span><span class="pln"> duration</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> delay</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> easing</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">,</span><span class="pln"> previousPlayers</span><span class="pun">:</span><span class="pln"> any</span><span class="pun">[])</span></code>
</pre></aio-code></code-example>
<p>Further explanation provided as needed. Bacon ipsum dolor amet pork belly capicola sirloin venison alcatra ground round ham hock jowl turkey picanha bresaola pancetta brisket chicken fatback. Burgdoggen kevin salami jowl shoulder jerky leberkas meatball.</p>
</section>
</div>

View File

@ -933,29 +933,18 @@ As always, strive for consistency.
<a href="#toc">Back to top</a>
{@a 02-06}
{@a 05-02}
### Directive selectors
### Component selectors
#### Style 02-06
#### Style 05-02
<div class="s-rule do">
**Do** Use lower camel case for naming the selectors of directives.
</div>
<div class="s-why">
**Why?** Keeps the names of the properties defined in the directives that are bound to the view consistent with the attribute names.
**Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components.
</div>
@ -966,16 +955,40 @@ As always, strive for consistency.
**Why?** The Angular HTML parser is case sensitive and recognizes lower camel case.
**Why?** Keeps the element names consistent with the specification for [Custom Elements](https://www.w3.org/TR/custom-elements/).
</div>
<code-example path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts" region="example" title="app/heroes/shared/hero-button/hero-button.component.ts">
</code-example>
<code-tabs>
<code-pane title="app/heroes/shared/hero-button/hero-button.component.ts" path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.ts" region="example">
</code-pane>
<code-pane title="app/app.component.html" path="styleguide/src/05-02/app/app.component.html">
</code-pane>
</code-tabs>
<a href="#toc">Back to top</a>
{@a 02-07}
### Custom prefix for components
### Component custom prefix
#### Style 02-07
@ -1078,11 +1091,51 @@ For example, the prefix `toh` represents from **T**our **o**f **H**eroes and the
<a href="#toc">Back to top</a>
{@a 02-06}
### Directive selectors
#### Style 02-06
<div class="s-rule do">
**Do** Use lower camel case for naming the selectors of directives.
</div>
<div class="s-why">
**Why?** Keeps the names of the properties defined in the directives that are bound to the view consistent with the attribute names.
</div>
<div class="s-why-last">
**Why?** The Angular HTML parser is case sensitive and recognizes lower camel case.
</div>
<a href="#toc">Back to top</a>
{@a 02-08}
### Custom prefix for directives
### Directive custom prefix
#### Style 02-08
@ -3056,9 +3109,9 @@ module are referenced across the entire application.
**Avoid** providing services in shared modules. Services are usually
**Consider** _not_ providing services in shared modules. Services are usually
singletons that are provided once for the entire application or
in a particular feature module.
in a particular feature module. There are exceptions, however. For example, in the sample code that follows, notice that the `SharedModule` provides `FilterTextService`. This is acceptable here because the service is stateless;that is, the consumers of the service aren't impacted by new instances.
</div>
@ -3710,59 +3763,6 @@ A typical *lazy loaded folder* contains a *routing component*, its child compone
## Components
{@a 05-02}
### Component selector names
#### Style 05-02
<div class="s-rule do">
**Do** use _dashed-case_ or _kebab-case_ for naming the element selectors of components.
</div>
<div class="s-why-last">
**Why?** Keeps the element names consistent with the specification for [Custom Elements](https://www.w3.org/TR/custom-elements/).
</div>
<code-example path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.avoid.ts" region="example" title="app/heroes/shared/hero-button/hero-button.component.ts">
</code-example>
<code-tabs>
<code-pane title="app/heroes/shared/hero-button/hero-button.component.ts" path="styleguide/src/05-02/app/heroes/shared/hero-button/hero-button.component.ts" region="example">
</code-pane>
<code-pane title="app/app.component.html" path="styleguide/src/05-02/app/app.component.html">
</code-pane>
</code-tabs>
<a href="#toc">Back to top</a>
{@a 05-03}
### Components as elements

View File

@ -398,7 +398,7 @@ But a component is more than just its class.
A component interacts with the DOM and with other components.
The _class-only_ tests can tell you about class behavior.
They cannot tell you if the component is going to render properly,
respond to user input and gestures, or integrate with its parent and and child components.
respond to user input and gestures, or integrate with its parent and child components.
None of the _class-only_ tests above can answer key questions about how the
components actually behave on screen.

View File

@ -132,7 +132,7 @@ QuickStart identifies two *typings*, or `d.ts`, files:
* [jasmine](http://jasmine.github.io/) typings for the Jasmine test framework.
* [node](https://www.npmjs.com/package/@types/node) for code that references objects in the *Node.js®* environment;
you can view an example in the [webpack](guide/webpack) page.
QuickStart doesn't require these typings but many of the samples do.

View File

@ -1,801 +0,0 @@
# Webpack: An Introduction
<style>
h4 {font-size: 17px !important; text-transform: none !important;}
.syntax { font-family: Consolas, 'Lucida Sans', Courier, sans-serif; color: black; font-size: 85%; }
</style>
[**Webpack**](https://webpack.github.io/) is a popular module bundler,
a tool for bundling application source code in convenient _chunks_
and for loading that code from a server into a browser.
It's an excellent alternative to the *SystemJS* approach used elsewhere in the documentation.
This guide offers a taste of Webpack and explains how to use it with Angular applications.
{@a top}
<!--
# Contents
* [What is Webpack?](guide/webpack#what-is-webpack)
* [Entries and outputs](guide/webpack#entries-outputs)
* [Multiple bundles](guide/webpack#multiple-bundles)
* [Loaders](guide/webpack#loaders)
* [Plugins](guide/webpack#plugins)
* [Configuring Webpack](guide/webpack#configure-webpack)
* [Polyfills](guide/webpack#polyfills)
* [Common configuration](guide/webpack#common-configuration)
* [Inside `webpack.common.js`](guide/webpack#inside-webpack-commonjs)
* [entry](guide/webpack#common-entries)
* [resolve extension-less imports](guide/webpack#common-resolves)
* [`module.rules`](guide/webpack#common-rules)
* [Plugins](guide/webpack#plugins)
* [`CommonsChunkPlugin`](guide/webpack#commons-chunk-plugin)
* [`HtmlWebpackPlugin`](guide/webpack#html-webpack-plugin)
* [Environment specific configuration](guide/webpack#environment-configuration)
* [Development configuration](guide/webpack#development-configuration)
* [Production configuration](guide/webpack#production-configuration)
* [Test configuration](guide/webpack#test-configuration)
* [Trying it out](guide/webpack#try)
* [Highlights](guide/webpack#highlights)
* [Conclusion](guide/webpack#conclusion)
-->
You can also <a href="generated/zips/webpack/webpack.zip" target="_blank">download the final result.</a>
{@a what-is-webpack}
## What is Webpack?
Webpack is a powerful module bundler.
A _bundle_ is a JavaScript file that incorporates _assets_ that *belong* together and
should be served to the client in a response to a single file request.
A bundle can include JavaScript, CSS styles, HTML, and almost any other kind of file.
Webpack roams over your application source code,
looking for `import` statements, building a dependency graph, and emitting one or more _bundles_.
With plugins and rules, Webpack can preprocess and minify different non-JavaScript files such as TypeScript, SASS, and LESS files.
You determine what Webpack does and how it does it with a JavaScript configuration file, `webpack.config.js`.
{@a entries-outputs}
### Entries and outputs
You supply Webpack with one or more *entry* files and let it find and incorporate the dependencies that radiate from those entries.
The one entry point file in this example is the application's root file, `src/main.ts`:
<code-example path="webpack/config/webpack.common.js" region="one-entry" title="webpack.config.js (single entry)" linenums="false">
</code-example>
Webpack inspects that file and traverses its `import` dependencies recursively.
<code-example path="webpack/src/app/app.component.ts" region="component" title="src/main.ts" linenums="false">
</code-example>
It sees that you're importing `@angular/core` so it adds that to its dependency list for potential inclusion in the bundle.
It opens the `@angular/core` file and follows _its_ network of `import` statements until it has built the complete dependency graph from `main.ts` down.
Then it **outputs** these files to the `app.js` _bundle file_ designated in configuration:
<code-example name="webpack.config.js (single output)" language="javascript">
output: {
filename: 'app.js'
}
</code-example>
This `app.js` output bundle is a single JavaScript file that contains the application source and its dependencies.
You'll load it later with a `<script>` tag in the `index.html`.
{@a multiple-bundles}
#### Multiple bundles
You probably don't want one giant bundle of everything.
It's preferable to separate the volatile application app code from comparatively stable vendor code modules.
Change the configuration so that it has two entry points, `main.ts` and `vendor.ts`:
<code-example language="javascript">
entry: {
app: 'src/app.ts',
vendor: 'src/vendor.ts'
},
output: {
filename: '[name].js'
}
</code-example>
Webpack constructs two separate dependency graphs
and emits *two* bundle files, one called `app.js` containing only the application code and
another called `vendor.js` with all the vendor dependencies.
<div class="l-sub-section">
The `[name]` in the output name is a *placeholder* that a Webpack plugin replaces with the entry names,
`app` and `vendor`. Plugins are [covered later](guide/webpack#commons-chunk-plugin) in the guide.
</div>
To tell Webpack what belongs in the vendor bundle,
add a `vendor.ts` file that only imports the application's third-party modules:
<code-example path="webpack/src/vendor.ts" title="src/vendor.ts" linenums="false">
</code-example>
{@a loaders}
### Loaders
Webpack can bundle any kind of file: JavaScript, TypeScript, CSS, SASS, LESS, images, HTML, fonts, whatever.
Webpack _itself_ only understands JavaScript files.
Teach it to transform non-JavaScript file into their JavaScript equivalents with *loaders*.
Configure loaders for TypeScript and CSS as follows.
<code-example language="javascript">
rules: [
{
test: /\.ts$/,
loader: 'awesome-typescript-loader'
},
{
test: /\.css$/,
loaders: 'style-loader!css-loader'
}
]
</code-example>
When Webpack encounters `import` statements like the following,
it applies the `test` RegEx patterns.
<code-example language="typescript">
import { AppComponent } from './app.component.ts';
import 'uiframework/dist/uiframework.css';
</code-example>
When a pattern matches the filename, Webpack processes the file with the associated loader.
The first `import` file matches the `.ts` pattern so Webpack processes it with the `awesome-typescript-loader`.
The imported file doesn't match the second pattern so its loader is ignored.
The second `import` matches the second `.css` pattern for which you have *two* loaders chained by the (!) character.
Webpack applies chained loaders *right to left*. So it applies
the `css` loader first to flatten CSS `@import` and `url(...)` statements.
Then it applies the `style` loader to append the css inside `<style>` elements on the page.
{@a plugins}
### Plugins
Webpack has a build pipeline with well-defined phases.
Tap into that pipeline with plugins such as the `uglify` minification plugin:
<code-example language="javascript">
plugins: [
new webpack.optimize.UglifyJsPlugin()
]
</code-example>
{@a configure-webpack}
## Configuring Webpack
After that brief orientation, you are ready to build your own Webpack configuration for Angular apps.
Begin by setting up the development environment.
Create a new project folder.
<code-example language="sh" class="code-shell">
mkdir angular-webpack
cd angular-webpack
</code-example>
Add these files:
<code-tabs>
<code-pane title="package.json" path="webpack/package.webpack.json">
</code-pane>
<code-pane title="src/tsconfig.json" path="webpack/src/tsconfig.1.json">
</code-pane>
<code-pane title="webpack.config.js" path="webpack/webpack.config.js">
</code-pane>
<code-pane title="karma.conf.js" path="webpack/karma.webpack.conf.js">
</code-pane>
<code-pane title="config/helpers.js" path="webpack/config/helpers.js">
</code-pane>
</code-tabs>
<div class="l-sub-section">
Many of these files should be familiar from other Angular documentation guides,
especially the [Typescript configuration](guide/typescript-configuration) and
[npm packages](guide/npm-packages) guides.
Webpack, the plugins, and the loaders are also installed as packages.
They are listed in the updated `packages.json`.
</div>
Open a terminal window and install the npm packages.
<code-example language="sh" class="code-shell">
npm install
</code-example>
{@a polyfills}
### Polyfills
You'll need polyfills to run an Angular application in most browsers as explained
in the [Browser Support](guide/browser-support) guide.
Polyfills should be bundled separately from the application and vendor bundles.
Add a `polyfills.ts` like this one to the `src/` folder.
<code-example path="webpack/src/polyfills.ts" title="src/polyfills.ts" linenums="false">
</code-example>
<div class="callout is-critical">
<header>
Loading polyfills
</header>
Load `zone.js` early within `polyfills.ts`, immediately after the other ES6 and metadata shims.
</div>
Because this bundle file will load first, `polyfills.ts` is also a good place to configure the browser environment
for production or development.
{@a common-configuration}
### Common configuration
Developers typically have separate configurations for development, production, and test environments.
All three have a lot of configuration in common.
Gather the common configuration in a file called `webpack.common.js`.
<code-example path="webpack/config/webpack.common.js" title="config/webpack.common.js" linenums="false">
</code-example>
{@a inside-webpack-commonjs}
### Inside _webpack.common.js_
Webpack is a NodeJS-based tool that reads configuration from a JavaScript commonjs module file.
The configuration imports dependencies with `require` statements
and exports several objects as properties of a `module.exports` object.
* [`entry`](guide/webpack#common-entries)&mdash;the entry-point files that define the bundles.
* [`resolve`](guide/webpack#common-resolves)&mdash;how to resolve file names when they lack extensions.
* [`module.rules`](guide/webpack#common-rules)&mdash; `module` is an object with `rules` for deciding how files are loaded.
* [`plugins`](guide/webpack#common-plugins)&mdash;creates instances of the plugins.
{@a common-entries}
#### _entry_
The first export is the `entry` object:
<code-example path="webpack/config/webpack.common.js" region="entries" title="config/webpack.common.js" linenums="false">
</code-example>
This `entry` object defines the three bundles:
* `polyfills`&mdash;the polyfills needed to run Angular applications in most modern browsers.
* `vendor`&mdash;the third-party dependencies such as Angular, lodash, and bootstrap.css.
* `app`&mdash;the application code.
{@a common-resolves}
#### _resolve_ extension-less imports
The app will `import` dozens if not hundreds of JavaScript and TypeScript files.
You could write `import` statements with explicit extensions like this example:
<code-example language="typescript">
import { AppComponent } from './app.component.ts';
</code-example>
But most `import` statements don't mention the extension at all.
Tell Webpack to resolve extension-less file requests by looking for matching files with
`.ts` extension or `.js` extension (for regular JavaScript files and pre-compiled TypeScript files).
<code-example path="webpack/config/webpack.common.js" region="resolve" title="config/webpack.common.js" linenums="false">
</code-example>
<div class="l-sub-section">
If Webpack should resolve extension-less files for styles and HTML,
add `.css` and `.html` to the list.
</div>
{@a common-rules}
#### _module.rules_
Rules tell Webpack which loaders to use for each file, or module:
<code-example path="webpack/config/webpack.common.js" region="loaders" title="config/webpack.common.js" linenums="false">
</code-example>
* `awesome-typescript-loader`&mdash;a loader to transpile the Typescript code to ES5, guided by the `tsconfig.json` file.
* `angular2-template-loader`&mdash;loads angular components' template and styles.
* `html-loader`&mdash;for component templates.
* images/fonts&mdash;Images and fonts are bundled as well.
* CSS&mdash;the first pattern matches application-wide styles; the second handles
component-scoped styles (the ones specified in a component's `styleUrls` metadata property).
<div class="l-sub-section">
The first pattern is for the application-wide styles. It excludes `.css` files within the `src/app` directory
where the component-scoped styles sit. The `ExtractTextPlugin` (described below) applies the `style` and `css`
loaders to these files.
The second pattern filters for component-scoped styles and loads them as strings via the `raw-loader`,
which is what Angular expects to do with styles specified in a `styleUrls` metadata property.
</div>
<div class="l-sub-section">
Multiple loaders can be chained using the array notation.
</div>
{@a common-plugins}
#### _plugins_
Finally, create instances of three plugins:
<code-example path="webpack/config/webpack.common.js" region="plugins" title="config/webpack.common.js" linenums="false">
</code-example>
{@a commons-chunk-plugin}
#### *CommonsChunkPlugin*
The `app.js` bundle should contain only application code. All vendor code belongs in the `vendor.js` bundle.
Of course the application code imports vendor code.
On its own, Webpack is not smart enough to keep the vendor code out of the `app.js` bundle.
The `CommonsChunkPlugin` does that job.
<div class="l-sub-section">
The `CommonsChunkPlugin` identifies the hierarchy among three _chunks_: `app` -> `vendor` -> `polyfills`.
Where Webpack finds that `app` has shared dependencies with `vendor`, it removes them from `app`.
It would remove `polyfills` from `vendor` if they shared dependencies, which they don't.
</div>
{@a html-webpack-plugin}
#### _HtmlWebpackPlugin_
Webpack generates a number of js and CSS files.
You _could_ insert them into the `index.html` _manually_. That would be tedious and error-prone.
Webpack can inject those scripts and links for you with the `HtmlWebpackPlugin`.
{@a environment-configuration}
### Environment-specific configuration
The `webpack.common.js` configuration file does most of the heavy lifting.
Create separate, environment-specific configuration files that build on `webpack.common`
by merging into it the peculiarities particular to the target environments.
These files tend to be short and simple.
{@a development-configuration}
### Development configuration
Here is the `webpack.dev.js` development configuration file.
<code-example path="webpack/config/webpack.dev.js" title="config/webpack.dev.js" linenums="false">
</code-example>
The development build relies on the Webpack development server, configured near the bottom of the file.
Although you tell Webpack to put output bundles in the `dist` folder,
the dev server keeps all bundles in memory; it doesn't write them to disk.
You won't find any files in the `dist` folder, at least not any generated from *this development build*.
The `HtmlWebpackPlugin`, added in `webpack.common.js`, uses the `publicPath` and the `filename` settings to generate
appropriate `<script>` and `<link>` tags into the `index.html`.
The CSS styles are buried inside the Javascript bundles by default. The `ExtractTextPlugin` extracts them into
external `.css` files that the `HtmlWebpackPlugin` inscribes as `<link>` tags into the `index.html`.
Refer to the [Webpack documentation](https://webpack.github.io/docs/) for details on these and
other configuration options in this file.
Grab the app code at the end of this guide and try:
<code-example language="sh" class="code-shell">
npm start
</code-example>
{@a production-configuration}
### Production configuration
Configuration of a *production* build resembles *development* configuration with a few key changes.
<code-example path="webpack/config/webpack.prod.js" title="config/webpack.prod.js" linenums="false">
</code-example>
You'll deploy the application and its dependencies to a real production server.
You won't deploy the artifacts needed only in development.
Put the production output bundle files in the `dist` folder.
Webpack generates file names with cache-busting hash.
Thanks to the `HtmlWebpackPlugin`, you don't have to update the `index.html` file when the hash changes.
There are additional plugins:
* *`NoEmitOnErrorsPlugin`&mdash;stops the build if there is an error.
* *`UglifyJsPlugin`&mdash;minifies the bundles.
* *`ExtractTextPlugin`&mdash;extracts embedded css as external files, adding cache-busting hash to the filename.
* *`DefinePlugin`&mdash;use to define environment variables that you can reference within the application.
* *`LoaderOptionsPlugins`&mdash;to override options of certain loaders.
Thanks to the `DefinePlugin` and the `ENV` variable defined at top, you can enable Angular production mode like this:
<code-example path="webpack/src/main.ts" region="enable-prod" title="src/main.ts" linenums="false">
</code-example>
Grab the app code at the end of this guide and try:
<code-example language="sh" class="code-shell">
npm run build
</code-example>
{@a test-configuration}
### Test configuration
You don't need much configuration to run unit tests.
You don't need the loaders and plugins that you declared for your development and production builds.
You probably don't need to load and process the application-wide styles files for unit tests and doing so would slow you down;
you'll use the `null` loader for those CSS files.
You could merge the test configuration into the `webpack.common` configuration and override the parts you don't want or need.
But it might be simpler to start over with a completely fresh configuration.
<code-example path="webpack/config/webpack.test.js" title="config/webpack.test.js" linenums="false">
</code-example>
Reconfigure [Karma](https://karma-runner.github.io/1.0/index.html) to use Webpack to run the tests:
<code-example path="webpack/config/karma.conf.js" title="config/karma.conf.js" linenums="false">
</code-example>
You don't precompile the TypeScript; Webpack transpiles the Typescript files on the fly, in memory, and feeds the emitted JS directly to Karma.
There are no temporary files on disk.
The `karma-test-shim` tells Karma what files to pre-load and
primes the Angular test framework with test versions of the providers that every app expects to be pre-loaded.
<code-example path="webpack/config/karma-test-shim.js" title="config/karma-test-shim.js" linenums="false">
</code-example>
Notice that you do _not_ load the application code explicitly.
You tell Webpack to find and load the test files (the files ending in `.spec.ts`).
Each spec file imports all&mdash;and only&mdash;the application source code that it tests.
Webpack loads just _those_ specific application files and ignores the other files that you aren't testing.
Grab the app code at the end of this guide and try:
<code-example language="sh" class="code-shell">
npm test
</code-example>
{@a try}
## Trying it out
Here is the source code for a small application that bundles with the
Webpack techniques covered in this guide.
<code-tabs>
<code-pane title="src/index.html" path="webpack/src/index.html">
</code-pane>
<code-pane title="src/main.ts" path="webpack/src/main.ts">
</code-pane>
<code-pane title="src/assets/css/styles.css" path="webpack/src/assets/css/styles.css">
</code-pane>
</code-tabs>
<code-tabs>
<code-pane title="src/app/app.component.ts" path="webpack/src/app/app.component.ts">
</code-pane>
<code-pane title="src/app/app.component.html" path="webpack/src/app/app.component.html">
</code-pane>
<code-pane title="src/app/app.component.css" path="webpack/src/app/app.component.css">
</code-pane>
<code-pane title="src/app/app.component.spec.ts" path="webpack/src/app/app.component.spec.ts">
</code-pane>
<code-pane title="src/app/app.module.ts" path="webpack/src/app/app.module.ts">
</code-pane>
</code-tabs>
The <code>app.component.html</code> displays this downloadable Angular logo
<a href="assets/images/logos/angular/angular.png">
<img src="assets/images/logos/angular/angular.png" height="40px" title="download Angular logo"></a>.
Create a folder called `images` under the project's `assets` folder, then right-click (Cmd+click on Mac)
on the image and download it to that folder.
{@a bundle-ts}
Here again are the TypeScript entry-point files that define the `polyfills` and `vendor` bundles.
<code-tabs>
<code-pane title="src/polyfills.ts" path="webpack/src/polyfills.ts">
</code-pane>
<code-pane title="src/vendor.ts" path="webpack/src/vendor.ts">
</code-pane>
</code-tabs>
{@a highlights}
<h3 class="no-toc">Highlights</h3>
* There are no `<script>` or `<link>` tags in the `index.html`.
The `HtmlWebpackPlugin` inserts them dynamically at runtime.
* The `AppComponent` in `app.component.ts` imports the application-wide css with a simple `import` statement.
* The `AppComponent` itself has its own html template and css file. WebPack loads them with calls to `require()`.
Webpack stashes those component-scoped files in the `app.js` bundle too.
You don't see those calls in the source code;
they're added behind the scenes by the `angular2-template-loader` plug-in.
* The `vendor.ts` consists of vendor dependency `import` statements that drive the `vendor.js` bundle.
The application imports these modules too; they'd be duplicated in the `app.js` bundle
if the `CommonsChunkPlugin` hadn't detected the overlap and removed them from `app.js`.
{@a conclusion}
## Conclusion
You've learned just enough Webpack to configurate development, test and production builds
for a small Angular application.
_You could always do more_. Search the web for expert advice and expand your Webpack knowledge.
[Back to top](guide/webpack#top)

View File

@ -12,5 +12,19 @@
"message": "Watch ng-conf live stream <br/>Apr 18th-20th, 2018",
"imageUrl": "generated/images/marketing/home/ng-conf.png",
"linkUrl": "https://www.ng-conf.org/livestream/"
},
{
"startDate": "2018-06-01",
"endDate": "2018-08-15",
"message": "Join us for Angular Mix<br/>October 10th-12th, 2018",
"imageUrl": "generated/images/marketing/home/angular-mix.png",
"linkUrl": "https://angularmix.com/"
},
{
"startDate": "2018-08-15",
"endDate": "2018-11-06",
"message": "Join us for Angular Connect<br/>November 6th-7th, 2018",
"imageUrl": "generated/images/marketing/home/angular-connect.png",
"linkUrl": "https://angularconnect.com/"
}
]

View File

@ -175,7 +175,13 @@
"rev": true,
"title": "Angular IDE by Webclipse",
"url": "https://www.genuitec.com/products/angular-ide"
}
},
"amexio-canvas": {
"desc": "Amexio Canvas is Drag and Drop Environment to create Fully Responsive Web and Smart Device HTML5/Angular Apps. Code will be auto generated and hot deployed by the Canvas for live testing. Out of the box 50+ Material Design Theme support. Commit your code to GitHub public or private repository.",
"rev": true,
"title": "Amexio Canvas Web Based Drag and Drop IDE by MetaMagic",
"url": "https://amexio.tech/"
}
}
},
"Tooling": {

View File

@ -61,12 +61,6 @@
"hidden": true
},
{
"url": "guide/webpack",
"title": "Webpack: An Introduction",
"hidden": true
},
{
"url": "guide/quickstart",
"title": "Getting Started",

View File

@ -112,7 +112,7 @@
"cross-spawn": "^5.1.0",
"css-selector-parser": "^1.3.0",
"dgeni": "^0.4.7",
"dgeni-packages": "^0.26.1",
"dgeni-packages": "^0.26.2",
"entities": "^1.1.1",
"eslint": "^3.19.0",
"eslint-plugin-jasmine": "^2.2.0",

View File

@ -82,31 +82,7 @@
};
</script>
<script>
if (window.document.documentMode) {
// polyfill IE11 in a blocking way
var s = document.createElement('script');
s.src = 'generated/ie-polyfills.min.js';
document.head.appendChild(s);
} else if (!Object.assign) {
// polyfill other non-evergreen browsers in a blocking way
var polyfillUrl = "https://cdn.polyfill.io/v2/polyfill.min.js?features=default,Array.prototype.find&flags=gated&unknown=polyfill";
// send a blocking XHR to fetch the polyfill
// then append it to the document so that its eval-ed synchronously
// this is required because the method used for IE is not reliable with other non-evergreen browsers
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function() {
var s = document.createElement('script');
s.type = 'text/javascript';
var code = this.responseText;
s.appendChild(document.createTextNode(code));
document.head.appendChild(s);
});
xhr.open("GET", polyfillUrl, false);
xhr.send();
}
</script>
<script nomodule src="generated/ie-polyfills.min.js"></script>
<script>
//load CE polyfill

View File

@ -1,79 +0,0 @@
.api-section {
position: relative;
pre {
white-space: pre-wrap;
}
table.api-table {
min-width: 680px;
thead th {
color: white;
font-size: 16px;
background-color: $blue;
border-radius: 4px 4px 0 0;
text-transform: none;
padding: 8px 24px;
}
tbody {
pre {
white-space: normal;
margin: 4px;
padding: 4px 16px;
}
td, th {
padding: 0;
}
th {
max-width: 150px;
}
}
}
}
.api-body {
max-width: 1200px;
table {
th {
text-transform: none;
font-size: 16px;
font-weight: bold;
}
tr {
border-bottom: 1px solid $lightgray;
}
td {
vertical-align: middle;
}
hr {
margin: 16px 0;
}
tr:last-child {
border-bottom: none;
}
&.item-table {
td {
padding: 32px;
}
}
&.list-table {
td {
padding: 16px 24px;
}
}
}
}

View File

@ -0,0 +1,41 @@
.api-body {
max-width: 1200px;
table {
th {
text-transform: none;
font-size: 16px;
font-weight: bold;
}
tr {
border-bottom: 1px solid $lightgray;
}
td {
vertical-align: middle;
}
hr {
margin: 16px 0;
}
tr:last-child {
border-bottom: none;
}
&.item-table {
td {
padding: 32px;
}
}
&.list-table {
td {
padding: 16px 24px;
}
}
}
}

View File

@ -2,7 +2,7 @@
LAYOUT STYLES
============================== */
@import 'api-page';
@import 'api-pages';
@import 'content-layout';
@import 'doc-viewer';
@import 'footer';

View File

@ -280,6 +280,7 @@ p {
.code-anchor {
cursor: pointer;
text-decoration: none;
font-size: inherit;
&:hover {
text-decoration: underline;

View File

@ -1,4 +1,4 @@
.page-actions {
.github-links {
float: right;
.material-icons {
border-radius: 4px;
@ -30,10 +30,30 @@
}
}
.method-table {
.method-table, .option-table {
th {
display: flex;
align-items: center;
h3 {
flex: 1;
}
.github-links {
a {
color: $mediumgray;
.material-icons:hover {
background: none;
color: $blue;
}
}
}
}
h3 {
margin: 6px 0;
font-weight: bold;
clear: left;
}
h4 {
@ -87,10 +107,6 @@
}
}
.api-section aio-code {
background-color: rgba(241, 241, 241, 0.2);
}
.from-constructor, .read-only-property {
font-style: italic;
color: $blue;

View File

@ -25,7 +25,7 @@ The zipper will use this information for creating new zips.
## Three kinds of examples
The majority of examples in AIO use `System.js` but there are also `CLI` and `Webpack` projects. This
The majority of examples in AIO use `CLI`, with some additionally using `Webpack` and upgrade usiing `SystemJS`. This
tool is able to differentiate between them.
The boilerplate uses a `package.json` that contains packages and scripts to run any kind of example.
@ -44,7 +44,6 @@ Here you find a:
* **base.json** - All the common scripts and packages
* **cli.json** - Extra scripts and packages for the CLI
* **webpack.json** - Extra scripts and packages for Webpack
* **universal.json** - Extra scripts and packages for universal
* **i18n.json** - Extra scripts and packages for i18n
* **systemjs.json** - All the System.js related packages but it also contains the remainder scripts
@ -68,11 +67,11 @@ In both `stackblitz.json` and `zipper.json` you can use two extra properties for
{
...
"removeSystemJsConfig": true,
"type": "webpack"
"type": "testing"
}
```
This would generate a zip for a webpack application and it will also remove everything related with
This would generate a zip for a testing application and it will also remove everything related with
SystemJS.
## Executing the zip generation

View File

@ -1,26 +0,0 @@
{
"scripts": [
{ "name": "start:webpack", "rename": "start" },
{ "name": "test:webpack", "rename": "test" },
{ "name": "build:webpack", "rename": "build" }
],
"dependencies": [],
"devDependencies": [
"angular2-template-loader",
"awesome-typescript-loader",
"css-loader",
"extract-text-webpack-plugin",
"file-loader",
"html-loader",
"html-webpack-plugin",
"karma-sourcemap-loader",
"karma-webpack",
"null-loader",
"raw-loader",
"rimraf",
"style-loader",
"webpack",
"webpack-dev-server",
"webpack-merge"
]
}

View File

@ -113,7 +113,6 @@ class ExampleZipper {
'!**/package.json',
'!**/example-config.json',
'!**/wallaby.js',
'!**/package.webpack.json',
// AoT related files
'!**/aot/**/*.*',
'!**/*-aot.*'

View File

@ -18,7 +18,6 @@ const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
const IGNORED_EXAMPLES = [ // temporary ignores
'quickstart',
'setup',
'webpack',
'upgrade-p'
];

View File

@ -26,13 +26,7 @@
"serve:cli": "http-server dist/",
"build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup-config.js",
"serve:aot": "lite-server -c bs-config.aot.json",
"start:webpack": "webpack-dev-server --inline --progress --port 8080",
"test:webpack": "karma start karma.webpack.conf.js",
"build:webpack": "rimraf dist && webpack --config config/webpack.prod.js --bail",
"build:babel": "babel src -d src --extensions \".es6\" --source-maps",
"build:uni-client": "webpack --config webpack.config.client.js",
"build:uni": "webpack --config webpack.config.universal.js",
"serve:uni": "node dist/server.js",
"clean": "rimraf src/dist && rimraf src/app/*.js* && rimraf src/universal/*.js* && rimraf src/main.js*",
"copy-dist-files": "node ./copy-dist-files.js",

View File

@ -58,12 +58,6 @@
"@types/node": "^6.0.45",
"canonical-path": "0.0.2",
"concurrently": "^3.0.0",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "2.0.0-beta.5",
"file-loader": "^0.9.0",
"html-loader": "^0.4.3",
"html-webpack-plugin": "^2.16.1",
"http-server": "^0.9.0",
"jasmine-core": "~2.99.1",
"jasmine-marbles": "^0.3.1",
@ -74,7 +68,6 @@
"karma-jasmine": "~1.1.1",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.2",
"karma-sourcemap-loader": "^0.3.7",
"lite-server": "^2.2.2",
"lodash": "^4.16.2",
"phantomjs-prebuilt": "^2.1.7",
@ -85,7 +78,6 @@
"rollup-plugin-node-resolve": "2.0.0",
"rollup-plugin-uglify": "^1.0.1",
"source-map-explorer": "^1.3.2",
"ts-loader": "^4.2.0",
"ts-node": "^5.0.1",
"tslint": "^5.9.1",
"typescript": "2.7.2",

File diff suppressed because it is too large Load Diff

View File

@ -42,12 +42,19 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
return EXPORT_DOC_TYPES.concat(['decorator', 'directive', 'pipe', 'module']);
})
/**
* These are the doc types that are contained within other docs
*/
.factory(function API_CONTAINED_DOC_TYPES() {
return ['member', 'function-overload', 'get-accessor-info', 'set-accessor-info', 'parameter'];
})
/**
* These are the doc types that are API docs, including ones that will be merged into container docs,
* such as members and overloads.
*/
.factory(function API_DOC_TYPES(API_DOC_TYPES_TO_RENDER) {
return API_DOC_TYPES_TO_RENDER.concat(['member', 'function-overload']);
.factory(function API_DOC_TYPES(API_DOC_TYPES_TO_RENDER, API_CONTAINED_DOC_TYPES) {
return API_DOC_TYPES_TO_RENDER.concat(API_CONTAINED_DOC_TYPES);
})
// Where do we get the source files?
@ -112,8 +119,8 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
parseTagsProcessor.tagDefinitions.concat(getInjectables(requireFolder(__dirname, './tag-defs')));
})
.config(function(computeStability, splitDescription, addNotYetDocumentedProperty, EXPORT_DOC_TYPES, API_DOC_TYPES) {
computeStability.docTypes = EXPORT_DOC_TYPES;
.config(function(computeStability, splitDescription, addNotYetDocumentedProperty, API_DOC_TYPES_TO_RENDER, API_DOC_TYPES) {
computeStability.docTypes = API_DOC_TYPES_TO_RENDER;
// Only split the description on the API docs
splitDescription.docTypes = API_DOC_TYPES;
addNotYetDocumentedProperty.docTypes = API_DOC_TYPES;
@ -155,6 +162,16 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
});
})
.config(function(filterContainedDocs, API_CONTAINED_DOC_TYPES) {
filterContainedDocs.docTypes = API_CONTAINED_DOC_TYPES;
})
.config(function(checkContentRules, API_DOC_TYPES, API_CONTAINED_DOC_TYPES) {
addMinLengthRules(checkContentRules);
addHeadingRules(checkContentRules, API_DOC_TYPES);
addAllowedPropertiesRules(checkContentRules, API_CONTAINED_DOC_TYPES);
})
.config(function(computePathsProcessor, EXPORT_DOC_TYPES, generateApiListDoc) {
const API_SEGMENT = 'api';
@ -188,3 +205,45 @@ module.exports = new Package('angular-api', [basePackage, typeScriptPackage])
autoLinkCode.docTypes = API_DOC_TYPES;
autoLinkCode.codeElements = ['code', 'code-example', 'code-pane'];
});
function addMinLengthRules(checkContentRules) {
const createMinLengthRule = require('./content-rules/minLength');
const paramRuleSet = checkContentRules.docTypeRules['parameter'] = checkContentRules.docTypeRules['parameter'] || {};
const paramRules = paramRuleSet['name'] = paramRuleSet['name'] || [];
paramRules.push(createMinLengthRule());
}
function addHeadingRules(checkContentRules, API_DOC_TYPES) {
const createNoMarkdownHeadingsRule = require('./content-rules/noMarkdownHeadings');
const noMarkdownHeadings = createNoMarkdownHeadingsRule();
const allowOnlyLevel3Headings = createNoMarkdownHeadingsRule(1, 2, '4,');
API_DOC_TYPES.forEach(docType => {
let rules;
const ruleSet = checkContentRules.docTypeRules[docType] = checkContentRules.docTypeRules[docType] || {};
rules = ruleSet['description'] = ruleSet['description'] || [];
rules.push(noMarkdownHeadings);
rules = ruleSet['shortDescription'] = ruleSet['shortDescription'] || [];
rules.push(noMarkdownHeadings);
rules = ruleSet['usageNotes'] = ruleSet['usageNotes'] || [];
rules.push(allowOnlyLevel3Headings);
});
}
function addAllowedPropertiesRules(checkContentRules, API_CONTAINED_DOC_TYPES) {
API_CONTAINED_DOC_TYPES.forEach(docType => {
const ruleSet = checkContentRules.docTypeRules[docType] = checkContentRules.docTypeRules[docType] || {};
const rules = ruleSet['usageNotes'] = ruleSet['usageNotes'] || [];
rules.push((doc, prop, value) => value && !isMethod(doc) &&
`Invalid property: "${prop}" is not allowed on "${doc.docType}" docs.`);
});
}
function isMethod(doc) {
return doc.hasOwnProperty('parameters') && !doc.isGetAccessor && !doc.isSetAccessor;
}

View File

@ -1,16 +1,15 @@
module.exports = function computeApiBreadCrumbs(EXPORT_DOC_TYPES) {
module.exports = function computeApiBreadCrumbs(API_DOC_TYPES_TO_RENDER) {
return {
$runAfter: ['paths-computed'],
$runBefore: ['rendering-docs'],
$process(docs) {
// Compute the breadcrumb for each doc by processing its containers
docs.forEach(doc => {
if (EXPORT_DOC_TYPES.indexOf(doc.docType) !== -1) {
doc.breadCrumbs = [
{ text: 'API', path: '/api' },
{ text: '@angular/' + doc.moduleDoc.id, path: doc.moduleDoc.path },
{ text: doc.name, path: doc.path }
];
if (API_DOC_TYPES_TO_RENDER.indexOf(doc.docType) !== -1) {
doc.breadCrumbs = [];
doc.breadCrumbs.push({ text: 'API', path: '/api' });
if (doc.moduleDoc) doc.breadCrumbs.push({ text: '@angular/' + doc.moduleDoc.id, path: doc.moduleDoc.path });
doc.breadCrumbs.push({ text: doc.name, path: doc.path });
}
});
}

View File

@ -13,14 +13,15 @@ describe('angular-api-package: computeApiBreadCrumbs processor', () => {
expect(processor.$runBefore).toEqual(['rendering-docs']);
});
it('should attach a breadCrumbs property to each of the EXPORT_DOC_TYPES docs', () => {
const EXPORT_DOC_TYPES = ['class', 'interface'];
const processor = processorFactory(EXPORT_DOC_TYPES);
it('should attach a breadCrumbs property to each of the API_DOC_TYPES_TO_RENDER docs', () => {
const API_DOC_TYPES_TO_RENDER = ['class', 'interface', 'module'];
const processor = processorFactory(API_DOC_TYPES_TO_RENDER);
const docs = [
{ docType: 'class', name: 'ClassA', path: 'module-1/class-a', moduleDoc: { id: 'moduleOne', path: 'module-1' } },
{ docType: 'interface', name: 'InterfaceB', path: 'module-2/interface-b', moduleDoc: { id: 'moduleTwo', path: 'module-2' } },
{ docType: 'guide', name: 'Guide One', path: 'guide/guide-1' },
{ docType: 'module', name: 'testing', id: 'http/testing', path: 'http/testing' },
];
processor.$process(docs);
@ -35,5 +36,9 @@ describe('angular-api-package: computeApiBreadCrumbs processor', () => {
{ text: 'InterfaceB', path: 'module-2/interface-b' },
]);
expect(docs[2].breadCrumbs).toBeUndefined();
expect(docs[3].breadCrumbs).toEqual([
{ text: 'API', path: '/api' },
{ text: 'testing', path: 'http/testing' },
]);
});
});

View File

@ -5,7 +5,7 @@
module.exports = function filterContainedDocs() {
return {
docTypes: ['member', 'function-overload', 'get-accessor-info', 'set-accessor-info', 'parameter'],
$runAfter: ['extra-docs-added'],
$runAfter: ['extra-docs-added', 'checkContentRules'],
$runBefore: ['computing-paths'],
$process: function(docs) {
var docTypes = this.docTypes;

View File

@ -1,6 +1,6 @@
module.exports = function filterPrivateDocs() {
return {
$runAfter: ['extra-docs-added'],
$runAfter: ['extra-docs-added', 'checkContentRules'],
$runBefore: ['computing-paths'],
$process: function(docs) {
return docs.filter(function(doc) { return doc.privateExport !== true; });

View File

@ -18,7 +18,7 @@ describe('filterPrivateDocs processor', () => {
it('should run after the correct processor', () => {
const processor = processorFactory();
expect(processor.$runAfter).toEqual(['extra-docs-added']);
expect(processor.$runAfter).toEqual(['extra-docs-added', 'checkContentRules']);
});
it('should remove docs that are marked as private exports', () => {

View File

@ -1,7 +1,7 @@
module.exports = function generateApiListDoc() {
return {
$runAfter: ['extra-docs-added'],
$runAfter: ['extra-docs-added', 'computeStability'],
$runBefore: ['rendering-docs'],
outputFolder: null,
$validate: {outputFolder: {presence: true}},

View File

@ -13,7 +13,7 @@ describe('generateApiListDoc processor', () => {
it('should run after the correct processor', () => {
const processor = processorFactory();
expect(processor.$runAfter).toEqual(['extra-docs-added']);
expect(processor.$runAfter).toEqual(['extra-docs-added', 'computeStability']);
});
it('should run before the correct processor', () => {

View File

@ -48,64 +48,62 @@ const {mergeProperties} = require('../../helpers/utils');
module.exports = function mergeDecoratorDocs(log) {
return {
$runAfter: ['processing-docs'],
$runBefore: ['docs-processed'],
$runBefore: ['docs-processed', 'checkContentRules'],
propertiesToMerge: [],
makeDecoratorCalls: [
{type: '', description: 'toplevel', functionName: 'makeDecorator'},
{type: 'Prop', description: 'property', functionName: 'makePropDecorator'},
{type: 'Param', description: 'parameter', functionName: 'makeParamDecorator'},
],
$process: function(docs) {
$process(docs) {
var makeDecoratorCalls = this.makeDecoratorCalls;
var propertiesToMerge = this.propertiesToMerge;
var docsToMerge = Object.create(null);
const decoratorDocs = Object.create(null);
docs.forEach(function(doc) {
// find all the decorators, signified by a call to `make...Decorator<Decorator>(metadata)`
docs.forEach(doc => {
const initializer = getInitializer(doc);
if (initializer) {
makeDecoratorCalls.forEach(function(call) {
// find all the decorators, signified by a call to `make...Decorator<Decorator>(metadata)`
this.makeDecoratorCalls.forEach(function(call) {
if (initializer.expression && initializer.expression.text === call.functionName) {
log.debug('mergeDecoratorDocs: found decorator', doc.docType, doc.name);
doc.docType = 'decorator';
doc.decoratorLocation = call.description;
// Get the type of the decorator metadata from the first "type" argument of the call.
// For example the `X` of `createDecorator<X>(...)`.
doc.decoratorType = initializer.arguments[0].text;
// clear the symbol type named since it is not needed
doc.symbolTypeName = undefined;
const decoratorType = initializer.arguments[0].text;
// keep track of the names of the metadata interface that will need to be merged into this decorator doc
docsToMerge[doc.name + 'Decorator'] = doc;
log.debug('mergeDecoratorDocs: found decorator', doc.docType, doc.name, decoratorType);
doc.docType = 'decorator';
doc.decoratorLocation = call.description;
doc.decoratorType = decoratorType;
decoratorDocs[doc.name + 'Decorator'] = doc;
}
});
}
});
// merge the metadata docs into the decorator docs
docs = docs.filter(function(doc) {
if (docsToMerge[doc.name]) {
// merge the info from the associated metadata interfaces into the decorator docs
docs = docs.filter(doc => {
if (decoratorDocs[doc.name]) {
// We have found an `XxxDecorator` document that will hold the call signature of the decorator
var decoratorDoc = docsToMerge[doc.name];
var callMember = doc.members.filter(function(member) { return member.isCallMember; })[0];
var decoratorDoc = decoratorDocs[doc.name];
var callMember = doc.members.find(member => member.isCallMember);
log.debug(
'mergeDecoratorDocs: merging', doc.name, 'into', decoratorDoc.name,
callMember.description.substring(0, 50));
// Merge the documentation found in this call signature into the original decorator
mergeProperties(decoratorDoc, callMember, propertiesToMerge);
mergeProperties(decoratorDoc, callMember, this.propertiesToMerge);
// remove doc from its module doc's exports
doc.moduleDoc.exports =
doc.moduleDoc.exports.filter(function(exportDoc) { return exportDoc !== doc; });
// remove from the overall list of docs to be rendered
return false;
doc.moduleDoc.exports = doc.moduleDoc.exports.filter(exportDoc => exportDoc !== doc);
}
return true;
return !decoratorDocs[doc.name];
});
return docs;
}
};
};

View File

@ -1,4 +1,5 @@
// A ts2dart compiler annotation that can be ignored in API docs.
// A ts2dart compiler annotation that we don't care about for API docs.
// But, if we don't have a tag-def for it the doc-gen will error.
module.exports = function() {
return {name: 'Annotation', ignore: true};
return {name: 'Annotation'};
};

View File

@ -65,7 +65,9 @@ module.exports = function autoLinkCode(getDocFromAlias) {
};
}
function foundValidDoc(docs) {
return docs.length === 1 && autoLinkCodeImpl.docTypes.indexOf(docs[0].docType) !== -1;
return docs.length === 1 &&
!docs[0].internal &&
autoLinkCodeImpl.docTypes.indexOf(docs[0].docType) !== -1;
}
function createLinkNode(doc, text) {

View File

@ -79,6 +79,13 @@ describe('autoLinkCode post-processor', () => {
'</code>');
});
it('should ignore code items that match an internal API doc', () => {
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass', internal: true });
const doc = { docType: 'test-doc', renderedContent: '<code>MyClass</code>' };
processor.$process([doc]);
expect(doc.renderedContent).toEqual('<code>MyClass</code>');
});
it('should insert anchors for individual text nodes within a code block', () => {
aliasMap.addDoc({ docType: 'class', id: 'MyClass', aliases: ['MyClass'], path: 'a/b/myclass' });
const doc = { docType: 'test-doc', renderedContent: '<code><span>MyClass</span><span>MyClass</span></code>' };

View File

@ -32,7 +32,7 @@ module.exports = function checkContentRules(log, createDocMessage) {
docTypeRules: {},
failOnContentErrors: false,
$runAfter: ['tags-extracted'],
$runBefore: ['processing-docs'],
$runBefore: [],
$process(docs) {
const logMessage = this.failOnContentErrors ? log.error.bind(log) : log.warn.bind(log);
const errors = [];

View File

@ -18,7 +18,7 @@ describe('checkContentRules processor', function() {
it('shpuld run at the right time', () => {
expect(processor.$runAfter).toEqual(['tags-extracted']);
expect(processor.$runBefore).toEqual(['processing-docs']);
expect(processor.$runBefore).toEqual([]);
});
it('should do nothing if not configured', () => {

View File

@ -9,7 +9,7 @@ describe('hasValues filter', () => {
it('should return true if the specified property is truthy on any item in the list', function() {
expect(filter.process([], 'a')).toEqual(false);
expect(filter.process(0), 'a').toEqual(false);
expect(filter.process(0, 'a')).toEqual(false);
expect(filter.process({}, 'a')).toEqual(false);
expect(filter.process([{a: 1}], 'a')).toEqual(true);
expect(filter.process([{b: 2}], 'a')).toEqual(false);

View File

@ -8,16 +8,20 @@ module.exports =
.factory(require('./services/getAliases'))
.factory(require('./services/getDocFromAlias'))
.factory(require('./services/getLinkInfo'))
.factory(require('./services/disambiguators/disambiguateByContainer'))
.factory(require('./services/disambiguators/disambiguateByDeprecated'))
.factory(require('./services/disambiguators/disambiguateByModule'))
.factory(require('./services/disambiguators/disambiguateByNonMember'))
.config(function(inlineTagProcessor, linkInlineTagDef) {
inlineTagProcessor.inlineTagDefinitions.push(linkInlineTagDef);
})
.config(function(getDocFromAlias, disambiguateByDeprecated, disambiguateByModule) {
.config(function(getDocFromAlias, disambiguateByContainer, disambiguateByDeprecated, disambiguateByModule, disambiguateByNonMember) {
getDocFromAlias.disambiguators = [
disambiguateByContainer,
disambiguateByDeprecated,
disambiguateByModule
disambiguateByModule,
disambiguateByNonMember,
];
});

View File

@ -14,7 +14,6 @@ var INLINE_LINK = /(\S+)(?:\s+([\s\S]+))?/;
module.exports = function linkInlineTagDef(getLinkInfo, createDocMessage, log) {
return {
name: 'link',
aliases: ['linkDocs'],
failOnBadLink: false,
description:
'Process inline link tags (of the form {@link some/uri Some Title}), replacing them with HTML anchors',

View File

@ -19,7 +19,6 @@ describe('link inline-tag-def', function() {
it('should be available as a service', () => {
expect(tag).toBeDefined();
expect(tag.name).toEqual('link');
expect(tag.aliases).toEqual(['linkDocs']);
});
it('should call getLinkInfo', () => {

View File

@ -0,0 +1,19 @@
/**
* This link disambiguator looks for matching docs that have a common container with the
* originatingDoc and will return just those.
*/
module.exports = function disambiguateByContainer() {
return _disambiguate;
};
function _disambiguate(alias, originatingDoc, docs) {
if (originatingDoc) {
const filteredDocs = docs.filter(doc => doc.containerDoc === originatingDoc);
if (filteredDocs.length === 0) {
// No docs match so let's look at the containers container
return _disambiguate(alias, originatingDoc.containerDoc, docs);
}
return filteredDocs;
}
return docs;
}

View File

@ -0,0 +1,34 @@
const disambiguateByContainer = require('./disambiguateByContainer')();
const containerA = { name: 'a' };
const containerB = { name: 'b' };
const docs = [
{ id: 'doc1', containerDoc: containerA },
{ id: 'doc2', containerDoc: containerA },
{ id: 'doc3', containerDoc: containerB },
];
describe('disambiguateByContainer', () => {
it('should return all docs if the originating doc has no containerDoc', () => {
expect(disambiguateByContainer('alias', { }, docs)).toEqual(docs);
});
it('should return all docs if no docs match the originating doc containerDoc', () => {
expect(disambiguateByContainer('alias', { containerDoc: { name: 'c' } }, docs)).toEqual(docs);
});
it('should return only docs that are contained by the originating doc or its containers', () => {
expect(disambiguateByContainer('alias', containerB, docs)).toEqual([
{ id: 'doc3', containerDoc: containerB },
]);
expect(disambiguateByContainer('alias', { containerDoc: containerA }, docs)).toEqual([
{ id: 'doc1', containerDoc: containerA },
{ id: 'doc2', containerDoc: containerA },
]);
expect(disambiguateByContainer('alias', { containerDoc: containerB }, docs)).toEqual([
{ id: 'doc3', containerDoc: containerB },
]);
});
});

View File

@ -0,0 +1,14 @@
/**
* This link disambiguator will remove all the members from the list of ambiguous links
* if there is at least one link to a doc that is not a member.
*
* The heuristic is that exports are more important than members when linking, and that
* in general members will be linked to via a more explicit code links such as
* `MyClass.member` rather than simply `member`.
*/
module.exports = function disambiguateByNonMember() {
return (alias, originatingDoc, docs) => {
const filteredDocs = docs.filter(doc => doc.docType !== 'member');
return filteredDocs.length > 0 ? filteredDocs : docs;
};
};

View File

@ -0,0 +1,23 @@
const disambiguateByNonMember = require('./disambiguateByNonMember')();
const doc1 = { id: 'doc1', docType: 'function', containerDoc: {} };
const doc2 = { id: 'doc2', docType: 'member', containerDoc: {} };
const doc3 = { id: 'doc3', docType: 'member', containerDoc: {} };
const doc4 = { id: 'doc4', docType: 'class', containerDoc: {} };
const doc5 = { id: 'doc5', docType: 'member', containerDoc: {} };
describe('disambiguateByNonMember', () => {
it('should filter out docs that are not members', () => {
const docs = [doc1, doc2, doc3, doc4, doc5];
expect(disambiguateByNonMember('alias', {}, docs)).toEqual([doc1, doc4]);
});
it('should return all docs if there are no members', () => {
const docs = [doc1, doc4];
expect(disambiguateByNonMember('alias', {}, docs)).toEqual([doc1, doc4]);
});
it('should return all docs if there are only members', () => {
const docs = [doc2, doc3, doc5];
expect(disambiguateByNonMember('alias', {}, docs)).toEqual([doc2, doc3, doc5]);
});
});

View File

@ -5,5 +5,5 @@ var Package = require('dgeni').Package;
* @description Overrides the renderMarkdown service with an implementation based on remark
*/
module.exports = new Package('remark', ['nunjucks'])
.factory(require('./services/markedNunjucksFilter'))
.factory(require('./services/renderMarkdown'));

View File

@ -0,0 +1,12 @@
/**
* Convert the value, as markdown, into HTML
* @param headingMappings A map of headings to convert (e.g. from h3 to h4).
*/
module.exports = function markedNunjucksFilter(renderMarkdown) {
return {
name: 'marked',
process: function(str, headingMappings) {
return str && renderMarkdown(str, headingMappings);
}
};
};

View File

@ -0,0 +1,31 @@
const visit = require('unist-util-visit');
function headingToLevel(heading) {
const match = /^h(\d+)/.exec(heading);
return match ? match[1] : '0';
}
function parseMappings(mappings) {
const mapping = {};
Object.keys(mappings).forEach(key => mapping[headingToLevel(key)] = headingToLevel(mappings[key]));
return mapping;
}
module.exports = function mapHeadings(mappings) {
const headings = parseMappings(mappings || {});
return () => ast => {
const nodesToFix = [];
Object.keys(headings).forEach(heading => {
visit(ast, 'heading', node => {
if (node.depth === Number(heading)) {
nodesToFix.push(node);
}
});
});
// Update the depth of the matched nodes
nodesToFix.forEach(node => node.depth = headings[node.depth]);
return ast;
};
};

View File

@ -1,25 +1,29 @@
const remark = require('remark');
const html = require('remark-html');
const code = require('./handlers/code');
const mapHeadings = require('./plugins/mapHeadings');
/**
* @dgService renderMarkdown
* @description
* Render the markdown in the given string as HTML.
* @param headingMap A map of headings to convert.
* E.g. `{h3: 'h4'} will map heading 3 level into heading 4.
*/
module.exports = function renderMarkdown() {
const handlers = { code };
const renderer = remark()
.use(inlineTagDefs)
.use(noIndentedCodeBlocks)
.use(plainHTMLBlocks)
// USEFUL DEBUGGING CODE
// .use(() => tree => {
// console.log(require('util').inspect(tree, { colors: true, depth: 4 }));
// })
.use(html, { handlers });
return function renderMarkdownImpl(content, headingMap) {
const renderer = remark()
.use(inlineTagDefs)
.use(noIndentedCodeBlocks)
.use(plainHTMLBlocks)
// USEFUL DEBUGGING CODE
// .use(() => tree => {
// console.log(require('util').inspect(tree, { colors: true, depth: 4 }));
// })
.use(mapHeadings(headingMap))
.use(html, { handlers: { code } });
return function renderMarkdownImpl(content) {
return renderer.processSync(content).toString();
};

View File

@ -95,4 +95,36 @@ describe('remark: renderMarkdown service', () => {
'</code-example>\n'
);
});
it('should map heading levels as specified', () => {
const content =
'# heading 1\n' +
'\n' +
'some paragraph\n' +
'\n' +
'## heading 2a\n' +
'\n' +
'some paragraph\n' +
'\n' +
'### heading 3\n' +
'\n' +
'some paragraph\n' +
'\n' +
'## heading 2b\n' +
'\n' +
'some paragraph\n' +
'\n';
const headingMappings = { h2: 'h3', h3: 'h5' };
const output = renderMarkdown(content, headingMappings);
expect(output).toEqual(
'<h1>heading 1</h1>\n' +
'<p>some paragraph</p>\n' +
'<h3>heading 2a</h3>\n' +
'<p>some paragraph</p>\n' +
'<h5>heading 3</h5>\n' +
'<p>some paragraph</p>\n' +
'<h3>heading 2b</h3>\n' +
'<p>some paragraph</p>\n'
);
});
});

View File

@ -2,10 +2,7 @@
{% set comma = joiner(',') %}
{% set slash = joiner('/') %}
<article>
<div class="page-actions">
<a href="{$ github.githubEditHref(doc, versionInfo) $}" aria-label="Suggest Edits" title="Suggest Edits"><i class="material-icons" aria-hidden="true" role="img">mode_edit</i></a>
<a href="{$ github.githubViewHref(doc, versionInfo) $}" aria-label="View Source" title="View Source"><i class="material-icons" aria-hidden="true" role="img">code</i></a>
</div>
{$ github.githubLinks(doc, versionInfo) $}
<div class="breadcrumb">
<script type="application/ld+json">
{

View File

@ -9,15 +9,15 @@
{% block details %}
{% block additional %}{% endblock %}
{% include "includes/description.html" %}
{$ memberHelpers.renderProperties(doc.staticProperties, 'static-properties', 'static-property', 'Static Properties') $}
{$ memberHelpers.renderMethodDetails(doc.staticMethods, 'static-methods', 'static-method', 'Static Methods') $}
{$ memberHelpers.renderProperties(doc.staticProperties, 'static-properties', 'static-property', 'Static properties') $}
{$ memberHelpers.renderMethodDetails(versionInfo, doc.staticMethods, 'static-methods', 'static-method', 'Static methods') $}
{% if doc.constructorDoc %}
<h2>Constructor</h2>
{$ memberHelpers.renderMethodDetail(doc.constructorDoc, 'constructor') $}{% endif %}
{$ memberHelpers.renderMethodDetail(versionInfo, doc.constructorDoc, 'constructor') $}{% endif %}
{$ memberHelpers.renderProperties(doc.properties, 'instance-properties', 'instance-property', 'Properties') $}
{$ memberHelpers.renderMethodDetails(doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
{$ memberHelpers.renderMethodDetails(versionInfo, doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
{% block annotations %}{% include "includes/annotations.html" %}{% endblock %}
{% endblock %}

View File

@ -1,9 +1,47 @@
{% import "lib/githubLinks.html" as github -%}
{% import "lib/memberHelpers.html" as memberHelper -%}
{% import "lib/paramList.html" as params -%}
{% extends 'export-base.template.html' %}
{% block overview %}{% include "includes/decorator-overview.html" %}{% endblock %}
{% block details %}
{% include "includes/description.html" %}
{$ memberHelper.renderProperties(doc.members, 'metadata-members', 'metadata-member', 'Options') $}
{% include "includes/description.html" %}
<section class="decorator-options">
<h2>Options</h2>
{% for option in doc.members %}
<a id="{$ option.anchor $}"></a>
<table class="is-full-width option-table">
<thead><tr><th>
<h3>{$ option.name $}</h3>
{$ github.githubLinks(option, versionInfo) $}
</th></tr></thead>
<tbody>
<tr>
<td>
{% if option.shortDescription %}{$ option.shortDescription | marked $}{% endif %}
</td>
</tr>
<tr>
<td>
<code-example language="ts" hideCopy="true" class="no-box api-heading">
{$ option.name $}: {$ option.type | escape $}
</code-example>
</td>
</tr>
<tr>
<td>
{%- if option.description %}
{$ option.description | marked({ h3: 'h4' }) $}
{% endif %}
{%- if option.usageNotes %}
{$ option.usageNotes | marked({ h3: 'h4' }) $}
{% endif %}
</td>
</tr>
</tbody>
</table>
{% endfor %}
</section>
{% endblock %}

View File

@ -1,10 +1,33 @@
{% import "lib/memberHelpers.html" as memberHelper -%}
{% import "lib/descendants.html" as descendants -%}
{% macro renderOptionsTable(doc) %}
<table class="is-full-width list-table option-overview">
<thead>
<tr><th>Option</th><th>Description</th></tr>
</thead>
<tbody>
{%- for option in doc.members %}
<tr class="option">
<td>
<a class="code-anchor" href="{$ doc.path $}#{$ option.anchor | urlencode $}">
<code>{$ option.name $}</code>
</a>
</td>
<td>{$ option.shortDescription | marked $}</td>
</tr>
{% endfor -%}
</tbody>
</table>
{% for ancestor in doc.extendsClauses %}{% if ancestor.doc %}
<h3 class="no-toc">Inherited from <a class="code-anchor" href="{$ ancestor.doc.path $}">{$ ancestor.doc.name $}</a> decorator</h3>
{$ renderOptionsTable(ancestor.doc) $}
{% endif %}{% endfor %}
{% endmacro %}
{% if doc.members.length %}
<section class="decorator-overview">
<code-example language="ts" hideCopy="true">
@{$ doc.name $}{$ doc.typeParams | escape $}({ {$ memberHelper.renderMembers(doc) $}
})
</code-example>
{$ renderOptionsTable(doc) $}
{$ descendants.renderDescendants(doc, 'decorator', 'Subclasses') $}
</section>
{% endif %}
{% endif %}

View File

@ -1,6 +1,6 @@
{% if doc.deprecated %}
<section class="deprecated">
<h2>Deprecation Notes</h2>
<h2>Deprecation notes</h2>
{$ doc.deprecated | marked $}
</section>
{% endif %}

View File

@ -1,6 +1,6 @@
{% if doc.members.length %}
<section class="meta-data">
<h2>Metadata Properties</h2>
<h2>Metadata properties</h2>
{% for metadata in doc.members %}{% if not metadata.internal %}
<div class="metadata-member">
<a name="{$ metadata.name $}" class="anchor-offset"></a>

View File

@ -11,7 +11,7 @@
{%- endfor %} }}</code-example>
{% if doc.valueParam.type %}
<h2>Input Value</h2>
<h2>Input value</h2>
{$ params.renderParameters([doc.valueParam], 'pipe-parameters', 'pipe-parameter', true) $}
{% endif %}
{% if doc.pipeParams.length %}

View File

@ -1,6 +1,6 @@
{% if doc.security %}
<section "security">
<h2>Security Risk</h2>
<h2>Security risk</h2>
{$ doc.security | marked $}
</section>
{% endif %}

View File

@ -1,6 +1,6 @@
{%- if doc.see.length %}
<section class="see-also">
<h2>See Also</h2>
<h2>See also</h2>
<ul>
{% for see in doc.see %}
<li>{$ see | marked $}</li>{% endfor %}

View File

@ -1,6 +1,6 @@
{% if doc.usageNotes %}
<section class="usage-notes">
<h2>Usage Notes</h2>
<h2>Usage notes</h2>
{$ doc.usageNotes | marked $}
</section>
{% endif %}

View File

@ -7,5 +7,5 @@
{% block details %}
{% include "includes/description.html" %}
{$ memberHelper.renderProperties(doc.properties, 'instance-properties', 'instance-property', 'Properties') $}
{$ memberHelper.renderMethodDetails(doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
{$ memberHelper.renderMethodDetails(versionInfo, doc.methods, 'instance-methods', 'instance-method', 'Methods') $}
{% endblock %}

View File

@ -1,6 +1,6 @@
{% macro githubViewHref(doc, versionInfo) -%}
https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInfo.repo $}/tree/{$ versionInfo.currentVersion.isSnapshot and versionInfo.currentVersion.SHA or versionInfo.currentVersion.raw $}/packages/{$ doc.fileInfo.realProjectRelativePath $}#L{$ doc.startingLine + 1 $}-L{$ doc.endingLine + 1 $}
{%- endmacro %}
{%- endmacro -%}
{% macro githubEditHref(doc, versionInfo) -%}
@ -9,4 +9,11 @@ https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInf
{%- elseif doc.docType === 'module' %}{$ doc.id.split('/')[0] $}
{%- else %}...{%- endif -%}
)%3A%20describe%20your%20change...#L{$ doc.startingLine + 1 $}-L{$ doc.endingLine + 1 $}
{%- endmacro %}
{%- endmacro -%}
{% macro githubLinks(doc, versionInfo) -%}
<div class="github-links">
<a href="{$ githubEditHref(doc, versionInfo) $}" aria-label="Suggest Edits" title="Suggest Edits"><i class="material-icons" aria-hidden="true" role="img">mode_edit</i></a>
<a href="{$ githubViewHref(doc, versionInfo) $}" aria-label="View Source" title="View Source"><i class="material-icons" aria-hidden="true" role="img">code</i></a>
</div>
{%- endmacro -%}

View File

@ -1,3 +1,4 @@
{% import "lib/githubLinks.html" as github -%}
{% import "lib/paramList.html" as params -%}
{%- macro renderHeritage(exportDoc) -%}
@ -69,15 +70,18 @@
{%- endif %}
{%- endmacro -%}
{%- macro renderMethodDetail(method, cssClass) -%}
{%- macro renderMethodDetail(versionInfo, method, cssClass) -%}
<a id="{$ method.anchor $}"></a>
<table class="is-full-width method-table {$ cssClass $}">
{% if method.name !== 'constructor' %}<thead><tr><th><h3>
{% if method.isCallMember %}<i>call signature</i>
{% elseif method.isNewMember %}<i>construct signature</i>
{% else %}{$ method.name $}()
{% endif %}
</h3></th></tr></thead>{% endif %}
{% if method.name !== 'constructor' %}<thead><tr><th>
<h3>
{% if method.isCallMember %}<i>call signature</i>
{% elseif method.isNewMember %}<i>construct signature</i>
{% else %}{$ method.name $}()
{% endif %}
</h3>
{$ github.githubLinks(method, versionInfo) $}
</th></tr></thead>{% endif %}
<tbody>
{% if method.shortDescription %}<tr>
<td class="short-description">
@ -113,22 +117,33 @@
</td>
</tr>
{% endif %}
{% if method.description %}<tr>
{% if method.description -%}
<tr>
<td class="description">
{$ method.description | marked $}
{$ method.description | marked({ h3: 'h4' }) $}
</td>
</tr>{% endif %}
</tbody>
</tr>
{%- endif %}
{% if method.usageNotes -%}
<tr>
<td class="usage-notes">
{$ method.usageNotes | marked({ h3: 'h4' }) $}
</td>
</tr>
{%- endif %}
</tbody>
</table>
{% endmacro -%}
{%- macro renderMethodDetails(methods, containerClass, itemClass, headingText) -%}
{%- macro renderMethodDetails(versionInfo, methods, containerClass, itemClass, headingText) -%}
{% set nonInternalMethods = methods | filterByPropertyValue('internal', undefined) %}
{% if nonInternalMethods.length %}
<section class="{$ containerClass $}">
<h2>{$ headingText $}</h2>
{% for member in nonInternalMethods %}
{$ renderMethodDetail(member, itemClass) $}
{$ renderMethodDetail(versionInfo, member, itemClass) $}
{% endfor %}
</section>
{% endif %}
@ -141,7 +156,7 @@
{% if nonInternalProperties.length -%}
<section class="{$ containerClass $}">
<h2>{$ headingText $}</h2>
<table class="is-full-width list-table properties-table">
<table class="is-full-width list-table property-table">
<thead>
<tr>
<th>{$ headings[0] or 'Property' $}</th>

View File

@ -3086,9 +3086,9 @@ devtools-timeline-model@1.1.6:
chrome-devtools-frontend "1.0.401423"
resolve "1.1.7"
dgeni-packages@^0.26.1:
version "0.26.1"
resolved "https://registry.yarnpkg.com/dgeni-packages/-/dgeni-packages-0.26.1.tgz#34b5ed880be2f91862095b15085c50cc84507aa8"
dgeni-packages@^0.26.2:
version "0.26.2"
resolved "https://registry.yarnpkg.com/dgeni-packages/-/dgeni-packages-0.26.2.tgz#dac22d7e861d4d72ed42af5272714f42b6b5bf3d"
dependencies:
canonical-path "0.0.2"
catharsis "^0.8.1"

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