diff options
Diffstat (limited to 'web')
-rw-r--r-- | web/cobrands/angus/js.js | 8 | ||||
-rw-r--r-- | web/cobrands/bristol/js.js | 4 | ||||
-rw-r--r-- | web/cobrands/fixmystreet.com/base.scss | 35 | ||||
-rw-r--r-- | web/cobrands/fixmystreet/fixmystreet.js | 3 | ||||
-rw-r--r-- | web/cobrands/fixmystreet/offline.js | 409 | ||||
-rw-r--r-- | web/cobrands/oxfordshire/base.scss | 1 | ||||
-rw-r--r-- | web/cobrands/sass/_top-banner.scss | 49 |
7 files changed, 475 insertions, 34 deletions
diff --git a/web/cobrands/angus/js.js b/web/cobrands/angus/js.js index af70fd92f..f3e7bf211 100644 --- a/web/cobrands/angus/js.js +++ b/web/cobrands/angus/js.js @@ -1,3 +1,9 @@ +(function(){ + +if (!fixmystreet.maps) { + return; +} + $(fixmystreet.add_assets({ wfs_url: "https://data.angus.gov.uk/geoserver/services/wfs", wfs_feature: "lighting_column_v", @@ -13,3 +19,5 @@ $(fixmystreet.add_assets({ }, geometryName: 'g' })); + +})(); diff --git a/web/cobrands/bristol/js.js b/web/cobrands/bristol/js.js index 129037d23..1fc23d61a 100644 --- a/web/cobrands/bristol/js.js +++ b/web/cobrands/bristol/js.js @@ -1,5 +1,9 @@ (function(){ +if (!fixmystreet.maps) { + return; +} + var options = { wfs_url: "https://maps.bristol.gov.uk/arcgis/services/ext/FixMyStreetSupportData/MapServer/WFSServer", wfs_feature: "COD_ASSETS_POINT", diff --git a/web/cobrands/fixmystreet.com/base.scss b/web/cobrands/fixmystreet.com/base.scss index e04465edc..d0a152627 100644 --- a/web/cobrands/fixmystreet.com/base.scss +++ b/web/cobrands/fixmystreet.com/base.scss @@ -7,40 +7,7 @@ @import "../sass/h5bp"; @import "_colours"; @import "../sass/base"; - -.top_banner { - color: $primary_text; - background: $primary; - p { - margin: auto; - padding: 0.5em 2em; - max-width: 50em; - text-align: center; - } - a { - color: $primary_text; - text-decoration: underline; - } -} - -.top_banner--donate { - background: #bef; -} - -// The banner interferes with the map moving/placement on mobile, and the top -// bar navigation on desktop (which both assume that .wrapper is at the top of -// the page) so hide there for now -.mappage .top_banner--donate { - display: none; -} - -// This banner is only shown via JavaScript AJAX call -.top_banner--country { - display: none; -} -.top_banner__close { - float: $right; -} +@import "../sass/top-banner"; #site-logo { background: url('data:image/png;base64,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') no-repeat; diff --git a/web/cobrands/fixmystreet/fixmystreet.js b/web/cobrands/fixmystreet/fixmystreet.js index e4c5ba71c..dd9167185 100644 --- a/web/cobrands/fixmystreet/fixmystreet.js +++ b/web/cobrands/fixmystreet/fixmystreet.js @@ -316,6 +316,7 @@ $.extend(fixmystreet.set_up, { $change = $form.find("input[name='change']" ), $submit = $form.find("input[type='submit']" ), $labels = $('label[for="' + $submit.attr('id') + '"]'), + problemId = $form.find("input[name='id']").val(), data = $form.serialize() + '&ajax=1', changeValue, buttonLabel, @@ -327,10 +328,12 @@ $.extend(fixmystreet.set_up, { buttonLabel = $submit.data('label-remove'); buttonValue = $submit.data('value-remove'); $('.shortlisted-status').remove(); + $(document).trigger('shortlist-add', problemId); } else if (data.outcome == 'remove') { changeValue = "add"; buttonLabel = $submit.data('label-add'); buttonValue = $submit.data('value-add'); + $(document).trigger('shortlist-remove', problemId); } $change.val(changeValue); $submit.val(buttonValue).attr('aria-label', buttonLabel); diff --git a/web/cobrands/fixmystreet/offline.js b/web/cobrands/fixmystreet/offline.js new file mode 100644 index 000000000..54ab12061 --- /dev/null +++ b/web/cobrands/fixmystreet/offline.js @@ -0,0 +1,409 @@ +fixmystreet.offlineBanner = (function() { + var toCache = 0; + var cachedSoFar = 0; + + function formText() { + var num = fixmystreet.offlineData.getForms().length; + return num + ' form' + (num===1 ? '' : 's'); + } + + function onlineText() { + return 'You have <a id="oFN" href=""><span>' + formText() + '</span> saved to submit</a>.'; + } + + function offlineText() { + return 'You are offline \u2013 <span>' + formText() + '</span> saved.'; + } + + return { + make: function(offline) { + var num = fixmystreet.offlineData.getForms().length; + var banner = ['<div class="top_banner top_banner--offline"><p><span id="offline_saving"></span> <span id="offline_forms">']; + if (offline || num > 0) { + banner.push(offline ? offlineText() : onlineText()); + } + banner.push('</span></p></div>'); + banner = $(banner.join('')); + banner.prependTo('.content'); + if (num === 0) { + banner.hide(); + } + + window.addEventListener("offline", function(e) { + $('#offline_forms').html(offlineText()); + }); + + window.addEventListener("online", function(e) { + $('#offline_forms').html(onlineText()); + }); + + function nextForm(DataOrJqXHR, textStatus, jqXHROrErrorThrown) { + fixmystreet.offlineData.shiftForm(); + $(document).dequeue('postForm'); + } + + function postForm(url, data) { + return $.ajax({ url: url, data: data, type: 'POST' }).done(nextForm); + } + + $(document).on('click', '#oFN', function(e) { + e.preventDefault(); + fixmystreet.offlineData.getForms().forEach(function(form) { + $(document).queue('postForm', function() { + postForm(form[0], form[1]).fail(function(jqXHR) { + if (jqXHR.status !== 400) { + return nextForm(); + } + // In case the request failed due to out-of-date CSRF token, + // try once more with a new token given in the error response. + var m = jqXHR.responseText.match(/name="token" value="([^"]*)"/); + if (!m) { + return nextForm(); + } + var token = m[1]; + if (!token) { + return nextForm(); + } + var param = form[1].replace(/&token=[^&]*/, '&token=' + token); + return postForm(form[0], param).fail(nextForm); + }); + }); + }); + $(document).dequeue('postForm'); + }); + }, + update: function() { + $('.top_banner--offline').slideDown(); + $('#offline_forms span').text(formText()); + }, + startProgress: function(l) { + $('.top_banner--offline').slideDown(); + toCache = l; + $('#offline_saving').html('Saving reports offline – <span>0</span>/' + toCache + '.'); + }, + progress: function() { + cachedSoFar += 1; + if (cachedSoFar === toCache) { + $('#offline_saving').text('Reports saved offline.'); + } else { + $('#offline_saving span').text(cachedSoFar); + } + } + }; +})(); + +fixmystreet.offlineData = (function() { + var data; + + function getData() { + if (data === undefined) { + data = JSON.parse(localStorage.getItem('offlineData')); + if (!data) { + data = { cachedReports: {}, forms: [] }; + } + } + return data; + } + + function saveData() { + localStorage.setItem('offlineData', JSON.stringify(getData())); + } + + return { + getForms: function() { + return getData().forms; + }, + addForm: function(action, formData) { + var forms = getData().forms; + if (!forms.length || formData != forms[forms.length - 1][1]) { + forms.push([action, formData]); + saveData(); + } + fixmystreet.offlineBanner.update(); + }, + shiftForm: function(idx) { + getData().forms.shift(); + saveData(); + fixmystreet.offlineBanner.update(); + }, + clearForms: function(idx) { + getData().forms = []; + saveData(); + fixmystreet.offlineBanner.update(); + }, + getCachedUrls: function() { + return Object.keys(getData().cachedReports); + }, + isIndexed: function(url, lastupdate) { + if (lastupdate) { + return getData().cachedReports[url] === lastupdate; + } + return !!getData().cachedReports[url]; + }, + add: function(url, lastupdate) { + var data = getData(); + data.cachedReports[url] = lastupdate || "-"; + saveData(); + }, + remove: function(urls) { + var data = getData(); + urls.forEach(function(url) { + delete data.cachedReports[url]; + }); + saveData(); + } + }; +})(); + +fixmystreet.cachet = (function(){ + var urlsInProgress = {}; + + function cacheURL(url, type) { + urlsInProgress[url] = 1; + + var ret; + if (type === 'image') { + ret = $.Deferred(function(deferred) { + var oReq = new XMLHttpRequest(); + oReq.open("GET", url, true); + oReq.responseType = "blob"; + oReq.onload = function(oEvent) { + var blob = oReq.response; + var reader = new window.FileReader(); + reader.readAsDataURL(blob); + reader.onloadend = function() { + localStorage.setItem(url, reader.result); + delete urlsInProgress[url]; + deferred.resolve(blob); + }; + }; + oReq.send(); + }); + } else { + ret = $.ajax(url).pipe(function(content, textStatus, jqXHR) { + localStorage.setItem(url, content); + delete urlsInProgress[url]; + return content; + }); + } + return ret; + } + + function cacheReport(item) { + return cacheURL(item.url, 'html').pipe(function(html) { + var $reportPage = $(html); + var imagesToGet = [ + item.url + '/map' // Static map image + ]; + $reportPage.find('img').each(function(i, img) { + if (img.src.indexOf('/photo/') === -1 || fixmystreet.offlineData.isIndexed(img.src) || urlsInProgress[img.src]) { + return; + } + imagesToGet.push(img.src); + imagesToGet.push(img.src.replace('.jpeg', '.fp.jpeg')); + }); + var imagePromises = imagesToGet.map(function(url) { + return cacheURL(url, 'image'); + }); + return $.when.apply(undefined, imagePromises).pipe(function() { + fixmystreet.offlineBanner.progress(); + fixmystreet.offlineData.add(item.url, item.lastupdate); + }, function() { + fixmystreet.offlineBanner.progress(); + fixmystreet.offlineData.add(item.url, item.lastupdate); + }); + }); + } + + // Cache a list of reports offline + // This fetches the HTML and any img elements in that HTML + function cacheReports(items) { + fixmystreet.offlineBanner.startProgress(items.length); + var promises = items.map(function(item) { + return cacheReport(item); + }); + return $.when.apply(undefined, promises); + } + + return { + cacheReports: cacheReports + }; +})(); + +fixmystreet.offline = (function() { + function getReportsFromList() { + var reports = $('.item-list__item').map(function(i, li) { + var $li = $(li), + url = $li.find('a')[0].pathname, + lastupdate = $li.data('lastupdate'); + return { 'url': url, 'lastupdate': lastupdate }; + }).get(); + return reports; + } + + function updateCachedReports() { + var toCache = []; + var toRemove = []; + var shouldBeCached = {}; + + localStorage.setItem('/my/planned', $('.item-list').html()); + + getReportsFromList().forEach(function(item, i) { + if (!fixmystreet.offlineData.isIndexed(item.url, item.lastupdate)) { + toCache.push(item); + } + shouldBeCached[item.url] = 1; + }); + + fixmystreet.offlineData.getCachedUrls().forEach(function(url) { + if ( !shouldBeCached[url] ) { + toRemove.push(url); + } + }); + + if (toRemove[0]) { + removeReports(toRemove); + } + if (toCache[0]) { + fixmystreet.cachet.cacheReports(toCache); + } + } + + // Remove a list of reports from the offline cache + function removeReports(urls) { + var pathsRemoved = []; + urls.forEach(function(url) { + var html = localStorage.getItem(url); + var $reportPage = $(html); + localStorage.removeItem(url + '/map'); + $reportPage.find('img').each(function(i, img) { + if (img.src.indexOf('/photo/') === -1) { + return; + } + localStorage.removeItem(img.src); + localStorage.removeItem(img.src.replace('.jpeg', '.fp.jpeg')); + }); + localStorage.removeItem(url); + }); + fixmystreet.offlineData.remove(urls); + } + + function showReportFromCache(url) { + var html = localStorage.getItem(url); + if (!html) { + return false; + } + var map = localStorage.getItem(url + '/map'); + var found = html.match(/<body[^>]*>[\s\S]*<\/body>/); + document.body.outerHTML = found[0]; + $('#map_box').html('<img src="' + map + '">').css({ textAlign: 'center', height: 'auto' }); + replaceImages('img'); + + $('.moderate-display.segmented-control, .shadow-wrap, #update_form, #report-cta, .mysoc-footer, .nav-wrapper').hide(); + + $('.js-back-to-report-list').attr('href', '/my/planned'); + + // Refill form with saved data if there is any + var savedForm; + fixmystreet.offlineData.getForms().forEach(function(form) { + if (form[0].endsWith(url)) { + savedForm = form[1]; + } + }); + if (savedForm) { + savedForm.replace(/\+/g, '%20').split('&').forEach(function(kv) { + kv = kv.split('=', 2); + if (kv[0] != 'save_inspected' && kv[0] != 'public_update' && kv[0] != 'save') { + $('[name=' + kv[0] + ']').val(decodeURIComponent(kv[1])); + } + }); + } + + $('#report_inspect_form').submit(function() { + var data = $(this).serialize() + '&save=1&saved_at=' + Math.floor(+new Date() / 1000); + fixmystreet.offlineData.addForm(this.action, data); + location.href = '/my/planned?saved=1'; + return false; + }); + + return true; + } + + function replaceImages(selector) { + $(selector).each(function(i, img) { + if (img.src.indexOf('/photo/') > -1) { + var dataImg = localStorage.getItem(img.src); + if (dataImg) { + img.src = dataImg; + } + } + }); + } + + return { + replaceImages: replaceImages, + showReportFromCache: showReportFromCache, + removeReports: removeReports, + updateCachedReports: updateCachedReports + }; + +})(); + +if ($('#offline_list').length) { + // We are OFFLINE + var success = false; + if (location.pathname.indexOf('/report') === 0) { + success = fixmystreet.offline.showReportFromCache(location.pathname); + } + if (!success) { + var html = localStorage.getItem('/my/planned'); + if (html) { + $('#offline_list').before('<h2>Your offline reports</h2>'); + $('#offline_list').html(html); + if (location.search.indexOf('saved=1') > 0) { + $('#offline_list').before('<p class="form-success">Your form has been saved offline for submission when back online.</p>'); + } + fixmystreet.offline.replaceImages('#offline_list img'); + var offlineForms = fixmystreet.offlineData.getForms(); + var savedForms = {}; + offlineForms.forEach(function(form) { + savedForms[form[0]] = 1; + }); + $('#offline_list a').each(function(i, a) { + if (savedForms[a.href]) { + $(this).find('h3').prepend('<em>Form data saved</em> '); + } + }); + $('#offline_clear').html('<button id="js-clear-localStorage">Clear offline data</button>'); + $('#js-clear-localStorage').click(function() { + fixmystreet.offline.removeReports(fixmystreet.offlineData.getCachedUrls()); + fixmystreet.offlineData.clearForms(); + localStorage.removeItem('/my/planned'); + alert('Offline data cleared'); + }); + } + } + fixmystreet.offlineBanner.make(true); +} else { + // Put the appcache manifest in a page in an iframe so that HTML pages + // aren't cached (thanks to Jake Archibald for documenting this!) + if (window.applicationCache && window.localStorage) { + $(document.body).prepend('<iframe src="/offline/appcache" style="position:absolute;top:-999em;visibility:hidden"></iframe>'); + } + + fixmystreet.offlineBanner.make(false); + + // On /my/planned, when online, cache all shortlisted + if (location.pathname === '/my/planned') { + fixmystreet.offline.updateCachedReports(); + } + + // Catch additions and removals from the shortlist + $(document).on('shortlist-add', function(e, id) { + var lastupdate = $('.problem-header').data('lastupdate'); + fixmystreet.cachet.cacheReports([{ 'url': '/report/' + id, 'lastupdate': lastupdate }]); + }); + $(document).on('shortlist-remove', function(e, id) { + fixmystreet.offline.removeReports(['/report/' + id]); + }); +} diff --git a/web/cobrands/oxfordshire/base.scss b/web/cobrands/oxfordshire/base.scss index 72ddbd437..0cc621310 100644 --- a/web/cobrands/oxfordshire/base.scss +++ b/web/cobrands/oxfordshire/base.scss @@ -3,6 +3,7 @@ @import "../sass/mixins"; @import "../sass/base"; +@import "../sass/top-banner"; #site-header { background: none; diff --git a/web/cobrands/sass/_top-banner.scss b/web/cobrands/sass/_top-banner.scss new file mode 100644 index 000000000..8677343c2 --- /dev/null +++ b/web/cobrands/sass/_top-banner.scss @@ -0,0 +1,49 @@ +.top_banner { + color: $primary_text; + background: $primary; + p { + margin: auto; + padding: 0.5em 2em; + max-width: 50em; + text-align: center; + } + a { + color: $primary_text; + text-decoration: underline; + } +} + +.top_banner--donate { + background: #bef; +} + +// The banner interferes with the map moving/placement on mobile, and the top +// bar navigation on desktop (which both assume that .wrapper is at the top of +// the page) so hide there for now +.mappage .top_banner--donate { + display: none; +} + +// This banner is only shown via JavaScript AJAX call +.top_banner--country { + display: none; +} + +.top_banner--offline { + position: fixed; left: 0; right: 0; top: 0; z-index: 100; + opacity: 0.9; + background: #c33; + color: #fff; +} + +.top_banner--offline a { + color: #fff; +} + +.top_banner--offline a:hover { + color: #000; +} + +.top_banner__close { + float: $right; +} |