Files
ansible/lib/python3.10/site-packages/ansibleplaybookgrapher/data/highlight-hover.js
2023-02-08 12:13:28 +01:00

170 lines
5.3 KiB
JavaScript

/**
* This file contains the functions responsible to highlight the plays, roles and tasks when rendering the SVG file in a browser
* or any SVG reader that support Javascript.
*/
/**
* The name of the CSS class for highlighted elements
* @type {string}
*/
const HIGHLIGHT_CLASS = "highlight";
/**
* The current selected element on the graph
* @type {null}
*/
let currentSelectedElement = null;
/**
* Highlight the linked nodes of the given root element
* @param {Element} parentElement
* @param {string[]} visitedElements
*/
function highlightLinkedNodes(parentElement, visitedElements = []) {
$(parentElement).find('link').each(function (index, element) {
const linkedElementId = $(element).attr('target');
const edgeId = $(element).attr('edge');
const currentElement = $(`#${linkedElementId}`);
currentElement.addClass(HIGHLIGHT_CLASS);
// Highlight the edge point to the target
$(`#${edgeId}`).addClass(HIGHLIGHT_CLASS);
if (!visitedElements.includes(linkedElementId)) {
visitedElements.push(linkedElementId);
// Recursively highlight
highlightLinkedNodes(currentElement, visitedElements);
}
})
}
/**
* Unhighlight the linked nodes of the given root element
* @param {Element} parentElement
* @param {string[]} visitedElements
* @param {boolean} isHover True when we are coming from a mouseleave event. In that case, we should not unhighlight if
* the parentElement is the current selected element
*/
function unHighlightLinkedNodes(parentElement, visitedElements = [], isHover) {
const currentSelectedElementId = $(currentSelectedElement).attr('id');
// Do not unhighlight the current selected element
if ($(parentElement).attr('id') !== currentSelectedElementId || !isHover) {
$(parentElement).find('link').each(function (index, element) {
const linkedElementId = $(element).attr('target');
const edgeId = $(element).attr('edge');
const linkedElement = $(`#${linkedElementId}`);
if (linkedElement.attr('id') !== currentSelectedElementId) {
linkedElement.removeClass(HIGHLIGHT_CLASS);
// Unhighlight the edge point to the target
$(`#${edgeId}`).removeClass(HIGHLIGHT_CLASS);
if (!visitedElements.includes(linkedElementId)) {
visitedElements.push(linkedElementId);
// Recursively unhighlight
unHighlightLinkedNodes(linkedElement, visitedElements, isHover);
}
}
})
}
}
/**
* Hover handler for mouseenter event
* @param {Event} event
*/
function hoverMouseEnter(event) {
highlightLinkedNodes(event.currentTarget, []);
}
/**
* Hover handler for mouseleave event
* @param {Event} event
*/
function hoverMouseLeave(event) {
unHighlightLinkedNodes(event.currentTarget, [], true);
}
/**
* Handler when clicking on some elements
* @param {Event} event
*/
function clickOnElement(event) {
const newClickedElement = $(event.currentTarget);
event.preventDefault(); // Disable the default click behavior since we override it here
if (newClickedElement.attr('id') === $(currentSelectedElement).attr('id')) { // clicking again on the same element
newClickedElement.removeClass(HIGHLIGHT_CLASS);
unHighlightLinkedNodes(currentSelectedElement, [], false);
currentSelectedElement = null;
} else { // clicking on a different node
// Remove highlight from all the nodes linked to the current selected node
unHighlightLinkedNodes(currentSelectedElement, [], false);
if (currentSelectedElement) {
currentSelectedElement.removeClass(HIGHLIGHT_CLASS);
}
newClickedElement.addClass(HIGHLIGHT_CLASS);
highlightLinkedNodes(newClickedElement, []);
currentSelectedElement = newClickedElement;
}
}
/**
* Handler when double clicking on some elements
* @param {Event} event
*/
function dblClickElement(event) {
const newElementDlbClicked = event.currentTarget;
const links = $(newElementDlbClicked).find("a[xlink\\:href]");
if (links.length > 0) {
document.location = $(links[0]).attr("xlink:href");
} else {
console.log("No links found on this element");
}
}
$("#svg").ready(function () {
let playbooks = $("g[id^=playbook_]");
let plays = $("g[id^=play_]");
let roles = $("g[id^=role_]");
let blocks = $("g[id^=block_]");
let tasks = $("g[id^=pre_task_], g[id^=task_], g[id^=post_task_]");
playbooks.hover(hoverMouseEnter, hoverMouseLeave);
playbooks.click(clickOnElement);
playbooks.dblclick(dblClickElement);
// Set hover and click events on the plays
plays.hover(hoverMouseEnter, hoverMouseLeave);
plays.click(clickOnElement);
plays.dblclick(dblClickElement);
// Set hover and click events on the roles
roles.hover(hoverMouseEnter, hoverMouseLeave);
roles.click(clickOnElement);
roles.dblclick(dblClickElement);
// Set hover and click events on the blocks
blocks.hover(hoverMouseEnter, hoverMouseLeave);
blocks.click(clickOnElement);
blocks.dblclick(dblClickElement);
// Set hover and click events on the tasks
tasks.hover(hoverMouseEnter, hoverMouseLeave);
tasks.click(clickOnElement);
tasks.dblclick(dblClickElement);
});