@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
161 lines • 4.01 kB
JavaScript
const hash = {
nodes: {
doc: 'doc',
paragraph: 'p',
text: 't',
bulletList: 'ul',
orderedList: 'ol',
listItem: 'li',
heading: 'h',
blockquote: 'blockq',
codeBlock: 'codebl',
panel: 'pnl',
rule: 'rl',
hardBreak: 'br',
mention: 'ment',
emoji: 'emj',
image: 'img',
caption: 'cap',
media: 'media',
mediaGroup: 'mediag',
mediaSingle: 'medias',
plain: 'pln',
table: 'table',
tableCell: 'td',
tableHeader: 'th',
tableRow: 'tr',
decisionList: 'dl',
decisionItem: 'di',
taskList: 'tl',
taskItem: 'ti',
extension: 'ext',
inlineExtension: 'exti',
bodiedExtension: 'extb',
multiBodiedExtension: 'extmbe',
extensionFrame: 'extfrm',
status: 'sts',
placeholder: 'plh',
inlineCard: 'cardi',
blockCard: 'cardb',
embedCard: 'carde',
expand: 'exp',
nestedExpand: 'expn',
unsupportedBlock: 'unsupb',
unsupportedInline: 'unsupi',
unknownBlock: 'unkb',
date: 'date'
},
marks: {
em: 'em',
strong: 'strong',
code: 'code',
strike: 'strike',
underline: 'undline',
link: 'lnk',
subsup: 'subsup',
textColor: 'txtclr',
unsupportedMark: 'unsupmrk',
unsupportedNodeAttribute: 'unsupnattr',
annotation: 'anno'
}
};
function shortHash(type, isMark) {
const code = hash[isMark ? 'marks' : 'nodes'][type];
return code ? code : type;
}
function compactStringifier(node) {
var _node$marks;
const isContentEmpty = !node.content;
const isTextNode = (node === null || node === void 0 ? void 0 : node.type) === 'text';
const hasMarks = (_node$marks = node.marks) === null || _node$marks === void 0 ? void 0 : _node$marks.length;
const isContentArray = Array.isArray(node.content);
const marks = child => {
if (hasMarks) {
return node.marks.reduce((str, mark) => `${shortHash(mark, true)}(${str})`, child);
}
return child;
};
let content;
if (isTextNode) {
content = String(node.nodeSize);
} else if (isContentEmpty) {
content = '';
} else if (isContentArray) {
content = node.content.map(node => compactStringifier(node)).join(',');
}
return marks(`${shortHash(node.type, false)}(${content})`);
}
export const getDocStructure = (doc, options) => {
try {
const result = getBlockNode(doc, 0);
if (options !== null && options !== void 0 && options.compact) {
return compactStringifier(result);
}
return result;
} catch (error) {
return `Error logging document structure: ${error}`;
}
};
const getBlockNode = (node, pos) => {
const blockNode = {
type: node.type.name,
pos,
nodeSize: node.nodeSize
};
const content = getBlockNodeContent(node.content, pos);
if (content.length > 0) {
blockNode.content = content;
}
const marks = getMarks(node);
if (marks.length > 0) {
blockNode.marks = marks;
}
return blockNode;
};
const getBlockNodeContent = (node, pos) => {
if (!node || !node.content || !node.content.length) {
return [];
}
let blockNodeContent = [];
const {
content
} = node;
if (content[0].isBlock) {
// children are block nodes
let prevNode;
blockNodeContent = content.map(node => {
pos += prevNode ? prevNode.nodeSize : 1;
prevNode = node;
return getBlockNode(node, pos);
});
} else {
// children are inline nodes .
const result = getInlineNodes(content, pos);
blockNodeContent = result.inlineNodes;
pos = result.pos;
}
return blockNodeContent;
};
const getInlineNodes = (nodes, pos) => {
let inlineNodes = nodes.map(node => {
const {
nodeSize
} = node;
const inlineNode = {
type: node.type.name,
pos,
nodeSize
};
const marks = getMarks(node);
if (marks.length > 0) {
inlineNode.marks = marks;
}
pos += nodeSize;
return inlineNode;
});
return {
inlineNodes,
pos
};
};
const getMarks = node => node.marks.map(mark => mark.type.name);