diff --git a/cq-prolyfill.js b/cq-prolyfill.js index e8c57be..c04ff62 100644 --- a/cq-prolyfill.js +++ b/cq-prolyfill.js @@ -1017,8 +1017,36 @@ function getContainer(element, prop) { } else { - var parentContainer = getContainer(element.parentNode, prop); + var parentNode = element.parentNode; + + // Skip to next positioned ancestor for absolute positioned elements + if (getComputedStyle(element).position === 'absolute') { + while ( + parentNode.parentNode + && parentNode.parentNode.nodeType === 1 + && ['relative', 'absolute'].indexOf(getComputedStyle(parentNode).position) === -1 + ) { + parentNode = parentNode.parentNode; + } + } + + // Skip to next ancestor with a transform applied for fixed positioned elements + if (getComputedStyle(element).position === 'fixed') { + while ( + parentNode.parentNode + && parentNode.parentNode.nodeType === 1 + && [undefined, 'none'].indexOf( + getComputedStyle(parentNode).transform + || getComputedStyle(parentNode).MsTransform + || getComputedStyle(parentNode).WebkitTransform + ) !== -1 + ) { + parentNode = parentNode.parentNode; + } + } + + var parentContainer = getContainer(parentNode, prop); while (getComputedStyle(parentNode).display === 'inline') { parentNode = parentNode.parentNode; } diff --git a/tests.js b/tests.js index 48ae36f..124405f 100644 --- a/tests.js +++ b/tests.js @@ -588,9 +588,15 @@ QUnit.test('evaluateQuery', function(assert) { }); -/*global getContainer, containerCache: true, createCacheMap*/ +/*global getContainer, styleCache: true, containerCache: true, createCacheMap*/ QUnit.test('getContainer', function(assert) { + styleCache = { + width: {}, + height: {}, + }; + containerCache = createCacheMap(); + var element = document.createElement('div'); element.innerHTML = '
'; document.body.appendChild(element); @@ -614,6 +620,27 @@ QUnit.test('getContainer', function(assert) { assert.strictEqual(getContainer(link, 'height'), span, ' display block percentage height'); assert.ok(containerCache.has(link)); + element.style.position = 'relative'; + link.style.position = 'absolute'; + containerCache = createCacheMap(); // Clear cache + assert.strictEqual(getContainer(link, 'width'), element, '
positioned ancestor'); + + span.style.position = 'absolute'; + containerCache = createCacheMap(); // Clear cache + assert.strictEqual(getContainer(link, 'width'), element, '
positioned ancestor with non-intrinsic size'); + + span.style.width = '100px'; + containerCache = createCacheMap(); // Clear cache + assert.strictEqual(getContainer(link, 'width'), span, ' positioned ancestor with fixed size'); + + link.style.position = 'fixed'; + containerCache = createCacheMap(); // Clear cache + assert.strictEqual(getContainer(link, 'width'), document.documentElement, ' fixed ancestor'); + + element.style.cssText = '-webkit-transform: translateX(0); -ms-transform: translateX(0); transform: translateX(0);'; + containerCache = createCacheMap(); // Clear cache + assert.strictEqual(getContainer(link, 'width'), element, '
ancestor with transform applied'); + document.body.removeChild(element); });