@atlaskit/editor-wikimarkup-transformer
Version:
Wiki markup transformer for JIRA and Confluence
189 lines (184 loc) • 6.28 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.parseContentLink = parseContentLink;
exports.parseLink = parseLink;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _text = require("../../utils/text");
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
/*
* This implementation is ported from JIRA with minimal modifications
* It uses a mutable "StringBuffer" to parse links. It would be ideal to
* move this to operating on immutable strings instead if possible
*
* TODO: CS-596 Replace string buffer usage with strings
*/
function trimIfPossible(s) {
if (s === null) {
return null;
}
return s.trim();
}
function extractLinkBody(buffer) {
var indexOfBang = buffer.indexOf('!');
var indexOfPipe = buffer.indexOf('|');
var lastIndexOfBang = buffer.lastIndexOf('!');
var notEscaped = indexOfBang === -1 || indexOfBang > indexOfPipe || indexOfBang === lastIndexOfBang;
if (notEscaped) {
return divideOn(buffer, '|');
}
var body = new _text.StringBuffer();
var inEscape = false;
for (var i = 0; i < buffer.length(); i++) {
var c = buffer.charAt(i);
if (c === '!') {
inEscape = !inEscape;
}
if (c === '|' && !inEscape) {
buffer.delete(0, i + 1);
return body.toString();
}
body.append(c);
}
return null;
}
function divideAfterLast(buffer, divider) {
if (buffer.length() === 0) {
return null;
}
return divideAfter(buffer, buffer.lastIndexOf(divider));
}
function divideAfter(buffer, index) {
if (typeof index === 'string') {
index = buffer.indexOf(index);
}
if (index < 0) {
return null;
} else if (index === buffer.length() - 1) {
buffer.deleteCharAt(buffer.length() - 1);
return null;
} else {
var body = buffer.substring(index + 1);
buffer.delete(index, buffer.length());
return body;
}
}
/**
* Split a StringBuffer on some dividing character. Return everything before the divider,
* and remove that prefix _and_ the divider from the StringBuffer. If there is no divider,
* return null.
* <p/>
* If the buffer begins with the divider, then the divider will be removed _and_ null returned.
* If the buffer ends with the divider, everything before the divider is returned and the buffer
* will remain empty.
*
* @param buffer the text we want to divide. Will be modified during the operation
* @param divider the character to divide the buffer on
* @return the characters before the divider, or the default if there are none
*/
function divideOn(buffer, divider) {
if (buffer.length() === 0) {
return null;
}
var i = buffer.indexOf(divider);
if (i < 0) {
return null;
} else if (i === 0) {
buffer.deleteCharAt(0);
return null;
} else {
var body = buffer.substring(0, i);
buffer.delete(0, i + 1);
return body;
}
}
function extractNumber(buf) {
var digits = new _text.StringBuffer();
var i = 0;
for (; i < buf.length() && (0, _text.isDigit)(buf.charAt(i)); i++) {
digits.append(buf.charAt(i));
}
if (i > 0) {
buf.delete(0, i);
}
try {
return parseInt(digits.toString(), 10);
} catch (e) {
return 0;
}
}
function parseLink(linkText) {
var originalLinkText = linkText;
// we want to decode single quotes (represented by ') back before parsing the link test
if (linkText.indexOf(''') !== -1) {
linkText = linkText.replace(''', "'");
}
var buf = new _text.StringBuffer(linkText);
var linkBody = extractLinkBody(buf);
var linkTitle = trimIfPossible(divideAfter(buf, '|'));
var notLinkBody = buf.toString().trim();
return {
originalLinkText: originalLinkText,
linkBody: linkBody,
linkTitle: linkTitle,
notLinkBody: notLinkBody
};
}
function parseContentLink(link) {
if (typeof link === 'string') {
link = parseLink(link);
}
var _link = link,
notLinkBody = _link.notLinkBody;
var shortcutName = null;
var shortcutValue = null;
var spaceKey = null;
var attachmentName = null;
var anchor = null;
var destinationTitle = '';
var contentId = 0;
// Don't treat it as a short link when it starts with "~"
if (!notLinkBody.startsWith('~')) {
var shortcutBuf = new _text.StringBuffer(notLinkBody);
shortcutName = trimIfPossible(divideAfterLast(shortcutBuf, '@'));
if ((0, _text.isNotBlank)(shortcutName)) {
shortcutValue = shortcutBuf.toString();
}
}
var buf = new _text.StringBuffer(notLinkBody);
if ((0, _text.isBlank)(shortcutName)) {
spaceKey = trimIfPossible(divideOn(buf, ':'));
if (buf.indexOf('$') === 0) {
buf.deleteCharAt(0);
contentId = extractNumber(buf);
if (contentId === 0) {
return _objectSpread(_objectSpread({}, link), {}, {
shortcutName: shortcutName,
shortcutValue: shortcutValue,
spaceKey: spaceKey,
contentId: contentId,
attachmentName: attachmentName,
anchor: anchor,
destinationTitle: destinationTitle
});
}
}
attachmentName = trimIfPossible(divideAfter(buf, '^'));
anchor = trimIfPossible(divideAfter(buf, '#'));
}
if (contentId === 0) {
destinationTitle = buf.toString().trim();
}
return _objectSpread(_objectSpread({}, link), {}, {
shortcutName: shortcutName,
shortcutValue: shortcutValue,
spaceKey: spaceKey,
contentId: contentId,
attachmentName: attachmentName,
anchor: anchor,
destinationTitle: destinationTitle
});
}