tw5-graph 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -0
- package/package.json +39 -0
- package/plugins/graph/DefaultColourMappings.multids +8 -0
- package/plugins/graph/ViewTemplateBodyFilter/graph.tid +5 -0
- package/plugins/graph/ViewTemplateBodyFilter/properties.tid +5 -0
- package/plugins/graph/edges/fields/list.tid +7 -0
- package/plugins/graph/edges/fields/tags.tid +7 -0
- package/plugins/graph/edges/functions/links.tid +8 -0
- package/plugins/graph/edges/functions/transcludes.tid +8 -0
- package/plugins/graph/fieldtypes/filter.js +212 -0
- package/plugins/graph/fieldtypes/list.js +31 -0
- package/plugins/graph/fieldtypes/title.js +27 -0
- package/plugins/graph/filterrunprefixes/cache.js +118 -0
- package/plugins/graph/filters/gettyped.js +26 -0
- package/plugins/graph/graphengine.js +38 -0
- package/plugins/graph/icon.tid +16 -0
- package/plugins/graph/images/drag.tid +13 -0
- package/plugins/graph/macros/action.addedge.tid +16 -0
- package/plugins/graph/macros/edges.typed.tid +54 -0
- package/plugins/graph/macros/graph.view.tid +24 -0
- package/plugins/graph/macros/node.default.tid +9 -0
- package/plugins/graph/macros/nodes.neighbors.tid +62 -0
- package/plugins/graph/macros/nodes.writable.tid +37 -0
- package/plugins/graph/macros/properties.persistent.tid +27 -0
- package/plugins/graph/macros/properties.popup.tid +76 -0
- package/plugins/graph/macros/properties.river.tid +27 -0
- package/plugins/graph/macros/properties.settings.tid +54 -0
- package/plugins/graph/macros/properties.stack.tid +17 -0
- package/plugins/graph/macros/tiddlywiki.files +17 -0
- package/plugins/graph/nodes/neighbors/1.tid +8 -0
- package/plugins/graph/plugin.info +14 -0
- package/plugins/graph/presettypes/edges/fields.tid +18 -0
- package/plugins/graph/presettypes/edges/functions.tid +5 -0
- package/plugins/graph/presettypes/nodes/neighbors.tid +4 -0
- package/plugins/graph/presettypes/nodes/stack.tid +6 -0
- package/plugins/graph/propertytypes/actions.js +15 -0
- package/plugins/graph/propertytypes/boolean.js +23 -0
- package/plugins/graph/propertytypes/color.js +61 -0
- package/plugins/graph/propertytypes/enum.js +25 -0
- package/plugins/graph/propertytypes/filter.js +44 -0
- package/plugins/graph/propertytypes/image.js +185 -0
- package/plugins/graph/propertytypes/number.js +24 -0
- package/plugins/graph/propertytypes/string.js +13 -0
- package/plugins/graph/propertytypes/tiddlywiki.files +17 -0
- package/plugins/graph/readme.tid +5 -0
- package/plugins/graph/relink/attributes.js +52 -0
- package/plugins/graph/relink/attributes.multids +19 -0
- package/plugins/graph/relink/configprefix.js +76 -0
- package/plugins/graph/relink/fieldedgeprefix.js +39 -0
- package/plugins/graph/relink/fields.multids +11 -0
- package/plugins/graph/relink/graphprefix.js +28 -0
- package/plugins/graph/relink/operators.multids +3 -0
- package/plugins/graph/relink/propertyfields.js +81 -0
- package/plugins/graph/relink/utils.js +99 -0
- package/plugins/graph/settings.tid +13 -0
- package/plugins/graph/startup/messages.js +46 -0
- package/plugins/graph/stylesheets/base.css.tid +272 -0
- package/plugins/graph/stylesheets/fullscreen/core.css +11 -0
- package/plugins/graph/stylesheets/fullscreen/core.css.meta +3 -0
- package/plugins/graph/stylesheets/fullscreen.css.tid +48 -0
- package/plugins/graph/stylesheets/popup.css.tid +107 -0
- package/plugins/graph/subfilters.tid +23 -0
- package/plugins/graph/tags/GraphToolbar.tid +2 -0
- package/plugins/graph/tags/SettingsTab.tid +2 -0
- package/plugins/graph/tags/Template.tid +2 -0
- package/plugins/graph/tags/ViewEditTemplate.tid +2 -0
- package/plugins/graph/templates/live-graph.tid +34 -0
- package/plugins/graph/templates/standard-graph.tid +40 -0
- package/plugins/graph/ui/Buttons/center.tid +38 -0
- package/plugins/graph/ui/Buttons/export.tid +65 -0
- package/plugins/graph/ui/Buttons/fullscreen.tid +35 -0
- package/plugins/graph/ui/Buttons/settings.tid +28 -0
- package/plugins/graph/ui/Buttons/tiddlywiki.files +16 -0
- package/plugins/graph/ui/EditTemplate/Edges.tid +22 -0
- package/plugins/graph/ui/EditTemplate/Neighbors.tid +35 -0
- package/plugins/graph/ui/EditTemplate/Nodes.tid +12 -0
- package/plugins/graph/ui/EditTemplate/Popups.tid +27 -0
- package/plugins/graph/ui/EditTemplate/Properties.tid +21 -0
- package/plugins/graph/ui/EditTemplate/tiddlywiki.files +16 -0
- package/plugins/graph/ui/Modals/NewPropertySet.tid +20 -0
- package/plugins/graph/ui/Modals/NewView.tid +20 -0
- package/plugins/graph/ui/Modals/Select.tid +72 -0
- package/plugins/graph/ui/Modals/SelectField.tid +21 -0
- package/plugins/graph/ui/Modals/SelectTiddler.tid +15 -0
- package/plugins/graph/ui/Modals/Tiddler.tid +22 -0
- package/plugins/graph/ui/Modals/TiddlerHeader.tid +15 -0
- package/plugins/graph/ui/PropertyTypes/boolean.tid +11 -0
- package/plugins/graph/ui/PropertyTypes/color.tid +16 -0
- package/plugins/graph/ui/PropertyTypes/enum.tid +15 -0
- package/plugins/graph/ui/PropertyTypes/number.tid +17 -0
- package/plugins/graph/ui/Settings/Engine.tid +23 -0
- package/plugins/graph/ui/Settings/Graphs/EditTemplate.tid +52 -0
- package/plugins/graph/ui/Settings/Graphs.tid +49 -0
- package/plugins/graph/ui/Settings/Properties/ObjectsTypeTemplate.tid +46 -0
- package/plugins/graph/ui/Settings/Properties.tid +14 -0
- package/plugins/graph/ui/Settings/Toolbar.tid +5 -0
- package/plugins/graph/ui/SideBar/Graph.tid +77 -0
- package/plugins/graph/ui/Toolbars/GraphToolbar.tid +15 -0
- package/plugins/graph/ui/ViewTemplate/graph-object.tid +13 -0
- package/plugins/graph/ui/ViewTemplate/graph.tid +11 -0
- package/plugins/graph/ui/ViewTemplate/properties.tid +80 -0
- package/plugins/graph/ui/grouped-tabs.tid +109 -0
- package/plugins/graph/ui/selector.tid +74 -0
- package/plugins/graph/utils/propertyholder.js +80 -0
- package/plugins/graph/utils/widgetiterator.js +47 -0
- package/plugins/graph/utils.js +95 -0
- package/plugins/graph/widgets/action-delay.js +72 -0
- package/plugins/graph/widgets/action-modal.js +121 -0
- package/plugins/graph/widgets/action-typed.js +56 -0
- package/plugins/graph/widgets/action-with.js +70 -0
- package/plugins/graph/widgets/boundingbox.js +126 -0
- package/plugins/graph/widgets/fieldtranscriber/filter.js +93 -0
- package/plugins/graph/widgets/fieldtranscriber/json.js +34 -0
- package/plugins/graph/widgets/fieldtranscriber/plain.js +11 -0
- package/plugins/graph/widgets/fieldtranscriber.js +98 -0
- package/plugins/graph/widgets/graphobject.js +154 -0
- package/plugins/graph/widgets/messagerelay.js +115 -0
- package/plugins/graph/widgets/properties.js +130 -0
- package/plugins/graph/widgets/subclass/edge.js +55 -0
- package/plugins/graph/widgets/subclass/edit-color.js +52 -0
- package/plugins/graph/widgets/subclass/graph.js +380 -0
- package/plugins/graph/widgets/subclass/node.js +56 -0
- package/plugins/graph/widgets/tiddlywiki.files +43 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Defines images types, and manages fetching a url from titles.
|
|
4
|
+
|
|
5
|
+
\*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
var Color = require("./color.js");
|
|
10
|
+
|
|
11
|
+
exports.name = "image";
|
|
12
|
+
|
|
13
|
+
exports.type = "title";
|
|
14
|
+
|
|
15
|
+
exports.toProperty = function(info, value, options) {
|
|
16
|
+
var parentWidget = options.widget;
|
|
17
|
+
var wiki = parentWidget.wiki;
|
|
18
|
+
var widget = parentWidget.imageWidget;
|
|
19
|
+
if (!wiki.tiddlerExists(value) && !wiki.isShadowTiddler(value)) {
|
|
20
|
+
// It's a tiddler. It must be a literal link to an external source.
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
if (!widget) {
|
|
24
|
+
var parser = wiki.getCacheForTiddler(value, "graphImageParser", function() {
|
|
25
|
+
return getImageParser(value, wiki);
|
|
26
|
+
});
|
|
27
|
+
widget = wiki.makeWidget(parser, {parentWidget: parentWidget});
|
|
28
|
+
widget.typeInfo = parser.typeInfo;
|
|
29
|
+
parentWidget.imageWidget = widget;
|
|
30
|
+
}
|
|
31
|
+
if (!widget.uri) {
|
|
32
|
+
var widget = parentWidget.imageWidget;
|
|
33
|
+
var container = $tw.fakeDocument.createElement("div");
|
|
34
|
+
var typeInfo = widget.typeInfo;
|
|
35
|
+
var url, svg;
|
|
36
|
+
widget.render(container, null);
|
|
37
|
+
if (!widget.typeInfo) {
|
|
38
|
+
// Probably just a literal link to an external image
|
|
39
|
+
url = container.innerHTML;
|
|
40
|
+
} else if (typeInfo.encoding === "base64") {
|
|
41
|
+
// .pdf .png .jpg etc.
|
|
42
|
+
url = "data:" + (typeInfo.deserializerType || "utf8") + ";base64," + container.innerHTML;
|
|
43
|
+
} else if (svg = findSVGElement(container)) {
|
|
44
|
+
// wikitext-based SVG?
|
|
45
|
+
//data = "data:" + deserializerType + ";" + encoding + "," + encodeURIComponent(text);
|
|
46
|
+
injectNamespace(svg);
|
|
47
|
+
var style = getStyle(info, parentWidget);
|
|
48
|
+
injectStyle(svg, style);
|
|
49
|
+
var encoding = "";
|
|
50
|
+
if(wiki.isImageTiddler(value)) {
|
|
51
|
+
encoding = ";utf8";
|
|
52
|
+
}
|
|
53
|
+
url = "data:image/svg+xml" + encoding + "," + encodeURIComponent(container.innerHTML);
|
|
54
|
+
} else {
|
|
55
|
+
url = null;
|
|
56
|
+
}
|
|
57
|
+
widget.url = url;
|
|
58
|
+
}
|
|
59
|
+
return parentWidget.imageWidget.url;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
exports.refresh = function(info, value, changedTiddlers, widget) {
|
|
63
|
+
if (changedTiddlers[value]) {
|
|
64
|
+
widget.imageWidget = undefined;
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
if (!widget.imageWidget) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
if (widget.imageWidget.refresh(changedTiddlers)) {
|
|
71
|
+
widget.imageWidget.uri = undefined;
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
// Now we need to check whether any property-dependent styles for the
|
|
75
|
+
// image have changed.
|
|
76
|
+
return refreshStyle(info, widget, changedTiddlers);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
function getImageParser(title, wiki) {
|
|
80
|
+
var parser;
|
|
81
|
+
var typeInfo;
|
|
82
|
+
// Check if it is an image tiddler
|
|
83
|
+
if(wiki.isImageTiddler(title)) {
|
|
84
|
+
var tiddler = wiki.getTiddler(title),
|
|
85
|
+
type = tiddler.fields.type,
|
|
86
|
+
text = tiddler.fields.text,
|
|
87
|
+
data;
|
|
88
|
+
typeInfo = $tw.config.contentTypeInfo[type] || {};
|
|
89
|
+
if(text) {
|
|
90
|
+
var encoding = typeInfo.encoding || "utf8";
|
|
91
|
+
if (encoding === "base64") {
|
|
92
|
+
parser = { tree: [{
|
|
93
|
+
type: "text",
|
|
94
|
+
attributes: { text: {type: "string", value: text} }
|
|
95
|
+
}]};
|
|
96
|
+
} else {
|
|
97
|
+
// It's an xml svg probably. We still need to parse it into
|
|
98
|
+
// a DOM tree for manipulation.
|
|
99
|
+
text = text.replace(/^<\?[^?]*\?>/, "");
|
|
100
|
+
// Also remove DOCTYPE declarations
|
|
101
|
+
text = text.replace(/^\s*<!DOCTYPE\s[^>]*>/, "");
|
|
102
|
+
parser = wiki.parseText("text/vnd.tiddlywiki", "\\rules only html commentinline commentblock\n" + text, {parseAsInline: true});
|
|
103
|
+
}
|
|
104
|
+
//deserializerType = typeInfo.deserializerType || type;
|
|
105
|
+
// Render the appropriate element for the image type by
|
|
106
|
+
// looking up the encoding in the content type info
|
|
107
|
+
} else if(tiddler.fields._canonical_uri) {
|
|
108
|
+
parser = {
|
|
109
|
+
tree: [{
|
|
110
|
+
type: "text",
|
|
111
|
+
attributes: { text: {type: "string", value: tiddler.fields._canonical_uri} }
|
|
112
|
+
}]};
|
|
113
|
+
// It's a link. We don't need to describe type info
|
|
114
|
+
typeInfo = null;
|
|
115
|
+
} else {
|
|
116
|
+
// This must be a lazily loaded tiddler. We don't support those yet.
|
|
117
|
+
text = null;
|
|
118
|
+
}
|
|
119
|
+
} else if (wiki.tiddlerExists(title) || wiki.isShadowTiddler(title)) {
|
|
120
|
+
// We assume it is wikitext trying to make an svg
|
|
121
|
+
parser = wiki.parseTiddler(title, {parseAsInline: true});
|
|
122
|
+
typeInfo = $tw.config.contentTypeInfo["image/svg+xml"];
|
|
123
|
+
} else {
|
|
124
|
+
parser = { tree: [{
|
|
125
|
+
type: "text",
|
|
126
|
+
attributes: { text: {type: "string", value: title} }
|
|
127
|
+
}]};
|
|
128
|
+
}
|
|
129
|
+
parser.typeInfo = typeInfo;
|
|
130
|
+
return parser;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
function findSVGElement(element) {
|
|
134
|
+
if (element.tag === "svg") {
|
|
135
|
+
return element;
|
|
136
|
+
}
|
|
137
|
+
if (element.children) {
|
|
138
|
+
for (var i = 0; i < element.children.length; i++) {
|
|
139
|
+
var found = findSVGElement(element.children[i]);
|
|
140
|
+
if (found) {
|
|
141
|
+
return found;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
function getStyle(info, objectWidget) {
|
|
149
|
+
if (!info.style) {
|
|
150
|
+
return "";
|
|
151
|
+
}
|
|
152
|
+
var styleParts = [];
|
|
153
|
+
for (var attribute in info.style) {
|
|
154
|
+
var key = info.style[attribute];
|
|
155
|
+
var styleValue = objectWidget.evaluateProperty(key);
|
|
156
|
+
if (styleValue) {
|
|
157
|
+
// probably "fill:color", but any kind of css styling is allowed.
|
|
158
|
+
styleParts.push(attribute + ":" + styleValue + ";");
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return styleParts.length > 0? ":root{" + styleParts.join("") + "}": "";
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
function refreshStyle(info, objectWidget, changedTiddlers) {
|
|
165
|
+
for (var attribute in info.style) {
|
|
166
|
+
var key = info.style[attribute];
|
|
167
|
+
if (objectWidget.refreshProperty(key, changedTiddlers)) {
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return false;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
function injectNamespace(svg) {
|
|
175
|
+
// wikitext svg does not need namespacing, but data URIs do
|
|
176
|
+
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
function injectStyle(svg, style) {
|
|
180
|
+
if (style) {
|
|
181
|
+
var styleElement = $tw.fakeDocument.createElement("style");
|
|
182
|
+
styleElement.textContent = style;
|
|
183
|
+
svg.insertBefore(styleElement, svg.children[0]);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Defines behavior for number types in graph engine properties.
|
|
4
|
+
|
|
5
|
+
\*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
exports.name = "number";
|
|
10
|
+
|
|
11
|
+
exports.toProperty = function(info, value) {
|
|
12
|
+
value = parseFloat(value);
|
|
13
|
+
if (isNaN(value)) {
|
|
14
|
+
// Ignore it. It's a bad number.
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
if (info.min !== undefined && value < info.min) {
|
|
18
|
+
value = info.min;
|
|
19
|
+
}
|
|
20
|
+
if (info.max !== undefined && value > info.max) {
|
|
21
|
+
value = info.max;
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"directories": [
|
|
3
|
+
{
|
|
4
|
+
"path": ".",
|
|
5
|
+
"filesRegExp": "^.*\\.js$",
|
|
6
|
+
"isTiddlerFile": false,
|
|
7
|
+
"fields": {
|
|
8
|
+
"title": {
|
|
9
|
+
"source": "filename",
|
|
10
|
+
"prefix": "$:/plugins/flibbles/graph/propertytypes/"
|
|
11
|
+
},
|
|
12
|
+
"type": "application/javascript",
|
|
13
|
+
"module-type": "graphpropertytype"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
title: $:/plugins/flibbles/graph/readme
|
|
2
|
+
|
|
3
|
+
//tw5-graph// is a plugin which provides a toolkit of widgets to interact with graph visualization software. This plugin does not include any visualization libraries itself. It must be coupled with a library plugin that acts as an engine.
|
|
4
|
+
|
|
5
|
+
[ext[Project page is available on github.|https://github.com/flibbles/tw5-graph]]
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
title: $:/plugins/flibbles/graph/relink/attributes.js
|
|
3
|
+
type: application/javascript
|
|
4
|
+
module-type: relinkhtmlattributes
|
|
5
|
+
|
|
6
|
+
Relinks attributes of $properties and other graph object widgets.
|
|
7
|
+
|
|
8
|
+
\*/
|
|
9
|
+
|
|
10
|
+
"use strict";
|
|
11
|
+
|
|
12
|
+
exports.name = "graph";
|
|
13
|
+
|
|
14
|
+
var utils = require("./utils.js");
|
|
15
|
+
var graphObjects = Object.create(null);
|
|
16
|
+
|
|
17
|
+
$tw.modules.forEachModuleOfType("widget-subclass", function(subclass, module) {
|
|
18
|
+
var type = module.prototype.graphObjectType;
|
|
19
|
+
if (module.baseClass === "graphobject") {
|
|
20
|
+
graphObjects["$" + module.name] = function() { return type; };
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
graphObjects["$graph"] = function() { return "graph"; };
|
|
25
|
+
|
|
26
|
+
// Current behavior is if $for is specified, but it's empty or wrong, then
|
|
27
|
+
// this widget gets ignored for relinking, just as it gets ignored by graphs.
|
|
28
|
+
graphObjects["$properties"] = function(element) {
|
|
29
|
+
var forAttr = element.attributes["$for"];
|
|
30
|
+
return forAttr !== undefined? forAttr.value: "nodes";
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
exports.getHandler = function(element, attribute, options) {
|
|
34
|
+
var forFunc = graphObjects[element.tag];
|
|
35
|
+
if (forFunc) {
|
|
36
|
+
return processAttribute(forFunc(element), attribute, options);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
function processAttribute(forObject, attribute, options) {
|
|
41
|
+
var name = attribute.name;
|
|
42
|
+
if (name[0] !== "$") {
|
|
43
|
+
var engine = utils.getEngine(options.wiki);
|
|
44
|
+
if (engine) {
|
|
45
|
+
var properties = engine.prototype.properties[forObject];
|
|
46
|
+
if (properties) {
|
|
47
|
+
var propertyInfo = properties[attribute.name];
|
|
48
|
+
return utils.getRelinker(propertyInfo);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
title: $:/config/flibbles/relink/attributes/
|
|
2
|
+
|
|
3
|
+
$action-addtyped/$field: fieldname
|
|
4
|
+
$action-addtyped/$tiddler: title
|
|
5
|
+
$action-delay/$state: title
|
|
6
|
+
$action-modal/$tiddler: title
|
|
7
|
+
$action-removetyped/$field: fieldname
|
|
8
|
+
$action-removetyped/$tiddler: title
|
|
9
|
+
$boundingbox/length: filter
|
|
10
|
+
$boundingbox/width: filter
|
|
11
|
+
$edge/$from: title
|
|
12
|
+
$edge/$to: title
|
|
13
|
+
$fieldtranscriber/state: title
|
|
14
|
+
$fieldtranscriber/field: fieldname
|
|
15
|
+
$fieldtranscriber/tiddler: title
|
|
16
|
+
$node/$tiddler: title
|
|
17
|
+
$properties/$tiddler: title
|
|
18
|
+
$properties/$field: fieldname
|
|
19
|
+
$properties/$filter: filter
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
title: $:/plugins/flibbles/graph/relink/configprefix.js
|
|
3
|
+
type: application/javascript
|
|
4
|
+
module-type: relinkprefix
|
|
5
|
+
|
|
6
|
+
Takes care of relinking property data tiddlers
|
|
7
|
+
in the $:/config/flibbles/graph namespace.
|
|
8
|
+
|
|
9
|
+
\*/
|
|
10
|
+
|
|
11
|
+
"use strict";
|
|
12
|
+
|
|
13
|
+
exports.prefix = "$:/config/flibbles/graph/";
|
|
14
|
+
|
|
15
|
+
var utils = require("./utils.js");
|
|
16
|
+
var jsonType = "application/json";
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
exports.report = function(tiddler, callback, options) {
|
|
20
|
+
forEachProperty(options.wiki, tiddler, function(key, data, relinker) {
|
|
21
|
+
relinker.report(data[key], function(title, blurb, info) {
|
|
22
|
+
var suffix = blurb? (": " + blurb): "";
|
|
23
|
+
callback(title, key + suffix, info);
|
|
24
|
+
}, options);
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
exports.relink = function(tiddler, fromTitle, toTitle, changes, options) {
|
|
29
|
+
var changed, tiddlerData;
|
|
30
|
+
var type = tiddler.fields.type;
|
|
31
|
+
var impossible = false;
|
|
32
|
+
forEachProperty(options.wiki, tiddler, function(key, data, relinker) {
|
|
33
|
+
var lineEntry = relinker.relink(data[key], fromTitle, toTitle, options);
|
|
34
|
+
if (lineEntry) {
|
|
35
|
+
changed = true;
|
|
36
|
+
if (lineEntry.output) {
|
|
37
|
+
data[key] = lineEntry.output;
|
|
38
|
+
tiddlerData = data;
|
|
39
|
+
if (!isLegalDictionaryValue(lineEntry.output)) {
|
|
40
|
+
type = jsonType;
|
|
41
|
+
changes.type = {output: jsonType};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
impossible = lineEntry.impossible || impossible;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
if (changed) {
|
|
48
|
+
changes.text = {};
|
|
49
|
+
if (tiddlerData) {
|
|
50
|
+
var text;
|
|
51
|
+
if (type === jsonType) {
|
|
52
|
+
text = JSON.stringify(tiddlerData, null, $tw.config.preferences.jsonSpaces);
|
|
53
|
+
} else {
|
|
54
|
+
text = $tw.utils.makeTiddlerDictionary(tiddlerData);
|
|
55
|
+
}
|
|
56
|
+
changes.text.output = text;
|
|
57
|
+
}
|
|
58
|
+
if (impossible) {
|
|
59
|
+
changes.text.impossible = true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
function forEachProperty(wiki, tiddler, callback) {
|
|
65
|
+
var title = tiddler.fields.title;
|
|
66
|
+
var slashPos = title.indexOf("/", exports.prefix.length);
|
|
67
|
+
if (slashPos >= 0) {
|
|
68
|
+
var objectType = title.substring(exports.prefix.length, slashPos);
|
|
69
|
+
var data = wiki.getTiddlerData(title);
|
|
70
|
+
utils.forEachPropertyIn(data, objectType, wiki, callback);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
function isLegalDictionaryValue(text) {
|
|
75
|
+
return text.indexOf("\n") < 0;
|
|
76
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
title: $:/plugins/flibbles/graph/relink/fieldedgeprefix.js
|
|
3
|
+
type: application/javascript
|
|
4
|
+
module-type: relinkprefix
|
|
5
|
+
|
|
6
|
+
Takes care of relinking all edge property files in the "field" category.
|
|
7
|
+
|
|
8
|
+
\*/
|
|
9
|
+
|
|
10
|
+
"use strict";
|
|
11
|
+
|
|
12
|
+
// We only use this module if relink-fieldnames is installed and active
|
|
13
|
+
// Otherewise we don't engage in renaming field edges.
|
|
14
|
+
if ($tw.wiki.getShadowSource("$:/plugins/flibbles/relink-fieldnames/utils.js")) {
|
|
15
|
+
|
|
16
|
+
exports.prefix = "$:/config/flibbles/graph/edges/fields/";
|
|
17
|
+
|
|
18
|
+
var utils = require("$:/plugins/flibbles/relink-fieldnames/utils.js");
|
|
19
|
+
|
|
20
|
+
exports.report = function(tiddler, callback, options) {
|
|
21
|
+
var field = tiddler.fields.title.substr(exports.prefix.length);
|
|
22
|
+
if (!utils.isReserved(field, options)) {
|
|
23
|
+
callback(field, "#graph field edgetype: " + field);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
exports.relink = function(tiddler, fromTitle, toTitle, changes, options) {
|
|
28
|
+
var field = tiddler.fields.title.substr(exports.prefix.length);
|
|
29
|
+
if (field === fromTitle && !utils.isReserved(field, options)) {
|
|
30
|
+
if (utils.isReserved(toTitle, options)
|
|
31
|
+
|| options.wiki.tiddlerExists(exports.prefix + toTitle)) {
|
|
32
|
+
changes.title = {impossible: true};
|
|
33
|
+
} else {
|
|
34
|
+
changes.title = {output: exports.prefix + toTitle};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
title: $:/config/flibbles/relink/fields/
|
|
2
|
+
|
|
3
|
+
# This configuration already exists in Relink. We duplicate it here in case
|
|
4
|
+
# anyone runs tw5-graph without relink installed. We'll still recognize filter.
|
|
5
|
+
filter: filter
|
|
6
|
+
|
|
7
|
+
# These, however, are unique to TW5-Graph
|
|
8
|
+
template: title
|
|
9
|
+
edges.fields: filter
|
|
10
|
+
edges.functions: filter
|
|
11
|
+
popup.template: wikitext
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
title: $:/plugins/flibbles/graph/relink/graphprefix.js
|
|
3
|
+
type: application/javascript
|
|
4
|
+
module-type: relinkprefix
|
|
5
|
+
|
|
6
|
+
Takes care of relinking everything graphTiddler related.
|
|
7
|
+
Such as the tiddlers in the $:/graph/ namespace.
|
|
8
|
+
|
|
9
|
+
\*/
|
|
10
|
+
|
|
11
|
+
"use strict";
|
|
12
|
+
|
|
13
|
+
exports.prefix = "$:/graph/";
|
|
14
|
+
|
|
15
|
+
var utils = require("./utils.js");
|
|
16
|
+
var tag = "$:/tags/flibbles/graph/TiddlerData";
|
|
17
|
+
|
|
18
|
+
exports.report = function(tiddler, callback, options) {
|
|
19
|
+
if (!tiddler.hasTag(tag)) {
|
|
20
|
+
return utils.reportTiddlerData(tiddler, callback, options);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
exports.relink = function(tiddler, fromTitle, toTitle, changes, options) {
|
|
25
|
+
if (!tiddler.hasTag(tag)) {
|
|
26
|
+
return utils.relinkTiddlerData(tiddler, fromTitle, toTitle, changes, options);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
title: $:/plugins/flibbles/graph/relink/propertyfields.js
|
|
3
|
+
type: application/javascript
|
|
4
|
+
module-type: relinkoperator
|
|
5
|
+
|
|
6
|
+
Takes care of relinking graph.* properties across all tiddlers.
|
|
7
|
+
|
|
8
|
+
\*/
|
|
9
|
+
|
|
10
|
+
"use strict";
|
|
11
|
+
|
|
12
|
+
exports.name = "graph fields";
|
|
13
|
+
|
|
14
|
+
var utils = require("./utils.js");
|
|
15
|
+
var fieldPrefix = "graph.";
|
|
16
|
+
var tag = "$:/tags/flibbles/graph/TiddlerData";
|
|
17
|
+
|
|
18
|
+
exports.report = function(tiddler, callback, options) {
|
|
19
|
+
if (tiddler.hasTag(tag)) {
|
|
20
|
+
utils.reportTiddlerData(tiddler, callback, options);
|
|
21
|
+
}
|
|
22
|
+
for (var field in tiddler.fields) {
|
|
23
|
+
if ($tw.utils.startsWith(field, fieldPrefix)) {
|
|
24
|
+
var type = field.substr(fieldPrefix.length);
|
|
25
|
+
var data;
|
|
26
|
+
try {
|
|
27
|
+
data = JSON.parse(tiddler.fields[field]);
|
|
28
|
+
} catch {}
|
|
29
|
+
utils.forEachPropertyIn(data, type, options.wiki, function(key, data, relinker) {
|
|
30
|
+
relinker.report(data[key], function(title, blurb, info) {
|
|
31
|
+
var prefix = "#" + type + " - " + key;
|
|
32
|
+
if (blurb) {
|
|
33
|
+
prefix += ": " + blurb;
|
|
34
|
+
}
|
|
35
|
+
callback(title, prefix, info);
|
|
36
|
+
}, options);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
exports.relink = function(tiddler, fromTitle, toTitle, changes, options) {
|
|
43
|
+
if (tiddler.hasTag(tag)) {
|
|
44
|
+
utils.relinkTiddlerData(tiddler, fromTitle, toTitle, changes, options);
|
|
45
|
+
}
|
|
46
|
+
var changedField = {};
|
|
47
|
+
var impossibleFields = {};
|
|
48
|
+
for (var field in tiddler.fields) {
|
|
49
|
+
if ($tw.utils.startsWith(field, fieldPrefix)) {
|
|
50
|
+
var fieldData = undefined,
|
|
51
|
+
changed = false,
|
|
52
|
+
impossible = false;
|
|
53
|
+
var type = field.substr(fieldPrefix.length);
|
|
54
|
+
var data;
|
|
55
|
+
try {
|
|
56
|
+
data = JSON.parse(tiddler.fields[field]);
|
|
57
|
+
} catch {}
|
|
58
|
+
utils.forEachPropertyIn(data, type, options.wiki, function(key, data, relinker) {
|
|
59
|
+
var lineEntry = relinker.relink(data[key], fromTitle, toTitle, options);
|
|
60
|
+
if (lineEntry) {
|
|
61
|
+
changed = true;
|
|
62
|
+
if (lineEntry.output) {
|
|
63
|
+
data[key] = lineEntry.output;
|
|
64
|
+
fieldData = data;
|
|
65
|
+
}
|
|
66
|
+
impossible = lineEntry.impossible || impossible;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
if (changed) {
|
|
70
|
+
changes[field] = {};
|
|
71
|
+
if (fieldData) {
|
|
72
|
+
var text = JSON.stringify(fieldData);
|
|
73
|
+
changes[field].output = text;
|
|
74
|
+
}
|
|
75
|
+
if (impossible) {
|
|
76
|
+
changes[field].impossible = true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
title: $:/plugins/flibbles/graph/relink/utils.js
|
|
3
|
+
type: application/javascript
|
|
4
|
+
module-type: library
|
|
5
|
+
|
|
6
|
+
These utilities only ever get loaded if Relink is installed.
|
|
7
|
+
|
|
8
|
+
\*/
|
|
9
|
+
|
|
10
|
+
"use strict";
|
|
11
|
+
|
|
12
|
+
var baseUtils = require("../utils.js");
|
|
13
|
+
var relinkUtils = require("$:/plugins/flibbles/relink/js/utils.js");
|
|
14
|
+
var PropertyTypes = $tw.modules.getModulesByTypeAsHashmap("graphpropertytype");
|
|
15
|
+
|
|
16
|
+
exports.forEachPropertyIn = function(data, objectType, wiki, callback) {
|
|
17
|
+
if (data) {
|
|
18
|
+
var engine = exports.getEngine(wiki);
|
|
19
|
+
if (engine) {
|
|
20
|
+
var properties = engine.prototype.properties[objectType];
|
|
21
|
+
if (properties) {
|
|
22
|
+
for (var key in data) {
|
|
23
|
+
var propertyInfo = properties[key];
|
|
24
|
+
var relinker = exports.getRelinker(propertyInfo);
|
|
25
|
+
if (relinker) {
|
|
26
|
+
callback(key, data, relinker);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
exports.getRelinker = function(propertyInfo) {
|
|
35
|
+
var relinker;
|
|
36
|
+
if (propertyInfo) {
|
|
37
|
+
var propertyClass = PropertyTypes[propertyInfo.type];
|
|
38
|
+
if (propertyClass && propertyClass.type) {
|
|
39
|
+
relinker = relinkUtils.getType(propertyClass.type);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return relinker;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
exports.getEngine = function(wiki) {
|
|
46
|
+
var value = $tw.macros.graphengine.get(wiki);
|
|
47
|
+
return baseUtils.getEngine(value);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
exports.reportTiddlerData = function(tiddler, callback, options) {
|
|
51
|
+
var data = options.wiki.getTiddlerDataCached(tiddler.fields.title, {});
|
|
52
|
+
for (var title in data) {
|
|
53
|
+
callback(title, data[title], {soft: true});
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
exports.relinkTiddlerData = function(tiddler, fromTitle, toTitle, changes, options) {
|
|
58
|
+
var data = options.wiki.getTiddlerDataCached(tiddler.fields.title, {});
|
|
59
|
+
if (data[fromTitle] !== undefined) {
|
|
60
|
+
var newData = {};
|
|
61
|
+
for (var title in data) {
|
|
62
|
+
if (title === fromTitle) {
|
|
63
|
+
newData[toTitle] = data[title];
|
|
64
|
+
} else {
|
|
65
|
+
newData[title] = data[title];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
var newText;
|
|
69
|
+
var type = tiddler.fields.type;
|
|
70
|
+
if (type === "application/x-tiddler-dictionary") {
|
|
71
|
+
if (isLegalDictionaryKey(toTitle)) {
|
|
72
|
+
newText = $tw.utils.makeTiddlerDictionary(newData);
|
|
73
|
+
} else {
|
|
74
|
+
type = "application/json";
|
|
75
|
+
changes.type = {output: type};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (type === "application/json") {
|
|
79
|
+
newText = JSON.stringify(newData, null, $tw.config.preferences.jsonSpaces);
|
|
80
|
+
}
|
|
81
|
+
changes.text = {output: newText};
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
function isLegalDictionaryKey(title) {
|
|
86
|
+
// We make a microdictionary with the value and make sure we get back
|
|
87
|
+
// a dictionary with the key pointing to an arbitrary x
|
|
88
|
+
var fields = $tw.utils.parseFields(title + ":x");
|
|
89
|
+
var found = false;
|
|
90
|
+
for (var key in fields) {
|
|
91
|
+
if (found
|
|
92
|
+
|| key !== title
|
|
93
|
+
|| fields[key] !== "x") {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
found = true;
|
|
97
|
+
}
|
|
98
|
+
return found;
|
|
99
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
title: $:/plugins/flibbles/graph/settings
|
|
2
|
+
tags: [[$:/tags/ControlPanel/SettingsTab]]
|
|
3
|
+
caption: Graph
|
|
4
|
+
|
|
5
|
+
\procedure filterTab() [!has[filter]] ~[subfilter{!!filter}]
|
|
6
|
+
\procedure settingsTabs() [[$:/tags/flibbles/graph/SettingsTab]tagging[]filter<filterTab>]
|
|
7
|
+
|
|
8
|
+
Settings page for TW5-Graph. See the [ext[project website|https://flibbles.github.io/tw5-graph]] for complete documentation.
|
|
9
|
+
|
|
10
|
+
<$transclude $variable=tabs
|
|
11
|
+
tabsList=<<settingsTabs>>
|
|
12
|
+
default={{{ [subfilter<settingsTabs>] }}}
|
|
13
|
+
explicitState="$:/state/flibbles/graph/settings" />
|