@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.
- 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 +56 -0
- package/plugins/graph/macros/properties.stack.tid +17 -0
- package/plugins/graph/macros/tiddlywiki.files +17 -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/stack.tid +6 -0
- package/plugins/graph/propertytypes/actions.js +15 -0
- package/plugins/graph/propertytypes/boolean.js +23 -0
- package/plugins/graph/propertytypes/enum.js +25 -0
- package/plugins/graph/propertytypes/image.js +140 -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 +263 -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 +46 -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 +5 -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 +44 -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.js +148 -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.js +98 -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/graphobject.js +120 -0
- package/plugins/graph/widgets/messagerelay.js +115 -0
- package/plugins/graph/widgets/properties.js +131 -0
- package/plugins/graph/widgets/subclass/edge.js +47 -0
- package/plugins/graph/widgets/subclass/graph.js +424 -0
- package/plugins/graph/widgets/subclass/node.js +44 -0
- package/plugins/graph/widgets/tiddlywiki.files +43 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Action widget that creates a modal to select an existing tiddler, or specify a new one. After dialog is confirmed, it will execute any nested actions it contains.
|
|
4
|
+
|
|
5
|
+
\*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
|
10
|
+
var utils = require("../utils.js");
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* This points to whatever action invoked the current modal. It assumes that
|
|
14
|
+
* only one modal is possible at a time. Probably a safe assumption.
|
|
15
|
+
*/
|
|
16
|
+
var primedWidget;
|
|
17
|
+
|
|
18
|
+
var ModalWidget = function(parseTreeNode, options) {
|
|
19
|
+
this.initialise(parseTreeNode, options);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
ModalWidget.prototype = new Widget();
|
|
23
|
+
|
|
24
|
+
ModalWidget.prototype.render = function(parent, nextSibling) {
|
|
25
|
+
this.parentDomNode = parent;
|
|
26
|
+
this.computeAttributes();
|
|
27
|
+
this.execute();
|
|
28
|
+
this.renderChildren(parent, nextSibling);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
ModalWidget.prototype.execute = function() {
|
|
32
|
+
this.modalTiddler = this.getAttribute("$tiddler");
|
|
33
|
+
this.modal = $tw.modal;
|
|
34
|
+
if (!this.modal || this.modal.wiki !== this.wiki) {
|
|
35
|
+
// Ah, we have a modal working with a subwiki (or a Node.JS system
|
|
36
|
+
// which has no modal). We'll create an overlay of the modal
|
|
37
|
+
// that works with our subwiki instead.
|
|
38
|
+
this.modal = Object.create($tw.modal || null);
|
|
39
|
+
this.modal.wiki = this.wiki;
|
|
40
|
+
}
|
|
41
|
+
this.makeChildWidgets();
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
ModalWidget.prototype.refresh = function(changedTiddlers) {
|
|
45
|
+
var changedAttributes = this.computeAttributes();
|
|
46
|
+
if ($tw.utils.count(changedAttributes) > 0) {
|
|
47
|
+
this.refreshSelf();
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return this.refreshChildren(changedTiddlers);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
ModalWidget.prototype.invokeAction = function(triggeringWidget, event) {
|
|
54
|
+
if (!$tw.rootWidget.eventListeners['tm-modal-finish']) {
|
|
55
|
+
$tw.rootWidget.addEventListener("tm-modal-finish", function(finishEvent) {
|
|
56
|
+
if (primedWidget) {
|
|
57
|
+
var value = finishEvent.param;
|
|
58
|
+
primedWidget.setVariable("selection", value);
|
|
59
|
+
primedWidget.refreshChildren();
|
|
60
|
+
primedWidget.invokeActions(primedWidget, event);
|
|
61
|
+
primedWidget = undefined;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
primedWidget = this;
|
|
66
|
+
var variables = Object.create(null);
|
|
67
|
+
for (var key in this.attributes) {
|
|
68
|
+
if (key.charAt(0) !== "$") {
|
|
69
|
+
variables[key] = this.attributes[key];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (this.modalTiddler) {
|
|
73
|
+
var self = this;
|
|
74
|
+
// We need to delay the assignment of click handlers for a few
|
|
75
|
+
// milliseconds. See Issue #43. If we don't, a click event might
|
|
76
|
+
// follow right after the "make modal" which closes the modal
|
|
77
|
+
// immediately.
|
|
78
|
+
delayEventListenerAssignment(function() {
|
|
79
|
+
self.modal.display(self.modalTiddler, {
|
|
80
|
+
variables: variables,
|
|
81
|
+
event: event});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
ModalWidget.prototype.allowActionPropagation = function() {
|
|
88
|
+
return false;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
function delayEventListenerAssignment(method) {
|
|
92
|
+
var assignments = [];
|
|
93
|
+
// We use this requested window instead of just accessing directly
|
|
94
|
+
// so that the test framework can mock it up.
|
|
95
|
+
var window = utils.window();
|
|
96
|
+
var oldListener = window.EventTarget.prototype.addEventListener;
|
|
97
|
+
window.EventTarget.prototype.addEventListener = function(type) {
|
|
98
|
+
var args = Array.prototype.slice.call(arguments);
|
|
99
|
+
if (type === "click") {
|
|
100
|
+
// This is the click which might accidentally apply to the
|
|
101
|
+
// backdrop if we're on mobile. Delay it.
|
|
102
|
+
assignments.push({self: this, args: args});
|
|
103
|
+
} else {
|
|
104
|
+
// Just call through. We don't care about this handler.
|
|
105
|
+
oldListener.apply(this, args);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
try {
|
|
109
|
+
method();
|
|
110
|
+
} finally {
|
|
111
|
+
window.EventTarget.prototype.addEventListener = oldListener;
|
|
112
|
+
}
|
|
113
|
+
setTimeout(function() {
|
|
114
|
+
for (var i = 0; i < assignments.length; i++) {
|
|
115
|
+
var set = assignments[i];
|
|
116
|
+
set.self.addEventListener.apply(set.self, set.args);
|
|
117
|
+
}
|
|
118
|
+
}, 10);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
exports["action-modal"] = ModalWidget;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Creates two action widgets for adding and removing from typed fields.
|
|
4
|
+
|
|
5
|
+
\*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
|
10
|
+
var typeOperators = $tw.modules.getModulesByTypeAsHashmap("fieldtype");
|
|
11
|
+
var relinkPrefix = "$:/config/flibbles/relink/fields/" ;
|
|
12
|
+
|
|
13
|
+
var TypedWidget = new Widget();
|
|
14
|
+
|
|
15
|
+
TypedWidget.render = function(parent, nextSibling) {
|
|
16
|
+
this.computeAttributes();
|
|
17
|
+
this.execute();
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
TypedWidget.execute = function() {
|
|
21
|
+
this.actionTiddler = this.getAttribute("$tiddler") || (!this.hasParseTreeNodeAttribute("$tiddler") && this.getVariable("currentTiddler"));
|
|
22
|
+
this.actionField = this.getAttribute("$field");
|
|
23
|
+
this.actionValue = this.getAttribute("$value");
|
|
24
|
+
this.actionTimestamp = this.getAttribute("$timestamp","yes") === "yes";
|
|
25
|
+
this.actionClean = this.getAttribute("$clean","yes") === "yes";
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
TypedWidget.invokeAction = function(triggeringWidget, event) {
|
|
29
|
+
var tiddler = this.wiki.getTiddler(this.actionTiddler),
|
|
30
|
+
hasChanged = false,
|
|
31
|
+
options = {wiki: this.wiki, widget: this};
|
|
32
|
+
if (this.actionTiddler && this.actionField) {
|
|
33
|
+
options.suppressTimestamp = !this.actionTimestamp;
|
|
34
|
+
var typeName = this.wiki.getTiddlerText(relinkPrefix + this.actionField, "list");
|
|
35
|
+
var type = typeOperators[typeName];
|
|
36
|
+
if (type) {
|
|
37
|
+
var newValue = type[this.actionMethod](tiddler, this.actionField, this.actionValue, options);
|
|
38
|
+
if (newValue !== undefined) {
|
|
39
|
+
if (newValue === "" && this.actionClean) {
|
|
40
|
+
newValue = undefined;
|
|
41
|
+
}
|
|
42
|
+
options.wiki.setText(this.actionTiddler, this.actionField, null, newValue, options);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
$tw.utils.each(["add", "remove"], function(method) {
|
|
49
|
+
var MethodWidget = function(parseTreeNode, options) {
|
|
50
|
+
this.initialise(parseTreeNode, options);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
MethodWidget.prototype = Object.create(TypedWidget);
|
|
54
|
+
MethodWidget.prototype.actionMethod = method;
|
|
55
|
+
exports["action-" + method + "typed"] = MethodWidget;
|
|
56
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Action widget that executes actions within it while exposing variables representing the mouse's current location.
|
|
4
|
+
|
|
5
|
+
\*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
|
10
|
+
|
|
11
|
+
var WithWidget = function(parseTreeNode, options) {
|
|
12
|
+
this.initialise(parseTreeNode, options);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
WithWidget.prototype = new Widget();
|
|
16
|
+
|
|
17
|
+
WithWidget.prototype.render = function(parent, nextSibling) {
|
|
18
|
+
this.parentDomNode = parent;
|
|
19
|
+
this.computeAttributes();
|
|
20
|
+
this.execute();
|
|
21
|
+
this.renderChildren(parent, nextSibling);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
WithWidget.prototype.execute = function() {
|
|
25
|
+
this.withOffset = this.getAttribute("$offset");
|
|
26
|
+
this.withCanvas = this.getAttribute("$canvas");
|
|
27
|
+
this.makeChildWidgets();
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
WithWidget.prototype.refresh = function(changedTiddlers) {
|
|
31
|
+
var changedAttributes = this.computeAttributes();
|
|
32
|
+
for (var attribute in changedAttributes) {
|
|
33
|
+
this.refreshSelf();
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
return this.refreshChildren(changedTiddlers);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
WithWidget.prototype.invokeAction = function(triggeringWidget, event) {
|
|
40
|
+
var graph = getGraphWidget(this);
|
|
41
|
+
if (graph) {
|
|
42
|
+
if (this.withOffset) {
|
|
43
|
+
var mouse = graph.mouse,
|
|
44
|
+
x = mouse.x.toString(),
|
|
45
|
+
y = mouse.y.toString();
|
|
46
|
+
this.setVariable(this.withOffset + "-x", x);
|
|
47
|
+
this.setVariable(this.withOffset + "-y", y);
|
|
48
|
+
}
|
|
49
|
+
if (this.withCanvas) {
|
|
50
|
+
var element = graph.graphElement;
|
|
51
|
+
this.setVariable(this.withCanvas + "-width", element.offsetWidth);
|
|
52
|
+
this.setVariable(this.withCanvas + "-height", element.offsetHeight);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
this.refreshChildren();
|
|
56
|
+
return true;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
function getGraphWidget(self) {
|
|
60
|
+
var widget = self.parentWidget;
|
|
61
|
+
while (widget) {
|
|
62
|
+
if (widget.graphObjectType === "graph") {
|
|
63
|
+
return widget;
|
|
64
|
+
}
|
|
65
|
+
widget = widget.parentWidget;
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
exports["action-with"] = WithWidget;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Widget for creating a DOM element which has strictly controlled dimensions,
|
|
4
|
+
intended for a contained 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
|
+
var BoxWidget = function(parseTreeNode, options) {
|
|
14
|
+
this.initialise(parseTreeNode, options);
|
|
15
|
+
utils.registerForGarbageCollection(this);
|
|
16
|
+
this.resizeInstance = this.resize.bind(this);
|
|
17
|
+
this.window = utils.window();
|
|
18
|
+
this.window.addEventListener("resize", this.resizeInstance);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Inherit from the base widget class
|
|
23
|
+
*/
|
|
24
|
+
BoxWidget.prototype = new Widget();
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Render this widget into the DOM
|
|
28
|
+
*/
|
|
29
|
+
BoxWidget.prototype.render = function(parent, nextSibling) {
|
|
30
|
+
this.parentDomNode = parent;
|
|
31
|
+
this.computeAttributes();
|
|
32
|
+
this.execute();
|
|
33
|
+
this.domNode = this.document.createElement("div");
|
|
34
|
+
this.domNode.className = this.boxClass;
|
|
35
|
+
parent.insertBefore(this.domNode, nextSibling);
|
|
36
|
+
// Make sure this comes AFTER inserting domNode into the tree,
|
|
37
|
+
// otherwise getBoundingClientRect() will be all zeros.
|
|
38
|
+
this.resize();
|
|
39
|
+
this.renderChildren(this.domNode, null);
|
|
40
|
+
this.domNodes.push(this.domNode);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Compute the internal state of the widget
|
|
45
|
+
*/
|
|
46
|
+
BoxWidget.prototype.execute = function() {
|
|
47
|
+
this.executeClass();
|
|
48
|
+
this.executeDimensions();
|
|
49
|
+
this.makeChildWidgets();
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
BoxWidget.prototype.executeDimensions = function() {
|
|
53
|
+
var self = this;
|
|
54
|
+
this.widthFilter = this.wiki.compileFilter(this.getAttribute("width", ""));
|
|
55
|
+
this.heightFilter = this.wiki.compileFilter(this.getAttribute("height", ""));
|
|
56
|
+
// We set up the widget so it only gets values for these variables
|
|
57
|
+
// if needed. This keeps down unncessary calls to window and document,
|
|
58
|
+
// and makes the $graph widget usable on Node, if that ever comes up.
|
|
59
|
+
var variableMethods = {
|
|
60
|
+
// It may be better to use document.body.clientWidth,
|
|
61
|
+
// which doesn't consider the scrollbar.
|
|
62
|
+
windowWidth: function() { return self.window.innerWidth.toString(); },
|
|
63
|
+
windowHeight: function() { return self.window.innerHeight.toString(); },
|
|
64
|
+
boundingLeft: function() { return self.domNode.getBoundingClientRect().left.toString(); },
|
|
65
|
+
boundingTop: function() { return self.domNode.getBoundingClientRect().top.toString(); },
|
|
66
|
+
};
|
|
67
|
+
var variables = {};
|
|
68
|
+
for (var name in variableMethods) {
|
|
69
|
+
Object.defineProperty(variables, name, { get: variableMethods[name] });
|
|
70
|
+
}
|
|
71
|
+
this.dimensionWidget = this.makeFakeWidgetWithVariables(variables);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Selectively refreshes the widget if needed.
|
|
76
|
+
* Returns true if the widget or any of its children needed re-rendering
|
|
77
|
+
*/
|
|
78
|
+
BoxWidget.prototype.refresh = function(changedTiddlers) {
|
|
79
|
+
var changedAttributes = this.computeAttributes();
|
|
80
|
+
var changed = false;
|
|
81
|
+
if (changedAttributes["class"]) {
|
|
82
|
+
this.executeClass();
|
|
83
|
+
this.domNode.className = this.boxClass;
|
|
84
|
+
changed = true;
|
|
85
|
+
}
|
|
86
|
+
if ($tw.utils.count(changedAttributes) > 0) {
|
|
87
|
+
this.executeDimensions();
|
|
88
|
+
changed = true;
|
|
89
|
+
}
|
|
90
|
+
// We always try to resize.
|
|
91
|
+
// The $dimension filters might spit out something different.
|
|
92
|
+
this.resize();
|
|
93
|
+
return this.refreshChildren(changedTiddlers) || changed;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
BoxWidget.prototype.executeClass = function() {
|
|
97
|
+
var nodeClass = "boundingbox";
|
|
98
|
+
var extraClasses = this.getAttribute("class", "");
|
|
99
|
+
if (extraClasses) {
|
|
100
|
+
nodeClass += " " + extraClasses;
|
|
101
|
+
}
|
|
102
|
+
this.boxClass = nodeClass;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
BoxWidget.prototype.resize = function(event) {
|
|
106
|
+
var newWidth = this.widthFilter(null, this.dimensionWidget)[0] || "";
|
|
107
|
+
var newHeight = this.heightFilter(null, this.dimensionWidget)[0] || "";
|
|
108
|
+
var style = this.domNode.style;
|
|
109
|
+
if (newWidth !== style.width) {
|
|
110
|
+
style.width = newWidth;
|
|
111
|
+
}
|
|
112
|
+
if (newHeight !== style.height) {
|
|
113
|
+
style.height = newHeight;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
BoxWidget.prototype.garbageCollect = function() {
|
|
118
|
+
this.window.removeEventListener("resize", this.resizeInstance);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
BoxWidget.prototype.isGarbage = function() {
|
|
122
|
+
var body = this.document.body;
|
|
123
|
+
return !body || !body.contains(this.domNode);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
exports.boundingbox = BoxWidget;
|
|
@@ -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,93 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Type for transcribing application/x-tiddler-filter between text and field.
|
|
4
|
+
|
|
5
|
+
Changes \n into " " between runs to mitigate the need for multilines.
|
|
6
|
+
However, it's impossible to guarantee a single line filter if newlines are
|
|
7
|
+
used in operands.
|
|
8
|
+
|
|
9
|
+
\*/
|
|
10
|
+
|
|
11
|
+
"use strict";
|
|
12
|
+
|
|
13
|
+
exports.name = "application/x-tiddler-filter";
|
|
14
|
+
|
|
15
|
+
exports.toField = function(text) {
|
|
16
|
+
return filterWhitespaceWalk(text, function(start, end) {
|
|
17
|
+
var substr = text.substring(start, end);
|
|
18
|
+
var change = substr.replaceAll("\n", " ");
|
|
19
|
+
return substr !== change ? change: null;
|
|
20
|
+
}).trim();
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
exports.fromField = function(text) {
|
|
24
|
+
return filterWhitespaceWalk(text, function(start, end) {
|
|
25
|
+
var substr = text.substring(start, end);
|
|
26
|
+
var change = substr.replaceAll(" ", "\n");
|
|
27
|
+
return substr !== change ? change: null;
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
var brackets = { "{": "}", "[": "]", "<": ">" };
|
|
32
|
+
|
|
33
|
+
function filterWhitespaceWalk(filterString, method) {
|
|
34
|
+
var p = 0, replaceHead = 0, replacements = [], match, nextBracketPos;
|
|
35
|
+
var whitespaceRegExp = /(\s+)/mg;
|
|
36
|
+
var operandRegExp = /((?:\+|\-|~|=|\:(\w+)(?:\:([\w\:, ]*))?)?)(?:(\[)|(?:"([^"]*)")|(?:'([^']*)')|([^\s\[\]]+))/mg;
|
|
37
|
+
while (p < filterString.length) {
|
|
38
|
+
whitespaceRegExp.lastIndex = p;
|
|
39
|
+
match = whitespaceRegExp.exec(filterString);
|
|
40
|
+
if (match && match.index === p) {
|
|
41
|
+
var end = p + match[0].length;
|
|
42
|
+
var replacement = method(p, end);
|
|
43
|
+
if (replacement !== null) {
|
|
44
|
+
replacements.push(filterString.substring(replaceHead, p));
|
|
45
|
+
replacements.push(replacement);
|
|
46
|
+
replaceHead = end;
|
|
47
|
+
}
|
|
48
|
+
p = end;
|
|
49
|
+
}
|
|
50
|
+
if (p < filterString.length) {
|
|
51
|
+
operandRegExp.lastIndex = p;
|
|
52
|
+
match = operandRegExp.exec(filterString);
|
|
53
|
+
if (!match || match.index !== p) {
|
|
54
|
+
// Broken filter
|
|
55
|
+
return filterString;
|
|
56
|
+
}
|
|
57
|
+
if (match[1]) {
|
|
58
|
+
// Skip the named prefix
|
|
59
|
+
p += match[1].length;
|
|
60
|
+
}
|
|
61
|
+
if (match[4]) {
|
|
62
|
+
// It's a filter operation. Skip by [...]
|
|
63
|
+
if (filterString.charAt(p++) !== "[") {
|
|
64
|
+
return filterString;
|
|
65
|
+
}
|
|
66
|
+
do {
|
|
67
|
+
if(filterString.charAt(p) === "!") {
|
|
68
|
+
filterString.charAt(p++);
|
|
69
|
+
}
|
|
70
|
+
// Get the operator name
|
|
71
|
+
nextBracketPos = filterString.substring(p).search(/[\[\{<\/]/);
|
|
72
|
+
if(nextBracketPos === -1) {
|
|
73
|
+
return filterString;
|
|
74
|
+
}
|
|
75
|
+
nextBracketPos += p;
|
|
76
|
+
var bracket = filterString.charAt(nextBracketPos);
|
|
77
|
+
nextBracketPos = filterString.indexOf(brackets[bracket], p);
|
|
78
|
+
if (nextBracketPos === -1) {
|
|
79
|
+
return filterString;
|
|
80
|
+
}
|
|
81
|
+
p = nextBracketPos + 1;
|
|
82
|
+
} while (filterString.charAt(p++) !== "]");
|
|
83
|
+
} else {
|
|
84
|
+
p = match.index + match[0].length;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (replacements.length > 0) {
|
|
89
|
+
replacements.push(filterString.substr(replaceHead));
|
|
90
|
+
return replacements.join("");
|
|
91
|
+
}
|
|
92
|
+
return filterString;
|
|
93
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*\
|
|
2
|
+
|
|
3
|
+
Type for transcribing application/json between text and field.
|
|
4
|
+
|
|
5
|
+
Focuses on keeping dataTiddler style pretty printing for text, but puts all
|
|
6
|
+
json on one line for fields.
|
|
7
|
+
|
|
8
|
+
\*/
|
|
9
|
+
|
|
10
|
+
"use strict";
|
|
11
|
+
|
|
12
|
+
exports.name = "application/json";
|
|
13
|
+
|
|
14
|
+
exports.toField = function(text) {
|
|
15
|
+
if (!text) {
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
return JSON.stringify(JSON.parse(text));
|
|
20
|
+
} catch {
|
|
21
|
+
return "{}";
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
exports.fromField = function(text) {
|
|
26
|
+
if (!text) {
|
|
27
|
+
return "";
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
return JSON.stringify(JSON.parse(text), null, $tw.config.preferences.jsonSpaces);
|
|
31
|
+
} catch {
|
|
32
|
+
return "{}";
|
|
33
|
+
}
|
|
34
|
+
};
|