|
//!\\ Please do not use eval in your everyday production code. And create DOM elements as less times as it possible. |
|
|
|
/* vendorPrefixed */ |
|
function(s){ |
|
return eval( |
|
// Constructing the string: |
|
|
|
// Appending zero at the start, it is needed for correct syntax |
|
0 + |
|
// List of vendor prefixes. dash alone is enough to be a separator |
|
"O-Moz-Webkit-Ms-" |
|
// modifying it |
|
.replace( |
|
// Get anything until dash (ungreedy) or empty line at the end |
|
// so the replacement chunks are: <O-><Moz-><Webkit-><Ms-><> |
|
/.*?-|$/g, |
|
// Do inline replacement. "$&" is the captured string |
|
// Explaination of this mash goes further |
|
"||(s='$&"+s+"')in new Image().style&&s" |
|
) |
|
// Property names are still in dashed-css-notation and we need camelCase |
|
// Replacing all "{dash} + {any char}" into "{any char}.toUpperCase()" |
|
// There is no dashes in the generated code, so we can freely replace all. |
|
.replace( |
|
/-(.)/g, |
|
// $1 is the 1st captured parens |
|
"'+'$1'.toUpperCase()+'" |
|
) |
|
// Here we got the string ready to be evaluated |
|
) |
|
// eval() the string and return what eval returned |
|
} |
|
// If s contained a single quote, we have syntax error here. |
|
// But in real life if you need css property with quote inside, you're doing something wrong. |
|
|
|
|
|
/** END OF FILE *********************************/ |
|
|
|
/** Comments: The generated string: *************/ |
|
/* Let variable s = "transform-origin" */ |
|
/* Indented in order to be clear */ |
|
|
|
// The syntax-correction zero. This will affect nothing as it is always false */ |
|
0 || |
|
|
|
// Here we evaluating the .toUpperCase's inserted by original code */ |
|
// Only if 'string'.replace(/regexp/, ''.toUpperCase.call) worked, I shouldn't do this evil eval tricks */ |
|
(s = 'O' + 't'.toUpperCase() + 'ransform' + 'o'.toUpperCase() + 'rigin') in new Image().style && s || |
|
// After toUpperCase worked we have: |
|
//>>> (s = "OTransformOrigin") in new Image().style && s || |
|
// Assigning string to variable s. |
|
// It is already defined in function's scope as an argument, so we do not pollute the outer scope |
|
//>>> s in new Image().style && s || |
|
// new Image() is like document.createElement("img") but much shorter |
|
// So we create a new, fresh and unpolluted DOM element. And right after that getting its .style |
|
//>>> s in [[style]] && s |
|
// If s is defined in style, we get true. s is always true |
|
// So if there's no such property, we get false and go to next statement after || |
|
// But if there is such prop, the following OR's are not evaluated |
|
// And the last encountered expression is |
|
//>>> s |
|
// So eval returns first property name that exists |
|
|
|
/* Same again */ |
|
(s = 'Moz' + 't'.toUpperCase() + 'ransform' + 'o'.toUpperCase() + 'rigin') in new Image().style && s || |
|
/* and again */ |
|
(s = 'Webkit'+'t'.toUpperCase() + 'ransform' + 'o'.toUpperCase() + 'rigin') in new Image().style && s || |
|
/* and even ms- */ |
|
(s = 'Ms' + 't'.toUpperCase() + 'ransform' + 'o'.toUpperCase() + 'rigin') in new Image().style && s || |
|
/* and finally without any vendor prefixes */ |
|
(s = 'transform' + 'o'.toUpperCase() + 'rigin') in new Image().style && s |
|
|
|
/* And here it ends. If nothing matched, return false */ |
@tsaniel, your function is faster, but I don't think that anyone should use 140bytes entries in production, so we can sacrifice size to speed only when it fits into 140 bytes. And it seems that you've forgot about Opera's
-o-.(Well… okay, to be honest, I used this function in production. A little)
By the way, I suppose, it's time to introduce something like 140mseconds. It would be hard to judge, though.