@@ -36,16 +36,32 @@ angular.module('textAngular.factories', [])
36
36
var taFixChrome = function ( html ) {
37
37
if ( ! html || ! angular . isString ( html ) || html . length <= 0 ) return html ;
38
38
// grab all elements with a style attibute
39
- var spanMatch = / < ( [ ^ > \/ ] + ?) s t y l e = ( " ( [ ^ " ] + ) " | ' ( [ ^ ' ] + ) ' ) ( [ ^ > ] * ) > / ig;
40
- var match , styleVal , newTag , finalHtml = '' , lastIndex = 0 ;
39
+ var spanMatch = / < ( [ ^ > \/ ] + ?) s t y l e = ( " ( [ ^ \" ] + ) " | ' ( [ ^ ' ] + ) ' ) ( [ ^ > ] * ) > / ig;
40
+ var appleConvertedSpaceMatch = / < s p a n c l a s s = " A p p l e - c o n v e r t e d - s p a c e " > ( [ ^ < ] + ) < \/ s p a n > / ig;
41
+ var match , styleVal , appleSpaceVal , newTag , finalHtml = '' , lastIndex = 0 ;
42
+ // remove all the Apple-converted-space spans and replace with the content of the span
43
+ /* istanbul ignore next: apple-contereted-space span match */
44
+ while ( match = appleConvertedSpaceMatch . exec ( html ) ) {
45
+ appleSpaceVal = match [ 1 ] ;
46
+ appleSpaceVal = appleSpaceVal . replace ( / & n b s p ; / ig, ' ' ) ;
47
+ finalHtml += html . substring ( lastIndex , match . index ) + appleSpaceVal ;
48
+ lastIndex = match . index + match [ 0 ] . length ;
49
+ }
50
+ /* istanbul ignore next: apple-contereted-space span has matched */
51
+ if ( lastIndex ) {
52
+ // modified....
53
+ html = finalHtml ;
54
+ finalHtml = '' ;
55
+ lastIndex = 0 ;
56
+ }
41
57
while ( match = spanMatch . exec ( html ) ) {
42
58
// one of the quoted values ' or "
43
59
/* istanbul ignore next: quotations match */
44
60
styleVal = match [ 3 ] || match [ 4 ] ;
45
61
// test for chrome inserted junk
46
- if ( styleVal && styleVal . match ( / l i n e - h e i g h t : 1 .[ 0 - 9 ] { 3 , 12 } ; | c o l o r : i n h e r i t ; l i n e - h e i g h t : 1 .1 ; / i) ) {
62
+ if ( styleVal && styleVal . match ( / l i n e - h e i g h t : 1 .[ 0 - 9 ] { 3 , 12 } ; | c o l o r : i n h e r i t ; l i n e - h e i g h t : 1 .1 ; | c o l o r : r g b \( \d { 1 , 3 } , \d { 1 , 3 } , \d { 1 , 3 } \) ; | b a c k g r o u n d - c o l o r : r g b \( \d { 1 , 3 } , \d { 1 , 3 } , \d { 1 , 3 } \) ; / i) ) {
47
63
// replace original tag with new tag
48
- styleVal = styleVal . replace ( / ( | ) f o n t - f a m i l y : i n h e r i t ; | ( | ) l i n e - h e i g h t : 1 .[ 0 - 9 ] { 3 , 12 } ; | ( | ) c o l o r : i n h e r i t ; / ig, '' ) ;
64
+ styleVal = styleVal . replace ( / ( | ) f o n t - f a m i l y : i n h e r i t ; | ( | ) l i n e - h e i g h t : 1 .[ 0 - 9 ] { 3 , 12 } ; | ( | ) c o l o r : i n h e r i t ; | ( | ) c o l o r : r g b \( \d { 1 , 3 } , \d { 1 , 3 } , \d { 1 , 3 } \) ; | ( | ) b a c k g r o u n d - c o l o r : r g b \( \d { 1 , 3 } , \d { 1 , 3 } , \d { 1 , 3 } \) ; / ig, '' ) ;
49
65
newTag = '<' + match [ 1 ] . trim ( ) ;
50
66
if ( styleVal . trim ( ) . length > 0 ) newTag += ' style=' + match [ 2 ] . substring ( 0 , 1 ) + styleVal + match [ 2 ] . substring ( 0 , 1 ) ;
51
67
newTag += match [ 5 ] . trim ( ) + ">" ;
@@ -75,7 +91,7 @@ angular.module('textAngular.factories', [])
75
91
tag : 'i'
76
92
}
77
93
] ;
78
-
94
+
79
95
var styleMatch = [ ] ;
80
96
for ( var i = 0 ; i < convert_infos . length ; i ++ ) {
81
97
var _partialStyle = '(' + convert_infos [ i ] . property + ':\\s*(' ;
@@ -88,7 +104,7 @@ angular.module('textAngular.factories', [])
88
104
styleMatch . push ( _partialStyle ) ;
89
105
}
90
106
var styleRegexString = '(' + styleMatch . join ( '|' ) + ')' ;
91
-
107
+
92
108
function wrapNested ( html , wrapTag ) {
93
109
var depth = 0 ;
94
110
var lastIndex = 0 ;
@@ -107,7 +123,7 @@ angular.module('textAngular.factories', [])
107
123
angular . element ( wrapTag ) [ 0 ] . outerHTML . substring ( wrapTag . length ) +
108
124
html . substring ( lastIndex ) ;
109
125
}
110
-
126
+
111
127
function transformLegacyStyles ( html ) {
112
128
if ( ! html || ! angular . isString ( html ) || html . length <= 0 ) return html ;
113
129
var i ;
@@ -155,7 +171,7 @@ angular.module('textAngular.factories', [])
155
171
else finalHtml += html . substring ( lastIndex ) ;
156
172
return finalHtml ;
157
173
}
158
-
174
+
159
175
function transformLegacyAttributes ( html ) {
160
176
if ( ! html || ! angular . isString ( html ) || html . length <= 0 ) return html ;
161
177
// replace all align='...' tags with text-align attributes
@@ -184,7 +200,7 @@ angular.module('textAngular.factories', [])
184
200
// return with remaining html
185
201
return finalHtml + html . substring ( lastIndex ) ;
186
202
}
187
-
203
+
188
204
return function taSanitize ( unsafe , oldsafe , ignore ) {
189
205
// unsafe html should NEVER built into a DOM object via angular.element. This allows XSS to be inserted and run.
190
206
if ( ! ignore ) {
@@ -198,7 +214,7 @@ angular.module('textAngular.factories', [])
198
214
// any exceptions (lets say, color for example) should be made here but with great care
199
215
// setup unsafe element for modification
200
216
unsafe = transformLegacyAttributes ( unsafe ) ;
201
-
217
+
202
218
var safe ;
203
219
try {
204
220
safe = $sanitize ( unsafe ) ;
@@ -207,9 +223,9 @@ angular.module('textAngular.factories', [])
207
223
} catch ( e ) {
208
224
safe = oldsafe || '' ;
209
225
}
210
-
226
+
211
227
// Do processing for <pre> tags, removing tabs and return carriages outside of them
212
-
228
+
213
229
var _preTags = safe . match ( / ( < p r e [ ^ > ] * > .* ?< \/ p r e [ ^ > ] * > ) / ig) ;
214
230
var processedSafe = safe . replace ( / ( & # ( 9 | 1 0 ) ; ) * / ig, '' ) ;
215
231
var re = / < p r e [ ^ > ] * > .* ?< \/ p r e [ ^ > ] * > / ig;
@@ -247,4 +263,4 @@ angular.module('textAngular.factories', [])
247
263
deferred . resolve ( ) ;
248
264
}
249
265
} ;
250
- } ] ) ;
266
+ } ] ) ;
0 commit comments