GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( ddb6fc...45f4d7 )
by Florian
01:10
created

js/okapi.js   F

Complexity

Total Complexity 75
Complexity/F 2.5

Size

Lines of Code 480
Function Count 30

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 9
Bugs 4 Features 1
Metric Value
cc 0
c 9
b 4
f 1
nc 16
dl 0
loc 480
rs 3.8888
wmc 75
mnd 2
bc 73
fnc 30
bpm 2.4333
cpm 2.5
noi 0

19 Functions

Rating   Name   Duplication   Size   Complexity  
A Okapi.icon 0 9 2
A Okapi.guessSiteId 0 13 3
A Okapi.setupIcons 0 20 2
A Okapi.centerMap 0 14 3
A Okapi.setupSites 0 60 2
A Okapi.init 0 13 1
A Okapi.parseLocation 0 13 2
A Okapi.setShowCache 0 5 1
A Okapi.restore 0 13 3
B Okapi.loadBboxSite 0 92 5
A Okapi.scheduleLoad 0 14 2
A Okapi.loadBbox 0 12 2
B Okapi.toggle 0 21 5
A Okapi.showPopup 0 54 3
A Okapi.popupCacheCode 0 14 4
A Okapi.unscheduleLoad 0 12 3
A Okapi.removeMarkers 0 23 3
A Okapi.registerPopup 0 13 2
A Okapi.createPopupContent 0 16 1

How to fix   Complexity   

Complexity

Complex classes like js/okapi.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/*jslint
2
  indent: 4
3
*/
4
5
/*global
6
  $, google, mytrans, window, Cookies, Coordinates, get_cookie_string
7
*/
8
9
10
var Okapi = {};
11
Okapi.m_map = null;
12
Okapi.m_sites = null;
13
Okapi.m_ready = false;
14
Okapi.m_showCache = null;
15
Okapi.m_enabled = false;
16
Okapi.m_popup = null;
17
Okapi.m_popupCacheCode = null;
18
Okapi.m_marker = null;
19
Okapi.m_icons = null;
20
Okapi.m_timer = null;
21
22
23
Okapi.init = function (themap) {
24
    'use strict';
25
26
    this.m_map = themap;
27
    var self = this;
28
29
    google.maps.event.addListener(this.m_map, "center_changed", function () {
30
        self.scheduleLoad();
31
    });
32
    google.maps.event.addListener(this.m_map, "zoom_changed", function () {
33
        self.scheduleLoad();
34
    });
35
};
36
37
38
Okapi.parseLocation = function (s) {
39
    'use strict';
40
41
    var loc = s.split("|"),
42
        lat = parseFloat(loc[0]),
43
        lng = parseFloat(loc[1]);
44
45
    if (Coordinates.valid(lat, lng)) {
46
        return new google.maps.LatLng(lat, lng);
47
    }
48
49
    return null;
50
};
51
52
53
Okapi.setShowCache = function (code) {
54
    'use strict';
55
56
    this.m_showCache = code;
57
};
58
59
60
Okapi.setupSites = function () {
61
    'use strict';
62
63
    if (this.m_sites) {
64
        return;
65
    }
66
67
    var self = this,
68
        main_url = "proxy2.php?url=http://www.opencaching.de/okapi/services/apisrv/installations",
69
        keys = {
70
            "Opencaching.DE" : "YSqPufH82encfJ67ZxV2",
71
            "Opencaching.PL" : "jhRyc6rGmT6XEvxva29B",
72
            "Opencaching.NL" : "gcwaesuq3REu8RtCgLDj",
73
            "Opencaching.US" : "GvgyCMvwfH42GqJGL494",
74
            "Opencache.UK" : "7t7VfpkCd4HuxPabfbHd",
75
            "Opencaching.RO" : "gqSWmVJhZGDwc4sRhyy7"
76
        },
77
        prefixes = {
78
            "Opencaching.DE" : "OC",
79
            "Opencaching.PL" : "OP",
80
            "Opencaching.NL" : "OB",
81
            "Opencaching.US" : "OU",
82
            "Opencache.UK" : "OK",
83
            "Opencaching.RO" : "OR"
84
        };
85
86
    this.m_sites = [];
87
88
    $.ajax({
89
        url: main_url,
90
        dataType: 'json',
91
        success: function (response) {
92
            response.map(function (site) {
93
                if (keys[site.site_name] !== undefined) {
94
                    self.m_sites.push({
95
                        siteid: self.m_sites.length,
96
                        name: site.site_name,
97
                        site_url: site.site_url,
98
                        url: site.okapi_base_url,
99
                        proxy: site.okapi_base_url.startsWith('http:'),
100
                        prefix: prefixes[site.site_name],
101
                        key: keys[site.site_name],
102
                        ignore_user: null,
103
                        markers: {},
104
                        finished: true
105
                    });
106
                }
107
            });
108
109
            self.m_ready = true;
110
            if (self.m_enabled) {
111
                self.scheduleLoad(true);
112
            }
113
            if (self.m_showCache && self.m_showCache !== "") {
114
                self.centerMap(self.m_showCache);
115
                self.m_showCache = null;
116
            }
117
        }
118
    });
119
};
120
121
122
Okapi.setupIcons = function () {
123
    'use strict';
124
125
    if (this.m_icons) {
126
        return;
127
    }
128
129
    this.m_icons = {
130
        "Other": new google.maps.MarkerImage("img/cachetype-1.png"),
131
        "Traditional": new google.maps.MarkerImage("img/cachetype-2.png"),
132
        "Multi": new google.maps.MarkerImage("img/cachetype-3.png"),
133
        "Virtual": new google.maps.MarkerImage("img/cachetype-4.png"),
134
        "Webcam": new google.maps.MarkerImage("img/cachetype-5.png"),
135
        "Event": new google.maps.MarkerImage("img/cachetype-6.png"),
136
        "Quiz": new google.maps.MarkerImage("img/cachetype-7.png"),
137
        "Math/Physics": new google.maps.MarkerImage("img/cachetype-8.png"),
138
        "Moving": new google.maps.MarkerImage("img/cachetype-9.png"),
139
        "Drive-In": new google.maps.MarkerImage("img/cachetype-10.png")
140
    };
141
};
142
143
144
Okapi.icon = function (type) {
145
    'use strict';
146
147
    if (this.m_icons[type] !== undefined) {
148
        return this.m_icons[type];
149
    }
150
151
    return this.m_icons.Other;
152
};
153
154
155
Okapi.guessSiteId = function (code) {
156
    'use strict';
157
158
    code = code.toUpperCase();
159
    var siteid;
160
    for (siteid = 0; siteid < this.m_sites.length; siteid += 1) {
161
        if (code.startsWith(this.m_sites[siteid].prefix)) {
162
            return siteid;
163
        }
164
    }
165
166
    return -1;
167
};
168
169
170
Okapi.centerMap = function (code) {
171
    'use strict';
172
173
    if (!this.m_ready) {
174
        return;
175
    }
176
177
    var siteid = this.guessSiteId(code);
178
    if (siteid < 0) {
179
        return;
180
    }
181
182
    this.showPopup(null, code.toUpperCase(), siteid);
183
};
184
185
186
Okapi.popupCacheCode = function () {
187
    'use strict';
188
189
    if (!this.m_popup) {
190
        return null;
191
    }
192
193
    var m = this.m_popup.getMap();
194
    if (!m || typeof m === "undefined") {
195
        return null;
196
    }
197
198
    return this.m_popupCacheCode;
199
};
200
201
202
Okapi.createPopupContent = function (code, response) {
203
    'use strict';
204
205
    var content =
206
        '<a href="' + response.url + '" target="_blank">' + code + ' <b>' + response.name + '</b></a><br />'
207
        + '<table class="cache-popup">'
208
        + '<tr><td>' + mytrans("geocache.owner") + '</td><td>' + '<a href="' + response.owner.profile_url + '" target="_blank"><b>' + response.owner.username + '</b></a></td></tr>'
209
        + '<tr><td>' + mytrans("geocache.type") + '</td><td>' + response.type + '</td></tr>'
210
        + '<tr><td>' + mytrans("geocache.size") + '</td><td>' + response.size2 + '</td></tr>'
211
        + '<tr><td>' + mytrans("geocache.status") + '</td><td>' + response.status + '</td></tr>'
212
        + '<tr><td>' + mytrans("geocache.difficulty") + '</td><td>' + response.difficulty + '/5</td></tr>'
213
        + '<tr><td>' + mytrans("geocache.terrain") + '</td><td>' + response.terrain + '/5</td></tr>'
214
        + '<tr><td>' + mytrans("geocache.finds") + '</td><td>' + response.founds + '</td></tr>'
215
        + '</table>';
216
    return content;
217
};
218
219
220
Okapi.showPopup = function (m, code, siteid) {
221
    'use strict';
222
223
    this.m_popupCacheCode = code;
224
225
    if (!this.m_popup) {
226
        this.m_popup = new google.maps.InfoWindow();
227
    }
228
229
    var self = this,
230
        site = this.m_sites[siteid],
231
        url,
232
        data;
233
234
    url = site.url + 'services/caches/geocache';
235
    data = {
236
        consumer_key: site.key,
237
        cache_code: code,
238
        fields: 'name|type|status|url|owner|founds|size2|difficulty|terrain|location'
239
    };
240
241
    if (site.proxy) {
242
        data = {
243
            url: url + "?" + $.param(data)
244
        };
245
        url = "proxy2.php";
246
    }
247
248
    $.ajax({
249
        url: url,
250
        dataType: 'json',
251
        data: data,
252
        success: function (response) {
253
            var coords = self.parseLocation(response.location);
254
            self.m_map.setCenter(coords);
255
256
            if (!m) {
257
                m = new google.maps.Marker({
258
                    position: coords,
259
                    map: self.m_map,
260
                    icon: self.icon(response.type)
261
                });
262
                if (self.m_maker) {
263
                    self.m_marker.setMap(null);
264
                }
265
                self.registerPopup(m, code, siteid);
266
                self.m_marker = m;
267
            }
268
269
            self.m_popup.setContent(self.createPopupContent(code, response));
270
            self.m_popup.open(self.m_map, m);
271
        }
272
    });
273
};
274
275
276
Okapi.registerPopup = function (m, code, siteid) {
277
    'use strict';
278
279
    if (!this.m_ready) {
280
        return;
281
    }
282
283
    var self = this;
284
285
    google.maps.event.addListener(m, 'click', function () {
286
        self.showPopup(m, code, siteid);
287
    });
288
};
289
290
291
Okapi.removeMarkers = function () {
292
    'use strict';
293
294
    if (!this.m_ready) {
295
        return;
296
    }
297
298
    this.m_sites.map(function (site) {
299
        var key;
300
        for (key in site.markers) {
301
            if (site.markers.hasOwnProperty(key)) {
302
                site.markers[key].setMap(null);
303
            }
304
        }
305
        site.markers = {};
306
    });
307
308
    if (this.m_marker) {
309
        this.m_marker.setMap(null);
310
        delete this.m_marker;
311
        this.m_marker = null;
312
    }
313
};
314
315
316
Okapi.loadBboxSite = function (siteid) {
317
    'use strict';
318
319
    if (!this.m_ready) {
320
        return;
321
    }
322
323
    var self = this,
324
        site = this.m_sites[siteid],
325
        b,
326
        bbox,
327
        url,
328
        data;
329
330
    if (!this.m_enabled) {
331
        site.finished = true;
332
        return;
333
    }
334
335
    if (!site.finished) {
336
        return;
337
    }
338
339
    site.finished = false;
340
341
    b = this.m_map.getBounds();
342
    bbox = b.getSouthWest().lat() + "|" + b.getSouthWest().lng() + "|" + b.getNorthEast().lat() + "|" + b.getNorthEast().lng();
343
344
    url = site.url + 'services/caches/shortcuts/search_and_retrieve';
345
    data = {
346
        consumer_key: site.key,
347
        search_method: 'services/caches/search/bbox',
348
        search_params: '{"bbox" : "' + bbox + '", "limit" : "500"}',
349
        retr_method: 'services/caches/geocaches',
350
        retr_params: '{"fields": "code|name|location|type|status|url"}',
351
        wrap: 'false'
352
    };
353
354
    if (site.proxy) {
355
        data = {
356
            url: url + "?" + $.param(data)
357
        };
358
        url = "proxy2.php";
359
    }
360
361
    $.ajax({
362
        url: url,
363
        dataType: 'json',
364
        data: data,
365
        success: function (response) {
366
            var addedCaches = {},
367
                cache,
368
                code;
369
370
            for (code in response) {
371
                if (!response.hasOwnProperty(code)) {
372
                    continue;
373
                }
374
375
                cache = response[code];
376
                if (cache.status !== "Available") {
377
                    continue;
378
                }
379
380
                addedCaches[cache.code] = true;
381
                if (site.markers[cache.code] !== undefined) {
382
                    continue;
383
                }
384
385
                site.markers[cache.code] = new google.maps.Marker({
386
                    position: self.parseLocation(cache.location),
387
                    map: self.m_map,
388
                    icon: self.icon(cache.type)
389
                });
390
391
                self.registerPopup(site.markers[cache.code], cache.code, siteid);
392
            }
393
394
            for (code in site.markers) {
395
                if (site.markers.hasOwnProperty(code) && addedCaches[code] === undefined) {
396
                    site.markers[code].setMap(null);
397
                    delete site.markers[code];
398
                }
399
            }
400
            site.finished = true;
401
        },
402
        error: function () {
403
            site.markers = {};
404
            site.finished = true;
405
        }
406
    });
407
};
408
409
410
Okapi.loadBbox = function () {
411
    'use strict';
412
413
    if (!this.m_ready) {
414
        return;
415
    }
416
417
    var self = this;
418
    this.m_sites.map(function (site) {
419
        self.loadBboxSite(site.siteid);
420
    });
421
};
422
423
424
Okapi.unscheduleLoad = function () {
425
    'use strict';
426
427
    if (!this.m_ready) {
428
        return;
429
    }
430
431
    if (this.m_timer) {
432
        window.clearTimeout(this.m_timer);
433
        this.m_timer = null;
434
    }
435
};
436
437
438
Okapi.scheduleLoad = function () {
439
    'use strict';
440
441
    if (!this.m_ready) {
442
        return;
443
    }
444
445
    var self = this;
446
447
    this.unscheduleLoad();
448
    this.m_timer = window.setTimeout(function () {
449
        self.loadBbox();
450
    }, 500);
451
};
452
453
454
Okapi.toggle = function (t) {
455
    'use strict';
456
457
    Cookies.set('load_caches', t ? "1" : "0", {expires: 30});
458
    if ($('#geocaches').is(':checked') !== t) {
459
        $('#geocaches').attr('checked', t);
460
    }
461
462
    if (this.m_enabled !== t) {
463
        this.m_enabled = t;
464
    }
465
466
    if (this.m_enabled) {
467
        this.setupIcons();
468
        this.setupSites();
469
        this.scheduleLoad();
470
    } else {
471
        this.unscheduleLoad();
472
        this.removeMarkers();
473
    }
474
};
475
476
477
Okapi.restore = function (defaultValue) {
478
    'use strict';
479
480
    var state = get_cookie_string("load_caches", "invalid");
481
482
    if (state === "0") {
483
        this.toggle(false);
484
    } else if (state === "1") {
485
        this.toggle(true);
486
    } else {
487
        this.toggle(defaultValue);
488
    }
489
};
490