Got rid of all of the XMLHttpRequests in favor of fetch().
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3842 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										276
									
								
								core/client.js
									
									
									
									
									
								
							
							
						
						
									
										276
									
								
								core/client.js
									
									
									
									
									
								
							@@ -106,15 +106,21 @@ function edit() {
 | 
				
			|||||||
		{tagName: "script", attributes: {src: "/static/codemirror/xml.min.js"}},
 | 
							{tagName: "script", attributes: {src: "/static/codemirror/xml.min.js"}},
 | 
				
			||||||
		{tagName: "script", attributes: {src: "/static/codemirror/htmlmixed.min.js"}},
 | 
							{tagName: "script", attributes: {src: "/static/codemirror/htmlmixed.min.js"}},
 | 
				
			||||||
	], function() {
 | 
						], function() {
 | 
				
			||||||
		load();
 | 
							load().catch(function(error) {
 | 
				
			||||||
 | 
								alert(error);
 | 
				
			||||||
 | 
								closeEditor();
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function trace() {
 | 
					function trace() {
 | 
				
			||||||
	var request = new XMLHttpRequest();
 | 
						fetch('/trace')
 | 
				
			||||||
	request.addEventListener("loadend", function() {
 | 
							.then(function(response) {
 | 
				
			||||||
		if (request.status == 200) {
 | 
								if (!response.ok) {
 | 
				
			||||||
			/* The trace is loaded. */
 | 
									throw new Error('Request failed: ' + response.status + ' ' + response.statusText);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return response.arrayBuffer();
 | 
				
			||||||
 | 
							}).then(function(data) {
 | 
				
			||||||
			var perfetto = window.open('/perfetto/');
 | 
								var perfetto = window.open('/perfetto/');
 | 
				
			||||||
			var done = false;
 | 
								var done = false;
 | 
				
			||||||
			if (perfetto) {
 | 
								if (perfetto) {
 | 
				
			||||||
@@ -122,7 +128,7 @@ function trace() {
 | 
				
			|||||||
					if (message.data == 'PONG') {
 | 
										if (message.data == 'PONG') {
 | 
				
			||||||
						perfetto.postMessage({
 | 
											perfetto.postMessage({
 | 
				
			||||||
							perfetto: {
 | 
												perfetto: {
 | 
				
			||||||
								buffer: request.response,
 | 
													buffer: data,
 | 
				
			||||||
								title: 'Tilde Friends Trace',
 | 
													title: 'Tilde Friends Trace',
 | 
				
			||||||
								url: window.location.href,
 | 
													url: window.location.href,
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
@@ -143,22 +149,9 @@ function trace() {
 | 
				
			|||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				alert("Unable to open perfetto.");
 | 
									alert("Unable to open perfetto.");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							}).catch(function(error) {
 | 
				
			||||||
			alert("Failed to load trace: " + request.status + ".");
 | 
								alert('Failed to load trace: ' + error);
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	request.addEventListener("error", function() {
 | 
					 | 
				
			||||||
		alert("Error loading trace.");
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
	request.addEventListener("timeout", function() {
 | 
					 | 
				
			||||||
		alert("Timed out loading trace.");
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
	request.addEventListener("abort", function() {
 | 
					 | 
				
			||||||
		alert("Loading trace aborted.");
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
	request.responseType = 'arraybuffer';
 | 
					 | 
				
			||||||
	request.open("GET", "/trace");
 | 
					 | 
				
			||||||
	request.send();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function stats() {
 | 
					function stats() {
 | 
				
			||||||
@@ -180,45 +173,27 @@ function guessMode(name) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function loadFile(name, id) {
 | 
					function loadFile(name, id) {
 | 
				
			||||||
	return new Promise(function(resolve, reject) {
 | 
						return fetch('/' + id + '/view').then(function(response) {
 | 
				
			||||||
		var request = new XMLHttpRequest();
 | 
							if (!response.ok) {
 | 
				
			||||||
		request.addEventListener("loadend", function() {
 | 
								throw new Error('Request failed: ' + response.status + ' ' + response.statusText);
 | 
				
			||||||
			if (request.status == 200) {
 | 
							}
 | 
				
			||||||
				gFiles[name].doc = new CodeMirror.Doc(request.responseText, guessMode(name));
 | 
							return response.text();
 | 
				
			||||||
 | 
						}).then(function(text) {
 | 
				
			||||||
 | 
							gFiles[name].doc = new CodeMirror.Doc(text, guessMode(name));
 | 
				
			||||||
		if (!Object.values(gFiles).some(x => !x.doc)) {
 | 
							if (!Object.values(gFiles).some(x => !x.doc)) {
 | 
				
			||||||
			document.getElementById("editPane").style.display = 'flex';
 | 
								document.getElementById("editPane").style.display = 'flex';
 | 
				
			||||||
			openFile(Object.keys(gFiles).sort()[0]);
 | 
								openFile(Object.keys(gFiles).sort()[0]);
 | 
				
			||||||
					resolve();
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				reject('Error loading source.');
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		request.addEventListener("error", function() {
 | 
					 | 
				
			||||||
			alert("Error loading source.");
 | 
					 | 
				
			||||||
			closeEditor();
 | 
					 | 
				
			||||||
			reject('Error loading source.');
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		request.addEventListener("timeout", function() {
 | 
					 | 
				
			||||||
			alert("Timed out loading source.");
 | 
					 | 
				
			||||||
			closeEditor();
 | 
					 | 
				
			||||||
			reject('Timed out loading source.');
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		request.addEventListener("abort", function() {
 | 
					 | 
				
			||||||
			alert("Loading source aborted.");
 | 
					 | 
				
			||||||
			closeEditor();
 | 
					 | 
				
			||||||
			reject('Loading source aborted.');
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		request.open("GET", "/" + id + "/view");
 | 
					 | 
				
			||||||
		request.send();
 | 
					 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function load(path) {
 | 
					function load(path) {
 | 
				
			||||||
	return new Promise(function(resolve, reject) {
 | 
						return fetch((path || url()) + 'view').then(function(response) {
 | 
				
			||||||
		var request = new XMLHttpRequest();
 | 
							if (!response.ok) {
 | 
				
			||||||
		request.addEventListener("loadend", function() {
 | 
								throw new Error(response.status + ' ' + response.statusText);
 | 
				
			||||||
			if (request.status == 200 || request.status == 404) {
 | 
							}
 | 
				
			||||||
 | 
							return response.json();
 | 
				
			||||||
 | 
						}).then(function(json) {
 | 
				
			||||||
		if (!gEditor) {
 | 
							if (!gEditor) {
 | 
				
			||||||
			gEditor = CodeMirror.fromTextArea(document.getElementById("editor"), {
 | 
								gEditor = CodeMirror.fromTextArea(document.getElementById("editor"), {
 | 
				
			||||||
				'theme': 'base16-dark',
 | 
									'theme': 'base16-dark',
 | 
				
			||||||
@@ -233,13 +208,9 @@ function load(path) {
 | 
				
			|||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		gFiles = {};
 | 
							gFiles = {};
 | 
				
			||||||
				var text;
 | 
					 | 
				
			||||||
		var isApp = false;
 | 
							var isApp = false;
 | 
				
			||||||
		var promises = [];
 | 
							var promises = [];
 | 
				
			||||||
				if (request.status == 200) {
 | 
					
 | 
				
			||||||
					text = request.responseText;
 | 
					 | 
				
			||||||
					try {
 | 
					 | 
				
			||||||
						var json = JSON.parse(text);
 | 
					 | 
				
			||||||
		if (json && json['type'] == 'tildefriends-app') {
 | 
							if (json && json['type'] == 'tildefriends-app') {
 | 
				
			||||||
			isApp = true;
 | 
								isApp = true;
 | 
				
			||||||
			Object.keys(json['files']).forEach(function(name) {
 | 
								Object.keys(json['files']).forEach(function(name) {
 | 
				
			||||||
@@ -249,44 +220,18 @@ function load(path) {
 | 
				
			|||||||
			if (Object.keys(json['files']).length == 0) {
 | 
								if (Object.keys(json['files']).length == 0) {
 | 
				
			||||||
				document.getElementById("editPane").style.display = 'flex';
 | 
									document.getElementById("editPane").style.display = 'flex';
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
							gApp = JSON.parse(text);
 | 
								gApp = json;
 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					} catch {
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					reject('Load failed.');
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (!isApp) {
 | 
							if (!isApp) {
 | 
				
			||||||
			document.getElementById("editPane").style.display = 'flex';
 | 
								document.getElementById("editPane").style.display = 'flex';
 | 
				
			||||||
					if (!text) {
 | 
								var text = '// New script.\n';
 | 
				
			||||||
						text = '// New script.\n';
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
			gCurrentFile = 'app.js';
 | 
								gCurrentFile = 'app.js';
 | 
				
			||||||
			gFiles[gCurrentFile] = {
 | 
								gFiles[gCurrentFile] = {
 | 
				
			||||||
				doc: new CodeMirror.Doc(text, guessMode(gCurrentFile)),
 | 
									doc: new CodeMirror.Doc(text, guessMode(gCurrentFile)),
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			openFile(gCurrentFile);
 | 
								openFile(gCurrentFile);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
				Promise.all(promises).then(resolve).catch(reject);
 | 
							return Promise.all(promises);
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		request.addEventListener("error", function() {
 | 
					 | 
				
			||||||
			alert("Error loading source.");
 | 
					 | 
				
			||||||
			closeEditor();
 | 
					 | 
				
			||||||
			reject('Error loading source.');
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		request.addEventListener("timeout", function() {
 | 
					 | 
				
			||||||
			alert("Timed out loading source.");
 | 
					 | 
				
			||||||
			closeEditor();
 | 
					 | 
				
			||||||
			reject('Timed out loading source.');
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		request.addEventListener("abort", function() {
 | 
					 | 
				
			||||||
			alert("Loading source aborted.");
 | 
					 | 
				
			||||||
			closeEditor();
 | 
					 | 
				
			||||||
			reject('Loading source aborted.');
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		request.open("GET", (path || url()) + "view");
 | 
					 | 
				
			||||||
		request.send();
 | 
					 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -314,18 +259,8 @@ function save(save_to) {
 | 
				
			|||||||
		gFiles[gCurrentFile].doc = gEditor.getDoc();
 | 
							gFiles[gCurrentFile].doc = gEditor.getDoc();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var appFinished = function(success) {
 | 
					 | 
				
			||||||
		document.getElementById("save").disabled = false;
 | 
					 | 
				
			||||||
		document.getElementById("push_to_parent").disabled = false;
 | 
					 | 
				
			||||||
		document.getElementById("pull_from_parent").disabled = false;
 | 
					 | 
				
			||||||
		Object.values(gFiles).forEach(function(file) {
 | 
					 | 
				
			||||||
			file.generation = file.doc.changeGeneration();
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		updateFiles();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var save_path = save_to;
 | 
						var save_path = save_to;
 | 
				
			||||||
	if (!save_to) {
 | 
						if (!save_path) {
 | 
				
			||||||
		var name = document.getElementById("name");
 | 
							var name = document.getElementById("name");
 | 
				
			||||||
		if (name && name.value) {
 | 
							if (name && name.value) {
 | 
				
			||||||
			save_path = name.value;
 | 
								save_path = name.value;
 | 
				
			||||||
@@ -334,11 +269,34 @@ function save(save_to) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var always = function() {
 | 
						var promises = [];
 | 
				
			||||||
		var anyUnfinished = Object.values(gFiles).some(x => x.request);
 | 
						for (let name of Object.keys(gFiles)) {
 | 
				
			||||||
		var anyUnsaved = Object.values(gFiles).some(x => !x.doc.isClean(x.generation) && !x.id);
 | 
							let file = gFiles[name];
 | 
				
			||||||
 | 
							if (file.doc.isClean(file.generation)) {
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!anyUnfinished && !anyUnsaved) {
 | 
							delete file.id;
 | 
				
			||||||
 | 
							promises.push(fetch('/save', {
 | 
				
			||||||
 | 
								method: 'POST',
 | 
				
			||||||
 | 
								headers: {
 | 
				
			||||||
 | 
									'Content-Type': 'text/plain',
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								body: file.doc.getValue(),
 | 
				
			||||||
 | 
							}).then(function(response) {
 | 
				
			||||||
 | 
								if (!response.ok) {
 | 
				
			||||||
 | 
									throw new Error('Saving "' + name + '": ' + response.status + ' ' + response.statusText);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return response.text();
 | 
				
			||||||
 | 
							}).then(function(text) {
 | 
				
			||||||
 | 
								file.id = text;
 | 
				
			||||||
 | 
								if (file.id.charAt(0) == '/') {
 | 
				
			||||||
 | 
									file.id = file.id.substr(1);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return Promise.all(promises).then(function() {
 | 
				
			||||||
		var app = {
 | 
							var app = {
 | 
				
			||||||
			type: "tildefriends-app",
 | 
								type: "tildefriends-app",
 | 
				
			||||||
			files: Object.fromEntries(Object.keys(gFiles).map(x => [x, gFiles[x].id || gApp.files[x]])),
 | 
								files: Object.fromEntries(Object.keys(gFiles).map(x => [x, gFiles[x].id || gApp.files[x]])),
 | 
				
			||||||
@@ -346,90 +304,40 @@ function save(save_to) {
 | 
				
			|||||||
		Object.values(gFiles).forEach(function(file) { delete file.id; });
 | 
							Object.values(gFiles).forEach(function(file) { delete file.id; });
 | 
				
			||||||
		gApp = JSON.parse(JSON.stringify(app));
 | 
							gApp = JSON.parse(JSON.stringify(app));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var request = new XMLHttpRequest();
 | 
							return fetch(save_path + 'save', {
 | 
				
			||||||
			request.addEventListener("error", function() {
 | 
								method: 'POST',
 | 
				
			||||||
				alert("Error saving: " + request.responseText);
 | 
								headers: {
 | 
				
			||||||
				appFinished(false);
 | 
									'Content-Type': 'application/json',
 | 
				
			||||||
			});
 | 
								},
 | 
				
			||||||
			request.addEventListener("loadend", function() {
 | 
								body: JSON.stringify(app),
 | 
				
			||||||
				if (request.status == 200) {
 | 
							}).then(function(response) {
 | 
				
			||||||
 | 
								if (!response.ok) {
 | 
				
			||||||
 | 
									throw new Error(response.status + ' ' + response.statusText);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (save_path != window.location.pathname) {
 | 
								if (save_path != window.location.pathname) {
 | 
				
			||||||
				alert('Saved to ' + save_path + '.');
 | 
									alert('Saved to ' + save_path + '.');
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				reconnect(save_path);
 | 
									reconnect(save_path);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
					appFinished(true);
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					alert("Unable to save: " + request.responseText);
 | 
					 | 
				
			||||||
					appFinished(false);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
			request.addEventListener("timeout", function() {
 | 
						}).catch(function(error) {
 | 
				
			||||||
				alert("Timed out saving: " + request.responseText);
 | 
							alert(error);
 | 
				
			||||||
				appFinished(false);
 | 
						}).finally(function() {
 | 
				
			||||||
			});
 | 
							document.getElementById("save").disabled = false;
 | 
				
			||||||
			request.addEventListener("abort", function() {
 | 
							document.getElementById("push_to_parent").disabled = false;
 | 
				
			||||||
				alert("Save aborted: " + request.responseText);
 | 
							document.getElementById("pull_from_parent").disabled = false;
 | 
				
			||||||
				appFinished(false);
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			request.open("POST", save_path + 'save', true);
 | 
					 | 
				
			||||||
			request.setRequestHeader("Content-Type", "text/json");
 | 
					 | 
				
			||||||
			request.send(JSON.stringify(app));
 | 
					 | 
				
			||||||
		} else if (!anyUnfinished) {
 | 
					 | 
				
			||||||
			appFinished(false);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var anySkipped = false;
 | 
					 | 
				
			||||||
		Object.values(gFiles).forEach(function(file) {
 | 
							Object.values(gFiles).forEach(function(file) {
 | 
				
			||||||
		if (file.doc.isClean(file.generation)) {
 | 
								file.generation = file.doc.changeGeneration();
 | 
				
			||||||
			anySkipped = true;
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		delete file.id;
 | 
					 | 
				
			||||||
		file.request = new XMLHttpRequest();
 | 
					 | 
				
			||||||
		file.request.addEventListener("error", function() {
 | 
					 | 
				
			||||||
			alert("Error saving: " + file.request.responseText);
 | 
					 | 
				
			||||||
			file.request = null;
 | 
					 | 
				
			||||||
			always();
 | 
					 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
		file.request.addEventListener("loadend", function() {
 | 
							updateFiles();
 | 
				
			||||||
			if (file.request.status == 200) {
 | 
					 | 
				
			||||||
				file.id = file.request.responseText;
 | 
					 | 
				
			||||||
				if (file.id.charAt(0) == '/') {
 | 
					 | 
				
			||||||
					file.id = file.id.substr(1);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				alert("Unable to save: " + file.request.responseText);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			file.request = null;
 | 
					 | 
				
			||||||
			always();
 | 
					 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
		file.request.addEventListener("timeout", function() {
 | 
					 | 
				
			||||||
			alert("Timed out saving: " + file.request.responseText);
 | 
					 | 
				
			||||||
			file.request = null;
 | 
					 | 
				
			||||||
			always();
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
		file.request.addEventListener("abort", function() {
 | 
					 | 
				
			||||||
			alert("Save aborted: " + file.request.responseText);
 | 
					 | 
				
			||||||
			file.request = null;
 | 
					 | 
				
			||||||
			always();
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		file.request.open("POST", "/save", true);
 | 
					 | 
				
			||||||
		file.request.setRequestHeader("Content-Type", "text/plain");
 | 
					 | 
				
			||||||
		file.request.send(file.doc.getValue());
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (anySkipped) {
 | 
					 | 
				
			||||||
		always();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function pullFromParent() {
 | 
					function pullFromParent() {
 | 
				
			||||||
	load(gParentApp ? gParentApp.path : null).then(x => save());
 | 
						load(gParentApp ? gParentApp.path : null).then(x => save()).catch(function(error) {
 | 
				
			||||||
 | 
							alert(error)
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function pushToParent() {
 | 
					function pushToParent() {
 | 
				
			||||||
@@ -687,17 +595,21 @@ function message(event) {
 | 
				
			|||||||
	} else if (event.data && event.data.action == "setHash") {
 | 
						} else if (event.data && event.data.action == "setHash") {
 | 
				
			||||||
		window.location.hash = event.data.hash;
 | 
							window.location.hash = event.data.hash;
 | 
				
			||||||
	} else if (event.data && event.data.action == 'storeBlob') {
 | 
						} else if (event.data && event.data.action == 'storeBlob') {
 | 
				
			||||||
		var request = new XMLHttpRequest();
 | 
							fetch('/save', {
 | 
				
			||||||
		request.addEventListener("loadend", function() {
 | 
								method: 'POST',
 | 
				
			||||||
			if (request.status == 200) {
 | 
								headers: {
 | 
				
			||||||
				var iframe = document.getElementById("document");
 | 
									'Content-Type': 'application/binary',
 | 
				
			||||||
				iframe.contentWindow.postMessage({'storeBlobComplete': {name: event.data.blob.name, path: request.responseText, type: event.data.blob.type}}, '*');
 | 
								},
 | 
				
			||||||
 | 
								body: event.data.blob.buffer,
 | 
				
			||||||
 | 
							}).then(function(response) {
 | 
				
			||||||
 | 
								if (!response.ok) {
 | 
				
			||||||
 | 
									throw new Error(response.status + ' ' + response.statusText);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								return response.text();
 | 
				
			||||||
 | 
							}).then(function(text) {
 | 
				
			||||||
 | 
								var iframe = document.getElementById("document");
 | 
				
			||||||
 | 
								iframe.contentWindow.postMessage({'storeBlobComplete': {name: event.data.blob.name, path: text, type: event.data.blob.type}}, '*');
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
		request.open('POST', "/save", true);
 | 
					 | 
				
			||||||
		request.setRequestHeader("Content-Type", "application/binary");
 | 
					 | 
				
			||||||
		console.log('storing', event.data.blob.buffer);
 | 
					 | 
				
			||||||
		request.send(event.data.blob.buffer);
 | 
					 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		send({event: "message", message: event.data});
 | 
							send({event: "message", message: event.data});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user