Skip to content

Commit e93118b

Browse files
committed
feat(ng_bind_html): ng-bind-html directive to innerHTML an expression
Closes dart-archive#116
1 parent b646df2 commit e93118b

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

lib/directives/all.dart

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import '../bootstrap.dart';
44

55
import 'ng_mustache.dart';
66
import 'ng_bind.dart';
7+
import 'ng_bind_html.dart';
78
import 'ng_class.dart';
89
import 'ng_events.dart';
910
import 'ng_cloak.dart';
@@ -20,6 +21,7 @@ import 'ng_switch.dart';
2021

2122
export 'ng_mustache.dart';
2223
export 'ng_bind.dart';
24+
export 'ng_bind_html.dart';
2325
export 'ng_class.dart';
2426
export 'ng_events.dart';
2527
export 'ng_cloak.dart';
@@ -39,6 +41,7 @@ void registerDirectives(AngularModule module) {
3941
module.directive(NgTextMustacheDirective);
4042
module.directive(NgAttrMustacheDirective);
4143
module.directive(NgBindAttrDirective);
44+
module.directive(NgBindHtmlAttrDirective);
4245
module.directive(NgClassAttrDirective);
4346
module.directive(NgClassOddAttrDirective);
4447
module.directive(NgClassEvenAttrDirective);

lib/directives/ng_bind_html.dart

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
library angular.directive.ng_bind_html;
2+
3+
import 'dart:html' as dom;
4+
import '../dom/directive.dart';
5+
6+
/**
7+
* Creates a binding that will innerHTML the result of evaluating the
8+
* `expression` bound to `ng-bind-html` into the current element in a secure
9+
* way. This expression must evaluate to a string. The innerHTML-ed content
10+
* will be sanitized using a default [NodeValidator] constructed as `new
11+
* dom.NodeValidatorBuilder.common()`. In a future version, when Strict
12+
* Contextual Escaping support has been added to Angular.dart, this directive
13+
* will allow one to bypass the sanitizaton and innerHTML arbitrary trusted
14+
* HTML.
15+
*
16+
* Example:
17+
*
18+
* <div ng-bind-html="htmlVar"></div>
19+
*/
20+
@NgDirective(
21+
selector: '[ng-bind-html]',
22+
map: const {'ng-bind-html': '=.value'})
23+
class NgBindHtmlAttrDirective {
24+
// The default HTML sanitizer. Eventually, we'll make this configurable or
25+
// use an optionally loaded `$sanitize` service.
26+
static final dom.NodeValidator validator = new dom.NodeValidatorBuilder.common();
27+
28+
dom.Element element;
29+
30+
NgBindHtmlAttrDirective(dom.Element this.element);
31+
32+
/**
33+
* Parsed expression from the `ng-bind-html` attribute.  The result of this
34+
* expression is innerHTML'd according to the rules specified in this class'
35+
* documention.
36+
*/
37+
set value(value) => element.setInnerHtml((value == null ? '' : value.toString()),
38+
validator: validator) ;
39+
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
library ng_bind_html_spec;
2+
3+
import '../_specs.dart';
4+
import '../_test_bed.dart';
5+
import 'dart:html' as dom;
6+
7+
main() {
8+
describe('BindHtmlDirective', () {
9+
TestBed _;
10+
11+
beforeEach(beforeEachTestBed((tb) => _ = tb));
12+
13+
it('should sanitize and set innerHtml and sanitize and set html',
14+
inject((Scope scope, Injector injector, Compiler compiler) {
15+
var element = $('<div ng-bind-html="htmlVar"></div>');
16+
compiler(element)(injector, element);
17+
scope.htmlVar = '<a href="http://www.google.com"><b>Google!</b></a>';
18+
scope.$digest();
19+
// Sanitization removes the href attribute on the <a> tag.
20+
expect(element.html()).toEqual('<a><b>Google!</b></a>');
21+
}));
22+
});
23+
}

0 commit comments

Comments
 (0)