15
15
*
16
16
* @param {string } text Input text.
17
17
* @param {string } target Window (_blank|_self|_parent|_top) or named frame to open links in.
18
+ * @param {object|function(url) } [attributes] Add custom attributes to the link element.
19
+ *
20
+ * Can be one of:
21
+ *
22
+ * - `object`: A map of attributes
23
+ * - `function`: Takes the url as a parameter and returns a map of attributes
24
+ *
25
+ * If the map of attributes contains a value for `target`, it overrides the value of
26
+ * the target parameter.
27
+ *
18
28
* @returns {string } Html-linkified text.
19
29
*
20
30
* @usage
32
42
'mailto:us@somewhere .org,\n'+
33
43
'another@somewhere.org,\n'+
34
44
'and one more: ftp://127.0.0.1/.';
35
- $scope.snippetWithTarget = 'http://angularjs.org/';
45
+ $scope.snippetWithSingleURL = 'http://angularjs.org/';
36
46
}]);
37
47
</script>
38
48
<div ng-controller="ExampleController">
55
65
<tr id="linky-target">
56
66
<td>linky target</td>
57
67
<td>
58
- <pre><div ng-bind-html="snippetWithTarget | linky:'_blank'"><br></div></pre>
68
+ <pre><div ng-bind-html="snippetWithSingleURL | linky:'_blank'"><br></div></pre>
59
69
</td>
60
70
<td>
61
- <div ng-bind-html="snippetWithTarget | linky:'_blank'"></div>
71
+ <div ng-bind-html="snippetWithSingleURL | linky:'_blank'"></div>
72
+ </td>
73
+ </tr>
74
+ <tr id="linky-custom-attributes">
75
+ <td>linky custom attributes</td>
76
+ <td>
77
+ <pre><div ng-bind-html="snippetWithSingleURL | linky:'_self':{rel:'nofollow'}"><br></div></pre>
78
+ </td>
79
+ <td>
80
+ <div ng-bind-html="snippetWithSingleURL | linky:'_self':{rel:'nofollow'}"></div>
62
81
</td>
63
82
</tr>
64
83
<tr id="escaped-html">
95
114
96
115
it('should work with the target property', function() {
97
116
expect(element(by.id('linky-target')).
98
- element(by.binding("snippetWithTarget | linky:'_blank'")).getText()).
117
+ element(by.binding("snippetWithSingleURL | linky:'_blank'")).getText()).
99
118
toBe('http://angularjs.org/');
100
119
expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
101
120
});
121
+
122
+ it('should optionally add custom attributes', function() {
123
+ expect(element(by.id('linky-custom-attributes')).
124
+ element(by.binding("snippetWithSingleURL | linky:'_self':{rel: 'nofollow'}")).getText()).
125
+ toBe('http://angularjs.org/');
126
+ expect(element(by.css('#linky-custom-attributes a')).getAttribute('rel')).toEqual('nofollow');
127
+ });
102
128
</file>
103
129
</example>
104
130
*/
@@ -107,7 +133,7 @@ angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
107
133
/ ( ( f t p | h t t p s ? ) : \/ \/ | ( w w w \. ) | ( m a i l t o : ) ? [ A - Z a - z 0 - 9 . _ % + - ] + @ ) \S * [ ^ \s . ; , ( ) { } < > " \u201d \u2019 ] / i,
108
134
MAILTO_REGEXP = / ^ m a i l t o : / i;
109
135
110
- return function ( text , target ) {
136
+ return function ( text , target , attributes ) {
111
137
if ( ! text ) return text ;
112
138
var match ;
113
139
var raw = text ;
@@ -137,8 +163,21 @@ angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
137
163
}
138
164
139
165
function addLink ( url , text ) {
166
+ var key ;
167
+ var computedAttributes = { } ;
140
168
html . push ( '<a ' ) ;
141
- if ( angular . isDefined ( target ) ) {
169
+ if ( angular . isObject ( attributes ) ) {
170
+ computedAttributes = attributes ;
171
+ for ( key in computedAttributes ) {
172
+ html . push ( key + '="' + computedAttributes [ key ] + '" ' ) ;
173
+ }
174
+ } else if ( angular . isFunction ( attributes ) ) {
175
+ computedAttributes = attributes ( url ) ;
176
+ for ( key in computedAttributes ) {
177
+ html . push ( key + '="' + computedAttributes [ key ] + '" ' ) ;
178
+ }
179
+ }
180
+ if ( angular . isDefined ( target ) && ! ( 'target' in computedAttributes ) ) {
142
181
html . push ( 'target="' ,
143
182
target ,
144
183
'" ' ) ;
0 commit comments