mirror of
				https://github.com/mermaid-js/mermaid.git
				synced 2025-11-04 12:54:08 +01:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			mermaid@11
			...
			fix/html-l
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					920d55402c | ||
| 
						 | 
					eb373ef207 | ||
| 
						 | 
					5be5415eee | ||
| 
						 | 
					1f6d235d23 | ||
| 
						 | 
					464ff95e5b | ||
| 
						 | 
					ade130747e | ||
| 
						 | 
					b85f75d434 | ||
| 
						 | 
					810071c46b | 
@@ -122,6 +122,46 @@ describe('Flowchart v2', () => {
 | 
			
		||||
      expect(svg).to.not.have.attr('style');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it('renders only pure SVG labels (no <foreignObject>) when flowchart.htmlLabels=false', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
  flowchart:
 | 
			
		||||
    htmlLabels: false
 | 
			
		||||
---
 | 
			
		||||
    flowchart LR
 | 
			
		||||
      subgraph \`**One**\`
 | 
			
		||||
        a["\`**The cat**
 | 
			
		||||
        in the hat\`"] -- "\`**edge label**\`" --> b{{"\`**The dog** in the hog\`"}}
 | 
			
		||||
      end
 | 
			
		||||
      subgraph \`**Two**\`
 | 
			
		||||
        c["\`**The cat**
 | 
			
		||||
        in the hat\`"] -- "\`**Bold edge label**\`" --> d["\`The dog in the hog\`"]
 | 
			
		||||
      end
 | 
			
		||||
    `
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg').find('foreignObject').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('renders only pure SVG labels (no <foreignObject>) when global htmlLabels=false', () => {
 | 
			
		||||
    renderGraph(
 | 
			
		||||
      `---
 | 
			
		||||
config:
 | 
			
		||||
    htmlLabels: false
 | 
			
		||||
---
 | 
			
		||||
    flowchart LR
 | 
			
		||||
      subgraph \`**One**\`
 | 
			
		||||
        a["\`**The cat**
 | 
			
		||||
        in the hat\`"] -- "\`**edge label**\`" --> b{{"\`**The dog** in the hog\`"}}
 | 
			
		||||
      end
 | 
			
		||||
      subgraph \`**Two**\`
 | 
			
		||||
        c["\`**The cat**
 | 
			
		||||
        in the hat\`"] -- "\`**Bold edge label**\`" --> d["\`The dog in the hog\`"]
 | 
			
		||||
      end
 | 
			
		||||
    `
 | 
			
		||||
    );
 | 
			
		||||
    cy.get('svg').find('foreignObject').should('not.exist');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('V2 - 16: Render Stadium shape', () => {
 | 
			
		||||
    imgSnapshotTest(
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
 | 
			
		||||
# Interface: DetailedError
 | 
			
		||||
 | 
			
		||||
Defined in: [packages/mermaid/src/utils.ts:783](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L783)
 | 
			
		||||
Defined in: [packages/mermaid/src/utils.ts:784](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L784)
 | 
			
		||||
 | 
			
		||||
## Properties
 | 
			
		||||
 | 
			
		||||
@@ -18,7 +18,7 @@ Defined in: [packages/mermaid/src/utils.ts:783](https://github.com/mermaid-js/me
 | 
			
		||||
 | 
			
		||||
> `optional` **error**: `any`
 | 
			
		||||
 | 
			
		||||
Defined in: [packages/mermaid/src/utils.ts:788](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L788)
 | 
			
		||||
Defined in: [packages/mermaid/src/utils.ts:789](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L789)
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
@@ -26,7 +26,7 @@ Defined in: [packages/mermaid/src/utils.ts:788](https://github.com/mermaid-js/me
 | 
			
		||||
 | 
			
		||||
> **hash**: `any`
 | 
			
		||||
 | 
			
		||||
Defined in: [packages/mermaid/src/utils.ts:786](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L786)
 | 
			
		||||
Defined in: [packages/mermaid/src/utils.ts:787](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L787)
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
@@ -34,7 +34,7 @@ Defined in: [packages/mermaid/src/utils.ts:786](https://github.com/mermaid-js/me
 | 
			
		||||
 | 
			
		||||
> `optional` **message**: `string`
 | 
			
		||||
 | 
			
		||||
Defined in: [packages/mermaid/src/utils.ts:789](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L789)
 | 
			
		||||
Defined in: [packages/mermaid/src/utils.ts:790](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L790)
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
@@ -42,4 +42,4 @@ Defined in: [packages/mermaid/src/utils.ts:789](https://github.com/mermaid-js/me
 | 
			
		||||
 | 
			
		||||
> **str**: `string`
 | 
			
		||||
 | 
			
		||||
Defined in: [packages/mermaid/src/utils.ts:784](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L784)
 | 
			
		||||
Defined in: [packages/mermaid/src/utils.ts:785](https://github.com/mermaid-js/mermaid/blob/master/packages/mermaid/src/utils.ts#L785)
 | 
			
		||||
 
 | 
			
		||||
@@ -33,10 +33,7 @@ const getStyles = (options: FlowChartStyleOptions) =>
 | 
			
		||||
    background-color: ${fade(options.tertiaryColor, 0.5)};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .edgeLabel .label {
 | 
			
		||||
    fill: ${options.nodeBorder};
 | 
			
		||||
    font-size: 14px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  .label {
 | 
			
		||||
    font-family: ${options.fontFamily};
 | 
			
		||||
@@ -68,6 +65,14 @@ const getStyles = (options: FlowChartStyleOptions) =>
 | 
			
		||||
    stroke: ${options.lineColor} !important;
 | 
			
		||||
    stroke-width: 1;
 | 
			
		||||
  }
 | 
			
		||||
    .background {
 | 
			
		||||
    fill: ${options.tertiaryColor};
 | 
			
		||||
    opacity: 0.7;
 | 
			
		||||
    background-color: ${options.tertiaryColor};
 | 
			
		||||
      rect {
 | 
			
		||||
        opacity: 0.5;
 | 
			
		||||
      }
 | 
			
		||||
 }
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
export default getStyles;
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ import { getConfig } from '../../diagram-api/diagramAPI.js';
 | 
			
		||||
import type { DiagramDB } from '../../diagram-api/types.js';
 | 
			
		||||
import { log } from '../../logger.js';
 | 
			
		||||
import type { Node, Edge } from '../../rendering-util/types.js';
 | 
			
		||||
import { shouldUseHtmlLabels } from '../../utils.js';
 | 
			
		||||
 | 
			
		||||
import {
 | 
			
		||||
  setAccTitle,
 | 
			
		||||
@@ -317,11 +318,17 @@ export class RequirementDB implements DiagramDB {
 | 
			
		||||
    for (const relation of this.relations) {
 | 
			
		||||
      let counter = 0;
 | 
			
		||||
      const isContains = relation.type === this.Relationships.CONTAINS;
 | 
			
		||||
 | 
			
		||||
      let relationLabel = `<<${relation.type}>>`;
 | 
			
		||||
      if (!shouldUseHtmlLabels()) {
 | 
			
		||||
        relationLabel = relationLabel.replace(/</g, '<').replace(/>/g, '>');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const edge: Edge = {
 | 
			
		||||
        id: `${relation.src}-${relation.dst}-${counter}`,
 | 
			
		||||
        start: this.requirements.get(relation.src)?.name ?? this.elements.get(relation.src)?.name,
 | 
			
		||||
        end: this.requirements.get(relation.dst)?.name ?? this.elements.get(relation.dst)?.name,
 | 
			
		||||
        label: `<<${relation.type}>>`,
 | 
			
		||||
        label: relationLabel,
 | 
			
		||||
        classes: 'relationshipLine',
 | 
			
		||||
        style: ['fill:none', isContains ? '' : 'stroke-dasharray: 10,7'],
 | 
			
		||||
        labelpos: 'c',
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,11 @@ const getStyles = (options) => `
 | 
			
		||||
  .labelBkg {
 | 
			
		||||
    background-color: ${options.edgeLabelBackground};
 | 
			
		||||
  }
 | 
			
		||||
  .background {
 | 
			
		||||
   fill: ${options.edgeLabelBackground};
 | 
			
		||||
   stroke: none;
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
`;
 | 
			
		||||
// fill', conf.rect_fill)
 | 
			
		||||
 
 | 
			
		||||
@@ -176,8 +176,9 @@ function updateTextContentAndStyles(tspan: any, wrappedLine: MarkdownWord[]) {
 | 
			
		||||
    if (index === 0) {
 | 
			
		||||
      innerTspan.text(word.content);
 | 
			
		||||
    } else {
 | 
			
		||||
      // TODO: check what joiner to use.
 | 
			
		||||
      innerTspan.text(' ' + word.content);
 | 
			
		||||
      const prev = wrappedLine[index - 1].content;
 | 
			
		||||
      const insertSpace = !prev.endsWith('<') && !word.content.startsWith('>');
 | 
			
		||||
      innerTspan.text((insertSpace ? ' ' : '') + word.content);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import intersectRect from '../rendering-elements/intersect/intersect-rect.js';
 | 
			
		||||
import createLabel from './createLabel.js';
 | 
			
		||||
import { createRoundedRectPathD } from './shapes/roundedRectPath.ts';
 | 
			
		||||
import { styles2String, userNodeOverrides } from './shapes/handDrawnShapeStyles.js';
 | 
			
		||||
import { shouldUseHtmlLabels } from '../../utils.js';
 | 
			
		||||
 | 
			
		||||
const rect = async (parent, node) => {
 | 
			
		||||
  log.info('Creating subgraph rect for ', node.id, node);
 | 
			
		||||
@@ -25,8 +26,7 @@ const rect = async (parent, node) => {
 | 
			
		||||
    .attr('id', node.id)
 | 
			
		||||
    .attr('data-look', node.look);
 | 
			
		||||
 | 
			
		||||
  const useHtmlLabels = evaluate(siteConfig.flowchart.htmlLabels);
 | 
			
		||||
 | 
			
		||||
  const useHtmlLabels = shouldUseHtmlLabels();
 | 
			
		||||
  // Create the label and insert it after the rect
 | 
			
		||||
  const labelEl = shapeSvg.insert('g').attr('class', 'cluster-label ');
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,12 @@
 | 
			
		||||
import { select } from 'd3';
 | 
			
		||||
import { getConfig } from '../../diagram-api/diagramAPI.js';
 | 
			
		||||
import common, {
 | 
			
		||||
  evaluate,
 | 
			
		||||
  hasKatex,
 | 
			
		||||
  renderKatexSanitized,
 | 
			
		||||
  sanitizeText,
 | 
			
		||||
} from '../../diagrams/common/common.js';
 | 
			
		||||
import { log } from '../../logger.js';
 | 
			
		||||
import { decodeEntities } from '../../utils.js';
 | 
			
		||||
import { decodeEntities, shouldUseHtmlLabels } from '../../utils.js';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param dom
 | 
			
		||||
@@ -63,8 +62,7 @@ const createLabel = async (_vertexText, style, isTitle, isNode) => {
 | 
			
		||||
  if (typeof vertexText === 'object') {
 | 
			
		||||
    vertexText = vertexText[0];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (evaluate(getConfig().flowchart.htmlLabels)) {
 | 
			
		||||
  if (shouldUseHtmlLabels()) {
 | 
			
		||||
    // TODO: addHtmlLabel accepts a labelStyle. Do we possibly have that?
 | 
			
		||||
    vertexText = vertexText.replace(/\\n|\n/g, '<br />');
 | 
			
		||||
    log.info('vertexText' + vertexText);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
import { getConfig } from '../../diagram-api/diagramAPI.js';
 | 
			
		||||
import { evaluate } from '../../diagrams/common/common.js';
 | 
			
		||||
import { log } from '../../logger.js';
 | 
			
		||||
import { createText } from '../createText.js';
 | 
			
		||||
import utils from '../../utils.js';
 | 
			
		||||
import utils, { shouldUseHtmlLabels } from '../../utils.js';
 | 
			
		||||
import {
 | 
			
		||||
  getLineFunctionsWithOffset,
 | 
			
		||||
  markerOffsets,
 | 
			
		||||
@@ -45,10 +44,13 @@ export const getLabelStyles = (styleArray) => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const insertEdgeLabel = async (elem, edge) => {
 | 
			
		||||
  let useHtmlLabels = evaluate(getConfig().flowchart.htmlLabels);
 | 
			
		||||
  const useHtmlLabels = shouldUseHtmlLabels();
 | 
			
		||||
 | 
			
		||||
  const { labelStyles } = styles2String(edge);
 | 
			
		||||
  edge.labelStyle = labelStyles;
 | 
			
		||||
  // if (useHtmlLabels === false) {
 | 
			
		||||
  //   edge.label = edge.label.replaceAll('>', '>').replaceAll('<', '<');
 | 
			
		||||
  // }
 | 
			
		||||
  const labelElement = await createText(elem, edge.label, {
 | 
			
		||||
    style: edge.labelStyle,
 | 
			
		||||
    useHtmlLabels,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,12 @@ import { getConfig } from '../../../diagram-api/diagramAPI.js';
 | 
			
		||||
import { select } from 'd3';
 | 
			
		||||
import defaultConfig from '../../../defaultConfig.js';
 | 
			
		||||
import { evaluate, sanitizeText } from '../../../diagrams/common/common.js';
 | 
			
		||||
import { decodeEntities, handleUndefinedAttr, parseFontSize } from '../../../utils.js';
 | 
			
		||||
import {
 | 
			
		||||
  decodeEntities,
 | 
			
		||||
  handleUndefinedAttr,
 | 
			
		||||
  parseFontSize,
 | 
			
		||||
  shouldUseHtmlLabels,
 | 
			
		||||
} from '../../../utils.js';
 | 
			
		||||
import type { D3Selection, Point } from '../../../types.js';
 | 
			
		||||
 | 
			
		||||
export const labelHelper = async <T extends SVGGraphicsElement>(
 | 
			
		||||
@@ -13,7 +18,7 @@ export const labelHelper = async <T extends SVGGraphicsElement>(
 | 
			
		||||
  _classes?: string
 | 
			
		||||
) => {
 | 
			
		||||
  let cssClasses;
 | 
			
		||||
  const useHtmlLabels = node.useHtmlLabels || evaluate(getConfig()?.htmlLabels);
 | 
			
		||||
  const useHtmlLabels = shouldUseHtmlLabels();
 | 
			
		||||
  if (!_classes) {
 | 
			
		||||
    cssClasses = 'node default';
 | 
			
		||||
  } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -7,12 +7,12 @@ import {
 | 
			
		||||
  curveBumpX,
 | 
			
		||||
  curveBumpY,
 | 
			
		||||
  curveBundle,
 | 
			
		||||
  curveCardinal,
 | 
			
		||||
  curveCardinalClosed,
 | 
			
		||||
  curveCardinalOpen,
 | 
			
		||||
  curveCardinal,
 | 
			
		||||
  curveCatmullRom,
 | 
			
		||||
  curveCatmullRomClosed,
 | 
			
		||||
  curveCatmullRomOpen,
 | 
			
		||||
  curveCatmullRom,
 | 
			
		||||
  curveLinear,
 | 
			
		||||
  curveLinearClosed,
 | 
			
		||||
  curveMonotoneX,
 | 
			
		||||
@@ -23,16 +23,17 @@ import {
 | 
			
		||||
  curveStepBefore,
 | 
			
		||||
  select,
 | 
			
		||||
} from 'd3';
 | 
			
		||||
import common from './diagrams/common/common.js';
 | 
			
		||||
import { sanitizeDirective } from './utils/sanitizeDirective.js';
 | 
			
		||||
import { log } from './logger.js';
 | 
			
		||||
import { detectType } from './diagram-api/detectType.js';
 | 
			
		||||
import assignWithDepth from './assignWithDepth.js';
 | 
			
		||||
import type { MermaidConfig } from './config.type.js';
 | 
			
		||||
import memoize from 'lodash-es/memoize.js';
 | 
			
		||||
import merge from 'lodash-es/merge.js';
 | 
			
		||||
import assignWithDepth from './assignWithDepth.js';
 | 
			
		||||
import { getUserDefinedConfig } from './config.js';
 | 
			
		||||
import type { MermaidConfig } from './config.type.js';
 | 
			
		||||
import { detectType } from './diagram-api/detectType.js';
 | 
			
		||||
import { directiveRegex } from './diagram-api/regexes.js';
 | 
			
		||||
import common, { evaluate } from './diagrams/common/common.js';
 | 
			
		||||
import { log } from './logger.js';
 | 
			
		||||
import type { D3Element, Point, TextDimensionConfig, TextDimensions } from './types.js';
 | 
			
		||||
import { sanitizeDirective } from './utils/sanitizeDirective.js';
 | 
			
		||||
 | 
			
		||||
export const ZERO_WIDTH_SPACE = '\u200b';
 | 
			
		||||
 | 
			
		||||
@@ -981,3 +982,14 @@ export function isLabelCoordinateInPath(point: Point, dAttr: string) {
 | 
			
		||||
 | 
			
		||||
  return sanitizedD.includes(roundedX.toString()) || sanitizedD.includes(roundedY.toString());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const shouldUseHtmlLabels = () => {
 | 
			
		||||
  const siteConfig = getUserDefinedConfig();
 | 
			
		||||
  let useHtmlLabels;
 | 
			
		||||
  if (siteConfig.flowchart?.htmlLabels !== undefined) {
 | 
			
		||||
    useHtmlLabels = evaluate(siteConfig.flowchart.htmlLabels);
 | 
			
		||||
  } else {
 | 
			
		||||
    useHtmlLabels = evaluate(siteConfig.htmlLabels);
 | 
			
		||||
  }
 | 
			
		||||
  return useHtmlLabels;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user