diff --git a/src/ng/compile.js b/src/ng/compile.js index e259cb3efcbe..b7652cf084f8 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -1044,6 +1044,325 @@ * */ +/** + * @ngdoc directive + * @name ngProp + * @restrict A + * @element ANY + * + * @usage + * + * ```html + * + * + * ``` + * + * or with uppercase letters in property (e.g. "propName"): + * + * + * ```html + * + * + * ``` + * + * + * @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 + * + * + * + * angular.module('exampleNgProp', []) + * .component('main', { + * templateUrl: 'main.html', + * controller: function($sce) { + * this.safeContent = 'Safe content'; + * this.unsafeContent = ''; + * this.trustedUnsafeContent = $sce.trustAsHtml(this.unsafeContent); + * } + * }); + * + * + *
+ *
+ * Binding to a property without security context: + *
+ * innerText (safeContent) + *
+ * + *
+ * "Safe" content that requires a security context will throw because the contents could potentially be dangerous ... + *
+ * innerHTML (safeContent) + *
+ * + *
+ * ... so that actually dangerous content cannot be executed: + *
+ * innerHTML (unsafeContent) + *
+ * + *
+ * ... but unsafe Content that has been trusted explicitly works - only do this if you are 100% sure! + *
+ * innerHTML (trustedUnsafeContent) + *
+ *
+ *
+ * + *
+ *
+ * + * .prop-unit { + * margin-bottom: 10px; + * } + * + * .prop-binding { + * min-height: 30px; + * border: 1px solid blue; + * } + * + * .prop-note { + * font-family: Monospace; + * } + * + *
+ * + * + * @example + * ### Binding to innerHTML with ngSanitize + * + * + * + * angular.module('exampleNgProp', ['ngSanitize']) + * .component('main', { + * templateUrl: 'main.html', + * controller: function($sce) { + * this.safeContent = 'Safe content'; + * this.unsafeContent = ''; + * this.trustedUnsafeContent = $sce.trustAsHtml(this.unsafeContent); + * } + * }); + * + * + *
+ *
+ * "Safe" content will be sanitized ... + *
+ * innerHTML (safeContent) + *
+ * + *
+ * ... as will dangerous content: + *
+ * innerHTML (unsafeContent) + *
+ * + *
+ * ... and content that has been trusted explicitly works the same as without ngSanitize: + *
+ * innerHTML (trustedUnsafeContent) + *
+ *
+ *
+ * + *
+ *
+ * + * .prop-unit { + * margin-bottom: 10px; + * } + * + * .prop-binding { + * min-height: 30px; + * border: 1px solid blue; + * } + * + * .prop-note { + * font-family: Monospace; + * } + * + *
+ * + */ + +/** @ngdoc directive + * @name ngOn + * @restrict A + * @element ANY + * + * @usage + * + * ```html + * + * + * ``` + * + * or with uppercase letters in property (e.g. "eventName"): + * + * + * ```html + * + * + * ``` + * + * @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 + * + * + * + * angular.module('exampleNgOn', []) + * .component('main', { + * templateUrl: 'main.html', + * controller: function() { + * this.clickCount = 0; + * this.mouseoverCount = 0; + * + * this.loadingState = 0; + * } + * }); + * + * + *
+ * This is equivalent to `ngClick` and `ngMouseover`:
+ *
+ * clickCount: {{$ctrl.clickCount}}
+ * mouseover: {{$ctrl.mouseoverCount}} + * + *
+ * + * For the `error` and `load` event on images no built-in AngularJS directives exist:
+ *
+ *
+ * Image is loading + * Image load error + * Image loaded successfully + *
+ *
+ *
+ * + *
+ *
+ *
+ * + * + * @example + * ### Bind to custom DOM events + * + * + * + * 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); + * }; + * } + * }); + * + * + *
+ * Event log: {{$ctrl.eventLog}} + *
+ * + + * + * + *
+ *
+ *
+ */ + var $compileMinErr = minErr('$compile'); function UNINITIALIZED_VALUE() {} diff --git a/src/ng/sce.js b/src/ng/sce.js index a5f618ef8fe4..6bc99f23761f 100644 --- a/src/ng/sce.js +++ b/src/ng/sce.js @@ -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.)

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.)

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.

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. | * *