UNPKG

@atlaskit/editor-core

Version:

A package contains Atlassian editor core functionality

302 lines • 15 kB
"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