diff --git a/aio/src/styles/2-modules/api-pages/_api-pages.scss b/aio/src/styles/2-modules/api-pages/_api-pages.scss
index 70c09237a2a..d96617e72c1 100644
--- a/aio/src/styles/2-modules/api-pages/_api-pages.scss
+++ b/aio/src/styles/2-modules/api-pages/_api-pages.scss
@@ -97,7 +97,6 @@
.github-links {
a {
-
.material-icons:hover {
background: none;
}
@@ -167,6 +166,10 @@
margin-top: 8px;
}
+ .final-message {
+ font-style: italic;
+ }
+
.api-heading {
@include mixins.font-size(14);
margin: 16px;
diff --git a/aio/src/styles/2-modules/label/_label-theme.scss b/aio/src/styles/2-modules/label/_label-theme.scss
index 1b26c97f42b..cb1c95ca85e 100644
--- a/aio/src/styles/2-modules/label/_label-theme.scss
+++ b/aio/src/styles/2-modules/label/_label-theme.scss
@@ -8,9 +8,17 @@
&.api-status-label {
background-color: constants.$mediumgray;
- &.deprecated, &.security, &.impure-pipe {
+ &.deprecated,
+ &.security,
+ &.impure-pipe {
background-color: constants.$brightred;
}
+
+ a {
+ color: inherit;
+ line-height: inherit;
+ font-size: inherit;
+ }
}
&.api-type-label {
diff --git a/aio/tools/transforms/angular-api-package/tag-defs/extensible.js b/aio/tools/transforms/angular-api-package/tag-defs/extensible.js
new file mode 100644
index 00000000000..a5d6c517165
--- /dev/null
+++ b/aio/tools/transforms/angular-api-package/tag-defs/extensible.js
@@ -0,0 +1,11 @@
+/**
+ * Use this tag to indicate that this class can be extended.
+ *
+ * This is the opposite of the Java `sealed` keyword.
+ */
+module.exports = function() {
+ return {
+ name: 'extensible',
+ transforms: function() { return true; }
+ };
+};
diff --git a/aio/tools/transforms/templates/api/base.template.html b/aio/tools/transforms/templates/api/base.template.html
index 19e7e0bd865..b99d9dcfa56 100644
--- a/aio/tools/transforms/templates/api/base.template.html
+++ b/aio/tools/transforms/templates/api/base.template.html
@@ -26,6 +26,9 @@
{% if doc.deprecated !== undefined %}{% endif %}
{% if doc.security !== undefined %}{% endif %}
{% if doc.pipeOptions.pure === 'false' %}{% endif %}
+ {% if doc.docType === 'class' and doc.extensible !== true and not doc.isAbstract %}{% endif %}
{% endblock %}
diff --git a/aio/tools/transforms/templates/api/class.template.html b/aio/tools/transforms/templates/api/class.template.html
index 5c22b539790..6fecb65a349 100644
--- a/aio/tools/transforms/templates/api/class.template.html
+++ b/aio/tools/transforms/templates/api/class.template.html
@@ -1,6 +1,5 @@
{% import "lib/ngmodule.html" as ngModuleHelpers -%}
{% extends 'export-base.template.html' -%}
-
{% block overview %}
{% include "includes/class-overview.html" %}
{% endblock %}
diff --git a/aio/tools/transforms/templates/api/lib/memberHelpers.html b/aio/tools/transforms/templates/api/lib/memberHelpers.html
index 0f0d3896ab4..e65208ccc5e 100644
--- a/aio/tools/transforms/templates/api/lib/memberHelpers.html
+++ b/aio/tools/transforms/templates/api/lib/memberHelpers.html
@@ -95,6 +95,14 @@
{% if method.shortDescription %}
{$ method.shortDescription | marked $}
+
+ {% if method.containerDoc.docType === 'class' and method.name === 'constructor' and not method.containerDoc.isAbstract and method.containerDoc.extensible !== true %}
+
+ This class is "final" and should not be extended.
+ See the public API notes.
+
+ {% endif %}
+
{%- if method.see.length %}
See also:
diff --git a/aio/tools/transforms/templates/lib/githubLinks.html b/aio/tools/transforms/templates/lib/githubLinks.html
index 35d575ab4e9..7a9e4fe518c 100644
--- a/aio/tools/transforms/templates/lib/githubLinks.html
+++ b/aio/tools/transforms/templates/lib/githubLinks.html
@@ -2,17 +2,23 @@
{$ fileInfo.realProjectRelativePath if fileInfo.realProjectRelativePath else fileInfo.projectRelativePath $}
{%- endmacro %}
-{% macro githubViewHref(doc, versionInfo) -%}
-{% set githubUrl = 'https://github.com/' + versionInfo.gitRepoInfo.owner + '/' + versionInfo.gitRepoInfo.repo -%}
+{% macro githubBaseUrl(versionInfo) -%}
+https://github.com/{$ versionInfo.gitRepoInfo.owner $}/{$ versionInfo.gitRepoInfo.repo $}
+{%- endmacro %}
+
+{% macro githubVersionedUrl(versionInfo) -%}
{% set version = versionInfo.currentVersion.isSnapshot and versionInfo.currentVersion.SHA or versionInfo.currentVersion.raw -%}
+{$ githubBaseUrl(versionInfo) $}/tree/{$ version $}
+{%- endmacro %}
+
+{% macro githubViewHref(doc, versionInfo) -%}
{% set lineInfo = doc.startingLine and ('#L' + (doc.startingLine + 1) + '-L' + (doc.endingLine + 1)) or '' -%}
-{$ githubUrl $}/tree/{$ version $}/{$ projectRelativePath(doc.fileInfo) $}{$ lineInfo $}
+{$ githubVersionedUrl(versionInfo) $}/{$ projectRelativePath(doc.fileInfo) $}{$ lineInfo $}
{%- endmacro %}
{% macro githubEditHref(doc, versionInfo, pathPrefix) -%}
-{% set githubUrl = 'https://github.com/' + versionInfo.gitRepoInfo.owner + '/' + versionInfo.gitRepoInfo.repo -%}
{% set lineInfo = doc.startingLine and ('#L' + (doc.startingLine + 1) + '-L' + (doc.endingLine + 1)) or '' -%}
-{$ githubUrl $}/edit/master/{$ projectRelativePath(doc.fileInfo) $}?message=docs
+{$ githubBaseUrl(versionInfo) $}/edit/master/{$ projectRelativePath(doc.fileInfo) $}?message=docs
{%- if doc.moduleDoc %}({$ doc.moduleDoc.id.split('/')[0] $})
{%- elseif doc.docType === 'module' %}({$ doc.id.split('/')[0] $})
{%- elseif doc.docType === 'content' %}
diff --git a/docs/PUBLIC_API.md b/docs/PUBLIC_API.md
index d4f96a44d0e..52fb194d0a6 100644
--- a/docs/PUBLIC_API.md
+++ b/docs/PUBLIC_API.md
@@ -41,6 +41,14 @@ We explicitly don't consider the following to be our public API surface:
Our peer dependencies (such as TypeScript, Zone.js, or RxJS) are not considered part of our API surface, but they are included in our SemVer policies. We might update the required version of any of these dependencies in minor releases if the update doesn't cause breaking changes for Angular applications. Peer dependency updates that result in non-trivial breaking changes must be deferred to major Angular releases.
+
+
+## Extending Angular classes
+
+All classes in Angular's public API are `final` (they should not be extended) unless explicitly stated in the API documentation.
+
+Extending such `final` classes is not supported, since protected members and internal implementation may change outside of major releases.
+
## Golden files