mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-01-06 15:30:26 +00:00
Minimal functional built-in plugin library
This commit is contained in:
parent
0ce5788747
commit
8fdaaa7213
100
core/modules/library.js
Normal file
100
core/modules/library.js
Normal file
@ -0,0 +1,100 @@
|
||||
/*\
|
||||
title: $:/core/modules/library.js
|
||||
type: application/javascript
|
||||
module-type: global
|
||||
|
||||
Library handling utilities
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
function Library(options) {
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
Library.prototype.getLibraryItems = function() {
|
||||
if(!this.items) {
|
||||
this.loadLibraryItems();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
Library.prototype.loadLibraryItems = function() {
|
||||
var self = this,
|
||||
fs = require("fs"),
|
||||
path = require("path");
|
||||
// Collect the library items from disk
|
||||
this.items = {};
|
||||
var collectPlugins = function(folder) {
|
||||
var pluginFolders = $tw.utils.getSubdirectories(folder) || [];
|
||||
for(var p=0; p<pluginFolders.length; p++) {
|
||||
if(!$tw.boot.excludeRegExp.test(pluginFolders[p])) {
|
||||
var pluginFields = $tw.loadPluginFolder(path.resolve(folder,"./" + pluginFolders[p]));
|
||||
if(pluginFields && pluginFields.title) {
|
||||
self.items[pluginFields.title] = pluginFields;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
collectPublisherPlugins = function(folder) {
|
||||
var publisherFolders = $tw.utils.getSubdirectories(folder) || [];
|
||||
for(var t=0; t<publisherFolders.length; t++) {
|
||||
if(!$tw.boot.excludeRegExp.test(publisherFolders[t])) {
|
||||
collectPlugins(path.resolve(folder,"./" + publisherFolders[t]));
|
||||
}
|
||||
}
|
||||
};
|
||||
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.pluginsPath,$tw.config.pluginsEnvVar),collectPublisherPlugins);
|
||||
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.themesPath,$tw.config.themesEnvVar),collectPublisherPlugins);
|
||||
$tw.utils.each($tw.getLibraryItemSearchPaths($tw.config.languagesPath,$tw.config.languagesEnvVar),collectPlugins);
|
||||
// Compile the metadata
|
||||
this.itemMetadata = [];
|
||||
$tw.utils.each(Object.keys(self.items),function(title) {
|
||||
var tiddler = self.items[title];
|
||||
// Collect the skinny list data
|
||||
var pluginTiddlers = $tw.utils.parseJSONSafe(tiddler.text),
|
||||
readmeContent = (pluginTiddlers.tiddlers[title + "/readme"] || {}).text,
|
||||
doesRequireReload = !!$tw.wiki.doesPluginInfoRequireReload(pluginTiddlers),
|
||||
iconTiddler = pluginTiddlers.tiddlers[title + "/icon"] || {},
|
||||
iconType = iconTiddler.type,
|
||||
iconText = iconTiddler.text,
|
||||
iconContent;
|
||||
if(iconType && iconText) {
|
||||
iconContent = $tw.utils.makeDataUri(iconText,iconType);
|
||||
}
|
||||
self.itemMetadata.push($tw.utils.extend({},tiddler,{
|
||||
text: undefined,
|
||||
readme: readmeContent,
|
||||
"requires-reload": doesRequireReload ? "yes" : "no",
|
||||
icon: iconContent
|
||||
}));
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
Library.prototype.getMetadata = function() {
|
||||
this.loadLibraryItems();
|
||||
return this.itemMetadata;
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
Library.prototype.getItem = function(title) {
|
||||
this.loadLibraryItems();
|
||||
if($tw.utils.hop(this.items,title)) {
|
||||
return this.items[title];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
exports.Library = Library;
|
||||
|
||||
})();
|
24
core/modules/server/routes/get-library-html.js
Normal file
24
core/modules/server/routes/get-library-html.js
Normal file
@ -0,0 +1,24 @@
|
||||
/*\
|
||||
title: $:/core/modules/server/routes/get-library-html.js
|
||||
type: application/javascript
|
||||
module-type: route
|
||||
|
||||
GET /library/
|
||||
|
||||
\*/
|
||||
(function() {
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.method = "GET";
|
||||
|
||||
exports.path = /^\/library$/;
|
||||
|
||||
exports.handler = function(request,response,state) {
|
||||
var text = state.wiki.getTiddlerText("$:/core/templates/library.template.html","");
|
||||
state.sendResponse(200,{"Content-Type": "text/html"},text,"utf8");
|
||||
};
|
||||
|
||||
}());
|
31
core/modules/server/routes/get-library-item.js
Normal file
31
core/modules/server/routes/get-library-item.js
Normal file
@ -0,0 +1,31 @@
|
||||
/*\
|
||||
title: $:/core/modules/server/routes/get-library-item.js
|
||||
type: application/javascript
|
||||
module-type: route
|
||||
|
||||
GET /library
|
||||
|
||||
\*/
|
||||
(function() {
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.method = "GET";
|
||||
|
||||
exports.path = /^\/library\/(.+)$/;
|
||||
|
||||
exports.handler = function(request,response,state) {
|
||||
var title = $tw.utils.decodeURIComponentSafe($tw.utils.decodeURIComponentSafe(state.params[0])),
|
||||
item = $tw.library.getItem(title);
|
||||
if(item) {
|
||||
var text = JSON.stringify(item);
|
||||
state.sendResponse(200,{"Content-Type": "application/json"},text,"utf8");
|
||||
} else {
|
||||
response.writeHead(404);
|
||||
response.end();
|
||||
}
|
||||
};
|
||||
|
||||
}());
|
24
core/modules/server/routes/get-library.js
Normal file
24
core/modules/server/routes/get-library.js
Normal file
@ -0,0 +1,24 @@
|
||||
/*\
|
||||
title: $:/core/modules/server/routes/get-library.js
|
||||
type: application/javascript
|
||||
module-type: route
|
||||
|
||||
GET /library
|
||||
|
||||
\*/
|
||||
(function() {
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.method = "GET";
|
||||
|
||||
exports.path = /^\/library\/$/;
|
||||
|
||||
exports.handler = function(request,response,state) {
|
||||
var text = JSON.stringify($tw.library.getMetadata());
|
||||
state.sendResponse(200,{"Content-Type": "application/json"},text,"utf8");
|
||||
};
|
||||
|
||||
}());
|
@ -119,6 +119,8 @@ exports.startup = function() {
|
||||
$tw.syncadaptor = new module.adaptorClass({wiki: $tw.wiki});
|
||||
}
|
||||
});
|
||||
// Kick off the library manager
|
||||
$tw.library = new $tw.Library();
|
||||
// Set up the syncer object if we've got a syncadaptor
|
||||
if($tw.syncadaptor) {
|
||||
$tw.syncer = new $tw.Syncer({
|
||||
|
127
core/templates/server/library.template.html.tid
Normal file
127
core/templates/server/library.template.html.tid
Normal file
@ -0,0 +1,127 @@
|
||||
title: $:/core/templates/library.template.html
|
||||
type: text/html
|
||||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<meta name="application-name" content="TiddlyWiki Plugin Library" />
|
||||
<meta name="application-version" content="v0.0.0" />
|
||||
<meta name="copyright" content="Copyright 2015 Jeremy Ruston" />
|
||||
<link id="faviconLink" rel="shortcut icon" href="favicon.ico">
|
||||
<title>Plugin Library</title>
|
||||
<script>
|
||||
/*
|
||||
A simple HTTP-over-window.postMessage implementation of a standard TiddlyWeb-compatible server. It uses real HTTP to load the individual tiddler JSON files.
|
||||
*/
|
||||
|
||||
// Listen for window messages
|
||||
window.addEventListener("message",function listener(event){
|
||||
console.log("plugin library: Received message from",event.origin);
|
||||
console.log("plugin library: Message content",event.data);
|
||||
switch(event.data.verb) {
|
||||
case "GET":
|
||||
if(event.data.url === "recipes/library/tiddlers.json") {
|
||||
// Route for recipes/library/tiddlers.json
|
||||
var url = "library/";
|
||||
httpGet(url,function(err,responseText) {
|
||||
if(err) {
|
||||
event.source.postMessage({
|
||||
verb: "GET-RESPONSE",
|
||||
status: "404",
|
||||
cookies: event.data.cookies,
|
||||
url: event.data.url,
|
||||
type: "text/plain",
|
||||
body: "Not found"
|
||||
},"*");
|
||||
} else {
|
||||
event.source.postMessage({
|
||||
verb: "GET-RESPONSE",
|
||||
status: "200",
|
||||
cookies: event.data.cookies,
|
||||
url: event.data.url,
|
||||
type: "application/json",
|
||||
body: responseText
|
||||
},"*");
|
||||
}
|
||||
});
|
||||
} else if(event.data.url.indexOf("recipes/library/tiddlers/") === 0) {
|
||||
var url = "library/" + encodeURIComponent(removeSuffix(removePrefix(event.data.url,"recipes/library/tiddlers/"),".json"));
|
||||
// Route for recipes/library/tiddlers/<uri-encoded-tiddler-title>.json
|
||||
httpGet(url,function(err,responseText) {
|
||||
if(err) {
|
||||
event.source.postMessage({
|
||||
verb: "GET-RESPONSE",
|
||||
status: "404",
|
||||
cookies: event.data.cookies,
|
||||
url: event.data.url,
|
||||
type: "text/plain",
|
||||
body: "Not found"
|
||||
},"*");
|
||||
} else {
|
||||
event.source.postMessage({
|
||||
verb: "GET-RESPONSE",
|
||||
status: "200",
|
||||
cookies: event.data.cookies,
|
||||
url: event.data.url,
|
||||
type: "application/json",
|
||||
body: responseText
|
||||
},"*");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
event.source.postMessage({
|
||||
verb: "GET-RESPONSE",
|
||||
status: "404",
|
||||
cookies: event.data.cookies,
|
||||
url: event.data.url,
|
||||
type: "text/plain",
|
||||
body: "Not found"
|
||||
},"*");
|
||||
}
|
||||
break;
|
||||
}
|
||||
},false);
|
||||
|
||||
// Helper to remove string prefixes
|
||||
function removePrefix(string,prefix) {
|
||||
if(string.indexOf(prefix) === 0) {
|
||||
return string.substr(prefix.length);
|
||||
} else {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to remove string suffixes
|
||||
function removeSuffix(string,suffix) {
|
||||
if(string.indexOf(suffix) === string.length - suffix.length) {
|
||||
return string.substr(0,string.length - suffix.length);
|
||||
} else {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper for HTTP GET
|
||||
function httpGet(url,callback) {
|
||||
var http = new XMLHttpRequest();
|
||||
http.open("GET",url,true);
|
||||
http.onreadystatechange = function() {
|
||||
if(http.readyState == 4 && http.status == 200) {
|
||||
callback(null,http.responseText);
|
||||
}
|
||||
};
|
||||
http.send();
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>HelloThere</h1>
|
||||
|
||||
<p>This is the TiddlyWiki plugin library. It is not intended to be opened directly in the browser.</p>
|
||||
|
||||
<p>See <a href="https://tiddlywiki.com/" target="_blank">https://tiddlywiki.com/</a> for details of how to install plugins.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
6
plugins/tiddlywiki/tiddlyweb/BuiltInLibrary.tid
Normal file
6
plugins/tiddlywiki/tiddlyweb/BuiltInLibrary.tid
Normal file
@ -0,0 +1,6 @@
|
||||
title: $:/plugins/tiddlywiki/tiddlyweb/BuiltinLibrary
|
||||
tags: $:/tags/PluginLibrary
|
||||
url: /library
|
||||
caption: TiddlyWiki Built-in Plugin Library
|
||||
|
||||
This is the TiddlyWiki Built-in Plugin Library
|
Loading…
Reference in New Issue
Block a user