diff --git a/cypress/platform/knsv.html b/cypress/platform/knsv.html index 070fe5dc6..15e5dcc61 100644 --- a/cypress/platform/knsv.html +++ b/cypress/platform/knsv.html @@ -25,14 +25,13 @@ -
APA
pie title Pets adopted by volunteers "Dogs" : 386 "Cats" : 85 "Rats" : 15
-
+
gantt title Adding GANTT diagram functionality to mermaid excludes :excludes the named dates/days from being included in a charted task.. @@ -64,7 +63,7 @@ commit commit merge newbranch
-
+
sequenceDiagram participant a as Alice participant j as John @@ -146,6 +145,76 @@ requirementDiagram end
+ flowchart TB + Function-->URL + click Function clickByFlow "Add a div" + click URL "https://mermaid-js.github.io/mermaid/#/" "Visit mermaid docs" _blank +
+
+ classDiagram-v2 + class Test + class ShapeLink + link ShapeLink "https://mermaid-js.github.io/mermaid/#/" "This is a tooltip for a link" + class ShapeCallback + callback ShapeCallback "clickByClass" "This is a tooltip for a callback" +
+
+ gantt + dateFormat YYYY-MM-DD + axisFormat %d/%m + title Adding GANTT diagram to mermaid + excludes weekdays 2014-01-10 + + section A section + Completed task :done, des1, 2014-01-06,2014-01-08 + Active task :active, des2, 2014-01-09, 3d + Future task : des3, after des2, 5d + Future task2 : des4, after des3, 5d + + section Critical tasks + Completed task in the critical line :crit, done, 2014-01-06,24h + Implement parser and jison :crit, done, after des1, 2d + Create tests for parser :crit, active, 3d + Future task in critical line :crit, 5d + Create tests for renderer :2d + Add to mermaid :1d + + section Documentation + Describe gantt syntax :active, a1, after des1, 3d + Add gantt diagram to demo page :after a1 , 20h + Add another diagram to demo page :doc1, after a1 , 48h + + section Clickable + Visit mermaidjs :active, cl1, 2014-01-07,2014-01-10 + Calling a Callback (look at the console log) :cl2, after cl1, 3d + Calling a Callback with args :cl3, after cl1, 3d + + click cl1 href "https://mermaid-js.github.io/mermaid/#/" + click cl2 call clickByGantt() + click cl3 call clickByGantt("test1", test2, test3) + + section Last section + Describe gantt syntax :after doc1, 3d + Add gantt diagram to demo page : 20h + Add another diagram to demo page : 48h +
+
+classDiagram +Class01 <|-- AveryLongClass : Cool +Class09 --> C2 : Where am i? +Class09 --* C3 +Class09 --|> Class07 +Class07 : equals() +Class07 : Object[] elementData +Class01 : size() +Class01 : int chimp +Class01 : int gorilla +class Class10 { + int id + size() +} +
+
stateDiagram [*] --> S1 state "Some long name" as S1 @@ -181,7 +250,7 @@ requirementDiagram }; mermaid.initialize({ // theme: 'dark', - theme: 'forest', + // theme: 'forest', // arrowMarkerAbsolute: true, // themeCSS: '.edgePath .path {stroke: red;} .arrowheadPath {fill: red;}', flowchart: { @@ -192,6 +261,7 @@ requirementDiagram }, class: { defaultRenderer: 'dagre-d3', + htmlLabels: true, }, // gantt: { axisFormat: '%m/%d/%Y' }, sequence: { actorFontFamily: 'courier', actorMargin: 50, showSequenceNumbers: false }, @@ -212,6 +282,15 @@ requirementDiagram function callback() { alert('It worked'); } + +function clickByFlow(elemName) { + const div = document.createElement('div'); + div.className = 'created-by-click'; + div.style = 'padding: 20px; background: green; color: white;'; + div.innerText = 'Clicked By Flow'; + + document.getElementsByTagName('body')[0].appendChild(div); +} diff --git a/src/dagre-wrapper/nodes.js b/src/dagre-wrapper/nodes.js index 2b164ea92..3123ce3bb 100644 --- a/src/dagre-wrapper/nodes.js +++ b/src/dagre-wrapper/nodes.js @@ -967,10 +967,13 @@ export const insertNode = (elem, node, dir) => { // Add link when appropriate if (node.link) { - newEl = elem - .insert('svg:a') - .attr('xlink:href', node.link) - .attr('target', node.linkTarget || '_blank'); + let target; + if (getConfig().securityLevel === 'sandbox') { + target = '_top'; + } else if (node.linkTarget) { + target = node.linkTarget || '_blank'; + } + newEl = elem.insert('svg:a').attr('xlink:href', node.link).attr('target', target); el = shapes[node.shape](newEl, node, dir); } else { el = shapes[node.shape](elem, node, dir); diff --git a/src/diagrams/class/classDb.js b/src/diagrams/class/classDb.js index 2223f4489..f2fc015e3 100644 --- a/src/diagrams/class/classDb.js +++ b/src/diagrams/class/classDb.js @@ -213,7 +213,9 @@ export const setLink = function (ids, linkStr, target) { if (_id[0].match(/\d/)) id = MERMAID_DOM_ID_PREFIX + id; if (typeof classes[id] !== 'undefined') { classes[id].link = utils.formatUrl(linkStr, config); - if (typeof target === 'string') { + if (config.securityLevel === 'sandbox') { + classes[id].linkTarget = '_top'; + } else if (typeof target === 'string') { classes[id].linkTarget = target; } else { classes[id].linkTarget = '_blank'; diff --git a/src/diagrams/flowchart/flowRenderer-v2.js b/src/diagrams/flowchart/flowRenderer-v2.js index 545107c0d..21300992c 100644 --- a/src/diagrams/flowchart/flowRenderer-v2.js +++ b/src/diagrams/flowchart/flowRenderer-v2.js @@ -496,7 +496,9 @@ export const draw = function (text, id) { link.setAttributeNS('http://www.w3.org/2000/svg', 'class', vertex.classes.join(' ')); link.setAttributeNS('http://www.w3.org/2000/svg', 'href', vertex.link); link.setAttributeNS('http://www.w3.org/2000/svg', 'rel', 'noopener'); - if (vertex.linkTarget) { + if (securityLevel === 'sandbox') { + link.setAttributeNS('http://www.w3.org/2000/svg', 'target', '_top'); + } else if (vertex.linkTarget) { link.setAttributeNS('http://www.w3.org/2000/svg', 'target', vertex.linkTarget); } diff --git a/src/diagrams/flowchart/flowRenderer.js b/src/diagrams/flowchart/flowRenderer.js index 72f4a9085..344120e06 100644 --- a/src/diagrams/flowchart/flowRenderer.js +++ b/src/diagrams/flowchart/flowRenderer.js @@ -503,7 +503,9 @@ export const draw = function (text, id) { link.setAttributeNS('http://www.w3.org/2000/svg', 'class', vertex.classes.join(' ')); link.setAttributeNS('http://www.w3.org/2000/svg', 'href', vertex.link); link.setAttributeNS('http://www.w3.org/2000/svg', 'rel', 'noopener'); - if (vertex.linkTarget) { + if (securityLevel === 'sandbox') { + link.setAttributeNS('http://www.w3.org/2000/svg', 'target', '_top'); + } else if (vertex.linkTarget) { link.setAttributeNS('http://www.w3.org/2000/svg', 'target', vertex.linkTarget); } diff --git a/src/diagrams/gantt/ganttDb.js b/src/diagrams/gantt/ganttDb.js index 1c06769c8..88c591520 100644 --- a/src/diagrams/gantt/ganttDb.js +++ b/src/diagrams/gantt/ganttDb.js @@ -10,6 +10,7 @@ let axisFormat = ''; let todayMarker = ''; let includes = []; let excludes = []; +let links = {}; let title = ''; let sections = []; let tasks = []; @@ -44,6 +45,7 @@ export const clear = function () { inclusiveEndDates = false; topAxis = false; lastOrder = 0; + links = {}; }; export const setAxisFormat = function (txt) { @@ -101,6 +103,10 @@ export const getExcludes = function () { return excludes; }; +export const getLinks = function () { + return links; +}; + export const setTitle = function (txt) { title = txt; }; @@ -505,6 +511,7 @@ export const setLink = function (ids, _linkStr) { pushFun(id, () => { window.open(linkStr, '_self'); }); + links[id] = linkStr; } }); setClass(ids, 'clickable'); @@ -642,6 +649,7 @@ export default { getExcludes, setClickEvent, setLink, + getLinks, bindFunctions, durationToDate, isInvalidDate, diff --git a/src/diagrams/gantt/ganttRenderer.js b/src/diagrams/gantt/ganttRenderer.js index 00b991f57..899c61e02 100644 --- a/src/diagrams/gantt/ganttRenderer.js +++ b/src/diagrams/gantt/ganttRenderer.js @@ -185,6 +185,10 @@ export const draw = function (text, id) { // Draw the rects representing the tasks const rectangles = svg.append('g').selectAll('rect').data(theArray).enter(); + const links = ganttDb.getLinks(); + + // Render the tasks with links + // Render the other tasks rectangles .append('rect') .attr('id', function (d) { @@ -381,6 +385,32 @@ export const draw = function (text, id) { return classStr + ' taskText taskText' + secNum + ' ' + taskType + ' width-' + textWidth; } }); + + const securityLevel = getConfig().securityLevel; + + // Wrap the tasks in an a tag for working links without javascript + if (securityLevel === 'sandbox') { + let sandboxElement; + sandboxElement = select('#i' + id); + const root = select(sandboxElement.nodes()[0].contentDocument.body); + const doc = sandboxElement.nodes()[0].contentDocument; + + rectangles + .filter(function (d) { + return typeof links[d.id] !== 'undefined'; + }) + .each(function (o) { + var taskRect = doc.querySelector('#' + o.id); + var taskText = doc.querySelector('#' + o.id + '-text'); + const oldParent = taskRect.parentNode; + var Link = doc.createElement('a'); + Link.setAttribute('xlink:href', links[o.id]); + Link.setAttribute('target', '_top'); + oldParent.appendChild(Link); + Link.appendChild(taskRect); + Link.appendChild(taskText); + }); + } } /** * @param theGap diff --git a/src/mermaidAPI.js b/src/mermaidAPI.js index 6544a80f7..c87075a59 100755 --- a/src/mermaidAPI.js +++ b/src/mermaidAPI.js @@ -518,32 +518,12 @@ const render = function (id, _txt, cb, container) { svgCode = svgCode.replace(/marker-end="url\(.*?#/g, 'marker-end="url(#', 'g'); } - // const iframe = document.createElement('iframe'); - // iframe.setAttribute('frameBorder', '0'); - // iframe.setAttribute('id', id); - // iframe.setAttribute('sanbox', ''); - // iframe.setAttribute('src', 'about:blank'); - // iframe.contentWindow.document.body = svgCode; - // element.innerHTML = ''; - // // element.appendChild(iframe); - // // element.innerHTML = ''; - svgCode = decodeEntities(svgCode); // Fix for when the br tag is used svgCode = svgCode.replace(/
/g, '
'); if (cnf.securityLevel === 'sandbox') { - // const newSvgCode = - // ''; - // svgCode = newSvgCode; - // svgCode = ``; let svgEl = root.select('#d' + id + ' svg').node(); let width = '100%'; let height = '100%'; @@ -553,7 +533,7 @@ const render = function (id, _txt, cb, container) { } svgCode = ``; }