add: mind map
This commit is contained in:
parent
7c66352b7c
commit
ef3fb769ce
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,318 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<body>
|
||||
<script src="chrome://__addonRef__/content/lib/js/go.js"></script>
|
||||
<style>
|
||||
html,
|
||||
body,
|
||||
div {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
#canvas {
|
||||
position:absolute;
|
||||
height:100%; width:100%;
|
||||
}
|
||||
</style>
|
||||
<div id="allSampleContent" class="p-4 w-full">
|
||||
<script id="code">
|
||||
function init() {
|
||||
window.addEventListener('message', handler, false)
|
||||
|
||||
// Since 2.2 you can also author concise templates with method chaining instead of GraphObject.make
|
||||
// For details, see https://gojs.net/latest/intro/buildingObjects.html
|
||||
const $ = go.GraphObject.make;
|
||||
|
||||
myDiagram = $(go.Diagram, "myDiagramDiv", {
|
||||
"commandHandler.copiesTree": true,
|
||||
"commandHandler.copiesParentKey": true,
|
||||
"commandHandler.deletesTree": true,
|
||||
"draggingTool.dragsTree": true,
|
||||
"undoManager.isEnabled": true,
|
||||
initialAutoScale: go.Diagram.UniformToFill,
|
||||
layout: $(go.TreeLayout,
|
||||
{ comparer: go.LayoutVertex.smartComparer })
|
||||
});
|
||||
|
||||
// a node consists of some text with a line shape underneath
|
||||
myDiagram.nodeTemplate = $(
|
||||
go.Node,
|
||||
"Vertical",
|
||||
{ selectionObjectName: "TEXT" },
|
||||
$(
|
||||
go.TextBlock,
|
||||
{
|
||||
name: "TEXT",
|
||||
minSize: new go.Size(30, 15),
|
||||
editable: true,
|
||||
},
|
||||
// remember not only the text string but the scale and the font in the node data
|
||||
new go.Binding("text", "text").makeTwoWay(),
|
||||
new go.Binding("scale", "scale").makeTwoWay(),
|
||||
new go.Binding("font", "font").makeTwoWay()
|
||||
),
|
||||
$(
|
||||
go.Shape,
|
||||
"LineH",
|
||||
{
|
||||
stretch: go.GraphObject.Horizontal,
|
||||
strokeWidth: 3,
|
||||
height: 3,
|
||||
// this line shape is the port -- what links connect with
|
||||
portId: "",
|
||||
fromSpot: go.Spot.LeftRightSides,
|
||||
toSpot: go.Spot.LeftRightSides,
|
||||
},
|
||||
new go.Binding("stroke", "brush"),
|
||||
// make sure links come in from the proper direction and go out appropriately
|
||||
new go.Binding("fromSpot", "dir", (d) => spotConverter(d, true)),
|
||||
new go.Binding("toSpot", "dir", (d) => spotConverter(d, false))
|
||||
),
|
||||
// remember the locations of each node in the node data
|
||||
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(
|
||||
go.Point.stringify
|
||||
),
|
||||
// make sure text "grows" in the desired direction
|
||||
new go.Binding("locationSpot", "dir", (d) =>
|
||||
spotConverter(d, false)
|
||||
)
|
||||
);
|
||||
|
||||
// selected nodes show a button for adding children
|
||||
myDiagram.nodeTemplate.selectionAdornmentTemplate = $(
|
||||
go.Adornment,
|
||||
"Spot",
|
||||
$(
|
||||
go.Panel,
|
||||
"Auto",
|
||||
// this Adornment has a rectangular blue Shape around the selected node
|
||||
$(go.Shape, { fill: null, stroke: "dodgerblue", strokeWidth: 3 }),
|
||||
$(go.Placeholder, { margin: new go.Margin(4, 4, 0, 4) })
|
||||
),
|
||||
// and this Adornment has a Button to the right of the selected node
|
||||
$(
|
||||
"Button",
|
||||
{
|
||||
alignment: go.Spot.Right,
|
||||
alignmentFocus: go.Spot.Left,
|
||||
click: jumpNode, // define click behavior for this Button in the Adornment
|
||||
},
|
||||
$(
|
||||
go.TextBlock,
|
||||
"↗️", // the Button content
|
||||
{ font: "bold 8pt sans-serif" }
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// a link is just a Bezier-curved line of the same color as the node to which it is connected
|
||||
myDiagram.linkTemplate = $(
|
||||
go.Link,
|
||||
{
|
||||
curve: go.Link.Bezier,
|
||||
fromShortLength: -2,
|
||||
toShortLength: -2,
|
||||
selectable: false,
|
||||
},
|
||||
$(
|
||||
go.Shape,
|
||||
{ strokeWidth: 3 },
|
||||
new go.Binding("stroke", "toNode", (n) => {
|
||||
if (n.data.brush) return n.data.brush;
|
||||
return "black";
|
||||
}).ofObject()
|
||||
)
|
||||
);
|
||||
|
||||
myDiagram.addDiagramListener("SelectionMoved", (e) => {
|
||||
var rootX = myDiagram.findNodeForKey(0).location.x;
|
||||
myDiagram.selection.each((node) => {
|
||||
if (node.data.parent !== 0) return; // Only consider nodes connected to the root
|
||||
var nodeX = node.location.x;
|
||||
if (rootX < nodeX && node.data.dir !== "right") {
|
||||
updateNodeDirection(node, "right");
|
||||
} else if (rootX > nodeX && node.data.dir !== "left") {
|
||||
updateNodeDirection(node, "left");
|
||||
}
|
||||
layoutTree(node);
|
||||
});
|
||||
});
|
||||
|
||||
// read in the predefined graph using the JSON format data held in the "mySavedModel" textarea
|
||||
// getData();
|
||||
window.parent.postMessage({type: "ready"}, "*");
|
||||
|
||||
}
|
||||
|
||||
function spotConverter(dir, from) {
|
||||
if (dir === "left") {
|
||||
return from ? go.Spot.Left : go.Spot.Right;
|
||||
} else {
|
||||
return from ? go.Spot.Right : go.Spot.Left;
|
||||
}
|
||||
}
|
||||
|
||||
function changeTextSize(obj, factor) {
|
||||
var adorn = obj.part;
|
||||
adorn.diagram.startTransaction("Change Text Size");
|
||||
var node = adorn.adornedPart;
|
||||
var tb = node.findObject("TEXT");
|
||||
tb.scale *= factor;
|
||||
adorn.diagram.commitTransaction("Change Text Size");
|
||||
}
|
||||
|
||||
function toggleTextWeight(obj) {
|
||||
var adorn = obj.part;
|
||||
adorn.diagram.startTransaction("Change Text Weight");
|
||||
var node = adorn.adornedPart;
|
||||
var tb = node.findObject("TEXT");
|
||||
// assume "bold" is at the start of the font specifier
|
||||
var idx = tb.font.indexOf("bold");
|
||||
if (idx < 0) {
|
||||
tb.font = "bold " + tb.font;
|
||||
} else {
|
||||
tb.font = tb.font.slice(idx + 5);
|
||||
}
|
||||
adorn.diagram.commitTransaction("Change Text Weight");
|
||||
}
|
||||
|
||||
function updateNodeDirection(node, dir) {
|
||||
myDiagram.model.setDataProperty(node.data, "dir", dir);
|
||||
// recursively update the direction of the child nodes
|
||||
var chl = node.findTreeChildrenNodes(); // gives us an iterator of the child nodes related to this particular node
|
||||
while (chl.next()) {
|
||||
updateNodeDirection(chl.value, dir);
|
||||
}
|
||||
}
|
||||
|
||||
function layoutTree(node) {
|
||||
if (node.data.key === 0) {
|
||||
// adding to the root?
|
||||
layoutAll(); // lay out everything
|
||||
} else {
|
||||
// otherwise lay out only the subtree starting at this parent node
|
||||
var parts = node.findTreeParts();
|
||||
layoutAngle(parts, node.data.dir === "left" ? 180 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
function layoutAngle(parts, angle) {
|
||||
var layout = go.GraphObject.make(go.TreeLayout, {
|
||||
angle: angle,
|
||||
arrangement: go.TreeLayout.ArrangementFixedRoots,
|
||||
nodeSpacing: 5,
|
||||
layerSpacing: 20,
|
||||
setsPortSpot: false, // don't set port spots since we're managing them with our spotConverter function
|
||||
setsChildPortSpot: false,
|
||||
});
|
||||
layout.doLayout(parts);
|
||||
}
|
||||
|
||||
function layoutAll() {
|
||||
var root = myDiagram.findNodeForKey(0);
|
||||
if (root === null) return;
|
||||
myDiagram.startTransaction("Layout");
|
||||
// split the nodes and links into two collections
|
||||
var rightward = new go.Set(/*go.Part*/);
|
||||
var leftward = new go.Set(/*go.Part*/);
|
||||
root.findLinksConnected().each((link) => {
|
||||
var child = link.toNode;
|
||||
if (child.data.dir === "left") {
|
||||
leftward.add(root); // the root node is in both collections
|
||||
leftward.add(link);
|
||||
leftward.addAll(child.findTreeParts());
|
||||
} else {
|
||||
rightward.add(root); // the root node is in both collections
|
||||
rightward.add(link);
|
||||
rightward.addAll(child.findTreeParts());
|
||||
}
|
||||
});
|
||||
// do one layout and then the other without moving the shared root node
|
||||
layoutAngle(rightward, 0);
|
||||
layoutAngle(leftward, 180);
|
||||
myDiagram.commitTransaction("Layout");
|
||||
}
|
||||
|
||||
function getData(){
|
||||
window.parent.postMessage({type: "getMindMapData"}, "*");
|
||||
}
|
||||
|
||||
function setData(nodes){
|
||||
const data = {
|
||||
class: "go.TreeModel",
|
||||
nodeDataArray: [{ key: 999, text: "Mind Map", parent: undefined }],
|
||||
};
|
||||
const colors = []
|
||||
for (const node of nodes) {
|
||||
console.log(node.model.link)
|
||||
const parent = node.parent.model.id === -1? 999:node.parent.model.id;
|
||||
data.nodeDataArray.push({
|
||||
key: node.model.id,
|
||||
text: `${node.model.rank===7?'🔗':''}${node.model.name.slice(0,10)}${node.model.name.length>=10?'...':''}`,
|
||||
parent: parent,
|
||||
lineIndex: node.model.lineIndex,
|
||||
noteLink: node.model.rank===7?node.model.link:'',
|
||||
brush: go.Brush.randomColor()
|
||||
});
|
||||
}
|
||||
myDiagram.model = go.Model.fromJson(data);
|
||||
}
|
||||
|
||||
|
||||
function jumpNode(e, obj) {
|
||||
var adorn = obj.part;
|
||||
var oldnode = adorn.adornedPart;
|
||||
var olddata = oldnode.data;
|
||||
if(olddata.noteLink){
|
||||
window.parent.postMessage({type: "jumpNote", link: olddata.noteLink}, "*");
|
||||
}else{
|
||||
window.parent.postMessage({type: "jumpNode", lineIndex: olddata.lineIndex}, "*");
|
||||
}
|
||||
}
|
||||
|
||||
function handler(e){
|
||||
console.log(e)
|
||||
if(e.data.type === "setMindMapData"){
|
||||
setData(e.data.nodes)
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("DOMContentLoaded", init);
|
||||
window.addEventListener('resize', (e)=>{myDiagram.diagram.layoutDiagram(true)})
|
||||
|
||||
</script>
|
||||
|
||||
<div id="sample">
|
||||
<div
|
||||
id="myDiagramDiv"
|
||||
style="
|
||||
width: 100%;
|
||||
position: relative;
|
||||
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
|
||||
cursor: auto;
|
||||
font: 13px sans-serif;
|
||||
overflow: hidden;
|
||||
"
|
||||
>
|
||||
<canvas
|
||||
tabindex="0"
|
||||
style="
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
z-index: 2;
|
||||
user-select: none;
|
||||
touch-action: none;
|
||||
cursor: auto;
|
||||
"
|
||||
>This text is displayed if your browser does not support the Canvas
|
||||
HTML element.</canvas
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -19,8 +19,10 @@
|
|||
<script src="chrome://zotero/content/note.js" />
|
||||
<script src="chrome://__addonRef__/content/lib/js/jquery.min.js"></script>
|
||||
<script src="chrome://__addonRef__/content/lib/js/dx.all.js"></script>
|
||||
<script src="chrome://__addonRef__/content/lib/js/go.js"></script>
|
||||
<script type="application/javascript">
|
||||
Zotero.Knowledge4Zotero.views.$ = $;
|
||||
Zotero.Knowledge4Zotero.views.go = go;
|
||||
</script>
|
||||
|
||||
<keyset>
|
||||
|
|
@ -30,7 +32,7 @@
|
|||
|
||||
<hbox flex="1">
|
||||
<vbox id="zotero-knowledge-outline" flex="1" width="300" minwidth="250" style="overflow: hidden;">
|
||||
<html:div class="dx-viewport">
|
||||
<html:div class="dx-viewport" id="outline-container">
|
||||
<div class="demo-container">
|
||||
<div class="form">
|
||||
<div class="drive-panel">
|
||||
|
|
@ -45,11 +47,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</html:div>
|
||||
<html:div id="outline-tools" flex="1" height="50" maxheight="50" minheight="50" style="display: flex; flex-flex-direction: row; justify-content: space-between; margin: 0px 30px 0px 30px;">
|
||||
<html:div id="mindmap-container">
|
||||
<iframe src="chrome://Knowledge4Zotero/content/mindMap.html" id="mindmapIframe"></iframe>
|
||||
</html:div>
|
||||
<html:div id="outline-tools" height="50" maxheight="50" minheight="50" style="display: flex; flex-flex-direction: row; justify-content: space-between; margin: 0px 30px 0px 30px;">
|
||||
<div class="tooltip">
|
||||
<div id="outline-selectknowledge"></div>
|
||||
<span class="tooltiptext">Select Main Knowledge</span>
|
||||
</div>
|
||||
<div class="tooltip">
|
||||
<div id="outline-switchview"></div>
|
||||
<span class="tooltiptext">Switch Outline/Mind Map View</span>
|
||||
</div>
|
||||
<div class="tooltip">
|
||||
<div id="outline-addafter"></div>
|
||||
<span class="tooltiptext">Add Heading</span>
|
||||
|
|
|
|||
1
build.js
1
build.js
|
|
@ -111,6 +111,7 @@ const optionsAddon = {
|
|||
path.join(buildDir, "**/*.rdf"),
|
||||
path.join(buildDir, "**/*.dtd"),
|
||||
path.join(buildDir, "**/*.xul"),
|
||||
path.join(buildDir, "**/*.html"),
|
||||
path.join(buildDir, "**/*.manifest"),
|
||||
"update.rdf",
|
||||
],
|
||||
|
|
|
|||
|
|
@ -42,7 +42,10 @@ class Knowledge extends AddonBase {
|
|||
this._Addon.views.bindTreeViewResize();
|
||||
this.setWorkspaceNote("main");
|
||||
this.currentLine = -1;
|
||||
this._Addon.views.initKnowledgeWindow(win);
|
||||
this._Addon.views.switchView(true);
|
||||
this._Addon.views.buildOutline();
|
||||
// this._Addon.views.buildMindMap();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -473,6 +476,7 @@ class Knowledge extends AddonBase {
|
|||
const isLink = lineElement.search(/zotero:\/\/note\//g) !== -1;
|
||||
if (isHeading || isLink) {
|
||||
let name = "";
|
||||
let link = "";
|
||||
if (isHeading) {
|
||||
const startIndex = lineElement.search(headerStartReg);
|
||||
const stopIndex = lineElement.search(headerStopReg);
|
||||
|
|
@ -483,6 +487,8 @@ class Knowledge extends AddonBase {
|
|||
} else {
|
||||
name = lineElement.slice(lineElement.search(/">/g) + 2);
|
||||
name = name.slice(0, name.search(/<\//g));
|
||||
link = lineElement.slice(lineElement.search(/href="/g) + 6);
|
||||
link = link.slice(0, link.search(/"/g));
|
||||
}
|
||||
while (currentNode.model.rank >= currentRank) {
|
||||
currentNode = currentNode.parent;
|
||||
|
|
@ -497,6 +503,7 @@ class Knowledge extends AddonBase {
|
|||
name: name,
|
||||
lineIndex: i,
|
||||
endIndex: noteLines.length,
|
||||
link: link,
|
||||
});
|
||||
currentNode.addChild(lastNode);
|
||||
currentNode = lastNode;
|
||||
|
|
@ -508,7 +515,7 @@ class Knowledge extends AddonBase {
|
|||
getNoteTreeAsList(
|
||||
note: ZoteroItem,
|
||||
filterRoot: boolean = true,
|
||||
filterLikn: boolean = true
|
||||
filterLink: boolean = true
|
||||
): TreeModel.Node<object>[] {
|
||||
note = note || this.getWorkspaceNote();
|
||||
if (!note) {
|
||||
|
|
@ -517,7 +524,7 @@ class Knowledge extends AddonBase {
|
|||
return this.getNoteTree(note).all(
|
||||
(node) =>
|
||||
(!filterRoot || node.model.lineIndex >= 0) &&
|
||||
(!filterLikn || node.model.rank <= 6)
|
||||
(!filterLink || node.model.rank <= 6)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
148
src/views.ts
148
src/views.ts
|
|
@ -4,6 +4,8 @@ class AddonViews extends AddonBase {
|
|||
progressWindowIcon: object;
|
||||
editorIcon: object;
|
||||
$: any;
|
||||
outlineView: boolean;
|
||||
_initIframe: typeof Promise;
|
||||
|
||||
constructor(parent: Knowledge4Zotero) {
|
||||
super(parent);
|
||||
|
|
@ -21,7 +23,10 @@ class AddonViews extends AddonBase {
|
|||
export: `<svg t="1651322116327" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11894" width="24" height="24"><path d="M849.2 599v217H178.5V599c-0.7-23.7-20.1-42.7-44-42.7s-43.3 19-44 42.7v252.5c0 28.9 23.6 52.5 52.5 52.5h741.7c28.9 0 52.5-23.6 52.5-52.5V599c-0.7-23.7-20.1-42.7-44-42.7s-43.3 19-44 42.7z" p-id="11895"></path><path d="M482.7 135.4l-164 164c-17.1 17.1-17.1 45.1 0 62.2s45.1 17.1 62.2 0l85.7-85.7v314.8c0 26 21.3 47.2 47.2 47.2 26 0 47.2-21.3 47.2-47.2V276l85.7 85.7c17.1 17.1 45.1 17.1 62.2 0s17.1-45.1 0-62.2l-164-164c-17.1-17.2-45.1-17.2-62.2-0.1z" p-id="11896"></path></svg>`,
|
||||
close: `<svg t="1651331457107" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12754" width="24" height="24"><path d="M557.311759 513.248864l265.280473-263.904314c12.54369-12.480043 12.607338-32.704421 0.127295-45.248112-12.512727-12.576374-32.704421-12.607338-45.248112-0.127295L512.127295 467.904421 249.088241 204.063755c-12.447359-12.480043-32.704421-12.54369-45.248112-0.063647-12.512727 12.480043-12.54369 32.735385-0.063647 45.280796l262.975407 263.775299-265.151458 263.744335c-12.54369 12.480043-12.607338 32.704421-0.127295 45.248112 6.239161 6.271845 14.463432 9.440452 22.687703 9.440452 8.160624 0 16.319527-3.103239 22.560409-9.311437l265.216826-263.807983 265.440452 266.240344c6.239161 6.271845 14.432469 9.407768 22.65674 9.407768 8.191587 0 16.352211-3.135923 22.591372-9.34412 12.512727-12.480043 12.54369-32.704421 0.063647-45.248112L557.311759 513.248864z" p-id="12755"></path></svg>`,
|
||||
openWorkspaceCollectionView: `<svg t="1651317033804" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2432" width="100%" height="100%"><path d="M874.9 459.4c-18.8 0-34 15.2-34 34v355.7c0 18.6-15.5 33.7-34.5 33.7H181.5c-19 0-34.5-15.1-34.5-33.7V232.3c0-18.6 15.5-33.7 34.5-33.7H541c18.8 0 34-15.2 34-34s-15.2-34-34-34H181.5C125 130.6 79 176.2 79 232.3v616.8c0 56 46 101.7 102.5 101.7h624.9c56.5 0 102.5-45.6 102.5-101.7V493.4c0-18.8-15.2-34-34-34z" fill="#b6b6b6" p-id="2433"></path><path d="M885.5 82.7H657.1c-18.8 0-34 15.2-34 34s15.2 34 34 34h169.7L358.5 619.1c-13.3 13.3-13.3 34.8 0 48.1 6.6 6.6 15.3 10 24 10s17.4-3.3 24-10l470-470v169.7c0 18.8 15.2 34 34 34s34-15.2 34-34V141.5c0.1-32.4-26.4-58.8-59-58.8z" fill="#b6b6b6" p-id="2434"></path></svg>`,
|
||||
switchView: `<svg t="1651813727621" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14171" width="18" height="18"><path d="M1024 733v131c0 53-43 96-96 96h-96c-53 0-96-43-96-96V733c0-53 43-96 96-96 8.8 0 16-7.2 16-16v-77c0-17.7-14.3-32-32-32H560c-8.8 0-16 7.2-16 16v94c0 8.3 6.7 15 15 15h1c53 0 96 43 96 96v131c0 53-43 96-96 96h-96c-53 0-96-43-96-96V733c0-53 43-96 96-96h1c8.3 0 15-6.7 15-15v-94c0-8.8-7.2-16-16-16H208c-17.7 0-32 14.3-32 32v77c0 8.8 7.2 16 16 16 53 0 96 43 96 96v131c0 53-43 96-96 96H96c-53 0-96-43-96-96V733c0-53 43-96 96-96 8.8 0 16-7.2 16-16v-77c0-53 43-96 96-96h256c8.8 0 16-7.2 16-16v-48h-96c-53 0-96-43-96-96V144c0-53 43-96 96-96h256c53 0 96 43 96 96v144c0 53-43 96-96 96h-96v48c0 8.8 7.2 16 16 16h256c53 0 96 43 96 96v77c0 8.8 7.2 16 16 16 53 0 96 43 96 96z" p-id="14172"></path></svg>`,
|
||||
};
|
||||
this.outlineView = true;
|
||||
this._initIframe = Zotero.Promise.defer();
|
||||
}
|
||||
|
||||
getEditor(_document: Document) {
|
||||
|
|
@ -181,13 +186,18 @@ class AddonViews extends AddonBase {
|
|||
}
|
||||
if (lineIndex >= indexMap.length) {
|
||||
lineIndex = indexMap.length - 1;
|
||||
} else if (indexMap.length < 0) {
|
||||
} else if (lineIndex < 0) {
|
||||
lineIndex = 0;
|
||||
}
|
||||
lineIndex = indexMap[lineIndex];
|
||||
if (lineIndex >= editor.children.length) {
|
||||
lineIndex = editor.children.length - 1;
|
||||
} else if (lineIndex < 0) {
|
||||
lineIndex = 0;
|
||||
}
|
||||
const mappedIndex = indexMap[lineIndex];
|
||||
|
||||
// @ts-ignore
|
||||
editor.parentNode.scrollTo(0, editor.children[mappedIndex].offsetTop);
|
||||
editor.parentNode.scrollTo(0, editor.children[lineIndex].offsetTop);
|
||||
}
|
||||
|
||||
addNewKnowledgeButton() {
|
||||
|
|
@ -203,7 +213,7 @@ class AddonViews extends AddonBase {
|
|||
});
|
||||
button.setAttribute(
|
||||
"style",
|
||||
"list-style-image: url('chrome://Knowledge4Zotero/skin/knowledge.png');"
|
||||
"list-style-image: url('chrome://Knowledge4Zotero/skin/knowledge@0.5x.png');"
|
||||
);
|
||||
addNoteButton.after(button);
|
||||
}
|
||||
|
|
@ -347,28 +357,103 @@ class AddonViews extends AddonBase {
|
|||
return reader.annotationItemIDs.length === updateCount;
|
||||
}
|
||||
|
||||
initKnowledgeWindow(_window: Window) {
|
||||
_window.addEventListener("message", (e) => this.messageHandler(e), false);
|
||||
}
|
||||
|
||||
async messageHandler(e) {
|
||||
const _window = this._Addon.knowledge.getWorkspaceWindow();
|
||||
if (e.data.type === "ready") {
|
||||
this._initIframe.resolve();
|
||||
} else if (e.data.type === "getMindMapData") {
|
||||
(
|
||||
_window.document.getElementById("mindmapIframe") as HTMLIFrameElement
|
||||
).contentWindow.postMessage(
|
||||
{
|
||||
type: "setMindMapData",
|
||||
nodes: this._Addon.knowledge.getNoteTreeAsList(),
|
||||
},
|
||||
"*"
|
||||
);
|
||||
} else if (e.data.type === "jumpNode") {
|
||||
this.scrollToLine(
|
||||
await this._Addon.knowledge.getWorkspaceEditorInstance(),
|
||||
e.data.lineIndex
|
||||
);
|
||||
} else if (e.data.type === "jumpNote") {
|
||||
Zotero.debug(e.data);
|
||||
this._Addon.events.onEditorEvent(
|
||||
new EditorMessage("onNoteLink", {
|
||||
params: await this._Addon.knowledge.getNoteFromLink(e.data.link),
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
switchView(status: boolean = undefined) {
|
||||
if (typeof status === "undefined") {
|
||||
status = !this.outlineView;
|
||||
}
|
||||
const _window = this._Addon.knowledge.getWorkspaceWindow();
|
||||
const mindmap = _window.document.getElementById("mindmap-container");
|
||||
const outline = _window.document.getElementById("outline-container");
|
||||
this.outlineView = status;
|
||||
if (this.outlineView) {
|
||||
mindmap.setAttribute("hidden", "hidden");
|
||||
outline.removeAttribute("hidden");
|
||||
} else {
|
||||
outline.setAttribute("hidden", "hidden");
|
||||
mindmap.removeAttribute("hidden");
|
||||
}
|
||||
this.buildOutline(this._Addon.knowledge.getWorkspaceNote());
|
||||
}
|
||||
|
||||
async updateMindMap() {
|
||||
Zotero.debug("Knowledge4Zotero: updateMindMap");
|
||||
await this._initIframe;
|
||||
const _window = this._Addon.knowledge.getWorkspaceWindow();
|
||||
const iframe = _window.document.getElementById(
|
||||
"mindmapIframe"
|
||||
) as HTMLIFrameElement;
|
||||
iframe.contentWindow.postMessage(
|
||||
{
|
||||
type: "setMindMapData",
|
||||
nodes: this._Addon.knowledge.getNoteTreeAsList(undefined, true, false),
|
||||
},
|
||||
"*"
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Outline Code Start
|
||||
*/
|
||||
|
||||
async buildOutline(note: ZoteroItem) {
|
||||
this._Addon.knowledge.currentNodeID = -1;
|
||||
let treeList = this._Addon.knowledge.getNoteTreeAsList(note, true, false);
|
||||
const treeData = [];
|
||||
treeList.map((node: TreeModel.Node<object>) => {
|
||||
treeData.push({
|
||||
id: String(node.model.id),
|
||||
name: node.model.name,
|
||||
rank: node.model.rank,
|
||||
icon: node.model.rank === 7 ? "textdocument" : undefined,
|
||||
lineIndex: node.model.lineIndex,
|
||||
endIndex: node.model.endIndex,
|
||||
isDirectory: node.hasChildren(),
|
||||
expanded: true,
|
||||
parentId:
|
||||
node.model.rank > 1 ? String(node.parent.model.id) : undefined,
|
||||
if (this.outlineView) {
|
||||
this._Addon.knowledge.currentNodeID = -1;
|
||||
let treeList = this._Addon.knowledge.getNoteTreeAsList(note, true, false);
|
||||
const treeData = [];
|
||||
treeList.map((node: TreeModel.Node<object>) => {
|
||||
treeData.push({
|
||||
id: String(node.model.id),
|
||||
name: node.model.name,
|
||||
rank: node.model.rank,
|
||||
icon: node.model.rank === 7 ? "textdocument" : undefined,
|
||||
lineIndex: node.model.lineIndex,
|
||||
endIndex: node.model.endIndex,
|
||||
isDirectory: node.hasChildren(),
|
||||
expanded: true,
|
||||
parentId:
|
||||
node.model.rank > 1 ? String(node.parent.model.id) : undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
this.$(() => {
|
||||
this.createTreeView("#treeview", treeData);
|
||||
this.createSortable("#treeview", "treeData");
|
||||
});
|
||||
this.$(() => {
|
||||
this.createTreeView("#treeview", treeData);
|
||||
this.createSortable("#treeview", "treeData");
|
||||
});
|
||||
} else {
|
||||
this.updateMindMap();
|
||||
}
|
||||
}
|
||||
|
||||
createTreeView(selector, items) {
|
||||
|
|
@ -399,6 +484,13 @@ class AddonViews extends AddonBase {
|
|||
);
|
||||
},
|
||||
});
|
||||
this.$("#outline-switchview").dxButton({
|
||||
// icon: this.editorIcon["switchView"],
|
||||
icon: "chart",
|
||||
onClick: async (e) => {
|
||||
this.switchView();
|
||||
},
|
||||
});
|
||||
this.$("#outline-addafter").dxButton({
|
||||
icon: "plus",
|
||||
onClick: (e) => {
|
||||
|
|
@ -509,6 +601,10 @@ class AddonViews extends AddonBase {
|
|||
height: `${this.$("window").height() - 130}px`,
|
||||
width: `${this.$("#zotero-knowledge-outline").width() - 10}px`,
|
||||
});
|
||||
this.$("#mindmapIframe").css({
|
||||
height: `${this.$("window").height() - 58}px`,
|
||||
width: `${this.$("#zotero-knowledge-outline").width() - 10}px`,
|
||||
});
|
||||
}
|
||||
|
||||
createSortable(selector, driveName) {
|
||||
|
|
@ -668,6 +764,10 @@ class AddonViews extends AddonBase {
|
|||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Outline Code End
|
||||
*/
|
||||
|
||||
showProgressWindow(
|
||||
header: string,
|
||||
context: string,
|
||||
|
|
|
|||
Loading…
Reference in New Issue