| 
									
										
										
										
											2012-05-03 20:47:16 +00:00
										 |  |  | /*\ | 
					
						
							|  |  |  | title: $:/core/modules/deserializers.js | 
					
						
							|  |  |  | type: application/javascript | 
					
						
							|  |  |  | module-type: tiddlerdeserializer | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-03 14:09:48 +00:00
										 |  |  | Functions to deserialise tiddlers from a block of text | 
					
						
							| 
									
										
										
										
											2012-05-03 20:47:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | \*/ | 
					
						
							|  |  |  | (function(){ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-04 17:49:04 +00:00
										 |  |  | /*jslint node: true, browser: true */ | 
					
						
							|  |  |  | /*global $tw: false */ | 
					
						
							| 
									
										
										
										
											2012-05-03 20:47:16 +00:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | Utility function to parse an old-style tiddler DIV in a *.tid file. It looks like this: | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | <div title="Title" creator="JoeBloggs" modifier="JoeBloggs" created="201102111106" modified="201102111310" tags="myTag [[my long tag]]"> | 
					
						
							|  |  |  | <pre>The text of the tiddler (without the expected HTML encoding). | 
					
						
							|  |  |  | </pre> | 
					
						
							|  |  |  | </div> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | Note that the field attributes are HTML encoded, but that the body of the <PRE> tag is not encoded. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | When these tiddler DIVs are encountered within a TiddlyWiki HTML file then the body is encoded in the usual way. | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | var parseTiddlerDiv = function(text /* [,fields] */) { | 
					
						
							|  |  |  | 	// Slot together the default results
 | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | 	var result = {}; | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | 	if(arguments.length > 1) { | 
					
						
							|  |  |  | 		for(var f=1; f<arguments.length; f++) { | 
					
						
							|  |  |  | 			var fields = arguments[f]; | 
					
						
							|  |  |  | 			for(var t in fields) { | 
					
						
							|  |  |  | 				result[t] = fields[t];		 | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | 	// Parse the DIV body
 | 
					
						
							| 
									
										
										
										
											2013-12-23 08:54:33 +00:00
										 |  |  | 	var startRegExp = /^\s*<div\s+([^>]*)>(\s*<pre>)?/gi, | 
					
						
							|  |  |  | 		endRegExp, | 
					
						
							|  |  |  | 		match = startRegExp.exec(text); | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | 	if(match) { | 
					
						
							| 
									
										
										
										
											2013-12-23 08:54:33 +00:00
										 |  |  | 		// Old-style DIVs don't have the <pre> tag
 | 
					
						
							|  |  |  | 		if(match[2]) { | 
					
						
							|  |  |  | 			endRegExp = /<\/pre>\s*<\/div>\s*$/gi; | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2013-12-23 08:54:33 +00:00
										 |  |  | 			endRegExp = /<\/div>\s*$/gi; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		var endMatch = endRegExp.exec(text); | 
					
						
							|  |  |  | 		if(endMatch) { | 
					
						
							|  |  |  | 			// Extract the text
 | 
					
						
							|  |  |  | 			result.text = text.substring(match.index + match[0].length,endMatch.index); | 
					
						
							|  |  |  | 			// Process the attributes
 | 
					
						
							| 
									
										
										
										
											2014-05-01 16:58:49 +00:00
										 |  |  | 			var attrRegExp = /\s*([^=\s]+)\s*=\s*(?:"([^"]*)"|'([^']*)')/gi, | 
					
						
							| 
									
										
										
										
											2013-12-23 08:54:33 +00:00
										 |  |  | 				attrMatch; | 
					
						
							|  |  |  | 			do { | 
					
						
							|  |  |  | 				attrMatch = attrRegExp.exec(match[1]); | 
					
						
							|  |  |  | 				if(attrMatch) { | 
					
						
							|  |  |  | 					var name = attrMatch[1]; | 
					
						
							| 
									
										
										
										
											2014-05-26 16:47:07 +00:00
										 |  |  | 					var value = attrMatch[2] !== undefined ? attrMatch[2] : attrMatch[3]; | 
					
						
							| 
									
										
										
										
											2013-12-23 08:54:33 +00:00
										 |  |  | 					result[name] = value; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} while(attrMatch); | 
					
						
							|  |  |  | 			return result; | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-12-23 08:54:33 +00:00
										 |  |  | 	return undefined; | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | exports["application/x-tiddler-html-div"] = function(text,fields) { | 
					
						
							|  |  |  | 	return [parseTiddlerDiv(text,fields)]; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | exports["application/json"] = function(text,fields) { | 
					
						
							| 
									
										
										
										
											2014-11-13 16:04:30 +00:00
										 |  |  | 	var incoming = JSON.parse(text), | 
					
						
							|  |  |  | 		results = []; | 
					
						
							|  |  |  | 	if($tw.utils.isArray(incoming)) { | 
					
						
							|  |  |  | 		for(var t=0; t<incoming.length; t++) { | 
					
						
							|  |  |  | 			var incomingFields = incoming[t], | 
					
						
							|  |  |  | 				fields = {}; | 
					
						
							|  |  |  | 			for(var f in incomingFields) { | 
					
						
							|  |  |  | 				if(typeof incomingFields[f] === "string") { | 
					
						
							|  |  |  | 					fields[f] = incomingFields[f]; | 
					
						
							| 
									
										
										
										
											2012-07-10 22:17:39 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-11-13 16:04:30 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			results.push(fields); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-13 16:04:30 +00:00
										 |  |  | 	return results; | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | /* | 
					
						
							|  |  |  | Parse an HTML file into tiddlers. There are three possibilities: | 
					
						
							| 
									
										
										
										
											2013-08-25 21:06:28 +00:00
										 |  |  | # A TiddlyWiki classic HTML file containing `text/x-tiddlywiki` tiddlers | 
					
						
							| 
									
										
										
										
											2013-05-13 16:42:07 +00:00
										 |  |  | # A TiddlyWiki5 HTML file containing `text/vnd.tiddlywiki` tiddlers | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | # An ordinary HTML file | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | exports["text/html"] = function(text,fields) { | 
					
						
							|  |  |  | 	// Check if we've got a store area
 | 
					
						
							|  |  |  | 	var storeAreaMarkerRegExp = /<div id=["']?storeArea['"]?( style=["']?display:none;["']?)?>/gi, | 
					
						
							|  |  |  | 		match = storeAreaMarkerRegExp.exec(text); | 
					
						
							|  |  |  | 	if(match) { | 
					
						
							| 
									
										
										
										
											2014-01-19 20:13:55 +00:00
										 |  |  | 		// If so, it's either a classic TiddlyWiki file or an unencrypted TW5 file
 | 
					
						
							| 
									
										
										
										
											2013-12-02 09:57:54 +00:00
										 |  |  | 		// First read the normal tiddlers
 | 
					
						
							|  |  |  | 		var results = deserializeTiddlyWikiFile(text,storeAreaMarkerRegExp.lastIndex,!!match[1],fields); | 
					
						
							|  |  |  | 		// Then any system tiddlers
 | 
					
						
							|  |  |  | 		var systemAreaMarkerRegExp = /<div id=["']?systemArea['"]?( style=["']?display:none;["']?)?>/gi, | 
					
						
							|  |  |  | 			sysMatch = systemAreaMarkerRegExp.exec(text); | 
					
						
							|  |  |  | 		if(sysMatch) { | 
					
						
							|  |  |  | 			results.push.apply(results,deserializeTiddlyWikiFile(text,systemAreaMarkerRegExp.lastIndex,!!sysMatch[1],fields)); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-08-30 19:44:26 +00:00
										 |  |  | 		return results; | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2014-01-19 20:13:55 +00:00
										 |  |  | 		// Check whether we've got an encrypted file
 | 
					
						
							|  |  |  | 		var encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text); | 
					
						
							|  |  |  | 		if(encryptedStoreArea) { | 
					
						
							|  |  |  | 			// If so, attempt to decrypt it using the current password
 | 
					
						
							|  |  |  | 			return $tw.utils.decryptStoreArea(encryptedStoreArea); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler
 | 
					
						
							|  |  |  | 			return deserializeHtmlFile(text,fields); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function deserializeHtmlFile(text,fields) { | 
					
						
							|  |  |  | 	var result = {}; | 
					
						
							|  |  |  | 	$tw.utils.each(fields,function(value,name) { | 
					
						
							|  |  |  | 		result[name] = value; | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 	result.text = text; | 
					
						
							|  |  |  | 	result.type = "text/html"; | 
					
						
							|  |  |  | 	return [result]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function deserializeTiddlyWikiFile(text,storeAreaEnd,isTiddlyWiki5,fields) { | 
					
						
							|  |  |  | 	var results = [], | 
					
						
							|  |  |  | 		endOfDivRegExp = /(<\/div>\s*)/gi, | 
					
						
							|  |  |  | 		startPos = storeAreaEnd, | 
					
						
							| 
									
										
										
										
											2013-08-25 21:06:28 +00:00
										 |  |  | 		defaultType = isTiddlyWiki5 ? undefined : "text/x-tiddlywiki"; | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | 	endOfDivRegExp.lastIndex = startPos; | 
					
						
							|  |  |  | 	var match = endOfDivRegExp.exec(text); | 
					
						
							|  |  |  | 	while(match) { | 
					
						
							|  |  |  | 		var endPos = endOfDivRegExp.lastIndex, | 
					
						
							|  |  |  | 			tiddlerFields = parseTiddlerDiv(text.substring(startPos,endPos),fields,{type: defaultType}); | 
					
						
							|  |  |  | 		if(!tiddlerFields) { | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-08-28 08:25:54 +00:00
										 |  |  | 		$tw.utils.each(tiddlerFields,function(value,name) { | 
					
						
							|  |  |  | 			if(typeof value === "string") { | 
					
						
							|  |  |  | 				tiddlerFields[name] = $tw.utils.htmlDecode(value); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | 		if(tiddlerFields.text !== null) { | 
					
						
							|  |  |  | 			results.push(tiddlerFields); | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | 		startPos = endPos; | 
					
						
							|  |  |  | 		match = endOfDivRegExp.exec(text); | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return results; | 
					
						
							| 
									
										
										
										
											2013-04-03 11:57:17 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-05-29 20:58:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-03 20:47:16 +00:00
										 |  |  | })(); |