UNPKG

@atlaskit/editor-confluence-transformer

Version:
403 lines (392 loc) 13.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.addMarks = addMarks; exports.calcPixelsFromCSSValue = calcPixelsFromCSSValue; exports.children = children; exports.createCodeFragment = createCodeFragment; exports.encodeMacroParams = void 0; exports.findTraversalPath = findTraversalPath; exports.getAcName = getAcName; exports.getAcTagChildNodes = getAcTagChildNodes; exports.getAcTagContent = getAcTagContent; exports.getAcTagNode = getAcTagNode; exports.getContent = getContent; exports.getExtensionMacroParams = void 0; exports.getMacroAttribute = getMacroAttribute; exports.getMacroParameters = getMacroParameters; exports.getNodeMarkOfType = getNodeMarkOfType; exports.getNodeName = getNodeName; exports.hasClass = hasClass; exports.mapPanelTypeToPm = exports.mapPanelTypeToCxhtml = void 0; exports.marksFromStyle = marksFromStyle; exports.parseMacro = parseMacro; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _model = require("@atlaskit/editor-prosemirror/model"); var _adfSchema = require("@atlaskit/adf-schema"); var _encodeCxhtml = require("./encode-cxhtml"); function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } /** * Deduce a set of marks from a style declaration. */ function marksFromStyle(schema, style) { var marks = []; // eslint-disable-next-line no-labels styles: for (var i = 0; i < style.length; i++) { var name = style.item(i); var value = style.getPropertyValue(name); switch (name) { case 'text-decoration-color': case 'text-decoration-style': // eslint-disable-next-line no-labels continue styles; case 'text-decoration-line': case 'text-decoration': switch (value) { case 'line-through': marks = schema.marks.strike.create().addToSet(marks); // eslint-disable-next-line no-labels continue styles; } break; case 'color': marks = schema.marks.textColor.create({ color: (0, _adfSchema.normalizeHexColor)(value) }).addToSet(marks); // eslint-disable-next-line no-labels continue styles; case 'background-color': marks = schema.marks.backgroundColor.create({ color: (0, _adfSchema.normalizeHexColor)(value) }).addToSet(marks); // eslint-disable-next-line no-labels continue styles; case 'font-family': if (value === 'monospace') { marks = schema.marks.code.create().addToSet(marks); // eslint-disable-next-line no-labels continue styles; } } throw new Error("Unable to derive a mark for CSS ".concat(name, ": ").concat(value)); } return marks; } /** * Create a fragment by adding a set of marks to each node. */ function addMarks(fragment, marks) { var result = fragment; for (var i = 0; i < fragment.childCount; i++) { var child = result.child(i); var newChild = child; var _iterator = _createForOfIteratorHelper(marks), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var mark = _step.value; newChild = newChild.mark(mark.addToSet(newChild.marks)); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } result = result.replaceChild(i, newChild); } return result; } function getNodeMarkOfType(node, markType) { if (!node.marks) { return null; } var foundMarks = node.marks.filter(function (mark) { return mark.type.name === markType.name; }); return foundMarks.length ? foundMarks[foundMarks.length - 1] : null; } /** * * Traverse the DOM node and build an array of the breadth-first-search traversal * through the tree. * * Detection of supported vs unsupported content happens at this stage. Unsupported * nodes do not have their children traversed. Doing this avoids attempting to * decode unsupported content descendents into ProseMirror nodes. */ function findTraversalPath(roots) { var inqueue = (0, _toConsumableArray2.default)(roots); var outqueue = []; var elem; // Ignored via go/ees005 // eslint-disable-next-line no-unmodified-loop-condition, no-cond-assign while (elem = inqueue.shift()) { outqueue.push(elem); var _children = void 0; // Ignored via go/ees005 // eslint-disable-next-line no-cond-assign if (isNodeSupportedContent(elem) && (_children = childrenOfNode(elem))) { var childIndex = void 0; for (childIndex = 0; childIndex < _children.length; childIndex++) { var child = _children[childIndex]; inqueue.push(child); } } } return outqueue; } function childrenOfNode(node) { var tag = getNodeName(node); if (tag === 'AC:STRUCTURED-MACRO') { return getAcTagChildNodes(node, 'AC:RICH-TEXT-BODY'); } return node.childNodes; } /** * Return an array containing the child nodes in a fragment. * * @param fragment */ function children(fragment) { var nodes = []; for (var i = 0; i < fragment.childCount; i++) { nodes.push(fragment.child(i)); } return nodes; } /** * Quickly determine if a DOM node is supported (i.e. can be represented in the ProseMirror * schema). * * When a node is not supported, its children are not traversed — instead the entire node content * is stored inside an `unsupportedInline`. * * @param node */ function isNodeSupportedContent(node) { if (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.CDATA_SECTION_NODE) { return true; } if (node instanceof HTMLElement || node.nodeType === Node.ELEMENT_NODE) { var tag = getNodeName(node); switch (tag) { case 'DEL': case 'S': case 'B': case 'STRONG': case 'I': case 'EM': case 'CODE': case 'SUB': case 'SUP': case 'U': case 'BLOCKQUOTE': case 'SPAN': case 'H1': case 'H2': case 'H3': case 'H4': case 'H5': case 'H6': case 'BR': case 'HR': case 'UL': case 'OL': case 'LI': case 'P': case 'A': case 'FAB:MENTION': case 'FAB:MEDIA-GROUP': case 'FAB:MEDIA-SINGLE': case 'FAB:MEDIA': case 'AC:INLINE-COMMENT-MARKER': case 'AC:STRUCTURED-MACRO': return true; } } return false; } function getAcName(node) { return node.getAttribute('ac:name') || ''; } function getNodeName(node) { return node.nodeName.toUpperCase(); } function getAcTagContent(node, tagName) { for (var i = 0, len = node.childNodes.length; i < len; i++) { var child = node.childNodes[i]; if (getNodeName(child) === tagName) { return child.textContent; } } return null; } function getAcTagChildNodes(node, tagName) { var child = getAcTagNode(node, tagName); if (child) { // return html collection only if childNodes are found return child.childNodes.length ? child.childNodes : null; } return null; } function getAcTagNode(node, tagName) { for (var i = 0, len = node.childNodes.length; i < len; i++) { var child = node.childNodes[i]; if (getNodeName(child).toLowerCase() === tagName) { return child; } } return null; } function getMacroAttribute(node, attribute) { return node.getAttribute('data-macro-' + attribute) || ''; } // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any function getMacroParameters(node) { var params = {}; getMacroAttribute(node, 'parameters').split('|').forEach(function (paramStr) { var param = paramStr.split('='); if (param.length) { params[param[0]] = param[1]; } }); return params; } // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/max-params function createCodeFragment(schema, codeContent, language, title) { var content = []; if (!!title) { var titleNode = schema.nodes.heading.createChecked({ level: 5 }, schema.text(title)); content.push(titleNode); } var codeBlockNode = schema.nodes.codeBlock.createChecked({ language: language }, schema.text(codeContent)); content.push(codeBlockNode); return _model.Fragment.from(content); } function hasClass(node, className) { if (node && node.className) { return node.className.indexOf(className) > -1; } return false; } /** * Calculates the size of an element in a given dimension, using its CSS property value, * which may be based to the parent element's dimensions. * * @param value Value for a CSS property. Supported units are px and %. * @param parentPixels The dimension of the container element, in pixels. */ function calcPixelsFromCSSValue(value, parentPixels) { if (value.substr(-2) === 'px') { return parseInt(value.slice(0, -2), 10); } else if (value.substr(-1) === '%') { return Math.round(parseInt(value.slice(0, -1), 10) / 100.0 * parentPixels); } return 0; } /* * Constructs a struct string of replacement blocks and marks for a given node */ function getContent(node, convertedNodes) { var fragment = _model.Fragment.fromArray([]); for (var childIndex = 0; childIndex < node.childNodes.length; childIndex++) { var child = node.childNodes[childIndex]; var thing = convertedNodes.get(child); if (thing instanceof _model.Fragment || thing instanceof _model.Node) { fragment = fragment.append(_model.Fragment.from(thing)); } } return fragment; } function parseMacro(node) { var macroName = getAcName(node) || 'Unnamed Macro'; // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion var macroId = node.getAttributeNS(_encodeCxhtml.AC_XMLNS, 'macro-id'); var properties = {}; var params = {}; for (var i = 0, len = node.childNodes.length; i < len; i++) { var child = node.childNodes[i]; var nodeName = getNodeName(child).toLowerCase(); if (child.nodeType === 3) { continue; } var value = child.textContent; // example: <ac:parameter ac:name=\"colour\">Red</ac:parameter> if (nodeName === 'ac:parameter') { var key = getAcName(child); if (key) { params[key] = value; } } else { // example: <fab:placeholder-url>, <fab:display-type>, <ac:rich-text-body> properties[nodeName] = value; } } return { macroId: macroId, macroName: macroName, properties: properties, params: params }; } // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any var getExtensionMacroParams = exports.getExtensionMacroParams = function getExtensionMacroParams(params) { // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-explicit-any var macroParams = {}; Object.keys(params).forEach(function (key) { /** Safe check for empty keys */ if (key) { macroParams[key] = { value: params[key] }; } }); return macroParams; }; var mapPanelTypeToPm = exports.mapPanelTypeToPm = function mapPanelTypeToPm(panelType) { switch (panelType) { case 'warning': return 'error'; case 'note': return 'warning'; case 'tip': return 'success'; } return panelType; }; var mapPanelTypeToCxhtml = exports.mapPanelTypeToCxhtml = function mapPanelTypeToCxhtml(panelType) { switch (panelType) { case 'error': return 'warning'; case 'warning': return 'note'; case 'success': return 'tip'; case 'note': return 'panel'; } return panelType; }; var encodeMacroParams = exports.encodeMacroParams = function encodeMacroParams(doc, params) { var elem = doc.createDocumentFragment(); Object.keys(params).forEach(function (name) { var el = doc.createElementNS(_encodeCxhtml.AC_XMLNS, 'ac:parameter'); el.setAttributeNS(_encodeCxhtml.AC_XMLNS, 'ac:name', name); el.textContent = params[name].value; elem.appendChild(el); }); return elem; };