-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspanX.js
More file actions
136 lines (114 loc) · 3.98 KB
/
spanX.js
File metadata and controls
136 lines (114 loc) · 3.98 KB
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/**
* SpanX.js
* Stephen Zuniga
* MIT License
*/
(function () {
/**
* Class for reducing the depth of your website
*
* @class SpanX
*/
function SpanX (options) {
this.set(options);
}
// Shortcuts
var proto = SpanX.prototype;
/**
* Default options for every SpanX instance
*/
proto._defaultOptions = {
maxDepth: 100
};
/**
* Return the object containing options
* If one doesn't exist, set them to the default
*
* @return {object} Options currently available for this instance
*/
proto.getOptions = function () {
return this._options;
};
/**
* Loop through the stylesheets on the page and find any rules that style the z-index
* Add the selector to an array with the index at the corresponding z-index
*
* @return {array} Selectors sorted by z-index
*/
proto.getSelectors = function () {
var stylesheets = document.styleSheets,
selectors = [];
// Loop through the pages stylesheets
for (var i = 0; i < stylesheets.length; i++) {
var rules = stylesheets[i].rules;
// If the stylesheet doesn't contain any rules, go to the next one
if (!rules) {
continue;
}
for (var j = 0; j < rules.length; j++) {
// If the current rule doesn't style the z-index, go to the next one
if (!rules[j].style || !rules[j].style.zIndex) {
continue;
}
// If the z-index is a new one, add it to the selectors array
if (!selectors[rules[j].style.zIndex]) {
selectors[rules[j].style.zIndex] = [];
}
selectors[rules[j].style.zIndex].push(rules[j].selectorText);
}
}
return selectors;
};
/**
* Get the selectors sorted by z-index and scale them to the optional limit
*/
proto.init = function () {
var options = this.getOptions(),
selectors = this.getSelectors(),
output = '',
lastIndex = selectors.length,
scale = lastIndex / options.maxDepth;
// Generate the css that will scale back the z-indices
for (var i = 0; i < lastIndex; i++) {
if (!selectors[i]) {
continue;
}
var selectorString = selectors[i].join(', ');
output += selectorString + ' { z-index: ' + Math.ceil(i / scale) + ' !important } ';
}
// Create a style element with the above styles
var spanXStyle = document.createElement('style');
spanXStyle.type = 'text/css';
spanXStyle.id = 'spanX';
spanXStyle.innerHTML = output;
document.head.appendChild(spanXStyle);
};
/**
* Update the options with the passed parameter(s)
* If the options global is not set, set it to the default options
* If the first parameter is an object, pass any new parameters to the options global
* If the first parameter is a string, and the second parameter exists, update the option using the first parameter as a key
*
* @param {object|string} Object of options, or string of an option key
* @param {mixed} Value to set if the first parameter is a string
*/
proto.set = function (prop, value) {
var objProp;
// Set the options to the defaults if they aren't currently set
if (!this._options) {
this._options = this._defaultOptions;
}
// if an object is passed as the first parameter, loop through it
if (typeof prop === 'object') {
for (objProp in prop) {
this.set(objProp, prop[objProp]);
}
}
// otherwise assume we were given a property and update it
else {
this._options[prop] = value;
}
};
// Expose the class via the global object
this.SpanX = SpanX;
}.call(this));