var -> let, and standardize these calls.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3907 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										207
									
								
								core/client.js
									
									
									
									
									
								
							
							
						
						
									
										207
									
								
								core/client.js
									
									
									
									
									
								
							| @@ -1,19 +1,30 @@ | ||||
| "use strict"; | ||||
|  | ||||
| var gSocket; | ||||
| var gCredentials; | ||||
| let gSocket; | ||||
| let gCredentials; | ||||
|  | ||||
| var gCurrentFile; | ||||
| var gFiles = {}; | ||||
| var gApp = {files: {}}; | ||||
| var gEditor; | ||||
| var gSplit; | ||||
| var gGraphs = {}; | ||||
| var gTimeSeries = {}; | ||||
| var gParentApp; | ||||
| let gCurrentFile; | ||||
| let gFiles = {}; | ||||
| let gApp = {files: {}}; | ||||
| let gEditor; | ||||
| let gSplit; | ||||
| let gGraphs = {}; | ||||
| let gTimeSeries = {}; | ||||
| let gParentApp; | ||||
| let gOriginalInput; | ||||
|  | ||||
| var kErrorColor = "#dc322f"; | ||||
| var kStatusColor = "#fff"; | ||||
| let kErrorColor = "#dc322f"; | ||||
| let kStatusColor = "#fff"; | ||||
|  | ||||
| /* Functions that server-side app code can call through app.setDocument()-style | ||||
|  * calls. */ | ||||
| const k_api = { | ||||
| 	setDocument: {args: ['content'], func: api_setDocument}, | ||||
| 	postMessage: {args: ['message'], func: api_postMessage}, | ||||
| 	error: {args: ['error'], func: api_error}, | ||||
| 	localStorageSet: {args: ['key', 'value'], func: api_localStorageSet}, | ||||
| 	localStorageGet: {args: ['key'], func: api_localStorageGet}, | ||||
| }; | ||||
|  | ||||
| window.addEventListener("keydown", function(event) { | ||||
| 	if (event.keyCode == 83 && (event.altKey || event.ctrlKey)) { | ||||
| @@ -35,13 +46,13 @@ function ensureLoaded(nodes, callback) { | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	var search = nodes.shift(); | ||||
| 	var head = document.head; | ||||
| 	var found = false; | ||||
| 	for (var i = 0; i < head.childNodes.length; i++) { | ||||
| 	let search = nodes.shift(); | ||||
| 	let head = document.head; | ||||
| 	let found = false; | ||||
| 	for (let i = 0; i < head.childNodes.length; i++) { | ||||
| 		if (head.childNodes[i].tagName == search.tagName) { | ||||
| 			var match = true; | ||||
| 			for (var attribute in search.attributes) { | ||||
| 			let match = true; | ||||
| 			for (let attribute in search.attributes) { | ||||
| 				if (head.childNodes[i].attributes[attribute].value != search.attributes[attribute]) { | ||||
| 					match = false; | ||||
| 				} | ||||
| @@ -55,11 +66,11 @@ function ensureLoaded(nodes, callback) { | ||||
| 	if (found) { | ||||
| 		ensureLoaded(nodes, callback); | ||||
| 	} else { | ||||
| 		var node = document.createElement(search.tagName); | ||||
| 		let node = document.createElement(search.tagName); | ||||
| 		node.onreadystatechange = node.onload = function() { | ||||
| 			ensureLoaded(nodes, callback); | ||||
| 		}; | ||||
| 		for (var attribute in search.attributes) { | ||||
| 		for (let attribute in search.attributes) { | ||||
| 			node.setAttribute(attribute, search.attributes[attribute]); | ||||
| 		} | ||||
| 		head.insertBefore(node, head.firstChild); | ||||
| @@ -133,8 +144,8 @@ function trace() { | ||||
| 			} | ||||
| 			return response.arrayBuffer(); | ||||
| 		}).then(function(data) { | ||||
| 			var perfetto = window.open('/perfetto/'); | ||||
| 			var done = false; | ||||
| 			let perfetto = window.open('/perfetto/'); | ||||
| 			let done = false; | ||||
| 			if (perfetto) { | ||||
| 				function message_handler(message) { | ||||
| 					if (message.data == 'PONG') { | ||||
| @@ -232,8 +243,8 @@ function load(path) { | ||||
| 			}); | ||||
| 		} | ||||
| 		gFiles = {}; | ||||
| 		var isApp = false; | ||||
| 		var promises = []; | ||||
| 		let isApp = false; | ||||
| 		let promises = []; | ||||
|  | ||||
| 		if (json && json['type'] == 'tildefriends-app') { | ||||
| 			isApp = true; | ||||
| @@ -248,7 +259,7 @@ function load(path) { | ||||
| 		} | ||||
| 		if (!isApp) { | ||||
| 			document.getElementById("editPane").style.display = 'flex'; | ||||
| 			var text = '// New script.\n'; | ||||
| 			let text = '// New script.\n'; | ||||
| 			gCurrentFile = 'app.js'; | ||||
| 			gFiles[gCurrentFile] = { | ||||
| 				doc: new CodeMirror.Doc(text, guessMode(gCurrentFile)), | ||||
| @@ -280,9 +291,9 @@ function save(save_to) { | ||||
| 		gFiles[gCurrentFile].doc = gEditor.getDoc(); | ||||
| 	} | ||||
|  | ||||
| 	var save_path = save_to; | ||||
| 	let save_path = save_to; | ||||
| 	if (!save_path) { | ||||
| 		var name = document.getElementById("name"); | ||||
| 		let name = document.getElementById("name"); | ||||
| 		if (name && name.value) { | ||||
| 			save_path = name.value; | ||||
| 		} else { | ||||
| @@ -290,7 +301,7 @@ function save(save_to) { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	var promises = []; | ||||
| 	let promises = []; | ||||
| 	for (let name of Object.keys(gFiles)) { | ||||
| 		let file = gFiles[name]; | ||||
| 		if (file.doc.isClean(file.generation)) { | ||||
| @@ -318,7 +329,7 @@ function save(save_to) { | ||||
| 	} | ||||
|  | ||||
| 	return Promise.all(promises).then(function() { | ||||
| 		var app = { | ||||
| 		let app = { | ||||
| 			type: "tildefriends-app", | ||||
| 			files: Object.fromEntries(Object.keys(gFiles).map(x => [x, gFiles[x].id || gApp.files[x]])), | ||||
| 		}; | ||||
| @@ -366,9 +377,9 @@ function pushToParent() { | ||||
| } | ||||
|  | ||||
| function url() { | ||||
| 	var hash = window.location.href.indexOf('#'); | ||||
| 	var question = window.location.href.indexOf('?'); | ||||
| 	var end = -1; | ||||
| 	let hash = window.location.href.indexOf('#'); | ||||
| 	let question = window.location.href.indexOf('?'); | ||||
| 	let end = -1; | ||||
| 	if (hash != -1 && (hash < end || end == -1)) | ||||
| 	{ | ||||
| 		end = hash; | ||||
| @@ -384,13 +395,42 @@ function hash() { | ||||
| 	return window.location.hash != "#" ? window.location.hash : ""; | ||||
| } | ||||
|  | ||||
| function api_setDocument(content) { | ||||
| 	let iframe = document.getElementById("document"); | ||||
| 	iframe.srcdoc = content; | ||||
| } | ||||
|  | ||||
| function api_postMessage(message) { | ||||
| 	let iframe = document.getElementById("document"); | ||||
| 	iframe.contentWindow.postMessage(message, "*"); | ||||
| } | ||||
|  | ||||
| function api_error(error) { | ||||
| 	if (error) { | ||||
| 		if (typeof(error) == 'string') { | ||||
| 			setStatusMessage('⚠️ ' + error, '#f00'); | ||||
| 		} else { | ||||
| 			setStatusMessage('⚠️ ' + merror.message + '\n' + error.stack, '#f00'); | ||||
| 		} | ||||
| 	} | ||||
| 	console.log('error', error); | ||||
| } | ||||
|  | ||||
| function api_localStorageSet(key, value) { | ||||
| 	window.localStorage.setItem('app:' + key, value); | ||||
| } | ||||
|  | ||||
| function api_localStorageGet(key, value) { | ||||
| 	send({message: 'localStorage', key: key, value: window.localStorage.getItem('app:' + key)}); | ||||
| } | ||||
|  | ||||
| function receive(message) { | ||||
| 	if (message && message.action == "session") { | ||||
| 		setStatusMessage("🟢 Executing...", kStatusColor); | ||||
| 		gCredentials = message.credentials; | ||||
| 		gParentApp = message.parentApp; | ||||
| 		updateLogin(); | ||||
| 		var parent_enabled = message.parentApp; | ||||
| 		let parent_enabled = message.parentApp; | ||||
| 		document.getElementById('push_to_parent').style.display = parent_enabled ? 'inline-block' : 'none'; | ||||
| 		document.getElementById('pull_from_parent').style.display = parent_enabled ? 'inline-block' : 'none'; | ||||
| 	} else if (message && message.action == "ready") { | ||||
| @@ -402,32 +442,13 @@ function receive(message) { | ||||
| 			/* Stats were opened before we connected. */ | ||||
| 			send({action: 'enableStats', enabled: true}); | ||||
| 		} | ||||
| 	} else if (message && message.action == "setDocument") { | ||||
| 		var iframe = document.getElementById("document"); | ||||
| 		iframe.srcdoc = message.content; | ||||
| 	} else if (message && message.action == "postMessage") { | ||||
| 		var iframe = document.getElementById("document"); | ||||
| 		iframe.contentWindow.postMessage(message.message, "*"); | ||||
| 	} else if (message && message.action == "ping") { | ||||
| 		send({action: "pong"}); | ||||
| 	} else if (message && message.action == "error") { | ||||
| 		if (message.error) { | ||||
| 			if (typeof(message.error) == 'string') { | ||||
| 				setStatusMessage('⚠️ ' + message.error, '#f00'); | ||||
| 			} else { | ||||
| 				setStatusMessage('⚠️ ' + mmessage.error.message + '\n' + message.error.stack, '#f00'); | ||||
| 			} | ||||
| 		} | ||||
| 		console.log('error', message); | ||||
| 	} else if (message && message.action == "localStorageSet") { | ||||
| 		window.localStorage.setItem('app:' + message.key, message.value); | ||||
| 	} else if (message && message.action == "localStorageGet") { | ||||
| 		send({message: 'localStorage', key: message.key, value: window.localStorage.getItem('app:' + message.key)}); | ||||
| 	} else if (message && message.action == "print") { | ||||
| 		console.log('app>', ...message.args); | ||||
| 	} else if (message && message.action == "stats") { | ||||
| 		var now = new Date().getTime(); | ||||
| 		for (var key of Object.keys(message.stats)) { | ||||
| 		let now = new Date().getTime(); | ||||
| 		for (let key of Object.keys(message.stats)) { | ||||
| 			const k_groups = { | ||||
| 				rpc_in: {group: 'rpc', name: 'in'}, | ||||
| 				rpc_out: {group: 'rpc', name: 'out'}, | ||||
| @@ -499,6 +520,11 @@ function receive(message) { | ||||
| 			} | ||||
| 			timeseries.append(now, message.stats[key]); | ||||
| 		} | ||||
| 	} else if (message && message.action) { | ||||
| 		let api = k_api[message.action]; | ||||
| 		if (api) { | ||||
| 			api.func(...api.args.map(x => message[x])); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -515,7 +541,7 @@ function keyEvent(event) { | ||||
| } | ||||
|  | ||||
| function setStatusMessage(message, color) { | ||||
| 	var node = document.getElementById("status"); | ||||
| 	let node = document.getElementById("status"); | ||||
| 	while (node.firstChild) { | ||||
| 		node.removeChild(node.firstChild); | ||||
| 	} | ||||
| @@ -536,12 +562,12 @@ function send(value) { | ||||
| } | ||||
|  | ||||
| function updateLogin() { | ||||
| 	var login = document.getElementById("login"); | ||||
| 	let login = document.getElementById("login"); | ||||
| 	while (login.firstChild) { | ||||
| 		login.removeChild(login.firstChild); | ||||
| 	} | ||||
|  | ||||
| 	var a = document.createElement("a"); | ||||
| 	let a = document.createElement("a"); | ||||
| 	if (gCredentials && gCredentials.session) { | ||||
| 		a.appendChild(document.createTextNode("logout " + gCredentials.session.name)); | ||||
| 		a.setAttribute("href", "/login/logout?return=" + encodeURIComponent(url() + hash())); | ||||
| @@ -552,11 +578,10 @@ function updateLogin() { | ||||
| 	login.appendChild(a); | ||||
| } | ||||
|  | ||||
| var gOriginalInput; | ||||
| function dragHover(event) { | ||||
| 	event.stopPropagation(); | ||||
| 	event.preventDefault(); | ||||
| 	var input = document.getElementById("input"); | ||||
| 	let input = document.getElementById("input"); | ||||
| 	if (event.type == "dragover") { | ||||
| 		if (!input.classList.contains("drop")) { | ||||
| 			input.classList.add("drop"); | ||||
| @@ -570,17 +595,17 @@ function dragHover(event) { | ||||
| } | ||||
|  | ||||
| function fixImage(sourceData, maxWidth, maxHeight, callback) { | ||||
| 	var result = sourceData; | ||||
| 	var image = new Image(); | ||||
| 	let result = sourceData; | ||||
| 	let image = new Image(); | ||||
| 	image.crossOrigin = "anonymous"; | ||||
| 	image.referrerPolicy = "no-referrer"; | ||||
| 	image.onload = function() { | ||||
| 		if (image.width > maxWidth || image.height > maxHeight) { | ||||
| 			var downScale = Math.min(maxWidth / image.width, maxHeight / image.height); | ||||
| 			var canvas = document.createElement("canvas"); | ||||
| 			let downScale = Math.min(maxWidth / image.width, maxHeight / image.height); | ||||
| 			let canvas = document.createElement("canvas"); | ||||
| 			canvas.width = image.width * downScale; | ||||
| 			canvas.height = image.height * downScale; | ||||
| 			var context = canvas.getContext("2d"); | ||||
| 			let context = canvas.getContext("2d"); | ||||
| 			context.clearRect(0, 0, canvas.width, canvas.height); | ||||
| 			image.width = canvas.width; | ||||
| 			image.height = canvas.height; | ||||
| @@ -605,13 +630,13 @@ function fileDropRead(event) { | ||||
| function fileDrop(event) { | ||||
| 	dragHover(event); | ||||
|  | ||||
| 	var done = false; | ||||
| 	let done = false; | ||||
| 	if (!done) { | ||||
| 		var files = event.target.files || event.dataTransfer.files; | ||||
| 		for (var i = 0; i < files.length; i++) { | ||||
| 			var file = files[i]; | ||||
| 		let files = event.target.files || event.dataTransfer.files; | ||||
| 		for (let i = 0; i < files.length; i++) { | ||||
| 			let file = files[i]; | ||||
| 			if (file.type.substring(0, "image/".length) == "image/") { | ||||
| 				var reader = new FileReader(); | ||||
| 				let reader = new FileReader(); | ||||
| 				reader.onloadend = fileDropRead; | ||||
| 				reader.readAsDataURL(file); | ||||
| 				done = true; | ||||
| @@ -620,8 +645,8 @@ function fileDrop(event) { | ||||
| 	} | ||||
|  | ||||
| 	if (!done) { | ||||
| 		var html = event.dataTransfer.getData("text/html"); | ||||
| 		var match = /<img.*src="([^"]+)"/.exec(html); | ||||
| 		let html = event.dataTransfer.getData("text/html"); | ||||
| 		let match = /<img.*src="([^"]+)"/.exec(html); | ||||
| 		if (match) { | ||||
| 			sendImage(match[1]); | ||||
| 			done = true; | ||||
| @@ -629,7 +654,7 @@ function fileDrop(event) { | ||||
| 	} | ||||
|  | ||||
| 	if (!done) { | ||||
| 		var text = event.dataTransfer.getData("text/plain"); | ||||
| 		let text = event.dataTransfer.getData("text/plain"); | ||||
| 		if (text) { | ||||
| 			send(text); | ||||
| 			done = true; | ||||
| @@ -638,7 +663,7 @@ function fileDrop(event) { | ||||
| } | ||||
|  | ||||
| function enableDragDrop() { | ||||
| 	var body = document.body; | ||||
| 	let body = document.body; | ||||
| 	body.addEventListener("dragover", dragHover); | ||||
| 	body.addEventListener("dragleave", dragHover); | ||||
| 	body.addEventListener("drop", fileDrop); | ||||
| @@ -664,7 +689,7 @@ function blur() { | ||||
|  | ||||
| function message(event) { | ||||
| 	if (event.data && event.data.event == "resizeMe" && event.data.width && event.data.height) { | ||||
| 		var iframe = document.getElementById("iframe_" + event.data.name); | ||||
| 		let iframe = document.getElementById("iframe_" + event.data.name); | ||||
| 		iframe.setAttribute("width", event.data.width); | ||||
| 		iframe.setAttribute("height", event.data.height); | ||||
| 	} else if (event.data && event.data.action == "setHash") { | ||||
| @@ -682,7 +707,7 @@ function message(event) { | ||||
| 			} | ||||
| 			return response.text(); | ||||
| 		}).then(function(text) { | ||||
| 			var iframe = document.getElementById("document"); | ||||
| 			let iframe = document.getElementById("document"); | ||||
| 			iframe.contentWindow.postMessage({'storeBlobComplete': {name: event.data.blob.name, path: text, type: event.data.blob.type, context: event.data.context}}, '*'); | ||||
| 		}); | ||||
| 	} else { | ||||
| @@ -719,13 +744,7 @@ function connectSocket(path) { | ||||
| 			gSocket.send(JSON.stringify({ | ||||
| 				action: "hello", | ||||
| 				path: path, | ||||
| 				api: [ | ||||
| 					['setDocument', 'content'], | ||||
| 					['postMessage', 'message'], | ||||
| 					['error', 'error'], | ||||
| 					['localStorageSet', 'key', 'value'], | ||||
| 					['localStorageGet', 'key'], | ||||
| 				], | ||||
| 				api: Object.entries(k_api).map(([key, value]) => [].concat([key], value.args)), | ||||
| 			})); | ||||
| 		} | ||||
| 		gSocket.onmessage = function(event) { | ||||
| @@ -755,8 +774,8 @@ function connectSocket(path) { | ||||
| } | ||||
|  | ||||
| function openFile(name) { | ||||
| 	var newDoc = (name && gFiles[name]) ? gFiles[name].doc : new CodeMirror.Doc("", guessMode(name)); | ||||
| 	var oldDoc = gEditor.swapDoc(newDoc); | ||||
| 	let newDoc = (name && gFiles[name]) ? gFiles[name].doc : new CodeMirror.Doc("", guessMode(name)); | ||||
| 	let oldDoc = gEditor.swapDoc(newDoc); | ||||
| 	if (gFiles[gCurrentFile]) { | ||||
| 		gFiles[gCurrentFile].doc = oldDoc; | ||||
| 	} | ||||
| @@ -770,13 +789,13 @@ function onFileClicked(event) { | ||||
| } | ||||
|  | ||||
| function updateFiles() { | ||||
| 	var node = document.getElementById("files"); | ||||
| 	let node = document.getElementById("files"); | ||||
| 	while (node.firstChild) { | ||||
| 		node.removeChild(node.firstChild); | ||||
| 	} | ||||
|  | ||||
| 	for (var file of Object.keys(gFiles).sort()) { | ||||
| 		var li = document.createElement("li"); | ||||
| 	for (let file of Object.keys(gFiles).sort()) { | ||||
| 		let li = document.createElement("li"); | ||||
| 		li.onclick = onFileClicked; | ||||
| 		li.appendChild(document.createTextNode(file)); | ||||
| 		if (file == gCurrentFile) { | ||||
| @@ -800,7 +819,7 @@ function makeNewFile(name) { | ||||
| } | ||||
|  | ||||
| function newFile() { | ||||
| 	var name = prompt("Name of new file:", "file.js"); | ||||
| 	let name = prompt("Name of new file:", "file.js"); | ||||
| 	if (name && !gFiles[name]) { | ||||
| 		makeNewFile(name); | ||||
| 	} | ||||
| @@ -823,18 +842,18 @@ window.addEventListener("load", function() { | ||||
| 	for (let tag of document.getElementsByTagName('a')) { | ||||
| 		if (tag.accessKey) { | ||||
| 			tag.classList.add('tooltip_parent'); | ||||
| 			var tooltip = document.createElement('div'); | ||||
| 			let tooltip = document.createElement('div'); | ||||
| 			tooltip.classList.add('tooltip'); | ||||
| 			if (tag.dataset.tip) { | ||||
| 				var description = document.createElement('div'); | ||||
| 				let description = document.createElement('div'); | ||||
| 				description.innerText = tag.dataset.tip; | ||||
| 				tooltip.appendChild(description); | ||||
| 			} | ||||
| 			var parts = tag.accessKeyLabel ? tag.accessKeyLabel.split('+') : []; | ||||
| 			for (var i = 0; i < parts.length; i++) | ||||
| 			let parts = tag.accessKeyLabel ? tag.accessKeyLabel.split('+') : []; | ||||
| 			for (let i = 0; i < parts.length; i++) | ||||
| 			{ | ||||
| 				var key = parts[i]; | ||||
| 				var kbd = document.createElement('kbd'); | ||||
| 				let key = parts[i]; | ||||
| 				let kbd = document.createElement('kbd'); | ||||
| 				kbd.innerText = key; | ||||
| 				tooltip.appendChild(kbd); | ||||
| 				if (i < parts.length - 1) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user