gemini-core
Version:
Utility which contains common modules for gemini and hermione
118 lines (106 loc) • 4.8 kB
JavaScript
/**
* Adapted from: https://raw.githubusercontent.com/Financial-Times/polyfill-service
*/
function getComputedStylePixel(element, property, fontSize) {
var
// Internet Explorer sometimes struggles to read currentStyle until the element's document is accessed.
value = element.document && element.currentStyle[property].match(/([\d\.]+)(%|cm|em|in|mm|pc|pt|)/) || [0, 0, ''],
size = value[1],
suffix = value[2],
rootSize;
fontSize = !fontSize ? fontSize : /%|em/.test(suffix) && element.parentElement ? getComputedStylePixel(element.parentElement, 'fontSize', null) : 16;
rootSize = property === 'fontSize' ? fontSize : /width/i.test(property) ? element.clientWidth : element.clientHeight;
return suffix === '%' ? size / 100 * rootSize :
suffix === 'cm' ? size * 0.3937 * 96 :
suffix === 'em' ? size * fontSize :
suffix === 'in' ? size * 96 :
suffix === 'mm' ? size * 0.3937 * 96 / 10 :
suffix === 'pc' ? size * 12 * 96 / 72 :
suffix === 'pt' ? size * 96 / 72 :
size;
}
function setShortStyleProperty(style, property) {
var
borderSuffix = property === 'border' ? 'Width' : '',
t = property + 'Top' + borderSuffix,
r = property + 'Right' + borderSuffix,
b = property + 'Bottom' + borderSuffix,
l = property + 'Left' + borderSuffix;
style[property] = (style[t] === style[r] && style[t] === style[b] && style[t] === style[l] ? [style[t]] :
style[t] === style[b] && style[l] === style[r] ? [style[t], style[r]] :
style[l] === style[r] ? [style[t], style[r], style[b]] :
[style[t], style[r], style[b], style[l]]).join(' ');
}
// <CSSStyleDeclaration>
function CSSStyleDeclaration(element) {
var currentStyle = element.currentStyle,
fontSize = getComputedStylePixel(element, 'fontSize'),
unCamelCase = function(match) {
return '-' + match.toLowerCase();
},
property;
for (property in currentStyle) {
Array.prototype.push.call(this, property === 'styleFloat' ? 'float' : property.replace(/[A-Z]/, unCamelCase));
if (property === 'width') {
this[property] = element.offsetWidth + 'px';
} else if (property === 'height') {
this[property] = element.offsetHeight + 'px';
} else if (property === 'styleFloat') {
this.float = currentStyle[property];
} else if (/margin.|padding.|border.+W/.test(property) && this[property] !== 'auto') {
this[property] = Math.round(getComputedStylePixel(element, property, fontSize)) + 'px';
} else if (/^outline/.test(property)) {
// errors on checking outline
try {
this[property] = currentStyle[property];
} catch (error) {
this.outlineColor = currentStyle.color;
this.outlineStyle = this.outlineStyle || 'none';
this.outlineWidth = this.outlineWidth || '0px';
this.outline = [this.outlineColor, this.outlineWidth, this.outlineStyle].join(' ');
}
} else {
this[property] = currentStyle[property];
}
}
setShortStyleProperty(this, 'margin');
setShortStyleProperty(this, 'padding');
setShortStyleProperty(this, 'border');
this.fontSize = Math.round(fontSize) + 'px';
}
CSSStyleDeclaration.prototype = {
constructor: CSSStyleDeclaration,
// <CSSStyleDeclaration>.getPropertyPriority
getPropertyPriority: function() {
throw new Error('NotSupportedError: DOM Exception 9');
},
// <CSSStyleDeclaration>.getPropertyValue
getPropertyValue: function(property) {
return this[property.replace(/-\w/g, function(match) {
return match[1].toUpperCase();
})];
},
// <CSSStyleDeclaration>.item
item: function(index) {
return this[index];
},
// <CSSStyleDeclaration>.removeProperty
removeProperty: function() {
throw new Error('NoModificationAllowedError: DOM Exception 7');
},
// <CSSStyleDeclaration>.setProperty
setProperty: function() {
throw new Error('NoModificationAllowedError: DOM Exception 7');
},
// <CSSStyleDeclaration>.getPropertyCSSValue
getPropertyCSSValue: function() {
throw new Error('NotSupportedError: DOM Exception 9');
}
};
// <Global>.getComputedStyle
exports.getComputedStyle = function getComputedStyle(element, pseudoEl) {
// IE9 needs matchMedia support but already support getComputedStyle
return window.getComputedStyle
? window.getComputedStyle(element, pseudoEl)
: new CSSStyleDeclaration(element);
};