@zakkzhang/tw5-graph 1.6.4

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.
Files changed (116) hide show
  1. package/README.md +65 -0
  2. package/package.json +39 -0
  3. package/plugins/graph/DefaultColourMappings.multids +8 -0
  4. package/plugins/graph/ViewTemplateBodyFilter/graph.tid +5 -0
  5. package/plugins/graph/ViewTemplateBodyFilter/properties.tid +5 -0
  6. package/plugins/graph/edges/fields/list.tid +7 -0
  7. package/plugins/graph/edges/fields/tags.tid +7 -0
  8. package/plugins/graph/edges/functions/links.tid +8 -0
  9. package/plugins/graph/edges/functions/transcludes.tid +8 -0
  10. package/plugins/graph/fieldtypes/filter.js +212 -0
  11. package/plugins/graph/fieldtypes/list.js +31 -0
  12. package/plugins/graph/fieldtypes/title.js +27 -0
  13. package/plugins/graph/filterrunprefixes/cache.js +118 -0
  14. package/plugins/graph/filters/gettyped.js +26 -0
  15. package/plugins/graph/graphengine.js +38 -0
  16. package/plugins/graph/icon.tid +16 -0
  17. package/plugins/graph/images/drag.tid +13 -0
  18. package/plugins/graph/macros/action.addedge.tid +16 -0
  19. package/plugins/graph/macros/edges.typed.tid +54 -0
  20. package/plugins/graph/macros/graph.view.tid +24 -0
  21. package/plugins/graph/macros/node.default.tid +9 -0
  22. package/plugins/graph/macros/nodes.neighbors.tid +62 -0
  23. package/plugins/graph/macros/nodes.writable.tid +37 -0
  24. package/plugins/graph/macros/properties.persistent.tid +27 -0
  25. package/plugins/graph/macros/properties.popup.tid +76 -0
  26. package/plugins/graph/macros/properties.river.tid +27 -0
  27. package/plugins/graph/macros/properties.settings.tid +56 -0
  28. package/plugins/graph/macros/properties.stack.tid +17 -0
  29. package/plugins/graph/macros/tiddlywiki.files +17 -0
  30. package/plugins/graph/plugin.info +14 -0
  31. package/plugins/graph/presettypes/edges/fields.tid +18 -0
  32. package/plugins/graph/presettypes/edges/functions.tid +5 -0
  33. package/plugins/graph/presettypes/nodes/stack.tid +6 -0
  34. package/plugins/graph/propertytypes/actions.js +15 -0
  35. package/plugins/graph/propertytypes/boolean.js +23 -0
  36. package/plugins/graph/propertytypes/enum.js +25 -0
  37. package/plugins/graph/propertytypes/image.js +140 -0
  38. package/plugins/graph/propertytypes/number.js +24 -0
  39. package/plugins/graph/propertytypes/string.js +13 -0
  40. package/plugins/graph/propertytypes/tiddlywiki.files +17 -0
  41. package/plugins/graph/readme.tid +5 -0
  42. package/plugins/graph/relink/attributes.js +52 -0
  43. package/plugins/graph/relink/attributes.multids +19 -0
  44. package/plugins/graph/relink/configprefix.js +76 -0
  45. package/plugins/graph/relink/fieldedgeprefix.js +39 -0
  46. package/plugins/graph/relink/fields.multids +11 -0
  47. package/plugins/graph/relink/graphprefix.js +28 -0
  48. package/plugins/graph/relink/operators.multids +3 -0
  49. package/plugins/graph/relink/propertyfields.js +81 -0
  50. package/plugins/graph/relink/utils.js +99 -0
  51. package/plugins/graph/settings.tid +13 -0
  52. package/plugins/graph/startup/messages.js +46 -0
  53. package/plugins/graph/stylesheets/base.css.tid +263 -0
  54. package/plugins/graph/stylesheets/fullscreen/core.css +11 -0
  55. package/plugins/graph/stylesheets/fullscreen/core.css.meta +3 -0
  56. package/plugins/graph/stylesheets/fullscreen.css.tid +46 -0
  57. package/plugins/graph/stylesheets/popup.css.tid +107 -0
  58. package/plugins/graph/subfilters.tid +23 -0
  59. package/plugins/graph/tags/GraphToolbar.tid +2 -0
  60. package/plugins/graph/tags/SettingsTab.tid +2 -0
  61. package/plugins/graph/tags/Template.tid +2 -0
  62. package/plugins/graph/tags/ViewEditTemplate.tid +2 -0
  63. package/plugins/graph/templates/live-graph.tid +34 -0
  64. package/plugins/graph/templates/standard-graph.tid +40 -0
  65. package/plugins/graph/ui/Buttons/center.tid +38 -0
  66. package/plugins/graph/ui/Buttons/export.tid +65 -0
  67. package/plugins/graph/ui/Buttons/fullscreen.tid +35 -0
  68. package/plugins/graph/ui/Buttons/settings.tid +28 -0
  69. package/plugins/graph/ui/Buttons/tiddlywiki.files +16 -0
  70. package/plugins/graph/ui/EditTemplate/Edges.tid +22 -0
  71. package/plugins/graph/ui/EditTemplate/Neighbors.tid +35 -0
  72. package/plugins/graph/ui/EditTemplate/Nodes.tid +12 -0
  73. package/plugins/graph/ui/EditTemplate/Popups.tid +27 -0
  74. package/plugins/graph/ui/EditTemplate/Properties.tid +21 -0
  75. package/plugins/graph/ui/EditTemplate/tiddlywiki.files +16 -0
  76. package/plugins/graph/ui/Modals/NewPropertySet.tid +20 -0
  77. package/plugins/graph/ui/Modals/NewView.tid +20 -0
  78. package/plugins/graph/ui/Modals/Select.tid +72 -0
  79. package/plugins/graph/ui/Modals/SelectField.tid +21 -0
  80. package/plugins/graph/ui/Modals/SelectTiddler.tid +15 -0
  81. package/plugins/graph/ui/Modals/Tiddler.tid +22 -0
  82. package/plugins/graph/ui/Modals/TiddlerHeader.tid +15 -0
  83. package/plugins/graph/ui/PropertyTypes/boolean.tid +11 -0
  84. package/plugins/graph/ui/PropertyTypes/color.tid +5 -0
  85. package/plugins/graph/ui/PropertyTypes/enum.tid +15 -0
  86. package/plugins/graph/ui/PropertyTypes/number.tid +17 -0
  87. package/plugins/graph/ui/Settings/Engine.tid +23 -0
  88. package/plugins/graph/ui/Settings/Graphs/EditTemplate.tid +52 -0
  89. package/plugins/graph/ui/Settings/Graphs.tid +49 -0
  90. package/plugins/graph/ui/Settings/Properties/ObjectsTypeTemplate.tid +44 -0
  91. package/plugins/graph/ui/Settings/Properties.tid +14 -0
  92. package/plugins/graph/ui/Settings/Toolbar.tid +5 -0
  93. package/plugins/graph/ui/SideBar/Graph.tid +77 -0
  94. package/plugins/graph/ui/Toolbars/GraphToolbar.tid +15 -0
  95. package/plugins/graph/ui/ViewTemplate/graph-object.tid +13 -0
  96. package/plugins/graph/ui/ViewTemplate/graph.tid +11 -0
  97. package/plugins/graph/ui/ViewTemplate/properties.tid +80 -0
  98. package/plugins/graph/ui/grouped-tabs.tid +109 -0
  99. package/plugins/graph/ui/selector.tid +74 -0
  100. package/plugins/graph/utils.js +148 -0
  101. package/plugins/graph/widgets/action-delay.js +72 -0
  102. package/plugins/graph/widgets/action-modal.js +121 -0
  103. package/plugins/graph/widgets/action-typed.js +56 -0
  104. package/plugins/graph/widgets/action-with.js +70 -0
  105. package/plugins/graph/widgets/boundingbox.js +126 -0
  106. package/plugins/graph/widgets/fieldTranscriber.js +98 -0
  107. package/plugins/graph/widgets/fieldtranscriber/filter.js +93 -0
  108. package/plugins/graph/widgets/fieldtranscriber/json.js +34 -0
  109. package/plugins/graph/widgets/fieldtranscriber/plain.js +11 -0
  110. package/plugins/graph/widgets/graphobject.js +120 -0
  111. package/plugins/graph/widgets/messagerelay.js +115 -0
  112. package/plugins/graph/widgets/properties.js +131 -0
  113. package/plugins/graph/widgets/subclass/edge.js +47 -0
  114. package/plugins/graph/widgets/subclass/graph.js +424 -0
  115. package/plugins/graph/widgets/subclass/node.js +44 -0
  116. package/plugins/graph/widgets/tiddlywiki.files +43 -0
@@ -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,13 @@
1
+ /*\
2
+
3
+ Defines behavior for string types in graph engine properties.
4
+
5
+ \*/
6
+
7
+ "use strict";
8
+
9
+ exports.name = "string";
10
+
11
+ exports.toProperty = function(info, value) {
12
+ return value || null;
13
+ };
@@ -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,3 @@
1
+ title: $:/config/flibbles/relink/operators/
2
+
3
+ gettyped: fieldname
@@ -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" />
@@ -0,0 +1,46 @@
1
+ /*\
2
+ title: $:/plugins/flibbles/graph/startup/messages.js
3
+ type: application/javascript
4
+ module-type: startup
5
+
6
+ Introduces some handling of custom messages that TW5-Graph needs.
7
+
8
+ DO NOT USE "tm-download-raw"! It's flimsy, poorly tested, and exists only
9
+ because there is no other way to download a binary file in Tiddlywiki.
10
+
11
+ As soon as I find a better way to do it, I'm deleting this file.
12
+
13
+ \*/
14
+
15
+ "use strict";
16
+
17
+ exports.name = "graph-messages";
18
+ exports.before = ["startup"];
19
+ exports.synchronous = true;
20
+
21
+ exports.startup = function() {
22
+ var CoreSaver = $tw.SaverHandler;
23
+ $tw.SaverHandler = function() {
24
+ CoreSaver.apply(this, arguments);
25
+ if ($tw.browser) {
26
+ var self = this;
27
+ $tw.rootWidget.addEventListener("tm-download-raw", function(event) {
28
+ return download(event, self);
29
+ });
30
+ }
31
+ }
32
+ $tw.SaverHandler.prototype = CoreSaver.prototype;
33
+ };
34
+
35
+ function download(event, saverHandler, variables) {
36
+ var title = event.param;
37
+ var wiki = event.widget.wiki;
38
+ var variables = event.paramObject;
39
+ const element = document.createElement("a");
40
+ var data = wiki.getTiddlerText(title);
41
+ element.setAttribute("download", variables.filename);
42
+ element.setAttribute("href", "data:" + variables.type + ";base64," + data);
43
+ var click = new MouseEvent("click");
44
+ element.dispatchEvent(click);
45
+ return true;
46
+ };