-
Notifications
You must be signed in to change notification settings - Fork 0
/
initial-style.js
82 lines (70 loc) · 3.5 KB
/
initial-style.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
(function() {
'use strict';
window.InitialStyle = {
/**
* Compute initial values for all CSS and SVG properties, as implemented by user agent. Ignores
* `perspective-origin` and `transform-origin` properties.
*
* Will append an element in DOM, get the style data and then remove the element. This will cause a repaint,
* but unlikely to have other side-effects, unless MutationObservers are observing that part of DOM.
*
* @param {Object=} options
* @param {Node=} options.parentNode A DOM node to which the dummy element will be appended. This DOM node
* should be attached to the document body or be the body itself. Default: document.body.
* @return {Object.<string, string|number>} An object that contains computed initial values of all CSS
* properties available to the user agent. Property names are CSS property names (in CSS formatting, with
* hyphens), property values are computed initial values.
*/
get: function(options) {
var settings = createSettings(options);
var initialStyleAsPlainObject;
doWithTempElement(settings.parentNode, function(tempElement) {
tempElement.setAttribute('style', getInitialStyleReset());
initialStyleAsPlainObject = cssStyleDeclarationToPlainObject(window.getComputedStyle(tempElement));
removeOriginProperties(initialStyleAsPlainObject);
});
return initialStyleAsPlainObject;
function createSettings(options) {
options = options ? options : {};
var settings = {
parentNode: typeof(options.parentNode) !== 'undefined' ? options.parentNode : document.body
};
if (typeof (settings.parentNode.appendChild) === 'undefined') {
throw new TypeError("parentNode doesn't implement appendChild");
}
return settings;
}
function doWithTempElement(parentNode, callback) {
var tempElement = document.createElement('div');
parentNode.appendChild(tempElement);
callback(tempElement);
parentNode.removeChild(tempElement);
}
function getInitialStyleReset() {
var INITIAL_STYLE = {
'all': 'initial',
// unaffected by `all` shorthand:
'direction': 'ltr',
'unicode-bidi': 'normal'
};
return Object.keys(INITIAL_STYLE).reduce(function(prev, propName) {
return prev + propName + ': ' + INITIAL_STYLE[propName] + ' !important; ';
}, '');
}
function cssStyleDeclarationToPlainObject(declaration) {
var result = {};
for (var i = 0; i < declaration.length; i++) {
var propName = declaration.item(i);
result[propName] = declaration.getPropertyValue(propName);
}
return result;
}
function removeOriginProperties(style) {
var ORIGIN_PROPERTIES = ['perspective-origin', '-webkit-perspective-origin', 'transform-origin', '-webkit-transform-origin'];
ORIGIN_PROPERTIES.forEach(function(propName) {
delete style[propName];
});
}
}
};
})();