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"); | 			node.setAttribute("target", data.target || "_blank"); | ||||||
| 		} else if (data.iframe) { | 		} else if (data.iframe) { | ||||||
| 			node = document.createElement("iframe"); | 			node = document.createElement("iframe"); | ||||||
|  | 			if (data.src) { | ||||||
|  | 				node.setAttribute("src", data.src); | ||||||
|  | 			} else { | ||||||
| 				node.setAttribute("srcdoc", data.iframe); | 				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("width", data.width || 320); | ||||||
| 			node.setAttribute("height", data.height || 240); | 			node.setAttribute("height", data.height || 240); | ||||||
| 			if (data.name) { | 			if (data.name) { | ||||||
| @@ -519,8 +523,14 @@ function blur() { | |||||||
| } | } | ||||||
|  |  | ||||||
| function onMessage(event) { | 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}); | 		send({event: "onWindowMessage", message: event.data}); | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| function submitButton() { | function submitButton() { | ||||||
| 	var inputs = document.getElementsByTagName("input"); | 	var inputs = document.getElementsByTagName("input"); | ||||||
|   | |||||||
| @@ -250,8 +250,9 @@ function updateConversation() { | |||||||
| 				terminal.clear(); | 				terminal.clear(); | ||||||
| 				printToConversation(gCurrentConversation, ["[", gCurrentConversation.name, "]"]); | 				printToConversation(gCurrentConversation, ["[", gCurrentConversation.name, "]"]); | ||||||
| 				if (history) { | 				if (history) { | ||||||
|  | 					let previous = Promise.resolve(); | ||||||
| 					for (let message of history) { | 					for (let message of history) { | ||||||
| 						printToConversation(gCurrentConversation, message); | 						previous = previous.then(x => printToConversation(gCurrentConversation, message)); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				updateUsers(); | 				updateUsers(); | ||||||
| @@ -326,10 +327,10 @@ function getConversation(session, conversationName) { | |||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  |  | ||||||
| function printToConversation(conversation, message, notify) { | async function printToConversation(conversation, message, notify) { | ||||||
| 	if (conversation == gCurrentConversation) { | 	if (conversation == gCurrentConversation) { | ||||||
| 		if (message.action == "message") { | 		if (message.action == "message") { | ||||||
| 			printMessage(message.message); | 			await printMessage(message.message); | ||||||
| 		} else if (message.action == "presence") { | 		} else if (message.action == "presence") { | ||||||
| 			if (message.presence == "unavailable") { | 			if (message.presence == "unavailable") { | ||||||
| 				terminal.print(new Date().toString(), ": ", message.user, " has left the room."); | 				terminal.print(new Date().toString(), ": ", message.user, " has left the room."); | ||||||
| @@ -405,7 +406,7 @@ function niceTime(lastTime, thisTime) { | |||||||
| 	return result.join(" "); | 	return result.join(" "); | ||||||
| } | } | ||||||
|  |  | ||||||
| function formatMessage(message) { | async function formatMessage(message) { | ||||||
| 	var result; | 	var result; | ||||||
| 	if (typeof message == "string") { | 	if (typeof message == "string") { | ||||||
| 		for (let i = 0; i < message.length; i++) { | 		for (let i = 0; i < message.length; i++) { | ||||||
| @@ -417,9 +418,17 @@ function formatMessage(message) { | |||||||
| 		var regex = /(\w+:\/*\S+?)(?=(?:[\.!?])?(?:$|\s))/gi; | 		var regex = /(\w+:\/*\S+?)(?=(?:[\.!?])?(?:$|\s))/gi; | ||||||
| 		var match; | 		var match; | ||||||
| 		var lastIndex = 0; | 		var lastIndex = 0; | ||||||
|  | 		let libunfurl; | ||||||
| 		while ((match = regex.exec(message)) !== null) { | 		while ((match = regex.exec(message)) !== null) { | ||||||
|  | 			if (!libunfurl) { | ||||||
|  | 				libunfurl = await core.getService("libunfurl", "libunfurl"); | ||||||
|  | 			} | ||||||
| 			result.push({class: "base1", value: message.substring(lastIndex, match.index)}); | 			result.push({class: "base1", value: message.substring(lastIndex, match.index)}); | ||||||
|  | 			if (!libunfurl) { | ||||||
| 				result.push({href: match[0]}); | 				result.push({href: match[0]}); | ||||||
|  | 			} else { | ||||||
|  | 				result.push(await libunfurl.postMessage(match[0])); | ||||||
|  | 			} | ||||||
| 			lastIndex = regex.lastIndex; | 			lastIndex = regex.lastIndex; | ||||||
| 		} | 		} | ||||||
| 		result.push({class: "base1", value: message.substring(lastIndex)}); | 		result.push({class: "base1", value: message.substring(lastIndex)}); | ||||||
| @@ -430,7 +439,7 @@ function formatMessage(message) { | |||||||
| } | } | ||||||
|  |  | ||||||
| var lastTimestamp = null; | var lastTimestamp = null; | ||||||
| function printMessage(message) { | async function printMessage(message) { | ||||||
| 	var now = message.timestamp || new Date().toString(); | 	var now = message.timestamp || new Date().toString(); | ||||||
| 	var from = message.from || "unknown"; | 	var from = message.from || "unknown"; | ||||||
|  |  | ||||||
| @@ -441,7 +450,7 @@ function printMessage(message) { | |||||||
| 		{class: "base3", value: from}, | 		{class: "base3", value: from}, | ||||||
| 		{class: "base00", value: ">"}, | 		{class: "base00", value: ">"}, | ||||||
| 		" ", | 		" ", | ||||||
| 		formatMessage(message.message)); | 		await formatMessage(message.message)); | ||||||
| 	lastTimestamp = now; | 	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), | 		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