Skip to content

Commit 6c7f18a

Browse files
committed
Add filtering for lengths for padding/margin/border/outline/font-size, and handle things like padding-top, etc. Resolves issue #1182
1 parent 153387d commit 6c7f18a

File tree

1 file changed

+82
-6
lines changed

1 file changed

+82
-6
lines changed

unpacked/extensions/Safe.js

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
},
4444
sizeMin: .7, // \scriptsize
4545
sizeMax: 1.44, // \large
46+
lengthMax: 3, // largest padding/border/margin, etc. in em's
4647
safeProtocols: {
4748
http: true,
4849
https: true,
@@ -86,6 +87,40 @@
8687
noUndefined: false,
8788
unicode: true,
8889
verb: true
90+
},
91+
//
92+
// CSS styles that have Top/Right/Bottom/Left versions
93+
//
94+
styleParts: {
95+
border: true,
96+
padding: true,
97+
margin: true,
98+
outline: true
99+
},
100+
//
101+
// CSS styles that are lengths needing max/min testing
102+
// A string value means test that style value;
103+
// An array gives [min,max] in em's
104+
// Otherwise use [-lengthMax,lengthMax] from above
105+
//
106+
styleLengths: {
107+
borderTop: "borderTopWidth",
108+
borderRight: "borderRightWidth",
109+
borderBottom: "borderBottomWidth",
110+
borderLeft: "borderLeftWidth",
111+
paddingTop: true,
112+
paddingRight: true,
113+
paddingBottom: true,
114+
paddingLeft: true,
115+
marginTop: true,
116+
marginRight: true,
117+
marginBottom: true,
118+
marginLeft: true,
119+
outlineTop: true,
120+
outlineRight: true,
121+
outlineBottom: true,
122+
outlineLeft: true,
123+
fontSize: [.7,1.44]
89124
}
90125
});
91126

@@ -149,14 +184,23 @@
149184
//
150185
// Set the div1 styles to the given styles, and clear div2
151186
//
152-
var STYLE1 = this.div1.style, STYLE2 = this.div2.style;
187+
var STYLE1 = this.div1.style, STYLE2 = this.div2.style, value;
153188
STYLE1.cssText = styles; STYLE2.cssText = "";
154189
//
155190
// Check each allowed style and transfer OK ones to div2
191+
// If the style has Top/Right/Bottom/Left, look at all four separately
156192
//
157193
for (var name in CONFIG.safeStyles) {if (CONFIG.safeStyles.hasOwnProperty(name)) {
158-
var value = this.filterStyle(name,STYLE1[name]);
159-
if (value != null) {STYLE2[name] = value}
194+
if (CONFIG.styleParts[name]) {
195+
for (var i = 0; i < 4; i++) {
196+
var NAME = name+["Top","Right","Bottom","Left"][i]
197+
value = this.filterStyle(NAME,STYLE1);
198+
if (value) {STYLE2[NAME] = value}
199+
}
200+
} else {
201+
value = this.filterStyle(name,STYLE1);
202+
if (value) {STYLE2[name] = value}
203+
}
160204
}}
161205
//
162206
// Return the div2 style string
@@ -168,11 +212,43 @@
168212
//
169213
// Filter an individual name:value style pair
170214
//
171-
filterStyle: function (name,value) {
172-
if (typeof value !== "string") {return null}
215+
filterStyle: function (name,styles) {
216+
var value = styles[name];
217+
if (typeof value !== "string" || value === "") {return null}
173218
if (value.match(/^\s*expression/)) {return null}
174219
if (value.match(/javascript:/)) {return null}
175-
return (CONFIG.safeStyles[name] ? value : null);
220+
var NAME = name.replace(/Top|Right|Left|Bottom/,"");
221+
if (!CONFIG.safeStyles[name] && !CONFIG.safeStyles[NAME]) {return null}
222+
if (!CONFIG.styleLengths[name]) {return value}
223+
return (this.filterStyleLength(name,value,styles) ? value : null);
224+
},
225+
filterStyleLength: function (name,value,styles) {
226+
if (typeof CONFIG.styleLengths[name] === "string") value = styles[CONFIG.styleLengths[name]];
227+
value = this.length2em(value);
228+
if (value == null) return false;
229+
var mM = [-CONFIG.lengthMax,CONFIG.lengthMax];
230+
if (CONFIG.styleLengths[name] instanceof Array) mM = CONFIG.styleLengths[name];
231+
return (value >= mM[0] && value <= mM[1]);
232+
},
233+
//
234+
// Conversion of units to em's
235+
//
236+
unit2em: {
237+
em: 1,
238+
ex: .5, // assume 1ex = .5em
239+
ch: .5, // assume 1ch = .5em
240+
rem: 1, // assume 1rem = 1em
241+
px: 1/16, // assume 1em = 16px
242+
mm: 96/25.4/16, // 25.4mm = 96px
243+
cm: 96/2.54/16, // 2.54cm = 96px
244+
in: 96/16, // 1in = 96px
245+
pt: 96/72/16, // 72pt = 1in
246+
pc: 96/6/16 // 1pc = 12pt
247+
},
248+
length2em: function (value) {
249+
var match = value.match(/(.+)(em|ex|ch|rem|px|mm|cm|in|pt|pc)/);
250+
if (!match) return null;
251+
return parseFloat(match[1])*this.unit2em[match[2]];
176252
},
177253

178254
//

0 commit comments

Comments
 (0)