Skip to content

Instantly share code, notes, and snippets.

@termi
Last active December 12, 2015 01:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save termi/4691008 to your computer and use it in GitHub Desktop.
Save termi/4691008 to your computer and use it in GitHub Desktop.
getComputedStyle for IE < 9
void function() {
var global = this
/** @const */
, _Array_slice = Array.prototype.slice
/** @const */
, _Function_apply = Function.prototype.apply
/** @const */
, _Function_call = Function.prototype.call
/** Use native "bind" or unsafe bind for service and performance needs
* @const
* @param {Object} object
* @param {...} var_args
* @return {Function} */
, _unSafeBind = Function.prototype.bind || function(object, var_args) {
var __method = this,
args = _Array_slice.call(arguments, 1);
return function () {
return _Function_apply.call(__method, object, args.concat(_Array_slice.call(arguments)));
}
}
/** @const */
, STRING_FOR_RE_style_important = "\\s*:\\s*(\\S+)\\s*(?:[$;]|(?:(!important)\\s*[$;]))"
, _CSSStyleDeclaration_prototype_methods = {
/**
* @param {String} propertyName
* @return String
*/
"getPropertyValue" : function(propertyName) {
return this.getAttribute(propertyName);
}
/**
* @param {String} propertyName
* @return String
*/
, "removeProperty" : function(propertyName) {
this.removeAttribute(propertyName);
}
/**
* @param {String} propertyName
* @param {String} value
* @param {String} priority
* @return void
*/
, "setProperty" : function(propertyName, value, priority) {
if(priority != "important") {
this.setAttribute(propertyName, value);
}
else {
var reg = new RegExp(propertyName + STRING_FOR_RE_style_important, "i")
, val = ";" + propertyName + ":" + value + " !important;"
;
if(reg.test(this.cssText)) {
this.cssText = this.cssText.replace(reg, val)
}
else this.cssText = this.cssText + val;
}
}
/**
@param {String} propertyName
@return String
*/
, "getPropertyPriority" : function(propertyName) {
var reg = new RegExp(propertyName + STRING_FOR_RE_style_important, "i");
return ((this.cssText || "").match(reg) || [])[2] || "";
}
/**
@param {Number} index
@return String
*/
, "item" : function(index) {
//TODO::
}
}
/** @const */
, RE_style_alpha_filter = /alpha\(opacity=([^\)]+)\)/
/** @type {Function}
* @this {Node} */
, style_getOpacityFromMSFilter = function() {
var val = (this.filter || "").match(RE_style_alpha_filter);
return val ? (parseInt(val[1]) / 100) + "" : "";//can't replace parseInt to '+(val[1])'
}
, _throwDOMException = function(msg) {
throw new Error(msg);
}
;
if( /\[native\scode\]/.test( global.getComputedStyle ) )return;
/**
* @link https://developer.mozilla.org/en/DOM/window.getComputedStyle
* getCurrentStyle - функция возвращяет текущий стиль элемента
* @param {?Node} element HTML-Элемент
* @param {?string} pseudoElt A string specifying the pseudo-element to match. Must be null (or not specified) for regular elements.
* @this {Window}
* @return {CSSStyleDeclaration} Стиль элемента
*/
global.getComputedStyle = function(element, pseudoElt) {
var _currentStyle = element.currentStyle || element.runtimeStyle;
if(!("getPropertyValue" in _currentStyle)) {
element.runtimeStyle.getPropertyValue = _CSSStyleDeclaration_prototype_methods["getPropertyValue"].bind(element);
element.runtimeStyle.setProperty = element.runtimeStyle.removeProperty = function() {
_throwDOMException("NO_MODIFICATION_ALLOWED_ERR");
};
element.runtimeStyle.getPropertyPriority = function(propertyName) {
//TODO: tests
return "";
};
element.runtimeStyle.item = _CSSStyleDeclaration_prototype_methods["item"];
}
var propDescription
, _CSSStyleDeclProt
;
if((_CSSStyleDeclProt = global["CSSStyleDeclaration"]) && (_CSSStyleDeclProt = _CSSStyleDeclProt.prototype) && (!("float" in _currentStyle) || !("opacity" in _currentStyle))) {
if(!("float" in _currentStyle)) {//TODO:: testing
propDescription = Object.getOwnPropertyDescriptor(_CSSStyleDeclProt, "float");
if(propDescription) {
delete _CSSStyleDeclProt["float"];
}
Object.defineProperty(element.runtimeStyle, "float", {
value : {
valueOf : _unSafeBind.call(function(){
return this.runtimeStyle.styleFloat || this.style.styleFloat
}, element)
}
});
if(propDescription) {
Object.defineProperty(_CSSStyleDeclProt, "float", propDescription);
}
}
if(!("opacity" in _currentStyle)) {//TODO:: testing
propDescription = Object.getOwnPropertyDescriptor(_CSSStyleDeclProt, "opacity");
if(propDescription) {
delete _CSSStyleDeclProt["opacity"];
}
Object.defineProperty(element.runtimeStyle, "opacity", {
value : {
valueOf : _unSafeBind.call(function(){
return this.runtimeStyle["msOpacity"] || this.style["msOpacity"] || style_getOpacityFromMSFilter.call(this.style) || style_getOpacityFromMSFilter.call(this.runtimeStyle);
}, element)
}
});
if(propDescription) {
Object.defineProperty(_CSSStyleDeclProt, "opacity", propDescription);
}
}
}
else {
if(!("float" in _currentStyle)) {
element.runtimeStyle["float"] = {
valueOf : _unSafeBind.call(function(){
return this.runtimeStyle.styleFloat || this.style.styleFloat
}, element)
}
}
if(!("opacity" in _currentStyle)) {
element.runtimeStyle["opacity"] = {
valueOf : _unSafeBind.call(function(){
return this.runtimeStyle["msOpacity"] || this.style["msOpacity"] || style_getOpacityFromMSFilter.call(this.style) || style_getOpacityFromMSFilter.call(this.runtimeStyle);
}, element)
}
}
}
return element.currentStyle;
}
}.call(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment