aboutsummaryrefslogtreecommitdiffstats
path: root/web/js
diff options
context:
space:
mode:
Diffstat (limited to 'web/js')
-rw-r--r--web/js/dashboard.js9
-rw-r--r--web/js/lazyload.js31
-rw-r--r--web/js/map-OpenLayers.js88
-rw-r--r--web/js/map-google-ol.js3
-rw-r--r--web/js/map-google.js2
-rw-r--r--web/js/validation_rules.js8
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'
+ }
+ }
};