CSS transform detection when DOM is ready

The code to detect CSS transforms requires a DOM to append an
element to. By performing this action when first called instead
of unconditionally upon library load, we can load OpenLayers in
the document's head again.
This commit is contained in:
ahocevar
2014-02-15 10:48:04 +01:00
parent a549df459b
commit 81f7ea106b

View File

@@ -12,80 +12,98 @@ goog.require('goog.vec.Mat4');
/**
* http://caniuse.com/#feat=transforms2d
* http://caniuse.com/#feat=transforms3d
* @enum {boolean}
*/
ol.dom.BrowserFeature = {
CAN_USE_CSS_TRANSFORM: (
/**
* Detect 2d transform.
* Adapted from http://stackoverflow.com/q/5661671/130442
* @return {boolean}
*/
function() {
if (!window.getComputedStyle) {
// this browser is ancient
return false;
}
var el = goog.dom.createElement(goog.dom.TagName.P),
has2d,
transforms = {
'webkitTransform': '-webkit-transform',
'OTransform': '-o-transform',
'msTransform': '-ms-transform',
'MozTransform': '-moz-transform',
'transform': 'transform'
};
goog.dom.appendChild(document.body, el);
for (var t in transforms) {
if (t in el.style) {
el.style[t] = 'translate(1px,1px)';
has2d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
}
}
goog.dom.removeNode(el);
return (goog.isDefAndNotNull(has2d) && has2d.length > 0 &&
has2d !== 'none');
})(),
CAN_USE_CSS_TRANSFORM3D: (
/**
* Detect 3d transform.
* Adapted from http://stackoverflow.com/q/5661671/130442
* @return {boolean}
*/
function() {
if (!window.getComputedStyle) {
// this browser is ancient
return false;
}
var el = goog.dom.createElement(goog.dom.TagName.P),
has3d,
transforms = {
'webkitTransform': '-webkit-transform',
'OTransform': '-o-transform',
'msTransform': '-ms-transform',
'MozTransform': '-moz-transform',
'transform': 'transform'
};
goog.dom.appendChild(document.body, el);
for (var t in transforms) {
if (t in el.style) {
el.style[t] = 'translate3d(1px,1px,1px)';
has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
}
}
goog.dom.removeNode(el);
return (goog.isDefAndNotNull(has3d) && has3d.length > 0 &&
has3d !== 'none');
})(),
USE_MS_MATRIX_TRANSFORM: ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE,
USE_MS_ALPHA_FILTER: ol.LEGACY_IE_SUPPORT && ol.IS_LEGACY_IE
};
/**
* Detect 2d transform.
* Adapted from http://stackoverflow.com/q/5661671/130442
* http://caniuse.com/#feat=transforms2d
* @return {boolean}
*/
ol.dom.canUseCssTransform = function() {
goog.asserts.assert(!goog.isNull(document.body));
var canUseCssTransform;
if (!goog.isDef(canUseCssTransform)) {
canUseCssTransform = (function() {
if (!goog.global.getComputedStyle) {
// this browser is ancient
return false;
}
var el = goog.dom.createElement(goog.dom.TagName.P),
has2d,
transforms = {
'webkitTransform': '-webkit-transform',
'OTransform': '-o-transform',
'msTransform': '-ms-transform',
'MozTransform': '-moz-transform',
'transform': 'transform'
};
goog.dom.appendChild(document.body, el);
for (var t in transforms) {
if (t in el.style) {
el.style[t] = 'translate(1px,1px)';
has2d = goog.global.getComputedStyle(el).getPropertyValue(
transforms[t]);
}
}
goog.dom.removeNode(el);
return (goog.isDefAndNotNull(has2d) && has2d.length > 0 &&
has2d !== 'none');
}());
}
return canUseCssTransform;
};
/**
* Detect 3d transform.
* Adapted from http://stackoverflow.com/q/5661671/130442
* http://caniuse.com/#feat=transforms3d
* @return {boolean}
*/
ol.dom.canUseCssTransform3D = function() {
goog.asserts.assert(!goog.isNull(document.body));
var canUseCssTransform3D;
if (!goog.isDef(canUseCssTransform3D)) {
canUseCssTransform3D = (function() {
if (!goog.global.getComputedStyle) {
// this browser is ancient
return false;
}
var el = goog.dom.createElement(goog.dom.TagName.P),
has3d,
transforms = {
'webkitTransform': '-webkit-transform',
'OTransform': '-o-transform',
'msTransform': '-ms-transform',
'MozTransform': '-moz-transform',
'transform': 'transform'
};
goog.dom.appendChild(document.body, el);
for (var t in transforms) {
if (t in el.style) {
el.style[t] = 'translate3d(1px,1px,1px)';
has3d = goog.global.getComputedStyle(el).getPropertyValue(
transforms[t]);
}
}
goog.dom.removeNode(el);
return (goog.isDefAndNotNull(has3d) && has3d.length > 0 &&
has3d !== 'none');
}());
}
return canUseCssTransform3D;
};
/**
* @param {Element} element Element.
* @param {string} value Value.
@@ -183,7 +201,7 @@ ol.dom.transformElement2D =
// using matrix() causes gaps in Chrome and Firefox on Mac OS X, so prefer
// matrix3d()
var i;
if (ol.dom.BrowserFeature.CAN_USE_CSS_TRANSFORM3D) {
if (ol.dom.canUseCssTransform3D()) {
var value3D;
if (goog.isDef(opt_precision)) {
@@ -197,7 +215,7 @@ ol.dom.transformElement2D =
value3D = transform.join(',');
}
ol.dom.setTransform(element, 'matrix3d(' + value3D + ')');
} else if (ol.dom.BrowserFeature.CAN_USE_CSS_TRANSFORM) {
} else if (ol.dom.canUseCssTransform()) {
/** @type {Array.<number>} */
var transform2D = [
goog.vec.Mat4.getElement(transform, 0, 0),