mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
Merge pull request #4268 from Valentine14th/bug/4023-image-rendering
fix: image rendering in nodes
This commit is contained in:
commit
727bf30824
@ -685,6 +685,16 @@ A ~~~ B
|
|||||||
{ titleTopMargin: 0 }
|
{ titleTopMargin: 0 }
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
it('4023: Should render html labels with images and-or text correctly', () => {
|
||||||
|
imgSnapshotTest(
|
||||||
|
`flowchart TD
|
||||||
|
B[<img src='https://mermaid.js.org/mermaid-logo.svg'>]
|
||||||
|
B-->C[<img src="https://mermaid.js.org/mermaid-logo.svg"> more text <img src='https://mermaid.js.org/mermaid-logo.svg'>]
|
||||||
|
B-->D(<img src='https://mermaid.js.org/mermaid-logo.svg'> some text)
|
||||||
|
B-->E(plain)`,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
});
|
||||||
describe('Markdown strings flowchart (#4220)', () => {
|
describe('Markdown strings flowchart (#4220)', () => {
|
||||||
describe('html labels', () => {
|
describe('html labels', () => {
|
||||||
it('With styling and classes', () => {
|
it('With styling and classes', () => {
|
||||||
|
@ -96,7 +96,7 @@ mermaid.initialize(config);
|
|||||||
|
|
||||||
#### Defined in
|
#### Defined in
|
||||||
|
|
||||||
[mermaidAPI.ts:667](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L667)
|
[mermaidAPI.ts:673](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/mermaidAPI.ts#L673)
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import { insertCluster, clear as clearClusters } from './clusters';
|
|||||||
import { insertEdgeLabel, positionEdgeLabel, insertEdge, clear as clearEdges } from './edges';
|
import { insertEdgeLabel, positionEdgeLabel, insertEdge, clear as clearEdges } from './edges';
|
||||||
import { log } from '../logger';
|
import { log } from '../logger';
|
||||||
|
|
||||||
const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
|
const recursiveRender = async (_elem, graph, diagramtype, parentCluster) => {
|
||||||
log.info('Graph in recursive render: XXX', graphlibJson.write(graph), parentCluster);
|
log.info('Graph in recursive render: XXX', graphlibJson.write(graph), parentCluster);
|
||||||
const dir = graph.graph().rankdir;
|
const dir = graph.graph().rankdir;
|
||||||
log.trace('Dir in recursive render - dir:', dir);
|
log.trace('Dir in recursive render - dir:', dir);
|
||||||
@ -35,44 +35,46 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
|
|||||||
|
|
||||||
// Insert nodes, this will insert them into the dom and each node will get a size. The size is updated
|
// Insert nodes, this will insert them into the dom and each node will get a size. The size is updated
|
||||||
// to the abstract node and is later used by dagre for the layout
|
// to the abstract node and is later used by dagre for the layout
|
||||||
graph.nodes().forEach(function (v) {
|
await Promise.all(
|
||||||
const node = graph.node(v);
|
graph.nodes().map(async function (v) {
|
||||||
if (parentCluster !== undefined) {
|
const node = graph.node(v);
|
||||||
const data = JSON.parse(JSON.stringify(parentCluster.clusterData));
|
if (parentCluster !== undefined) {
|
||||||
// data.clusterPositioning = true;
|
const data = JSON.parse(JSON.stringify(parentCluster.clusterData));
|
||||||
log.info('Setting data for cluster XXX (', v, ') ', data, parentCluster);
|
// data.clusterPositioning = true;
|
||||||
graph.setNode(parentCluster.id, data);
|
log.info('Setting data for cluster XXX (', v, ') ', data, parentCluster);
|
||||||
if (!graph.parent(v)) {
|
graph.setNode(parentCluster.id, data);
|
||||||
log.trace('Setting parent', v, parentCluster.id);
|
if (!graph.parent(v)) {
|
||||||
graph.setParent(v, parentCluster.id, data);
|
log.trace('Setting parent', v, parentCluster.id);
|
||||||
|
graph.setParent(v, parentCluster.id, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
log.info('(Insert) Node XXX' + v + ': ' + JSON.stringify(graph.node(v)));
|
||||||
log.info('(Insert) Node XXX' + v + ': ' + JSON.stringify(graph.node(v)));
|
if (node && node.clusterNode) {
|
||||||
if (node && node.clusterNode) {
|
// const children = graph.children(v);
|
||||||
// const children = graph.children(v);
|
log.info('Cluster identified', v, node.width, graph.node(v));
|
||||||
log.info('Cluster identified', v, node.width, graph.node(v));
|
const o = await recursiveRender(nodes, node.graph, diagramtype, graph.node(v));
|
||||||
const o = recursiveRender(nodes, node.graph, diagramtype, graph.node(v));
|
const newEl = o.elem;
|
||||||
const newEl = o.elem;
|
updateNodeBounds(node, newEl);
|
||||||
updateNodeBounds(node, newEl);
|
node.diff = o.diff || 0;
|
||||||
node.diff = o.diff || 0;
|
log.info('Node bounds (abc123)', v, node, node.width, node.x, node.y);
|
||||||
log.info('Node bounds (abc123)', v, node, node.width, node.x, node.y);
|
setNodeElem(newEl, node);
|
||||||
setNodeElem(newEl, node);
|
|
||||||
|
|
||||||
log.warn('Recursive render complete ', newEl, node);
|
log.warn('Recursive render complete ', newEl, node);
|
||||||
} else {
|
|
||||||
if (graph.children(v).length > 0) {
|
|
||||||
// This is a cluster but not to be rendered recursively
|
|
||||||
// Render as before
|
|
||||||
log.info('Cluster - the non recursive path XXX', v, node.id, node, graph);
|
|
||||||
log.info(findNonClusterChild(node.id, graph));
|
|
||||||
clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node };
|
|
||||||
// insertCluster(clusters, graph.node(v));
|
|
||||||
} else {
|
} else {
|
||||||
log.info('Node - the non recursive path', v, node.id, node);
|
if (graph.children(v).length > 0) {
|
||||||
insertNode(nodes, graph.node(v), dir);
|
// This is a cluster but not to be rendered recursively
|
||||||
|
// Render as before
|
||||||
|
log.info('Cluster - the non recursive path XXX', v, node.id, node, graph);
|
||||||
|
log.info(findNonClusterChild(node.id, graph));
|
||||||
|
clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node };
|
||||||
|
// insertCluster(clusters, graph.node(v));
|
||||||
|
} else {
|
||||||
|
log.info('Node - the non recursive path', v, node.id, node);
|
||||||
|
await insertNode(nodes, graph.node(v), dir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
});
|
);
|
||||||
|
|
||||||
// Insert labels, this will insert them into the dom so that the width can be calculated
|
// Insert labels, this will insert them into the dom so that the width can be calculated
|
||||||
// Also figure out which edges point to/from clusters and adjust them accordingly
|
// Also figure out which edges point to/from clusters and adjust them accordingly
|
||||||
@ -146,7 +148,7 @@ const recursiveRender = (_elem, graph, diagramtype, parentCluster) => {
|
|||||||
return { elem, diff };
|
return { elem, diff };
|
||||||
};
|
};
|
||||||
|
|
||||||
export const render = (elem, graph, markers, diagramtype, id) => {
|
export const render = async (elem, graph, markers, diagramtype, id) => {
|
||||||
insertMarkers(elem, markers, diagramtype, id);
|
insertMarkers(elem, markers, diagramtype, id);
|
||||||
clearNodes();
|
clearNodes();
|
||||||
clearEdges();
|
clearEdges();
|
||||||
@ -157,7 +159,7 @@ export const render = (elem, graph, markers, diagramtype, id) => {
|
|||||||
adjustClustersAndEdges(graph);
|
adjustClustersAndEdges(graph);
|
||||||
log.warn('Graph after:', graphlibJson.write(graph));
|
log.warn('Graph after:', graphlibJson.write(graph));
|
||||||
// log.warn('Graph ever after:', graphlibJson.write(graph.node('A').graph));
|
// log.warn('Graph ever after:', graphlibJson.write(graph.node('A').graph));
|
||||||
recursiveRender(elem, graph, diagramtype);
|
await recursiveRender(elem, graph, diagramtype);
|
||||||
};
|
};
|
||||||
|
|
||||||
// const shapeDefinitions = {};
|
// const shapeDefinitions = {};
|
||||||
|
@ -8,8 +8,8 @@ import note from './shapes/note';
|
|||||||
import { parseMember } from '../diagrams/class/svgDraw';
|
import { parseMember } from '../diagrams/class/svgDraw';
|
||||||
import { evaluate } from '../diagrams/common/common';
|
import { evaluate } from '../diagrams/common/common';
|
||||||
|
|
||||||
const question = (parent, node) => {
|
const question = async (parent, node) => {
|
||||||
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
|
||||||
|
|
||||||
const w = bbox.width + node.padding;
|
const w = bbox.width + node.padding;
|
||||||
const h = bbox.height + node.padding;
|
const h = bbox.height + node.padding;
|
||||||
@ -69,8 +69,8 @@ const choice = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const hexagon = (parent, node) => {
|
const hexagon = async (parent, node) => {
|
||||||
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
|
||||||
|
|
||||||
const f = 4;
|
const f = 4;
|
||||||
const h = bbox.height + node.padding;
|
const h = bbox.height + node.padding;
|
||||||
@ -96,8 +96,8 @@ const hexagon = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const rect_left_inv_arrow = (parent, node) => {
|
const rect_left_inv_arrow = async (parent, node) => {
|
||||||
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
|
||||||
|
|
||||||
const w = bbox.width + node.padding;
|
const w = bbox.width + node.padding;
|
||||||
const h = bbox.height + node.padding;
|
const h = bbox.height + node.padding;
|
||||||
@ -122,8 +122,8 @@ const rect_left_inv_arrow = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const lean_right = (parent, node) => {
|
const lean_right = async (parent, node) => {
|
||||||
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
|
||||||
|
|
||||||
const w = bbox.width + node.padding;
|
const w = bbox.width + node.padding;
|
||||||
const h = bbox.height + node.padding;
|
const h = bbox.height + node.padding;
|
||||||
@ -145,8 +145,8 @@ const lean_right = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const lean_left = (parent, node) => {
|
const lean_left = async (parent, node) => {
|
||||||
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
|
||||||
|
|
||||||
const w = bbox.width + node.padding;
|
const w = bbox.width + node.padding;
|
||||||
const h = bbox.height + node.padding;
|
const h = bbox.height + node.padding;
|
||||||
@ -168,8 +168,8 @@ const lean_left = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const trapezoid = (parent, node) => {
|
const trapezoid = async (parent, node) => {
|
||||||
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
|
||||||
|
|
||||||
const w = bbox.width + node.padding;
|
const w = bbox.width + node.padding;
|
||||||
const h = bbox.height + node.padding;
|
const h = bbox.height + node.padding;
|
||||||
@ -191,8 +191,8 @@ const trapezoid = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const inv_trapezoid = (parent, node) => {
|
const inv_trapezoid = async (parent, node) => {
|
||||||
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
|
||||||
|
|
||||||
const w = bbox.width + node.padding;
|
const w = bbox.width + node.padding;
|
||||||
const h = bbox.height + node.padding;
|
const h = bbox.height + node.padding;
|
||||||
@ -214,8 +214,8 @@ const inv_trapezoid = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const rect_right_inv_arrow = (parent, node) => {
|
const rect_right_inv_arrow = async (parent, node) => {
|
||||||
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
|
||||||
|
|
||||||
const w = bbox.width + node.padding;
|
const w = bbox.width + node.padding;
|
||||||
const h = bbox.height + node.padding;
|
const h = bbox.height + node.padding;
|
||||||
@ -238,8 +238,8 @@ const rect_right_inv_arrow = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const cylinder = (parent, node) => {
|
const cylinder = async (parent, node) => {
|
||||||
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
|
||||||
|
|
||||||
const w = bbox.width + node.padding;
|
const w = bbox.width + node.padding;
|
||||||
const rx = w / 2;
|
const rx = w / 2;
|
||||||
@ -310,8 +310,13 @@ const cylinder = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const rect = (parent, node) => {
|
const rect = async (parent, node) => {
|
||||||
const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, 'node ' + node.classes, true);
|
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||||
|
parent,
|
||||||
|
node,
|
||||||
|
'node ' + node.classes,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
// add the rect
|
// add the rect
|
||||||
const rect = shapeSvg.insert('rect', ':first-child');
|
const rect = shapeSvg.insert('rect', ':first-child');
|
||||||
@ -352,8 +357,8 @@ const rect = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const labelRect = (parent, node) => {
|
const labelRect = async (parent, node) => {
|
||||||
const { shapeSvg } = labelHelper(parent, node, 'label', true);
|
const { shapeSvg } = await labelHelper(parent, node, 'label', true);
|
||||||
|
|
||||||
log.trace('Classes = ', node.classes);
|
log.trace('Classes = ', node.classes);
|
||||||
// add the rect
|
// add the rect
|
||||||
@ -539,8 +544,8 @@ const rectWithTitle = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const stadium = (parent, node) => {
|
const stadium = async (parent, node) => {
|
||||||
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
|
||||||
|
|
||||||
const h = bbox.height + node.padding;
|
const h = bbox.height + node.padding;
|
||||||
const w = bbox.width + h / 4 + node.padding;
|
const w = bbox.width + h / 4 + node.padding;
|
||||||
@ -565,8 +570,8 @@ const stadium = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const circle = (parent, node) => {
|
const circle = async (parent, node) => {
|
||||||
const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, undefined, true);
|
||||||
const circle = shapeSvg.insert('circle', ':first-child');
|
const circle = shapeSvg.insert('circle', ':first-child');
|
||||||
|
|
||||||
// center the circle around its coordinate
|
// center the circle around its coordinate
|
||||||
@ -590,8 +595,8 @@ const circle = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const doublecircle = (parent, node) => {
|
const doublecircle = async (parent, node) => {
|
||||||
const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox, halfPadding } = await labelHelper(parent, node, undefined, true);
|
||||||
const gap = 5;
|
const gap = 5;
|
||||||
const circleGroup = shapeSvg.insert('g', ':first-child');
|
const circleGroup = shapeSvg.insert('g', ':first-child');
|
||||||
const outerCircle = circleGroup.insert('circle');
|
const outerCircle = circleGroup.insert('circle');
|
||||||
@ -626,8 +631,8 @@ const doublecircle = (parent, node) => {
|
|||||||
return shapeSvg;
|
return shapeSvg;
|
||||||
};
|
};
|
||||||
|
|
||||||
const subroutine = (parent, node) => {
|
const subroutine = async (parent, node) => {
|
||||||
const { shapeSvg, bbox } = labelHelper(parent, node, undefined, true);
|
const { shapeSvg, bbox } = await labelHelper(parent, node, undefined, true);
|
||||||
|
|
||||||
const w = bbox.width + node.padding;
|
const w = bbox.width + node.padding;
|
||||||
const h = bbox.height + node.padding;
|
const h = bbox.height + node.padding;
|
||||||
@ -976,7 +981,7 @@ const shapes = {
|
|||||||
|
|
||||||
let nodeElems = {};
|
let nodeElems = {};
|
||||||
|
|
||||||
export const insertNode = (elem, node, dir) => {
|
export const insertNode = async (elem, node, dir) => {
|
||||||
let newEl;
|
let newEl;
|
||||||
let el;
|
let el;
|
||||||
|
|
||||||
@ -989,9 +994,9 @@ export const insertNode = (elem, node, dir) => {
|
|||||||
target = node.linkTarget || '_blank';
|
target = node.linkTarget || '_blank';
|
||||||
}
|
}
|
||||||
newEl = elem.insert('svg:a').attr('xlink:href', node.link).attr('target', target);
|
newEl = elem.insert('svg:a').attr('xlink:href', node.link).attr('target', target);
|
||||||
el = shapes[node.shape](newEl, node, dir);
|
el = await shapes[node.shape](newEl, node, dir);
|
||||||
} else {
|
} else {
|
||||||
el = shapes[node.shape](elem, node, dir);
|
el = await shapes[node.shape](elem, node, dir);
|
||||||
newEl = el;
|
newEl = el;
|
||||||
}
|
}
|
||||||
if (node.tooltip) {
|
if (node.tooltip) {
|
||||||
@ -1017,6 +1022,7 @@ export const clear = () => {
|
|||||||
|
|
||||||
export const positionNode = (node) => {
|
export const positionNode = (node) => {
|
||||||
const el = nodeElems[node.id];
|
const el = nodeElems[node.id];
|
||||||
|
|
||||||
log.trace(
|
log.trace(
|
||||||
'Transforming node',
|
'Transforming node',
|
||||||
node.diff,
|
node.diff,
|
||||||
|
@ -3,12 +3,17 @@ import { log } from '../../logger';
|
|||||||
import { getConfig } from '../../config';
|
import { getConfig } from '../../config';
|
||||||
import intersect from '../intersect/index.js';
|
import intersect from '../intersect/index.js';
|
||||||
|
|
||||||
const note = (parent, node) => {
|
const note = async (parent, node) => {
|
||||||
const useHtmlLabels = node.useHtmlLabels || getConfig().flowchart.htmlLabels;
|
const useHtmlLabels = node.useHtmlLabels || getConfig().flowchart.htmlLabels;
|
||||||
if (!useHtmlLabels) {
|
if (!useHtmlLabels) {
|
||||||
node.centerLabel = true;
|
node.centerLabel = true;
|
||||||
}
|
}
|
||||||
const { shapeSvg, bbox, halfPadding } = labelHelper(parent, node, 'node ' + node.classes, true);
|
const { shapeSvg, bbox, halfPadding } = await labelHelper(
|
||||||
|
parent,
|
||||||
|
node,
|
||||||
|
'node ' + node.classes,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
log.info('Classes = ', node.classes);
|
log.info('Classes = ', node.classes);
|
||||||
// add the rect
|
// add the rect
|
||||||
|
@ -4,7 +4,8 @@ import { getConfig } from '../../config';
|
|||||||
import { decodeEntities } from '../../mermaidAPI';
|
import { decodeEntities } from '../../mermaidAPI';
|
||||||
import { select } from 'd3';
|
import { select } from 'd3';
|
||||||
import { evaluate, sanitizeText } from '../../diagrams/common/common';
|
import { evaluate, sanitizeText } from '../../diagrams/common/common';
|
||||||
export const labelHelper = (parent, node, _classes, isNode) => {
|
|
||||||
|
export const labelHelper = async (parent, node, _classes, isNode) => {
|
||||||
let classes;
|
let classes;
|
||||||
const useHtmlLabels = node.useHtmlLabels || evaluate(getConfig().flowchart.htmlLabels);
|
const useHtmlLabels = node.useHtmlLabels || evaluate(getConfig().flowchart.htmlLabels);
|
||||||
if (!_classes) {
|
if (!_classes) {
|
||||||
@ -51,17 +52,47 @@ export const labelHelper = (parent, node, _classes, isNode) => {
|
|||||||
|
|
||||||
// Get the size of the label
|
// Get the size of the label
|
||||||
let bbox = text.getBBox();
|
let bbox = text.getBBox();
|
||||||
|
const halfPadding = node.padding / 2;
|
||||||
|
|
||||||
if (evaluate(getConfig().flowchart.htmlLabels)) {
|
if (evaluate(getConfig().flowchart.htmlLabels)) {
|
||||||
const div = text.children[0];
|
const div = text.children[0];
|
||||||
const dv = select(text);
|
const dv = select(text);
|
||||||
|
|
||||||
|
// if there are images, need to wait for them to load before getting the bounding box
|
||||||
|
const images = div.getElementsByTagName('img');
|
||||||
|
if (images) {
|
||||||
|
const noImgText = labelText.replace(/<img[^>]*>/g, '').trim() === '';
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
[...images].map(
|
||||||
|
(img) =>
|
||||||
|
new Promise((res) =>
|
||||||
|
img.addEventListener('load', function () {
|
||||||
|
img.style.display = 'flex';
|
||||||
|
img.style.flexDirection = 'column';
|
||||||
|
|
||||||
|
if (noImgText) {
|
||||||
|
// default size if no text
|
||||||
|
const bodyFontSize = getConfig().fontSize
|
||||||
|
? getConfig().fontSize
|
||||||
|
: window.getComputedStyle(document.body).fontSize;
|
||||||
|
const enlargingFactor = 5;
|
||||||
|
img.style.width = parseInt(bodyFontSize, 10) * enlargingFactor + 'px';
|
||||||
|
} else {
|
||||||
|
img.style.width = '100%';
|
||||||
|
}
|
||||||
|
res(img);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
bbox = div.getBoundingClientRect();
|
bbox = div.getBoundingClientRect();
|
||||||
dv.attr('width', bbox.width);
|
dv.attr('width', bbox.width);
|
||||||
dv.attr('height', bbox.height);
|
dv.attr('height', bbox.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
const halfPadding = node.padding / 2;
|
|
||||||
|
|
||||||
// Center the label
|
// Center the label
|
||||||
if (useHtmlLabels) {
|
if (useHtmlLabels) {
|
||||||
label.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + -bbox.height / 2 + ')');
|
label.attr('transform', 'translate(' + -bbox.width / 2 + ', ' + -bbox.height / 2 + ')');
|
||||||
|
@ -248,7 +248,7 @@ export const setConf = function (cnf: any) {
|
|||||||
* @param _version -
|
* @param _version -
|
||||||
* @param diagObj -
|
* @param diagObj -
|
||||||
*/
|
*/
|
||||||
export const draw = function (text: string, id: string, _version: string, diagObj: any) {
|
export const draw = async function (text: string, id: string, _version: string, diagObj: any) {
|
||||||
log.info('Drawing class - ', id);
|
log.info('Drawing class - ', id);
|
||||||
|
|
||||||
// TODO V10: Why flowchart? Might be a mistake when copying.
|
// TODO V10: Why flowchart? Might be a mistake when copying.
|
||||||
@ -300,7 +300,7 @@ export const draw = function (text: string, id: string, _version: string, diagOb
|
|||||||
// Run the renderer. This is what draws the final graph.
|
// Run the renderer. This is what draws the final graph.
|
||||||
// @ts-ignore Ignore type error for now
|
// @ts-ignore Ignore type error for now
|
||||||
const element = root.select('#' + id + ' g');
|
const element = root.select('#' + id + ' g');
|
||||||
render(
|
await render(
|
||||||
element,
|
element,
|
||||||
g,
|
g,
|
||||||
['aggregation', 'extension', 'composition', 'dependency', 'lollipop'],
|
['aggregation', 'extension', 'composition', 'dependency', 'lollipop'],
|
||||||
|
@ -35,229 +35,231 @@ let nodeDb = {};
|
|||||||
// * @param doc
|
// * @param doc
|
||||||
// * @param diagObj
|
// * @param diagObj
|
||||||
// */
|
// */
|
||||||
export const addVertices = function (vert, svgId, root, doc, diagObj, parentLookupDb, graph) {
|
export const addVertices = async function (vert, svgId, root, doc, diagObj, parentLookupDb, graph) {
|
||||||
const svg = root.select(`[id="${svgId}"]`);
|
const svg = root.select(`[id="${svgId}"]`);
|
||||||
const nodes = svg.insert('g').attr('class', 'nodes');
|
const nodes = svg.insert('g').attr('class', 'nodes');
|
||||||
const keys = Object.keys(vert);
|
const keys = Object.keys(vert);
|
||||||
|
|
||||||
// Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
|
// Iterate through each item in the vertex object (containing all the vertices found) in the graph definition
|
||||||
keys.forEach(function (id) {
|
await Promise.all(
|
||||||
const vertex = vert[id];
|
keys.map(async function (id) {
|
||||||
|
const vertex = vert[id];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Variable for storing the classes for the vertex
|
* Variable for storing the classes for the vertex
|
||||||
*
|
*
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
let classStr = 'default';
|
let classStr = 'default';
|
||||||
if (vertex.classes.length > 0) {
|
if (vertex.classes.length > 0) {
|
||||||
classStr = vertex.classes.join(' ');
|
classStr = vertex.classes.join(' ');
|
||||||
}
|
}
|
||||||
classStr = classStr + ' flowchart-label';
|
classStr = classStr + ' flowchart-label';
|
||||||
const styles = getStylesFromArray(vertex.styles);
|
const styles = getStylesFromArray(vertex.styles);
|
||||||
|
|
||||||
// Use vertex id as text in the box if no text is provided by the graph definition
|
// Use vertex id as text in the box if no text is provided by the graph definition
|
||||||
let vertexText = vertex.text !== undefined ? vertex.text : vertex.id;
|
let vertexText = vertex.text !== undefined ? vertex.text : vertex.id;
|
||||||
|
|
||||||
// We create a SVG label, either by delegating to addHtmlLabel or manually
|
// We create a SVG label, either by delegating to addHtmlLabel or manually
|
||||||
let vertexNode;
|
let vertexNode;
|
||||||
const labelData = { width: 0, height: 0 };
|
const labelData = { width: 0, height: 0 };
|
||||||
|
|
||||||
const ports = [
|
const ports = [
|
||||||
{
|
{
|
||||||
id: vertex.id + '-west',
|
id: vertex.id + '-west',
|
||||||
layoutOptions: {
|
layoutOptions: {
|
||||||
'port.side': 'WEST',
|
'port.side': 'WEST',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
id: vertex.id + '-east',
|
||||||
id: vertex.id + '-east',
|
layoutOptions: {
|
||||||
layoutOptions: {
|
'port.side': 'EAST',
|
||||||
'port.side': 'EAST',
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
id: vertex.id + '-south',
|
||||||
id: vertex.id + '-south',
|
layoutOptions: {
|
||||||
layoutOptions: {
|
'port.side': 'SOUTH',
|
||||||
'port.side': 'SOUTH',
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
id: vertex.id + '-north',
|
||||||
id: vertex.id + '-north',
|
layoutOptions: {
|
||||||
layoutOptions: {
|
'port.side': 'NORTH',
|
||||||
'port.side': 'NORTH',
|
},
|
||||||
},
|
},
|
||||||
},
|
];
|
||||||
];
|
|
||||||
|
|
||||||
let radious = 0;
|
let radious = 0;
|
||||||
let _shape = '';
|
let _shape = '';
|
||||||
let layoutOptions = {};
|
let layoutOptions = {};
|
||||||
// Set the shape based parameters
|
// Set the shape based parameters
|
||||||
switch (vertex.type) {
|
switch (vertex.type) {
|
||||||
case 'round':
|
case 'round':
|
||||||
radious = 5;
|
radious = 5;
|
||||||
_shape = 'rect';
|
_shape = 'rect';
|
||||||
break;
|
break;
|
||||||
case 'square':
|
case 'square':
|
||||||
_shape = 'rect';
|
_shape = 'rect';
|
||||||
break;
|
break;
|
||||||
case 'diamond':
|
case 'diamond':
|
||||||
_shape = 'question';
|
_shape = 'question';
|
||||||
layoutOptions = {
|
layoutOptions = {
|
||||||
portConstraints: 'FIXED_SIDE',
|
portConstraints: 'FIXED_SIDE',
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'hexagon':
|
case 'hexagon':
|
||||||
_shape = 'hexagon';
|
_shape = 'hexagon';
|
||||||
break;
|
break;
|
||||||
case 'odd':
|
case 'odd':
|
||||||
_shape = 'rect_left_inv_arrow';
|
_shape = 'rect_left_inv_arrow';
|
||||||
break;
|
break;
|
||||||
case 'lean_right':
|
case 'lean_right':
|
||||||
_shape = 'lean_right';
|
_shape = 'lean_right';
|
||||||
break;
|
break;
|
||||||
case 'lean_left':
|
case 'lean_left':
|
||||||
_shape = 'lean_left';
|
_shape = 'lean_left';
|
||||||
break;
|
break;
|
||||||
case 'trapezoid':
|
case 'trapezoid':
|
||||||
_shape = 'trapezoid';
|
_shape = 'trapezoid';
|
||||||
break;
|
break;
|
||||||
case 'inv_trapezoid':
|
case 'inv_trapezoid':
|
||||||
_shape = 'inv_trapezoid';
|
_shape = 'inv_trapezoid';
|
||||||
break;
|
break;
|
||||||
case 'odd_right':
|
case 'odd_right':
|
||||||
_shape = 'rect_left_inv_arrow';
|
_shape = 'rect_left_inv_arrow';
|
||||||
break;
|
break;
|
||||||
case 'circle':
|
case 'circle':
|
||||||
_shape = 'circle';
|
_shape = 'circle';
|
||||||
break;
|
break;
|
||||||
case 'ellipse':
|
case 'ellipse':
|
||||||
_shape = 'ellipse';
|
_shape = 'ellipse';
|
||||||
break;
|
break;
|
||||||
case 'stadium':
|
case 'stadium':
|
||||||
_shape = 'stadium';
|
_shape = 'stadium';
|
||||||
break;
|
break;
|
||||||
case 'subroutine':
|
case 'subroutine':
|
||||||
_shape = 'subroutine';
|
_shape = 'subroutine';
|
||||||
break;
|
break;
|
||||||
case 'cylinder':
|
case 'cylinder':
|
||||||
_shape = 'cylinder';
|
_shape = 'cylinder';
|
||||||
break;
|
break;
|
||||||
case 'group':
|
case 'group':
|
||||||
_shape = 'rect';
|
_shape = 'rect';
|
||||||
break;
|
break;
|
||||||
case 'doublecircle':
|
case 'doublecircle':
|
||||||
_shape = 'doublecircle';
|
_shape = 'doublecircle';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_shape = 'rect';
|
_shape = 'rect';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the node
|
// Add the node
|
||||||
const node = {
|
const node = {
|
||||||
labelStyle: styles.labelStyle,
|
labelStyle: styles.labelStyle,
|
||||||
shape: _shape,
|
shape: _shape,
|
||||||
labelText: vertexText,
|
labelText: vertexText,
|
||||||
labelType: vertex.labelType,
|
labelType: vertex.labelType,
|
||||||
rx: radious,
|
rx: radious,
|
||||||
ry: radious,
|
ry: radious,
|
||||||
class: classStr,
|
class: classStr,
|
||||||
style: styles.style,
|
style: styles.style,
|
||||||
id: vertex.id,
|
id: vertex.id,
|
||||||
link: vertex.link,
|
link: vertex.link,
|
||||||
linkTarget: vertex.linkTarget,
|
linkTarget: vertex.linkTarget,
|
||||||
tooltip: diagObj.db.getTooltip(vertex.id) || '',
|
tooltip: diagObj.db.getTooltip(vertex.id) || '',
|
||||||
domId: diagObj.db.lookUpDomId(vertex.id),
|
domId: diagObj.db.lookUpDomId(vertex.id),
|
||||||
haveCallback: vertex.haveCallback,
|
haveCallback: vertex.haveCallback,
|
||||||
width: vertex.type === 'group' ? 500 : undefined,
|
width: vertex.type === 'group' ? 500 : undefined,
|
||||||
dir: vertex.dir,
|
dir: vertex.dir,
|
||||||
type: vertex.type,
|
type: vertex.type,
|
||||||
props: vertex.props,
|
props: vertex.props,
|
||||||
padding: getConfig().flowchart.padding,
|
padding: getConfig().flowchart.padding,
|
||||||
};
|
};
|
||||||
let boundingBox;
|
let boundingBox;
|
||||||
let nodeEl;
|
let nodeEl;
|
||||||
|
|
||||||
// Add the element to the DOM
|
// Add the element to the DOM
|
||||||
if (node.type !== 'group') {
|
if (node.type !== 'group') {
|
||||||
nodeEl = insertNode(nodes, node, vertex.dir);
|
nodeEl = insertNode(nodes, node, vertex.dir);
|
||||||
boundingBox = nodeEl.node().getBBox();
|
boundingBox = nodeEl.node().getBBox();
|
||||||
} else {
|
} else {
|
||||||
const svgLabel = doc.createElementNS('http://www.w3.org/2000/svg', 'text');
|
const svgLabel = doc.createElementNS('http://www.w3.org/2000/svg', 'text');
|
||||||
// svgLabel.setAttribute('style', styles.labelStyle.replace('color:', 'fill:'));
|
// svgLabel.setAttribute('style', styles.labelStyle.replace('color:', 'fill:'));
|
||||||
// const rows = vertexText.split(common.lineBreakRegex);
|
// const rows = vertexText.split(common.lineBreakRegex);
|
||||||
// for (const row of rows) {
|
// for (const row of rows) {
|
||||||
// const tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
// const tspan = doc.createElementNS('http://www.w3.org/2000/svg', 'tspan');
|
||||||
// tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
|
// tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
|
||||||
// tspan.setAttribute('dy', '1em');
|
// tspan.setAttribute('dy', '1em');
|
||||||
// tspan.setAttribute('x', '1');
|
// tspan.setAttribute('x', '1');
|
||||||
// tspan.textContent = row;
|
// tspan.textContent = row;
|
||||||
// svgLabel.appendChild(tspan);
|
// svgLabel.appendChild(tspan);
|
||||||
|
// }
|
||||||
|
// vertexNode = svgLabel;
|
||||||
|
// const bbox = vertexNode.getBBox();
|
||||||
|
const { shapeSvg, bbox } = await labelHelper(nodes, node, undefined, true);
|
||||||
|
labelData.width = bbox.width;
|
||||||
|
labelData.wrappingWidth = getConfig().flowchart.wrappingWidth;
|
||||||
|
labelData.height = bbox.height;
|
||||||
|
labelData.labelNode = shapeSvg.node();
|
||||||
|
node.labelData = labelData;
|
||||||
|
}
|
||||||
|
// const { shapeSvg, bbox } = await labelHelper(svg, node, undefined, true);
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
id: vertex.id,
|
||||||
|
ports: vertex.type === 'diamond' ? ports : [],
|
||||||
|
// labelStyle: styles.labelStyle,
|
||||||
|
// shape: _shape,
|
||||||
|
layoutOptions,
|
||||||
|
labelText: vertexText,
|
||||||
|
labelData,
|
||||||
|
// labels: [{ text: vertexText }],
|
||||||
|
// rx: radius,
|
||||||
|
// ry: radius,
|
||||||
|
// class: classStr,
|
||||||
|
// style: styles.style,
|
||||||
|
// link: vertex.link,
|
||||||
|
// linkTarget: vertex.linkTarget,
|
||||||
|
// tooltip: diagObj.db.getTooltip(vertex.id) || '',
|
||||||
|
domId: diagObj.db.lookUpDomId(vertex.id),
|
||||||
|
// haveCallback: vertex.haveCallback,
|
||||||
|
width: boundingBox?.width,
|
||||||
|
height: boundingBox?.height,
|
||||||
|
// dir: vertex.dir,
|
||||||
|
type: vertex.type,
|
||||||
|
// props: vertex.props,
|
||||||
|
// padding: getConfig().flowchart.padding,
|
||||||
|
// boundingBox,
|
||||||
|
el: nodeEl,
|
||||||
|
parent: parentLookupDb.parentById[vertex.id],
|
||||||
|
};
|
||||||
|
// if (!Object.keys(parentLookupDb.childrenById).includes(vertex.id)) {
|
||||||
|
// graph.children.push({
|
||||||
|
// ...data,
|
||||||
|
// });
|
||||||
// }
|
// }
|
||||||
// vertexNode = svgLabel;
|
nodeDb[node.id] = data;
|
||||||
// const bbox = vertexNode.getBBox();
|
// log.trace('setNode', {
|
||||||
const { shapeSvg, bbox } = labelHelper(nodes, node, undefined, true);
|
// labelStyle: styles.labelStyle,
|
||||||
labelData.width = bbox.width;
|
// shape: _shape,
|
||||||
labelData.wrappingWidth = getConfig().flowchart.wrappingWidth;
|
// labelText: vertexText,
|
||||||
labelData.height = bbox.height;
|
// rx: radius,
|
||||||
labelData.labelNode = shapeSvg.node();
|
// ry: radius,
|
||||||
node.labelData = labelData;
|
// class: classStr,
|
||||||
}
|
// style: styles.style,
|
||||||
// const { shapeSvg, bbox } = labelHelper(svg, node, undefined, true);
|
// id: vertex.id,
|
||||||
|
// domId: diagObj.db.lookUpDomId(vertex.id),
|
||||||
const data = {
|
// width: vertex.type === 'group' ? 500 : undefined,
|
||||||
id: vertex.id,
|
// type: vertex.type,
|
||||||
ports: vertex.type === 'diamond' ? ports : [],
|
// dir: vertex.dir,
|
||||||
// labelStyle: styles.labelStyle,
|
// props: vertex.props,
|
||||||
// shape: _shape,
|
// padding: getConfig().flowchart.padding,
|
||||||
layoutOptions,
|
// parent: parentLookupDb.parentById[vertex.id],
|
||||||
labelText: vertexText,
|
// });
|
||||||
labelData,
|
})
|
||||||
// labels: [{ text: vertexText }],
|
);
|
||||||
// rx: radius,
|
|
||||||
// ry: radius,
|
|
||||||
// class: classStr,
|
|
||||||
// style: styles.style,
|
|
||||||
// link: vertex.link,
|
|
||||||
// linkTarget: vertex.linkTarget,
|
|
||||||
// tooltip: diagObj.db.getTooltip(vertex.id) || '',
|
|
||||||
domId: diagObj.db.lookUpDomId(vertex.id),
|
|
||||||
// haveCallback: vertex.haveCallback,
|
|
||||||
width: boundingBox?.width,
|
|
||||||
height: boundingBox?.height,
|
|
||||||
// dir: vertex.dir,
|
|
||||||
type: vertex.type,
|
|
||||||
// props: vertex.props,
|
|
||||||
// padding: getConfig().flowchart.padding,
|
|
||||||
// boundingBox,
|
|
||||||
el: nodeEl,
|
|
||||||
parent: parentLookupDb.parentById[vertex.id],
|
|
||||||
};
|
|
||||||
// if (!Object.keys(parentLookupDb.childrenById).includes(vertex.id)) {
|
|
||||||
// graph.children.push({
|
|
||||||
// ...data,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
nodeDb[node.id] = data;
|
|
||||||
// log.trace('setNode', {
|
|
||||||
// labelStyle: styles.labelStyle,
|
|
||||||
// shape: _shape,
|
|
||||||
// labelText: vertexText,
|
|
||||||
// rx: radius,
|
|
||||||
// ry: radius,
|
|
||||||
// class: classStr,
|
|
||||||
// style: styles.style,
|
|
||||||
// id: vertex.id,
|
|
||||||
// domId: diagObj.db.lookUpDomId(vertex.id),
|
|
||||||
// width: vertex.type === 'group' ? 500 : undefined,
|
|
||||||
// type: vertex.type,
|
|
||||||
// dir: vertex.dir,
|
|
||||||
// props: vertex.props,
|
|
||||||
// padding: getConfig().flowchart.padding,
|
|
||||||
// parent: parentLookupDb.parentById[vertex.id],
|
|
||||||
// });
|
|
||||||
});
|
|
||||||
return graph;
|
return graph;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -861,7 +863,7 @@ export const draw = async function (text, id, _version, diagObj) {
|
|||||||
// in order to get the size of the node. You can't get the size of a node
|
// in order to get the size of the node. You can't get the size of a node
|
||||||
// that is not in the dom so we need to add it to the dom, get the size
|
// that is not in the dom so we need to add it to the dom, get the size
|
||||||
// we will position the nodes when we get the layout from elkjs
|
// we will position the nodes when we get the layout from elkjs
|
||||||
graph = addVertices(vert, id, root, doc, diagObj, parentLookupDb, graph, svg);
|
graph = await addVertices(vert, id, root, doc, diagObj, parentLookupDb, graph);
|
||||||
|
|
||||||
// Time for the edges, we start with adding an element in the node to hold the edges
|
// Time for the edges, we start with adding an element in the node to hold the edges
|
||||||
const edgesEl = svg.insert('g').attr('class', 'edges edgePath');
|
const edgesEl = svg.insert('g').attr('class', 'edges edgePath');
|
||||||
|
@ -362,7 +362,7 @@ export const getClasses = function (text, diagObj) {
|
|||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const draw = function (text, id, _version, diagObj) {
|
export const draw = async function (text, id, _version, diagObj) {
|
||||||
log.info('Drawing flowchart');
|
log.info('Drawing flowchart');
|
||||||
diagObj.db.clear();
|
diagObj.db.clear();
|
||||||
flowDb.setGen('gen-2');
|
flowDb.setGen('gen-2');
|
||||||
@ -451,7 +451,7 @@ export const draw = function (text, id, _version, diagObj) {
|
|||||||
|
|
||||||
// Run the renderer. This is what draws the final graph.
|
// Run the renderer. This is what draws the final graph.
|
||||||
const element = root.select('#' + id + ' g');
|
const element = root.select('#' + id + ' g');
|
||||||
render(element, g, ['point', 'circle', 'cross'], 'flowchart', id);
|
await render(element, g, ['point', 'circle', 'cross'], 'flowchart', id);
|
||||||
|
|
||||||
utils.insertTitle(svg, 'flowchartTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
|
utils.insertTitle(svg, 'flowchartTitleText', conf.titleTopMargin, diagObj.db.getDiagramTitle());
|
||||||
|
|
||||||
|
@ -382,7 +382,7 @@ const getDir = (parsedItem, defaultDir = DEFAULT_NESTED_DOC_DIR) => {
|
|||||||
* @param _version
|
* @param _version
|
||||||
* @param diag
|
* @param diag
|
||||||
*/
|
*/
|
||||||
export const draw = function (text, id, _version, diag) {
|
export const draw = async function (text, id, _version, diag) {
|
||||||
log.info('Drawing state diagram (v2)', id);
|
log.info('Drawing state diagram (v2)', id);
|
||||||
// diag.sb.clear();
|
// diag.sb.clear();
|
||||||
nodeDb = {};
|
nodeDb = {};
|
||||||
@ -436,7 +436,7 @@ export const draw = function (text, id, _version, diag) {
|
|||||||
// Run the renderer. This is what draws the final graph.
|
// Run the renderer. This is what draws the final graph.
|
||||||
|
|
||||||
const element = root.select('#' + id + ' g');
|
const element = root.select('#' + id + ' g');
|
||||||
render(element, g, ['barb'], CSS_DIAGRAM, id);
|
await render(element, g, ['barb'], CSS_DIAGRAM, id);
|
||||||
|
|
||||||
const padding = 8;
|
const padding = 8;
|
||||||
|
|
||||||
|
@ -406,6 +406,12 @@ const render = async function (
|
|||||||
// clean up text CRLFs
|
// clean up text CRLFs
|
||||||
text = text.replace(/\r\n?/g, '\n'); // parser problems on CRLF ignore all CR and leave LF;;
|
text = text.replace(/\r\n?/g, '\n'); // parser problems on CRLF ignore all CR and leave LF;;
|
||||||
|
|
||||||
|
// clean up html tags so that all attributes use single quotes, parser throws error on double quotes
|
||||||
|
text = text.replace(
|
||||||
|
/<(\w+)([^>]*)>/g,
|
||||||
|
(match, tag, attributes) => '<' + tag + attributes.replace(/="([^"]*)"/g, "='$1'") + '>'
|
||||||
|
);
|
||||||
|
|
||||||
const idSelector = '#' + id;
|
const idSelector = '#' + id;
|
||||||
const iFrameID = 'i' + id;
|
const iFrameID = 'i' + id;
|
||||||
const iFrameID_selector = '#' + iFrameID;
|
const iFrameID_selector = '#' + iFrameID;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user