Skip to content

Commit ef0807a

Browse files
iloveskittles82Shalabi222Robert35-dll
authored
BibEntry nodes (#16)
* current library attribute added added current library as attribute of HTTPClient class, refactored methods accordingly, changed comments to match and renamed "performFetch" to "performRequest" * WIP method to grab all bibentries * cleanup and renaming deleted unused icons folder and old index(1).html renamed branch * add buttons for Bibentry nodes * Display entry preview (#18) * Adding Entry Preview Feature to the Nodes * Adding Entry Preview to the child nodes * WIP merged cayw and getting entry preview functionality * removed unused imports * Fixed displaying BibEntry nodes' previews :3 * Minor format consistency check * fixing entry preview bugs * Fixed hiding popovers upon deleting nodes * Prevented editing BibEntries' topics (also fixed small bug when their previews dissapeared upon double clicks) --------- Co-authored-by: Shalabi <Mohamed.Shalabi@Student.HTW-Berlin.de> Co-authored-by: Robert Koch <Robert.Koch@Student.HTW-Berlin.de> --------- Co-authored-by: Shalabi <Mohamed.Shalabi@Student.HTW-Berlin.de> Co-authored-by: Robert Koch <Robert.Koch@Student.HTW-Berlin.de>
1 parent 82c8eba commit ef0807a

File tree

3 files changed

+104
-25
lines changed

3 files changed

+104
-25
lines changed

index.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ <h5 class="modal-title" id="exampleModalLabel">Choose a JabMap to open</h5>
148148
</div>
149149
</div>
150150
</div>
151-
152151
<script type="module" src="/src/main.js"></script>
153152
</body>
154153

src/jsmind/src/jsmind.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,13 @@ export default class jsMind {
245245
return this.begin_edit(the_node);
246246
}
247247
}
248+
// Altered lines:
249+
let nodeType = node.data.type;
250+
if (nodeType === 'BIBE') {
251+
console.log('No editing for BIBE nodes >:(');
252+
return;
253+
}
254+
// End
248255
if (this.get_editable()) {
249256
this.view.edit_node_begin(node);
250257
} else {

src/main.js

Lines changed: 97 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import '@popperjs/core';
12
import 'bootstrap/dist/css/bootstrap.min.css';
2-
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
3+
import { Popover } from 'bootstrap';
34
import 'bootstrap-icons/font/bootstrap-icons.css';
45
import jsMind from './jsmind/src/jsmind.js';
56
// * Note: this import is important for proper manual node creation / addition
@@ -73,10 +74,12 @@ const options = {
7374
handles: { // Named shortcut key event processor
7475
'undo': function (jm, e) {
7576
// display mind map's previous state (undo the last operation)
77+
hidePopovers();
7678
jm.undo();
7779
},
7880
'redo': function (jm, e) {
7981
// display mind map's next state (redo the next operation)
82+
hidePopovers();
8083
jm.redo();
8184
},
8285
'toggleTag': function (jm, e) {
@@ -102,7 +105,7 @@ const options = {
102105
addchild: [45, 4096 + 13], // <Insert>, <Ctrl> + <Enter>
103106
addbrother: 13, // <Enter>
104107
editnode: 113, // <F2>
105-
delnode: 46, // <Delete>
108+
delnode: [46, 8], // <Delete>
106109
toggle: 32, // <Space>
107110
left: 37, // <Left>
108111
up: 38, // <Up>
@@ -179,7 +182,7 @@ function applyTag(selectedNode, iconKey) {
179182
* the selected node.
180183
* @param { object } selectedNode - The node a highlight should be
181184
* applied to / removed from.
182-
* @param { string } highlightKey - The color of the highlight.
185+
* @param { string } highlight - The color of the highlight.
183186
*/
184187
function applyHighlight(selectedNode, highlight) {
185188
selectedNode.data.highlight = selectedNode.data.highlight !== highlight ?
@@ -203,7 +206,7 @@ function extendNode(node) {
203206
node.highlight = node.highlight ?? null;
204207

205208
node.citeKey = node.citeKey ?? null;
206-
node.bibPreview = node.bibPreview ?? null;
209+
node.preview = node.preview ?? null;
207210

208211
assignNodeType(node);
209212

@@ -221,21 +224,83 @@ function assignNodeType(node) {
221224
type = 'BIBE';
222225
}
223226

224-
// * Note: this will probably be extended to handle PDFF / PDFC types
227+
// * Note: this will probably be extended to handle PDFF / PDFC types
225228
node.type = type;
226229
}
227230
// extend the default mind map
228231
extendNode(mind.data);
229232

230-
// create a render for mind maps and display the initial one
233+
// create a render for mind maps
231234
const jm = new jsMind(options);
235+
236+
// add some logic to jsMind's events
237+
// * Note: this is called after the original logic is performed
238+
jm.add_event_listener((type, data) => {
239+
if (type === jsMind.event_type.show) {
240+
addPopoversToBibEntryNodes();
241+
}
242+
if (type === jsMind.event_type.edit) {
243+
hidePopovers();
244+
}
245+
if (type === jsMind.event_type.select) {
246+
hidePopovers();
247+
}
248+
});
249+
250+
// display the initial state and add it to the action stack
232251
jm.show(mind);
233-
// add the initial state to the action stack
234252
jm.resetStack();
235253

236254
// create a HTTP client instance
237255
let httpClient = new HTTPClient();
238256

257+
/**
258+
* Hides all existing Bootsrap's popovers.
259+
*/
260+
function hidePopovers() {
261+
// iterate through all Bootstrap's toggles as HTML elements
262+
document.querySelectorAll('.popover').forEach((bsToggle) => {
263+
bsToggle.remove();
264+
});
265+
}
266+
267+
/**
268+
* Attaches Bootstrap's popovers to all BibEntry nodes.
269+
*/
270+
function addPopoversToBibEntryNodes() {
271+
// iterate through all nodes as HTML elements
272+
const allNodes = document.querySelectorAll('jmnode');
273+
allNodes.forEach(nodeElem => {
274+
// if one already has a popover, skip it
275+
if (nodeElem.getAttribute('data-bs-toggle') === 'popover') {
276+
return;
277+
}
278+
279+
// get node's instance
280+
const nodeId = nodeElem.getAttribute('nodeid');
281+
if (!nodeId) {
282+
return;
283+
}
284+
const node = jm.get_node(nodeId);
285+
// if one isn't a BibEntry node, skip it
286+
if (node?.data?.type !== 'BIBE') {
287+
return;
288+
}
289+
290+
// otherwise create a popover for it
291+
const previewHTML = node.data.preview;
292+
293+
nodeElem.setAttribute('data-bs-toggle', 'popover');
294+
nodeElem.setAttribute('data-bs-trigger', 'hover focus');
295+
nodeElem.setAttribute('data-bs-placement', 'bottom');
296+
nodeElem.setAttribute('data-bs-html', 'true');
297+
nodeElem.setAttribute('title', 'Entry Preview');
298+
nodeElem.setAttribute('data-bs-content', previewHTML);
299+
300+
new Popover(nodeElem, { container: 'body' });
301+
});
302+
}
303+
239304
//--- Button click handlers ---
240305

241306
// saving - sends mind map's content to JabRef's HTTP server
@@ -259,7 +324,7 @@ openBtn.onclick = async function () {
259324
`</option>`;
260325
}
261326

262-
if(bsSelect.innerHTML != '') {
327+
if (bsSelect.innerHTML != '') {
263328
// select first element
264329
bsSelect.selectedIndex = 0;
265330
}
@@ -282,6 +347,8 @@ openSelectedMapBtn.onclick = async function () {
282347
// if no mind map exists, show the default one
283348
let loadedMap = loadResponse.map ?? mind;
284349

350+
extendNode(loadedMap.data);
351+
285352
// display the retrieved mind map
286353
jm.show(loadedMap);
287354
jm.resetStack();
@@ -300,11 +367,13 @@ printMapToConsoleBtn.onclick = async function () {
300367

301368
// undo - discard the last operation (display the previous state)
302369
undoBtn.onclick = function () {
370+
hidePopovers();
303371
jm.undo();
304372
}
305373

306374
// redo - reapply the next operation (display the following state)
307375
redoBtn.onclick = function () {
376+
hidePopovers();
308377
jm.redo();
309378
}
310379

@@ -331,13 +400,13 @@ newChildBtn.onclick = function () {
331400
async function getBibNodesProperties() {
332401
// open cayw window and retrieve selected keys
333402
let selectedKeys = await httpClient.getCiteKeysWithCAYW();
334-
403+
335404
// and get preview string for each selected key
336405
let bibNodesProperties = [];
337406
for (let i = 0; i < selectedKeys.length; i++) {
338407
bibNodesProperties.push({
339408
key: selectedKeys[i],
340-
preview: await httpClient.getPreviewString(selectedKeys[i])
409+
preview: await httpClient.getPreviewHTML(selectedKeys[i])
341410
});
342411
}
343412

@@ -397,6 +466,8 @@ addBibEntryAsChildBtn.onclick = async function () {
397466
});
398467
// save map state for undo/redo
399468
jm.saveState();
469+
// and create popovers for new BibEntry nodes
470+
addPopoversToBibEntryNodes();
400471
}
401472

402473
addBibEntryAsSiblingBtn.onclick = async function () {
@@ -426,48 +497,50 @@ addBibEntryAsSiblingBtn.onclick = async function () {
426497
});
427498
// save map state for undo/redo
428499
jm.saveState();
500+
// and create popovers for new BibEntry nodes
501+
addPopoversToBibEntryNodes();
429502
}
430503

431504
// icon-dropdown menu button handlers
432505
iconCycleBtn.onclick = function () {
433-
if(jm != null) {
434-
applyTag(jm.get_selected_node(),1);
506+
if (jm != null) {
507+
applyTag(jm.get_selected_node(), 1);
435508
}
436509
}
437510

438511
iconStarBtn.onclick = function () {
439-
if(jm != null) {
440-
applyTag(jm.get_selected_node(),2);
512+
if (jm != null) {
513+
applyTag(jm.get_selected_node(), 2);
441514
}
442515
}
443516

444517
iconQuestionBtn.onclick = function () {
445-
if(jm != null) {
446-
applyTag(jm.get_selected_node(),3);
518+
if (jm != null) {
519+
applyTag(jm.get_selected_node(), 3);
447520
}
448521
}
449522

450523
iconWarningBtn.onclick = function () {
451-
if(jm != null) {
452-
applyTag(jm.get_selected_node(),6);
524+
if (jm != null) {
525+
applyTag(jm.get_selected_node(), 6);
453526
}
454527
}
455528

456529
iconLightbulbBtn.onclick = function () {
457-
if(jm != null) {
458-
applyTag(jm.get_selected_node(),7);
530+
if (jm != null) {
531+
applyTag(jm.get_selected_node(), 7);
459532
}
460533
}
461534

462535
iconGreenFlagBtn.onclick = function () {
463-
if(jm != null) {
464-
applyTag(jm.get_selected_node(),8);
536+
if (jm != null) {
537+
applyTag(jm.get_selected_node(), 8);
465538
}
466539
}
467540

468541
iconRedFlagBtn.onclick = function () {
469-
if(jm != null) {
470-
applyTag(jm.get_selected_node(),9);
542+
if (jm != null) {
543+
applyTag(jm.get_selected_node(), 9);
471544
}
472545
}
473546

0 commit comments

Comments
 (0)