docs(\$compile): add docs for ngProp and ngOn bindings

The docs are written as if ngProp and ngOn were regular directives,
which makes them easier to find.

Closes #16627
This commit is contained in:
Martin Staffa
2018-08-03 12:17:03 +02:00
committed by GitHub
parent dedb10c0b8
commit af3b71ef46
2 changed files with 320 additions and 1 deletions
+319
View File
@@ -1044,6 +1044,325 @@
*
*/
/**
* @ngdoc directive
* @name ngProp
* @restrict A
* @element ANY
*
* @usage
*
* ```html
* <ANY ng-prop-propname="expression">
* </ANY>
* ```
*
* or with uppercase letters in property (e.g. "propName"):
*
*
* ```html
* <ANY ng-prop-prop_name="expression">
* </ANY>
* ```
*
*
* @description
* The `ngProp` directive binds an expression to a DOM element property.
* `ngProp` allows writing to arbitrary properties by including
* the property name in the attribute, e.g. `ng-prop-value="'my value'"` binds 'my value' to
* the `value` property.
*
* Usually, it's not necessary to write to properties in AngularJS, as the built-in directives
* handle the most common use cases (instead of the above example, you would use {@link ngValue}).
*
* However, [custom elements](https://developer.mozilla.org/docs/Web/Web_Components/Using_custom_elements)
* often use custom properties to hold data, and `ngProp` can be used to provide input to these
* custom elements.
*
* ## Binding to camelCase properties
*
* Since HTML attributes are case-insensitive, camelCase properties like `innerHTML` must be escaped.
* AngularJS uses the underscore (_) in front of a character to indicate that it is uppercase, so
* `innerHTML` must be written as `ng-prop-inner_h_t_m_l="expression"` (Note that this is just an
* example, and for binding HTML {@link ngBindHtml} should be used.
*
* ## Security
*
* Binding expressions to arbitrary properties poses a security risk, as properties like `innerHTML`
* can insert potentially dangerous HTML into the application, e.g. script tags that execute
* malicious code.
* For this reason, `ngProp` applies Strict Contextual Escaping with the {@link ng.$sce $sce service}.
* This means vulnerable properties require their content to be "trusted", based on the
* context of the property. For example, the `innerHTML` is in the `HTML` context, and the
* `iframe.src` property is in the `RESOURCE_URL` context, which requires that values written to
* this property are trusted as a `RESOURCE_URL`.
*
* This can be set explicitly by calling $sce.trustAs(type, value) on the value that is
* trusted before passing it to the `ng-prop-*` directive. There are exist shorthand methods for
* each context type in the form of {@link ng.$sce#trustAsResourceUrl $sce.trustAsResourceUrl()} et al.
*
* In some cases you can also rely upon automatic sanitization of untrusted values - see below.
*
* Based on the context, other options may exist to mark a value as trusted / configure the behavior
* of {@link ng.$sce}. For example, to restrict the `RESOURCE_URL` context to specific origins, use
* the {@link $sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist()}
* and {@link $sceDelegateProvider#resourceUrlBlacklist resourceUrlBlacklist()}.
*
* {@link ng.$sce#what-trusted-context-types-are-supported- Find out more about the different context types}.
*
* ### HTML Sanitization
*
* By default, `$sce` will throw an error if it detects untrusted HTML content, and will not bind the
* content.
* However, if you include the {@link ngSanitize ngSanitize module}, it will try to sanitize the
* potentially dangerous HTML, e.g. strip non-whitelisted tags and attributes when binding to
* `innerHTML`.
*
* @example
* ### Binding to different contexts
*
* <example name="ngProp" module="exampleNgProp">
* <file name="app.js">
* angular.module('exampleNgProp', [])
* .component('main', {
* templateUrl: 'main.html',
* controller: function($sce) {
* this.safeContent = '<strong>Safe content</strong>';
* this.unsafeContent = '<button onclick="alert(\'Hello XSS!\')">Click for XSS</button>';
* this.trustedUnsafeContent = $sce.trustAsHtml(this.unsafeContent);
* }
* });
* </file>
* <file name="main.html">
* <div>
* <div class="prop-unit">
* Binding to a property without security context:
* <div class="prop-binding" ng-prop-inner_text="$ctrl.safeContent"></div>
* <span class="prop-note">innerText</span> (safeContent)
* </div>
*
* <div class="prop-unit">
* "Safe" content that requires a security context will throw because the contents could potentially be dangerous ...
* <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.safeContent"></div>
* <span class="prop-note">innerHTML</span> (safeContent)
* </div>
*
* <div class="prop-unit">
* ... so that actually dangerous content cannot be executed:
* <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.unsafeContent"></div>
* <span class="prop-note">innerHTML</span> (unsafeContent)
* </div>
*
* <div class="prop-unit">
* ... but unsafe Content that has been trusted explicitly works - only do this if you are 100% sure!
* <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.trustedUnsafeContent"></div>
* <span class="prop-note">innerHTML</span> (trustedUnsafeContent)
* </div>
* </div>
* </file>
* <file name="index.html">
* <main></main>
* </file>
* <file name="styles.css">
* .prop-unit {
* margin-bottom: 10px;
* }
*
* .prop-binding {
* min-height: 30px;
* border: 1px solid blue;
* }
*
* .prop-note {
* font-family: Monospace;
* }
* </file>
* </example>
*
*
* @example
* ### Binding to innerHTML with ngSanitize
*
* <example name="ngProp" module="exampleNgProp" deps="angular-sanitize.js">
* <file name="app.js">
* angular.module('exampleNgProp', ['ngSanitize'])
* .component('main', {
* templateUrl: 'main.html',
* controller: function($sce) {
* this.safeContent = '<strong>Safe content</strong>';
* this.unsafeContent = '<button onclick="alert(\'Hello XSS!\')">Click for XSS</button>';
* this.trustedUnsafeContent = $sce.trustAsHtml(this.unsafeContent);
* }
* });
* </file>
* <file name="main.html">
* <div>
* <div class="prop-unit">
* "Safe" content will be sanitized ...
* <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.safeContent"></div>
* <span class="prop-note">innerHTML</span> (safeContent)
* </div>
*
* <div class="prop-unit">
* ... as will dangerous content:
* <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.unsafeContent"></div>
* <span class="prop-note">innerHTML</span> (unsafeContent)
* </div>
*
* <div class="prop-unit">
* ... and content that has been trusted explicitly works the same as without ngSanitize:
* <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.trustedUnsafeContent"></div>
* <span class="prop-note">innerHTML</span> (trustedUnsafeContent)
* </div>
* </div>
* </file>
* <file name="index.html">
* <main></main>
* </file>
* <file name="styles.css">
* .prop-unit {
* margin-bottom: 10px;
* }
*
* .prop-binding {
* min-height: 30px;
* border: 1px solid blue;
* }
*
* .prop-note {
* font-family: Monospace;
* }
* </file>
* </example>
*
*/
/** @ngdoc directive
* @name ngOn
* @restrict A
* @element ANY
*
* @usage
*
* ```html
* <ANY ng-on-eventname="expression">
* </ANY>
* ```
*
* or with uppercase letters in property (e.g. "eventName"):
*
*
* ```html
* <ANY ng-on-event_name="expression">
* </ANY>
* ```
*
* @description
* The `ngOn` directive adds an event listener to a DOM element via
* {@link angular.element angular.element().on()}, and evaluates an expression when the event is
* fired.
* `ngOn` allows adding listeners for arbitrary events by including
* the event name in the attribute, e.g. `ng-on-drop="onDrop()"` executes the 'onDrop()' expression
* when the `drop` event is fired.
*
* AngularJS provides specific directives for many events, such as {@link ngClick}, so in most
* cases it is not necessary to use `ngOn`. However, AngularJS does not support all events
* (e.g. the `drop` event in the example above), and new events might be introduced in later DOM
* standards.
*
* Another use-case for `ngOn` is listening to
* [custom events](https://developer.mozilla.org/docs/Web/Guide/Events/Creating_and_triggering_events)
* fired by
* [custom elements](https://developer.mozilla.org/docs/Web/Web_Components/Using_custom_elements).
*
* ## Binding to camelCase properties
*
* Since HTML attributes are case-insensitive, camelCase properties like `myEvent` must be escaped.
* AngularJS uses the underscore (_) in front of a character to indicate that it is uppercase, so
* `myEvent` must be written as `ng-on-my_event="expression"`.
*
* @example
* ### Bind to built-in DOM events
*
* <example name="ngOn" module="exampleNgOn">
* <file name="app.js">
* angular.module('exampleNgOn', [])
* .component('main', {
* templateUrl: 'main.html',
* controller: function() {
* this.clickCount = 0;
* this.mouseoverCount = 0;
*
* this.loadingState = 0;
* }
* });
* </file>
* <file name="main.html">
* <div>
* This is equivalent to `ngClick` and `ngMouseover`:<br>
* <button
* ng-on-click="$ctrl.clickCount = $ctrl.clickCount + 1"
* ng-on-mouseover="$ctrl.mouseoverCount = $ctrl.mouseoverCount + 1">Click or mouseover</button><br>
* clickCount: {{$ctrl.clickCount}}<br>
* mouseover: {{$ctrl.mouseoverCount}}
*
* <hr>
*
* For the `error` and `load` event on images no built-in AngularJS directives exist:<br>
* <img src="thisimagedoesnotexist.png" ng-on-error="$ctrl.loadingState = -1" ng-on-load="$ctrl.loadingState = 1"><br>
* <div ng-switch="$ctrl.loadingState">
* <span ng-switch-when="0">Image is loading</span>
* <span ng-switch-when="-1">Image load error</span>
* <span ng-switch-when="1">Image loaded successfully</span>
* </div>
* </div>
* </file>
* <file name="index.html">
* <main></main>
* </file>
* </example>
*
*
* @example
* ### Bind to custom DOM events
*
* <example name="ngOnCustom" module="exampleNgOn">
* <file name="app.js">
* angular.module('exampleNgOn', [])
* .component('main', {
* templateUrl: 'main.html',
* controller: function() {
* this.eventLog = '';
*
* this.listener = function($event) {
* this.eventLog = 'Event with type "' + $event.type + '" fired at ' + $event.detail;
* };
* }
* })
* .component('childComponent', {
* templateUrl: 'child.html',
* controller: function($element) {
* this.fireEvent = function() {
* var event = new CustomEvent('customtype', { detail: new Date()});
*
* $element[0].dispatchEvent(event);
* };
* }
* });
* </file>
* <file name="main.html">
* <child-component ng-on-customtype="$ctrl.listener($event)"></child-component><br>
* <span>Event log: {{$ctrl.eventLog}}</span>
* </file>
* <file name="child.html">
<button ng-click="$ctrl.fireEvent()">Fire custom event</button>
* </file>
* <file name="index.html">
* <main></main>
* </file>
* </example>
*/
var $compileMinErr = minErr('$compile');
function UNINITIALIZED_VALUE() {}
+1 -1
View File
@@ -623,7 +623,7 @@ function $SceDelegateProvider() {
* | `$sce.CSS` | For CSS that's safe to source into the application. Currently unused. Feel free to use it in your own directives. |
* | `$sce.MEDIA_URL` | For URLs that are safe to render as media. Is automatically converted from string by sanitizing when needed. |
* | `$sce.URL` | For URLs that are safe to follow as links. Is automatically converted from string by sanitizing when needed. Note that `$sce.URL` makes a stronger statement about the URL than `$sce.MEDIA_URL` does and therefore contexts requiring values trusted for `$sce.URL` can be used anywhere that values trusted for `$sce.MEDIA_URL` are required.|
* | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contents are also safe to include in your application. Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG` (e.g. `IFRAME`, `OBJECT`, etc.) <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` or `$sce.MEDIA_URL` do and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` or `$sce.MEDIA_URL` are required. |
* | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contents are also safe to include in your application. Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG` (e.g. `IFRAME`, `OBJECT`, etc.) <br><br>Note that `$sce.RESOURCE_URL` makes a stronger statement about the URL than `$sce.URL` or `$sce.MEDIA_URL` do and therefore contexts requiring values trusted for `$sce.RESOURCE_URL` can be used anywhere that values trusted for `$sce.URL` or `$sce.MEDIA_URL` are required. <br><br> The {@link $sceDelegateProvider#resourceUrlWhitelist $sceDelegateProvider#resourceUrlWhitelist()} and {@link $sceDelegateProvider#resourceUrlBlacklist $sceDelegateProvider#resourceUrlBlacklist()} can be used to restrict trusted origins for `RESOURCE_URL` |
* | `$sce.JS` | For JavaScript that is safe to execute in your application's context. Currently unused. Feel free to use it in your own directives. |
*
*