Skip to content

Commit

Permalink
Improve performance and file size of getContainer(), #47
Browse files Browse the repository at this point in the history
  • Loading branch information
ausi committed Jun 15, 2017
1 parent cc459da commit 203f11a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 53 deletions.
60 changes: 25 additions & 35 deletions cq-prolyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,7 @@ function evaluateQuery(parent, query) {
cValue = getSize(container, query._prop);
}
else {
cValue = getComputedStyle(container).getPropertyValue(query._prop);
cValue = getComputedStyle(container, query._prop);
}

if (query._filter) {
Expand Down Expand Up @@ -1000,7 +1000,7 @@ function getContainer(element, prop) {

else if (prop !== 'width' && prop !== 'height') {
// Skip transparent background colors
if (prop === 'background-color' && !parseColor(getComputedStyle(element).getPropertyValue(prop))[3]) {
if (prop === 'background-color' && !parseColor(getComputedStyle(element, prop))[3]) {
cache[prop] = getContainer(element.parentNode, prop);
}
else {
Expand All @@ -1009,7 +1009,7 @@ function getContainer(element, prop) {
}

// Skip inline elements
else if (getComputedStyle(element).display === 'inline') {
else if (getComputedStyle(element, 'display') === 'inline') {
cache[prop] = getContainer(element.parentNode, prop);
}

Expand All @@ -1022,33 +1022,33 @@ function getContainer(element, prop) {
var parentNode = element.parentNode;

// Skip to next positioned ancestor for absolute positioned elements
if (getComputedStyle(element).position === 'absolute') {
if (getComputedStyle(element, 'position') === 'absolute') {
while (
parentNode.parentNode
&& parentNode.parentNode.nodeType === 1
&& ['relative', 'absolute'].indexOf(getComputedStyle(parentNode).position) === -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') {
if (getComputedStyle(element, 'position') === 'fixed') {
while (
parentNode.parentNode
&& parentNode.parentNode.nodeType === 1
&& [undefined, 'none'].indexOf(
getComputedStyle(parentNode).transform
|| getComputedStyle(parentNode).MsTransform
|| getComputedStyle(parentNode).WebkitTransform
getComputedStyle(parentNode, 'transform')
|| getComputedStyle(parentNode, 'MsTransform')
|| getComputedStyle(parentNode, 'WebkitTransform')
) !== -1
) {
parentNode = parentNode.parentNode;
}
}

var parentContainer = getContainer(parentNode, prop);
while (getComputedStyle(parentNode).display === 'inline') {
while (getComputedStyle(parentNode, 'display') === 'inline') {
parentNode = parentNode.parentNode;
}
if (parentNode === parentContainer && !isIntrinsicSize(element, prop)) {
Expand Down Expand Up @@ -1090,23 +1090,23 @@ function isFixedSize(element, prop) {
*/
function isIntrinsicSize(element, prop) {

var computedStyle = getComputedStyle(element);
var display = getComputedStyle(element, 'display');

if (computedStyle.display === 'none') {
if (display === 'none') {
return false;
}

if (computedStyle.display === 'inline') {
if (display === 'inline') {
return true;
}

// Non-floating non-absolute block elements (only width)
if (
prop === 'width'
&& ['block', 'list-item', 'flex', 'grid'].indexOf(computedStyle.display) !== -1
&& computedStyle.cssFloat === 'none'
&& computedStyle.position !== 'absolute'
&& computedStyle.position !== 'fixed'
&& ['block', 'list-item', 'flex', 'grid'].indexOf(display) !== -1
&& getComputedStyle(element, 'float') === 'none'
&& getComputedStyle(element, 'position') !== 'absolute'
&& getComputedStyle(element, 'position') !== 'fixed'
) {
return false;
}
Expand Down Expand Up @@ -1141,7 +1141,7 @@ function isIntrinsicSize(element, prop) {
* @return {number}
*/
function getSize(element, prop) {
var style = getComputedStyle(element);
var style = window.getComputedStyle(element);
if (prop === 'width') {
return element.offsetWidth
- parseFloat(style.borderLeftWidth)
Expand Down Expand Up @@ -1194,39 +1194,29 @@ function getComputedLength(value, element) {
if (unit === 'ex') {
value /= 2;
}
return parseFloat(getComputedStyle(element).fontSize) * value;
return parseFloat(getComputedStyle(element, 'fontSize')) * value;
}

/**
* @param {Element} element
* @return {CSSStyleDeclaration}
*/
function getComputedStyle(element) {
function getComputedStyle(element, prop) {

var style = window.getComputedStyle(element);

var value = style[prop] || style.getPropertyValue(prop);

// Fix display inline in some browsers
if (style.display === 'inline' && (
if (value === 'inline' && prop === 'display' && (
style.position === 'absolute'
|| style.position === 'fixed'
|| style.cssFloat !== 'none'
)) {
var newStyle = {};
for (var prop in style) {
if (typeof style[prop] === 'string') {
newStyle[prop] = style[prop];
}
}
style = newStyle;
style.display = 'block';
style.getPropertyValue = function(property) {
return this[property.replace(/-+(.)/g, function(match, char) {
return char.toUpperCase();
})];
};
return 'block';
}

return style;
return value;

}

Expand Down
36 changes: 18 additions & 18 deletions tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ QUnit[/Opera\/9\.80\s.*Version\/12\.16/.test(navigator.userAgent)
assert.equal(getOriginalStyle(element, 'width'), '20%', 'Container Query with crossOrigin');
load('cors.css', false, false, function() {
assert.ok(getOriginalStyle(element, 'width') === undefined || getOriginalStyle(element, 'width') === '10%', 'Non-CORS Style Stylesheet');
assert.equal(getComputedStyle(element).color, 'rgb(255, 0, 0)', 'Non-CORS Style Stylesheet computed style');
assert.equal(getComputedStyle(element, 'color'), 'rgb(255, 0, 0)', 'Non-CORS Style Stylesheet computed style');
load('cors.css', true, false, function() {
assert.ok(getOriginalStyle(element, 'width') === undefined || getOriginalStyle(element, 'width') === '10%', 'Non-CORS Style Stylesheet with crossOrigin');
if ('crossOrigin' in document.createElement('link')) {
assert.equal(getComputedStyle(element).color, 'rgb(0, 0, 0)', 'Non-CORS Style Stylesheet with crossOrigin computed style (crossOrigin supported)');
assert.equal(getComputedStyle(element, 'color'), 'rgb(0, 0, 0)', 'Non-CORS Style Stylesheet with crossOrigin computed style (crossOrigin supported)');
}
else {
assert.equal(getComputedStyle(element).color, 'rgb(255, 0, 0)', 'Non-CORS Style Stylesheet with crossOrigin computed style (crossOrigin not supported)');
assert.equal(getComputedStyle(element, 'color'), 'rgb(255, 0, 0)', 'Non-CORS Style Stylesheet with crossOrigin computed style (crossOrigin not supported)');
}
load('cors-with-cq.css', false, false, function() {
assert.strictEqual(getOriginalStyle(element, 'width'), undefined, 'Non-CORS Container Query');
Expand Down Expand Up @@ -93,7 +93,7 @@ QUnit.test('DOM Mutations', function(assert) {
delete config.skipObserving;
startObserving();

assert.equal(getComputedStyle(element).display, 'block', 'Display block');
assert.equal(getComputedStyle(element, 'display'), 'block', 'Display block');

var style = document.createElement('style');
style.type = 'text/css';
Expand All @@ -102,7 +102,7 @@ QUnit.test('DOM Mutations', function(assert) {

requestAnimationFrame(function() { setTimeout(function() {

assert.equal(getComputedStyle(element).display, 'none', 'Display none');
assert.equal(getComputedStyle(element, 'display'), 'none', 'Display none');

var element2 = document.createElement('div');
element2.className = 'mutations-test';
Expand All @@ -115,18 +115,18 @@ QUnit.test('DOM Mutations', function(assert) {

requestAnimationFrame(function() { setTimeout(function() {

assert.equal(getComputedStyle(element2).display, 'none', 'Display none');
assert.equal(getComputedStyle(element2, 'display'), 'none', 'Display none');

fixture.appendChild(element3);
assert.equal(getComputedStyle(element3).display, 'block', 'Display block');
assert.equal(getComputedStyle(element3, 'display'), 'block', 'Display block');

fixture.removeChild(style);

requestAnimationFrame(function() { setTimeout(function() {

assert.equal(getComputedStyle(element).display, 'block', 'Display block');
assert.equal(getComputedStyle(element2).display, 'block', 'Display block');
assert.equal(getComputedStyle(element3).display, 'block', 'Display block');
assert.equal(getComputedStyle(element, 'display'), 'block', 'Display block');
assert.equal(getComputedStyle(element2, 'display'), 'block', 'Display block');
assert.equal(getComputedStyle(element3, 'display'), 'block', 'Display block');

// Cleanup
if (observer) {
Expand Down Expand Up @@ -798,15 +798,15 @@ QUnit.test('getComputedStyle', function(assert) {
element.style.height = '1in';
element.style.cssFloat = 'left';
fixture.appendChild(element);
assert.equal(getComputedStyle(element).width, '100px', 'Normal style');
assert.equal(getComputedStyle(element).height, '96px', 'Converted to pixel');
assert.equal(getComputedStyle(element).cssFloat, 'left', 'Float left');
assert.equal(getComputedStyle(element).display, 'block', 'Default style');
assert.equal(getComputedStyle(element, 'width'), '100px', 'Normal style');
assert.equal(getComputedStyle(element, 'height'), '96px', 'Converted to pixel');
assert.equal(getComputedStyle(element, 'float'), 'left', 'Float left');
assert.equal(getComputedStyle(element, 'cssFloat'), 'left', 'Float left cssFloat');
assert.equal(getComputedStyle(element, 'display'), 'block', 'Default style');
element.style.cssText = 'display: inline; float: left; font-size: 10px';
assert.equal(getComputedStyle(element).display, 'block', 'Correct display value');
assert.equal(getComputedStyle(element).getPropertyValue('display'), 'block', 'Correct display value via getPropertyValue');
assert.equal(getComputedStyle(element).fontSize, '10px', 'Correct font-size value');
assert.equal(getComputedStyle(element).getPropertyValue('font-size'), '10px', 'Correct font-size value via getPropertyValue');
assert.equal(getComputedStyle(element, 'display'), 'block', 'Correct display value');
assert.equal(getComputedStyle(element, 'fontSize'), '10px', 'Correct font-size value');
assert.equal(getComputedStyle(element, 'font-size'), '10px', 'Correct font-size value via getPropertyValue');
});

/*global getOriginalStyle, buildStyleCache*/
Expand Down

0 comments on commit 203f11a

Please sign in to comment.