@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
96 lines (93 loc) • 3.61 kB
JavaScript
import { unitToNumber } from './unit-to-number';
// calculates content width of a cell
export function contentWidth(elem, container) {
var colWidths = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var canvas = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : document.createElement('canvas');
return calcContentWidth(elem, container || elem, canvas, colWidths);
}
function calcContentWidth(elem, container, canvas, colWidths) {
var flowWidths = [];
var curWidth = 0;
for (var i = 0; i < elem.childNodes.length; i++) {
// Ignored via go/ees005
// eslint-disable-next-line @atlaskit/editor/no-as-casting
var child = elem.childNodes[i];
if (child.nodeType === Node.COMMENT_NODE) {
continue;
}
if (child.nodeType === Node.TEXT_NODE) {
// Ignored via go/ees005
// eslint-disable-next-line @atlaskit/editor/no-as-casting
var parent = child.parentNode;
var parentStyle = getComputedStyle(parent);
var contentLength = 0;
if (parent.nodeName === 'CODE' || parent.nodeName === 'PRE') {
contentLength = handlePreText(canvas, parent, child.textContent, parentStyle.font);
} else {
contentLength = measureText(canvas, child.textContent, parentStyle.font);
}
var left = parent.offsetLeft - container.offsetLeft;
flowWidths.push(curWidth);
curWidth += contentLength + left;
// If the text isn't meant to wrap, we should set that as a hard limit.
if (parentStyle.whiteSpace === 'nowrap') {
// + 3 is for date offset plus cursor
// TODO: ED-26961 - There should be a programmatic way to get this.
colWidths.push(parent.offsetWidth + 3);
}
} else {
// TODO: ED-26961 - doesn't quite work right with spacing
var style = getComputedStyle(child);
if (style.minWidth && style.minWidth.endsWith('px') && style.minWidth !== '0px') {
colWidths.push(unitToNumber(style.minWidth));
}
var _contentWidth = contentWidth(child, container, colWidths, canvas),
width = _contentWidth.width;
if (style.display && style.display.indexOf('inline') > -1) {
// is inline element, add to curWidth
curWidth += width;
} else {
// block element, reset curWidth
flowWidths.push(curWidth);
curWidth = width;
}
}
}
flowWidths.push(curWidth);
return {
minWidth: colWidths.reduce(function (oldMax, width) {
return Math.max(width, oldMax);
}, 0),
width: flowWidths.reduce(function (oldMax, width) {
return Math.max(width, oldMax);
}, 0)
};
}
function measureText(canvas, text, font) {
var ctx = canvas.getContext('2d');
if (!ctx) {
return 0;
}
if (font) {
ctx.font = font;
}
return Math.round(ctx.measureText(text || '').width);
}
function handlePreText(canvas, node, textContent, font) {
var parent = node;
if (node.nodeName === 'CODE') {
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @atlaskit/editor/no-as-casting
parent = node.parentNode;
}
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
var computedStyle = getComputedStyle(parent);
if (textContent && computedStyle.whiteSpace === 'pre') {
// If white space is pre grab the longest line in the block.
return textContent.split('\n').reduce(function (acc, current) {
return Math.max(measureText(canvas, current, font), acc);
}, 0);
}
return measureText(canvas, textContent, font);
}