diff options
Diffstat (limited to 'web/js')
-rw-r--r-- | web/js/dashboard.js | 9 | ||||
-rw-r--r-- | web/js/lazyload.js | 31 | ||||
-rw-r--r-- | web/js/map-OpenLayers.js | 88 | ||||
-rw-r--r-- | web/js/map-google-ol.js | 3 | ||||
-rw-r--r-- | web/js/map-google.js | 2 | ||||
-rw-r--r-- | web/js/validation_rules.js | 8 |
6 files changed, 105 insertions, 36 deletions
diff --git a/web/js/dashboard.js b/web/js/dashboard.js index a6e06e048..b35af2996 100644 --- a/web/js/dashboard.js +++ b/web/js/dashboard.js @@ -137,6 +137,11 @@ $(function(){ setUpLabelsForChart(this); } }, + elements: { + line: { + cubicInterpolationMode: 'monotone' + } + }, layout: { padding: { top: 4 @@ -179,8 +184,8 @@ $(function(){ rowValues.push( parseInt($(this).find('td').text(), 10) ); }); - for (var i=colours.length; i<rowLabels.length; i++) { - colours[i] = colours[i % colours.length]; + for (var l=colours.length, i=l; i<rowLabels.length; i++) { + colours[i] = colours[i % l]; } var barChart = new Chart($canvas, { diff --git a/web/js/lazyload.js b/web/js/lazyload.js new file mode 100644 index 000000000..770fc62d4 --- /dev/null +++ b/web/js/lazyload.js @@ -0,0 +1,31 @@ +// jshint esversion: 6 + +(function(){ + if (!('IntersectionObserver' in window)) { + return; + } + + // Now we're here, we can assume quite modern JavaScript! + + const observer = new IntersectionObserver(onIntersection, { + rootMargin: "50px 0px" + }); + + const images = document.querySelectorAll(".js-lazyload"); + images.forEach(image => { + observer.observe(image); + }); + + function onIntersection(entries, observer) { + entries.forEach(entry => { + if (entry.intersectionRatio > 0) { + // Loading the image is the only thing we care about, so can + // stop observing. + observer.unobserve(entry.target); + // Removing this class (which is suppressing background-image) + // will trigger the image load + entry.target.classList.remove('js-lazyload'); + } + }); + } +})(); diff --git a/web/js/map-OpenLayers.js b/web/js/map-OpenLayers.js index 31f5f49d8..0f6cca2b5 100644 --- a/web/js/map-OpenLayers.js +++ b/web/js/map-OpenLayers.js @@ -22,6 +22,23 @@ $.extend(fixmystreet.utils, { fixmystreet.maps = fixmystreet.maps || {}; + var drag = { + activate: function() { + this._drag = new OpenLayers.Control.DragFeatureFMS( fixmystreet.markers, { + onComplete: function(feature, e) { + fixmystreet.update_pin( feature.geometry ); + } + } ); + fixmystreet.map.addControl( this._drag ); + this._drag.activate(); + }, + deactivate: function() { + if (this._drag) { + this._drag.deactivate(); + } + } + }; + $.extend(fixmystreet.maps, { // This function might be passed either an OpenLayers.LonLat (so has // lon and lat), or an OpenLayers.Geometry.Point (so has x and y). @@ -212,41 +229,50 @@ $.extend(fixmystreet.utils, { } } fixmystreet.markers.redraw(); + }, + + /* Keep track of how many things are loading simultaneously, and only hide + * the loading spinner when everything has finished. + * This allows multiple layers to be loading at once without each layer + * having to keep track of the others or be responsible for manipulating + * the spinner in the DOM. + */ + loading_spinner: { + count: 0, + show: function() { + fixmystreet.maps.loading_spinner.count++; + if (fixmystreet.maps.loading_spinner.count > 0) { + // Show the loading indicator over the map + $('#loading-indicator').removeClass('hidden'); + $('#loading-indicator').attr('aria-hidden', false); + } + }, + hide: function() { + fixmystreet.maps.loading_spinner.count--; + if (fixmystreet.maps.loading_spinner.count <= 0) { + // Remove loading indicator + $('#loading-indicator').addClass('hidden'); + $('#loading-indicator').attr('aria-hidden', true); + } + } } }); - var drag = { - activate: function() { - this._drag = new OpenLayers.Control.DragFeatureFMS( fixmystreet.markers, { - onComplete: function(feature, e) { - fixmystreet.update_pin( feature.geometry ); - } - } ); - fixmystreet.map.addControl( this._drag ); - this._drag.activate(); - }, - deactivate: function() { - if (this._drag) { - this._drag.deactivate(); - } - } - }; - /* Make sure pins aren't going to reload just because we're zooming out, * we already have the pins when the page loaded */ function zoomToBounds(bounds) { if (!bounds) { return; } - fixmystreet.markers.strategies[0].deactivate(); + var strategy = fixmystreet.markers.strategies[0]; + strategy.deactivate(); var center = bounds.getCenterLonLat(); var z = fixmystreet.map.getZoomForExtent(bounds); - if ( z < 13 && $('html').hasClass('mobile') ) { - z = 13; - } fixmystreet.map.setCenter(center, z); // Reactivate the strategy and make it think it's done an update - fixmystreet.markers.strategies[0].activate(); - fixmystreet.markers.strategies[0].calculateBounds(); - fixmystreet.markers.strategies[0].resolution = fixmystreet.map.getResolution(); + strategy.activate(); + if (strategy instanceof OpenLayers.Strategy.BBOX) { + strategy.calculateBounds(); + strategy.resolution = fixmystreet.map.getResolution(); + } } function sidebar_highlight(problem_id) { @@ -542,6 +568,8 @@ $.extend(fixmystreet.utils, { fixmystreet.map.removePopup(fixmystreet.map.popups[0]); } }); + fixmystreet.markers.events.register( 'loadstart', null, fixmystreet.maps.loading_spinner.show); + fixmystreet.markers.events.register( 'loadend', null, fixmystreet.maps.loading_spinner.hide); var markers = fixmystreet.maps.markers_list( fixmystreet.pins, true ); fixmystreet.markers.addFeatures( markers ); @@ -851,19 +879,17 @@ OpenLayers.Protocol.FixMyStreet = OpenLayers.Class(OpenLayers.Protocol.HTTP, { use_page: false, read: function(options) { - // Show the loading indicator over the map - $('#loading-indicator').removeClass('hidden'); - $('#loading-indicator').attr('aria-hidden', false); // Pass the values of the category, status, and sort fields as query params + options.params = options.params || {}; $.each({ filter_category: 'filter_categories', status: 'statuses', sort: 'sort' }, function(key, id) { var val = $('#' + id).val(); if (val !== undefined) { - options.params = options.params || {}; options.params[key] = val; } }); + var page; if (this.use_page) { - var page = $('.pagination').data('page'); + page = $('.pagination').data('page'); this.use_page = false; } else if (this.initial_page) { page = 1; @@ -880,9 +906,7 @@ OpenLayers.Protocol.FixMyStreet = OpenLayers.Class(OpenLayers.Protocol.HTTP, { /* Pan data handler */ OpenLayers.Format.FixMyStreet = OpenLayers.Class(OpenLayers.Format.JSON, { read: function(json, filter) { - // Remove loading indicator - $('#loading-indicator').addClass('hidden'); - $('#loading-indicator').attr('aria-hidden', true); + var obj; if (typeof json == 'string') { obj = OpenLayers.Format.JSON.prototype.read.apply(this, [json, filter]); } else { diff --git a/web/js/map-google-ol.js b/web/js/map-google-ol.js index 7369a8e9f..99670d4f2 100644 --- a/web/js/map-google-ol.js +++ b/web/js/map-google-ol.js @@ -10,6 +10,7 @@ $(function(){ fixmystreet.map.setBaseLayer(fixmystreet.map.layers[1]); } }); + // jshint undef:false if (typeof fixmystreet_google_default !== 'undefined' && fixmystreet_google_default == 'satellite') { $('#map_layer_toggle').click(); } @@ -36,7 +37,9 @@ fixmystreet.maps.config = function() { var road_layer = {}; // Empty object defaults to standard road layer function apply_map_styles() { + // jshint undef:false var styledMapType = new google.maps.StyledMapType(fixmystreet_google_maps_custom_style); + // jshint undef:true this.mapObject.mapTypes.set('styled', styledMapType); this.mapObject.setMapTypeId('styled'); } diff --git a/web/js/map-google.js b/web/js/map-google.js index 75a1b25a1..bf9909f02 100644 --- a/web/js/map-google.js +++ b/web/js/map-google.js @@ -41,7 +41,7 @@ fixmystreet.maps = {}; }); fixmystreet.report_marker = marker; google.maps.event.removeListener(fixmystreet.event_update_map); - for (m=0; m<fixmystreet.markers.length; m++) { + for (var m=0; m<fixmystreet.markers.length; m++) { fixmystreet.markers[m].setMap(null); } } diff --git a/web/js/validation_rules.js b/web/js/validation_rules.js index 5295a53ca..e6d745336 100644 --- a/web/js/validation_rules.js +++ b/web/js/validation_rules.js @@ -1,5 +1,11 @@ validation_rules = { title: { required: true }, detail: { required: true }, - update: { required: true } + update: { required: true }, + password_register: { + remote: { + url: '/auth/common_password', + type: 'post' + } + } }; |