tabs-state-uncompressed.js
8.83 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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/**
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
/**
* JavaScript behavior to allow selected tab to be remained after save or page reload
* keeping state in sessionStorage with better handling of multiple tab widgets per page
* and not saving the state if there is no id in the url (like on the CREATE page of content)
*/
jQuery(function ($) {
// Ensure in IE8 we can use xpath
if (typeof wgxpath.install === "function") {
wgxpath.install();
}
/**
* Tiny jQuery extension to allow getting of url params
* @use jQuery.urlParam('param') or $.urlParam('myRegex|anotherRegex')
* If no trailing equals sign in name, add one, allows for general reuse
*/
$.urlParam = function (name) {
if (!new RegExp("=$").exec(name)) {
name = name + '=';
}
var results = new RegExp("[\\?&](" + name + ")([^&#]*)").exec(window.location.href);
return results ? results[1] : null;
};
// jQuery extension to get the XPATH of a DOM element
$.getXpath = function (el) {
if (typeof el == "string") {
return document.evaluate(el, document, null, 0, null);
}
if (!el || el.nodeType != 1) {
return "";
}
if (el.id) {
return "//*[@id='" + el.id + "']";
}
var a = [];
var sames = a.filter.call(el.parentNode.children, function (x) {
return x.tagName == el.tagName;
});
var b = [];
return $.getXpath(el.parentNode) + "/" + el.tagName.toLowerCase() + (sames.length > 1 ? "[" + (b.indexOf.call(sames, el) + 1) + "]" : "");
};
// jQuery extension to get the DOM element from an XPATH
$.findXpath = function (exp, ctxt) {
var item;
var coll = [];
var result = document.evaluate(exp, ctxt || document, null, 5, null);
while (item = result.iterateNext()) {
coll.push(item);
}
return $(coll);
};
var loadTabs = function () {
/**
* Remove an item from an array
*/
function remove_item(activeTabsHrefs, tabCollection) {
for (var i = 0; i < activeTabsHrefs.length; i++) {
if (activeTabsHrefs[i].indexOf(tabCollection) > -1) {
activeTabsHrefs.splice(i, 1);
}
}
return activeTabsHrefs;
}
/**
* Generate the sessionStorage key we will use
* This is the URL minus some cleanup
*/
function getStorageKey() {
return window.location.href.toString().split(window.location.host)[1].replace(/&return=[a-zA-Z0-9%]+/, "").split('#')[0];
}
/**
* Save this tab to the storage in the form of a pseudo keyed array
*/
function saveActiveTab(event) {
// Get a new storage key, normally the full url we are on with some cleanup
var storageKey = getStorageKey();
// get this tabs own href
var href = $(event.target).attr("href");
// find the collection of tabs this tab belongs to, and calcuate the unique xpath to it
var tabCollection = $.getXpath($(event.target).closest(".nav-tabs").first().get(0));
// error handling
if (!tabCollection || typeof href == "undefined") {
return;
}
// Create a dummy keyed array as js doesnt allow keyed arrays
var storageValue = tabCollection + "|" + href;
// Get the current array from the storage
var activeTabsHrefs = JSON.parse(sessionStorage.getItem(storageKey));
// If none start a new array
if (!activeTabsHrefs) {
var activeTabsHrefs = [];
} else {
// Avoid Duplicates in the storage
remove_item(activeTabsHrefs, tabCollection);
}
// Save clicked tab, with relationship to tabCollection to the array
activeTabsHrefs.push(storageValue);
// Store the selected tabs as an array in sessionStorage
sessionStorage.setItem(storageKey, JSON.stringify(activeTabsHrefs));
}
// Array with active tabs hrefs
var activeTabsHrefs = JSON.parse(sessionStorage.getItem(getStorageKey()));
// jQuery object with all tabs links
var alltabs = $("a[data-toggle='tab']");
// When a tab is clicked, save its state!
alltabs.on("click", function (e) {
saveActiveTab(e);
});
// Clean default tabs
alltabs.parent(".active").removeClass("active");
// If we cannot find a tab storage for this url, see if we are coming from a save of a new item
if (!activeTabsHrefs) {
var unSavedStateUrl = getStorageKey().replace(/\&id=[0-9]*|[a-z]\&{1}_id=[0-9]*/, '');
activeTabsHrefs = JSON.parse(sessionStorage.getItem(unSavedStateUrl));
sessionStorage.removeItem(unSavedStateUrl);
}
// we have some tab states to restore, if we see a hash then let that trump the saved state
if (activeTabsHrefs !== null && !window.location.hash) {
// When moving from tab area to a different view
$.each(activeTabsHrefs, function (index, tabFakexPath) {
// Click the tab
var parts = tabFakexPath.split("|");
$.findXpath(parts[0]).find("a[data-toggle='tab'][href='" + parts[1] + "']").click();
});
} else { // clean slate start
// a list of tabs to click
var tabsToClick = [];
// If we are passing a hash then this trumps everything
if (window.location.hash) {
// for each set of tabs on the page
alltabs.parents("ul").each(function (index, ul) {
// If no tabs is saved, activate first tab from each tab set and save it
var tabToClick = $(ul).find("a[href='" + window.location.hash + "']");
// If we found some|one
if (tabToClick.length) {
// if we managed to locate its selector directly
if (tabToClick.selector) {
// highlight tab of the tabs if the hash matches
tabsToClick.push(tabToClick);
} else {
// highlight first tab of the tabs
tabsToClick.push(tabToClick.first());
}
var parentPane = tabToClick.closest('.tab-pane');
// bubble up for nested tabs (like permissions tabs in the permissions pane)
if (parentPane) {
var id = parentPane.attr('id');
if (id) {
var parentTabToClick = $(parentPane).find("a[href='#" + id + "']");
if (parentTabToClick) {
tabsToClick.push(parentTabToClick);
}
}
}
}
// cleanup for another loop
parentTabToClick = null;
tabToClick = null;
parentPane = null;
id = null;
});
// run in the right order bubbling up
tabsToClick.reverse();
// for all queued tabs
for (var i = 0; i < tabsToClick.length; i++) {
// click the tabs, thus storing them
jQuery(tabsToClick[i].selector).click();
}
// Remove the #hash in the url - with support for older browsers with no flicker
var scrollV, scrollH, loc = window.location;
if ("pushState" in history)
history.pushState("", document.title, loc.pathname + loc.search);
else {
// Prevent scrolling by storing the page's current scroll offset
scrollV = document.body.scrollTop;
scrollH = document.body.scrollLeft;
loc.hash = "";
// Restore the scroll offset, should be flicker free
document.body.scrollTop = scrollV;
document.body.scrollLeft = scrollH;
}
} else {
alltabs.parents("ul").each(function (index, ul) {
// If no tabs is saved, activate first tab from each tab set and save it
$(ul).find("a").first().click();
});
}
}
};
setTimeout(loadTabs, 100);
});