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
Thomas Bouffard 2023-01-17 12:08:32 +01:00 committed by GitHub
parent ed2ae41428
commit 6fc05a3876
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 765 additions and 805 deletions

View File

@ -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();
});
});

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { describe, expect, test } from '@jest/globals';
import { expect, test } from '@jest/globals';
import { CellOverlay, Point } from '../../../src';
test('Constructor set all parameters', () => {

View File

@ -598,6 +598,16 @@ export const setOpacity = (node: HTMLElement | SVGElement, value: number) => {
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
* the given string. The string may contain HTML markup. Newlines should be
@ -635,27 +645,13 @@ export const getSizeForString = (
// Sets the font style
if (fontStyle !== null) {
if ((fontStyle & FONT.BOLD) === FONT.BOLD) {
div.style.fontWeight = 'bold';
}
if ((fontStyle & FONT.ITALIC) === FONT.ITALIC) {
div.style.fontStyle = 'italic';
}
matchBinaryMask(fontStyle, FONT.BOLD) && (div.style.fontWeight = 'bold');
matchBinaryMask(fontStyle, FONT.ITALIC) && (div.style.fontWeight = 'italic');
const txtDecor = [];
if ((fontStyle & FONT.UNDERLINE) == FONT.UNDERLINE) {
txtDecor.push('underline');
}
if ((fontStyle & FONT.STRIKETHROUGH) == FONT.STRIKETHROUGH) {
txtDecor.push('line-through');
}
if (txtDecor.length > 0) {
div.style.textDecoration = txtDecor.join(' ');
}
matchBinaryMask(fontStyle, FONT.UNDERLINE) && txtDecor.push('underline');
matchBinaryMask(fontStyle, FONT.STRIKETHROUGH) && txtDecor.push('line-through');
txtDecor.length > 0 && (div.style.textDecoration = txtDecor.join(' '));
}
// Disables block layout and outside wrapping and hides the div

View File

@ -18,7 +18,7 @@ limitations under the License.
import { isNotNullish } from '../../util/Utils';
import { mod } from '../../util/mathUtils';
import { getAlignmentAsPoint } from '../../util/styleUtils';
import { getAlignmentAsPoint, matchBinaryMask } from '../../util/styleUtils';
import Client from '../../Client';
import {
ABSOLUTE_LINE_HEIGHT,
@ -477,31 +477,16 @@ class SvgCanvas2D extends AbstractCanvas2D {
alt.setAttribute('font-size', `${Math.round(s.fontSize)}px`);
// Text-anchor start is default in SVG
if (anchor !== 'start') {
alt.setAttribute('text-anchor', anchor);
}
if ((s.fontStyle & FONT.BOLD) === FONT.BOLD) {
alt.setAttribute('font-weight', 'bold');
}
if ((s.fontStyle & FONT.ITALIC) === FONT.ITALIC) {
anchor !== 'start' && alt.setAttribute('text-anchor', anchor);
const fontStyle = s.fontStyle;
matchBinaryMask(fontStyle, FONT.BOLD) && alt.setAttribute('font-weight', 'bold');
matchBinaryMask(fontStyle, FONT.ITALIC) &&
alt.setAttribute('font-style', 'italic');
}
const txtDecor = [];
if ((s.fontStyle & FONT.UNDERLINE) === FONT.UNDERLINE) {
txtDecor.push('underline');
}
if ((s.fontStyle & FONT.STRIKETHROUGH) === FONT.STRIKETHROUGH) {
txtDecor.push('line-through');
}
if (txtDecor.length > 0) {
alt.setAttribute('text-decoration', txtDecor.join(' '));
}
matchBinaryMask(fontStyle, FONT.UNDERLINE) && txtDecor.push('underline');
matchBinaryMask(fontStyle, FONT.STRIKETHROUGH) && txtDecor.push('line-through');
txtDecor.length > 0 && alt.setAttribute('text-decoration', txtDecor.join(' '));
write(alt, <string>text);
return alt;
@ -1385,27 +1370,14 @@ class SvgCanvas2D extends AbstractCanvas2D {
this.pointerEvents ? this.pointerEventsValue : 'none'
}; `;
if ((s.fontStyle & FONT.BOLD) === FONT.BOLD) {
css += 'font-weight: bold; ';
}
const fontStyle = s.fontStyle;
matchBinaryMask(fontStyle, FONT.BOLD) && (css += 'font-weight: bold; ');
matchBinaryMask(fontStyle, FONT.ITALIC) && (css += 'font-style: italic; ');
if ((s.fontStyle & FONT.ITALIC) === FONT.ITALIC) {
css += 'font-style: italic; ';
}
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(' ')}; `;
}
const txtDecor = [];
matchBinaryMask(fontStyle, FONT.UNDERLINE) && txtDecor.push('underline');
matchBinaryMask(fontStyle, FONT.STRIKETHROUGH) && txtDecor.push('line-through');
txtDecor.length > 0 && (css += `text-decoration: ${txtDecor.join(' ')}; `);
return css;
}
@ -1690,27 +1662,14 @@ class SvgCanvas2D extends AbstractCanvas2D {
node.setAttribute('font-family', s.fontFamily);
}
if ((s.fontStyle & FONT.BOLD) === FONT.BOLD) {
node.setAttribute('font-weight', 'bold');
}
if ((s.fontStyle & FONT.ITALIC) === FONT.ITALIC) {
node.setAttribute('font-style', 'italic');
}
const fontStyle = s.fontStyle;
matchBinaryMask(fontStyle, FONT.BOLD) && node.setAttribute('font-weight', 'bold');
matchBinaryMask(fontStyle, FONT.ITALIC) && node.setAttribute('font-style', 'italic');
const txtDecor = [];
if ((s.fontStyle & FONT.UNDERLINE) === FONT.UNDERLINE) {
txtDecor.push('underline');
}
if ((s.fontStyle & FONT.STRIKETHROUGH) === FONT.STRIKETHROUGH) {
txtDecor.push('line-through');
}
if (txtDecor.length > 0) {
node.setAttribute('text-decoration', txtDecor.join(' '));
}
matchBinaryMask(fontStyle, FONT.UNDERLINE) && txtDecor.push('underline');
matchBinaryMask(fontStyle, FONT.STRIKETHROUGH) && txtDecor.push('line-through');
txtDecor.length > 0 && node.setAttribute('text-decoration', txtDecor.join(' '));
}
/**
@ -1778,13 +1737,8 @@ class SvgCanvas2D extends AbstractCanvas2D {
div.style.visibility = 'hidden';
div.style.display = 'inline-block';
if ((s.fontStyle & FONT.BOLD) === FONT.BOLD) {
div.style.fontWeight = 'bold';
}
if ((s.fontStyle & FONT.ITALIC) === FONT.ITALIC) {
div.style.fontStyle = 'italic';
}
matchBinaryMask(s.fontStyle, FONT.BOLD) && (div.style.fontWeight = 'bold');
matchBinaryMask(s.fontStyle, FONT.ITALIC) && (div.style.fontStyle = 'italic');
str = htmlEntities(str, false);
div.innerHTML = str.replace(/\n/g, '<br/>');

View File

@ -32,7 +32,7 @@ import {
LINE_HEIGHT,
} from '../../../util/Constants';
import { getBoundingBox } from '../../../util/mathUtils';
import { getAlignmentAsPoint } from '../../../util/styleUtils';
import { getAlignmentAsPoint, matchBinaryMask } from '../../../util/styleUtils';
import Point from '../Point';
import AbstractCanvas2D from '../../canvas/AbstractCanvas2D';
import Shape from '../Shape';
@ -599,27 +599,13 @@ class TextShape extends Shape {
this.color
}; line-height: ${lh}; pointer-events: ${this.pointerEvents ? 'all' : 'none'}; `;
if ((this.fontStyle & FONT.BOLD) === FONT.BOLD) {
css += 'font-weight: bold; ';
}
matchBinaryMask(this.fontStyle, FONT.BOLD) && (css += 'font-weight: bold; ');
matchBinaryMask(this.fontStyle, FONT.ITALIC) && (css += 'font-style: italic; ');
if ((this.fontStyle & FONT.ITALIC) === FONT.ITALIC) {
css += 'font-style: italic; ';
}
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(' ')}; `;
}
const txtDecor = [];
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(' ')}; `);
return css;
}
@ -814,29 +800,18 @@ class TextShape extends Shape {
style.verticalAlign = 'top';
style.color = this.color;
if ((this.fontStyle & FONT.BOLD) === FONT.BOLD) {
style.fontWeight = 'bold';
} else {
style.fontWeight = '';
}
matchBinaryMask(this.fontStyle, FONT.BOLD)
? (style.fontWeight = 'bold')
: (style.fontWeight = '');
if ((this.fontStyle & FONT.ITALIC) === FONT.ITALIC) {
style.fontStyle = 'italic';
} else {
style.fontStyle = '';
}
matchBinaryMask(this.fontStyle, FONT.ITALIC)
? (style.fontStyle = 'italic')
: (style.fontStyle = '');
const txtDecor = [];
if ((this.fontStyle & FONT.UNDERLINE) === FONT.UNDERLINE) {
txtDecor.push('underline');
}
if ((this.fontStyle & FONT.STRIKETHROUGH) === FONT.STRIKETHROUGH) {
txtDecor.push('line-through');
}
style.textDecoration = txtDecor.join(' ');
matchBinaryMask(this.fontStyle, FONT.UNDERLINE) && txtDecor.push('underline');
matchBinaryMask(this.fontStyle, FONT.STRIKETHROUGH) && txtDecor.push('line-through');
txtDecor.length > 0 && (style.textDecoration = txtDecor.join(' '));
if (this.align === ALIGN.CENTER) {
style.textAlign = 'center';

File diff suppressed because it is too large Load Diff