Permalink
Browse files

Correctly handle box-shadows

Now box-shadows rects are calculated the same way as in Blink
engine.
  • Loading branch information...
1 parent 9f02fbc commit b9f7bcc11968053f7c2644e2f167e6dccdacf902 Sergey Tatarintsev committed Feb 25, 2014
Showing with 34 additions and 21 deletions.
  1. +34 −21 lib/element-rect.js
View
55 lib/element-rect.js
@@ -27,39 +27,52 @@ exports.get = function get(element) {
.then(function(rect) {
return element.getCssValue('box-shadow').then(function(boxShadow) {
var shadows = parseBoxShadow(boxShadow);
- return shadows.reduce(addBoxShadowRect, rect);
+ return adjustRect(rect, shadows);
});
});
};
function parseBoxShadow(value) {
- var regex = /.+? ((?:\d*)(?:\.\d+)?)px ((?:\d*)(?:\.\d+)?)px ((?:\d*)(?:\.\d+)?)px ((?:\d*)(?:\.\d+)?)px( inset)?/,
+ var regex = /.+? ([-+]?\d*\.?\d+)px ([-+]?\d*\.?\d+)px ([-+]?\d*\.?\d+)px ([-+]?\d*\.?\d+)px( inset)?/,
results = [],
match;
while ((match = value.match(regex))) {
- //ignore inset shadows
- if (!match[5]) {
- results.push({
- offsetX: +match[1],
- offsetY: +match[2],
- blurRadius: +match[3],
- spreadRadius: +match[4]
- });
- }
-
+ results.push({
+ offsetX: +match[1],
+ offsetY: +match[2],
+ blurRadius: +match[3],
+ spreadRadius: +match[4],
+ inset: !!match[5]
+ });
value = value.substring(match.index + match[0].length);
}
return results;
}
-function addBoxShadowRect(rect, shadow) {
- var size = shadow.blurRadius + shadow.spreadRadius,
- shadowRect = new Rect(
- rect.x + shadow.offsetX - size,
- rect.y + shadow.offsetY - size,
- rect.width - shadow.offsetX + 2 * size,
- rect.height - shadow.offsetY + 2 *size
- );
- return rect.merge(shadowRect);
+function adjustRect(rect, shadows) {
+ var extent = calculateShadowExtent(shadows);
+ return new Rect(
+ Math.max(0, rect.x + extent.left),
+ Math.max(0, rect.y + extent.top),
+ rect.width - extent.left + extent.right,
+ rect.height - extent.top + extent.bottom
+ );
+}
+
+function calculateShadowExtent(shadows) {
+ var result = {top: 0, left: 0, right: 0, bottom: 0};
+ shadows.forEach(function(shadow) {
+ if (shadow.inset) {
+ //skip inset shadows
+ return;
+ }
+
+ var blurAndSpread = shadow.spreadRadius + shadow.blurRadius;
+ result.left = Math.min(shadow.offsetX - blurAndSpread, result.left);
+ result.right = Math.max(shadow.offsetX + blurAndSpread, result.right);
+ result.top = Math.min(shadow.offsetY - blurAndSpread, result.top);
+ result.bottom = Math.max(shadow.offsetY + blurAndSpread, result.bottom);
+ });
+ return result;
}

0 comments on commit b9f7bcc

Please sign in to comment.