@atlaskit/editor-core
Version:
A package contains Atlassian editor core functionality
302 lines • 15 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var _1 = require("../../");
var parse_cxhtml_1 = require("./parse-cxhtml");
var encode_cxhtml_1 = require("./encode-cxhtml");
var utils_1 = require("./utils");
var content_wrapper_1 = require("./content-wrapper");
var convertedNodes = new WeakMap();
// This reverted mapping is used to map Unsupported Node back to it's original cxhtml
var convertedNodesReverted = new WeakMap();
function default_1(cxhtml, schema) {
var dom = parse_cxhtml_1.default(cxhtml).querySelector('body');
return schema.nodes.doc.createChecked({}, parseDomNode(schema, dom));
}
exports.default = default_1;
function parseDomNode(schema, dom) {
var nodes = utils_1.findTraversalPath(Array.prototype.slice.call(dom.childNodes, 0));
// Process through nodes in reverse (so deepest child elements are first).
for (var i = nodes.length - 1; i >= 0; i--) {
var node = nodes[i];
var content_1 = utils_1.getContent(node, convertedNodes);
var candidate = converter(schema, content_1, node);
if (typeof candidate !== 'undefined' && candidate !== null) {
convertedNodes.set(node, candidate);
convertedNodesReverted.set(candidate, node);
}
}
var content = utils_1.getContent(dom, convertedNodes);
var compatibleContent = content.childCount > 0
? schema.nodes.doc.validContent(content)
? content
: content_wrapper_1.docContentWrapper(schema, content, convertedNodesReverted)
: schema.nodes.paragraph.createChecked({});
return compatibleContent;
}
function converter(schema, content, node) {
// text
if (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.CDATA_SECTION_NODE) {
var text = node.textContent;
return text ? schema.text(text) : null;
}
// All unsupported content is wrapped in an `unsupportedInline` node. Wrapping
// `unsupportedInline` inside `paragraph` where appropriate is handled when
// the content is inserted into a parent.
var unsupportedInline = schema.nodes.confluenceUnsupportedInline.create({ cxhtml: encode_cxhtml_1.default(node) });
// marks and nodes
if (node instanceof Element) {
var tag = utils_1.getNodeName(node);
switch (tag) {
// Marks
case 'DEL':
case 'S':
return content ? utils_1.addMarks(content, [schema.marks.strike.create()]) : null;
case 'B':
case 'STRONG':
return content ? utils_1.addMarks(content, [schema.marks.strong.create()]) : null;
case 'I':
case 'EM':
return content ? utils_1.addMarks(content, [schema.marks.em.create()]) : null;
case 'CODE':
return content ? utils_1.addMarks(content, [schema.marks.code.create()]) : null;
case 'SUB':
case 'SUP':
var type = tag === 'SUB' ? 'sub' : 'sup';
return content ? utils_1.addMarks(content, [schema.marks.subsup.create({ type: type })]) : null;
case 'U':
return content ? utils_1.addMarks(content, [schema.marks.underline.create()]) : null;
case 'A':
return content ? utils_1.addMarks(content, [schema.marks.link.create({ href: node.getAttribute('href') })]) : null;
// Nodes
case 'BLOCKQUOTE':
return schema.nodes.blockquote.createChecked({}, schema.nodes.blockquote.validContent(content)
? content
: content_wrapper_1.blockquoteContentWrapper(schema, content, convertedNodesReverted));
case 'SPAN':
return utils_1.addMarks(content, utils_1.marksFromStyle(schema, node.style));
case 'H1':
case 'H2':
case 'H3':
case 'H4':
case 'H5':
case 'H6':
var level = Number(tag.charAt(1));
return schema.nodes.heading.createChecked({ level: level }, schema.nodes.heading.validContent(content)
? content
: content_wrapper_1.ensureInline(schema, content, convertedNodesReverted));
case 'BR':
return schema.nodes.hardBreak.createChecked();
case 'HR':
return schema.nodes.rule.createChecked();
case 'UL':
return schema.nodes.bulletList.createChecked({}, schema.nodes.bulletList.validContent(content)
? content
: content_wrapper_1.listContentWrapper(schema, content, convertedNodesReverted));
case 'OL':
return schema.nodes.orderedList.createChecked({}, schema.nodes.orderedList.validContent(content)
? content
: content_wrapper_1.listContentWrapper(schema, content, convertedNodesReverted));
case 'LI':
return schema.nodes.listItem.createChecked({}, schema.nodes.listItem.validContent(content)
? content
: content_wrapper_1.listItemContentWrapper(schema, content, convertedNodesReverted));
case 'P':
var output_1 = _1.Fragment.from([]);
var textNodes_1 = [];
var mediaNodes_1 = [];
if (!node.childNodes.length) {
return schema.nodes.paragraph.createChecked({}, content);
}
content.forEach(function (childNode, offset) {
if (childNode.type === schema.nodes.media) {
// if there were text nodes before this node
// combine them into one paragraph and empty the list
if (textNodes_1.length) {
var paragraph = schema.nodes.paragraph.createChecked({}, textNodes_1);
output_1 = output_1.addToEnd(paragraph);
textNodes_1 = [];
}
mediaNodes_1.push(childNode);
}
else {
// if there were media nodes before this node
// combine them into one mediaGroup and empty the list
if (mediaNodes_1.length) {
var mediaGroup = schema.nodes.mediaGroup.createChecked({}, mediaNodes_1);
output_1 = output_1.addToEnd(mediaGroup);
mediaNodes_1 = [];
}
textNodes_1.push(childNode);
}
});
// combine remaining text nodes
if (textNodes_1.length) {
var paragraph = schema.nodes.paragraph.createChecked({}, content_wrapper_1.ensureInline(schema, _1.Fragment.fromArray(textNodes_1), convertedNodesReverted));
output_1 = output_1.addToEnd(paragraph);
}
// combine remaining media nodes
if (mediaNodes_1.length) {
var mediaGroup = schema.nodes.mediaGroup.createChecked({}, mediaNodes_1);
output_1 = output_1.addToEnd(mediaGroup);
}
return output_1;
case 'AC:STRUCTURED-MACRO':
return convertConfluenceMacro(schema, node) || unsupportedInline;
case 'FAB:LINK':
if (node.firstChild &&
node.firstChild instanceof Element &&
utils_1.getNodeName(node.firstChild) === 'FAB:MENTION') {
var cdata_1 = node.firstChild.firstChild;
return schema.nodes.mention.create({
id: node.firstChild.getAttribute('atlassian-id'),
text: cdata_1.nodeValue,
});
}
break;
case 'FAB:MENTION':
var cdata = node.firstChild;
return schema.nodes.mention.create({
id: node.getAttribute('atlassian-id'),
text: cdata.nodeValue,
});
case 'FAB:MEDIA':
var mediaAttrs = {
id: node.getAttribute('media-id') || '',
type: (node.getAttribute('media-type') || 'file'),
collection: node.getAttribute('media-collection') || '',
};
if (node.hasAttribute('file-name')) {
mediaAttrs.__fileName = node.getAttribute('file-name');
}
if (node.hasAttribute('file-size')) {
mediaAttrs.__fileSize = parseInt(node.getAttribute('file-size'), 10);
}
if (node.hasAttribute('file-mime-type')) {
mediaAttrs.__fileMimeType = node.getAttribute('file-mime-type');
}
return schema.nodes.media.create(mediaAttrs);
case 'PRE':
return schema.nodes.codeBlock.create({ language: null }, schema.text(node.textContent || ''));
case 'TABLE':
if (utils_1.hasClass(node, 'wysiwyg-macro')) {
return convertWYSIWYGMacro(schema, node) || unsupportedInline;
}
else if (utils_1.hasClass(node, 'confluenceTable')) {
return convertTable(schema, node);
}
return unsupportedInline;
case 'DIV':
if (utils_1.hasClass(node, 'codeHeader')) {
var codeHeader = schema.text(node.textContent || '', [schema.marks.strong.create()]);
return schema.nodes.heading.createChecked({ level: 5 }, _1.Fragment.from(codeHeader));
}
else if (node.querySelector('.syntaxhighlighter')) {
var codeblockNode = node.querySelector('.syntaxhighlighter');
return convertCodeFromView(schema, codeblockNode) || unsupportedInline;
}
else if (utils_1.hasClass(node, 'preformatted')) {
return convertNoFormatFromView(schema, node) || unsupportedInline;
}
return unsupportedInline;
}
}
return unsupportedInline;
}
function convertConfluenceMacro(schema, node) {
var name = utils_1.getAcName(node);
switch (name) {
case 'CODE':
var language = utils_1.getAcParameter(node, 'language');
var title = utils_1.getAcParameter(node, 'title');
var codeContent = utils_1.getAcTagContent(node, 'AC:PLAIN-TEXT-BODY') || ' ';
return utils_1.createCodeFragment(schema, codeContent, language, title);
case 'NOFORMAT': {
var codeContent_1 = utils_1.getAcTagContent(node, 'AC:PLAIN-TEXT-BODY') || ' ';
return schema.nodes.codeBlock.create({ language: null }, schema.text(codeContent_1));
}
case 'WARNING':
case 'INFO':
case 'NOTE':
case 'TIP':
var panelTitle = utils_1.getAcParameter(node, 'title');
var panelRichTextBody = utils_1.getAcTagNode(node, 'AC:RICH-TEXT-BODY') || '';
var panelBody = [];
if (panelTitle) {
panelBody.push(schema.nodes.heading.create({ level: 3 }, schema.text(panelTitle)));
}
if (panelRichTextBody) {
var pmNode = parseDomNode(schema, panelRichTextBody);
panelBody = panelBody.concat(pmNode.content);
}
else {
panelBody.push(schema.nodes.paragraph.create({}));
}
return schema.nodes.panel.create({ panelType: name.toLowerCase() }, panelBody);
case 'JIRA':
var schemaVersion = node.getAttributeNS(encode_cxhtml_1.AC_XMLNS, 'schema-version');
var macroId = node.getAttributeNS(encode_cxhtml_1.AC_XMLNS, 'macro-id');
var server = utils_1.getAcParameter(node, 'server');
var serverId = utils_1.getAcParameter(node, 'serverId');
var issueKey = utils_1.getAcParameter(node, 'key');
// if this is an issue list, render it as unsupported node
// @see https://product-fabric.atlassian.net/browse/ED-1193?focusedCommentId=26672&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-26672
if (!issueKey) {
return schema.nodes.confluenceUnsupportedInline.create({ cxhtml: encode_cxhtml_1.default(node) });
}
return schema.nodes.confluenceJiraIssue.create({
issueKey: issueKey,
macroId: macroId,
schemaVersion: schemaVersion,
server: server,
serverId: serverId,
});
}
return null;
}
function convertWYSIWYGMacro(schema, node) {
var name = utils_1.getMacroAttribute(node, 'name').toUpperCase();
switch (name) {
case 'CODE':
case 'NOFORMAT':
var codeContent = node.querySelector('pre').textContent || ' ';
var _a = utils_1.getMacroParameters(node), language = _a.language, title = _a.title;
return utils_1.createCodeFragment(schema, codeContent, language, title);
}
return null;
}
function convertCodeFromView(schema, node) {
var container = node.querySelector('.container');
var content = '';
if (container) {
var childNodes = container.childNodes;
for (var i = 0, len = childNodes.length; i < len; i++) {
content += childNodes[i].textContent + (i === len - 1 ? '' : '\n');
}
}
var language;
if (node.className) {
language = (node.className.match(/\w+$/) || [''])[0];
}
return utils_1.createCodeFragment(schema, content, language);
}
function convertNoFormatFromView(schema, node) {
var codeContent = node.querySelector('pre').textContent || ' ';
return utils_1.createCodeFragment(schema, codeContent);
}
function convertTable(schema, node) {
var _a = schema.nodes, table = _a.table, tableRow = _a.tableRow, tableCell = _a.tableCell, tableHeader = _a.tableHeader;
var rowNodes = [];
var rows = node.querySelectorAll('tr');
for (var i = 0, rowsCount = rows.length; i < rowsCount; i++) {
var cellNodes = [];
var cols = rows[i].querySelectorAll('td,th');
for (var j = 0, colsCount = cols.length; j < colsCount; j++) {
var cell = cols[j].nodeName === 'td' ? tableCell : tableHeader;
var pmNode = parseDomNode(schema, cols[j]);
cellNodes.push(cell.createChecked(null, pmNode));
}
rowNodes.push(tableRow.create(null, _1.Fragment.from(cellNodes)));
}
return table.create(null, _1.Fragment.from(rowNodes));
}
//# sourceMappingURL=parse.js.map