mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
handle string and number font size configurations
This commit is contained in:
parent
874f4c0641
commit
b93ce24c3d
@ -1,5 +1,6 @@
|
||||
import common from '../common/common';
|
||||
import { addFunction } from '../../interactionDb';
|
||||
import { parseFontSize } from '../../utils';
|
||||
import { sanitizeUrl } from '@braintree/sanitize-url';
|
||||
|
||||
export const drawRect = function (elem, rectData) {
|
||||
@ -156,6 +157,8 @@ export const drawText = function (elem, textData) {
|
||||
textHeight = 0;
|
||||
const lines = textData.text.split(common.lineBreakRegex);
|
||||
|
||||
const [_textFontSize, _textFontSizePx] = parseFontSize(textData.fontSize);
|
||||
|
||||
let textElems = [];
|
||||
let dy = 0;
|
||||
let yfunc = () => textData.y;
|
||||
@ -215,12 +218,8 @@ export const drawText = function (elem, textData) {
|
||||
}
|
||||
}
|
||||
for (let [i, line] of lines.entries()) {
|
||||
if (
|
||||
textData.textMargin !== undefined &&
|
||||
textData.textMargin === 0 &&
|
||||
textData.fontSize !== undefined
|
||||
) {
|
||||
dy = i * textData.fontSize;
|
||||
if (textData.textMargin !== undefined && textData.textMargin === 0 && _textFontSize !== null) {
|
||||
dy = i * _textFontSize;
|
||||
}
|
||||
|
||||
const textElem = elem.append('text');
|
||||
@ -235,8 +234,8 @@ export const drawText = function (elem, textData) {
|
||||
if (textData.fontFamily !== undefined) {
|
||||
textElem.style('font-family', textData.fontFamily);
|
||||
}
|
||||
if (textData.fontSize !== undefined) {
|
||||
textElem.style('font-size', textData.fontSize);
|
||||
if (_textFontSizePx !== null) {
|
||||
textElem.style('font-size', _textFontSizePx);
|
||||
}
|
||||
if (textData.fontWeight !== undefined) {
|
||||
textElem.style('font-weight', textData.fontWeight);
|
||||
@ -840,8 +839,7 @@ const _drawTextCandidateFunc = (function () {
|
||||
function byTspan(content, g, x, y, width, height, textAttrs, conf) {
|
||||
const { actorFontSize, actorFontFamily, actorFontWeight } = conf;
|
||||
|
||||
let _actorFontSize =
|
||||
actorFontSize && actorFontSize.replace ? actorFontSize.replace('px', '') : actorFontSize;
|
||||
const [_actorFontSize, _actorFontSizePx] = parseFontSize(actorFontSize);
|
||||
|
||||
const lines = content.split(common.lineBreakRegex);
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
@ -851,7 +849,7 @@ const _drawTextCandidateFunc = (function () {
|
||||
.attr('x', x + width / 2)
|
||||
.attr('y', y)
|
||||
.style('text-anchor', 'middle')
|
||||
.style('font-size', actorFontSize)
|
||||
.style('font-size', _actorFontSizePx)
|
||||
.style('font-weight', actorFontWeight)
|
||||
.style('font-family', actorFontFamily);
|
||||
text
|
||||
|
@ -125,6 +125,30 @@ describe('svgDraw', function () {
|
||||
expect(text3.attr).toHaveBeenCalledWith('y', 10);
|
||||
expect(text3.text).toHaveBeenCalledWith('fine lines');
|
||||
});
|
||||
it('should work with numeral font sizes', function () {
|
||||
const svg = MockD3('svg');
|
||||
svgDraw.drawText(svg, {
|
||||
x: 10,
|
||||
y: 10,
|
||||
dy: '1em',
|
||||
text: 'One fine text message',
|
||||
class: 'noteText',
|
||||
fontFamily: 'courier',
|
||||
fontSize: 10,
|
||||
fontWeight: '500',
|
||||
});
|
||||
expect(svg.__children.length).toBe(1);
|
||||
const text = svg.__children[0];
|
||||
expect(text.__name).toBe('text');
|
||||
expect(text.attr).toHaveBeenCalledWith('x', 10);
|
||||
expect(text.attr).toHaveBeenCalledWith('y', 10);
|
||||
expect(text.attr).toHaveBeenCalledWith('dy', '1em');
|
||||
expect(text.attr).toHaveBeenCalledWith('class', 'noteText');
|
||||
expect(text.text).toHaveBeenCalledWith('One fine text message');
|
||||
expect(text.style).toHaveBeenCalledWith('font-family', 'courier');
|
||||
expect(text.style).toHaveBeenCalledWith('font-size', '10px');
|
||||
expect(text.style).toHaveBeenCalledWith('font-weight', '500');
|
||||
});
|
||||
});
|
||||
describe('drawBackgroundRect', function () {
|
||||
it('should append a rect before the previous element within a given bound', function () {
|
||||
|
@ -402,3 +402,29 @@ describe('when inserting titles', function () {
|
||||
expect(titleAttrSpy).toHaveBeenCalledWith('class', 'testClass');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when parsing font sizes', function () {
|
||||
it('parses number inputs', function () {
|
||||
expect(utils.parseFontSize(14)).toEqual([14, '14px']);
|
||||
});
|
||||
|
||||
it('parses string em inputs', function () {
|
||||
expect(utils.parseFontSize('14em')).toEqual([14, '14em']);
|
||||
});
|
||||
|
||||
it('parses string px inputs', function () {
|
||||
expect(utils.parseFontSize('14px')).toEqual([14, '14px']);
|
||||
});
|
||||
|
||||
it('parses string inputs without units', function () {
|
||||
expect(utils.parseFontSize('14')).toEqual([14, '14px']);
|
||||
});
|
||||
|
||||
it('handles undefined input', function () {
|
||||
expect(utils.parseFontSize(undefined)).toEqual([null, null]);
|
||||
});
|
||||
|
||||
it('handles unparseable input', function () {
|
||||
expect(utils.parseFontSize({ fontSize: 14 })).toEqual([null, null]);
|
||||
});
|
||||
});
|
||||
|
@ -543,12 +543,14 @@ export const drawSimpleText = function (
|
||||
// Remove and ignore br:s
|
||||
const nText = textData.text.replace(common.lineBreakRegex, ' ');
|
||||
|
||||
const [, _fontSizePx] = parseFontSize(textData.fontSize);
|
||||
|
||||
const textElem = elem.append('text');
|
||||
textElem.attr('x', textData.x);
|
||||
textElem.attr('y', textData.y);
|
||||
textElem.style('text-anchor', textData.anchor);
|
||||
textElem.style('font-family', textData.fontFamily);
|
||||
textElem.style('font-size', textData.fontSize);
|
||||
textElem.style('font-size', _fontSizePx);
|
||||
textElem.style('font-weight', textData.fontWeight);
|
||||
textElem.attr('fill', textData.fill);
|
||||
if (textData.class !== undefined) {
|
||||
@ -722,6 +724,8 @@ export const calculateTextDimensions: (
|
||||
return { width: 0, height: 0 };
|
||||
}
|
||||
|
||||
const [, _fontSizePx] = parseFontSize(fontSize);
|
||||
|
||||
// We can't really know if the user supplied font family will render on the user agent;
|
||||
// thus, we'll take the max width between the user supplied font family, and a default
|
||||
// of sans-serif.
|
||||
@ -745,7 +749,7 @@ export const calculateTextDimensions: (
|
||||
const textObj = getTextObj();
|
||||
textObj.text = line;
|
||||
const textElem = drawSimpleText(g, textObj)
|
||||
.style('font-size', fontSize)
|
||||
.style('font-size', _fontSizePx)
|
||||
.style('font-weight', fontWeight)
|
||||
.style('font-family', fontFamily);
|
||||
|
||||
@ -941,6 +945,32 @@ export const insertTitle = (
|
||||
.attr('class', cssClass);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses a raw fontSize configuration value into a number and string value.
|
||||
*
|
||||
* @param fontSize - a string or number font size configuration value
|
||||
*
|
||||
* @returns parsed number and string style font size values, or nulls if a number value can't
|
||||
* be parsed from an input string.
|
||||
*/
|
||||
export const parseFontSize = (fontSize: string | number | undefined): [number?, string?] => {
|
||||
// if the font size is a number, assume a px string representation
|
||||
if (typeof fontSize === 'number') {
|
||||
return [fontSize, fontSize + 'px'];
|
||||
}
|
||||
|
||||
const fontSizeNumber = parseInt(fontSize, 10);
|
||||
if (Number.isNaN(fontSizeNumber)) {
|
||||
// if a number value can't be parsed, return null for both values
|
||||
return [null, null];
|
||||
} else if (fontSize === String(fontSizeNumber)) {
|
||||
// if a string input doesn't contain any units, assume px units
|
||||
return [fontSizeNumber, fontSize + 'px'];
|
||||
} else {
|
||||
return [fontSizeNumber, fontSize];
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
assignWithDepth,
|
||||
wrapLabel,
|
||||
@ -964,4 +994,5 @@ export default {
|
||||
directiveSanitizer,
|
||||
sanitizeCss,
|
||||
insertTitle,
|
||||
parseFontSize,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user