-
Notifications
You must be signed in to change notification settings - Fork 0
/
browser.js
129 lines (118 loc) · 3.37 KB
/
browser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Polyfill node-js libs required by the gpx parser:
window.require = function(name) {
if(name === 'events') {
return Events;
} else if(name === 'timers') {
return {
setImmediate: function(func, ...args) {
return setTimeout(func, 0, ...args);
}
};
}
throw new Error(`No Node Polyfill for ${name}`);
};
import Events from 'events/events';
import { process_gpx_string } from './main.js';
function log(string) {
const ele = document.getElementById('log');
if(string === false) {
ele.innerHTML = '';
} else {
// most minimal sanitizer here of course this is NOT safe for
// the general case
string.replace(/</g, '<').replace(/>/g, '>');
ele.innerHTML += `${string}<br>`;
}
}
async function downloadFile(suggestedName, content) {
if(false && window.showSaveFilePicker) {
// XXX sadly not working. Due to promise chain requried user interaction
// is missing.
try {
const handle = await window.showSaveFilePicker({suggestedName });
const writable = await handle.createWritable();
await writable.write(content);
await writable.close();
} catch(err) {
log(`Failed writing output`);
console.log('Save failed');
console.error(err);
}
} else {
// Fallback if the File System Access API is not supported…
// Create the blob URL.
const blobURL = URL.createObjectURL(new Blob([content]));
const a = document.createElement('a');
a.href = blobURL;
a.download = suggestedName;
a.style.display = 'none';
document.body.append(a);
a.click();
// Revoke the blob URL and remove the element.
setTimeout(() => {
URL.revokeObjectURL(blobURL);
a.remove();
}, 1000);
log(`Your browser should now "download" the generated file.`);
log(`Ready for next file!`);
}
}
async function handleUpload(evt) {
let files = evt.target.files;
log(false); // clear
for(let i = 0; i < files.length; i++) {
let f = files[i];
log(`Read ${f.name}`);
let suggestedName = f.name.replace(/.gpx/, '-pois.kml');
if(suggestedName === f.name) {
suggestedName = `${f.name}-pois.kml`;
}
let reader = new FileReader();
let job = new Promise((resolve, reject) => {
reader.onload = async function(e) {
const input = e.target.result;
log(`Fetching POIs ...`);
let opt = {};
for(const node of document.querySelectorAll('.poi-opts input')) {
opt[node.id] = node.valueAsNumber || undefined;
}
const output = await process_gpx_string(input, 'upload', opt);
log(`Save File as KML ...`);
await downloadFile(suggestedName, output);
resolve(e);
};
reader.onerror = function(err) {
reject(err);
};
reader.readAsText(f);
});
try {
// serialize all files
await job;
log(`Done ${f.name}`);
} catch(err) {
log(`Failed ${f.name}`);
console.error(`Failed File: ${job}`);
console.error(err);
}
}
}
function handleInputChange() {
var val = this.valueAsNumber;
var unit = this.dataset.unit;
if(!val) {
val = 'Off';
} else {
val = `${this.value} ${unit}`;
}
document.getElementById(`${this.id}-out`).textContent = val;
}
window.startApp = function() {
document.getElementById('gpxfile').addEventListener('change', handleUpload);
for(const node of document.querySelectorAll('.poi-opts input')) {
node.addEventListener('change', handleInputChange);
handleInputChange.call(node);
}
log(false); // clear
log('Ready!');
};