forked from cory/tildefriends
		
	I just learned that URL unfurling is a thing, and now this chat client supports it (poorly).
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3335 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		| @@ -280,8 +280,12 @@ function printStructured(container, data) { | ||||
| 			node.setAttribute("target", data.target || "_blank"); | ||||
| 		} else if (data.iframe) { | ||||
| 			node = document.createElement("iframe"); | ||||
| 			if (data.src) { | ||||
| 				node.setAttribute("src", data.src); | ||||
| 			} else { | ||||
| 				node.setAttribute("srcdoc", data.iframe); | ||||
| 			node.setAttribute("sandbox", "allow-forms allow-scripts allow-top-navigation"); | ||||
| 			} | ||||
| 			node.setAttribute("sandbox", "allow-forms allow-scripts allow-top-navigation allow-same-origin"); | ||||
| 			node.setAttribute("width", data.width || 320); | ||||
| 			node.setAttribute("height", data.height || 240); | ||||
| 			if (data.name) { | ||||
| @@ -519,7 +523,13 @@ function blur() { | ||||
| } | ||||
|  | ||||
| function onMessage(event) { | ||||
| 	if (event.data && event.data.event == "resizeMe" && event.data.width && event.data.height) { | ||||
| 		var iframe = document.getElementById("iframe_" + event.data.name); | ||||
| 		iframe.setAttribute("width", event.data.width); | ||||
| 		iframe.setAttribute("height", event.data.height); | ||||
| 	} else { | ||||
| 		send({event: "onWindowMessage", message: event.data}); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| function submitButton() { | ||||
|   | ||||
| @@ -250,8 +250,9 @@ function updateConversation() { | ||||
| 				terminal.clear(); | ||||
| 				printToConversation(gCurrentConversation, ["[", gCurrentConversation.name, "]"]); | ||||
| 				if (history) { | ||||
| 					let previous = Promise.resolve(); | ||||
| 					for (let message of history) { | ||||
| 						printToConversation(gCurrentConversation, message); | ||||
| 						previous = previous.then(x => printToConversation(gCurrentConversation, message)); | ||||
| 					} | ||||
| 				} | ||||
| 				updateUsers(); | ||||
| @@ -326,10 +327,10 @@ function getConversation(session, conversationName) { | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| function printToConversation(conversation, message, notify) { | ||||
| async function printToConversation(conversation, message, notify) { | ||||
| 	if (conversation == gCurrentConversation) { | ||||
| 		if (message.action == "message") { | ||||
| 			printMessage(message.message); | ||||
| 			await printMessage(message.message); | ||||
| 		} else if (message.action == "presence") { | ||||
| 			if (message.presence == "unavailable") { | ||||
| 				terminal.print(new Date().toString(), ": ", message.user, " has left the room."); | ||||
| @@ -405,7 +406,7 @@ function niceTime(lastTime, thisTime) { | ||||
| 	return result.join(" "); | ||||
| } | ||||
|  | ||||
| function formatMessage(message) { | ||||
| async function formatMessage(message) { | ||||
| 	var result; | ||||
| 	if (typeof message == "string") { | ||||
| 		for (let i = 0; i < message.length; i++) { | ||||
| @@ -417,9 +418,17 @@ function formatMessage(message) { | ||||
| 		var regex = /(\w+:\/*\S+?)(?=(?:[\.!?])?(?:$|\s))/gi; | ||||
| 		var match; | ||||
| 		var lastIndex = 0; | ||||
| 		let libunfurl; | ||||
| 		while ((match = regex.exec(message)) !== null) { | ||||
| 			if (!libunfurl) { | ||||
| 				libunfurl = await core.getService("libunfurl", "libunfurl"); | ||||
| 			} | ||||
| 			result.push({class: "base1", value: message.substring(lastIndex, match.index)}); | ||||
| 			if (!libunfurl) { | ||||
| 				result.push({href: match[0]}); | ||||
| 			} else { | ||||
| 				result.push(await libunfurl.postMessage(match[0])); | ||||
| 			} | ||||
| 			lastIndex = regex.lastIndex; | ||||
| 		} | ||||
| 		result.push({class: "base1", value: message.substring(lastIndex)}); | ||||
| @@ -430,7 +439,7 @@ function formatMessage(message) { | ||||
| } | ||||
|  | ||||
| var lastTimestamp = null; | ||||
| function printMessage(message) { | ||||
| async function printMessage(message) { | ||||
| 	var now = message.timestamp || new Date().toString(); | ||||
| 	var from = message.from || "unknown"; | ||||
|  | ||||
| @@ -441,7 +450,7 @@ function printMessage(message) { | ||||
| 		{class: "base3", value: from}, | ||||
| 		{class: "base00", value: ">"}, | ||||
| 		" ", | ||||
| 		formatMessage(message.message)); | ||||
| 		await formatMessage(message.message)); | ||||
| 	lastTimestamp = now; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										67
									
								
								packages/cory/libunfurl/libunfurl.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								packages/cory/libunfurl/libunfurl.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| "use strict"; | ||||
|  | ||||
| //! {"category": "libraries", "require": ["libhttp", "libxml"], "permissions": ["network"]} | ||||
|  | ||||
| let libxml = require("libxml"); | ||||
| let libhttp = require("libhttp"); | ||||
|  | ||||
| let gEmbedIndex = 0; | ||||
|  | ||||
| async function unfurl(url) { | ||||
| 	let result = {href: url}; | ||||
| 	let response = await libhttp.get(url); | ||||
| 	let parsed = libxml.StreamParser().parse(response.body); | ||||
| 	let oEmbedUrl; | ||||
| 	for (let node of parsed) { | ||||
| 		if (node.type == "element" && node.value == "link" && node.attributes.type == "application/json+oembed") { | ||||
| 			oEmbedUrl = node.attributes.href; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (oEmbedUrl) { | ||||
| 		response = await libhttp.get(oEmbedUrl); | ||||
| 		let oEmbed = JSON.parse(response.body); | ||||
| 		gEmbedIndex++; | ||||
| 		result = [{href: url}, "\n", { | ||||
| 			name: "oEmbed" + gEmbedIndex, | ||||
| 			iframe: ` | ||||
| 	<span style="border: 0; padding: 0; margin: 0; overflow: hidden"> | ||||
| 		${oEmbed.html} | ||||
| 	</span> | ||||
| 	<script language="javascript"> | ||||
| 		let gResizeMeMessage = { | ||||
| 			event: "resizeMe", | ||||
| 			name: "oEmbed${gEmbedIndex}", | ||||
| 			width: -1, | ||||
| 			height: -1, | ||||
| 		}; | ||||
| 		setInterval(function() { | ||||
| 			if (document.body.scrollHeight != gResizeMeMessage.height | ||||
| 				|| document.body.scrollWidth != gResizeMeMessage.width) { | ||||
| 				gResizeMeMessage.width = document.body.scrollWidth; | ||||
| 				gResizeMeMessage.height = document.body.scrollHeight; | ||||
| 				parent.postMessage(gResizeMeMessage, "*"); | ||||
| 			} | ||||
| 		}, 100); | ||||
| 	</script> | ||||
| `, | ||||
| 			width: oEmbed.width || 320, | ||||
| 			height: oEmbed.height || 120, | ||||
| 			style: "margin: 0; padding: 0; border: 0; overflow: hidden", | ||||
| 		}]; | ||||
| 	} | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| async function test() { | ||||
| 	terminal.print(await unfurl("https://twitter.com/511nyAlbany/status/777221230915096576")); | ||||
| 	terminal.print(await unfurl("https://www.youtube.com/watch?v=pTA0DSfrGZ0")); | ||||
| } | ||||
|  | ||||
| //test().catch(terminal.print); | ||||
|  | ||||
| core.register("onMessage", function(sender, message) { | ||||
| 	return unfurl(message).catch(error => [message, "(error retrieving: ", error, ")"]); | ||||
| }); | ||||
| @@ -252,3 +252,10 @@ exports.StanzaParser = function(depth) { | ||||
| 		reset: parser.reset.bind(parser), | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| exports.StreamParser = function() { | ||||
| 	let parser = new XmlStreamParser(); | ||||
| 	return { | ||||
| 		parse: parser.parse.bind(parser), | ||||
| 	}; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user