@@ -16,6 +16,8 @@ var bind;
16
16
var extend ;
17
17
var forEach ;
18
18
var isDefined ;
19
+ var isArray ;
20
+ var isObject ;
19
21
var lowercase ;
20
22
var noop ;
21
23
var nodeContains ;
@@ -145,8 +147,10 @@ var htmlSanitizeWriter;
145
147
*/
146
148
function $SanitizeProvider ( ) {
147
149
var svgEnabled = false ;
150
+ var hasBeenInstantiated = false ;
148
151
149
152
this . $get = [ '$$sanitizeUri' , function ( $$sanitizeUri ) {
153
+ hasBeenInstantiated = true ;
150
154
if ( svgEnabled ) {
151
155
extend ( validElements , svgElements ) ;
152
156
}
@@ -199,6 +203,56 @@ function $SanitizeProvider() {
199
203
}
200
204
} ;
201
205
206
+
207
+ /**
208
+ * @ngdoc method
209
+ * @name $sanitizeProvider#addValidElements
210
+ * @kind function
211
+ *
212
+ * @param {Array|Object } elements List of valid elements.
213
+ *
214
+ * Object properties:
215
+ *
216
+ * - `svgElements` – `{string[]=}` – An array of SVG elements' names.
217
+ * - `htmlVoidElements` – `{string[]=}` – An array of void elements' names.
218
+ * - `htmlElements` – `{string[]=}` – An array of html elements' names.
219
+ */
220
+ this . addValidElements = function ( elements ) {
221
+ if ( hasBeenInstantiated ) return this ;
222
+
223
+ if ( isArray ( elements ) ) {
224
+ addElementsTo ( validElements , elements ) ;
225
+ return this ;
226
+ }
227
+
228
+ if ( isObject ( elements ) ) {
229
+ addElementsTo ( svgElements , elements [ 'svgElements' ] ) ;
230
+ addElementsTo ( voidElements , elements [ 'htmlVoidElements' ] ) ;
231
+ addElementsTo ( validElements , elements [ 'htmlVoidElements' ] ) ;
232
+ addElementsTo ( validElements , elements [ 'htmlElements' ] ) ;
233
+ }
234
+
235
+ return this ;
236
+ } ;
237
+
238
+
239
+ /**
240
+ * @ngdoc method
241
+ * @name $sanitizeProvider#addValidAttrs
242
+ * @kind function
243
+ *
244
+ * @description
245
+ * The added attributes will not be treated as URI attributes, which means their values will
246
+ * not sanitized as URIs using the aHrefSanitizationWhitelist and imgSrcSanitizationWhitelist of {@link ng.$compileProvider $compileProvider}.
247
+ *
248
+ * @param {Array } attrs List of valid attributes
249
+ */
250
+ this . addValidAttrs = function ( attrs ) {
251
+ if ( hasBeenInstantiated ) return this ;
252
+ extend ( validAttrs , arrayToMap ( attrs , true ) ) ;
253
+ return this ;
254
+ } ;
255
+
202
256
//////////////////////////////////////////////////////////////////////////////////////////////////
203
257
// Private stuff
204
258
//////////////////////////////////////////////////////////////////////////////////////////////////
@@ -207,6 +261,8 @@ function $SanitizeProvider() {
207
261
extend = angular . extend ;
208
262
forEach = angular . forEach ;
209
263
isDefined = angular . isDefined ;
264
+ isArray = angular . isArray ;
265
+ isObject = angular . isObject ;
210
266
lowercase = angular . $$lowercase ;
211
267
noop = angular . noop ;
212
268
@@ -230,36 +286,36 @@ function $SanitizeProvider() {
230
286
231
287
// Safe Void Elements - HTML5
232
288
// http://dev.w3.org/html5/spec/Overview.html#void-elements
233
- var voidElements = toMap ( 'area,br,col,hr,img,wbr' ) ;
289
+ var voidElements = stringToMap ( 'area,br,col,hr,img,wbr' ) ;
234
290
235
291
// Elements that you can, intentionally, leave open (and which close themselves)
236
292
// http://dev.w3.org/html5/spec/Overview.html#optional-tags
237
- var optionalEndTagBlockElements = toMap ( 'colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr' ) ,
238
- optionalEndTagInlineElements = toMap ( 'rp,rt' ) ,
293
+ var optionalEndTagBlockElements = stringToMap ( 'colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr' ) ,
294
+ optionalEndTagInlineElements = stringToMap ( 'rp,rt' ) ,
239
295
optionalEndTagElements = extend ( { } ,
240
296
optionalEndTagInlineElements ,
241
297
optionalEndTagBlockElements ) ;
242
298
243
299
// Safe Block Elements - HTML5
244
- var blockElements = extend ( { } , optionalEndTagBlockElements , toMap ( 'address,article,' +
300
+ var blockElements = extend ( { } , optionalEndTagBlockElements , stringToMap ( 'address,article,' +
245
301
'aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' +
246
302
'h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,section,table,ul' ) ) ;
247
303
248
304
// Inline Elements - HTML5
249
- var inlineElements = extend ( { } , optionalEndTagInlineElements , toMap ( 'a,abbr,acronym,b,' +
305
+ var inlineElements = extend ( { } , optionalEndTagInlineElements , stringToMap ( 'a,abbr,acronym,b,' +
250
306
'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,' +
251
307
'samp,small,span,strike,strong,sub,sup,time,tt,u,var' ) ) ;
252
308
253
309
// SVG Elements
254
310
// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Elements
255
311
// Note: the elements animate,animateColor,animateMotion,animateTransform,set are intentionally omitted.
256
312
// They can potentially allow for arbitrary javascript to be executed. See #11290
257
- var svgElements = toMap ( 'circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' +
313
+ var svgElements = stringToMap ( 'circle,defs,desc,ellipse,font-face,font-face-name,font-face-src,g,glyph,' +
258
314
'hkern,image,linearGradient,line,marker,metadata,missing-glyph,mpath,path,polygon,polyline,' +
259
315
'radialGradient,rect,stop,svg,switch,text,title,tspan' ) ;
260
316
261
317
// Blocked Elements (will be stripped)
262
- var blockedElements = toMap ( 'script,style' ) ;
318
+ var blockedElements = stringToMap ( 'script,style' ) ;
263
319
264
320
var validElements = extend ( { } ,
265
321
voidElements ,
@@ -268,17 +324,17 @@ function $SanitizeProvider() {
268
324
optionalEndTagElements ) ;
269
325
270
326
//Attributes that have href and hence need to be sanitized
271
- var uriAttrs = toMap ( 'background,cite,href,longdesc,src,xlink:href,xml:base' ) ;
327
+ var uriAttrs = stringToMap ( 'background,cite,href,longdesc,src,xlink:href,xml:base' ) ;
272
328
273
- var htmlAttrs = toMap ( 'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
329
+ var htmlAttrs = stringToMap ( 'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,' +
274
330
'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,' +
275
331
'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,' +
276
332
'scope,scrolling,shape,size,span,start,summary,tabindex,target,title,type,' +
277
333
'valign,value,vspace,width' ) ;
278
334
279
335
// SVG attributes (without "id" and "name" attributes)
280
336
// https://wiki.whatwg.org/wiki/Sanitization_rules#svg_Attributes
281
- var svgAttrs = toMap ( 'accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
337
+ var svgAttrs = stringToMap ( 'accent-height,accumulate,additive,alphabetic,arabic-form,ascent,' +
282
338
'baseProfile,bbox,begin,by,calcMode,cap-height,class,color,color-rendering,content,' +
283
339
'cx,cy,d,dx,dy,descent,display,dur,end,fill,fill-rule,font-family,font-size,font-stretch,' +
284
340
'font-style,font-variant,font-weight,from,fx,fy,g1,g2,glyph-name,gradientUnits,hanging,' +
@@ -299,14 +355,24 @@ function $SanitizeProvider() {
299
355
svgAttrs ,
300
356
htmlAttrs ) ;
301
357
302
- function toMap ( str , lowercaseKeys ) {
303
- var obj = { } , items = str . split ( ',' ) , i ;
358
+ function stringToMap ( str , lowercaseKeys ) {
359
+ return arrayToMap ( str . split ( ',' ) , lowercaseKeys ) ;
360
+ }
361
+
362
+ function arrayToMap ( items , lowercaseKeys ) {
363
+ var obj = { } , i ;
304
364
for ( i = 0 ; i < items . length ; i ++ ) {
305
365
obj [ lowercaseKeys ? lowercase ( items [ i ] ) : items [ i ] ] = true ;
306
366
}
307
367
return obj ;
308
368
}
309
369
370
+ function addElementsTo ( elementsMap , newElements ) {
371
+ if ( newElements && newElements . length ) {
372
+ extend ( elementsMap , arrayToMap ( newElements ) ) ;
373
+ }
374
+ }
375
+
310
376
/**
311
377
* Create an inert document that contains the dirty HTML that needs sanitizing
312
378
* Depending upon browser support we use one of three strategies for doing this.
0 commit comments