@atlaskit/editor-wikimarkup-transformer
Version:
Wiki markup transformer for JIRA and Confluence
173 lines (169 loc) • 7.59 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isNextLineEmpty = isNextLineEmpty;
exports.normalizeInlineNodes = normalizeInlineNodes;
exports.normalizeNestedExpands = normalizeNestedExpands;
exports.normalizePMNodes = normalizePMNodes;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _paragraph = require("../nodes/paragraph");
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; }
function normalizePMNodes(nodes, schema, parentNode) {
return [normalizeMediaGroups, normalizeNestedExpands, normalizeInlineNodes].reduce(function (currentNodes, normFunc) {
return normFunc(currentNodes, schema, parentNode);
}, nodes);
}
function normalizeNestedExpands(nodes, schema, parentNode) {
// When we round-trip through ADF - WikiMarkup - ADF, expands get replaced by strong text.
// That would result in the nested expand being in an invalid situation as it's no longer
// nested in either a table or expand
// This solves the issue for nested expands that sit in the root, which should cover every
// case for Jira software
var output = [];
var _iterator = _createForOfIteratorHelper(nodes),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var _node$type;
var node = _step.value;
if ((node === null || node === void 0 || (_node$type = node.type) === null || _node$type === void 0 ? void 0 : _node$type.name) === 'nestedExpand' && parentNode === 'doc') {
output.push(convertNodeToExpand(node, schema));
} else {
output.push(node);
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return output;
}
function normalizeInlineNodes(nodes, schema, _parentNode) {
var output = [];
var inlineNodeBuffer = [];
var _iterator2 = _createForOfIteratorHelper(nodes),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var node = _step2.value;
if (!node.isBlock) {
inlineNodeBuffer.push(node);
continue;
}
if (inlineNodeBuffer.length > 0) {
output.push.apply(output, (0, _toConsumableArray2.default)((0, _paragraph.createParagraphNodeFromInlineNodes)(inlineNodeBuffer, schema)));
}
inlineNodeBuffer = []; // clear buffer
output.push(node);
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
if (inlineNodeBuffer.length > 0) {
output.push.apply(output, (0, _toConsumableArray2.default)((0, _paragraph.createParagraphNodeFromInlineNodes)(inlineNodeBuffer, schema)));
}
if (output.length === 0) {
return [(0, _paragraph.createEmptyParagraphNode)(schema)];
}
return output;
}
/**
* Normalize the list of the given nodes for media groups.
* The rule is: if there are consecutive media group nodes (each with a single child media
* node) separated by any space or a single newline, then merge them into one media group
* with multiple child media nodes.
* @param nodes list of nodes to normalize. Must not be null
* @param schema
*/
function normalizeMediaGroups(nodes, schema, _parentNode) {
var output = [];
var mediaGroupBuffer = [];
var separatorBuffer = [];
var _iterator3 = _createForOfIteratorHelper(nodes),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var n = _step3.value;
if (n.type.name === 'mediaGroup' && n.childCount === 1) {
mediaGroupBuffer.push(n);
//separator buffer keeps track of the seperator(s) between each mediaGroup nodes,
//so needs resetting every time we encounter a new mediaGroup node
separatorBuffer = [];
continue;
}
if (mediaGroupBuffer.length > 0) {
if (isSignificantSeparatorNode(n, separatorBuffer)) {
output.push(createMergedMediaGroup(mediaGroupBuffer, schema));
output.push.apply(output, (0, _toConsumableArray2.default)(separatorBuffer));
output.push(n);
mediaGroupBuffer = [];
separatorBuffer = [];
} else {
separatorBuffer.push(n);
}
continue;
}
output.push(n);
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
if (mediaGroupBuffer.length > 0) {
output.push(createMergedMediaGroup(mediaGroupBuffer, schema));
}
// Dump everything else from separator buffer if anything is left
output.push.apply(output, (0, _toConsumableArray2.default)(separatorBuffer));
return output;
}
/**
* Creates a single mediaGroup whose children are the single media elements from the given mediaGroupNodes.
* @param mediaGroupNodes list of mediaGroups that have a single child each
* @param schema the schema
*/
function createMergedMediaGroup(mediaGroupNodes, schema) {
var mediaGroup = schema.nodes.mediaGroup;
var mediaNodes = mediaGroupNodes.map(function (v) {
return v.child(0);
});
return mediaGroup.createChecked({}, mediaNodes);
}
function isSignificantSeparatorNode(n, separatorBuffer) {
return isHardBreak(n, separatorBuffer) || !isEmptyTextNode(n) || isMediaGroupWithMultipleChildren(n);
}
/**
* Existing media groups with more than one child is considered as a significant separator.
*/
function isMediaGroupWithMultipleChildren(n) {
return n.type.name === 'mediaGroup' && n.childCount > 1;
}
/**
* If the current node is a hard break, AND there's already at least
* one hard break in the separator buffer, then we want to return true.
* @param n the current node to examine
* @param separatorBuffer the existing separator buffer.
*/
function isHardBreak(n, separatorBuffer) {
return n.type.name === 'hardBreak' && separatorBuffer.map(function (v) {
return v.type.name;
}).indexOf('hardBreak') !== -1;
}
function isEmptyTextNode(n) {
return n.textContent !== undefined && n.textContent.trim().length === 0;
}
function isNextLineEmpty(input) {
// Line with only spaces is considered an empty line
return input.trim().length === 0;
}
function convertNodeToExpand(node, schema) {
var expand = schema.nodes.expand;
return expand.createChecked(node.attrs, node.content);
}