Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions packages/core/__tests__/util/styleUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
import { describe, expect, test } from '@jest/globals';
import {
matchBinaryMask,
parseCssNumber,
setStyleFlag,
setCellStyleFlags,
setCellStyles,
Expand All @@ -40,7 +41,43 @@ describe('matchBinaryMask', () => {
});
});

describe('parseCssNumber', () => {
test.each([
['thin', 2],
['medium', 4],
['thick', 6],
['10', 10],
['3.14', 3.14],
['-5', -5],
['0', 0],
['', 0],
['invalid', 0],
['10px', 10],
['1.5em', 1.5],
])('parses %s correctly to %d', (input, expected) => {
expect(parseCssNumber(input)).toBe(expected);
});
});

describe('setStyleFlag', () => {
test('preserves other style properties', () => {
const style = { fontStyle: FONT.BOLD, fillColor: 'red', strokeColor: 'blue' };
setStyleFlag(style, 'fontStyle', FONT.ITALIC, true);
expect(style).toEqual({
fontStyle: FONT.BOLD | FONT.ITALIC,
fillColor: 'red',
strokeColor: 'blue',
});
});

test('multiple flags can be combined', () => {
const style: CellStyle = {};
setStyleFlag(style, 'fontStyle', FONT.BOLD, true);
setStyleFlag(style, 'fontStyle', FONT.ITALIC, true);
setStyleFlag(style, 'fontStyle', FONT.UNDERLINE, true);
expect(style.fontStyle).toBe(FONT.BOLD | FONT.ITALIC | FONT.UNDERLINE);
});

test('fontStyle undefined, set bold, no value', () => {
const style: CellStyle = {};
setStyleFlag(style, 'fontStyle', FONT.BOLD);
Expand Down
77 changes: 31 additions & 46 deletions packages/core/src/util/styleUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ import GraphDataModel from '../view/GraphDataModel';
import type { CellStateStyle, CellStyle, NumericCellStateStyleKeys } from '../types';

/**
* Removes the cursors from the style of the given DOM node and its
* descendants.
* Removes the cursors from the style of the given DOM node and its descendants.
*
* @param element DOM node to remove the cursor style from.
*/
Expand Down Expand Up @@ -67,10 +66,7 @@ export const getCurrentStyle = (element: HTMLElement) => {
};

/**
* Function: parseCssNumber
*
* Parses the given CSS numeric value adding handling for the values thin,
* medium and thick (2, 4 and 6).
* Parses the given CSS numeric value adding handling for the values thin, medium and thick (2, 4 and 6).
*/
export const parseCssNumber = (value: string) => {
if (value === 'thin') {
Expand All @@ -91,13 +87,10 @@ export const parseCssNumber = (value: string) => {
};

/**
* Function: setPrefixedStyle
*
* Adds the given style with the standard name and an optional vendor prefix for the current
* browser.
* Adds the given style with the standard name and an optional vendor prefix for the current browser.
*
* ```javascript
* mxUtils.setPrefixedStyle(node.style, 'transformOrigin', '0% 0%');
* styleUtils.setPrefixedStyle(node.style, 'transformOrigin', '0% 0%');
* ```
*/
export const setPrefixedStyle = (
Expand Down Expand Up @@ -155,8 +148,8 @@ export const getDocumentSize = () => {
};

/**
* Makes sure the given node is inside the visible area of the window. This
* is done by setting the left and top in the style.
* Makes sure the given node is inside the visible area of the window.
* This is done by setting the left and top in the style.
*/
export const fit = (node: HTMLElement) => {
const ds = getDocumentSize();
Expand All @@ -182,13 +175,11 @@ export const fit = (node: HTMLElement) => {
};

/**
* Returns the offset for the specified container as an {@link Point}. The
* offset is the distance from the top left corner of the container to the
* top left corner of the document.
* Returns the offset for the specified container as an {@link Point}.
* The offset is the distance from the top left corner of the container to the top left corner of the document.
*
* @param container DOM node to return the offset for.
* @param scollOffset Optional boolean to add the scroll offset of the document.
* Default is false.
* @param scrollOffset Optional boolean to add the scroll offset of the document. Default is `false`.
*/
export const getOffset = (container: HTMLElement, scrollOffset = false) => {
let offsetLeft = 0;
Expand Down Expand Up @@ -227,8 +218,7 @@ export const getOffset = (container: HTMLElement, scrollOffset = false) => {
};

/**
* Returns the scroll origin of the given document or the current document
* if no document is given.
* Returns the scroll origin of the given document or the current document if no document is given.
*/
export const getDocumentScrollOrigin = (doc: Document) => {
// @ts-ignore 'parentWindow' is an unknown property.
Expand All @@ -248,13 +238,11 @@ export const getDocumentScrollOrigin = (doc: Document) => {
};

/**
* Returns the top, left corner of the viewrect as an {@link Point}.
* Returns the top, left corner of the view rectangle as an {@link Point}.
*
* @param node DOM node whose scroll origin should be returned.
* @param includeAncestors Whether the scroll origin of the ancestors should be
* included. Default is false.
* @param includeDocument Whether the scroll origin of the document should be
* included. Default is true.
* @param includeAncestors Whether the scroll origin of the ancestors should be included. Default is `false`.
* @param includeDocument Whether the scroll origin of the document should be included. Default is `true`.
*/
export const getScrollOrigin = (
node: HTMLElement | null = null,
Expand Down Expand Up @@ -293,12 +281,10 @@ export const getScrollOrigin = (
};

/**
* Converts the specified point (x, y) using the offset of the specified
* container and returns a new {@link Point} with the result.
* Converts the specified point (x, y) using the offset of the specified container and returns a new {@link Point} with the result.
*
* ```javascript
* let pt = mxUtils.convertPoint(graph.container,
* mxEvent.getClientX(evt), mxEvent.getClientY(evt));
* const pt = styleUtils.convertPoint(graph.container, eventUtils.getClientX(evt), eventUtils.getClientY(evt));
* ```
*
* @param container DOM node to use for the offset.
Expand All @@ -316,8 +302,7 @@ export const convertPoint = (container: HTMLElement, x: number, y: number) => {
};

/**
* Assigns the value for the given key in the styles of the given cells, or
* removes the key from the styles if the value is null.
* Assigns the value for the given key in the styles of the given cells, or removes the key from the styles if the value is `null`.
*
* @param model {@link GraphDataModel} to execute the transaction in.
* @param cells Array of {@link Cell}s to be updated.
Expand Down Expand Up @@ -442,23 +427,21 @@ export const matchBinaryMask = (value: number, mask: number) => {
};

/**
* 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
* converted to <br> before calling this method. The caller is responsible
* for sanitizing the HTML markup.
* 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 converted to `<br>` before calling this method.
* The caller is responsible for sanitizing the HTML markup.
*
* Example:
*
* ```javascript
* let label = graph.getLabel(cell).replace(/\n/g, "<br>");
* let size = graph.getSizeForString(label);
* const label = graph.getLabel(cell).replace(/\n/g, "<br>");
* const size = graph.getSizeForString(label);
* ```
*
* @param text String whose size should be returned.
* @param fontSize Integer that specifies the font size in pixels. Default is
* {@link Constants#DEFAULT_FONTSIZE}.
* @param fontFamily String that specifies the name of the font family. Default
* is {@link Constants#DEFAULT_FONTFAMILY}.
* @param fontSize Integer that specifies the font size in pixels. Default is {@link DEFAULT_FONTSIZE}.
* @param fontFamily String that specifies the name of the font family. Default is {@link DEFAULT_FONTFAMILY}.
* @param textWidth Optional width for text wrapping.
* @param fontStyle Optional font style.
*/
Expand Down Expand Up @@ -512,7 +495,7 @@ export const getSizeForString = (

/**
* Sorts the given cells according to the order in the cell hierarchy.
* Ascending is optional and defaults to true.
* Ascending is optional and defaults to `true`.
*/
export const sortCells = (cells: Cell[], ascending = true): Cell[] => {
const lookup = new Dictionary<Cell, string[]>();
Expand Down Expand Up @@ -541,10 +524,12 @@ export const sortCells = (cells: Cell[], ascending = true): Cell[] => {
};

/**
* Returns an {@link Point} that represents the horizontal and vertical alignment
* for numeric computations. X is -0.5 for center, -1 for right and 0 for
* left alignment. Y is -0.5 for middle, -1 for bottom and 0 for top
* alignment. Default values for missing arguments is top, left.
* Returns an {@link Point} that represents the horizontal and vertical alignment for numeric computations.
*
* X is -0.5 for center, -1 for right and 0 for left alignment.
* Y is -0.5 for middle, -1 for bottom and 0 for top alignment.
*
* Default values for missing arguments is top, left.
*/
export const getAlignmentAsPoint = (align: string, valign: string) => {
let dx = -0.5;
Expand Down