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,98 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Widget for transcribing the text of one data tiddler
|
|
4
|
+
into the field of another. and vice-versa.
|
|
5
|
+
|
|
6
|
+
\*/
|
|
7
|
+
|
|
8
|
+
"use strict";
|
|
9
|
+
|
|
10
|
+
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
|
11
|
+
|
|
12
|
+
var Scribers = $tw.modules.getModulesByTypeAsHashmap("fieldtranscribertype");
|
|
13
|
+
|
|
14
|
+
var ScriberWidget = function(parseTreeNode, options) {
|
|
15
|
+
this.initialise(parseTreeNode, options);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
ScriberWidget.prototype = new Widget();
|
|
19
|
+
|
|
20
|
+
ScriberWidget.prototype.render = function(parent, nextSibling) {
|
|
21
|
+
this.parentDomNode = parent;
|
|
22
|
+
this.computeAttributes();
|
|
23
|
+
this.execute();
|
|
24
|
+
this.renderChildren(parent, nextSibling);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
ScriberWidget.prototype.execute = function() {
|
|
28
|
+
this.scribeField = this.getAttribute("field");
|
|
29
|
+
this.scribeTiddler = this.getAttribute("tiddler") || (!this.hasParseTreeNodeAttribute("tiddler") && this.getVariable("currentTiddler"));
|
|
30
|
+
this.scribeType = this.getAttribute("type");
|
|
31
|
+
this.scribeState = this.getAttribute("state");
|
|
32
|
+
if (!this.scribeState) {
|
|
33
|
+
this.scribeState = "$:/temp/flibbles/graph/fieldtranscriber/" + encodeURIComponent(this.scribeField) + "/" + this.scribeTiddler;
|
|
34
|
+
}
|
|
35
|
+
if (!Scribers[this.scribeType]) {
|
|
36
|
+
this.scribeType = "text/plain";
|
|
37
|
+
}
|
|
38
|
+
this.setVariable("state", this.scribeState);
|
|
39
|
+
this.transcriber = Scribers[this.scribeType];
|
|
40
|
+
this.prepState();
|
|
41
|
+
this.makeChildWidgets();
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
ScriberWidget.prototype.refresh = function(changedTiddlers) {
|
|
45
|
+
var changedAttributes = this.computeAttributes();
|
|
46
|
+
if ($tw.utils.count(changedAttributes) > 0) {
|
|
47
|
+
this.refreshSelf();
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
if (changedTiddlers[this.scribeState] && this.scribeField) {
|
|
51
|
+
// Our tracked state has changed. Time to transcribe.
|
|
52
|
+
var state = this.wiki.getTiddler(this.scribeState);
|
|
53
|
+
if (state) {
|
|
54
|
+
var stateText = state.getFieldString("text");
|
|
55
|
+
if (this.stateText !== stateText) {
|
|
56
|
+
var fieldText = this.transcriber.toField(stateText);
|
|
57
|
+
if (fieldText !== this.fieldText) {
|
|
58
|
+
this.wiki.setText(this.scribeTiddler, this.scribeField, null, fieldText);
|
|
59
|
+
this.fieldText = fieldText;
|
|
60
|
+
this.stateText = stateText;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
this.wiki.setText(this.scribeTiddler, this.scribeField, null, undefined);
|
|
65
|
+
this.fieldText = undefined;
|
|
66
|
+
this.stateText = undefined;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (changedTiddlers[this.scribeTiddler]) {
|
|
70
|
+
this.prepState();
|
|
71
|
+
}
|
|
72
|
+
return this.refreshChildren(changedTiddlers);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
ScriberWidget.prototype.prepState = function() {
|
|
76
|
+
if (this.scribeState && this.scribeField) {
|
|
77
|
+
var tiddler = this.wiki.getTiddler(this.scribeTiddler);
|
|
78
|
+
if (tiddler) {
|
|
79
|
+
var fieldText = tiddler.fields[this.scribeField];
|
|
80
|
+
if (this.fieldText !== fieldText) {
|
|
81
|
+
this.fieldText = fieldText;
|
|
82
|
+
if (fieldText === undefined) {
|
|
83
|
+
this.wiki.deleteTiddler(this.scribeState);
|
|
84
|
+
this.stateText = undefined;
|
|
85
|
+
} else {
|
|
86
|
+
this.stateText = this.transcriber.fromField(fieldText);
|
|
87
|
+
this.wiki.addTiddler({
|
|
88
|
+
title: this.scribeState,
|
|
89
|
+
text: this.stateText,
|
|
90
|
+
type: this.scribeType
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
exports.fieldtranscriber = ScriberWidget;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Base-class widget that provides standard functionality for all "graph objects",
|
|
4
|
+
such as nodes or edges.
|
|
5
|
+
|
|
6
|
+
\*/
|
|
7
|
+
|
|
8
|
+
"use strict";
|
|
9
|
+
|
|
10
|
+
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
|
11
|
+
var utils = require("../utils.js");
|
|
12
|
+
|
|
13
|
+
var ObjectWidget = function(parseTreeNode, options) {};
|
|
14
|
+
|
|
15
|
+
ObjectWidget.prototype = new Widget();
|
|
16
|
+
|
|
17
|
+
// Graph object widgets are a type of property holder.
|
|
18
|
+
Object.assign(ObjectWidget.prototype, utils.PropertyHolder);
|
|
19
|
+
|
|
20
|
+
ObjectWidget.prototype.render = function(parent, nextSibling) {
|
|
21
|
+
this.parentDomNode = parent;
|
|
22
|
+
this.parentPropertiesWidget = utils.getParentProperties(this, this.graphObjectType);
|
|
23
|
+
this.computeAttributes();
|
|
24
|
+
this.execute();
|
|
25
|
+
this.computeParents();
|
|
26
|
+
this.renderChildren(parent, nextSibling);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
ObjectWidget.prototype.refresh = function(changedTiddlers) {
|
|
30
|
+
var changedAttributes = this.computeAttributes();
|
|
31
|
+
// Did our parents experience a change to their properties?
|
|
32
|
+
if (this.computeParents()
|
|
33
|
+
// Did our own property attribute change obviously?
|
|
34
|
+
|| $tw.utils.count(changedAttributes) > 0
|
|
35
|
+
// Were the properties cleared because they were stale?
|
|
36
|
+
|| !this.properties
|
|
37
|
+
// maybe properties changed covertly... (expensive)
|
|
38
|
+
|| this.refreshProperties(changedTiddlers)) {
|
|
39
|
+
this.execute();
|
|
40
|
+
// They'll need to be refreshed
|
|
41
|
+
this.properties = null;
|
|
42
|
+
}
|
|
43
|
+
// Then we give our children a chance to refresh too
|
|
44
|
+
return this.refreshChildren(changedTiddlers) || !this.properties;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
ObjectWidget.prototype.allowActionPropagation = function() {
|
|
48
|
+
return false;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/*
|
|
52
|
+
Can be overriden to allow object types to set properties based on rules
|
|
53
|
+
and behaviors specific to that typeA.
|
|
54
|
+
*/
|
|
55
|
+
ObjectWidget.prototype.setCustomProperties = function(properties, rules) {};
|
|
56
|
+
|
|
57
|
+
/*
|
|
58
|
+
This is an opportunity for a graphObject to evaluate itself in relation with
|
|
59
|
+
all other collected graph objects, as well as knowing its own relative index.
|
|
60
|
+
It can use this opportunity to flag itself as needing refreshing, or
|
|
61
|
+
return true to indicate it should be pruned away as an illegal object.
|
|
62
|
+
*/
|
|
63
|
+
ObjectWidget.prototype.curate = function(objects, index) { return false; };
|
|
64
|
+
|
|
65
|
+
/*
|
|
66
|
+
Calculates and stores the properties raw values in the object.
|
|
67
|
+
Then returns the evaluated property values to be used by the engine.
|
|
68
|
+
*/
|
|
69
|
+
ObjectWidget.prototype.calculatePropertyValues = function(rules) {
|
|
70
|
+
return this.evaluateProperties(this.computeProperties(rules), rules);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/*
|
|
74
|
+
Computes the properties for this object and returns them in an object.
|
|
75
|
+
*/
|
|
76
|
+
ObjectWidget.prototype.computeProperties = function(rules) {
|
|
77
|
+
var newProperties = Object.create(null);
|
|
78
|
+
// First, we set any auto-properties, so that anything else
|
|
79
|
+
// will have the opportunity to override them.
|
|
80
|
+
for (var name in rules) {
|
|
81
|
+
var property = rules[name];
|
|
82
|
+
// It's flagged to always be sent to the engine.
|
|
83
|
+
// Send along the default value. It may be overridden momentarily.
|
|
84
|
+
if (property.always) {
|
|
85
|
+
newProperties[name] = property.default;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Then we travel down and set properties based on containing
|
|
89
|
+
// $property widgets.
|
|
90
|
+
for (var i = this.applicableParents.length-1; i >= 0; i--) {
|
|
91
|
+
var widget = this.applicableParents[i];
|
|
92
|
+
for (var property in widget.properties) {
|
|
93
|
+
newProperties[property] = widget.properties[property];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Then object types get a chance to set properties based on
|
|
97
|
+
// their own unique rules.
|
|
98
|
+
this.setCustomProperties(newProperties, rules);
|
|
99
|
+
// Then we set properties based on explicit attributes
|
|
100
|
+
// on this object. These take highest priority.
|
|
101
|
+
for (var key in this.attributes) {
|
|
102
|
+
if (key.charAt(0) !== "$") {
|
|
103
|
+
var value = this.attributes[key];
|
|
104
|
+
if (value) {
|
|
105
|
+
newProperties[key] = this.attributes[key];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return newProperties;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
ObjectWidget.prototype.catchGraphEvent = function(graphEvent, triggeringWidget, variables) {
|
|
113
|
+
var actions = this.attributes[graphEvent.type];
|
|
114
|
+
if (actions) {
|
|
115
|
+
triggeringWidget.invokeActionString(actions, triggeringWidget, graphEvent.event, variables);
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
ObjectWidget.prototype.computeParents = function() {
|
|
122
|
+
var index = 0;
|
|
123
|
+
var changed = false;
|
|
124
|
+
var list = this.applicableParents = this.applicableParents || [];
|
|
125
|
+
this.traversePropertyWidgets(function(widget) {
|
|
126
|
+
if (list[index] !== widget) {
|
|
127
|
+
list[index] = widget;
|
|
128
|
+
changed = true;
|
|
129
|
+
} else if (widget.propertiesChanged) {
|
|
130
|
+
changed = true;
|
|
131
|
+
}
|
|
132
|
+
index++;
|
|
133
|
+
});
|
|
134
|
+
if (index !== list.length) {
|
|
135
|
+
list.length = index;
|
|
136
|
+
changed = true;
|
|
137
|
+
}
|
|
138
|
+
return changed;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Explore for any $properties which might apply to this. Can be overridden.
|
|
143
|
+
*/
|
|
144
|
+
ObjectWidget.prototype.traversePropertyWidgets = function(method) {
|
|
145
|
+
var widget = this.parentPropertiesWidget;
|
|
146
|
+
while (widget !== null) {
|
|
147
|
+
if (widget.filterFunc([this.id], widget).length > 0) {
|
|
148
|
+
method(widget);
|
|
149
|
+
}
|
|
150
|
+
widget = widget.parentPropertiesWidget;
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
exports.graphobject = ObjectWidget;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Widget for relaying emitted messages to other parts of the widget.
|
|
4
|
+
This allows buttons for a graph to exist outside of that graph.
|
|
5
|
+
|
|
6
|
+
\*/
|
|
7
|
+
|
|
8
|
+
"use strict";
|
|
9
|
+
|
|
10
|
+
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
|
11
|
+
var utils = require("../utils.js");
|
|
12
|
+
|
|
13
|
+
// Relayed is used to avoid infinite loops. Once an event is relayed,
|
|
14
|
+
// it puts itself in this object under the relay name, so it can't be
|
|
15
|
+
// relayed again through that name
|
|
16
|
+
var relayed = Object.create(null);
|
|
17
|
+
|
|
18
|
+
var RelayWidget = function(parseTreeNode, options) {
|
|
19
|
+
this.initialise(parseTreeNode, options);
|
|
20
|
+
utils.registerForGarbageCollection(this);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
RelayWidget.prototype = new Widget();
|
|
24
|
+
|
|
25
|
+
RelayWidget.prototype.render = function(parent, nextSibling) {
|
|
26
|
+
this.parentDomNode = parent;
|
|
27
|
+
this.computeAttributes();
|
|
28
|
+
this.execute();
|
|
29
|
+
this.renderChildren(parent, nextSibling);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
RelayWidget.prototype.execute = function() {
|
|
33
|
+
this.relayName = this.getAttribute("name");
|
|
34
|
+
this.relayTo = this.getAttribute("to");
|
|
35
|
+
if (this.relayName) {
|
|
36
|
+
var register = this.wiki.relayRegister = this.wiki.relayRegister || Object.create(null);
|
|
37
|
+
register[this.relayName] = register[this.relayName] || [];
|
|
38
|
+
register[this.relayName].push(this);
|
|
39
|
+
}
|
|
40
|
+
this.makeChildWidgets();
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
RelayWidget.prototype.refresh = function(changedTiddlers) {
|
|
44
|
+
var changedAttributes = this.computeAttributes();
|
|
45
|
+
var changed = false;
|
|
46
|
+
if (changedAttributes.name) {
|
|
47
|
+
this.garbageCollect();
|
|
48
|
+
this.refreshSelf();
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
if (changedAttributes.to) {
|
|
52
|
+
this.relayTo = this.getAttribute("to");
|
|
53
|
+
changed = true;
|
|
54
|
+
}
|
|
55
|
+
return this.refreshChildren(changedTiddlers) || changed;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
RelayWidget.prototype.dispatchEvent = function(event) {
|
|
59
|
+
var register = this.wiki.relayRegister;
|
|
60
|
+
if (this.relayTo
|
|
61
|
+
&& register
|
|
62
|
+
&& register[this.relayTo]
|
|
63
|
+
&& relayed[this.relayTo] !== event) {
|
|
64
|
+
relayed[this.relayTo] = event;
|
|
65
|
+
var targets = register[this.relayTo];
|
|
66
|
+
for (var i = 0; i < targets.length; i++) {
|
|
67
|
+
var target = targets[i];
|
|
68
|
+
if (!target.isGarbage()) {
|
|
69
|
+
targets[i].dispatchEvent(event);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
return Widget.prototype.dispatchEvent.call(this, event);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
RelayWidget.prototype.isGarbage = function() {
|
|
78
|
+
var root = rootWidget(this);
|
|
79
|
+
return root !== $tw.rootWidget;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
RelayWidget.prototype.garbageCollect = function() {
|
|
83
|
+
if (this.relayName) {
|
|
84
|
+
var register = this.wiki.relayRegister[this.relayName];
|
|
85
|
+
for (var i = 0; i < register.length; i++) {
|
|
86
|
+
if (register[i] === this) {
|
|
87
|
+
// Remove this from the register
|
|
88
|
+
register.splice(i, 1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
this.relayName = undefined;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
function rootWidget(relay) {
|
|
96
|
+
var parent = relay.parentWidget;
|
|
97
|
+
while (parent) {
|
|
98
|
+
var i = 0;
|
|
99
|
+
for (; i < parent.children.length; i++) {
|
|
100
|
+
if (parent.children[i] === relay) {
|
|
101
|
+
// Confirmed that the parent still owns this child
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (i == parent.children.length) {
|
|
106
|
+
// Ownership was not confirmed
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
relay = parent;
|
|
110
|
+
parent = relay.parentWidget;
|
|
111
|
+
}
|
|
112
|
+
return relay;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
exports.messagerelay = RelayWidget;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Widget for setting properties on graph objects.
|
|
4
|
+
|
|
5
|
+
\*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
|
10
|
+
var utils = require("../utils.js");
|
|
11
|
+
var Engines = $tw.modules.getModulesByTypeAsHashmap("graphengine");
|
|
12
|
+
var PropertyTypes = $tw.modules.getModulesByTypeAsHashmap("graphpropertytype");
|
|
13
|
+
|
|
14
|
+
var Properties = function(parseTreeNode, options) {
|
|
15
|
+
this.initialise(parseTreeNode, options);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
Properties.prototype = new Widget();
|
|
19
|
+
|
|
20
|
+
Properties.prototype.graphPropertiesWidget = true;
|
|
21
|
+
|
|
22
|
+
Properties.prototype.render = function(parent, nextSibling) {
|
|
23
|
+
this.parentDomNode = parent;
|
|
24
|
+
this.computeAttributes();
|
|
25
|
+
this.execute();
|
|
26
|
+
this.renderChildren(parent, nextSibling);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
Properties.prototype.execute = function() {
|
|
30
|
+
this.type = this.getAttribute("$for", "nodes");
|
|
31
|
+
this.parentPropertiesWidget = utils.getParentProperties(this, this.type);
|
|
32
|
+
this.filter = this.getAttribute("$filter");
|
|
33
|
+
this.properties = this.getProperties();
|
|
34
|
+
this.filterFunc = this.filter? this.wiki.compileFilter(this.filter): function(source) { return source; };
|
|
35
|
+
this.makeChildWidgets();
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
Properties.prototype.refresh = function(changedTiddlers) {
|
|
39
|
+
var changedAttributes = this.computeAttributes();
|
|
40
|
+
this.propertiesChanged = false;
|
|
41
|
+
if (changedAttributes["$for"]) {
|
|
42
|
+
// If the $for changed, we need to refocus to the different object type.
|
|
43
|
+
this.refreshSelf();
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
if (propertiesChanged(changedAttributes)
|
|
47
|
+
|| changedAttributes["$tiddler"]
|
|
48
|
+
|| changedAttributes["$field"]
|
|
49
|
+
|| (this.dataTiddler
|
|
50
|
+
&& changedTiddlers[this.dataTiddler]
|
|
51
|
+
&& this.rawData !== getTiddlerString(this.wiki, this.dataTiddler, this.field))) {
|
|
52
|
+
// Our styling attributes have changed, so everything this $style
|
|
53
|
+
// affects needs to refresh.
|
|
54
|
+
this.properties = this.getProperties();
|
|
55
|
+
this.propertiesChanged = true;
|
|
56
|
+
}
|
|
57
|
+
// If we have a filterFunc, we need to worry about whether this style
|
|
58
|
+
// applies to a different subset of its children objects or not.
|
|
59
|
+
if (changedAttributes["$filter"]) {
|
|
60
|
+
this.filter = this.getAttribute("$filter");
|
|
61
|
+
this.filterFunc = this.filter? this.wiki.compileFilter(this.filter): function(source) { return source; };
|
|
62
|
+
}
|
|
63
|
+
return this.refreshChildren(changedTiddlers) || this.propertiesChanged;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
Properties.prototype.getProperties = function() {
|
|
67
|
+
this.field = this.getAttribute("$field");
|
|
68
|
+
this.dataTiddler = this.getAttribute("$tiddler");
|
|
69
|
+
if (!this.dataTiddler && this.field) {
|
|
70
|
+
this.dataTiddler = this.getVariable("currentTiddler");
|
|
71
|
+
}
|
|
72
|
+
var styleObject = Object.create(null);
|
|
73
|
+
if (this.dataTiddler) {
|
|
74
|
+
var data;
|
|
75
|
+
// We recall the actual raw data string so
|
|
76
|
+
// we can see whether it changes later on.
|
|
77
|
+
this.rawData = getTiddlerString(this.wiki, this.dataTiddler, this.field);
|
|
78
|
+
if (!this.field || this.field === "text") {
|
|
79
|
+
data = this.wiki.getTiddlerData(this.dataTiddler);
|
|
80
|
+
} else {
|
|
81
|
+
try {
|
|
82
|
+
data = this.rawData? JSON.parse(this.rawData): {};
|
|
83
|
+
} catch {
|
|
84
|
+
data = {};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
for (var entry in data) {
|
|
88
|
+
var datum = data[entry];
|
|
89
|
+
// We only accept non-empty values
|
|
90
|
+
if (datum && typeof datum === "string") {
|
|
91
|
+
styleObject[entry] = datum;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
for (var name in this.attributes) {
|
|
96
|
+
if (name.charAt(0) !== '$' && this.attributes[name]) {
|
|
97
|
+
styleObject[name] = this.attributes[name];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return styleObject;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
function getTiddlerString(wiki, title, field) {
|
|
104
|
+
var tiddler = wiki.getTiddler(title);
|
|
105
|
+
return tiddler && tiddler.getFieldString(field || "text");
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
Properties.prototype.catchGraphEvent = function(graphEvent, target, variables) {
|
|
109
|
+
if (graphEvent.objectType === this.type
|
|
110
|
+
&& this.filterFunc([target.id], this).length > 0) {
|
|
111
|
+
var actions = this.properties[graphEvent.type];
|
|
112
|
+
if (actions) {
|
|
113
|
+
variables.targetTiddler = graphEvent.id;
|
|
114
|
+
this.invokeActionString(actions, this, graphEvent.event, variables);
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
function propertiesChanged(changedAttributes) {
|
|
122
|
+
for (var name in changedAttributes) {
|
|
123
|
+
if (name.charAt(0) !== "$") {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return false;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
exports.properties = Properties;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Widget for creating edges within graphs.
|
|
4
|
+
|
|
5
|
+
\*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
var nextId = 1;
|
|
10
|
+
|
|
11
|
+
exports.baseClass = "graphobject";
|
|
12
|
+
exports.name = "edge";
|
|
13
|
+
// These are object properties that will get added to the variable context
|
|
14
|
+
// when action strings are invoked.
|
|
15
|
+
exports.actionContext = ["id", "fromTiddler", "toTiddler"];
|
|
16
|
+
|
|
17
|
+
exports.constructor = function(parseTreeNode, options) {
|
|
18
|
+
this.initialise(parseTreeNode, options);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
var EdgeWidget = exports.prototype = {};
|
|
22
|
+
|
|
23
|
+
EdgeWidget.graphObjectType = "edges";
|
|
24
|
+
|
|
25
|
+
EdgeWidget.execute = function() {
|
|
26
|
+
this.id = this.getAttribute("$id");
|
|
27
|
+
if (!this.id) {
|
|
28
|
+
// We do this instead of using getAttribute's default arg
|
|
29
|
+
// so we don't increment unecessarily, and maybe reuse
|
|
30
|
+
// the same auto-id if this edge refreshes Self. This'll give better
|
|
31
|
+
// results when updating the graph. It's a CHANGED edge, not a new one.
|
|
32
|
+
this.counter = this.counter || nextId++;
|
|
33
|
+
this.id = "$:/edge/" + this.counter;
|
|
34
|
+
}
|
|
35
|
+
this.fromTiddler = this.getAttribute("$from", this.getVariable("currentTiddler"));
|
|
36
|
+
this.toTiddler = this.getAttribute("$to", this.getVariable("toTiddler"));
|
|
37
|
+
this.makeChildWidgets();
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
EdgeWidget.setCustomProperties = function(properties) {
|
|
41
|
+
if (this.fromTiddler) {
|
|
42
|
+
properties.from = this.fromTiddler;
|
|
43
|
+
}
|
|
44
|
+
if (this.toTiddler) {
|
|
45
|
+
properties.to = this.toTiddler;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
EdgeWidget.curate = function(objects) {
|
|
50
|
+
// Edges are not legal if there aren't corresponding nodes for its
|
|
51
|
+
// to and from.
|
|
52
|
+
return !objects.nodes
|
|
53
|
+
|| !objects.nodes[this.fromTiddler]
|
|
54
|
+
|| !objects.nodes[this.toTiddler];
|
|
55
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Specialized form of <$edit-text/> which handles displaying palette colors,
|
|
4
|
+
if that's what its underlying value specifies.
|
|
5
|
+
|
|
6
|
+
\*/
|
|
7
|
+
|
|
8
|
+
exports.baseClass = "edit-text";
|
|
9
|
+
exports.name = "edit-color";
|
|
10
|
+
|
|
11
|
+
var ColorType = require("../../propertytypes/color.js");
|
|
12
|
+
|
|
13
|
+
exports.constructor = function(parseTreeNode, options) {
|
|
14
|
+
this.initialise(parseTreeNode, options);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
var EditWidget = exports.prototype = {};
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
We expand on getEditInfo to evaluate any potential palette colors and adust
|
|
21
|
+
the info accordingly.
|
|
22
|
+
*/
|
|
23
|
+
EditWidget.getEditInfo = function() {
|
|
24
|
+
var info = Object.getPrototypeOf(Object.getPrototypeOf(this)).getEditInfo.call(this);
|
|
25
|
+
this._rawColor = info.value;
|
|
26
|
+
if (info.value) {
|
|
27
|
+
info.value = ColorType.toProperty(null, info.value, {widget: this}) || info.value;
|
|
28
|
+
}
|
|
29
|
+
return info;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
We hard-code this widget to be a color input.
|
|
34
|
+
*/
|
|
35
|
+
EditWidget.execute = function() {
|
|
36
|
+
Object.getPrototypeOf(Object.getPrototypeOf(this)).execute.call(this);
|
|
37
|
+
this.editType = "color";
|
|
38
|
+
this.editTag = "input";
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
We elaborate refresh to also check if the palette has changed.
|
|
43
|
+
*/
|
|
44
|
+
EditWidget.refresh = function(changedTiddlers) {
|
|
45
|
+
if (Object.getPrototypeOf(Object.getPrototypeOf(this)).refresh.call(this, changedTiddlers)) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
if (ColorType.refresh(null, this._rawColor, changedTiddlers, this)) {
|
|
49
|
+
var editInfo = this.getEditInfo();
|
|
50
|
+
this.updateEditor(editInfo.value, editInfo.type);
|
|
51
|
+
}
|
|
52
|
+
};
|