refactor: simplify fontStyle code checking binary mask (#174)
Introduce the `styleUtils.matchBinaryMask` function to remove duplication in the code checking binary mask on `fontStyle`.development
parent
ed2ae41428
commit
6fc05a3876
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
Copyright 2023-present The maxGraph project Contributors
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, expect, test } from '@jest/globals';
|
||||||
|
import { matchBinaryMask } from '../../src/util/styleUtils';
|
||||||
|
import { FONT } from '../../src/util/Constants';
|
||||||
|
|
||||||
|
describe('matchBinaryMask', () => {
|
||||||
|
test('match self', () => {
|
||||||
|
expect(matchBinaryMask(FONT.STRIKETHROUGH, FONT.STRIKETHROUGH)).toBeTruthy();
|
||||||
|
});
|
||||||
|
test('match', () => {
|
||||||
|
expect(matchBinaryMask(9465, FONT.BOLD)).toBeTruthy();
|
||||||
|
});
|
||||||
|
test('match another', () => {
|
||||||
|
expect(matchBinaryMask(19484, FONT.UNDERLINE)).toBeTruthy();
|
||||||
|
});
|
||||||
|
test('no match', () => {
|
||||||
|
expect(matchBinaryMask(46413, FONT.ITALIC)).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { describe, expect, test } from '@jest/globals';
|
import { expect, test } from '@jest/globals';
|
||||||
import { CellOverlay, Point } from '../../../src';
|
import { CellOverlay, Point } from '../../../src';
|
||||||
|
|
||||||
test('Constructor set all parameters', () => {
|
test('Constructor set all parameters', () => {
|
||||||
|
|
|
@ -598,6 +598,16 @@ export const setOpacity = (node: HTMLElement | SVGElement, value: number) => {
|
||||||
node.style.opacity = String(value / 100);
|
node.style.opacity = String(value / 100);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param value the value to check.
|
||||||
|
* @param mask the binary mask to apply.
|
||||||
|
* @returns `true` if the value matches the binary mask.
|
||||||
|
* @private Subject to change prior being part of the public API.
|
||||||
|
*/
|
||||||
|
export const matchBinaryMask = (value: number, mask: number) => {
|
||||||
|
return (value & mask) === mask;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an {@link Rectangle} with the size (width and height in pixels) of
|
* Returns an {@link Rectangle} with the size (width and height in pixels) of
|
||||||
* the given string. The string may contain HTML markup. Newlines should be
|
* the given string. The string may contain HTML markup. Newlines should be
|
||||||
|
@ -635,27 +645,13 @@ export const getSizeForString = (
|
||||||
|
|
||||||
// Sets the font style
|
// Sets the font style
|
||||||
if (fontStyle !== null) {
|
if (fontStyle !== null) {
|
||||||
if ((fontStyle & FONT.BOLD) === FONT.BOLD) {
|
matchBinaryMask(fontStyle, FONT.BOLD) && (div.style.fontWeight = 'bold');
|
||||||
div.style.fontWeight = 'bold';
|
matchBinaryMask(fontStyle, FONT.ITALIC) && (div.style.fontWeight = 'italic');
|
||||||
}
|
|
||||||
|
|
||||||
if ((fontStyle & FONT.ITALIC) === FONT.ITALIC) {
|
|
||||||
div.style.fontStyle = 'italic';
|
|
||||||
}
|
|
||||||
|
|
||||||
const txtDecor = [];
|
const txtDecor = [];
|
||||||
|
matchBinaryMask(fontStyle, FONT.UNDERLINE) && txtDecor.push('underline');
|
||||||
if ((fontStyle & FONT.UNDERLINE) == FONT.UNDERLINE) {
|
matchBinaryMask(fontStyle, FONT.STRIKETHROUGH) && txtDecor.push('line-through');
|
||||||
txtDecor.push('underline');
|
txtDecor.length > 0 && (div.style.textDecoration = txtDecor.join(' '));
|
||||||
}
|
|
||||||
|
|
||||||
if ((fontStyle & FONT.STRIKETHROUGH) == FONT.STRIKETHROUGH) {
|
|
||||||
txtDecor.push('line-through');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (txtDecor.length > 0) {
|
|
||||||
div.style.textDecoration = txtDecor.join(' ');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disables block layout and outside wrapping and hides the div
|
// Disables block layout and outside wrapping and hides the div
|
||||||
|
|
|
@ -18,7 +18,7 @@ limitations under the License.
|
||||||
|
|
||||||
import { isNotNullish } from '../../util/Utils';
|
import { isNotNullish } from '../../util/Utils';
|
||||||
import { mod } from '../../util/mathUtils';
|
import { mod } from '../../util/mathUtils';
|
||||||
import { getAlignmentAsPoint } from '../../util/styleUtils';
|
import { getAlignmentAsPoint, matchBinaryMask } from '../../util/styleUtils';
|
||||||
import Client from '../../Client';
|
import Client from '../../Client';
|
||||||
import {
|
import {
|
||||||
ABSOLUTE_LINE_HEIGHT,
|
ABSOLUTE_LINE_HEIGHT,
|
||||||
|
@ -477,31 +477,16 @@ class SvgCanvas2D extends AbstractCanvas2D {
|
||||||
alt.setAttribute('font-size', `${Math.round(s.fontSize)}px`);
|
alt.setAttribute('font-size', `${Math.round(s.fontSize)}px`);
|
||||||
|
|
||||||
// Text-anchor start is default in SVG
|
// Text-anchor start is default in SVG
|
||||||
if (anchor !== 'start') {
|
anchor !== 'start' && alt.setAttribute('text-anchor', anchor);
|
||||||
alt.setAttribute('text-anchor', anchor);
|
const fontStyle = s.fontStyle;
|
||||||
}
|
matchBinaryMask(fontStyle, FONT.BOLD) && alt.setAttribute('font-weight', 'bold');
|
||||||
|
matchBinaryMask(fontStyle, FONT.ITALIC) &&
|
||||||
if ((s.fontStyle & FONT.BOLD) === FONT.BOLD) {
|
|
||||||
alt.setAttribute('font-weight', 'bold');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((s.fontStyle & FONT.ITALIC) === FONT.ITALIC) {
|
|
||||||
alt.setAttribute('font-style', 'italic');
|
alt.setAttribute('font-style', 'italic');
|
||||||
}
|
|
||||||
|
|
||||||
const txtDecor = [];
|
const txtDecor = [];
|
||||||
|
matchBinaryMask(fontStyle, FONT.UNDERLINE) && txtDecor.push('underline');
|
||||||
if ((s.fontStyle & FONT.UNDERLINE) === FONT.UNDERLINE) {
|
matchBinaryMask(fontStyle, FONT.STRIKETHROUGH) && txtDecor.push('line-through');
|
||||||
txtDecor.push('underline');
|
txtDecor.length > 0 && alt.setAttribute('text-decoration', txtDecor.join(' '));
|
||||||
}
|
|
||||||
|
|
||||||
if ((s.fontStyle & FONT.STRIKETHROUGH) === FONT.STRIKETHROUGH) {
|
|
||||||
txtDecor.push('line-through');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (txtDecor.length > 0) {
|
|
||||||
alt.setAttribute('text-decoration', txtDecor.join(' '));
|
|
||||||
}
|
|
||||||
|
|
||||||
write(alt, <string>text);
|
write(alt, <string>text);
|
||||||
return alt;
|
return alt;
|
||||||
|
@ -1385,27 +1370,14 @@ class SvgCanvas2D extends AbstractCanvas2D {
|
||||||
this.pointerEvents ? this.pointerEventsValue : 'none'
|
this.pointerEvents ? this.pointerEventsValue : 'none'
|
||||||
}; `;
|
}; `;
|
||||||
|
|
||||||
if ((s.fontStyle & FONT.BOLD) === FONT.BOLD) {
|
const fontStyle = s.fontStyle;
|
||||||
css += 'font-weight: bold; ';
|
matchBinaryMask(fontStyle, FONT.BOLD) && (css += 'font-weight: bold; ');
|
||||||
}
|
matchBinaryMask(fontStyle, FONT.ITALIC) && (css += 'font-style: italic; ');
|
||||||
|
|
||||||
if ((s.fontStyle & FONT.ITALIC) === FONT.ITALIC) {
|
const txtDecor = [];
|
||||||
css += 'font-style: italic; ';
|
matchBinaryMask(fontStyle, FONT.UNDERLINE) && txtDecor.push('underline');
|
||||||
}
|
matchBinaryMask(fontStyle, FONT.STRIKETHROUGH) && txtDecor.push('line-through');
|
||||||
|
txtDecor.length > 0 && (css += `text-decoration: ${txtDecor.join(' ')}; `);
|
||||||
const deco = [];
|
|
||||||
|
|
||||||
if ((s.fontStyle & FONT.UNDERLINE) === FONT.UNDERLINE) {
|
|
||||||
deco.push('underline');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((s.fontStyle & FONT.STRIKETHROUGH) === FONT.STRIKETHROUGH) {
|
|
||||||
deco.push('line-through');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deco.length > 0) {
|
|
||||||
css += `text-decoration: ${deco.join(' ')}; `;
|
|
||||||
}
|
|
||||||
|
|
||||||
return css;
|
return css;
|
||||||
}
|
}
|
||||||
|
@ -1690,27 +1662,14 @@ class SvgCanvas2D extends AbstractCanvas2D {
|
||||||
node.setAttribute('font-family', s.fontFamily);
|
node.setAttribute('font-family', s.fontFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((s.fontStyle & FONT.BOLD) === FONT.BOLD) {
|
const fontStyle = s.fontStyle;
|
||||||
node.setAttribute('font-weight', 'bold');
|
matchBinaryMask(fontStyle, FONT.BOLD) && node.setAttribute('font-weight', 'bold');
|
||||||
}
|
matchBinaryMask(fontStyle, FONT.ITALIC) && node.setAttribute('font-style', 'italic');
|
||||||
|
|
||||||
if ((s.fontStyle & FONT.ITALIC) === FONT.ITALIC) {
|
|
||||||
node.setAttribute('font-style', 'italic');
|
|
||||||
}
|
|
||||||
|
|
||||||
const txtDecor = [];
|
const txtDecor = [];
|
||||||
|
matchBinaryMask(fontStyle, FONT.UNDERLINE) && txtDecor.push('underline');
|
||||||
if ((s.fontStyle & FONT.UNDERLINE) === FONT.UNDERLINE) {
|
matchBinaryMask(fontStyle, FONT.STRIKETHROUGH) && txtDecor.push('line-through');
|
||||||
txtDecor.push('underline');
|
txtDecor.length > 0 && node.setAttribute('text-decoration', txtDecor.join(' '));
|
||||||
}
|
|
||||||
|
|
||||||
if ((s.fontStyle & FONT.STRIKETHROUGH) === FONT.STRIKETHROUGH) {
|
|
||||||
txtDecor.push('line-through');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (txtDecor.length > 0) {
|
|
||||||
node.setAttribute('text-decoration', txtDecor.join(' '));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1778,13 +1737,8 @@ class SvgCanvas2D extends AbstractCanvas2D {
|
||||||
div.style.visibility = 'hidden';
|
div.style.visibility = 'hidden';
|
||||||
div.style.display = 'inline-block';
|
div.style.display = 'inline-block';
|
||||||
|
|
||||||
if ((s.fontStyle & FONT.BOLD) === FONT.BOLD) {
|
matchBinaryMask(s.fontStyle, FONT.BOLD) && (div.style.fontWeight = 'bold');
|
||||||
div.style.fontWeight = 'bold';
|
matchBinaryMask(s.fontStyle, FONT.ITALIC) && (div.style.fontStyle = 'italic');
|
||||||
}
|
|
||||||
|
|
||||||
if ((s.fontStyle & FONT.ITALIC) === FONT.ITALIC) {
|
|
||||||
div.style.fontStyle = 'italic';
|
|
||||||
}
|
|
||||||
|
|
||||||
str = htmlEntities(str, false);
|
str = htmlEntities(str, false);
|
||||||
div.innerHTML = str.replace(/\n/g, '<br/>');
|
div.innerHTML = str.replace(/\n/g, '<br/>');
|
||||||
|
|
|
@ -32,7 +32,7 @@ import {
|
||||||
LINE_HEIGHT,
|
LINE_HEIGHT,
|
||||||
} from '../../../util/Constants';
|
} from '../../../util/Constants';
|
||||||
import { getBoundingBox } from '../../../util/mathUtils';
|
import { getBoundingBox } from '../../../util/mathUtils';
|
||||||
import { getAlignmentAsPoint } from '../../../util/styleUtils';
|
import { getAlignmentAsPoint, matchBinaryMask } from '../../../util/styleUtils';
|
||||||
import Point from '../Point';
|
import Point from '../Point';
|
||||||
import AbstractCanvas2D from '../../canvas/AbstractCanvas2D';
|
import AbstractCanvas2D from '../../canvas/AbstractCanvas2D';
|
||||||
import Shape from '../Shape';
|
import Shape from '../Shape';
|
||||||
|
@ -599,27 +599,13 @@ class TextShape extends Shape {
|
||||||
this.color
|
this.color
|
||||||
}; line-height: ${lh}; pointer-events: ${this.pointerEvents ? 'all' : 'none'}; `;
|
}; line-height: ${lh}; pointer-events: ${this.pointerEvents ? 'all' : 'none'}; `;
|
||||||
|
|
||||||
if ((this.fontStyle & FONT.BOLD) === FONT.BOLD) {
|
matchBinaryMask(this.fontStyle, FONT.BOLD) && (css += 'font-weight: bold; ');
|
||||||
css += 'font-weight: bold; ';
|
matchBinaryMask(this.fontStyle, FONT.ITALIC) && (css += 'font-style: italic; ');
|
||||||
}
|
|
||||||
|
|
||||||
if ((this.fontStyle & FONT.ITALIC) === FONT.ITALIC) {
|
const txtDecor = [];
|
||||||
css += 'font-style: italic; ';
|
matchBinaryMask(this.fontStyle, FONT.UNDERLINE) && txtDecor.push('underline');
|
||||||
}
|
matchBinaryMask(this.fontStyle, FONT.STRIKETHROUGH) && txtDecor.push('line-through');
|
||||||
|
txtDecor.length > 0 && (css += `text-decoration: ${txtDecor.join(' ')}; `);
|
||||||
const deco = [];
|
|
||||||
|
|
||||||
if ((this.fontStyle & FONT.UNDERLINE) === FONT.UNDERLINE) {
|
|
||||||
deco.push('underline');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((this.fontStyle & FONT.STRIKETHROUGH) === FONT.STRIKETHROUGH) {
|
|
||||||
deco.push('line-through');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deco.length > 0) {
|
|
||||||
css += `text-decoration: ${deco.join(' ')}; `;
|
|
||||||
}
|
|
||||||
|
|
||||||
return css;
|
return css;
|
||||||
}
|
}
|
||||||
|
@ -814,29 +800,18 @@ class TextShape extends Shape {
|
||||||
style.verticalAlign = 'top';
|
style.verticalAlign = 'top';
|
||||||
style.color = this.color;
|
style.color = this.color;
|
||||||
|
|
||||||
if ((this.fontStyle & FONT.BOLD) === FONT.BOLD) {
|
matchBinaryMask(this.fontStyle, FONT.BOLD)
|
||||||
style.fontWeight = 'bold';
|
? (style.fontWeight = 'bold')
|
||||||
} else {
|
: (style.fontWeight = '');
|
||||||
style.fontWeight = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((this.fontStyle & FONT.ITALIC) === FONT.ITALIC) {
|
matchBinaryMask(this.fontStyle, FONT.ITALIC)
|
||||||
style.fontStyle = 'italic';
|
? (style.fontStyle = 'italic')
|
||||||
} else {
|
: (style.fontStyle = '');
|
||||||
style.fontStyle = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const txtDecor = [];
|
const txtDecor = [];
|
||||||
|
matchBinaryMask(this.fontStyle, FONT.UNDERLINE) && txtDecor.push('underline');
|
||||||
if ((this.fontStyle & FONT.UNDERLINE) === FONT.UNDERLINE) {
|
matchBinaryMask(this.fontStyle, FONT.STRIKETHROUGH) && txtDecor.push('line-through');
|
||||||
txtDecor.push('underline');
|
txtDecor.length > 0 && (style.textDecoration = txtDecor.join(' '));
|
||||||
}
|
|
||||||
|
|
||||||
if ((this.fontStyle & FONT.STRIKETHROUGH) === FONT.STRIKETHROUGH) {
|
|
||||||
txtDecor.push('line-through');
|
|
||||||
}
|
|
||||||
|
|
||||||
style.textDecoration = txtDecor.join(' ');
|
|
||||||
|
|
||||||
if (this.align === ALIGN.CENTER) {
|
if (this.align === ALIGN.CENTER) {
|
||||||
style.textAlign = 'center';
|
style.textAlign = 'center';
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue