@atlaskit/adf-schema
Version:
Shared package that contains the ADF-schema (json) and ProseMirror node/mark specs
287 lines (277 loc) • 10.8 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import { hexToEditorBackgroundPaletteColorTokenName } from '@atlaskit/editor-palette';
import { getTokenValue } from '@atlaskit/tokens';
import { B100, B50, B75, G200, G50, G75, hexToRgba, isHex, isRgb, N0, N20, N60, N800, P100, P50, P75, R100, R50, R75, rgbToHex, T100, T50, T75, Y200, Y50, Y75 } from '../../utils/colors';
import { uuid } from '../../utils/uuid';
export var tablePrefixSelector = 'pm-table';
export var tableCellSelector = "".concat(tablePrefixSelector, "-cell-content-wrap");
export var tableHeaderSelector = "".concat(tablePrefixSelector, "-header-content-wrap");
export var tableCellContentWrapperSelector = "".concat(tablePrefixSelector, "-cell-nodeview-wrapper");
export var tableCellContentDomSelector = "".concat(tablePrefixSelector, "-cell-nodeview-content-dom");
var DEFAULT_TABLE_HEADER_CELL_BACKGROUND = N20.toLocaleLowerCase();
export var getCellAttrs = function getCellAttrs(dom) {
var defaultValues = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var widthAttr = dom.getAttribute('data-colwidth');
var width = widthAttr && /^\d+(,\d+)*$/.test(widthAttr) ? widthAttr.split(',').map(function (str) {
return Number(str);
}) : null;
var colspan = Number(dom.getAttribute('colspan') || 1);
var backgroundColor = dom.style.backgroundColor;
/**
* We have pivoted to store background color information in
* data-cell-background.
* We will have original hex code (which we map to DST token)
* stored in data-cell-background, use that.
* More details at https://product-fabric.atlassian.net/wiki/spaces/EUXQ/pages/3472556903/Tokenising+tableCell+background+colors#Update-toDom-and-parseDom-to-store-and-read-background-color-from-data-cell-background-attribute.4
*/
var dataCellBackground = dom.getAttribute('data-cell-background');
var dataCellBackgroundHexCode = dataCellBackground && isHex(dataCellBackground) ? dataCellBackground : undefined;
// ignore setting background attr if ds neutral token is detected
if (backgroundColor.includes('--ds-background-neutral')) {
backgroundColor = '';
} else {
if (backgroundColor && isRgb(backgroundColor)) {
var result = rgbToHex(backgroundColor);
if (result !== null) {
backgroundColor = result;
}
}
}
var backgroundHexCode = dataCellBackgroundHexCode || (backgroundColor && backgroundColor !== defaultValues['background'] ? backgroundColor : null);
return {
colspan: colspan,
rowspan: Number(dom.getAttribute('rowspan') || 1),
colwidth: width && width.length === colspan ? width : null,
background: backgroundHexCode
};
};
/**
* gets cell dom attributes based on node attributes
* @returns CellDomAttrs
*/
export var getCellDomAttrs = function getCellDomAttrs(node) {
var attrs = {};
var nodeType = node.type.name;
if (node.attrs.colspan !== 1) {
attrs.colspan = node.attrs.colspan;
}
if (node.attrs.rowspan !== 1) {
attrs.rowspan = node.attrs.rowspan;
}
if (node.attrs.colwidth) {
attrs['data-colwidth'] = node.attrs.colwidth.join(',');
}
if (node.attrs.background) {
var background = node.attrs.background;
// to ensure that we don't overwrite product's style:
// - it clears background color for <th> if its set to gray
// - it clears background color for <td> if its set to white
// - it clears background color for <th> if ds neutral token is detected
var ignored = nodeType === 'tableHeader' && background === tableBackgroundColorNames.get('light gray') || nodeType === 'tableCell' && background === tableBackgroundColorNames.get('white') || nodeType === 'tableHeader' && background.includes('--ds-background-neutral');
if (ignored) {
attrs.style = '';
} else {
var color = isRgb(background) ? rgbToHex(background) : background;
var tokenName = hexToEditorBackgroundPaletteColorTokenName(color);
// eslint-disable-next-line @atlaskit/design-system/no-unsafe-design-token-usage
var tokenColor = tokenName ? getTokenValue(tokenName) : color;
attrs.style = "".concat(attrs.style || '', "background-color: ").concat(tokenColor, ";");
/**
* Storing hex code in data-cell-background because
* we want to have DST token (css variable) or
* DST token value (value (hex code) of css variable) in
* inline style to correct render table cell background
* based on selected theme.
* Currently we rely on background color hex code stored in
* inline style.
* Because of that when we copy and paste table, we end up
* having DST token or DST token value in ADF instead of
* original hex code which we map to DST token.
* So, introducing data-cell-background.
* More details at https://product-fabric.atlassian.net/wiki/spaces/EUXQ/pages/3472556903/Tokenising+tableCell+background+colors#Update-toDom-and-parseDom-to-store-and-read-background-color-from-data-cell-background-attribute.4
*/
if (color) {
attrs['data-cell-background'] = color;
}
attrs.colorname = tableBackgroundColorPalette.get(color);
}
}
if (nodeType === 'tableHeader') {
attrs.class = tableHeaderSelector;
} else {
attrs.class = tableCellSelector;
}
return attrs;
};
export var tableBackgroundColorPalette = new Map();
export var tableBackgroundBorderColor = hexToRgba(N800, 0.12) || N0;
export var tableBackgroundColorNames = new Map();
[[N0, 'White'], [B50, 'Light blue'], [T50, 'Light teal'], [G50, 'Light green'], [Y50, 'Light yellow'], [R50, 'Light red'], [P50, 'Light purple'], [N20, 'Light gray'], [B75, 'Blue'], [T75, 'Teal'], [G75, 'Green'], [Y75, 'Yellow'], [R75, 'Red'], [P75, 'Purple'], [N60, 'Gray'], [B100, 'Dark blue'], [T100, 'Dark teal'], [G200, 'Dark green'], [Y200, 'Dark yellow'], [R100, 'Dark red'], [P100, 'Dark purple']].forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
colorValue = _ref2[0],
colorName = _ref2[1];
tableBackgroundColorPalette.set(colorValue.toLowerCase(), colorName);
tableBackgroundColorNames.set(colorName.toLowerCase(), colorValue.toLowerCase());
});
/**
* @name table_node
*/
/**
* @name table_row_node
*/
/**
* @name table_cell_content
* @minItems 1
* @allowUnsupportedBlock true
*/
/**
* @name table_cell_node
*/
/**
* @name table_header_node
*/
// TODO: Fix any, potential issue. ED-5048
var createTableSpec = function createTableSpec() {
var attrs = {
isNumberColumnEnabled: {
default: false
},
layout: {
default: 'default'
},
__autoSize: {
default: false
},
localId: {
default: ''
}
};
var tableNodeSpec = {
content: 'tableRow+',
attrs: attrs,
marks: 'unsupportedMark unsupportedNodeAttribute',
tableRole: 'table',
isolating: true,
selectable: true,
group: 'block',
parseDOM: [{
tag: 'table',
getAttrs: function getAttrs(node) {
var _dom$parentElement;
var dom = node;
var breakoutWrapper = (_dom$parentElement = dom.parentElement) === null || _dom$parentElement === void 0 ? void 0 : _dom$parentElement.parentElement;
return {
isNumberColumnEnabled: dom.getAttribute('data-number-column') === 'true' ? true : false,
layout:
// copying from editor
dom.getAttribute('data-layout') || ( // copying from renderer
breakoutWrapper === null || breakoutWrapper === void 0 ? void 0 : breakoutWrapper.getAttribute('data-layout')) || 'default',
__autoSize: dom.getAttribute('data-autosize') === 'true' ? true : false,
localId: dom.getAttribute('data-table-local-id') || uuid.generate()
};
}
}],
toDOM: function toDOM(node) {
var attrs = {
'data-number-column': node.attrs.isNumberColumnEnabled,
'data-layout': node.attrs.layout,
'data-autosize': node.attrs.__autoSize,
'data-table-local-id': node.attrs.localId
};
return ['table', attrs, ['tbody', 0]];
}
};
return tableNodeSpec;
};
export var table = createTableSpec();
var shouldIncludeAttribute = function shouldIncludeAttribute(key, value) {
return !key.startsWith('__') && (key !== 'localId' || !!value);
};
export var tableToJSON = function tableToJSON(node) {
return {
attrs: Object.keys(node.attrs).filter(function (key) {
return shouldIncludeAttribute(key, node.attrs[key]);
}).reduce(function (obj, key) {
obj[key] = node.attrs[key];
return obj;
}, {})
};
};
export var tableRow = {
selectable: false,
content: '(tableCell | tableHeader)+',
marks: 'unsupportedMark unsupportedNodeAttribute',
tableRole: 'row',
parseDOM: [{
tag: 'tr'
}],
toDOM: function toDOM() {
return ['tr', 0];
}
};
var cellAttrs = {
colspan: {
default: 1
},
rowspan: {
default: 1
},
colwidth: {
default: null
},
background: {
default: null
}
};
export var tableCell = {
selectable: false,
content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading | codeBlock | mediaSingle | mediaGroup | decisionList | taskList | blockCard | embedCard | extension | nestedExpand | unsupportedBlock)+',
attrs: cellAttrs,
tableRole: 'cell',
marks: 'alignment dataConsumer fragment unsupportedMark unsupportedNodeAttribute',
isolating: true,
parseDOM: [
// Ignore number cell copied from renderer
{
tag: '.ak-renderer-table-number-column',
ignore: true
}, {
tag: 'td',
getAttrs: function getAttrs(dom) {
return getCellAttrs(dom);
}
}],
toDOM: function toDOM(node) {
return ['td', getCellDomAttrs(node), 0];
}
};
export var toJSONTableCell = function toJSONTableCell(node) {
return {
attrs: Object.keys(node.attrs).reduce(function (obj, key) {
if (cellAttrs[key].default !== node.attrs[key]) {
obj[key] = node.attrs[key];
}
return obj;
}, {})
};
};
export var tableHeader = {
selectable: false,
content: '(paragraph | panel | blockquote | orderedList | bulletList | rule | heading | codeBlock | mediaSingle | mediaGroup | decisionList | taskList | blockCard | embedCard | extension | nestedExpand)+',
attrs: cellAttrs,
tableRole: 'header_cell',
isolating: true,
marks: 'alignment dataConsumer fragment unsupportedMark unsupportedNodeAttribute',
parseDOM: [{
tag: 'th',
getAttrs: function getAttrs(dom) {
return getCellAttrs(dom, {
background: DEFAULT_TABLE_HEADER_CELL_BACKGROUND
});
}
}],
toDOM: function toDOM(node) {
return ['th', getCellDomAttrs(node), 0];
}
};
export var toJSONTableHeader = toJSONTableCell;