Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit a02ed88

Browse files
committed
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
1 parent a5914c9 commit a02ed88

File tree

2 files changed

+320
-1
lines changed

2 files changed

+320
-1
lines changed

src/ng/compile.js

Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,325 @@
10441044
*
10451045
*/
10461046

1047+
/**
1048+
* @ngdoc directive
1049+
* @name ngProp
1050+
* @restrict A
1051+
* @element ANY
1052+
*
1053+
* @usage
1054+
*
1055+
* ```html
1056+
* <ANY ng-prop-propname="expression">
1057+
* </ANY>
1058+
* ```
1059+
*
1060+
* or with uppercase letters in property (e.g. "propName"):
1061+
*
1062+
*
1063+
* ```html
1064+
* <ANY ng-prop-prop_name="expression">
1065+
* </ANY>
1066+
* ```
1067+
*
1068+
*
1069+
* @description
1070+
* The `ngProp` directive binds an expression to a DOM element property.
1071+
* `ngProp` allows writing to arbitrary properties by including
1072+
* the property name in the attribute, e.g. `ng-prop-value="'my value'"` binds 'my value' to
1073+
* the `value` property.
1074+
*
1075+
* Usually, it's not necessary to write to properties in AngularJS, as the built-in directives
1076+
* handle the most common use cases (instead of the above example, you would use {@link ngValue}).
1077+
*
1078+
* However, [custom elements](https://developer.mozilla.org/docs/Web/Web_Components/Using_custom_elements)
1079+
* often use custom properties to hold data, and `ngProp` can be used to provide input to these
1080+
* custom elements.
1081+
*
1082+
* ## Binding to camelCase properties
1083+
*
1084+
* Since HTML attributes are case-insensitive, camelCase properties like `innerHTML` must be escaped.
1085+
* AngularJS uses the underscore (_) in front of a character to indicate that it is uppercase, so
1086+
* `innerHTML` must be written as `ng-prop-inner_h_t_m_l="expression"` (Note that this is just an
1087+
* example, and for binding HTML {@link ngBindHtml} should be used.
1088+
*
1089+
* ## Security
1090+
*
1091+
* Binding expressions to arbitrary properties poses a security risk, as properties like `innerHTML`
1092+
* can insert potentially dangerous HTML into the application, e.g. script tags that execute
1093+
* malicious code.
1094+
* For this reason, `ngProp` applies Strict Contextual Escaping with the {@link ng.$sce $sce service}.
1095+
* This means vulnerable properties require their content to be "trusted", based on the
1096+
* context of the property. For example, the `innerHTML` is in the `HTML` context, and the
1097+
* `iframe.src` property is in the `RESOURCE_URL` context, which requires that values written to
1098+
* this property are trusted as a `RESOURCE_URL`.
1099+
*
1100+
* This can be set explicitly by calling $sce.trustAs(type, value) on the value that is
1101+
* trusted before passing it to the `ng-prop-*` directive. There are exist shorthand methods for
1102+
* each context type in the form of {@link ng.$sce#trustAsResourceUrl $sce.trustAsResourceUrl()} et al.
1103+
*
1104+
* In some cases you can also rely upon automatic sanitization of untrusted values - see below.
1105+
*
1106+
* Based on the context, other options may exist to mark a value as trusted / configure the behavior
1107+
* of {@link ng.$sce}. For example, to restrict the `RESOURCE_URL` context to specific origins, use
1108+
* the {@link $sceDelegateProvider#resourceUrlWhitelist resourceUrlWhitelist()}
1109+
* and {@link $sceDelegateProvider#resourceUrlBlacklist resourceUrlBlacklist()}.
1110+
*
1111+
* {@link ng.$sce#what-trusted-context-types-are-supported- Find out more about the different context types}.
1112+
*
1113+
* ### HTML Sanitization
1114+
*
1115+
* By default, `$sce` will throw an error if it detects untrusted HTML content, and will not bind the
1116+
* content.
1117+
* However, if you include the {@link ngSanitize ngSanitize module}, it will try to sanitize the
1118+
* potentially dangerous HTML, e.g. strip non-whitelisted tags and attributes when binding to
1119+
* `innerHTML`.
1120+
*
1121+
* @example
1122+
* ### Binding to different contexts
1123+
*
1124+
* <example name="ngProp" module="exampleNgProp">
1125+
* <file name="app.js">
1126+
* angular.module('exampleNgProp', [])
1127+
* .component('main', {
1128+
* templateUrl: 'main.html',
1129+
* controller: function($sce) {
1130+
* this.safeContent = '<strong>Safe content</strong>';
1131+
* this.unsafeContent = '<button onclick="alert(\'Hello XSS!\')">Click for XSS</button>';
1132+
* this.trustedUnsafeContent = $sce.trustAsHtml(this.unsafeContent);
1133+
* }
1134+
* });
1135+
* </file>
1136+
* <file name="main.html">
1137+
* <div>
1138+
* <div class="prop-unit">
1139+
* Binding to a property without security context:
1140+
* <div class="prop-binding" ng-prop-inner_text="$ctrl.safeContent"></div>
1141+
* <span class="prop-note">innerText</span> (safeContent)
1142+
* </div>
1143+
*
1144+
* <div class="prop-unit">
1145+
* "Safe" content that requires a security context will throw because the contents could potentially be dangerous ...
1146+
* <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.safeContent"></div>
1147+
* <span class="prop-note">innerHTML</span> (safeContent)
1148+
* </div>
1149+
*
1150+
* <div class="prop-unit">
1151+
* ... so that actually dangerous content cannot be executed:
1152+
* <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.unsafeContent"></div>
1153+
* <span class="prop-note">innerHTML</span> (unsafeContent)
1154+
* </div>
1155+
*
1156+
* <div class="prop-unit">
1157+
* ... but unsafe Content that has been trusted explicitly works - only do this if you are 100% sure!
1158+
* <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.trustedUnsafeContent"></div>
1159+
* <span class="prop-note">innerHTML</span> (trustedUnsafeContent)
1160+
* </div>
1161+
* </div>
1162+
* </file>
1163+
* <file name="index.html">
1164+
* <main></main>
1165+
* </file>
1166+
* <file name="styles.css">
1167+
* .prop-unit {
1168+
* margin-bottom: 10px;
1169+
* }
1170+
*
1171+
* .prop-binding {
1172+
* min-height: 30px;
1173+
* border: 1px solid blue;
1174+
* }
1175+
*
1176+
* .prop-note {
1177+
* font-family: Monospace;
1178+
* }
1179+
* </file>
1180+
* </example>
1181+
*
1182+
*
1183+
* @example
1184+
* ### Binding to innerHTML with ngSanitize
1185+
*
1186+
* <example name="ngProp" module="exampleNgProp" deps="angular-sanitize.js">
1187+
* <file name="app.js">
1188+
* angular.module('exampleNgProp', ['ngSanitize'])
1189+
* .component('main', {
1190+
* templateUrl: 'main.html',
1191+
* controller: function($sce) {
1192+
* this.safeContent = '<strong>Safe content</strong>';
1193+
* this.unsafeContent = '<button onclick="alert(\'Hello XSS!\')">Click for XSS</button>';
1194+
* this.trustedUnsafeContent = $sce.trustAsHtml(this.unsafeContent);
1195+
* }
1196+
* });
1197+
* </file>
1198+
* <file name="main.html">
1199+
* <div>
1200+
* <div class="prop-unit">
1201+
* "Safe" content will be sanitized ...
1202+
* <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.safeContent"></div>
1203+
* <span class="prop-note">innerHTML</span> (safeContent)
1204+
* </div>
1205+
*
1206+
* <div class="prop-unit">
1207+
* ... as will dangerous content:
1208+
* <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.unsafeContent"></div>
1209+
* <span class="prop-note">innerHTML</span> (unsafeContent)
1210+
* </div>
1211+
*
1212+
* <div class="prop-unit">
1213+
* ... and content that has been trusted explicitly works the same as without ngSanitize:
1214+
* <div class="prop-binding" ng-prop-inner_h_t_m_l="$ctrl.trustedUnsafeContent"></div>
1215+
* <span class="prop-note">innerHTML</span> (trustedUnsafeContent)
1216+
* </div>
1217+
* </div>
1218+
* </file>
1219+
* <file name="index.html">
1220+
* <main></main>
1221+
* </file>
1222+
* <file name="styles.css">
1223+
* .prop-unit {
1224+
* margin-bottom: 10px;
1225+
* }
1226+
*
1227+
* .prop-binding {
1228+
* min-height: 30px;
1229+
* border: 1px solid blue;
1230+
* }
1231+
*
1232+
* .prop-note {
1233+
* font-family: Monospace;
1234+
* }
1235+
* </file>
1236+
* </example>
1237+
*
1238+
*/
1239+
1240+
/** @ngdoc directive
1241+
* @name ngOn
1242+
* @restrict A
1243+
* @element ANY
1244+
*
1245+
* @usage
1246+
*
1247+
* ```html
1248+
* <ANY ng-on-eventname="expression">
1249+
* </ANY>
1250+
* ```
1251+
*
1252+
* or with uppercase letters in property (e.g. "eventName"):
1253+
*
1254+
*
1255+
* ```html
1256+
* <ANY ng-on-event_name="expression">
1257+
* </ANY>
1258+
* ```
1259+
*
1260+
* @description
1261+
* The `ngOn` directive adds an event listener to a DOM element via
1262+
* {@link angular.element angular.element().on()}, and evaluates an expression when the event is
1263+
* fired.
1264+
* `ngOn` allows adding listeners for arbitrary events by including
1265+
* the event name in the attribute, e.g. `ng-on-drop="onDrop()"` executes the 'onDrop()' expression
1266+
* when the `drop` event is fired.
1267+
*
1268+
* AngularJS provides specific directives for many events, such as {@link ngClick}, so in most
1269+
* cases it is not necessary to use `ngOn`. However, AngularJS does not support all events
1270+
* (e.g. the `drop` event in the example above), and new events might be introduced in later DOM
1271+
* standards.
1272+
*
1273+
* Another use-case for `ngOn` is listening to
1274+
* [custom events](https://developer.mozilla.org/docs/Web/Guide/Events/Creating_and_triggering_events)
1275+
* fired by
1276+
* [custom elements](https://developer.mozilla.org/docs/Web/Web_Components/Using_custom_elements).
1277+
*
1278+
* ## Binding to camelCase properties
1279+
*
1280+
* Since HTML attributes are case-insensitive, camelCase properties like `myEvent` must be escaped.
1281+
* AngularJS uses the underscore (_) in front of a character to indicate that it is uppercase, so
1282+
* `myEvent` must be written as `ng-on-my_event="expression"`.
1283+
*
1284+
* @example
1285+
* ### Bind to built-in DOM events
1286+
*
1287+
* <example name="ngOn" module="exampleNgOn">
1288+
* <file name="app.js">
1289+
* angular.module('exampleNgOn', [])
1290+
* .component('main', {
1291+
* templateUrl: 'main.html',
1292+
* controller: function() {
1293+
* this.clickCount = 0;
1294+
* this.mouseoverCount = 0;
1295+
*
1296+
* this.loadingState = 0;
1297+
* }
1298+
* });
1299+
* </file>
1300+
* <file name="main.html">
1301+
* <div>
1302+
* This is equivalent to `ngClick` and `ngMouseover`:<br>
1303+
* <button
1304+
* ng-on-click="$ctrl.clickCount = $ctrl.clickCount + 1"
1305+
* ng-on-mouseover="$ctrl.mouseoverCount = $ctrl.mouseoverCount + 1">Click or mouseover</button><br>
1306+
* clickCount: {{$ctrl.clickCount}}<br>
1307+
* mouseover: {{$ctrl.mouseoverCount}}
1308+
*
1309+
* <hr>
1310+
*
1311+
* For the `error` and `load` event on images no built-in AngularJS directives exist:<br>
1312+
* <img src="thisimagedoesnotexist.png" ng-on-error="$ctrl.loadingState = -1" ng-on-load="$ctrl.loadingState = 1"><br>
1313+
* <div ng-switch="$ctrl.loadingState">
1314+
* <span ng-switch-when="0">Image is loading</span>
1315+
* <span ng-switch-when="-1">Image load error</span>
1316+
* <span ng-switch-when="1">Image loaded successfully</span>
1317+
* </div>
1318+
* </div>
1319+
* </file>
1320+
* <file name="index.html">
1321+
* <main></main>
1322+
* </file>
1323+
* </example>
1324+
*
1325+
*
1326+
* @example
1327+
* ### Bind to custom DOM events
1328+
*
1329+
* <example name="ngOnCustom" module="exampleNgOn">
1330+
* <file name="app.js">
1331+
* angular.module('exampleNgOn', [])
1332+
* .component('main', {
1333+
* templateUrl: 'main.html',
1334+
* controller: function() {
1335+
* this.eventLog = '';
1336+
*
1337+
* this.listener = function($event) {
1338+
* this.eventLog = 'Event with type "' + $event.type + '" fired at ' + $event.detail;
1339+
* };
1340+
* }
1341+
* })
1342+
* .component('childComponent', {
1343+
* templateUrl: 'child.html',
1344+
* controller: function($element) {
1345+
* this.fireEvent = function() {
1346+
* var event = new CustomEvent('customtype', { detail: new Date()});
1347+
*
1348+
* $element[0].dispatchEvent(event);
1349+
* };
1350+
* }
1351+
* });
1352+
* </file>
1353+
* <file name="main.html">
1354+
* <child-component ng-on-customtype="$ctrl.listener($event)"></child-component><br>
1355+
* <span>Event log: {{$ctrl.eventLog}}</span>
1356+
* </file>
1357+
* <file name="child.html">
1358+
<button ng-click="$ctrl.fireEvent()">Fire custom event</button>
1359+
* </file>
1360+
* <file name="index.html">
1361+
* <main></main>
1362+
* </file>
1363+
* </example>
1364+
*/
1365+
10471366
var $compileMinErr = minErr('$compile');
10481367

10491368
function UNINITIALIZED_VALUE() {}

src/ng/sce.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ function $SceDelegateProvider() {
623623
* | `$sce.CSS` | For CSS that's safe to source into the application. Currently unused. Feel free to use it in your own directives. |
624624
* | `$sce.MEDIA_URL` | For URLs that are safe to render as media. Is automatically converted from string by sanitizing when needed. |
625625
* | `$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.|
626-
* | `$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. |
626+
* | `$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` |
627627
* | `$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. |
628628
*
629629
*

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy