targetj 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,348 @@
1
+ function LoadingManager() {
2
+
3
+ this.resultMap = {};
4
+ this.loadingMap = {};
5
+
6
+ this.singleLoadList = undefined;
7
+ this.groupLoadList = undefined;
8
+ this.imgLoadList = undefined;
9
+
10
+ this.stopLoadingAfterAttempts = TUtil.isDefined(tapp.stopLoadingAfterAttempts) ? tapp.stopLoadingAfterAttempts : 10;
11
+ this.attemptFailedInterval = TUtil.isDefined(tapp.attemptFailedInterval) ? tapp.attemptFailedInterval : 2000;
12
+
13
+ this.statistics = {};
14
+ }
15
+
16
+ LoadingManager.prototype.initSingleLoad = function (fetchId, query, forceLoad) {
17
+
18
+ if (this.isLoading(fetchId) || (this.isLoaded(fetchId) && !forceLoad) || this.getLoadingAttempts(fetchId) > this.stopLoadingAfterAttempts) return;
19
+
20
+ this.initLoadingMap(fetchId);
21
+
22
+ this.singleLoadList = this.singleLoadList ? this.singleLoadList : {};
23
+ this.singleLoadList[fetchId] = { fetchId: fetchId, query: query };
24
+ };
25
+
26
+ LoadingManager.prototype.initGroupLoad = function (fetchId, dataId, query, idKey, separator) {
27
+ var groupId = JSON.stringify({ query: query, idKey: idKey, separator: separator });
28
+
29
+ if (this.isLoading(fetchId) || this.isLoaded(fetchId) || this.getLoadingAttempts(fetchId) > this.stopLoadingAfterAttempts) return;
30
+
31
+ this.initLoadingMap(fetchId);
32
+
33
+ this.groupLoadList = this.groupLoadList ? this.groupLoadList : {};
34
+ if (!this.groupLoadList[groupId]) {
35
+ this.groupLoadList[groupId] = [];
36
+ }
37
+
38
+ this.groupLoadList[groupId].push({ fetchId: fetchId, dataId: dataId });
39
+ };
40
+
41
+ LoadingManager.prototype.initImgLoad = function (fetchId, src) {
42
+
43
+ if (this.isLoading(fetchId) || this.isLoaded(fetchId) || this.getLoadingAttempts(fetchId) > this.stopLoadingAfterAttempts) return;
44
+
45
+ this.initLoadingMap(fetchId, 'image');
46
+
47
+ this.imgLoadList = this.imgLoadList ? this.imgLoadList : {};
48
+ this.imgLoadList[fetchId] = { fetchId: fetchId, src: src };
49
+ };
50
+
51
+ LoadingManager.prototype.isLoading = function(fetchId) {
52
+ return TUtil.isDefined(this.loadingMap[fetchId]) ? this.loadingMap[fetchId].loadingFlag : false;
53
+ };
54
+
55
+ LoadingManager.prototype.isLoaded = function(fetchId) {
56
+ return TUtil.isDefined(this.resultMap[fetchId]) && this.resultMap[fetchId].success === true;
57
+ };
58
+
59
+ LoadingManager.prototype.getLoadingAttempts = function(fetchId) {
60
+ return TUtil.isDefined(this.loadingMap[fetchId]) ? this.loadingMap[fetchId].attempts : 0;
61
+ };
62
+
63
+ LoadingManager.prototype.getSuccessLoadingTime = function(fetchId) {
64
+ return TUtil.isDefined(this.loadingMap[fetchId]) && this.loadingMap[fetchId].success === true ? this.loadingMap[fetchId].loadingTime : undefined;
65
+ };
66
+
67
+ LoadingManager.prototype.getFailedInterval = function(fetchId) {
68
+ return TUtil.isDefined(this.loadingMap[fetchId]) ? this.loadingMap[fetchId].attempts * this.attemptFailedInterval : 0;
69
+ };
70
+
71
+ LoadingManager.prototype.fetchResult = function(fetchId) {
72
+ return this.resultMap[fetchId];
73
+ };
74
+
75
+ LoadingManager.prototype.hasLoadedSuccessfully = function(fetchId) {
76
+ return this.resultMap[fetchId] && this.resultMap[fetchId].success === true;
77
+ };
78
+
79
+ LoadingManager.prototype.hasLoadedUnsuccessfully = function(fetchId) {
80
+ return this.resultMap[fetchId] && this.resultMap[fetchId].success === false;
81
+ };
82
+
83
+ LoadingManager.prototype.fetchErrors = function(fetchId) {
84
+ return this.resultMap[fetchId] && this.resultMap[fetchId].result && this.resultMap[fetchId].result.errors ? this.resultMap[fetchId].result.errors : undefined;
85
+ };
86
+ LoadingManager.prototype.initLoadingMap = function(fetchId, category) {
87
+ category = category ? category : this.getCategoryFromFetchId(fetchId);
88
+
89
+ if (TUtil.isDefined(this.loadingMap[fetchId])) {
90
+ this.loadingMap[fetchId].loadingFlag = true;
91
+ this.loadingMap[fetchId].startTime = browser.now();
92
+ this.loadingMap[fetchId].loadingTime = undefined;
93
+
94
+ } else {
95
+ this.loadingMap[fetchId] = {
96
+ fetchId: fetchId,
97
+ category: category,
98
+ loadingFlag: true,
99
+ attempts: 0,
100
+ startTime: browser.now(),
101
+ loadingTime: undefined,
102
+ success: false
103
+ };
104
+ }
105
+ };
106
+
107
+ LoadingManager.prototype.groupLoad = function () {
108
+ if (!this.groupLoadList) return;
109
+
110
+ var groupIds = Object.keys(this.groupLoadList);
111
+
112
+ for (var i = 0; i < groupIds.length; i++) {
113
+ var groupId = groupIds[i];
114
+ var fetchList = this.groupLoadList[groupId];
115
+
116
+ var dataIds = [], dataIdFetchIdMap = {};
117
+
118
+ for (var j = 0; j < fetchList.length; j++) {
119
+ var dataId = fetchList[j].dataId;
120
+ dataIds.push(dataId);
121
+ dataIdFetchIdMap[dataId] = fetchList[j].fetchId;
122
+ }
123
+
124
+ if (dataIds.length > 0) {
125
+ var groupObj = JSON.parse(groupId);
126
+ var groupQuery = this.updateQueryValue(groupObj.query, dataIds.join(groupObj.separator));
127
+ this.groupAjax(groupQuery, dataIdFetchIdMap, groupObj.idKey);
128
+ }
129
+
130
+ delete this.groupLoadList[groupId];
131
+ }
132
+
133
+ this.groupLoadList = undefined;
134
+
135
+ };
136
+
137
+ LoadingManager.prototype.singleLoad = function () {
138
+ if (!this.singleLoadList) return;
139
+
140
+ var keys = Object.keys(this.singleLoadList);
141
+
142
+ for (var i = 0; i < keys.length; i++) {
143
+ var load = this.singleLoadList[keys[i]];
144
+
145
+ this.singleAjax(load.query, load.fetchId);
146
+ }
147
+
148
+ this.singleLoadList = undefined;
149
+ };
150
+
151
+ LoadingManager.prototype.imgLoad = function () {
152
+ if (!this.imgLoadList) return;
153
+
154
+ var keys = Object.keys(this.imgLoadList);
155
+
156
+ for (var i = 0; i < keys.length; i++) {
157
+ var load = this.imgLoadList[keys[i]];
158
+
159
+ this.imgAjax(load.src, load.fetchId);
160
+ }
161
+
162
+ this.imgLoadList = undefined;
163
+ };
164
+
165
+ LoadingManager.prototype.updateQueryValue = function(query, value) {
166
+ for (var prop in query) {
167
+ if (query[prop] === '%s') {
168
+ query[prop] = value;
169
+ } else if (query[prop] === '%d') {
170
+ query[prop] = typeof value === 'number' ? value : parseFloat(value);
171
+ } else if (typeof query[prop] === 'object') {
172
+ this.updateQueryValue(query[prop], value);
173
+ }
174
+ }
175
+ return query;
176
+ };
177
+
178
+ LoadingManager.prototype.singleAjax = function (query, fetchId) {
179
+ var self = this;
180
+
181
+ var defaultQuery = {
182
+ dataType: "json",
183
+ type: "GET",
184
+ success: function (dataList) {
185
+ self.loadingMap[fetchId].loadingFlag = false;
186
+ self.loadingMap[fetchId].loadingTime = browser.now() - self.loadingMap[fetchId].startTime;
187
+ self.loadingMap[fetchId].success = true;
188
+ self.loadingMap[fetchId].attempts++;
189
+
190
+ self.resultMap[fetchId] = Object.assign({ result: dataList }, self.loadingMap[fetchId] );
191
+ delete self.loadingMap[fetchId];
192
+
193
+ self.updateStatistics(fetchId);
194
+
195
+ tapp.manager.scheduleRun(0, "singleAjax_success_" + fetchId);
196
+ },
197
+ error: function (textStatus) {
198
+ self.resultMap[fetchId] = { error: textStatus, success: false };
199
+
200
+ self.loadingMap[fetchId].loadingFlag = false;
201
+ self.loadingMap[fetchId].loadingTime = browser.now() - self.loadingMap[fetchId].startTime;
202
+ self.loadingMap[fetchId].attempts++;
203
+
204
+ tapp.manager.scheduleRun(0, "singleAjax_error_" + fetchId);
205
+ }
206
+ };
207
+
208
+ $Dom.ajax(Object.assign(defaultQuery, query));
209
+ };
210
+
211
+ LoadingManager.prototype.groupAjax = function (query, dataIdFetchIdMap, idKey) {
212
+
213
+ var self = this;
214
+
215
+ var defaultQuery = {
216
+ dataType: "json",
217
+ type: "GET",
218
+ success: function (dataList) {
219
+ for (var i = 0; i < dataList.length; i++) {
220
+
221
+ var dataId = dataList[i][idKey];
222
+ if (dataIdFetchIdMap[dataId]) {
223
+ var fetchId = dataIdFetchIdMap[dataId];
224
+ self.loadingMap[fetchId].loadingFlag = false;
225
+ self.loadingMap[fetchId].loadingTime = browser.now() - self.loadingMap[fetchId].startTime;
226
+ self.loadingMap[fetchId].success = true;
227
+ self.loadingMap[fetchId].attempts++;
228
+
229
+ self.resultMap[fetchId] = Object.assign({ result: dataList[i] }, self.loadingMap[fetchId] );
230
+
231
+ self.updateStatistics(fetchId);
232
+
233
+ delete self.loadingMap[fetchId];
234
+ delete dataIdFetchIdMap[dataId];
235
+ }
236
+ }
237
+
238
+ Object.keys(dataIdFetchIdMap).forEach(function(dataId) {
239
+
240
+ var fetchId = dataIdFetchIdMap[dataId];
241
+
242
+ if (!self.loadingMap[fetchId].success) {
243
+ self.loadingMap[fetchId].loadingFlag = false;
244
+ self.loadingMap[fetchId].loadingTime = browser.now() - self.loadingMap[fetchId].startTime;
245
+ self.loadingMap[fetchId].attempts++;
246
+ }
247
+ });
248
+
249
+ tapp.manager.scheduleRun(0, "groupAjax_success_" + query);
250
+ },
251
+ error: function (textStatus) {
252
+ Object.keys(dataIdFetchIdMap).forEach(function(dataId) {
253
+ var fetchId =dataIdFetchIdMap[dataId];
254
+
255
+ self.resultMap[fetchId] = { error: textStatus, success: false };
256
+ self.loadingMap[fetchId].loadingFlag = false;
257
+ self.loadingMap[fetchId].attempts++;
258
+ });
259
+
260
+ tapp.manager.scheduleRun(0, "groupAjax_error_" + query);
261
+ }
262
+ };
263
+
264
+ $Dom.ajax(Object.assign(defaultQuery, query));
265
+ };
266
+
267
+ LoadingManager.prototype.imgAjax = function (src, fetchId) {
268
+ var self = this;
269
+
270
+ var image = new Image();
271
+ image.src = src;
272
+
273
+ image.onload = function() {
274
+ self.loadingMap[fetchId].loadingFlag = false;
275
+ self.loadingMap[fetchId].loadingTime = browser.now() - self.loadingMap[fetchId].startTime;
276
+ self.loadingMap[fetchId].success = true;
277
+ self.loadingMap[fetchId].attempts++;
278
+
279
+ self.resultMap[fetchId] = Object.assign({ width: this.width, height: this.height, $image: new $Dom(image) }, self.loadingMap[fetchId]);
280
+
281
+ self.updateStatistics(fetchId, 'image');
282
+ delete self.loadingMap[fetchId];
283
+
284
+ tapp.manager.scheduleRun(0, "imgAjax_success_" + fetchId);
285
+ };
286
+
287
+ image.onerror = image.onabort = function () {
288
+ self.resultMap[fetchId] = { result: "no image", success: false };
289
+
290
+ self.loadingMap[fetchId].loadingFlag = false;
291
+ self.loadingMap[fetchId].loadingTime = browser.now() - self.loadingMap[fetchId].startTime;
292
+ self.loadingMap[fetchId].attempts++;
293
+
294
+
295
+ tapp.manager.scheduleRun(0, "imgAjax_error_" + fetchId);
296
+ };
297
+
298
+ };
299
+
300
+ LoadingManager.prototype.getCategoryFromFetchId = function(fetchId) {
301
+ return fetchId.replace(/[^a-zA-Z]/g, '');
302
+ };
303
+
304
+ LoadingManager.prototype.updateStatistics = function(fetchId, category) {
305
+ category = category ? category : this.getCategoryFromFetchId(fetchId);
306
+
307
+ if (this.statistics[category]) {
308
+ this.statistics[category].count++;
309
+ this.statistics[category].totalTime += this.resultMap[fetchId].loadingTime;
310
+ this.statistics[category].lastUpdate = browser.now();
311
+ delete this.statistics[category].averageTime;
312
+ } else {
313
+ this.statistics[category] = {
314
+ count: 1,
315
+ totalTime: this.resultMap[fetchId].loadingTime,
316
+ lastUpdate: browser.now()
317
+ };
318
+ }
319
+ };
320
+
321
+ LoadingManager.prototype.getAverageLoadingTime = function(category) {
322
+ var now = browser.now();
323
+
324
+ if (this.statistics[category] && this.statistics[category].averageTime && (now - this.statistics[category].lastUpdate) < 500) {
325
+ return this.statistics[category].averageTime;
326
+ }
327
+
328
+ var totalTime = this.statistics[category] ? this.statistics[category].totalTime : 0;
329
+ var count = this.statistics[category] ? this.statistics[category].count : 0;
330
+
331
+
332
+ Object.values(this.loadingMap).filter(function(loadItem) { return loadItem.category === category; }).forEach(function(loadItem) {
333
+ totalTime += now - loadItem.startTime;
334
+ count++;
335
+ });
336
+
337
+ if (this.statistics[category]) {
338
+
339
+ this.statistics[category].averageTime = count > 0 ? totalTime / count : 0;
340
+ this.statistics[category].lastUpdate = browser.now();
341
+
342
+ return this.statistics[category].averageTime;
343
+ } else {
344
+ return 0;
345
+ }
346
+ };
347
+
348
+
@@ -0,0 +1,156 @@
1
+ function LocationManager() {
2
+ this.hasLocationList = [];
3
+ this.hasLocationMap = {};
4
+
5
+ this.bracketThreshold = 4;
6
+ this.locationCount = [];
7
+ }
8
+
9
+ LocationManager.prototype.calculateAll = function() {
10
+ this.hasLocationList.length = 0;
11
+ this.hasLocationMap = {};
12
+ this.locationCount.length = 0;
13
+ tapp.targetManager.doneTargets.length = 0;
14
+ this.startTime = browser.now();
15
+
16
+ this.calculate();
17
+
18
+ if (tapp.targetManager.doneTargets.length > 0) {
19
+ tapp.targetManager.doneTargets.forEach(function(target) {
20
+ //imperative call is possible till this gets executed so we need to make sure that it is still done
21
+ if (target.tmodel.isTargetDone(target.key)) {
22
+ target.tmodel.setTargetComplete(target.key);
23
+ }
24
+ });
25
+
26
+ tapp.manager.scheduleRun(10, "done to complete");
27
+ }
28
+ };
29
+
30
+ LocationManager.prototype.calculate = function() {
31
+ this.addToLocationList(tapp.ui);
32
+ this.calculateContainer(tapp.ui);
33
+ };
34
+
35
+ LocationManager.prototype.getChildren = function(container) {
36
+ var brackets;
37
+
38
+ if (this.isProlificContainer(container)) {
39
+ brackets = Bracket.generate(container);
40
+ }
41
+
42
+ return brackets ? brackets.list : container.getChildren();
43
+ };
44
+
45
+ LocationManager.prototype.isProlificContainer = function(container) {
46
+ return container.canBeBracketed() && container.getChildren().length > this.bracketThreshold;
47
+ };
48
+
49
+ LocationManager.prototype.calculateContainer = function(container) {
50
+ var allChildren = this.getChildren(container);
51
+
52
+ var viewport = container.createViewport();
53
+ container.resetVisibleList();
54
+
55
+ var i = 0;
56
+
57
+ while (i < allChildren.length && tapp.isRunning()) {
58
+
59
+ var child = allChildren[i++];
60
+
61
+ var outerXEast = undefined, innerXEast = undefined;
62
+
63
+
64
+ this.calculateTargets(child);
65
+
66
+ if (child.getActualValueLastUpdate('canBeBracketed') > child.getParent().getActualValueLastUpdate("allChildren")) {
67
+ delete child.getParent().targetValues['allChildren'];
68
+ }
69
+
70
+ viewport.setCurrentChild(child);
71
+ child.setLocation(viewport);
72
+
73
+ innerXEast = TUtil.isDefined(container.getValue('innerXEast')) ? container.getValue('innerXEast') : container.absX + container.getInnerWidth();
74
+ outerXEast = TUtil.isDefined(child.getValue('outerXEast')) ? child.getValue('outerXEast') : child.absX + child.getInnerWidth();
75
+
76
+ if (viewport.isOverflow(outerXEast, innerXEast)) {
77
+ viewport.overflow();
78
+ child.setLocation(viewport);
79
+ } else {
80
+ child.setLocation(viewport);
81
+ }
82
+
83
+ if (child.canBeVisible() && !this.hasLocationMap[child.oid]) {
84
+ this.addToLocationList(child);
85
+ }
86
+
87
+ if (!child.targetUpdatingMap.x) {
88
+ if (TUtil.isDefined(child.targets.x)) {
89
+ tapp.targetManager.setTargetValue(child, 'x');
90
+ } else if (!TUtil.isDefined(child.targetValues.x)) {
91
+ child.setValue('x', child.x);
92
+ }
93
+ }
94
+
95
+ if (!child.targetUpdatingMap.y) {
96
+ if (TUtil.isDefined(child.targets.y)) {
97
+ tapp.targetManager.setTargetValue(child, 'y');
98
+ } else if (!TUtil.isDefined(child.targetValues.y)) {
99
+ child.setValue('y', child.y);
100
+ }
101
+ }
102
+
103
+ viewport.isVisible(child);
104
+
105
+ child.addToParentVisibleList();
106
+
107
+ if (child.shouldCalculateChildrenLocations()) {
108
+ this.calculateContainer(child);
109
+ } else {
110
+ child.manuallyCalculateChildrenLocations();
111
+ }
112
+
113
+ if (child.isVisible() && child.canBeVisible() && (child.targetUpdatingList.length > 0 || child.updatingChildren.length > 0)) {
114
+ container.addUpdatingChild(child);
115
+ }
116
+
117
+ if (child.isInFlow()) {
118
+ var childLastHeight = child.getHeight();
119
+
120
+ if (child.hasChildren()) {
121
+ tapp.targetManager.setTargetValuesWithKeys(child, ['width', 'height'], true);
122
+ tapp.targetManager.setJustActualValue(child, 'width');
123
+ tapp.targetManager.setJustActualValue(child, 'height');
124
+ }
125
+
126
+ if (child.getHeight() !== childLastHeight && tapp.events.isScrollTopHandler(child.getParent())
127
+ && tapp.events.currentTouch.dir === 'up') {
128
+ this.calculateContainer(child);
129
+ }
130
+
131
+ if (TUtil.isNumber(child.getValue('appendNewLine'))) {
132
+ viewport.appendNewLine();
133
+ } else {
134
+ viewport.nextLocation();
135
+ }
136
+ }
137
+
138
+ this.locationCount.push(child.oid + "-" + child.targetUpdatingList.length + "-" + (browser.now() - this.startTime));
139
+
140
+ }
141
+
142
+ viewport.calcContentWidthHeight();
143
+ };
144
+
145
+ LocationManager.prototype.calculateTargets = function(tmodel) {
146
+ tapp.targetManager.setTargetValues(tmodel);
147
+ tapp.targetManager.setActualValues(tmodel);
148
+
149
+ if (!TUtil.isDefined(tmodel.targetValues.width) && tmodel.hasDom()) TargetUtil.setWidthFromDom(tmodel);
150
+ if (!TUtil.isDefined(tmodel.targetValues.height) && tmodel.hasDom()) TargetUtil.setHeightFromDom(tmodel);
151
+ };
152
+
153
+ LocationManager.prototype.addToLocationList = function(child) {
154
+ this.hasLocationList.push(child);
155
+ this.hasLocationMap[child.oid] = child;
156
+ };
@@ -0,0 +1,104 @@
1
+ function PageManager() {
2
+ this.lastLink = document.URL;
3
+ this.pageCache = {};
4
+ }
5
+
6
+ PageManager.prototype.openPage = function(link, isPageFetchNeeded) {
7
+
8
+ isPageFetchNeeded = TUtil.isDefined(isPageFetchNeeded) ? isPageFetchNeeded : true;
9
+
10
+ tapp.stop();
11
+ tapp.reset();
12
+
13
+ var self = this;
14
+
15
+ if (typeof tapp.updateAnalytics === 'function') {
16
+ tapp.updateAnalytics(link);
17
+ }
18
+
19
+ if (!this.pageCache[link] && isPageFetchNeeded) {
20
+
21
+ $Dom.ajax({
22
+ url:link,
23
+ type: 'GET',
24
+ data: { tpageOnly: true },
25
+ success: function (data) {
26
+ tapp.$dom.outerHTML(data);
27
+ tapp.ui = tapp.uiFn();
28
+ self.lastLink = link;
29
+ tapp.start();
30
+ },
31
+ error: function () {
32
+ self.lastLink = undefined;
33
+ history.back();
34
+ }
35
+ });
36
+
37
+ } else if (!this.pageCache[link]) {
38
+ tapp.$dom.innerHTML("");
39
+ tapp.ui = tapp.uiFn();
40
+ self.lastLink = link;
41
+ setTimeout(tapp.start);
42
+ } else {
43
+
44
+ tapp.$dom.innerHTML(this.pageCache[link].html);
45
+ tapp.ui = this.pageCache[link].ui;
46
+ TUtil.initDoms(this.pageCache[link].visibleList);
47
+ tapp.manager.lists.visible = this.pageCache[link].visibleList.slice(0);
48
+ self.lastLink = link;
49
+ setTimeout(tapp.start);
50
+ }
51
+ };
52
+
53
+ PageManager.prototype.openLinkFromHistory = function(state) {
54
+ if (state.link) {
55
+ this.openPage(state.link);
56
+ } else if (state.browserUrl) {
57
+ history.replaceState({ link: state.browserUrl }, "", state.browserUrl);
58
+ this.openPage(state.browserUrl);
59
+ }
60
+
61
+ tapp.manager.scheduleRun(0, "pagemanager-openLinkFromHistory");
62
+ };
63
+
64
+ PageManager.prototype.openLink = function(link, isPageFetchNeeded) {
65
+
66
+ link = TUtil.getFullLink(link);
67
+
68
+ if (this.lastLink) {
69
+ this.pageCache[this.lastLink] = {
70
+ link: this.lastLink,
71
+ html: tapp.$dom.innerHTML(),
72
+ visibleList: tapp.manager.lists.visible.slice(0),
73
+ ui: tapp.ui
74
+ };
75
+ }
76
+
77
+ history.pushState({ link: link }, "", link);
78
+
79
+ this.openPage(link, isPageFetchNeeded);
80
+
81
+ tapp.manager.scheduleRun(0, "pagemanager-processOpenLink");
82
+ };
83
+
84
+ PageManager.prototype.updateBrowserUrl = function(link) {
85
+ var currentState = window.history.state;
86
+
87
+ if (!currentState.browserUrl) {
88
+ this.pageCache[document.URL] = {
89
+ link: document.URL,
90
+ html: tapp.$dom.innerHTML(),
91
+ visibleList: tapp.manager.lists.visible.slice(0),
92
+ ui: tapp.ui
93
+ };
94
+ history.pushState({ browserUrl: link }, "", link);
95
+ } else {
96
+ history.replaceState({ browserUrl: link }, "", link);
97
+ }
98
+
99
+ tapp.manager.scheduleRun(0, "pagemanager-processUpdateBrowserUrl");
100
+ };
101
+
102
+ PageManager.prototype.back = function() {
103
+ return history.back();
104
+ };