Skip to content

Commit bd1d6c4

Browse files
committed
Patch CSSStyleDeclaration to handle units of 'ex' (and others). Resolves issue #233
1 parent 5b96b17 commit bd1d6c4

1 file changed

Lines changed: 109 additions & 0 deletions

File tree

lib/patch/jsdom.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,113 @@ var WIDTH = (function () {
170170
})();
171171

172172

173+
//
174+
// Patch for CSSStyleDeclaration lengthRegEx so that it includes ex units
175+
// (plus a number of other units that are left out)
176+
//
177+
var FixValueType = function () {
178+
var parsers = require(PARSERS);
179+
180+
var integerRegEx = /^[\-+]?[0-9]+$/;
181+
var numberRegEx = /^[\-+]?[0-9]*\.[0-9]+$/;
182+
var lengthRegEx = /^(0|[\-+]?[0-9]*\.?[0-9]+(in|cm|mm|pt|pc|px|em|ex|ch|rem|vh|vw|vmin|vmax))$/;
183+
var percentRegEx = /^[\-+]?[0-9]*\.?[0-9]+%$/;
184+
var urlRegEx = /^url\(\s*([^\)]*)\s*\)$/;
185+
var stringRegEx = /^(\"[^\"]*\"|\'[^\']*\')$/;
186+
var colorRegEx1 = /^#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])?$/;
187+
var colorRegEx2 = /^rgb\(([^\)]*)\)$/;
188+
var colorRegEx3 = /^rgba\(([^\)]*)\)$/;
189+
var angleRegEx = /^([\-+]?[0-9]*\.?[0-9]+)(deg|grad|rad)$/;
190+
191+
parsers.valueType = function valueType(val) {
192+
var TYPES = parsers.TYPES;
193+
if (val === '' || val === null) return TYPES.NULL_OR_EMPTY_STR;
194+
if (typeof val === 'number') val = val.toString();
195+
if (typeof val !== 'string') return undefined;
196+
197+
if (integerRegEx.test(val)) return TYPES.INTEGER;
198+
if (numberRegEx.test(val)) return TYPES.NUMBER;
199+
if (lengthRegEx.test(val)) return TYPES.LENGTH;
200+
if (percentRegEx.test(val)) return TYPES.PERCENT;
201+
if (urlRegEx.test(val)) return TYPES.URL;
202+
if (stringRegEx.test(val)) return TYPES.STRING;
203+
if (angleRegEx.test(val)) return TYPES.ANGLE;
204+
if (colorRegEx1.test(val)) return TYPES.COLOR;
205+
var res = colorRegEx2.exec(val);
206+
var parts;
207+
if (res !== null) {
208+
parts = res[1].split(/\s*,\s*/);
209+
if (parts.length !== 3) return undefined;
210+
if (parts.every(percentRegEx.test.bind(percentRegEx)) ||
211+
parts.every(integerRegEx.test.bind(integerRegEx))) return TYPES.COLOR;
212+
return undefined;
213+
}
214+
res = colorRegEx3.exec(val);
215+
if (res !== null) {
216+
parts = res[1].split(/\s*,\s*/);
217+
if (parts.length !== 4) return undefined;
218+
if (parts.slice(0, 3).every(percentRegEx.test.bind(percentRegEx)) ||
219+
parts.every(integerRegEx.test.bind(integerRegEx))) {
220+
if (numberRegEx.test(parts[3])) return TYPES.COLOR;
221+
}
222+
return undefined;
223+
}
224+
val = val.toLowerCase();
225+
switch (val) {
226+
case 'maroon':
227+
case 'red':
228+
case 'orange':
229+
case 'yellow':
230+
case 'olive':
231+
case 'purple':
232+
case 'fuchsia':
233+
case 'white':
234+
case 'lime':
235+
case 'green':
236+
case 'navy':
237+
case 'blue':
238+
case 'aqua':
239+
case 'teal':
240+
case 'black':
241+
case 'silver':
242+
case 'gray':
243+
// the following are deprecated in CSS3
244+
case 'activeborder':
245+
case 'activecaption':
246+
case 'appworkspace':
247+
case 'background':
248+
case 'buttonface':
249+
case 'buttonhighlight':
250+
case 'buttonshadow':
251+
case 'buttontext':
252+
case 'captiontext':
253+
case 'graytext':
254+
case 'highlight':
255+
case 'highlighttext':
256+
case 'inactiveborder':
257+
case 'inactivecaption':
258+
case 'inactivecaptiontext':
259+
case 'infobackground':
260+
case 'infotext':
261+
case 'menu':
262+
case 'menutext':
263+
case 'scrollbar':
264+
case 'threeddarkshadow':
265+
case 'threedface':
266+
case 'threedhighlight':
267+
case 'threedlightshadow':
268+
case 'threedshadow':
269+
case 'window':
270+
case 'windowframe':
271+
case 'windowtext':
272+
return TYPES.COLOR;
273+
default:
274+
return TYPES.KEYWORD;
275+
}
276+
};
277+
}
278+
279+
173280
//
174281
// Patch jsdom functions
175282
//
@@ -276,4 +383,6 @@ exports.patch = function (jsdom) {
276383
var core = require("jsdom/lib/jsdom/level1/core");
277384
Object.defineProperties(core.CSSStyleDeclaration.prototype,{width: WIDTH});
278385
}
386+
div.style.marginTop = "3ex";
387+
if (div.style.marginTop !== "3ex") FixValueType();
279388
}

0 commit comments

Comments
 (0)