Anonymous

Changes

From KIproBatt Wiki
21,735 bytes added ,  05:57, 17 May 2022
no edit summary
Line 1: Line 1:  
$(document).ready(function() {
 
$(document).ready(function() {
   
     $.getScript('https://unpkg.com/vis-network/standalone/umd/vis-network.min.js').done(function() {
 
     $.getScript('https://unpkg.com/vis-network/standalone/umd/vis-network.min.js').done(function() {
    var pathId = 0;
+
        var pathId = 0;
    var newNodes = {};
+
        var newNodes = {};
    var editNodes = {};
+
        var editNodes = {};
    var editDeletedEdges = {};
+
        var editDeletedEdges = {};
    var editDeletedNodes = {};
+
        var editDeletedNodes = {};
   
+
        $(".InteractiveSemanticGraph").each(function(index) {
    $(".visNetworkGraph").each(function(index) {
+
            if ($('.InteractiveSemanticGraph').length) { //check if div element(s) exist
        if ($('.visNetworkGraph').length) { //check if div element(s) exist
+
                var input = JSON.parse(this.innerHTML);
            var input = JSON.parse(this.innerHTML);
+
                // create an array with nodes
+
                var nodes = new vis.DataSet([]);
            // create an array with nodes
+
                // create an array with edges
            var nodes = new vis.DataSet([]);
+
                var edges = new vis.DataSet([]);
            // create an array with edges
+
                //colors for the graph
            var edges = new vis.DataSet([]);
+
                var colors = [];
            //colors for the graph
+
                var oldGroups = {};
            var colors = [];
+
                var givenDiv = this;
            var oldGroups = {};
+
                givenDiv.style.position = "relative";
var givenDiv = this;
+
                givenDiv.style.display = "inline-block";
givenDiv.style.position = "relative";
  −
givenDiv.style.display = "inline-block";
  −
     −
+
//Function for random colors
            function getColor() {
+
                 var h = Math.random();
                 return "hsl(" + 360 * Math.random() + ',' +
+
                var golden = 0.618033988749895;
                    (25 + 70 * Math.random()) + '%,' +
  −
                    (85 + 10 * Math.random()) + '%)';
  −
            }
     −
            var h = Math.random();
+
                function randomHSL() {
            var golden = 0.618033988749895;
+
                    h += golden;
            function randomHSL() {
+
                    h %= 1;
            h += golden;
+
                    return "hsla(" + (360 * h) + "," +
            h %= 1;
+
                        "70%," +
            //~~(360 * Math.random())
+
                        "80%,1)";
                return "hsla(" + (360 * h) + "," +
+
                }
                    "70%," +
+
                for (var i = 0; i < input.properties.length; i++) {
                    "80%,1)";
+
                    colors.push(randomHSL());
            }
+
                }
   −
            for (var i = 0; i < input.properties.length; i++) {
+
                 function isLabelSet(id) {
                 colors.push(randomHSL());
+
                    node = nodes.get(id);
            }
+
                    if (node === null) return false;
 
+
                    else return id;
            function isLabelSet(id) {
+
                 }
                node = nodes.get(id);
  −
                if (node === null) return false;
  −
                else return id;
  −
            }
  −
 
  −
            //var colors = ['#ff7878', '#73ff77', '#e878ff', '#ffae57', '#80f8ff', '#ffff75', '#adadad', '#b482ff'];
  −
 
  −
            nodes.add({
  −
                id: input.root,
  −
                label: input.root, //todo: query display title
  −
                color: '#6dbfa9'
  −
            });
  −
 
  −
            //Creates API query Url with the given root and properties
  −
            function createUrl(root, properties) {
  −
                 var url = `/w/api.php?action=ask&query=[[${encodeURIComponent(root)}]]`;
  −
                var propertiesVar = '';
  −
                for (var i = 0; i < properties.length; i++) {
  −
                    propertiesVar += '|?' + encodeURIComponent(properties[i]);
      +
                nodes.add({
 +
                    id: input.root,
 +
                    label: input.root, //todo: query display title
 +
                    color: '#6dbfa9'
 +
                });
 +
                //Creates API query Url with the given root and properties
 +
                function createUrl(root, properties) {
 +
                if (properties[0] === "-Category") properties[0] = "Category";
 +
                else if (root.startsWith("Category:")) root = ":" + root; //[[Category:X]] queries pages within this category, [[:Category:X]] the category itself
 +
                    var url = `/w/api.php?action=ask&query=[[${encodeURIComponent(root)}]]`;
 +
                    var propertiesVar = '';
 +
                    for (var i = 0; i < properties.length; i++) {
 +
                        propertiesVar += '|?' + encodeURIComponent(properties[i]) + "=" + encodeURIComponent(properties[i]); //explicit label overwrites property display title. ToDo: extrakt label in result and get corresponding printout
 +
                        propertiesVar += '|?' + encodeURIComponent(properties[i] + ".Display title of") + "=" + encodeURIComponent(properties[i] + ".Display title of"); //explicit query for display title due to slow update of the displaytitle page field
 +
                    }
 +
                    url = url + propertiesVar + '&format=json';
 +
                    return url;
 
                 }
 
                 }
 +
                //Makes an API call with the given parameters and adds the results to the nodes and edges datasets.
 +
                //With a given nodeID the edges are set to the nodeID, else they are set to the root node.
 +
                function fetchData(root, properties, nodeID, setGroup, setColor) {
 +
                    fetch(createUrl(root, properties))
 +
                        .then(response => response.json())
 +
                        .then(data => {
 +
                            if (!nodeID && root) { //first query on root node
 +
                                var rootNode = nodes.get(root);
 +
                                rootNode.url = data.query.results[root].fullurl;
 +
                                if (data.query.results[root].displaytitle) rootNode.label = data.query.results[root].displaytitle;
 +
                            }
   −
                url = url + propertiesVar + '&format=json';
+
                            for (var i = 0; i < properties.length; i++) {
                return url;
  −
            }
     −
            //Makes an API call with the given parameters and adds the results to the nodes and edges datasets.
+
                                for (var j = 0; j < data.query.results[root].printouts[properties[i]].length; j++) {
            //With a given nodeID the edges are set to the nodeID, else they are set to the root node.
  −
            function fetchData(root, properties, nodeID, setGroup, setColor) {
  −
                fetch(createUrl(root, properties))
  −
                    .then(response => response.json())
  −
                    .then(data => {
  −
                    if (!nodeID && root){ //first query on root node
  −
                    var rootNode = nodes.get(root);
  −
                    rootNode.url = data.query.results[root].fullurl;
  −
                    if (data.query.results[root].displaytitle) rootNode.label = data.query.results[root].displaytitle;
  −
                    }
  −
                        for (var i = 0; i < properties.length; i++) {
  −
                            for (var j = 0; j < data.query.results[root].printouts[properties[i]].length; j++) {
  −
                           
  −
                           
  −
                            //define colors
  −
                                if(!(properties[i] in legendColors) && setColor) {legendColors[properties[i]] = colors[i]; }
  −
                                else {setColor = legendColors[properties[i]]; colors[i] = legendColors[properties[i]]; colors[i] = legendColors[properties[i]];}
  −
                                //define id and label. use displaytitle if available. Use string representation of non-page properties
  −
                                var id = "";
  −
                                var label = "";
  −
                                if (data.query.results[root].printouts[properties[i]][j].fulltext) id = data.query.results[root].printouts[properties[i]][j].fulltext;
  −
                                else if(data.query.results[root].printouts[properties[i]][j].value) id = '' + data.query.results[root].printouts[properties[i]][j].value + ' ' + data.query.results[root].printouts[properties[i]][j].unit; 
  −
                                else id = data.query.results[root].printouts[properties[i]][j].toString();
  −
                                if (data.query.results[root].printouts[properties[i]][j].displaytitle) label = data.query.results[root].printouts[properties[i]][j].displaytitle;
  −
                                if (label === "") label = id;
  −
  −
                                if (isLabelSet(id) === false) {
     −
                                     if (setGroup && setColor) {
+
                                    //define colors
                                         nodes.add({
+
                                     if (!(properties[i] in legendColors) && setColor) {
                                            id: id,
+
                                         legendColors[properties[i]] = colors[i];
                                            label: label,
  −
                                            color: setColor,
  −
                                            group: setGroup[0],
  −
                                            hidden: false,
  −
                                            url: data.query.results[root].printouts[properties[i]][j].fullurl,
  −
                                            oncontext: true,
  −
                                        });
  −
                                        oldGroups["" + id] = setGroup[0];
   
                                     } else {
 
                                     } else {
                                         nodes.add({
+
                                         setColor = legendColors[properties[i]];
                                            id: id,
+
                                        colors[i] = legendColors[properties[i]];
                                            label: label,
+
                                         colors[i] = legendColors[properties[i]];
                                            color: colors[i],
  −
                                            group: properties[i],
  −
                                            hidden: false,
  −
                                            url: data.query.results[root].printouts[properties[i]][j].fullurl
  −
                                        });
  −
                                         oldGroups["" + id] = properties[i];
   
                                     }
 
                                     }
                                     if (nodeID) {
+
                                    //define id and label. use displaytitle if available. Use string representation of non-page properties
 +
                                    var id = "";
 +
                                    var label = "";
 +
                                    if (data.query.results[root].printouts[properties[i]][j].fulltext) id = data.query.results[root].printouts[properties[i]][j].fulltext;
 +
                                    else if (data.query.results[root].printouts[properties[i]][j].value) id = '' + data.query.results[root].printouts[properties[i]][j].value + ' ' + data.query.results[root].printouts[properties[i]][j].unit;
 +
                                    else id = data.query.results[root].printouts[properties[i]][j].toString();
 +
                                     if (data.query.results[root].printouts[properties[i]][j].displaytitle) label = data.query.results[root].printouts[properties[i]][j].displaytitle;
 +
                                    if (data.query.results[root].printouts[properties[i] + ".Display title of"][j]) label = data.query.results[root].printouts[properties[i] + ".Display title of"][j]; //explicit use property display title due to slow update of the displaytitle page field
 +
                                    if (label === "") label = id;
 +
                                    if (isLabelSet(id) === false) {
 +
                                        if (setGroup && setColor) {
 +
                                            nodes.add({
 +
                                                id: id,
 +
                                                label: label,
 +
                                                color: setColor,
 +
                                                group: setGroup[0],
 +
                                                hidden: false,
 +
                                                url: data.query.results[root].printouts[properties[i]][j].fullurl,
 +
                                                oncontext: true,
 +
                                            });
 +
                                            oldGroups["" + id] = setGroup[0];
 +
                                        } else {
 +
                                            nodes.add({
 +
                                                id: id,
 +
                                                label: label,
 +
                                                color: colors[i],
 +
                                                group: properties[i],
 +
                                                hidden: false,
 +
                                                url: data.query.results[root].printouts[properties[i]][j].fullurl
 +
                                            });
 +
                                            oldGroups["" + id] = properties[i];
 +
                                        }
 +
                                        if (nodeID) {
 +
                                            edges.add({
 +
                                                from: nodeID,
 +
                                                to: id,
 +
                                                label: properties[i],
 +
                                                color: colors[i],
 +
                                                group: properties[i]
 +
                                            });
 +
                                        } else {
 +
                                            edges.add({
 +
                                                from: input.root,
 +
                                                to: id,
 +
                                                label: properties[i],
 +
                                                color: colors[i],
 +
                                                group: properties[i]
 +
                                            });
 +
                                        }
 +
                                    } else {
 
                                         edges.add({
 
                                         edges.add({
 
                                             from: nodeID,
 
                                             from: nodeID,
                                             to: id,
+
                                             to: isLabelSet(id),
 
                                             label: properties[i],
 
                                             label: properties[i],
                                             color: colors[i],
+
                                             color: setColor,
                                            group: properties[i]
  −
                                        });
  −
                                    } else {
  −
                                        edges.add({
  −
                                            from: input.root,
  −
                                            to: id,
  −
                                            label: properties[i],
  −
                                            color: colors[i],
   
                                             group: properties[i]
 
                                             group: properties[i]
 
                                         });
 
                                         });
 
                                     }
 
                                     }
                                   
  −
                                } else {
  −
                                    edges.add({
  −
                                        from: nodeID,
  −
                                        to: isLabelSet(id),
  −
                                        label: properties[i],
  −
                                        color: setColor,
  −
                                        group: properties[i]
  −
                                    });
   
                                 }
 
                                 }
 
                             }
 
                             }
 +
                            network.setOptions(options);
 +
                            network.body.emitter.emit('_dataChanged');
 +
                            network.redraw();
 +
                        });
 +
                }
 +
                fetchData(input.root, input.properties);
 +
                // create a network
 +
                var container = this; //document.getElementById("InteractiveSemanticGraph");
 +
                var data = {
 +
                    nodes: nodes,
 +
                    edges: edges,
 +
                };
 +
                var options = {
 +
                    width: "100%",
 +
                    height: "100%",
 +
                    interaction: {
 +
                        hover: true
 +
                    },
 +
                    manipulation: {
 +
                        enabled: true,
 +
                        editEdge: false,
 +
                        deleteNode: function(data, callback) {
 +
                            deleteSelectedNode(data, callback)
 +
                        }.bind(this),
 +
                        deleteEdge: function(data, callback) {
 +
                            deleteSelectedEdge(data, callback)
 +
                        }.bind(this),
 +
                        addNode: function(data, callback) {
 +
                            // filling in the popup DOM elements
 +
                            document.getElementById("node-operation").innerText = "Add Node";
 +
                            dragElement(document.getElementById("node-popUp"));
 +
                            editNode(data, clearNodePopUp, callback);
 +
                        },
 +
                        addEdge: function(data, callback) {
 +
                            if (data.from == data.to) {
 +
                                var r = confirm("Do you want to connect the node to itself?");
 +
                                if (r != true) {
 +
                                    callback(null);
 +
                                    return;
 +
                                }
 +
                            }
 +
                            document.getElementById("edge-operation").innerText = "Add Edge";
 +
                            dragElement(document.getElementById("edge-popUp"));
 +
                            editEdgeWithoutDrag(data, callback);
 +
                        },
 +
                    },
 +
                    edges: {
 +
                        arrows: {
 +
                            to: {
 +
                                enabled: true
 +
                            },
 +
                            //from:{enabled: true}
 
                         }
 
                         }
                        network.setOptions(options);
+
                     },
                        network.body.emitter.emit('_dataChanged');
+
                    groups: {
                        network.redraw();
+
                        useDefaultGroups: false
                       
+
                    },
                     });
+
                    physics: {
            }
+
                        stabilization: {
            fetchData(input.root, input.properties);
+
                            enabled: true,
            // create a network
+
                        },
            var container = this; //document.getElementById("visNetworkGraph");
+
                        barnesHut: {
            var data = {
+
                            gravitationalConstant: -40000,
                nodes: nodes,
+
                            centralGravity: 0,
                edges: edges,
+
                            springLength: 0,
            };
+
                            springConstant: 0.5,
            var options = {
+
                            damping: 1,
                width: "100%",
+
                             avoidOverlap: 0
                height: "100%",
  −
                interaction: {
  −
                    hover: true
  −
                },
  −
                manipulation: {
  −
                    enabled: true,
  −
                    editEdge: false,
  −
                    deleteNode: function (data, callback) {deleteSelectedNode(data, callback)}.bind(this),
  −
                    deleteEdge: function (data, callback) {deleteSelectedEdge(data, callback)}.bind(this),
  −
                    addNode: function (data, callback) {
  −
                   
  −
        // filling in the popup DOM elements
  −
        document.getElementById("node-operation").innerText = "Add Node";
  −
        dragElement(document.getElementById("node-popUp"));
  −
        editNode(data, clearNodePopUp, callback);
  −
      },
  −
      addEdge: function (data, callback) {
  −
        if (data.from == data.to) {
  −
          var r = confirm("Do you want to connect the node to itself?");
  −
          if (r != true) {
  −
            callback(null);
  −
            return;
  −
          }
  −
        }
  −
        document.getElementById("edge-operation").innerText = "Add Edge";
  −
        dragElement(document.getElementById("edge-popUp"));
  −
        editEdgeWithoutDrag(data, callback);
  −
      },
  −
          },
  −
                edges: {
  −
                    arrows: {
  −
                        to: {
  −
                             enabled: true
   
                         },
 
                         },
                         //from:{enabled: true}
+
                         maxVelocity: 5
                    }
  −
                },
  −
                groups: {
  −
                    useDefaultGroups: false
  −
                },
  −
                physics: {
  −
                    stabilization: {
  −
                        enabled: true,
  −
                    },
  −
                    barnesHut: {
  −
                        gravitationalConstant: -40000,
  −
                        centralGravity: 0,
  −
                        springLength: 0,
  −
                        springConstant: 0.5,
  −
                        damping: 1,
  −
                        avoidOverlap: 0
   
                     },
 
                     },
                    maxVelocity: 5
  −
                },
  −
  −
            };
  −
            //Creates groups in the options and sets them all to hidden:false.
  −
            for (var i = 0; i < input.properties.length; i++) {
  −
                options.groups[input.properties[i]] = {
  −
                    hidden: false
   
                 };
 
                 };
            }
+
                //Creates groups in the options and sets them all to hidden:false.
            var network = new vis.Network(container, data, options);
+
                for (var i = 0; i < input.properties.length; i++) {
           
+
                    options.groups[input.properties[i]] = {
 
+
                        hidden: false
 
+
                    };
 
+
                }
function getAllEdgesBetween(node1,node2) {
+
                var network = new vis.Network(container, data, options);
    return edges.get().filter(function (edge) {
+
        return (edge.from === node1 && edge.to === node2 )|| (edge.from === node2 && edge.to === node1);
+
//The function getAllEdgesBetween() returns all edges between two nodes
    });
+
                function getAllEdgesBetween(node1, node2) {
}
+
                    return edges.get().filter(function(edge) {
 
+
                        return (edge.from === node1 && edge.to === node2) || (edge.from === node2 && edge.to === node1);
function getAllCombs(arrays){
+
                    });
    var numberOfCombs = 1;
+
                }
    for(var i=0; i<arrays.length; i++){
  −
        numberOfCombs = numberOfCombs * arrays[i].length;
  −
    }
  −
    var allCombs = new Array(numberOfCombs);
  −
    for(var i=0; i<allCombs.length; i++){
  −
        allCombs[i] = new Array(arrays.length);
  −
    }
  −
   
  −
    for(var i=0; i<arrays.length; i++){
  −
        var current = arrays[i];
  −
        for(var c=0; c<numberOfCombs; c++){
  −
  −
            for(var j=0; j<current.length; j++){
  −
                allCombs[c][i] = current[c%current.length];
   
                  
 
                  
            }
+
                //Cartesian Product of arrays
        }
+
                function cartesianProduct(arr) {
    }
+
    return arr.reduce(function(a,b){
+
        return a.map(function(x){
    return allCombs;
+
            return b.map(function(y){
}
+
                return x.concat([y]);
   
+
            })
function getEdgePathsForPath(path){
+
        }).reduce(function(a,b){ return a.concat(b) },[])
  var arraysOfEdgesForNodeInPath = [];
+
    }, [[]])
  for(var i=1; i<path.length; i++){
+
}
    var edgesBetween = getAllEdgesBetween(path[i-1], path[i]);
+
//Cartesian Product of given arrays
    var localedgesBetween = edgesBetween.slice();
+
                function getAllCombs(arrays) {
    arraysOfEdgesForNodeInPath.push(localedgesBetween);
+
                var allCombs = cartesianProduct(arrays);
  }
+
                    return allCombs;
  var allEdgePaths = getAllCombs(arraysOfEdgesForNodeInPath);
+
                }
return allEdgePaths;
+
//Gets Path array with nodes, returns Cartesian Product of edges
}
+
                function getEdgePathsForPath(path) {
 
+
                    var arraysOfEdgesForNodeInPath = [];
function reverseLabel(label){
+
                    for (var i = 1; i < path.length; i++) {
  if(label[0] == "-"){
+
                        var edgesBetween = getAllEdgesBetween(path[i - 1], path[i]);
    return label.substring(1);
+
                        var localedgesBetween = edgesBetween.slice();
  }
+
                       
  else{
+
                        arraysOfEdgesForNodeInPath.push(localedgesBetween);
    return "-" + label;
+
                    }
  }
+
                    var allEdgePaths = getAllCombs(arraysOfEdgesForNodeInPath);
}
+
                    return allEdgePaths;
 
+
                }
function getEdgeLabelStringsForPath(path){
+
//Given Label is reversed with "-" or "-" is removed
  var allEdgePaths = getEdgePathsForPath(path);
+
                function reverseLabel(label) {
  var allStrings = new Array(allEdgePaths.length);
+
                    if (label[0] == "-") {
  for(var i=0; i<allEdgePaths.length; i++){
+
                        return label.substring(1);
    var s = "";
+
                    } else {
    for(var j=0; j<allEdgePaths[i].length;j++){
+
                        return "-" + label;
     
+
                    }
      var edge = allEdgePaths[i][j];
+
                }
      var label = edge.label;
+
//Gets Path array with nodes, returns all possible edge paths
      var nodeId1 = path[j];
+
                function getEdgeLabelStringsForPath(path) {
      var nodeId2 = path[j+1];
+
                    var allEdgePaths = getEdgePathsForPath(path);
      if(edge.to == nodeId1 && edge.from == nodeId2){
+
                    var allStrings = new Array(allEdgePaths.length);
        label = reverseLabel(label);
+
                    for (var i = 0; i < allEdgePaths.length; i++) {
      }
+
                        var s = "";
      if(j == (allEdgePaths[i].length - 1)){
+
                        for (var j = 0; j < allEdgePaths[i].length; j++) {
        s = s + label;
+
                            var edge = allEdgePaths[i][j];
      }
+
                            var label = edge.label;
      else{
+
                            var nodeId1 = path[j];
        s = s + label + ".";
+
                            var nodeId2 = path[j + 1];
      }
+
                            if (edge.to == nodeId1 && edge.from == nodeId2) {
   
+
                                label = reverseLabel(label);
     
+
                            }
    }
+
                            if (j == (allEdgePaths[i].length - 1)) {
    allStrings[i] = s;
+
                                s = s + label;
  }
+
                            } else {
  return allStrings;
+
                                s = s + label + ".";
}
+
                            }
 
+
                        }
function getAllStringsForAllPaths(paths){
+
                        allStrings[i] = s;
  var arrayOfAllStrings = [];
+
                    }
  for(var i=0; i<paths.length;i++){
+
                    return allStrings;
    var path = paths[i];
+
                }
    var allStrings = getEdgeLabelStringsForPath(path);
+
//Gets Path arrays with nodes, returns all possible edge paths
    arrayOfAllStrings.push(allStrings);
+
                function getAllStringsForAllPaths(paths) {
  }
+
                    var arrayOfAllStrings = [];
return arrayOfAllStrings;
+
                    for (var i = 0; i < paths.length; i++) {
}
+
                        var path = paths[i];
 
+
                        var allStrings = getEdgeLabelStringsForPath(path);
 
+
                        arrayOfAllStrings.push(allStrings);
 
+
                    }
function removeItem(arr, value) {
+
                    return arrayOfAllStrings;
  var index = arr.indexOf(value);
+
                }
  if (index > -1) {
+
//Removes the given value from the given array
    arr.splice(index, 1);
+
                function removeItem(arr, value) {
  }
+
                    var index = arr.indexOf(value);
  return arr;
+
                    if (index > -1) {
}
+
                        arr.splice(index, 1);
 
+
                    }
 
+
                    return arr;
 
+
                }
 
+
//Returns all paths between startNode and endNode
function findAllPaths(startNode, endNode){
+
                function findAllPaths(startNode, endNode) {
    var visitedNodes = [];
+
                    var visitedNodes = [];
    var currentPath = [];
+
                    var currentPath = [];
    var allPaths = [];
+
                    var allPaths = [];
    dfs(startNode, endNode, currentPath, allPaths, visitedNodes);
+
                    dfs(startNode, endNode, currentPath, allPaths, visitedNodes);
    return allPaths;
+
                    return allPaths;
}
+
                }
 
+
//Algorithm to search for all paths between two nodes
function dfs(start, end, currentPath, allPaths, visitedNodes){
+
                function dfs(start, end, currentPath, allPaths, visitedNodes) {
    if(visitedNodes.includes(start)) return;
+
                    if (visitedNodes.includes(start)) return;
    visitedNodes.push(start);
+
                    visitedNodes.push(start);
    currentPath.push(start);
+
                    currentPath.push(start);
    if(start == end){
+
                    if (start == end) {
    var localCurrentPath = currentPath.slice();
+
                        var localCurrentPath = currentPath.slice();
        allPaths.push(localCurrentPath);
+
                        allPaths.push(localCurrentPath);
        removeItem(visitedNodes, start);
+
                        removeItem(visitedNodes, start);
        currentPath.pop();
+
                        currentPath.pop();
        return;
+
                        return;
    }
+
                    }
   
+
                    var neighbours = network.getConnectedNodes(start);
    var neighbours = network.getConnectedNodes(start);
+
                    for (var i = 0; i < neighbours.length; i++) {
    for(var i = 0; i < neighbours.length; i++){  
+
                        var current = neighbours[i];
        var current = neighbours[i];
+
                        dfs(current, end, currentPath, allPaths, visitedNodes);
        dfs(current, end, currentPath, allPaths, visitedNodes);
+
                    }
    }
+
                    currentPath.pop();
 
+
                    removeItem(visitedNodes, start);
    currentPath.pop();
  −
    removeItem(visitedNodes, start);
  −
 
  −
}
  −
 
  −
 
  −
 
  −
 
  −
 
  −
           
  −
           
  −
 
  −
            //This function deletes all children of a given node.
  −
            function getAllReachableNodesTo(nodeId, excludeIds, reachableNodes) {
  −
 
  −
                if (reachableNodes.includes(nodeId) || excludeIds.includes(nodeId)) { return;}
  −
                var children = network.getConnectedNodes(nodeId);
  −
                reachableNodes.push(nodeId);
  −
                for (var i = 0; i < children.length; i++) {
  −
                    getAllReachableNodesTo(children[i], excludeIds, reachableNodes);
  −
                    //if(excludeIds.includes(children[i]))continue;
  −
                    //reachableNodes.push(children[i]);
   
                 }
 
                 }
            }
+
                //Algorithm that gets all nodes that are reachable from the given node in the graph
           
+
                function getAllReachableNodesTo(nodeId, excludeIds, reachableNodes) {
            function deleteNodesChildren(nodeId, deleteEdge) {
+
                    if (reachableNodes.includes(nodeId) || excludeIds.includes(nodeId)) {
                var excludedIds = [];
+
                        return;
                if(deleteEdge === true){
+
                    }
                console.log("deleteEdge true")
+
                    var children = network.getConnectedNodes(nodeId);
                }else{
+
                    reachableNodes.push(nodeId);
                excludedIds.push(nodeId);
+
                    for (var i = 0; i < children.length; i++) {
 +
                        getAllReachableNodesTo(children[i], excludeIds, reachableNodes);
 +
                        //if(excludeIds.includes(children[i]))continue;
 +
                        //reachableNodes.push(children[i]);
 +
                    }
 
                 }
 
                 }
                 var reachableNodesTo = [];
+
//This function deletes all children of a given node.
                getAllReachableNodesTo(input.root, excludedIds, reachableNodesTo);
+
                 function deleteNodesChildren(nodeId, deleteEdge) {
                var nodesToDelete = [];
+
                    var excludedIds = [];
                var allIds = nodes.getIds();
+
                    if (deleteEdge === true) {
 
+
                        console.log("deleteEdge true")
                for (var i = 0; i < allIds.length; i++) {
+
                    } else {
                    if (reachableNodesTo.includes(allIds[i])) continue;
+
                        excludedIds.push(nodeId);
                    if (allIds[i] == nodeId) {
+
                    }
                    deleteEdges(nodeId);
+
                    var reachableNodesTo = [];
                    continue;
+
                    getAllReachableNodesTo(input.root, excludedIds, reachableNodesTo);
 +
                    var nodesToDelete = [];
 +
                    var allIds = nodes.getIds();
 +
                    for (var i = 0; i < allIds.length; i++) {
 +
                        if (reachableNodesTo.includes(allIds[i])) continue;
 +
                        if (allIds[i] == nodeId) {
 +
                            deleteEdges(nodeId);
 +
                            continue;
 +
                        }
 +
                        nodesToDelete.push(allIds[i]);
 +
                        deleteEdges(allIds[i]);
 +
                        nodes.remove(allIds[i]);
 +
                        delete oldGroups["" + allIds[i]];
 +
                        delete objClickedProps["" + allIds[i]];
 
                     }
 
                     }
                     nodesToDelete.push(allIds[i]);
+
                     return nodesToDelete;
                    deleteEdges(allIds[i]);
  −
                    nodes.remove(allIds[i]);
  −
                    delete oldGroups["" + allIds[i]];
  −
                    delete objClickedProps["" + allIds[i]];
   
                 }
 
                 }
 
+
//Deletes all edges from given node
                 return nodesToDelete;
+
                 function deleteEdges(nodeID) {
            }
+
                    var fromEdges = edges.get({
           
+
                        filter: function(item) {
function deleteEdges(nodeID){
+
                            return item.from == nodeID;
var fromEdges = edges.get({
+
                        }
                    filter: function (item) {
+
                    });
                        return item.from == nodeID;
+
                    for (var j = 0; j < fromEdges.length; j++) {
 +
                        edges.remove(fromEdges[j]);
 
                     }
 
                     }
                });
  −
               
  −
        for(var j = 0; j < fromEdges.length; j++){
  −
        edges.remove(fromEdges[j]);
  −
        }
  −
}
  −
var nodesClicked = [];
  −
var tip = '<p><strong>Hinweis:</strong> Um sich einen Pfad zwischen zwei Knoten ausgeben zu lassen, <em>Strg</em> gedrückt halten und die gewünschten zwei Knoten mit der <em>linken Maustaste</em> anklicken. </p>'
  −
this.insertAdjacentHTML('afterbegin', tip);
  −
  −
network.on("click", function(params) {
  −
  −
                if (params.nodes[0] && params.event.srcEvent.ctrlKey) {
  −
               
  −
                if(nodesClicked.length < 2){
  −
                nodesClicked.push(params.nodes[0]);
  −
                }
  −
                if(nodesClicked.length == 2 && nodesClicked[0] != nodesClicked[1]){
  −
                var foundPaths = findAllPaths(nodesClicked[0],nodesClicked[1]);
  −
                //.querySelector('[id^="poll-"]').id;
  −
                if(document.querySelectorAll('[id^="fullPath"]')){
  −
                for(var i=0; i < document.querySelectorAll('[id^="fullPath"]').length; i++){
  −
                document.querySelectorAll('[id^="fullPath"]')[i].remove();
  −
                }
  −
                }
  −
                var element = '<div id="fullPath'+ pathId +'"></div>'
  −
givenDiv.children[0].insertAdjacentHTML('afterend', element);
  −
  −
                var allStringsArray = getAllStringsForAllPaths(foundPaths);
  −
               
  −
                var stringDiv = givenDiv.querySelector('#fullPath' + pathId);
  −
               
  −
                if(foundPaths.length == 1){stringDiv.innerHTML = "<strong>Gefundener Pfad:</strong><br>"}else{stringDiv.innerHTML = "<strong>Gefundene Pfade:</strong><br>"}
  −
               
  −
                for(var s=0; s<foundPaths.length; s++){
  −
                if(foundPaths.length == 1){var pathNumb = ""}else{var pathNumb = "<strong>" + (s+1) + ". Pfad:</strong> <br>"}
  −
               
  −
                stringDiv.innerHTML += pathNumb + "<strong>Knoten: </strong>";
  −
  for(var t=0; t<foundPaths[s].length; t++){
  −
    var currentFoundPath = foundPaths[s][t];
  −
   
  −
    if(t == (foundPaths[s].length - 1)){
  −
        stringDiv.innerHTML = stringDiv.innerHTML + currentFoundPath + " ";
  −
    }
  −
    else{
  −
        stringDiv.innerHTML = stringDiv.innerHTML + currentFoundPath + " - ";
  −
    }
  −
  }
  −
  stringDiv.innerHTML += "<br>"
  −
  stringDiv.innerHTML += "<strong>Kanten:</strong> "
  −
  for(var t=0; t<allStringsArray[s].length; t++){
  −
    var currentString = allStringsArray[s][t];
  −
    var currentFoundPath = foundPaths[s][t];
  −
    var stringDiv = givenDiv.querySelector('#fullPath' + pathId);
  −
    stringDiv.innerHTML = stringDiv.innerHTML + currentString;
  −
  }
  −
  stringDiv.innerHTML += "<br>"
  −
}
  −
  −
                nodesClicked = [];
  −
  −
                }
  −
                if(nodesClicked[0] === nodesClicked[1] || nodesClicked.length > 2){
  −
                nodesClicked = [];
  −
                }
  −
               
  −
               
   
                 }
 
                 }
pathId++;
+
                var nodesClicked = [];
});
+
                var tip = '<p><strong>Hinweis:</strong> Um sich einen Pfad zwischen zwei Knoten ausgeben zu lassen, <em>Strg</em> gedrückt halten und die gewünschten zwei Knoten mit der <em>linken Maustaste</em> anklicken. </p>'
 
+
                this.insertAdjacentHTML('afterbegin', tip);
$(document).keyup(function(event) {
+
                //Ctrl and click on two nodes, puts out all possible paths between the two nodes under the tip
  if(!event.ctrlKey){
+
                network.on("click", function(params) {
  nodesClicked = [];
+
                    if (params.nodes[0] && params.event.srcEvent.ctrlKey) {
  }
+
                        if (nodesClicked.length < 2) {
});
+
                            nodesClicked.push(params.nodes[0]);
+
                        }
+
                        if (nodesClicked.length == 2 && nodesClicked[0] != nodesClicked[1]) {
+
                            var foundPaths = findAllPaths(nodesClicked[0], nodesClicked[1]);
+
                            //.querySelector('[id^="poll-"]').id;
+
                            if (document.querySelectorAll('[id^="fullPath"]')) {
 
+
                                for (var i = 0; i < document.querySelectorAll('[id^="fullPath"]').length; i++) {
            var contextCreatedProps = [];
+
                                    document.querySelectorAll('[id^="fullPath"]')[i].remove();
 
  −
            network.on("doubleClick", function(params) {
  −
  −
                if (params.nodes[0]) {
  −
               
  −
                var conManNodes = network.getConnectedNodes(params.nodes[0], 'to');
  −
               
  −
                var onlyConManNodes = true;
  −
                for(var i = 0; i < conManNodes.length;i++){
  −
               
  −
               
  −
                if(!(nodes.get(conManNodes[i]).oncontext || nodes.get(conManNodes[i]).manually)){
  −
                onlyConManNodes = false;
  −
                }
  −
                }
  −
               
  −
                //Node is expanded -> delete it and all nodes related to its expansion
  −
                    if (network.getConnectedNodes(params.nodes[0]).length > 1 && onlyConManNodes == false) {
  −
                        deleteNodesChildren(params.nodes[0]);
  −
                        for (var i = 0; i < contextCreatedProps.length; i++) {
  −
                            var noNodesInNetwork = true;
  −
                            for (var j = 0; j < nodes.getIds().length; j++) {
  −
                                if (contextCreatedProps[i] == nodes.get(nodes.getIds()[j]).group) {
  −
                                    noNodesInNetwork = false;
   
                                 }
 
                                 }
 
                             }
 
                             }
                             if (noNodesInNetwork === true) {
+
                             var element = '<div id="fullPath' + pathId + '"></div>'
                                givenDiv.querySelector('#' + contextCreatedProps[i]).remove();
+
                            givenDiv.children[0].insertAdjacentHTML('afterend', element);
                                contextCreatedProps.splice(contextCreatedProps.indexOf(contextCreatedProps[i]), 1);
+
                            var allStringsArray = getAllStringsForAllPaths(foundPaths);
                                 i--;
+
                            var stringDiv = givenDiv.querySelector('#fullPath' + pathId);
 +
                            if (foundPaths.length == 1) {
 +
                                stringDiv.innerHTML = "<strong>Gefundener Pfad:</strong><br>"
 +
                            } else {
 +
                                 stringDiv.innerHTML = "<strong>Gefundene Pfade:</strong><br>"
 
                             }
 
                             }
 +
                            for (var s = 0; s < foundPaths.length; s++) {
 +
                                if (foundPaths.length == 1) {
 +
                                    var pathNumb = ""
 +
                                } else {
 +
                                    var pathNumb = "<strong>" + (s + 1) + ". Pfad:</strong> <br>"
 +
                                }
 +
                                stringDiv.innerHTML += pathNumb + "<strong>Knoten: </strong>";
 +
                                for (var t = 0; t < foundPaths[s].length; t++) {
 +
                                    var currentFoundPath = foundPaths[s][t];
 +
                                    if (t == (foundPaths[s].length - 1)) {
 +
                                        stringDiv.innerHTML = stringDiv.innerHTML + currentFoundPath + " ";
 +
                                    } else {
 +
                                        stringDiv.innerHTML = stringDiv.innerHTML + currentFoundPath + " - ";
 +
                                    }
 +
                                }
 +
                                stringDiv.innerHTML += "<br>"
 +
                                stringDiv.innerHTML += "<strong>Kanten:</strong><br>"
 +
                                for (var t = 0; t < allStringsArray[s].length; t++) {
 +
                                    var currentString = allStringsArray[s][t];
 +
                                    var currentFoundPath = foundPaths[s][t];
 +
                                    var stringDiv = givenDiv.querySelector('#fullPath' + pathId);
 +
                                    stringDiv.innerHTML = stringDiv.innerHTML + '&#9679; ' + currentString + '<br>';
 +
                                }
 +
                                stringDiv.innerHTML += "<br>"
 +
                            }
 +
                            nodesClicked = [];
 +
                        }
 +
                        if (nodesClicked[0] === nodesClicked[1] || nodesClicked.length > 2) {
 +
                            nodesClicked = [];
 
                         }
 
                         }
                        delete objClickedProps["" + params.nodes[0]];
  −
                       
  −
                        //nodesArray.splice(nodesArray.indexOf(params.nodes[0]), 1);
  −
                    } else {
  −
                    //Node is unexpanded -> expand it
  −
                        var nodeById = nodes.get(params.nodes[0]);
  −
                        fetchData(nodeById.id, input.properties, params.nodes[0]);
  −
                        //nodesArray.push(params.nodes[0]);
   
                     }
 
                     }
 
+
                    pathId++;
                 }
+
                 });
            });
+
                $(document).keyup(function(event) {
           
+
                    if (!event.ctrlKey) {
            function newGroup(node, legendGroup) {
+
                        nodesClicked = [];
 +
                    }
 +
                });
 +
                var contextCreatedProps = [];
 
                  
 
                  
                 nodes.update({
+
                 network.on("doubleClick", function(params) {
                    id: node,
+
                    if (params.nodes[0]) {
                     group: legendGroup
+
                    //Checks if all node children are created from context menu or manually, if so it creates nodes for before defined properties else it deletes all children
 +
                        var conManNodes = network.getConnectedNodes(params.nodes[0], 'to');
 +
                        var onlyConManNodes = true;
 +
                        for (var i = 0; i < conManNodes.length; i++) {
 +
                            if (!(nodes.get(conManNodes[i]).oncontext || nodes.get(conManNodes[i]).manually)) {
 +
                                onlyConManNodes = false;
 +
                            }
 +
                        }
 +
                        //Node is expanded -> delete it and all nodes related to its expansion
 +
                        if (network.getConnectedNodes(params.nodes[0]).length > 1 && onlyConManNodes == false) {
 +
                            deleteNodesChildren(params.nodes[0]);
 +
                            for (var i = 0; i < contextCreatedProps.length; i++) {
 +
                                var noNodesInNetwork = true;
 +
                                for (var j = 0; j < nodes.getIds().length; j++) {
 +
                                    if (contextCreatedProps[i] == nodes.get(nodes.getIds()[j]).group) {
 +
                                        noNodesInNetwork = false;
 +
                                    }
 +
                                }
 +
                                if (noNodesInNetwork === true) {
 +
                                    givenDiv.querySelector('#' + contextCreatedProps[i]).remove();
 +
                                    contextCreatedProps.splice(contextCreatedProps.indexOf(contextCreatedProps[i]), 1);
 +
                                    i--;
 +
                                }
 +
                            }
 +
                            delete objClickedProps["" + params.nodes[0]];
 +
                            //nodesArray.splice(nodesArray.indexOf(params.nodes[0]), 1);
 +
                        } else {
 +
                            //Node is unexpanded -> expand it
 +
                            var nodeById = nodes.get(params.nodes[0]);
 +
                            fetchData(nodeById.id, input.properties, params.nodes[0]);
 +
                            //nodesArray.push(params.nodes[0]);
 +
                        }
 +
                     }
 
                 });
 
                 });
   −
 
+
                function newGroup(node, legendGroup) {
                var connectedNodes = network.getConnectedNodes(node, 'to');
+
                    nodes.update({
 
+
                        id: node,
                for (var i = 0; i < connectedNodes.length; i++) {
+
                        group: legendGroup
                    newGroup(connectedNodes[i], legendGroup);
+
                    });
 +
                    var connectedNodes = network.getConnectedNodes(node, 'to');
 +
                    for (var i = 0; i < connectedNodes.length; i++) {
 +
                        newGroup(connectedNodes[i], legendGroup);
 +
                    }
 
                 }
 
                 }
            }
+
                //Checks, if a node has a path over visible edges to the root node.
 
+
                //If not, the nodes gets hidden
//Checks, if a node has a path over visible edges to the root node.
+
                function setNodeVisibilityByVisiblePath(nodeId, rootNodeId) {
//If not, the nodes gets hidden
+
                    if (nodeId == rootNodeId) return true; //root is always visible
function setNodeVisibilityByVisiblePath(nodeId, rootNodeId){
+
                    var node = nodes.get(nodeId);
if (nodeId == rootNodeId) return true; //root is always visible
+
                    if (node.visited) return !node.hidden //prevent circles. ToDo: Reuse results between runs
var node = nodes.get(nodeId);
+
                    node.visited = true;
if (node.visited) return !node.hidden //prevent circles. ToDo: Reuse results between runs
+
                    node.hidden = true;
node.visited = true;
+
                    var connectedEdgesIds = network.getConnectedEdges(nodeId);
node.hidden = true;
+
                    var connectedEdges = edges.get(connectedEdgesIds);
var connectedEdgesIds = network.getConnectedEdges(nodeId);
+
                    connectedEdges.forEach(function(edge) {
var connectedEdges = edges.get(connectedEdgesIds);
+
                        if (edge.hidden) return; //don't follow hidden edges
connectedEdges.forEach(function(edge) {
+
                        var connectedNodesIds = network.getConnectedNodes(edge.id);
if (edge.hidden) return; //don't follow hidden edges
+
                        var connectedNodes = nodes.get(connectedNodesIds);
                    var connectedNodesIds = network.getConnectedNodes(edge.id);
+
                        connectedNodes.forEach(function(connectedNode) {
                    var connectedNodes = nodes.get(connectedNodesIds);
+
                            if (connectedNode.id == nodeId) return; //prevent self evaluation
                    connectedNodes.forEach(function(connectedNode) {
+
                            if (setNodeVisibilityByVisiblePath(connectedNode.id, rootNodeId)) {
                    if (connectedNode.id == nodeId) return; //prevent self evaluation
+
                                node.hidden = false; //set node visible, if at least one connected node is visible
                    if (setNodeVisibilityByVisiblePath(connectedNode.id, rootNodeId)) {
+
                            }
                    node.hidden = false; //set node visible, if at least one connected node is visible
+
                        });
                    }
   
                     });
 
                     });
                });
+
                    node.physics = !node.hidden; //disable physics for hidden nodes
                node.physics = !node.hidden;//disable physics for hidden nodes
+
                    return !node.hidden;
                return !node.hidden;
+
                }
}
     −
            function legendFunctionality() {
+
                function legendFunctionality() {
 
+
                    var legendGroup;
                var legendGroup;
+
                    var group;
                var group;
+
                    var nodeChildren;
                var nodeChildren;
+
                    legendGroup = this.parentNode.childNodes[1].innerHTML;
                legendGroup = this.parentNode.childNodes[1].innerHTML;
+
                    var strategy = "strategy2"
               
+
                    if (strategy == "strategy2") {
               
+
                        //A node is visible if at least one path over visible edges to the root node exists.
                var strategy = "strategy2"
+
                        options.groups[legendGroup].hidden = !options.groups[legendGroup].hidden; //toggle state
               
+
                        if (options.groups[legendGroup].hidden) this.parentNode.childNodes[1].style.background = '#FFFFFF';
                if (strategy == "strategy2"){
+
                        else this.parentNode.childNodes[1].style.background = '#DEF';
                //A node is visible if at least one path over visible edges to the root node exists.
+
                        //update all edges
                options.groups[legendGroup].hidden = !options.groups[legendGroup].hidden; //toggle state
+
                        edges.forEach(function(edge) {
                if(options.groups[legendGroup].hidden) this.parentNode.childNodes[1].style.background = '#FFFFFF';
+
                            edge.hidden = options.groups[edge.label].hidden;
                else this.parentNode.childNodes[1].style.background = '#DEF';
+
                            edge.physics = !edge.hidden;
                //update all edges
+
                        });
                edges.forEach(function(edge) {
+
                        //reset nodes
                    edge.hidden = options.groups[edge.label].hidden;
+
                        nodes.forEach(function(node) {
                    edge.physics = !edge.hidden;
+
                            node.hidden = false;
                });
+
                            node.physics = !node.hidden;
                //reset nodes
+
                            node.visited = false;
                    nodes.forEach(function(node) {
+
                        });
                    node.hidden = false;
+
                        //check each node
                    node.physics = !node.hidden;
+
                        nodes.forEach(function(node) {
                    node.visited = false;
+
                            setNodeVisibilityByVisiblePath(node.id, input.root)
                    });
+
                            //reset visited state. Todo: Reuse visited nodes between runs
                    //check each node
+
                            nodes.forEach(function(node) {
                    nodes.forEach(function(node) {
+
                                node.visited = false;
                    setNodeVisibilityByVisiblePath(node.id, input.root)
+
                            });
                    //reset visited state. Todo: Reuse visited nodes between runs
+
                        });
                    nodes.forEach(function(node) {
+
                    }
                    node.visited = false;
+
                    network.setOptions(options);
                    });
+
                    network.body.emitter.emit('_dataChanged');
 +
                    network.redraw();
 +
                    var allFalse = Object.keys(options.groups).every(function(k) {
 +
                        if (k === 'useDefaultGroups') {
 +
                            return true
 +
                        }
 +
                        return options.groups[k].hidden === false
 
                     });
 
                     });
                }
+
                     if (allFalse === true) {
               
+
                         /*oldGroups = {};*/
                network.setOptions(options);
  −
                network.body.emitter.emit('_dataChanged');
  −
                network.redraw();
  −
 
  −
                var allFalse = Object.keys(options.groups).every(function(k) {
  −
                     if (k === 'useDefaultGroups') {
  −
                         return true
   
                     }
 
                     }
                    return options.groups[k].hidden === false
+
                };
                 });
+
                var legendDiv = document.createElement("div");
                 if (allFalse === true) {
+
                this.append(legendDiv);
                     /*oldGroups = {};*/
+
                legendDiv.style.width = '100%';
 +
                legendDiv.style.position = 'relative';
 +
                legendDiv.style.display = 'inline-block';
 +
                legendDiv.id = "legendContainer";
 +
                 var legendColors = {};
 +
                 for (var i = 0; i < input.properties.length; i++) {
 +
                    legendColors[input.properties[i]] = colors[i];
 +
                    var propertyContainer = document.createElement("div");
 +
                    var propertyColor = document.createElement("div");
 +
                    var propertyName = document.createElement("div");
 +
                    propertyContainer.className = "legend-element-container";
 +
                    propertyContainer.id = input.properties[i];
 +
                    propertyColor.className = "color-container";
 +
                    propertyName.className = "name-container";
 +
                    propertyColor.style.float = "left";
 +
                    propertyName.style.float = "left";
 +
                    propertyColor.style.border = "1px solid black";
 +
                    propertyName.style.border = "1px solid black";
 +
                    propertyColor.style.background = colors[i];
 +
                    propertyColor.innerHTML = "";
 +
                    propertyName.innerHTML = input.properties[i];
 +
                    propertyColor.style.width = "30px";
 +
                    propertyColor.style.height = "30px";
 +
                    propertyName.style.height = "30px";
 +
                    propertyName.style.background = '#DEF';
 +
                     //propertyName.text-align = 'center';
 +
                    propertyContainer.paddinng = '5px 5px 5px 5px';
 +
                    propertyName.addEventListener("click", legendFunctionality);
 +
                    propertyColor.addEventListener("click", legendFunctionality);
 +
                    legendDiv.append(propertyContainer);
 +
                    propertyContainer.append(propertyColor);
 +
                    propertyContainer.append(propertyName);
 
                 }
 
                 }
            };
+
                 var ul = document.createElement("ul");
 
+
                ul.className = 'custom-menu';
            var legendDiv = document.createElement("div");
+
                document.body.append(ul);
            this.append(legendDiv);
+
                objClickedProps = {};
            legendDiv.style.width = '100%';
+
                objColors = {};
            legendDiv.style.position = 'relative';
+
                var start = 0;
            legendDiv.style.display = 'inline-block';
+
                //On a node right click it puts out all properties of the clicked node and a link to the node wiki-page
           
+
                network.on("oncontext", function(params) {
            legendDiv.id = "legendContainer";
+
                    params.event.preventDefault();
            var legendColors = {};
+
                    var timeNow = Date.now();
            for (var i = 0; i < input.properties.length; i++) {
+
                    var timeDiff = timeNow - start
                legendColors[input.properties[i]] = colors[i];
+
                    if (timeDiff > 300) {
                var propertyContainer = document.createElement("div");
+
                        start = Date.now();
                var propertyColor = document.createElement("div");
+
                        //console.log(nodes.get(network.getNodeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y })));
                var propertyName = document.createElement("div");
+
                        //console.log(edges.get(network.getEdgeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y })));
 
+
                        $('.custom-menu').each(function(index) {
                propertyContainer.className = "legend-element-container";
+
                            while (this.lastElementChild) {
                propertyContainer.id = input.properties[i];
+
                                this.removeChild(this.lastElementChild);
 
+
                            }
                propertyColor.className = "color-container";
+
                        });
 
+
                        if (!(network.getEdgeAt({
                propertyName.className = "name-container";
+
                                x: params.pointer.DOM.x,
 
+
                                y: params.pointer.DOM.y
                propertyColor.style.float = "left";
+
                            }) && network.getNodeAt({
                propertyName.style.float = "left";
+
                                x: params.pointer.DOM.x,
                propertyColor.style.border = "1px solid black";
+
                                y: params.pointer.DOM.y
                propertyName.style.border = "1px solid black";
+
                            }))) {
 
+
                            if (edges.get(network.getEdgeAt({
                propertyColor.style.background = colors[i];
+
                                    x: params.pointer.DOM.x,
                propertyColor.innerHTML = "";
+
                                    y: params.pointer.DOM.y
                propertyName.innerHTML = input.properties[i];
+
                                })).from) {
 
+
                                params.event.preventDefault();
                propertyColor.style.width = "30px";
+
                                if (edges.get(network.getEdgeAt({
                propertyColor.style.height = "30px";
+
                                        x: params.pointer.DOM.x,
                propertyName.style.height = "30px";
+
                                        y: params.pointer.DOM.y
                propertyName.style.background = '#DEF';
+
                                    })).label == 'Category') {
 
+
                                    var li = document.createElement("li");
                //propertyName.text-align = 'center';
+
                                    li.innerHTML = '' + '\uD83D\uDD17' + ' ' + edges.get(network.getEdgeAt({
                propertyContainer.paddinng = '5px 5px 5px 5px';
+
                                        x: params.pointer.DOM.x,
 
+
                                        y: params.pointer.DOM.y
                propertyName.addEventListener("click", legendFunctionality);
+
                                    })).to;
                propertyColor.addEventListener("click", legendFunctionality);
+
                                    li.addEventListener("click", function NewTab() {
 
+
                                        window.open('/wiki/' + edges.get(network.getEdgeAt({
                legendDiv.append(propertyContainer);
+
                                            x: params.pointer.DOM.x,
                propertyContainer.append(propertyColor);
+
                                            y: params.pointer.DOM.y
                 propertyContainer.append(propertyName);
+
                                        })).to);
 
+
                                    });
            }
+
                                    ul.prepend(li);
 
+
                                } else {
            var ul = document.createElement("ul");
+
                                    var li = document.createElement("li");
            ul.className = 'custom-menu';
+
                                    li.innerHTML = '' + '\uD83D\uDD17' + ' ' + edges.get(network.getEdgeAt({
            document.body.append(ul);
+
                                        x: params.pointer.DOM.x,
            objClickedProps = {};
+
                                        y: params.pointer.DOM.y
            objColors = {};
+
                                    })).label;
            var start = 0;
+
                                    li.addEventListener("click", function NewTab() {
           
+
                                        window.open('/wiki/' + 'Property:' + edges.get(network.getEdgeAt({
 
+
                                            x: params.pointer.DOM.x,
            network.on("oncontext", function(params) {
+
                                            y: params.pointer.DOM.y
            params.event.preventDefault();
+
                                        })).label);
            var timeNow = Date.now();
+
                                    });
            var timeDiff = timeNow - start
+
                                    ul.prepend(li);
            if(timeDiff > 300){
  −
            start = Date.now();
  −
                console.log(nodes.get(network.getNodeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y })));
  −
               
  −
//console.log(edges.get(network.getEdgeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y })));
  −
               
  −
                $('.custom-menu').each( function(index) {
  −
                while (this.lastElementChild) {
  −
                    this.removeChild(this.lastElementChild);
  −
                }});
  −
                if(!(network.getEdgeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y }) && network.getNodeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y }))){
  −
                if(edges.get(network.getEdgeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y })).from){
  −
                params.event.preventDefault();
  −
     
  −
                if(edges.get(network.getEdgeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y })).label == 'Category'){
  −
               
  −
                var li = document.createElement("li");
  −
                        li.innerHTML = '' + '\uD83D\uDD17' + ' ' + edges.get(network.getEdgeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y })).to;
  −
 
  −
                                li.addEventListener("click", function NewTab() {
  −
                                window.open('/wiki/' + edges.get(network.getEdgeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y })).to);
  −
                                });
  −
                                ul.prepend(li);}else{
  −
                                var li = document.createElement("li");
  −
                        li.innerHTML = '' + '\uD83D\uDD17' + ' ' + edges.get(network.getEdgeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y })).label;
  −
 
  −
                                li.addEventListener("click", function NewTab() {
  −
                                window.open('/wiki/' + 'Property:' + edges.get(network.getEdgeAt({ x: params.pointer.DOM.x, y: params.pointer.DOM.y })).label);
  −
                                });
  −
                                ul.prepend(li);
   
                                 }
 
                                 }
                        $(".custom-menu").finish().toggle(100).css({
+
                                $(".custom-menu").finish().toggle(100).css({
                        top: params.event.pageY + "px",
+
                                    top: params.event.pageY + "px",
                        left: params.event.pageX + "px",
+
                                    left: params.event.pageX + "px",
                        display: "block"
+
                                    display: "block"
                    });
  −
                }
  −
                }
  −
                if (network.getNodeAt({
  −
                        x: params.pointer.DOM.x,
  −
                        y: params.pointer.DOM.y
  −
                    })) {
  −
                    params.event.preventDefault();
  −
  −
const nodeID = nodes.get(network.getNodeAt({x: params.pointer.DOM.x,y: params.pointer.DOM.y})).id;
  −
const subject = nodeID.split("#")[0];
  −
var subObject = "";
  −
if (nodeID.split("#")[1]) {
  −
subObject = nodeID.split("#")[1].replace(" ", "_");
  −
}
  −
//inverse properties are only available in html format
  −
const query = `/w/api.php?action=smwbrowse&browse=subject&params={"subject":"${encodeURIComponent(subject)}","subobject":"${subObject}","options":{"showAll":"true"}, "ns":0, "type":"html"}&format=json`;
  −
 
  −
                    fetch(query)
  −
                        .then(response => response.json())
  −
                        .then(data => {
  −
                        var selected_node =  nodes.get(network.getNodeAt({
  −
                            x: params.pointer.DOM.x,
  −
                            y: params.pointer.DOM.y
  −
                        }));
  −
                        if (selected_node.url){
  −
                       
  −
                        var li = document.createElement("li");
  −
                        li.innerHTML = '' + '\uD83D\uDD17' + ' ' + selected_node.label;
  −
 
  −
                                li.addEventListener("click", function NewTab() {
  −
                                window.open(selected_node.url);
   
                                 });
 
                                 });
                                  
+
                            }
                                 ul.prepend(li);
+
                        }
                       
+
                        if (network.getNodeAt({
                        }
+
                                 x: params.pointer.DOM.x,
                        var page_properties = [];
+
                                y: params.pointer.DOM.y
                        $html = $(data.query);
+
                            })) {
$html.find("div.smwb-propvalue").each(function(){
+
                            params.event.preventDefault();
$prop = $(this).find("div.smwb-prophead a");
+
                            const nodeID = nodes.get(network.getNodeAt({
//var propName = $prop.text();
+
                                x: params.pointer.DOM.x,
//var propName = $prop.attr('title').replace("Property:", "");
+
                                y: params.pointer.DOM.y
var propName = "";
+
                            })).id;
if ($prop.attr('title') === "Special:Categories") propName += "Category";
+
                            var subject = nodeID.split("#")[0];
else propName += $prop.attr('href').split("Property:")[1].split("&")[0];
+
                            var subObject = "";
page_properties.push(propName);
+
                            if (nodeID.split("#")[1]) {
//console.log(propName);
+
                                 subObject = nodeID.split("#")[1].replace(" ", "_");
$(this).find("div.smwb-propval span.smwb-value").each(function(){
+
                            }
var value = $(this).find("a").attr("title");
+
                            var namespace_id = 0;
//console.log("-> " + value);
+
                            if (subject.split(":")[1]) {
});
+
                            const namespace = subject.split(":")[0];
})
+
                            subject = subject.split(":")[1];
$html.find("div.smwb-ipropvalue").each(function(){
+
                            namespace_id = mw.config.get('wgNamespaceIds')[namespace.replaceAll(" ","_").toLowerCase()];
$prop = $(this).find("div.smwb-prophead a");
+
                            //console.log(`Namespace ${namespace}, ID ${namespace_id}`);
//var propName = $prop.text();
+
                            }
//var propName = $prop.attr('title').replace("Property:", "");
+
                           
var propName = "-";
+
                            //inverse properties are only available in html format
if ($prop.attr('title') === "Special:Categories") propName += "Category";
+
                            const query = `/w/api.php?action=smwbrowse&browse=subject&params={"subject":"${encodeURIComponent(subject)}","subobject":"${subObject}","options":{"showAll":"true"}, "ns":${namespace_id}, "type":"html"}&format=json`;
else propName += $prop.attr('href').split("Property:")[1].split("&")[0];
+
                            fetch(query)
page_properties.push(propName);
+
                                .then(response => response.json())
//console.log(propName);
+
                                .then(data => {
$(this).find("div.smwb-propval span.smwb-ivalue").each(function(){
+
                                    var selected_node = nodes.get(network.getNodeAt({
var value = $(this).find("a").attr("title");
+
                                        x: params.pointer.DOM.x,
//console.log("-> " + value);
+
                                        y: params.pointer.DOM.y
});
+
                                    }));
})
+
                                    if (selected_node.url) {
for (var i = 0; i < page_properties.length; i++) {
+
                                        var li = document.createElement("li");
                            if (!page_properties[i].startsWith("_")) {
+
                                        li.innerHTML = '' + '\uD83D\uDD17' + ' ' + selected_node.label;
                                var li = document.createElement("li");
+
                                        li.addEventListener("click", function NewTab() {
                                li.dataset.action = page_properties[i].replaceAll('_',' ');
+
                                            window.open(selected_node.url);
                                li.innerHTML = page_properties[i].replaceAll('_',' ');
+
                                        });
                                ul.append(li);
+
                                        ul.prepend(li);
                            }
+
                                    }
                        }
+
                                    var page_properties = [];
                       
+
                                    $html = $(data.query);
                        /* old: use json result */
+
                                    $html.find("div.smwb-propvalue").each(function() {
                        /*
+
                                        $prop = $(this).find("div.smwb-prophead a");
 +
                                        //var propName = $prop.text();
 +
                                        //var propName = $prop.attr('title').replace("Property:", "");
 +
                                        var propName = "";
 +
                                        if ($prop.attr('title') === "Special:Categories") propName += "Category";
 +
                                        else if ($prop.attr('title') === "Special:ListRedirects") return;
 +
                                        else if ($prop.attr('href')) propName += $prop.attr('href').split("Property:")[1].split("&")[0];
 +
                                        else return; //empty property
 +
                                        page_properties.push(propName);
 +
                                        //console.log(propName);
 +
                                        $(this).find("div.smwb-propval span.smwb-value").each(function() {
 +
                                            var value = $(this).find("a").attr("title");
 +
                                            //console.log("-> " + value);
 +
                                        });
 +
                                    })
 +
                                    $html.find("div.smwb-ipropvalue").each(function() {
 +
                                        $prop = $(this).find("div.smwb-prophead a");
 +
                                        //var propName = $prop.text();
 +
                                        //var propName = $prop.attr('title').replace("Property:", "");
 +
                                        var propName = "-";
 +
                                        if ($prop.attr('title') === "Special:Categories") propName += "Category";
 +
                                        else if ($prop.attr('title') === "Special:ListRedirects") return;
 +
                                        else if ($prop.attr('href')) propName += $prop.attr('href').split("Property:")[1].split("&")[0];
 +
                                        else return; //empty property
 +
                                        page_properties.push(propName);
 +
                                        //console.log(propName);
 +
                                        $(this).find("div.smwb-propval span.smwb-ivalue").each(function() {
 +
                                            var value = $(this).find("a").attr("title");
 +
                                            //console.log("-> " + value);
 +
                                        });
 +
                                    })
 +
                                    for (var i = 0; i < page_properties.length; i++) {
 +
                                        if (!page_properties[i].startsWith("_")) {
 +
                                            var li = document.createElement("li");
 +
                                            li.dataset.action = page_properties[i].replaceAll('_', ' ');
 +
                                            li.innerHTML = page_properties[i].replaceAll('_', ' ');
 +
                                            ul.append(li);
 +
                                        }
 +
                                    }
 +
                                    /* old: use json result */
 +
                                    /*
 
                         var page_properties = data.query.data; //normal page
 
                         var page_properties = data.query.data; //normal page
 
                         if (selected_node.id.includes('#')) { //subobject
 
                         if (selected_node.id.includes('#')) { //subobject
Line 828: Line 771:  
                            }
 
                            }
 
                        }*/
 
                        }*/
 
+
                        //On left click on one of the properties it creates nodes for the clicked property and if the legend doesnt have that property as a legend entry it is created
                            $(".custom-menu li").click(function() {
+
                                    $(".custom-menu li").click(function() {
 
+
                                        var clickedProperty = [$(this).attr("data-action")]
                                var clickedProperty = [$(this).attr("data-action")]
+
                                        var clickedPropertyColor = randomHSL();
                               
+
                                        if (!(clickedProperty in legendColors)) {
                                var clickedPropertyColor = randomHSL();
+
                                            legendColors[clickedProperty] = clickedPropertyColor;
                               
+
                                        } else {
                                if(!(clickedProperty in legendColors)){legendColors[clickedProperty] = clickedPropertyColor; }else{clickedPropertyColor = legendColors[clickedProperty]; }
+
                                            clickedPropertyColor = legendColors[clickedProperty];
 
+
                                        }
                               
+
                                        if (objColors[clickedProperty]) {
 
+
                                            clickedPropertyColor = objColors[clickedProperty]
                                if (objColors[clickedProperty]) {
+
                                        } else {
                                    clickedPropertyColor = objColors[clickedProperty]
+
                                            objColors[clickedProperty] = clickedPropertyColor;
                                } else {
+
                                        }
                                    objColors[clickedProperty] = clickedPropertyColor;
+
                                        if (!objClickedProps[nodes.get(network.getNodeAt({
                                }
+
                                                x: params.pointer.DOM.x,
 
+
                                                y: params.pointer.DOM.y
 
+
                                            })).id]) {
                                if (!objClickedProps[nodes.get(network.getNodeAt({
+
                                            objClickedProps[nodes.get(network.getNodeAt({
                                        x: params.pointer.DOM.x,
+
                                                x: params.pointer.DOM.x,
                                        y: params.pointer.DOM.y
+
                                                y: params.pointer.DOM.y
                                    })).id]) {
+
                                            })).id] = new Array();
                                    objClickedProps[nodes.get(network.getNodeAt({
+
                                        }
                                        x: params.pointer.DOM.x,
+
                                        if (!objClickedProps["" + nodes.get(network.getNodeAt({
                                        y: params.pointer.DOM.y
+
                                                x: params.pointer.DOM.x,
                                    })).id] = new Array();
+
                                                y: params.pointer.DOM.y
                                }
+
                                            })).id].includes(clickedProperty[0])) {
 
+
                                            fetchData(nodes.get(network.getNodeAt({
 
+
                                                x: params.pointer.DOM.x,
 
+
                                                y: params.pointer.DOM.y
                                if (!objClickedProps["" + nodes.get(network.getNodeAt({
+
                                            })).id, clickedProperty, nodes.get(network.getNodeAt({
                                        x: params.pointer.DOM.x,
+
                                                x: params.pointer.DOM.x,
                                        y: params.pointer.DOM.y
+
                                                y: params.pointer.DOM.y
                                    })).id].includes(clickedProperty[0])) {
+
                                            })).id, clickedProperty, clickedPropertyColor)
                                    fetchData(nodes.get(network.getNodeAt({
+
                                            objClickedProps["" + nodes.get(network.getNodeAt({
                                        x: params.pointer.DOM.x,
+
                                                x: params.pointer.DOM.x,
                                        y: params.pointer.DOM.y
+
                                                y: params.pointer.DOM.y
                                    })).id, clickedProperty, nodes.get(network.getNodeAt({
+
                                            })).id].push(clickedProperty[0]);
                                        x: params.pointer.DOM.x,
+
                                        }
                                        y: params.pointer.DOM.y
+
                                        if (!(contextCreatedProps.includes(clickedProperty[0]) || input.properties.includes(clickedProperty[0]) /*|| legendColors[clickedProperty[0]]*/ )) {
                                    })).id, clickedProperty, clickedPropertyColor)
+
                                            contextCreatedProps.push(clickedProperty[0]);
                                    objClickedProps["" + nodes.get(network.getNodeAt({
+
                                            options.groups[clickedProperty] = {
                                        x: params.pointer.DOM.x,
+
                                                hidden: false
                                        y: params.pointer.DOM.y
+
                                            };
                                    })).id].push(clickedProperty[0]);
+
                                            var propertyContainer = document.createElement("div");
                                }
+
                                            var propertyColor = document.createElement("div");
 
+
                                            var propertyName = document.createElement("div");
                                if (!(contextCreatedProps.includes(clickedProperty[0]) || input.properties.includes(clickedProperty[0]) /*|| legendColors[clickedProperty[0]]*/ )) {
+
                                            propertyContainer.className = "legend-element-container";
 
+
                                            propertyContainer.id = clickedProperty;
                                    contextCreatedProps.push(clickedProperty[0]);
+
                                            propertyColor.className = "color-container";
 
+
                                            propertyName.className = "name-container";
                                    options.groups[clickedProperty] = {
+
                                            propertyColor.style.float = "left";
                                        hidden: false
+
                                            propertyName.style.float = "left";
                                    };
+
                                            propertyColor.style.border = "1px solid black";
 
+
                                            propertyName.style.border = "1px solid black";
                                    var propertyContainer = document.createElement("div");
+
                                            propertyContainer.style = "margin-right: 5px";
                                    var propertyColor = document.createElement("div");
+
                                            propertyColor.style.background = clickedPropertyColor;
                                    var propertyName = document.createElement("div");
+
                                            propertyColor.innerHTML = "";
                                   
+
                                            propertyName.innerHTML = clickedProperty;
 
+
                                            propertyColor.style.width = "30px";
                                    propertyContainer.className = "legend-element-container";
+
                                            propertyColor.style.height = "30px";
                                    propertyContainer.id = clickedProperty;
+
                                            propertyName.style.height = "30px";
 
+
                                            propertyName.style.background = '#DEF';
                                    propertyColor.className = "color-container";
+
                                            //propertyName.text-align = 'center';
 
+
                                            propertyName.margin = 'auto 5px auto 5px';
                                    propertyName.className = "name-container";
+
                                            propertyName.addEventListener("click", legendFunctionality);
 
+
                                            propertyColor.addEventListener("click", legendFunctionality);
                                    propertyColor.style.float = "left";
+
                                            legendDiv.append(propertyContainer);
                                    propertyName.style.float = "left";
+
                                            propertyContainer.append(propertyColor);
                                    propertyColor.style.border = "1px solid black";
+
                                            propertyContainer.append(propertyName);
                                    propertyName.style.border = "1px solid black";
+
                                        }
                                    propertyContainer.style = "margin-right: 5px";
+
                                        $(".custom-menu").hide(100);
 
+
                                    });
 
+
                                 });
                                    propertyColor.style.background = clickedPropertyColor;
+
                            $(".custom-menu").finish().toggle(100).css({
                                    propertyColor.innerHTML = "";
+
                                 top: params.event.pageY + "px",
                                    propertyName.innerHTML = clickedProperty;
+
                                left: params.event.pageX + "px",
 
+
                                display: "block"
                                    propertyColor.style.width = "30px";
+
                            });
                                    propertyColor.style.height = "30px";
+
                        }
                                    propertyName.style.height = "30px";
+
                    }
                                    propertyName.style.background = '#DEF';
+
                });
 
+
                // If the document is clicked somewhere it hides the context menu
                                    //propertyName.text-align = 'center';
+
                $(document).bind("mousedown", function(e) {
                                    propertyName.margin = 'auto 5px auto 5px';
+
                    // If the clicked element is not the menu
 
+
                    if (!$(e.target).parents(".custom-menu").length > 0) {
                                    propertyName.addEventListener("click", legendFunctionality);
+
                        // Hide it
                                    propertyColor.addEventListener("click", legendFunctionality);
+
                        $(".custom-menu").hide(100);
 
+
                    }
 
+
                });
                                    legendDiv.append(propertyContainer);
+
//Add Node popup
                                    propertyContainer.append(propertyColor);
+
                function editNode(data, cancelAction, callback) {
                                    propertyContainer.append(propertyName);
+
                    var newNodeActive = true;
 
+
                    document.getElementById("node-label").value = data.label;
                                 }
+
                    document.getElementById("node-saveButton").onclick = saveNodeData.bind(
 
+
                        this,
                                 $(".custom-menu").hide(100);
+
                        data,
 +
                        callback
 +
                    );
 +
                    document.getElementById("node-cancelButton").onclick = cancelAction.bind(
 +
                        this,
 +
                        callback
 +
                    );
 +
                    //document.getElementById("node-popUp")
 +
                    $('canvas').on('click', function(e) {
 +
                        if (newNodeActive === true) {
 +
                            $("#node-popUp").css({
 +
                                top: e.pageY + "px",
 +
                                left: e.pageX + "px",
 +
                                display: "block"
 
                             });
 
                             });
                         });
+
                         }
 
+
                         newNodeActive = false;
                    $(".custom-menu").finish().toggle(100).css({
  −
                         top: params.event.pageY + "px",
  −
                        left: params.event.pageX + "px",
  −
                        display: "block"
   
                     });
 
                     });
 
                 }
 
                 }
            }
+
            });
+
                function clearNodePopUp() {
            // If the document is clicked somewhere
+
                    document.getElementById("node-saveButton").onclick = null;
            $(document).bind("mousedown", function(e) {
+
                    document.getElementById("node-cancelButton").onclick = null;
 +
                    document.getElementById("node-popUp").style.display = "none";
 +
                }
   −
                 // If the clicked element is not the menu
+
                 function cancelNodeEdit(callback) {
                 if (!$(e.target).parents(".custom-menu").length > 0) {
+
                    clearNodePopUp();
 
+
                    callback(null);
                     // Hide it
+
                }
                     $(".custom-menu").hide(100);
+
//saveNodeData to the graph
 +
                 function saveNodeData(data, callback) {
 +
                    data.label = document.getElementById("node-label").value;
 +
                    data.id = document.getElementById("node-label").value;
 +
                    data.hidden = false;
 +
                     data.physics = false;
 +
                     document.getElementById("node-label").value = "";
 +
                    clearNodePopUp();
 +
                    callback(data);
 
                 }
 
                 }
            });
+
//addEdge popup
         
+
                function editEdgeWithoutDrag(data, callback) {
function editNode(data, cancelAction, callback) {
+
                    var newEdgeActive = true;
var newNodeActive = true;
+
                    // filling in the popup DOM elements
  document.getElementById("node-label").value = data.label;
+
                    document.getElementById("edge-label").value = data.label;
  document.getElementById("node-saveButton").onclick = saveNodeData.bind(
+
                   
    this,
+
                    document.getElementById("edge-saveButton").onclick = saveEdgeData.bind(
    data,
+
                        this,
    callback
+
                        data,
  );
+
                        callback
  document.getElementById("node-cancelButton").onclick = cancelAction.bind(
+
                    );
    this,
+
                    document.getElementById("edge-cancelButton").onclick = cancelEdgeEdit.bind(
    callback
+
                        this,
  );
+
                        callback
  //document.getElementById("node-popUp")
+
                    );
 
+
                    $('canvas').on('click', function(e) {
 
+
                        if (newEdgeActive === true) {
  $('canvas').on('click', function(e) {
+
                            $("#edge-popUp").css({
  if(newNodeActive === true){
+
                                top: e.pageY + "px",
    $("#node-popUp").css({
+
                                left: e.pageX + "px",
                        top: e.pageY + "px",
+
                                display: "block"
                        left: e.pageX + "px",
+
                            });
                        display: "block"
+
                        }
                        });}
  −
                        newNodeActive = false;
  −
                       
  −
});
  −
 
  −
}
  −
 
  −
// Callback passed as parameter is ignored
  −
function clearNodePopUp() {
  −
  document.getElementById("node-saveButton").onclick = null;
  −
  document.getElementById("node-cancelButton").onclick = null;
  −
  document.getElementById("node-popUp").style.display = "none";
  −
}
  −
 
  −
function cancelNodeEdit(callback) {
  −
  clearNodePopUp();
  −
  callback(null);
  −
}
  −
 
  −
function saveNodeData(data, callback) {
  −
  data.label = document.getElementById("node-label").value;
  −
  data.id = document.getElementById("node-label").value;
  −
  data.hidden = false;
  −
  data.physics = false;
  −
  document.getElementById("node-label").value = "";
  −
  clearNodePopUp();
  −
  callback(data);
  −
}
  −
 
  −
function editEdgeWithoutDrag(data, callback) {
  −
var newEdgeActive = true;
  −
  // filling in the popup DOM elements
  −
  document.getElementById("edge-label").value = data.label;
  −
    /*if(data.from === "H.1"){
  −
  console.log("here");
  −
  return;}*/
  −
  document.getElementById("edge-saveButton").onclick = saveEdgeData.bind(
  −
    this,
  −
    data,
  −
    callback
  −
  );
  −
  document.getElementById("edge-cancelButton").onclick = cancelEdgeEdit.bind(
  −
    this,
  −
    callback
  −
  );
  −
 
  −
  $('canvas').on('click', function(e) {
  −
  if(newEdgeActive === true){
  −
    $("#edge-popUp").css({
  −
                        top: e.pageY + "px",
  −
                        left: e.pageX + "px",
  −
                        display: "block"
  −
                        });}
   
                         newEdgeActive = false;
 
                         newEdgeActive = false;
});
+
                    });
  //document.getElementById("edge-popUp").style.display = "block";
+
                    //document.getElementById("edge-popUp").style.display = "block";
}
+
                }
   −
function clearEdgePopUp() {
+
                function clearEdgePopUp() {
  document.getElementById("edge-saveButton").onclick = null;
+
                    document.getElementById("edge-saveButton").onclick = null;
  document.getElementById("edge-cancelButton").onclick = null;
+
                    document.getElementById("edge-cancelButton").onclick = null;
  document.getElementById("edge-popUp").style.display = "none";
+
                    document.getElementById("edge-popUp").style.display = "none";
}
+
                }
   −
function cancelEdgeEdit(callback) {
+
                function cancelEdgeEdit(callback) {
  clearEdgePopUp();
+
                    clearEdgePopUp();
  callback(null);
+
                    callback(null);
}
+
                }
   −
function isLabelReversed(label){
+
                function isLabelReversed(label) {
  if(label[0] == "-"){
+
                    if (label[0] == "-") {
    return true;
+
                        return true;
  }
+
                    } else {
  else{
+
                        return false;
    return false;
+
                    }
  }
+
                }
}
+
                var pageBool;
 
+
                //Checks if page exists in the wiki
 
+
                async function pageExists(id) {
 
+
                    await fetch('/w/api.php?action=parse&page=' + id + '&prop=wikitext&format=json')
 
  −
 
  −
 
  −
var pageBool;
  −
async function pageExists(id){
  −
  −
await fetch('/w/api.php?action=parse&page='+ id +'&prop=wikitext&format=json')
   
                         .then(response => response.json())
 
                         .then(response => response.json())
 
                         .then(data => {
 
                         .then(data => {
                       
+
                            if (data.error) {
                        if(data.error){
+
                                pageBool = false;
                        pageBool = false;
+
                            } else {
                        }else{
+
                                pageBool = true;
                        pageBool = true;
+
                            }
                        }
  −
                       
   
                         })
 
                         })
return pageBool;
+
                    return pageBool;
}
+
                }
 
+
                var wikiText = "";
var wikiText = "";
+
                var semantic = "";
var semantic = "";
+
                //Splits Wikitext and Semantic/Element or Semantic/Link
async function editWikiText(node){
+
                async function editWikiText(node) {
await fetch('/w/api.php?action=parse&page='+ node +'&prop=wikitext&format=json')
+
                    await fetch('/w/api.php?action=parse&page=' + node + '&prop=wikitext&format=json')
 
                         .then(response => response.json())
 
                         .then(response => response.json())
 
                         .then(data => {
 
                         .then(data => {
                        wikiText = data.parse.wikitext['*'];
+
                            wikiText = data.parse.wikitext['*'];
                        semantic = "";
+
                            semantic = "";
if(wikiText.search(/(\{\{Semantic\/[^}]*[\r\n]*\}[\r\n]*\})/g) >= 0){
+
                            if (wikiText.search(/(\{\{Semantic\/[^}]*[\r\n]*\}[\r\n]*\})/g) >= 0) {
//var edgeStringFound = wikiText.search(re) >= 0;
+
                                //var edgeStringFound = wikiText.search(re) >= 0;
const found = wikiText.match(/(\{\{Semantic\/[^}]*[\r\n]*\}[\r\n]*\})/g);
+
                                const found = wikiText.match(/(\{\{Semantic\/[^}]*[\r\n]*\}[\r\n]*\})/g);
+
                                var newWikiText = wikiText;
var newWikiText = wikiText;
+
                                for (var i = 0; i < found.length; i++) {
for(var i=0; i<found.length;i++){
+
                                    if (i == found.length - 1) {
if(i == found.length-1){
+
                                        semantic += found[i];
semantic += found[i];
+
                                        newWikiText = newWikiText.replace(/(\{\{Semantic\/[^}]*[\r\n]*\}[\r\n]*\}[\r\n]*\}[\r\n]*\})/g, "");
newWikiText = newWikiText.replace(/(\{\{Semantic\/[^}]*[\r\n]*\}[\r\n]*\}[\r\n]*\}[\r\n]*\})/g, "");
+
                                        newWikiText = newWikiText.replace(/(\{\{Semantic\/Link[^}]*[\r\n]*\}[\r\n]*\})/g, "");
}else{
+
                                    } else {
semantic += found[i];
+
                                        semantic += found[i];
newWikiText = newWikiText.replace(found[i], "");
+
                                        newWikiText = newWikiText.replace(found[i], "");
}
+
                                     }
}
  −
wikiText = newWikiText;
  −
  −
  −
 
  −
 
  −
}
  −
});
  −
return [semantic, wikiText];
  −
}
  −
 
  −
 
  −
 
  −
async function saveEdgeData(data, callback) {
  −
  if (typeof data.to === "object") data.to = data.to.id;
  −
  if (typeof data.from === "object") data.from = data.from.id;
  −
 
  −
  data.label = document.getElementById("edge-label").value;
  −
  options.groups[data.label] = {hidden: false};
  −
  var toNode = nodes.get(data.to);
  −
  var fromNode = nodes.get(data.from);
  −
  fromNode.physics = true;
  −
  toNode.physics = true;
  −
  delete fromNode.x;
  −
  delete fromNode.y;
  −
  delete toNode.x;
  −
  delete toNode.y;
  −
  if(!toNode.group){toNode.group = data.label}
  −
  if(!fromNode.group){fromNode.group = data.label}
  −
  if(legendColors[data.label]){data.color = legendColors[data.label];}else{data.color = randomHSL(); }
  −
  if(!toNode.color){toNode.color = data.color; toNode.manually = true;}
  −
  if(!fromNode.color){fromNode.color = data.color; fromNode.manually = true;}
  −
 
  −
  if(!(contextCreatedProps.includes(data.label) || input.properties.includes(data.label))){
  −
  contextCreatedProps.push(data.label);
  −
var propertyContainer = document.createElement("div");
  −
    var propertyColor = document.createElement("div");
  −
    var propertyName = document.createElement("div");
  −
   
  −
 
  −
    propertyContainer.className = "legend-element-container";
  −
    propertyContainer.id = data.label;
  −
 
  −
    propertyColor.className = "color-container";
  −
 
  −
    propertyName.className = "name-container";
  −
 
  −
    propertyColor.style.float = "left";
  −
    propertyName.style.float = "left";
  −
    propertyColor.style.border = "1px solid black";
  −
    propertyName.style.border = "1px solid black";
  −
    propertyContainer.style = "margin-right: 5px";
  −
 
  −
 
  −
    propertyColor.style.background = data.color;
  −
    propertyColor.innerHTML = "";
  −
    propertyName.innerHTML = data.label;
  −
 
  −
    propertyColor.style.width = "30px";
  −
    propertyColor.style.height = "30px";
  −
    propertyName.style.height = "30px";
  −
    propertyName.style.background = '#DEF';
  −
 
  −
    //propertyName.text-align = 'center';
  −
    propertyName.margin = 'auto 5px auto 5px';
  −
 
  −
    propertyName.addEventListener("click", legendFunctionality);
  −
    propertyColor.addEventListener("click", legendFunctionality);
  −
 
  −
 
  −
    legendDiv.append(propertyContainer);
  −
    propertyContainer.append(propertyColor);
  −
    propertyContainer.append(propertyName);
  −
  legendColors[data.label] = data.color;
  −
  }
  −
  if(isLabelReversed(data.label)){
  −
  if(await pageExists(fromNode.id) === false){
  −
  if(!(newNodes[fromNode.id])){
  −
  newNodes[fromNode.id] = '' + '{{Semantic/Element' +
  −
'|label=' + fromNode.label +
  −
'|description=test' +
  −
'|relations=';
  −
  }
  −
 
  −
  }
  −
 
  −
  if(await pageExists(toNode.id) === true){
  −
  var splitWikiText = await editWikiText(toNode.id);
  −
  if(editNodes[toNode.id]){
  −
  editNodes[toNode.id] += '' + '{{Semantic/Link'+
  −
'|property=' + reverseLabel(data.label) +
  −
'|value=' + fromNode.id +
  −
'}}' + '';
  −
 
  −
  }else{
  −
  if(splitWikiText[0]){
  −
  editNodes[toNode.id] = splitWikiText[1] + splitWikiText[0] + '{{Semantic/Link'+
  −
'|property=' + reverseLabel(data.label) +
  −
'|value=' + fromNode.id +
  −
'}}' + '';
  −
  }else{
  −
  editNodes[toNode.id] = splitWikiText[1] + '{{Semantic/Element' +
  −
'|label=' + toNode.label +
  −
'|description=test' +
  −
'|relations='+
  −
  '{{Semantic/Link'+
  −
'|property=' + reverseLabel(data.label) +
  −
'|value=' + fromNode.id +
  −
'}}' + '';
  −
  }
  −
  }
  −
  }else{
  −
  if(newNodes[toNode.id]){
  −
  newNodes[toNode.id] += '' + '{{Semantic/Link'+
  −
'|property=' + reverseLabel(data.label) +
  −
'|value=' + fromNode.id +
  −
'}}' + '';
  −
  }else{
  −
  newNodes[toNode.id] = '' + '{{Semantic/Element' +
  −
'|label=' + toNode.label +
  −
'|description=test' +
  −
'|relations={{Semantic/Link'+
  −
'|property=' + reverseLabel(data.label) +
  −
'|value=' + fromNode.id +
  −
'}}'+
  −
'';
  −
  }
  −
  }
  −
 
  −
  }else{
  −
 
  −
  if(await pageExists(toNode.id) === false){
  −
  if(!(newNodes[toNode.id])){
  −
  newNodes[toNode.id] = '' + '{{Semantic/Element' +
  −
'|label=' + toNode.label +
  −
'|description=test' +
  −
'|relations=';
  −
  }
  −
  }
  −
  if(await pageExists(fromNode.id) === true){
  −
  var splitWikiText = await editWikiText(fromNode.id);
  −
  if(editNodes[fromNode.id]){
  −
  editNodes[fromNode.id] += '' + '{{Semantic/Link'+
  −
'|property=' + data.label +
  −
'|value=' + toNode.id +
  −
'}}' + '';
  −
  }else{
  −
  if(splitWikiText[0]){
  −
  editNodes[fromNode.id] = splitWikiText[1] +  splitWikiText[0] + '{{Semantic/Link'+
  −
'|property=' + data.label +
  −
'|value=' + toNode.id +
  −
'}}' + '';
  −
  }else{
  −
  editNodes[fromNode.id] = splitWikiText[1] + '{{Semantic/Element' +
  −
'|label=' + fromNode.label +
  −
'|description=test' +
  −
'|relations='+
  −
  '{{Semantic/Link'+
  −
'|property=' + data.label +
  −
'|value=' + toNode.id +
  −
'}}' + '';
  −
  }
  −
  }
  −
  }else{
  −
  if(newNodes[fromNode.id]){
  −
  newNodes[fromNode.id] += '' + '{{Semantic/Link'+
  −
'|property=' + data.label +
  −
'|value=' + toNode.id +
  −
'}}' + '';
  −
 
  −
  }else{
  −
  newNodes[fromNode.id] = '' + '{{Semantic/Element' +
  −
'|label=' + fromNode.label +
  −
'|description=test' +
  −
'|relations={{Semantic/Link'+
  −
'|property=' + data.label +
  −
'|value=' + toNode.id +
  −
'}}'+
  −
'';
  −
  −
  }
  −
  }
  −
 
  −
  }
  −
 
  −
  //console.log(toNode);
  −
  //console.log(fromNode);
  −
 
  −
console.log(editNodes);
  −
console.log(newNodes);
  −
 
  −
  clearEdgePopUp();
  −
  callback(data);
  −
  network.setOptions(options);
  −
  network.body.emitter.emit('_dataChanged');
  −
  network.redraw();
  −
}
  −
    var saveBtn= document.createElement("button");
  −
            saveBtn.addEventListener("click", saveGraphChanges);
  −
            saveBtn.innerHTML = "Speichern";
  −
            saveBtn.style.width = "auto";
  −
            saveBtn.style.height = "auto";
  −
 
  −
givenDiv.appendChild(saveBtn);
  −
function saveGraphChanges() {
  −
var alertString = "";
  −
OO.ui.confirm( 'Änderungen übernehmen?' ).done( async function ( confirmed ) {
  −
    if ( confirmed ) {
  −
for (const [key, value] of Object.entries(newNodes)) {
  −
  var params = {
  −
action: 'edit',
  −
title: '' + key,
  −
appendtext: '' + value + '}}',
  −
format: 'json'
  −
},
  −
api = new mw.Api();
  −
  −
await api.postWithToken( 'csrf', params ).done( function ( data ) {
  −
console.log( data );
  −
alertString += "Seite " + key + " erstellt!\r\n"
  −
} );
  −
}
  −
  −
for (const [key, value] of Object.entries(editNodes)) {
  −
  var params = {
  −
action: 'edit',
  −
title: '' + key,
  −
text: '' + value + '}}',
  −
format: 'json'
  −
},
  −
api = new mw.Api();
  −
  −
await api.postWithToken( 'csrf', params ).done( function ( data ) {
  −
console.log( data );
  −
alertString += "Seite " + key + " bearbeitet!\r\n"
  −
} );
  −
}
  −
  −
for (const [key, value] of Object.entries(editDeletedEdges)) {
  −
  var params = {
  −
action: 'edit',
  −
title: '' + key,
  −
text: '' + value,
  −
format: 'json'
  −
},
  −
api = new mw.Api();
  −
  −
await api.postWithToken( 'csrf', params ).done( function ( data ) {
  −
console.log( data );
  −
alertString += "Auf der Seite " + key + " wurde ein Attribut gelöscht!\r\n"
  −
} );
  −
}
  −
  −
for (const [key, value] of Object.entries(editDeletedNodes)) {
  −
  var params = {
  −
action: 'delete',
  −
title: '' + key,
  −
format: 'json'
  −
},
  −
api = new mw.Api();
  −
await api.postWithToken( 'csrf', params ).done( function ( data ) {
  −
console.log( data );
  −
alertString += "Seite " + key + " wurde gelöscht!\r\n"
  −
} );
  −
}
  −
console.log( alertString );
  −
// Example: Customize the displayed actions at the time the window is opened.
  −
var messageDialog = new OO.ui.MessageDialog();
  −
  −
// Create and append a window manager.
  −
var windowManager = new OO.ui.WindowManager();
  −
$( 'body' ).append( windowManager.$element );
  −
  −
// Add the dialog to the window manager.
  −
windowManager.addWindows( [ messageDialog ] );
  −
  −
// Configure the message dialog when it is opened with the window manager's openWindow() method.
  −
  −
windowManager.openWindow( messageDialog, {
  −
  title: 'Folgende Änderugnen wurden übernommen:',
  −
  message: '' + alertString,
  −
  verbose: true,
  −
  actions: [
  −
    {
  −
      action: 'accept',
  −
      label: 'Okay',
  −
      flags: 'primary'
  −
    }
  −
  ]
  −
});
  −
/*OO.ui.alert( "" + alertString ).done( function () {
  −
    console.log( alertString );
  −
} );*/
  −
  −
    } else {
  −
       
  −
    }
  −
   
  −
} );
  −
  −
 
  −
}
  −
  −
 
  −
 
  −
 
  −
function deleteSelectedNode(data, callback){
  −
console.log(contextCreatedProps);
  −
deleteNodesChildren(data.nodes[0]);
  −
nodes.remove(data.nodes[0]);
  −
                        for (var i = 0; i < contextCreatedProps.length; i++) {
  −
                            var noNodesInNetwork = true;
  −
                            for (var j = 0; j < nodes.getIds().length; j++) {
  −
                                if (contextCreatedProps[i] == nodes.get(nodes.getIds()[j]).group) {
  −
                               
  −
                                     noNodesInNetwork = false;
   
                                 }
 
                                 }
 +
                                wikiText = newWikiText;
 
                             }
 
                             }
                            if (noNodesInNetwork === true) {
+
                        });
                           
+
                    return [semantic, wikiText];
                                givenDiv.querySelector('#' + contextCreatedProps[i]).remove();
+
                }
                                contextCreatedProps.splice(contextCreatedProps.indexOf(contextCreatedProps[i]), 1);
+
                //Save button on create edge popup
                                 i--;
+
                async function saveEdgeData(data, callback) {
 +
                //Sets various options to the nodes that the edge gets connected
 +
                    if (typeof data.to === "object") data.to = data.to.id;
 +
                    if (typeof data.from === "object") data.from = data.from.id;
 +
                    data.label = document.getElementById("edge-label").value;
 +
                    options.groups[data.label] = {
 +
                        hidden: false
 +
                    };
 +
                    var toNode = nodes.get(data.to);
 +
                    var fromNode = nodes.get(data.from);
 +
                    fromNode.physics = true;
 +
                    toNode.physics = true;
 +
                    delete fromNode.x;
 +
                    delete fromNode.y;
 +
                    delete toNode.x;
 +
                    delete toNode.y;
 +
                    if (!toNode.group) {
 +
                        toNode.group = data.label
 +
                    }
 +
                    if (!fromNode.group) {
 +
                        fromNode.group = data.label
 +
                    }
 +
                    if (legendColors[data.label]) {
 +
                        data.color = legendColors[data.label];
 +
                    } else {
 +
                        data.color = randomHSL();
 +
                    }
 +
                    if (!toNode.color) {
 +
                        toNode.color = data.color;
 +
                        toNode.manually = true;
 +
                    }
 +
                    if (!fromNode.color) {
 +
                        fromNode.color = data.color;
 +
                        fromNode.manually = true;
 +
                    }
 +
                    //If the given property is not set in the legend, a legend entry is created
 +
                    if (!(contextCreatedProps.includes(data.label) || input.properties.includes(data.label))) {
 +
                        contextCreatedProps.push(data.label);
 +
                        var propertyContainer = document.createElement("div");
 +
                        var propertyColor = document.createElement("div");
 +
                        var propertyName = document.createElement("div");
 +
                        propertyContainer.className = "legend-element-container";
 +
                        propertyContainer.id = data.label;
 +
                        propertyColor.className = "color-container";
 +
                        propertyName.className = "name-container";
 +
                        propertyColor.style.float = "left";
 +
                        propertyName.style.float = "left";
 +
                        propertyColor.style.border = "1px solid black";
 +
                        propertyName.style.border = "1px solid black";
 +
                        propertyContainer.style = "margin-right: 5px";
 +
                        propertyColor.style.background = data.color;
 +
                        propertyColor.innerHTML = "";
 +
                        propertyName.innerHTML = data.label;
 +
                        propertyColor.style.width = "30px";
 +
                        propertyColor.style.height = "30px";
 +
                        propertyName.style.height = "30px";
 +
                        propertyName.style.background = '#DEF';
 +
                        //propertyName.text-align = 'center';
 +
                        propertyName.margin = 'auto 5px auto 5px';
 +
                        propertyName.addEventListener("click", legendFunctionality);
 +
                        propertyColor.addEventListener("click", legendFunctionality);
 +
                        legendDiv.append(propertyContainer);
 +
                        propertyContainer.append(propertyColor);
 +
                        propertyContainer.append(propertyName);
 +
                        legendColors[data.label] = data.color;
 +
                    }
 +
                    //Creates new wikitext that will be saved after the save button is clicked
 +
                    if (isLabelReversed(data.label)) {
 +
                        if (await pageExists(fromNode.id) === false) {
 +
                            if (!(newNodes[fromNode.id])) {
 +
                                 newNodes[fromNode.id] = '' + '{{Semantic/Element' +
 +
                                    '|label=' + fromNode.label +
 +
                                    '|description=test' +
 +
                                    '|relations=';
 
                             }
 
                             }
 
                         }
 
                         }
 
+
                         if (await pageExists(toNode.id) === true) {
                          
+
                            var splitWikiText = await editWikiText(toNode.id);
    delete oldGroups["" + data.nodes[0]];
+
                            if (editNodes[toNode.id]) {
                       
+
                                editNodes[toNode.id] += '' + '{{Semantic/Link' +
                        delete objClickedProps["" + data.nodes[0]];
+
                                    '|property=' + reverseLabel(data.label) +
                        callback();
+
                                    '|value=' + fromNode.id +
                        document.querySelector('.vis-delete').remove();
+
                                    '}}' + '';
editDeletedNodes[""+data.nodes[0]] = "";
+
                            } else {
delete newNodes[""+data.nodes[0]];
+
                                if (splitWikiText[0].search(/(\{\{Semantic\/Element[^}]*[\r\n]*\}[\r\n]*\})/g) >= 0) {
delete editNodes[""+data.nodes[0]];
+
                                    editNodes[toNode.id] = splitWikiText[1] + splitWikiText[0] + '{{Semantic/Link' +
console.log(editDeletedNodes);
+
                                        '|property=' + reverseLabel(data.label) +
 
+
                                        '|value=' + fromNode.id +
}
+
                                        '}}' + '';
 
+
                                } else {
async function deleteSelectedEdge(data, callback){
+
                                    editNodes[toNode.id] = splitWikiText[1] + '{{Semantic/Element' +
var edgeToNode = edges.get(data.edges[0]).to;
+
                                        '|label=' + toNode.label +
var edgeFromNode = edges.get(data.edges[0]).from;
+
                                        '|description=test' +
var edgeLabel = edges.get(data.edges[0]).label;
+
                                        '|relations=' +
console.log(edgeLabel);
+
                                        '{{Semantic/Link' +
edges.remove(data.edges[0]);
+
                                        '|property=' + reverseLabel(data.label) +
deleteNodesChildren(edgeToNode, true);
+
                                        '|value=' + fromNode.id +
deleteNodesChildren(edgeFromNode, true);
+
                                        '}}' + '' + splitWikiText[0];
  −
for (var i = 0; i < contextCreatedProps.length; i++) {
  −
                            var noNodesInNetwork = true;
  −
                            for (var j = 0; j < nodes.getIds().length; j++) {
  −
                                if (contextCreatedProps[i] == nodes.get(nodes.getIds()[j]).group) {
  −
                               
  −
                                    noNodesInNetwork = false;
   
                                 }
 
                                 }
 
                             }
 
                             }
                             if (noNodesInNetwork === true) {
+
                        } else {
                           
+
                             if (newNodes[toNode.id]) {
                                 givenDiv.querySelector('#' + contextCreatedProps[i]).remove();
+
                                 newNodes[toNode.id] += '' + '{{Semantic/Link' +
                                 contextCreatedProps.splice(contextCreatedProps.indexOf(contextCreatedProps[i]), 1);
+
                                    '|property=' + reverseLabel(data.label) +
                                i--;
+
                                    '|value=' + fromNode.id +
 +
                                    '}}' + '';
 +
                            } else {
 +
                                 newNodes[toNode.id] = '' + '{{Semantic/Element' +
 +
                                    '|label=' + toNode.label +
 +
                                    '|description=test' +
 +
                                    '|relations={{Semantic/Link' +
 +
                                    '|property=' + reverseLabel(data.label) +
 +
                                    '|value=' + fromNode.id +
 +
                                    '}}' +
 +
                                    '';
 
                             }
 
                             }
 
                         }
 
                         }
+
                    } else {
if(edgeLabel[0] == "-"){
+
                        if (await pageExists(toNode.id) === false) {
if(await pageExists(edgeToNode) === true){
+
                            if (!(newNodes[toNode.id])) {
await fetch('/w/api.php?action=parse&page='+ edgeToNode +'&prop=wikitext&format=json')
+
                                newNodes[toNode.id] = '' + '{{Semantic/Element' +
                        .then(response => response.json())
+
                                    '|label=' + toNode.label +
                        .then(data => {
+
                                    '|description=test' +
                        var wikiText = data.parse.wikitext['*'];
+
                                    '|relations=';
console.log(wikiText);
+
                            }
  −
                        var edgeString = `(\{\{Semantic\/Link[\\r\\n]*\\|[\\r\\n]*property=`+reverseLabel(edgeLabel)+`[\\r\\n]*\\|[\\r\\n]*value=`+edgeFromNode+`[\\r\\n]*\\}[\\r\\n]*\\}[\\r\\n]*)`
  −
//var edgeString = '(\\{\\{Semantic\/Element[^}]*[\\r\\n]*\\}[\\r\\n]*\\}[\\r\\n]*[\\r\\n]*\\}[\\r\\n]*\\})'
  −
var re = new RegExp(edgeString,"g");
  −
                       
  −
                        var edgeStringFound = wikiText.search(re) >= 0;
  −
                       
  −
                        if(edgeStringFound){
  −
                        if(editDeletedEdges[""+ edgeToNode]){
  −
                        var newWikiText = editDeletedEdges[""+ edgeToNode].replace(re, "");
  −
                        editDeletedEdges[""+ edgeToNode] = newWikiText;
  −
                        }else{
  −
                        var newWikiText = wikiText.replace(re, "");
  −
                        console.log(newWikiText)
  −
                        editDeletedEdges[""+ edgeToNode] = newWikiText;
  −
                        }
  −
   
   
                         }
 
                         }
                          
+
                         if (await pageExists(fromNode.id) === true) {
                        if(newNodes[""+edgeToNode]){
+
                            var splitWikiText = await editWikiText(fromNode.id);
                       
+
                            if (editNodes[fromNode.id]) {
                        var newWikiText = newNodes[""+edgeToNode].replace(re, "");
+
                                editNodes[fromNode.id] += '' + '{{Semantic/Link' +
                        newNodes[""+edgeToNode] = newWikiText;
+
                                    '|property=' + data.label +
 
+
                                    '|value=' + toNode.id +
 +
                                    '}}' + '';
 +
                            } else {
 +
                                if (splitWikiText[0].search(/(\{\{Semantic\/Element[^}]*[\r\n]*\}[\r\n]*\})/g) >= 0) {
 +
                                    editNodes[fromNode.id] = splitWikiText[1] + splitWikiText[0] + '{{Semantic/Link' +
 +
                                        '|property=' + data.label +
 +
                                        '|value=' + toNode.id +
 +
                                        '}}' + '';
 +
                                } else {
 +
                                    editNodes[fromNode.id] = splitWikiText[1] + '{{Semantic/Element' +
 +
                                        '|label=' + fromNode.label +
 +
                                        '|description=test' +
 +
                                        '|relations=' +
 +
                                        '{{Semantic/Link' +
 +
                                        '|property=' + data.label +
 +
                                        '|value=' + toNode.id +
 +
                                        '}}' + '' + splitWikiText[0];
 +
                                }
 +
                            }
 +
                        } else {
 +
                            if (newNodes[fromNode.id]) {
 +
                                newNodes[fromNode.id] += '' + '{{Semantic/Link' +
 +
                                    '|property=' + data.label +
 +
                                    '|value=' + toNode.id +
 +
                                    '}}' + '';
 +
                            } else {
 +
                                newNodes[fromNode.id] = '' + '{{Semantic/Element' +
 +
                                    '|label=' + fromNode.label +
 +
                                    '|description=test' +
 +
                                    '|relations={{Semantic/Link' +
 +
                                    '|property=' + data.label +
 +
                                    '|value=' + toNode.id +
 +
                                    '}}' +
 +
                                    '';
 +
                            }
 
                         }
 
                         }
                       
+
                    }
                         if(editNodes[""+edgeToNode]){
+
                    //console.log(toNode);
                       
+
                    //console.log(fromNode);
                        var newWikiText = editNodes[""+edgeToNode].replace(re, "");
+
                    //console.log(editNodes);
                        editNodes[""+edgeToNode] = newWikiText;
+
                    //console.log(newNodes);
                       
+
                    clearEdgePopUp();
 +
                    callback(data);
 +
                    network.setOptions(options);
 +
                    network.body.emitter.emit('_dataChanged');
 +
                    network.redraw();
 +
                }
 +
                //save button
 +
                var saveBtn = document.createElement("button");
 +
                saveBtn.addEventListener("click", saveGraphChanges);
 +
                saveBtn.innerHTML = "Speichern";
 +
                saveBtn.style.width = "auto";
 +
                saveBtn.style.height = "auto";
 +
                givenDiv.appendChild(saveBtn);
 +
 +
//Called on save button click. Creates new wiki pages or edits them with the created wiki text.
 +
                function saveGraphChanges() {
 +
                    var alertString = "";
 +
                    OO.ui.confirm('Änderungen übernehmen?').done(async function(confirmed) {
 +
                         if (confirmed) {
 +
                            for (const [key, value] of Object.entries(newNodes)) {
 +
                                var params = {
 +
                                        action: 'edit',
 +
                                        title: '' + key,
 +
                                        appendtext: '' + value + '}}',
 +
                                        format: 'json'
 +
                                    },
 +
                                    api = new mw.Api();
 +
                                await api.postWithToken('csrf', params).done(function(data) {
 +
                                    console.log(data);
 +
                                    alertString += "Seite " + key + " erstellt!\r\n"
 +
                                });
 +
                            }
 +
                            for (const [key, value] of Object.entries(editNodes)) {
 +
                                var params = {
 +
                                        action: 'edit',
 +
                                        title: '' + key,
 +
                                        text: '' + value + '}}',
 +
                                        format: 'json'
 +
                                    },
 +
                                    api = new mw.Api();
 +
                                await api.postWithToken('csrf', params).done(function(data) {
 +
                                    console.log(data);
 +
                                    alertString += "Seite " + key + " bearbeitet!\r\n"
 +
                                });
 +
                            }
 +
                            for (const [key, value] of Object.entries(editDeletedEdges)) {
 +
                                var params = {
 +
                                        action: 'edit',
 +
                                        title: '' + key,
 +
                                        text: '' + value,
 +
                                        format: 'json'
 +
                                    },
 +
                                    api = new mw.Api();
 +
                                await api.postWithToken('csrf', params).done(function(data) {
 +
                                    console.log(data);
 +
                                    alertString += "Auf der Seite " + key + " wurde ein Attribut gelöscht!\r\n"
 +
                                });
 +
                            }
 +
                            for (const [key, value] of Object.entries(editDeletedNodes)) {
 +
                                var params = {
 +
                                        action: 'delete',
 +
                                        title: '' + key,
 +
                                        format: 'json'
 +
                                    },
 +
                                    api = new mw.Api();
 +
                                await api.postWithToken('csrf', params).done(function(data) {
 +
                                    console.log(data);
 +
                                    alertString += "Seite " + key + " wurde gelöscht!\r\n"
 +
                                });
 +
                            }
 +
                            // Example: Customize the displayed actions at the time the window is opened.
 +
                            var messageDialog = new OO.ui.MessageDialog();
 +
                            // Create and append a window manager.
 +
                            var windowManager = new OO.ui.WindowManager();
 +
                            $('body').append(windowManager.$element);
 +
                            // Add the dialog to the window manager.
 +
                            windowManager.addWindows([messageDialog]);
 +
                            // Configure the message dialog when it is opened with the window manager's openWindow() method.
 +
                            windowManager.openWindow(messageDialog, {
 +
                                title: 'Folgende Änderugnen wurden übernommen:',
 +
                                message: '' + alertString,
 +
                                verbose: true,
 +
                                actions: [{
 +
                                    action: 'accept',
 +
                                    label: 'Okay',
 +
                                    flags: 'primary'
 +
                                }]
 +
                            });
 +
                            /*OO.ui.alert( "" + alertString ).done( function () {
 +
                                console.log( alertString );
 +
                            } );*/
 +
                        } else {}
 +
                    });
 +
                }
 +
//Deletes node in manipulation mode and the wiki page.
 +
                function deleteSelectedNode(data, callback) {
 +
                    deleteNodesChildren(data.nodes[0]);
 +
                    nodes.remove(data.nodes[0]);
 +
                    for (var i = 0; i < contextCreatedProps.length; i++) {
 +
                        var noNodesInNetwork = true;
 +
                        for (var j = 0; j < nodes.getIds().length; j++) {
 +
                            if (contextCreatedProps[i] == nodes.get(nodes.getIds()[j]).group) {
 +
                                noNodesInNetwork = false;
 +
                            }
 
                         }
 
                         }
 
+
                         if (noNodesInNetwork === true) {
                         });}else{
+
                            givenDiv.querySelector('#' + contextCreatedProps[i]).remove();
                        if(network.getConnectedNodes(edgeToNode).length == 0){
+
                            contextCreatedProps.splice(contextCreatedProps.indexOf(contextCreatedProps[i]), 1);
                        delete newNodes[""+edgeToNode];
+
                            i--;
                        }else{
  −
                        var edgeString = `(\{\{Semantic\/Link[\\r\\n]*\\|[\\r\\n]*property=`+reverseLabel(edgeLabel)+`[\\r\\n]*\\|[\\r\\n]*value=`+edgeFromNode+`[\\r\\n]*\\}[\\r\\n]*\\}[\\r\\n]*)`;
  −
 
  −
                        var re = new RegExp(edgeString,"g");
  −
                        var wikiText = newNodes[""+edgeToNode];
  −
                        var newWikiText = wikiText.replace(re,"");
  −
                        newNodes[""+edgeToNode] = newWikiText;
  −
                        }
   
                         }
 
                         }
}else{
+
                    }
if(await pageExists(edgeFromNode) === true){
+
                    delete oldGroups["" + data.nodes[0]];
await fetch('/w/api.php?action=parse&page='+ edgeFromNode +'&prop=wikitext&format=json')
+
                    delete objClickedProps["" + data.nodes[0]];
                        .then(response => response.json())
+
                    callback();
                        .then(data => {
+
                    document.querySelector('.vis-delete').remove();
                        var wikiText = data.parse.wikitext['*'];
+
                    editDeletedNodes["" + data.nodes[0]] = "";
console.log(wikiText);
+
                    delete newNodes["" + data.nodes[0]];
+
                    delete editNodes["" + data.nodes[0]];
                        var edgeString = `(\{\{Semantic\/Link[\\r\\n]*\\|[\\r\\n]*property=`+edgeLabel+`[\\r\\n]*\\|[\\r\\n]*value=`+edgeToNode+`[\\r\\n]*\\}[\\r\\n]*\\}[\\r\\n]*)`;
+
                }
//var edgeString = '(\\{\\{Semantic\/Element[^}]*[\\r\\n]*\\}[\\r\\n]*\\}[\\r\\n]*[\\r\\n]*\\}[\\r\\n]*\\})'
+
                //Deletes edge in manipulation mode and deletes the property from the node wikipages
var re = new RegExp(edgeString,"g");
+
                async function deleteSelectedEdge(data, callback) {
                       
+
                    var edgeToNode = edges.get(data.edges[0]).to;
                        var edgeStringFound = wikiText.search(re) >= 0;
+
                    var edgeFromNode = edges.get(data.edges[0]).from;
                       
+
                    var edgeLabel = edges.get(data.edges[0]).label;
                        if(edgeStringFound){
+
                    edges.remove(data.edges[0]);
                        if(editDeletedEdges[""+ edgeFromNode]){
+
                    deleteNodesChildren(edgeToNode, true);
                        var newWikiText = editDeletedEdges[""+ edgeFromNode].replace(re, "");
+
                    deleteNodesChildren(edgeFromNode, true);
                        editDeletedEdges[""+ edgeFromNode] = newWikiText;
+
                    for (var i = 0; i < contextCreatedProps.length; i++) {
                        }else{
+
                        var noNodesInNetwork = true;
                        var newWikiText = wikiText.replace(re, "");
+
                        for (var j = 0; j < nodes.getIds().length; j++) {
                        console.log(newWikiText)
+
                            if (contextCreatedProps[i] == nodes.get(nodes.getIds()[j]).group) {
                        editDeletedEdges[""+ edgeFromNode] = newWikiText;
+
                                noNodesInNetwork = false;
                        }
+
                            }
   
   
                         }
 
                         }
                       
+
                         if (noNodesInNetwork === true) {
                         if(newNodes[""+edgeFromNode]){
+
                            givenDiv.querySelector('#' + contextCreatedProps[i]).remove();
                       
+
                            contextCreatedProps.splice(contextCreatedProps.indexOf(contextCreatedProps[i]), 1);
                        var newWikiText = newNodes[""+edgeFromNode].replace(re, "");
+
                            i--;
                        newNodes[""+edgeFromNode] = newWikiText;
  −
 
   
                         }
 
                         }
                          
+
                    }
                        if(editNodes[""+edgeFromNode]){
+
                    if (edgeLabel[0] == "-") {
                       
+
                         if (await pageExists(edgeToNode) === true) {
                        var newWikiText = editNodes[""+edgeFromNode].replace(re, "");
+
                            await fetch('/w/api.php?action=parse&page=' + edgeToNode + '&prop=wikitext&format=json')
                        editNodes[""+edgeFromNode] = newWikiText;
+
                                .then(response => response.json())
                       
+
                                .then(data => {
 +
                                    var wikiText = data.parse.wikitext['*'];
 +
                                    var edgeString = `(\{\{Semantic\/Link[\\r\\n]*\\|[\\r\\n]*property=` + reverseLabel(edgeLabel) + `[\\r\\n]*\\|[\\r\\n]*value=` + edgeFromNode + `[\\r\\n]*\\}[\\r\\n]*\\}[\\r\\n]*)`
 +
                                    //var edgeString = '(\\{\\{Semantic\/Element[^}]*[\\r\\n]*\\}[\\r\\n]*\\}[\\r\\n]*[\\r\\n]*\\}[\\r\\n]*\\})'
 +
                                    var re = new RegExp(edgeString, "g");
 +
                                    var edgeStringFound = wikiText.search(re) >= 0;
 +
                                    if (edgeStringFound) {
 +
                                        if (editDeletedEdges["" + edgeToNode]) {
 +
                                            var newWikiText = editDeletedEdges["" + edgeToNode].replace(re, "");
 +
                                            editDeletedEdges["" + edgeToNode] = newWikiText;
 +
                                        } else {
 +
                                            var newWikiText = wikiText.replace(re, "");
 +
                                            editDeletedEdges["" + edgeToNode] = newWikiText;
 +
                                        }
 +
                                    }
 +
                                    if (newNodes["" + edgeToNode]) {
 +
                                        var newWikiText = newNodes["" + edgeToNode].replace(re, "");
 +
                                        newNodes["" + edgeToNode] = newWikiText;
 +
                                    }
 +
                                    if (editNodes["" + edgeToNode]) {
 +
                                        var newWikiText = editNodes["" + edgeToNode].replace(re, "");
 +
                                        editNodes["" + edgeToNode] = newWikiText;
 +
                                    }
 +
                                });
 +
                        } else {
 +
                            if (network.getConnectedNodes(edgeToNode).length == 0) {
 +
                                delete newNodes["" + edgeToNode];
 +
                            } else {
 +
                                var edgeString = `(\{\{Semantic\/Link[\\r\\n]*\\|[\\r\\n]*property=` + reverseLabel(edgeLabel) + `[\\r\\n]*\\|[\\r\\n]*value=` + edgeFromNode + `[\\r\\n]*\\}[\\r\\n]*\\}[\\r\\n]*)`;
 +
                                var re = new RegExp(edgeString, "g");
 +
                                var wikiText = newNodes["" + edgeToNode];
 +
                                var newWikiText = wikiText.replace(re, "");
 +
                                newNodes["" + edgeToNode] = newWikiText;
 +
                            }
 
                         }
 
                         }
 
+
                    } else {
                       
+
                        if (await pageExists(edgeFromNode) === true) {
                        });}else{
+
                            await fetch('/w/api.php?action=parse&page=' + edgeFromNode + '&prop=wikitext&format=json')
                        if(network.getConnectedNodes(edgeFromNode).length == 0){
+
                                .then(response => response.json())
                        delete newNodes[""+edgeFromNode];
+
                                .then(data => {
                        }else{
+
                                    var wikiText = data.parse.wikitext['*'];
                        var edgeString = `(\{\{Semantic\/Link[\\r\\n]*\\|[\\r\\n]*property=`+edgeLabel+`[\\r\\n]*\\|[\\r\\n]*value=`+edgeToNode+`[\\r\\n]*\\}[\\r\\n]*\\}[\\r\\n]*)`;
+
                                    var edgeString = `(\{\{Semantic\/Link[\\r\\n]*\\|[\\r\\n]*property=` + edgeLabel + `[\\r\\n]*\\|[\\r\\n]*value=` + edgeToNode + `[\\r\\n]*\\}[\\r\\n]*\\}[\\r\\n]*)`;
 
+
                                    //var edgeString = '(\\{\\{Semantic\/Element[^}]*[\\r\\n]*\\}[\\r\\n]*\\}[\\r\\n]*[\\r\\n]*\\}[\\r\\n]*\\})'
                        var re = new RegExp(edgeString,"g");
+
                                    var re = new RegExp(edgeString, "g");
                        var wikiText = newNodes[""+edgeFromNode];
+
                                    var edgeStringFound = wikiText.search(re) >= 0;
                        var newWikiText = wikiText.replace(re,"");
+
                                    if (edgeStringFound) {
                        newNodes[""+edgeFromNode] = newWikiText;
+
                                        if (editDeletedEdges["" + edgeFromNode]) {
                        }
+
                                            var newWikiText = editDeletedEdges["" + edgeFromNode].replace(re, "");
                        console.log(newNodes);
+
                                            editDeletedEdges["" + edgeFromNode] = newWikiText;
 +
                                        } else {
 +
                                            var newWikiText = wikiText.replace(re, "");
 +
                                            editDeletedEdges["" + edgeFromNode] = newWikiText;
 +
                                        }
 +
                                    }
 +
                                    if (newNodes["" + edgeFromNode]) {
 +
                                        var newWikiText = newNodes["" + edgeFromNode].replace(re, "");
 +
                                        newNodes["" + edgeFromNode] = newWikiText;
 +
                                    }
 +
                                    if (editNodes["" + edgeFromNode]) {
 +
                                        var newWikiText = editNodes["" + edgeFromNode].replace(re, "");
 +
                                        editNodes["" + edgeFromNode] = newWikiText;
 +
                                    }
 +
                                });
 +
                        } else {
 +
                            if (network.getConnectedNodes(edgeFromNode).length == 0) {
 +
                                delete newNodes["" + edgeFromNode];
 +
                            } else {
 +
                                var edgeString = `(\{\{Semantic\/Link[\\r\\n]*\\|[\\r\\n]*property=` + edgeLabel + `[\\r\\n]*\\|[\\r\\n]*value=` + edgeToNode + `[\\r\\n]*\\}[\\r\\n]*\\}[\\r\\n]*)`;
 +
                                var re = new RegExp(edgeString, "g");
 +
                                var wikiText = newNodes["" + edgeFromNode];
 +
                                var newWikiText = wikiText.replace(re, "");
 +
                                newNodes["" + edgeFromNode] = newWikiText;
 +
                            }
 
                         }
 
                         }
                       
+
                    }
}
+
                    //nodes.remove(edges.get(data.edges[0]).to);
+
                    callback(data);
+
                    document.querySelector('.vis-delete').remove();
+
                }
+
                //HTML for the manipulation popups
console.log(editDeletedEdges);
+
                var editHtml = '' +
//nodes.remove(edges.get(data.edges[0]).to);
+
                    '<div id="node-popUp">' +
+
                    '  <span id="node-operation" style="cursor: move;">node</span> <br />' +
callback(data);
+
                    '  <table style="margin: auto">' +
document.querySelector('.vis-delete').remove();
+
                    '    <tbody>' +
console.log(objClickedProps);
+
                    '      <tr>' +
    console.log(oldGroups);
+
                    '        <td>label</td>' +
}
+
                    '        <td><input id="node-label" value="" /></td>' +
 +
                    '      </tr>' +
 +
                    '    </tbody>' +
 +
                    '  </table>' +
 +
                    '  <input type="button" value="save" id="node-saveButton" />' +
 +
                    '  <input type="button" value="cancel" id="node-cancelButton" />' +
 +
                    '</div>' +
 +
                    '' +
 +
                    '<div id="edge-popUp">' +
 +
                    '  <span id="edge-operation" style="cursor: move;">edge</span> <br />' +
 +
                    '  <table style="margin: auto">' +
 +
                    '    <tbody>' +
 +
                    '      <tr>' +
 +
                    '        <td>label</td>' +
 +
                    '        <td><input id="edge-label" value="" /></td>' +
 +
                    '      </tr>' +
 +
                    '    </tbody>' +
 +
                    '  </table>' +
 +
                    '  <input type="button" value="save" id="edge-saveButton" />' +
 +
                    '  <input type="button" value="cancel" id="edge-cancelButton" />' +
 +
                    '</div>' +
 +
                    '';
 +
                var editHtmlDiv = document.createElement("div");
 +
                editHtmlDiv.innerHTML = editHtml;
 +
                document.body.appendChild(editHtmlDiv);
 +
                //dragElement(document.getElementById("node-popUp"));
 +
                //dragElement(document.getElementById("edge-popUp"));
 +
               
 +
                //function to make the manipulation popups draggable
 +
                function dragElement(elmnt) {
 +
                    var pos1 = 0,
 +
                        pos2 = 0,
 +
                        pos3 = 0,
 +
                        pos4 = 0;
 +
                    if (document.getElementById(elmnt.id)) {
 +
                        // if present, the header is where you move the DIV from:
 +
                        document.getElementById("node-operation").onmousedown = dragMouseDown;
 +
                        document.getElementById("edge-operation").onmousedown = dragMouseDown;
 +
                    } else {
 +
                        // otherwise, move the DIV from anywhere inside the DIV:
 +
                        elmnt.onmousedown = dragMouseDown;
 +
                    }
   −
var editHtml = '' +
+
                    function dragMouseDown(e) {
 +
                        e = e || window.event;
 +
                        e.preventDefault();
 +
                        // get the mouse cursor position at startup:
 +
                        pos3 = e.clientX;
 +
                        pos4 = e.clientY;
 +
                        document.onmouseup = closeDragElement;
 +
                        // call a function whenever the cursor moves:
 +
                        document.onmousemove = elementDrag;
 +
                    }
   −
'<div id="node-popUp">' +
+
                    function elementDrag(e) {
'  <span id="node-operation" style="cursor: move;">node</span> <br />' +
+
                        e = e || window.event;
'  <table style="margin: auto">' +
+
                        e.preventDefault();
'    <tbody>' +
+
                        // calculate the new cursor position:
'      <tr>' +
+
                        pos1 = pos3 - e.clientX;
'        <td>label</td>' +
+
                        pos2 = pos4 - e.clientY;
'        <td><input id="node-label" value="" /></td>' +
+
                        pos3 = e.clientX;
'      </tr>' +
+
                        pos4 = e.clientY;
'    </tbody>' +
+
                        // set the element's new position:
'  </table>' +
+
                        elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
'  <input type="button" value="save" id="node-saveButton" />' +
+
                        elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
'  <input type="button" value="cancel" id="node-cancelButton" />' +
+
                    }
'</div>' +
  −
'' +
  −
'<div id="edge-popUp">' +
  −
'  <span id="edge-operation" style="cursor: move;">edge</span> <br />' +
  −
'  <table style="margin: auto">' +  
  −
'    <tbody>' +
  −
'      <tr>' +
  −
'        <td>label</td>' +
  −
'        <td><input id="edge-label" value="" /></td>' +
  −
'      </tr>' +
  −
'    </tbody>' +
  −
'  </table>' +
  −
'  <input type="button" value="save" id="edge-saveButton" />' +  
  −
'  <input type="button" value="cancel" id="edge-cancelButton" />' +
  −
'</div>' +
  −
'';
     −
 
+
                    function closeDragElement() {
 
+
                        // stop moving when mouse button is released:
 
+
                        document.onmouseup = null;
var editHtmlDiv = document.createElement("div");
+
                        document.onmousemove = null;
editHtmlDiv.innerHTML = editHtml;
+
                    }
document.body.appendChild(editHtmlDiv);
+
                }
 
+
            }
 
+
         });
 
  −
 
  −
 
  −
 
  −
 
  −
//dragElement(document.getElementById("node-popUp"));
  −
//dragElement(document.getElementById("edge-popUp"));
  −
 
  −
function dragElement(elmnt) {
  −
  var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  −
  if (document.getElementById(elmnt.id)) {
  −
 
  −
    // if present, the header is where you move the DIV from:
  −
    document.getElementById("node-operation").onmousedown = dragMouseDown;
  −
    document.getElementById("edge-operation").onmousedown = dragMouseDown;
  −
  } else {
  −
    // otherwise, move the DIV from anywhere inside the DIV:
  −
    elmnt.onmousedown = dragMouseDown;
  −
  }
  −
 
  −
  function dragMouseDown(e) {
  −
    e = e || window.event;
  −
    e.preventDefault();
  −
    // get the mouse cursor position at startup:
  −
    pos3 = e.clientX;
  −
    pos4 = e.clientY;
  −
    document.onmouseup = closeDragElement;
  −
    // call a function whenever the cursor moves:
  −
    document.onmousemove = elementDrag;
  −
  }
  −
 
  −
  function elementDrag(e) {
  −
    e = e || window.event;
  −
    e.preventDefault();
  −
    // calculate the new cursor position:
  −
    pos1 = pos3 - e.clientX;
  −
    pos2 = pos4 - e.clientY;
  −
    pos3 = e.clientX;
  −
    pos4 = e.clientY;
  −
    // set the element's new position:
  −
    elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
  −
    elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
  −
  }
  −
 
  −
  function closeDragElement() {
  −
    // stop moving when mouse button is released:
  −
    document.onmouseup = null;
  −
    document.onmousemove = null;
  −
  }
  −
}
  −
 
  −
 
  −
         }
  −
    });
   
     });
 
     });
   
});
 
});
Bots, bulkpusher, Bureaucrats, checkuser, filepusher, Interface administrators, oversight, pusher, rdfioadministrator, rdfiocurator, Administrators (Semantic MediaWiki), Curators (Semantic MediaWiki), Editors (Semantic MediaWiki), Administrators
5,444

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.