1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-11-23 18:17:20 +00:00
TiddlyWiki5/core/modules/startup/browser-messaging.js
Jeremy Ruston 82c8fe7fa8
Introduce JSON parse utility function with error handling (#6401)
* Introduce JSON parse utility function with error handling

Fixes #6400

* Fix typo
2022-02-21 15:29:25 +00:00

184 lines
5.5 KiB
JavaScript

/*\
title: $:/core/modules/browser-messaging.js
type: application/javascript
module-type: startup
Browser message handling
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
// Export name and synchronous status
exports.name = "browser-messaging";
exports.platforms = ["browser"];
exports.after = ["startup"];
exports.synchronous = true;
/*
Load a specified url as an iframe and call the callback when it is loaded. If the url is already loaded then the existing iframe instance is used
*/
function loadIFrame(url,callback) {
// Check if iframe already exists
var iframeInfo = $tw.browserMessaging.iframeInfoMap[url];
if(iframeInfo) {
// We've already got the iframe
callback(null,iframeInfo);
} else {
// Create the iframe and save it in the list
var iframe = document.createElement("iframe");
iframeInfo = {
url: url,
status: "loading",
domNode: iframe
};
$tw.browserMessaging.iframeInfoMap[url] = iframeInfo;
saveIFrameInfoTiddler(iframeInfo);
// Add the iframe to the DOM and hide it
iframe.style.display = "none";
iframe.setAttribute("library","true");
document.body.appendChild(iframe);
// Set up onload
iframe.onload = function() {
iframeInfo.status = "loaded";
saveIFrameInfoTiddler(iframeInfo);
callback(null,iframeInfo);
};
iframe.onerror = function() {
callback("Cannot load iframe");
};
try {
iframe.src = url;
} catch(ex) {
callback(ex);
}
}
}
/*
Unload library iframe for given url
*/
function unloadIFrame(url){
$tw.utils.each(document.getElementsByTagName('iframe'), function(iframe) {
if(iframe.getAttribute("library") === "true" &&
iframe.getAttribute("src") === url) {
iframe.parentNode.removeChild(iframe);
}
});
}
function saveIFrameInfoTiddler(iframeInfo) {
$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),{
title: "$:/temp/ServerConnection/" + iframeInfo.url,
text: iframeInfo.status,
tags: ["$:/tags/ServerConnection"],
url: iframeInfo.url
},$tw.wiki.getModificationFields()));
}
exports.startup = function() {
// Initialise the store of iframes we've created
$tw.browserMessaging = {
iframeInfoMap: {} // Hashmap by URL of {url:,status:"loading/loaded",domNode:}
};
// Listen for widget messages to control loading the plugin library
$tw.rootWidget.addEventListener("tm-load-plugin-library",function(event) {
var paramObject = event.paramObject || {},
url = paramObject.url;
if(url) {
loadIFrame(url,function(err,iframeInfo) {
if(err) {
alert($tw.language.getString("Error/LoadingPluginLibrary") + ": " + url);
} else {
iframeInfo.domNode.contentWindow.postMessage({
verb: "GET",
url: "recipes/library/tiddlers.json",
cookies: {
type: "save-info",
infoTitlePrefix: paramObject.infoTitlePrefix || "$:/temp/RemoteAssetInfo/",
url: url
}
},"*");
}
});
}
});
// Listen for widget messages to control unloading the plugin library
$tw.rootWidget.addEventListener("tm-unload-plugin-library",function(event) {
var paramObject = event.paramObject || {},
url = paramObject.url;
$tw.browserMessaging.iframeInfoMap[url] = undefined;
if(url) {
unloadIFrame(url);
$tw.utils.each(
$tw.wiki.filterTiddlers("[[$:/temp/ServerConnection/" + url + "]] [prefix[$:/temp/RemoteAssetInfo/" + url + "/]]"),
function(title) {
$tw.wiki.deleteTiddler(title);
}
);
}
});
$tw.rootWidget.addEventListener("tm-load-plugin-from-library",function(event) {
var paramObject = event.paramObject || {},
url = paramObject.url,
title = paramObject.title;
if(url && title) {
loadIFrame(url,function(err,iframeInfo) {
if(err) {
alert($tw.language.getString("Error/LoadingPluginLibrary") + ": " + url);
} else {
iframeInfo.domNode.contentWindow.postMessage({
verb: "GET",
url: "recipes/library/tiddlers/" + encodeURIComponent(title) + ".json",
cookies: {
type: "save-tiddler",
url: url
}
},"*");
}
});
}
});
// Listen for window messages from other windows
window.addEventListener("message",function listener(event){
// console.log("browser-messaging: ",document.location.toString())
// console.log("browser-messaging: Received message from",event.origin);
// console.log("browser-messaging: Message content",event.data);
switch(event.data.verb) {
case "GET-RESPONSE":
if(event.data.status.charAt(0) === "2") {
if(event.data.cookies) {
if(event.data.cookies.type === "save-info") {
var tiddlers = $tw.utils.parseJSONSafe(event.data.body);
$tw.utils.each(tiddlers,function(tiddler) {
$tw.wiki.addTiddler(new $tw.Tiddler($tw.wiki.getCreationFields(),tiddler,{
title: event.data.cookies.infoTitlePrefix + event.data.cookies.url + "/" + tiddler.title,
"original-title": tiddler.title,
text: "",
type: "text/vnd.tiddlywiki",
"original-type": tiddler.type,
"plugin-type": undefined,
"original-plugin-type": tiddler["plugin-type"],
"module-type": undefined,
"original-module-type": tiddler["module-type"],
tags: ["$:/tags/RemoteAssetInfo"],
"original-tags": $tw.utils.stringifyList(tiddler.tags || []),
"server-url": event.data.cookies.url
},$tw.wiki.getModificationFields()));
});
} else if(event.data.cookies.type === "save-tiddler") {
var tiddler = $tw.utils.parseJSONSafe(event.data.body);
$tw.wiki.addTiddler(new $tw.Tiddler(tiddler));
}
}
}
break;
}
},false);
};
})();