Merge pull request #546 from finn-no/vendor-prefixes
Vendor prefix detection. Thanks @gregersrygg for this excellent contribution.
This commit is contained in:
@@ -132,6 +132,7 @@
|
||||
jsFiles = [
|
||||
"OpenLayers/BaseTypes/Class.js",
|
||||
"OpenLayers/Util.js",
|
||||
"OpenLayers/Util/vendorPrefix.js",
|
||||
"OpenLayers/Animation.js",
|
||||
"OpenLayers/BaseTypes.js",
|
||||
"OpenLayers/BaseTypes/Bounds.js",
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* full text of the license.
|
||||
*
|
||||
* @requires OpenLayers/SingleFile.js
|
||||
* @requires OpenLayers/Util/vendorPrefix.js
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -19,11 +20,8 @@ OpenLayers.Animation = (function(window) {
|
||||
* Property: isNative
|
||||
* {Boolean} true if a native requestAnimationFrame function is available
|
||||
*/
|
||||
var isNative = !!(window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.oRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame);
|
||||
var requestAnimationFrame = OpenLayers.Util.vendorPrefix.js(window, "requestAnimationFrame");
|
||||
var isNative = !!(requestAnimationFrame);
|
||||
|
||||
/**
|
||||
* Function: requestFrame
|
||||
@@ -36,11 +34,7 @@ OpenLayers.Animation = (function(window) {
|
||||
* element - {DOMElement} Optional element that visually bounds the animation.
|
||||
*/
|
||||
var requestFrame = (function() {
|
||||
var request = window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.oRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame ||
|
||||
var request = window[requestAnimationFrame] ||
|
||||
function(callback, element) {
|
||||
window.setTimeout(callback, 16);
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* full text of the license. */
|
||||
|
||||
/**
|
||||
* @requires OpenLayers/Util/vendorPrefix.js
|
||||
* @requires OpenLayers/Handler/Pinch.js
|
||||
*/
|
||||
|
||||
@@ -162,8 +163,10 @@ OpenLayers.Control.PinchZoom = OpenLayers.Class(OpenLayers.Control, {
|
||||
*/
|
||||
applyTransform: function(transform) {
|
||||
var style = this.map.layerContainerDiv.style;
|
||||
style['-webkit-transform'] = transform;
|
||||
style['-moz-transform'] = transform;
|
||||
var transformProperty = OpenLayers.Util.vendorPrefix.style("transform");
|
||||
if (transformProperty) {
|
||||
style[transformProperty] = transform;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
131
lib/OpenLayers/Util/vendorPrefix.js
Normal file
131
lib/OpenLayers/Util/vendorPrefix.js
Normal file
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
|
||||
* full list of contributors). Published under the 2-clause BSD license.
|
||||
* See license.txt in the OpenLayers distribution or repository for the
|
||||
* full text of the license.
|
||||
*
|
||||
* @requires OpenLayers/SingleFile.js
|
||||
*/
|
||||
|
||||
OpenLayers.Util = OpenLayers.Util || {};
|
||||
/**
|
||||
* Namespace: OpenLayers.Util.vendorPrefix
|
||||
* A collection of utility functions to detect vendor prefixed features
|
||||
*/
|
||||
OpenLayers.Util.vendorPrefix = (function() {
|
||||
"use strict";
|
||||
|
||||
var VENDOR_PREFIXES = ["", "O", "ms", "Moz", "Webkit"],
|
||||
divStyle = document.createElement("div").style,
|
||||
cssCache = {},
|
||||
jsCache = {};
|
||||
|
||||
|
||||
/**
|
||||
* Function: domToCss
|
||||
* Converts a upper camel case DOM style property name to a CSS property
|
||||
* i.e. transformOrigin -> transform-origin
|
||||
* or WebkitTransformOrigin -> -webkit-transform-origin
|
||||
*
|
||||
* Parameters:
|
||||
* prefixedDom - {String} The property to convert
|
||||
*
|
||||
* Returns:
|
||||
* {String} The CSS property
|
||||
*/
|
||||
function domToCss(prefixedDom) {
|
||||
if (!prefixedDom) { return null; }
|
||||
return prefixedDom.
|
||||
replace(/([A-Z])/g, function(c) { return "-" + c.toLowerCase(); }).
|
||||
replace(/^ms-/, "-ms-");
|
||||
}
|
||||
|
||||
/**
|
||||
* APIMethod: css
|
||||
* Detect which property is used for a CSS property
|
||||
*
|
||||
* Parameters:
|
||||
* property - {String} The standard (unprefixed) CSS property name
|
||||
*
|
||||
* Returns:
|
||||
* {String} The standard CSS property, prefixed property or null if not
|
||||
* supported
|
||||
*/
|
||||
function css(property) {
|
||||
if (cssCache[property] === undefined) {
|
||||
var domProperty = property.
|
||||
replace(/(-[\s\S])/g, function(c) { return c.charAt(1).toUpperCase(); });
|
||||
var prefixedDom = style(domProperty);
|
||||
cssCache[property] = domToCss(prefixedDom);
|
||||
}
|
||||
return cssCache[property];
|
||||
}
|
||||
|
||||
/**
|
||||
* APIMethod: js
|
||||
* Detect which property is used for a JS property/method
|
||||
*
|
||||
* Parameters:
|
||||
* obj - {Object} The object to test on
|
||||
* property - {String} The standard (unprefixed) JS property name
|
||||
*
|
||||
* Returns:
|
||||
* {String} The standard JS property, prefixed property or null if not
|
||||
* supported
|
||||
*/
|
||||
function js(obj, property) {
|
||||
if (jsCache[property] === undefined) {
|
||||
var tmpProp,
|
||||
i = 0,
|
||||
l = VENDOR_PREFIXES.length,
|
||||
prefix,
|
||||
isStyleObj = (typeof obj.cssText !== "undefined");
|
||||
|
||||
jsCache[property] = null;
|
||||
for(; i<l; i++) {
|
||||
prefix = VENDOR_PREFIXES[i];
|
||||
if(prefix) {
|
||||
if (!isStyleObj) {
|
||||
// js prefix should be lower-case, while style
|
||||
// properties have upper case on first character
|
||||
prefix = prefix.toLowerCase();
|
||||
}
|
||||
tmpProp = prefix + property.charAt(0).toUpperCase() + property.slice(1);
|
||||
} else {
|
||||
tmpProp = property;
|
||||
}
|
||||
|
||||
if(obj[tmpProp] !== undefined) {
|
||||
jsCache[property] = tmpProp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return jsCache[property];
|
||||
}
|
||||
|
||||
/**
|
||||
* APIMethod: style
|
||||
* Detect which property is used for a DOM style property
|
||||
*
|
||||
* Parameters:
|
||||
* property - {String} The standard (unprefixed) style property name
|
||||
*
|
||||
* Returns:
|
||||
* {String} The standard style property, prefixed property or null if not
|
||||
* supported
|
||||
*/
|
||||
function style(property) {
|
||||
return js(divStyle, property);
|
||||
}
|
||||
|
||||
return {
|
||||
css: css,
|
||||
js: js,
|
||||
style: style,
|
||||
|
||||
// used for testing
|
||||
cssCache: cssCache,
|
||||
jsCache: jsCache
|
||||
};
|
||||
}());
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
// dependencies for tests
|
||||
var OpenLayers = [
|
||||
"OpenLayers/Util/vendorPrefix.js",
|
||||
"OpenLayers/Animation.js"
|
||||
];
|
||||
|
||||
|
||||
117
tests/Util/vendorPrefix.html
Normal file
117
tests/Util/vendorPrefix.html
Normal file
@@ -0,0 +1,117 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>vendorPrefix.js Tests</title>
|
||||
<script>
|
||||
var div = document.createElement("div");
|
||||
var style = div.style,
|
||||
orgCreateElement = document.createElement;
|
||||
|
||||
// wrap document.createElement to control property values
|
||||
document.createElement = function(type) {
|
||||
return div;
|
||||
};
|
||||
|
||||
// dependencies for tests
|
||||
var OpenLayers = [
|
||||
"OpenLayers/Util/vendorPrefix.js"
|
||||
];
|
||||
|
||||
</script>
|
||||
<script src="../OLLoader.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
/**
|
||||
* Test vendor prefixing
|
||||
*/
|
||||
function test_vendor_prefixes(t) {
|
||||
t.plan(20);
|
||||
var err;
|
||||
|
||||
function clearCache(type) {
|
||||
var cache = OpenLayers.Util.vendorPrefix[type.replace("style", "js") + "Cache"];
|
||||
for (var key in cache) {
|
||||
delete cache[key];
|
||||
}
|
||||
}
|
||||
|
||||
function setStyleMockProp(prop, value) {
|
||||
if (prop && value === undefined) {
|
||||
delete style[prop];
|
||||
} else if (prop) {
|
||||
style[prop] = value;
|
||||
}
|
||||
}
|
||||
|
||||
function curryTestPrefix(type) {
|
||||
return function(standardProp, expectedPrefix, msg) {
|
||||
var prefixedProp, err;
|
||||
try {
|
||||
clearCache(type);
|
||||
setStyleMockProp(expectedPrefix, "");
|
||||
prefixedProp = OpenLayers.Util.vendorPrefix[type](standardProp);
|
||||
} catch(e) {
|
||||
err = e;
|
||||
} finally {
|
||||
setStyleMockProp(expectedPrefix, undefined);
|
||||
}
|
||||
|
||||
if(!err) {
|
||||
t.eq(prefixedProp, expectedPrefix, msg);
|
||||
} else {
|
||||
t.fail("Error when testing " + type.toUpperCase() + " vendor prefix: " + err.message);
|
||||
}
|
||||
};
|
||||
}
|
||||
var testDomPrefix = curryTestPrefix("style"),
|
||||
testCssPrefix = curryTestPrefix("css");
|
||||
|
||||
testDomPrefix("unsupported", null, "DOM vendor prefix - unsupported");
|
||||
testCssPrefix("unsupported", null, "CSS vendor prefix - unsupported");
|
||||
|
||||
testDomPrefix("test", "test", "DOM vendor prefix - single word");
|
||||
testCssPrefix("test", "test", "CSS vendor prefix - single word");
|
||||
|
||||
testDomPrefix("testMultiWord", "testMultiWord", "DOM vendor prefix - multiple words");
|
||||
testCssPrefix("test-multi-word", "test-multi-word", "CSS vendor prefix - multiple words");
|
||||
|
||||
testDomPrefix("multiWord", "WebkitMultiWord", "DOM vendor prefix - multiple words for WebKit");
|
||||
testCssPrefix("multi-word", "-webkit-multi-word", "CSS vendor prefix - multiple words for WebKit");
|
||||
|
||||
testDomPrefix("multiWord", "MozMultiWord", "DOM vendor prefix - multiple words for Mozilla");
|
||||
testCssPrefix("multi-word", "-moz-multi-word", "CSS vendor prefix - multiple words for Mozilla");
|
||||
|
||||
testDomPrefix("multiWord", "OMultiWord", "DOM vendor prefix - multiple words for Opera");
|
||||
testCssPrefix("multi-word", "-o-multi-word", "CSS vendor prefix - multiple words for Opera");
|
||||
|
||||
testDomPrefix("multiWord", "msMultiWord", "DOM vendor prefix - multiple words for Internet Explorer");
|
||||
testCssPrefix("multi-word", "-ms-multi-word", "CSS vendor prefix - multiple words for Internet Explorer");
|
||||
|
||||
// test vendor prefix on object
|
||||
clearCache("js");
|
||||
t.eq( OpenLayers.Util.vendorPrefix.js( {}, "unsupported" ), null, "Standard object property - unsupported");
|
||||
|
||||
clearCache("js");
|
||||
t.eq( OpenLayers.Util.vendorPrefix.js( { "test": true }, "test" ), "test", "Standard object property");
|
||||
|
||||
clearCache("js");
|
||||
t.eq( OpenLayers.Util.vendorPrefix.js( { "oTest": true }, "test" ), "oTest", "Standard object property");
|
||||
|
||||
clearCache("js");
|
||||
t.eq( OpenLayers.Util.vendorPrefix.js( { "msTest": true }, "test" ), "msTest", "Standard object property");
|
||||
|
||||
clearCache("js");
|
||||
t.eq( OpenLayers.Util.vendorPrefix.js( { "mozTest": true }, "test" ), "mozTest", "Standard object property");
|
||||
|
||||
clearCache("js");
|
||||
t.eq( OpenLayers.Util.vendorPrefix.js( { "webkitTest": true }, "test" ), "webkitTest", "Standard object property");
|
||||
|
||||
// unwrap document.createElement
|
||||
document.createElement = orgCreateElement;
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
@@ -231,6 +231,7 @@
|
||||
<li>Tween.html</li>
|
||||
<li>Kinetic.html</li>
|
||||
<li>Util.html</li>
|
||||
<li>Util/vendorPrefix.html</li>
|
||||
<li>deprecated/Ajax.html</li>
|
||||
<li>deprecated/Util.html</li>
|
||||
<li>deprecated/BaseTypes/Class.html</li>
|
||||
|
||||
Reference in New Issue
Block a user