Download in client from Blob URL
This commit is contained in:
parent
0fc468a682
commit
7aa2fcb93c
5 changed files with 33 additions and 140 deletions
|
|
@ -22,5 +22,6 @@
|
||||||
touchScreen: touchScreen,
|
touchScreen: touchScreen,
|
||||||
touchScreenDetectable: touchScreenDetectable,
|
touchScreenDetectable: touchScreenDetectable,
|
||||||
touch: touch,
|
touch: touch,
|
||||||
|
download: 'Blob' in window && 'createObjectURL' in URL && 'download' in document.createElement('a'),
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ BR.Export = L.Class.extend({
|
||||||
var trackname = (this.trackname = document.getElementById('trackname'));
|
var trackname = (this.trackname = document.getElementById('trackname'));
|
||||||
this.tracknameAllowedChars = BR.conf.tracknameAllowedChars;
|
this.tracknameAllowedChars = BR.conf.tracknameAllowedChars;
|
||||||
|
|
||||||
if (this.tracknameAllowedChars) {
|
// a.download attribute automatically replaces invalid characters
|
||||||
|
if (!BR.Browser.download && this.tracknameAllowedChars) {
|
||||||
this.tracknameMessage = document.getElementById('trackname-message');
|
this.tracknameMessage = document.getElementById('trackname-message');
|
||||||
var patternRegex = new RegExp('[' + this.tracknameAllowedChars + ']+');
|
var patternRegex = new RegExp('[' + this.tracknameAllowedChars + ']+');
|
||||||
|
|
||||||
|
|
@ -52,19 +53,33 @@ BR.Export = L.Class.extend({
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (true) {
|
if (BR.Browser.download) {
|
||||||
var uri = this.router.getUrl(this.latLngs, this.pois.getMarkers(), null, format, nameUri, includeWaypoints);
|
|
||||||
|
|
||||||
// var evt = document.createEvent('MouseEvents');
|
|
||||||
// evt.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
|
||||||
// var link = document.createElement('a');
|
|
||||||
// link.href = uri;
|
|
||||||
// link.dispatchEvent(evt);
|
|
||||||
//} else {
|
|
||||||
|
|
||||||
const track = this._formatTrack(format, name, includeWaypoints);
|
const track = this._formatTrack(format, name, includeWaypoints);
|
||||||
console.log('track: ', track);
|
|
||||||
BR.Diff.diff(uri, track, format);
|
const mimeTypeMap = {
|
||||||
|
gpx: 'application/gpx+xml',
|
||||||
|
kml: 'application/vnd.google-earth.kml+xml',
|
||||||
|
geojson: 'application/vnd.geo+json',
|
||||||
|
csv: 'text/tab-separated-values',
|
||||||
|
};
|
||||||
|
|
||||||
|
const mimeType = mimeTypeMap[format];
|
||||||
|
|
||||||
|
const blob = new Blob([track], {
|
||||||
|
type: mimeType + ';charset=utf-8',
|
||||||
|
});
|
||||||
|
const objectUrl = URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = objectUrl;
|
||||||
|
link.download = (name || 'brouter') + '.' + format;
|
||||||
|
link.click();
|
||||||
|
} else {
|
||||||
|
var uri = this.router.getUrl(this.latLngs, this.pois.getMarkers(), null, format, nameUri, includeWaypoints);
|
||||||
|
var evt = document.createEvent('MouseEvents');
|
||||||
|
evt.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||||
|
var link = document.createElement('a');
|
||||||
|
link.href = uri;
|
||||||
|
link.dispatchEvent(evt);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -134,7 +149,6 @@ BR.Export = L.Class.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
_generateTrackname: function () {
|
_generateTrackname: function () {
|
||||||
return; // TODO remove
|
|
||||||
var trackname = this.trackname;
|
var trackname = this.trackname;
|
||||||
this._getCityAtPosition(
|
this._getCityAtPosition(
|
||||||
this.latLngs[0],
|
this.latLngs[0],
|
||||||
|
|
@ -143,7 +157,7 @@ BR.Export = L.Class.extend({
|
||||||
this.latLngs[this.latLngs.length - 1],
|
this.latLngs[this.latLngs.length - 1],
|
||||||
L.bind(function (to) {
|
L.bind(function (to) {
|
||||||
var distance = document.getElementById('distance').innerHTML;
|
var distance = document.getElementById('distance').innerHTML;
|
||||||
if (this.tracknameAllowedChars) {
|
if (!BR.Browser.download && this.tracknameAllowedChars) {
|
||||||
distance = distance.replace(',', '.'); // temp. fix (#202)
|
distance = distance.replace(',', '.'); // temp. fix (#202)
|
||||||
}
|
}
|
||||||
if (!from || !to) {
|
if (!from || !to) {
|
||||||
|
|
@ -161,7 +175,7 @@ BR.Export = L.Class.extend({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.tracknameAllowedChars) {
|
if (!BR.Browser.download && this.tracknameAllowedChars) {
|
||||||
// temp. fix: replace and remove characters that will get removed by server quick fix (#194)
|
// temp. fix: replace and remove characters that will get removed by server quick fix (#194)
|
||||||
trackname.value = trackname.value.replace(/[>)]/g, '').replace(/ \(/g, ' - ');
|
trackname.value = trackname.value.replace(/[>)]/g, '').replace(/ \(/g, ' - ');
|
||||||
this._validationMessage();
|
this._validationMessage();
|
||||||
|
|
|
||||||
124
js/util/Diff.js
124
js/util/Diff.js
|
|
@ -1,124 +0,0 @@
|
||||||
BR.Diff = {};
|
|
||||||
|
|
||||||
// <script src="https://unpkg.com/googlediff@0.1.0/javascript/diff_match_patch.js"></script>
|
|
||||||
BR.Diff.diff = function (uri, track, format) {
|
|
||||||
BR.Util.get(
|
|
||||||
uri,
|
|
||||||
((err, text) => {
|
|
||||||
if (err) {
|
|
||||||
console.error('Error exporting "' + profileUrl + '": ' + err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format === 'gpx') {
|
|
||||||
text = BR.Gpx.pretty(BR.Diff.adoptGpx(text));
|
|
||||||
} else if (format === 'geojson') {
|
|
||||||
text = JSON.stringify(JSON.parse(text), null, 2);
|
|
||||||
}
|
|
||||||
var dmp = new diff_match_patch();
|
|
||||||
var diff = dmp.diff_main(text, track);
|
|
||||||
dmp.diff_cleanupSemantic(diff);
|
|
||||||
|
|
||||||
if (dmp.diff_levenshtein(diff) > 0) {
|
|
||||||
let i = 0;
|
|
||||||
while (i < diff.length - 2) {
|
|
||||||
if (
|
|
||||||
diff[i][0] === 0 &&
|
|
||||||
diff[i + 1][0] === -1 &&
|
|
||||||
diff[i + 2][0] === 1 &&
|
|
||||||
(/(rteTime|rteSpeed)>\d+\.\d{0,2}$/.test(diff[i][1]) || /time=[0-9h ]*m \d$/.test(diff[i][1]))
|
|
||||||
) {
|
|
||||||
const del = +diff[i + 1][1];
|
|
||||||
const ins = +diff[i + 2][1];
|
|
||||||
if (Number.isInteger(del) && Number.isInteger(ins) && Math.abs(del - ins) <= 1) {
|
|
||||||
diff.splice(i + 1, 2);
|
|
||||||
if (i + 1 < diff.length && diff[i + 1][0] === 0) {
|
|
||||||
diff[i + 1][1] = diff[i][1] + diff[i + 1][1];
|
|
||||||
diff.splice(i, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dmp.diff_levenshtein(diff) > 0) {
|
|
||||||
//console.log('server: ', text);
|
|
||||||
//console.log('client: ', track);
|
|
||||||
console.log(diff);
|
|
||||||
bootbox.alert(BR.Diff.diffPrettyHtml(diff));
|
|
||||||
} else {
|
|
||||||
console.log('diff equal');
|
|
||||||
}
|
|
||||||
}).bind(this)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// diff_match_patch.prototype.diff_prettyHtml modified to only show specified number of context lines
|
|
||||||
BR.Diff.diffPrettyHtml = function (diffs, contextLen = 2) {
|
|
||||||
var html = [];
|
|
||||||
var pattern_amp = /&/g;
|
|
||||||
var pattern_lt = /</g;
|
|
||||||
var pattern_gt = />/g;
|
|
||||||
var pattern_para = /\n/g;
|
|
||||||
for (var x = 0; x < diffs.length; x++) {
|
|
||||||
var op = diffs[x][0]; // Operation (insert, delete, equal)
|
|
||||||
var data = diffs[x][1]; // Text of change.
|
|
||||||
var text = data
|
|
||||||
.replace(pattern_amp, '&')
|
|
||||||
.replace(pattern_lt, '<')
|
|
||||||
.replace(pattern_gt, '>')
|
|
||||||
//.replace(pattern_para, '¶<br>');
|
|
||||||
.replace(pattern_para, '<br>');
|
|
||||||
switch (op) {
|
|
||||||
case DIFF_INSERT:
|
|
||||||
html[x] = '<ins style="background:#e6ffe6;">' + text + '</ins>';
|
|
||||||
break;
|
|
||||||
case DIFF_DELETE:
|
|
||||||
html[x] = '<del style="background:#ffe6e6;">' + text + '</del>';
|
|
||||||
break;
|
|
||||||
case DIFF_EQUAL:
|
|
||||||
const lines = text.split('<br>');
|
|
||||||
const len = lines.length;
|
|
||||||
if (len > contextLen * 2) {
|
|
||||||
text = [...lines.slice(0, contextLen), '...', ...lines.slice(-contextLen)].join('<br>');
|
|
||||||
}
|
|
||||||
|
|
||||||
html[x] = '<span>' + text + '</span>';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return html.join('');
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO remove
|
|
||||||
// copied from Gpx.test.js
|
|
||||||
BR.Diff.adoptGpx = function (gpx, replaceCreator = true) {
|
|
||||||
const creator = 'BRouter-Web 0.15.1';
|
|
||||||
const name = 'Track';
|
|
||||||
const newline = '\n';
|
|
||||||
|
|
||||||
gpx = gpx.replace(/=\.(?=\d)/, '=0.');
|
|
||||||
if (replaceCreator) {
|
|
||||||
gpx = gpx.replace(/creator="(?!OsmAndRouter)[^"]*"/, `creator="${creator}"`);
|
|
||||||
}
|
|
||||||
gpx = gpx.replace(/creator="([^"]*)" version="1.1"/, 'version="1.1" \n creator="$1"');
|
|
||||||
//gpx = gpx.replace(/<trk>\n <name>[^<]*<\/name>/, `<trk>\n <name>${name}</name>`);
|
|
||||||
gpx = gpx
|
|
||||||
.split(newline)
|
|
||||||
.map((line) => line.replace(/lon="([^"]*)" lat="([^"]*)"/, 'lat="$2" lon="$1"'))
|
|
||||||
.join(newline);
|
|
||||||
gpx = gpx.replace(/(lon|lat)="([-0-9]+.[0-9]+?)0+"/g, '$1="$2"'); // remove trailing zeros
|
|
||||||
// remove trailing zeros comment-style voicehints
|
|
||||||
gpx = gpx.replace(/;\s*([-0-9]+.[0-9]+?)0+;/g, (match, p1) => `;${p1.padStart(10)};`);
|
|
||||||
gpx = gpx.replace(/>([-0-9]+?\.\d*0+)<\//g, (match, p1) => `>${+p1}</`); // remove trailing zeros
|
|
||||||
gpx = gpx.replace('</gpx>\n', '</gpx>');
|
|
||||||
|
|
||||||
// added
|
|
||||||
// trunc bc. float precision diffs
|
|
||||||
gpx = gpx.replace(/(rteTime|rteSpeed)>([^<]*)<\//g, (match, p1, p2) => `${p1}>${(+p2).toFixed(3)}</`);
|
|
||||||
gpx = gpx.replace(/\n?\s*<\/extensions>\n?\s*<extensions>/, ''); // ignore (invalid) double tag
|
|
||||||
|
|
||||||
return gpx;
|
|
||||||
};
|
|
||||||
|
|
@ -3,6 +3,7 @@ BR.conf = {};
|
||||||
$ = require('jquery');
|
$ = require('jquery');
|
||||||
require('leaflet');
|
require('leaflet');
|
||||||
turf = require('@turf/turf');
|
turf = require('@turf/turf');
|
||||||
|
require('../../js/Browser.js');
|
||||||
require('../../js/control/Export.js');
|
require('../../js/control/Export.js');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ BR.version = '1.5.1';
|
||||||
turf = require('@turf/turf');
|
turf = require('@turf/turf');
|
||||||
togpx = require('togpx');
|
togpx = require('togpx');
|
||||||
require('leaflet');
|
require('leaflet');
|
||||||
|
require('../../js/Browser.js');
|
||||||
require('../../js/format/VoiceHints.js');
|
require('../../js/format/VoiceHints.js');
|
||||||
require('../../js/format/Xml.js');
|
require('../../js/format/Xml.js');
|
||||||
require('../../js/format/Gpx.js');
|
require('../../js/format/Gpx.js');
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue